|
|
/***********************************************************************
* * STATUS.C * * * The Microsoft At Work Fax Address Book Provider. * This file contains the methods that implement the status object. * * The following routines are implemented in this file: * * HrNewStatusObject() * ABS_QueryInterface() * ABS_Release() * ABS_ValidateState() * ABS_SettingsDialog() * ABS_ChangePassword() * ABS_FlushQueues() * * Copyright 1992, 1993, 1994 Microsoft Corporation. All Rights Reserved. * ***********************************************************************/
#include "faxab.h"
/*
* AB Status vtbl filled in here */
static const ABS_Vtbl vtblABS = {
ABS_QueryInterface, (ABS_AddRef_METHOD *) ROOT_AddRef, ABS_Release, (ABS_GetLastError_METHOD *) ROOT_GetLastError, (ABS_SaveChanges_METHOD *) WRAP_SaveChanges, (ABS_GetProps_METHOD *) WRAP_GetProps, (ABS_GetPropList_METHOD *) WRAP_GetPropList, (ABS_OpenProperty_METHOD *) WRAP_OpenProperty, (ABS_SetProps_METHOD *) WRAP_SetProps, (ABS_DeleteProps_METHOD *) WRAP_DeleteProps, (ABS_CopyTo_METHOD *) WRAP_CopyTo, (ABS_CopyProps_METHOD *) WRAP_CopyProps, (ABS_GetNamesFromIDs_METHOD *) WRAP_GetNamesFromIDs, (ABS_GetIDsFromNames_METHOD *) WRAP_GetIDsFromNames, ABS_ValidateState, ABS_SettingsDialog, ABS_ChangePassword, ABS_FlushQueues };
/*************************************************************************
* - HrNewStatusObject - * Creates the Status object associated with a particular FAB logon object * * */ HRESULT HrNewStatusObject( LPMAPISTATUS * lppABS, ULONG * lpulObjType, ULONG ulFlags, LPABLOGON lpABLogon, LPCIID lpIID, HINSTANCE hLibrary, LPALLOCATEBUFFER lpAllocBuff, LPALLOCATEMORE lpAllocMore, LPFREEBUFFER lpFreeBuff, LPMALLOC lpMalloc ) { LPABSTATUS lpABS = NULL; SCODE sc; HRESULT hr = hrSuccess; LPPROPDATA lpPropData = NULL; SPropValue spv[6]; LPTSTR lpszFileName; #ifdef UNICODE
CHAR szAnsiFileName[ MAX_PATH ]; #endif
/*
* */ if ( lpIID && (memcmp(lpIID, &IID_IMAPIStatus, SIZEOF(IID)) && memcmp(lpIID, &IID_IMAPIProp, SIZEOF(IID)) && memcmp(lpIID, &IID_IUnknown, SIZEOF(IID)) ) ) { DebugTraceSc(HrNewStatusObject, E_NOINTERFACE); return ResultFromScode(E_NOINTERFACE); }
/*
* Allocate space for the ABSTATUS structure */ sc = lpAllocBuff( SIZEOF(ABSTATUS), (LPVOID *) &lpABS );
if (FAILED(sc)) { hr = ResultFromScode(sc); goto err; }
lpABS->lpVtbl = &vtblABS; lpABS->lcInit = 1; lpABS->hResult = hrSuccess; lpABS->idsLastError = 0;
lpABS->hLibrary = hLibrary; lpABS->lpAllocBuff = lpAllocBuff; lpABS->lpAllocMore = lpAllocMore; lpABS->lpFreeBuff = lpFreeBuff; lpABS->lpMalloc = lpMalloc;
lpABS->lpABLogon = lpABLogon;
/*
* Create lpPropData */
sc = CreateIProp( (LPIID) &IID_IMAPIPropData, lpAllocBuff, lpAllocMore, lpFreeBuff, lpMalloc, &lpPropData );
if (FAILED(sc)) { hr = ResultFromScode(sc); goto err; }
/*
* Set up initial set of properties associated with this * status object. */
/*
* Register my status row... */ hr = HrLpszGetCurrentFileName(lpABLogon, &lpszFileName); if (HR_FAILED(hr)) { goto err; }
spv[0].ulPropTag = PR_DISPLAY_NAME_A; #ifdef UNICODE
szAnsiFileName[0] = 0; WideCharToMultiByte( CP_ACP, 0, lpszFileName, -1, szAnsiFileName, ARRAYSIZE(szAnsiFileName), NULL, NULL ); spv[0].Value.lpszA = szAnsiFileName; #else
spv[0].Value.LPSZ = lpszFileName; #endif
spv[1].ulPropTag = PR_RESOURCE_METHODS; spv[1].Value.l = 0;
spv[2].ulPropTag = PR_RESOURCE_FLAGS; spv[2].Value.l = 0;
spv[3].ulPropTag = PR_STATUS_CODE; spv[3].Value.l = STATUS_AVAILABLE;
spv[4].ulPropTag = PR_STATUS_STRING_A; spv[4].Value.lpszA = "Available";
spv[5].ulPropTag = PR_PROVIDER_DISPLAY_A; spv[5].Value.lpszA = "Microsoft Fax Address Book Provider";
/*
* Set the default properties */ hr = lpPropData->lpVtbl->SetProps( lpPropData, ARRAYSIZE(spv), spv, NULL );
/*
* Done with the current file name */ lpFreeBuff(lpszFileName);
if (HR_FAILED(hr)) { goto err; }
(void) lpPropData->lpVtbl->HrSetObjAccess(lpPropData, IPROP_READONLY);
lpABS->lpPropData = (LPMAPIPROP) lpPropData;
InitializeCriticalSection(&lpABS->cs);
*lpulObjType = MAPI_STATUS; *lppABS = (LPMAPISTATUS) lpABS;
out:
DebugTraceResult(HrNewStatusObject, hr); return hr;
err: if (lpPropData) lpPropData->lpVtbl->Release(lpPropData);
lpFreeBuff( lpABS );
goto out;
}
/*************************************************************************
* * - ABS_QueryInterface - * This method would allow this object to return a different interface than * the current one. This object need only support IMAPIStatus and any interface * it derives from. * */ STDMETHODIMP ABS_QueryInterface( LPABSTATUS lpABS, REFIID lpiid, LPVOID FAR * lppNewObj ) {
HRESULT hr = hrSuccess; /*
* Check to see if lpABS is what we expect */ if ( IsBadReadPtr(lpABS, SIZEOF(ABSTATUS)) || lpABS->lpVtbl != &vtblABS ) { hr = ResultFromScode(E_INVALIDARG); goto out; }
/* Validate other parameters */
if ( IsBadReadPtr(lpiid, (UINT) SIZEOF(IID)) || IsBadWritePtr(lppNewObj, SIZEOF(LPVOID)) ) { hr = ResultFromScode(E_INVALIDARG); goto out; }
/* See if the requested interface is one of ours */
if ( memcmp(lpiid, &IID_IUnknown, SIZEOF(IID)) && memcmp(lpiid, &IID_IMAPIProp, SIZEOF(IID)) && memcmp(lpiid, &IID_IMAPIStatus, SIZEOF(IID)) ) { *lppNewObj = NULL; /* OLE requires zeroing [out] parameter */ hr = ResultFromScode(E_NOINTERFACE); goto out; }
/* We'll do this one. Bump the usage count and return a new pointer. */
EnterCriticalSection(&lpABS->cs);
++lpABS->lcInit;
LeaveCriticalSection(&lpABS->cs);
*lppNewObj = lpABS;
out:
DebugTraceResult(ABS_QueryInterface, hr); return hr; }
/**************************************************
* - ABS_Release - * Decrement lpInit. * When lcInit == 0, free up the lpABS structure * */ STDMETHODIMP_(ULONG) ABS_Release(LPABSTATUS lpABS) { LONG lcInit;
/*
* Check to see if lpABS is what we expect */ if (IsBadReadPtr(lpABS, SIZEOF(ABSTATUS))) { /*
* No jump table found */ return 1; }
/*
* Check to see that it's the correct jump table */ if (lpABS->lpVtbl != &vtblABS) { /*
* Not my jump table */ return 1; }
EnterCriticalSection(&lpABS->cs);
lcInit = --lpABS->lcInit;
LeaveCriticalSection(&lpABS->cs);
if (lcInit == 0) {
/*
* Get rid of the lpPropData */
lpABS->lpPropData->lpVtbl->Release(lpABS->lpPropData);
/*
* Delete the critical section */
DeleteCriticalSection(&lpABS->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. */
lpABS->lpVtbl = NULL;
/*
* Need to free the object */
lpABS->lpFreeBuff( lpABS ); return 0; }
return lcInit;
}
/**********************************************************************
* - ABS_ValidateState - * Since I did not set any flags for the property PR_RESOURCE_METHODS * I don't have to support this method. * */
STDMETHODIMP ABS_ValidateState( LPABSTATUS lpABS, ULONG ulUIParam, ULONG ulFlags ) { HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT); /*
* Check to see if lpABS is what we expect */ if ( IsBadReadPtr(lpABS, SIZEOF(ABSTATUS)) || lpABS->lpVtbl != &vtblABS ) { hr = ResultFromScode(E_INVALIDARG); goto out; }
/* Validate other parameters */ if (ulFlags & ~(SUPPRESS_UI | REFRESH_XP_HEADER_CACHE | PROCESS_XP_HEADER_CACHE | FORCE_XP_CONNECT | FORCE_XP_DISCONNECT | CONFIG_CHANGED)) { hr = ResultFromScode(MAPI_E_UNKNOWN_FLAGS); goto out; }
out: DebugTraceResult(ABS_ValidateState, hr); return hr; }
/**********************************************************************
* - ABS_SettingsDialog - * Since I did not set any flags for the property PR_RESOURCE_METHODS * I don't have to support this method. * */ STDMETHODIMP ABS_SettingsDialog( LPABSTATUS lpABS, ULONG ulUIParam, ULONG ulFlags ) { HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT); /*
* Check to see if lpABS is what we expect */ if ( IsBadReadPtr(lpABS, SIZEOF(ABSTATUS)) || lpABS->lpVtbl != &vtblABS ) { hr = ResultFromScode(E_INVALIDARG); goto out; }
/* Validate other parameters */ if (ulFlags & ~(UI_READONLY)) { hr = ResultFromScode(MAPI_E_UNKNOWN_FLAGS); goto out; }
out: DebugTraceResult(ABS_SettingsDialog, hr); return hr; }
/**********************************************************************
* - ABS_ChangePassword - * Since I did not set any flags for the property PR_RESOURCE_METHODS * I don't have to support this method. * * Note: in the parameter validation below I chose only check the first 15 * characters of the passwords. This was arbitrary. */ STDMETHODIMP ABS_ChangePassword( LPABSTATUS lpABS, LPTSTR lpOldPass, LPTSTR lpNewPass, ULONG ulFlags ) { HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT); /*
* Check to see if lpABS is what we expect */ if ( IsBadReadPtr(lpABS, SIZEOF(ABSTATUS)) || lpABS->lpVtbl != &vtblABS ) { hr = ResultFromScode(E_INVALIDARG); goto out; }
/* Validate other parameters */
if (ulFlags & ~(MAPI_UNICODE)) { hr = ResultFromScode(MAPI_E_UNKNOWN_FLAGS); goto out; }
if ( ulFlags & MAPI_UNICODE ) { // UNICODE is currently not supported by the sample AB
hr = ResultFromScode( MAPI_E_BAD_CHARWIDTH ); goto out; }
if (ulFlags) { /*
* We're checking UNICODE strings */ if (IsBadStringPtrW((LPWSTR) lpOldPass, (UINT) 15) || IsBadStringPtrW((LPWSTR) lpNewPass, (UINT) 15)) {
hr = ResultFromScode(E_INVALIDARG); goto out; } } else { /*
* We're not checking UNICODE strings */ if (IsBadStringPtrA((LPSTR) lpOldPass, (UINT) 15) || IsBadStringPtrA((LPSTR) lpNewPass, (UINT) 15)) {
hr = ResultFromScode(E_INVALIDARG); goto out; } }
out: DebugTraceResult(ABS_ChangePassword, hr); return hr; }
/**********************************************************************
* - ABS_FlushQueues - * Since I did not set any flags for the property PR_RESOURCE_METHODS * I don't have to support this method. * */ STDMETHODIMP ABS_FlushQueues( LPABSTATUS lpABS, ULONG ulUIParam, ULONG cbTargetTransport, LPENTRYID lpTargetTransport, ULONG ulFlags ) { HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT); /*
* Check to see if lpABS is what we expect */ if (IsBadReadPtr(lpABS, SIZEOF(ABSTATUS)) || lpABS->lpVtbl != &vtblABS ) { hr = ResultFromScode(E_INVALIDARG); goto out; }
/* Validate other parameters */
if ( cbTargetTransport && ((cbTargetTransport < (ULONG) SIZEOF (ENTRYID)) || IsBadReadPtr(lpTargetTransport, (UINT) cbTargetTransport) ) ) { hr = ResultFromScode(E_INVALIDARG); goto out; }
if (ulFlags & ~(FLUSH_NO_UI | FLUSH_UPLOAD | FLUSH_DOWNLOAD | FLUSH_FORCE)) { hr = ResultFromScode(MAPI_E_UNKNOWN_FLAGS); goto out; }
out: DebugTraceResult(ABS_FlushQueues, hr); return hr; }
|