From fb949605ba604cf2bffa993f735f7f549e5ea343 Mon Sep 17 00:00:00 2001 From: Stephane Lussier Date: Sun, 18 Jun 2000 19:29:40 +0000 Subject: [PATCH] - Fixed a memory corruption in safe arrays when using SafeArrayCopy() function with a SafeArray created with FADF_FIXEDSIZE. - Added more FADF flags in the .h file. - FADF flags were defined twice, corrected the situation. --- dlls/oleaut32/safearray.c | 61 +++++++++++++++++++++++++-------------- include/wine/obj_oleaut.h | 38 ++++++++++-------------- 2 files changed, 56 insertions(+), 43 deletions(-) diff --git a/dlls/oleaut32/safearray.c b/dlls/oleaut32/safearray.c index 57ed899474f..0f2b62dc0d0 100644 --- a/dlls/oleaut32/safearray.c +++ b/dlls/oleaut32/safearray.c @@ -542,7 +542,7 @@ HRESULT WINAPI SafeArrayDestroyData( /* check if this array is a Vector, in which case do not free the data block since it has been allocated by AllocDescriptor and therefore deserve to be freed by DestroyDescriptor */ - if(!(psa->fFeatures & FADF_FIXEDSIZE)) { /* Set when we do CreateVector */ + if(!(psa->fFeatures & FADF_CREATEVECTOR)) { /* Set when we do CreateVector */ /* free the whole chunk */ if((hRes = HeapFree( GetProcessHeap(), 0, psa->pvData)) == 0) /*falied*/ @@ -639,6 +639,7 @@ HRESULT WINAPI SafeArrayCopy( { HRESULT hRes; DWORD dAllocSize; + ULONG ulWholeArraySize; /* size of the thing */ if(! validArg(psa)) return E_INVALIDARG; @@ -650,12 +651,17 @@ HRESULT WINAPI SafeArrayCopy( sizeof(*psa)+(sizeof(*(psa->rgsabound))*(psa->cDims-1))); (*ppsaOut)->pvData = NULL; /* do not point to the same data area */ - + + /* make sure the new safe array doesn't have the FADF_CREATEVECTOR flag, + because the data has not been allocated with the descriptor. */ + (*ppsaOut)->fFeatures &= ~FADF_CREATEVECTOR; + /* Get the allocated memory size for source and allocate it for target */ - dAllocSize = HeapSize(GetProcessHeap(), 0, psa->pvData); + ulWholeArraySize = getArraySize(psa); /* Number of item in SA */ + dAllocSize = ulWholeArraySize*psa->cbElements; + (*ppsaOut)->pvData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dAllocSize); - if( (*ppsaOut)->pvData != NULL) { /* HeapAlloc succeed */ if( (hRes=duplicateData(psa, ppsaOut)) != S_OK) { /* E_OUTOFMEMORY */ @@ -699,18 +705,18 @@ SAFEARRAY* WINAPI SafeArrayCreateVector( (sizeof(*psa) + (VARTYPE_SIZE[vt] * cElements))))) { return NULL; } - + /* setup data members... */ psa->cDims = 1; /* always and forever */ - psa->fFeatures = getFeatures(vt) | FADF_FIXEDSIZE; + psa->fFeatures = getFeatures(vt) | FADF_CREATEVECTOR; /* undocumented flag used by Microsoft */ psa->cLocks = 0; - psa->pvData = psa+sizeof(*psa); + psa->pvData = (BYTE*)psa + sizeof(*psa); psa->cbElements = VARTYPE_SIZE[vt]; psa->rgsabound[0].cElements = cElements; psa->rgsabound[0].lLbound = lLbound; - - return(psa); + + return(psa); } /************************************************************************ @@ -825,19 +831,32 @@ static BOOL resizeSafeArray( } } - /* Ok now, if we are enlarging the array, we *MUST* move the whole block - pointed to by pvData. If we are shorthening the array, this move is - optional but we do it anyway becuase the benefit is that we are - releasing to the system the unused memory */ - - if((pvNewBlock = HeapReAlloc(GetProcessHeap(), 0, psa->pvData, - (ulWholeArraySize + lDelta) * psa->cbElements)) == NULL) - return FALSE; /* TODO If we get here it means: - SHRINK situation : we've deleted the undesired - data and did not release the memory - GROWING situation: we've been unable to grow the array - */ + if (!(psa->fFeatures & FADF_CREATEVECTOR)) + { + /* Ok now, if we are enlarging the array, we *MUST* move the whole block + pointed to by pvData. If we are shorthening the array, this move is + optional but we do it anyway becuase the benefit is that we are + releasing to the system the unused memory */ + if((pvNewBlock = HeapReAlloc(GetProcessHeap(), 0, psa->pvData, + (ulWholeArraySize + lDelta) * psa->cbElements)) == NULL) + return FALSE; /* TODO If we get here it means: + SHRINK situation : we've deleted the undesired + data and did not release the memory + GROWING situation: we've been unable to grow the array + */ + } + else + { + /* Allocate a new block, because the previous data has been allocated with + the descriptor in SafeArrayCreateVector function. */ + + if((pvNewBlock = HeapAlloc(GetProcessHeap(), 0, + ulWholeArraySize * psa->cbElements)) == NULL) + return FALSE; + + psa->fFeatures &= ~FADF_CREATEVECTOR; + } /* reassign to the new block of data */ psa->pvData = pvNewBlock; return TRUE; diff --git a/include/wine/obj_oleaut.h b/include/wine/obj_oleaut.h index 5eeefb154d5..1ccb8906325 100644 --- a/include/wine/obj_oleaut.h +++ b/include/wine/obj_oleaut.h @@ -66,15 +66,22 @@ typedef struct ISupportErrorInfo ISupportErrorInfo,*LPSUPPORTERRORINFO; * 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 ) +#define FADF_AUTO ( 0x1 ) +#define FADF_STATIC ( 0x2 ) +#define FADF_EMBEDDED ( 0x4 ) +#define FADF_FIXEDSIZE ( 0x10 ) +#define FADF_RECORD ( 0x20 ) +#define FADF_HAVEIID ( 0x40 ) +#define FADF_HAVEVARTYPE ( 0x80 ) +#define FADF_BSTR ( 0x100 ) +#define FADF_UNKNOWN ( 0x200 ) +#define FADF_DISPATCH ( 0x400 ) +#define FADF_VARIANT ( 0x800 ) +#define FADF_RESERVED ( 0xf008 ) + +/* Undocumented flags */ +#define FADF_CREATEVECTOR ( 0x2000 ) /* set when the safe array is created using SafeArrayCreateVector */ + typedef struct tagSAFEARRAYBOUND { @@ -423,19 +430,6 @@ typedef enum tagVARFLAGS VARFLAG_FIMMEDIATEBIND = 0x1000 } VARFLAGS; -/***************************************************************** - * 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 ) /* * Data types for Variants.