Implemented SafeArray{SetIID,GetIID,SetRecordInfo,GetRecordInfo}.
Added support for FADF_HAVEIID, FADF_RECORD, FADF_HAVEVARTYPE. Implemented SafeArrayAllocDescriptorEx and SafeArrayGetVarType correctly. Fixed second argument of SafeArrayCopyData (it is just SAFEARRAY*). Changed allocation to include 16 bytes before the SAFEARRAY (to store IID/VARTYPE/IRecordInfo*). VARTYPE -> size array was not indexed correctly. Added lots of testcases for most functionality. Added IRecordInfo interface definition.
This commit is contained in:
parent
48e583db52
commit
8ff278d25e
|
@ -41,8 +41,8 @@
|
||||||
41 stdcall SafeArrayAllocDescriptorEx(long long ptr) SafeArrayAllocDescriptorEx
|
41 stdcall SafeArrayAllocDescriptorEx(long long ptr) SafeArrayAllocDescriptorEx
|
||||||
42 stub SafeArrayCreateEx
|
42 stub SafeArrayCreateEx
|
||||||
43 stub SafeArrayCreateVectorEx
|
43 stub SafeArrayCreateVectorEx
|
||||||
44 stub SafeArraySetRecordInfo
|
44 stdcall SafeArraySetRecordInfo(ptr ptr) SafeArraySetRecordInfo
|
||||||
45 stub SafeArrayGetRecordInfo
|
45 stdcall SafeArrayGetRecordInfo(ptr ptr) SafeArrayGetRecordInfo
|
||||||
46 stdcall VarParseNumFromStr(wstr long long ptr ptr) VarParseNumFromStr
|
46 stdcall VarParseNumFromStr(wstr long long ptr ptr) VarParseNumFromStr
|
||||||
47 stdcall VarNumFromParseNum(ptr ptr long ptr) VarNumFromParseNum
|
47 stdcall VarNumFromParseNum(ptr ptr long ptr) VarNumFromParseNum
|
||||||
48 stdcall VarI2FromUI1(long ptr) VarI2FromUI1
|
48 stdcall VarI2FromUI1(long ptr) VarI2FromUI1
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
54 stdcall VarI2FromStr(wstr long long ptr) VarI2FromStr
|
54 stdcall VarI2FromStr(wstr long long ptr) VarI2FromStr
|
||||||
55 stub VarI2FromDisp
|
55 stub VarI2FromDisp
|
||||||
56 stdcall VarI2FromBool(long ptr) VarI2FromBool
|
56 stdcall VarI2FromBool(long ptr) VarI2FromBool
|
||||||
57 stub SafeArraySetIID
|
57 stdcall SafeArraySetIID(ptr ptr) SafeArraySetIID
|
||||||
58 stdcall VarI4FromUI1(long ptr) VarI4FromUI1
|
58 stdcall VarI4FromUI1(long ptr) VarI4FromUI1
|
||||||
59 stdcall VarI4FromI2(long ptr) VarI4FromI2
|
59 stdcall VarI4FromI2(long ptr) VarI4FromI2
|
||||||
60 stdcall VarI4FromR4(long ptr) VarI4FromR4
|
60 stdcall VarI4FromR4(long ptr) VarI4FromR4
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
64 stdcall VarI4FromStr(wstr long long ptr) VarI4FromStr
|
64 stdcall VarI4FromStr(wstr long long ptr) VarI4FromStr
|
||||||
65 stub VarI4FromDisp
|
65 stub VarI4FromDisp
|
||||||
66 stdcall VarI4FromBool(long ptr) VarI4FromBool
|
66 stdcall VarI4FromBool(long ptr) VarI4FromBool
|
||||||
67 stub SafeArrayGetIID
|
67 stdcall SafeArrayGetIID(ptr ptr) SafeArrayGetIID
|
||||||
68 stdcall VarR4FromUI1(long ptr) VarR4FromUI1
|
68 stdcall VarR4FromUI1(long ptr) VarR4FromUI1
|
||||||
69 stdcall VarR4FromI2(long ptr) VarR4FromI2
|
69 stdcall VarR4FromI2(long ptr) VarR4FromI2
|
||||||
70 stdcall VarR4FromI4(long ptr) VarR4FromI4
|
70 stdcall VarR4FromI4(long ptr) VarR4FromI4
|
||||||
|
|
|
@ -20,6 +20,15 @@
|
||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
/* Memory Layout of a SafeArray:
|
||||||
|
*
|
||||||
|
* -0x10: start of memory.
|
||||||
|
* -0x10: GUID for VT_DISPATCH and VT_UNKNOWN safearrays (if FADF_HAVEIID)
|
||||||
|
* -0x04: DWORD varianttype; (for all others, except VT_RECORD) (if FADF_HAVEVARTYPE)
|
||||||
|
* -0x4: IRecordInfo* iface; (if FADF_RECORD, for VT_RECORD (can be NULL))
|
||||||
|
* 0x00: SAFEARRAY,
|
||||||
|
* 0x10: SAFEARRAYBOUNDS[0...]
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -59,7 +68,7 @@ static ULONG
|
||||||
getArraySize(SAFEARRAY *psa);
|
getArraySize(SAFEARRAY *psa);
|
||||||
|
|
||||||
static HRESULT
|
static HRESULT
|
||||||
duplicateData(SAFEARRAY *psa, SAFEARRAY **ppsaOut);
|
duplicateData(SAFEARRAY *psa, SAFEARRAY *ppsaOut);
|
||||||
|
|
||||||
/* Association between VARTYPE and their size.
|
/* Association between VARTYPE and their size.
|
||||||
A size of zero is defined for the unsupported types. */
|
A size of zero is defined for the unsupported types. */
|
||||||
|
@ -100,6 +109,38 @@ VARTYPE_NOT_SUPPORTED, /* VT_CARRAY [T] C style array */
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_USERDEFINED [T] user defined type */
|
VARTYPE_NOT_SUPPORTED, /* VT_USERDEFINED [T] user defined type */
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_LPSTR [T][P] null terminated string */
|
VARTYPE_NOT_SUPPORTED, /* VT_LPSTR [T][P] null terminated string */
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_LPWSTR [T][P] wide null term string */
|
VARTYPE_NOT_SUPPORTED, /* VT_LPWSTR [T][P] wide null term string */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 32 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 33 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 34 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 35 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* VT_RECORD record */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 37 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 38 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 39 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 40 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 41 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 42 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 43 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 44 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 45 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 46 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 47 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 48 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 49 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 50 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 51 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 52 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 53 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 54 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 55 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 56 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 57 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 58 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 59 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 60 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 61 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 62 */
|
||||||
|
VARTYPE_NOT_SUPPORTED, /* 63 */
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_FILETIME [P] FILETIME */
|
VARTYPE_NOT_SUPPORTED, /* VT_FILETIME [P] FILETIME */
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_BLOB [P] Length prefixed bytes */
|
VARTYPE_NOT_SUPPORTED, /* VT_BLOB [P] Length prefixed bytes */
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_STREAM [P] Name of stream follows */
|
VARTYPE_NOT_SUPPORTED, /* VT_STREAM [P] Name of stream follows */
|
||||||
|
@ -109,9 +150,6 @@ VARTYPE_NOT_SUPPORTED, /* VT_STORED_OBJECT [P] Storage contains object*/
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_BLOB_OBJECT [P] Blob contains an object*/
|
VARTYPE_NOT_SUPPORTED, /* VT_BLOB_OBJECT [P] Blob contains an object*/
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_CF [P] Clipboard format */
|
VARTYPE_NOT_SUPPORTED, /* VT_CF [P] Clipboard format */
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_CLSID [P] A Class ID */
|
VARTYPE_NOT_SUPPORTED, /* VT_CLSID [P] A Class ID */
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_VECTOR [P] simple counted array */
|
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_ARRAY [V] SAFEARRAY* */
|
|
||||||
VARTYPE_NOT_SUPPORTED /* VT_BYREF [V] void* for local use */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int LAST_VARTYPE = sizeof(VARTYPE_SIZE)/sizeof(VARTYPE_SIZE[0]);
|
static const int LAST_VARTYPE = sizeof(VARTYPE_SIZE)/sizeof(VARTYPE_SIZE[0]);
|
||||||
|
@ -127,23 +165,24 @@ HRESULT WINAPI SafeArrayAllocDescriptor(
|
||||||
{
|
{
|
||||||
SAFEARRAYBOUND *sab;
|
SAFEARRAYBOUND *sab;
|
||||||
LONG allocSize = 0;
|
LONG allocSize = 0;
|
||||||
|
LPVOID ptr;
|
||||||
|
|
||||||
if (!cDims || cDims >= 0x10000) /* 65536 appears to be the limit */
|
if (!cDims || cDims >= 0x10000) /* 65536 appears to be the limit */
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
if (!ppsaOut)
|
if (!ppsaOut)
|
||||||
return E_POINTER;
|
return E_POINTER;
|
||||||
|
|
||||||
|
/* GUID + SAFEARRAY + SAFEARRAYBOUND * (cDims -1)
|
||||||
/* SAFEARRAY + SAFEARRAYBOUND * (cDims -1) ( -1 because there is already one
|
* ( -1 because there is already one ( in SAFEARRAY struct
|
||||||
( in SAFEARRAY struct */
|
*/
|
||||||
allocSize = sizeof(**ppsaOut) + (sizeof(*sab) * (cDims-1));
|
allocSize = sizeof(GUID) + sizeof(**ppsaOut) + (sizeof(*sab) * (cDims-1));
|
||||||
|
|
||||||
/* Allocate memory for SAFEARRAY struc */
|
/* Allocate memory for SAFEARRAY struc */
|
||||||
if(( (*ppsaOut)=HeapAlloc(
|
ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, allocSize);
|
||||||
GetProcessHeap(), HEAP_ZERO_MEMORY, allocSize)) == NULL){
|
if (!ptr)
|
||||||
return(E_UNEXPECTED);
|
return E_OUTOFMEMORY;
|
||||||
}
|
*ppsaOut = ptr+sizeof(GUID);
|
||||||
(*ppsaOut)->cDims = cDims;
|
(*ppsaOut)->cDims = cDims;
|
||||||
TRACE("(%d): %lu bytes allocated for descriptor.\n", cDims, allocSize);
|
TRACE("(%d): %lu bytes allocated for descriptor.\n", cDims, allocSize);
|
||||||
|
|
||||||
return(S_OK);
|
return(S_OK);
|
||||||
|
@ -152,21 +191,37 @@ HRESULT WINAPI SafeArrayAllocDescriptor(
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* SafeArrayAllocDescriptorEx (OLEAUT32.41)
|
* SafeArrayAllocDescriptorEx (OLEAUT32.41)
|
||||||
* Allocate the appropriate amount of memory for the SafeArray descriptor
|
* Allocate the appropriate amount of memory for the SafeArray descriptor
|
||||||
*
|
* and also store information about the vartype before the returned pointer.
|
||||||
* This is a minimal implementation just to get things moving.
|
|
||||||
*
|
|
||||||
* The MSDN documentation on this doesn't tell us much.
|
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI SafeArrayAllocDescriptorEx(
|
HRESULT WINAPI SafeArrayAllocDescriptorEx(
|
||||||
VARTYPE vt,
|
VARTYPE vt,
|
||||||
UINT cDims,
|
UINT cDims,
|
||||||
SAFEARRAY **ppsaOut)
|
SAFEARRAY **ppsaOut)
|
||||||
{
|
{
|
||||||
if ( (vt >= LAST_VARTYPE) ||
|
HRESULT hres;
|
||||||
( VARTYPE_SIZE[vt] == VARTYPE_NOT_SUPPORTED ) )
|
|
||||||
return E_UNEXPECTED;
|
|
||||||
|
|
||||||
return SafeArrayAllocDescriptor (cDims, ppsaOut);
|
hres = SafeArrayAllocDescriptor (cDims, ppsaOut);
|
||||||
|
if (FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
switch (vt) {
|
||||||
|
case VT_DISPATCH:
|
||||||
|
(*ppsaOut)->fFeatures = FADF_HAVEIID;
|
||||||
|
SafeArraySetIID( *ppsaOut, &IID_IDispatch);
|
||||||
|
break;
|
||||||
|
case VT_UNKNOWN:
|
||||||
|
(*ppsaOut)->fFeatures = FADF_HAVEIID;
|
||||||
|
SafeArraySetIID( *ppsaOut, &IID_IUnknown);
|
||||||
|
break;
|
||||||
|
case VT_RECORD:
|
||||||
|
(*ppsaOut)->fFeatures = FADF_RECORD;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
(*ppsaOut)->fFeatures = FADF_HAVEVARTYPE;
|
||||||
|
((DWORD*)*ppsaOut)[-1] = vt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -213,12 +268,18 @@ SAFEARRAY* WINAPI SafeArrayCreate(
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Allocate memory for the array descriptor */
|
/* Allocate memory for the array descriptor */
|
||||||
if( FAILED( hRes = SafeArrayAllocDescriptor(cDims, &psa)))
|
if( FAILED( hRes = SafeArrayAllocDescriptorEx(vt, cDims, &psa)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* setup data members... */
|
/* setup data members... */
|
||||||
psa->cDims = cDims;
|
psa->cDims = cDims;
|
||||||
psa->fFeatures = getFeatures(vt);
|
switch (vt) {
|
||||||
|
case VT_BSTR: psa->fFeatures |= FADF_BSTR;break;
|
||||||
|
case VT_UNKNOWN: psa->fFeatures |= FADF_UNKNOWN;break;
|
||||||
|
case VT_DISPATCH: psa->fFeatures |= FADF_DISPATCH;break;
|
||||||
|
case VT_VARIANT: psa->fFeatures |= FADF_VARIANT;break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
psa->cLocks = 0;
|
psa->cLocks = 0;
|
||||||
psa->pvData = NULL;
|
psa->pvData = NULL;
|
||||||
psa->cbElements= VARTYPE_SIZE[vt];
|
psa->cbElements= VARTYPE_SIZE[vt];
|
||||||
|
@ -246,14 +307,16 @@ SAFEARRAY* WINAPI SafeArrayCreate(
|
||||||
HRESULT WINAPI SafeArrayDestroyDescriptor(
|
HRESULT WINAPI SafeArrayDestroyDescriptor(
|
||||||
SAFEARRAY *psa)
|
SAFEARRAY *psa)
|
||||||
{
|
{
|
||||||
|
LPVOID ptr;
|
||||||
|
|
||||||
/* Check for lockness before to free... */
|
/* Check for lockness before to free... */
|
||||||
if(psa->cLocks > 0)
|
if(psa->cLocks > 0)
|
||||||
return DISP_E_ARRAYISLOCKED;
|
return DISP_E_ARRAYISLOCKED;
|
||||||
|
|
||||||
/* The array is unlocked, then, deallocate memory */
|
/* The array is unlocked, then, deallocate memory */
|
||||||
if(HeapFree( GetProcessHeap(), 0, psa) == FALSE)
|
ptr = ((IID*)psa)-1;
|
||||||
|
if(HeapFree( GetProcessHeap(), 0, ptr) == FALSE)
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
return(S_OK);
|
return(S_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +391,7 @@ HRESULT WINAPI SafeArrayPutElement(
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if(psa->fFeatures == FADF_BSTR) { /* Create a new object */
|
if(psa->fFeatures & FADF_BSTR) { /* Create a new object */
|
||||||
BSTR pbstrReAllocStr = NULL;
|
BSTR pbstrReAllocStr = NULL;
|
||||||
if(pv &&
|
if(pv &&
|
||||||
((pbstrReAllocStr = SYSDUPSTRING( (OLECHAR*)pv )) == NULL)) {
|
((pbstrReAllocStr = SYSDUPSTRING( (OLECHAR*)pv )) == NULL)) {
|
||||||
|
@ -337,7 +400,7 @@ HRESULT WINAPI SafeArrayPutElement(
|
||||||
} else
|
} else
|
||||||
*((BSTR*)elementStorageAddress) = pbstrReAllocStr;
|
*((BSTR*)elementStorageAddress) = pbstrReAllocStr;
|
||||||
}
|
}
|
||||||
else if(psa->fFeatures == FADF_VARIANT) {
|
else if(psa->fFeatures & FADF_VARIANT) {
|
||||||
HRESULT hr = VariantCopy(elementStorageAddress, pv);
|
HRESULT hr = VariantCopy(elementStorageAddress, pv);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
SafeArrayUnlock(psa);
|
SafeArrayUnlock(psa);
|
||||||
|
@ -385,7 +448,7 @@ HRESULT WINAPI SafeArrayGetElement(
|
||||||
/* Figure out the number of byte to skip ... */
|
/* Figure out the number of byte to skip ... */
|
||||||
elementStorageAddress = (char *) psa->pvData+(stepCountInSAData*psa->cbElements);
|
elementStorageAddress = (char *) psa->pvData+(stepCountInSAData*psa->cbElements);
|
||||||
|
|
||||||
if( psa->fFeatures == FADF_BSTR) { /* reallocate the obj */
|
if( psa->fFeatures & FADF_BSTR) { /* reallocate the obj */
|
||||||
BSTR pbstrStoredStr = *(OLECHAR**)elementStorageAddress;
|
BSTR pbstrStoredStr = *(OLECHAR**)elementStorageAddress;
|
||||||
BSTR pbstrReturnedStr = NULL;
|
BSTR pbstrReturnedStr = NULL;
|
||||||
if( pbstrStoredStr &&
|
if( pbstrStoredStr &&
|
||||||
|
@ -395,7 +458,7 @@ HRESULT WINAPI SafeArrayGetElement(
|
||||||
} else
|
} else
|
||||||
*((BSTR*)pv) = pbstrReturnedStr;
|
*((BSTR*)pv) = pbstrReturnedStr;
|
||||||
}
|
}
|
||||||
else if( psa->fFeatures == FADF_VARIANT) {
|
else if( psa->fFeatures & FADF_VARIANT) {
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
VariantInit(pv);
|
VariantInit(pv);
|
||||||
hr = VariantCopy(pv, elementStorageAddress);
|
hr = VariantCopy(pv, elementStorageAddress);
|
||||||
|
@ -624,7 +687,7 @@ HRESULT WINAPI SafeArrayDestroyData(
|
||||||
if(!(psa->fFeatures & FADF_CREATEVECTOR)) { /* Set when we do CreateVector */
|
if(!(psa->fFeatures & FADF_CREATEVECTOR)) { /* Set when we do CreateVector */
|
||||||
|
|
||||||
/* free the whole chunk */
|
/* free the whole chunk */
|
||||||
if((hRes = HeapFree( GetProcessHeap(), 0, psa->pvData)) == 0) /*falied*/
|
if((hRes = HeapFree( GetProcessHeap(), 0, psa->pvData)) == 0) /*failed*/
|
||||||
return E_UNEXPECTED; /* UNDOC error condition */
|
return E_UNEXPECTED; /* UNDOC error condition */
|
||||||
|
|
||||||
psa->pvData = NULL;
|
psa->pvData = NULL;
|
||||||
|
@ -640,7 +703,7 @@ HRESULT WINAPI SafeArrayDestroyData(
|
||||||
*/
|
*/
|
||||||
HRESULT WINAPI SafeArrayCopyData(
|
HRESULT WINAPI SafeArrayCopyData(
|
||||||
SAFEARRAY *psaSource,
|
SAFEARRAY *psaSource,
|
||||||
SAFEARRAY **psaTarget)
|
SAFEARRAY *psaTarget)
|
||||||
{
|
{
|
||||||
USHORT cDimCount; /* looper */
|
USHORT cDimCount; /* looper */
|
||||||
LONG lDelta; /* looper */
|
LONG lDelta; /* looper */
|
||||||
|
@ -648,10 +711,10 @@ HRESULT WINAPI SafeArrayCopyData(
|
||||||
ULONG ulWholeArraySize; /* Number of item in SA */
|
ULONG ulWholeArraySize; /* Number of item in SA */
|
||||||
BSTR bstr;
|
BSTR bstr;
|
||||||
|
|
||||||
if(! (validArg(psaSource) && validArg(*psaTarget)) )
|
if(! (validArg(psaSource) && validArg(psaTarget)) )
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
if(SafeArrayGetDim(psaSource) != SafeArrayGetDim(*psaTarget))
|
if(SafeArrayGetDim(psaSource) != SafeArrayGetDim(psaTarget))
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
ulWholeArraySize = getArraySize(psaSource);
|
ulWholeArraySize = getArraySize(psaSource);
|
||||||
|
@ -659,34 +722,34 @@ HRESULT WINAPI SafeArrayCopyData(
|
||||||
/* The two arrays boundaries must be of same lenght */
|
/* The two arrays boundaries must be of same lenght */
|
||||||
for(cDimCount=0;cDimCount < psaSource->cDims; cDimCount++)
|
for(cDimCount=0;cDimCount < psaSource->cDims; cDimCount++)
|
||||||
if( psaSource->rgsabound[cDimCount].cElements !=
|
if( psaSource->rgsabound[cDimCount].cElements !=
|
||||||
(*psaTarget)->rgsabound[cDimCount].cElements)
|
psaTarget->rgsabound[cDimCount].cElements)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
if( isPointer((*psaTarget)->fFeatures) ) { /* the target contains ptr
|
if( isPointer(psaTarget->fFeatures) ) { /* the target contains ptr
|
||||||
that must be released */
|
that must be released */
|
||||||
for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
|
for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
|
||||||
punk = *(IUnknown**)
|
punk = *(IUnknown**)
|
||||||
((char *) (*psaTarget)->pvData + (lDelta * (*psaTarget)->cbElements));
|
((char *) psaTarget->pvData + (lDelta * psaTarget->cbElements));
|
||||||
|
|
||||||
if( punk != NULL)
|
if( punk != NULL)
|
||||||
IUnknown_Release(punk);
|
IUnknown_Release(punk);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if( (*psaTarget)->fFeatures & FADF_BSTR) { /* the target contain BSTR
|
else if( psaTarget->fFeatures & FADF_BSTR) { /* the target contain BSTR
|
||||||
that must be freed */
|
that must be freed */
|
||||||
for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
|
for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
|
||||||
bstr =
|
bstr =
|
||||||
*(BSTR*)((char *) (*psaTarget)->pvData + (lDelta * (*psaTarget)->cbElements));
|
*(BSTR*)((char *) psaTarget->pvData + (lDelta * psaTarget->cbElements));
|
||||||
|
|
||||||
if( bstr != NULL)
|
if( bstr != NULL)
|
||||||
SysFreeString( bstr );
|
SysFreeString( bstr );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( (*psaTarget)->fFeatures & FADF_VARIANT) {
|
else if( psaTarget->fFeatures & FADF_VARIANT) {
|
||||||
|
|
||||||
for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
|
for(lDelta=0;lDelta < ulWholeArraySize; lDelta++) {
|
||||||
VariantClear((VARIANT*)((char *) (*psaTarget)->pvData + (lDelta * (*psaTarget)->cbElements)));
|
VariantClear((VARIANT*)((char *) psaTarget->pvData + (lDelta * psaTarget->cbElements)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,10 +795,27 @@ HRESULT WINAPI SafeArrayCopy(
|
||||||
|
|
||||||
if((hRes=SafeArrayAllocDescriptor(psa->cDims, ppsaOut)) == S_OK){
|
if((hRes=SafeArrayAllocDescriptor(psa->cDims, ppsaOut)) == S_OK){
|
||||||
|
|
||||||
/* Duplicate the SAFEARRAY struc */
|
/* Duplicate the SAFEARRAY struct */
|
||||||
memcpy(*ppsaOut, psa,
|
memcpy(*ppsaOut, psa,
|
||||||
sizeof(*psa)+(sizeof(*(psa->rgsabound))*(psa->cDims-1)));
|
sizeof(*psa)+(sizeof(*(psa->rgsabound))*(psa->cDims-1)));
|
||||||
|
|
||||||
|
/* If the features that use storage before the SAFEARRAY struct are
|
||||||
|
* enabled, also copy this memory range. Flags have been copied already.
|
||||||
|
*/
|
||||||
|
if (psa->fFeatures & (FADF_HAVEIID | FADF_HAVEVARTYPE))
|
||||||
|
memcpy(((GUID*)*ppsaOut)-1, ((GUID*)psa)-1, sizeof(GUID));
|
||||||
|
|
||||||
|
/* Copy the IRecordInfo* reference */
|
||||||
|
if (psa->fFeatures & FADF_RECORD) {
|
||||||
|
IRecordInfo *ri;
|
||||||
|
|
||||||
|
ri = ((IRecordInfo**)psa)[-1];
|
||||||
|
if (ri) {
|
||||||
|
((IRecordInfo**)*ppsaOut)[-1] = ri;
|
||||||
|
IRecordInfo_AddRef(ri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(*ppsaOut)->pvData = NULL; /* do not point to the same data area */
|
(*ppsaOut)->pvData = NULL; /* do not point to the same data area */
|
||||||
|
|
||||||
/* make sure the new safe array doesn't have the FADF_CREATEVECTOR flag,
|
/* make sure the new safe array doesn't have the FADF_CREATEVECTOR flag,
|
||||||
|
@ -750,7 +830,7 @@ HRESULT WINAPI SafeArrayCopy(
|
||||||
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dAllocSize);
|
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dAllocSize);
|
||||||
if( (*ppsaOut)->pvData != NULL) { /* HeapAlloc succeed */
|
if( (*ppsaOut)->pvData != NULL) { /* HeapAlloc succeed */
|
||||||
|
|
||||||
if( (hRes=duplicateData(psa, ppsaOut)) != S_OK) { /* E_OUTOFMEMORY */
|
if( (hRes=duplicateData(psa, *ppsaOut)) != S_OK) { /* E_OUTOFMEMORY */
|
||||||
HeapFree(GetProcessHeap(), 0, (*ppsaOut)->pvData);
|
HeapFree(GetProcessHeap(), 0, (*ppsaOut)->pvData);
|
||||||
(*ppsaOut)->pvData = NULL;
|
(*ppsaOut)->pvData = NULL;
|
||||||
SafeArrayDestroyDescriptor(*ppsaOut);
|
SafeArrayDestroyDescriptor(*ppsaOut);
|
||||||
|
@ -779,6 +859,7 @@ SAFEARRAY* WINAPI SafeArrayCreateVector(
|
||||||
ULONG cElements)
|
ULONG cElements)
|
||||||
{
|
{
|
||||||
SAFEARRAY *psa;
|
SAFEARRAY *psa;
|
||||||
|
LPVOID *ptr;
|
||||||
|
|
||||||
/* Validate supported VARTYPE */
|
/* Validate supported VARTYPE */
|
||||||
if ( (vt >= LAST_VARTYPE) ||
|
if ( (vt >= LAST_VARTYPE) ||
|
||||||
|
@ -786,11 +867,12 @@ SAFEARRAY* WINAPI SafeArrayCreateVector(
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Allocate memory for the array descriptor and data contiguously */
|
/* Allocate memory for the array descriptor and data contiguously */
|
||||||
if( FAILED( psa = HeapAlloc( GetProcessHeap(),
|
ptr = HeapAlloc( GetProcessHeap(),
|
||||||
HEAP_ZERO_MEMORY,
|
HEAP_ZERO_MEMORY,
|
||||||
(sizeof(*psa) + (VARTYPE_SIZE[vt] * cElements))))) {
|
(sizeof(GUID)+sizeof(*psa)+(VARTYPE_SIZE[vt]*cElements)));
|
||||||
|
if (!ptr)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
psa = (SAFEARRAY*)(ptr+sizeof(GUID));
|
||||||
|
|
||||||
/* setup data members... */
|
/* setup data members... */
|
||||||
psa->cDims = 1; /* always and forever */
|
psa->cDims = 1; /* always and forever */
|
||||||
|
@ -874,13 +956,13 @@ static BOOL validArg(
|
||||||
/* Check whether the size of the chunk makes sense... That's the only thing
|
/* Check whether the size of the chunk makes sense... That's the only thing
|
||||||
I can think of now... */
|
I can think of now... */
|
||||||
|
|
||||||
psaSize = HeapSize(GetProcessHeap(), 0, psa);
|
psaSize = HeapSize(GetProcessHeap(), 0, ((IID*)psa)-1);
|
||||||
if (psaSize == -1)
|
if (psaSize == -1)
|
||||||
/* uh, foreign heap. Better don't mess with it ! */
|
/* uh, foreign heap. Better don't mess with it ! */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* size of the descriptor when the SA is not created with CreateVector */
|
/* size of the descriptor when the SA is not created with CreateVector */
|
||||||
descSize = sizeof(*psa) + (sizeof(*sab) * (psa->cDims-1));
|
descSize = sizeof(GUID) + sizeof(*psa) + (sizeof(*sab) * (psa->cDims-1));
|
||||||
|
|
||||||
/* size of the descriptor + data when created with CreateVector */
|
/* size of the descriptor + data when created with CreateVector */
|
||||||
fullSize = sizeof(*psa) + (psa->cbElements * psa->rgsabound[0].cElements);
|
fullSize = sizeof(*psa) + (psa->cbElements * psa->rgsabound[0].cElements);
|
||||||
|
@ -960,14 +1042,12 @@ static BOOL resizeSafeArray(
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Used to set the fFeatures data member of the SAFEARRAY structure.
|
* Used to set the fFeatures data member of the SAFEARRAY structure.
|
||||||
*/
|
*/
|
||||||
static INT getFeatures(
|
static INT getFeatures(VARTYPE vt) {
|
||||||
VARTYPE vt)
|
switch (vt) {
|
||||||
{
|
case VT_BSTR: return FADF_BSTR;
|
||||||
switch(vt) {
|
case VT_UNKNOWN: return FADF_UNKNOWN;
|
||||||
case VT_BSTR: return FADF_BSTR;
|
case VT_DISPATCH: return FADF_DISPATCH;
|
||||||
case VT_UNKNOWN: return FADF_UNKNOWN;
|
case VT_VARIANT: return FADF_VARIANT;
|
||||||
case VT_DISPATCH: return FADF_DISPATCH;
|
|
||||||
case VT_VARIANT: return FADF_VARIANT;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1088,14 +1168,14 @@ static ULONG getArraySize(
|
||||||
*/
|
*/
|
||||||
static HRESULT duplicateData(
|
static HRESULT duplicateData(
|
||||||
SAFEARRAY *psa,
|
SAFEARRAY *psa,
|
||||||
SAFEARRAY **ppsaOut)
|
SAFEARRAY *ppsaOut)
|
||||||
{
|
{
|
||||||
ULONG ulWholeArraySize; /* size of the thing */
|
ULONG ulWholeArraySize; /* size of the thing */
|
||||||
LONG lDelta;
|
LONG lDelta;
|
||||||
|
|
||||||
ulWholeArraySize = getArraySize(psa); /* Number of item in SA */
|
ulWholeArraySize = getArraySize(psa); /* Number of item in SA */
|
||||||
|
|
||||||
SafeArrayLock(*ppsaOut);
|
SafeArrayLock(ppsaOut);
|
||||||
|
|
||||||
if( isPointer(psa->fFeatures) ) { /* If datatype is object increment
|
if( isPointer(psa->fFeatures) ) { /* If datatype is object increment
|
||||||
object's reference count */
|
object's reference count */
|
||||||
|
@ -1109,8 +1189,7 @@ static HRESULT duplicateData(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the source array data into target array */
|
/* Copy the source array data into target array */
|
||||||
memcpy((*ppsaOut)->pvData, psa->pvData,
|
memcpy(ppsaOut->pvData, psa->pvData, ulWholeArraySize*psa->cbElements);
|
||||||
ulWholeArraySize*psa->cbElements);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if( psa->fFeatures & FADF_BSTR ) { /* if datatype is BSTR allocate
|
else if( psa->fFeatures & FADF_BSTR ) { /* if datatype is BSTR allocate
|
||||||
|
@ -1121,11 +1200,11 @@ static HRESULT duplicateData(
|
||||||
if(( pbstrReAllocStr = SYSDUPSTRING(
|
if(( pbstrReAllocStr = SYSDUPSTRING(
|
||||||
*(BSTR*)((char *) psa->pvData+(lDelta * psa->cbElements)))) == NULL) {
|
*(BSTR*)((char *) psa->pvData+(lDelta * psa->cbElements)))) == NULL) {
|
||||||
|
|
||||||
SafeArrayUnlock(*ppsaOut);
|
SafeArrayUnlock(ppsaOut);
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
*((BSTR*)((char *) (*ppsaOut)->pvData+(lDelta * psa->cbElements))) =
|
*((BSTR*)((char *)ppsaOut->pvData+(lDelta * psa->cbElements))) =
|
||||||
pbstrReAllocStr;
|
pbstrReAllocStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1133,19 +1212,14 @@ static HRESULT duplicateData(
|
||||||
else if( psa->fFeatures & FADF_VARIANT ) {
|
else if( psa->fFeatures & FADF_VARIANT ) {
|
||||||
|
|
||||||
for(lDelta=0; lDelta < ulWholeArraySize; lDelta++) {
|
for(lDelta=0; lDelta < ulWholeArraySize; lDelta++) {
|
||||||
VariantCopy((VARIANT*)((char *) (*ppsaOut)->pvData+(lDelta * psa->cbElements)),
|
VariantCopy((VARIANT*)((char *) ppsaOut->pvData+(lDelta * psa->cbElements)),
|
||||||
(VARIANT*)((char *) psa->pvData+(lDelta * psa->cbElements)));
|
(VARIANT*)((char *) psa->pvData+(lDelta * psa->cbElements)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else { /* Simply copy the source array data into target array */
|
||||||
|
memcpy(ppsaOut->pvData, psa->pvData, ulWholeArraySize*psa->cbElements);
|
||||||
}
|
}
|
||||||
else { /* Simply copy the source array data into target array */
|
SafeArrayUnlock(ppsaOut);
|
||||||
|
|
||||||
memcpy((*ppsaOut)->pvData, psa->pvData,
|
|
||||||
ulWholeArraySize*psa->cbElements);
|
|
||||||
}
|
|
||||||
|
|
||||||
SafeArrayUnlock(*ppsaOut);
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1158,44 +1232,106 @@ HRESULT WINAPI SafeArrayGetVartype(
|
||||||
SAFEARRAY* psa,
|
SAFEARRAY* psa,
|
||||||
VARTYPE* pvt)
|
VARTYPE* pvt)
|
||||||
{
|
{
|
||||||
HRESULT hr = E_INVALIDARG;
|
|
||||||
VARTYPE vt = VT_EMPTY;
|
|
||||||
|
|
||||||
/* const short VARTYPE_OFFSET = -4; */
|
|
||||||
|
|
||||||
if (psa->fFeatures & FADF_HAVEVARTYPE)
|
if (psa->fFeatures & FADF_HAVEVARTYPE)
|
||||||
{
|
{
|
||||||
/* VT tag @ negative offset 4 in the array descriptor */
|
/* VT tag @ negative offset 4 in the array descriptor */
|
||||||
FIXME("Returning VT_BSTR instead of VT_...\n");
|
*pvt = ((DWORD*)psa)[-1];
|
||||||
vt = VT_BSTR;
|
return S_OK;
|
||||||
}
|
|
||||||
else if (psa->fFeatures & FADF_RECORD)
|
|
||||||
{
|
|
||||||
vt = VT_RECORD;
|
|
||||||
}
|
|
||||||
else if (psa->fFeatures & FADF_BSTR)
|
|
||||||
{
|
|
||||||
vt = VT_BSTR;
|
|
||||||
}
|
|
||||||
else if (psa->fFeatures & FADF_UNKNOWN)
|
|
||||||
{
|
|
||||||
vt = VT_UNKNOWN;
|
|
||||||
}
|
|
||||||
else if (psa->fFeatures & FADF_DISPATCH)
|
|
||||||
{
|
|
||||||
vt = VT_DISPATCH;
|
|
||||||
}
|
|
||||||
else if (psa->fFeatures & FADF_VARIANT)
|
|
||||||
{
|
|
||||||
vt = VT_VARIANT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vt != VT_EMPTY)
|
if (psa->fFeatures & FADF_RECORD)
|
||||||
{
|
{
|
||||||
*pvt = vt;
|
*pvt = VT_RECORD;
|
||||||
hr = S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("HRESULT = %08lx\n", hr);
|
if (psa->fFeatures & FADF_BSTR)
|
||||||
return hr;
|
{
|
||||||
|
*pvt = VT_BSTR;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (psa->fFeatures & FADF_UNKNOWN)
|
||||||
|
{
|
||||||
|
*pvt = VT_UNKNOWN;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (psa->fFeatures & FADF_DISPATCH)
|
||||||
|
{
|
||||||
|
*pvt = VT_UNKNOWN; /* Yes, checked against windows */
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (psa->fFeatures & FADF_VARIANT)
|
||||||
|
{
|
||||||
|
*pvt = VT_VARIANT;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
if (psa->fFeatures & FADF_HAVEIID)
|
||||||
|
{
|
||||||
|
/* We could check the IID here, but Windows apparently does not
|
||||||
|
* do that and returns VT_UNKNOWN for VT_DISPATCH too.
|
||||||
|
*/
|
||||||
|
*pvt = VT_UNKNOWN;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN("No vt found for safearray\n");
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* SafeArraySetIID (OLEAUT32.57)
|
||||||
|
*/
|
||||||
|
HRESULT WINAPI SafeArraySetIID(SAFEARRAY *arr, REFIID riid) {
|
||||||
|
IID *xiid = ((IID*)arr)-1;
|
||||||
|
TRACE("(%p, %s).\n",arr,debugstr_guid(riid));
|
||||||
|
|
||||||
|
if (!arr || !(arr->fFeatures & FADF_HAVEIID))
|
||||||
|
return E_INVALIDARG;
|
||||||
|
memcpy(xiid, riid, sizeof(GUID));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* SafeArrayGetIID (OLEAUT32.67)
|
||||||
|
*/
|
||||||
|
HRESULT WINAPI SafeArrayGetIID(SAFEARRAY *arr, IID *riid) {
|
||||||
|
IID *xiid = ((IID*)arr)-1;
|
||||||
|
TRACE("(%p, %s).\n",arr,debugstr_guid(riid));
|
||||||
|
|
||||||
|
if (!arr || !(arr->fFeatures & FADF_HAVEIID))
|
||||||
|
return E_INVALIDARG;
|
||||||
|
memcpy(riid, xiid, sizeof(GUID));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* SafeArraySetRecordInfo (OLEAUT32.44)
|
||||||
|
*/
|
||||||
|
HRESULT WINAPI SafeArraySetRecordInfo(SAFEARRAY *arr, IRecordInfo *iface) {
|
||||||
|
LPRECORDINFO oldiface;
|
||||||
|
|
||||||
|
if (!arr || !(arr->fFeatures & FADF_RECORD))
|
||||||
|
return E_INVALIDARG;
|
||||||
|
oldiface = ((IRecordInfo**)arr)[-1];
|
||||||
|
if (oldiface)
|
||||||
|
IRecordInfo_Release(oldiface);
|
||||||
|
((IRecordInfo**)arr)[-1] = iface;
|
||||||
|
if (iface)
|
||||||
|
IRecordInfo_AddRef(iface);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* SafeArrayGetRecordInfo (OLEAUT32.45)
|
||||||
|
*/
|
||||||
|
HRESULT WINAPI SafeArrayGetRecordInfo(SAFEARRAY *arr, IRecordInfo** iface) {
|
||||||
|
if (!arr || !(arr->fFeatures & FADF_RECORD))
|
||||||
|
return E_INVALIDARG;
|
||||||
|
*iface = ((IRecordInfo**)arr)[-1];
|
||||||
|
if (*iface)
|
||||||
|
IRecordInfo_AddRef(*iface);
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ SRCDIR = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
TESTDLL = oleaut32.dll
|
TESTDLL = oleaut32.dll
|
||||||
IMPORTS = oleaut32
|
IMPORTS = oleaut32
|
||||||
|
EXTRALIBS = $(LIBUUID)
|
||||||
|
|
||||||
CTESTS = \
|
CTESTS = \
|
||||||
safearray.c \
|
safearray.c \
|
||||||
|
|
|
@ -37,60 +37,66 @@
|
||||||
#include "oleauto.h"
|
#include "oleauto.h"
|
||||||
|
|
||||||
#define VARTYPE_NOT_SUPPORTED 0
|
#define VARTYPE_NOT_SUPPORTED 0
|
||||||
static ULONG vttypes[] = {
|
static struct {
|
||||||
/* this is taken from wtypes.h. Only [S]es are supported by the SafeArray */
|
enum VARENUM vt; /* VT */
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_EMPTY [V] [P] nothing */
|
UINT elemsize; /* elementsize by VT */
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_NULL [V] [P] SQL style Nul */
|
UINT expflags; /* fFeatures from SafeArrayAllocDescriptorEx */
|
||||||
2, /* VT_I2 [V][T][P][S] 2 byte signed int */
|
UINT addflags; /* additional fFeatures from SafeArrayCreate */
|
||||||
4, /* VT_I4 [V][T][P][S] 4 byte signed int */
|
} vttypes[] = {
|
||||||
4, /* VT_R4 [V][T][P][S] 4 byte real */
|
{VT_EMPTY, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
8, /* VT_R8 [V][T][P][S] 8 byte real */
|
{VT_NULL, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
8, /* VT_CY [V][T][P][S] currency */
|
{VT_I2, 2, FADF_HAVEVARTYPE,0},
|
||||||
8, /* VT_DATE [V][T][P][S] date */
|
{VT_I4, 4, FADF_HAVEVARTYPE,0},
|
||||||
sizeof(BSTR), /* VT_BSTR [V][T][P][S] OLE Automation string*/
|
{VT_R4, 4, FADF_HAVEVARTYPE,0},
|
||||||
sizeof(LPDISPATCH), /* VT_DISPATCH [V][T][P][S] IDispatch * */
|
{VT_R8, 8, FADF_HAVEVARTYPE,0},
|
||||||
4, /* VT_ERROR [V][T] [S] SCODE */
|
{VT_CY, 8, FADF_HAVEVARTYPE,0},
|
||||||
2, /* VT_BOOL [V][T][P][S] True=-1, False=0*/
|
{VT_DATE, 8, FADF_HAVEVARTYPE,0},
|
||||||
sizeof(VARIANT), /* VT_VARIANT [V][T][P][S] VARIANT * */
|
{VT_BSTR, sizeof(BSTR), FADF_HAVEVARTYPE,FADF_BSTR},
|
||||||
sizeof(LPUNKNOWN), /* VT_UNKNOWN [V][T] [S] IUnknown * */
|
{VT_DISPATCH, sizeof(LPDISPATCH), FADF_HAVEIID, FADF_DISPATCH},
|
||||||
sizeof(DECIMAL), /* VT_DECIMAL [V][T] [S] 16 byte fixed point */
|
{VT_ERROR, 4, FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* no VARTYPE here..... */
|
{VT_BOOL, 2, FADF_HAVEVARTYPE,0},
|
||||||
1, /* VT_I1 [T] [S] signed char */
|
{VT_VARIANT, sizeof(VARIANT), FADF_HAVEVARTYPE,FADF_VARIANT},
|
||||||
1, /* VT_UI1 [V][T][P][S] unsigned char */
|
{VT_UNKNOWN, sizeof(LPUNKNOWN), FADF_HAVEIID, FADF_UNKNOWN},
|
||||||
2, /* VT_UI2 [T][P][S] unsigned short */
|
{VT_DECIMAL, sizeof(DECIMAL), FADF_HAVEVARTYPE,0},
|
||||||
4, /* VT_UI4 [T][P][S] unsigned int */
|
{15, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0}, /* no VT_xxx */
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_I8 [T][P] signed 64-bit int */
|
{VT_I1, 1, FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_UI8 [T][P] unsigned 64-bit int */
|
{VT_UI1, 1, FADF_HAVEVARTYPE,0},
|
||||||
sizeof(INT), /* VT_INT [T] signed machine int */
|
{VT_UI2, 2, FADF_HAVEVARTYPE,0},
|
||||||
sizeof(UINT), /* VT_UINT [T] unsigned machine int */
|
{VT_UI4, 4, FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_VOID [T] C style void */
|
{VT_I8, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_HRESULT [T] Standard return type */
|
{VT_UI8, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_PTR [T] pointer type */
|
{VT_INT, sizeof(INT), FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_SAFEARRAY [T] (use VT_ARRAY in VARIANT)*/
|
{VT_UINT, sizeof(UINT), FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_CARRAY [T] C style array */
|
{VT_VOID, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_USERDEFINED [T] user defined type */
|
{VT_HRESULT, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_LPSTR [T][P] null terminated string */
|
{VT_PTR, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_LPWSTR [T][P] wide null term string */
|
{VT_SAFEARRAY,VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_FILETIME [P] FILETIME */
|
{VT_CARRAY, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_BLOB [P] Length prefixed bytes */
|
{VT_USERDEFINED,VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_STREAM [P] Name of stream follows */
|
{VT_LPSTR, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_STORAGE [P] Name of storage follows */
|
{VT_LPWSTR, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_STREAMED_OBJECT[P] Stream contains an object*/
|
{VT_FILETIME, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_STORED_OBJECT [P] Storage contains object*/
|
{VT_RECORD, VARTYPE_NOT_SUPPORTED,FADF_RECORD,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_BLOB_OBJECT [P] Blob contains an object*/
|
{VT_BLOB, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_CF [P] Clipboard format */
|
{VT_STREAM, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_CLSID [P] A Class ID */
|
{VT_STORAGE, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_VECTOR [P] simple counted array */
|
{VT_STREAMED_OBJECT,VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED, /* VT_ARRAY [V] SAFEARRAY* */
|
{VT_STORED_OBJECT,VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
VARTYPE_NOT_SUPPORTED /* VT_BYREF [V] void* for local use */
|
{VT_BLOB_OBJECT,VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
|
{VT_CF, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
|
{VT_CLSID, VARTYPE_NOT_SUPPORTED,FADF_HAVEVARTYPE,0},
|
||||||
};
|
};
|
||||||
|
|
||||||
START_TEST(safearray)
|
START_TEST(safearray)
|
||||||
{
|
{
|
||||||
SAFEARRAY *a;
|
SAFEARRAY *a, b, *c;
|
||||||
unsigned short i;
|
unsigned int i;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
SAFEARRAYBOUND bound;
|
SAFEARRAYBOUND bound;
|
||||||
|
VARIANT v;
|
||||||
|
LPVOID data;
|
||||||
|
IID iid;
|
||||||
|
VARTYPE vt;
|
||||||
|
|
||||||
hres = SafeArrayAllocDescriptor(0,&a);
|
hres = SafeArrayAllocDescriptor(0,&a);
|
||||||
ok(E_INVALIDARG == hres,"SAAD(0) failed with hres %lx",hres);
|
ok(E_INVALIDARG == hres,"SAAD(0) failed with hres %lx",hres);
|
||||||
|
@ -100,12 +106,12 @@ START_TEST(safearray)
|
||||||
|
|
||||||
for (i=1;i<100;i++) {
|
for (i=1;i<100;i++) {
|
||||||
hres=SafeArrayAllocDescriptor(i,&a);
|
hres=SafeArrayAllocDescriptor(i,&a);
|
||||||
ok(S_OK == hres,"SAAD(%d) failed with %lx\n",i,hres);
|
ok(S_OK == hres,"SAAD(%d) failed with %lx",i,hres);
|
||||||
|
|
||||||
ok(a->cDims == i,"a->cDims not initialised?\n");
|
ok(a->cDims == i,"a->cDims not initialised?");
|
||||||
|
|
||||||
hres=SafeArrayDestroyDescriptor(a);
|
hres=SafeArrayDestroyDescriptor(a);
|
||||||
ok(S_OK == hres,"SADD failed with %lx\n",hres);
|
ok(S_OK == hres,"SADD failed with %lx",hres);
|
||||||
}
|
}
|
||||||
|
|
||||||
hres=SafeArrayAllocDescriptor(65535,&a);
|
hres=SafeArrayAllocDescriptor(65535,&a);
|
||||||
|
@ -124,13 +130,163 @@ START_TEST(safearray)
|
||||||
bound.cElements = 1;
|
bound.cElements = 1;
|
||||||
bound.lLbound = 0;
|
bound.lLbound = 0;
|
||||||
a = SafeArrayCreate(-1, 1, &bound);
|
a = SafeArrayCreate(-1, 1, &bound);
|
||||||
ok(NULL == a,"SAC(-1,1,[1,0]) not failed?\n");
|
ok(NULL == a,"SAC(-1,1,[1,0]) not failed?");
|
||||||
|
|
||||||
for (i=0;i<sizeof(vttypes)/sizeof(vttypes[0]);i++) {
|
for (i=0;i<sizeof(vttypes)/sizeof(vttypes[0]);i++) {
|
||||||
a = SafeArrayCreate(i, 1, &bound);
|
a = SafeArrayCreate(vttypes[i].vt, 1, &bound);
|
||||||
ok( ((a == NULL) && (vttypes[i] == 0)) ||
|
ok( ((a == NULL) && (vttypes[i].elemsize == 0)) ||
|
||||||
((a != NULL) && (vttypes[i] == a->cbElements)),
|
((a != NULL) && (vttypes[i].elemsize == a->cbElements)),
|
||||||
"SAC(%d,1,[1,0]), result %ld, expected %ld\n",i,(a?a->cbElements:0),vttypes[i]
|
"SAC(%d,1,[1,0]), result %ld, expected %d",vttypes[i].vt,(a?a->cbElements:0),vttypes[i].elemsize
|
||||||
);
|
);
|
||||||
|
if (a!=NULL)
|
||||||
|
ok(a->fFeatures == (vttypes[i].expflags | vttypes[i].addflags),"SAC of %d returned feature flags %x, expected %x", vttypes[i].vt, a->fFeatures, vttypes[i].expflags|vttypes[i].addflags);
|
||||||
|
ok(SafeArrayGetElemsize(a) == vttypes[i].elemsize,"SAGE for vt %d returned elemsize %d instead of expected %d",vttypes[i].vt, SafeArrayGetElemsize(a),vttypes[i].elemsize);
|
||||||
|
|
||||||
|
if (!a) continue;
|
||||||
|
|
||||||
|
hres = SafeArrayGetVartype(a, &vt);
|
||||||
|
ok(hres == S_OK, "SAGVT of array with vt %d failed with %lx", vttypes[i].vt, hres);
|
||||||
|
if (vttypes[i].vt == VT_DISPATCH) {
|
||||||
|
/* Special case. Checked against Windows. */
|
||||||
|
ok(vt == VT_UNKNOWN, "SAGVT of array with VT_DISPATCH returned not VT_UNKNOWN, but %d", vt);
|
||||||
|
} else {
|
||||||
|
ok(vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d", vttypes[i].vt, vt);
|
||||||
|
}
|
||||||
|
|
||||||
|
hres = SafeArrayCopy(a, &c);
|
||||||
|
ok(hres == S_OK, "failed to copy safearray of vt %d with hres %lx", vttypes[i].vt, hres);
|
||||||
|
|
||||||
|
ok(vttypes[i].elemsize == c->cbElements,"copy of SAC(%d,1,[1,0]), result %ld, expected %d",vttypes[i].vt,(c?c->cbElements:0),vttypes[i].elemsize
|
||||||
|
);
|
||||||
|
ok(c->fFeatures == (vttypes[i].expflags | vttypes[i].addflags),"SAC of %d returned feature flags %x, expected %x", vttypes[i].vt, c->fFeatures, vttypes[i].expflags|vttypes[i].addflags);
|
||||||
|
ok(SafeArrayGetElemsize(c) == vttypes[i].elemsize,"SAGE for vt %d returned elemsize %d instead of expected %d",vttypes[i].vt, SafeArrayGetElemsize(c),vttypes[i].elemsize);
|
||||||
|
|
||||||
|
hres = SafeArrayGetVartype(c, &vt);
|
||||||
|
ok(hres == S_OK, "SAGVT of array with vt %d failed with %lx", vttypes[i].vt, hres);
|
||||||
|
if (vttypes[i].vt == VT_DISPATCH) {
|
||||||
|
/* Special case. Checked against Windows. */
|
||||||
|
ok(vt == VT_UNKNOWN, "SAGVT of array with VT_DISPATCH returned not VT_UNKNOWN, but %d", vt);
|
||||||
|
} else {
|
||||||
|
ok(vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d", vttypes[i].vt, vt);
|
||||||
|
}
|
||||||
|
hres = SafeArrayCopyData(a, c);
|
||||||
|
ok(hres == S_OK, "failed to copy safearray data of vt %d with hres %lx", vttypes[i].vt, hres);
|
||||||
|
|
||||||
|
hres = SafeArrayDestroyData(c);
|
||||||
|
ok(hres == S_OK,"SADD of copy of array with vt %d failed with hres %lx", vttypes[i].vt, hres);
|
||||||
|
|
||||||
|
hres = SafeArrayDestroy(a);
|
||||||
|
ok(hres == S_OK,"SAD of array with vt %d failed with hres %lx", vttypes[i].vt, hres);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Test conversion of type|VT_ARRAY <-> VT_BSTR */
|
||||||
|
bound.lLbound = 0;
|
||||||
|
bound.cElements = 10;
|
||||||
|
a = SafeArrayCreate(VT_UI1, 1, &bound);
|
||||||
|
ok(a != NULL, "SAC failed.");
|
||||||
|
ok(S_OK == SafeArrayAccessData(a, &data),"SACD failed");
|
||||||
|
memcpy(data,"Hello World",10);
|
||||||
|
ok(S_OK == SafeArrayUnaccessData(a),"SAUD failed");
|
||||||
|
V_VT(&v) = VT_ARRAY|VT_UI1;
|
||||||
|
V_ARRAY(&v) = a;
|
||||||
|
hres = VariantChangeTypeEx(&v, &v, 0, 0, VT_BSTR);
|
||||||
|
ok(hres==S_OK, "CTE VT_ARRAY|VT_UI1 -> VT_BSTR failed with %lx",hres);
|
||||||
|
ok(V_VT(&v) == VT_BSTR,"CTE VT_ARRAY|VT_UI1 -> VT_BSTR did not return VT_BSTR, but %d.",V_VT(&v));
|
||||||
|
ok(V_BSTR(&v)[0] == 0x6548,"First letter are not 'He', but %x", V_BSTR(&v)[0]);
|
||||||
|
|
||||||
|
/* check locking functions */
|
||||||
|
a = SafeArrayCreate(VT_I4, 1, &bound);
|
||||||
|
ok(a!=NULL,"SAC should not fail");
|
||||||
|
|
||||||
|
hres = SafeArrayAccessData(a, &data);
|
||||||
|
ok(hres == S_OK,"SAAD failed with hres %lx",hres);
|
||||||
|
|
||||||
|
hres = SafeArrayDestroy(a);
|
||||||
|
ok(hres == DISP_E_ARRAYISLOCKED,"locked safe array destroy not failed with DISP_E_ARRAYISLOCKED, but with hres %lx", hres);
|
||||||
|
|
||||||
|
hres = SafeArrayDestroyData(a);
|
||||||
|
ok(hres == DISP_E_ARRAYISLOCKED,"locked safe array destroy data not failed with DISP_E_ARRAYISLOCKED, but with hres %lx", hres);
|
||||||
|
|
||||||
|
hres = SafeArrayDestroyDescriptor(a);
|
||||||
|
ok(hres == DISP_E_ARRAYISLOCKED,"locked safe array destroy descriptor not failed with DISP_E_ARRAYISLOCKED, but with hres %lx", hres);
|
||||||
|
|
||||||
|
hres = SafeArrayUnaccessData(a);
|
||||||
|
ok(hres == S_OK,"SAUD failed after lock/destroy test");
|
||||||
|
|
||||||
|
hres = SafeArrayDestroy(a);
|
||||||
|
ok(hres == S_OK,"SAD failed after lock/destroy test");
|
||||||
|
|
||||||
|
/* Test if we need to destroy data before descriptor */
|
||||||
|
a = SafeArrayCreate(VT_I4, 1, &bound);
|
||||||
|
ok(a!=NULL,"SAC should not fail");
|
||||||
|
hres = SafeArrayDestroyDescriptor(a);
|
||||||
|
ok(hres == S_OK,"SADD with data in array failed with hres %lx",hres);
|
||||||
|
|
||||||
|
|
||||||
|
/* IID functions */
|
||||||
|
/* init a small stack safearray */
|
||||||
|
memset(&b, 0, sizeof(b));
|
||||||
|
b.cDims = 1;
|
||||||
|
memset(&iid, 0x42, sizeof(IID));
|
||||||
|
hres = SafeArraySetIID(&b,&iid);
|
||||||
|
ok(hres == E_INVALIDARG,"SafeArraySetIID of non IID capable safearray did not return E_INVALIDARG, but %lx",hres);
|
||||||
|
|
||||||
|
hres = SafeArrayAllocDescriptor(1,&a);
|
||||||
|
ok((a->fFeatures & FADF_HAVEIID) == 0,"newly allocated descriptor with SAAD should not have FADF_HAVEIID");
|
||||||
|
hres = SafeArraySetIID(a,&iid);
|
||||||
|
ok(hres == E_INVALIDARG,"SafeArraySetIID of newly allocated descriptor with SAAD should return E_INVALIDARG, but %lx",hres);
|
||||||
|
|
||||||
|
for (i=0;i<sizeof(vttypes)/sizeof(vttypes[0]);i++) {
|
||||||
|
hres = SafeArrayAllocDescriptorEx(vttypes[i].vt,1,&a);
|
||||||
|
ok(a->fFeatures == vttypes[i].expflags,"SAADE(%d) resulted with flags %x, expected %x\n", vttypes[i].vt, a->fFeatures, vttypes[i].expflags);
|
||||||
|
if (a->fFeatures & FADF_HAVEIID) {
|
||||||
|
hres = SafeArrayGetIID(a, &iid);
|
||||||
|
ok(hres == S_OK,"SAGIID failed for vt %d with hres %lx", vttypes[i].vt,hres);
|
||||||
|
switch (vttypes[i].vt) {
|
||||||
|
case VT_UNKNOWN:
|
||||||
|
ok(IsEqualGUID(((GUID*)a)-1,&IID_IUnknown),"guid for VT_UNKNOWN is not IID_IUnknown");
|
||||||
|
ok(IsEqualGUID(&iid, &IID_IUnknown),"SAGIID returned wrong GUID for IUnknown");
|
||||||
|
break;
|
||||||
|
case VT_DISPATCH:
|
||||||
|
ok(IsEqualGUID(((GUID*)a)-1,&IID_IDispatch),"guid for VT_UNKNOWN is not IID_IDispatch");
|
||||||
|
ok(IsEqualGUID(&iid, &IID_IDispatch),"SAGIID returned wrong GUID for IDispatch");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ok(FALSE,"unknown vt %d with FADF_HAVEIID",vttypes[i].vt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hres = SafeArrayGetIID(a, &iid);
|
||||||
|
ok(hres == E_INVALIDARG,"SAGIID did not fail for vt %d with hres %lx", vttypes[i].vt,hres);
|
||||||
|
}
|
||||||
|
if (a->fFeatures & FADF_RECORD) {
|
||||||
|
ok(vttypes[i].vt == VT_RECORD,"FADF_RECORD for non record %d",vttypes[i].vt);
|
||||||
|
}
|
||||||
|
if (a->fFeatures & FADF_HAVEVARTYPE) {
|
||||||
|
ok(vttypes[i].vt == ((DWORD*)a)[-1], "FADF_HAVEVARTYPE set, but vt %d mismatch stored %ld",vttypes[i].vt,((DWORD*)a)[-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
hres = SafeArrayGetVartype(a, &vt);
|
||||||
|
ok(hres == S_OK, "SAGVT of array with vt %d failed with %lx", vttypes[i].vt, hres);
|
||||||
|
|
||||||
|
if (vttypes[i].vt == VT_DISPATCH) {
|
||||||
|
/* Special case. Checked against Windows. */
|
||||||
|
ok(vt == VT_UNKNOWN, "SAGVT of array with VT_DISPATCH returned not VT_UNKNOWN, but %d", vt);
|
||||||
|
} else {
|
||||||
|
ok(vt == vttypes[i].vt, "SAGVT of array with vt %d returned %d", vttypes[i].vt, vt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a->fFeatures & FADF_HAVEIID) {
|
||||||
|
hres = SafeArraySetIID(a, &IID_IStorage); /* random IID */
|
||||||
|
ok(hres == S_OK,"SASIID failed with FADF_HAVEIID set for vt %d with %lx", vttypes[i].vt, hres);
|
||||||
|
hres = SafeArrayGetIID(a, &iid);
|
||||||
|
ok(hres == S_OK,"SAGIID failed with FADF_HAVEIID set for vt %d with %lx", vttypes[i].vt, hres);
|
||||||
|
ok(IsEqualGUID(&iid, &IID_IStorage),"returned iid is not IID_IStorage");
|
||||||
|
} else {
|
||||||
|
hres = SafeArraySetIID(a, &IID_IStorage); /* random IID */
|
||||||
|
ok(hres == E_INVALIDARG,"SASIID did not failed with !FADF_HAVEIID set for vt %d with %lx", vttypes[i].vt, hres);
|
||||||
|
}
|
||||||
|
hres = SafeArrayDestroyDescriptor(a);
|
||||||
|
ok(hres == S_OK,"SADD failed with hres %lx",hres);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,9 @@ HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **pperrinfo);
|
||||||
HRESULT WINAPI
|
HRESULT WINAPI
|
||||||
SafeArrayAllocDescriptor(UINT cDims, struct tagSAFEARRAY **ppsaOut);
|
SafeArrayAllocDescriptor(UINT cDims, struct tagSAFEARRAY **ppsaOut);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
SafeArrayAllocDescriptorEx(VARTYPE vt,UINT cDims,struct tagSAFEARRAY **ppsaOut);
|
||||||
|
|
||||||
HRESULT WINAPI
|
HRESULT WINAPI
|
||||||
SafeArrayAllocData(struct tagSAFEARRAY *psa);
|
SafeArrayAllocData(struct tagSAFEARRAY *psa);
|
||||||
|
|
||||||
|
@ -104,7 +107,7 @@ HRESULT WINAPI
|
||||||
SafeArrayPtrOfIndex(struct tagSAFEARRAY *psa, LONG *rgIndices, void **ppvData);
|
SafeArrayPtrOfIndex(struct tagSAFEARRAY *psa, LONG *rgIndices, void **ppvData);
|
||||||
|
|
||||||
HRESULT WINAPI
|
HRESULT WINAPI
|
||||||
SafeArrayCopyData(struct tagSAFEARRAY *psaSource, struct tagSAFEARRAY **psaTarget);
|
SafeArrayCopyData(struct tagSAFEARRAY *psaSource, struct tagSAFEARRAY *psaTarget);
|
||||||
|
|
||||||
HRESULT WINAPI
|
HRESULT WINAPI
|
||||||
SafeArrayDestroyData(struct tagSAFEARRAY *psa);
|
SafeArrayDestroyData(struct tagSAFEARRAY *psa);
|
||||||
|
@ -121,6 +124,21 @@ SafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElements);
|
||||||
HRESULT WINAPI
|
HRESULT WINAPI
|
||||||
SafeArrayRedim(struct tagSAFEARRAY *psa, struct tagSAFEARRAYBOUND *psaboundNew);
|
SafeArrayRedim(struct tagSAFEARRAY *psa, struct tagSAFEARRAYBOUND *psaboundNew);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
SafeArraySetIID(struct tagSAFEARRAY *psa, REFGUID riid);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
SafeArrayGetIID(struct tagSAFEARRAY *psa, GUID *riid);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
SafeArrayGetVartype(struct tagSAFEARRAY *psa, VARTYPE *vt);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
SafeArrayGetRecordInfo(struct tagSAFEARRAY *psa, IRecordInfo **recordinfo);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
SafeArraySetRecordInfo(struct tagSAFEARRAY *psa, IRecordInfo *recordinfo);
|
||||||
|
|
||||||
|
|
||||||
/* These are macros that help accessing the VARIANT date type.
|
/* These are macros that help accessing the VARIANT date type.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -33,6 +33,9 @@ typedef struct IDispatch IDispatch,*LPDISPATCH;
|
||||||
DEFINE_OLEGUID(IID_ITypeInfo, 0x00020401,0,0);
|
DEFINE_OLEGUID(IID_ITypeInfo, 0x00020401,0,0);
|
||||||
typedef struct ITypeInfo ITypeInfo,*LPTYPEINFO;
|
typedef struct ITypeInfo ITypeInfo,*LPTYPEINFO;
|
||||||
|
|
||||||
|
DEFINE_OLEGUID(IID_IRecordInfo, 0x0000002f,0,0);
|
||||||
|
typedef struct IRecordInfo IRecordInfo,*LPRECORDINFO;
|
||||||
|
|
||||||
DEFINE_OLEGUID(IID_ITypeLib, 0x00020402,0,0);
|
DEFINE_OLEGUID(IID_ITypeLib, 0x00020402,0,0);
|
||||||
typedef struct ITypeLib ITypeLib,*LPTYPELIB;
|
typedef struct ITypeLib ITypeLib,*LPTYPELIB;
|
||||||
|
|
||||||
|
@ -802,4 +805,52 @@ ICOM_DEFINE(IEnumVARIANT,IUnknown)
|
||||||
#define IEnumVARIANT_Reset(p) ICOM_CALL (Reset,p)
|
#define IEnumVARIANT_Reset(p) ICOM_CALL (Reset,p)
|
||||||
#define IEnumVARIANT_Clone(p,a) ICOM_CALL1(Clone,p,a)
|
#define IEnumVARIANT_Clone(p,a) ICOM_CALL1(Clone,p,a)
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* IRecordInfo interface
|
||||||
|
*/
|
||||||
|
#define ICOM_INTERFACE IRecordInfo
|
||||||
|
#define IRecordInfo_METHODS \
|
||||||
|
ICOM_METHOD1(HRESULT, RecordInit, PVOID, pvNew) \
|
||||||
|
ICOM_METHOD1(HRESULT, RecordClear, PVOID, pvExisting) \
|
||||||
|
ICOM_METHOD2(HRESULT, RecordCopy, PVOID, pvExisting, PVOID, pvNew) \
|
||||||
|
ICOM_METHOD1(HRESULT, GetGUID, GUID*, pguid) \
|
||||||
|
ICOM_METHOD1(HRESULT, GetName, BSTR*, pbstrName) \
|
||||||
|
ICOM_METHOD1(HRESULT, GetSize, ULONG*, pcbSize) \
|
||||||
|
ICOM_METHOD1(HRESULT, GetTypeInfo, ITypeInfo**, ppTypeInfo) \
|
||||||
|
ICOM_METHOD3(HRESULT, GetField, PVOID, pvData, LPCOLESTR, szFieldName, VARIANT*, pvarField) \
|
||||||
|
ICOM_METHOD4(HRESULT, GetFieldNoCopy, PVOID, pvData, LPCOLESTR, szFieldName, VARIANT*, pvarField, PVOID *,ppvDataCArray) \
|
||||||
|
ICOM_METHOD4(HRESULT, PutField, ULONG, wFlags, PVOID, pvData, LPCOLESTR, szFieldName, VARIANT*, pvarField) \
|
||||||
|
ICOM_METHOD4(HRESULT, PutFieldNoCopy, ULONG, wFlags, PVOID, pvData, LPCOLESTR, szFieldName, VARIANT*, pvarField) \
|
||||||
|
ICOM_METHOD2(HRESULT, GetFieldNames, ULONG*, pcNames, BSTR*, rgBstrNames) \
|
||||||
|
ICOM_METHOD1(BOOL, IsMatchingType, IRecordInfo*, pRecordInfo) \
|
||||||
|
ICOM_METHOD (LPVOID, RecordCreate) \
|
||||||
|
ICOM_METHOD2(HRESULT, RecordCreateCopy, PVOID, pvSource, PVOID*, ppvDest) \
|
||||||
|
ICOM_METHOD1(HRESULT, RecordDestroy, PVOID, pvRecord)
|
||||||
|
|
||||||
|
#define IRecordInfo_IMETHODS \
|
||||||
|
IUnknown_IMETHODS \
|
||||||
|
IRecordInfo_METHODS
|
||||||
|
ICOM_DEFINE(IRecordInfo,IUnknown)
|
||||||
|
#undef ICOM_INTERFACE
|
||||||
|
|
||||||
|
/*** IUnknown methods ***/
|
||||||
|
#define IRecordInfo_QueryInterface(p,a,b) ICOM_CALL2(QueryInterface,p,a,b)
|
||||||
|
#define IRecordInfo_AddRef(p) ICOM_CALL (AddRef,p)
|
||||||
|
#define IRecordInfo_Release(p) ICOM_CALL (Release,p)
|
||||||
|
/*** IRecordInfo methods ***/
|
||||||
|
#define IRecordInfo_RecordInit(p,a) ICOM_CALL1(RecordInit,p,a)
|
||||||
|
#define IRecordInfo_RecordClear(p,a) ICOM_CALL1(RecordClear,p,a)
|
||||||
|
#define IRecordInfo_RecordCopy(p,a,b) ICOM_CALL2(RecordCopy,p,a,b)
|
||||||
|
#define IRecordInfo_GetGUID(p,a) ICOM_CALL1(GetGUID,p,a)
|
||||||
|
#define IRecordInfo_GetName(p,a) ICOM_CALL1(GetName,p,a)
|
||||||
|
#define IRecordInfo_GetTypeInfo(p,a) ICOM_CALL1(GetTypeInfo,p,a)
|
||||||
|
#define IRecordInfo_GetField(p,a,b,c) ICOM_CALL3(GetField,p,a,b,c)
|
||||||
|
#define IRecordInfo_GetFieldNoCopy(p,a,b,c,d) ICOM_CALL4(GetFieldNoCopy,p,a,b,c,d)
|
||||||
|
#define IRecordInfo_PutField(p,a,b,c,d) ICOM_CALL4(PutField,p,a,b,c,d)
|
||||||
|
#define IRecordInfo_PutFieldNoCopy(p,a,b,c,d) ICOM_CALL4(PutField,p,a,b,c,d)
|
||||||
|
#define IRecordInfo_GetFieldNames(p,a,b) ICOM_CALL2(GetFieldNames,p,a,b)
|
||||||
|
#define IRecordInfo_RecordCreate(p) ICOM_CALL (RecordCreate,p)
|
||||||
|
#define IRecordInfo_RecordCreateCopy(p,a,b) ICOM_CALL2(RecordCreateCopy,p,a,b)
|
||||||
|
#define IRecordInfo_RecordDestroy(p,a) ICOM_CALL1(RecordDestroy,p,a)
|
||||||
|
|
||||||
#endif /* __WINE_WINE_OBJ_OLEAUT_H */
|
#endif /* __WINE_WINE_OBJ_OLEAUT_H */
|
||||||
|
|
Loading…
Reference in New Issue