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.

539 lines
18 KiB

  1. // ADMTMsi.cpp : Defines the initialization routines for the DLL.
  2. //
  3. #include "stdafx.h"
  4. #include <stdio.h>
  5. #include <windows.h>
  6. #include <winuser.h>
  7. #include <lm.h>
  8. #include <msi.h>
  9. #include <msiquery.h>
  10. #include "ADMTMsi.h"
  11. #include "folders.h"
  12. using namespace nsFolders;
  13. #ifdef _DEBUG
  14. #define new DEBUG_NEW
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. //
  19. // Note!
  20. //
  21. // If this DLL is dynamically linked against the MFC
  22. // DLLs, any functions exported from this DLL which
  23. // call into MFC must have the AFX_MANAGE_STATE macro
  24. // added at the very beginning of the function.
  25. //
  26. // For example:
  27. //
  28. // extern "C" BOOL PASCAL EXPORT ExportedFunction()
  29. // {
  30. // AFX_MANAGE_STATE(AfxGetStaticModuleState());
  31. // // normal function body here
  32. // }
  33. //
  34. // It is very important that this macro appear in each
  35. // function, prior to any calls into MFC. This means that
  36. // it must appear as the first statement within the
  37. // function, even before any object variable declarations
  38. // as their constructors may generate calls into the MFC
  39. // DLL.
  40. //
  41. // Please see MFC Technical Notes 33 and 58 for additional
  42. // details.
  43. //
  44. /////////////////////////////////////////////////////////////////////////////
  45. // CADMTMsiApp
  46. BEGIN_MESSAGE_MAP(CADMTMsiApp, CWinApp)
  47. //{{AFX_MSG_MAP(CADMTMsiApp)
  48. // NOTE - the ClassWizard will add and remove mapping macros here.
  49. // DO NOT EDIT what you see in these blocks of generated code!
  50. //}}AFX_MSG_MAP
  51. END_MESSAGE_MAP()
  52. /////////////////////////////////////////////////////////////////////////////
  53. // CADMTMsiApp construction
  54. CADMTMsiApp::CADMTMsiApp()
  55. {
  56. // TODO: add construction code here,
  57. // Place all significant initialization in InitInstance
  58. }
  59. /////////////////////////////////////////////////////////////////////////////
  60. // The one and only CADMTMsiApp object
  61. CADMTMsiApp theApp;
  62. HWND installWnd = 0;
  63. /********************
  64. * Helper Functions *
  65. ********************/
  66. /*********************************************************************
  67. * *
  68. * Written by: Paul Thompson *
  69. * Date: 25 JAN 2001 *
  70. * *
  71. * This function is a callback function used by GetWndFromInstall*
  72. * to compare titles and store the found HWND globally. *
  73. * *
  74. *********************************************************************/
  75. //BEGIN CheckTitle
  76. BOOL CALLBACK CheckTitle(HWND hwnd, LPARAM lParam)
  77. {
  78. /* local variables */
  79. WCHAR sText[MAX_PATH];
  80. WCHAR * pTitle;
  81. BOOL bSuccess;
  82. int len;
  83. /* function body */
  84. pTitle = (WCHAR*)lParam; //get the title to compare
  85. //get the title of this window
  86. len = GetWindowText(hwnd, sText, MAX_PATH);
  87. if ((len) && (pTitle))
  88. {
  89. if (wcsstr(sText, pTitle))
  90. {
  91. installWnd = hwnd;
  92. return FALSE;
  93. }
  94. }
  95. return TRUE;
  96. }
  97. //END CheckTitle
  98. /*********************************************************************
  99. * *
  100. * Written by: Paul Thompson *
  101. * Date: 25 JAN 2001 *
  102. * *
  103. * This function is responsible for getting the HWND of the *
  104. * current installation to be used to display a MessageBox tied to *
  105. * the install GUI. *
  106. * *
  107. *********************************************************************/
  108. //BEGIN GetWndFromInstall
  109. void GetWndFromInstall(MSIHANDLE hInstall)
  110. {
  111. /* local variables */
  112. WCHAR szPropName[MAX_PATH];
  113. UINT lret = ERROR_SUCCESS;
  114. WCHAR sTitle[MAX_PATH];
  115. DWORD nCount = MAX_PATH;
  116. /* function body */
  117. //get the installation's title
  118. wcscpy(szPropName, L"ProductName");
  119. lret = MsiGetProperty(hInstall, szPropName, sTitle, &nCount);
  120. if (lret != ERROR_SUCCESS)
  121. wcscpy(sTitle, L"ADMT Password Migration DLL");
  122. //get the window handle for the install GUI
  123. EnumChildWindows(NULL, CheckTitle, (LPARAM)sTitle);
  124. if (!installWnd)
  125. installWnd = GetForegroundWindow();
  126. }
  127. //END GetWndFromInstall
  128. /**********************
  129. * exported functions *
  130. **********************/
  131. /*********************************************************************
  132. * *
  133. * Written by: Paul Thompson *
  134. * Date: 22 DEC 2000 *
  135. * *
  136. * This function is responsible for saving current ADMT files in *
  137. * the %TEMP% folder prior to installing the new version. The *
  138. * installation will later call the restore function to restore the *
  139. * saved file. Currently this mechanism is used for saving the *
  140. * current protar.mdb database. *
  141. * *
  142. *********************************************************************/
  143. //BEGIN SaveCurrentFiles
  144. UINT __stdcall SaveCurrentFiles(MSIHANDLE hInstall)
  145. {
  146. /* local constants */
  147. const int GETENVVAR_ERROR = 0; //this indicates an error from the "GetEnvironmentVariable" function
  148. const WCHAR sDCValue[2] = L"1";
  149. /* local variables */
  150. WCHAR tempdir[MAX_PATH];
  151. WCHAR filename[MAX_PATH];
  152. WCHAR newfilename[MAX_PATH];
  153. int length;
  154. UINT lret = ERROR_SUCCESS;
  155. WCHAR sPropName[MAX_PATH];
  156. WCHAR sDir[MAX_PATH];
  157. DWORD nCount = MAX_PATH;
  158. HANDLE hFile;
  159. WIN32_FIND_DATA fDat;
  160. BOOL bSuccess;
  161. /* function body */
  162. //initialize these strings
  163. wcscpy(sPropName, L"INSTALLDIR");
  164. //if INSTALLDIR was not retrieved, set to default
  165. if (MsiGetProperty(hInstall, sPropName, sDir, &nCount) != ERROR_SUCCESS)
  166. {
  167. length = GetEnvironmentVariable( L"ProgramFiles", sDir, MAX_PATH);
  168. if (length != GETENVVAR_ERROR)
  169. wcscat(sDir, L"\\Active Directory Migration Tool\\");
  170. else
  171. return ERROR_INSTALL_FAILURE;
  172. }
  173. //find the temp dir
  174. length = GetTempPath(MAX_PATH, tempdir);
  175. if (length == 0)
  176. {
  177. return ERROR_INSTALL_FAILURE;
  178. }
  179. //copy files to temp
  180. wcscpy(filename, sDir);
  181. wcscat(filename, L"Protar.mdb");
  182. wcscpy(newfilename, tempdir);
  183. wcscat(newfilename, L"Protar.mdb");
  184. hFile = FindFirstFile(filename, &fDat);
  185. //if found, copy it
  186. if (hFile != INVALID_HANDLE_VALUE)
  187. {
  188. FindClose(hFile);
  189. bSuccess = CopyFile(filename, newfilename, FALSE);
  190. if (bSuccess)
  191. {
  192. lret = ERROR_SUCCESS;
  193. wcscpy(sPropName, L"bMDBSaved");
  194. lret = MsiSetProperty(hInstall, sPropName, sDCValue);
  195. }
  196. else
  197. lret = ERROR_INSTALL_FAILURE;
  198. }
  199. else
  200. {
  201. wcscpy(sPropName, L"bMDBNotPresent");
  202. lret = MsiSetProperty(hInstall, sPropName, sDCValue);
  203. }
  204. return lret;
  205. }
  206. //END SaveCurrentFiles
  207. /*********************************************************************
  208. * *
  209. * Written by: Paul Thompson *
  210. * Date: 22 DEC 2000 *
  211. * *
  212. * This function is responsible for restoring ADMT files *
  213. * previously stored by a call to "SaveCurrentFiles". Currently this*
  214. * mechanism is used for saving the current protar.mdb database. *
  215. * *
  216. *********************************************************************/
  217. //BEGIN RestoreFiles
  218. UINT __stdcall RestoreFiles(MSIHANDLE hInstall)
  219. {
  220. /* local constants */
  221. const int GETENVVAR_ERROR = 0; //this indicates an error from the "GetEnvironmentVariable" function
  222. const WCHAR sDCValue[2] = L"1";
  223. /* local variables */
  224. WCHAR sDir[MAX_PATH];
  225. WCHAR tempdir[MAX_PATH];
  226. WCHAR filename[MAX_PATH];
  227. WCHAR newfilename[MAX_PATH];
  228. UINT lret = ERROR_SUCCESS;
  229. BOOL bSuccess;
  230. WCHAR sPropName[MAX_PATH];
  231. DWORD nCount = MAX_PATH;
  232. int length;
  233. /* function body */
  234. //get the dir where we saved the files previously
  235. wcscpy(sPropName, L"INSTALLDIR");
  236. //if not retrieved, set to default
  237. if (MsiGetProperty(hInstall, sPropName, sDir, &nCount) != ERROR_SUCCESS)
  238. {
  239. length = GetEnvironmentVariable( L"ProgramFiles", sDir, MAX_PATH);
  240. if (length != GETENVVAR_ERROR)
  241. wcscat(sDir, L"\\Active Directory Migration Tool\\");
  242. else
  243. return ERROR_INSTALL_FAILURE;
  244. }
  245. //get the dir where we saved the files previously
  246. length = GetTempPath(MAX_PATH, tempdir);
  247. if (length == 0)
  248. {
  249. return ERROR_INSTALL_FAILURE;
  250. }
  251. //copy files back
  252. wcscpy(filename, tempdir);
  253. wcscat(filename, L"Protar.mdb");
  254. wcscpy(newfilename, sDir);
  255. wcscat(newfilename, L"Protar.mdb");
  256. bSuccess = CopyFile(filename, newfilename, FALSE);
  257. if (bSuccess)
  258. {
  259. wcscpy(sPropName, L"bMDBRestored");
  260. lret = MsiSetProperty(hInstall, sPropName, sDCValue);
  261. DeleteFile(filename);
  262. }
  263. else
  264. {
  265. lret = ERROR_INSTALL_FAILURE;
  266. }
  267. return lret;
  268. }
  269. //END RestoreFiles
  270. /*********************************************************************
  271. * *
  272. * Written by: Paul Thompson *
  273. * Date: 12 SEPT 2000 *
  274. * *
  275. * This function is responsible for displaying a message box. *
  276. * *
  277. *********************************************************************/
  278. //BEGIN DisplayExiting
  279. UINT __stdcall DisplayExiting(MSIHANDLE hInstall)
  280. {
  281. /* local variables */
  282. WCHAR sPropName[MAX_PATH];
  283. UINT lret = ERROR_SUCCESS;
  284. WCHAR sTitle[MAX_PATH] = L"";
  285. WCHAR sMsg[MAX_PATH] = L"";
  286. DWORD nCount = MAX_PATH;
  287. /* function body */
  288. //initialize these strings
  289. wcscpy(sPropName, L"bMDBSaved");
  290. //if this is not a DC, get its messages
  291. if (MsiGetProperty(hInstall, sPropName, sMsg, &nCount) == ERROR_SUCCESS)
  292. {
  293. if (!wcscmp(sMsg, L"0"))
  294. {
  295. //get the leave messagebox msg string and title for not being able to save protar.mdb
  296. wcscpy(sPropName, L"MDBLeaveMsg");
  297. nCount = MAX_PATH;
  298. lret = MsiGetProperty(hInstall, sPropName, sMsg, &nCount);
  299. if (lret != ERROR_SUCCESS)
  300. wcscpy(sMsg, L"ADMT's internal database, protar.mdb, could not be saved. The installation cannot continue.");
  301. wcscpy(sPropName, L"MDBLeaveTitle");
  302. nCount = MAX_PATH;
  303. lret = MsiGetProperty(hInstall, sPropName, sTitle, &nCount);
  304. if (lret != ERROR_SUCCESS)
  305. wcscpy(sTitle, L"Protar.mdb Not Saved!");
  306. }
  307. else
  308. {
  309. //get the leave messagebox msg string and title for not being able to restore protar.mdb
  310. wcscpy(sPropName, L"MDB2LeaveMsg");
  311. nCount = MAX_PATH;
  312. lret = MsiGetProperty(hInstall, sPropName, sMsg, &nCount);
  313. if (lret != ERROR_SUCCESS)
  314. {
  315. wcscpy(sMsg, L"ADMT's internal database, protar.mdb, could not be restored. Manually restore");
  316. wcscat(sMsg, L" it from the, environment variable, TEMP directory.");
  317. }
  318. wcscpy(sPropName, L"MDB2LeaveTitle");
  319. nCount = MAX_PATH;
  320. lret = MsiGetProperty(hInstall, sPropName, sTitle, &nCount);
  321. if (lret != ERROR_SUCCESS)
  322. wcscpy(sTitle, L"Protar.mdb Not Restored!");
  323. }
  324. }
  325. GetWndFromInstall(hInstall);
  326. MessageBox(installWnd, sMsg, sTitle, MB_ICONSTOP | MB_OK);
  327. return lret;
  328. }
  329. //END DisplayExiting
  330. /*********************************************************************
  331. * *
  332. * Written by: Paul Thompson *
  333. * Date: 14 JAN 2000 *
  334. * *
  335. * This function is responsible for displaying a message box. *
  336. * *
  337. *********************************************************************/
  338. //BEGIN IsUpgrade
  339. UINT __stdcall IsUpgrade(MSIHANDLE hInstall)
  340. {
  341. /* local constants */
  342. const int GETENVVAR_ERROR = 0; //this indicates an error from the "GetEnvironmentVariable" function
  343. const WCHAR sExit[2] = L"1";
  344. /* local variables */
  345. WCHAR sPropName[MAX_PATH];
  346. UINT lret = ERROR_SUCCESS;
  347. WCHAR sTitle[MAX_PATH] = L"";
  348. WCHAR sMsg[MAX_PATH] = L"";
  349. WCHAR sDir[MAX_PATH] = L"";
  350. WCHAR sKey[MAX_PATH] = L"";
  351. DWORD nCount = MAX_PATH;
  352. long lrtn = ERROR_SUCCESS;
  353. HKEY hADMTKey;
  354. int length;
  355. /* function body */
  356. /* see if ADMT V1.0 is installed by looking at the registry and find
  357. out where it is installed at */
  358. bool bNewVersionInstalled = false;
  359. bool bToUpgrade = false; // indicates whether to check upgrade or not
  360. bool bADMTKeyOpened = false;
  361. // open the ADMT Registry key under Software\Microsoft and check RegistryUpdated key value
  362. // if the RegistryUpdated value exists and is REG_DWORD, the new version is installed
  363. lret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_ADMT, 0, KEY_READ, &hADMTKey);
  364. if (lret == ERROR_SUCCESS)
  365. {
  366. DWORD type;
  367. DWORD value;
  368. DWORD valueSize = sizeof(value);
  369. lret = RegQueryValueEx(hADMTKey, REGVAL_REGISTRYUPDATED, NULL, &type, (LPBYTE)&value, &valueSize);
  370. if (lret != ERROR_SUCCESS)
  371. {
  372. lret = ERROR_SUCCESS; // we ignore all errors
  373. }
  374. else if (type == REG_DWORD)
  375. {
  376. bNewVersionInstalled = true;
  377. }
  378. RegCloseKey(hADMTKey);
  379. }
  380. else if (lret == ERROR_FILE_NOT_FOUND)
  381. {
  382. // if this key cannot be found, it is Ok
  383. lret = ERROR_SUCCESS;
  384. }
  385. // if the new version is not installed, it is necessary to check whether to upgrade
  386. if (lret == ERROR_SUCCESS && !bNewVersionInstalled)
  387. {
  388. lret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_MCSADMT, 0, KEY_READ, &hADMTKey);
  389. if (lret == ERROR_SUCCESS)
  390. {
  391. // we need to attempt to upgrade from v1 to v2
  392. bToUpgrade = true;
  393. bADMTKeyOpened = true;
  394. }
  395. else if (lret == ERROR_FILE_NOT_FOUND)
  396. {
  397. lret = ERROR_SUCCESS;
  398. }
  399. }
  400. // check if to upgrade
  401. if (bToUpgrade)
  402. {
  403. //get the current install path
  404. wcscpy(sPropName, L"Directory");
  405. nCount = MAX_PATH;
  406. if (RegQueryValueEx(hADMTKey, sPropName, NULL, NULL,
  407. (LPBYTE)sDir, &nCount) != ERROR_SUCCESS)
  408. {
  409. length = GetEnvironmentVariable( L"ProgramFiles", sDir, MAX_PATH);
  410. if (length != GETENVVAR_ERROR)
  411. {
  412. wcscat(sDir, L"\\Active Directory Migration Tool\\");
  413. lret = ERROR_SUCCESS;
  414. }
  415. else
  416. lret = ERROR_INSTALL_FAILURE;
  417. }
  418. RegCloseKey(hADMTKey);
  419. bADMTKeyOpened = false;
  420. if (lret == ERROR_SUCCESS)
  421. {
  422. //now see if V1.0 is really installed (key exists)
  423. wcscpy(sKey, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{76789332-34CD-11D3-9E6A-00A0C9AFE10F}");
  424. lret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, sKey, 0, KEY_READ, &hADMTKey);
  425. if (lret == ERROR_SUCCESS)
  426. {
  427. bADMTKeyOpened = true;
  428. //get the upgrade messagebox msg string and title
  429. AFX_MANAGE_STATE(AfxGetStaticModuleState()); // make sure we can get the right resource
  430. CString szMsg;
  431. CString szTitle;
  432. wcscpy(sPropName, L"UpgradeMsg");
  433. nCount = MAX_PATH;
  434. lret = MsiGetProperty(hInstall, sPropName, sMsg, &nCount);
  435. if (lret != ERROR_SUCCESS)
  436. szMsg.LoadString(IDS_SETUP_UPGRADE_MESSAGE);
  437. else
  438. szMsg = sMsg;
  439. nCount = MAX_PATH;
  440. wcscpy(sPropName, L"UpgradeTitle");
  441. lret = MsiGetProperty(hInstall, sPropName, sTitle, &nCount);
  442. if (lret != ERROR_SUCCESS)
  443. szTitle.LoadString(IDS_SETUP_UPGRADE_TITLE);
  444. else
  445. szTitle = sTitle;
  446. //if they want to upgrade, save the install path
  447. GetWndFromInstall(hInstall);
  448. if (MessageBox(installWnd, szMsg, szTitle, MB_ICONQUESTION | MB_YESNO) == IDYES)
  449. {
  450. wcscpy(sPropName, L"INSTALLDIR");
  451. lret = MsiSetProperty(hInstall, sPropName, sDir);
  452. }
  453. else //else, set the flag to exit the install
  454. {
  455. wcscpy(sPropName, L"bUpgradeExit");
  456. lret = MsiSetProperty(hInstall, sPropName, sExit);
  457. }
  458. }
  459. else if (lret == ERROR_FILE_NOT_FOUND)
  460. lret = ERROR_SUCCESS;
  461. }
  462. }
  463. // if the ADMT key is still opened, close it
  464. if (bADMTKeyOpened)
  465. RegCloseKey(hADMTKey);
  466. return lret;
  467. }
  468. //END IsUpgrade