904 lines
24 KiB
C
904 lines
24 KiB
C
/*++
|
||
|
||
Copyright (c) 1996 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
ioctl.c
|
||
|
||
Abstract:
|
||
|
||
Implements resource and resource type IOCTL interfaces in
|
||
the CLUSAPI.
|
||
|
||
Author:
|
||
|
||
John Vert (jvert) 10/9/1996
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
#include "clusapip.h"
|
||
|
||
|
||
DWORD
|
||
WINAPI
|
||
ClusterResourceControl(
|
||
IN HRESOURCE hResource,
|
||
IN OPTIONAL HNODE hHostNode,
|
||
IN DWORD dwControlCode,
|
||
IN LPVOID lpInBuffer,
|
||
IN DWORD nInBufferSize,
|
||
OUT LPVOID lpOutBuffer,
|
||
IN DWORD nOutBufferSize,
|
||
OUT LPDWORD lpBytesReturned
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Provides for arbitrary communication and control between an application
|
||
and a specific instance of a resource.
|
||
|
||
Arguments:
|
||
|
||
hResource - Supplies a handle to the resource to be controlled.
|
||
|
||
hHostNode - Supplies a handle to the node on which the resource
|
||
control should be delivered. If this is NULL, the node where
|
||
the resource is online is used.
|
||
|
||
dwControlCode- Supplies the control code that defines the
|
||
structure and action of the resource control.
|
||
Values of dwControlCode between 0 and 0x10000000 are reserved
|
||
for future definition and use by Microsoft. All other values
|
||
are available for use by ISVs.
|
||
|
||
lpInBuffer- Supplies a pointer to the input buffer to be passed
|
||
to the resource.
|
||
|
||
nInBufferSize- Supplies the size, in bytes, of the data pointed
|
||
to by lpInBuffer.
|
||
|
||
lpOutBuffer- Supplies a pointer to the output buffer to be
|
||
filled in by the resource.
|
||
|
||
nOutBufferSize- Supplies the size, in bytes, of the available
|
||
space pointed to by lpOutBuffer.
|
||
|
||
lpBytesReturned - Returns the number of bytes of lpOutBuffer
|
||
actually filled in by the resource.
|
||
|
||
Return Value:
|
||
|
||
ERROR_SUCCESS if successful
|
||
|
||
Win32 error code otherwise
|
||
|
||
--*/
|
||
|
||
{
|
||
PCRESOURCE Resource;
|
||
HNODE_RPC hDestNode;
|
||
DWORD Status;
|
||
DWORD Required;
|
||
PVOID Buffer;
|
||
DWORD Dummy;
|
||
DWORD BytesReturned;
|
||
|
||
Buffer = lpOutBuffer;
|
||
if ((Buffer == NULL) &&
|
||
(nOutBufferSize == 0)) {
|
||
Buffer = &Dummy;
|
||
}
|
||
|
||
Resource = (PCRESOURCE)hResource;
|
||
if (ARGUMENT_PRESENT(hHostNode)) {
|
||
hDestNode = ((PCNODE)hHostNode)->hNode;
|
||
WRAP(Status,
|
||
(ApiNodeResourceControl(Resource->hResource,
|
||
hDestNode,
|
||
dwControlCode,
|
||
lpInBuffer,
|
||
nInBufferSize,
|
||
Buffer,
|
||
nOutBufferSize,
|
||
&BytesReturned,
|
||
&Required)),
|
||
Resource->Cluster);
|
||
} else {
|
||
|
||
WRAP(Status,
|
||
(ApiResourceControl(Resource->hResource,
|
||
dwControlCode,
|
||
lpInBuffer,
|
||
nInBufferSize,
|
||
Buffer,
|
||
nOutBufferSize,
|
||
&BytesReturned,
|
||
&Required)),
|
||
Resource->Cluster);
|
||
}
|
||
if ( (Status == ERROR_SUCCESS) ||
|
||
(Status == ERROR_MORE_DATA) ) {
|
||
if ( (Status == ERROR_MORE_DATA) &&
|
||
(lpOutBuffer == NULL) ) {
|
||
Status = ERROR_SUCCESS;
|
||
}
|
||
if ( !BytesReturned ) {
|
||
BytesReturned = Required;
|
||
}
|
||
}
|
||
|
||
if ( ARGUMENT_PRESENT(lpBytesReturned) ) {
|
||
*lpBytesReturned = BytesReturned;
|
||
} else {
|
||
if ( (Status == ERROR_SUCCESS) &&
|
||
(BytesReturned > nOutBufferSize) ) {
|
||
Status = ERROR_MORE_DATA;
|
||
}
|
||
}
|
||
|
||
return(Status);
|
||
|
||
}
|
||
|
||
|
||
DWORD
|
||
WINAPI
|
||
ClusterResourceTypeControl(
|
||
IN HCLUSTER hCluster,
|
||
IN LPCWSTR lpszResourceTypeName,
|
||
IN OPTIONAL HNODE hHostNode,
|
||
IN DWORD dwControlCode,
|
||
IN LPVOID lpInBuffer,
|
||
IN DWORD nInBufferSize,
|
||
OUT LPVOID lpOutBuffer,
|
||
IN DWORD nOutBufferSize,
|
||
OUT LPDWORD lpBytesReturned
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Provides for arbitrary communication and control between an application
|
||
and a specific instance of a resource type.
|
||
|
||
Arguments:
|
||
|
||
lpszResourceTypename - Supplies the name of the resource type to be
|
||
controlled.
|
||
|
||
hHostNode - Supplies a handle to the node on which the resource type
|
||
control should be delivered. If this is NULL, the node where
|
||
the application is bound performs the request.
|
||
|
||
dwControlCode- Supplies the control code that defines the
|
||
structure and action of the resource type control.
|
||
Values of dwControlCode between 0 and 0x10000000 are reserved
|
||
for future definition and use by Microsoft. All other values
|
||
are available for use by ISVs
|
||
|
||
lpInBuffer- Supplies a pointer to the input buffer to be passed
|
||
to the resource type.
|
||
|
||
nInBufferSize- Supplies the size, in bytes, of the data pointed
|
||
to by lpInBuffer.
|
||
|
||
lpOutBuffer- Supplies a pointer to the output buffer to be
|
||
filled in by the resource type.
|
||
|
||
nOutBufferSize- Supplies the size, in bytes, of the available
|
||
space pointed to by lpOutBuffer.
|
||
|
||
lpBytesReturned - Returns the number of bytes of lpOutBuffer
|
||
actually filled in by the resource type.
|
||
|
||
Return Value:
|
||
|
||
ERROR_SUCCESS if successful
|
||
|
||
Win32 error code otherwise
|
||
|
||
--*/
|
||
|
||
{
|
||
PCLUSTER Cluster;
|
||
HNODE_RPC hDestNode;
|
||
DWORD Status;
|
||
DWORD Required;
|
||
PVOID Buffer;
|
||
DWORD Dummy;
|
||
DWORD BytesReturned;
|
||
|
||
Buffer = lpOutBuffer;
|
||
if ((Buffer == NULL) &&
|
||
(nOutBufferSize == 0)) {
|
||
Buffer = &Dummy;
|
||
}
|
||
|
||
Cluster = (PCLUSTER)hCluster;
|
||
if (ARGUMENT_PRESENT(hHostNode)) {
|
||
hDestNode = ((PCNODE)hHostNode)->hNode;
|
||
WRAP(Status,
|
||
(ApiNodeResourceTypeControl(Cluster->hCluster,
|
||
lpszResourceTypeName,
|
||
hDestNode,
|
||
dwControlCode,
|
||
lpInBuffer,
|
||
nInBufferSize,
|
||
Buffer,
|
||
nOutBufferSize,
|
||
&BytesReturned,
|
||
&Required)),
|
||
Cluster);
|
||
} else {
|
||
WRAP(Status,
|
||
(ApiResourceTypeControl(Cluster->hCluster,
|
||
lpszResourceTypeName,
|
||
dwControlCode,
|
||
lpInBuffer,
|
||
nInBufferSize,
|
||
Buffer,
|
||
nOutBufferSize,
|
||
&BytesReturned,
|
||
&Required)),
|
||
Cluster);
|
||
}
|
||
|
||
if ( (Status == ERROR_SUCCESS) ||
|
||
(Status == ERROR_MORE_DATA) ) {
|
||
if ( (Status == ERROR_MORE_DATA) &&
|
||
(lpOutBuffer == NULL) ) {
|
||
Status = ERROR_SUCCESS;
|
||
}
|
||
if ( !BytesReturned ) {
|
||
BytesReturned = Required;
|
||
}
|
||
}
|
||
|
||
if ( ARGUMENT_PRESENT(lpBytesReturned) ) {
|
||
*lpBytesReturned = BytesReturned;
|
||
} else {
|
||
if ( (Status == ERROR_SUCCESS) &&
|
||
(BytesReturned > nOutBufferSize) ) {
|
||
Status = ERROR_MORE_DATA;
|
||
}
|
||
}
|
||
|
||
return(Status);
|
||
|
||
}
|
||
|
||
|
||
DWORD
|
||
WINAPI
|
||
ClusterGroupControl(
|
||
IN HGROUP hGroup,
|
||
IN OPTIONAL HNODE hHostNode,
|
||
IN DWORD dwControlCode,
|
||
IN LPVOID lpInBuffer,
|
||
IN DWORD nInBufferSize,
|
||
OUT LPVOID lpOutBuffer,
|
||
IN DWORD nOutBufferSize,
|
||
OUT LPDWORD lpBytesReturned
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Provides for arbitrary communication and control between an application
|
||
and a specific instance of a group.
|
||
|
||
Arguments:
|
||
|
||
hGroup - Supplies a handle to the group to be controlled.
|
||
|
||
hHostNode - Supplies a handle to the node on which the group
|
||
control should be delivered. If this is NULL, the node where
|
||
the group is owned is used.
|
||
|
||
dwControlCode- Supplies the control code that defines the
|
||
structure and action of the resource control.
|
||
Values of dwControlCode between 0 and 0x10000000 are reserved
|
||
for future definition and use by Microsoft. All other values
|
||
are available for use by ISVs.
|
||
|
||
lpInBuffer- Supplies a pointer to the input buffer to be passed
|
||
to the group.
|
||
|
||
nInBufferSize- Supplies the size, in bytes, of the data pointed
|
||
to by lpInBuffer.
|
||
|
||
lpOutBuffer- Supplies a pointer to the output buffer to be
|
||
filled in by the group.
|
||
|
||
nOutBufferSize- Supplies the size, in bytes, of the available
|
||
space pointed to by lpOutBuffer.
|
||
|
||
lpBytesReturned - Returns the number of bytes of lpOutBuffer
|
||
actually filled in by the resource.
|
||
|
||
Return Value:
|
||
|
||
ERROR_SUCCESS if successful
|
||
|
||
Win32 error code otherwise
|
||
|
||
--*/
|
||
|
||
{
|
||
PCGROUP Group;
|
||
HNODE_RPC hDestNode;
|
||
DWORD Status;
|
||
DWORD Required;
|
||
PVOID Buffer;
|
||
DWORD Dummy;
|
||
DWORD BytesReturned;
|
||
|
||
Buffer = lpOutBuffer;
|
||
if ((Buffer == NULL) &&
|
||
(nOutBufferSize == 0)) {
|
||
Buffer = &Dummy;
|
||
}
|
||
|
||
Group = (PCGROUP)hGroup;
|
||
if (ARGUMENT_PRESENT(hHostNode)) {
|
||
hDestNode = ((PCNODE)hHostNode)->hNode;
|
||
WRAP(Status,
|
||
(ApiNodeGroupControl(Group->hGroup,
|
||
hDestNode,
|
||
dwControlCode,
|
||
lpInBuffer,
|
||
nInBufferSize,
|
||
Buffer,
|
||
nOutBufferSize,
|
||
&BytesReturned,
|
||
&Required)),
|
||
Group->Cluster);
|
||
} else {
|
||
|
||
WRAP(Status,
|
||
(ApiGroupControl(Group->hGroup,
|
||
dwControlCode,
|
||
lpInBuffer,
|
||
nInBufferSize,
|
||
Buffer,
|
||
nOutBufferSize,
|
||
&BytesReturned,
|
||
&Required)),
|
||
Group->Cluster);
|
||
}
|
||
if ( (Status == ERROR_SUCCESS) ||
|
||
(Status == ERROR_MORE_DATA) ) {
|
||
if ( (Status == ERROR_MORE_DATA) &&
|
||
(lpOutBuffer == NULL) ) {
|
||
Status = ERROR_SUCCESS;
|
||
}
|
||
if ( !BytesReturned ) {
|
||
BytesReturned = Required;
|
||
}
|
||
}
|
||
|
||
if ( ARGUMENT_PRESENT(lpBytesReturned) ) {
|
||
*lpBytesReturned = BytesReturned;
|
||
} else {
|
||
if ( (Status == ERROR_SUCCESS) &&
|
||
(BytesReturned > nOutBufferSize) ) {
|
||
Status = ERROR_MORE_DATA;
|
||
}
|
||
}
|
||
|
||
return(Status);
|
||
|
||
}
|
||
|
||
|
||
DWORD
|
||
WINAPI
|
||
ClusterNodeControl(
|
||
IN HNODE hNode,
|
||
IN OPTIONAL HNODE hHostNode,
|
||
IN DWORD dwControlCode,
|
||
IN LPVOID lpInBuffer,
|
||
IN DWORD nInBufferSize,
|
||
OUT LPVOID lpOutBuffer,
|
||
IN DWORD nOutBufferSize,
|
||
OUT LPDWORD lpBytesReturned
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Provides for arbitrary communication and control between an application
|
||
and a specific instance of a node.
|
||
|
||
Arguments:
|
||
|
||
hNode - Supplies a handle to the node to be controlled.
|
||
|
||
hHostNode - Supplies a handle to the node on which the node
|
||
control should be delivered. If this is NULL, the node where
|
||
the application is bound performs the request.
|
||
|
||
dwControlCode- Supplies the control code that defines the
|
||
structure and action of the resource control.
|
||
Values of dwControlCode between 0 and 0x10000000 are reserved
|
||
for future definition and use by Microsoft. All other values
|
||
are available for use by ISVs.
|
||
|
||
lpInBuffer- Supplies a pointer to the input buffer to be passed
|
||
to the node.
|
||
|
||
nInBufferSize- Supplies the size, in bytes, of the data pointed
|
||
to by lpInBuffer.
|
||
|
||
lpOutBuffer- Supplies a pointer to the output buffer to be
|
||
filled in by the node.
|
||
|
||
nOutBufferSize- Supplies the size, in bytes, of the available
|
||
space pointed to by lpOutBuffer.
|
||
|
||
lpBytesReturned - Returns the number of bytes of lpOutBuffer
|
||
actually filled in by the node.
|
||
|
||
Return Value:
|
||
|
||
ERROR_SUCCESS if successful
|
||
|
||
Win32 error code otherwise
|
||
|
||
--*/
|
||
|
||
{
|
||
PCNODE Node;
|
||
HNODE_RPC hDestNode;
|
||
DWORD Status;
|
||
DWORD Required;
|
||
PVOID Buffer;
|
||
DWORD Dummy;
|
||
DWORD BytesReturned;
|
||
|
||
Buffer = lpOutBuffer;
|
||
if ((Buffer == NULL) &&
|
||
(nOutBufferSize == 0)) {
|
||
Buffer = &Dummy;
|
||
}
|
||
|
||
Node = (PCNODE)hNode;
|
||
if (ARGUMENT_PRESENT(hHostNode)) {
|
||
hDestNode = ((PCNODE)hHostNode)->hNode;
|
||
WRAP(Status,
|
||
(ApiNodeNodeControl(Node->hNode,
|
||
hDestNode,
|
||
dwControlCode,
|
||
lpInBuffer,
|
||
nInBufferSize,
|
||
Buffer,
|
||
nOutBufferSize,
|
||
&BytesReturned,
|
||
&Required)),
|
||
Node->Cluster);
|
||
} else {
|
||
|
||
WRAP(Status,
|
||
(ApiNodeControl(Node->hNode,
|
||
dwControlCode,
|
||
lpInBuffer,
|
||
nInBufferSize,
|
||
Buffer,
|
||
nOutBufferSize,
|
||
&BytesReturned,
|
||
&Required)),
|
||
Node->Cluster);
|
||
}
|
||
if ( (Status == ERROR_SUCCESS) ||
|
||
(Status == ERROR_MORE_DATA) ) {
|
||
if ( (Status == ERROR_MORE_DATA) &&
|
||
(lpOutBuffer == NULL) ) {
|
||
Status = ERROR_SUCCESS;
|
||
}
|
||
if ( !BytesReturned ) {
|
||
BytesReturned = Required;
|
||
}
|
||
}
|
||
|
||
if ( ARGUMENT_PRESENT(lpBytesReturned) ) {
|
||
*lpBytesReturned = BytesReturned;
|
||
} else {
|
||
if ( (Status == ERROR_SUCCESS) &&
|
||
(BytesReturned > nOutBufferSize) ) {
|
||
Status = ERROR_MORE_DATA;
|
||
}
|
||
}
|
||
|
||
return(Status);
|
||
|
||
}
|
||
|
||
|
||
DWORD
|
||
WINAPI
|
||
ClusterNetworkControl(
|
||
IN HNETWORK hNetwork,
|
||
IN OPTIONAL HNODE hHostNode,
|
||
IN DWORD dwControlCode,
|
||
IN LPVOID lpInBuffer,
|
||
IN DWORD nInBufferSize,
|
||
OUT LPVOID lpOutBuffer,
|
||
IN DWORD nOutBufferSize,
|
||
OUT LPDWORD lpBytesReturned
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Provides for arbitrary communication and control between an application
|
||
and a specific instance of a network.
|
||
|
||
Arguments:
|
||
|
||
hNetwork - Supplies a handle to the network to be controlled.
|
||
|
||
hHostNode - Supplies a handle to the node on which the node
|
||
control should be delivered. If this is NULL, the node where
|
||
the application is bound performs the request.
|
||
|
||
dwControlCode- Supplies the control code that defines the
|
||
structure and action of the resource control.
|
||
Values of dwControlCode between 0 and 0x10000000 are reserved
|
||
for future definition and use by Microsoft. All other values
|
||
are available for use by ISVs.
|
||
|
||
lpInBuffer- Supplies a pointer to the input buffer to be passed
|
||
to the network.
|
||
|
||
nInBufferSize- Supplies the size, in bytes, of the data pointed
|
||
to by lpInBuffer.
|
||
|
||
lpOutBuffer- Supplies a pointer to the output buffer to be
|
||
filled in by the network.
|
||
|
||
nOutBufferSize- Supplies the size, in bytes, of the available
|
||
space pointed to by lpOutBuffer.
|
||
|
||
lpBytesReturned - Returns the number of bytes of lpOutBuffer
|
||
actually filled in by the network.
|
||
|
||
Return Value:
|
||
|
||
ERROR_SUCCESS if successful
|
||
|
||
Win32 error code otherwise
|
||
|
||
--*/
|
||
|
||
{
|
||
PCNETWORK Network;
|
||
HNODE_RPC hDestNode;
|
||
DWORD Status;
|
||
DWORD Required;
|
||
PVOID Buffer;
|
||
DWORD Dummy;
|
||
DWORD BytesReturned = 0;
|
||
|
||
Buffer = lpOutBuffer;
|
||
if ((Buffer == NULL) && (nOutBufferSize == 0)) {
|
||
Buffer = &Dummy;
|
||
}
|
||
|
||
Network = (PCNETWORK)hNetwork;
|
||
|
||
//
|
||
// another node was specified so redirect the request to it
|
||
//
|
||
|
||
if (ARGUMENT_PRESENT(hHostNode)) {
|
||
|
||
hDestNode = ((PCNODE)hHostNode)->hNode;
|
||
WRAP(Status,
|
||
(ApiNodeNetworkControl(Network->hNetwork,
|
||
hDestNode,
|
||
dwControlCode,
|
||
lpInBuffer,
|
||
nInBufferSize,
|
||
Buffer,
|
||
nOutBufferSize,
|
||
&BytesReturned,
|
||
&Required)),
|
||
Network->Cluster);
|
||
} else {
|
||
|
||
WRAP(Status,
|
||
(ApiNetworkControl(Network->hNetwork,
|
||
dwControlCode,
|
||
lpInBuffer,
|
||
nInBufferSize,
|
||
Buffer,
|
||
nOutBufferSize,
|
||
&BytesReturned,
|
||
&Required)),
|
||
Network->Cluster);
|
||
}
|
||
|
||
if ( (Status == ERROR_SUCCESS) || (Status == ERROR_MORE_DATA) ) {
|
||
|
||
if ( (Status == ERROR_MORE_DATA) && (lpOutBuffer == NULL) ) {
|
||
Status = ERROR_SUCCESS;
|
||
}
|
||
|
||
if ( !BytesReturned ) {
|
||
BytesReturned = Required;
|
||
}
|
||
}
|
||
|
||
if ( ARGUMENT_PRESENT(lpBytesReturned) ) {
|
||
*lpBytesReturned = BytesReturned;
|
||
} else {
|
||
if ( (Status == ERROR_SUCCESS) &&
|
||
(BytesReturned > nOutBufferSize) ) {
|
||
Status = ERROR_MORE_DATA;
|
||
}
|
||
}
|
||
|
||
return(Status);
|
||
}
|
||
|
||
|
||
DWORD
|
||
WINAPI
|
||
ClusterNetInterfaceControl(
|
||
IN HNETINTERFACE hNetInterface,
|
||
IN OPTIONAL HNODE hHostNode,
|
||
IN DWORD dwControlCode,
|
||
IN LPVOID lpInBuffer,
|
||
IN DWORD nInBufferSize,
|
||
OUT LPVOID lpOutBuffer,
|
||
IN DWORD nOutBufferSize,
|
||
OUT LPDWORD lpBytesReturned
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Provides for arbitrary communication and control between an application
|
||
and a specific instance of a network interface.
|
||
|
||
Arguments:
|
||
|
||
hNetInterface - Supplies a handle to the netinterface to be controlled.
|
||
|
||
hHostNode - Supplies a handle to the node on which the node
|
||
control should be delivered. If this is NULL, the node where
|
||
the application is bound performs the request.
|
||
|
||
dwControlCode- Supplies the control code that defines the
|
||
structure and action of the resource control.
|
||
Values of dwControlCode between 0 and 0x10000000 are reserved
|
||
for future definition and use by Microsoft. All other values
|
||
are available for use by ISVs.
|
||
|
||
lpInBuffer- Supplies a pointer to the input buffer to be passed
|
||
to the network.
|
||
|
||
nInBufferSize- Supplies the size, in bytes, of the data pointed
|
||
to by lpInBuffer.
|
||
|
||
lpOutBuffer- Supplies a pointer to the output buffer to be
|
||
filled in by the network.
|
||
|
||
nOutBufferSize- Supplies the size, in bytes, of the available
|
||
space pointed to by lpOutBuffer.
|
||
|
||
lpBytesReturned - Returns the number of bytes of lpOutBuffer
|
||
actually filled in by the network.
|
||
|
||
Return Value:
|
||
|
||
ERROR_SUCCESS if successful
|
||
|
||
Win32 error code otherwise
|
||
|
||
--*/
|
||
|
||
{
|
||
PCNETINTERFACE NetInterface;
|
||
HNODE_RPC hDestNode;
|
||
DWORD Status;
|
||
DWORD Required;
|
||
PVOID Buffer;
|
||
DWORD Dummy;
|
||
DWORD BytesReturned = 0;
|
||
|
||
Buffer = lpOutBuffer;
|
||
if ((Buffer == NULL) && (nOutBufferSize == 0)) {
|
||
Buffer = &Dummy;
|
||
}
|
||
|
||
NetInterface = (PCNETINTERFACE)hNetInterface;
|
||
|
||
//
|
||
// another node was specified so redirect the request to it
|
||
//
|
||
|
||
if (ARGUMENT_PRESENT(hHostNode)) {
|
||
|
||
hDestNode = ((PCNODE)hHostNode)->hNode;
|
||
WRAP(Status,
|
||
(ApiNodeNetInterfaceControl(NetInterface->hNetInterface,
|
||
hDestNode,
|
||
dwControlCode,
|
||
lpInBuffer,
|
||
nInBufferSize,
|
||
Buffer,
|
||
nOutBufferSize,
|
||
&BytesReturned,
|
||
&Required)),
|
||
NetInterface->Cluster);
|
||
} else {
|
||
|
||
WRAP(Status,
|
||
(ApiNetInterfaceControl(NetInterface->hNetInterface,
|
||
dwControlCode,
|
||
lpInBuffer,
|
||
nInBufferSize,
|
||
Buffer,
|
||
nOutBufferSize,
|
||
&BytesReturned,
|
||
&Required)),
|
||
NetInterface->Cluster);
|
||
}
|
||
|
||
if ( (Status == ERROR_SUCCESS) || (Status == ERROR_MORE_DATA) ) {
|
||
|
||
if ( (Status == ERROR_MORE_DATA) && (lpOutBuffer == NULL) ) {
|
||
Status = ERROR_SUCCESS;
|
||
}
|
||
|
||
if ( !BytesReturned ) {
|
||
BytesReturned = Required;
|
||
}
|
||
}
|
||
|
||
if ( ARGUMENT_PRESENT(lpBytesReturned) ) {
|
||
*lpBytesReturned = BytesReturned;
|
||
} else {
|
||
if ( (Status == ERROR_SUCCESS) &&
|
||
(BytesReturned > nOutBufferSize) ) {
|
||
Status = ERROR_MORE_DATA;
|
||
}
|
||
}
|
||
|
||
return(Status);
|
||
}
|
||
|
||
|
||
|
||
DWORD
|
||
WINAPI
|
||
ClusterControl(
|
||
IN HCLUSTER hCluster,
|
||
IN OPTIONAL HNODE hHostNode,
|
||
IN DWORD dwControlCode,
|
||
IN LPVOID lpInBuffer,
|
||
IN DWORD nInBufferSize,
|
||
OUT LPVOID lpOutBuffer,
|
||
IN DWORD nOutBufferSize,
|
||
OUT LPDWORD lpBytesReturned
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Provides for arbitrary communication and control between an application
|
||
and a specific instance of a cluster.
|
||
|
||
Arguments:
|
||
|
||
hCluster - Supplies a handle to the cluster to be controlled.
|
||
|
||
hHostNode - Supplies a handle to the node on which the cluster
|
||
control should be delivered. If this is NULL, the node where
|
||
the application is bound performs the request.
|
||
|
||
dwControlCode- Supplies the control code that defines the
|
||
structure and action of the cluster control.
|
||
Values of dwControlCode between 0 and 0x10000000 are reserved
|
||
for future definition and use by Microsoft. All other values
|
||
are available for use by ISVs.
|
||
|
||
lpInBuffer- Supplies a pointer to the input buffer to be passed
|
||
to the cluster.
|
||
|
||
nInBufferSize- Supplies the size, in bytes, of the data pointed
|
||
to by lpInBuffer.
|
||
|
||
lpOutBuffer- Supplies a pointer to the output buffer to be
|
||
filled in by the cluster.
|
||
|
||
nOutBufferSize- Supplies the size, in bytes, of the available
|
||
space pointed to by lpOutBuffer.
|
||
|
||
lpBytesReturned - Returns the number of bytes of lpOutBuffer
|
||
actually filled in by the cluster.
|
||
|
||
Return Value:
|
||
|
||
ERROR_SUCCESS if successful
|
||
|
||
Win32 error code otherwise
|
||
|
||
--*/
|
||
|
||
{
|
||
HNODE_RPC hDestNode;
|
||
DWORD Status;
|
||
DWORD Required;
|
||
PVOID Buffer;
|
||
DWORD Dummy;
|
||
DWORD BytesReturned;
|
||
PCLUSTER pCluster;
|
||
|
||
|
||
Buffer = lpOutBuffer;
|
||
if ((Buffer == NULL) &&
|
||
(nOutBufferSize == 0)) {
|
||
Buffer = &Dummy;
|
||
}
|
||
|
||
pCluster = GET_CLUSTER(hCluster);
|
||
|
||
if (ARGUMENT_PRESENT(hHostNode)) {
|
||
hDestNode = ((PCNODE)hHostNode)->hNode;
|
||
WRAP(Status,
|
||
(ApiNodeClusterControl(pCluster->hCluster,
|
||
hDestNode,
|
||
dwControlCode,
|
||
lpInBuffer,
|
||
nInBufferSize,
|
||
Buffer,
|
||
nOutBufferSize,
|
||
&BytesReturned,
|
||
&Required)),
|
||
pCluster);
|
||
} else {
|
||
|
||
WRAP(Status,
|
||
(ApiClusterControl(pCluster->hCluster,
|
||
dwControlCode,
|
||
lpInBuffer,
|
||
nInBufferSize,
|
||
Buffer,
|
||
nOutBufferSize,
|
||
&BytesReturned,
|
||
&Required)),
|
||
pCluster);
|
||
}
|
||
if ( (Status == ERROR_SUCCESS) ||
|
||
(Status == ERROR_MORE_DATA) ) {
|
||
if ( (Status == ERROR_MORE_DATA) &&
|
||
(lpOutBuffer == NULL) ) {
|
||
Status = ERROR_SUCCESS;
|
||
}
|
||
if ( !BytesReturned ) {
|
||
BytesReturned = Required;
|
||
}
|
||
}
|
||
|
||
if ( ARGUMENT_PRESENT(lpBytesReturned) ) {
|
||
*lpBytesReturned = BytesReturned;
|
||
} else {
|
||
if ( (Status == ERROR_SUCCESS) &&
|
||
(BytesReturned > nOutBufferSize) ) {
|
||
Status = ERROR_MORE_DATA;
|
||
}
|
||
}
|
||
|
||
return(Status);
|
||
|
||
}
|
||
|
||
|