You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
887 lines
30 KiB
887 lines
30 KiB
/*
|
|
-
|
|
- me.c
|
|
-
|
|
* Contains code for handling the ME object that represents the user
|
|
*
|
|
*/
|
|
#include "_apipch.h"
|
|
|
|
|
|
|
|
HRESULT HrCreatePrePopulatedMe(LPADRBOOK lpIAB,
|
|
BOOL bShowBeforeAdding, HWND hWndParent,
|
|
ULONG * lpcbEID, LPENTRYID * lppbEID, DWORD * lpdwAction);
|
|
|
|
typedef struct _SetMeParams
|
|
{
|
|
LPIAB lpIAB;
|
|
BOOL bGetMe; // Get operation or Set operation
|
|
LPSBinary lpsbIn;
|
|
SBinary sbOut; // Will contain a pointer to the returned EID
|
|
BOOL bCreateNew; // New item created as a result of this or not
|
|
LPRECIPIENT_INFO lpList;
|
|
} SETMEPARAMS, * LPSETMEPARAMS;
|
|
|
|
|
|
// [PaulHi] 2/3/99 Raid 69884 Unique default GUID to store non-identity aware
|
|
// profile tags
|
|
// {5188FAFD-BC52-11d2-B36A-00C04F72E62D}
|
|
#include <initguid.h>
|
|
DEFINE_GUID(GUID_DEFAULT_PROFILE_ID,
|
|
0x5188fafd, 0xbc52, 0x11d2, 0xb3, 0x6a, 0x0, 0xc0, 0x4f, 0x72, 0xe6, 0x2d);
|
|
|
|
|
|
static DWORD rgDLHelpIDs[] =
|
|
{
|
|
IDC_SETME_RADIO_CREATE, IDH_WAB_CHOOSE_PROFILE_CREATE_NEW,
|
|
IDC_SETME_RADIO_SELECT, IDH_WAB_CHOOSE_PROFILE_SELECTFROM,
|
|
IDC_SETME_LIST, IDH_WAB_CHOOSE_PROFILE_LIST,
|
|
IDD_DIALOG_SETME, IDH_WAB_CHOOSE_PROFILE_LIST,
|
|
|
|
0,0
|
|
};
|
|
/*
|
|
-
|
|
- EnableSelectWindow
|
|
*
|
|
*/
|
|
void EnableSelectLVWindow(HWND hWndLV, BOOL bSelect)
|
|
{
|
|
// if this is being disabled, remove the LVS_SHOWSELALWAYS style
|
|
// else add the style
|
|
DWORD dwStyle = GetWindowLong(hWndLV, GWL_STYLE);
|
|
|
|
if(bSelect)
|
|
dwStyle |= LVS_SHOWSELALWAYS;
|
|
else
|
|
dwStyle &= ~LVS_SHOWSELALWAYS;
|
|
|
|
SetWindowLong(hWndLV, GWL_STYLE, dwStyle);
|
|
|
|
EnableWindow(hWndLV, bSelect);
|
|
}
|
|
|
|
/*
|
|
-
|
|
- HrFindMe
|
|
-
|
|
* sbMe - me item's entryid
|
|
*
|
|
* If this is an identity aware WAB, then this function finds the ME for the current
|
|
* identity or the ME for the default identity if there isn't a current one
|
|
*
|
|
*
|
|
*/
|
|
HRESULT HrFindMe(LPADRBOOK lpAdrBook, LPSBinary lpsbMe, LPTSTR lpProfileID)
|
|
{
|
|
SPropertyRestriction SPropRes = {0};
|
|
ULONG ulcEIDCount = 1,i=0;
|
|
LPSBinary rgsbEIDs = NULL;
|
|
HRESULT hr = E_FAIL;
|
|
SCODE sc;
|
|
LPIAB lpIAB = (LPIAB)lpAdrBook;
|
|
TCHAR szProfileID[MAX_PATH];
|
|
|
|
ULONG ulcValues = 0;
|
|
LPSPropValue lpPropArray = NULL;
|
|
SizedSPropTagArray(1, MEProps) =
|
|
{
|
|
1, { PR_WAB_USER_PROFILEID }
|
|
};
|
|
|
|
// [PaulHi] 2/3/99 Raid 69884
|
|
// We have to at least get the default identity GUID or error out. Otherwise the
|
|
// PR_WAB_USER_PROFILEID property is invalid and later references to the profile
|
|
// "me" contact will be erroneous.
|
|
*szProfileID = '\0';
|
|
if(lpProfileID && lstrlen(lpProfileID))
|
|
StrCpyN(szProfileID, lpProfileID, ARRAYSIZE(szProfileID));
|
|
else if(bAreWABAPIProfileAware(lpIAB))
|
|
{
|
|
if ( bDoesThisWABHaveAnyUsers(lpIAB) &&
|
|
bIsThereACurrentUser(lpIAB) &&
|
|
lpIAB->szProfileID &&
|
|
lstrlen(lpIAB->szProfileID) )
|
|
{
|
|
StrCpyN(szProfileID,lpIAB->szProfileID, ARRAYSIZE(szProfileID));
|
|
}
|
|
else
|
|
{
|
|
if(HR_FAILED(hr = HrGetDefaultIdentityInfo(lpIAB, DEFAULT_ID_PROFILEID,NULL, szProfileID, ARRAYSIZE(szProfileID), NULL, 0)))
|
|
goto out;
|
|
}
|
|
}
|
|
else
|
|
HrGetUserProfileID((GUID *)&GUID_DEFAULT_PROFILE_ID, szProfileID, MAX_PATH-1);
|
|
|
|
SPropRes.ulPropTag = PR_WAB_THISISME;
|
|
SPropRes.relop = RELOP_EQ;
|
|
SPropRes.lpProp = NULL;
|
|
|
|
// We do a search in the WAB for entries containing the
|
|
// PR_WAB_THISISME property. There should be only one such entry.
|
|
|
|
// BUGBUG <JasonSo>: Need to ensure somewhere that the ME record is always
|
|
// in the default container.
|
|
hr = FindRecords(lpIAB->lpPropertyStore->hPropertyStore,
|
|
NULL,
|
|
AB_MATCH_PROP_ONLY,
|
|
TRUE,
|
|
&SPropRes,
|
|
&ulcEIDCount, &rgsbEIDs);
|
|
|
|
if(HR_FAILED(hr) || !rgsbEIDs || !ulcEIDCount)
|
|
goto out;
|
|
|
|
for(i=0;i<ulcEIDCount;i++)
|
|
{
|
|
// Need to open each item and look at it's ProfileID if any
|
|
if(!HR_FAILED(HrGetPropArray(lpAdrBook, (LPSPropTagArray)&MEProps,
|
|
rgsbEIDs[i].cb, (LPENTRYID)rgsbEIDs[i].lpb,
|
|
MAPI_UNICODE,
|
|
&ulcValues, &lpPropArray)))
|
|
{
|
|
if(ulcValues && lpPropArray)
|
|
{
|
|
if( lpPropArray[0].ulPropTag == PR_WAB_USER_PROFILEID &&
|
|
!lstrcmpi(lpPropArray[0].Value.LPSZ, szProfileID))
|
|
{
|
|
// match
|
|
// return the first item out of the rgsbEIDs array (ideally there should be only one)
|
|
lpsbMe->cb = rgsbEIDs[i].cb;
|
|
|
|
if (FAILED(sc = MAPIAllocateBuffer(lpsbMe->cb, (LPVOID *) (&(lpsbMe->lpb)))))
|
|
{
|
|
hr = MAPI_E_NOT_ENOUGH_MEMORY;
|
|
goto out;
|
|
}
|
|
|
|
CopyMemory(lpsbMe->lpb, rgsbEIDs[i].lpb, lpsbMe->cb);
|
|
break;
|
|
}
|
|
FreeBufferAndNull(&lpPropArray);
|
|
}
|
|
}
|
|
}
|
|
|
|
FreeEntryIDs(lpIAB->lpPropertyStore->hPropertyStore,
|
|
ulcEIDCount, rgsbEIDs);
|
|
out:
|
|
FreeBufferAndNull(&lpPropArray);
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*
|
|
-
|
|
- HrSetMe
|
|
-
|
|
* Sets the actual ME property on a given entryid
|
|
*
|
|
* if bResetOldMe is TRUE, finds the old ME and
|
|
* deletes the ME property off the old ME
|
|
*
|
|
*/
|
|
HRESULT HrSetMe(LPADRBOOK lpAdrBook, LPSBinary lpsb, BOOL bResetOldMe)
|
|
{
|
|
LPMAILUSER lpMU = NULL, lpMUOld = 0;
|
|
SBinary sbOld = {0};
|
|
HRESULT hr = E_FAIL;
|
|
SPropValue Prop[2];
|
|
ULONG ulObjType = 0;
|
|
TCHAR szProfileID[MAX_PATH];
|
|
LPIAB lpIAB = (LPIAB)lpAdrBook;
|
|
|
|
if(!lpsb || !lpsb->cb || !lpsb->lpb)
|
|
goto out;
|
|
|
|
Prop[0].ulPropTag = PR_WAB_THISISME;
|
|
Prop[0].Value.l = 0; // Value doesnt matter, only existence of this prop matters
|
|
|
|
// [PaulHi] 2/3/99 Raid 69884
|
|
// We have to at least get the default identity GUID or error out. Otherwise the
|
|
// PR_WAB_USER_PROFILEID property is invalid and later references to the profile
|
|
// "me" contact will be erroneous.
|
|
*szProfileID = '\0';
|
|
if(bAreWABAPIProfileAware(lpIAB))
|
|
{
|
|
if ( bDoesThisWABHaveAnyUsers(lpIAB) &&
|
|
bIsThereACurrentUser(lpIAB) &&
|
|
lpIAB->szProfileID &&
|
|
lstrlen(lpIAB->szProfileID) )
|
|
{
|
|
StrCpyN(szProfileID,lpIAB->szProfileID, ARRAYSIZE(szProfileID));
|
|
}
|
|
else
|
|
{
|
|
if(HR_FAILED(hr = HrGetDefaultIdentityInfo(lpIAB, DEFAULT_ID_PROFILEID,NULL, szProfileID, ARRAYSIZE(szProfileID), NULL, 0)))
|
|
goto out;
|
|
}
|
|
}
|
|
else
|
|
HrGetUserProfileID((GUID *)&GUID_DEFAULT_PROFILE_ID, szProfileID, MAX_PATH-1);
|
|
|
|
Prop[1].ulPropTag = PR_WAB_USER_PROFILEID;
|
|
Prop[1].Value.LPSZ = szProfileID;
|
|
|
|
if(bResetOldMe)
|
|
{
|
|
if(HR_FAILED(hr = HrFindMe(lpAdrBook, &sbOld, szProfileID)))
|
|
goto out;
|
|
|
|
if(sbOld.cb && sbOld.lpb)
|
|
{
|
|
SizedSPropTagArray(1, ptaOldMe)=
|
|
{
|
|
1, PR_WAB_THISISME
|
|
};
|
|
|
|
if (HR_FAILED(hr = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook, sbOld.cb, (LPENTRYID) sbOld.lpb,
|
|
NULL, MAPI_MODIFY, &ulObjType, (LPUNKNOWN *)&lpMUOld)))
|
|
goto out;
|
|
|
|
if(HR_FAILED(hr = lpMUOld->lpVtbl->DeleteProps(lpMUOld, (LPSPropTagArray) &ptaOldMe, NULL)))
|
|
goto out;
|
|
|
|
if(HR_FAILED(hr = lpMUOld->lpVtbl->SaveChanges(lpMUOld, 0)))
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
if (HR_FAILED(hr = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook, lpsb->cb, (LPENTRYID) lpsb->lpb,
|
|
NULL, MAPI_MODIFY, &ulObjType,
|
|
(LPUNKNOWN *)&lpMU)))
|
|
{
|
|
DebugPrintError(( TEXT("IAB->OpenEntry: %x"), hr));
|
|
goto out;
|
|
}
|
|
|
|
if(HR_FAILED(hr = lpMU->lpVtbl->SetProps(lpMU,
|
|
(lstrlen(szProfileID) ? 2 : 1), //in case we don't have a profile or default profile, don't set the prop
|
|
Prop, NULL)))
|
|
goto out;
|
|
|
|
if(HR_FAILED(hr = lpMU->lpVtbl->SaveChanges(lpMU, 0)))
|
|
goto out;
|
|
|
|
out:
|
|
if(sbOld.lpb)
|
|
MAPIFreeBuffer(sbOld.lpb);
|
|
|
|
if(lpMU)
|
|
lpMU->lpVtbl->Release(lpMU);
|
|
|
|
if(lpMUOld)
|
|
lpMUOld->lpVtbl->Release(lpMUOld);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*
|
|
-
|
|
- fnSetMe
|
|
-
|
|
* Dialog Proc for the SetMe dialog
|
|
* The dialog is displayed for calls to both set me or get me and so we have
|
|
* to do a very few number of things seperately for each.
|
|
*
|
|
*/
|
|
INT_PTR CALLBACK fnSetMe(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
LPSETMEPARAMS lpSMP = (LPSETMEPARAMS) GetWindowLongPtr(hDlg,DWLP_USER);
|
|
|
|
switch(message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_SETME_LIST);
|
|
lpSMP = (LPSETMEPARAMS) lParam;
|
|
SetWindowLongPtr(hDlg,DWLP_USER,lParam); //Save this for future reference
|
|
|
|
// init the list view
|
|
HrInitListView(hWndLV ,LVS_REPORT | LVS_SORTASCENDING, FALSE);
|
|
|
|
// Normally we want the CreateNew button selected unless an existing
|
|
// EID was passed in, in which case that item should be selected
|
|
{
|
|
BOOL bSelect = (lpSMP->lpsbIn && lpSMP->lpsbIn->lpb);
|
|
CheckRadioButton(hDlg, IDC_SETME_RADIO_CREATE, IDC_SETME_RADIO_SELECT,
|
|
( bSelect ? IDC_SETME_RADIO_SELECT : IDC_SETME_RADIO_CREATE ) );
|
|
EnableSelectLVWindow(hWndLV, bSelect);
|
|
}
|
|
|
|
{
|
|
SORT_INFO sortinfo = {0};
|
|
SPropertyRestriction PropRes = {0};
|
|
SPropValue sp = {0};
|
|
|
|
PropRes.ulPropTag = PR_OBJECT_TYPE;
|
|
PropRes.relop = RELOP_EQ;
|
|
sp.ulPropTag = PR_OBJECT_TYPE;
|
|
sp.Value.l = MAPI_MAILUSER;
|
|
PropRes.lpProp = &sp;
|
|
|
|
// We need to fill the ListView with the WAB contacts (no distlists)
|
|
if(!HR_FAILED(HrGetWABContentsList(lpSMP->lpIAB, sortinfo,
|
|
NULL, &PropRes, 0, NULL, TRUE, &(lpSMP->lpList))))
|
|
{
|
|
HrFillListView(hWndLV, lpSMP->lpList);
|
|
}
|
|
}
|
|
if(ListView_GetItemCount(hWndLV) <= 0)
|
|
{
|
|
EnableWindow(GetDlgItem(hDlg, IDC_SETME_RADIO_SELECT), FALSE);
|
|
SetFocus(GetDlgItem(hDlg, IDC_SETME_RADIO_CREATE));
|
|
}
|
|
else
|
|
{
|
|
LVSelectItem(hWndLV, 0);
|
|
if(lpSMP->lpsbIn && lpSMP->lpsbIn->lpb)
|
|
{
|
|
// We need to find this item and select it
|
|
int nCount = ListView_GetItemCount(hWndLV);
|
|
SetFocus(GetDlgItem(hDlg, IDC_SETME_RADIO_SELECT));
|
|
while(nCount >= 0)
|
|
{
|
|
LPRECIPIENT_INFO lpItem = GetItemFromLV(hWndLV, nCount);
|
|
if(lpItem && lpItem->bIsMe) // All ME items are tagged as such
|
|
{
|
|
if( lpSMP->lpsbIn->cb == lpItem->cbEntryID &&
|
|
!memcmp(lpItem->lpEntryID, lpSMP->lpsbIn->lpb, lpSMP->lpsbIn->cb))
|
|
{
|
|
// it's a match
|
|
LVSelectItem(hWndLV, nCount);
|
|
EnableSelectLVWindow(hWndLV, TRUE);
|
|
SetFocus(hWndLV);
|
|
}
|
|
else
|
|
{
|
|
// this is some other ME not corresponding to the current Identity
|
|
// or the default identity so remove it from the window ..
|
|
ListView_DeleteItem(hWndLV, nCount);
|
|
}
|
|
}
|
|
nCount--;
|
|
}
|
|
}
|
|
else
|
|
SetFocus(GetDlgItem(hDlg, IDC_SETME_RADIO_CREATE));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case WM_HELP:
|
|
WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
|
|
g_szWABHelpFileName,
|
|
HELP_WM_HELP,
|
|
(DWORD_PTR)(LPSTR) rgDLHelpIDs );
|
|
break;
|
|
|
|
case WM_CONTEXTMENU:
|
|
WABWinHelp((HWND) wParam,
|
|
g_szWABHelpFileName,
|
|
HELP_CONTEXTMENU,
|
|
(DWORD_PTR)(LPSTR) rgDLHelpIDs );
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
switch (GET_WM_COMMAND_ID(wParam, lParam))
|
|
{
|
|
case IDOK:
|
|
{
|
|
int nID = IDOK;
|
|
// Check if user said 'Create' or if user 'Selected'
|
|
SBinary sb = {0};
|
|
if(IsDlgButtonChecked(hDlg, IDC_SETME_RADIO_CREATE))
|
|
{
|
|
HRESULT hr = HrCreatePrePopulatedMe( (LPADRBOOK)lpSMP->lpIAB, TRUE, hDlg,
|
|
&sb.cb, (LPENTRYID *)&(sb.lpb), NULL );
|
|
if(hr == MAPI_E_USER_CANCEL)
|
|
{
|
|
return FALSE;
|
|
}
|
|
else if(HR_FAILED(hr))
|
|
{
|
|
ShowMessageBox(hDlg, idsCouldNotAddUserToWAB, MB_ICONEXCLAMATION | MB_OK);
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
lpSMP->sbOut.cb = sb.cb;
|
|
lpSMP->sbOut.lpb = sb.lpb;
|
|
lpSMP->bCreateNew = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Get the current selection from the DLG
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_SETME_LIST);
|
|
if(ListView_GetSelectedCount(hWndLV) > 0)
|
|
{
|
|
int iItem = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
|
|
if(iItem != -1)
|
|
{
|
|
LPRECIPIENT_INFO lpItem = GetItemFromLV(hWndLV, iItem);;
|
|
lpSMP->sbOut.cb = lpItem->cbEntryID;
|
|
if(!FAILED(MAPIAllocateBuffer(lpItem->cbEntryID, (LPVOID *) (&(lpSMP->sbOut.lpb)))))
|
|
CopyMemory(lpSMP->sbOut.lpb, lpItem->lpEntryID, lpItem->cbEntryID);
|
|
}
|
|
}
|
|
}
|
|
EndDialog(hDlg, nID);
|
|
}
|
|
break;
|
|
case IDCANCEL:
|
|
EndDialog(hDlg, IDCANCEL);
|
|
break;
|
|
case IDC_SETME_RADIO_CREATE:
|
|
case IDC_SETME_RADIO_SELECT:
|
|
{
|
|
HWND hWndLV = GetDlgItem(hDlg, IDC_SETME_LIST);
|
|
if(ListView_GetItemCount(hWndLV) > 0)
|
|
EnableSelectLVWindow(hWndLV, (GET_WM_COMMAND_ID(wParam, lParam) == IDC_SETME_RADIO_SELECT));
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
-
|
|
- HrShowSelectMeDialog
|
|
-
|
|
*
|
|
* bGetMe - TRUE = GET, FALSE = SET
|
|
* lpsbEIDin - EID of existing ME entry
|
|
* lpsbEIDout - EID of selected ME entry
|
|
*
|
|
*/
|
|
HRESULT HrShowSelectMeDialog(LPIAB lpIAB, HWND hWndParent, BOOL bGetMe,
|
|
LPSBinary lpsbEIDin, LPSBinary lpsbEIDout, DWORD * lpdwAction)
|
|
{
|
|
SETMEPARAMS smp = {0};
|
|
HRESULT hr = S_OK;
|
|
int nRetVal = 0;
|
|
|
|
smp.lpIAB = lpIAB;
|
|
smp.bGetMe = bGetMe;
|
|
smp.lpsbIn = lpsbEIDin;
|
|
|
|
nRetVal = (int) DialogBoxParam(hinstMapiX, MAKEINTRESOURCE(IDD_DIALOG_SETME),
|
|
hWndParent, fnSetMe, (LPARAM) &smp);
|
|
|
|
if(smp.lpList)
|
|
FreeRecipList(&(smp.lpList));
|
|
|
|
if(lpsbEIDout && smp.sbOut.cb && smp.sbOut.lpb)
|
|
{
|
|
lpsbEIDout->cb = smp.sbOut.cb;
|
|
lpsbEIDout->lpb = smp.sbOut.lpb;
|
|
}
|
|
else if(smp.sbOut.lpb)
|
|
MAPIFreeBuffer(smp.sbOut.lpb);
|
|
|
|
if(lpdwAction && smp.bCreateNew)
|
|
*lpdwAction = WABOBJECT_ME_NEW;
|
|
|
|
if(nRetVal == IDCANCEL)
|
|
hr = MAPI_E_USER_CANCEL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
typedef struct _RegWizardProp
|
|
{
|
|
ULONG ulPropTag;
|
|
LPTSTR szRegElement;
|
|
} REGWIZARDPROP, * LPREGWIZARDPROP;
|
|
|
|
extern BOOL bDNisByLN;
|
|
|
|
/*
|
|
- HrCreatePrePopulated Me
|
|
-
|
|
* Attempts to prepopulate the Me entry from RegWizard information from the registry
|
|
* (Note that the regwizard only exists on win98 and NT5)
|
|
*
|
|
*/
|
|
HRESULT HrCreatePrePopulatedMe(LPADRBOOK lpAdrBook,
|
|
BOOL bShowBeforeAdding, HWND hWndParent,
|
|
ULONG * lpcbEID, LPENTRYID * lppbEID, DWORD * lpdwAction)
|
|
{
|
|
LPTSTR lpszRegWizKey = TEXT("Software\\Microsoft\\User Information");
|
|
|
|
enum _RegWizElements
|
|
{
|
|
eDisplayName=0,
|
|
eFname,
|
|
eLname,
|
|
eCompanyName,
|
|
eEmailName,
|
|
eAddr1,
|
|
eAddr2,
|
|
eCity,
|
|
eState,
|
|
eZip,
|
|
eAreaCode,
|
|
ePhone,
|
|
eCountry,
|
|
eMax,
|
|
};
|
|
|
|
REGWIZARDPROP rgRegWizElement[] =
|
|
{
|
|
{ PR_DISPLAY_NAME, TEXT("DisplayNameX") }, // this is a fake one, it doesn't actually exist
|
|
{ PR_GIVEN_NAME, TEXT("Default First Name") },
|
|
{ PR_SURNAME, TEXT("Default Last Name") },
|
|
{ PR_COMPANY_NAME, TEXT("Default Company") },
|
|
{ PR_EMAIL_ADDRESS, TEXT("E-mail Address") },
|
|
{ PR_HOME_ADDRESS_STREET, TEXT("Mailing Address") },
|
|
{ PR_NULL, TEXT("Additional Address") },
|
|
{ PR_HOME_ADDRESS_CITY, TEXT("City") },
|
|
{ PR_HOME_ADDRESS_STATE_OR_PROVINCE, TEXT("State") },
|
|
{ PR_HOME_ADDRESS_POSTAL_CODE, TEXT("ZIP Code") },
|
|
{ PR_NULL, TEXT("AreaCode") },
|
|
{ PR_HOME_TELEPHONE_NUMBER, TEXT("Daytime Phone") },
|
|
{ PR_HOME_ADDRESS_COUNTRY, TEXT("Country") }, //this is fake - we will read this from the system locale
|
|
};
|
|
|
|
SPropValue SProp[eMax];
|
|
LPTSTR lpAddress = NULL;
|
|
LPTSTR lpDisplayName = NULL;
|
|
ULONG cValues = 0;
|
|
ULONG i = 0;
|
|
HRESULT hr = S_OK;
|
|
HKEY hKey = NULL;
|
|
// in case there is an identity, use the identities name ...
|
|
TCHAR lpszProfileName[MAX_PATH];
|
|
LPIAB lpIAB = (LPIAB)lpAdrBook;
|
|
LPTSTR * sz = NULL;
|
|
ULONG cbPABEID = 0;
|
|
LPENTRYID lpPABEID = NULL;
|
|
|
|
if(!(sz = LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR)*eMax)))
|
|
{
|
|
hr = MAPI_E_NOT_ENOUGH_MEMORY;
|
|
goto out;
|
|
}
|
|
for(i=0;i<eMax;i++)
|
|
{
|
|
if(!(sz[i] = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*MAX_PATH)))
|
|
{
|
|
hr = MAPI_E_NOT_ENOUGH_MEMORY;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
*lpszProfileName = '\0';
|
|
// if identities are registered, use the current identity or the default identity
|
|
if(bDoesThisWABHaveAnyUsers(lpIAB))
|
|
{
|
|
if(bIsThereACurrentUser(lpIAB) && lpIAB->szProfileName && lstrlen(lpIAB->szProfileName))
|
|
{
|
|
StrCpyN(lpszProfileName,lpIAB->szProfileName, ARRAYSIZE(lpszProfileName));
|
|
}
|
|
else
|
|
{
|
|
TCHAR szDefProfile[MAX_PATH];
|
|
if(HR_FAILED(hr = HrGetDefaultIdentityInfo(lpIAB, DEFAULT_ID_PROFILEID | DEFAULT_ID_NAME,
|
|
NULL, szDefProfile, ARRAYSIZE(szDefProfile), lpszProfileName, 0)))
|
|
{
|
|
if(hr == 0x80040154) // E_CLASS_NOT_REGISTERD means no IDentity Manager
|
|
hr = S_OK;
|
|
else
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
// Get the data from the registry
|
|
|
|
if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpszRegWizKey, 0, KEY_READ, &hKey))
|
|
{
|
|
DWORD dwType = REG_SZ;
|
|
for(i=0;i<eMax;i++)
|
|
{
|
|
ULONG ulErr = 0;
|
|
DWORD dwSize = MAX_PATH;
|
|
*(sz[i]) = '\0';
|
|
SProp[i].ulPropTag = rgRegWizElement[i].ulPropTag;
|
|
SProp[i].Value.LPSZ = sz[i];
|
|
ulErr = RegQueryValueEx( hKey, rgRegWizElement[i].szRegElement, NULL, &dwType, (LPBYTE) sz[i], &dwSize );
|
|
if(ulErr != ERROR_SUCCESS)
|
|
DebugTrace(TEXT("oooo> RegQueryValueEx failed: %d\n"),ulErr);
|
|
}
|
|
if(lpszProfileName && lstrlen(lpszProfileName))
|
|
{
|
|
SProp[eDisplayName].ulPropTag = PR_DISPLAY_NAME;
|
|
SProp[eDisplayName].Value.LPSZ = lpszProfileName;
|
|
}
|
|
else
|
|
{
|
|
SProp[eDisplayName].ulPropTag = PR_NULL;
|
|
}
|
|
|
|
// Need to do some cleanup and adjustment to the data
|
|
if(SProp[eCompanyName].ulPropTag == PR_COMPANY_NAME && lstrlen(SProp[eCompanyName].Value.LPSZ))
|
|
{
|
|
// This is a company address
|
|
SProp[eAddr1].ulPropTag = PR_BUSINESS_ADDRESS_STREET;
|
|
SProp[eCity].ulPropTag = PR_BUSINESS_ADDRESS_CITY;
|
|
SProp[eState].ulPropTag = PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE;
|
|
SProp[eZip].ulPropTag = PR_BUSINESS_ADDRESS_POSTAL_CODE;
|
|
SProp[ePhone].ulPropTag = PR_BUSINESS_TELEPHONE_NUMBER;
|
|
SProp[eCountry].ulPropTag = PR_BUSINESS_ADDRESS_COUNTRY;
|
|
|
|
// if there is a copany name .. it ends up as the Display Name .. so we need to try and
|
|
// create a display name ..
|
|
if(SProp[eDisplayName].ulPropTag == PR_NULL)
|
|
{
|
|
LPTSTR lpFirst = SProp[eFname].Value.LPSZ;
|
|
LPTSTR lpLast = SProp[eLname].Value.LPSZ;
|
|
LPTSTR lpMiddle = szEmpty;
|
|
if(SetLocalizedDisplayName(lpFirst, lpMiddle, lpLast, NULL, NULL,
|
|
NULL, 0, bDNisByLN, NULL, &lpDisplayName))
|
|
{
|
|
SProp[eDisplayName].Value.LPSZ = lpDisplayName;
|
|
SProp[eDisplayName].ulPropTag = PR_DISPLAY_NAME;
|
|
}
|
|
else
|
|
SProp[eDisplayName].ulPropTag = PR_NULL;
|
|
}
|
|
}
|
|
|
|
if(lstrlen(SProp[eAddr2].Value.LPSZ))
|
|
{
|
|
ULONG cchSize = lstrlen(SProp[eAddr1].Value.LPSZ) +
|
|
lstrlen(SProp[eAddr2].Value.LPSZ) +
|
|
lstrlen(szCRLF) + 1;
|
|
|
|
if(lpAddress = LocalAlloc(LMEM_ZEROINIT,sizeof(TCHAR)*cchSize))
|
|
{
|
|
StrCpyN(lpAddress, szEmpty, cchSize);
|
|
StrCatBuff(lpAddress, SProp[eAddr1].Value.LPSZ, cchSize);
|
|
StrCatBuff(lpAddress, szCRLF, cchSize);
|
|
StrCatBuff(lpAddress, SProp[eAddr2].Value.LPSZ, cchSize);
|
|
SProp[eAddr1].Value.LPSZ = lpAddress;
|
|
}
|
|
}
|
|
|
|
if(lstrlen(SProp[eAreaCode].Value.LPSZ))
|
|
{
|
|
ULONG cchSize = lstrlen(SProp[eAreaCode].Value.LPSZ)+lstrlen(SProp[ePhone].Value.LPSZ)+1;
|
|
if(cchSize < MAX_PATH)
|
|
{
|
|
StrCatBuff(SProp[eAreaCode].Value.LPSZ, TEXT(" "), cchSize);
|
|
StrCatBuff(SProp[eAreaCode].Value.LPSZ, SProp[ePhone].Value.LPSZ, cchSize);
|
|
SProp[ePhone].Value.LPSZ = SProp[eAreaCode].Value.LPSZ;
|
|
}
|
|
}
|
|
|
|
// need to get the country code from the current user locale since the regwizard uses
|
|
// some internal code of it's own ..
|
|
if(GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SENGCOUNTRY,
|
|
(LPTSTR) SProp[eCountry].Value.LPSZ, MAX_PATH) < 0)
|
|
{
|
|
SProp[eCountry].ulPropTag = PR_NULL;
|
|
}
|
|
|
|
cValues = eMax;
|
|
RegCloseKey(hKey);
|
|
}
|
|
else
|
|
{
|
|
// We will give this new entry 2 propertys
|
|
// - a display name and PR_WAB_THISISME
|
|
SPropValue Prop;
|
|
TCHAR szName[MAX_PATH];
|
|
DWORD dwName = CharSizeOf(szName);
|
|
|
|
// To get a display name, first query the users logon name
|
|
// If no name, use something generic like "Your Name"
|
|
if(!lpszProfileName && !GetUserName(szName, &dwName))
|
|
LoadString(hinstMapiX, idsYourName, szName, CharSizeOf(szName));
|
|
|
|
SProp[0].ulPropTag = PR_DISPLAY_NAME;
|
|
SProp[0].Value.LPSZ = lpszProfileName ? lpszProfileName : szName;
|
|
cValues = 1;
|
|
}
|
|
|
|
if(!HR_FAILED(hr = lpAdrBook->lpVtbl->GetPAB(lpAdrBook, &cbPABEID, &lpPABEID)))
|
|
{
|
|
hr = HrCreateNewEntry( lpAdrBook, hWndParent, MAPI_MAILUSER,
|
|
cbPABEID, lpPABEID, MAPI_ABCONT,// goes into the PAB container
|
|
0, bShowBeforeAdding,
|
|
cValues, SProp,
|
|
lpcbEID, lppbEID);
|
|
}
|
|
if(HR_FAILED(hr))
|
|
goto out;
|
|
|
|
if(lpdwAction)
|
|
*lpdwAction = WABOBJECT_ME_NEW;
|
|
|
|
out:
|
|
if(sz)
|
|
{
|
|
for(i=0;i<eMax;i++)
|
|
LocalFreeAndNull(&sz[i]);
|
|
LocalFree(sz);
|
|
}
|
|
LocalFreeAndNull(&lpDisplayName);
|
|
LocalFreeAndNull(&lpAddress);
|
|
FreeBufferAndNull(&lpPABEID);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*
|
|
- HrGetMeObject
|
|
-
|
|
* Purpose:
|
|
* Retrieves/creates the ME Object
|
|
*
|
|
* Returns:
|
|
* ulFlags - 0 or AB_NO_DIALOG
|
|
* If 0, shows a dialog,
|
|
* If AB_NO_DIALOG, creates a new object by stealth if it doesnt exist
|
|
* If AB_ME_NO_CREATE, fails if ME not found without creating new one
|
|
*
|
|
* lpdwAction - set to WABOBJECT_ME_NEW if new ME created
|
|
* lpsbEID - holds returned EID - the lpb member is MAPIAllocated and must be MAPIFreed
|
|
* ulReserved - reserved
|
|
*/
|
|
HRESULT HrGetMeObject(LPADRBOOK lpAdrBook,
|
|
ULONG ulFlags,
|
|
DWORD * lpdwAction,
|
|
SBinary * lpsbEID,
|
|
ULONG_PTR ulReserved)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
SBinary sbMe = {0};
|
|
SCODE sc;
|
|
HWND hWndParent = (HWND) ulReserved;
|
|
LPIAB lpIAB = (LPIAB)lpAdrBook;
|
|
|
|
if(!lpsbEID || !lpIAB)
|
|
{
|
|
hr = MAPI_E_INVALID_PARAMETER;
|
|
goto out;
|
|
}
|
|
|
|
if(HR_FAILED(hr = HrFindMe(lpAdrBook, &sbMe, NULL)))
|
|
goto out;
|
|
|
|
if(sbMe.cb && sbMe.lpb)
|
|
{
|
|
// return the first item out of the rgsbEIDs array (ideally there should be only one)
|
|
(*lpsbEID).cb = sbMe.cb;
|
|
(*lpsbEID).lpb = sbMe.lpb;
|
|
|
|
if(lpdwAction)
|
|
*lpdwAction = 0;
|
|
}
|
|
else
|
|
{
|
|
if(ulFlags & WABOBJECT_ME_NOCREATE)
|
|
{
|
|
hr = MAPI_E_NOT_FOUND;
|
|
goto out;
|
|
}
|
|
|
|
if(ulFlags & AB_NO_DIALOG)
|
|
{
|
|
// nothing found .. we have to create a new entry
|
|
|
|
if(HR_FAILED(hr = HrCreatePrePopulatedMe(lpAdrBook, FALSE, NULL,
|
|
&(lpsbEID->cb), (LPENTRYID *) &(lpsbEID->lpb), lpdwAction)))
|
|
goto out;
|
|
}
|
|
else
|
|
{
|
|
// Need to show the dialog that lets user create a new entry or select an existing entry
|
|
hr = HrShowSelectMeDialog(lpIAB, hWndParent, TRUE, NULL, lpsbEID, lpdwAction);
|
|
if(HR_FAILED(hr))
|
|
goto out;
|
|
}
|
|
|
|
if(lpsbEID->cb && lpsbEID->lpb)
|
|
{
|
|
hr = HrSetMe(lpAdrBook, lpsbEID, FALSE);
|
|
}
|
|
}
|
|
out:
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
- HrSetMeObject
|
|
-
|
|
* Purpose:
|
|
* Retrieves/creates the ME Object
|
|
*
|
|
* Returns:
|
|
* ulFlags - 0 or MAPI_DIALOG
|
|
* If no entryid is passed in, and MAPI_DIALOG is specified, a dialog pops up
|
|
* asking the user to create a ME or to select a ME object .. the selection in the SetMe
|
|
* dialog is set to the current ME object, if any
|
|
* If no entryid is passed in, and MAPI_DIALOG is not specified, the function fails
|
|
* If an entryid is passed in, and MAPI_DIALOG is specified, the SetME dialog is displayed
|
|
* with the corresponding entryid-object selected in it
|
|
* If an entryid is passed in, and MAPI_DIALOG is not specified, the entryid, if exists, is
|
|
* set as the ME object and the old ME object stripped
|
|
*/
|
|
HRESULT HrSetMeObject(LPADRBOOK lpAdrBook, ULONG ulFlags, SBinary sbEID, ULONG_PTR ulParam)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
SBinary sbOut = {0};
|
|
SBinary sbIn = {0};
|
|
LPIAB lpIAB = (LPIAB) lpAdrBook;
|
|
|
|
if(!(ulFlags & MAPI_DIALOG) && !sbEID.lpb)
|
|
goto out;
|
|
|
|
if(sbEID.cb && sbEID.lpb)
|
|
sbIn = sbEID;
|
|
else
|
|
{
|
|
if(HR_FAILED(hr = HrFindMe(lpAdrBook, &sbIn, NULL)))
|
|
goto out;
|
|
}
|
|
|
|
if(ulFlags & MAPI_DIALOG)
|
|
{
|
|
// Need to show the dialog that lets user create a new entry or select an existing entry
|
|
hr = HrShowSelectMeDialog(lpIAB, (HWND) ulParam, FALSE, &sbIn, &sbOut, NULL);
|
|
if(HR_FAILED(hr))
|
|
goto out;
|
|
}
|
|
else
|
|
{
|
|
sbOut = sbEID;
|
|
}
|
|
|
|
if(sbOut.cb && sbOut.lpb)
|
|
{
|
|
hr = HrSetMe(lpAdrBook, &sbOut, TRUE);
|
|
}
|
|
|
|
out:
|
|
if(sbOut.lpb != sbEID.lpb)
|
|
MAPIFreeBuffer(sbOut.lpb);
|
|
if(sbIn.lpb != sbEID.lpb)
|
|
MAPIFreeBuffer(sbIn.lpb);
|
|
|
|
return hr;
|
|
}
|