Windows2003-3790/inetcore/outlookexpress/wabw/wabapi/me.c
2020-09-30 16:53:55 +02:00

888 lines
30 KiB
C

/*
-
- 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;
}