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.

536 lines
13 KiB

  1. // Copyright (c) 2001 Microsoft Corporation
  2. //
  3. // File: PrintInstallationUnit.cpp
  4. //
  5. // Synopsis: Defines a PrintInstallationUnit
  6. // This object has the knowledge for installing the
  7. // printer services
  8. //
  9. // History: 02/06/2001 JeffJon Created
  10. #include "pch.h"
  11. #include "resource.h"
  12. #include "PrintInstallationUnit.h"
  13. // Finish page help
  14. static PCWSTR CYS_PRINT_FINISH_PAGE_HELP = L"cys.chm::/print_server_role.htm";
  15. static PCWSTR CYS_PRINT_MILESTONE_HELP = L"cys.chm::/print_server_role.htm#printsrvsummary";
  16. static PCWSTR CYS_PRINT_AFTER_FINISH_HELP = L"cys.chm::/print_server_role.htm#printsrvcompletion";
  17. PrintInstallationUnit::PrintInstallationUnit() :
  18. printRoleResult(PRINT_SUCCESS),
  19. forAllClients(false),
  20. InstallationUnit(
  21. IDS_PRINT_SERVER_TYPE,
  22. IDS_PRINT_SERVER_DESCRIPTION,
  23. IDS_PRINT_FINISH_TITLE,
  24. IDS_PRINT_FINISH_UNINSTALL_TITLE,
  25. IDS_PRINT_FINISH_MESSAGE,
  26. IDS_PRINT_SUCCESS_NO_SHARES,
  27. IDS_PRINT_UNINSTALL_MESSAGE,
  28. IDS_PRINT_UNINSTALL_FAILED,
  29. IDS_PRINT_UNINSTALL_WARNING,
  30. IDS_PRINT_UNINSTALL_CHECKBOX,
  31. CYS_PRINT_FINISH_PAGE_HELP,
  32. CYS_PRINT_MILESTONE_HELP,
  33. CYS_PRINT_AFTER_FINISH_HELP,
  34. PRINTSERVER_SERVER)
  35. {
  36. LOG_CTOR(PrintInstallationUnit);
  37. }
  38. PrintInstallationUnit::~PrintInstallationUnit()
  39. {
  40. LOG_DTOR(PrintInstallationUnit);
  41. }
  42. InstallationReturnType
  43. PrintInstallationUnit::InstallService(HANDLE logfileHandle, HWND hwnd)
  44. {
  45. LOG_FUNCTION(PrintInstallationUnit::InstallService);
  46. InstallationReturnType result = INSTALL_SUCCESS;
  47. printRoleResult = PRINT_SUCCESS;
  48. String resultText;
  49. // Always execute the Add Printer Wizard
  50. CYS_APPEND_LOG(String::load(IDS_PRINTER_WIZARD_CONFIG_LOG_TEXT));
  51. HRESULT hr = S_OK;
  52. UpdateInstallationProgressText(hwnd, IDS_PRINT_PROGRESS_PRINTER_WIZARD);
  53. if (ExecuteWizard(hwnd, CYS_PRINTER_WIZARD_NAME, resultText, hr))
  54. {
  55. // if there are shared printers, then we consider ourselves
  56. // successful.
  57. if (IsServiceInstalled())
  58. {
  59. CYS_APPEND_LOG(String::load(IDS_PRINT_SERVER_SUCCESSFUL));
  60. }
  61. else
  62. {
  63. if (SUCCEEDED(hr))
  64. {
  65. CYS_APPEND_LOG(String::load(IDS_PRINT_SERVER_UNSUCCESSFUL));
  66. result = INSTALL_FAILURE;
  67. printRoleResult = PRINT_WIZARD_RUN_NO_SHARES;
  68. }
  69. else
  70. {
  71. // The call to ExecuteWizard should have provided us with the
  72. // error message.
  73. ASSERT(!resultText.empty());
  74. CYS_APPEND_LOG(resultText);
  75. result = INSTALL_FAILURE;
  76. if (HRESULT_CODE(hr) == ERROR_CANCELLED)
  77. {
  78. printRoleResult = PRINT_WIZARD_CANCELLED;
  79. }
  80. else
  81. {
  82. printRoleResult = PRINT_FAILURE;
  83. }
  84. }
  85. }
  86. }
  87. else
  88. {
  89. // This should never be reached so assert if we get here
  90. ASSERT(false);
  91. LOG(L"Add Printer Wizard failed");
  92. result = INSTALL_FAILURE;
  93. printRoleResult = PRINT_FAILURE;
  94. }
  95. if (forAllClients)
  96. {
  97. // Now execute the Add Printer Driver Wizard
  98. UpdateInstallationProgressText(hwnd, IDS_PRINT_PROGRESS_DRIVERS_WIZARD);
  99. if (ExecuteWizard(hwnd, CYS_PRINTER_DRIVER_WIZARD_NAME, resultText, hr))
  100. {
  101. // NTRAID#NTBUG9-462079-2001/09/04-sburns
  102. if (SUCCEEDED(hr))
  103. {
  104. ASSERT(resultText.empty());
  105. CYS_APPEND_LOG(String::load(IDS_PRINTER_DRIVER_WIZARD_SUCCEEDED));
  106. }
  107. else
  108. {
  109. // The call to ExecuteWizard should have provided us with the
  110. // error message.
  111. ASSERT(!resultText.empty());
  112. CYS_APPEND_LOG(resultText);
  113. }
  114. }
  115. else
  116. {
  117. // This should never be reached so assert if we get here
  118. ASSERT(false);
  119. LOG(L"Add Printer Driver Wizard failed");
  120. }
  121. }
  122. CYS_APPEND_LOG(L"\r\n");
  123. LOG_INSTALL_RETURN(result);
  124. return result;
  125. }
  126. HRESULT
  127. PrintInstallationUnit::RemovePrinters(
  128. PRINTER_INFO_5& printerInfo)
  129. {
  130. LOG_FUNCTION2(
  131. PrintInstallationUnit::RemovePrinters,
  132. printerInfo.pPrinterName);
  133. HRESULT hr = S_OK;
  134. do
  135. {
  136. HANDLE printerHandle = 0;
  137. // need to open the printer with admin access
  138. PRINTER_DEFAULTS defaults = { 0, 0, PRINTER_ALL_ACCESS };
  139. if (!OpenPrinter(
  140. printerInfo.pPrinterName,
  141. &printerHandle,
  142. &defaults))
  143. {
  144. hr = Win::GetLastErrorAsHresult();
  145. LOG(String::format(
  146. L"Failed to open printer: hr = 0x%1!x!",
  147. hr));
  148. break;
  149. }
  150. // Now that we were able to open the printer
  151. // delete it
  152. if (!DeletePrinter(printerHandle))
  153. {
  154. hr = Win::GetLastErrorAsHresult();
  155. LOG(String::format(
  156. L"SetPrinter failed: hr = 0x%1!x!",
  157. hr));
  158. break;
  159. }
  160. } while (false);
  161. LOG_HRESULT(hr);
  162. return hr;
  163. }
  164. UnInstallReturnType
  165. PrintInstallationUnit::UnInstallService(HANDLE logfileHandle, HWND hwnd)
  166. {
  167. LOG_FUNCTION(PrintInstallationUnit::UnInstallService);
  168. UnInstallReturnType result = UNINSTALL_SUCCESS;
  169. CYS_APPEND_LOG(String::load(IDS_LOG_PRINT_UNINSTALL_HEADER));
  170. UpdateInstallationProgressText(hwnd, IDS_UNINSTALL_PRINT_PROGRESS);
  171. // I am using level 5 here because it is the cheapest way to get
  172. // the printer attributes
  173. BYTE* printerInfo = 0;
  174. DWORD bytesNeeded = 0;
  175. DWORD numberOfPrinters = 0;
  176. DWORD error = 0;
  177. do
  178. {
  179. if (!EnumPrinters(
  180. PRINTER_ENUM_LOCAL | PRINTER_ENUM_SHARED,
  181. 0,
  182. 5,
  183. printerInfo,
  184. bytesNeeded,
  185. &bytesNeeded,
  186. &numberOfPrinters))
  187. {
  188. error = GetLastError();
  189. if (error == ERROR_INSUFFICIENT_BUFFER ||
  190. error == ERROR_INVALID_USER_BUFFER)
  191. {
  192. // The buffer isn't large enough so allocate
  193. // a new buffer and try again
  194. LOG(L"Reallocating buffer and trying again...");
  195. if (printerInfo)
  196. {
  197. delete[] printerInfo;
  198. printerInfo = 0;
  199. }
  200. printerInfo = new BYTE[bytesNeeded];
  201. if (!printerInfo)
  202. {
  203. LOG(L"Could not allocate printerInfo buffer!");
  204. break;
  205. }
  206. continue;
  207. }
  208. else
  209. {
  210. // Error occurred reading shared printers
  211. result = UNINSTALL_FAILURE;
  212. break;
  213. }
  214. }
  215. else
  216. {
  217. // Remove the sharing bit from all the shared printers
  218. LOG(String::format(
  219. L"Found %1!d! printers",
  220. numberOfPrinters));
  221. PRINTER_INFO_5* printerInfoArray =
  222. reinterpret_cast<PRINTER_INFO_5*>(printerInfo);
  223. for (DWORD index = 0; index < numberOfPrinters; ++index)
  224. {
  225. HRESULT hr =
  226. RemovePrinters(
  227. printerInfoArray[index]);
  228. if (FAILED(hr))
  229. {
  230. result = UNINSTALL_FAILURE;
  231. break;
  232. }
  233. }
  234. if (printerInfo)
  235. {
  236. delete[] printerInfo;
  237. printerInfo = 0;
  238. }
  239. break;
  240. }
  241. } while (true);
  242. if (result == UNINSTALL_SUCCESS)
  243. {
  244. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_PRINT_SUCCESS));
  245. }
  246. else
  247. {
  248. CYS_APPEND_LOG(String::load(IDS_LOG_UNINSTALL_PRINT_FAILURE));
  249. }
  250. CYS_APPEND_LOG(L"\r\n");
  251. LOG_UNINSTALL_RETURN(result);
  252. return result;
  253. }
  254. bool
  255. PrintInstallationUnit::GetMilestoneText(String& message)
  256. {
  257. LOG_FUNCTION(PrintInstallationUnit::GetMilestoneText);
  258. if (forAllClients)
  259. {
  260. message += String::load(IDS_PRINT_FINISH_ALL_CLIENTS);
  261. }
  262. else
  263. {
  264. message += String::load(IDS_PRINT_FINISH_W2K_CLIENTS);
  265. }
  266. LOG_BOOL(true);
  267. return true;
  268. }
  269. bool
  270. PrintInstallationUnit::GetUninstallMilestoneText(String& message)
  271. {
  272. LOG_FUNCTION(PrintInstallationUnit::GetUninstallMilestoneText);
  273. message = String::load(IDS_PRINT_UNINSTALL_TEXT);
  274. LOG_BOOL(true);
  275. return true;
  276. }
  277. void
  278. PrintInstallationUnit::SetClients(bool allclients)
  279. {
  280. LOG_FUNCTION2(
  281. PrintInstallationUnit::SetClients,
  282. allclients ? L"true" : L"false");
  283. forAllClients = allclients;
  284. }
  285. int
  286. PrintInstallationUnit::GetWizardStart()
  287. {
  288. LOG_FUNCTION(PrintInstallationUnit::GetWizardStart);
  289. int wizardStart = IDD_PRINT_SERVER_PAGE;
  290. bool installingRole = true;
  291. if (IsServiceInstalled())
  292. {
  293. installingRole = false;
  294. wizardStart = IDD_UNINSTALL_MILESTONE_PAGE;
  295. }
  296. SetInstalling(installingRole);
  297. LOG(String::format(
  298. L"wizardStart = %1!d!",
  299. wizardStart));
  300. return wizardStart;
  301. }
  302. String
  303. PrintInstallationUnit::GetServiceDescription()
  304. {
  305. LOG_FUNCTION(PrintInstallationUnit::GetServiceDescription);
  306. unsigned int description = descriptionID;
  307. if (IsServiceInstalled())
  308. {
  309. description = IDS_PRINT_SERVER_DESCRIPTION_INSTALLED;
  310. }
  311. return String::load(description);
  312. }
  313. void
  314. PrintInstallationUnit::ServerRoleLinkSelected(int linkIndex, HWND /*hwnd*/)
  315. {
  316. LOG_FUNCTION2(
  317. PrintInstallationUnit::ServerRoleLinkSelected,
  318. String::format(
  319. L"linkIndex = %1!d!",
  320. linkIndex));
  321. if (IsServiceInstalled())
  322. {
  323. ASSERT(linkIndex == 0);
  324. LaunchMYS();
  325. }
  326. else
  327. {
  328. ASSERT(linkIndex == 0);
  329. LOG(L"Showing configuration help");
  330. ShowHelp(CYS_PRINT_FINISH_PAGE_HELP);
  331. }
  332. }
  333. String
  334. PrintInstallationUnit::GetFinishText()
  335. {
  336. LOG_FUNCTION(PrintInstallationUnit::GetFinishText);
  337. unsigned int messageID = finishMessageID;
  338. if (installing)
  339. {
  340. if (printRoleResult == PRINT_SUCCESS)
  341. {
  342. messageID = finishMessageID;
  343. }
  344. else if (printRoleResult == PRINT_FAILURE)
  345. {
  346. messageID = IDS_PRINT_INSTALL_FAILED;
  347. }
  348. else
  349. {
  350. messageID = finishInstallFailedMessageID;
  351. }
  352. }
  353. else
  354. {
  355. messageID = finishUninstallMessageID;
  356. }
  357. return String::load(messageID);
  358. }
  359. void
  360. PrintInstallationUnit::FinishLinkSelected(int linkIndex, HWND hwnd)
  361. {
  362. LOG_FUNCTION2(
  363. PrintInstallationUnit::FinishLinkSelected,
  364. String::format(
  365. L"linkIndex = %1!d!",
  366. linkIndex));
  367. if (installing)
  368. {
  369. if (linkIndex == 0 &&
  370. printRoleResult == PRINT_SUCCESS)
  371. {
  372. LOG("Showing after checklist");
  373. ShowHelp(CYS_PRINT_AFTER_FINISH_HELP);
  374. }
  375. else if (linkIndex == 0)
  376. {
  377. LOG("Running Add Printer Wizard");
  378. String unusedResult;
  379. HRESULT unusedHr = S_OK;
  380. ExecuteWizard(hwnd, CYS_PRINTER_WIZARD_NAME, unusedResult, unusedHr);
  381. // NTRAID#NTBUG9-603366-2002/06/03-JeffJon-Close down CYS so
  382. // that the user doesn't think they still failed even after
  383. // running through the wizard again successfully from this
  384. // link
  385. Win::PropSheet_PressButton(
  386. Win::GetParent(hwnd),
  387. PSBTN_FINISH);
  388. }
  389. else if (linkIndex == 1)
  390. {
  391. LOG(L"Opening Printers and Faxes");
  392. String fullPath =
  393. FS::AppendPath(
  394. Win::GetSystemDirectory(),
  395. L"control.exe");
  396. String commandline = L"printers";
  397. MyCreateProcess(fullPath, commandline);
  398. // NTRAID#NTBUG9-603366-2002/06/03-JeffJon-Close down CYS so
  399. // that the user doesn't think they still failed even after
  400. // running through the wizard again successfully from this
  401. // link
  402. Win::PropSheet_PressButton(
  403. Win::GetParent(hwnd),
  404. PSBTN_FINISH);
  405. }
  406. }
  407. else
  408. {
  409. if (IsServiceInstalled())
  410. {
  411. // There was a failure
  412. // REVIEW_JEFFJON: From spec: ???
  413. }
  414. }
  415. }
  416. bool
  417. PrintInstallationUnit::DoInstallerCheck(HWND /*hwnd*/) const
  418. {
  419. LOG_FUNCTION(PrintInstallationUnit::DoInstallerCheck);
  420. // The printer wizards allow for more than one instance
  421. // to run at the same time
  422. bool result = false;
  423. LOG_BOOL(result);
  424. return result;
  425. }