📄 prop.c
字号:
* See IUnknown_Release.
*/
static inline ULONG WINAPI IMAPIProp_fnRelease(LPMAPIPROP iface)
{
IPropDataImpl *This = (IPropDataImpl*)iface;
LONG lRef;
TRACE("(%p)->(count before=%u)\n", This, This->lRef);
lRef = InterlockedDecrement(&This->lRef);
if (!lRef)
{
TRACE("Destroying IPropData (%p)\n",This);
/* Note: No need to lock, since no other thread is referencing iface */
while (!list_empty(&This->values))
{
struct list *head = list_head(&This->values);
LPIPropDataItem current = LIST_ENTRY(head, IPropDataItem, entry);
list_remove(head);
This->lpFree(current->value);
This->lpFree(current);
}
DeleteCriticalSection(&This->cs);
This->lpFree(This);
}
return (ULONG)lRef;
}
/**************************************************************************
* IMAPIProp_GetLastError {MAPI32}
*
* Get information about the last error that occurred in an IMAPIProp object.
*
* PARAMS
* iface [I] IMAPIProp object that experienced the error
* hRes [I] Result of the call that returned an error
* ulFlags [I] 0=return Ascii strings, MAPI_UNICODE=return Unicode strings
* lppError [O] Destination for detailed error information
*
* RETURNS
* Success: S_OK. *lppError contains details about the last error.
* Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid,
* MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails.
*
* NOTES
* - If this function succeeds, the returned information in *lppError must be
* freed using MAPIFreeBuffer() once the caller is finished with it.
* - It is possible for this function to suceed and set *lppError to NULL,
* if there is no further information to report about hRes.
*/
static inline HRESULT WINAPI
IMAPIProp_fnGetLastError(LPMAPIPROP iface, HRESULT hRes,
ULONG ulFlags, LPMAPIERROR *lppError)
{
TRACE("(%p,0x%08X,0x%08X,%p)\n", iface, hRes, ulFlags, lppError);
if (!lppError || SUCCEEDED(hRes) || (ulFlags & ~MAPI_UNICODE))
return MAPI_E_INVALID_PARAMETER;
*lppError = NULL;
return S_OK;
}
/**************************************************************************
* IMAPIProp_SaveChanges {MAPI32}
*
* Update any changes made to a tansactional IMAPIProp object.
*
* PARAMS
* iface [I] IMAPIProp object to update
* ulFlags [I] Flags controlling the update.
*
* RETURNS
* Success: S_OK. Any outstanding changes are committed to the object.
* Failure: An HRESULT error code describing the error.
*/
static inline HRESULT WINAPI
IMAPIProp_fnSaveChanges(LPMAPIPROP iface, ULONG ulFlags)
{
TRACE("(%p,0x%08X)\n", iface, ulFlags);
/* Since this object is not transacted we do not need to implement this */
/* FIXME: Should we set the access levels to clean? */
return S_OK;
}
/**************************************************************************
* IMAPIProp_GetProps {MAPI32}
*
* Get property values from an IMAPIProp object.
*
* PARAMS
* iface [I] IMAPIProp object to get the property values from
* lpTags [I] Property tage of property values to be retrieved
* ulFlags [I] Return 0=Ascii MAPI_UNICODE=Unicode strings for
* unspecified types
* lpCount [O] Destination for number of properties returned
* lppProps [O] Destination for returned property values
*
* RETURNS
* Success: S_OK. *lppProps and *lpCount are updated.
* Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
* MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails, or
* MAPI_W_ERRORS_RETURNED if not all properties were retrieved
* successfully.
* NOTES
* - If MAPI_W_ERRORS_RETURNED is returned, any properties that could not be
* retrieved from iface are present in lppProps with their type
* changed to PT_ERROR and Id unchanged.
*/
static inline HRESULT WINAPI
IMAPIProp_fnGetProps(LPMAPIPROP iface, LPSPropTagArray lpTags,
ULONG ulFlags, ULONG *lpCount, LPSPropValue *lppProps)
{
ULONG i;
HRESULT hRet = S_OK;
IPropDataImpl *This = (IPropDataImpl*)iface;
TRACE("(%p,%p,0x%08x,%p,%p) stub\n", iface, lpTags, ulFlags,
lpCount, lppProps);
if (!iface || ulFlags & ~MAPI_UNICODE || !lpTags || *lpCount || !lppProps)
return MAPI_E_INVALID_PARAMETER;
FIXME("semi-stub, flags not supported\n");
*lpCount = lpTags->cValues;
*lppProps = NULL;
if (*lpCount)
{
hRet = MAPIAllocateBuffer(*lpCount * sizeof(SPropValue), (LPVOID*)lppProps);
if (FAILED(hRet))
return hRet;
IMAPIPROP_Lock(This);
for (i = 0; i < lpTags->cValues; i++)
{
HRESULT hRetTmp = E_INVALIDARG;
LPIPropDataItem item;
item = IMAPIPROP_GetValue(This, lpTags->aulPropTag[i]);
if (item)
hRetTmp = PropCopyMore(&(*lppProps)[i], item->value,
This->lpMore, *lppProps);
if (FAILED(hRetTmp))
{
hRet = MAPI_W_ERRORS_RETURNED;
(*lppProps)[i].ulPropTag =
CHANGE_PROP_TYPE(lpTags->aulPropTag[i], PT_ERROR);
}
}
IMAPIPROP_Unlock(This);
}
return hRet;
}
/**************************************************************************
* MAPIProp_GetPropList {MAPI32}
*
* Get the list of property tags for all values in an IMAPIProp object.
*
* PARAMS
* iface [I] IMAPIProp object to get the property tag list from
* ulFlags [I] Return 0=Ascii MAPI_UNICODE=Unicode strings for
* unspecified types
* lppTags [O] Destination for the retrieved peoperty tag list
*
* RETURNS
* Success: S_OK. *lppTags contains the tags for all available properties.
* Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
* MAPI_E_BAD_CHARWIDTH, if Ascii or Unicode strings are requested
* and that type of string is not supported.
*/
static inline HRESULT WINAPI
IMAPIProp_fnGetPropList(LPMAPIPROP iface, ULONG ulFlags,
LPSPropTagArray *lppTags)
{
IPropDataImpl *This = (IPropDataImpl*)iface;
ULONG i;
HRESULT hRet;
TRACE("(%p,0x%08x,%p) stub\n", iface, ulFlags, lppTags);
if (!iface || ulFlags & ~MAPI_UNICODE || !lppTags)
return MAPI_E_INVALID_PARAMETER;
FIXME("semi-stub, flags not supported\n");
*lppTags = NULL;
IMAPIPROP_Lock(This);
hRet = MAPIAllocateBuffer(CbNewSPropTagArray(This->ulNumValues),
(LPVOID*)lppTags);
if (SUCCEEDED(hRet))
{
struct list *cursor;
i = 0;
LIST_FOR_EACH(cursor, &This->values)
{
LPIPropDataItem current = LIST_ENTRY(cursor, IPropDataItem, entry);
(*lppTags)->aulPropTag[i] = current->value->ulPropTag;
i++;
}
(*lppTags)->cValues = This->ulNumValues;
}
IMAPIPROP_Unlock(This);
return hRet;
}
/**************************************************************************
* IMAPIProp_OpenProperty {MAPI32}
*
* Not documented at this time.
*
* RETURNS
* An HRESULT success/failure code.
*/
static inline HRESULT WINAPI
IMAPIProp_fnOpenProperty(LPMAPIPROP iface, ULONG ulPropTag, LPCIID iid,
ULONG ulOpts, ULONG ulFlags, LPUNKNOWN *lpUnk)
{
FIXME("(%p,%u,%s,%u,0x%08x,%p) stub\n", iface, ulPropTag,
debugstr_guid(iid), ulOpts, ulFlags, lpUnk);
return MAPI_E_NO_SUPPORT;
}
/**************************************************************************
* IMAPIProp_SetProps {MAPI32}
*
* Add or edit the property values in an IMAPIProp object.
*
* PARAMS
* iface [I] IMAPIProp object to get the property tag list from
* ulValues [I] Number of properties in lpProps
* lpProps [I] Property values to set
* lppProbs [O] Optional destination for any problems that occurred
*
* RETURNS
* Success: S_OK. The properties in lpProps are added to iface if they don't
* exist, or changed to the values in lpProps if they do
* Failure: An HRESULT error code describing the error
*/
static inline HRESULT WINAPI
IMAPIProp_fnSetProps(LPMAPIPROP iface, ULONG ulValues,
LPSPropValue lpProps, LPSPropProblemArray *lppProbs)
{
IPropDataImpl *This = (IPropDataImpl*)iface;
HRESULT hRet = S_OK;
ULONG i;
TRACE("(%p,%u,%p,%p)\n", iface, ulValues, lpProps, lppProbs);
if (!iface || !lpProps)
return MAPI_E_INVALID_PARAMETER;
for (i = 0; i < ulValues; i++)
{
if (FBadProp(&lpProps[i]) ||
PROP_TYPE(lpProps[i].ulPropTag) == PT_OBJECT ||
PROP_TYPE(lpProps[i].ulPropTag) == PT_NULL)
return MAPI_E_INVALID_PARAMETER;
}
IMAPIPROP_Lock(This);
/* FIXME: Under what circumstances is lpProbs created? */
for (i = 0; i < ulValues; i++)
{
LPIPropDataItem item = IMAPIPROP_GetValue(This, lpProps[i].ulPropTag);
if (item)
{
HRESULT hRetTmp;
LPVOID lpMem = NULL;
/* Found, so update the existing value */
if (item->value->ulPropTag != lpProps[i].ulPropTag)
FIXME("semi-stub, overwriting type (not coercing)\n");
hRetTmp = This->lpAlloc(sizeof(SPropValue), &lpMem);
if (SUCCEEDED(hRetTmp))
{
hRetTmp = PropCopyMore(lpMem, &lpProps[i], This->lpMore, lpMem);
if (SUCCEEDED(hRetTmp))
{
This->lpFree(item->value);
item->value = lpMem;
continue;
}
This->lpFree(lpMem);
}
hRet = hRetTmp;
}
else
{
/* Add new value */
if (!(item = IMAPIPROP_AddValue(This, &lpProps[i])))
hRet = MAPI_E_NOT_ENOUGH_MEMORY;
}
}
IMAPIPROP_Unlock(This);
return hRet;
}
/**************************************************************************
* IMAPIProp_DeleteProps {MAPI32}
*
* Delete one or more property values from an IMAPIProp object.
*
* PARAMS
* iface [I] IMAPIProp object to remove property values from.
* lpTags [I] Collection of property Id's to remove from iface.
* lppProbs [O] Destination for problems encountered, if any.
*
* RETURNS
* Success: S_OK. Any properties in iface matching property Id's in lpTags have
* been deleted. If lppProbs is non-NULL it contains details of any
* errors that occurred.
* Failure: MAPI_E_INVALID_PARAMETER, if any parameter is invalid.
* E_ACCESSDENIED, if this object was created using CreateIProp() and
* a subsequent call to IPropData_SetObjAcess() was made specifying
* IPROP_READONLY as the access type.
*
* NOTES
* - lppProbs will not be populated for cases where a property Id is present
* in lpTags but not in iface.
* - lppProbs should be deleted with MAPIFreeBuffer() if returned.
*/
static inline HRESULT WINAPI
IMAPIProp_fnDeleteProps(LPMAPIPROP iface, LPSPropTagArray lpTags,
LPSPropProblemArray *lppProbs)
{
IPropDataImpl *This = (IPropDataImpl*)iface;
ULONG i, numProbs = 0;
HRESULT hRet = S_OK;
TRACE("(%p,%p,%p)\n", iface, lpTags, lppProbs);
if (!iface || !lpTags)
return MAPI_E_INVALID_PARAMETER;
if (lppProbs)
*lppProbs = NULL;
for (i = 0; i < lpTags->cValues; i++)
{
if (FBadPropTag(lpTags->aulPropTag[i]) ||
PROP_TYPE(lpTags->aulPropTag[i]) == PT_OBJECT ||
PROP_TYPE(lpTags->aulPropTag[i]) == PT_NULL)
return MAPI_E_INVALID_PARAMETER;
}
IMAPIPROP_Lock(This);
if (This->ulObjAccess != IPROP_READWRITE)
{
IMAPIPROP_Unlock(This);
return E_ACCESSDENIED;
}
for (i = 0; i < lpTags->cValues; i++)
{
LPIPropDataItem item = IMAPIPROP_GetValue(This, lpTags->aulPropTag[i]);
if (item)
{
if (item->ulAccess & IPROP_READWRITE)
{
/* Everything hunky-dory, remove the item */
list_remove(&item->entry);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -