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.

480 lines
15 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. clusutil.cpp
  5. Abstract:
  6. This file has to be kept in sync with \kinglet\rats\testsrc\kernel\cluster\clusapi\clusutil
  7. Author:
  8. Sivaprasad Padisetty (sivapad) 6/25/97
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. //#include <windows.h>
  13. //#include <stdlib.h>
  14. #include <clusapi.h>
  15. #include "clusutil.h"
  16. DWORDTOSTRINGMAP aTypeMap [] =
  17. {
  18. {L"NODE_STATE", CLUSTER_CHANGE_NODE_STATE},
  19. {L"NODE_DELETED", CLUSTER_CHANGE_NODE_DELETED},
  20. {L"NODE_ADDED", CLUSTER_CHANGE_NODE_ADDED},
  21. {L"NODE_PROPERTY", CLUSTER_CHANGE_NODE_PROPERTY},
  22. {L"REGISTRY_NAME", CLUSTER_CHANGE_REGISTRY_NAME},
  23. {L"REGISTRY_ATTRIBUTES", CLUSTER_CHANGE_REGISTRY_ATTRIBUTES},
  24. {L"REGISTRY_VALUE", CLUSTER_CHANGE_REGISTRY_VALUE},
  25. {L"REGISTRY_SUBTREE", CLUSTER_CHANGE_REGISTRY_SUBTREE},
  26. {L"RESOURCE_STATE", CLUSTER_CHANGE_RESOURCE_STATE},
  27. {L"RESOURCE_DELETED", CLUSTER_CHANGE_RESOURCE_DELETED},
  28. {L"RESOURCE_ADDED", CLUSTER_CHANGE_RESOURCE_ADDED},
  29. {L"RESOURCE_PROPERTY", CLUSTER_CHANGE_RESOURCE_PROPERTY},
  30. {L"GROUP_STATE", CLUSTER_CHANGE_GROUP_STATE},
  31. {L"GROUP_DELETED", CLUSTER_CHANGE_GROUP_DELETED},
  32. {L"GROUP_ADDED", CLUSTER_CHANGE_GROUP_ADDED},
  33. {L"GROUP_PROPERTY", CLUSTER_CHANGE_GROUP_PROPERTY},
  34. {L"RESOURCE_TYPE_DELETED", CLUSTER_CHANGE_RESOURCE_TYPE_DELETED},
  35. {L"RESOURCE_TYPE_ADDED", CLUSTER_CHANGE_RESOURCE_TYPE_ADDED},
  36. {L"NETWORK_STATE", CLUSTER_CHANGE_NETWORK_STATE},
  37. {L"NETWORK_DELETED", CLUSTER_CHANGE_NETWORK_DELETED},
  38. {L"NETWORK_ADDED", CLUSTER_CHANGE_NETWORK_ADDED},
  39. {L"NETWORK_PROPERTY", CLUSTER_CHANGE_NETWORK_PROPERTY},
  40. {L"NETINTERFACE_STATE", CLUSTER_CHANGE_NETINTERFACE_STATE},
  41. {L"NETINTERFACE_DELETED", CLUSTER_CHANGE_NETINTERFACE_DELETED},
  42. {L"NETINTERFACE_ADDED", CLUSTER_CHANGE_NETINTERFACE_ADDED},
  43. {L"NETINTERFACE_PROPERTY", CLUSTER_CHANGE_NETINTERFACE_PROPERTY},
  44. {L"QUORUM_STATE", CLUSTER_CHANGE_QUORUM_STATE},
  45. {L"CLUSTER_STATE", CLUSTER_CHANGE_CLUSTER_STATE},
  46. {L"CLUSTER_PROPERTY", CLUSTER_CHANGE_CLUSTER_PROPERTY},
  47. {L"HANDLE_CLOSE", CLUSTER_CHANGE_HANDLE_CLOSE},
  48. {NULL, 0 }
  49. } ;
  50. LPCWSTR GetType (PDWORDTOSTRINGMAP pTypeMap, ULONG_PTR dwCode)
  51. {
  52. int i = 0;
  53. while (pTypeMap [i].pszDesc)
  54. {
  55. if (pTypeMap [i].dwCode == dwCode)
  56. return pTypeMap [i].pszDesc ;
  57. i++ ;
  58. }
  59. return L"Unknown Type" ;
  60. }
  61. LPCWSTR GetType (ULONG_PTR dwFilter)
  62. {
  63. return GetType (aTypeMap, dwFilter) ;
  64. }
  65. DWORDTOSUBSTRINGMAP aSubTypeMap [] =
  66. {
  67. {L"Unknown", CLUSTER_CHANGE_RESOURCE_STATE, ClusterResourceStateUnknown},
  68. {L"Online", CLUSTER_CHANGE_RESOURCE_STATE, ClusterResourceOnline},
  69. {L"Offline", CLUSTER_CHANGE_RESOURCE_STATE, ClusterResourceOffline},
  70. {L"Failed", CLUSTER_CHANGE_RESOURCE_STATE, ClusterResourceFailed},
  71. {L"OnlinePending", CLUSTER_CHANGE_RESOURCE_STATE, ClusterResourceOnlinePending},
  72. {L"OfflinePending", CLUSTER_CHANGE_RESOURCE_STATE, ClusterResourceOfflinePending},
  73. {L"Unknown", CLUSTER_CHANGE_GROUP_STATE, ClusterGroupStateUnknown},
  74. {L"Online", CLUSTER_CHANGE_GROUP_STATE, ClusterGroupOnline},
  75. {L"Offline", CLUSTER_CHANGE_GROUP_STATE, ClusterGroupOffline},
  76. {L"Failed", CLUSTER_CHANGE_GROUP_STATE, ClusterGroupFailed},
  77. {L"PartialOnline", CLUSTER_CHANGE_GROUP_STATE, ClusterGroupPartialOnline},
  78. {L"Pending", CLUSTER_CHANGE_GROUP_STATE, ClusterGroupPending},
  79. {L"Unknown", CLUSTER_CHANGE_NODE_STATE, ClusterNodeStateUnknown},
  80. {L"Up", CLUSTER_CHANGE_NODE_STATE, ClusterNodeUp},
  81. {L"Down", CLUSTER_CHANGE_NODE_STATE, ClusterNodeDown},
  82. {L"Paused", CLUSTER_CHANGE_NODE_STATE, ClusterNodePaused},
  83. {L"Joining", CLUSTER_CHANGE_NODE_STATE, ClusterNodeJoining},
  84. {L"Unknown", CLUSTER_CHANGE_NETWORK_STATE, ClusterNetworkStateUnknown},
  85. {L"Unavailable", CLUSTER_CHANGE_NETWORK_STATE, ClusterNetworkUnavailable},
  86. {L"Down", CLUSTER_CHANGE_NETWORK_STATE, ClusterNetworkDown},
  87. {L"Partitioned", CLUSTER_CHANGE_NETWORK_STATE, ClusterNetworkPartitioned},
  88. {L"Up", CLUSTER_CHANGE_NETWORK_STATE, ClusterNetworkUp},
  89. {L"Unknown", CLUSTER_CHANGE_NETINTERFACE_STATE, ClusterNetInterfaceStateUnknown},
  90. {L"Unavailable", CLUSTER_CHANGE_NETINTERFACE_STATE, ClusterNetInterfaceUnavailable},
  91. {L"Failed", CLUSTER_CHANGE_NETINTERFACE_STATE, ClusterNetInterfaceFailed},
  92. {L"Unreachable", CLUSTER_CHANGE_NETINTERFACE_STATE, ClusterNetInterfaceUnreachable},
  93. {L"Up", CLUSTER_CHANGE_NETINTERFACE_STATE, ClusterNetInterfaceUp},
  94. {NULL, 0, 0 }
  95. } ;
  96. LPCWSTR GetSubType (PDWORDTOSUBSTRINGMAP pTypeMap, DWORD dwCode, DWORD dwSubCode)
  97. {
  98. int i = 0;
  99. while (pTypeMap [i].pszDesc)
  100. {
  101. if (pTypeMap [i].dwCode == dwCode &&
  102. pTypeMap [i].dwSubCode == dwSubCode )
  103. return pTypeMap [i].pszDesc ;
  104. i++ ;
  105. }
  106. return L"Unknown Type" ;
  107. }
  108. /*
  109. Ini File Manipulating routines.
  110. */
  111. const LPCWSTR pszDefaultIni = L".\\CLUSMAN.INI" ;
  112. void
  113. RecurseEvalParam (LPCWSTR pszParam, LPWSTR pszValue, LPCWSTR pszSection)
  114. {
  115. LPCWSTR pszIniFile = _wgetenv (L"CLUSMANINI") ;
  116. if (!pszIniFile)
  117. pszIniFile = pszDefaultIni ;
  118. LPCWSTR pszTmp, pszStart, pszEnd ;
  119. WCHAR szVariable [PARAM_LEN], szTmpParam [PARAM_LEN], szTmpValue [PARAM_LEN] ;
  120. while (*pszParam)
  121. {
  122. if (*pszParam != L'%')
  123. *pszValue++ = *pszParam++ ;
  124. else // Has to substitute for the parameter.
  125. {
  126. pszEnd = pszStart = pszParam + 1 ;
  127. while (*pszEnd && *pszEnd != L'%')pszEnd++ ;
  128. if (!*pszEnd) // Only one % is found. Just copy the string to the value
  129. {
  130. while (*pszParam)
  131. *pszValue++ = *pszParam++ ;
  132. }
  133. else
  134. {
  135. pszParam = pszEnd + 1 ;
  136. wcsncpy (szVariable, pszStart, (UINT)(pszEnd - pszStart)) ;
  137. szVariable [pszEnd-pszStart] = L'\0' ;
  138. if (wcslen (szVariable) == 0)
  139. continue ;
  140. pszTmp = _wgetenv (szVariable) ;
  141. if (pszTmp) // Env variable found, copy it.
  142. {
  143. RecurseEvalParam (pszTmp, szTmpValue) ;
  144. pszTmp = szTmpValue ;
  145. while (*pszTmp)
  146. *pszValue++ = *pszTmp++ ;
  147. }
  148. else // Now try in the Ini File
  149. {
  150. if (GetPrivateProfileString (pszSection, szVariable, L"", szTmpParam, sizeof (szTmpParam)/sizeof(szTmpParam[0]), pszIniFile) > 0)
  151. { // Copied some stuff.
  152. RecurseEvalParam (szTmpParam, szTmpValue) ;
  153. pszTmp = szTmpValue ;
  154. while (*pszTmp)
  155. *pszValue++ = *pszTmp++ ;
  156. }
  157. }
  158. }
  159. }
  160. }
  161. *pszValue = L'\0' ;
  162. }
  163. int RecurseEvalIntParam (LPCWSTR pszParam)
  164. {
  165. WCHAR szBuf [PARAM_LEN] ;
  166. RecurseEvalParam (pszParam, szBuf) ;
  167. return szBuf [0] == L'\0'?0:_wtoi (szBuf) ;
  168. }
  169. void
  170. SaveParam (LPCWSTR pszKey, LPCWSTR pszValue)
  171. {
  172. LPCWSTR pszIniFile = _wgetenv (L"CLUSMANINI") ;
  173. if (!pszIniFile)
  174. pszIniFile = pszDefaultIni ;
  175. WritePrivateProfileString (L"PARAMETER", pszKey, pszValue, pszIniFile) ;
  176. }
  177. void
  178. SaveIntParam (LPCWSTR pszKey, int iValue)
  179. {
  180. LPCWSTR pszIniFile = _wgetenv (L"CLUSMANINI") ;
  181. if (!pszIniFile)
  182. pszIniFile = pszDefaultIni ;
  183. WCHAR szBuf [80] ;
  184. wsprintf (szBuf, L"%d", iValue) ;
  185. WritePrivateProfileString (L"PARAMETER", pszKey, szBuf, pszIniFile) ;
  186. }
  187. void MemSet (LPWSTR pszBuf, WCHAR c, DWORD cb)
  188. {
  189. while (cb--)
  190. *pszBuf++ = c ;
  191. }
  192. int MemCheck (LPCWSTR pszBuf, WCHAR c, DWORD cb)
  193. {
  194. while (cb--)
  195. if (*pszBuf++ != c)
  196. return 1 ;
  197. return 0 ;
  198. }
  199. // Get the state of the resource of the name of the resource
  200. CLUSTER_RESOURCE_STATE MyGetClusterResourceState (HCLUSTER hCluster, LPCWSTR pszResourceName, LPWSTR pszNodeName, LPWSTR pszGroupName)
  201. {
  202. HRESOURCE hResource ;
  203. CLUSTER_RESOURCE_STATE dwState ;
  204. DWORD cbNodeName, cbGroupName ;
  205. if (hResource = OpenClusterResource (hCluster, pszResourceName))
  206. {
  207. // This is a bug of hard coding the length. Hopefully the code does not crash.
  208. cbGroupName = (pszGroupName)?80:0 ;
  209. cbNodeName = (pszNodeName)?80:0 ;
  210. dwState = GetClusterResourceState (hResource, pszNodeName, &cbNodeName, pszGroupName, &cbGroupName) ;
  211. CloseClusterResource (hResource) ;
  212. }
  213. else
  214. dwState = ClusterResourceStateUnknown ;
  215. return dwState ;
  216. }
  217. // Get the state of the Group given the name.
  218. CLUSTER_GROUP_STATE MyGetClusterGroupState (HCLUSTER hCluster, LPCWSTR pszGroupName, LPWSTR pszNodeName)
  219. {
  220. HGROUP hGroup ;
  221. CLUSTER_GROUP_STATE dwState ;
  222. DWORD cbNodeName ;
  223. if (hGroup = OpenClusterGroup (hCluster, pszGroupName))
  224. {
  225. // This is a bug of hard coding the length. Hopefully the code does not crash.
  226. cbNodeName = (pszNodeName)?80:0 ;
  227. dwState = GetClusterGroupState (hGroup, pszNodeName, &cbNodeName) ;
  228. CloseClusterGroup (hGroup) ;
  229. }
  230. else
  231. dwState = ClusterGroupStateUnknown ;
  232. return dwState ;
  233. }
  234. // Get the state of the Node given the name.
  235. CLUSTER_NODE_STATE MyGetClusterNodeState (HCLUSTER hCluster, LPWSTR pszNodeName)
  236. {
  237. HNODE hNode ;
  238. CLUSTER_NODE_STATE dwState ;
  239. if (hNode = OpenClusterNode (hCluster, pszNodeName))
  240. {
  241. dwState = GetClusterNodeState (hNode) ;
  242. CloseClusterNode (hNode) ;
  243. }
  244. else
  245. dwState = ClusterNodeStateUnknown ;
  246. return dwState ;
  247. }
  248. // Get the state of the Network given the name.
  249. CLUSTER_NETWORK_STATE MyGetClusterNetworkState (HCLUSTER hCluster, LPWSTR pszNetworkName)
  250. {
  251. HNETWORK hNetwork ;
  252. CLUSTER_NETWORK_STATE dwState ;
  253. if (hNetwork = OpenClusterNetwork (hCluster, pszNetworkName))
  254. {
  255. dwState = GetClusterNetworkState (hNetwork) ;
  256. CloseClusterNetwork (hNetwork) ;
  257. }
  258. else
  259. dwState = ClusterNetworkStateUnknown ;
  260. return dwState ;
  261. }
  262. // Get the state of the NetInterface given the name.
  263. CLUSTER_NETINTERFACE_STATE MyGetClusterNetInterfaceState (HCLUSTER hCluster, LPWSTR pszNetInterfaceName)
  264. {
  265. HNETINTERFACE hNetInterface ;
  266. CLUSTER_NETINTERFACE_STATE dwState ;
  267. if (hNetInterface = OpenClusterNetInterface (hCluster, pszNetInterfaceName))
  268. {
  269. dwState = GetClusterNetInterfaceState (hNetInterface) ;
  270. CloseClusterNetInterface (hNetInterface) ;
  271. }
  272. else
  273. dwState = ClusterNetInterfaceStateUnknown ;
  274. return dwState ;
  275. }
  276. // returns 0 on success.
  277. // hCluster is the handle to the cluster.
  278. // pszFileName is filename where to store the cluster information.
  279. #include <stdio.h>
  280. DumpClusterDetails (HCLUSTER hCluster, LPCWSTR pszFileName, LPCWSTR pszComment)
  281. {
  282. FILE *fp = _wfopen (pszFileName, L"a") ;
  283. HCLUSENUM hEnum = NULL ;
  284. DWORD cbNodeName, cbGroupName, cbResourceName, dwEnumType, dwIndex = 0 ;
  285. BOOL bMoreData = TRUE ;
  286. WCHAR szNodeName [512], szGroupName [512], szResourceName [512] ;
  287. DWORD dwState ;
  288. fwprintf (fp, L"\n*********************************************************************\n") ;
  289. fwprintf (fp, pszComment) ;
  290. fwprintf (fp, L"*********************************************************************\n") ;
  291. __try
  292. {
  293. // Dump all the Node Information
  294. fwprintf (fp, L"DUMP ALL THE NODE INFORMATION\n------------------------------\n") ;
  295. if ((hEnum = ClusterOpenEnum (hCluster, CLUSTER_ENUM_NODE)) == NULL)
  296. {
  297. fwprintf (fp, L"Clus Open Enum failed for the node\n") ;
  298. return 1 ;
  299. }
  300. while (bMoreData)
  301. {
  302. cbNodeName = sizeof (szNodeName)/sizeof (szNodeName[0]) ;
  303. switch (ClusterEnum (hEnum, dwIndex, &dwEnumType, szNodeName, &cbNodeName))
  304. {
  305. case ERROR_SUCCESS:
  306. dwState = (DWORD) MyGetClusterNodeState (hCluster, szNodeName) ;
  307. fwprintf (fp, L"%-30s Status:%-30s\n", szNodeName, GetSubType (aSubTypeMap, CLUSTER_CHANGE_NODE_STATE, dwState)) ;
  308. break ;
  309. case ERROR_NO_MORE_ITEMS:
  310. bMoreData = FALSE ;
  311. break ;
  312. default:
  313. fwprintf (fp, L"ClusterEnum returned Invalid Value\n") ;
  314. bMoreData = FALSE ;
  315. return 1 ;
  316. }
  317. dwIndex++ ;
  318. }
  319. ClusterCloseEnum (hEnum) ;
  320. // Dump all the Group Information
  321. dwIndex = 0 ;
  322. bMoreData = TRUE ;
  323. fwprintf (fp, L"DUMP ALL THE GROUP INFORMATION\n------------------------------\n") ;
  324. if ((hEnum = ClusterOpenEnum (hCluster, CLUSTER_ENUM_GROUP)) == NULL)
  325. {
  326. fwprintf (fp, L"Clus Open Enum failed for the node\n") ;
  327. return 1 ;
  328. }
  329. while (bMoreData)
  330. {
  331. cbGroupName = sizeof (szGroupName) / sizeof (szGroupName [0]) ;
  332. switch (ClusterEnum (hEnum, dwIndex, &dwEnumType, szGroupName, &cbGroupName))
  333. {
  334. case ERROR_SUCCESS:
  335. dwState = (DWORD) MyGetClusterGroupState (hCluster, szGroupName, szNodeName) ;
  336. fwprintf (fp, L"%-30s Node:%-30s Status:%-30s\n", szGroupName, szNodeName, GetSubType (aSubTypeMap, CLUSTER_CHANGE_GROUP_STATE, dwState)) ;
  337. break ;
  338. case ERROR_NO_MORE_ITEMS:
  339. bMoreData = FALSE ;
  340. break ;
  341. default:
  342. fwprintf (fp, L"ClusterEnum returned Invalid Value\n") ;
  343. bMoreData = FALSE ;
  344. return 1 ;
  345. }
  346. dwIndex++ ;
  347. }
  348. ClusterCloseEnum (hEnum) ;
  349. // Dump all the Resource Information
  350. dwIndex = 0 ;
  351. bMoreData = TRUE ;
  352. fwprintf (fp, L"DUMP ALL THE RESOURCE INFORMATION\n---------------------------------\n") ;
  353. if ((hEnum = ClusterOpenEnum (hCluster, CLUSTER_ENUM_RESOURCE)) == NULL)
  354. {
  355. fwprintf (fp, L"Clus Open Enum failed for the node\n") ;
  356. return 1 ;
  357. }
  358. while (bMoreData)
  359. {
  360. cbResourceName = sizeof (szResourceName) / sizeof (szResourceName [0]) ;
  361. switch (ClusterEnum (hEnum, dwIndex, &dwEnumType, szResourceName, &cbResourceName))
  362. {
  363. case ERROR_SUCCESS:
  364. dwState = (DWORD)MyGetClusterResourceState (hCluster, szResourceName, szNodeName, szGroupName) ;
  365. fwprintf (fp, L"%-30s Node:%-30s Group:%-30s Status:%-30s\n", szResourceName, szNodeName, szGroupName, GetSubType (aSubTypeMap, CLUSTER_CHANGE_RESOURCE_STATE, dwState)) ;
  366. break ;
  367. case ERROR_NO_MORE_ITEMS:
  368. bMoreData = FALSE ;
  369. break ;
  370. default:
  371. fwprintf (fp, L"ClusterEnum returned Invalid Value\n") ;
  372. bMoreData = FALSE ;
  373. return 1 ;
  374. }
  375. dwIndex++ ;
  376. }
  377. ClusterCloseEnum (hEnum) ;
  378. hEnum = NULL ;
  379. return 0 ;
  380. }
  381. __finally
  382. {
  383. if (hEnum)
  384. ClusterCloseEnum (hEnum) ;
  385. fclose (fp) ;
  386. }
  387. }