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.

400 lines
14 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. tnotify.c
  5. Abstract:
  6. Test for cluster notification API
  7. Author:
  8. John Vert (jvert) 9-Apr-1996
  9. Revision History:
  10. --*/
  11. #include "windows.h"
  12. #include "cluster.h"
  13. #include "stdio.h"
  14. #include "stdlib.h"
  15. #include "conio.h"
  16. #define NOTIFY_KEY_ALL 27
  17. #define NOTIFY_KEY_GROUP 38
  18. #define NOTIFY_KEY_RESOURCE 42
  19. #define NOTIFY_KEY_NODE 1032
  20. #define NOTIFY_KEY_REGISTRY 0xabcdef
  21. #define NOTIFY_KEY_REGISTRY_GROUP 0x1234
  22. #define NOTIFY_KEY_REGISTRY_RESOURCE 0x5678
  23. #define NOTIFY_KEY_CLUSTER_RECONNECT 0x89AB
  24. #define MAX_HANDLES 64
  25. HNODE NodeHandles[MAX_HANDLES];
  26. HRESOURCE ResourceHandles[MAX_HANDLES];
  27. HGROUP GroupHandles[MAX_HANDLES];
  28. HKEY RegistryHandles[MAX_HANDLES];
  29. DWORD NodeHandleCount=0;
  30. DWORD ResourceHandleCount=0;
  31. DWORD GroupHandleCount=0;
  32. DWORD RegistryHandleCount=0;
  33. int
  34. _cdecl
  35. main (argc, argv)
  36. int argc;
  37. char *argv[];
  38. {
  39. HCLUSTER Cluster;
  40. HCHANGE hChange;
  41. DWORD NotifyKey;
  42. DWORD Filter;
  43. WCHAR Buffer[50];
  44. ULONG BufSize;
  45. DWORD Status;
  46. HCLUSENUM Enum;
  47. DWORD i;
  48. DWORD Type;
  49. HGROUP Group;
  50. HRESOURCE Resource;
  51. HNODE Node;
  52. HKEY ClusterKey;
  53. WCHAR szClusterName[MAX_COMPUTERNAME_LENGTH + 1] ;
  54. LPWSTR lpszClusterName = NULL ;
  55. /*
  56. Added by Karthikl
  57. */
  58. if(argc > 1)
  59. {
  60. if(_strnicmp(argv[1], "-?", 2) == 0 || _strnicmp(argv[1], "/?", 2) == 0)
  61. {
  62. printf("tnotify.exe <clustername>\n") ;
  63. printf("Test program to check the notification stuff\n") ;
  64. printf("Run with a cluster name if running from a client machine\n") ;
  65. return ERROR_SUCCESS ;
  66. }
  67. else
  68. {
  69. int result = MultiByteToWideChar(CP_ACP,
  70. 0,
  71. argv[1],
  72. -1,
  73. szClusterName,
  74. MAX_COMPUTERNAME_LENGTH + 1) ;
  75. if(result)
  76. {
  77. lpszClusterName = szClusterName ;
  78. }
  79. else
  80. {
  81. Status = GetLastError() ;
  82. fprintf(stderr, "MultiByteToWideChar failed %d\n", Status);
  83. return Status ;
  84. }
  85. }
  86. }
  87. // end karthikl
  88. // CLUSTER_CHANGE_CLUSTER_RECONNECT
  89. //
  90. // Get notifications for current cluster.
  91. //
  92. Cluster = OpenCluster(lpszClusterName);
  93. if (Cluster == NULL) {
  94. fprintf(stderr, "OpenCluster failed %d\n",GetLastError());
  95. return(0);
  96. }
  97. hChange = CreateClusterNotifyPort(INVALID_HANDLE_VALUE,
  98. INVALID_HANDLE_VALUE,
  99. CLUSTER_CHANGE_ALL,
  100. NOTIFY_KEY_ALL);
  101. if (hChange == NULL) {
  102. fprintf(stderr, "First CreateClusterNotifyPort failed %d\n",GetLastError());
  103. return(0);
  104. }
  105. hChange = CreateClusterNotifyPort(hChange,
  106. Cluster,
  107. CLUSTER_CHANGE_ALL,
  108. NOTIFY_KEY_ALL);
  109. if (hChange == NULL) {
  110. fprintf(stderr, "Second CreateClusterNotifyPort failed %d\n",GetLastError());
  111. return(0);
  112. }
  113. //
  114. // Post a notification for the root of the cluster registry.
  115. //
  116. ClusterKey = GetClusterKey(Cluster, KEY_READ);
  117. if (ClusterKey == NULL) {
  118. fprintf(stderr, "GetClusterKey failed %d\n",GetLastError());
  119. return(0);
  120. }
  121. RegistryHandles[RegistryHandleCount++] = ClusterKey;
  122. Status = RegisterClusterNotify(hChange,
  123. CLUSTER_CHANGE_REGISTRY_NAME |
  124. CLUSTER_CHANGE_REGISTRY_ATTRIBUTES |
  125. CLUSTER_CHANGE_REGISTRY_VALUE |
  126. CLUSTER_CHANGE_REGISTRY_SUBTREE |
  127. CLUSTER_CHANGE_HANDLE_CLOSE,
  128. ClusterKey,
  129. NOTIFY_KEY_REGISTRY);
  130. if (Status != ERROR_SUCCESS) {
  131. fprintf(stderr, "RegisterClusterNotify for key failed %d\n",Status);
  132. }
  133. //
  134. // Enumerate nodes, groups, and resources and post a specific
  135. // notification for each one.
  136. //
  137. Enum = ClusterOpenEnum(Cluster, CLUSTER_ENUM_NODE |
  138. CLUSTER_ENUM_RESOURCE |
  139. CLUSTER_ENUM_GROUP);
  140. if (Enum == NULL) {
  141. fprintf(stderr, "ClusterOpenEnum failed %d\n", GetLastError());
  142. return(0);
  143. }
  144. for (i=0; ; i++) {
  145. BufSize = sizeof(Buffer) / sizeof(WCHAR);
  146. Status = ClusterEnum(Enum,
  147. i,
  148. &Type,
  149. Buffer,
  150. &BufSize);
  151. if (Status == ERROR_NO_MORE_ITEMS) {
  152. break;
  153. } else if (Status != ERROR_SUCCESS) {
  154. fprintf(stderr, "ClusterEnum %d returned error %d\n",i,Status);
  155. return(0);
  156. }
  157. switch (Type) {
  158. case CLUSTER_ENUM_GROUP:
  159. Group = OpenClusterGroup(Cluster, Buffer);
  160. if (Group == NULL) {
  161. fprintf(stderr, "OpenClusterGroup %ws failed %d\n",Buffer, GetLastError());
  162. continue;
  163. }
  164. GroupHandles[GroupHandleCount++] = Group;
  165. Status = RegisterClusterNotify(hChange,
  166. CLUSTER_CHANGE_GROUP_STATE | CLUSTER_CHANGE_HANDLE_CLOSE,
  167. Group,
  168. NOTIFY_KEY_GROUP);
  169. if (Status != ERROR_SUCCESS) {
  170. fprintf(stderr, "RegisterClusterNotify for group %ws failed %d\n",Buffer,Status);
  171. continue;
  172. }
  173. ClusterKey = GetClusterGroupKey(Group, KEY_READ);
  174. if (Status != ERROR_SUCCESS) {
  175. fprintf(stderr, "GetClusterGroupKey for group %ws failed %d\n",Buffer,GetLastError());
  176. continue;
  177. }
  178. RegistryHandles[RegistryHandleCount++] = ClusterKey;
  179. Status = RegisterClusterNotify(hChange,
  180. CLUSTER_CHANGE_REGISTRY_NAME |
  181. CLUSTER_CHANGE_REGISTRY_ATTRIBUTES |
  182. CLUSTER_CHANGE_REGISTRY_VALUE |
  183. CLUSTER_CHANGE_REGISTRY_SUBTREE |
  184. CLUSTER_CHANGE_HANDLE_CLOSE,
  185. ClusterKey,
  186. NOTIFY_KEY_REGISTRY_GROUP);
  187. if (Status != ERROR_SUCCESS) {
  188. fprintf(stderr,
  189. "RegisterClusterNotify for group %ws key failed %d\n",
  190. Buffer,
  191. Status);
  192. }
  193. break;
  194. case CLUSTER_ENUM_RESOURCE:
  195. Resource = OpenClusterResource(Cluster, Buffer);
  196. if (Resource == NULL) {
  197. fprintf(stderr, "OpenClusterResource %ws failed %d\n",Buffer, GetLastError());
  198. continue;
  199. }
  200. ResourceHandles[ResourceHandleCount++] = Resource;
  201. Status = RegisterClusterNotify(hChange,
  202. CLUSTER_CHANGE_RESOURCE_STATE | CLUSTER_CHANGE_HANDLE_CLOSE,
  203. Resource,
  204. NOTIFY_KEY_RESOURCE);
  205. if (Status != ERROR_SUCCESS) {
  206. fprintf(stderr, "RegisterClusterNotify for resource %ws failed %d\n",Buffer,Status);
  207. continue;
  208. }
  209. ClusterKey = GetClusterResourceKey(Resource, KEY_READ);
  210. if (Status != ERROR_SUCCESS) {
  211. fprintf(stderr, "GetClusterResourceKey for resource %ws failed %d\n",Buffer,GetLastError());
  212. continue;
  213. }
  214. RegistryHandles[RegistryHandleCount++] = ClusterKey;
  215. Status = RegisterClusterNotify(hChange,
  216. CLUSTER_CHANGE_REGISTRY_NAME |
  217. CLUSTER_CHANGE_REGISTRY_ATTRIBUTES |
  218. CLUSTER_CHANGE_REGISTRY_VALUE |
  219. CLUSTER_CHANGE_REGISTRY_SUBTREE |
  220. CLUSTER_CHANGE_HANDLE_CLOSE,
  221. ClusterKey,
  222. NOTIFY_KEY_REGISTRY_RESOURCE);
  223. if (Status != ERROR_SUCCESS) {
  224. fprintf(stderr,
  225. "RegisterClusterNotify for resource %ws key failed %d\n",
  226. Buffer,
  227. Status);
  228. }
  229. break;
  230. case CLUSTER_ENUM_NODE:
  231. Node = OpenClusterNode(Cluster, Buffer);
  232. if (Node == NULL) {
  233. fprintf(stderr, "OpenClusterNode %ws failed %d\n",Buffer, GetLastError());
  234. continue;
  235. }
  236. NodeHandles[NodeHandleCount++] = Node;
  237. Status = RegisterClusterNotify(hChange,
  238. CLUSTER_CHANGE_NODE_STATE | CLUSTER_CHANGE_NODE_DELETED | CLUSTER_CHANGE_HANDLE_CLOSE,
  239. Node,
  240. NOTIFY_KEY_NODE);
  241. if (Status != ERROR_SUCCESS) {
  242. fprintf(stderr, "RegisterClusterNotify for node %ws failed %d\n",Buffer,Status);
  243. continue;
  244. }
  245. break;
  246. default:
  247. fprintf(stderr, "Invalid Type %d returned from ClusterEnum\n", Type);
  248. return(0);
  249. }
  250. }
  251. // finally register the notification event for CLUSTER_CHANGE_CLUSTER_RECONNECT
  252. if(lpszClusterName != NULL) // implies we are connecting from a client
  253. {
  254. Status = RegisterClusterNotify(hChange,
  255. CLUSTER_CHANGE_CLUSTER_RECONNECT|CLUSTER_CHANGE_CLUSTER_STATE,
  256. Cluster,
  257. NOTIFY_KEY_CLUSTER_RECONNECT);
  258. if (Status != ERROR_SUCCESS)
  259. {
  260. fprintf(stderr, "RegisterClusterNotify for CLUSTER_CHANGE_CLUSTER_RECONNECT failed %d\n",Status);
  261. }
  262. else
  263. {
  264. fprintf(stderr, "Success registering CLUSTER_CHANGE_CLUSTER_RECONNECT\n");
  265. }
  266. }
  267. //
  268. // Just read out changes forever
  269. //
  270. printf("Waiting for notification events\n");
  271. while (!_kbhit()) {
  272. BufSize = sizeof(Buffer) / sizeof(WCHAR);
  273. Status = GetClusterNotify(hChange,
  274. &NotifyKey,
  275. &Filter,
  276. Buffer,
  277. &BufSize,
  278. INFINITE);
  279. if (Status != ERROR_SUCCESS) {
  280. fprintf(stderr, "GetClusterNotify failed %d\n", GetLastError());
  281. return(0);
  282. }
  283. switch (NotifyKey) {
  284. case NOTIFY_KEY_ALL:
  285. printf("Clusterwide notify: Filter %08lx, Name %ws\n",
  286. Filter, Buffer);
  287. break;
  288. case NOTIFY_KEY_GROUP:
  289. printf("Group notify: Filter %08lx, Name %ws\n",
  290. Filter, Buffer);
  291. break;
  292. case NOTIFY_KEY_RESOURCE:
  293. printf("Resource notify: Filter %08lx, Name %ws\n",
  294. Filter, Buffer);
  295. break;
  296. case NOTIFY_KEY_NODE:
  297. printf("Node notify: Filter %08lx, Name %ws\n",
  298. Filter, Buffer);
  299. break;
  300. case NOTIFY_KEY_REGISTRY:
  301. printf("Registry notify: Filter %08lx, Name %ws\n",
  302. Filter, Buffer);
  303. break;
  304. case NOTIFY_KEY_REGISTRY_GROUP:
  305. printf("Registry group notify: Filter %08lx, Name %ws\n",
  306. Filter, Buffer);
  307. break;
  308. case NOTIFY_KEY_REGISTRY_RESOURCE:
  309. printf("Registry resource notify: Filter %08lx, Name %ws\n",
  310. Filter, Buffer);
  311. break;
  312. case NOTIFY_KEY_CLUSTER_RECONNECT:
  313. printf("Cluster Reconnect notify: Filter %08lx, Name %ws\n",
  314. Filter, Buffer);
  315. break ;
  316. default:
  317. printf("UNKNOWN NOTIFY KEY %d, Filter %08lx, Name %ws\n",
  318. NotifyKey, Filter, Buffer);
  319. break;
  320. }
  321. }
  322. //
  323. // Close all the open handles
  324. //
  325. for (i=0; i<NodeHandleCount; i++) {
  326. CloseClusterNode(NodeHandles[i]);
  327. }
  328. for (i=0; i<ResourceHandleCount; i++) {
  329. CloseClusterResource(ResourceHandles[i]);
  330. }
  331. for (i=0; i<GroupHandleCount; i++) {
  332. CloseClusterGroup(GroupHandles[i]);
  333. }
  334. for (i=0; i<RegistryHandleCount; i++) {
  335. ClusterRegCloseKey(RegistryHandles[i]);
  336. }
  337. CloseCluster(Cluster);
  338. //
  339. // Drain out all the handle close events.
  340. //
  341. Sleep(5000);
  342. do {
  343. BufSize = sizeof(Buffer) / sizeof(WCHAR);
  344. Status = GetClusterNotify(hChange,
  345. &NotifyKey,
  346. &Filter,
  347. Buffer,
  348. &BufSize,
  349. 0);
  350. if (Status == ERROR_SUCCESS) {
  351. printf("Draining notification NotifyKey = %08lx\n", NotifyKey);
  352. printf(" Filter = %08lx\n", Filter);
  353. printf(" Name = %ws\n", Buffer);
  354. } else {
  355. printf("Draining notifies returned %d\n",Status);
  356. }
  357. } while ( Status == ERROR_SUCCESS );
  358. CloseClusterNotifyPort(hChange);
  359. }