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.

489 lines
12 KiB

  1. // Copyright (c) 2002 Microsoft Corporation
  2. //
  3. // File: InstallationProgressPage.cpp
  4. //
  5. // Synopsis: Defines the Installation Progress Page for the CYS
  6. // wizard. This page shows the progress of the installation
  7. // through a progress bar and changing text
  8. //
  9. // History: 01/16/2002 JeffJon Created
  10. #include "pch.h"
  11. #include "resource.h"
  12. #include "InstallationUnitProvider.h"
  13. #include "InstallationProgressPage.h"
  14. static PCWSTR PROGRESS_PAGE_HELP = L"cys.chm::/cys_topnode.htm";
  15. InstallationProgressPage::InstallationProgressPage()
  16. :
  17. CYSWizardPage(
  18. IDD_PROGRESS_PAGE,
  19. IDS_PROGRESS_TITLE,
  20. IDS_PROGRESS_SUBTITLE,
  21. 0,
  22. false)
  23. {
  24. LOG_CTOR(InstallationProgressPage);
  25. }
  26. InstallationProgressPage::InstallationProgressPage(
  27. int dialogResID,
  28. int titleResID,
  29. int subtitleResID)
  30. :
  31. CYSWizardPage(
  32. dialogResID,
  33. titleResID,
  34. subtitleResID,
  35. 0,
  36. false)
  37. {
  38. LOG_CTOR(InstallationProgressPage);
  39. }
  40. InstallationProgressPage::~InstallationProgressPage()
  41. {
  42. LOG_DTOR(InstallationProgressPage);
  43. }
  44. void
  45. TimeStampTheLog(HANDLE logfileHandle)
  46. {
  47. LOG_FUNCTION(TimeStampTheLog);
  48. ASSERT(logfileHandle);
  49. SYSTEMTIME currentTime;
  50. ::ZeroMemory(&currentTime, sizeof(SYSTEMTIME));
  51. Win::GetLocalTime(currentTime);
  52. String date;
  53. HRESULT unused = Win::GetDateFormat(
  54. currentTime,
  55. date);
  56. ASSERT(SUCCEEDED(unused));
  57. String time;
  58. unused = Win::GetTimeFormat(
  59. currentTime,
  60. time);
  61. ASSERT(SUCCEEDED(unused));
  62. String logDate = String::format(
  63. L"(%1 %2)\r\n",
  64. date.c_str(),
  65. time.c_str());
  66. CYS_APPEND_LOG(logDate);
  67. }
  68. // Private window messages for sending the state of the finished thread
  69. const UINT InstallationProgressPage::CYS_THREAD_SUCCESS = WM_USER + 1001;
  70. const UINT InstallationProgressPage::CYS_THREAD_FAILED = WM_USER + 1002;
  71. const UINT InstallationProgressPage::CYS_THREAD_USER_CANCEL = WM_USER + 1003;
  72. const UINT InstallationProgressPage::CYS_PROGRESS_UPDATE = WM_USER + 1004;
  73. void _cdecl
  74. installationProc(void* p)
  75. {
  76. if (!p)
  77. {
  78. ASSERT(p);
  79. return;
  80. }
  81. InstallationProgressPage* page =
  82. reinterpret_cast<InstallationProgressPage*>(p);
  83. if (!page)
  84. {
  85. ASSERT(page);
  86. return;
  87. }
  88. unsigned int finishMessage = InstallationProgressPage::CYS_THREAD_SUCCESS;
  89. // Initialize COM for this thread
  90. HRESULT hr = ::CoInitialize(0);
  91. if (FAILED(hr))
  92. {
  93. ASSERT(SUCCEEDED(hr));
  94. return;
  95. }
  96. // Open the log file and pass the handle to the installation unit
  97. // Create the log file
  98. bool logFileAvailable = false;
  99. String logName;
  100. HANDLE logfileHandle = AppendLogFile(
  101. CYS_LOGFILE_NAME,
  102. logName);
  103. if (logfileHandle &&
  104. logfileHandle != INVALID_HANDLE_VALUE)
  105. {
  106. LOG(String::format(L"New log file was created: %1", logName.c_str()));
  107. logFileAvailable = true;
  108. // Time stamp the log
  109. TimeStampTheLog(logfileHandle);
  110. }
  111. else
  112. {
  113. LOG(L"Unable to create the log file!!!");
  114. logFileAvailable = false;
  115. }
  116. // Install the current Installation Unit. This may be one or more services depending on the
  117. // path that was taken through the wizard
  118. InstallationUnit& installationUnit =
  119. InstallationUnitProvider::GetInstance().GetCurrentInstallationUnit();
  120. // NTRAID#NTBUG-604592-2002/04/23-JeffJon-I am calling Installing here
  121. // instead of IsServiceInstalled so that we perform the action that
  122. // the user selected on the role selection page. The state of
  123. // IsServiceInstalled could have changed since they hit Next on that
  124. // page.
  125. if (!installationUnit.Installing())
  126. {
  127. UnInstallReturnType uninstallResult =
  128. installationUnit.UnInstallService(logfileHandle, page->GetHWND());
  129. // Set the uninstall result so that the finish page can read it
  130. installationUnit.SetUninstallResult(uninstallResult);
  131. if (UNINSTALL_SUCCESS == uninstallResult)
  132. {
  133. LOG(L"Service uninstalled successfully");
  134. }
  135. else if (UNINSTALL_NO_CHANGES == uninstallResult)
  136. {
  137. LOG(L"No changes");
  138. LOG(L"Not logging results");
  139. }
  140. else if (UNINSTALL_SUCCESS_REBOOT == uninstallResult)
  141. {
  142. LOG(L"Service uninstalled successfully");
  143. LOG(L"Not logging results because reboot was initiated");
  144. }
  145. else if (UNINSTALL_SUCCESS_PROMPT_REBOOT == uninstallResult)
  146. {
  147. LOG(L"Service uninstalled successfully");
  148. LOG(L"Prompting user to reboot");
  149. if (-1 == SetupPromptReboot(
  150. 0,
  151. page->GetHWND(),
  152. FALSE))
  153. {
  154. LOG(String::format(
  155. L"Failed to reboot: hr = %1!x!",
  156. Win::GetLastErrorAsHresult()));
  157. }
  158. // At this point the system should be shutting down
  159. // so don't do anything else
  160. }
  161. else
  162. {
  163. LOG(L"Service failed to uninstall");
  164. }
  165. // Add an additional line at the end of the log file
  166. // only if we are not rebooting. All the reboot
  167. // scenarios require additional logging to the same
  168. // entry.
  169. if (uninstallResult != UNINSTALL_SUCCESS_REBOOT)
  170. {
  171. CYS_APPEND_LOG(L"\r\n");
  172. }
  173. }
  174. else
  175. {
  176. InstallationReturnType installResult =
  177. installationUnit.CompletePath(logfileHandle, page->GetHWND());
  178. // Set the installation result so that the finish
  179. // page can read it
  180. installationUnit.SetInstallResult(installResult);
  181. if (INSTALL_SUCCESS == installResult)
  182. {
  183. LOG(L"Service installed successfully");
  184. }
  185. else if (INSTALL_NO_CHANGES == installResult)
  186. {
  187. LOG(L"No changes");
  188. LOG(L"Not logging results");
  189. }
  190. else if (INSTALL_SUCCESS_REBOOT == installResult)
  191. {
  192. LOG(L"Service installed successfully");
  193. LOG(L"Not logging results because reboot was initiated");
  194. }
  195. else if (INSTALL_SUCCESS_PROMPT_REBOOT == installResult)
  196. {
  197. LOG(L"Service installed successfully");
  198. LOG(L"Prompting user to reboot");
  199. if (-1 == SetupPromptReboot(
  200. 0,
  201. page->GetHWND(),
  202. FALSE))
  203. {
  204. LOG(String::format(
  205. L"Failed to reboot: hr = %1!x!",
  206. Win::GetLastErrorAsHresult()));
  207. }
  208. // At this point the system should be shutting down
  209. // so don't do anything else
  210. }
  211. else
  212. {
  213. LOG(L"Service failed to install");
  214. }
  215. // Add an additional line at the end of the log file
  216. // only if we are not rebooting. All the reboot
  217. // scenarios require additional logging to the same
  218. // entry.
  219. if (installResult != INSTALL_SUCCESS_REBOOT)
  220. {
  221. CYS_APPEND_LOG(L"\r\n");
  222. }
  223. }
  224. // Close the log file
  225. Win::CloseHandle(logfileHandle);
  226. Win::SendMessage(
  227. page->GetHWND(),
  228. finishMessage,
  229. 0,
  230. 0);
  231. CoUninitialize();
  232. }
  233. void
  234. InstallationProgressPage::OnInit()
  235. {
  236. LOG_FUNCTION(InstallationProgressPage::OnInit);
  237. CYSWizardPage::OnInit();
  238. // Disable all the buttons on the page. The
  239. // user shouldn't really be able to do anything on
  240. // this page. Just sit back relax and watch the
  241. // installation happen.
  242. Win::PropSheet_SetWizButtons(
  243. Win::GetParent(hwnd),
  244. 0);
  245. SetCancelState(false);
  246. // Start up the animation
  247. Win::Animate_Open(
  248. Win::GetDlgItem(hwnd, IDC_ANIMATION),
  249. MAKEINTRESOURCE(IDR_PROGRESS_AVI));
  250. // Start up another thread that will perform the operations
  251. // and post messages back to the page to update the UI
  252. _beginthread(installationProc, 0, this);
  253. }
  254. bool
  255. InstallationProgressPage::OnMessage(
  256. UINT message,
  257. WPARAM wparam,
  258. LPARAM lparam)
  259. {
  260. // LOG_FUNCTION(InstallationProgressPage::OnMessage);
  261. bool result = false;
  262. switch (message)
  263. {
  264. case CYS_PROGRESS_UPDATE:
  265. {
  266. String update = reinterpret_cast<PCWSTR>(wparam);
  267. Win::SetDlgItemText(
  268. hwnd,
  269. IDC_STEP_TEXT_STATIC,
  270. update);
  271. }
  272. break;
  273. case CYS_THREAD_USER_CANCEL:
  274. // shouldCancel = true;
  275. // fall through...
  276. case CYS_THREAD_SUCCESS:
  277. case CYS_THREAD_FAILED:
  278. {
  279. Win::Animate_Stop(Win::GetDlgItem(hwnd, IDC_ANIMATION));
  280. InstallationUnit& installationUnit =
  281. InstallationUnitProvider::GetInstance().
  282. GetCurrentInstallationUnit();
  283. bool continueToNext = false;
  284. if (installationUnit.Installing())
  285. {
  286. InstallationReturnType installResult =
  287. installationUnit.GetInstallResult();
  288. if (installResult != INSTALL_SUCCESS_REBOOT &&
  289. installResult != INSTALL_SUCCESS_PROMPT_REBOOT)
  290. {
  291. continueToNext = true;
  292. }
  293. }
  294. else
  295. {
  296. UnInstallReturnType uninstallResult =
  297. installationUnit.GetUnInstallResult();
  298. if (uninstallResult != UNINSTALL_SUCCESS_REBOOT &&
  299. uninstallResult != UNINSTALL_SUCCESS_PROMPT_REBOOT)
  300. {
  301. continueToNext = true;
  302. }
  303. }
  304. if (continueToNext)
  305. {
  306. Win::PropSheet_PressButton(
  307. Win::GetParent(hwnd),
  308. PSBTN_NEXT);
  309. }
  310. result = true;
  311. break;
  312. }
  313. default:
  314. {
  315. result =
  316. CYSWizardPage::OnMessage(
  317. message,
  318. wparam,
  319. lparam);
  320. break;
  321. }
  322. }
  323. return result;
  324. }
  325. int
  326. InstallationProgressPage::Validate()
  327. {
  328. LOG_FUNCTION(InstallationProgressPage::Validate);
  329. int nextPage = IDD_FINISH_PAGE;
  330. LOG(String::format(
  331. L"nextPage = %1!d!",
  332. nextPage));
  333. return nextPage;
  334. }
  335. bool
  336. InstallationProgressPage::OnQueryCancel()
  337. {
  338. LOG_FUNCTION(InstallationProgressPage::OnQueryCancel);
  339. // Don't allow cancel
  340. Win::SetWindowLongPtr(
  341. hwnd,
  342. DWLP_MSGRESULT,
  343. TRUE);
  344. return true;
  345. }
  346. bool
  347. InstallationProgressPage::OnSetActive()
  348. {
  349. LOG_FUNCTION(InstallationProgressPage::OnSetActive);
  350. SetCancelState(false);
  351. return true;
  352. }
  353. bool
  354. InstallationProgressPage::OnKillActive()
  355. {
  356. LOG_FUNCTION(InstallationProgressPage::OnKillActive);
  357. SetCancelState(true);
  358. return true;
  359. }
  360. void
  361. InstallationProgressPage::SetCancelState(bool enable)
  362. {
  363. LOG_FUNCTION(InstallationProgressPage::SetCancelState);
  364. // Set the state of the button
  365. Win::EnableWindow(
  366. Win::GetDlgItem(
  367. Win::GetParent(hwnd),
  368. IDCANCEL),
  369. enable);
  370. // Set the state of the X in the upper right corner
  371. HMENU menu = GetSystemMenu(GetParent(hwnd), FALSE);
  372. if (menu)
  373. {
  374. if (enable)
  375. {
  376. EnableMenuItem(
  377. menu,
  378. SC_CLOSE,
  379. MF_BYCOMMAND | MF_ENABLED);
  380. }
  381. else
  382. {
  383. EnableMenuItem(
  384. menu,
  385. SC_CLOSE,
  386. MF_BYCOMMAND | MF_GRAYED);
  387. }
  388. }
  389. }