windows-nt/Source/XPSP1/NT/base/cluster/clusapi/tnotify.c
2020-09-26 16:20:57 +08:00

401 lines
14 KiB
C

/*++
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 <clustername>\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<NodeHandleCount; i++) {
CloseClusterNode(NodeHandles[i]);
}
for (i=0; i<ResourceHandleCount; i++) {
CloseClusterResource(ResourceHandles[i]);
}
for (i=0; i<GroupHandleCount; i++) {
CloseClusterGroup(GroupHandles[i]);
}
for (i=0; i<RegistryHandleCount; i++) {
ClusterRegCloseKey(RegistryHandles[i]);
}
CloseCluster(Cluster);
//
// Drain out all the handle close events.
//
Sleep(5000);
do {
BufSize = sizeof(Buffer) / sizeof(WCHAR);
Status = GetClusterNotify(hChange,
&NotifyKey,
&Filter,
Buffer,
&BufSize,
0);
if (Status == ERROR_SUCCESS) {
printf("Draining notification NotifyKey = %08lx\n", NotifyKey);
printf(" Filter = %08lx\n", Filter);
printf(" Name = %ws\n", Buffer);
} else {
printf("Draining notifies returned %d\n",Status);
}
} while ( Status == ERROR_SUCCESS );
CloseClusterNotifyPort(hChange);
}