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.

467 lines
9.2 KiB

  1. /*++
  2. Copyright (c) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. oscheck.c
  5. Abstract:
  6. Checks all the nooks and crannies of the OS to make sure
  7. it is ok to run a cluster on it.
  8. Author:
  9. John Vert (jvert) 11/11/1996
  10. Revision History:
  11. --*/
  12. #include <clusrtlp.h>
  13. #include <winbase.h>
  14. static
  15. DWORD
  16. GetEnableClusterRegValue(
  17. DWORD * pdwValue
  18. )
  19. /*++
  20. Routine Description:
  21. Read the registry override registry value for enabling clusters.
  22. Arguments:
  23. pdwValue - Return value read from the registry.
  24. Return Value:
  25. ERROR_SUCCESS if the operation was successful.
  26. Win32 error code on failure.
  27. --*/
  28. {
  29. DWORD sc;
  30. HKEY hkey = NULL;
  31. DWORD dwType;
  32. DWORD cbValue = sizeof( DWORD );
  33. if ( !ARGUMENT_PRESENT( pdwValue ) ) {
  34. return ERROR_INVALID_PARAMETER;
  35. }
  36. //
  37. // Default to the value 0 - not Enabled!
  38. //
  39. *pdwValue = 0;
  40. //
  41. // Open the registry key containing the value.
  42. //
  43. sc = RegOpenKeyEx(
  44. HKEY_LOCAL_MACHINE,
  45. TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Cluster Server"),
  46. 0,
  47. KEY_READ,
  48. &hkey );
  49. if ( sc != ERROR_SUCCESS ) {
  50. goto Cleanup;
  51. }
  52. //
  53. // Read the override value.
  54. //
  55. sc = RegQueryValueEx(
  56. hkey,
  57. TEXT("EnableCluster"),
  58. 0,
  59. &dwType,
  60. (LPBYTE) pdwValue,
  61. &cbValue );
  62. if ( sc != ERROR_SUCCESS ) {
  63. goto Cleanup;
  64. }
  65. Cleanup:
  66. if ( hkey != NULL ) {
  67. RegCloseKey( hkey );
  68. }
  69. return( sc );
  70. } // GetEnableClusterRegValue
  71. DWORD
  72. GetServicePack(
  73. VOID
  74. )
  75. /*++
  76. Routine Description:
  77. Figures out what service pack is installed
  78. Arguments:
  79. None
  80. Return Value:
  81. The service pack number.
  82. --*/
  83. {
  84. OSVERSIONINFOW Version;
  85. LPWSTR p;
  86. DWORD sp;
  87. //
  88. // Check for required operating system version.
  89. //
  90. Version.dwOSVersionInfoSize = sizeof(Version);
  91. GetVersionExW(&Version);
  92. if (lstrlenW(Version.szCSDVersion) < lstrlenW(L"Service Pack ")) {
  93. return(0);
  94. }
  95. p = &Version.szCSDVersion[0] + lstrlenW(L"Service Pack ");
  96. sp = wcstoul(p, NULL, 10);
  97. return(sp);
  98. } // GetServicePack
  99. BOOL
  100. ClRtlIsOSValid(
  101. VOID
  102. )
  103. /*++
  104. Routine Description:
  105. Checks all the nooks and crannies of the OS to see if it is OK to have
  106. a cluster there.
  107. Arguments:
  108. None.
  109. Return Value:
  110. TRUE if it's ok.
  111. FALSE if it's not ok.
  112. --*/
  113. {
  114. BOOL fIsValid = FALSE;
  115. OSVERSIONINFOEX osiv;
  116. DWORDLONG dwlConditionMask;
  117. ZeroMemory( &osiv, sizeof( OSVERSIONINFOEX ) );
  118. osiv.dwOSVersionInfoSize = sizeof( OSVERSIONINFOEX );
  119. // The following call to VerifyVersionInfo() will test the OS level and that the
  120. // product suite is Enterprise.
  121. osiv.dwMajorVersion = 5;
  122. osiv.dwMinorVersion = 1;
  123. osiv.wServicePackMajor = 0;
  124. osiv.wSuiteMask = VER_SUITE_ENTERPRISE;
  125. dwlConditionMask = (DWORDLONG) 0L;
  126. VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL );
  127. VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL );
  128. VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL );
  129. VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
  130. if ( VerifyVersionInfo( &osiv,
  131. VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR |
  132. VER_SUITENAME,
  133. dwlConditionMask ) ) {
  134. fIsValid = TRUE;
  135. goto Cleanup;
  136. }
  137. //
  138. // Check if embedded
  139. //
  140. osiv.wSuiteMask = VER_SUITE_EMBEDDEDNT;
  141. if ( VerifyVersionInfo( &osiv,
  142. VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR |
  143. VER_SUITENAME,
  144. dwlConditionMask ) ) {
  145. fIsValid = TRUE;
  146. goto Cleanup;
  147. }
  148. //
  149. // Is the default node limit greater than 0?
  150. //
  151. if ( ClRtlGetDefaultNodeLimit( ClRtlGetSuiteType() ) > 0 ) {
  152. fIsValid = TRUE;
  153. goto Cleanup;
  154. }
  155. //
  156. // If we get here, the this version of the OS won't support clustering.
  157. //
  158. SetLastError( ERROR_CLUSTER_WRONG_OS_VERSION );
  159. Cleanup:
  160. return( fIsValid );
  161. } // ClRtlIsOSValid
  162. BOOL
  163. ClRtlIsOSTypeValid(
  164. VOID
  165. )
  166. /*++
  167. Routine Description:
  168. Checks to see if the operating system type (server, Enterprise, whatever) is
  169. ok to install a cluster.
  170. Arguments:
  171. None.
  172. Return Value:
  173. TRUE if it's ok.
  174. FALSE if it's not ok.
  175. --*/
  176. {
  177. BOOL fIsValid = FALSE;
  178. OSVERSIONINFOEX osiv;
  179. DWORDLONG dwlConditionMask;
  180. ZeroMemory( &osiv, sizeof( OSVERSIONINFOEX ) );
  181. osiv.dwOSVersionInfoSize = sizeof( OSVERSIONINFOEX );
  182. // The call to VerifyVersionInfo will test whether product suite is Advanced
  183. // Server, aka "Enterprise".
  184. osiv.wSuiteMask = VER_SUITE_ENTERPRISE;
  185. dwlConditionMask = (DWORDLONG) 0L;
  186. VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
  187. // Is this Datacenter or Advanced Server?
  188. if ( VerifyVersionInfo( &osiv, VER_SUITENAME, dwlConditionMask ) ) {
  189. fIsValid = TRUE;
  190. goto Cleanup;
  191. }
  192. // Is this Embedded NT?
  193. osiv.wSuiteMask = VER_SUITE_EMBEDDEDNT;
  194. if ( VerifyVersionInfo( &osiv, VER_SUITENAME, dwlConditionMask ) ) {
  195. fIsValid = TRUE;
  196. goto Cleanup;
  197. }
  198. //
  199. // Is the default node limit greater than 0?
  200. //
  201. if ( ClRtlGetDefaultNodeLimit( ClRtlGetSuiteType() ) > 0 ) {
  202. fIsValid = TRUE;
  203. goto Cleanup;
  204. }
  205. //
  206. // If we get here, the this version of the OS won't support clustering.
  207. //
  208. SetLastError( ERROR_CLUSTER_WRONG_OS_VERSION );
  209. Cleanup:
  210. return( fIsValid );
  211. } // ClRtlIsOSTypeValid
  212. //*********************************************************
  213. #define DATACENTER_DEFAULT_NODE_LIMIT 8
  214. #define ADVANCEDSERVER_DEFAULT_NODE_LIMIT 4
  215. #define EMBEDDED_DEFAULT_NODE_LIMIT 4
  216. #define SERVER_DEFAULT_NODE_LIMIT 0 // ** not used currently **
  217. //*********************************************************
  218. DWORD
  219. ClRtlGetDefaultNodeLimit(
  220. DWORD SuiteType
  221. )
  222. /*++
  223. Routine Description:
  224. Determines the default maximum number of nodes allowed in the cluster, based
  225. on the product suite.
  226. Arguments:
  227. None.
  228. Return Value:
  229. The default maximum number of nodes allowed in the cluster.
  230. Note that this function will return ZERO if the product suite is neither
  231. DataCenter, Advanced Server (aka Enterprise), nor Embedded.
  232. --*/
  233. {
  234. DWORD NodeLimit;
  235. switch( SuiteType )
  236. {
  237. case DataCenter:
  238. NodeLimit = DATACENTER_DEFAULT_NODE_LIMIT;
  239. break;
  240. case Enterprise:
  241. NodeLimit = ADVANCEDSERVER_DEFAULT_NODE_LIMIT;
  242. break;
  243. case EmbeddedNT:
  244. NodeLimit = EMBEDDED_DEFAULT_NODE_LIMIT;
  245. break;
  246. case VER_SERVER_NT:
  247. default:
  248. {
  249. DWORD dwOverride;
  250. //
  251. // Check the override registry value.
  252. //
  253. GetEnableClusterRegValue( &dwOverride );
  254. if ( dwOverride != 0 ) {
  255. NodeLimit = 2;
  256. } else {
  257. NodeLimit = 0;
  258. }
  259. }
  260. }
  261. return( NodeLimit );
  262. } // ClRtlGetDefaultNodeLimit
  263. DWORD
  264. ClRtlGetSuiteType(
  265. void
  266. )
  267. /*++
  268. Routine Description:
  269. Returns the current product suite type.
  270. Arguments:
  271. None.
  272. Return Value:
  273. Returns the product suite type DataCenter or Enterprise (aka Advanced Server)
  274. Returns zero if not DataCenter or Enterprise
  275. --*/
  276. {
  277. DWORD dwSuiteType = 0;
  278. OSVERSIONINFOEX osiv;
  279. DWORDLONG dwlConditionMask;
  280. ZeroMemory( &osiv, sizeof( OSVERSIONINFOEX ) );
  281. osiv.dwOSVersionInfoSize = sizeof( OSVERSIONINFOEX );
  282. // First check if product suite is DataCenter.
  283. osiv.wSuiteMask = VER_SUITE_DATACENTER;
  284. dwlConditionMask = (DWORDLONG) 0L;
  285. VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
  286. if ( VerifyVersionInfo( &osiv, VER_SUITENAME, dwlConditionMask ) == TRUE )
  287. {
  288. // This is DataCenter.
  289. dwSuiteType = DataCenter;
  290. goto Cleanup;
  291. }
  292. ZeroMemory( &osiv, sizeof( OSVERSIONINFOEX ) );
  293. osiv.dwOSVersionInfoSize = sizeof( OSVERSIONINFOEX );
  294. // Next check if this is Advanced Server (Enterprise).
  295. osiv.wSuiteMask = VER_SUITE_ENTERPRISE;
  296. dwlConditionMask = (DWORDLONG) 0L;
  297. VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
  298. if ( VerifyVersionInfo( &osiv, VER_SUITENAME, dwlConditionMask ) == TRUE )
  299. {
  300. dwSuiteType = Enterprise;
  301. goto Cleanup;
  302. }
  303. // Next check if this is Embedded.
  304. osiv.wSuiteMask = VER_SUITE_EMBEDDEDNT;
  305. dwlConditionMask = (DWORDLONG) 0L;
  306. VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
  307. if ( VerifyVersionInfo( &osiv, VER_SUITENAME, dwlConditionMask ) == TRUE )
  308. {
  309. dwSuiteType = EmbeddedNT;
  310. goto Cleanup;
  311. }
  312. // Finally check if this is any Server.
  313. if ( GetVersionEx( (LPOSVERSIONINFO) &osiv ) ) {
  314. if ( osiv.wProductType == VER_NT_SERVER ) {
  315. dwSuiteType = VER_SERVER_NT;
  316. goto Cleanup;
  317. }
  318. }
  319. Cleanup:
  320. return( dwSuiteType );
  321. } // ClRtlGetSuiteType