Source code of Windows XP (NT5)
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.

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