Commit fb949605 authored by Stephane Lussier's avatar Stephane Lussier Committed by Alexandre Julliard

- 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.
parent 4d4e1217
......@@ -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;
......
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment