ABCONT.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:38k
源码类别:
Windows编程
开发平台:
Visual C++
- /***********************************************************************
- *
- * ABCONT.C
- *
- * Sample AB directory container object
- *
- * This file contains the code for implementing the Sample AB
- * directory container object.
- *
- * This directory container was retrieved by OpenEntry on the entryid
- * retrieved from the single row of the hierarchy table (IVTROOT in root.c).
- *
- * The following routines are implemented in this file:
- *
- * HrNewSampDirectory
- * ABC_Release
- * ABC_SaveChanges
- * ABC_OpenProperty
- * ABC_GetContentsTable
- * ABC_GetHierarchyTable
- *
- * HrGetDetailsDialog
- *
- * HrNewABCButton
- * ABCBUTT_QueryInterface
- * ABCBUTT_Release
- * ABCBUTT_Activate
- * ABCBUTT_GetState
- *
- * Copyright 1992-1995 Microsoft Corporation. All Rights Reserved.
- *
- ***********************************************************************/
- #include "abp.h"
- #include "sampabp.rh"
- #include <smpab.h>
- /*
- * Proptags used only in this module
- */
- #define PR_RADIO_BUTTON_VALUE PROP_TAG(PT_LONG, 0x6601)
- #define PR_BUTTON_PRESS PROP_TAG(PT_OBJECT, 0x6603)
- #define PR_SAB_FILE_TEMP PROP_TAG(PT_TSTRING,0x6605)
- /*
- * Possible values for PR_RADIO_BUTTON_VALUE
- */
- #define RADIO_BUTTON_1_RETURN_VALUE 1
- #define RADIO_BUTTON_2_RETURN_VALUE 2
- #define RADIO_BUTTON_3_RETURN_VALUE 3
- #define RADIO_BUTTON_4_RETURN_VALUE 4
- /*
- * Structure for the 'this'
- */
- typedef struct _ABCNT
- {
- const ABC_Vtbl FAR * lpVtbl;
- SAB_Wrapped;
- /* details display table */
- LPTABLEDATA lpTDatDetails;
- } ABCNT, *LPABCNT;
- /*
- * This is the data structure passed to the
- * HrNotify method of the Table Data Object
- * in ABCBUTT_Activate that uniquely identifies
- * the control in the display table that needs
- * to be updated.
- */
- typedef struct
- {
- MAPIUID muid;
- ULONG ulIdc;
- } NOTIFDATA;
- /*
- * The actual data. Note that the control
- * is specified by IDC_DIR_SAB_FILE_NAME.
- */
- NOTIFDATA notifdata =
- {MUIDABSAMPLE, IDC_DIR_SAB_FILE_NAME};
- /* Display table control structures for the Directory property sheet. */
- /*
- * Edit control that displays the current .SAB file.
- */
- DTBLEDIT editDirFileName =
- {
- sizeof(DTBLEDIT),
- 0,
- MAX_PATH,
- PR_SAB_FILE_TEMP
- };
- /*
- * Button control for changing the current .SAB file.
- */
- DTBLBUTTON buttonDirChange =
- {
- sizeof(DTBLBUTTON),
- 0,
- PR_BUTTON_PRESS
- };
- /*
- * The next four controls are radio buttons. Note how they
- * are related by their use of PR_RADIO_BUTTON_VALUE and
- * differentiated by RADIO_BUTTON_x_RETURN_VALUE. Also note
- * the '4' which says how many controls are in this group
- * of radio buttons.
- */
- DTBLRADIOBUTTON radiobuttonDir1 =
- {
- sizeof(DTBLRADIOBUTTON),
- 0,
- 4,
- PR_RADIO_BUTTON_VALUE,
- RADIO_BUTTON_1_RETURN_VALUE
- };
- DTBLRADIOBUTTON radiobuttonDir2 =
- {
- sizeof(DTBLRADIOBUTTON),
- 0,
- 4,
- PR_RADIO_BUTTON_VALUE,
- RADIO_BUTTON_2_RETURN_VALUE
- };
- DTBLRADIOBUTTON radiobuttonDir3 =
- {
- sizeof(DTBLRADIOBUTTON),
- 0,
- 4,
- PR_RADIO_BUTTON_VALUE,
- RADIO_BUTTON_3_RETURN_VALUE
- };
- DTBLRADIOBUTTON radiobuttonDir4 =
- {
- sizeof(DTBLRADIOBUTTON),
- 0,
- 4,
- PR_RADIO_BUTTON_VALUE,
- RADIO_BUTTON_4_RETURN_VALUE
- };
- /*
- * This is the page for the directory details.
- */
- DTCTL rgdtctlDirGeneral[] =
- {
- /*
- * directory general propery page
- * This names the pane for this page.
- * Although not currently not required in
- * this version, we expect to require it by
- * the time MAPI 1.0 ships.
- */
- {DTCT_PAGE, 0, NULL, 0, NULL, 0,
- &dtblpage},
- /* controls and edit control containing sab file name */
- {DTCT_LABEL, 0, NULL, 0, NULL, IDC_STATIC_CONTROL,
- &dtbllabel},
- {DTCT_LABEL, 0, NULL, 0, NULL, IDC_STATIC_CONTROL,
- &dtbllabel},
- {DTCT_EDIT, 0, (LPBYTE) ¬ifdata, sizeof(NOTIFDATA),
- szNoFilter, IDC_DIR_SAB_FILE_NAME, &editDirFileName},
- /* control and push button for changing sab file */
- {DTCT_LABEL, 0, NULL, 0, NULL, IDC_STATIC_CONTROL,
- &dtbllabel},
- {DTCT_BUTTON, 0, NULL, 0, NULL, IDC_DIR_CHANGE,
- &buttonDirChange},
- /* radio button group box and radio buttons */
- {DTCT_GROUPBOX, 0, NULL, 0, NULL, IDC_STATIC_CONTROL,
- &dtblgroupbox},
- {DTCT_RADIOBUTTON, DT_EDITABLE, NULL, 0, NULL, IDC_DIR_RADIO_1,
- &radiobuttonDir1},
- {DTCT_RADIOBUTTON, DT_EDITABLE, NULL, 0, NULL, IDC_DIR_RADIO_2,
- &radiobuttonDir2},
- {DTCT_RADIOBUTTON, DT_EDITABLE, NULL, 0, NULL, IDC_DIR_RADIO_3,
- &radiobuttonDir3},
- {DTCT_RADIOBUTTON, DT_EDITABLE, NULL, 0, NULL, IDC_DIR_RADIO_4,
- &radiobuttonDir4},
- };
- /*
- * Display table pages for Directory Details
- */
- DTPAGE rgdtpageDir[] =
- {
- {
- sizeof(rgdtctlDirGeneral) / sizeof(DTCTL),
- (LPTSTR) MAKEINTRESOURCE(DirGeneralPage),
- "",
- rgdtctlDirGeneral
- }
- };
- /*
- * ABCont vtbl is filled in here.
- */
- ABC_Vtbl vtblABC =
- {
- (ABC_QueryInterface_METHOD *) ROOT_QueryInterface,
- (ABC_AddRef_METHOD *) ROOT_AddRef,
- ABC_Release,
- (ABC_GetLastError_METHOD *) ROOT_GetLastError,
- ABC_SaveChanges,
- (ABC_GetProps_METHOD *) WRAP_GetProps,
- (ABC_GetPropList_METHOD *) WRAP_GetPropList,
- ABC_OpenProperty,
- (ABC_SetProps_METHOD *) WRAP_SetProps,
- (ABC_DeleteProps_METHOD *) WRAP_DeleteProps,
- (ABC_CopyTo_METHOD *) WRAP_CopyTo,
- (ABC_CopyProps_METHOD *) WRAP_CopyProps,
- (ABC_GetNamesFromIDs_METHOD *) WRAP_GetNamesFromIDs,
- (ABC_GetIDsFromNames_METHOD *) WRAP_GetIDsFromNames,
- ABC_GetContentsTable,
- ABC_GetHierarchyTable,
- (ABC_OpenEntry_METHOD *) ROOT_OpenEntry,
- (ABC_SetSearchCriteria_METHOD *) ROOT_SetSearchCriteria,
- (ABC_GetSearchCriteria_METHOD *) ROOT_GetSearchCriteria,
- (ABC_CreateEntry_METHOD *) ROOT_CreateEntry,
- (ABC_CopyEntries_METHOD *) ROOT_CopyEntries,
- (ABC_DeleteEntries_METHOD *) ROOT_DeleteEntries,
- (ABC_ResolveNames_METHOD *) ROOT_ResolveNames
- };
- /*
- * Private functions
- */
- HRESULT HrNewABCButton( LPABCNT lpABC,
- ULONG ulInterfaceOptions,
- ULONG ulFlags,
- LPMAPICONTROL FAR * lppMAPICont);
- //HRESULT HrGetSearchDialog(LPABCNT lpABC, LPMAPITABLE * lppSearchTable);
- HRESULT HrGetDetailsDialog(LPABCNT lpABC, LPMAPITABLE * lppDetailsTable);
- /*
- - NewSampDirectory
- -
- * Creates a Directory container object.
- *
- *
- */
- /*
- * properties of which I want to track whether or not they've
- * been changed.
- */
- enum { ivalWatchPR_SAB_FILE_TEMP = 0,
- cvalWatchMax };
- SizedSPropTagArray(cvalWatchMax, tagaPropsToWatch) =
- {
- cvalWatchMax,
- {
- PR_SAB_FILE_TEMP
- }
- };
- /*
- * Properties that are initially set on this object
- */
- enum { ivalabcPR_DISPLAY_TYPE = 0,
- ivalabcPR_OBJECT_TYPE,
- ivalabcPR_ENTRYID,
- ivalabcPR_RECORD_KEY,
- ivalabcPR_SEARCH_KEY,
- ivalabcPR_DISPLAY_NAME_A,
- ivalabcPR_CONTAINER_FLAGS,
- ivalabcPR_SAB_FILE,
- ivalabcPR_SAB_FILE_TEMP,
- ivalabcPR_RADIO_BUTTON_VALUE,
- cvalabcMax };
- static SizedSPropTagArray( cvalabcMax, tagaABCAccess) =
- {
- cvalabcMax,
- { PR_DISPLAY_TYPE,
- PR_OBJECT_TYPE,
- PR_ENTRYID,
- PR_RECORD_KEY,
- PR_SEARCH_KEY,
- PR_DISPLAY_NAME_A,
- PR_CONTAINER_FLAGS,
- PR_SAB_FILE,
- PR_SAB_FILE_TEMP,
- PR_RADIO_BUTTON_VALUE
- }
- };
- static ULONG rgulABCAccess[cvalabcMax] =
- {
- IPROP_READONLY | IPROP_CLEAN, /* PR_DISPLAY_TYPE */
- IPROP_READONLY | IPROP_CLEAN, /* PR_OBJECT_TYPE */
- IPROP_READONLY | IPROP_CLEAN, /* PR_ENTRYID */
- IPROP_READONLY | IPROP_CLEAN, /* PR_RECORD_KEY */
- IPROP_READONLY | IPROP_CLEAN, /* PR_SEARCH_KEY */
- IPROP_READONLY | IPROP_CLEAN, /* PR_DISPLAY_NAME_A */
- IPROP_READONLY | IPROP_CLEAN, /* PR_CONTAINER_FLAGS */
- IPROP_READWRITE | IPROP_CLEAN, /* PR_SAB_FILE */
- IPROP_READWRITE | IPROP_CLEAN, /* PR_SAB_FILE_TEMP */
- IPROP_READWRITE | IPROP_CLEAN /* PR_RADIO_BUTTON_VALUE */
- };
- HRESULT
- HrNewSampDirectory( LPABCONT * lppABC,
- ULONG * lpulObjType,
- LPABLOGON lpABLogon,
- LPCIID lpInterface,
- HINSTANCE hLibrary,
- LPALLOCATEBUFFER lpAllocBuff,
- LPALLOCATEMORE lpAllocMore,
- LPFREEBUFFER lpFreeBuff,
- LPMALLOC lpMalloc )
- {
- HRESULT hResult = hrSuccess;
- LPABCNT lpABC = NULL;
- SCODE sc;
- LPPROPDATA lpPropData = NULL;
- SPropValue spv[cvalabcMax];
- char szBuf[MAX_PATH];
- MAPIUID * lpMuidLogon;
- LPSTR lpszFileName;
- DIR_ENTRYID eidRoot = { {0, 0, 0, 0},
- MUIDABSAMPLE,
- SAMP_VERSION,
- SAMP_DIRECTORY };
- /* Do I support this interface?? */
- if (lpInterface)
- {
- if (memcmp(lpInterface, &IID_IABContainer, sizeof(IID)) &&
- memcmp(lpInterface, &IID_IMAPIContainer, sizeof(IID)) &&
- memcmp(lpInterface, &IID_IMAPIProp, sizeof(IID)) &&
- memcmp(lpInterface, &IID_IUnknown, sizeof(IID)))
- {
- DebugTraceSc(HrNewSampDirectory, MAPI_E_INTERFACE_NOT_SUPPORTED);
- return ResultFromScode(MAPI_E_INTERFACE_NOT_SUPPORTED);
- }
- }
- /*
- * Allocate space for the directory container structure
- */
- sc = lpAllocBuff( sizeof(ABCNT), (LPVOID *) &lpABC );
- if (FAILED(sc))
- {
- hResult = ResultFromScode(sc);
- goto err;
- }
- lpABC->lpVtbl = &vtblABC;
- lpABC->lcInit = 1;
- lpABC->hResult = hrSuccess;
- lpABC->idsLastError = 0;
- lpABC->hLibrary = hLibrary;
- lpABC->lpAllocBuff = lpAllocBuff;
- lpABC->lpAllocMore = lpAllocMore;
- lpABC->lpFreeBuff = lpFreeBuff;
- lpABC->lpMalloc = lpMalloc;
- lpABC->lpABLogon = lpABLogon;
- lpABC->lpTDatDetails = NULL;
- /*
- * Create property storage object
- */
- sc = CreateIProp((LPIID) &IID_IMAPIPropData,
- lpAllocBuff,
- lpAllocMore,
- lpFreeBuff,
- lpMalloc,
- &lpPropData);
- if (FAILED(sc))
- {
- hResult = ResultFromScode(sc);
- goto err;
- }
- /*
- * initialize the muid in the entry id
- */
- lpMuidLogon = LpMuidFromLogon(lpABLogon);
- eidRoot.muidID = *lpMuidLogon;
- /*
- * Set up initial set of properties associated with this
- * container.
- */
- spv[ivalabcPR_DISPLAY_TYPE].ulPropTag = PR_DISPLAY_TYPE;
- spv[ivalabcPR_DISPLAY_TYPE].Value.l = DT_NOT_SPECIFIC;
- spv[ivalabcPR_OBJECT_TYPE].ulPropTag = PR_OBJECT_TYPE;
- spv[ivalabcPR_OBJECT_TYPE].Value.l = MAPI_ABCONT;
- spv[ivalabcPR_ENTRYID].ulPropTag = PR_ENTRYID;
- spv[ivalabcPR_ENTRYID].Value.bin.cb = sizeof(DIR_ENTRYID);
- spv[ivalabcPR_ENTRYID].Value.bin.lpb = (LPBYTE) &eidRoot;
- spv[ivalabcPR_RECORD_KEY].ulPropTag = PR_RECORD_KEY;
- spv[ivalabcPR_RECORD_KEY].Value.bin.cb = sizeof(DIR_ENTRYID);
- spv[ivalabcPR_RECORD_KEY].Value.bin.lpb = (LPBYTE) &eidRoot;
- spv[ivalabcPR_SEARCH_KEY].ulPropTag = PR_SEARCH_KEY;
- spv[ivalabcPR_SEARCH_KEY].Value.bin.cb = sizeof(DIR_ENTRYID);
- spv[ivalabcPR_SEARCH_KEY].Value.bin.lpb = (LPBYTE) &eidRoot;
- spv[ivalabcPR_DISPLAY_NAME_A].ulPropTag = PR_DISPLAY_NAME_A;
- GenerateContainerDN(lpABLogon, szBuf);
- spv[ivalabcPR_DISPLAY_NAME_A].Value.lpszA = szBuf;
- spv[ivalabcPR_CONTAINER_FLAGS].ulPropTag = PR_CONTAINER_FLAGS;
- spv[ivalabcPR_CONTAINER_FLAGS].Value.l = AB_RECIPIENTS;
- /*
- * Get the current .SAB file name from our logon object
- */
- hResult = HrLpszGetCurrentFileName(lpABLogon, &lpszFileName);
- if (HR_FAILED(hResult))
- {
- goto err;
- }
- spv[ivalabcPR_SAB_FILE].ulPropTag = PR_SAB_FILE;
- spv[ivalabcPR_SAB_FILE].Value.lpszA = lpszFileName;
- spv[ivalabcPR_SAB_FILE_TEMP].ulPropTag = PR_SAB_FILE_TEMP;
- spv[ivalabcPR_SAB_FILE_TEMP].Value.lpszA = lpszFileName;
- spv[ivalabcPR_RADIO_BUTTON_VALUE].ulPropTag = PR_RADIO_BUTTON_VALUE;
- spv[ivalabcPR_RADIO_BUTTON_VALUE].Value.l = RADIO_BUTTON_1_RETURN_VALUE;
- /*
- * Set the default properties
- */
- hResult = lpPropData->lpVtbl->SetProps(lpPropData,
- cvalabcMax,
- spv,
- NULL);
- /*
- * No longer need this buffer
- */
- lpFreeBuff(lpszFileName);
- if (HR_FAILED(hResult))
- {
- goto err;
- }
- /*
- * We mark all properties as being CLEAN initially. Only PR_SAB_FILE,
- * PR_SAB_FILE_TEMP, and PR_RADIO_BUTTON_VALUE are marked as READWRITE
- * (Readable/Writable by the client) the others are marked as READONLY
- * so that the client may not alter them.
- *
- * Notice that the ABC_SaveChanges code checks the IPROP_DIRTY bit
- * on PR_SAB_FILE_TEMP to see if the client altered it!
- */
- (void) lpPropData->lpVtbl->HrSetPropAccess(lpPropData,
- (LPSPropTagArray) &tagaABCAccess,
- rgulABCAccess);
- InitializeCriticalSection(&lpABC->cs);
- /* We must AddRef the lpABLogon object since we will be using it
- */
- lpABLogon->lpVtbl->AddRef(lpABLogon);
- lpABC->lpPropData = (LPMAPIPROP) lpPropData;
- *lppABC = (LPABCONT) lpABC;
- *lpulObjType = MAPI_ABCONT;
- out:
- DebugTraceResult(HrNewSampDirectory, hResult);
- return hResult;
- err:
- /*
- * free the ABContainer object
- */
- lpFreeBuff( lpABC );
- /*
- * free the property storage object
- */
- if (lpPropData)
- lpPropData->lpVtbl->Release(lpPropData);
- goto out;
- }
- /*
- - ABC_Release
- -
- * Decrement lcInit.
- * When lcInit == 0, free up the lpABC structure
- *
- */
- STDMETHODIMP_(ULONG)
- ABC_Release(LPABCNT lpABC)
- {
- long lcInit;
- /*
- * Check to see if it has a jump table
- */
- ABC_ValidateObject(Release, lpABC);
- Validate_IUnknown_Release(lpABC);
- EnterCriticalSection(&lpABC->cs);
- lcInit = --lpABC->lcInit;
- LeaveCriticalSection(&lpABC->cs);
- if (lcInit == 0)
- {
- /*
- * Get rid of the lpPropData
- */
- if (lpABC->lpPropData)
- lpABC->lpPropData->lpVtbl->Release(lpABC->lpPropData);
- /*
- * Get rid of the details table
- */
- if (lpABC->lpTDatDetails)
- lpABC->lpTDatDetails->lpVtbl->Release(lpABC->lpTDatDetails);
- /*
- * Release our reference to the ABLogon object.
- */
- if (lpABC->lpABLogon)
- {
- lpABC->lpABLogon->lpVtbl->Release(lpABC->lpABLogon);
- lpABC->lpABLogon = NULL;
- }
- /*
- * Destroy the critical section for this object
- */
- DeleteCriticalSection(&lpABC->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.
- */
- lpABC->lpVtbl = NULL;
- /*
- * Need to free the object
- */
- lpABC->lpFreeBuff(lpABC);
- return 0;
- }
- return lpABC->lcInit;
- }
- /*
- - ABC_SaveChanges
- -
- * This is used to save changes associated with the search dialog
- * in order to get the advanced search restriction and to save changes
- * associated with the container details dialog.
- *
- */
- SPropTagArray tagaSAB_FILE =
- {
- 1,
- {
- PR_SAB_FILE_TEMP
- }
- };
- STDMETHODIMP
- ABC_SaveChanges(LPABCNT lpABC, ULONG ulFlags)
- {
- HRESULT hResult = hrSuccess;
- ULONG ulCount;
- LPSPropValue lpspv = NULL;
- ULONG FAR *rgulAccess = NULL;
- ULONG ulAccess = IPROP_CLEAN | IPROP_READWRITE;
- LPSPropTagArray ptagaSAB_FILE = (LPSPropTagArray) &tagaSAB_FILE;
- LPPROPDATA lpPropData = (LPPROPDATA) lpABC->lpPropData;
- ABC_ValidateObject(SaveChanges, lpABC);
- Validate_IMAPIProp_SaveChanges(lpABC, ulFlags);
- EnterCriticalSection(&lpABC->cs);
- /*
- * Check to see if anyone has dirtied the PR_SAB_FILE_TEMP
- */
- (void) lpPropData->lpVtbl->HrGetPropAccess(lpPropData,
- &ptagaSAB_FILE,
- &rgulAccess);
- if (!rgulAccess || !((*rgulAccess) & IPROP_DIRTY))
- {
- /*
- * No, nothing to update then head on out
- */
- goto ret;
- }
- /*
- * Set back to being clean
- */
- (void )lpPropData->lpVtbl->HrSetPropAccess(lpPropData,
- ptagaSAB_FILE,
- &ulAccess);
- /*
- * Get the temporary sab file name
- */
- hResult = lpPropData->lpVtbl->GetProps(
- lpPropData,
- &tagaSAB_FILE,
- 0, /* ansi */
- &ulCount,
- &lpspv);
- if (HR_FAILED(hResult))
- {
- goto ret;
- }
- if (lpspv->ulPropTag != PR_SAB_FILE_TEMP)
- {
- /*
- * There's no reason this property shouldn't be there.
- */
- hResult = ResultFromScode(MAPI_E_CORRUPT_DATA);
- goto ret;
- }
- /*
- * Save the new name back into the object as PR_SAB_FILE
- */
- lpspv->ulPropTag = PR_SAB_FILE;
- hResult = lpPropData->lpVtbl->SetProps(
- lpPropData,
- 1,
- lpspv, NULL);
- if (HR_FAILED(hResult))
- {
- /*
- * Do nothing... So I couldn't save it away this time...
- */
- hResult = hrSuccess;
- goto ret;
- }
- /*
- * Update every other object that needs this new information
- */
- hResult = HrReplaceCurrentFileName(lpABC->lpABLogon, lpspv->Value.lpszA);
- ret:
- LeaveCriticalSection(&lpABC->cs);
- lpABC->lpFreeBuff(lpspv);
- lpABC->lpFreeBuff(rgulAccess);
- DebugTraceResult(ABC_SaveChanges, hResult);
- return hResult;
- }
- /*************************************************************************
- *
- - ABC_OpenProperty
- -
- *
- * This method allows the opening of the following object:
- *
- * PR_BUTTON_PRESS :- Gets the MAPIControl object associated
- * with the button on this container's details.
- * PR_DETAILS_TABLE :- Gets the display table associated with
- * the details for this container.
- * PR_SEARCH :- Gets the advanced search object associated with
- * this container.
- * PR_CONTAINER_CONTENTS :- Same as GetContentsTable()
- * PR_CONTAINER_HIERARCHY :- Same as GetHierarchyTable()
- *
- *
- */
- STDMETHODIMP
- ABC_OpenProperty(LPABCNT lpABC,
- ULONG ulPropTag,
- LPCIID lpiid,
- ULONG ulInterfaceOptions,
- ULONG ulFlags,
- LPUNKNOWN * lppUnk)
- {
- HRESULT hResult;
- ABC_ValidateObject(OpenProperty, lpABC);
- Validate_IMAPIProp_OpenProperty(lpABC, ulPropTag, lpiid, ulInterfaceOptions,
- ulFlags, lppUnk);
- /*
- * Check for flags we can't support
- */
- if (ulFlags & (MAPI_CREATE|MAPI_MODIFY))
- {
- hResult = ResultFromScode(E_ACCESSDENIED);
- goto out;
- }
- if (ulInterfaceOptions & ~MAPI_UNICODE)
- {
- /*
- * Only UNICODE flag should be set for any of the objects that might
- * be returned from this object.
- */
- hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
- goto out;
- }
- if ( ulInterfaceOptions & MAPI_UNICODE )
- {
- hResult = ResultFromScode(MAPI_E_BAD_CHARWIDTH);
- DebugTraceArg( ABC_OpenProperty, "bad character width" );
- goto out;
- }
- /*
- * Details for this directory entry
- */
- if ((ulPropTag == PR_DETAILS_TABLE) ||
- (ulPropTag == PR_BUTTON_PRESS) ||
- (ulPropTag == PR_CONTAINER_CONTENTS) ||
- (ulPropTag == PR_CONTAINER_HIERARCHY) ||
- (ulPropTag == PR_SEARCH))
- {
- /*
- * Check to see if they're expecting a table interface for all props but
- * PR_BUTTON_PRESS.
- */
- if ((ulPropTag != PR_BUTTON_PRESS) &&
- (ulPropTag != PR_SEARCH) &&
- memcmp(lpiid, &IID_IMAPITable, sizeof(IID)))
- {
- hResult = ResultFromScode(MAPI_E_INTERFACE_NOT_SUPPORTED);
- goto out;
- }
- switch (ulPropTag)
- {
- case PR_BUTTON_PRESS:
- {
- /*
- * Check to see if they're expecting a generic control interface
- */
- if (memcmp(lpiid, &IID_IMAPIControl, sizeof(IID)))
- {
- hResult = ResultFromScode(MAPI_E_INTERFACE_NOT_SUPPORTED);
- goto out;
- }
- hResult = HrNewABCButton(lpABC,
- ulInterfaceOptions,
- ulFlags,
- (LPMAPICONTROL FAR *) lppUnk);
- break;
- }
- case PR_DETAILS_TABLE:
- {
- hResult = HrGetDetailsDialog(lpABC, (LPMAPITABLE *) lppUnk);
- break;
- }
- case PR_SEARCH:
- {
- /*
- * Check to see if they're expecting a generic control interface
- */
- if (memcmp(lpiid, &IID_IMAPIContainer, sizeof(IID)))
- {
- hResult = ResultFromScode(MAPI_E_INTERFACE_NOT_SUPPORTED);
- goto out;
- }
- hResult = HrNewSearch((LPMAPICONTAINER *) lppUnk,
- lpABC->lpABLogon,
- lpiid,
- lpABC->hLibrary,
- lpABC->lpAllocBuff,
- lpABC->lpAllocMore,
- lpABC->lpFreeBuff,
- lpABC->lpMalloc);
- break;
- }
- case PR_CONTAINER_CONTENTS:
- {
- hResult = ABC_GetContentsTable(lpABC, 0, (LPMAPITABLE *) lppUnk);
- break;
- }
- case PR_CONTAINER_HIERARCHY:
- {
- hResult = ABC_GetHierarchyTable(lpABC, 0, (LPMAPITABLE *) lppUnk);
- break;
- }
- default:
- Assert(FALSE);
- break;
- }
- } else
- {
- hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
- }
- out:
- DebugTraceResult(ABC_OpenProperty, hResult);
- return hResult;
- }
- /*************************************************************************
- *
- - ABC_GetContentsTable
- -
- *
- * Retrieves the IMAPITable that has the contents of this container.
- */
- STDMETHODIMP
- ABC_GetContentsTable(LPABCNT lpABC, ULONG ulFlags,
- LPMAPITABLE * lppTable)
- {
- HRESULT hResult;
- /*
- * Validate parameters
- */
- ABC_ValidateObject(GetContentsTable, lpABC);
- Validate_IMAPIContainer_GetContentsTable(lpABC, ulFlags, lppTable);
- /*
- * Certain flags are not supported
- */
- if (ulFlags & (MAPI_ASSOCIATED))
- {
- hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
- goto out;
- }
- if ( ulFlags & MAPI_UNICODE )
- {
- DebugTraceArg( ABC_GetContentsTable, "Bad character width" );
- hResult = ResultFromScode( MAPI_E_BAD_CHARWIDTH );
- goto out;
- }
- /*
- * Create the new Contents table
- */
- hResult = HrNewIVTAbc(lppTable,
- lpABC->lpABLogon,
- (LPABCONT) lpABC,
- lpABC->hLibrary,
- lpABC->lpAllocBuff,
- lpABC->lpAllocMore,
- lpABC->lpFreeBuff,
- lpABC->lpMalloc);
- out:
- DebugTraceResult(ABC_GetContentsTable, hResult);
- return hResult;
- }
- /*
- - ABC_GetHierarchyTable
- -
- *
- * There is no hierarchy table associated with this object.
- *
- */
- STDMETHODIMP
- ABC_GetHierarchyTable(LPABCNT lpABC, ULONG ulFlags,
- LPMAPITABLE * lppTable)
- {
- HRESULT hResult;
- /*
- * Check to see if it has a lpVtbl object member
- */
- if (IsBadReadPtr(lpABC, offsetof(ABCNT, lpVtbl)+sizeof(ABC_Vtbl *)))
- {
- /*
- * Not large enough
- */
- hResult = MakeResult(E_INVALIDARG);
- DebugTraceResult(ABC_HierarchyTable, hResult);
- return hResult;
- }
- /*
- * Check to see that the Vtbl is large enough to include this method
- */
- if (IsBadReadPtr(lpABC->lpVtbl,
- offsetof(ABC_Vtbl, GetHierarchyTable)+sizeof(ABC_GetHierarchyTable_METHOD *)))
- {
- /*
- * Jump table not derived from IUnknown
- */
- hResult = MakeResult(E_INVALIDARG);
- DebugTraceResult(ABC_HierarchyTable, hResult);
- return hResult;
- }
- /*
- * Check to see if the method is the same
- */
- if (ABC_GetHierarchyTable != lpABC->lpVtbl->GetHierarchyTable)
- {
- /*
- * Wrong object - the object passed doesn't have this
- * method.
- */
- hResult = ResultFromScode(E_INVALIDARG);
- DebugTraceResult(ABC_HierarchyTable, hResult);
- return hResult;
- }
- Validate_IMAPIContainer_GetHierarchyTable(lpABC, ulFlags, lppTable);
- /*
- * We don't support this method on this object
- */
- hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
- DebugTraceResult(ABC_GetHierarchyTable, hResult);
- return hResult;
- }
- /*
- - HrGetDetailsDialog
- -
- * Builds a display table for this directory.
- */
- HRESULT
- HrGetDetailsDialog(LPABCNT lpABC, LPMAPITABLE * lppDetailsTable)
- {
- HRESULT hResult;
- if (!lpABC->lpTDatDetails)
- {
- /* Create a display table */
- hResult = BuildDisplayTable(
- lpABC->lpAllocBuff,
- lpABC->lpAllocMore,
- lpABC->lpFreeBuff,
- lpABC->lpMalloc,
- lpABC->hLibrary,
- sizeof(rgdtpageDir) / sizeof(DTPAGE),
- rgdtpageDir,
- 0,
- lppDetailsTable,
- &lpABC->lpTDatDetails);
- } else
- {
- hResult = lpABC->lpTDatDetails->lpVtbl->HrGetView(
- lpABC->lpTDatDetails,
- NULL,
- NULL,
- 0,
- lppDetailsTable);
- }
- DebugTraceResult(HrGetDetailsDialog, hResult);
- return hResult;
- }
- /*
- * Button object for this directory's details dialog
- */
- /*
- * Declaration of IMAPIControl object implementation
- */
- #undef INTERFACE
- #define INTERFACE struct _ABCBUTT
- #undef MAPIMETHOD_
- #define MAPIMETHOD_(type,method) MAPIMETHOD_DECLARE(type,method,ABCBUTT_)
- MAPI_IUNKNOWN_METHODS(IMPL)
- MAPI_IMAPICONTROL_METHODS(IMPL)
- #undef MAPIMETHOD_
- #define MAPIMETHOD_(type,method) MAPIMETHOD_TYPEDEF(type,method,ABCBUTT_)
- MAPI_IUNKNOWN_METHODS(IMPL)
- MAPI_IMAPICONTROL_METHODS(IMPL)
- #undef MAPIMETHOD_
- #define MAPIMETHOD_(type,method) STDMETHOD_(type,method)
- DECLARE_MAPI_INTERFACE(ABCBUTT_)
- {
- MAPI_IUNKNOWN_METHODS(IMPL)
- MAPI_IMAPICONTROL_METHODS(IMPL)
- };
- /*
- *
- * Declaration of structure behind button
- *
- */
- typedef struct _ABCBUTT
- {
- ABCBUTT_Vtbl FAR * lpVtbl;
- SAB_IUnknown;
- /*
- * My parent container object
- */
- LPABCNT lpABC;
- } ABCBUTT, *LPABCBUTT;
- /*
- * Fill in the vtbl
- */
- ABCBUTT_Vtbl vtblABCBUTT =
- {
- ABCBUTT_QueryInterface,
- (ABCBUTT_AddRef_METHOD *) ROOT_AddRef,
- ABCBUTT_Release,
- (ABCBUTT_GetLastError_METHOD *) ROOT_GetLastError,
- ABCBUTT_Activate,
- ABCBUTT_GetState
- };
- #define ABCBUTT_ValidateObject(Method, pThis)
- {
- HRESULT hResult;
- if (IsBadReadPtr(pThis, sizeof(ABCBUTT)))
- {
- hResult = ResultFromScode(E_INVALIDARG);
- DebugTraceResult(ABCBUTT##_##Method, hResult);
- return hResult;
- }
- if (pThis->lpVtbl != &vtblABCBUTT)
- {
- hResult = ResultFromScode(E_INVALIDARG);
- DebugTraceResult(ABCBUTT##_##Method, hResult);
- return hResult;
- }
- }
- /*
- - HrNewABCButton
- -
- * Creates the MAPIControl object that is the code behind the button
- * on the Sample AB's directory details.
- */
- HRESULT
- HrNewABCButton( LPABCNT lpABC,
- ULONG ulInterfaceOptions,
- ULONG ulFlags,
- LPMAPICONTROL FAR * lppMAPICont)
- {
- LPABCBUTT lpABCButt = NULL;
- SCODE scode;
- scode = lpABC->lpAllocBuff(sizeof(ABCBUTT),(LPVOID *) &lpABCButt);
- if (FAILED(scode))
- {
- DebugTraceSc(HrNewABCButton, scode);
- return ResultFromScode(scode);
- }
- lpABCButt->lpVtbl = &vtblABCBUTT;
- lpABCButt->lcInit = 1;
- lpABCButt->hResult = hrSuccess;
- lpABCButt->idsLastError = 0;
- lpABCButt->hLibrary = lpABC->hLibrary;
- lpABCButt->lpAllocBuff = lpABC->lpAllocBuff;
- lpABCButt->lpAllocMore = lpABC->lpAllocMore;
- lpABCButt->lpFreeBuff = lpABC->lpFreeBuff;
- lpABCButt->lpMalloc = lpABC->lpMalloc;
- lpABCButt->lpABC = lpABC;
- /*
- * I need my parent object to stay around while this object
- * does so that I can get to it in my Activate() method.
- * To do this just AddRef() it.
- */
- lpABC->lpVtbl->AddRef(lpABC);
- InitializeCriticalSection(&lpABCButt->cs);
- *lppMAPICont = (LPMAPICONTROL) lpABCButt;
- return hrSuccess;
- }
- /*************************************************************************
- *
- *
- - ABCBUTT_QueryInterface
- -
- *
- * Allows QI'ing to IUnknown and IMAPIControl.
- *
- */
- STDMETHODIMP
- ABCBUTT_QueryInterface( LPABCBUTT lpABCButt,
- REFIID lpiid,
- LPVOID FAR * lppNewObj)
- {
- HRESULT hResult = hrSuccess;
- /* Minimally validate the lpABCButt parameter */
- ABCBUTT_ValidateObject(QueryInterface, lpABCButt);
- Validate_IUnknown_QueryInterface(lpABCButt, lpiid, lppNewObj);
- /* See if the requested interface is one of ours */
- if (memcmp(lpiid, &IID_IUnknown, sizeof(IID)) &&
- memcmp(lpiid, &IID_IMAPIControl, sizeof(IID)))
- {
- *lppNewObj = NULL; /* OLE requires zeroing [out] parameter */
- hResult = ResultFromScode(E_NOINTERFACE);
- goto out;
- }
- /* We'll do this one. Bump the usage count and return a new pointer. */
- EnterCriticalSection(&lpABCButt->cs);
- ++lpABCButt->lcInit;
- LeaveCriticalSection(&lpABCButt->cs);
- *lppNewObj = lpABCButt;
- out:
- DebugTraceResult(ABCBUTT_QueryInterface, hResult);
- return hResult;
- }
- /*
- - ABCBUTT_Release
- -
- * Releases and cleans up this object
- */
- STDMETHODIMP_(ULONG)
- ABCBUTT_Release(LPABCBUTT lpABCButt)
- {
- long lcInit;
- /* Minimally validate the lpABCButt parameter */
- if (IsBadReadPtr(lpABCButt, sizeof(ABCBUTT)))
- {
- return 1;
- }
- if (lpABCButt->lpVtbl != &vtblABCBUTT)
- {
- return 1;
- }
- Validate_IUnknown_Release(lpABCButt);
- EnterCriticalSection(&lpABCButt->cs);
- lcInit = --lpABCButt->lcInit;
- LeaveCriticalSection(&lpABCButt->cs);
- if (lcInit == 0)
- {
- /*
- * Release my parent
- */
- lpABCButt->lpABC->lpVtbl->Release(lpABCButt->lpABC);
- /*
- * Destroy the critical section for this object
- */
- DeleteCriticalSection(&lpABCButt->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.
- */
- lpABCButt->lpVtbl = NULL;
- /*
- * Free the object
- */
- lpABCButt->lpFreeBuff(lpABCButt);
- return 0;
- }
- return lcInit;
- }
- /*
- - ABCBUTT_Activate
- -
- *
- * Activates this control. In this case, it brings up the common file browsing
- * dialog and allows the user to pick a different .SAB file.
- *
- * Note that if all is successful it sends a display table notification. The UI
- * will respond to this by updating the particular control that was said to have
- * changed in the notification.
- */
- STDMETHODIMP
- ABCBUTT_Activate(LPABCBUTT lpABCButt, ULONG ulFlags,
- ULONG ulUIParam)
- {
- HRESULT hResult = hrSuccess;
- OPENFILENAME openfilename;
- char szFileName[MAX_PATH];
- char szDirName[MAX_PATH];
- SPropValue sProp;
- LPSPropValue lpspv = NULL;
- ULONG ulCount, ich;
- /* Minimally validate the lpABCButt parameter */
- ABCBUTT_ValidateObject(Activate, lpABCButt);
- Validate_IMAPIControl_Activate(lpABCButt, ulFlags, ulUIParam);
- if (ulFlags)
- {
- /*
- * No flags defined for this method
- */
- hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
- goto out;
- }
- /*
- * First, get the old SAB file name so that it shows up in the
- * choose file dialog
- */
- hResult = lpABCButt->lpABC->lpPropData->lpVtbl->GetProps(
- lpABCButt->lpABC->lpPropData,
- &tagaSAB_FILE,
- 0, /* ansi */
- &ulCount,
- &lpspv);
- if (HR_FAILED(hResult))
- {
- goto out;
- }
- if (lpspv->ulPropTag != PR_SAB_FILE_TEMP)
- {
- /*
- * Property wasn't there...
- */
- hResult = ResultFromScode(MAPI_E_CORRUPT_DATA);
- goto out;
- }
- lstrcpyA(szFileName, lpspv->Value.lpszA);
- szDirName[0] = ' ';
- /* get the path name */
- for (ich = lstrlenA(lpspv->Value.lpszA) - 1; ich > 0; ich--)
- {
- if (lpspv->Value.lpszA[ich] == '\')
- {
- lpspv->Value.lpszA[ich] = ' ';
- break;
- }
- else if (lpspv->Value.lpszA[ich] == ':')
- {
- lpspv->Value.lpszA[ich + 1] = ' ';
- break;
- }
- }
- lstrcpyA(szDirName, lpspv->Value.lpszA);
- /*
- * Get the user to select one
- */
- 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 = szDirName;
- openfilename.lpstrTitle = "Sample Address Book";
- openfilename.Flags = OFN_FILEMUSTEXIST |
- OFN_HIDEREADONLY |
- OFN_NOCHANGEDIR;
- 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))
- {
- hResult = hrSuccess;
- goto out;
- }
- /*
- * Save SAB FileName into the container object
- */
- sProp.ulPropTag = PR_SAB_FILE_TEMP;
- sProp.Value.lpszA = szFileName;
- hResult = lpABCButt->lpABC->lpPropData->lpVtbl->SetProps(
- lpABCButt->lpABC->lpPropData,
- 1,
- &sProp,
- NULL);
- if (HR_FAILED(hResult))
- {
- goto out;
- }
- /*
- * Notify the details table so that everyone with a view open
- * will get notified
- */
- if (lpABCButt->lpABC->lpTDatDetails)
- {
- sProp.ulPropTag = PR_CONTROL_ID;
- sProp.Value.bin.lpb = (LPBYTE) ¬ifdata;
- sProp.Value.bin.cb = sizeof(NOTIFDATA);
- hResult = lpABCButt->lpABC->lpTDatDetails->lpVtbl->HrNotify(
- lpABCButt->lpABC->lpTDatDetails,
- 0,
- 1,
- &sProp);
- }
- out:
- lpABCButt->lpFreeBuff(lpspv);
- DebugTraceResult(ABCBUTT_Activate, hResult);
- return hResult;
- }
- /*
- - ABCBUTT_GetState
- -
- * Says whether this control should appear enabled or not at this time.
- *
- */
- STDMETHODIMP
- ABCBUTT_GetState(LPABCBUTT lpABCButt, ULONG ulFlags,
- ULONG * lpulState)
- {
- HRESULT hResult = hrSuccess;
- /* Minimally validate the lpABCButt parameter */
- ABCBUTT_ValidateObject(GetStatus, lpABCButt);
- Validate_IMAPIControl_GetState(lpABCButt, ulFlags, lpulState);
- /*
- * Means that at this time this button should appear enabled.
- */
- *lpulState = MAPI_ENABLED;
- DebugTraceResult(ABCBUTT_GetState, hResult);
- return hResult;
- }