579 lines
13 KiB
C
579 lines
13 KiB
C
/***********************************************************************
|
|
*
|
|
* 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;
|
|
}
|