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.

780 lines
16 KiB

  1. // Copyright (c) 2002 Microsoft Corporation
  2. //
  3. // File: RoleStatus.h
  4. //
  5. // Synopsis: Defines the functions that are declared
  6. // in CYS.h that are used to determine the
  7. // status of the CYS server roles
  8. //
  9. // History: 01/21/2002 JeffJon Created
  10. #include "pch.h"
  11. #include "CYS.h"
  12. #include "state.h"
  13. #include "regkeys.h"
  14. // table of items that are available in the server type list box
  15. // The order in this table is important because it is the order
  16. // in which the roles will show up in CYS. Please do not change
  17. // the order unless there is a good reason to do so.
  18. extern ServerRoleStatus serverRoleStatusTable[] =
  19. {
  20. { FILESERVER_SERVER, GetFileServerStatus },
  21. { PRINTSERVER_SERVER, GetPrintServerStatus },
  22. { WEBAPP_SERVER, GetWebServerStatus },
  23. { POP3_SERVER, GetPOP3Status },
  24. { TERMINALSERVER_SERVER, GetTerminalServerStatus },
  25. { RRAS_SERVER, GetRRASStatus },
  26. { DC_SERVER, GetDCStatus },
  27. { DNS_SERVER, GetDNSStatus },
  28. { DHCP_SERVER, GetDHCPStats },
  29. { MEDIASERVER_SERVER, GetMediaServerStatus },
  30. { WINS_SERVER, GetWINSStatus },
  31. };
  32. size_t
  33. GetServerRoleStatusTableElementCount()
  34. {
  35. return sizeof(serverRoleStatusTable)/sizeof(ServerRoleStatus);
  36. }
  37. // Helper to get the status if all you have is the installation type
  38. InstallationStatus
  39. GetInstallationStatusForServerRole(
  40. ServerRole role)
  41. {
  42. LOG_FUNCTION(GetInstallationStatusForServerRole);
  43. InstallationStatus result = STATUS_NONE;
  44. for (
  45. size_t index = 0;
  46. index < GetServerRoleStatusTableElementCount();
  47. ++index)
  48. {
  49. if (serverRoleStatusTable[index].role == role)
  50. {
  51. result = serverRoleStatusTable[index].Status();
  52. break;
  53. }
  54. }
  55. LOG_ROLE_STATUS(result);
  56. return result;
  57. }
  58. // Helper function to verify role against SKU and platform
  59. bool
  60. IsAllowedSKUAndPlatform(DWORD flags)
  61. {
  62. LOG_FUNCTION(IsAllowedSKUAndPlatform);
  63. bool result = false;
  64. LOG(String::format(
  65. L"Current role SKUs: 0x%1!x!",
  66. flags));
  67. DWORD sku = State::GetInstance().GetProductSKU();
  68. LOG(String::format(
  69. L"Verifying against computer sku: 0x%1!x!",
  70. sku));
  71. if (sku & flags)
  72. {
  73. DWORD platform = State::GetInstance().GetPlatform();
  74. LOG(String::format(
  75. L"Verifying against computer platform: 0x%1!x!",
  76. platform));
  77. if (platform & flags)
  78. {
  79. result = true;
  80. }
  81. }
  82. LOG_BOOL(result);
  83. return result;
  84. }
  85. // Functions to determine the server role status
  86. InstallationStatus
  87. GetDNSStatus()
  88. {
  89. LOG_FUNCTION(GetDNSStatus);
  90. InstallationStatus result = STATUS_NONE;
  91. do
  92. {
  93. if (!IsAllowedSKUAndPlatform(CYS_ALL_SERVER_SKUS))
  94. {
  95. result = STATUS_NOT_AVAILABLE;
  96. break;
  97. }
  98. if (IsServiceInstalledHelper(CYS_DNS_SERVICE_NAME))
  99. {
  100. result = STATUS_COMPLETED;
  101. }
  102. } while (false);
  103. LOG_ROLE_STATUS(result);
  104. return result;
  105. }
  106. InstallationStatus
  107. GetDHCPStats()
  108. {
  109. LOG_FUNCTION(GetDHCPStats);
  110. InstallationStatus result = STATUS_NONE;
  111. do
  112. {
  113. if (!IsAllowedSKUAndPlatform(CYS_ALL_SERVER_SKUS))
  114. {
  115. result = STATUS_NOT_AVAILABLE;
  116. break;
  117. }
  118. if (IsServiceInstalledHelper(CYS_DHCP_SERVICE_NAME))
  119. {
  120. result = STATUS_COMPLETED;
  121. }
  122. else if (IsDhcpConfigured())
  123. {
  124. result = STATUS_CONFIGURED;
  125. }
  126. } while (false);
  127. LOG_ROLE_STATUS(result);
  128. return result;
  129. }
  130. InstallationStatus
  131. GetWINSStatus()
  132. {
  133. LOG_FUNCTION(GetWINSStatus);
  134. InstallationStatus result = STATUS_NONE;
  135. do
  136. {
  137. if (!IsAllowedSKUAndPlatform(CYS_ALL_SERVER_SKUS))
  138. {
  139. result = STATUS_NOT_AVAILABLE;
  140. break;
  141. }
  142. if (IsServiceInstalledHelper(CYS_WINS_SERVICE_NAME))
  143. {
  144. result = STATUS_COMPLETED;
  145. }
  146. } while (false);
  147. LOG_ROLE_STATUS(result);
  148. return result;
  149. }
  150. InstallationStatus
  151. GetRRASStatus()
  152. {
  153. LOG_FUNCTION(GetRRASStatus);
  154. InstallationStatus result = STATUS_NONE;
  155. do
  156. {
  157. if (!IsAllowedSKUAndPlatform(CYS_ALL_SERVER_SKUS))
  158. {
  159. result = STATUS_NOT_AVAILABLE;
  160. break;
  161. }
  162. DWORD resultValue = 0;
  163. bool regResult = GetRegKeyValue(
  164. CYS_RRAS_CONFIGURED_REGKEY,
  165. CYS_RRAS_CONFIGURED_VALUE,
  166. resultValue);
  167. if (regResult &&
  168. resultValue != 0)
  169. {
  170. result = STATUS_COMPLETED;
  171. }
  172. } while (false);
  173. LOG_ROLE_STATUS(result);
  174. return result;
  175. }
  176. InstallationStatus
  177. GetTerminalServerStatus()
  178. {
  179. LOG_FUNCTION(GetTerminalServerStatus);
  180. InstallationStatus result = STATUS_NONE;
  181. do
  182. {
  183. if (!IsAllowedSKUAndPlatform(CYS_ALL_SERVER_SKUS))
  184. {
  185. result = STATUS_NOT_AVAILABLE;
  186. break;
  187. }
  188. DWORD regValue = 0;
  189. bool keyResult = GetRegKeyValue(
  190. CYS_APPLICATION_MODE_REGKEY,
  191. CYS_APPLICATION_MODE_VALUE,
  192. regValue);
  193. ASSERT(keyResult);
  194. if (keyResult &&
  195. regValue == CYS_APPLICATION_MODE_ON)
  196. {
  197. result = STATUS_COMPLETED;
  198. }
  199. } while (false);
  200. LOG_ROLE_STATUS(result);
  201. return result;
  202. }
  203. InstallationStatus
  204. GetFileServerStatus()
  205. {
  206. LOG_FUNCTION(GetFileServerStatus);
  207. InstallationStatus result = STATUS_NONE;
  208. do
  209. {
  210. if (!IsAllowedSKUAndPlatform(CYS_ALL_SERVER_SKUS))
  211. {
  212. result = STATUS_NOT_AVAILABLE;
  213. break;
  214. }
  215. if (IsNonSpecialSharePresent())
  216. {
  217. result = STATUS_CONFIGURED;
  218. }
  219. } while (false);
  220. LOG_ROLE_STATUS(result);
  221. return result;
  222. }
  223. InstallationStatus
  224. GetPrintServerStatus()
  225. {
  226. LOG_FUNCTION(GetPrintServerStatus);
  227. InstallationStatus result = STATUS_NONE;
  228. do
  229. {
  230. if (!IsAllowedSKUAndPlatform(CYS_ALL_SERVER_SKUS))
  231. {
  232. result = STATUS_NOT_AVAILABLE;
  233. break;
  234. }
  235. // I am using level 4 here because the MSDN documentation
  236. // says that this will be the fastest.
  237. BYTE* printerInfo = 0;
  238. DWORD bytesNeeded = 0;
  239. DWORD numberOfPrinters = 0;
  240. DWORD error = 0;
  241. do
  242. {
  243. if (!EnumPrinters(
  244. PRINTER_ENUM_LOCAL | PRINTER_ENUM_SHARED,
  245. 0,
  246. 4,
  247. printerInfo,
  248. bytesNeeded,
  249. &bytesNeeded,
  250. &numberOfPrinters))
  251. {
  252. error = GetLastError();
  253. if (error != ERROR_INSUFFICIENT_BUFFER &&
  254. error != ERROR_INVALID_USER_BUFFER)
  255. {
  256. LOG(String::format(
  257. L"EnumPrinters() failed: error = %1!x!",
  258. error));
  259. break;
  260. }
  261. // The buffer isn't large enough so allocate
  262. // a new buffer and try again
  263. LOG(L"Reallocating buffer and trying again...");
  264. if (printerInfo)
  265. {
  266. delete[] printerInfo;
  267. printerInfo = 0;
  268. }
  269. printerInfo = new BYTE[bytesNeeded];
  270. if (!printerInfo)
  271. {
  272. LOG(L"Could not allocate printerInfo buffer!");
  273. break;
  274. }
  275. }
  276. else
  277. {
  278. break;
  279. }
  280. } while (true);
  281. LOG(String::format(
  282. L"numberOfPrinters = %1!d!",
  283. numberOfPrinters));
  284. if (numberOfPrinters > 0)
  285. {
  286. result = STATUS_COMPLETED;
  287. }
  288. delete[] printerInfo;
  289. } while (false);
  290. LOG_ROLE_STATUS(result);
  291. return result;
  292. }
  293. InstallationStatus
  294. GetMediaServerStatus()
  295. {
  296. LOG_FUNCTION(GetMediaServerStatus);
  297. InstallationStatus result = STATUS_NONE;
  298. do
  299. {
  300. // All 32bit SKUs
  301. if (!IsAllowedSKUAndPlatform(CYS_ALL_SKUS_NO_64BIT))
  302. {
  303. result = STATUS_NOT_AVAILABLE;
  304. break;
  305. }
  306. // If we can find wmsserver.dll, we assume netshow is installed
  307. String installDir;
  308. if (!GetRegKeyValue(
  309. REGKEY_WINDOWS_MEDIA,
  310. REGKEY_WINDOWS_MEDIA_SERVERDIR,
  311. installDir,
  312. HKEY_LOCAL_MACHINE))
  313. {
  314. LOG(L"Failed to read the installDir regkey");
  315. result = STATUS_NONE;
  316. break;
  317. }
  318. String wmsServerPath = installDir + L"WMServer.exe";
  319. LOG(String::format(
  320. L"Path to WMS server: %1",
  321. wmsServerPath.c_str()));
  322. if (!wmsServerPath.empty())
  323. {
  324. if (FS::FileExists(wmsServerPath))
  325. {
  326. result = STATUS_COMPLETED;
  327. }
  328. else
  329. {
  330. LOG(L"Path does not exist");
  331. }
  332. }
  333. else
  334. {
  335. LOG(L"Failed to append path");
  336. }
  337. } while (false);
  338. LOG_ROLE_STATUS(result);
  339. return result;
  340. }
  341. InstallationStatus
  342. GetWebServerStatus()
  343. {
  344. LOG_FUNCTION(GetWebServerStatus);
  345. InstallationStatus result = STATUS_NONE;
  346. do
  347. {
  348. if (!IsAllowedSKUAndPlatform(CYS_ALL_SERVER_SKUS))
  349. {
  350. result = STATUS_NOT_AVAILABLE;
  351. break;
  352. }
  353. if (IsServiceInstalledHelper(CYS_WEB_SERVICE_NAME))
  354. {
  355. result = STATUS_COMPLETED;
  356. }
  357. } while (false);
  358. LOG_ROLE_STATUS(result);
  359. return result;
  360. }
  361. InstallationStatus
  362. GetDCStatus()
  363. {
  364. LOG_FUNCTION(GetDCStatus);
  365. InstallationStatus result = STATUS_NONE;
  366. do
  367. {
  368. if (!IsAllowedSKUAndPlatform(CYS_ALL_SERVER_SKUS))
  369. {
  370. result = STATUS_NOT_AVAILABLE;
  371. break;
  372. }
  373. // Special case AD installation so that it is not available if
  374. // CertServer is installed
  375. if (NTService(L"CertSvc").IsInstalled())
  376. {
  377. result = STATUS_NOT_AVAILABLE;
  378. break;
  379. }
  380. if (State::GetInstance().IsDC())
  381. {
  382. result = STATUS_COMPLETED;
  383. }
  384. } while (false);
  385. LOG_ROLE_STATUS(result);
  386. return result;
  387. }
  388. // NTRAID#NTBUG9-698722-2002/09/03-artm
  389. // Only need to check if machine is currently a DC, not if
  390. // running dcpromo would be allowed.
  391. InstallationStatus
  392. GetDCStatusForMYS()
  393. {
  394. LOG_FUNCTION(GetDCStatusForMYS);
  395. InstallationStatus result = STATUS_NONE;
  396. if (State::GetInstance().IsDC())
  397. {
  398. result = STATUS_COMPLETED;
  399. }
  400. LOG_ROLE_STATUS(result);
  401. return result;
  402. }
  403. InstallationStatus
  404. GetPOP3Status()
  405. {
  406. LOG_FUNCTION(GetPOP3Status);
  407. InstallationStatus result = STATUS_NONE;
  408. do
  409. {
  410. if (!IsAllowedSKUAndPlatform(CYS_ALL_SERVER_SKUS))
  411. {
  412. result = STATUS_NOT_AVAILABLE;
  413. break;
  414. }
  415. // If we can read this regkey then POP3 is installed
  416. String pop3Version;
  417. bool regResult = GetRegKeyValue(
  418. CYS_POP3_REGKEY,
  419. CYS_POP3_VERSION,
  420. pop3Version,
  421. HKEY_LOCAL_MACHINE);
  422. if (regResult)
  423. {
  424. result = STATUS_COMPLETED;
  425. }
  426. } while (false);
  427. LOG_ROLE_STATUS(result);
  428. return result;
  429. }
  430. // Define the GUIDs used by the Server Appliance Kit COM object
  431. #include <initguid.h>
  432. DEFINE_GUID(CLSID_SaInstall,0x142B8185,0x53AE,0x45B3,0x88,0x8F,0xC9,0x83,0x5B,0x15,0x6C,0xA9);
  433. DEFINE_GUID(IID_ISaInstall,0xF4DEDEF3,0x4D83,0x4516,0xBC,0x1E,0x10,0x3A,0x63,0xF5,0xF0,0x14);
  434. bool
  435. IsSAKUnitInstalled(SA_TYPE unitType)
  436. {
  437. LOG_FUNCTION2(
  438. IsSAKUnitInstalled,
  439. String::format(L"type = %1!d!", (int) unitType));
  440. bool result = true;
  441. do
  442. {
  443. // Check to make sure we are not on 64bit
  444. if (State::GetInstance().Is64Bit())
  445. {
  446. result = false;
  447. break;
  448. }
  449. // Get the Server Appliance Kit COM object
  450. SmartInterface<ISaInstall> sakInstall;
  451. HRESULT hr = sakInstall.AcquireViaCreateInstance(
  452. CLSID_SaInstall,
  453. 0,
  454. CLSCTX_INPROC_SERVER);
  455. if (FAILED(hr))
  456. {
  457. LOG(String::format(
  458. L"Failed to get the SAK COM object: hr = 0x%1!x!",
  459. hr));
  460. break;
  461. }
  462. // Check to see if NAS is already installed
  463. VARIANT_BOOL saInstalled;
  464. hr = sakInstall->SAAlreadyInstalled(unitType, &saInstalled);
  465. if (FAILED(hr))
  466. {
  467. LOG(String::format(
  468. L"Failed call to SAAlreadyInstalled: hr = 0x%1!x!",
  469. hr));
  470. break;
  471. }
  472. if (!saInstalled)
  473. {
  474. result = false;
  475. }
  476. } while (false);
  477. LOG_BOOL(result);
  478. return result;
  479. }
  480. bool
  481. IsClusterServer()
  482. {
  483. LOG_FUNCTION(IsClusterServer());
  484. bool result = false;
  485. DWORD clusterState = 0;
  486. DWORD err = ::GetNodeClusterState(0, &clusterState);
  487. if (err == ERROR_SUCCESS &&
  488. clusterState != ClusterStateNotConfigured)
  489. {
  490. result = true;
  491. }
  492. else
  493. {
  494. LOG(String::format(
  495. L"GetNodeClusterState returned err = %1!x!",
  496. err));
  497. }
  498. LOG_BOOL(result);
  499. return result;
  500. }
  501. String
  502. GetSAKURL()
  503. {
  504. LOG_FUNCTION(GetSAKURL);
  505. String result =
  506. String::format(
  507. L"https://%1:8098",
  508. State::GetInstance().GetComputerName().c_str());
  509. LOG(result);
  510. return result;
  511. }
  512. bool
  513. IsSupportedSku()
  514. {
  515. LOG_FUNCTION(IsSupportedSku);
  516. bool result = true;
  517. DWORD productSKU = State::GetInstance().RetrieveProductSKU();
  518. if (CYS_UNSUPPORTED_SKU == productSKU)
  519. {
  520. result = false;
  521. }
  522. LOG_BOOL(result);
  523. return result;
  524. }
  525. bool
  526. IsStartupFlagSet()
  527. {
  528. LOG_FUNCTION(IsStartupFlagSet);
  529. bool result = false;
  530. do
  531. {
  532. // This code copied from shell\explorer\initcab.cpp
  533. DWORD data = 0;
  534. // If the user's preference is present and zero, then don't show
  535. // the wizard, else continue with other tests
  536. bool regResult =
  537. GetRegKeyValue(
  538. REGTIPS,
  539. REGTIPS_SHOW_VALUE,
  540. data,
  541. HKEY_CURRENT_USER);
  542. if (regResult && !data)
  543. {
  544. break;
  545. }
  546. // This is to check an old W2K regkey that was documented in Q220838.
  547. // If the key exists and is zero then don't run the wizard
  548. data = 0;
  549. regResult =
  550. GetRegKeyValue(
  551. SZ_REGKEY_W2K,
  552. SZ_REGVAL_W2K,
  553. data,
  554. HKEY_CURRENT_USER);
  555. if (regResult && !data)
  556. {
  557. break;
  558. }
  559. // If the user's preference is absent or non-zero, then we need to
  560. // start the wizard.
  561. data = 0;
  562. regResult =
  563. GetRegKeyValue(
  564. SZ_REGKEY_SRVWIZ_ROOT,
  565. L"",
  566. data,
  567. HKEY_CURRENT_USER);
  568. if (!regResult ||
  569. data)
  570. {
  571. result = true;
  572. break;
  573. }
  574. } while (false);
  575. LOG_BOOL(result);
  576. return result;
  577. }
  578. bool
  579. ShouldShowMYSAccordingToPolicy()
  580. {
  581. LOG_FUNCTION(ShouldShowMYSAccordingToPolicy);
  582. bool result = true;
  583. do
  584. {
  585. // If group policy is set for "Don't show MYS",
  586. // then don't show MYS regardless of user setting
  587. DWORD data = 0;
  588. bool regResult =
  589. GetRegKeyValue(
  590. MYS_REGKEY_POLICY,
  591. MYS_REGKEY_POLICY_DISABLE_SHOW,
  592. data);
  593. if (regResult && data)
  594. {
  595. result = false;
  596. }
  597. } while (false);
  598. LOG_BOOL(result);
  599. return result;
  600. }