⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prop.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:

/*************************************************************************
 * 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 + -