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.
1140 lines
24 KiB
1140 lines
24 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
enum.c
|
|
|
|
Abstract:
|
|
|
|
Server side support for Cluster APIs dealing with enumeration
|
|
|
|
Author:
|
|
|
|
John Vert (jvert) 9-Feb-1996
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#include "apip.h"
|
|
|
|
//
|
|
// Define structure passed to enumeration routine.
|
|
//
|
|
typedef struct _REFOBJECT {
|
|
HDMKEY RootKey;
|
|
LPCWSTR FriendlyName;
|
|
DWORD NameLength;
|
|
LPWSTR NameBuffer;
|
|
OBJECT_TYPE Type;
|
|
} REFOBJECT, *PREFOBJECT;
|
|
|
|
BOOL
|
|
ApipEnumResourceWorker(
|
|
IN PENUM_LIST *pEnum,
|
|
IN PVOID Context2,
|
|
IN PFM_RESOURCE Node,
|
|
IN LPCWSTR Name
|
|
);
|
|
|
|
BOOL
|
|
ApipEnumGroupResourceWorker(
|
|
IN PENUM_LIST *pEnum,
|
|
IN PVOID Context2,
|
|
IN PFM_RESOURCE Node,
|
|
IN LPCWSTR Name
|
|
);
|
|
|
|
BOOL
|
|
ApipEnumNodeWorker(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated,
|
|
IN PNM_NODE Node,
|
|
IN LPCWSTR Name
|
|
);
|
|
|
|
|
|
BOOL
|
|
ApipEnumResTypeWorker(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated,
|
|
IN PFM_RESTYPE ResType,
|
|
IN LPCWSTR Name
|
|
);
|
|
|
|
BOOL
|
|
ApipEnumGroupWorker(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated,
|
|
IN PFM_GROUP Group,
|
|
IN LPCWSTR Name
|
|
);
|
|
|
|
BOOL
|
|
ApipEnumNetworkWorker(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated,
|
|
IN PVOID Object,
|
|
IN LPCWSTR Name
|
|
);
|
|
|
|
DWORD
|
|
ApipEnumInternalNetworks(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated
|
|
);
|
|
|
|
BOOL
|
|
ApipEnumNetworkInterfaceWorker(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated,
|
|
IN PVOID Object,
|
|
IN LPCWSTR Name
|
|
);
|
|
|
|
VOID
|
|
ApipFreeEnum(
|
|
IN PENUM_LIST Enum
|
|
);
|
|
|
|
|
|
|
|
error_status_t
|
|
s_ApiCreateEnum(
|
|
IN handle_t IDL_handle,
|
|
IN DWORD dwType,
|
|
OUT PENUM_LIST *ReturnEnum
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Enumerates all the specified objects and returns the
|
|
list of objects to the caller. The client-side is
|
|
responsible for freeing the allocated memory.
|
|
|
|
Arguments:
|
|
|
|
IDL_handle - RPC binding handle, not used
|
|
|
|
dwType - Supplies the type of objects to be enumerated
|
|
|
|
ReturnEnum - Returns the requested objects.
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS if successful
|
|
|
|
Win32 error code otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD Status;
|
|
DWORD Allocated = 0;
|
|
PENUM_LIST Enum = NULL;
|
|
|
|
//initialize to NULL for failure cases
|
|
*ReturnEnum = NULL;
|
|
|
|
if (dwType != CLUSTER_ENUM_NODE) {
|
|
API_CHECK_INIT();
|
|
}
|
|
|
|
if (dwType & CLUSTER_ENUM_INTERNAL_NETWORK) {
|
|
if ((dwType & ~CLUSTER_ENUM_INTERNAL_NETWORK) != 0) {
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
}
|
|
else {
|
|
if (dwType & ~CLUSTER_ENUM_ALL) {
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
}
|
|
|
|
Allocated = INITIAL_ENUM_LIST_ALLOCATION;
|
|
Enum = MIDL_user_allocate(ENUM_SIZE(Allocated));
|
|
if (Enum == NULL) {
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto ErrorExit;
|
|
}
|
|
Enum->EntryCount = 0;
|
|
|
|
//
|
|
// Enumerate all nodes
|
|
//
|
|
if (dwType & CLUSTER_ENUM_NODE) {
|
|
OmEnumObjects(ObjectTypeNode,
|
|
ApipEnumNodeWorker,
|
|
&Enum,
|
|
&Allocated);
|
|
|
|
}
|
|
|
|
//
|
|
// Enumerate all resource types
|
|
//
|
|
if (dwType & CLUSTER_ENUM_RESTYPE) {
|
|
OmEnumObjects(ObjectTypeResType,
|
|
ApipEnumResTypeWorker,
|
|
&Enum,
|
|
&Allocated);
|
|
}
|
|
|
|
//
|
|
// Enumerate all resources
|
|
//
|
|
if (dwType & CLUSTER_ENUM_RESOURCE) {
|
|
OmEnumObjects(ObjectTypeResource,
|
|
ApipEnumResourceWorker,
|
|
&Enum,
|
|
&Allocated);
|
|
|
|
}
|
|
|
|
//
|
|
// Enumerate all groups
|
|
//
|
|
if (dwType & CLUSTER_ENUM_GROUP) {
|
|
OmEnumObjects(ObjectTypeGroup,
|
|
ApipEnumGroupWorker,
|
|
&Enum,
|
|
&Allocated);
|
|
|
|
}
|
|
|
|
//
|
|
// Enumerate all networks
|
|
//
|
|
if (dwType & CLUSTER_ENUM_NETWORK) {
|
|
OmEnumObjects(ObjectTypeNetwork,
|
|
ApipEnumNetworkWorker,
|
|
&Enum,
|
|
&Allocated);
|
|
}
|
|
|
|
//
|
|
// Enumerate internal networks in highest to lowest priority order.
|
|
//
|
|
if (dwType & CLUSTER_ENUM_INTERNAL_NETWORK) {
|
|
Status = ApipEnumInternalNetworks(&Enum, &Allocated);
|
|
|
|
if (Status != ERROR_SUCCESS) {
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Enumerate all network interfaces
|
|
//
|
|
if (dwType & CLUSTER_ENUM_NETINTERFACE) {
|
|
OmEnumObjects(ObjectTypeNetInterface,
|
|
ApipEnumNetworkInterfaceWorker,
|
|
&Enum,
|
|
&Allocated);
|
|
}
|
|
|
|
*ReturnEnum = Enum;
|
|
return(ERROR_SUCCESS);
|
|
|
|
ErrorExit:
|
|
|
|
if (Enum != NULL) {
|
|
ApipFreeEnum(Enum);
|
|
}
|
|
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
ApipFreeEnum(
|
|
IN PENUM_LIST Enum
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Frees an ENUM_LIST and all of its strings.
|
|
|
|
Arguments:
|
|
|
|
Enum - Supplies the Enum to free.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD i;
|
|
|
|
//
|
|
// Walk through enumeration freeing all the names
|
|
//
|
|
for (i=0; i<Enum->EntryCount; i++) {
|
|
MIDL_user_free(Enum->Entry[i].Name);
|
|
}
|
|
MIDL_user_free(Enum);
|
|
}
|
|
|
|
|
|
VOID
|
|
ApipAddToEnum(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated,
|
|
IN LPCWSTR Name,
|
|
IN DWORD Type
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Common worker callback routine for enumerating objects.
|
|
Adds the specified resource to the list that is being
|
|
built up.
|
|
|
|
Arguments:
|
|
|
|
pEnum - Supplies a pointer to the current enumeration list.
|
|
|
|
pAllocated - Supplies a pointer to a dword specifying the current
|
|
allocation size of the ENUM_LIST.
|
|
|
|
Name - Supplies the name of the object to be added to the ENUM_LIST.
|
|
|
|
A copy of this name will be created by using MIDL_user_allocate.
|
|
|
|
Type - Supplies the object's type
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
PENUM_LIST Enum;
|
|
PENUM_LIST NewEnum;
|
|
DWORD NewAllocated;
|
|
DWORD Index;
|
|
LPWSTR NewName;
|
|
|
|
NewName = MIDL_user_allocate((lstrlenW(Name)+1)*sizeof(WCHAR));
|
|
if (NewName == NULL) {
|
|
ClRtlLogPrint(LOG_CRITICAL, "[API] ApipAddToEnum: No memory for object name\n");
|
|
return;
|
|
}
|
|
lstrcpyW(NewName, Name);
|
|
Enum = *pEnum;
|
|
if (Enum->EntryCount >= *pAllocated) {
|
|
//
|
|
// Need to grow the ENUM_LIST
|
|
//
|
|
NewAllocated = *pAllocated + 8;
|
|
NewEnum = MIDL_user_allocate(ENUM_SIZE(NewAllocated));
|
|
if (NewEnum == NULL) {
|
|
ClRtlLogPrint(LOG_CRITICAL, "[API] ApipAddToEnum: No memory for enum list\n");
|
|
MIDL_user_free(NewName);
|
|
return;
|
|
}
|
|
CopyMemory(NewEnum, Enum, ENUM_SIZE(*pAllocated));
|
|
CL_ASSERT( Enum->EntryCount == NewEnum->EntryCount );
|
|
*pAllocated = NewAllocated;
|
|
*pEnum = NewEnum;
|
|
MIDL_user_free(Enum);
|
|
Enum = NewEnum;
|
|
}
|
|
|
|
//
|
|
// Initialize new entry field.
|
|
//
|
|
Enum->Entry[Enum->EntryCount].Name = NewName;
|
|
Enum->Entry[Enum->EntryCount].Type = Type;
|
|
++Enum->EntryCount;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
ApipEnumResourceWorker(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated,
|
|
IN PFM_RESOURCE Resource,
|
|
IN LPCWSTR Name
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Worker callback routine for the enumeration of resources.
|
|
Adds the specified resource to the list that is being
|
|
built up.
|
|
|
|
Arguments:
|
|
|
|
pEnum - Supplies a pointer to the current enumeration list.
|
|
|
|
pAllocated - Supplies a pointer to a dword specifying the current
|
|
allocation size of the ENUM_LIST.
|
|
|
|
Resource - Supplies the resource to be added to the ENUM_LIST
|
|
|
|
Name - Supplies the resource's name
|
|
|
|
Return Value:
|
|
|
|
TRUE to indicate that enumeration should continue.
|
|
|
|
|
|
--*/
|
|
{
|
|
LPWSTR RealName;
|
|
|
|
RealName = ApipGetObjectName(Resource);
|
|
if (RealName != NULL) {
|
|
ApipAddToEnum(pEnum,
|
|
pAllocated,
|
|
RealName,
|
|
CLUSTER_ENUM_RESOURCE);
|
|
MIDL_user_free( RealName);
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
BOOL
|
|
ApipEnumGroupResourceWorker(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated,
|
|
IN PFM_RESOURCE Resource,
|
|
IN LPCWSTR Name
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Worker callback routine for the enumeration of resources.
|
|
Adds the specified resource to the list that is being
|
|
built up.
|
|
|
|
Arguments:
|
|
|
|
pEnum - Supplies a pointer to the current enumeration list.
|
|
|
|
pAllocated - Supplies a pointer to a dword specifying the current
|
|
allocation size of the ENUM_LIST.
|
|
|
|
Resource - Supplies the resource to be added to the ENUM_LIST
|
|
|
|
Name - Supplies the resource's name
|
|
|
|
Return Value:
|
|
|
|
TRUE to indicate that enumeration should continue.
|
|
|
|
|
|
--*/
|
|
{
|
|
LPWSTR RealName;
|
|
|
|
RealName = ApipGetObjectName(Resource);
|
|
if (RealName != NULL) {
|
|
ApipAddToEnum(pEnum,
|
|
pAllocated,
|
|
RealName,
|
|
CLUSTER_GROUP_ENUM_CONTAINS);
|
|
MIDL_user_free( RealName );
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
BOOL
|
|
ApipEnumNodeWorker(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated,
|
|
IN PNM_NODE Node,
|
|
IN LPCWSTR Name
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Worker callback routine for the enumeration of nodes.
|
|
Adds the specified node to the list that is being
|
|
built up.
|
|
|
|
Arguments:
|
|
|
|
pEnum - Supplies a pointer to the current enumeration list.
|
|
|
|
pAllocated - Supplies a pointer to a dword specifying the current
|
|
allocation size of the ENUM_LIST.
|
|
|
|
Node - Supplies the node to be added to the ENUM_LIST
|
|
|
|
Name - Supplies the node's name
|
|
|
|
Return Value:
|
|
|
|
TRUE to indicate that enumeration should continue.
|
|
|
|
|
|
--*/
|
|
{
|
|
LPCWSTR RealName;
|
|
|
|
RealName = OmObjectName(Node);
|
|
if (RealName != NULL) {
|
|
ApipAddToEnum(pEnum,
|
|
pAllocated,
|
|
RealName,
|
|
CLUSTER_ENUM_NODE);
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
BOOL
|
|
ApipEnumResTypeWorker(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated,
|
|
IN PFM_RESTYPE ResType,
|
|
IN LPCWSTR Name
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Worker callback routine for the enumeration of resource types.
|
|
Adds the specified resource type to the list that is being
|
|
built up.
|
|
|
|
Arguments:
|
|
|
|
pEnum - Supplies a pointer to the current enumeration list.
|
|
|
|
pAllocated - Supplies a pointer to a dword specifying the current
|
|
allocation size of the ENUM_LIST.
|
|
|
|
Node - Supplies the resource type to be added to the ENUM_LIST
|
|
|
|
Name - Supplies the resource type's name
|
|
|
|
Return Value:
|
|
|
|
TRUE to indicate that enumeration should continue.
|
|
|
|
|
|
--*/
|
|
{
|
|
ApipAddToEnum(pEnum,
|
|
pAllocated,
|
|
Name,
|
|
CLUSTER_ENUM_RESTYPE);
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
BOOL
|
|
ApipEnumGroupWorker(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated,
|
|
IN PFM_GROUP Group,
|
|
IN LPCWSTR Name
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Worker callback routine for the enumeration of groups.
|
|
Adds the specified group to the list that is being
|
|
built up.
|
|
|
|
Arguments:
|
|
|
|
pEnum - Supplies a pointer to the current enumeration list.
|
|
|
|
pAllocated - Supplies a pointer to a dword specifying the current
|
|
allocation size of the ENUM_LIST.
|
|
|
|
Group - Supplies the group to be added to the ENUM_LIST
|
|
|
|
Name - Supplies the group's name
|
|
|
|
Return Value:
|
|
|
|
TRUE to indicate that enumeration should continue.
|
|
|
|
|
|
--*/
|
|
{
|
|
LPCWSTR RealName;
|
|
|
|
RealName = OmObjectName(Group);
|
|
if (RealName != NULL) {
|
|
ApipAddToEnum(pEnum,
|
|
pAllocated,
|
|
RealName,
|
|
CLUSTER_ENUM_GROUP);
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
ApipEnumNetworkWorker(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated,
|
|
IN PVOID Object,
|
|
IN LPCWSTR Name
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Worker callback routine for the enumeration of networks.
|
|
Adds the specified network to the list that is being
|
|
built up.
|
|
|
|
Arguments:
|
|
|
|
pEnum - Supplies a pointer to the current enumeration list.
|
|
|
|
pAllocated - Supplies a pointer to a dword specifying the current
|
|
allocation size of the ENUM_LIST.
|
|
|
|
Object - Supplies the object to be added to the ENUM_LIST
|
|
|
|
Name - Supplies the network's name
|
|
|
|
Return Value:
|
|
|
|
TRUE to indicate that enumeration should continue.
|
|
|
|
|
|
--*/
|
|
{
|
|
LPWSTR RealName;
|
|
|
|
RealName = ApipGetObjectName(Object);
|
|
if (RealName != NULL) {
|
|
ApipAddToEnum(pEnum,
|
|
pAllocated,
|
|
RealName,
|
|
CLUSTER_ENUM_NETWORK);
|
|
MIDL_user_free( RealName );
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
DWORD
|
|
ApipEnumInternalNetworks(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Enumerates all networks used for internal communication.
|
|
|
|
Arguments:
|
|
|
|
pEnum - Supplies a pointer to the current enumeration list.
|
|
|
|
pAllocated - Supplies a pointer to a dword specifying the current
|
|
allocation size of the ENUM_LIST.
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS if successful
|
|
|
|
Win32 error code otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD Status;
|
|
DWORD NetworkCount;
|
|
PNM_NETWORK *NetworkList;
|
|
DWORD i;
|
|
LPWSTR RealName;
|
|
|
|
|
|
Status = NmEnumInternalNetworks(&NetworkCount, &NetworkList);
|
|
|
|
if (Status != ERROR_SUCCESS) {
|
|
return(Status);
|
|
}
|
|
|
|
for (i=0; i<NetworkCount; i++) {
|
|
RealName = ApipGetObjectName(NetworkList[i]);
|
|
|
|
if (RealName != NULL) {
|
|
ApipAddToEnum(pEnum,
|
|
pAllocated,
|
|
RealName,
|
|
(DWORD) CLUSTER_ENUM_INTERNAL_NETWORK);
|
|
MIDL_user_free( RealName );
|
|
}
|
|
|
|
OmDereferenceObject(NetworkList[i]);
|
|
}
|
|
|
|
if (NetworkList != NULL) {
|
|
LocalFree(NetworkList);
|
|
}
|
|
|
|
return(ERROR_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
BOOL
|
|
ApipEnumNetworkInterfaceWorker(
|
|
IN PENUM_LIST *pEnum,
|
|
IN DWORD *pAllocated,
|
|
IN PVOID Object,
|
|
IN LPCWSTR Name
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Worker callback routine for the enumeration of network interfaces.
|
|
Adds the specified network interface to the list that is being
|
|
built up.
|
|
|
|
Arguments:
|
|
|
|
pEnum - Supplies a pointer to the current enumeration list.
|
|
|
|
pAllocated - Supplies a pointer to a dword specifying the current
|
|
allocation size of the ENUM_LIST.
|
|
|
|
Object - Supplies the object to be added to the ENUM_LIST
|
|
|
|
Name - Supplies the network interface's name
|
|
|
|
Return Value:
|
|
|
|
TRUE to indicate that enumeration should continue.
|
|
|
|
|
|
--*/
|
|
{
|
|
LPWSTR RealName;
|
|
|
|
RealName = ApipGetObjectName(Object);
|
|
if (RealName != NULL) {
|
|
ApipAddToEnum(pEnum,
|
|
pAllocated,
|
|
RealName,
|
|
CLUSTER_ENUM_NETINTERFACE);
|
|
MIDL_user_free( RealName );
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
error_status_t
|
|
s_ApiCreateNodeEnum(
|
|
IN HNODE_RPC hNode,
|
|
IN DWORD dwType,
|
|
OUT PENUM_LIST *ReturnEnum
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Enumerates all the resource objects contained in the specified
|
|
node and returns them to the caller. The client-side is
|
|
responsible for freeing the allocated memory.
|
|
|
|
Arguments:
|
|
|
|
hNode - Supplies the node to be enumerated
|
|
|
|
dwType - Supplies a bitmask of the type of properties to be
|
|
enumerated.
|
|
|
|
ReturnEnum - Returns the requested objects.
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS if successful
|
|
|
|
Win32 error code otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD Status;
|
|
DWORD Allocated = 0;
|
|
PENUM_LIST Enum = NULL;
|
|
PNM_INTERFACE * InterfaceList;
|
|
DWORD InterfaceCount;
|
|
PNM_NODE Node;
|
|
DWORD i;
|
|
|
|
|
|
API_CHECK_INIT();
|
|
|
|
VALIDATE_NODE_EXISTS(Node, hNode);
|
|
|
|
Allocated = INITIAL_ENUM_LIST_ALLOCATION;
|
|
Enum = MIDL_user_allocate(ENUM_SIZE(Allocated));
|
|
|
|
if (Enum == NULL) {
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Enum->EntryCount = 0;
|
|
|
|
if (dwType & CLUSTER_NODE_ENUM_NETINTERFACES) {
|
|
Status = NmEnumNodeInterfaces(
|
|
Node,
|
|
&InterfaceCount,
|
|
&InterfaceList
|
|
);
|
|
|
|
if (Status != ERROR_SUCCESS) {
|
|
goto ErrorExit;
|
|
}
|
|
|
|
for (i=0; i<InterfaceCount; i++) {
|
|
ApipAddToEnum(&Enum,
|
|
&Allocated,
|
|
OmObjectName(InterfaceList[i]),
|
|
CLUSTER_NODE_ENUM_NETINTERFACES);
|
|
OmDereferenceObject(InterfaceList[i]);
|
|
}
|
|
|
|
if (InterfaceList != NULL) {
|
|
LocalFree(InterfaceList);
|
|
}
|
|
}
|
|
|
|
*ReturnEnum = Enum;
|
|
|
|
return(ERROR_SUCCESS);
|
|
|
|
ErrorExit:
|
|
if (Enum != NULL) {
|
|
ApipFreeEnum(Enum);
|
|
}
|
|
|
|
*ReturnEnum = NULL;
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
|
error_status_t
|
|
s_ApiCreateGroupResourceEnum(
|
|
IN HGROUP_RPC hGroup,
|
|
IN DWORD dwType,
|
|
OUT PENUM_LIST *ReturnEnum
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Enumerates all the resource objects contained in the specified
|
|
group and returns them to the caller. The client-side is
|
|
responsible for freeing the allocated memory.
|
|
|
|
Arguments:
|
|
|
|
hGroup - Supplies the group to be enumerated
|
|
|
|
dwType - Supplies a bitmask of the type of properties to be
|
|
enumerated. Currently defined types include
|
|
|
|
CLUSTER_GROUP_ENUM_CONTAINS - All resources contained in the specified
|
|
group
|
|
|
|
CLUSTER_GROUP_ENUM_NODES - All nodes in the specified group's preferred
|
|
owner list.
|
|
|
|
ReturnEnum - Returns the requested objects.
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS if successful
|
|
|
|
Win32 error code otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD Status;
|
|
DWORD Allocated = 0;
|
|
PENUM_LIST Enum = NULL;
|
|
PFM_GROUP Group;
|
|
|
|
API_CHECK_INIT();
|
|
|
|
VALIDATE_GROUP_EXISTS(Group, hGroup);
|
|
|
|
Allocated = INITIAL_ENUM_LIST_ALLOCATION;
|
|
Enum = MIDL_user_allocate(ENUM_SIZE(Allocated));
|
|
if (Enum == NULL) {
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto ErrorExit;
|
|
}
|
|
Enum->EntryCount = 0;
|
|
|
|
//
|
|
// Enumerate all contained resources
|
|
//
|
|
if (dwType & CLUSTER_GROUP_ENUM_CONTAINS) {
|
|
//
|
|
// Enumerate all resources for the Group.
|
|
//
|
|
Status = FmEnumerateGroupResources(Group,
|
|
ApipEnumGroupResourceWorker,
|
|
&Enum,
|
|
&Allocated);
|
|
if ( Status != ERROR_SUCCESS ) {
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
if (dwType & CLUSTER_GROUP_ENUM_NODES) {
|
|
LPWSTR Buffer=NULL;
|
|
DWORD BufferSize=0;
|
|
DWORD DataSize=0;
|
|
DWORD i;
|
|
HDMKEY GroupKey;
|
|
LPCWSTR Next;
|
|
PNM_NODE Node;
|
|
|
|
//
|
|
// Enumerate all preferred nodes for the group.
|
|
// Just get this data right out of the registry.
|
|
//
|
|
GroupKey = DmOpenKey(DmGroupsKey,
|
|
OmObjectId(Group),
|
|
KEY_READ);
|
|
if (GroupKey == NULL) {
|
|
Status = GetLastError();
|
|
goto ErrorExit;
|
|
}
|
|
Status = DmQueryMultiSz(GroupKey,
|
|
CLUSREG_NAME_GRP_PREFERRED_OWNERS,
|
|
&Buffer,
|
|
&BufferSize,
|
|
&DataSize);
|
|
DmCloseKey(GroupKey);
|
|
if (Status != ERROR_FILE_NOT_FOUND) {
|
|
if (Status != ERROR_SUCCESS) {
|
|
//
|
|
// Chittur Subbaraman (chitturs) - 10/05/98
|
|
// Fix memory leak
|
|
//
|
|
LocalFree(Buffer);
|
|
goto ErrorExit;
|
|
}
|
|
for (i=0; ; i++) {
|
|
Next = ClRtlMultiSzEnum(Buffer, DataSize/sizeof(WCHAR), i);
|
|
if (Next == NULL) {
|
|
Status = ERROR_SUCCESS;
|
|
break;
|
|
}
|
|
Node = OmReferenceObjectById(ObjectTypeNode, Next);
|
|
if (Node != NULL) {
|
|
ApipAddToEnum(&Enum,
|
|
&Allocated,
|
|
OmObjectName(Node),
|
|
CLUSTER_GROUP_ENUM_NODES);
|
|
OmDereferenceObject(Node);
|
|
}
|
|
|
|
}
|
|
}
|
|
//
|
|
// Chittur Subbaraman (chitturs) - 10/05/98
|
|
// Fix memory leak
|
|
//
|
|
LocalFree(Buffer);
|
|
}
|
|
|
|
*ReturnEnum = Enum;
|
|
return(ERROR_SUCCESS);
|
|
|
|
ErrorExit:
|
|
if (Enum != NULL) {
|
|
ApipFreeEnum(Enum);
|
|
}
|
|
|
|
*ReturnEnum = NULL;
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
|
error_status_t
|
|
s_ApiCreateNetworkEnum(
|
|
IN HNETWORK_RPC hNetwork,
|
|
IN DWORD dwType,
|
|
OUT PENUM_LIST *ReturnEnum
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Enumerates all the interface objects contained in the specified
|
|
network and returns them to the caller. The client-side is
|
|
responsible for freeing the allocated memory.
|
|
|
|
Arguments:
|
|
|
|
hNetwork - Supplies the network to be enumerated
|
|
|
|
dwType - Supplies a bitmask of the type of properties to be
|
|
enumerated.
|
|
|
|
ReturnEnum - Returns the requested objects.
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS if successful
|
|
|
|
Win32 error code otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD Status;
|
|
DWORD Allocated = 0;
|
|
PENUM_LIST Enum = NULL;
|
|
PNM_INTERFACE * InterfaceList;
|
|
DWORD InterfaceCount;
|
|
PNM_NETWORK Network;
|
|
DWORD i;
|
|
|
|
|
|
API_CHECK_INIT();
|
|
|
|
VALIDATE_NETWORK_EXISTS(Network, hNetwork);
|
|
|
|
Allocated = INITIAL_ENUM_LIST_ALLOCATION;
|
|
Enum = MIDL_user_allocate(ENUM_SIZE(Allocated));
|
|
|
|
if (Enum == NULL) {
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Enum->EntryCount = 0;
|
|
|
|
if (dwType & CLUSTER_NETWORK_ENUM_NETINTERFACES) {
|
|
Status = NmEnumNetworkInterfaces(
|
|
Network,
|
|
&InterfaceCount,
|
|
&InterfaceList
|
|
);
|
|
|
|
if (Status != ERROR_SUCCESS) {
|
|
goto ErrorExit;
|
|
}
|
|
|
|
for (i=0; i<InterfaceCount; i++) {
|
|
ApipAddToEnum(&Enum,
|
|
&Allocated,
|
|
OmObjectName(InterfaceList[i]),
|
|
CLUSTER_NETWORK_ENUM_NETINTERFACES);
|
|
OmDereferenceObject(InterfaceList[i]);
|
|
}
|
|
|
|
if (InterfaceList != NULL) {
|
|
LocalFree(InterfaceList);
|
|
}
|
|
}
|
|
|
|
*ReturnEnum = Enum;
|
|
|
|
return(ERROR_SUCCESS);
|
|
|
|
ErrorExit:
|
|
if (Enum != NULL) {
|
|
ApipFreeEnum(Enum);
|
|
}
|
|
|
|
*ReturnEnum = NULL;
|
|
return(Status);
|
|
|
|
}
|
|
|
|
LPWSTR
|
|
ApipGetObjectName(
|
|
IN PVOID Object
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Allocates a string and fills in the object's name.
|
|
|
|
Arguments:
|
|
|
|
Object - A pointer to the object to get its name.
|
|
|
|
Return Value:
|
|
|
|
A pointer to a WSTR that contains the user-friendly name of the object.
|
|
NULL on failure - use GetLastError to get the Win32 error code.
|
|
|
|
--*/
|
|
|
|
{
|
|
LPWSTR Name;
|
|
DWORD NameSize;
|
|
|
|
if ( OmObjectName(Object) == NULL ) {
|
|
Name = MIDL_user_allocate(1 * sizeof(WCHAR));
|
|
if ( Name != NULL ) {
|
|
*Name = (WCHAR)0;
|
|
} else {
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
}
|
|
} else {
|
|
NameSize = lstrlenW(OmObjectName(Object));
|
|
Name = MIDL_user_allocate((NameSize + 1) * sizeof(WCHAR));
|
|
if ( Name != NULL ) {
|
|
lstrcpyW( Name, OmObjectName(Object) );
|
|
} else {
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
}
|
|
}
|
|
|
|
return(Name);
|
|
|
|
} // ApipGetObjectName
|
|
|