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.

1849 lines
59 KiB

  1. /*-----------------------------------------
  2. //
  3. // WABExe.C -- Enables viewing the WAB modeless UI
  4. //
  5. //
  6. -------------------------------------------*/
  7. #include <windows.h>
  8. #include <wab.h>
  9. #include <wabguid.h>
  10. #include "..\wab32res\resrc2.h"
  11. #include <advpub.h>
  12. #include <shlwapi.h>
  13. #include "wabexe.h"
  14. #define ARRAYSIZE(_rg) (sizeof(_rg)/sizeof(_rg[0]))
  15. #define WinMainT WinMain
  16. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  17. LRESULT CALLBACK WndProcW (HWND, UINT, WPARAM, LPARAM) ;
  18. #define MAX_INPUT_STRING 200
  19. // #define LDAP_AUTH_SICILY (0x86L | 0x0200)
  20. char szAppName [] = "Address Book Viewer" ;
  21. const LPTSTR szWABFilter = TEXT("*.wab");
  22. const UCHAR szEmpty[] = "";
  23. // Command Line Parameters
  24. static const TCHAR szParamOpen[] = "/Open";
  25. static const TCHAR szParamNew[] = "/New";
  26. static const TCHAR szParamShowExisting[] = "/ShowExisting";
  27. static const TCHAR szParamFind[] = "/Find";
  28. static const TCHAR szParamVCard[] = "/VCard";
  29. static const TCHAR szParamLDAPUrl[] = "/LDAP:";
  30. static const TCHAR szParamCert[] = "/Certificate";
  31. static const TCHAR szParamFirstRun[] = "/FirstRun";
  32. static const TCHAR szAllProfiles[] = "/All";
  33. static const TCHAR szWabKey[]="Software\\Microsoft\\Wab";
  34. static const TCHAR szVCardNoCheckKey[]="NoVCardCheck";
  35. static const TCHAR lpszSharedKey[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\SharedDlls");
  36. HINSTANCE hInstWABDll = NULL;
  37. HINSTANCE hInst = NULL; // this module's resource instance handle
  38. HINSTANCE hInstApp = NULL; // this module's instance handle
  39. HINSTANCE LoadLibrary_WABDll();
  40. LPWABOPEN lpfnWABOpen = NULL;
  41. const static TCHAR szWABOpen[] = TEXT("WABOpen");
  42. static const GUID MPSWab_GUID = // keep this in sync with the one in wabapi\mpswab.h
  43. { 0xc1843281, 0x585, 0x11d0, { 0xb2, 0x90, 0x0, 0xaa, 0x0, 0x3c, 0xf6, 0x76 } };
  44. BOOL bGetFileNameFromDlg(HWND hwnd,
  45. HINSTANCE hInstance,
  46. LPTSTR lpszDirectory,
  47. int szTitleID,
  48. DWORD dwFlags,
  49. LPTSTR szFileName,
  50. DWORD cchFileName);
  51. #define WAB_VCARDFILE 0x00000001
  52. #define WAB_FINDSESSION 0x00000010
  53. #define WAB_LDAPURL 0x00000100
  54. #define WAB_CERTFILE 0x00001000
  55. #define WAB_ALLPROFILES 0x00010000
  56. BOOL bGetFileNameFromCmdLine(HWND hwnd,
  57. HINSTANCE hInstance,
  58. LPTSTR lpszCmdLine,
  59. LPTSTR szWABTitle,
  60. ULONG * ulFlag,
  61. LPTSTR szFileName,
  62. DWORD cchFileName);
  63. static const char c_szReg[] = "Reg";
  64. static const char c_szUnReg[] = "UnReg";
  65. static const char c_szAdvPackDll[] = "ADVPACK.DLL";
  66. //$$//////////////////////////////////////////////////////////////////////
  67. //
  68. // LoadAllocString - Loads a string resource and allocates enough
  69. // memory to hold it.
  70. //
  71. // StringID - String identifier to load
  72. //
  73. // returns the LocalAlloc'd, null terminated string. Caller is responsible
  74. // for LocalFree'ing this buffer. If the string can't be loaded or memory
  75. // can't be allocated, returns NULL.
  76. //
  77. //////////////////////////////////////////////////////////////////////////
  78. LPTSTR LoadAllocString(int StringID, HINSTANCE hInstance) {
  79. ULONG ulSize = 0;
  80. LPTSTR lpBuffer = NULL;
  81. TCHAR szBuffer[261]; // Big enough? Strings better be smaller than 260!
  82. ulSize = LoadString(hInstance, StringID, szBuffer, sizeof(szBuffer));
  83. if (ulSize && (lpBuffer = LocalAlloc(LPTR, (ulSize + 1)*sizeof(TCHAR)))) {
  84. StrCpyN(lpBuffer, szBuffer, ulSize+1);
  85. }
  86. return(lpBuffer);
  87. }
  88. //$$//////////////////////////////////////////////////////////////////////
  89. //
  90. // FormatAllocFilter - Loads a file filter name string resource and
  91. // formats it with the file extension filter
  92. //
  93. // StringID - String identifier to load
  94. // szFilter - file name filter, ie, "*.vcf"
  95. //
  96. // returns the LocalAlloc'd, null terminated string. Caller is responsible
  97. // for LocalFree'ing this buffer. If the string can't be loaded or memory
  98. // can't be allocated, returns NULL.
  99. //
  100. //////////////////////////////////////////////////////////////////////////
  101. LPTSTR FormatAllocFilter(int StringID, const LPTSTR lpFilter, HINSTANCE hInstance) {
  102. LPTSTR lpFileType;
  103. LPTSTR lpTemp;
  104. LPTSTR lpBuffer = NULL;
  105. ULONG cbFileType, cbFilter;
  106. cbFilter = lstrlen(lpFilter);
  107. if (lpFileType = LoadAllocString(StringID,hInstance)) {
  108. cbFileType = lstrlen(lpFileType);
  109. if (lpBuffer = LocalAlloc(LPTR, (cbFileType+1+lstrlen(lpFilter)+ 2)*sizeof(TCHAR))) {
  110. lpTemp = lpBuffer;
  111. StrCpyN(lpTemp, lpFileType, cbFileType+1);
  112. lpTemp += cbFileType;
  113. lpTemp++; // leave null there
  114. StrCpyN(lpTemp, lpFilter, cbFilter+1);
  115. lpTemp += cbFilter;
  116. lpTemp++; // leave null there
  117. *lpTemp = '\0';
  118. }
  119. LocalFree(lpFileType);
  120. }
  121. return(lpBuffer);
  122. }
  123. //$$//////////////////////////////////////////////////////////////////////
  124. //
  125. // GetWABExePath - queries the reg for the full path of the wab exe
  126. //
  127. // sz is a preallocated buffer
  128. //
  129. //////////////////////////////////////////////////////////////////////////
  130. TCHAR lpszWABExeRegPath[] = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Wab.exe");
  131. void GetWABExePath(LPTSTR sz, ULONG cbsz)
  132. {
  133. DWORD dwType = 0;
  134. DWORD dwSize = cbsz;
  135. *sz = '\0';
  136. RegQueryValue( HKEY_LOCAL_MACHINE,
  137. lpszWABExeRegPath,
  138. sz, &dwSize);
  139. if(!lstrlen(sz))
  140. StrCpyN(sz, TEXT("WAB.Exe"), cbsz);
  141. }
  142. static const TCHAR szWabAutoFileKey[]=".wab";
  143. static const TCHAR szWabAutoFile[]="wab_auto_file";
  144. static const TCHAR szWabAutoFileNameKey[]="wab_auto_file";
  145. static const TCHAR szWabAutoFileName[]="WAB File";
  146. static const TCHAR szWabCommandOpenKey[]="wab_auto_file\\shell\\open\\command";
  147. static const TCHAR szWabCommandOpen[]="\"%s\" %%1";
  148. //$$//////////////////////////////////////////////////////////////////////
  149. //
  150. // CheckWABDefaultHandler
  151. //
  152. // Checks if WAB.exe is the default handler for the WAB in the registry.
  153. // If not, sets wab.exe as the default handler
  154. //
  155. //////////////////////////////////////////////////////////////////////////
  156. void CheckWABDefaultHandler()
  157. {
  158. HKEY hKey = NULL;
  159. TCHAR sz[MAX_PATH];
  160. TCHAR szWABExe[MAX_PATH];
  161. DWORD dwDisposition = 0;
  162. // Check to see if something is registered or not ...
  163. // Open key
  164. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CLASSES_ROOT,
  165. szWabAutoFileKey,
  166. 0, //reserved
  167. NULL,
  168. REG_OPTION_NON_VOLATILE,
  169. KEY_ALL_ACCESS,
  170. NULL,
  171. &hKey,
  172. &dwDisposition))
  173. {
  174. goto out;
  175. }
  176. if (dwDisposition == REG_CREATED_NEW_KEY)
  177. {
  178. // New key ... need to give it a value .. this will be the
  179. // default value
  180. //
  181. DWORD dwLenName = lstrlen(szWabAutoFile);
  182. if (ERROR_SUCCESS != RegSetValueEx( hKey,
  183. NULL,
  184. 0,
  185. REG_SZ,
  186. (LPBYTE) szWabAutoFile,
  187. dwLenName))
  188. {
  189. goto out;
  190. }
  191. RegCloseKey(hKey);
  192. hKey = NULL;
  193. // Create the other keys also
  194. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CLASSES_ROOT,
  195. szWabAutoFileNameKey,
  196. 0, //reserved
  197. NULL,
  198. REG_OPTION_NON_VOLATILE,
  199. KEY_ALL_ACCESS,
  200. NULL,
  201. &hKey,
  202. &dwDisposition))
  203. {
  204. goto out;
  205. }
  206. dwLenName = lstrlen(szWabAutoFileName);
  207. if (ERROR_SUCCESS != RegSetValueEx( hKey,
  208. NULL,
  209. 0,
  210. REG_SZ,
  211. (LPBYTE) szWabAutoFileName,
  212. dwLenName))
  213. {
  214. goto out;
  215. }
  216. RegCloseKey(hKey);
  217. hKey = NULL;
  218. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CLASSES_ROOT,
  219. szWabCommandOpenKey,
  220. 0, //reserved
  221. NULL,
  222. REG_OPTION_NON_VOLATILE,
  223. KEY_ALL_ACCESS,
  224. NULL,
  225. &hKey,
  226. &dwDisposition))
  227. {
  228. goto out;
  229. }
  230. GetWABExePath(szWABExe, sizeof(szWABExe));
  231. wnsprintf(sz, ARRAYSIZE(sz), szWabCommandOpen, szWABExe);
  232. dwLenName = lstrlen(sz);
  233. if (ERROR_SUCCESS != RegSetValueEx( hKey,
  234. NULL,
  235. 0,
  236. REG_SZ,
  237. (LPBYTE) sz,
  238. dwLenName))
  239. {
  240. goto out;
  241. }
  242. RegCloseKey(hKey);
  243. hKey = NULL;
  244. }
  245. out:
  246. if(hKey)
  247. RegCloseKey(hKey);
  248. return;
  249. }
  250. enum _RetVal
  251. {
  252. MAKE_DEFAULT=0,
  253. DONT_MAKE_DEFAULT
  254. };
  255. enum _DoVCardCheck
  256. {
  257. NO_VCARD_CHECK=1,
  258. DO_VCARD_CHECK
  259. };
  260. //$$//////////////////////////////////////////////////////////////////////
  261. //
  262. // fnAskVCardProc
  263. //
  264. //
  265. //////////////////////////////////////////////////////////////////////////
  266. INT_PTR CALLBACK fnAskVCardProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  267. {
  268. switch(message)
  269. {
  270. case WM_INITDIALOG:
  271. break;
  272. case WM_COMMAND:
  273. switch (LOWORD(wParam))
  274. {
  275. case IDC_CHECK_ALWAYS:
  276. {
  277. // Set a registry setting depending on the check mark value
  278. UINT nIsChecked = IsDlgButtonChecked(hDlg, IDC_CHECK_ALWAYS);
  279. DWORD dwCheck = (nIsChecked == BST_CHECKED) ? NO_VCARD_CHECK : DO_VCARD_CHECK;
  280. {
  281. // Set this value in the registry
  282. HKEY hKey = NULL;
  283. DWORD dwDisposition;
  284. // Open the WAB Key
  285. if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER,
  286. szWabKey,
  287. 0, //reserved
  288. NULL,
  289. REG_OPTION_NON_VOLATILE,
  290. KEY_ALL_ACCESS,
  291. NULL,
  292. &hKey,
  293. &dwDisposition))
  294. {
  295. //if this key exists, get the WAB DoVCardCheck value
  296. DWORD dwLenName = sizeof(dwCheck);
  297. DWORD dwType = REG_DWORD;
  298. RegSetValueEx( hKey,
  299. szVCardNoCheckKey,
  300. 0,
  301. dwType, //reserved
  302. (LPBYTE) &dwCheck,
  303. dwLenName);
  304. }
  305. if(hKey)
  306. RegCloseKey(hKey);
  307. }
  308. }
  309. break;
  310. case IDOK:
  311. EndDialog(hDlg, MAKE_DEFAULT);
  312. break;
  313. case IDCANCEL:
  314. EndDialog(hDlg, DONT_MAKE_DEFAULT);
  315. break;
  316. }
  317. break;
  318. default:
  319. return FALSE;
  320. break;
  321. }
  322. return TRUE;
  323. }
  324. static const TCHAR szVCardAutoFileKey[]=".vcf";
  325. static const TCHAR szVCardAutoFile[]="vcard_wab_auto_file";
  326. static const TCHAR szVCardContentTypeValue[]="Content Type";
  327. static const TCHAR szVCardContentType[]="text/x-vcard";
  328. static const TCHAR szVCardMimeDatabase[]="MIME\\Database\\Content Type\\text/x-vcard";
  329. static const TCHAR szVCardExtension[]="Extension";
  330. static const TCHAR szVCardAutoFileNameKey[]="vcard_wab_auto_file";
  331. static const TCHAR szVCardAutoFileName[]="vCard File";
  332. static const TCHAR szVCardCommandOpenKey[]="vcard_wab_auto_file\\shell\\open\\command";
  333. static const TCHAR szVCardCommandOpen[]="\"%s\" /vcard %%1";
  334. static const TCHAR szVCardDefaultIconKey[]="vcard_wab_auto_file\\DefaultIcon";
  335. static const TCHAR szVCardDefaultIcon[]="\"%s\",1";
  336. //$$//////////////////////////////////////////////////////////////////////
  337. //
  338. // CheckVCardDefaultHandler
  339. //
  340. // Checks if WAB.exe is the default handler for the VCard in the registry.
  341. // If not, sets wab.exe as the default handler
  342. //
  343. //////////////////////////////////////////////////////////////////////////
  344. void CheckVCardDefaultHandler(HWND hWnd,
  345. HINSTANCE hInstance)
  346. {
  347. TCHAR sz[MAX_PATH];
  348. TCHAR szWABExe[MAX_PATH];
  349. HKEY hKey = NULL;
  350. HKEY hVCardKey = NULL;
  351. DWORD dwDisposition = 0;
  352. DWORD dwType = 0;
  353. DWORD dwLenName = 0;
  354. //First check if they want us to check at all ..
  355. // Open key
  356. if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER,
  357. szWabKey,
  358. 0, //reserved
  359. NULL,
  360. REG_OPTION_NON_VOLATILE,
  361. KEY_READ,
  362. NULL,
  363. &hKey,
  364. &dwDisposition))
  365. {
  366. // Found the key
  367. if (dwDisposition == REG_OPENED_EXISTING_KEY)
  368. {
  369. //if this key exists, get the WAB DoVCardCheck value
  370. DWORD dwCheck = 0;
  371. dwLenName = sizeof(dwCheck);
  372. if (ERROR_SUCCESS == RegQueryValueEx(hKey,
  373. szVCardNoCheckKey,
  374. NULL,
  375. &dwType, //reserved
  376. (LPBYTE) &dwCheck,
  377. &dwLenName))
  378. {
  379. // success .. what did we get back
  380. if (dwCheck == NO_VCARD_CHECK) // Dont Check
  381. goto out;
  382. }
  383. // else no success - so should do the check
  384. }
  385. // else no success, do the check
  386. }
  387. // else no success, do the check
  388. if(hKey)
  389. RegCloseKey(hKey);
  390. // Check to see if something is registered as a vCard handler or not ...
  391. // Open key
  392. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CLASSES_ROOT,
  393. szVCardAutoFileKey,
  394. 0, //reserved
  395. NULL,
  396. REG_OPTION_NON_VOLATILE,
  397. KEY_ALL_ACCESS,
  398. NULL,
  399. &hKey,
  400. &dwDisposition))
  401. {
  402. goto out;
  403. }
  404. if (dwDisposition == REG_OPENED_EXISTING_KEY)
  405. {
  406. // This key exists .. check who is registered to handle vCards ..
  407. TCHAR szHandlerNameKey[MAX_PATH];
  408. StrCpyN(szHandlerNameKey, szEmpty, ARRAYSIZE(szHandlerNameKey));
  409. dwLenName = sizeof(szHandlerNameKey);
  410. if (ERROR_SUCCESS == RegQueryValueEx(hKey,
  411. NULL,
  412. NULL,
  413. &dwType, //reserved
  414. szHandlerNameKey,
  415. &dwLenName))
  416. {
  417. // We got the value for this .. is it us ?
  418. if(!lstrcmpi(szVCardAutoFile, szHandlerNameKey))
  419. {
  420. //its us, dont do anything
  421. goto out;
  422. }
  423. else if (szHandlerNameKey && lstrlen(szHandlerNameKey) != 0)
  424. {
  425. // Its not us, pop up a dialog asking if they want us
  426. int nRetVal = (int) DialogBox(
  427. hInstance,
  428. MAKEINTRESOURCE(IDD_DIALOG_DEFAULT_VCARD_VIEWER),
  429. hWnd,
  430. fnAskVCardProc);
  431. if (nRetVal == DONT_MAKE_DEFAULT)
  432. goto out;
  433. } // else couldnt open.. go ahead and make us default
  434. } // else couldnt open.. go ahead and make us default
  435. }
  436. // If we are here then either dwDisposition == REG_CREATED_NEW_KEY or
  437. // there is some problem that couldnt let us read the above so set us as
  438. // the default ...
  439. {
  440. // New key ... need to give it a value .. this will be the
  441. // default value
  442. //
  443. DWORD dwLenName = lstrlen(szVCardAutoFile);
  444. if (ERROR_SUCCESS != RegSetValueEx( hKey,
  445. NULL,
  446. 0,
  447. REG_SZ,
  448. (LPBYTE) szVCardAutoFile,
  449. dwLenName))
  450. {
  451. goto out;
  452. }
  453. dwLenName = lstrlen(szVCardContentType);
  454. if (ERROR_SUCCESS != RegSetValueEx( hKey,
  455. szVCardContentTypeValue,
  456. 0,
  457. REG_SZ,
  458. (LPBYTE) szVCardContentType,
  459. dwLenName))
  460. {
  461. goto out;
  462. }
  463. RegCloseKey(hKey);
  464. hKey = NULL;
  465. // Create the other keys also
  466. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CLASSES_ROOT,
  467. szVCardAutoFileNameKey,
  468. 0, //reserved
  469. NULL,
  470. REG_OPTION_NON_VOLATILE,
  471. KEY_ALL_ACCESS,
  472. NULL,
  473. &hKey,
  474. &dwDisposition))
  475. {
  476. goto out;
  477. }
  478. dwLenName = lstrlen(szVCardAutoFileName);
  479. if (ERROR_SUCCESS != RegSetValueEx( hKey,
  480. NULL,
  481. 0,
  482. REG_SZ,
  483. (LPBYTE) szVCardAutoFileName,
  484. dwLenName))
  485. {
  486. goto out;
  487. }
  488. RegCloseKey(hKey);
  489. hKey = NULL;
  490. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CLASSES_ROOT,
  491. szVCardCommandOpenKey,
  492. 0, //reserved
  493. NULL,
  494. REG_OPTION_NON_VOLATILE,
  495. KEY_ALL_ACCESS,
  496. NULL,
  497. &hKey,
  498. &dwDisposition))
  499. {
  500. goto out;
  501. }
  502. GetWABExePath(szWABExe, sizeof(szWABExe));
  503. wnsprintf(sz, ARRAYSIZE(sz), szVCardCommandOpen, szWABExe);
  504. dwLenName = lstrlen(sz);
  505. if (ERROR_SUCCESS != RegSetValueEx( hKey,
  506. NULL,
  507. 0,
  508. REG_SZ,
  509. (LPBYTE) sz,
  510. dwLenName))
  511. {
  512. goto out;
  513. }
  514. RegCloseKey(hKey);
  515. hKey = NULL;
  516. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CLASSES_ROOT,
  517. szVCardDefaultIconKey,
  518. 0, //reserved
  519. NULL,
  520. REG_OPTION_NON_VOLATILE,
  521. KEY_ALL_ACCESS,
  522. NULL,
  523. &hKey,
  524. &dwDisposition))
  525. {
  526. goto out;
  527. }
  528. wnsprintf(sz, ARRAYSIZE(sz), szVCardDefaultIcon, szWABExe);
  529. dwLenName = lstrlen(sz);
  530. if (ERROR_SUCCESS != RegSetValueEx( hKey,
  531. NULL,
  532. 0,
  533. REG_SZ,
  534. (LPBYTE) sz,
  535. dwLenName))
  536. {
  537. goto out;
  538. }
  539. RegCloseKey(hKey);
  540. hKey = NULL;
  541. // Set HKCR\MIME\Database\Content Type\text/x-vCard: Extension=.vcf
  542. if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CLASSES_ROOT,
  543. szVCardMimeDatabase,
  544. 0, //reserved
  545. NULL,
  546. REG_OPTION_NON_VOLATILE,
  547. KEY_ALL_ACCESS,
  548. NULL,
  549. &hKey,
  550. &dwDisposition))
  551. {
  552. goto out;
  553. }
  554. dwLenName = lstrlen(szVCardAutoFileKey);
  555. if (ERROR_SUCCESS != RegSetValueEx( hKey,
  556. szVCardExtension,
  557. 0,
  558. REG_SZ,
  559. (LPBYTE) szVCardAutoFileKey,
  560. dwLenName))
  561. {
  562. goto out;
  563. }
  564. RegCloseKey(hKey);
  565. hKey = NULL;
  566. }
  567. out:
  568. if(hVCardKey)
  569. RegCloseKey(hVCardKey);
  570. if(hKey)
  571. RegCloseKey(hKey);
  572. return;
  573. }
  574. //$$//////////////////////////////////////////////////////////////////////
  575. //
  576. // Callback dismiss function for IADRBOOK->Address
  577. //
  578. //////////////////////////////////////////////////////////////////////////
  579. void STDMETHODCALLTYPE WABDismissFunction(ULONG_PTR ulUIParam, LPVOID lpvContext)
  580. {
  581. LPDWORD lpdw = (LPDWORD) lpvContext;
  582. PostQuitMessage(0);
  583. return;
  584. }
  585. void GetWABDllPath(LPTSTR szPath, ULONG cb);
  586. static const LPTSTR szWABResourceDLL = TEXT("wab32res.dll");
  587. static const LPTSTR szWABDLL = TEXT("wab32.dll");
  588. static const LPTSTR c_szShlwapiDll = TEXT("shlwapi.dll");
  589. static const LPTSTR c_szDllGetVersion = TEXT("DllGetVersion");
  590. typedef HRESULT (CALLBACK * SHDLLGETVERSIONPROC)(DLLVERSIONINFO *);
  591. typedef HINSTANCE (STDAPICALLTYPE *PFNMLLOADLIBARY)(LPCTSTR lpLibFileName, HMODULE hModule, DWORD dwCrossCodePage);
  592. /*
  593. - LoadWABResourceDLL
  594. -
  595. * WAB resources are split up into a seperate dll so we want to load them from there
  596. * The Resource DLL location should be the same as the wab32.dll location
  597. * So we will try to make sure we don't fail here -
  598. * 1. Get current WAB32.dll path and look in that directory
  599. * 2. Just loadlibrary(wab32.dll)
  600. *
  601. * The MLLoadLibrary function should be used if available (IE5 only thing) since
  602. * it will load the correct language pack
  603. *
  604. */
  605. HINSTANCE LoadWABResourceDLL(HINSTANCE hInstWAB32)
  606. {
  607. HINSTANCE hinst = NULL;
  608. PFNMLLOADLIBARY pfnLoadLibrary = NULL;
  609. HINSTANCE hinstShlwapi = LoadLibrary(c_szShlwapiDll);
  610. SHDLLGETVERSIONPROC pfnVersion = NULL;
  611. DLLVERSIONINFO info = {0};
  612. // [PaulHi] 1/26/99 Raid 67380
  613. // Make sure we have the correct version of SHLWAPI.DLL before we use it
  614. if (hinstShlwapi != NULL)
  615. {
  616. pfnVersion = (SHDLLGETVERSIONPROC)GetProcAddress(hinstShlwapi, c_szDllGetVersion);
  617. if (pfnVersion != NULL)
  618. {
  619. info.cbSize = sizeof(DLLVERSIONINFO);
  620. if (SUCCEEDED(pfnVersion(&info)))
  621. {
  622. if (info.dwMajorVersion >= 5)
  623. {
  624. // pfnLoadLibrary = (PFNMLLOADLIBARY)GetProcAddress(hinstShlwapi, (LPCSTR)378); // UNICODE version
  625. pfnLoadLibrary = (PFNMLLOADLIBARY)GetProcAddress(hinstShlwapi, (LPCSTR)377); //ANSI version
  626. }
  627. }
  628. }
  629. }
  630. hinst = pfnLoadLibrary ?
  631. pfnLoadLibrary(szWABResourceDLL, hInstWAB32, 0) :
  632. LoadLibrary(szWABResourceDLL);
  633. if(!hinst)
  634. {
  635. // maybe not on the path so look in the wab32.dll directory
  636. TCHAR szResDLL[MAX_PATH];
  637. *szResDLL = '\0';
  638. GetWABDllPath(szResDLL, sizeof(szResDLL));
  639. if(lstrlen(szResDLL))
  640. {
  641. // the returned filename will always end in wab32.dll so we can nix that many characters off
  642. // and replace with wab32res.dll
  643. szResDLL[lstrlen(szResDLL) - lstrlen(szWABDLL)] = '\0';
  644. StrCatBuff(szResDLL, szWABResourceDLL, ARRAYSIZE(szResDLL));
  645. hinst = pfnLoadLibrary ?
  646. pfnLoadLibrary(szResDLL, hInstWAB32, 0) :
  647. LoadLibrary(szResDLL);
  648. }
  649. }
  650. if(hinstShlwapi)
  651. FreeLibrary(hinstShlwapi);
  652. return hinst;
  653. }
  654. /*
  655. - Strip quotes from File Names
  656. -
  657. * szFileName needs to be a buffer
  658. */
  659. void StripQuotes(LPTSTR szFileName)
  660. {
  661. // now let's get rid of " and ' in the filename string
  662. if( szFileName && lstrlen(szFileName))
  663. {
  664. TCHAR szCopy[MAX_PATH];
  665. LPTSTR lpTemp, lpTempBegin;
  666. int len = lstrlen(szFileName);
  667. lpTempBegin = szFileName;
  668. StrCpyN(szCopy, szFileName, ARRAYSIZE(szCopy));
  669. for( lpTemp = szCopy; lpTemp < szCopy+len; lpTemp++)
  670. {
  671. if( *lpTemp != '"' )//&& *lpTemp != '\'' )
  672. *(lpTempBegin++) = *lpTemp;
  673. }
  674. *(lpTempBegin) = '\0';
  675. }
  676. }
  677. /*
  678. -
  679. - CheckifRunningOnWinNT
  680. *
  681. * Checks the OS we are running on and returns TRUE for WinNT
  682. * False for Win9x
  683. */
  684. BOOL bCheckifRunningOnWinNT()
  685. {
  686. OSVERSIONINFO osvi = {0};
  687. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  688. GetVersionEx(&osvi);
  689. return (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT);
  690. }
  691. ///////////////////////////////////////////////////////////////////////////////
  692. // ConvertAtoW
  693. //
  694. // Helper function
  695. ///////////////////////////////////////////////////////////////////////////////
  696. LPWSTR ConvertAtoW(LPCSTR lpszA)
  697. {
  698. int cch;
  699. LPWSTR lpW = NULL;
  700. ULONG ulSize;
  701. if ( !lpszA)
  702. goto ret;
  703. cch = (lstrlenA( lpszA ) + 1);
  704. ulSize = cch*sizeof(WCHAR);
  705. if(lpW = LocalAlloc(LMEM_ZEROINIT, ulSize))
  706. {
  707. MultiByteToWideChar( GetACP(), 0, lpszA, -1, lpW, cch );
  708. }
  709. ret:
  710. return lpW;
  711. }
  712. //$$//////////////////////////////////////////////////////////////////////
  713. //
  714. // WinMain
  715. //
  716. //////////////////////////////////////////////////////////////////////////
  717. int WINAPI WinMain( HINSTANCE hInstance,
  718. HINSTANCE hPrevInstance,
  719. LPSTR lpszCmdLine,
  720. int nCmdShow)
  721. {
  722. HWND hwnd = NULL;
  723. MSG msg ;
  724. LPWABOBJECT lpWABObject = NULL;
  725. LPADRBOOK lpAdrBook = NULL;
  726. HRESULT hResult = hrSuccess;
  727. ADRPARM AdrParms = {0};
  728. WAB_PARAM WP = {0};
  729. LPTSTR szFileName = NULL;
  730. int nLen = MAX_PATH+1;
  731. //TCHAR szFileName[MAX_PATH+1];
  732. //TCHAR szDefaultFile[MAX_PATH+1];
  733. LPTSTR lpszTitle = NULL;
  734. ULONG ulFlag = 0;
  735. LPTSTR lpszVCardFileName = NULL;
  736. LPTSTR lpszCertFileName = NULL;
  737. LPTSTR lpszLDAPUrl = NULL;
  738. // "Windows Address Book" - used for msgboxes when we dont have
  739. // a file name
  740. TCHAR szWABTitle[MAX_PATH];
  741. // Contains the opened file name in the title
  742. // This makes it easier to search for a default address book
  743. // even if mutiple other ones are open
  744. TCHAR szWABTitleWithFileName[MAX_PATH];
  745. // Check which platform we are running on.
  746. BOOL bRunningOnNT = bCheckifRunningOnWinNT();
  747. hInstApp = hInstance;
  748. hInst = LoadWABResourceDLL(hInstance);
  749. if(lpszCmdLine && lstrlen(lpszCmdLine) > nLen)
  750. nLen = lstrlen(lpszCmdLine)+1;
  751. szFileName = LocalAlloc(LMEM_ZEROINIT, nLen*sizeof(TCHAR));
  752. if(!szFileName)
  753. goto out;
  754. // if this is the firstrun flag, all we need to do is call WABOpen and then exit
  755. //
  756. if(!lstrcmpi(lpszCmdLine,szParamFirstRun))
  757. {
  758. const LPTSTR lpszNewWABKey = TEXT("Software\\Microsoft\\WAB\\WAB4");
  759. const LPTSTR lpszFirstRunValue = TEXT("FirstRun");
  760. HKEY hKey = NULL;
  761. DWORD dwType = 0, dwValue = 0, dwSize = sizeof(DWORD);
  762. // First check if this is a first run - if its not a first run then we can just skip out
  763. if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, lpszNewWABKey, 0, KEY_READ, &hKey))
  764. {
  765. if(ERROR_SUCCESS == RegQueryValueEx( hKey, lpszFirstRunValue, NULL, &dwType, (LPBYTE) &dwValue, &dwSize))
  766. {
  767. if(hKey)
  768. RegCloseKey(hKey);
  769. goto out;
  770. }
  771. else
  772. if(hKey)
  773. RegCloseKey(hKey);
  774. }
  775. // Either the WAB4 key did not exist, or the first run value was not found.
  776. // In either case, fix this
  777. hInstWABDll = LoadLibrary_WABDll();
  778. if(hInstWABDll)
  779. lpfnWABOpen = (LPWABOPEN) GetProcAddress(hInstWABDll, szWABOpen);
  780. if(lpfnWABOpen)
  781. lpfnWABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
  782. goto out;
  783. }
  784. CheckWABDefaultHandler();
  785. CheckVCardDefaultHandler(NULL, hInst);
  786. szFileName[0]='\0';
  787. // We will show a file name in the title only if a file name is
  788. // explicitly specified .. if the file name is not explicitly specified,
  789. // we will revert to a generic "Address Book" title
  790. LoadString(hInst, idsWABTitle, szWABTitle, sizeof(szWABTitle));
  791. LoadString(hInst, idsWABTitleWithFileName, szWABTitleWithFileName, sizeof(szWABTitleWithFileName));
  792. // Get the default windows address book from the registry
  793. //szDefaultFile[0]='\0';
  794. //GetWABDefaultAddressBookName(szDefaultFile);
  795. if(!lstrcmpi(lpszCmdLine,szParamShowExisting))
  796. {
  797. //perhaps this already exists - find the window and set focus to it
  798. // /ShowExisting flag always opens the default wab file
  799. // The title of this wab.exe window will have the default file
  800. // name in the title.
  801. /*
  802. LPTSTR lpsz = szDefaultFile;
  803. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING |FORMAT_MESSAGE_ARGUMENT_ARRAY,
  804. szWABTitleWithFileName,
  805. 0,
  806. 0,
  807. (LPTSTR) &lpszTitle,
  808. 0,
  809. (va_list *)&lpsz);
  810. */
  811. // Create the Expected Title from the default
  812. hwnd = FindWindow("WABBrowseView", NULL);//szWABTitle); //lpszTitle);
  813. if(hwnd)
  814. {
  815. ULONG ulFlags = SW_SHOWNORMAL;
  816. ulFlags |= IsZoomed(hwnd) ? SW_SHOWMAXIMIZED : SW_RESTORE;
  817. //SetForegroundWindow(hwnd);
  818. ShowWindow(hwnd, ulFlags);
  819. SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
  820. SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
  821. SetActiveWindow(hwnd);
  822. SetFocus(hwnd);
  823. goto out;
  824. }
  825. }
  826. if (bRunningOnNT)
  827. {
  828. LPWSTR lpwszAppName = ConvertAtoW(szAppName);
  829. WNDCLASSW wndclassW;
  830. // [PaulHi] 4/29/99 Raid 75578
  831. // On NT we need to create a Unicode main window so the child windows
  832. // can display Unicode characters.
  833. wndclassW.style = CS_HREDRAW | CS_VREDRAW ;
  834. wndclassW.lpfnWndProc = WndProcW ;
  835. wndclassW.cbClsExtra = 0 ;
  836. wndclassW.cbWndExtra = 0 ;
  837. wndclassW.hInstance = hInstApp;
  838. wndclassW.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1)) ;
  839. wndclassW.hCursor = LoadCursor(NULL, IDC_ARROW) ;
  840. wndclassW.hbrBackground = GetStockObject(WHITE_BRUSH) ;
  841. wndclassW.lpszMenuName = lpwszAppName ;
  842. wndclassW.lpszClassName = lpwszAppName ;
  843. RegisterClassW(&wndclassW);
  844. hwnd = CreateWindowW (lpwszAppName, lpwszAppName,
  845. WS_OVERLAPPEDWINDOW,
  846. 0, // CW_USEDEFAULT,
  847. 0, // CW_USEDEFAULT,
  848. 300, // CW_USEDEFAULT,
  849. 200, // CW_USEDEFAULT,
  850. NULL,
  851. NULL,
  852. hInstApp,
  853. NULL);
  854. LocalFree(lpwszAppName);
  855. }
  856. else
  857. {
  858. WNDCLASS wndclass;
  859. wndclass.style = CS_HREDRAW | CS_VREDRAW ;
  860. wndclass.lpfnWndProc = WndProc ;
  861. wndclass.cbClsExtra = 0 ;
  862. wndclass.cbWndExtra = 0 ;
  863. wndclass.hInstance = hInstApp;
  864. wndclass.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON1)) ;
  865. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW) ;
  866. wndclass.hbrBackground = GetStockObject(WHITE_BRUSH) ;
  867. wndclass.lpszMenuName = szAppName ;
  868. wndclass.lpszClassName = szAppName ;
  869. RegisterClass(&wndclass);
  870. hwnd = CreateWindow (szAppName, szAppName,
  871. WS_OVERLAPPEDWINDOW,
  872. 0, // CW_USEDEFAULT,
  873. 0, // CW_USEDEFAULT,
  874. 300, // CW_USEDEFAULT,
  875. 200, // CW_USEDEFAULT,
  876. NULL,
  877. NULL,
  878. hInstApp,
  879. NULL);
  880. }
  881. if(!hwnd)
  882. goto out;
  883. else
  884. WP.hwnd = hwnd;
  885. if(lstrlen(lpszCmdLine))
  886. {
  887. if(!bGetFileNameFromCmdLine( hwnd,
  888. hInst,
  889. lpszCmdLine,
  890. szWABTitle,
  891. &ulFlag,
  892. szFileName,
  893. nLen))
  894. {
  895. goto out;
  896. }
  897. }
  898. if(ulFlag & WAB_VCARDFILE)
  899. {
  900. StripQuotes(szFileName);
  901. lpszVCardFileName = szFileName;
  902. // [PaulHi] 12/2/98 Raid #55033
  903. WP.ulFlags = WAB_ENABLE_PROFILES;
  904. }
  905. else if(ulFlag & WAB_LDAPURL)
  906. {
  907. lpszLDAPUrl = szFileName;
  908. }
  909. else if(ulFlag & WAB_CERTFILE)
  910. {
  911. StripQuotes(szFileName);
  912. lpszCertFileName = szFileName;
  913. }
  914. else if(ulFlag & WAB_ALLPROFILES)
  915. {
  916. WP.ulFlags &= ~WAB_ENABLE_PROFILES;
  917. ulFlag &= ~WAB_ALLPROFILES;
  918. }
  919. else if(szFileName && lstrlen(szFileName))
  920. {
  921. WP.szFileName = szFileName;
  922. // [PaulHi] 3/2/99 Raid 73492
  923. // [PaulHi] 4/22/99 Modified
  924. // Can't do this because identity mode will only show folders for that
  925. // identity, which may not be the folder in this general WAB file.
  926. // WP.ulFlags = WAB_ENABLE_PROFILES; // Start with profiles on
  927. }
  928. else if(!(ulFlag & WAB_ALLPROFILES))
  929. {
  930. WP.ulFlags = WAB_ENABLE_PROFILES;
  931. }
  932. hInstWABDll = LoadLibrary_WABDll();
  933. if(hInstWABDll)
  934. lpfnWABOpen = (LPWABOPEN) GetProcAddress(hInstWABDll, szWABOpen);
  935. if(!lpfnWABOpen)
  936. goto out;
  937. WP.cbSize = sizeof(WAB_PARAM);
  938. WP.guidPSExt = MPSWab_GUID;
  939. hResult = lpfnWABOpen(&lpAdrBook, &lpWABObject, &WP, 0);
  940. if(HR_FAILED(hResult))
  941. {
  942. TCHAR szBuf[MAX_PATH];
  943. int id;
  944. switch(hResult)
  945. {
  946. case MAPI_E_NOT_ENOUGH_MEMORY:
  947. id = idsWABOpenErrorMemory;
  948. break;
  949. case MAPI_E_NO_ACCESS:
  950. id = idsWABOpenErrorLocked;
  951. break;
  952. case MAPI_E_CORRUPT_DATA:
  953. id = idsWABOpenErrorCorrupt;
  954. break;
  955. case MAPI_E_DISK_ERROR:
  956. id = idsWABOpenErrorDisk;
  957. break;
  958. case MAPI_E_INVALID_OBJECT:
  959. id = idsWABOpenErrorNotWAB;
  960. break;
  961. case E_FAIL:
  962. default:
  963. id = idsWABOpenError;
  964. break;
  965. }
  966. LoadString(hInst, id, szBuf, sizeof(szBuf));
  967. MessageBox(hwnd, szBuf, szWABTitle, MB_OK | MB_ICONERROR);
  968. goto out;
  969. }
  970. if (lpAdrBook)
  971. {
  972. if(!ulFlag)
  973. {
  974. // We are in the business of showing the address book
  975. LPTSTR lpsz = NULL;
  976. lpszTitle = NULL;
  977. if(lstrlen(szFileName))
  978. {
  979. lpsz = szFileName;
  980. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING |FORMAT_MESSAGE_ARGUMENT_ARRAY,
  981. szWABTitleWithFileName,
  982. 0,
  983. 0,
  984. (LPTSTR) &lpszTitle,
  985. 0,
  986. (va_list *)&lpsz);
  987. }
  988. AdrParms.cDestFields = 0;
  989. AdrParms.ulFlags = DIALOG_SDI;
  990. AdrParms.lpvDismissContext = NULL;
  991. AdrParms.lpfnDismiss = &WABDismissFunction;
  992. AdrParms.lpfnABSDI = NULL;
  993. //if(lpszTitle)
  994. AdrParms.lpszCaption = lpszTitle; //szWABTitle;
  995. //else // its possible to not have a file name the first time we run this ..
  996. // AdrParms.lpszCaption = szWABTitle;
  997. AdrParms.nDestFieldFocus = AdrParms.cDestFields-1;
  998. hResult = lpAdrBook->lpVtbl->Address( lpAdrBook,
  999. (ULONG_PTR *) &hwnd,
  1000. &AdrParms,
  1001. NULL);
  1002. if(HR_FAILED(hResult))
  1003. {
  1004. TCHAR szBuf[MAX_PATH];
  1005. int id;
  1006. switch(hResult)
  1007. {
  1008. case MAPI_E_UNCONFIGURED: // no commctrl
  1009. id = idsWABAddressErrorMissing;
  1010. break;
  1011. default:
  1012. id = idsWABAddressErrorMissing;
  1013. break;
  1014. }
  1015. LoadString(hInst, id, szBuf, sizeof(szBuf));
  1016. MessageBox(hwnd, szBuf, szWABTitle, MB_OK | MB_ICONERROR);
  1017. goto out;
  1018. }
  1019. // [PaulHi] 4/29/99 Raid 75578 Must use Unicode versions of
  1020. // message pump APIs for NT so Unicode data can be displayed.
  1021. if (bRunningOnNT)
  1022. {
  1023. while (GetMessageW(&msg, NULL, 0, 0))
  1024. {
  1025. if (AdrParms.lpfnABSDI)
  1026. {
  1027. if ((*(AdrParms.lpfnABSDI))((ULONG_PTR) hwnd, (LPVOID) &msg))
  1028. continue;
  1029. }
  1030. TranslateMessage(&msg);
  1031. DispatchMessageW(&msg);
  1032. }
  1033. }
  1034. else
  1035. {
  1036. while (GetMessage(&msg, NULL, 0, 0))
  1037. {
  1038. if (AdrParms.lpfnABSDI)
  1039. {
  1040. if ((*(AdrParms.lpfnABSDI))((ULONG_PTR) hwnd, (LPVOID) &msg))
  1041. continue;
  1042. }
  1043. TranslateMessage (&msg) ;
  1044. DispatchMessage (&msg) ;
  1045. }
  1046. }
  1047. }
  1048. else if(ulFlag & WAB_FINDSESSION)
  1049. {
  1050. lpWABObject->lpVtbl->Find( lpWABObject,
  1051. (LPADRBOOK) lpAdrBook,
  1052. NULL);//hwnd);
  1053. }
  1054. else if(ulFlag & WAB_LDAPURL)
  1055. {
  1056. BOOL bUnicode = FALSE;
  1057. BOOL bIsNT = bCheckifRunningOnWinNT();
  1058. LPWSTR lpUrlW = NULL;
  1059. LPWSTR lpCmdLineW = GetCommandLineW();
  1060. //When working with LDAP URLs on NT, we want to err on the side of safety and
  1061. // get the LDAP URL in UNICODE format if possible ..
  1062. if(bIsNT)
  1063. {
  1064. LPWSTR lp = lpCmdLineW;
  1065. WCHAR szLDAPW[] = L"/ldap:";
  1066. WCHAR szTemp[16];
  1067. int nLenW = lstrlenW(szLDAPW);
  1068. // parse the command line till we find "/ldap:" and then use the
  1069. // remainder as the LDAP URL
  1070. while(lp && *lp)
  1071. {
  1072. CopyMemory(szTemp, lp, min(sizeof(szTemp),nLenW * sizeof(WCHAR)));
  1073. szTemp[nLenW] = '\0';
  1074. if(!lstrcmpiW(szTemp, szLDAPW))
  1075. {
  1076. lp+=nLenW;
  1077. lpUrlW = lp;
  1078. break;
  1079. }
  1080. else
  1081. lp++;
  1082. }
  1083. }
  1084. hResult = lpWABObject->lpVtbl->LDAPUrl(lpWABObject,
  1085. (LPADRBOOK) lpAdrBook,
  1086. hwnd,
  1087. MAPI_DIALOG | (lpUrlW ? MAPI_UNICODE : 0 ),
  1088. lpUrlW ? (LPSTR)lpUrlW : lpszLDAPUrl,
  1089. NULL);
  1090. }
  1091. else if(ulFlag & WAB_VCARDFILE)
  1092. {
  1093. hResult = lpWABObject->lpVtbl->VCardDisplay(
  1094. lpWABObject,
  1095. (LPADRBOOK) lpAdrBook,
  1096. NULL, //hwnd,
  1097. lpszVCardFileName);
  1098. if(HR_FAILED(hResult) && (hResult != MAPI_E_USER_CANCEL))
  1099. {
  1100. TCHAR szBuf[MAX_PATH];
  1101. int id;
  1102. switch(hResult)
  1103. {
  1104. default:
  1105. id = idsWABOpenVCardError;
  1106. break;
  1107. }
  1108. LoadString(hInst, id, szBuf, sizeof(szBuf));
  1109. MessageBox(hwnd, szBuf, szWABTitle, MB_OK | MB_ICONERROR);
  1110. goto out;
  1111. }
  1112. }
  1113. else if(ulFlag & WAB_CERTFILE)
  1114. {
  1115. CertFileDisplay(NULL, // hwnd
  1116. lpWABObject,
  1117. lpAdrBook,
  1118. lpszCertFileName);
  1119. }
  1120. }
  1121. out:
  1122. if(lpAdrBook)
  1123. lpAdrBook->lpVtbl->Release(lpAdrBook);
  1124. if (lpWABObject)
  1125. lpWABObject->lpVtbl->Release(lpWABObject);
  1126. if (lpszTitle)
  1127. LocalFree(lpszTitle);
  1128. if(hInstWABDll)
  1129. FreeLibrary(hInstWABDll);
  1130. if(szFileName)
  1131. LocalFree(szFileName);
  1132. if(hInst)
  1133. FreeLibrary(hInst);
  1134. return (int) msg.wParam;
  1135. }
  1136. //$$//////////////////////////////////////////////////////////////////
  1137. //
  1138. // WndProc for the hidden parent window that launches the UI
  1139. //
  1140. ////////////////////////////////////////////////////////////////////////
  1141. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
  1142. switch (message) {
  1143. case WM_CREATE:
  1144. break;
  1145. case WM_DESTROY:
  1146. PostQuitMessage(0);
  1147. return(0);
  1148. }
  1149. return(DefWindowProc (hwnd, message, wParam, lParam));
  1150. }
  1151. //$$//////////////////////////////////////////////////////////////////
  1152. //
  1153. // WndProc for the hidden parent window that launches the UI. Unicode version
  1154. //
  1155. ////////////////////////////////////////////////////////////////////////
  1156. LRESULT CALLBACK WndProcW (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
  1157. switch (message) {
  1158. case WM_CREATE:
  1159. break;
  1160. case WM_DESTROY:
  1161. PostQuitMessage(0);
  1162. return(0);
  1163. }
  1164. return(DefWindowProcW (hwnd, message, wParam, lParam));
  1165. }
  1166. //$$//////////////////////////////////////////////////////////////////
  1167. //
  1168. ////////////////////////////////////////////////////////////////////////
  1169. int _stdcall WinMainCRTStartup (void)
  1170. {
  1171. int i;
  1172. STARTUPINFOA si;
  1173. PTSTR pszCmdLine = GetCommandLine();
  1174. SetErrorMode(SEM_FAILCRITICALERRORS);
  1175. if (*pszCmdLine == TEXT ('\"')) {
  1176. // Scan, and skip over, subsequent characters until
  1177. // another double-quote or a null is encountered.
  1178. while (*++pszCmdLine && (*pszCmdLine != TEXT ('\"')));
  1179. // If we stopped on a double-quote (usual case), skip over it.
  1180. if (*pszCmdLine == TEXT ('\"')) {
  1181. pszCmdLine++;
  1182. }
  1183. } else {
  1184. while (*pszCmdLine > TEXT (' ')) {
  1185. pszCmdLine++;
  1186. }
  1187. }
  1188. // Skip past any white space preceeding the second token.
  1189. while (*pszCmdLine && (*pszCmdLine <= TEXT (' '))) {
  1190. pszCmdLine++;
  1191. }
  1192. si.dwFlags = 0;
  1193. GetStartupInfo (&si);
  1194. i = WinMainT(GetModuleHandle (NULL), NULL, pszCmdLine,
  1195. si.dwFlags & STARTF_USESHOWWINDOW ? si.wShowWindow : SW_SHOWDEFAULT);
  1196. ExitProcess(i);
  1197. return(i);
  1198. }
  1199. //$$//////////////////////////////////////////////////////////////////
  1200. //
  1201. // bGetFileNameFromDlg - opens the FIleOpen common dialog
  1202. //
  1203. ////////////////////////////////////////////////////////////////////////
  1204. BOOL bGetFileNameFromDlg(HWND hwnd,
  1205. HINSTANCE hInstance,
  1206. LPTSTR lpszDirectory,
  1207. int szTitleID,
  1208. DWORD dwFlags,
  1209. LPTSTR szFileName,
  1210. DWORD cchFileName)
  1211. {
  1212. OPENFILENAME ofn;
  1213. TCHAR szBuf[MAX_PATH];
  1214. BOOL bRet = FALSE;
  1215. TCHAR szFile[MAX_PATH];
  1216. LPTSTR lpFilter = FormatAllocFilter(idsWABOpenFileFilter, szWABFilter, hInstance);
  1217. szFile[0]='\0';
  1218. LoadString(hInstance, szTitleID, szBuf, sizeof(szBuf));
  1219. ofn.lStructSize = sizeof(ofn);
  1220. ofn.hwndOwner = hwnd;
  1221. ofn.hInstance = hInstance;
  1222. ofn.lpstrFilter = lpFilter;
  1223. ofn.lpstrCustomFilter = NULL;
  1224. ofn.nMaxCustFilter = 0;
  1225. ofn.nFilterIndex = 0;
  1226. ofn.lpstrFile = szFile;
  1227. ofn.nMaxFile = sizeof(szFile);
  1228. ofn.lpstrFileTitle = NULL;
  1229. ofn.nMaxFileTitle = 0;
  1230. ofn.lpstrInitialDir = lpszDirectory;
  1231. ofn.lpstrTitle = szBuf;
  1232. ofn.nFileOffset = 0;
  1233. ofn.nFileExtension = 0;
  1234. ofn.lpstrDefExt = "wab";
  1235. ofn.lCustData = 0;
  1236. ofn.lpfnHook = NULL;
  1237. ofn.lpTemplateName = NULL;
  1238. ofn.Flags = dwFlags;
  1239. if(GetOpenFileName(&ofn))
  1240. {
  1241. bRet = TRUE;
  1242. StrCpyN(szFileName, szFile, cchFileName);
  1243. }
  1244. if(lpFilter)
  1245. LocalFree(lpFilter);
  1246. return bRet;
  1247. }
  1248. /***************************************************************************
  1249. Name : StrICmpN
  1250. Purpose : Compare strings, ignore case, stop at N characters
  1251. Parameters: szString1 = first string
  1252. szString2 = second string
  1253. N = number of characters to compare
  1254. Returns : 0 if first N characters of strings are equivalent.
  1255. Comment :
  1256. ***************************************************************************/
  1257. int StrICmpN(LPTSTR lpsz1, LPTSTR lpsz2, ULONG N) {
  1258. int Result = 0;
  1259. LPTSTR szString1 = NULL, lp1 = NULL;
  1260. LPTSTR szString2 = NULL, lp2 = NULL;
  1261. ULONG cchString1, cchString2;
  1262. cchString1 = lstrlen(lpsz1)+1;
  1263. szString1 = LocalAlloc(LMEM_ZEROINIT, cchString1);
  1264. if(!szString1)
  1265. return 1;
  1266. lp1 = szString1;
  1267. cchString2 = lstrlen(lpsz2)+1;
  1268. szString2 = LocalAlloc(LMEM_ZEROINIT, cchString2);
  1269. if(!szString2)
  1270. return 1;
  1271. lp2 = szString2;
  1272. StrCpyN(szString1, lpsz1, cchString1);
  1273. StrCpyN(szString2, lpsz2, cchString2);
  1274. if (szString1 && szString2) {
  1275. szString1 = CharUpper(szString1);
  1276. szString2 = CharUpper(szString2);
  1277. while (*szString1 && *szString2 && N)
  1278. {
  1279. N--;
  1280. if (*szString1 != *szString2)
  1281. {
  1282. Result = 1;
  1283. break;
  1284. }
  1285. szString1=CharNext(szString1);
  1286. szString2=CharNext(szString2);
  1287. }
  1288. } else {
  1289. Result = -1; // arbitrarily non-equal result
  1290. }
  1291. if(lp1)
  1292. LocalFree(lp1);
  1293. if(lp2)
  1294. LocalFree(lp2);
  1295. return(Result);
  1296. }
  1297. //$$//////////////////////////////////////////////////////////////////
  1298. //
  1299. // bGetFileNameFromCmdLine - Parses command line and acts appropriately till
  1300. // we have a valid filename, cancel or failure.
  1301. //
  1302. // Input parameters -
  1303. // hWnd
  1304. // hInstance
  1305. // lpszCmdLine
  1306. // szWabTitle (for message boxes)
  1307. // szFileName - file name returned from command line
  1308. //
  1309. // Command line Parameters we understand so far
  1310. //
  1311. // (none) - opens default wab file
  1312. // /find - launches wab with find window
  1313. // filename- opens the file
  1314. // /open - open file dialog to pick a wab file
  1315. // /new - new file dialog to create a wab file
  1316. // /showexisting - brings any already open default-wab file browse
  1317. // view to the forefront
  1318. // /? -? - pops up a parameter dialog
  1319. //
  1320. ////////////////////////////////////////////////////////////////////////
  1321. BOOL bGetFileNameFromCmdLine(HWND hwnd,
  1322. HINSTANCE hInstance,
  1323. LPTSTR lpszCmdLine,
  1324. LPTSTR szWABTitle,
  1325. ULONG * lpulFlag,
  1326. LPTSTR szFileName,
  1327. DWORD cchFileName)
  1328. {
  1329. BOOL bRet = FALSE;
  1330. TCHAR szBuf[2*MAX_PATH];
  1331. LPTSTR lpTemp = lpszCmdLine;
  1332. // if(lpbIsVCardFile)
  1333. // *lpbIsVCardFile = FALSE;
  1334. if(lpulFlag)
  1335. *lpulFlag = 0;
  1336. else
  1337. goto out;
  1338. if (!lstrcmpi(lpszCmdLine,szParamShowExisting))
  1339. {
  1340. // do nothing
  1341. szFileName[0] = '\0';
  1342. bRet = TRUE;
  1343. goto out;
  1344. }
  1345. else if (!lstrcmpi(lpszCmdLine,szParamFind))
  1346. {
  1347. // do nothing
  1348. szFileName[0] = '\0';
  1349. bRet = TRUE;
  1350. *lpulFlag = WAB_FINDSESSION;
  1351. goto out;
  1352. }
  1353. else if( (!lstrcmpi(lpszCmdLine,TEXT("/?"))) ||
  1354. (!lstrcmpi(lpszCmdLine,TEXT("-?"))) )
  1355. {
  1356. LoadString(hInstance, idsWABUsage, szBuf, sizeof(szBuf));
  1357. MessageBox(hwnd, szBuf, szWABTitle, MB_OK | MB_ICONINFORMATION);
  1358. goto out;
  1359. }
  1360. else if(!lstrcmpi(lpszCmdLine,szParamOpen))
  1361. {
  1362. if(bGetFileNameFromDlg(hwnd,
  1363. hInstance,
  1364. NULL,
  1365. idsWABOpenFileTitle,
  1366. OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST,
  1367. szFileName,
  1368. cchFileName))
  1369. {
  1370. bRet = TRUE;
  1371. }
  1372. goto out;
  1373. }
  1374. else if(!lstrcmpi(lpszCmdLine,szParamNew))
  1375. {
  1376. if(bGetFileNameFromDlg(hwnd,
  1377. hInstance,
  1378. NULL,
  1379. idsWABNewFileTitle,
  1380. OFN_HIDEREADONLY | OFN_PATHMUSTEXIST,
  1381. szFileName,
  1382. cchFileName))
  1383. {
  1384. bRet = TRUE;
  1385. }
  1386. goto out;
  1387. }
  1388. else if (!StrICmpN(lpTemp, (LPTSTR)szParamVCard, sizeof(szParamVCard)))
  1389. {
  1390. lpTemp += sizeof(szParamVCard); // move past the switch
  1391. while(lpTemp && *lpTemp && (*lpTemp==' '))
  1392. lpTemp=CharNext(lpTemp);
  1393. if(lpTemp && lstrlen(lpTemp))
  1394. {
  1395. StrCpyN(szFileName, lpTemp, cchFileName);
  1396. *lpulFlag = WAB_VCARDFILE;
  1397. bRet = TRUE;
  1398. }
  1399. goto out;
  1400. }
  1401. else if (!StrICmpN(lpTemp, (LPTSTR)szParamCert, sizeof(szParamCert)))
  1402. {
  1403. lpTemp += sizeof(szParamCert); // move past the switch
  1404. while(lpTemp && *lpTemp && (*lpTemp==' '))
  1405. lpTemp=CharNext(lpTemp);
  1406. if(lpTemp && lstrlen(lpTemp))
  1407. {
  1408. StrCpyN(szFileName, lpTemp, cchFileName);
  1409. *lpulFlag = WAB_CERTFILE;
  1410. bRet = TRUE;
  1411. }
  1412. goto out;
  1413. }
  1414. else if (!StrICmpN(lpTemp, (LPTSTR)szParamLDAPUrl, sizeof(szParamLDAPUrl)))
  1415. {
  1416. // We are expecting a url of the form
  1417. // /ldap:ldap-url
  1418. lpTemp += sizeof(szParamLDAPUrl)-1; // move past the switch
  1419. if(lpTemp && lstrlen(lpTemp))
  1420. {
  1421. StrCpyN(szFileName, lpTemp, cchFileName);
  1422. *lpulFlag = WAB_LDAPURL;
  1423. bRet = TRUE;
  1424. }
  1425. goto out;
  1426. }
  1427. else if (!StrICmpN(lpTemp, (LPTSTR)szAllProfiles, sizeof(szAllProfiles)))
  1428. {
  1429. *lpulFlag = WAB_ALLPROFILES;
  1430. bRet = TRUE;
  1431. goto out;
  1432. }
  1433. else
  1434. {
  1435. //perhaps this is a file name
  1436. //See if we can find this file in this computer
  1437. DWORD dwAttr = GetFileAttributes(lpszCmdLine);
  1438. if(dwAttr != 0xFFFFFFFF)
  1439. {
  1440. //Found the file
  1441. if(!(dwAttr & FILE_ATTRIBUTE_DIRECTORY))
  1442. {
  1443. //Not a directory, must be a file
  1444. StrCpyN(szFileName,lpszCmdLine, cchFileName);
  1445. }
  1446. else
  1447. {
  1448. //This is a directory - open a dialog in this directory
  1449. if(bGetFileNameFromDlg(hwnd,
  1450. hInstance,
  1451. lpszCmdLine,
  1452. idsWABOpenFileTitle,
  1453. OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST,
  1454. szFileName,
  1455. cchFileName))
  1456. {
  1457. bRet = TRUE;
  1458. }
  1459. goto out;
  1460. }
  1461. }
  1462. else
  1463. {
  1464. // we couldnt find any such file
  1465. LPTSTR lpszMsg = NULL;
  1466. int nRet;
  1467. DWORD dwLastError = GetLastError();
  1468. if(dwLastError == 3)
  1469. {
  1470. // Path not found
  1471. LoadString(hInstance, idsWABPathNotFound, szBuf, sizeof(szBuf));
  1472. FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING |FORMAT_MESSAGE_ARGUMENT_ARRAY,
  1473. szBuf,
  1474. 0,
  1475. 0,
  1476. (LPTSTR) &lpszMsg,
  1477. 0,
  1478. (va_list *)&lpszCmdLine);
  1479. MessageBox( NULL, lpszMsg, szWABTitle, MB_OK|MB_ICONEXCLAMATION );
  1480. LocalFree( lpszMsg );
  1481. goto out;
  1482. }
  1483. else if(dwLastError == 2)
  1484. {
  1485. // File not found
  1486. LoadString(hInstance, idsWABFileNotFound, szBuf, sizeof(szBuf));
  1487. FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING |FORMAT_MESSAGE_ARGUMENT_ARRAY,
  1488. szBuf,
  1489. 0,
  1490. 0,
  1491. (LPTSTR) &lpszMsg,
  1492. 0,
  1493. (va_list *)&lpszCmdLine);
  1494. nRet = MessageBox(hwnd, lpszMsg, szWABTitle, MB_YESNO | MB_ICONEXCLAMATION);
  1495. LocalFree( lpszMsg );
  1496. switch(nRet)
  1497. {
  1498. case IDYES:
  1499. // use this as the file name (TBD - waht if path doesnt match ?)
  1500. StrCpyN(szFileName,lpszCmdLine, cchFileName);
  1501. bRet = TRUE;
  1502. break;
  1503. case IDNO:
  1504. goto out;
  1505. break;
  1506. }
  1507. }
  1508. else
  1509. {
  1510. LoadString(hInstance, idsWABInvalidCmdLine, szBuf, sizeof(szBuf));
  1511. MessageBox( NULL, szBuf, szWABTitle, MB_OK|MB_ICONEXCLAMATION );
  1512. goto out;
  1513. }
  1514. }
  1515. }
  1516. bRet = TRUE;
  1517. out:
  1518. return bRet;
  1519. }
  1520. //$$//////////////////////////////////////////////////////////////////////
  1521. //
  1522. // GetWABDllPath
  1523. //
  1524. //
  1525. //////////////////////////////////////////////////////////////////////////
  1526. void GetWABDllPath(LPTSTR szPath, ULONG cb)
  1527. {
  1528. DWORD dwType = 0;
  1529. ULONG cbData;
  1530. HKEY hKey = NULL;
  1531. TCHAR szPathT[MAX_PATH];
  1532. if(szPath)
  1533. {
  1534. *szPath = '\0';
  1535. // open the szWABDllPath key under
  1536. if (ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1537. WAB_DLL_PATH_KEY,
  1538. 0, //reserved
  1539. KEY_READ,
  1540. &hKey))
  1541. {
  1542. cbData = sizeof(szPathT);
  1543. if (ERROR_SUCCESS == RegQueryValueEx( hKey,
  1544. "",
  1545. NULL,
  1546. &dwType,
  1547. (LPBYTE) szPathT,
  1548. &cbData))
  1549. {
  1550. if (dwType == REG_EXPAND_SZ)
  1551. cbData = ExpandEnvironmentStrings(szPathT, szPath, cb / sizeof(TCHAR));
  1552. else
  1553. {
  1554. if(GetFileAttributes(szPathT) != 0xFFFFFFFF)
  1555. StrCpyN(szPath, szPathT, cb / sizeof(TCHAR));
  1556. }
  1557. }
  1558. }
  1559. }
  1560. if(hKey)
  1561. RegCloseKey(hKey);
  1562. }
  1563. //$$//////////////////////////////////////////////////////////////////////
  1564. //
  1565. // LoadLibrary_WABDll()
  1566. //
  1567. // Since we are moving the WAB directory out of Windows\SYstem, we cant be
  1568. // sure it will be on the path. Hence we need to make sure that WABOpen will
  1569. // work - by loading the wab32.dll upfront
  1570. //
  1571. ///////////////////////////////////////////////////////////////////////////
  1572. HINSTANCE LoadLibrary_WABDll()
  1573. {
  1574. LPTSTR lpszWABDll = TEXT("Wab32.dll");
  1575. TCHAR szWABDllPath[MAX_PATH];
  1576. HINSTANCE hinst = NULL;
  1577. GetWABDllPath(szWABDllPath, sizeof(szWABDllPath));
  1578. hinst = LoadLibrary( (lstrlen(szWABDllPath)) ? szWABDllPath : lpszWABDll );
  1579. return hinst;
  1580. }