/***********************************************************************
*
* WRAP.C
*
* Sample Address Book Wrap object
* This file contains the code for implementing the Sample AB
* WRAP object.
*
* This file contains methods with "default" actions for objects which
* expose IUnknown and/or IMAPIProp. These "default" actions are to call
* the appropriate method of a "wrapped" object that is a member of this
* object. Various methods in this file are used throughout this sample
* provider and are especially useful with the objects that implement template
* ids (see TID.C and OOTID.C).
*
* Copyright 1992-1995 Microsoft Corporation. All Rights Reserved.
*
***********************************************************************/
#include "abp.h"
typedef struct _WRAP {
WRAP_Vtbl * lpVtbl;
SAB_Wrapped;
} WRAP, *LPWRAP;
/*********************************************************************
*
* The actual Wrapped IMAPIProp methods
*
*/
STDMETHODIMP
WRAP_QueryInterface(LPWRAP lpWRAP,
REFIID lpiid,
LPVOID * lppNewObj)
{
HRESULT hr;
/*
* Check to see if it has a lpVtbl object member
*/
if (IsBadReadPtr(lpWRAP, offsetof(WRAP, lpVtbl)+sizeof(WRAP_Vtbl *)))
{
/*
* No jump table found
*/
return ResultFromScode(E_INVALIDARG);
}
/*
* Check to see that the Vtbl is large enough to include this method
*/
if (IsBadReadPtr(lpWRAP->lpVtbl,
offsetof(WRAP_Vtbl, QueryInterface)+sizeof(WRAP_QueryInterface_METHOD *)))
{
/*
* Jump table not derived from IUnknown
*/
return ResultFromScode(E_INVALIDARG);
}
/*
* Check to see if the method is the same
*/
if (WRAP_QueryInterface != lpWRAP->lpVtbl->QueryInterface)
{
/*
* Wrong object - the object passed doesn't have this
* method.
*/
return ResultFromScode(E_INVALIDARG);
}
EnterCriticalSection(&lpWRAP->cs);
/* Call the internal prop interface */
hr = lpWRAP->lpPropData->lpVtbl->QueryInterface(
lpWRAP->lpPropData,
lpiid,
lppNewObj);
/* If this object is successful in QI'ing and it returns exactly the
* same object, then I need to AddRef my own "wrapper" object so that
* my release code works correctly AND replace the *lppNewObj with the
* "wrapper" object.
*/
if (!HR_FAILED(hr) && (lpWRAP->lpPropData == *lppNewObj))
{
++lpWRAP->lcInit;
*lppNewObj = lpWRAP;
}
LeaveCriticalSection(&lpWRAP->cs);
return hr;
}
STDMETHODIMP_(ULONG) WRAP_AddRef(LPWRAP lpWRAP)
{
ULONG ulRet;
/*
* Check to see if it has a lpVtbl object member
*/
if (IsBadReadPtr(lpWRAP, offsetof(WRAP, lpVtbl)+sizeof(WRAP_Vtbl *)))
{
/*
* No jump table found
*/
return 1;
}
/*
* Check to see that the Vtbl is large enough to include this method
*/
if (IsBadReadPtr(lpWRAP->lpVtbl,
offsetof(WRAP_Vtbl, AddRef)+sizeof(WRAP_AddRef_METHOD *)))
{
/*
* Jump table not derived from IUnknown
*/
return 1;
}
/*
* Check to see if the method is the same
*/
if (WRAP_AddRef != lpWRAP->lpVtbl->AddRef)
{
/*
* Wrong object - the object passed doesn't have this
* method.
*/
return 1;
}
EnterCriticalSection(&lpWRAP->cs);
++lpWRAP->lcInit;
/* Call the internal prop interface */
ulRet = lpWRAP->lpPropData->lpVtbl->AddRef(lpWRAP->lpPropData);
LeaveCriticalSection(&lpWRAP->cs);
return ulRet;
}
STDMETHODIMP_(ULONG) WRAP_Release(LPWRAP lpWRAP)
{
long lcInit;
/*
* Check to see if it has a lpVtbl object member
*/
if (IsBadReadPtr(lpWRAP, offsetof(WRAP, lpVtbl)+sizeof(WRAP_Vtbl *)))
{
/*
* No jump table found
*/
return 1;
}
/*
* Check to see that the Vtbl is large enough to include this method
*/
if (IsBadReadPtr(lpWRAP->lpVtbl,
offsetof(WRAP_Vtbl, Release)+sizeof(WRAP_Release_METHOD *)))
{
/*
* Jump table not derived from IUnknown
*/
return 1;
}
/*
* Check to see if the method is the same
*/
if (WRAP_Release != lpWRAP->lpVtbl->Release)
{
/*
* Wrong object - the object passed doesn't have this
* method.
*/
return 1;
}
EnterCriticalSection(&lpWRAP->cs);
/*
* Release the imapiprop object
*/
lpWRAP->lpPropData->lpVtbl->Release(
lpWRAP->lpPropData);
lcInit = --lpWRAP->lcInit;
LeaveCriticalSection(&lpWRAP->cs);
if (lcInit == 0)
{
/*
* Release our reference to the ABLogon object.
*/
if (lpWRAP->lpABLogon)
{
lpWRAP->lpABLogon->lpVtbl->Release(lpWRAP->lpABLogon);
lpWRAP->lpABLogon = NULL;
}
/*
* Get rid of my critical section
*/
DeleteCriticalSection(&lpWRAP->cs);
/*
* Set the Jump table to NULL. This way the client will find out
* real fast if it's calling a method on a released object. That is,
* the client will crash. Hopefully, this will happen during the
* development stage of the client.
*/
lpWRAP->lpVtbl = NULL;
/*
* Need to free the object
*/
lpWRAP->lpFreeBuff(lpWRAP);
return 0;
}
return lcInit;
}
STDMETHODIMP
WRAP_GetLastError( LPWRAP lpWRAP,
HRESULT hError,
ULONG ulFlags,
LPMAPIERROR FAR * lppMapiError )
{
HRESULT hResult;
/*
* Check to see if it has a lpVtbl object member
*/
if (IsBadReadPtr(lpWRAP, offsetof(WRAP, lpVtbl)+sizeof(WRAP_Vtbl *)))
{
/*
* No jump table found
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see that the Vtbl is large enough to include this method
*/
if (IsBadReadPtr(lpWRAP->lpVtbl,
offsetof(WRAP_Vtbl, GetLastError)+sizeof(WRAP_GetLastError_METHOD *)))
{
/*
* Jump table not derived from IUnknown
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see if the method is the same
*/
if (WRAP_GetLastError != lpWRAP->lpVtbl->GetLastError)
{
/*
* Wrong object - the object passed doesn't have this
* method.
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
if ( ulFlags & ~MAPI_UNICODE )
{
hResult = ResultFromScode( MAPI_E_UNKNOWN_FLAGS );
return hResult ;
}
if ( ulFlags & MAPI_UNICODE )
{
hResult = ResultFromScode( MAPI_E_BAD_CHARWIDTH );
return hResult;
}
return lpWRAP->lpPropData->lpVtbl->GetLastError(
lpWRAP->lpPropData,
hError,
ulFlags,
lppMapiError );
}
/* IProperty */
STDMETHODIMP
WRAP_SaveChanges( LPWRAP lpWRAP,
ULONG ulFlags)
{
HRESULT hResult;
/*
* Check to see if it has a lpVtbl object member
*/
if (IsBadReadPtr(lpWRAP, offsetof(WRAP, lpVtbl)+sizeof(WRAP_Vtbl *)))
{
/*
* No jump table found
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see that the Vtbl is large enough to include this method
*/
if (IsBadReadPtr(lpWRAP->lpVtbl,
offsetof(WRAP_Vtbl, SaveChanges)+sizeof(WRAP_SaveChanges_METHOD *)))
{
/*
* Jump table not derived from IUnknown
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see if the method is the same
*/
if (WRAP_SaveChanges != lpWRAP->lpVtbl->SaveChanges)
{
/*
* Wrong object - the object passed doesn't have this
* method.
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
hResult = lpWRAP->lpPropData->lpVtbl->SaveChanges(
lpWRAP->lpPropData,
ulFlags);
return hResult;
}
STDMETHODIMP
WRAP_GetProps( LPWRAP lpWRAP,
LPSPropTagArray lpPropTagArray,
ULONG ulFlags,
ULONG * lpcValues,
LPSPropValue * lppPropArray)
{
HRESULT hResult;
/*
* Check to see if it has a lpVtbl object member
*/
if (IsBadReadPtr(lpWRAP, offsetof(WRAP, lpVtbl)+sizeof(WRAP_Vtbl *)))
{
/*
* No jump table found
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see that the Vtbl is large enough to include this method
*/
if (IsBadReadPtr(lpWRAP->lpVtbl,
offsetof(WRAP_Vtbl, GetProps)+sizeof(WRAP_GetProps_METHOD *)))
{
/*
* Jump table not derived from IUnknown
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see if the method is the same
*/
if (WRAP_GetProps != lpWRAP->lpVtbl->GetProps)
{
/*
* Wrong object - the object passed doesn't have this
* method.
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
if ( ulFlags & ~(MAPI_UNICODE) )
{
hResult = ResultFromScode( MAPI_E_UNKNOWN_FLAGS );
return hResult;
}
if ( ulFlags & MAPI_UNICODE )
{
hResult = ResultFromScode( MAPI_E_BAD_CHARWIDTH );
return hResult;
}
return lpWRAP->lpPropData->lpVtbl->GetProps(
lpWRAP->lpPropData,
lpPropTagArray,
ulFlags,
lpcValues,
lppPropArray);
}
STDMETHODIMP
WRAP_GetPropList( LPWRAP lpWRAP,
ULONG ulFlags,
LPSPropTagArray * lppPropTagArray)
{
HRESULT hResult = hrSuccess;
/*
* Check to see if it has a lpVtbl object member
*/
if (IsBadReadPtr(lpWRAP, offsetof(WRAP, lpVtbl)+sizeof(WRAP_Vtbl *)))
{
/*
* No jump table found
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see that the Vtbl is large enough to include this method
*/
if (IsBadReadPtr(lpWRAP->lpVtbl,
offsetof(WRAP_Vtbl, GetPropList)+sizeof(WRAP_GetPropList_METHOD *)))
{
/*
* Jump table not derived from IUnknown
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see if the method is the same
*/
if (WRAP_GetPropList != lpWRAP->lpVtbl->GetPropList)
{
/*
* Wrong object - the object passed doesn't have this
* method.
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
if ( ulFlags & ~(MAPI_UNICODE) )
{
hResult = ResultFromScode( MAPI_E_UNKNOWN_FLAGS );
return hResult;
}
if ( ulFlags & MAPI_UNICODE )
{
hResult = ResultFromScode( MAPI_E_BAD_CHARWIDTH );
return hResult;
}
return lpWRAP->lpPropData->lpVtbl->GetPropList(
lpWRAP->lpPropData,
ulFlags,
lppPropTagArray);
}
STDMETHODIMP
WRAP_OpenProperty( LPWRAP lpWRAP,
ULONG ulPropTag,
LPCIID lpiid,
ULONG ulInterfaceOptions,
ULONG ulFlags,
LPUNKNOWN * lppUnk)
{
HRESULT hResult;
/*
* Check to see if it has a lpVtbl object member
*/
if (IsBadReadPtr(lpWRAP, offsetof(WRAP, lpVtbl)+sizeof(WRAP_Vtbl *)))
{
/*
* No jump table found
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see that the Vtbl is large enough to include this method
*/
if (IsBadReadPtr(lpWRAP->lpVtbl,
offsetof(WRAP_Vtbl, OpenProperty)+sizeof(WRAP_OpenProperty_METHOD *)))
{
/*
* Jump table not derived from IUnknown
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see if the method is the same
*/
if (WRAP_OpenProperty != lpWRAP->lpVtbl->OpenProperty)
{
/*
* Wrong object - the object passed doesn't have this
* method.
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
if ( ulInterfaceOptions & ~MAPI_UNICODE )
{
hResult = ResultFromScode( MAPI_E_UNKNOWN_FLAGS );
return hResult;
}
if ( ulInterfaceOptions & MAPI_UNICODE )
{
hResult = ResultFromScode( MAPI_E_BAD_CHARWIDTH );
return hResult;
}
hResult = lpWRAP->lpPropData->lpVtbl->OpenProperty(
lpWRAP->lpPropData,
ulPropTag,
lpiid,
ulInterfaceOptions,
ulFlags,
lppUnk);
return hResult;
}
STDMETHODIMP
WRAP_SetProps( LPWRAP lpWRAP,
ULONG cValues,
LPSPropValue lpPropArray,
LPSPropProblemArray * lppProblems)
{
HRESULT hResult;
/*
* Check to see if it has a lpVtbl object member
*/
if (IsBadReadPtr(lpWRAP, offsetof(WRAP, lpVtbl)+sizeof(WRAP_Vtbl *)))
{
/*
* No jump table found
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see that the Vtbl is large enough to include this method
*/
if (IsBadReadPtr(lpWRAP->lpVtbl,
offsetof(WRAP_Vtbl, SetProps)+sizeof(WRAP_SetProps_METHOD *)))
{
/*
* Jump table not derived from IUnknown
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see if the method is the same
*/
if (WRAP_SetProps != lpWRAP->lpVtbl->SetProps)
{
/*
* Wrong object - the object passed doesn't have this
* method.
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
return lpWRAP->lpPropData->lpVtbl->SetProps(
lpWRAP->lpPropData,
cValues,
lpPropArray,
lppProblems);
}
STDMETHODIMP
WRAP_DeleteProps( LPWRAP lpWRAP,
LPSPropTagArray lpPropTagArray,
LPSPropProblemArray * lppProblems)
{
HRESULT hResult;
/*
* Check to see if it has a lpVtbl object member
*/
if (IsBadReadPtr(lpWRAP, offsetof(WRAP, lpVtbl)+sizeof(WRAP_Vtbl *)))
{
/*
* No jump table found
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see that the Vtbl is large enough to include this method
*/
if (IsBadReadPtr(lpWRAP->lpVtbl,
offsetof(WRAP_Vtbl, DeleteProps)+sizeof(WRAP_DeleteProps_METHOD *)))
{
/*
* Jump table not derived from IUnknown
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see if the method is the same
*/
if (WRAP_DeleteProps != lpWRAP->lpVtbl->DeleteProps)
{
/*
* Wrong object - the object passed doesn't have this
* method.
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
return lpWRAP->lpPropData->lpVtbl->DeleteProps(
lpWRAP->lpPropData,
lpPropTagArray,
lppProblems);
}
STDMETHODIMP
WRAP_CopyTo(LPWRAP lpWRAP,
ULONG ciidExclude,
LPCIID rgiidExclude,
LPSPropTagArray lpExcludeProps,
ULONG ulUIParam,
LPMAPIPROGRESS lpProgress,
LPCIID lpInterface,
LPVOID lpDestObj,
ULONG ulFlags,
LPSPropProblemArray FAR * lppProblems)
{
HRESULT hResult;
/*
* Check to see if it has a lpVtbl object member
*/
if (IsBadReadPtr(lpWRAP, offsetof(WRAP, lpVtbl)+sizeof(WRAP_Vtbl *)))
{
/*
* No jump table found
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see that the Vtbl is large enough to include this method
*/
if (IsBadReadPtr(lpWRAP->lpVtbl,
offsetof(WRAP_Vtbl, CopyTo)+sizeof(WRAP_CopyTo_METHOD *)))
{
/*
* Jump table not derived from IUnknown
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see if the method is the same
*/
if (WRAP_CopyTo != lpWRAP->lpVtbl->CopyTo)
{
/*
* Wrong object - the object passed doesn't have this
* method.
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
return lpWRAP->lpPropData->lpVtbl->CopyTo(
lpWRAP->lpPropData,
ciidExclude,
rgiidExclude,
lpExcludeProps,
ulUIParam,
lpProgress,
lpInterface,
lpDestObj,
ulFlags,
lppProblems);
}
STDMETHODIMP
WRAP_CopyProps(LPWRAP lpWRAP,
LPSPropTagArray lpIncludeProps,
ULONG ulUIParam,
LPMAPIPROGRESS lpProgress,
LPCIID lpInterface,
LPVOID lpDestObj,
ULONG ulFlags,
LPSPropProblemArray FAR * lppProblems)
{
HRESULT hResult;
/*
* Check to see if it has a lpVtbl object member
*/
if (IsBadReadPtr(lpWRAP, offsetof(WRAP, lpVtbl)+sizeof(WRAP_Vtbl *)))
{
/*
* No jump table found
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see that the Vtbl is large enough to include this method
*/
if (IsBadReadPtr(lpWRAP->lpVtbl,
offsetof(WRAP_Vtbl, CopyProps)+sizeof(WRAP_CopyProps_METHOD *)))
{
/*
* Jump table not derived from IUnknown
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see if the method is the same
*/
if (WRAP_CopyProps != lpWRAP->lpVtbl->CopyProps)
{
/*
* Wrong object - the object passed doesn't have this
* method.
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
return lpWRAP->lpPropData->lpVtbl->CopyProps(
lpWRAP->lpPropData,
lpIncludeProps,
ulUIParam,
lpProgress,
lpInterface,
lpDestObj,
ulFlags,
lppProblems);
}
STDMETHODIMP
WRAP_GetNamesFromIDs( LPWRAP lpWRAP,
LPSPropTagArray * lppPropTags,
LPGUID lpPropSetGuid,
ULONG ulFlags,
ULONG * lpcPropNames,
LPMAPINAMEID ** lpppPropNames)
{
HRESULT hResult;
/*
* Check to see if it has a lpVtbl object member
*/
if (IsBadReadPtr(lpWRAP, offsetof(WRAP, lpVtbl)+sizeof(WRAP_Vtbl *)))
{
/*
* No jump table found
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see that the Vtbl is large enough to include this method
*/
if (IsBadReadPtr(lpWRAP->lpVtbl,
offsetof(WRAP_Vtbl, GetNamesFromIDs)+sizeof(WRAP_GetNamesFromIDs_METHOD *)))
{
/*
* Jump table not derived from IUnknown
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see if the method is the same
*/
if (WRAP_GetNamesFromIDs != lpWRAP->lpVtbl->GetNamesFromIDs)
{
/*
* Wrong object - the object passed doesn't have this
* method.
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
return lpWRAP->lpPropData->lpVtbl->GetNamesFromIDs(
lpWRAP->lpPropData,
lppPropTags,
lpPropSetGuid,
ulFlags,
lpcPropNames,
lpppPropNames);
}
STDMETHODIMP
WRAP_GetIDsFromNames( LPWRAP lpWRAP,
ULONG cPropNames,
LPMAPINAMEID * lppPropNames,
ULONG ulFlags,
LPSPropTagArray * lppPropTags)
{
HRESULT hResult;
/*
* Check to see if it has a lpVtbl object member
*/
if (IsBadReadPtr(lpWRAP, offsetof(WRAP, lpVtbl)+sizeof(WRAP_Vtbl *)))
{
/*
* No jump table found
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see that the Vtbl is large enough to include this method
*/
if (IsBadReadPtr(lpWRAP->lpVtbl,
offsetof(WRAP_Vtbl, GetIDsFromNames)+sizeof(WRAP_GetIDsFromNames_METHOD *)))
{
/*
* Jump table not derived from IUnknown
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
/*
* Check to see if the method is the same
*/
if (WRAP_GetIDsFromNames != lpWRAP->lpVtbl->GetIDsFromNames)
{
/*
* Wrong object - the object passed doesn't have this
* method.
*/
hResult = ResultFromScode(E_INVALIDARG);
return hResult;
}
return lpWRAP->lpPropData->lpVtbl->GetIDsFromNames(
lpWRAP->lpPropData,
cPropNames,
lppPropNames,
ulFlags,
lppPropTags);
}