Implemented support for arrays and safe arrays in VARIANT data
structures. Also moved the SAFEARRAY definition (yet again) to the obj_oleaut.h file.
This commit is contained in:
parent
11db496578
commit
bc5477f7d2
|
@ -7,38 +7,6 @@
|
||||||
/* the following depend only on obj_base.h */
|
/* the following depend only on obj_base.h */
|
||||||
#include "wine/obj_oleaut.h"
|
#include "wine/obj_oleaut.h"
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************
|
|
||||||
* SafeArray defines and structs
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define FADF_AUTO ( 0x1 )
|
|
||||||
#define FADF_STATIC ( 0x2 )
|
|
||||||
#define FADF_EMBEDDED ( 0x4 )
|
|
||||||
#define FADF_FIXEDSIZE ( 0x10 )
|
|
||||||
#define FADF_BSTR ( 0x100 )
|
|
||||||
#define FADF_UNKNOWN ( 0x200 )
|
|
||||||
#define FADF_DISPATCH ( 0x400 )
|
|
||||||
#define FADF_VARIANT ( 0x800 )
|
|
||||||
#define FADF_RESERVED ( 0xf0e8 )
|
|
||||||
|
|
||||||
typedef struct tagSAFEARRAYBOUND
|
|
||||||
{
|
|
||||||
ULONG cElements; /* Number of elements in dimension */
|
|
||||||
LONG lLbound; /* Lower bound of dimension */
|
|
||||||
} SAFEARRAYBOUND;
|
|
||||||
|
|
||||||
typedef struct tagSAFEARRAY
|
|
||||||
{
|
|
||||||
USHORT cDims; /* Count of array dimension */
|
|
||||||
USHORT fFeatures; /* Flags describing the array */
|
|
||||||
ULONG cbElements; /* Size of each element */
|
|
||||||
ULONG cLocks; /* Number of lock on array */
|
|
||||||
PVOID pvData; /* Pointer to data valid when cLocks > 0 */
|
|
||||||
SAFEARRAYBOUND rgsabound[ 1 ]; /* One bound for each dimension */
|
|
||||||
} SAFEARRAY, *LPSAFEARRAY;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum tagCALLCONV {
|
typedef enum tagCALLCONV {
|
||||||
CC_CDECL = 1,
|
CC_CDECL = 1,
|
||||||
CC_MSCPASCAL = CC_CDECL + 1,
|
CC_MSCPASCAL = CC_CDECL + 1,
|
||||||
|
|
|
@ -65,6 +65,37 @@ typedef struct ISupportErrorInfo ISupportErrorInfo,*LPSUPPORTERRORINFO;
|
||||||
* Automation data types
|
* Automation data types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*****************************************************************
|
||||||
|
* SafeArray defines and structs
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FADF_AUTO ( 0x1 )
|
||||||
|
#define FADF_STATIC ( 0x2 )
|
||||||
|
#define FADF_EMBEDDED ( 0x4 )
|
||||||
|
#define FADF_FIXEDSIZE ( 0x10 )
|
||||||
|
#define FADF_BSTR ( 0x100 )
|
||||||
|
#define FADF_UNKNOWN ( 0x200 )
|
||||||
|
#define FADF_DISPATCH ( 0x400 )
|
||||||
|
#define FADF_VARIANT ( 0x800 )
|
||||||
|
#define FADF_RESERVED ( 0xf0e8 )
|
||||||
|
|
||||||
|
typedef struct tagSAFEARRAYBOUND
|
||||||
|
{
|
||||||
|
ULONG cElements; /* Number of elements in dimension */
|
||||||
|
LONG lLbound; /* Lower bound of dimension */
|
||||||
|
} SAFEARRAYBOUND;
|
||||||
|
|
||||||
|
typedef struct tagSAFEARRAY
|
||||||
|
{
|
||||||
|
USHORT cDims; /* Count of array dimension */
|
||||||
|
USHORT fFeatures; /* Flags describing the array */
|
||||||
|
ULONG cbElements; /* Size of each element */
|
||||||
|
ULONG cLocks; /* Number of lock on array */
|
||||||
|
PVOID pvData; /* Pointer to data valid when cLocks > 0 */
|
||||||
|
SAFEARRAYBOUND rgsabound[ 1 ]; /* One bound for each dimension */
|
||||||
|
} SAFEARRAY, *LPSAFEARRAY;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Data types for Variants.
|
* Data types for Variants.
|
||||||
*/
|
*/
|
||||||
|
@ -175,8 +206,8 @@ struct tagVARIANT {
|
||||||
DECIMAL decVal;
|
DECIMAL decVal;
|
||||||
IUnknown* punkVal;
|
IUnknown* punkVal;
|
||||||
IDispatch* pdispVal;
|
IDispatch* pdispVal;
|
||||||
SAFEARRAY* parray;
|
|
||||||
*/
|
*/
|
||||||
|
SAFEARRAY* parray;
|
||||||
|
|
||||||
/* By reference
|
/* By reference
|
||||||
*/
|
*/
|
||||||
|
@ -201,8 +232,8 @@ struct tagVARIANT {
|
||||||
DECIMAL* pdecVal;
|
DECIMAL* pdecVal;
|
||||||
IUnknown** ppunkVal;
|
IUnknown** ppunkVal;
|
||||||
IDispatch** ppdispVal;
|
IDispatch** ppdispVal;
|
||||||
SAFEARRAY** pparray;
|
|
||||||
*/
|
*/
|
||||||
|
SAFEARRAY** pparray;
|
||||||
} _wine_tagVARIANT_UNION_NAME;
|
} _wine_tagVARIANT_UNION_NAME;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -387,6 +387,13 @@ HRESULT WINAPI SafeArrayGetLBound(
|
||||||
UINT WINAPI SafeArrayGetDim(
|
UINT WINAPI SafeArrayGetDim(
|
||||||
SAFEARRAY * psa)
|
SAFEARRAY * psa)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* A quick test in Windows shows that the behavior here for an invalid
|
||||||
|
* pointer is to return 0.
|
||||||
|
*/
|
||||||
|
if(! validArg(psa))
|
||||||
|
return 0;
|
||||||
|
|
||||||
return psa->cDims;
|
return psa->cDims;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,6 +403,13 @@ UINT WINAPI SafeArrayGetDim(
|
||||||
UINT WINAPI SafeArrayGetElemsize(
|
UINT WINAPI SafeArrayGetElemsize(
|
||||||
SAFEARRAY * psa)
|
SAFEARRAY * psa)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* A quick test in Windows shows that the behavior here for an invalid
|
||||||
|
* pointer is to return 0.
|
||||||
|
*/
|
||||||
|
if(! validArg(psa))
|
||||||
|
return 0;
|
||||||
|
|
||||||
return psa->cbElements;
|
return psa->cbElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,6 +742,12 @@ static BOOL validArg(
|
||||||
LONG descSize = 0;
|
LONG descSize = 0;
|
||||||
LONG fullSize = 0;
|
LONG fullSize = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Let's check for the null pointer just in case.
|
||||||
|
*/
|
||||||
|
if (psa == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
/* Check whether the size of the chunk make sens... That's the only thing
|
/* Check whether the size of the chunk make sens... That's the only thing
|
||||||
I can think of now... */
|
I can think of now... */
|
||||||
|
|
||||||
|
|
|
@ -1646,10 +1646,8 @@ void WINAPI VariantInit(VARIANTARG* pvarg)
|
||||||
{
|
{
|
||||||
TRACE(ole,"(%p),stub\n",pvarg);
|
TRACE(ole,"(%p),stub\n",pvarg);
|
||||||
|
|
||||||
|
memset(pvarg, 0, sizeof (VARIANTARG));
|
||||||
pvarg->vt = VT_EMPTY;
|
pvarg->vt = VT_EMPTY;
|
||||||
pvarg->wReserved1 = 0;
|
|
||||||
pvarg->wReserved2= 0;
|
|
||||||
pvarg->wReserved3= 0;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1665,12 +1663,21 @@ void WINAPI VariantInit(VARIANTARG* pvarg)
|
||||||
HRESULT WINAPI VariantClear(VARIANTARG* pvarg)
|
HRESULT WINAPI VariantClear(VARIANTARG* pvarg)
|
||||||
{
|
{
|
||||||
HRESULT res = S_OK;
|
HRESULT res = S_OK;
|
||||||
TRACE(ole,"(%p),stub\n",pvarg);
|
TRACE(ole,"(%p)\n",pvarg);
|
||||||
|
|
||||||
res = ValidateVariantType( pvarg->vt );
|
res = ValidateVariantType( pvarg->vt );
|
||||||
if( res == S_OK )
|
if( res == S_OK )
|
||||||
{
|
{
|
||||||
if( !( pvarg->vt & VT_BYREF ) )
|
if( !( pvarg->vt & VT_BYREF ) )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The VT_ARRAY flag is a special case of a safe array.
|
||||||
|
*/
|
||||||
|
if ( (pvarg->vt & VT_ARRAY) != 0)
|
||||||
|
{
|
||||||
|
SafeArrayDestroy(pvarg->u.parray);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
switch( pvarg->vt & VT_TYPEMASK )
|
switch( pvarg->vt & VT_TYPEMASK )
|
||||||
{
|
{
|
||||||
|
@ -1684,17 +1691,18 @@ HRESULT WINAPI VariantClear(VARIANTARG* pvarg)
|
||||||
case( VT_UNKNOWN ):
|
case( VT_UNKNOWN ):
|
||||||
break;
|
break;
|
||||||
case( VT_SAFEARRAY ):
|
case( VT_SAFEARRAY ):
|
||||||
|
SafeArrayDestroy(pvarg->u.parray);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the fields to empty.
|
/*
|
||||||
|
* Empty all the fields and mark the type as empty.
|
||||||
*/
|
*/
|
||||||
pvarg->wReserved1 = 0;
|
memset(pvarg, 0, sizeof (VARIANTARG));
|
||||||
pvarg->wReserved2 = 0;
|
|
||||||
pvarg->wReserved3 = 0;
|
|
||||||
pvarg->vt = VT_EMPTY;
|
pvarg->vt = VT_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1709,9 +1717,11 @@ HRESULT WINAPI VariantClear(VARIANTARG* pvarg)
|
||||||
HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
|
HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
|
||||||
{
|
{
|
||||||
HRESULT res = S_OK;
|
HRESULT res = S_OK;
|
||||||
TRACE(ole,"(%p, %p),stub\n", pvargDest, pvargSrc);
|
|
||||||
|
TRACE(ole,"(%p, %p)\n", pvargDest, pvargSrc);
|
||||||
|
|
||||||
res = ValidateVariantType( pvargSrc->vt );
|
res = ValidateVariantType( pvargSrc->vt );
|
||||||
|
|
||||||
/* If the pointer are to the same variant we don't need
|
/* If the pointer are to the same variant we don't need
|
||||||
* to do anything.
|
* to do anything.
|
||||||
*/
|
*/
|
||||||
|
@ -1730,11 +1740,19 @@ HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
|
||||||
pvargDest->vt = pvargSrc->vt;
|
pvargDest->vt = pvargSrc->vt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The VT_ARRAY flag is another way to designate a safe array.
|
||||||
|
*/
|
||||||
|
if (pvargSrc->vt & VT_ARRAY)
|
||||||
|
{
|
||||||
|
SafeArrayCopy(pvargSrc->u.parray, &pvargDest->u.parray);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* In the case of by value we need to
|
/* In the case of by value we need to
|
||||||
* copy the actuall value. In the case of
|
* copy the actuall value. In the case of
|
||||||
* VT_BSTR a copy of the string is made,
|
* VT_BSTR a copy of the string is made,
|
||||||
* if VT_ARRAY the entire array is copied
|
|
||||||
* if VT_DISPATCH or VT_IUNKNOWN AddReff is
|
* if VT_DISPATCH or VT_IUNKNOWN AddReff is
|
||||||
* called to increment the object's reference count.
|
* called to increment the object's reference count.
|
||||||
*/
|
*/
|
||||||
|
@ -1750,16 +1768,19 @@ HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
|
||||||
case( VT_UNKNOWN ):
|
case( VT_UNKNOWN ):
|
||||||
break;
|
break;
|
||||||
case( VT_SAFEARRAY ):
|
case( VT_SAFEARRAY ):
|
||||||
|
SafeArrayCopy(pvargSrc->u.parray, &pvargDest->u.parray);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pvargDest->u = pvargSrc->u;
|
pvargDest->u = pvargSrc->u;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pvargDest->vt = pvargSrc->vt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pvargDest->vt = pvargSrc->vt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1773,9 +1794,11 @@ HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
|
||||||
HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
|
HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
|
||||||
{
|
{
|
||||||
HRESULT res = S_OK;
|
HRESULT res = S_OK;
|
||||||
TRACE(ole,"(%p, %p),stub\n", pvargDest, pvargSrc);
|
|
||||||
|
TRACE(ole,"(%p, %p)\n", pvargDest, pvargSrc);
|
||||||
|
|
||||||
res = ValidateVariantType( pvargSrc->vt );
|
res = ValidateVariantType( pvargSrc->vt );
|
||||||
|
|
||||||
if( res != S_OK )
|
if( res != S_OK )
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
@ -1783,6 +1806,7 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
|
||||||
{
|
{
|
||||||
VARIANTARG varg;
|
VARIANTARG varg;
|
||||||
VariantInit( &varg );
|
VariantInit( &varg );
|
||||||
|
|
||||||
/* handle the in place copy.
|
/* handle the in place copy.
|
||||||
*/
|
*/
|
||||||
if( pvargDest == pvargSrc )
|
if( pvargDest == pvargSrc )
|
||||||
|
@ -1792,14 +1816,26 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
|
||||||
res = VariantCopy( &varg, pvargSrc );
|
res = VariantCopy( &varg, pvargSrc );
|
||||||
pvargSrc = &varg;
|
pvargSrc = &varg;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( res == S_OK )
|
if( res == S_OK )
|
||||||
{
|
{
|
||||||
res = VariantClear( pvargDest );
|
res = VariantClear( pvargDest );
|
||||||
|
|
||||||
if( res == S_OK )
|
if( res == S_OK )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The VT_ARRAY flag is another way to designate a safearray variant.
|
||||||
|
*/
|
||||||
|
if ( pvargSrc->vt & VT_ARRAY)
|
||||||
|
{
|
||||||
|
SafeArrayCopy(*pvargSrc->u.pparray, &pvargDest->u.parray);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* In the case of by reference we need
|
/* In the case of by reference we need
|
||||||
* to copy the date pointed to by the variant.
|
* to copy the date pointed to by the variant.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Get the variant type.
|
/* Get the variant type.
|
||||||
*/
|
*/
|
||||||
switch( pvargSrc->vt & VT_TYPEMASK )
|
switch( pvargSrc->vt & VT_TYPEMASK )
|
||||||
|
@ -1833,6 +1869,7 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
|
||||||
* that will be passed to the VariantCopyInd function.
|
* that will be passed to the VariantCopyInd function.
|
||||||
*/
|
*/
|
||||||
(pvargSrc->u.pvarVal)->wReserved1 |= PROCESSING_INNER_VARIANT;
|
(pvargSrc->u.pvarVal)->wReserved1 |= PROCESSING_INNER_VARIANT;
|
||||||
|
|
||||||
/* Dereference the inner variant.
|
/* Dereference the inner variant.
|
||||||
*/
|
*/
|
||||||
res = VariantCopyInd( pvargDest, pvargSrc->u.pvarVal );
|
res = VariantCopyInd( pvargDest, pvargSrc->u.pvarVal );
|
||||||
|
@ -1842,6 +1879,7 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
|
||||||
case( VT_UNKNOWN ):
|
case( VT_UNKNOWN ):
|
||||||
break;
|
break;
|
||||||
case( VT_SAFEARRAY ):
|
case( VT_SAFEARRAY ):
|
||||||
|
SafeArrayCopy(*pvargSrc->u.pparray, &pvargDest->u.parray);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* This is a by reference Variant which means that the union
|
/* This is a by reference Variant which means that the union
|
||||||
|
@ -1855,9 +1893,12 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
|
||||||
memcpy( &pvargDest->u, pvargSrc->u.byref, SizeOfVariantData( pvargSrc ) );
|
memcpy( &pvargDest->u, pvargSrc->u.byref, SizeOfVariantData( pvargSrc ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pvargDest->vt = pvargSrc->vt & VT_TYPEMASK;
|
pvargDest->vt = pvargSrc->vt & VT_TYPEMASK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this should not fail.
|
/* this should not fail.
|
||||||
*/
|
*/
|
||||||
VariantClear( &varg );
|
VariantClear( &varg );
|
||||||
|
@ -1866,6 +1907,7 @@ HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
|
||||||
{
|
{
|
||||||
res = VariantCopy( pvargDest, pvargSrc );
|
res = VariantCopy( pvargDest, pvargSrc );
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue