ABUSER.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:39k
源码类别:
Windows编程
开发平台:
Visual C++
- /***********************************************************************
- *
- * ABUSER.C
- *
- * Sample AB Mail User object
- * This file contains the code for implementing the Sample AB
- * Mail user.
- *
- * The mail user has a read-only interface. Hence a few of the methods
- * will always return E_ACCESSDENIED.
- *
- * Typically it would be in this module (particularly HrNewABUser) that
- * your provider would validate the existance of the entry associated
- * with a particular entryid. The Sample Address Book doesn't do this
- * because it doesn't need to.
- *
- * The following routines are implemented in this file:
- *
- * HrNewSampUser
- * ABU_QueryInterface
- * ABU_Release
- * ABU_OpenProperty
- * HrBuildListBoxTable
- * HrBuildDDListboxTable
- * HrBuildComboBoxTable
- *
- * Copyright 1992-1995 Microsoft Corporation. All Rights Reserved.
- *
- ***********************************************************************/
- #include "abp.h"
- #include "sampabp.rh"
- /*
- * Defined in ABP.C
- */
- #define MAX_ADDRTYPE 25
- #define MAX_EMAIL_ADDRESS MAX_PATH
- #define MAX_COMBO_EDIT 25
- #define MAX_LISTBOX_ROWS 25
- /* property tags used on details property sheet */
- #define PR_CHECKBOX_1_VALUE PROP_TAG(PT_BOOLEAN,0x6601)
- #define PR_CHECKBOX_2_VALUE PROP_TAG(PT_BOOLEAN,0x6602)
- #define PR_CHECKBOX_3_VALUE PROP_TAG(PT_BOOLEAN,0x6603)
- #define PR_LISTBOX_VALUE PROP_TAG(PT_LONG,0x6604)
- #define PR_COMBOBOX_VALUE PROP_TAG(PT_STRING8,0x6606)
- #define PR_DDLISTBOX_VALUE PROP_TAG(PT_LONG,0x6608)
- /* Display table control structures for the General and Options property sheets. */
- /* First Pane "General", this is the information specific about the first
- * edit control, which is used to display the display name of this user. */
- DTBLEDIT editUserDisplayName =
- {
- sizeof(DTBLEDIT),
- 0,
- MAX_DISPLAY_NAME,
- PR_DISPLAY_NAME_A
- };
- /*
- * "General" pane. This is the information about the email address type associated
- * with this entry
- */
- DTBLEDIT editUserEmailType =
- {
- sizeof(DTBLEDIT),
- 0,
- MAX_ADDRTYPE,
- PR_ADDRTYPE_A
- };
- /*
- * "General" pane. This is the information about the email address associated with
- * this entry.
- */
- DTBLEDIT editUserEmailAddress =
- {
- sizeof(DTBLEDIT),
- 0,
- MAX_EMAIL_ADDRESS,
- PR_EMAIL_ADDRESS_A
- };
- /*
- * This is the actual definition for the "General" pane. It lists all the controls
- * found on it.
- */
- DTCTL rgdtctlUserGeneral[] =
- {
- /*
- * general property page
- * MAPI UI will default this first pane to be named "General" in this release.
- * However, subsequent releases will not include this behaviour. Because of this
- * it is stongly suggested that your provider provide a DTCT_PAGE control for each
- * pane.
- */
- {DTCT_PAGE, 0, NULL, 0, NULL, 0,
- &dtblpage},
- /* display name control and edit control */
- {DTCT_LABEL, 0, NULL, 0, NULL, IDC_STATIC_CONTROL,
- &dtbllabel},
- {DTCT_EDIT, 0, NULL, 0, szNoFilter, IDC_USER_DISPLAY_NAME,
- &editUserDisplayName},
- /* inbox path control and edit control */
- {DTCT_LABEL, 0, NULL, 0, NULL, IDC_STATIC_CONTROL,
- &dtbllabel},
- {DTCT_EDIT, 0, NULL, 0, szNoFilter, IDC_USER_INBOX_PATH,
- &editUserEmailAddress},
- /* address type control and edit control */
- {DTCT_LABEL, 0, NULL, 0, NULL, IDC_STATIC_CONTROL,
- &dtbllabel},
- {DTCT_EDIT, 0, NULL, 0, szAddrTypeFilter, IDC_USER_EMAIL_TYPE,
- &editUserEmailType},
- };
- /* controls for the options property page */
- /*
- * "Options" property page. This is the information that allows the
- * UI to fill in the listbox control on this pane.
- */
- DTBLLBX listbox1 =
- {
- 0,
- PR_LISTBOX_VALUE,
- PR_LISTBOX_TABLE
- };
- /*
- * "Options" property page. The following three controls define a set of check boxes
- * that are found on this pane. Notice that the three prop tags in these structures
- * are different - compare them to the radio buttons found in ABCONT.C.
- */
- DTBLCHECKBOX checkbox1 =
- {
- sizeof(DTBLCHECKBOX),
- 0,
- PR_CHECKBOX_1_VALUE
- };
- DTBLCHECKBOX checkbox2 =
- {
- sizeof(DTBLCHECKBOX),
- 0,
- PR_CHECKBOX_2_VALUE
- };
- DTBLCHECKBOX checkbox3 =
- {
- sizeof(DTBLCHECKBOX),
- 0,
- PR_CHECKBOX_3_VALUE
- };
- /*
- * "Options" property page. This is the information required for
- * the UI to generate a drop down list box.
- */
- DTBLDDLBX ddlistbox1 =
- {
- sizeof(DTBLDDLBX),
- PR_DISPLAY_NAME_A,
- PR_DDLISTBOX_VALUE,
- PR_DDLISTBOX_TABLE
- };
- /*
- * "Options" property page. This is the information required for the
- * UI to generate a combo box control.
- */
- DTBLCOMBOBOX combobox1 =
- {
- sizeof(DTBLCOMBOBOX),
- 0,
- MAX_COMBO_EDIT,
- PR_COMBOBOX_VALUE,
- PR_COMBOBOX_TABLE
- };
- /*
- * This is the actual definition of the "Options" pane. This lists all the
- * controls found on that page.
- */
- DTCTL rgdtctlUserAdvanced[] =
- {
- /* options property page
- * This tells the UI what the tab for this pane should say.
- */
- {DTCT_PAGE, 0, NULL, 0, NULL, 0, &dtblpage},
- /* control and listbox */
- {DTCT_LABEL, 0, NULL, 0, NULL,
- IDC_STATIC_CONTROL, &dtbllabel},
- {DTCT_LBX, 0, NULL, 0, NULL,
- IDC_USER_LISTBOX, &listbox1},
- /* group box and radio buttons */
- {DTCT_GROUPBOX, 0, NULL, 0, NULL,
- IDC_STATIC_CONTROL, &dtblgroupbox},
- {DTCT_CHECKBOX, DT_EDITABLE, NULL, 0, NULL,
- IDC_USER_CHECKBOX_1, &checkbox1},
- {DTCT_CHECKBOX, DT_EDITABLE, NULL, 0, NULL,
- IDC_USER_CHECKBOX_2, &checkbox2},
- {DTCT_CHECKBOX, DT_EDITABLE, NULL, 0, NULL,
- IDC_USER_CHECKBOX_3, &checkbox3},
- /* control and drop down listbox */
- {DTCT_LABEL, 0, NULL, 0, NULL,
- IDC_STATIC_CONTROL, &dtbllabel},
- {DTCT_DDLBX, DT_EDITABLE, NULL, 0, NULL,
- IDC_USER_DDLISTBOX, &ddlistbox1},
- /* control and combobox */
- {DTCT_LABEL, 0, NULL, 0, NULL,
- IDC_STATIC_CONTROL, &dtbllabel},
- {DTCT_COMBOBOX, DT_EDITABLE, NULL, 0, szNoFilter,
- IDC_USER_COMBOBOX, &combobox1},
- };
- /* Display table pages */
- /*
- * This lists the order in which the panes will appear in the UI. The
- * UI is driven by a display table which is generated by a call to
- * BuildDisplayTable() which takes the following DTPAGE structure.
- */
- DTPAGE rgdtpage[] =
- {
- {
- sizeof(rgdtctlUserGeneral) / sizeof(DTCTL),
- (LPTSTR) MAKEINTRESOURCE(UserGeneralPage),
- "",
- rgdtctlUserGeneral
- },
- {
- sizeof(rgdtctlUserAdvanced) / sizeof(DTCTL),
- (LPTSTR) MAKEINTRESOURCE(UserAdvancedPage),
- "",
- rgdtctlUserAdvanced
- }
- };
- /*
- * Definition of the ABUSER object
- */
- typedef struct _ABUSER
- {
- const ABU_Vtbl FAR * lpVtbl;
- SAB_Wrapped;
- /*
- * Tables used in options property page
- */
- LPTABLEDATA lpTDatListBox;
- LPTABLEDATA lpTDatDDListBox;
- LPTABLEDATA lpTDatComboBox;
- } ABUSER, *LPABUSER;
- /*
- * ABUser vtbl filled in here
- */
- const ABU_Vtbl vtblABU =
- {
- ABU_QueryInterface,
- (ABU_AddRef_METHOD *) ROOT_AddRef,
- ABU_Release,
- (ABU_GetLastError_METHOD *) ROOT_GetLastError,
- (ABU_SaveChanges_METHOD *) WRAP_SaveChanges,
- (ABU_GetProps_METHOD *) WRAP_GetProps,
- (ABU_GetPropList_METHOD *) WRAP_GetPropList,
- ABU_OpenProperty,
- (ABU_SetProps_METHOD *) WRAP_SetProps,
- (ABU_DeleteProps_METHOD *) WRAP_DeleteProps,
- (ABU_CopyTo_METHOD *) WRAP_CopyTo,
- (ABU_CopyProps_METHOD *) WRAP_CopyProps,
- (ABU_GetNamesFromIDs_METHOD *) WRAP_GetNamesFromIDs,
- (ABU_GetIDsFromNames_METHOD *) WRAP_GetIDsFromNames,
- };
- HRESULT HrBuildListBoxTable(LPABUSER lpABUser);
- HRESULT HrBuildDDListBoxTable(LPABUSER lpABUser);
- HRESULT HrBuildComboBoxTable(LPABUSER lpABUser);
- enum { ivalusrPR_DISPLAY_TYPE = 0,
- ivalusrPR_OBJECT_TYPE,
- ivalusrPR_ENTRYID,
- ivalusrPR_RECORD_KEY,
- ivalusrPR_DISPLAY_NAME_A,
- ivalusrPR_TRANSMITABLE_DISPLAY_NAME_A,
- ivalusrPR_EMAIL_ADDRESS_A,
- ivalusrPR_ADDRTYPE_A,
- ivalusrPR_SEARCH_KEY,
- ivalusrPR_LISTBOX_VALUE,
- ivalusrPR_CHECKBOX_1_VALUE,
- ivalusrPR_CHECKBOX_2_VALUE,
- ivalusrPR_CHECKBOX_3_VALUE,
- ivalusrPR_DDLISTBOX_VALUE,
- ivalusrPR_COMBOBOX_VALUE,
- ivalusrPR_TEMPLATEID,
- cvalusrMax };
- static SizedSPropTagArray( cvalusrMax, tagaABUAccess) =
- {
- cvalusrMax,
- { PR_DISPLAY_TYPE,
- PR_OBJECT_TYPE,
- PR_ENTRYID,
- PR_RECORD_KEY,
- PR_DISPLAY_NAME_A,
- PR_TRANSMITABLE_DISPLAY_NAME_A,
- PR_EMAIL_ADDRESS_A,
- PR_ADDRTYPE_A,
- PR_SEARCH_KEY,
- PR_LISTBOX_VALUE,
- PR_CHECKBOX_1_VALUE,
- PR_CHECKBOX_2_VALUE,
- PR_CHECKBOX_3_VALUE,
- PR_DDLISTBOX_VALUE,
- PR_COMBOBOX_VALUE,
- PR_TEMPLATEID
- }
- };
- static ULONG rgulABUAccess[cvalusrMax] =
- {
- 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_DISPLAY_NAME_A */
- IPROP_READONLY | IPROP_CLEAN, /* PR_TRANSMITABLE_DISPLAY_NAME_A */
- IPROP_READONLY | IPROP_CLEAN, /* PR_EMAIL_ADDRESS_A */
- IPROP_READONLY | IPROP_CLEAN, /* PR_ADDRTYPE_A */
- IPROP_READONLY | IPROP_CLEAN, /* PR_SEARCH_KEY */
- IPROP_READWRITE | IPROP_CLEAN, /* PR_LISTBOX_VALUE */
- IPROP_READWRITE | IPROP_CLEAN, /* PR_CHECKBOX_1_VALUE */
- IPROP_READWRITE | IPROP_CLEAN, /* PR_CHECKBOX_2_VALUE */
- IPROP_READWRITE | IPROP_CLEAN, /* PR_CHECKBOX_3_VALUE */
- IPROP_READWRITE | IPROP_CLEAN, /* PR_DDLISTBOX_VALUE */
- IPROP_READWRITE | IPROP_CLEAN, /* PR_COMBOBOX_VALUE */
- IPROP_READONLY | IPROP_CLEAN /* PR_TEMPLATEID */
- };
- /*************************************************************************
- *
- - HrNewSampUser
- -
- * Creates the IMAPIProp associated with a mail user.
- *
- *
- */
- HRESULT
- HrNewSampUser( LPMAILUSER * lppMAPIPropEntry,
- ULONG * lpulObjType,
- ULONG cbEntryID,
- LPENTRYID lpEntryID,
- LPABLOGON lpABPLogon,
- LPCIID lpInterface,
- HINSTANCE hLibrary,
- LPALLOCATEBUFFER lpAllocBuff,
- LPALLOCATEMORE lpAllocMore,
- LPFREEBUFFER lpFreeBuff,
- LPMALLOC lpMalloc )
- {
- LPABUSER lpABUser = NULL;
- SCODE sc;
- HRESULT hr = hrSuccess;
- LPPROPDATA lpPropData = NULL;
- SPropValue spv[cvalusrMax];
- ULONG cbT = 0;
- LPBYTE lpbT = NULL;
- LPSTR lpszEMA = NULL;
- /* Do I support this interface?? */
- if (lpInterface)
- {
- if (memcmp(lpInterface, &IID_IMailUser, sizeof(IID)) &&
- memcmp(lpInterface, &IID_IMAPIProp, sizeof(IID)) &&
- memcmp(lpInterface, &IID_IUnknown, sizeof(IID)))
- {
- DebugTraceSc(HrNewSampUser, MAPI_E_INTERFACE_NOT_SUPPORTED);
- return ResultFromScode(MAPI_E_INTERFACE_NOT_SUPPORTED);
- }
- }
- /*
- * Allocate space for the ROOT structure
- */
- sc = lpAllocBuff(sizeof(ABUSER), (LPVOID *) &lpABUser);
- if (FAILED(sc))
- {
- hr = ResultFromScode(sc);
- goto err;
- }
- lpABUser->lpVtbl = &vtblABU;
- lpABUser->lcInit = 1;
- lpABUser->hResult = hrSuccess;
- lpABUser->idsLastError = 0;
- lpABUser->hLibrary = hLibrary;
- lpABUser->lpAllocBuff = lpAllocBuff;
- lpABUser->lpAllocMore = lpAllocMore;
- lpABUser->lpFreeBuff = lpFreeBuff;
- lpABUser->lpMalloc = lpMalloc;
- lpABUser->lpABLogon = lpABPLogon;
- lpABUser->lpTDatListBox = NULL;
- lpABUser->lpTDatDDListBox = NULL;
- lpABUser->lpTDatComboBox = NULL;
- /*
- * Create property storage object
- */
- 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
- * mailuser.
- */
- /*
- * Easy ones first
- */
- spv[ivalusrPR_DISPLAY_TYPE].ulPropTag = PR_DISPLAY_TYPE;
- spv[ivalusrPR_DISPLAY_TYPE].Value.l = DT_MAILUSER;
- spv[ivalusrPR_OBJECT_TYPE].ulPropTag = PR_OBJECT_TYPE;
- spv[ivalusrPR_OBJECT_TYPE].Value.l = MAPI_MAILUSER;
- spv[ivalusrPR_ENTRYID].ulPropTag = PR_ENTRYID;
- spv[ivalusrPR_ENTRYID].Value.bin.cb = sizeof(USR_ENTRYID);
- spv[ivalusrPR_ENTRYID].Value.bin.lpb = (LPBYTE) lpEntryID;
- /*
- * Now the calculated props
- */
- spv[ivalusrPR_RECORD_KEY].ulPropTag = PR_RECORD_KEY;
- spv[ivalusrPR_RECORD_KEY].Value.bin.cb = sizeof(USR_ENTRYID);
- spv[ivalusrPR_RECORD_KEY].Value.bin.lpb = (LPBYTE) lpEntryID;
- spv[ivalusrPR_DISPLAY_NAME_A].ulPropTag = PR_DISPLAY_NAME_A;
- spv[ivalusrPR_DISPLAY_NAME_A].Value.lpszA = ((LPUSR_ENTRYID) lpEntryID)->abcrec.rgchDisplayName;
- /* Should always be the same as PR_DISPLAY_NAME */
- spv[ivalusrPR_TRANSMITABLE_DISPLAY_NAME_A].ulPropTag = PR_TRANSMITABLE_DISPLAY_NAME_A;
- spv[ivalusrPR_TRANSMITABLE_DISPLAY_NAME_A].Value.lpszA = ((LPUSR_ENTRYID) lpEntryID)->abcrec.rgchDisplayName;
- spv[ivalusrPR_EMAIL_ADDRESS_A].ulPropTag = PR_EMAIL_ADDRESS_A;
- spv[ivalusrPR_EMAIL_ADDRESS_A].Value.lpszA = ((LPUSR_ENTRYID) lpEntryID)->abcrec.rgchEmailAddress;
- lpszEMA = ((LPUSR_ENTRYID) lpEntryID)->abcrec.rgchEmailAddress;
- spv[ivalusrPR_ADDRTYPE_A].ulPropTag = PR_ADDRTYPE_A;
- spv[ivalusrPR_ADDRTYPE_A].Value.lpszA = lpszEMT;
- /*
- * Build the search key...
- */
- /* Search keys for mailable recipients that have email addresses are
- * defined as "EmailType':'EmailAddress ". We do the +2 for the ':' and
- * ' '.
- */
- cbT = lstrlenA(lpszEMA) + lstrlenA(lpszEMT) + 2;
- sc = lpAllocBuff( cbT, (LPVOID *) &lpbT );
- if (FAILED(sc))
- {
- hr = ResultFromScode(sc);
- goto err;
- }
- lstrcpyA((LPSTR) lpbT, lpszEMT);
- lstrcatA((LPSTR) lpbT, ":");
- lstrcatA((LPSTR) lpbT, lpszEMA);
- CharUpperBuff((LPTSTR) lpbT, (UINT) cbT);
- spv[ivalusrPR_SEARCH_KEY].ulPropTag = PR_SEARCH_KEY;
- spv[ivalusrPR_SEARCH_KEY].Value.bin.cb = cbT;
- spv[ivalusrPR_SEARCH_KEY].Value.bin.lpb = lpbT;
- /* properties used by the options property page */
- spv[ivalusrPR_LISTBOX_VALUE].ulPropTag = PR_LISTBOX_VALUE;
- spv[ivalusrPR_LISTBOX_VALUE].Value.l = 5;
- spv[ivalusrPR_CHECKBOX_1_VALUE].ulPropTag = PR_CHECKBOX_1_VALUE;
- spv[ivalusrPR_CHECKBOX_1_VALUE].Value.b = TRUE;
- spv[ivalusrPR_CHECKBOX_2_VALUE].ulPropTag = PR_CHECKBOX_2_VALUE;
- spv[ivalusrPR_CHECKBOX_2_VALUE].Value.b = FALSE;
- spv[ivalusrPR_CHECKBOX_3_VALUE].ulPropTag = PR_CHECKBOX_3_VALUE;
- spv[ivalusrPR_CHECKBOX_3_VALUE].Value.b = TRUE;
- spv[ivalusrPR_DDLISTBOX_VALUE].ulPropTag = PR_DDLISTBOX_VALUE;
- spv[ivalusrPR_DDLISTBOX_VALUE].Value.l = 10;
- spv[ivalusrPR_COMBOBOX_VALUE].ulPropTag = PR_COMBOBOX_VALUE;
- spv[ivalusrPR_COMBOBOX_VALUE].Value.lpszA = "ComboBox item 10";
- /*
- * Note that we're using our entryID for our templateID.
- * This is a really simple way to implement templateIDs.
- * (See TID.C)
- */
- spv[ivalusrPR_TEMPLATEID].ulPropTag = PR_TEMPLATEID;
- spv[ivalusrPR_TEMPLATEID].Value.bin.cb = sizeof(USR_ENTRYID);
- spv[ivalusrPR_TEMPLATEID].Value.bin.lpb = (LPBYTE) lpEntryID;
- /*
- * Set the default properties
- */
- hr = lpPropData->lpVtbl->SetProps(
- lpPropData,
- cvalusrMax,
- spv,
- NULL);
- if (HR_FAILED(hr))
- {
- goto err;
- }
- /*
- * Although this object is basically read only, we wanted to show
- * an example of how the check-boxes and other controls on the
- * "Options" pane work. If we had set this object to be read only,
- * the values behind those controls would have been static.
- */
- (void)lpPropData->lpVtbl->HrSetObjAccess(lpPropData, IPROP_READWRITE);
- /*
- * Set the client access rights to the various properties. Notice
- * that everything is READONLY except for the properties related to
- * the controls on the "Options" pane.
- *
- * All properties are intially marked as CLEAN.
- */
- (void) lpPropData->lpVtbl->HrSetPropAccess(lpPropData,
- (LPSPropTagArray) &tagaABUAccess,
- rgulABUAccess);
- lpABUser->lpPropData = (LPMAPIPROP) lpPropData;
- InitializeCriticalSection(&lpABUser->cs);
- /* We must AddRef the lpABPLogon object since we will be using it
- */
- lpABPLogon->lpVtbl->AddRef(lpABPLogon);
- *lppMAPIPropEntry = (LPVOID) lpABUser;
- *lpulObjType = MAPI_MAILUSER;
- out:
- lpFreeBuff(lpbT);
- DebugTraceResult(HrNewSampUser, hr);
- return hr;
- err:
- if (lpPropData)
- lpPropData->lpVtbl->Release(lpPropData);
- lpFreeBuff(lpABUser);
- goto out;
- }
- /*************************************************************************
- *
- *
- - ABU_QueryInterface
- -
- * Allows QI'ing to only IUnknown, IMAPIProp, and IMailUser.
- *
- * This method is reused in TID.C, OOTID.C, and ABOOSER.C. Hence the
- * difference in checking of the 'this' pointer from other methods within
- * this object.
- */
- STDMETHODIMP
- ABU_QueryInterface(LPABUSER lpABUser,
- REFIID lpiid,
- LPVOID FAR * lppNewObj)
- {
- HRESULT hr = hrSuccess;
- /* Minimally check the lpABUser object
- * Can't do any more extensive checking that this because this method is reused
- * in OOUSER.C.
- */
- if (IsBadReadPtr(lpABUser, offsetof(ABUSER, lpVtbl)+sizeof(ABU_Vtbl *)))
- {
- hr = ResultFromScode(E_INVALIDARG);
- goto out;
- }
- if (IsBadReadPtr(lpABUser->lpVtbl,
- offsetof(ABU_Vtbl, QueryInterface)+sizeof(ABU_QueryInterface_METHOD *)))
- {
- hr = ResultFromScode(E_INVALIDARG);
- goto out;
- }
- if (ABU_QueryInterface != lpABUser->lpVtbl->QueryInterface)
- {
- hr = ResultFromScode(E_INVALIDARG);
- goto out;
- }
- Validate_IUnknown_QueryInterface(lpABUser, lpiid, lppNewObj);
- /* 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_IMailUser, sizeof(IID)))
- {
- *lppNewObj = NULL; /* OLE requires zeroing [out] parameter */
- hr = ResultFromScode(E_NOINTERFACE);
- goto out;
- }
- /* Bump the usage count and return same object pointer. */
- EnterCriticalSection(&lpABUser->cs);
- ++lpABUser->lcInit;
- LeaveCriticalSection(&lpABUser->cs);
- *lppNewObj = lpABUser;
- out:
- DebugTraceResult(ABU_QueryInterface, hr);
- return hr;
- }
- /**************************************************
- *
- - ABU_Release
- -
- * Decrement lcInit.
- * When lcInit == 0, free up the lpABUser structure
- *
- */
- STDMETHODIMP_(ULONG)
- ABU_Release(LPABUSER lpABUser)
- {
- LONG lcInit;
- /*
- * Check to see if it's big enough to hold this object
- */
- if (IsBadReadPtr(lpABUser, sizeof(ABUSER)))
- {
- /*
- * Not large enough
- */
- return 1;
- }
- /*
- * Check to see that it's the correct vtbl
- */
- if (lpABUser->lpVtbl != &vtblABU)
- {
- /*
- * Not my vtbl
- */
- return 1;
- }
- Validate_IUnknown_Release(lpABUser);
- EnterCriticalSection(&lpABUser->cs);
- lcInit = --lpABUser->lcInit;
- LeaveCriticalSection(&lpABUser->cs);
- if (lcInit == 0)
- {
- /*
- * Get rid of the lpPropData
- */
- lpABUser->lpPropData->lpVtbl->Release(lpABUser->lpPropData);
- /*
- * Get rid of the tables used by the options property page
- */
- if (lpABUser->lpTDatListBox)
- lpABUser->lpTDatListBox->lpVtbl->Release(lpABUser->lpTDatListBox);
- if (lpABUser->lpTDatDDListBox)
- lpABUser->lpTDatDDListBox->lpVtbl->Release(lpABUser->lpTDatDDListBox);
- if (lpABUser->lpTDatComboBox)
- lpABUser->lpTDatComboBox->lpVtbl->Release(lpABUser->lpTDatComboBox);
- /*
- * Release our reference to the ABLogon object.
- */
- if (lpABUser->lpABLogon)
- {
- lpABUser->lpABLogon->lpVtbl->Release(lpABUser->lpABLogon);
- lpABUser->lpABLogon = NULL;
- }
- /*
- * Destroy the critical section for this object
- */
- DeleteCriticalSection(&lpABUser->cs);
- /*
- * Set the vtbl 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.
- */
- lpABUser->lpVtbl = NULL;
- /*
- * Need to free the object
- */
- lpABUser->lpFreeBuff( lpABUser );
- return 0;
- }
- return lcInit;
- }
- /*************************************************************************
- *
- - ABU_OpenProperty
- -
- *
- * This is how we get the display table associated with this users
- * details screen. This is also how we get the tables which are needed
- * to fill out the "Options" property pane.
- */
- STDMETHODIMP
- ABU_OpenProperty(LPABUSER lpABUser,
- ULONG ulPropTag,
- LPCIID lpiid,
- ULONG ulInterfaceOptions,
- ULONG ulFlags,
- LPUNKNOWN * lppUnk)
- {
- HRESULT hResult;
- ABU_ValidateObject(OpenProperty, lpABUser);
- Validate_IMAPIProp_OpenProperty(lpABUser, ulPropTag, lpiid,
- ulInterfaceOptions, ulFlags, lppUnk);
- if (ulInterfaceOptions & ~MAPI_UNICODE )
- {
- /*
- * Only the Unicode flag should be set for any of the objects that might
- * be returned from this object.
- */
- hResult = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
- DebugTraceResult(ABU_OpenProperty, hResult);
- return hResult;
- }
- if ( ulInterfaceOptions & MAPI_UNICODE )
- {
- hResult = ResultFromScode(MAPI_E_BAD_CHARWIDTH);
- DebugTraceResult(ABU_OpenProperty, hResult);
- return hResult;
- }
- if (ulFlags & MAPI_CREATE)
- {
- hResult = ResultFromScode(E_ACCESSDENIED);
- DebugTraceResult(ABU_OpenProperty, hResult);
- return hResult;
- }
- if (ulPropTag == PR_DETAILS_TABLE ||
- ulPropTag == PR_LISTBOX_TABLE ||
- ulPropTag == PR_DDLISTBOX_TABLE ||
- ulPropTag == PR_COMBOBOX_TABLE)
- {
- /* Check to see if they're expecting a table interface */
- if (memcmp(lpiid, &IID_IMAPITable, sizeof(IID)))
- {
- hResult = ResultFromScode(MAPI_E_INTERFACE_NOT_SUPPORTED);
- return hResult;
- }
- }
- EnterCriticalSection(&lpABUser->cs);
- switch (ulPropTag)
- {
- case PR_DETAILS_TABLE:
- {
- /* Looking for the display table*/
- /* Create a display table */
- hResult = BuildDisplayTable(
- lpABUser->lpAllocBuff,
- lpABUser->lpAllocMore,
- lpABUser->lpFreeBuff,
- lpABUser->lpMalloc,
- lpABUser->hLibrary,
- sizeof(rgdtpage) / sizeof(DTPAGE),
- rgdtpage,
- 0,
- (LPMAPITABLE *) lppUnk,
- NULL);
- break;
- }
- case PR_LISTBOX_TABLE:
- {
- /*
- * Looking for the table that fills the listbox
- * on the Options pane on this user's details
- */
- /*
- * If we don't already have a Table Data Object, make one.
- */
- if (!lpABUser->lpTDatListBox)
- {
- hResult = HrBuildListBoxTable(lpABUser);
- if (HR_FAILED(hResult))
- goto out;
- }
- Assert(lpABUser->lpTDatListBox);
- /* Get a view from the table data object*/
- hResult = lpABUser->lpTDatListBox->lpVtbl->HrGetView(
- lpABUser->lpTDatListBox,
- NULL,
- NULL,
- 0,
- (LPMAPITABLE *) lppUnk);
- break;
- }
- case PR_DDLISTBOX_TABLE:
- {
- /*
- * Locking for the table that fills the drop down listbox
- * on the Options pane on this user's details.
- */
- if (!lpABUser->lpTDatDDListBox)
- {
- hResult = HrBuildDDListBoxTable(lpABUser);
- if (HR_FAILED(hResult))
- goto out;
- }
- Assert(lpABUser->lpTDatDDListBox);
- /* Get a view from the table data object */
- hResult = lpABUser->lpTDatDDListBox->lpVtbl->HrGetView(
- lpABUser->lpTDatDDListBox,
- NULL,
- NULL,
- 0,
- (LPMAPITABLE *) lppUnk);
- break;
- }
- case PR_COMBOBOX_TABLE:
- {
- /*
- * Locking for the table that fills the combobox
- * on the Options pane on this user's details.
- */
- if (!lpABUser->lpTDatComboBox)
- {
- hResult = HrBuildComboBoxTable(lpABUser);
- if (HR_FAILED(hResult))
- goto out;
- }
- Assert(lpABUser->lpTDatComboBox);
- /* Get a view from the table data object */
- hResult =
- lpABUser->lpTDatComboBox->lpVtbl->HrGetView(
- lpABUser->lpTDatComboBox,
- NULL,
- NULL,
- 0,
- (LPMAPITABLE *) lppUnk);
- break;
- }
- default:
- {
- hResult = ResultFromScode(MAPI_E_NO_SUPPORT);
- break;
- }
- }
- out:
- LeaveCriticalSection(&lpABUser->cs);
- DebugTraceResult(ABU_OpenProperty, hResult);
- return hResult;
- }
- /**********************************************************************
- *
- * Private functions
- */
- /*
- * Default column set for listbox table
- */
- enum { ivallbxPR_DISPLAY_NAME_A = 0,
- ivallbxPR_COMMENT_A,
- ivallbxPR_ENTRYID,
- ivallbxPR_DISPLAY_TYPE,
- ivallbxPR_LISTBOX_VALUE,
- ivallbxPR_INSTANCE_KEY,
- cvallbxMax };
- const SizedSPropTagArray(cvallbxMax, tagaColSetListBox) =
- {
- cvallbxMax,
- {
- PR_DISPLAY_NAME_A,
- PR_COMMENT_A,
- PR_ENTRYID,
- PR_DISPLAY_TYPE,
- PR_LISTBOX_VALUE,
- PR_INSTANCE_KEY
- }
- };
- typedef struct _options_entryid
- {
- BYTE abFlags[4];
- MAPIUID muid;
- ULONG ulVersion;
- ULONG ulType;
- ULONG ulRowNumber;
- } OPTIONS_ENTRYID, *LPOPTIONS_ENTRYID;
- #define CBOPTIONS_ENTRYID sizeof(OPTIONS_ENTRYID)
- OPTIONS_ENTRYID OptionsEntryID =
- {
- {0, 0, 0, 0},
- MUIDABSAMPLE,
- SAMP_VERSION,
- SAMP_UNKNOWN,
- 0
- };
- HRESULT
- HrBuildListBoxTable(LPABUSER lpABUser)
- {
- SCODE sc;
- HRESULT hResult;
- SPropValue rgsPropValue[cvallbxMax];
- SRow sRow;
- char szDisplay[MAX_FMT_DET_DN+2]; /* +2 for digits */
- char szComment[MAX_FMT_DET_COMMENT+2]; /* +2 for digits */
- char szFmtDisplay[MAX_FMT_DET_DN];
- char szFmtComment[MAX_FMT_DET_COMMENT];
- LPSTR pszFmtComment = (LPSTR) szFmtComment;
- LPSTR pszFmtDisplay = (LPSTR) szFmtDisplay;
- ULONG uliRow;
- /*
- * Get string resources
- */
- sc = ScLoadString( IDS_FMT_DET_DN,
- MAX_FMT_DET_DN,
- NULL,
- lpABUser->hLibrary,
- (LPSTR *) &pszFmtDisplay);
- if (FAILED(sc))
- {
- hResult = ResultFromScode(sc);
- goto out;
- }
- sc = ScLoadString( IDS_FMT_DET_COMMENT,
- MAX_FMT_DET_COMMENT,
- NULL,
- lpABUser->hLibrary,
- (LPSTR *) &pszFmtComment);
- if (FAILED(sc))
- {
- hResult = ResultFromScode(sc);
- goto out;
- }
- /* Create a Table Data object */
- sc = CreateTable(
- (LPIID) &IID_IMAPITableData,
- lpABUser->lpAllocBuff,
- lpABUser->lpAllocMore,
- lpABUser->lpFreeBuff,
- lpABUser->lpMalloc,
- 0,
- PR_DISPLAY_NAME_A,
- (LPSPropTagArray) &tagaColSetListBox,
- &(lpABUser->lpTDatListBox));
- if (FAILED(sc))
- {
- hResult = ResultFromScode(sc);
- goto out;
- }
- /* constants */
- sRow.cValues = cvallbxMax;
- sRow.lpProps = rgsPropValue;
- /*
- * Although assignment of szDisplay and szComment happen here, their actual
- * values happen below in the for loop.
- */
- rgsPropValue[ivallbxPR_DISPLAY_NAME_A].ulPropTag = PR_DISPLAY_NAME_A;
- rgsPropValue[ivallbxPR_DISPLAY_NAME_A].Value.lpszA = szDisplay;
- rgsPropValue[ivallbxPR_COMMENT_A].ulPropTag = PR_COMMENT_A;
- rgsPropValue[ivallbxPR_COMMENT_A].Value.lpszA = szComment;
- /*
- * For this release of MAPI the following two properties are required
- * for all listboxes exposed in any details dialog. This requirement is
- * scheduled to be removed before ship
- */
- rgsPropValue[ivallbxPR_ENTRYID].ulPropTag = PR_ENTRYID;
- rgsPropValue[ivallbxPR_ENTRYID].Value.bin.lpb = (LPBYTE) &OptionsEntryID;
- rgsPropValue[ivallbxPR_ENTRYID].Value.bin.cb = CBOPTIONS_ENTRYID;
- rgsPropValue[ivallbxPR_DISPLAY_TYPE].ulPropTag = PR_DISPLAY_TYPE;
- rgsPropValue[ivallbxPR_DISPLAY_TYPE].Value.l = 0; /* There are no defines for this yet */
- rgsPropValue[ivallbxPR_LISTBOX_VALUE].ulPropTag = PR_LISTBOX_VALUE;
- rgsPropValue[ivallbxPR_INSTANCE_KEY].ulPropTag = PR_INSTANCE_KEY;
- rgsPropValue[ivallbxPR_INSTANCE_KEY].Value.bin.cb = sizeof(ULONG);
- /* fill up the table */
- for (uliRow = 0; uliRow < MAX_LISTBOX_ROWS; uliRow++)
- {
- wsprintfA(szDisplay, szFmtDisplay, uliRow);
- wsprintfA(szComment, szFmtComment, uliRow);
- OptionsEntryID.ulRowNumber = uliRow;
- rgsPropValue[ivallbxPR_LISTBOX_VALUE].Value.l = uliRow;
- rgsPropValue[ivallbxPR_INSTANCE_KEY].Value.bin.lpb = (LPBYTE) &uliRow;
- hResult = lpABUser->lpTDatListBox->lpVtbl->HrModifyRow(
- lpABUser->lpTDatListBox,
- &sRow);
- if (HR_FAILED(hResult))
- {
- /*
- * Mask errors here...
- * We want to do this because it's probibly still a valid
- * table data object that I can get views from. Most likely
- * just some of the rows will be missing...
- */
- hResult = hrSuccess;
- break;
- }
- /*
- * get rid of any warnings
- */
- hResult = hrSuccess;
- }
- out:
- DebugTraceResult(hrBuildListBoxTable, hResult);
- return hResult;
- }
- /*
- * Default column set for the dropdown listbox table
- */
- enum { ivalddPR_DISPLAY_NAME_A = 0,
- ivalddPR_ENTRYID,
- ivalddPR_DISPLAY_TYPE,
- ivalddPR_DDLISTBOX_VALUE,
- ivalddPR_INSTANCE_KEY,
- cvalddMax };
- const SizedSPropTagArray(cvalddMax, tagaColSetDDListBox) =
- {
- cvalddMax,
- {
- PR_DISPLAY_NAME_A,
- PR_ENTRYID,
- PR_DISPLAY_TYPE,
- PR_DDLISTBOX_VALUE,
- PR_INSTANCE_KEY
- }
- };
- HRESULT
- HrBuildDDListBoxTable(LPABUSER lpABUser)
- {
- SCODE sc;
- HRESULT hResult;
- SPropValue rgsPropValue[cvalddMax];
- SRow sRow;
- char szFmtDisplay[MAX_FMT_DD_DN];
- char szDisplay[MAX_FMT_DD_DN+2]; /* +2 for digits */
- ULONG uliRow;
- LPSTR pszFmtDisplay = (LPSTR) szFmtDisplay;
- /*
- * Get resource strings
- */
- sc = ScLoadString( IDS_FMT_DD_DN,
- MAX_FMT_DD_DN,
- NULL,
- lpABUser->hLibrary,
- (LPSTR *)&pszFmtDisplay );
- if (FAILED(sc))
- {
- hResult = ResultFromScode(sc);
- goto out;
- }
- /* Create a Table Data object */
- sc = CreateTable(
- (LPIID) &IID_IMAPITableData,
- lpABUser->lpAllocBuff,
- lpABUser->lpAllocMore,
- lpABUser->lpFreeBuff,
- lpABUser->lpMalloc,
- 0,
- PR_DISPLAY_NAME_A,
- (LPSPropTagArray) &tagaColSetDDListBox,
- &(lpABUser->lpTDatDDListBox));
- if (FAILED(sc))
- {
- hResult = ResultFromScode(sc);
- goto out;
- }
- /* constants */
- sRow.cValues = cvalddMax;
- sRow.lpProps = rgsPropValue;
- /*
- * Although assignment of szDisplay happens here, its actual
- * values happen below in the for loop.
- */
- rgsPropValue[ivalddPR_DISPLAY_NAME_A].ulPropTag = PR_DISPLAY_NAME_A;
- rgsPropValue[ivalddPR_DISPLAY_NAME_A].Value.lpszA = szDisplay;
- /*
- * For this release of MAPI the following two properties are required
- * for all listboxes exposed in any details dialog. This requirement is
- * scheduled to be removed before ship
- */
- rgsPropValue[ivalddPR_ENTRYID].ulPropTag = PR_ENTRYID;
- rgsPropValue[ivalddPR_ENTRYID].Value.bin.lpb = (LPBYTE) &OptionsEntryID;
- rgsPropValue[ivalddPR_ENTRYID].Value.bin.cb = CBOPTIONS_ENTRYID;
- rgsPropValue[ivalddPR_DISPLAY_TYPE].ulPropTag = PR_DISPLAY_TYPE;
- rgsPropValue[ivalddPR_DISPLAY_TYPE].Value.l = 0;
- rgsPropValue[ivalddPR_DDLISTBOX_VALUE].ulPropTag = PR_DDLISTBOX_VALUE;
- rgsPropValue[ivalddPR_INSTANCE_KEY].ulPropTag = PR_INSTANCE_KEY;
- rgsPropValue[ivalddPR_INSTANCE_KEY].Value.bin.cb = sizeof(ULONG);
- /* fill up the table */
- for (uliRow = 0; uliRow < 25; uliRow++)
- {
- wsprintfA(szDisplay, szFmtDisplay, uliRow);
- OptionsEntryID.ulRowNumber = uliRow;
- rgsPropValue[ivalddPR_DDLISTBOX_VALUE].Value.l = uliRow;
- rgsPropValue[ivalddPR_INSTANCE_KEY].Value.bin.lpb = (LPBYTE) &uliRow;
- hResult = lpABUser->lpTDatDDListBox->lpVtbl->HrModifyRow(
- lpABUser->lpTDatDDListBox,
- &sRow);
- if (HR_FAILED(hResult))
- {
- /*
- * Mask errors here...
- * We want to do this because it's probibly still a valid
- * table data object that I can get views from. Most likely
- * just some of the rows will be missing...
- */
- hResult = hrSuccess;
- break;
- }
- /*
- * get rid of any warnings
- */
- hResult = hrSuccess;
- }
- out:
- DebugTraceResult(HrBuildDDListBoxTable, hResult);
- return hResult;
- }
- /*
- * Default column set for the combobox table
- */
- enum { ivalcbPR_DISPLAY_NAME_A = 0,
- ivalcbPR_ENTRYID,
- ivalcbPR_DISPLAY_TYPE,
- ivalcbPR_COMBOBOX_VALUE,
- ivalcbPR_INSTANCE_KEY,
- cvalcbMax };
- const SizedSPropTagArray(cvalcbMax, tagaColSetComboBox) =
- {
- cvalcbMax,
- {
- PR_DISPLAY_NAME_A,
- PR_ENTRYID,
- PR_DISPLAY_TYPE,
- PR_COMBOBOX_VALUE,
- PR_INSTANCE_KEY
- }
- };
- HRESULT
- HrBuildComboBoxTable(LPABUSER lpABUser)
- {
- SCODE sc;
- HRESULT hResult;
- SPropValue rgsPropValue[cvalcbMax];
- SRow sRow;
- char szFmtDisplay[MAX_FMT_COMBO_DN];
- char szDisplay[MAX_FMT_COMBO_DN + 2]; /* +2 for digits */
- ULONG uliRow;
- LPSTR pszFmtDisplay = (LPSTR) szFmtDisplay;
- /*
- * Get resource strings
- */
- sc = ScLoadString( IDS_FMT_COMBO_DN,
- MAX_FMT_COMBO_DN,
- NULL,
- lpABUser->hLibrary,
- (LPSTR *) &pszFmtDisplay );
- if (FAILED(sc))
- {
- hResult = ResultFromScode(sc);
- goto out;
- }
- /* Create a table data object */
- sc = CreateTable(
- (LPIID) &IID_IMAPITableData,
- lpABUser->lpAllocBuff,
- lpABUser->lpAllocMore,
- lpABUser->lpFreeBuff,
- lpABUser->lpMalloc,
- 0,
- PR_DISPLAY_NAME_A,
- (LPSPropTagArray) &tagaColSetComboBox,
- &(lpABUser->lpTDatComboBox));
- if (FAILED(sc))
- {
- hResult = ResultFromScode(sc);
- goto out;
- }
- /* constants */
- sRow.cValues = cvalcbMax;
- sRow.lpProps = rgsPropValue;
- /*
- * Although assignment of szDisplay happens here, its actual
- * values happen below in the for loop.
- */
- rgsPropValue[ivalcbPR_DISPLAY_NAME_A].ulPropTag = PR_DISPLAY_NAME_A;
- rgsPropValue[ivalcbPR_DISPLAY_NAME_A].Value.lpszA = szDisplay;
- /*
- * For this release of MAPI the following two properties are required
- * for all listboxes exposed in any details dialog. This requirement is
- * scheduled to be removed before ship
- */
- rgsPropValue[ivalcbPR_ENTRYID].ulPropTag = PR_ENTRYID;
- rgsPropValue[ivalcbPR_ENTRYID].Value.bin.lpb = (LPBYTE) &OptionsEntryID;
- rgsPropValue[ivalcbPR_ENTRYID].Value.bin.cb = CBOPTIONS_ENTRYID;
- rgsPropValue[ivalcbPR_DISPLAY_TYPE].ulPropTag = PR_DISPLAY_TYPE;
- rgsPropValue[ivalcbPR_DISPLAY_TYPE].Value.l = 0;
- rgsPropValue[ivalcbPR_COMBOBOX_VALUE].ulPropTag = PR_COMBOBOX_VALUE;
- rgsPropValue[ivalcbPR_COMBOBOX_VALUE].Value.lpszA = szDisplay;
- rgsPropValue[ivalcbPR_INSTANCE_KEY].ulPropTag = PR_INSTANCE_KEY;
- rgsPropValue[ivalcbPR_INSTANCE_KEY].Value.bin.cb = sizeof(ULONG);
- /* fill up the table */
- for (uliRow = 0; uliRow < 25; uliRow++)
- {
- wsprintfA(szDisplay, szFmtDisplay, uliRow);
- OptionsEntryID.ulRowNumber = uliRow;
- rgsPropValue[ivalcbPR_INSTANCE_KEY].Value.bin.lpb = (LPBYTE) &uliRow;
- hResult = lpABUser->lpTDatComboBox->lpVtbl->HrModifyRow(
- lpABUser->lpTDatComboBox,
- &sRow);
- if (HR_FAILED(hResult))
- {
- /*
- * Mask errors here...
- * We want to do this because it's probibly still a valid
- * table data object that I can get views from. Most likely
- * just some of the rows will be missing...
- */
- hResult = hrSuccess;
- break;
- }
- /*
- * get rid of any warnings
- */
- hResult = hrSuccess;
- }
- out:
- DebugTraceResult(HrBuildComboBoxTable, hResult);
- return hResult;
- }