📄 prop.c
字号:
/*************************************************************************
* FBadRglpszW@8 (MAPI32.176)
*
* See FBadRglpszA.
*/
BOOL WINAPI FBadRglpszW(LPWSTR *lppszStrs, ULONG ulCount)
{
ULONG i;
TRACE("(%p,%d)\n", lppszStrs, ulCount);
if (!ulCount)
return FALSE;
if (!lppszStrs || IsBadReadPtr(lppszStrs, ulCount * sizeof(LPWSTR)))
return TRUE;
for (i = 0; i < ulCount; i++)
{
if (!lppszStrs[i] || IsBadStringPtrW(lppszStrs[i], -1))
return TRUE;
}
return FALSE;
}
/*************************************************************************
* FBadRowSet@4 (MAPI32.177)
*
* Determine if a row is invalid
*
* PARAMS
* lpRow [I] Row to check
*
* RETURNS
* TRUE, if lpRow is invalid, FALSE otherwise.
*/
BOOL WINAPI FBadRowSet(LPSRowSet lpRowSet)
{
ULONG i;
TRACE("(%p)\n", lpRowSet);
if (!lpRowSet || IsBadReadPtr(lpRowSet, CbSRowSet(lpRowSet)))
return TRUE;
for (i = 0; i < lpRowSet->cRows; i++)
{
if (FBadRow(&lpRowSet->aRow[i]))
return TRUE;
}
return FALSE;
}
/*************************************************************************
* FBadPropTag@4 (MAPI32.179)
*
* Determine if a property tag is invalid
*
* PARAMS
* ulPropTag [I] Property tag to check
*
* RETURNS
* TRUE, if ulPropTag is invalid, FALSE otherwise.
*/
ULONG WINAPI FBadPropTag(ULONG ulPropTag)
{
TRACE("(0x%08x)\n", ulPropTag);
switch (ulPropTag & (~MV_FLAG & PROP_TYPE_MASK))
{
case PT_UNSPECIFIED:
case PT_NULL:
case PT_I2:
case PT_LONG:
case PT_R4:
case PT_DOUBLE:
case PT_CURRENCY:
case PT_APPTIME:
case PT_ERROR:
case PT_BOOLEAN:
case PT_OBJECT:
case PT_I8:
case PT_STRING8:
case PT_UNICODE:
case PT_SYSTIME:
case PT_CLSID:
case PT_BINARY:
return FALSE;
}
return TRUE;
}
/*************************************************************************
* FBadRow@4 (MAPI32.180)
*
* Determine if a row is invalid
*
* PARAMS
* lpRow [I] Row to check
*
* RETURNS
* TRUE, if lpRow is invalid, FALSE otherwise.
*/
ULONG WINAPI FBadRow(LPSRow lpRow)
{
ULONG i;
TRACE("(%p)\n", lpRow);
if (!lpRow || IsBadReadPtr(lpRow, sizeof(SRow)) || !lpRow->lpProps ||
IsBadReadPtr(lpRow->lpProps, lpRow->cValues * sizeof(SPropValue)))
return TRUE;
for (i = 0; i < lpRow->cValues; i++)
{
if (FBadProp(&lpRow->lpProps[i]))
return TRUE;
}
return FALSE;
}
/*************************************************************************
* FBadProp@4 (MAPI32.181)
*
* Determine if a property is invalid
*
* PARAMS
* lpProp [I] Property to check
*
* RETURNS
* TRUE, if lpProp is invalid, FALSE otherwise.
*/
ULONG WINAPI FBadProp(LPSPropValue lpProp)
{
if (!lpProp || IsBadReadPtr(lpProp, sizeof(SPropValue)) ||
FBadPropTag(lpProp->ulPropTag))
return TRUE;
switch (PROP_TYPE(lpProp->ulPropTag))
{
/* Single value properties containing pointers */
case PT_STRING8:
if (!lpProp->Value.lpszA || IsBadStringPtrA(lpProp->Value.lpszA, -1))
return TRUE;
break;
case PT_UNICODE:
if (!lpProp->Value.lpszW || IsBadStringPtrW(lpProp->Value.lpszW, -1))
return TRUE;
break;
case PT_BINARY:
if (IsBadReadPtr(lpProp->Value.bin.lpb, lpProp->Value.bin.cb))
return TRUE;
break;
case PT_CLSID:
if (IsBadReadPtr(lpProp->Value.lpguid, sizeof(GUID)))
return TRUE;
break;
/* Multiple value properties (arrays) containing no pointers */
case PT_MV_I2:
return PROP_BadArray(lpProp, sizeof(SHORT));
case PT_MV_LONG:
return PROP_BadArray(lpProp, sizeof(LONG));
case PT_MV_LONGLONG:
return PROP_BadArray(lpProp, sizeof(LONG64));
case PT_MV_FLOAT:
return PROP_BadArray(lpProp, sizeof(float));
case PT_MV_SYSTIME:
return PROP_BadArray(lpProp, sizeof(FILETIME));
case PT_MV_APPTIME:
case PT_MV_DOUBLE:
return PROP_BadArray(lpProp, sizeof(double));
case PT_MV_CURRENCY:
return PROP_BadArray(lpProp, sizeof(CY));
case PT_MV_CLSID:
return PROP_BadArray(lpProp, sizeof(GUID));
/* Multiple value properties containing pointers */
case PT_MV_STRING8:
return FBadRglpszA(lpProp->Value.MVszA.lppszA,
lpProp->Value.MVszA.cValues);
case PT_MV_UNICODE:
return FBadRglpszW(lpProp->Value.MVszW.lppszW,
lpProp->Value.MVszW.cValues);
case PT_MV_BINARY:
return FBadEntryList((LPENTRYLIST)&lpProp->Value.MVbin);
}
return FALSE;
}
/*************************************************************************
* FBadColumnSet@4 (MAPI32.182)
*
* Determine if an array of property tags is invalid
*
* PARAMS
* lpCols [I] Property tag array to check
*
* RETURNS
* TRUE, if lpCols is invalid, FALSE otherwise.
*/
ULONG WINAPI FBadColumnSet(LPSPropTagArray lpCols)
{
ULONG ulRet = FALSE, i;
TRACE("(%p)\n", lpCols);
if (!lpCols || IsBadReadPtr(lpCols, CbSPropTagArray(lpCols)))
ulRet = TRUE;
else
{
for (i = 0; i < lpCols->cValues; i++)
{
if ((lpCols->aulPropTag[i] & PROP_TYPE_MASK) == PT_ERROR ||
FBadPropTag(lpCols->aulPropTag[i]))
{
ulRet = TRUE;
break;
}
}
}
TRACE("Returning %s\n", ulRet ? "TRUE" : "FALSE");
return ulRet;
}
/**************************************************************************
* IMAPIProp {MAPI32}
*
* The default Mapi interface for manipulating object properties.
*
* DESCRIPTION
* This object provides an interface to an objects properties. It is exposed
* by several types of Mapi objects in order to simplify the querying and
* modification of properties.
*
* METHODS
*/
/* A single property in a property data collection */
typedef struct
{
struct list entry;
ULONG ulAccess; /* The property value access level */
LPSPropValue value; /* The property value */
} IPropDataItem, *LPIPropDataItem;
/* The main property data collection structure */
typedef struct
{
const IPropDataVtbl *lpVtbl;
LONG lRef; /* Reference count */
ALLOCATEBUFFER *lpAlloc; /* Memory allocation routine */
ALLOCATEMORE *lpMore; /* Linked memory allocation routine */
FREEBUFFER *lpFree; /* Memory free routine */
ULONG ulObjAccess; /* Object access level */
ULONG ulNumValues; /* Number of items in values list */
struct list values; /* List of property values */
CRITICAL_SECTION cs; /* Lock for thread safety */
} IPropDataImpl;
/* Internal - Get a property value, assumes lock is held */
static IPropDataItem *IMAPIPROP_GetValue(IPropDataImpl *This, ULONG ulPropTag)
{
struct list *cursor;
LIST_FOR_EACH(cursor, &This->values)
{
LPIPropDataItem current = LIST_ENTRY(cursor, IPropDataItem, entry);
/* Note that propery types don't have to match, just Id's */
if (PROP_ID(current->value->ulPropTag) == PROP_ID(ulPropTag))
return current;
}
return NULL;
}
/* Internal - Add a new property value, assumes lock is held */
static IPropDataItem *IMAPIPROP_AddValue(IPropDataImpl *This,
LPSPropValue lpProp)
{
LPVOID lpMem;
LPIPropDataItem lpNew;
HRESULT hRet;
hRet = This->lpAlloc(sizeof(IPropDataItem), &lpMem);
if (SUCCEEDED(hRet))
{
lpNew = lpMem;
lpNew->ulAccess = IPROP_READWRITE;
/* Allocate the value separately so we can update it easily */
lpMem = NULL;
hRet = This->lpAlloc(sizeof(SPropValue), &lpMem);
if (SUCCEEDED(hRet))
{
lpNew->value = lpMem;
hRet = PropCopyMore(lpNew->value, lpProp, This->lpMore, lpMem);
if (SUCCEEDED(hRet))
{
list_add_tail(&This->values, &lpNew->entry);
This->ulNumValues++;
return lpNew;
}
This->lpFree(lpNew->value);
}
This->lpFree(lpNew);
}
return NULL;
}
/* Internal - Lock an IPropData object */
static inline void IMAPIPROP_Lock(IPropDataImpl *This)
{
EnterCriticalSection(&This->cs);
}
/* Internal - Unlock an IPropData object */
static inline void IMAPIPROP_Unlock(IPropDataImpl *This)
{
LeaveCriticalSection(&This->cs);
}
/* This one seems to be missing from mapidefs.h */
#define CbNewSPropProblemArray(c) \
(offsetof(SPropProblemArray,aProblem)+(c)*sizeof(SPropProblem))
/**************************************************************************
* IMAPIProp_QueryInterface {MAPI32}
*
* Inherited method from the IUnknown Interface.
* See IUnknown_QueryInterface.
*
* NOTES
* This object exposes the following interfaces:
* - IUnknown() : The default interface for all COM-Objects.
* - IMAPIProp() : The default Mapi interface for manipulating object properties.
*/
static inline HRESULT WINAPI
IMAPIProp_fnQueryInterface(LPMAPIPROP iface, REFIID riid, LPVOID *ppvObj)
{
IPropDataImpl *This = (IPropDataImpl*)iface;
TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppvObj);
if (!ppvObj || !riid)
return MAPI_E_INVALID_PARAMETER;
*ppvObj = NULL;
if(IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IMAPIProp) ||
IsEqualIID(riid, &IID_IMAPIPropData))
{
*ppvObj = This;
IPropData_AddRef(iface);
TRACE("returning %p\n", *ppvObj);
return S_OK;
}
TRACE("returning E_NOINTERFACE\n");
return MAPI_E_INTERFACE_NOT_SUPPORTED;
}
/**************************************************************************
* IMAPIProp_AddRef {MAPI32}
*
* Inherited method from the IUnknown Interface.
* See IUnknown_AddRef.
*/
static inline ULONG WINAPI IMAPIProp_fnAddRef(LPMAPIPROP iface)
{
IPropDataImpl *This = (IPropDataImpl*)iface;
TRACE("(%p)->(count before=%u)\n", This, This->lRef);
return InterlockedIncrement(&This->lRef);
}
/**************************************************************************
* IMAPIProp_Release {MAPI32}
*
* Inherited method from the IUnknown Interface.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -