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.

490 lines
9.2 KiB

  1. // Copyright (c) 1997-2001 Microsoft Corporation
  2. //
  3. // File: state.cpp
  4. //
  5. // Synopsis: Defines the state object that is global
  6. // to CYS. It holds the network and OS/SKU info
  7. //
  8. // History: 02/02/2001 JeffJon Created
  9. #include "pch.h"
  10. #include "state.h"
  11. static State* stateInstance = 0;
  12. State::State() :
  13. dhcpServerAvailable(false),
  14. dhcpAvailabilityRetrieved(false),
  15. hasStateBeenRetrieved(false),
  16. rerunWizard(true),
  17. productSKU(CYS_SERVER),
  18. hasNTFSDrive(false),
  19. computerName()
  20. {
  21. LOG_CTOR(State);
  22. }
  23. void
  24. State::Destroy()
  25. {
  26. LOG_FUNCTION(State::Destroy);
  27. if (stateInstance)
  28. {
  29. delete stateInstance;
  30. stateInstance = 0;
  31. }
  32. }
  33. State&
  34. State::GetInstance()
  35. {
  36. if (!stateInstance)
  37. {
  38. stateInstance = new State();
  39. }
  40. ASSERT(stateInstance);
  41. return *stateInstance;
  42. }
  43. bool
  44. State::IsDC() const
  45. {
  46. LOG_FUNCTION(State::IsDC);
  47. bool result = false;
  48. do
  49. {
  50. DSROLE_PRIMARY_DOMAIN_INFO_BASIC* info = 0;
  51. HRESULT hr = MyDsRoleGetPrimaryDomainInformation(0, info);
  52. if(FAILED(hr))
  53. {
  54. LOG(String::format(
  55. L"Failed MyDsRoleGetPrimaryDomainInformation(0): hr = 0x%1!x!",
  56. hr));
  57. break;
  58. }
  59. if (info &&
  60. (info->MachineRole == DsRole_RolePrimaryDomainController ||
  61. info->MachineRole == DsRole_RoleBackupDomainController) )
  62. {
  63. result = true;
  64. }
  65. ::DsRoleFreeMemory(info);
  66. } while (false);
  67. LOG_BOOL(result);
  68. return result;
  69. }
  70. bool
  71. State::IsDCPromoRunning() const
  72. {
  73. LOG_FUNCTION(State::IsDCPromoRunning);
  74. // Uses the IsDcpromoRunning from Burnslib
  75. bool result = IsDcpromoRunning();
  76. LOG_BOOL(result);
  77. return result;
  78. }
  79. bool
  80. State::IsDCPromoPendingReboot() const
  81. {
  82. LOG_FUNCTION(State::IsDCPromoPendingReboot);
  83. bool result = false;
  84. do
  85. {
  86. // Uses the IsDcpromoRunning from Burnslib
  87. if (!IsDcpromoRunning())
  88. {
  89. // this test is redundant if dcpromo is running, so only
  90. // perform it when dcpromo is not running.
  91. DSROLE_OPERATION_STATE_INFO* info = 0;
  92. HRESULT hr = MyDsRoleGetPrimaryDomainInformation(0, info);
  93. if (SUCCEEDED(hr) && info)
  94. {
  95. if (info->OperationState == DsRoleOperationNeedReboot)
  96. {
  97. result = true;
  98. }
  99. ::DsRoleFreeMemory(info);
  100. }
  101. }
  102. } while (false);
  103. LOG_BOOL(result);
  104. return result;
  105. }
  106. bool
  107. State::IsUpgradeState() const
  108. {
  109. LOG_FUNCTION(State::IsUpgradeState);
  110. bool result = false;
  111. do
  112. {
  113. DSROLE_UPGRADE_STATUS_INFO* info = 0;
  114. HRESULT hr = MyDsRoleGetPrimaryDomainInformation(0, info);
  115. if (FAILED(hr))
  116. {
  117. LOG(String::format(
  118. L"MyDsRoleGetPrimaryDomainInformation(0): hr = 0x%1!x!",
  119. hr));
  120. break;
  121. }
  122. if (info && info->OperationState == DSROLE_UPGRADE_IN_PROGRESS)
  123. {
  124. result = true;
  125. }
  126. ::DsRoleFreeMemory(info);
  127. } while (false);
  128. LOG_BOOL(result);
  129. return result;
  130. }
  131. bool
  132. State::IsFirstDC() const
  133. {
  134. LOG_FUNCTION(State::IsFirstDC);
  135. DWORD value = 0;
  136. bool result = GetRegKeyValue(CYS_FIRST_DC_REGKEY, CYS_FIRST_DC_VALUE, value);
  137. if (value != 1)
  138. {
  139. result = false;
  140. }
  141. LOG_BOOL(result);
  142. return result;
  143. }
  144. int
  145. State::GetNICCount() const
  146. {
  147. return adapterConfiguration.GetNICCount();
  148. }
  149. NetworkInterface
  150. State::GetNIC(unsigned int nicIndex)
  151. {
  152. LOG_FUNCTION2(
  153. State::GetNIC,
  154. String::format(
  155. L"%1!d!",
  156. nicIndex));
  157. return adapterConfiguration.GetNIC(nicIndex);
  158. }
  159. bool
  160. State::RetrieveMachineConfigurationInformation(HWND /*hwndParent*/)
  161. {
  162. LOG_FUNCTION(State::RetrieveMachineConfigurationInformation);
  163. ASSERT(!hasStateBeenRetrieved);
  164. // For now I will make this a synchronous action.
  165. // We should have some sort of fancy UI that lets
  166. // the user know we are progressing
  167. Win::WaitCursor cursor;
  168. // This is used to get the minimal information needed to
  169. // determine if we should enable the express path
  170. // This should probably just be changed to gather the
  171. // information and let the page decide what to do
  172. HRESULT hr = RetrieveNICInformation();
  173. if (SUCCEEDED(hr))
  174. {
  175. // Only bother to check for a DHCP server on the network if we are not
  176. // a DC and only have one NIC. Right now we only use this info
  177. // for determining whether or not to show the Express path option
  178. if (!(IsDC() || IsUpgradeState()) &&
  179. (GetNICCount() == 1))
  180. {
  181. CheckDhcpServer();
  182. }
  183. }
  184. RetrieveProductSKU();
  185. RetrievePlatform();
  186. // Retrieve the drive information (quotas enabled, partition types, etc.)
  187. RetrieveDriveInformation();
  188. hasStateBeenRetrieved = true;
  189. return true;
  190. }
  191. void
  192. State::RetrieveProductSKU()
  193. {
  194. LOG_FUNCTION(State::RetrieveProductSKU);
  195. // I am making the assumption that we are on a
  196. // Server SKU if GetVersionEx fails
  197. productSKU = CYS_SERVER;
  198. OSVERSIONINFOEX info;
  199. HRESULT hr = Win::GetVersionEx(info);
  200. if (SUCCEEDED(hr))
  201. {
  202. do
  203. {
  204. if (info.wSuiteMask & VER_SUITE_DATACENTER)
  205. {
  206. // datacenter
  207. productSKU = CYS_DATACENTER_SERVER;
  208. break;
  209. }
  210. if (info.wSuiteMask & VER_SUITE_ENTERPRISE)
  211. {
  212. // advanced server
  213. productSKU = CYS_ADVANCED_SERVER;
  214. break;
  215. }
  216. if (info.wSuiteMask & VER_SUITE_PERSONAL)
  217. {
  218. // personal
  219. productSKU = CYS_PERSONAL;
  220. break;
  221. }
  222. if (info.wProductType == VER_NT_WORKSTATION)
  223. {
  224. // profesional
  225. productSKU = CYS_PROFESSIONAL;
  226. }
  227. else
  228. {
  229. // server
  230. productSKU = CYS_SERVER;
  231. }
  232. } while (false);
  233. }
  234. LOG(String::format(L"Product SKU = 0x%1!x!", productSKU ));
  235. return;
  236. }
  237. void
  238. State::RetrievePlatform()
  239. {
  240. LOG_FUNCTION(State::RetrievePlatform);
  241. // I am making the assumption that we are not on a
  242. // 64bit machine if GetSystemInfo fails
  243. SYSTEM_INFO info;
  244. Win::GetSystemInfo(info);
  245. switch (info.wProcessorArchitecture)
  246. {
  247. case PROCESSOR_ARCHITECTURE_IA64:
  248. case PROCESSOR_ARCHITECTURE_ALPHA64:
  249. case PROCESSOR_ARCHITECTURE_AMD64:
  250. platform = CYS_64BIT;
  251. break;
  252. default:
  253. platform = CYS_32BIT;
  254. break;
  255. }
  256. LOG(String::format(L"Platform = 0x%1!x!", platform));
  257. return;
  258. }
  259. HRESULT
  260. State::RetrieveNICInformation()
  261. {
  262. ASSERT(!hasStateBeenRetrieved);
  263. HRESULT hr = S_OK;
  264. if (!adapterConfiguration.IsInitialized())
  265. {
  266. hr = adapterConfiguration.Initialize();
  267. }
  268. LOG_HRESULT(hr);
  269. return hr;
  270. }
  271. void
  272. State::CheckDhcpServer()
  273. {
  274. LOG_FUNCTION(State::CheckDhcpServer);
  275. // This should loop through all network interfaces
  276. // seeing if we can obtain a lease on any of them
  277. if (GetNICCount() > 0)
  278. {
  279. DWORD nicIPAddress = GetNIC(0).GetIPAddress(0);
  280. // force to bool
  281. dhcpServerAvailable = (IsDHCPAvailableOnInterface(nicIPAddress) != 0);
  282. }
  283. dhcpAvailabilityRetrieved = true;
  284. LOG_BOOL(dhcpServerAvailable);
  285. }
  286. bool
  287. State::HasNTFSDrive() const
  288. {
  289. LOG_FUNCTION(State::HasNTFSDrive);
  290. return hasNTFSDrive;
  291. }
  292. void
  293. State::RetrieveDriveInformation()
  294. {
  295. LOG_FUNCTION(State::RetrieveDriveInformation);
  296. do
  297. {
  298. // Get a list of the valid drives
  299. StringVector dl;
  300. HRESULT hr = FS::GetValidDrives(std::back_inserter(dl));
  301. if (FAILED(hr))
  302. {
  303. LOG(String::format(L"Failed to GetValidDrives: hr = %1!x!", hr));
  304. break;
  305. }
  306. // Loop through the list
  307. ASSERT(dl.size());
  308. for (
  309. StringVector::iterator i = dl.begin();
  310. i != dl.end();
  311. ++i)
  312. {
  313. // look for the NTFS partition
  314. FS::FSType fsType = FS::GetFileSystemType(*i);
  315. if (fsType == FS::NTFS5 ||
  316. fsType == FS::NTFS4)
  317. {
  318. // found one. good to go
  319. LOG(String::format(L"%1 is NTFS", i->c_str()));
  320. hasNTFSDrive = true;
  321. break;
  322. }
  323. }
  324. } while (false);
  325. LOG_BOOL(hasNTFSDrive);
  326. return;
  327. }
  328. void
  329. State::SetRerunWizard(bool rerun)
  330. {
  331. LOG_FUNCTION2(
  332. State::SetRerunWizard,
  333. rerun ? L"true" : L"false");
  334. rerunWizard = rerun;
  335. }
  336. bool
  337. State::SetHomeRegkey(const String& newKeyValue)
  338. {
  339. LOG_FUNCTION2(
  340. State::SetHomeRegkey,
  341. newKeyValue);
  342. bool result = SetRegKeyValue(
  343. CYS_HOME_REGKEY,
  344. CYS_HOME_VALUE,
  345. newKeyValue,
  346. HKEY_LOCAL_MACHINE,
  347. true);
  348. ASSERT(result);
  349. LOG_BOOL(result);
  350. return result;
  351. }
  352. bool
  353. State::GetHomeRegkey(String& keyValue) const
  354. {
  355. LOG_FUNCTION(State::GetHomeRegkey);
  356. bool result = GetRegKeyValue(
  357. CYS_HOME_REGKEY,
  358. CYS_HOME_VALUE,
  359. keyValue);
  360. LOG_BOOL(result);
  361. return result;
  362. }
  363. String
  364. State::GetComputerName()
  365. {
  366. LOG_FUNCTION(State::GetComputerName);
  367. if (computerName.empty())
  368. {
  369. computerName = Win::GetComputerNameEx(ComputerNameDnsHostname);
  370. }
  371. LOG(computerName);
  372. return computerName;
  373. }