Leaked source code of windows server 2003
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

  1. /*
  2. -
  3. - me.c
  4. -
  5. * Contains code for handling the ME object that represents the user
  6. *
  7. */
  8. #include "_apipch.h"
  9. HRESULT HrCreatePrePopulatedMe(LPADRBOOK lpIAB,
  10. BOOL bShowBeforeAdding, HWND hWndParent,
  11. ULONG * lpcbEID, LPENTRYID * lppbEID, DWORD * lpdwAction);
  12. typedef struct _SetMeParams
  13. {
  14. LPIAB lpIAB;
  15. BOOL bGetMe; // Get operation or Set operation
  16. LPSBinary lpsbIn;
  17. SBinary sbOut; // Will contain a pointer to the returned EID
  18. BOOL bCreateNew; // New item created as a result of this or not
  19. LPRECIPIENT_INFO lpList;
  20. } SETMEPARAMS, * LPSETMEPARAMS;
  21. // [PaulHi] 2/3/99 Raid 69884 Unique default GUID to store non-identity aware
  22. // profile tags
  23. // {5188FAFD-BC52-11d2-B36A-00C04F72E62D}
  24. #include <initguid.h>
  25. DEFINE_GUID(GUID_DEFAULT_PROFILE_ID,
  26. 0x5188fafd, 0xbc52, 0x11d2, 0xb3, 0x6a, 0x0, 0xc0, 0x4f, 0x72, 0xe6, 0x2d);
  27. static DWORD rgDLHelpIDs[] =
  28. {
  29. IDC_SETME_RADIO_CREATE, IDH_WAB_CHOOSE_PROFILE_CREATE_NEW,
  30. IDC_SETME_RADIO_SELECT, IDH_WAB_CHOOSE_PROFILE_SELECTFROM,
  31. IDC_SETME_LIST, IDH_WAB_CHOOSE_PROFILE_LIST,
  32. IDD_DIALOG_SETME, IDH_WAB_CHOOSE_PROFILE_LIST,
  33. 0,0
  34. };
  35. /*
  36. -
  37. - EnableSelectWindow
  38. *
  39. */
  40. void EnableSelectLVWindow(HWND hWndLV, BOOL bSelect)
  41. {
  42. // if this is being disabled, remove the LVS_SHOWSELALWAYS style
  43. // else add the style
  44. DWORD dwStyle = GetWindowLong(hWndLV, GWL_STYLE);
  45. if(bSelect)
  46. dwStyle |= LVS_SHOWSELALWAYS;
  47. else
  48. dwStyle &= ~LVS_SHOWSELALWAYS;
  49. SetWindowLong(hWndLV, GWL_STYLE, dwStyle);
  50. EnableWindow(hWndLV, bSelect);
  51. }
  52. /*
  53. -
  54. - HrFindMe
  55. -
  56. * sbMe - me item's entryid
  57. *
  58. * If this is an identity aware WAB, then this function finds the ME for the current
  59. * identity or the ME for the default identity if there isn't a current one
  60. *
  61. *
  62. */
  63. HRESULT HrFindMe(LPADRBOOK lpAdrBook, LPSBinary lpsbMe, LPTSTR lpProfileID)
  64. {
  65. SPropertyRestriction SPropRes = {0};
  66. ULONG ulcEIDCount = 1,i=0;
  67. LPSBinary rgsbEIDs = NULL;
  68. HRESULT hr = E_FAIL;
  69. SCODE sc;
  70. LPIAB lpIAB = (LPIAB)lpAdrBook;
  71. TCHAR szProfileID[MAX_PATH];
  72. ULONG ulcValues = 0;
  73. LPSPropValue lpPropArray = NULL;
  74. SizedSPropTagArray(1, MEProps) =
  75. {
  76. 1, { PR_WAB_USER_PROFILEID }
  77. };
  78. // [PaulHi] 2/3/99 Raid 69884
  79. // We have to at least get the default identity GUID or error out. Otherwise the
  80. // PR_WAB_USER_PROFILEID property is invalid and later references to the profile
  81. // "me" contact will be erroneous.
  82. *szProfileID = '\0';
  83. if(lpProfileID && lstrlen(lpProfileID))
  84. StrCpyN(szProfileID, lpProfileID, ARRAYSIZE(szProfileID));
  85. else if(bAreWABAPIProfileAware(lpIAB))
  86. {
  87. if ( bDoesThisWABHaveAnyUsers(lpIAB) &&
  88. bIsThereACurrentUser(lpIAB) &&
  89. lpIAB->szProfileID &&
  90. lstrlen(lpIAB->szProfileID) )
  91. {
  92. StrCpyN(szProfileID,lpIAB->szProfileID, ARRAYSIZE(szProfileID));
  93. }
  94. else
  95. {
  96. if(HR_FAILED(hr = HrGetDefaultIdentityInfo(lpIAB, DEFAULT_ID_PROFILEID,NULL, szProfileID, ARRAYSIZE(szProfileID), NULL, 0)))
  97. goto out;
  98. }
  99. }
  100. else
  101. HrGetUserProfileID((GUID *)&GUID_DEFAULT_PROFILE_ID, szProfileID, MAX_PATH-1);
  102. SPropRes.ulPropTag = PR_WAB_THISISME;
  103. SPropRes.relop = RELOP_EQ;
  104. SPropRes.lpProp = NULL;
  105. // We do a search in the WAB for entries containing the
  106. // PR_WAB_THISISME property. There should be only one such entry.
  107. // BUGBUG <JasonSo>: Need to ensure somewhere that the ME record is always
  108. // in the default container.
  109. hr = FindRecords(lpIAB->lpPropertyStore->hPropertyStore,
  110. NULL,
  111. AB_MATCH_PROP_ONLY,
  112. TRUE,
  113. &SPropRes,
  114. &ulcEIDCount, &rgsbEIDs);
  115. if(HR_FAILED(hr) || !rgsbEIDs || !ulcEIDCount)
  116. goto out;
  117. for(i=0;i<ulcEIDCount;i++)
  118. {
  119. // Need to open each item and look at it's ProfileID if any
  120. if(!HR_FAILED(HrGetPropArray(lpAdrBook, (LPSPropTagArray)&MEProps,
  121. rgsbEIDs[i].cb, (LPENTRYID)rgsbEIDs[i].lpb,
  122. MAPI_UNICODE,
  123. &ulcValues, &lpPropArray)))
  124. {
  125. if(ulcValues && lpPropArray)
  126. {
  127. if( lpPropArray[0].ulPropTag == PR_WAB_USER_PROFILEID &&
  128. !lstrcmpi(lpPropArray[0].Value.LPSZ, szProfileID))
  129. {
  130. // match
  131. // return the first item out of the rgsbEIDs array (ideally there should be only one)
  132. lpsbMe->cb = rgsbEIDs[i].cb;
  133. if (FAILED(sc = MAPIAllocateBuffer(lpsbMe->cb, (LPVOID *) (&(lpsbMe->lpb)))))
  134. {
  135. hr = MAPI_E_NOT_ENOUGH_MEMORY;
  136. goto out;
  137. }
  138. CopyMemory(lpsbMe->lpb, rgsbEIDs[i].lpb, lpsbMe->cb);
  139. break;
  140. }
  141. FreeBufferAndNull(&lpPropArray);
  142. }
  143. }
  144. }
  145. FreeEntryIDs(lpIAB->lpPropertyStore->hPropertyStore,
  146. ulcEIDCount, rgsbEIDs);
  147. out:
  148. FreeBufferAndNull(&lpPropArray);
  149. return hr;
  150. }
  151. /*
  152. -
  153. - HrSetMe
  154. -
  155. * Sets the actual ME property on a given entryid
  156. *
  157. * if bResetOldMe is TRUE, finds the old ME and
  158. * deletes the ME property off the old ME
  159. *
  160. */
  161. HRESULT HrSetMe(LPADRBOOK lpAdrBook, LPSBinary lpsb, BOOL bResetOldMe)
  162. {
  163. LPMAILUSER lpMU = NULL, lpMUOld = 0;
  164. SBinary sbOld = {0};
  165. HRESULT hr = E_FAIL;
  166. SPropValue Prop[2];
  167. ULONG ulObjType = 0;
  168. TCHAR szProfileID[MAX_PATH];
  169. LPIAB lpIAB = (LPIAB)lpAdrBook;
  170. if(!lpsb || !lpsb->cb || !lpsb->lpb)
  171. goto out;
  172. Prop[0].ulPropTag = PR_WAB_THISISME;
  173. Prop[0].Value.l = 0; // Value doesnt matter, only existence of this prop matters
  174. // [PaulHi] 2/3/99 Raid 69884
  175. // We have to at least get the default identity GUID or error out. Otherwise the
  176. // PR_WAB_USER_PROFILEID property is invalid and later references to the profile
  177. // "me" contact will be erroneous.
  178. *szProfileID = '\0';
  179. if(bAreWABAPIProfileAware(lpIAB))
  180. {
  181. if ( bDoesThisWABHaveAnyUsers(lpIAB) &&
  182. bIsThereACurrentUser(lpIAB) &&
  183. lpIAB->szProfileID &&
  184. lstrlen(lpIAB->szProfileID) )
  185. {
  186. StrCpyN(szProfileID,lpIAB->szProfileID, ARRAYSIZE(szProfileID));
  187. }
  188. else
  189. {
  190. if(HR_FAILED(hr = HrGetDefaultIdentityInfo(lpIAB, DEFAULT_ID_PROFILEID,NULL, szProfileID, ARRAYSIZE(szProfileID), NULL, 0)))
  191. goto out;
  192. }
  193. }
  194. else
  195. HrGetUserProfileID((GUID *)&GUID_DEFAULT_PROFILE_ID, szProfileID, MAX_PATH-1);
  196. Prop[1].ulPropTag = PR_WAB_USER_PROFILEID;
  197. Prop[1].Value.LPSZ = szProfileID;
  198. if(bResetOldMe)
  199. {
  200. if(HR_FAILED(hr = HrFindMe(lpAdrBook, &sbOld, szProfileID)))
  201. goto out;
  202. if(sbOld.cb && sbOld.lpb)
  203. {
  204. SizedSPropTagArray(1, ptaOldMe)=
  205. {
  206. 1, PR_WAB_THISISME
  207. };
  208. if (HR_FAILED(hr = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook, sbOld.cb, (LPENTRYID) sbOld.lpb,
  209. NULL, MAPI_MODIFY, &ulObjType, (LPUNKNOWN *)&lpMUOld)))
  210. goto out;
  211. if(HR_FAILED(hr = lpMUOld->lpVtbl->DeleteProps(lpMUOld, (LPSPropTagArray) &ptaOldMe, NULL)))
  212. goto out;
  213. if(HR_FAILED(hr = lpMUOld->lpVtbl->SaveChanges(lpMUOld, 0)))
  214. goto out;
  215. }
  216. }
  217. if (HR_FAILED(hr = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook, lpsb->cb, (LPENTRYID) lpsb->lpb,
  218. NULL, MAPI_MODIFY, &ulObjType,
  219. (LPUNKNOWN *)&lpMU)))
  220. {
  221. DebugPrintError(( TEXT("IAB->OpenEntry: %x"), hr));
  222. goto out;
  223. }
  224. if(HR_FAILED(hr = lpMU->lpVtbl->SetProps(lpMU,
  225. (lstrlen(szProfileID) ? 2 : 1), //in case we don't have a profile or default profile, don't set the prop
  226. Prop, NULL)))
  227. goto out;
  228. if(HR_FAILED(hr = lpMU->lpVtbl->SaveChanges(lpMU, 0)))
  229. goto out;
  230. out:
  231. if(sbOld.lpb)
  232. MAPIFreeBuffer(sbOld.lpb);
  233. if(lpMU)
  234. lpMU->lpVtbl->Release(lpMU);
  235. if(lpMUOld)
  236. lpMUOld->lpVtbl->Release(lpMUOld);
  237. return hr;
  238. }
  239. /*
  240. -
  241. - fnSetMe
  242. -
  243. * Dialog Proc for the SetMe dialog
  244. * The dialog is displayed for calls to both set me or get me and so we have
  245. * to do a very few number of things seperately for each.
  246. *
  247. */
  248. INT_PTR CALLBACK fnSetMe(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  249. {
  250. LPSETMEPARAMS lpSMP = (LPSETMEPARAMS) GetWindowLongPtr(hDlg,DWLP_USER);
  251. switch(message)
  252. {
  253. case WM_INITDIALOG:
  254. {
  255. HWND hWndLV = GetDlgItem(hDlg, IDC_SETME_LIST);
  256. lpSMP = (LPSETMEPARAMS) lParam;
  257. SetWindowLongPtr(hDlg,DWLP_USER,lParam); //Save this for future reference
  258. // init the list view
  259. HrInitListView(hWndLV ,LVS_REPORT | LVS_SORTASCENDING, FALSE);
  260. // Normally we want the CreateNew button selected unless an existing
  261. // EID was passed in, in which case that item should be selected
  262. {
  263. BOOL bSelect = (lpSMP->lpsbIn && lpSMP->lpsbIn->lpb);
  264. CheckRadioButton(hDlg, IDC_SETME_RADIO_CREATE, IDC_SETME_RADIO_SELECT,
  265. ( bSelect ? IDC_SETME_RADIO_SELECT : IDC_SETME_RADIO_CREATE ) );
  266. EnableSelectLVWindow(hWndLV, bSelect);
  267. }
  268. {
  269. SORT_INFO sortinfo = {0};
  270. SPropertyRestriction PropRes = {0};
  271. SPropValue sp = {0};
  272. PropRes.ulPropTag = PR_OBJECT_TYPE;
  273. PropRes.relop = RELOP_EQ;
  274. sp.ulPropTag = PR_OBJECT_TYPE;
  275. sp.Value.l = MAPI_MAILUSER;
  276. PropRes.lpProp = &sp;
  277. // We need to fill the ListView with the WAB contacts (no distlists)
  278. if(!HR_FAILED(HrGetWABContentsList(lpSMP->lpIAB, sortinfo,
  279. NULL, &PropRes, 0, NULL, TRUE, &(lpSMP->lpList))))
  280. {
  281. HrFillListView(hWndLV, lpSMP->lpList);
  282. }
  283. }
  284. if(ListView_GetItemCount(hWndLV) <= 0)
  285. {
  286. EnableWindow(GetDlgItem(hDlg, IDC_SETME_RADIO_SELECT), FALSE);
  287. SetFocus(GetDlgItem(hDlg, IDC_SETME_RADIO_CREATE));
  288. }
  289. else
  290. {
  291. LVSelectItem(hWndLV, 0);
  292. if(lpSMP->lpsbIn && lpSMP->lpsbIn->lpb)
  293. {
  294. // We need to find this item and select it
  295. int nCount = ListView_GetItemCount(hWndLV);
  296. SetFocus(GetDlgItem(hDlg, IDC_SETME_RADIO_SELECT));
  297. while(nCount >= 0)
  298. {
  299. LPRECIPIENT_INFO lpItem = GetItemFromLV(hWndLV, nCount);
  300. if(lpItem && lpItem->bIsMe) // All ME items are tagged as such
  301. {
  302. if( lpSMP->lpsbIn->cb == lpItem->cbEntryID &&
  303. !memcmp(lpItem->lpEntryID, lpSMP->lpsbIn->lpb, lpSMP->lpsbIn->cb))
  304. {
  305. // it's a match
  306. LVSelectItem(hWndLV, nCount);
  307. EnableSelectLVWindow(hWndLV, TRUE);
  308. SetFocus(hWndLV);
  309. }
  310. else
  311. {
  312. // this is some other ME not corresponding to the current Identity
  313. // or the default identity so remove it from the window ..
  314. ListView_DeleteItem(hWndLV, nCount);
  315. }
  316. }
  317. nCount--;
  318. }
  319. }
  320. else
  321. SetFocus(GetDlgItem(hDlg, IDC_SETME_RADIO_CREATE));
  322. }
  323. }
  324. break;
  325. case WM_HELP:
  326. WABWinHelp(((LPHELPINFO)lParam)->hItemHandle,
  327. g_szWABHelpFileName,
  328. HELP_WM_HELP,
  329. (DWORD_PTR)(LPSTR) rgDLHelpIDs );
  330. break;
  331. case WM_CONTEXTMENU:
  332. WABWinHelp((HWND) wParam,
  333. g_szWABHelpFileName,
  334. HELP_CONTEXTMENU,
  335. (DWORD_PTR)(LPSTR) rgDLHelpIDs );
  336. break;
  337. case WM_COMMAND:
  338. switch (GET_WM_COMMAND_ID(wParam, lParam))
  339. {
  340. case IDOK:
  341. {
  342. int nID = IDOK;
  343. // Check if user said 'Create' or if user 'Selected'
  344. SBinary sb = {0};
  345. if(IsDlgButtonChecked(hDlg, IDC_SETME_RADIO_CREATE))
  346. {
  347. HRESULT hr = HrCreatePrePopulatedMe( (LPADRBOOK)lpSMP->lpIAB, TRUE, hDlg,
  348. &sb.cb, (LPENTRYID *)&(sb.lpb), NULL );
  349. if(hr == MAPI_E_USER_CANCEL)
  350. {
  351. return FALSE;
  352. }
  353. else if(HR_FAILED(hr))
  354. {
  355. ShowMessageBox(hDlg, idsCouldNotAddUserToWAB, MB_ICONEXCLAMATION | MB_OK);
  356. return FALSE;
  357. }
  358. else
  359. {
  360. lpSMP->sbOut.cb = sb.cb;
  361. lpSMP->sbOut.lpb = sb.lpb;
  362. lpSMP->bCreateNew = TRUE;
  363. }
  364. }
  365. else
  366. {
  367. // Get the current selection from the DLG
  368. HWND hWndLV = GetDlgItem(hDlg, IDC_SETME_LIST);
  369. if(ListView_GetSelectedCount(hWndLV) > 0)
  370. {
  371. int iItem = ListView_GetNextItem(hWndLV, -1, LVNI_SELECTED);
  372. if(iItem != -1)
  373. {
  374. LPRECIPIENT_INFO lpItem = GetItemFromLV(hWndLV, iItem);;
  375. lpSMP->sbOut.cb = lpItem->cbEntryID;
  376. if(!FAILED(MAPIAllocateBuffer(lpItem->cbEntryID, (LPVOID *) (&(lpSMP->sbOut.lpb)))))
  377. CopyMemory(lpSMP->sbOut.lpb, lpItem->lpEntryID, lpItem->cbEntryID);
  378. }
  379. }
  380. }
  381. EndDialog(hDlg, nID);
  382. }
  383. break;
  384. case IDCANCEL:
  385. EndDialog(hDlg, IDCANCEL);
  386. break;
  387. case IDC_SETME_RADIO_CREATE:
  388. case IDC_SETME_RADIO_SELECT:
  389. {
  390. HWND hWndLV = GetDlgItem(hDlg, IDC_SETME_LIST);
  391. if(ListView_GetItemCount(hWndLV) > 0)
  392. EnableSelectLVWindow(hWndLV, (GET_WM_COMMAND_ID(wParam, lParam) == IDC_SETME_RADIO_SELECT));
  393. }
  394. break;
  395. }
  396. break;
  397. }
  398. return FALSE;
  399. }
  400. /*
  401. -
  402. - HrShowSelectMeDialog
  403. -
  404. *
  405. * bGetMe - TRUE = GET, FALSE = SET
  406. * lpsbEIDin - EID of existing ME entry
  407. * lpsbEIDout - EID of selected ME entry
  408. *
  409. */
  410. HRESULT HrShowSelectMeDialog(LPIAB lpIAB, HWND hWndParent, BOOL bGetMe,
  411. LPSBinary lpsbEIDin, LPSBinary lpsbEIDout, DWORD * lpdwAction)
  412. {
  413. SETMEPARAMS smp = {0};
  414. HRESULT hr = S_OK;
  415. int nRetVal = 0;
  416. smp.lpIAB = lpIAB;
  417. smp.bGetMe = bGetMe;
  418. smp.lpsbIn = lpsbEIDin;
  419. nRetVal = (int) DialogBoxParam(hinstMapiX, MAKEINTRESOURCE(IDD_DIALOG_SETME),
  420. hWndParent, fnSetMe, (LPARAM) &smp);
  421. if(smp.lpList)
  422. FreeRecipList(&(smp.lpList));
  423. if(lpsbEIDout && smp.sbOut.cb && smp.sbOut.lpb)
  424. {
  425. lpsbEIDout->cb = smp.sbOut.cb;
  426. lpsbEIDout->lpb = smp.sbOut.lpb;
  427. }
  428. else if(smp.sbOut.lpb)
  429. MAPIFreeBuffer(smp.sbOut.lpb);
  430. if(lpdwAction && smp.bCreateNew)
  431. *lpdwAction = WABOBJECT_ME_NEW;
  432. if(nRetVal == IDCANCEL)
  433. hr = MAPI_E_USER_CANCEL;
  434. return hr;
  435. }
  436. typedef struct _RegWizardProp
  437. {
  438. ULONG ulPropTag;
  439. LPTSTR szRegElement;
  440. } REGWIZARDPROP, * LPREGWIZARDPROP;
  441. extern BOOL bDNisByLN;
  442. /*
  443. - HrCreatePrePopulated Me
  444. -
  445. * Attempts to prepopulate the Me entry from RegWizard information from the registry
  446. * (Note that the regwizard only exists on win98 and NT5)
  447. *
  448. */
  449. HRESULT HrCreatePrePopulatedMe(LPADRBOOK lpAdrBook,
  450. BOOL bShowBeforeAdding, HWND hWndParent,
  451. ULONG * lpcbEID, LPENTRYID * lppbEID, DWORD * lpdwAction)
  452. {
  453. LPTSTR lpszRegWizKey = TEXT("Software\\Microsoft\\User Information");
  454. enum _RegWizElements
  455. {
  456. eDisplayName=0,
  457. eFname,
  458. eLname,
  459. eCompanyName,
  460. eEmailName,
  461. eAddr1,
  462. eAddr2,
  463. eCity,
  464. eState,
  465. eZip,
  466. eAreaCode,
  467. ePhone,
  468. eCountry,
  469. eMax,
  470. };
  471. REGWIZARDPROP rgRegWizElement[] =
  472. {
  473. { PR_DISPLAY_NAME, TEXT("DisplayNameX") }, // this is a fake one, it doesn't actually exist
  474. { PR_GIVEN_NAME, TEXT("Default First Name") },
  475. { PR_SURNAME, TEXT("Default Last Name") },
  476. { PR_COMPANY_NAME, TEXT("Default Company") },
  477. { PR_EMAIL_ADDRESS, TEXT("E-mail Address") },
  478. { PR_HOME_ADDRESS_STREET, TEXT("Mailing Address") },
  479. { PR_NULL, TEXT("Additional Address") },
  480. { PR_HOME_ADDRESS_CITY, TEXT("City") },
  481. { PR_HOME_ADDRESS_STATE_OR_PROVINCE, TEXT("State") },
  482. { PR_HOME_ADDRESS_POSTAL_CODE, TEXT("ZIP Code") },
  483. { PR_NULL, TEXT("AreaCode") },
  484. { PR_HOME_TELEPHONE_NUMBER, TEXT("Daytime Phone") },
  485. { PR_HOME_ADDRESS_COUNTRY, TEXT("Country") }, //this is fake - we will read this from the system locale
  486. };
  487. SPropValue SProp[eMax];
  488. LPTSTR lpAddress = NULL;
  489. LPTSTR lpDisplayName = NULL;
  490. ULONG cValues = 0;
  491. ULONG i = 0;
  492. HRESULT hr = S_OK;
  493. HKEY hKey = NULL;
  494. // in case there is an identity, use the identities name ...
  495. TCHAR lpszProfileName[MAX_PATH];
  496. LPIAB lpIAB = (LPIAB)lpAdrBook;
  497. LPTSTR * sz = NULL;
  498. ULONG cbPABEID = 0;
  499. LPENTRYID lpPABEID = NULL;
  500. if(!(sz = LocalAlloc(LMEM_ZEROINIT, sizeof(LPTSTR)*eMax)))
  501. {
  502. hr = MAPI_E_NOT_ENOUGH_MEMORY;
  503. goto out;
  504. }
  505. for(i=0;i<eMax;i++)
  506. {
  507. if(!(sz[i] = LocalAlloc(LMEM_ZEROINIT, sizeof(TCHAR)*MAX_PATH)))
  508. {
  509. hr = MAPI_E_NOT_ENOUGH_MEMORY;
  510. goto out;
  511. }
  512. }
  513. *lpszProfileName = '\0';
  514. // if identities are registered, use the current identity or the default identity
  515. if(bDoesThisWABHaveAnyUsers(lpIAB))
  516. {
  517. if(bIsThereACurrentUser(lpIAB) && lpIAB->szProfileName && lstrlen(lpIAB->szProfileName))
  518. {
  519. StrCpyN(lpszProfileName,lpIAB->szProfileName, ARRAYSIZE(lpszProfileName));
  520. }
  521. else
  522. {
  523. TCHAR szDefProfile[MAX_PATH];
  524. if(HR_FAILED(hr = HrGetDefaultIdentityInfo(lpIAB, DEFAULT_ID_PROFILEID | DEFAULT_ID_NAME,
  525. NULL, szDefProfile, ARRAYSIZE(szDefProfile), lpszProfileName, 0)))
  526. {
  527. if(hr == 0x80040154) // E_CLASS_NOT_REGISTERD means no IDentity Manager
  528. hr = S_OK;
  529. else
  530. goto out;
  531. }
  532. }
  533. }
  534. // Get the data from the registry
  535. if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpszRegWizKey, 0, KEY_READ, &hKey))
  536. {
  537. DWORD dwType = REG_SZ;
  538. for(i=0;i<eMax;i++)
  539. {
  540. ULONG ulErr = 0;
  541. DWORD dwSize = MAX_PATH;
  542. *(sz[i]) = '\0';
  543. SProp[i].ulPropTag = rgRegWizElement[i].ulPropTag;
  544. SProp[i].Value.LPSZ = sz[i];
  545. ulErr = RegQueryValueEx( hKey, rgRegWizElement[i].szRegElement, NULL, &dwType, (LPBYTE) sz[i], &dwSize );
  546. if(ulErr != ERROR_SUCCESS)
  547. DebugTrace(TEXT("oooo> RegQueryValueEx failed: %d\n"),ulErr);
  548. }
  549. if(lpszProfileName && lstrlen(lpszProfileName))
  550. {
  551. SProp[eDisplayName].ulPropTag = PR_DISPLAY_NAME;
  552. SProp[eDisplayName].Value.LPSZ = lpszProfileName;
  553. }
  554. else
  555. {
  556. SProp[eDisplayName].ulPropTag = PR_NULL;
  557. }
  558. // Need to do some cleanup and adjustment to the data
  559. if(SProp[eCompanyName].ulPropTag == PR_COMPANY_NAME && lstrlen(SProp[eCompanyName].Value.LPSZ))
  560. {
  561. // This is a company address
  562. SProp[eAddr1].ulPropTag = PR_BUSINESS_ADDRESS_STREET;
  563. SProp[eCity].ulPropTag = PR_BUSINESS_ADDRESS_CITY;
  564. SProp[eState].ulPropTag = PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE;
  565. SProp[eZip].ulPropTag = PR_BUSINESS_ADDRESS_POSTAL_CODE;
  566. SProp[ePhone].ulPropTag = PR_BUSINESS_TELEPHONE_NUMBER;
  567. SProp[eCountry].ulPropTag = PR_BUSINESS_ADDRESS_COUNTRY;
  568. // if there is a copany name .. it ends up as the Display Name .. so we need to try and
  569. // create a display name ..
  570. if(SProp[eDisplayName].ulPropTag == PR_NULL)
  571. {
  572. LPTSTR lpFirst = SProp[eFname].Value.LPSZ;
  573. LPTSTR lpLast = SProp[eLname].Value.LPSZ;
  574. LPTSTR lpMiddle = szEmpty;
  575. if(SetLocalizedDisplayName(lpFirst, lpMiddle, lpLast, NULL, NULL,
  576. NULL, 0, bDNisByLN, NULL, &lpDisplayName))
  577. {
  578. SProp[eDisplayName].Value.LPSZ = lpDisplayName;
  579. SProp[eDisplayName].ulPropTag = PR_DISPLAY_NAME;
  580. }
  581. else
  582. SProp[eDisplayName].ulPropTag = PR_NULL;
  583. }
  584. }
  585. if(lstrlen(SProp[eAddr2].Value.LPSZ))
  586. {
  587. ULONG cchSize = lstrlen(SProp[eAddr1].Value.LPSZ) +
  588. lstrlen(SProp[eAddr2].Value.LPSZ) +
  589. lstrlen(szCRLF) + 1;
  590. if(lpAddress = LocalAlloc(LMEM_ZEROINIT,sizeof(TCHAR)*cchSize))
  591. {
  592. StrCpyN(lpAddress, szEmpty, cchSize);
  593. StrCatBuff(lpAddress, SProp[eAddr1].Value.LPSZ, cchSize);
  594. StrCatBuff(lpAddress, szCRLF, cchSize);
  595. StrCatBuff(lpAddress, SProp[eAddr2].Value.LPSZ, cchSize);
  596. SProp[eAddr1].Value.LPSZ = lpAddress;
  597. }
  598. }
  599. if(lstrlen(SProp[eAreaCode].Value.LPSZ))
  600. {
  601. ULONG cchSize = lstrlen(SProp[eAreaCode].Value.LPSZ)+lstrlen(SProp[ePhone].Value.LPSZ)+1;
  602. if(cchSize < MAX_PATH)
  603. {
  604. StrCatBuff(SProp[eAreaCode].Value.LPSZ, TEXT(" "), cchSize);
  605. StrCatBuff(SProp[eAreaCode].Value.LPSZ, SProp[ePhone].Value.LPSZ, cchSize);
  606. SProp[ePhone].Value.LPSZ = SProp[eAreaCode].Value.LPSZ;
  607. }
  608. }
  609. // need to get the country code from the current user locale since the regwizard uses
  610. // some internal code of it's own ..
  611. if(GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SENGCOUNTRY,
  612. (LPTSTR) SProp[eCountry].Value.LPSZ, MAX_PATH) < 0)
  613. {
  614. SProp[eCountry].ulPropTag = PR_NULL;
  615. }
  616. cValues = eMax;
  617. RegCloseKey(hKey);
  618. }
  619. else
  620. {
  621. // We will give this new entry 2 propertys
  622. // - a display name and PR_WAB_THISISME
  623. SPropValue Prop;
  624. TCHAR szName[MAX_PATH];
  625. DWORD dwName = CharSizeOf(szName);
  626. // To get a display name, first query the users logon name
  627. // If no name, use something generic like "Your Name"
  628. if(!lpszProfileName && !GetUserName(szName, &dwName))
  629. LoadString(hinstMapiX, idsYourName, szName, CharSizeOf(szName));
  630. SProp[0].ulPropTag = PR_DISPLAY_NAME;
  631. SProp[0].Value.LPSZ = lpszProfileName ? lpszProfileName : szName;
  632. cValues = 1;
  633. }
  634. if(!HR_FAILED(hr = lpAdrBook->lpVtbl->GetPAB(lpAdrBook, &cbPABEID, &lpPABEID)))
  635. {
  636. hr = HrCreateNewEntry( lpAdrBook, hWndParent, MAPI_MAILUSER,
  637. cbPABEID, lpPABEID, MAPI_ABCONT,// goes into the PAB container
  638. 0, bShowBeforeAdding,
  639. cValues, SProp,
  640. lpcbEID, lppbEID);
  641. }
  642. if(HR_FAILED(hr))
  643. goto out;
  644. if(lpdwAction)
  645. *lpdwAction = WABOBJECT_ME_NEW;
  646. out:
  647. if(sz)
  648. {
  649. for(i=0;i<eMax;i++)
  650. LocalFreeAndNull(&sz[i]);
  651. LocalFree(sz);
  652. }
  653. LocalFreeAndNull(&lpDisplayName);
  654. LocalFreeAndNull(&lpAddress);
  655. FreeBufferAndNull(&lpPABEID);
  656. return hr;
  657. }
  658. /*
  659. - HrGetMeObject
  660. -
  661. * Purpose:
  662. * Retrieves/creates the ME Object
  663. *
  664. * Returns:
  665. * ulFlags - 0 or AB_NO_DIALOG
  666. * If 0, shows a dialog,
  667. * If AB_NO_DIALOG, creates a new object by stealth if it doesnt exist
  668. * If AB_ME_NO_CREATE, fails if ME not found without creating new one
  669. *
  670. * lpdwAction - set to WABOBJECT_ME_NEW if new ME created
  671. * lpsbEID - holds returned EID - the lpb member is MAPIAllocated and must be MAPIFreed
  672. * ulReserved - reserved
  673. */
  674. HRESULT HrGetMeObject(LPADRBOOK lpAdrBook,
  675. ULONG ulFlags,
  676. DWORD * lpdwAction,
  677. SBinary * lpsbEID,
  678. ULONG_PTR ulReserved)
  679. {
  680. HRESULT hr = S_OK;
  681. SBinary sbMe = {0};
  682. SCODE sc;
  683. HWND hWndParent = (HWND) ulReserved;
  684. LPIAB lpIAB = (LPIAB)lpAdrBook;
  685. if(!lpsbEID || !lpIAB)
  686. {
  687. hr = MAPI_E_INVALID_PARAMETER;
  688. goto out;
  689. }
  690. if(HR_FAILED(hr = HrFindMe(lpAdrBook, &sbMe, NULL)))
  691. goto out;
  692. if(sbMe.cb && sbMe.lpb)
  693. {
  694. // return the first item out of the rgsbEIDs array (ideally there should be only one)
  695. (*lpsbEID).cb = sbMe.cb;
  696. (*lpsbEID).lpb = sbMe.lpb;
  697. if(lpdwAction)
  698. *lpdwAction = 0;
  699. }
  700. else
  701. {
  702. if(ulFlags & WABOBJECT_ME_NOCREATE)
  703. {
  704. hr = MAPI_E_NOT_FOUND;
  705. goto out;
  706. }
  707. if(ulFlags & AB_NO_DIALOG)
  708. {
  709. // nothing found .. we have to create a new entry
  710. if(HR_FAILED(hr = HrCreatePrePopulatedMe(lpAdrBook, FALSE, NULL,
  711. &(lpsbEID->cb), (LPENTRYID *) &(lpsbEID->lpb), lpdwAction)))
  712. goto out;
  713. }
  714. else
  715. {
  716. // Need to show the dialog that lets user create a new entry or select an existing entry
  717. hr = HrShowSelectMeDialog(lpIAB, hWndParent, TRUE, NULL, lpsbEID, lpdwAction);
  718. if(HR_FAILED(hr))
  719. goto out;
  720. }
  721. if(lpsbEID->cb && lpsbEID->lpb)
  722. {
  723. hr = HrSetMe(lpAdrBook, lpsbEID, FALSE);
  724. }
  725. }
  726. out:
  727. return hr;
  728. }
  729. /*
  730. - HrSetMeObject
  731. -
  732. * Purpose:
  733. * Retrieves/creates the ME Object
  734. *
  735. * Returns:
  736. * ulFlags - 0 or MAPI_DIALOG
  737. * If no entryid is passed in, and MAPI_DIALOG is specified, a dialog pops up
  738. * asking the user to create a ME or to select a ME object .. the selection in the SetMe
  739. * dialog is set to the current ME object, if any
  740. * If no entryid is passed in, and MAPI_DIALOG is not specified, the function fails
  741. * If an entryid is passed in, and MAPI_DIALOG is specified, the SetME dialog is displayed
  742. * with the corresponding entryid-object selected in it
  743. * If an entryid is passed in, and MAPI_DIALOG is not specified, the entryid, if exists, is
  744. * set as the ME object and the old ME object stripped
  745. */
  746. HRESULT HrSetMeObject(LPADRBOOK lpAdrBook, ULONG ulFlags, SBinary sbEID, ULONG_PTR ulParam)
  747. {
  748. HRESULT hr = E_FAIL;
  749. SBinary sbOut = {0};
  750. SBinary sbIn = {0};
  751. LPIAB lpIAB = (LPIAB) lpAdrBook;
  752. if(!(ulFlags & MAPI_DIALOG) && !sbEID.lpb)
  753. goto out;
  754. if(sbEID.cb && sbEID.lpb)
  755. sbIn = sbEID;
  756. else
  757. {
  758. if(HR_FAILED(hr = HrFindMe(lpAdrBook, &sbIn, NULL)))
  759. goto out;
  760. }
  761. if(ulFlags & MAPI_DIALOG)
  762. {
  763. // Need to show the dialog that lets user create a new entry or select an existing entry
  764. hr = HrShowSelectMeDialog(lpIAB, (HWND) ulParam, FALSE, &sbIn, &sbOut, NULL);
  765. if(HR_FAILED(hr))
  766. goto out;
  767. }
  768. else
  769. {
  770. sbOut = sbEID;
  771. }
  772. if(sbOut.cb && sbOut.lpb)
  773. {
  774. hr = HrSetMe(lpAdrBook, &sbOut, TRUE);
  775. }
  776. out:
  777. if(sbOut.lpb != sbEID.lpb)
  778. MAPIFreeBuffer(sbOut.lpb);
  779. if(sbIn.lpb != sbEID.lpb)
  780. MAPIFreeBuffer(sbIn.lpb);
  781. return hr;
  782. }