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.

936 lines
29 KiB

  1. /*
  2. * WABMIG.C
  3. *
  4. * Migrate PAB to WAB
  5. *
  6. * Copyright 1996-1997 Microsoft Corporation. All Rights Reserved.
  7. */
  8. #include "_comctl.h"
  9. #include <windows.h>
  10. #include <commctrl.h>
  11. #include <mapix.h>
  12. #include <wab.h>
  13. #include <wabguid.h>
  14. #include <wabdbg.h>
  15. #include <wabmig.h>
  16. #include <emsabtag.h>
  17. #define _WABMIG_C TRUE
  18. #include "_wabmig.h"
  19. #include "..\..\wab32res\resrc2.h"
  20. #include "dbgutil.h"
  21. #include <shlwapi.h>
  22. #define WinMainT WinMain
  23. const TCHAR szDescription[] = "description";
  24. const TCHAR szDll[] = "dll";
  25. const TCHAR szEntry[] = "entry";
  26. const TCHAR szEXPORT[] = "EXPORT";
  27. const TCHAR szIMPORT[] = "IMPORT";
  28. const TCHAR szPROFILEID[] = "PID:";
  29. const TCHAR szFILE[] = "File:";
  30. const TCHAR szEmpty[] = "";
  31. // Globals
  32. WAB_IMPORT_OPTIONS ImportOptions = {WAB_REPLACE_PROMPT, // replace option
  33. FALSE}; // No more errors
  34. WAB_EXPORT_OPTIONS ExportOptions = {WAB_REPLACE_PROMPT, // replace option
  35. FALSE}; // No more errors
  36. const LPTSTR szWABKey = "Software\\Microsoft\\WAB";
  37. LPTARGET_INFO rgTargetInfo = NULL;
  38. HINSTANCE hInst;
  39. HINSTANCE hInstApp;
  40. BOOL fMigrating = FALSE;
  41. BOOL fError = FALSE;
  42. BOOL fExport = FALSE;
  43. LPADRBOOK lpAdrBookWAB = NULL;
  44. LPWABOBJECT lpWABObject = NULL;
  45. LPTSTR lpImportDll = NULL;
  46. LPTSTR lpImportFn = NULL;
  47. LPTSTR lpImportDesc = NULL;
  48. LPTSTR lpImportName = NULL;
  49. LPTSTR lpExportDll = NULL;
  50. LPTSTR lpExportFn = NULL;
  51. LPTSTR lpExportDesc = NULL;
  52. LPTSTR lpExportName = NULL;
  53. //
  54. // Global WAB Allocator access functions
  55. //
  56. typedef struct _WAB_ALLOCATORS {
  57. LPWABOBJECT lpWABObject;
  58. LPWABALLOCATEBUFFER lpAllocateBuffer;
  59. LPWABALLOCATEMORE lpAllocateMore;
  60. LPWABFREEBUFFER lpFreeBuffer;
  61. } WAB_ALLOCATORS, *LPWAB_ALLOCATORS;
  62. WAB_ALLOCATORS WABAllocators = {0};
  63. /***************************************************************************
  64. Name : SetGlobalBufferFunctions
  65. Purpose : Set the global buffer functions based on methods from
  66. the WAB object.
  67. Parameters: lpWABObject = the open wab object
  68. Returns : none
  69. Comment :
  70. ***************************************************************************/
  71. void SetGlobalBufferFunctions(LPWABOBJECT lpWABObject) {
  72. if (lpWABObject && ! WABAllocators.lpWABObject) {
  73. WABAllocators.lpAllocateBuffer = lpWABObject->lpVtbl->AllocateBuffer;
  74. WABAllocators.lpAllocateMore = lpWABObject->lpVtbl->AllocateMore;
  75. WABAllocators.lpFreeBuffer = lpWABObject->lpVtbl->FreeBuffer;
  76. WABAllocators.lpWABObject = lpWABObject;
  77. }
  78. }
  79. /***************************************************************************
  80. Name : WABAllocateBuffer
  81. Purpose : Use the WAB Allocator
  82. Parameters: cbSize = size to allocate
  83. lppBuffer = returned buffer
  84. Returns : SCODE
  85. Comment :
  86. ***************************************************************************/
  87. SCODE WABAllocateBuffer(ULONG cbSize, LPVOID FAR * lppBuffer) {
  88. if (WABAllocators.lpWABObject && WABAllocators.lpAllocateBuffer) {
  89. return(WABAllocators.lpAllocateBuffer(WABAllocators.lpWABObject, cbSize, lppBuffer));
  90. } else {
  91. return(MAPI_E_INVALID_OBJECT);
  92. DebugTrace("WAB Allocators not set up!\n");
  93. Assert(FALSE);
  94. }
  95. }
  96. /***************************************************************************
  97. Name : WABAllocateMore
  98. Purpose : Use the WAB Allocator
  99. Parameters: cbSize = size to allocate
  100. lpObject = existing allocation
  101. lppBuffer = returned buffer
  102. Returns : SCODE
  103. Comment :
  104. ***************************************************************************/
  105. SCODE WABAllocateMore(ULONG cbSize, LPVOID lpObject, LPVOID FAR * lppBuffer) {
  106. if (WABAllocators.lpWABObject && WABAllocators.lpAllocateMore) {
  107. return(WABAllocators.lpAllocateMore(WABAllocators.lpWABObject, cbSize, lpObject, lppBuffer));
  108. } else {
  109. DebugTrace("WAB Allocators not set up!\n");
  110. Assert(FALSE);
  111. return(MAPI_E_INVALID_OBJECT);
  112. }
  113. }
  114. /***************************************************************************
  115. Name : WABFreeBuffer
  116. Purpose : Use the WAB Allocator
  117. Parameters: lpBuffer = buffer to free
  118. Returns : SCODE
  119. Comment :
  120. ***************************************************************************/
  121. SCODE WABFreeBuffer(LPVOID lpBuffer) {
  122. if (WABAllocators.lpWABObject && WABAllocators.lpFreeBuffer) {
  123. return(WABAllocators.lpFreeBuffer(WABAllocators.lpWABObject, lpBuffer));
  124. } else {
  125. DebugTrace("WAB Allocators not set up!\n");
  126. Assert(FALSE);
  127. return(MAPI_E_INVALID_OBJECT);
  128. }
  129. }
  130. /***************************************************************************
  131. Name : StrICmpN
  132. Purpose : Compare strings, ignore case, stop at N characters
  133. Parameters: szString1 = first string
  134. szString2 = second string
  135. N = number of characters to compare
  136. Returns : 0 if first N characters of strings are equivalent.
  137. Comment :
  138. ***************************************************************************/
  139. int StrICmpN(LPTSTR szString1, LPTSTR szString2, ULONG N) {
  140. int Result = 0;
  141. if (szString1 && szString2) {
  142. while (*szString1 && *szString2 && N)
  143. {
  144. N--;
  145. if (toupper(*szString1) != toupper(*szString2)) {
  146. Result = 1;
  147. break;
  148. }
  149. szString1++;
  150. szString2++;
  151. }
  152. } else {
  153. Result = -1; // arbitrarily non-equal result
  154. }
  155. return(Result);
  156. }
  157. /***************************************************************************
  158. Name : AllocRegValue
  159. Purpose : Allocate space for and query the registry value
  160. Parameters: hKey = registry key to query
  161. lpValueName = name of value to query
  162. lppString -> returned buffer string (caller must LocalFree)
  163. Returns : TRUE on success, FALSE on error
  164. Comment :
  165. ***************************************************************************/
  166. BOOL AllocRegValue(HKEY hKey, LPTSTR lpValueName, LPTSTR * lppString) {
  167. TCHAR szTemp[1];
  168. ULONG ulSize = 1; // Expect ERROR_MORE_DATA
  169. DWORD dwErr;
  170. DWORD dwType;
  171. if (dwErr = RegQueryValueEx(hKey,
  172. (LPTSTR)lpValueName, // name of value
  173. NULL,
  174. &dwType,
  175. szTemp,
  176. &ulSize)) {
  177. if (dwErr == ERROR_MORE_DATA) {
  178. if (! (*lppString = LocalAlloc(LPTR, ulSize))) {
  179. DebugTrace("AllocRegValue can't allocate string -> %u\n", GetLastError());
  180. } else {
  181. // Try again with sufficient buffer
  182. if (! RegQueryValueEx(hKey,
  183. lpValueName,
  184. NULL,
  185. &dwType,
  186. *lppString,
  187. &ulSize)) {
  188. if (dwType != REG_SZ) {
  189. LocalFree(*lppString);
  190. *lppString = NULL;
  191. } else {
  192. return(TRUE);
  193. }
  194. }
  195. }
  196. }
  197. }
  198. return(FALSE);
  199. }
  200. HRESULT ProgressCallback(HWND hwnd, LPWAB_PROGRESS lpProgress) {
  201. MSG msg;
  202. if (lpProgress->lpText) {
  203. DebugTrace("Status Message: %s\n", lpProgress->lpText);
  204. SetDlgItemText(hwnd, IDC_Message, lpProgress->lpText);
  205. }
  206. if (lpProgress->denominator) {
  207. if (lpProgress->numerator == 0) {
  208. ShowWindow(GetDlgItem(hwnd, IDC_Progress), SW_SHOW);
  209. }
  210. SendMessage(GetDlgItem(hwnd, IDC_Progress), PBM_SETRANGE, 0, MAKELPARAM(0, min(lpProgress->denominator, 32767)));
  211. SendMessage(GetDlgItem(hwnd, IDC_Progress), PBM_SETSTEP, (WPARAM)1, 0);
  212. SendMessage(GetDlgItem(hwnd, IDC_Progress), PBM_SETPOS, (WPARAM)min(lpProgress->numerator, lpProgress->denominator), 0);
  213. }
  214. // msgpump to process user moving window, or pressing cancel... :)
  215. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
  216. TranslateMessage(&msg);
  217. DispatchMessage(&msg);
  218. }
  219. return(hrSuccess);
  220. }
  221. /***************************************************************************
  222. Name : SetDialogMessage
  223. Purpose : Sets the message text for the dialog box item IDC_Message
  224. Parameters: hwnd = window handle of dialog
  225. ids = stringid of message resource
  226. Returns : none
  227. ***************************************************************************/
  228. void SetDialogMessage(HWND hwnd, int ids) {
  229. TCHAR szBuffer[MAX_RESOURCE_STRING + 1];
  230. if (LoadString(hInst, ids, szBuffer, sizeof(szBuffer))) {
  231. DebugTrace("Status Message: %s\n", szBuffer);
  232. if (! SetDlgItemText(hwnd, IDC_Message, szBuffer)) {
  233. DebugTrace("SetDlgItemText -> %u\n", GetLastError());
  234. }
  235. } else {
  236. DebugTrace("Cannot load resource string %u\n", ids);
  237. Assert(FALSE);
  238. }
  239. }
  240. /////////////////////////////////////////////////////////////////////////
  241. // GetWABDllPath - loads the WAB DLL path from the registry
  242. // szPath - ptr to buffer
  243. // cb - sizeof buffer
  244. //
  245. void GetWABDllPath(LPTSTR szPath, ULONG cb)
  246. {
  247. DWORD dwType = 0;
  248. HKEY hKey = NULL;
  249. TCHAR szPathT[MAX_PATH];
  250. ULONG cbData = sizeof(szPathT);
  251. if(szPath)
  252. {
  253. *szPath = '\0';
  254. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, WAB_DLL_PATH_KEY, 0, KEY_READ, &hKey))
  255. {
  256. if(ERROR_SUCCESS == RegQueryValueEx( hKey, "", NULL, &dwType, (LPBYTE) szPathT, &cbData))
  257. {
  258. if (dwType == REG_EXPAND_SZ)
  259. cbData = ExpandEnvironmentStrings(szPathT, szPath, cb / sizeof(TCHAR));
  260. else
  261. {
  262. if(GetFileAttributes(szPathT) != 0xFFFFFFFF)
  263. StrCpyN(szPath, szPathT, cb/sizeof(TCHAR));
  264. }
  265. }
  266. }
  267. }
  268. if(hKey) RegCloseKey(hKey);
  269. return;
  270. }
  271. ///////////////////////////////////////////////////////////////////////////
  272. // LoadLibrary_WABDll() - Load the WAB library based on the WAB DLL path
  273. //
  274. HINSTANCE LoadLibrary_WABDll()
  275. {
  276. TCHAR szWABDllPath[MAX_PATH];
  277. HINSTANCE hinst = NULL;
  278. GetWABDllPath(szWABDllPath, sizeof(szWABDllPath));
  279. return(hinst = LoadLibrary( (lstrlen(szWABDllPath)) ? szWABDllPath : WAB_DLL_NAME));
  280. }
  281. /*
  282. -
  283. - bSearchCmdLine - searches for given arg in given line and returns
  284. * data after the arg
  285. */
  286. BOOL bSearchCmdLine(LPTSTR lpCmdLine, LPTSTR szArg, LPTSTR szData, DWORD cchSize)
  287. {
  288. LPTSTR lpCmd = NULL, lp = NULL, lpTemp = NULL;
  289. BOOL fRet = FALSE;
  290. DWORD cchSizeCmd = 0;
  291. if(!lpCmdLine || !lstrlen(lpCmdLine) || !szArg || !lstrlen(szArg))
  292. return FALSE;
  293. cchSizeCmd = lstrlen(lpCmdLine)+1;
  294. if(!(lpCmd = LocalAlloc(LMEM_ZEROINIT, cchSizeCmd)))
  295. return FALSE;
  296. StrCpyN(lpCmd, lpCmdLine, cchSizeCmd);
  297. lpTemp = lpCmd;
  298. while(lpTemp && *lpTemp)
  299. {
  300. if (! StrICmpN(lpTemp, (LPTSTR)szArg, lstrlen(szArg)))
  301. {
  302. fRet = TRUE;
  303. lpTemp += lstrlen(szArg); // move past the switch
  304. if(szData)
  305. {
  306. lp = lpTemp;
  307. while(lp && *lp && *lp!='\0' && *lp!='+') //delimiter is a '+' so we dont mess up long file names
  308. lp++;
  309. *lp = '\0';
  310. if(lstrlen(lpTemp))
  311. StrCpyN(szData, lpTemp, cchSize);
  312. }
  313. break;
  314. }
  315. lpTemp++;
  316. }
  317. LocalFree(lpCmd);
  318. return fRet;
  319. }
  320. typedef HINSTANCE (STDAPICALLTYPE *PFNMLLOADLIBARY)(LPCTSTR lpLibFileName, HMODULE hModule, DWORD dwCrossCodePage);
  321. static const TCHAR c_szShlwapiDll[] = TEXT("shlwapi.dll");
  322. static const char c_szDllGetVersion[] = "DllGetVersion";
  323. static const TCHAR c_szWABResourceDLL[] = TEXT("wab32res.dll");
  324. static const TCHAR c_szWABDLL[] = TEXT("wab32.dll");
  325. HINSTANCE LoadWABResourceDLL(HINSTANCE hInstWAB32)
  326. {
  327. TCHAR szPath[MAX_PATH];
  328. HINSTANCE hinstShlwapi;
  329. PFNMLLOADLIBARY pfn;
  330. DLLGETVERSIONPROC pfnVersion;
  331. int iEnd;
  332. DLLVERSIONINFO info;
  333. HINSTANCE hInst = NULL;
  334. hinstShlwapi = LoadLibrary(c_szShlwapiDll);
  335. if (hinstShlwapi != NULL)
  336. {
  337. pfnVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstShlwapi, c_szDllGetVersion);
  338. if (pfnVersion != NULL)
  339. {
  340. info.cbSize = sizeof(DLLVERSIONINFO);
  341. if (SUCCEEDED(pfnVersion(&info)))
  342. {
  343. if (info.dwMajorVersion >= 5)
  344. {
  345. #ifdef UNICODE
  346. pfn = (PFNMLLOADLIBARY)GetProcAddress(hinstShlwapi, (LPCSTR)378);
  347. #else
  348. pfn = (PFNMLLOADLIBARY)GetProcAddress(hinstShlwapi, (LPCSTR)377);
  349. #endif // UNICODE
  350. if (pfn != NULL)
  351. hInst = pfn(c_szWABResourceDLL, hInstWAB32, 0);
  352. }
  353. }
  354. }
  355. FreeLibrary(hinstShlwapi);
  356. }
  357. if (NULL == hInst)
  358. {
  359. GetWABDllPath(szPath, sizeof(szPath));
  360. iEnd = lstrlen(szPath);
  361. if (iEnd > 0)
  362. {
  363. iEnd = iEnd - lstrlen(c_szWABDLL);
  364. StrCpyN(&szPath[iEnd], c_szWABResourceDLL, sizeof(szPath)/sizeof(TCHAR)-iEnd);
  365. hInst = LoadLibrary(szPath);
  366. }
  367. }
  368. AssertSz(hInst, TEXT("Failed to LoadLibrary Lang Dll"));
  369. return(hInst);
  370. }
  371. /***************************************************************************
  372. Name : WinMain
  373. Purpose :
  374. Parameters: Command line parameters
  375. "" - defaults to import for default wab
  376. "filename" - defaults to import
  377. "/import [filename]" - default wab or specified wab
  378. "/export [filename]" - default wab or specified wab
  379. Returns :
  380. ***************************************************************************/
  381. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) {
  382. MSG msg ;
  383. int nRetVal;
  384. LPSTR lpTemp = lpszCmdLine;
  385. HINSTANCE hinstWAB;
  386. WABMIGDLGPARAM wmdp = {0};
  387. hInstApp = hInstance;
  388. hInst = LoadWABResourceDLL(hInstApp);
  389. DebugTrace("WABMIG cmdline = %s\n", lpszCmdLine);
  390. fExport = bSearchCmdLine(lpszCmdLine, (LPTSTR)szEXPORT, NULL, 0);
  391. bSearchCmdLine(lpszCmdLine, (LPTSTR)szPROFILEID, wmdp.szProfileID, ARRAYSIZE(wmdp.szProfileID));
  392. bSearchCmdLine(lpszCmdLine, (LPTSTR)szFILE, wmdp.szFileName, ARRAYSIZE(wmdp.szFileName));
  393. DebugTrace("%s: id=%s file=%s\n", fExport?szEXPORT:szIMPORT, wmdp.szProfileID, wmdp.szFileName);
  394. // Load the WABDll and getprocaddress for WABOpen
  395. hinstWAB = LoadLibrary_WABDll();
  396. if(hinstWAB)
  397. lpfnWABOpen = (LPWABOPEN) GetProcAddress(hinstWAB, TEXT("WABOpen"));
  398. DebugTrace("WABMig got filename: %s\n", wmdp.szFileName);
  399. if(lpfnWABOpen)
  400. {
  401. nRetVal = (int) DialogBoxParam(hInst,
  402. MAKEINTRESOURCE(fExport ? IDD_ExportDialog : IDD_ImportDialog),
  403. NULL,
  404. fExport ? ExportDialogProc : ImportDialogProc,
  405. (LPARAM) &wmdp);
  406. switch(nRetVal) {
  407. case -1: //some error occured
  408. DebugTrace("Couldn't create import dialog -> %u\n", GetLastError());
  409. default:
  410. break;
  411. }
  412. }
  413. else
  414. {
  415. TCHAR sz[MAX_PATH];
  416. TCHAR szTitle[MAX_PATH];
  417. *szTitle = *sz = '\0';
  418. LoadString(hInst, IDS_MESSAGE_TITLE, szTitle, sizeof(szTitle));
  419. LoadString(hInst, IDS_NO_WAB, sz, sizeof(sz));
  420. MessageBox(NULL, sz, szTitle, MB_OK | MB_ICONSTOP);
  421. }
  422. if(hinstWAB)
  423. FreeLibrary(hinstWAB);
  424. if(hInst)
  425. FreeLibrary(hInst);
  426. return(nRetVal == -1);
  427. }
  428. INT_PTR CALLBACK ErrorDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
  429. LPERROR_INFO lpEI = (LPERROR_INFO)GetWindowLongPtr(hwnd, DWLP_USER);
  430. switch (message) {
  431. case WM_INITDIALOG:
  432. {
  433. TCHAR szBuffer[MAX_RESOURCE_STRING + 1];
  434. LPTSTR lpszMessage;
  435. SetWindowLongPtr(hwnd, DWLP_USER, lParam); //Save this for future reference
  436. lpEI = (LPERROR_INFO)lParam;
  437. if (LoadString(hInst,
  438. lpEI->ids,
  439. szBuffer, sizeof(szBuffer))) {
  440. LPTSTR lpszArg[2] = {lpEI->lpszDisplayName, lpEI->lpszEmailAddress};
  441. if (! FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  442. szBuffer,
  443. 0, 0, //ignored
  444. (LPTSTR)&lpszMessage,
  445. 0,
  446. (va_list *)lpszArg)) {
  447. DebugTrace("FormatMessage -> %u\n", GetLastError());
  448. } else {
  449. DebugTrace("Status Message: %s\n", lpszMessage);
  450. if (! SetDlgItemText(hwnd, IDC_ErrorMessage, lpszMessage)) {
  451. DebugTrace("SetDlgItemText -> %u\n", GetLastError());
  452. }
  453. LocalFree(lpszMessage);
  454. }
  455. }
  456. return(TRUE);
  457. }
  458. case WM_COMMAND :
  459. switch (wParam) {
  460. case IDCANCEL:
  461. lpEI->ErrorResult = ERROR_ABORT;
  462. // fall through to close.
  463. case IDCLOSE:
  464. // Ignore the contents of the radio button
  465. SendMessage(hwnd, WM_CLOSE, 0, 0L);
  466. return(0);
  467. case IDOK:
  468. // Get the contents of the radio button
  469. ImportOptions.fNoErrors = (IsDlgButtonChecked(hwnd, IDC_NoMoreError) == 1);
  470. ExportOptions.fNoErrors = (IsDlgButtonChecked(hwnd, IDC_NoMoreError) == 1);
  471. SendMessage(hwnd, WM_CLOSE, 0, 0);
  472. return(0);
  473. case IDM_EXIT:
  474. SendMessage(hwnd, WM_DESTROY, 0, 0L);
  475. return(0);
  476. }
  477. break ;
  478. case IDCANCEL:
  479. // treat it like a close
  480. SendMessage(hwnd, WM_CLOSE, 0, 0);
  481. break;
  482. case WM_CLOSE:
  483. EndDialog(hwnd, FALSE);
  484. return(0);
  485. default:
  486. return(FALSE);
  487. }
  488. return(TRUE);
  489. }
  490. /***************************************************************************
  491. bOutlookUsingWAB
  492. if Outlook is installed on the machine and is setup to use the WAB
  493. then there is no PAB on this machine - the PAB is the WAB and the
  494. WAB import imports to itself ...
  495. So we look for this case and if it is true, we drop the PAB importer
  496. from the UI
  497. ****************************************************************************/
  498. BOOL bOutlookUsingWAB()
  499. {
  500. HKEY hKey = NULL;
  501. LPTSTR lpReg = "Software\\Microsoft\\Office\\8.0\\Outlook\\Setup";
  502. LPTSTR lpOMI = "MailSupport";
  503. BOOL bUsingWAB = FALSE;
  504. if(ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  505. lpReg, 0, KEY_READ, &hKey))
  506. {
  507. DWORD dwType = 0, dwSize = sizeof(DWORD), dwData = 0;
  508. if(ERROR_SUCCESS == RegQueryValueEx(hKey, lpOMI, NULL,
  509. &dwType, (LPBYTE)&dwData, &dwSize))
  510. {
  511. if(dwType == REG_DWORD && dwData == 0) // the value must be one ..
  512. bUsingWAB = TRUE;
  513. }
  514. }
  515. if(hKey)
  516. RegCloseKey(hKey);
  517. return bUsingWAB;
  518. }
  519. /***************************************************************************
  520. Name : PopulateTargetList
  521. Purpose : Fills in the list box with the import/exporters from the
  522. registry.
  523. Parameters: hwndLB = handle of Listbox
  524. lpszSelection = NULL or name to set as default selection
  525. Returns : HRESULT
  526. Comment : This routine is a MESS! Should break it up when we get time.
  527. ***************************************************************************/
  528. HRESULT PopulateTargetList(HWND hWndLB,
  529. LPTSTR lpszSelection)
  530. {
  531. ULONG ulObjectType = 0;
  532. ULONG i=0, j=0;
  533. TCHAR szBuf[MAX_PATH];
  534. ULONG ulItemCount = 0;
  535. HRESULT hr = hrSuccess;
  536. DWORD dwErr, cbBuf;
  537. HKEY hKeyWAB = NULL;
  538. HKEY hKeyImport = NULL;
  539. HKEY hKey = NULL;
  540. ULONG ulIndex;
  541. ULONG ulNumImporters = 0;
  542. ULONG ulExternals = 0;
  543. BOOL bHidePAB = FALSE;
  544. //
  545. // We need to clear out the list list box if it has any entries ...
  546. //
  547. FreeLBItemData(hWndLB);
  548. // If outlook is using the WAB as the PAB then we want to hide
  549. // the PAB entry from the importer and exporter
  550. //
  551. bHidePAB = bOutlookUsingWAB();
  552. // How big a target list do I need?
  553. // Load all the entries from the registry
  554. // Open WAB Import Key
  555. if (! (dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, //HKEY_CURRENT_USER,
  556. szWABKey,
  557. 0,
  558. KEY_READ,
  559. &hKeyWAB))) {
  560. // Yes, WAB Key open, get Import or Export Key
  561. if (! (dwErr = RegOpenKeyEx(hKeyWAB,
  562. fExport ? "Export" : "Import",
  563. 0,
  564. KEY_READ,
  565. &hKeyImport))) {
  566. // Enumerate Importer/Exporter keys
  567. // How many keys are there?
  568. if (! (dwErr = RegQueryInfoKey(hKeyImport,
  569. NULL, NULL, NULL,
  570. &ulExternals, // how many importer/exporter keys are there?
  571. NULL, NULL, NULL, NULL, NULL, NULL, NULL))) {
  572. }
  573. }
  574. }
  575. ulNumImporters = ulExternals + ulItemCount;
  576. if ((rgTargetInfo = LocalAlloc(LPTR, ulNumImporters * sizeof(TARGET_INFO)))) {
  577. ulIndex = 0;
  578. cbBuf= sizeof(szBuf);
  579. } else {
  580. DebugTrace("LocalAlloc of TargetInfoArray -> %u\n", GetLastError());
  581. hr = ResultFromScode(MAPI_E_NOT_ENOUGH_MEMORY);
  582. goto exit;
  583. }
  584. if (ulExternals) {
  585. // Add external importers/exporters to the list
  586. while (ulIndex < ulExternals && ! (dwErr = RegEnumKeyEx(hKeyImport,
  587. ulIndex,
  588. szBuf,
  589. &cbBuf,
  590. NULL, NULL, NULL, NULL))) {
  591. // Got another one,
  592. DebugTrace("Found Importer: [%s]\n", szBuf);
  593. // if we want to hide the pab and this is the pab then
  594. // skip else add
  595. //
  596. if(!(bHidePAB && !lstrcmpi(szBuf, TEXT("PAB"))))
  597. {
  598. // Add it to the list
  599. if (rgTargetInfo[ulItemCount].lpRegName = LocalAlloc(LPTR,
  600. lstrlen(szBuf) + 1)) {
  601. StrCpyN(rgTargetInfo[ulItemCount].lpRegName, szBuf, lstrlen(szBuf) + 1);
  602. // Open the key
  603. if (! (dwErr = RegOpenKeyEx(hKeyImport,
  604. szBuf,
  605. 0,
  606. KEY_READ,
  607. &hKey))) {
  608. AllocRegValue(hKey, (LPTSTR)szDescription, &rgTargetInfo[ulItemCount].lpDescription);
  609. AllocRegValue(hKey, (LPTSTR)szDll, &rgTargetInfo[ulItemCount].lpDll);
  610. AllocRegValue(hKey, (LPTSTR)szEntry, &rgTargetInfo[ulItemCount].lpEntry);
  611. RegCloseKey(hKey);
  612. if (! rgTargetInfo[ulItemCount].lpDescription) {
  613. // No Description, use reg name
  614. if (rgTargetInfo[ulItemCount].lpDescription = LocalAlloc(LPTR,
  615. lstrlen(szBuf) + 1)) {
  616. StrCpyN(rgTargetInfo[ulItemCount].lpDescription, szBuf, strlen(szBuf) + 1);
  617. }
  618. }
  619. // Add to the list
  620. SendMessage(hWndLB, LB_SETITEMDATA, (WPARAM)
  621. SendMessage(hWndLB, LB_ADDSTRING, (WPARAM)0,
  622. (LPARAM)rgTargetInfo[ulItemCount].lpDescription),
  623. (LPARAM)ulItemCount);
  624. if (lpszSelection && !lstrcmpi(rgTargetInfo[ulItemCount].lpDescription, lpszSelection)) {
  625. // Set the default selection to Windows Address Book
  626. SendMessage(hWndLB, LB_SETCURSEL, (WPARAM)ulIndex, (LPARAM)0);
  627. }
  628. ulItemCount++;
  629. }
  630. } else {
  631. DebugTrace("LocalAlloc of Importer Name -> %u\n", GetLastError());
  632. }
  633. }
  634. cbBuf = sizeof(szBuf);
  635. ulIndex++;
  636. }
  637. }
  638. exit:
  639. if (hKeyImport) {
  640. RegCloseKey(hKeyImport);
  641. }
  642. if (hKeyWAB) {
  643. RegCloseKey(hKeyWAB);
  644. }
  645. return(hr);
  646. }
  647. /***************************************************************************
  648. Name : FreeLBItemData
  649. Purpose : Frees the structures associated with the Target List box.
  650. Parameters: hwndLB = handle of Listbox
  651. Returns : none
  652. Comment
  653. ***************************************************************************/
  654. void FreeLBItemData(HWND hWndLB)
  655. {
  656. ULONG i = 0;
  657. ULONG ulItemCount = 0;
  658. LPTARGET_INFO lpTargetInfo = rgTargetInfo;
  659. if (! hWndLB) {
  660. return;
  661. }
  662. ulItemCount = (ULONG) SendMessage(hWndLB, LB_GETCOUNT, 0, 0);
  663. if (lpTargetInfo != NULL) {
  664. if (ulItemCount != 0) {
  665. for(i = 0; i < ulItemCount; i++) {
  666. if(lpTargetInfo->lpRegName) {
  667. LocalFree(lpTargetInfo->lpRegName);
  668. }
  669. if (lpTargetInfo->lpDescription) {
  670. LocalFree(lpTargetInfo->lpDescription);
  671. }
  672. if (lpTargetInfo->lpDll) {
  673. LocalFree(lpTargetInfo->lpDll);
  674. }
  675. if (lpTargetInfo->lpEntry) {
  676. LocalFree(lpTargetInfo->lpEntry);
  677. }
  678. lpTargetInfo++;
  679. }
  680. SendMessage(hWndLB, LB_RESETCONTENT, 0, 0);
  681. }
  682. // Free global array
  683. LocalFree(rgTargetInfo);
  684. rgTargetInfo = NULL;
  685. }
  686. }
  687. /***************************************************************************
  688. Name : ShowMessageBoxParam
  689. Purpose : Generic MessageBox displayer
  690. Parameters: hWndParent - Handle of message box parent
  691. MsgID - resource id of message string
  692. ulFlags - MessageBox flags
  693. ... - format parameters
  694. Returns : MessageBox return code
  695. ***************************************************************************/
  696. int __cdecl ShowMessageBoxParam(HWND hWndParent, int MsgId, int ulFlags, ...)
  697. {
  698. TCHAR szBuf[MAX_RESOURCE_STRING + 1] = "";
  699. TCHAR szCaption[MAX_PATH] = "";
  700. LPTSTR lpszBuffer = NULL;
  701. int iRet = 0;
  702. va_list vl;
  703. va_start(vl, ulFlags);
  704. LoadString(hInst, MsgId, szBuf, sizeof(szBuf));
  705. if (FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  706. szBuf,
  707. 0,0, // ignored
  708. (LPTSTR)&lpszBuffer,
  709. sizeof(szBuf), // MAX_UI_STR
  710. (va_list *)&vl)) {
  711. TCHAR szCaption[MAX_PATH];
  712. GetWindowText(hWndParent, szCaption, sizeof(szCaption));
  713. if (! lstrlen(szCaption)) { // if no caption get the parents caption - this is necessary for property sheets
  714. GetWindowText(GetParent(hWndParent), szCaption, sizeof(szCaption));
  715. if (! lstrlen(szCaption)) //if still not caption, use empty title
  716. szCaption[0] = (TCHAR)'\0';
  717. }
  718. iRet = MessageBox(hWndParent, lpszBuffer, szCaption, ulFlags);
  719. LocalFree(lpszBuffer);
  720. }
  721. va_end(vl);
  722. return(iRet);
  723. }
  724. //$$//////////////////////////////////////////////////////////////////////
  725. //
  726. // LoadAllocString - Loads a string resource and allocates enough
  727. // memory to hold it.
  728. //
  729. // StringID - String identifier to load
  730. //
  731. // returns the LocalAlloc'd, null terminated string. Caller is responsible
  732. // for LocalFree'ing this buffer. If the string can't be loaded or memory
  733. // can't be allocated, returns NULL.
  734. //
  735. //////////////////////////////////////////////////////////////////////////
  736. LPTSTR LoadAllocString(int StringID) {
  737. ULONG ulSize = 0;
  738. LPTSTR lpBuffer = NULL;
  739. TCHAR szBuffer[MAX_RESOURCE_STRING + 1];
  740. ulSize = LoadString(hInst, StringID, szBuffer, sizeof(szBuffer));
  741. if (ulSize && (lpBuffer = LocalAlloc(LPTR, ulSize + 1))) {
  742. StrCpyN(lpBuffer, szBuffer, ulSize + 1);
  743. }
  744. return(lpBuffer);
  745. }