ABP.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:29k
源码类别:
Windows编程
开发平台:
Visual C++
- /***********************************************************************
- *
- * ABP.C
- *
- *
- * The Sample Address Book Provider.
- * This file contains the routines that handle the ABPJump table.
- *
- * The following routines are implemented in this file:
- *
- * ABProviderInit
- * ABP_QueryInterface
- * ABP_Release
- * ABP_Shutdown
- * ABP_Logon
- *
- * ServiceEntry
- * HrOpenSingleProvider
- *
- * RemoveLogonObject
- * FindLogonObject
- * ScLoadString
- *
- * Copyright 1992-1995 Microsoft Corporation. All Rights Reserved.
- *
- ***********************************************************************/
- #include "abp.h"
- #include <smpab.h>
- /*
- * The Local Identifier
- */
- LCID lcidUser;
- /*
- * This provider's MAPIUID. It's used as part of the entryIDs generated from this provider.
- */
- MAPIUID muidABSample = MUIDABSAMPLE;
- /*
- * This provider's value for PR_AB_PROVIDER_ID. It's found in the hierarchy table exposed
- * by this provider
- */
- MAPIUID muidSABProviderID = SAB_PROVIDER_ID;
- /*
- * This provider's Email Type
- */
- LPSTR lpszEMT = SZEMAILTYPE;
- /*
- * Used to keep track of all logon objects created on the ABPInit object
- */
- typedef struct _object
- {
- struct _object *lppNext;
- LPVOID lpObject;
- } OBJECTLIST, *LPOBJECTLIST;
- /*
- * structures and filters defined for display tables
- *
- */
- DTBLLABEL dtbllabel = {sizeof(DTBLLABEL), 0};
- DTBLPAGE dtblpage = {sizeof(DTBLPAGE), 0, 0, 0};
- DTBLGROUPBOX dtblgroupbox = {sizeof(DTBLGROUPBOX), 0};
- CHAR szNoFilter[] = "*";
- CHAR szAddrTypeFilter[] = "[~:]";
- CHAR szFileNameFilter[] = "[~ \\]"; /* ends up [~<space><tab>\] */
- /*
- * Prototypes for the functions in this file, most of which I return
- * in the jump table returned from ABProviderInit().
- */
- //ABPROVIDERINIT ABProviderInit;
- MSGSERVICEENTRY ServiceEntry;
- HRESULT HrOpenSingleProvider(LPPROVIDERADMIN lpAdminProviders,
- LPPROFSECT FAR * lppProfSect);
- /*
- * Definition of the init object
- */
- typedef struct _ABP {
- ABP_Vtbl FAR * lpVtbl;
- SAB_IUnknown;
- /*
- * list of logon objects
- */
- LPOBJECTLIST lpObjectList;
- } ABP, FAR *LPABP;
- /*
- * The ABInit object's vtbl is filled in here
- */
- ABP_Vtbl vtblABP =
- {
- ABP_QueryInterface,
- (ABP_AddRef_METHOD *) ROOT_AddRef,
- ABP_Release,
- ABP_Shutdown,
- ABP_Logon
- };
- /*
- - ABProviderInit
- -
- * Initializes this provider. Returns an IABProvider object.
- *
- */
- STDINITMETHODIMP
- ABProviderInit(
- HINSTANCE hLibrary,
- LPMALLOC lpMalloc,
- LPALLOCATEBUFFER lpAllocBuff,
- LPALLOCATEMORE lpAllocMore,
- LPFREEBUFFER lpFreeBuff,
- ULONG ulFlags,
- ULONG ulMAPIVersion,
- ULONG FAR * lpulABVersion,
- LPABPROVIDER FAR * lppABProvider)
- {
- HRESULT hResult = hrSuccess;
- LPABP lpABP;
- SCODE sc;
- /*
- * Check the version
- */
- if (ulMAPIVersion < CURRENT_SPI_VERSION)
- {
- /*
- * MAPI's version is too old.
- */
- /*
- * See if they understand my version
- */
- *lpulABVersion = CURRENT_SPI_VERSION;
- DebugTraceSc(ABProviderInit, MAPI_E_VERSION);
- return ResultFromScode(MAPI_E_VERSION);
- }
- /*
- * Allocate memory for this Init Object
- */
- sc = lpAllocBuff (sizeof(ABP), &lpABP);
- if (FAILED(sc))
- {
- /*
- * Out of memory
- */
- DebugTraceSc(ABProviderInit, sc);
- return ResultFromScode(sc);
- }
- /*
- * Initialize the idle engine that MAPI supplies. This is most useful
- * when browsing the .SAB file. See ABCTBLn.C.
- */
- if (MAPIInitIdle(NULL) == -1)
- {
- hResult = ResultFromScode(E_FAIL);
- goto err;
- }
- /*
- * Hold on to the lpMalloc
- */
- Assert(lpMalloc);
- lpMalloc->lpVtbl->AddRef(lpMalloc);
- lpABP->lpVtbl = &vtblABP;
- lpABP->lcInit = 1;
- lpABP->hLibrary = hLibrary;
- lpABP->lpMalloc = lpMalloc;
- lpABP->lpAllocBuff = lpAllocBuff;
- lpABP->lpAllocMore = lpAllocMore;
- lpABP->lpFreeBuff = lpFreeBuff;
- lpABP->lpObjectList = NULL;
- InitializeCriticalSection(&lpABP->cs);
- *lppABProvider = (LPABPROVIDER) lpABP;
- *lpulABVersion = CURRENT_SPI_VERSION;
- /*
- * Get our Locale Identifier
- */
- lcidUser = GetUserDefaultLCID();
- out:
- DebugTraceResult(ABProviderInit, hResult);
- return hResult;
- err:
- lpFreeBuff(lpABP);
- goto out;
- }
- /*
- - ABP_QueryInterface
- -
- * Supports QI'ing to IUnknown and IABProvider
- *
- * Note that for all the methods of IABProvider that parameter validation
- * is unnecessary. This is because MAPI is handling all the parameters
- * being passed in.
- * At best you can assert your parameters.
- */
- STDMETHODIMP
- ABP_QueryInterface(LPABP lpABP, REFIID lpiid, LPVOID * ppvObj)
- {
- /* See if the requested interface is one of ours */
- if (memcmp(lpiid, &IID_IUnknown, sizeof(IID)) &&
- memcmp(lpiid, &IID_IABProvider, sizeof(IID)))
- {
- *ppvObj = NULL; /* OLE requires zeroing [out] parameter on error */
- DebugTraceSc(ABP_QueryInterface, E_NOINTERFACE);
- return ResultFromScode(E_NOINTERFACE);
- }
- /* We'll do this one. Bump the usage count and return a new pointer. */
- EnterCriticalSection(&lpABP->cs);
- ++lpABP->lcInit;
- LeaveCriticalSection(&lpABP->cs);
- *ppvObj = lpABP;
- return hrSuccess;
- }
- /*
- - ABP_Release
- -
- * Releases and cleans up this object
- */
- STDMETHODIMP_(ULONG)
- ABP_Release(LPABP lpABP)
- {
- long lcInit;
- EnterCriticalSection(&lpABP->cs);
- lcInit = --lpABP->lcInit;
- LeaveCriticalSection(&lpABP->cs);
- if (lcInit == 0)
- {
- DeleteCriticalSection(&lpABP->cs);
- lpABP->lpVtbl = NULL;
- lpABP->lpFreeBuff(lpABP);
- return (0);
- }
- return lcInit;
- }
- /*
- - ABP_Shutdown
- -
- * Informs this provider that MAPI is done with it.
- *
- *
- */
- STDMETHODIMP
- ABP_Shutdown(LPABP lpABP, ULONG FAR * lpulFlags)
- {
- MAPIDeinitIdle();
- if (lpABP->lpMalloc)
- {
- lpABP->lpMalloc->lpVtbl->Release(lpABP->lpMalloc);
- lpABP->lpMalloc = NULL;
- }
- return hrSuccess;
- }
- /*
- - ABP_Logon
- -
- * Create a logon object and return it to MAPI.
- *
- */
- /*
- * The PropTagArray used to retrieve logon properties
- */
- enum { ivallogonPR_SAB_FILE,
- ivallogonPR_SAB_UID,
- cvallogonMax };
- static const SizedSPropTagArray(cvallogonMax, tagaSABLogonProps) =
- {
- cvallogonMax,
- {
- PR_SAB_FILE,
- PR_SAB_UID
- }
- };
- STDMETHODIMP
- ABP_Logon( LPABP lpABP,
- LPMAPISUP lpMAPISup,
- ULONG ulUIParam,
- LPTSTR lpszProfileName,
- ULONG ulFlags,
- ULONG FAR * lpulpcbSecurity,
- LPBYTE FAR * lppbSecurity,
- LPMAPIERROR FAR * lppMapiError,
- LPABLOGON FAR * lppABPLogon)
- {
- LPABLOGON lpABLogon = NULL;
- HRESULT hResult = hrSuccess;
- SCODE scode;
- LPPROFSECT lpProfSect = NULL;
- LPSPropValue lpsPropVal = NULL;
- ULONG cValues = 0;
- LPSTR lpstrT = NULL;
- BOOL fUINeeded;
- BOOL fNeedMAPIUID = FALSE;
- MAPIUID muidID;
- LPOBJECTLIST lpObjectList;
- CHAR szFileName[MAX_PATH];
- szFileName[0] = ' ';
- *lppMapiError = NULL;
- if ( ulFlags & MAPI_UNICODE )
- {
- DebugTraceArg( ABP_Logon, "Bad Character width" );
- return ResultFromScode( MAPI_E_BAD_CHARWIDTH );
- }
- /*
- * Get the name of my browse file from the profile section
- */
- /* Open the section for my provider */
- hResult = lpMAPISup->lpVtbl->OpenProfileSection(lpMAPISup,
- NULL,
- MAPI_MODIFY,
- &lpProfSect);
- if (HR_FAILED(hResult))
- goto out;
- /* Get the property containing the browse file name and the sab uid. */
- hResult = lpProfSect->lpVtbl->GetProps(
- lpProfSect,
- (LPSPropTagArray) &tagaSABLogonProps,
- 0, /* ansi */
- &cValues,
- &lpsPropVal);
- if (HR_FAILED(hResult))
- goto out;
- #ifdef DEBUG
- if (hResult != hrSuccess)
- {
- if (PROP_TYPE(lpsPropVal[ivallogonPR_SAB_FILE].ulPropTag) == PT_ERROR
- && lpsPropVal[0].Value.err != MAPI_E_NOT_FOUND)
- {
- TraceSz1("ABP_Logon (PR_SAB_FILE) got unexpected scode: %sn",
- SzDecodeScode(lpsPropVal[ivallogonPR_SAB_FILE].Value.err));
- }
- if (PROP_TYPE(lpsPropVal[ivallogonPR_SAB_UID].ulPropTag) == PT_ERROR
- && lpsPropVal[ivallogonPR_SAB_UID].Value.err != MAPI_E_NOT_FOUND)
- {
- TraceSz1("ABP_Logon (PR_SAB_UID) got unexpected scode: %sn",
- SzDecodeScode(lpsPropVal[1].Value.err));
- }
- }
- #endif
- /* Ignore warnings from reading the property. */
- hResult = hrSuccess;
- /* copy the sab file name */
- if (lpsPropVal[0].ulPropTag == PR_SAB_FILE)
- {
- UINT cch = lstrlenA(lpsPropVal[0].Value.lpszA);
- if (cch >= MAX_PATH)
- cch = MAX_PATH - 1;
- if (cch)
- memcpy(szFileName, lpsPropVal[0].Value.lpszA, cch);
- szFileName[cch] = ' ';
- }
- else
- {
- DebugTrace("ABP_Logon PR_SAB_FILE not found");
- }
- /* copy the sab uid */
- if (lpsPropVal[1].ulPropTag == PR_SAB_UID)
- {
- memcpy(&muidID, lpsPropVal[1].Value.bin.lpb, sizeof(MAPIUID));
- }
- else
- {
- DebugTrace("ABP_Logon PR_SAB_UID not found");
- fNeedMAPIUID = TRUE;
- }
- /* Discard GetProps() return data, if any. */
- lpABP->lpFreeBuff(lpsPropVal);
- /*
- * UI needed unless the file name is good and file exists.
- */
- fUINeeded = TRUE;
- if (szFileName[0] != 0)
- {
- /* Verify the file exists. */
- HANDLE hFile = CreateFile(
- szFileName,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (hFile != INVALID_HANDLE_VALUE)
- {
- CloseHandle(hFile);
- fUINeeded = FALSE;
- }
- }
- /*
- * if the sab file name was not found in the profile or the sab file
- * does not exist we have to get the user to pick another one and
- * save back into the profile
- */
- if (fUINeeded)
- {
- OPENFILENAME openfilename;
- SPropValue sProp[1];
- /*
- * Can't bring up UI unless the client allows it
- */
- if (ulFlags & AB_NO_DIALOG)
- {
- hResult = ResultFromScode(MAPI_E_LOGON_FAILED);
- goto out;
- }
- /*
- * Get the user to select a file
- */
- openfilename.lStructSize = sizeof(OPENFILENAME);
- openfilename.hwndOwner = (HWND) ulUIParam;
- openfilename.hInstance = 0; /* Ignored */
- openfilename.lpstrFilter = TEXT("Sample AB files *.sab ");
- openfilename.lpstrCustomFilter = NULL;
- openfilename.nMaxCustFilter = 0;
- openfilename.nFilterIndex = 0;
- openfilename.lpstrFile = szFileName;
- openfilename.nMaxFile = MAX_PATH;
- openfilename.lpstrFileTitle = NULL;
- openfilename.nMaxFileTitle = 0;
- openfilename.lpstrInitialDir = NULL;
- openfilename.lpstrTitle = TEXT("Sample Address Book");
- openfilename.Flags = OFN_FILEMUSTEXIST |
- OFN_HIDEREADONLY |
- OFN_NOCHANGEDIR;
- openfilename.nFileOffset = 0;
- openfilename.nFileExtension = 0;
- openfilename.lpstrDefExt = TEXT("sab");
- openfilename.lCustData = 0;
- openfilename.lpfnHook = NULL;
- openfilename.lpTemplateName = NULL;
- /*
- * Call up the common dialog
- */
- if (!GetOpenFileName(&openfilename))
- {
- #ifdef DEBUG
- DWORD dwT;
- dwT = CommDlgExtendedError();
- #endif /* DEBUG */
- hResult = ResultFromScode(MAPI_E_LOGON_FAILED);
- goto out;
- }
- /*
- * Set the sab file name property value
- */
- sProp[0].ulPropTag = PR_SAB_FILE;
- sProp[0].Value.lpszA = szFileName;
- /*
- * Save the sab file into the profile
- */
- if (hResult = lpProfSect->lpVtbl->SetProps(lpProfSect, 1, sProp, NULL))
- {
- /*
- * Do nothing... So I couldn't save it away this time...
- */
- DebugTraceResult("ABP_Logon got unexpected result on SetPropsn", hResult);
- hResult = hrSuccess;
- }
- }
- /*
- * if the uid was not found we have to generate a new muid for the
- * PR_SAB_ID property and save it back into the profile
- */
- if (fNeedMAPIUID)
- {
- SPropValue sProp[1];
- /*
- * Get a new sab uid
- */
- hResult = lpMAPISup->lpVtbl->NewUID(lpMAPISup, &muidID);
- if (HR_FAILED(hResult))
- {
- goto out;
- }
- /*
- * Set the sab uid property value
- */
- sProp[0].ulPropTag = PR_SAB_UID;
- sProp[0].Value.bin.cb = sizeof(MAPIUID);
- sProp[0].Value.bin.lpb = (LPBYTE) &muidID;
- /*
- * Save the sab uid into the profile
- */
- if (hResult = lpProfSect->lpVtbl->SetProps(lpProfSect, 1, sProp, NULL))
- {
- /*
- * Do nothing... So I couldn't save it away this time...
- */
- DebugTraceResult("ABP_Logon got unexpected result on SetPropsn", hResult);
- hResult = hrSuccess;
- }
- }
- /*
- * Allocate space for keeping the file name in the ABLogon object
- */
- if (scode = lpABP->lpAllocBuff(lstrlenA(szFileName)+1, &lpstrT))
- {
- hResult = ResultFromScode(scode);
- goto out;
- }
- lstrcpyA(lpstrT, szFileName);
- hResult = HrNewABLogon(&lpABLogon,
- (LPABPROVIDER) lpABP,
- lpMAPISup,
- lpstrT,
- &muidID,
- lpABP->hLibrary,
- lpABP->lpAllocBuff,
- lpABP->lpAllocMore,
- lpABP->lpFreeBuff,
- lpABP->lpMalloc );
- if (HR_FAILED(hResult))
- {
- goto out;
- }
- /*
- * Allocate space for another object list item
- */
- scode = lpABP->lpAllocBuff(sizeof(OBJECTLIST), &lpObjectList);
- if (FAILED(scode))
- {
- hResult = ResultFromScode(scode);
- goto out;
- }
- /* Get the Critical Section */
- EnterCriticalSection(&lpABP->cs);
- /* add logon object to begining of providers object list */
- lpObjectList->lpObject = (LPVOID) lpABLogon;
- lpObjectList->lppNext = lpABP->lpObjectList;
- /* insert new logon object into the head of the providers object list */
- lpABP->lpObjectList = lpObjectList;
- /* leave critical section */
- LeaveCriticalSection(&lpABP->cs);
- /*
- * Register my MAPIUID for this provider,
- * but do not allow an error from setting the
- * MAPIUID to cause failure to Logon.
- */
- (void)lpMAPISup->lpVtbl->SetProviderUID(lpMAPISup,
- (LPMAPIUID) &muidABSample, 0);
- *lppABPLogon = lpABLogon;
- out:
- if (lpProfSect)
- lpProfSect->lpVtbl->Release(lpProfSect);
- if (hResult)
- {
- lpABP->lpFreeBuff(lpstrT);
- Assert(lpABLogon == NULL);
- /* Verify we don't return warnings at this time. */
- Assert(HR_FAILED(hResult));
- }
- DebugTraceResult(ABP_Logon, hResult);
- return hResult;
- }
- /*
- * Removes a particular logon object from the list of logon objects
- * that's kept track of in the IABProvider object
- */
- void
- RemoveLogonObject(LPABPROVIDER lpABProvider, LPVOID lpvABLogon, LPFREEBUFFER lpFreeBuff)
- {
- LPOBJECTLIST *lppObjectList;
- LPOBJECTLIST lpObjectListT;
- LPABP lpABP = (LPABP) lpABProvider;
- #if defined DEBUG
- BOOL fFound = FALSE;
- #endif
- /* Get the Critical Section */
- EnterCriticalSection(&lpABP->cs);
- /*
- * remove this logon object from the provider init objects list
- * of logon objects
- */
- lppObjectList = &(lpABP->lpObjectList);
- while (*lppObjectList)
- {
- /* is this the logon object? */
- if ((*lppObjectList)->lpObject == lpvABLogon)
- {
- /* save next list item */
- lpObjectListT = (*lppObjectList)->lppNext;
- /* free the object list item */
- lpFreeBuff(*lppObjectList);
- /* delete object from the list */
- *lppObjectList = lpObjectListT;
- #if defined DEBUG
- fFound = TRUE;
- #endif
- break;
- }
- lppObjectList = &(*lppObjectList)->lppNext;
- }
- /* leave critical section */
- LeaveCriticalSection(&lpABP->cs);
- #if defined DEBUG
- AssertSz(fFound, TEXT("Logon object not found on providers object list"));
- #endif
- return;
- }
- /*
- * Finds a particular logon object by its muid.
- */
- void
- FindLogonObject(LPABPROVIDER lpABProvider, LPMAPIUID lpMuidToFind, LPABLOGON * lppABLogon)
- {
- LPABP lpABP = (LPABP) lpABProvider;
- LPABLOGON lpABLogonT = NULL;
- LPOBJECTLIST lpObjectList = NULL;
- LPMAPIUID lpMuidLogon = NULL;
- Assert(!IsBadReadPtr(lpABP, sizeof(ABP)));
- Assert(!IsBadReadPtr(lpMuidToFind, sizeof(MAPIUID)));
- Assert(!IsBadReadPtr(lppABLogon, sizeof(LPABLOGON)));
- /* Get the Critical Section */
- EnterCriticalSection(&lpABP->cs);
- *lppABLogon = NULL;
- for (lpObjectList = lpABP->lpObjectList;
- lpObjectList; lpObjectList = lpObjectList->lppNext)
- {
- lpABLogonT = (LPABLOGON) lpObjectList->lpObject;
- lpMuidLogon = LpMuidFromLogon(lpABLogonT);
- if (memcmp((LPVOID) lpMuidLogon, (LPVOID) lpMuidToFind, sizeof(MAPIUID)) == 0)
- {
- *lppABLogon = lpABLogonT;
- break;
- }
- }
- /* leave critical section */
- LeaveCriticalSection(&lpABP->cs);
- }
- /*
- - ServiceEntry
- -
- * This funtion is used by MAPI to configure the Sample Address Book.
- * It's a lot like ABP_Logon, except that it doesn't return a logon object
- * and it can be passed in its configuration information (as defined in
- * smpab.h) from MAPI so that no UI is required.
- *
- */
- STDAPI
- ServiceEntry(HINSTANCE hInstance,
- LPMALLOC lpMalloc,
- LPMAPISUP lpMAPISup,
- ULONG ulUIParam,
- ULONG ulFlags,
- ULONG ulContext,
- ULONG cValues,
- LPSPropValue lpProps,
- LPPROVIDERADMIN lpAdminProviders,
- LPMAPIERROR FAR *lppMapiError)
- {
- OPENFILENAME openfilename;
- char szFileName[MAX_PATH];
- HRESULT hResult = hrSuccess;
- LPSPropValue lpsPropVal = NULL;
- ULONG ulCount = 0;
- LPALLOCATEBUFFER lpAllocBuff;
- LPALLOCATEMORE lpAllocMore;
- LPFREEBUFFER lpFreeBuff;
- LPPROFSECT lpProf = NULL;
- BOOL fUINeeded = FALSE;
- BOOL fNeedMAPIUID = FALSE;
- SPropValue sProp[2];
- ULONG uliProp;
- MAPIUID muid;
- /* Validate parameters */
- /* check the support object */
- if (IsBadReadPtr(lpMAPISup, sizeof(LPMAPISUP)))
- {
- DebugTraceSc(ServiceEntry, E_INVALIDARG);
- return ResultFromScode(E_INVALIDARG);
- }
- if ( ulFlags & MAPI_UNICODE )
- {
- DebugTraceArg( ServiceEntry, "Bad character width" );
- return ResultFromScode( MAPI_E_BAD_CHARWIDTH );
- }
- /*
- * check for context
- */
- if (ulContext == MSG_SERVICE_DELETE || ulContext == MSG_SERVICE_INSTALL
- || ulContext == MSG_SERVICE_UNINSTALL)
- return hrSuccess;
- if (ulContext != MSG_SERVICE_CONFIGURE && ulContext != MSG_SERVICE_CREATE)
- {
- DebugTrace(TEXT("ServiceEntry unsupported context"));
- return ResultFromScode(MAPI_E_NO_SUPPORT);
- }
- /* Get the memory allocation routines we'll be needing. */
- hResult = lpMAPISup->lpVtbl->GetMemAllocRoutines(lpMAPISup,
- &lpAllocBuff, &lpAllocMore, &lpFreeBuff);
- if (hResult)
- {
- DebugTraceResult(MAPISUP: :GetMemAllocRoutines, hResult);
- goto out;
- }
- /* Open the profile section associated with our provider */
- hResult = HrOpenSingleProvider(lpAdminProviders, &lpProf);
- if (hResult)
- {
- DebugTrace(TEXT("Unable to open the profile."));
- goto out;
- }
- szFileName[0] = ' ';
- /* get sab filename and uid from profile */
- hResult = lpProf->lpVtbl->GetProps(
- lpProf,
- (LPSPropTagArray) &tagaSABLogonProps,
- ulFlags & MAPI_UNICODE,
- &ulCount,
- &lpsPropVal);
- /* Ignore errors/warnings from reading the property. */
- hResult = hrSuccess;
- /* Look for the .SAB in the config props first */
- for (uliProp = 0; uliProp < cValues; uliProp++)
- {
- if (PROP_ID(lpProps[uliProp].ulPropTag) == PROP_ID(PR_SAB_FILE))
- break;
- }
- if (uliProp < cValues &&
- PROP_TYPE(lpProps[uliProp].ulPropTag) != PT_ERROR)
- {
- ULONG cch = lstrlenA(lpProps[uliProp].Value.lpszA);
- if (cch >= MAX_PATH)
- cch = MAX_PATH - 1;
- if (cch)
- memcpy(szFileName, lpProps[uliProp].Value.lpszA, (size_t) cch);
- szFileName[cch] = ' ';
- }
- else if (lpsPropVal && PROP_ID(lpsPropVal[0].ulPropTag) ==
- PROP_ID(PR_SAB_FILE) &&
- PROP_TYPE(lpsPropVal[0].ulPropTag) != PT_ERROR)
- {
- ULONG cch = lstrlenA(lpsPropVal[0].Value.lpszA);
- if (cch >= MAX_PATH)
- cch = MAX_PATH - 1;
- if (cch)
- memcpy(szFileName, lpsPropVal[0].Value.lpszA, (size_t) cch);
- szFileName[cch] = ' ';
- }
- else
- {
- /* need to ask the user for the sab file */
- fUINeeded = TRUE;
- }
- /* Look for the SAB_UID in the config props first */
- for (uliProp = 0; uliProp < cValues; uliProp++)
- {
- if (PROP_ID(lpProps[uliProp].ulPropTag) == PROP_ID(PR_SAB_UID))
- break;
- }
- if (uliProp < cValues &&
- PROP_TYPE(lpProps[uliProp].ulPropTag) != PT_ERROR)
- {
- memcpy(&muid, lpProps[uliProp].Value.bin.lpb, sizeof(MAPIUID));
- }
- else if (lpsPropVal && PROP_ID(lpsPropVal[1].ulPropTag) ==
- PROP_ID(PR_SAB_UID) && PROP_TYPE(lpsPropVal[1].ulPropTag) != PT_ERROR)
- {
- memcpy(&muid, lpsPropVal[1].Value.bin.lpb, sizeof(MAPIUID));
- }
- else
- {
- /* need to generate a uid */
- fNeedMAPIUID = TRUE;
- }
- /* Discard GetProps() return data, if any.
- */
- if (lpsPropVal)
- lpFreeBuff(lpsPropVal);
- /*
- * if the sab file name was not found in the profile we have to
- * get the user to pick one and save it back into the profile
- */
- if ( fUINeeded
- && !(ulFlags & (SERVICE_UI_ALLOWED | SERVICE_UI_ALWAYS | UI_SERVICE)))
- {
- /* We need UI to configure but it's not allowed so we can't configure.
- */
- hResult = ResultFromScode(MAPI_E_UNCONFIGURED);
- DebugTrace("SMPAB::ServiceEntry - Missing properties required to configure service.n");
- goto out;
- }
- if ((fUINeeded) || (ulFlags & UI_SERVICE))
- {
- /*
- * Get the user to pick a SAB file
- */
- openfilename.lStructSize = sizeof(OPENFILENAME);
- openfilename.hwndOwner = (HWND) ulUIParam;
- openfilename.hInstance = 0; /* Ignored */
- openfilename.lpstrFilter = "Sample AB files *.sab ";
- openfilename.lpstrCustomFilter = NULL;
- openfilename.nMaxCustFilter = 0;
- openfilename.nFilterIndex = 0;
- openfilename.lpstrFile = szFileName;
- openfilename.nMaxFile = MAX_PATH;
- openfilename.lpstrFileTitle = NULL;
- openfilename.nMaxFileTitle = 0;
- openfilename.lpstrInitialDir = NULL;
- openfilename.lpstrTitle = "Pick a Sample Address Book file";
- openfilename.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_HIDEREADONLY;
- openfilename.nFileOffset = 0;
- openfilename.nFileExtension = 0;
- openfilename.lpstrDefExt = "sab";
- openfilename.lCustData = 0;
- openfilename.lpfnHook = NULL;
- openfilename.lpTemplateName = NULL;
- /*
- * Call up the common dialog
- */
- if (!GetOpenFileName(&openfilename))
- {
- /* user pressed cancel */
- goto out;
- }
- }
- /*
- * if the uid was not found we have to generate a new muid for the
- * PR_SAB_ID property and save it back into the profile
- */
- if (fNeedMAPIUID)
- {
- hResult = lpMAPISup->lpVtbl->NewUID(lpMAPISup, &muid);
- if (HR_FAILED(hResult))
- {
- /*
- * Can't get a uid so just leave
- */
- goto out;
- }
- }
- /*
- * Set the file name property
- */
- sProp[ivallogonPR_SAB_FILE].ulPropTag = PR_SAB_FILE;
- sProp[ivallogonPR_SAB_FILE].Value.lpszA = szFileName;
- /*
- * Set the id property
- */
- sProp[ivallogonPR_SAB_UID].ulPropTag = PR_SAB_UID;
- sProp[ivallogonPR_SAB_UID].Value.bin.cb = sizeof(MAPIUID);
- sProp[ivallogonPR_SAB_UID].Value.bin.lpb = (LPBYTE) &muid;
- /*
- * Save the sab file and the uid back into the profile
- */
- hResult = lpProf->lpVtbl->SetProps(
- lpProf,
- sizeof(sProp) / sizeof(SPropValue),
- sProp,
- NULL);
- if (HR_FAILED(hResult))
- {
- /*
- * Do nothing... So I couldn't save it away this time...
- */
- DebugTrace(TEXT("ServiceEntry could not SetProp in profile"));
- hResult = hrSuccess;
- }
- out:
- if (lpProf)
- lpProf->lpVtbl->Release(lpProf);
- DebugTraceResult(ServiceEntry, hResult);
- return hResult;
- }
- /*
- - HrOpenSingleProvider
- -
- * Opens the profile section associated with this provider.
- *
- * If the ServiceEntry() function exported from a provider had
- * more than 1 section associated with it, this is where you'd get the chance
- * to get all of them.
- */
- static SizedSPropTagArray(1, tagaProviderTable) =
- {
- 1,
- {
- PR_PROVIDER_UID
- }
- };
- HRESULT
- HrOpenSingleProvider(LPPROVIDERADMIN lpAdminProviders,
- LPPROFSECT FAR * lppProfSect)
- {
- HRESULT hResult;
- LPMAPITABLE lpTable = NULL;
- LPSRowSet lpRows = NULL;
- LPSPropValue lpProp;
- hResult = lpAdminProviders->lpVtbl->GetProviderTable(
- lpAdminProviders,
- 0,
- &lpTable);
- if (HR_FAILED(hResult))
- goto out;
- hResult = lpTable->lpVtbl->SetColumns(lpTable, (LPSPropTagArray) &tagaProviderTable, 0);
- if (HR_FAILED(hResult))
- goto out;
- hResult = lpTable->lpVtbl->QueryRows(lpTable, 1, 0, &lpRows);
- if (HR_FAILED(hResult))
- goto out;
- if (lpRows->cRows == 0)
- {
- hResult = ResultFromScode(MAPI_E_NOT_FOUND);
- goto out;
- }
- lpProp = lpRows->aRow[0].lpProps;
- hResult = lpAdminProviders->lpVtbl->OpenProfileSection(
- lpAdminProviders,
- (LPMAPIUID) lpProp->Value.bin.lpb,
- NULL,
- MAPI_MODIFY,
- lppProfSect);
- out:
- FreeProws(lpRows);
- if (lpTable)
- lpTable->lpVtbl->Release(lpTable);
- DebugTraceResult(HrOpenSingleProvider, hResult);
- return hResult;
- }
- /*
- - ScLoadString
- -
- * Loads a string from a resource. It will optionally allocate the string if
- * a allocation function is passed in. Otherwise it assumes that the *lppsz
- * is already allocated.
- */
- SCODE ScLoadString( UINT ids,
- ULONG ulcch,
- LPALLOCATEBUFFER lpAllocBuff,
- HINSTANCE hLibrary,
- LPSTR * lppsz)
- {
- SCODE sc = S_OK;
- int iRet;
- /*
- * Assert parameters
- */
- Assert((lpAllocBuff ? !IsBadCodePtr((FARPROC) lpAllocBuff):TRUE));
- Assert(ids!=0);
- if (lpAllocBuff)
- {
- sc = lpAllocBuff(ulcch, lppsz);
- if (FAILED(sc))
- {
- goto out;
- }
- }
- #ifdef DEBUG
- else
- {
- Assert(!IsBadWritePtr(*lppsz, (UINT) ulcch));
- }
- #endif /* DEBUG */
- iRet = LoadStringA( hLibrary,
- ids,
- *lppsz,
- (UINT) ulcch);
- if (!iRet)
- {
- DebugTrace("LoadString() failed...n");
- sc = E_FAIL;
- goto out;
- }
- out:
- DebugTraceSc(ScLoadString, sc);
- return sc;
- }