/*++ Copyright (c) 1996 Microsoft Corporation Module Name: tnotify.c Abstract: Test for cluster notification API Author: John Vert (jvert) 9-Apr-1996 Revision History: --*/ #include "windows.h" #include "cluster.h" #include "stdio.h" #include "stdlib.h" #include "conio.h" #define NOTIFY_KEY_ALL 27 #define NOTIFY_KEY_GROUP 38 #define NOTIFY_KEY_RESOURCE 42 #define NOTIFY_KEY_NODE 1032 #define NOTIFY_KEY_REGISTRY 0xabcdef #define NOTIFY_KEY_REGISTRY_GROUP 0x1234 #define NOTIFY_KEY_REGISTRY_RESOURCE 0x5678 #define NOTIFY_KEY_CLUSTER_RECONNECT 0x89AB #define MAX_HANDLES 64 HNODE NodeHandles[MAX_HANDLES]; HRESOURCE ResourceHandles[MAX_HANDLES]; HGROUP GroupHandles[MAX_HANDLES]; HKEY RegistryHandles[MAX_HANDLES]; DWORD NodeHandleCount=0; DWORD ResourceHandleCount=0; DWORD GroupHandleCount=0; DWORD RegistryHandleCount=0; int _cdecl main (argc, argv) int argc; char *argv[]; { HCLUSTER Cluster; HCHANGE hChange; DWORD NotifyKey; DWORD Filter; WCHAR Buffer[50]; ULONG BufSize; DWORD Status; HCLUSENUM Enum; DWORD i; DWORD Type; HGROUP Group; HRESOURCE Resource; HNODE Node; HKEY ClusterKey; WCHAR szClusterName[MAX_COMPUTERNAME_LENGTH + 1] ; LPWSTR lpszClusterName = NULL ; /* Added by Karthikl */ if(argc > 1) { if(_strnicmp(argv[1], "-?", 2) == 0 || _strnicmp(argv[1], "/?", 2) == 0) { printf("tnotify.exe \n") ; printf("Test program to check the notification stuff\n") ; printf("Run with a cluster name if running from a client machine\n") ; return ERROR_SUCCESS ; } else { int result = MultiByteToWideChar(CP_ACP, 0, argv[1], -1, szClusterName, MAX_COMPUTERNAME_LENGTH + 1) ; if(result) { lpszClusterName = szClusterName ; } else { Status = GetLastError() ; fprintf(stderr, "MultiByteToWideChar failed %d\n", Status); return Status ; } } } // end karthikl // CLUSTER_CHANGE_CLUSTER_RECONNECT // // Get notifications for current cluster. // Cluster = OpenCluster(lpszClusterName); if (Cluster == NULL) { fprintf(stderr, "OpenCluster failed %d\n",GetLastError()); return(0); } hChange = CreateClusterNotifyPort(INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, CLUSTER_CHANGE_ALL, NOTIFY_KEY_ALL); if (hChange == NULL) { fprintf(stderr, "First CreateClusterNotifyPort failed %d\n",GetLastError()); return(0); } hChange = CreateClusterNotifyPort(hChange, Cluster, CLUSTER_CHANGE_ALL, NOTIFY_KEY_ALL); if (hChange == NULL) { fprintf(stderr, "Second CreateClusterNotifyPort failed %d\n",GetLastError()); return(0); } // // Post a notification for the root of the cluster registry. // ClusterKey = GetClusterKey(Cluster, KEY_READ); if (ClusterKey == NULL) { fprintf(stderr, "GetClusterKey failed %d\n",GetLastError()); return(0); } RegistryHandles[RegistryHandleCount++] = ClusterKey; Status = RegisterClusterNotify(hChange, CLUSTER_CHANGE_REGISTRY_NAME | CLUSTER_CHANGE_REGISTRY_ATTRIBUTES | CLUSTER_CHANGE_REGISTRY_VALUE | CLUSTER_CHANGE_REGISTRY_SUBTREE | CLUSTER_CHANGE_HANDLE_CLOSE, ClusterKey, NOTIFY_KEY_REGISTRY); if (Status != ERROR_SUCCESS) { fprintf(stderr, "RegisterClusterNotify for key failed %d\n",Status); } // // Enumerate nodes, groups, and resources and post a specific // notification for each one. // Enum = ClusterOpenEnum(Cluster, CLUSTER_ENUM_NODE | CLUSTER_ENUM_RESOURCE | CLUSTER_ENUM_GROUP); if (Enum == NULL) { fprintf(stderr, "ClusterOpenEnum failed %d\n", GetLastError()); return(0); } for (i=0; ; i++) { BufSize = sizeof(Buffer) / sizeof(WCHAR); Status = ClusterEnum(Enum, i, &Type, Buffer, &BufSize); if (Status == ERROR_NO_MORE_ITEMS) { break; } else if (Status != ERROR_SUCCESS) { fprintf(stderr, "ClusterEnum %d returned error %d\n",i,Status); return(0); } switch (Type) { case CLUSTER_ENUM_GROUP: Group = OpenClusterGroup(Cluster, Buffer); if (Group == NULL) { fprintf(stderr, "OpenClusterGroup %ws failed %d\n",Buffer, GetLastError()); continue; } GroupHandles[GroupHandleCount++] = Group; Status = RegisterClusterNotify(hChange, CLUSTER_CHANGE_GROUP_STATE | CLUSTER_CHANGE_HANDLE_CLOSE, Group, NOTIFY_KEY_GROUP); if (Status != ERROR_SUCCESS) { fprintf(stderr, "RegisterClusterNotify for group %ws failed %d\n",Buffer,Status); continue; } ClusterKey = GetClusterGroupKey(Group, KEY_READ); if (Status != ERROR_SUCCESS) { fprintf(stderr, "GetClusterGroupKey for group %ws failed %d\n",Buffer,GetLastError()); continue; } RegistryHandles[RegistryHandleCount++] = ClusterKey; Status = RegisterClusterNotify(hChange, CLUSTER_CHANGE_REGISTRY_NAME | CLUSTER_CHANGE_REGISTRY_ATTRIBUTES | CLUSTER_CHANGE_REGISTRY_VALUE | CLUSTER_CHANGE_REGISTRY_SUBTREE | CLUSTER_CHANGE_HANDLE_CLOSE, ClusterKey, NOTIFY_KEY_REGISTRY_GROUP); if (Status != ERROR_SUCCESS) { fprintf(stderr, "RegisterClusterNotify for group %ws key failed %d\n", Buffer, Status); } break; case CLUSTER_ENUM_RESOURCE: Resource = OpenClusterResource(Cluster, Buffer); if (Resource == NULL) { fprintf(stderr, "OpenClusterResource %ws failed %d\n",Buffer, GetLastError()); continue; } ResourceHandles[ResourceHandleCount++] = Resource; Status = RegisterClusterNotify(hChange, CLUSTER_CHANGE_RESOURCE_STATE | CLUSTER_CHANGE_HANDLE_CLOSE, Resource, NOTIFY_KEY_RESOURCE); if (Status != ERROR_SUCCESS) { fprintf(stderr, "RegisterClusterNotify for resource %ws failed %d\n",Buffer,Status); continue; } ClusterKey = GetClusterResourceKey(Resource, KEY_READ); if (Status != ERROR_SUCCESS) { fprintf(stderr, "GetClusterResourceKey for resource %ws failed %d\n",Buffer,GetLastError()); continue; } RegistryHandles[RegistryHandleCount++] = ClusterKey; Status = RegisterClusterNotify(hChange, CLUSTER_CHANGE_REGISTRY_NAME | CLUSTER_CHANGE_REGISTRY_ATTRIBUTES | CLUSTER_CHANGE_REGISTRY_VALUE | CLUSTER_CHANGE_REGISTRY_SUBTREE | CLUSTER_CHANGE_HANDLE_CLOSE, ClusterKey, NOTIFY_KEY_REGISTRY_RESOURCE); if (Status != ERROR_SUCCESS) { fprintf(stderr, "RegisterClusterNotify for resource %ws key failed %d\n", Buffer, Status); } break; case CLUSTER_ENUM_NODE: Node = OpenClusterNode(Cluster, Buffer); if (Node == NULL) { fprintf(stderr, "OpenClusterNode %ws failed %d\n",Buffer, GetLastError()); continue; } NodeHandles[NodeHandleCount++] = Node; Status = RegisterClusterNotify(hChange, CLUSTER_CHANGE_NODE_STATE | CLUSTER_CHANGE_NODE_DELETED | CLUSTER_CHANGE_HANDLE_CLOSE, Node, NOTIFY_KEY_NODE); if (Status != ERROR_SUCCESS) { fprintf(stderr, "RegisterClusterNotify for node %ws failed %d\n",Buffer,Status); continue; } break; default: fprintf(stderr, "Invalid Type %d returned from ClusterEnum\n", Type); return(0); } } // finally register the notification event for CLUSTER_CHANGE_CLUSTER_RECONNECT if(lpszClusterName != NULL) // implies we are connecting from a client { Status = RegisterClusterNotify(hChange, CLUSTER_CHANGE_CLUSTER_RECONNECT|CLUSTER_CHANGE_CLUSTER_STATE, Cluster, NOTIFY_KEY_CLUSTER_RECONNECT); if (Status != ERROR_SUCCESS) { fprintf(stderr, "RegisterClusterNotify for CLUSTER_CHANGE_CLUSTER_RECONNECT failed %d\n",Status); } else { fprintf(stderr, "Success registering CLUSTER_CHANGE_CLUSTER_RECONNECT\n"); } } // // Just read out changes forever // printf("Waiting for notification events\n"); while (!_kbhit()) { BufSize = sizeof(Buffer) / sizeof(WCHAR); Status = GetClusterNotify(hChange, &NotifyKey, &Filter, Buffer, &BufSize, INFINITE); if (Status != ERROR_SUCCESS) { fprintf(stderr, "GetClusterNotify failed %d\n", GetLastError()); return(0); } switch (NotifyKey) { case NOTIFY_KEY_ALL: printf("Clusterwide notify: Filter %08lx, Name %ws\n", Filter, Buffer); break; case NOTIFY_KEY_GROUP: printf("Group notify: Filter %08lx, Name %ws\n", Filter, Buffer); break; case NOTIFY_KEY_RESOURCE: printf("Resource notify: Filter %08lx, Name %ws\n", Filter, Buffer); break; case NOTIFY_KEY_NODE: printf("Node notify: Filter %08lx, Name %ws\n", Filter, Buffer); break; case NOTIFY_KEY_REGISTRY: printf("Registry notify: Filter %08lx, Name %ws\n", Filter, Buffer); break; case NOTIFY_KEY_REGISTRY_GROUP: printf("Registry group notify: Filter %08lx, Name %ws\n", Filter, Buffer); break; case NOTIFY_KEY_REGISTRY_RESOURCE: printf("Registry resource notify: Filter %08lx, Name %ws\n", Filter, Buffer); break; case NOTIFY_KEY_CLUSTER_RECONNECT: printf("Cluster Reconnect notify: Filter %08lx, Name %ws\n", Filter, Buffer); break ; default: printf("UNKNOWN NOTIFY KEY %d, Filter %08lx, Name %ws\n", NotifyKey, Filter, Buffer); break; } } // // Close all the open handles // for (i=0; i