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.
652 lines
15 KiB
652 lines
15 KiB
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
utils.c
|
|
|
|
Abstract:
|
|
|
|
Common utility routines for clusters resources
|
|
|
|
Author:
|
|
|
|
John Vert (jvert) 12/15/1996
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#include "clusres.h"
|
|
#include "clusrtl.h"
|
|
#include "clusudef.h"
|
|
|
|
|
|
|
|
DWORD
|
|
ClusResOpenDriver(
|
|
HANDLE *Handle,
|
|
LPWSTR DriverName
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function opens a specified IO drivers.
|
|
|
|
Arguments:
|
|
|
|
Handle - pointer to location where the opened drivers handle is
|
|
returned.
|
|
|
|
DriverName - name of the driver to be opened.
|
|
|
|
Return Value:
|
|
|
|
Windows Error Code.
|
|
|
|
--*/
|
|
{
|
|
OBJECT_ATTRIBUTES objectAttributes;
|
|
IO_STATUS_BLOCK ioStatusBlock;
|
|
UNICODE_STRING nameString;
|
|
NTSTATUS status;
|
|
|
|
*Handle = NULL;
|
|
|
|
//
|
|
// Open a Handle to the IP driver.
|
|
//
|
|
|
|
RtlInitUnicodeString(&nameString, DriverName);
|
|
|
|
InitializeObjectAttributes(
|
|
&objectAttributes,
|
|
&nameString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
(HANDLE) NULL,
|
|
(PSECURITY_DESCRIPTOR) NULL
|
|
);
|
|
|
|
status = NtCreateFile(
|
|
Handle,
|
|
SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
|
|
&objectAttributes,
|
|
&ioStatusBlock,
|
|
NULL,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
FILE_OPEN_IF,
|
|
0,
|
|
NULL,
|
|
0
|
|
);
|
|
|
|
return( RtlNtStatusToDosError( status ) );
|
|
|
|
} // ClusResOpenDriver
|
|
|
|
|
|
|
|
NTSTATUS
|
|
ClusResDoIoctl(
|
|
HANDLE Handle,
|
|
DWORD IoctlCode,
|
|
PVOID Request,
|
|
DWORD RequestSize,
|
|
PVOID Response,
|
|
PDWORD ResponseSize
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Utility routine used to issue a filtering ioctl to the tcpip driver.
|
|
|
|
Arguments:
|
|
|
|
Handle - An open file handle on which to issue the request.
|
|
|
|
IoctlCode - The IOCTL opcode.
|
|
|
|
Request - A pointer to the input buffer.
|
|
|
|
RequestSize - Size of the input buffer.
|
|
|
|
Response - A pointer to the output buffer.
|
|
|
|
ResponseSize - On input, the size in bytes of the output buffer.
|
|
On output, the number of bytes returned in the output buffer.
|
|
|
|
Return Value:
|
|
|
|
NT Status Code.
|
|
|
|
--*/
|
|
{
|
|
IO_STATUS_BLOCK ioStatusBlock;
|
|
NTSTATUS status;
|
|
|
|
|
|
ioStatusBlock.Information = 0;
|
|
|
|
status = NtDeviceIoControlFile(
|
|
Handle, // Driver handle
|
|
NULL, // Event
|
|
NULL, // APC Routine
|
|
NULL, // APC context
|
|
&ioStatusBlock, // Status block
|
|
IoctlCode, // Control code
|
|
Request, // Input buffer
|
|
RequestSize, // Input buffer size
|
|
Response, // Output buffer
|
|
*ResponseSize // Output buffer size
|
|
);
|
|
|
|
if (status == STATUS_PENDING) {
|
|
status = NtWaitForSingleObject(
|
|
Handle,
|
|
TRUE,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
if (status == STATUS_SUCCESS) {
|
|
status = ioStatusBlock.Status;
|
|
*ResponseSize = (DWORD)ioStatusBlock.Information;
|
|
}
|
|
else {
|
|
*ResponseSize = 0;
|
|
}
|
|
|
|
return(status);
|
|
|
|
} // ClusResDoIoctl
|
|
|
|
LPWSTR
|
|
ClusResLoadMessage(
|
|
DWORD MessageID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Look up the specified string resource as stored in this DLL's resource
|
|
area. Caller is responsible for freeing the buffer with LocalFree().
|
|
|
|
Arguments:
|
|
|
|
MessageID - message number as stored in inc\clusstrs.h
|
|
|
|
Return Value:
|
|
|
|
pointer to string, otherwise NULL with GLE set
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD charsCopied;
|
|
DWORD charsAllocated = 0;
|
|
LPWSTR messageBuffer;
|
|
HMODULE clusresHandle;
|
|
DWORD returnStatus = ERROR_SUCCESS;
|
|
|
|
//
|
|
// get a handle to clusres
|
|
//
|
|
clusresHandle = LoadLibraryEx( CLUSRES_MODULE_NAME, NULL, LOAD_LIBRARY_AS_DATAFILE );
|
|
if ( clusresHandle == NULL ) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// start with 128 char buffer and double until we fail or we get all of the
|
|
// string.
|
|
//
|
|
charsAllocated = 128;
|
|
|
|
realloc:
|
|
charsCopied = 0;
|
|
messageBuffer = LocalAlloc( LMEM_FIXED, charsAllocated * sizeof( WCHAR ));
|
|
if ( messageBuffer ) {
|
|
|
|
charsCopied = LoadString(clusresHandle,
|
|
MessageID,
|
|
messageBuffer,
|
|
charsAllocated);
|
|
|
|
if ( charsCopied != 0 ) {
|
|
if ( charsCopied == ( charsAllocated - 1 )) {
|
|
LocalFree( messageBuffer );
|
|
charsAllocated *= 2;
|
|
goto realloc;
|
|
}
|
|
} else {
|
|
returnStatus = GetLastError();
|
|
LocalFree( messageBuffer );
|
|
messageBuffer = NULL;
|
|
}
|
|
} else {
|
|
returnStatus = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
FreeLibrary( clusresHandle );
|
|
|
|
//
|
|
// if LoadString failed, set last error to its error status and not
|
|
// FreeLibrary's
|
|
//
|
|
if ( returnStatus != ERROR_SUCCESS ) {
|
|
SetLastError( returnStatus );
|
|
}
|
|
|
|
return messageBuffer;
|
|
|
|
} // ClusResLoadMessage
|
|
|
|
VOID
|
|
ClusResLogEventWithName0(
|
|
IN HKEY hResourceKey,
|
|
IN DWORD LogLevel,
|
|
IN DWORD LogModule,
|
|
IN LPSTR FileName,
|
|
IN DWORD LineNumber,
|
|
IN DWORD MessageId,
|
|
IN DWORD dwByteCount,
|
|
IN PVOID lpBytes
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Logs an event to the eventlog. The display name of the resource is retrieved
|
|
and passed as the first insertion string.
|
|
|
|
Arguments:
|
|
|
|
hResourceKey - Supplies the cluster resource key.
|
|
|
|
LogLevel - Supplies the logging level, one of
|
|
LOG_CRITICAL 1
|
|
LOG_UNUSUAL 2
|
|
LOG_NOISE 3
|
|
|
|
LogModule - Supplies the module ID.
|
|
|
|
FileName - Supplies the filename of the caller
|
|
|
|
LineNumber - Supplies the line number of the caller
|
|
|
|
MessageId - Supplies the message ID to be logged.
|
|
|
|
dwByteCount - Supplies the number of error-specific bytes to log. If this
|
|
is zero, lpBytes is ignored.
|
|
|
|
lpBytes - Supplies the error-specific bytes to log.
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS if successful
|
|
|
|
Win32 error code otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD BufSize;
|
|
DWORD Status;
|
|
WCHAR ResourceName[80];
|
|
PWCHAR resName = ResourceName;
|
|
DWORD dwType;
|
|
|
|
//
|
|
// Get the display name for this resource.
|
|
//
|
|
BufSize = sizeof( ResourceName );
|
|
|
|
again:
|
|
Status = ClusterRegQueryValue( hResourceKey,
|
|
CLUSREG_NAME_RES_NAME,
|
|
&dwType,
|
|
(LPBYTE)resName,
|
|
&BufSize );
|
|
|
|
if ( Status == ERROR_MORE_DATA ) {
|
|
resName = LocalAlloc( LMEM_FIXED, BufSize );
|
|
if ( resName != NULL ) {
|
|
goto again;
|
|
}
|
|
|
|
resName = ResourceName;
|
|
ResourceName[0] = UNICODE_NULL;
|
|
} else if ( Status != ERROR_SUCCESS ) {
|
|
ResourceName[0] = '\0';
|
|
}
|
|
|
|
ClusterLogEvent1(LogLevel,
|
|
LogModule,
|
|
FileName,
|
|
LineNumber,
|
|
MessageId,
|
|
dwByteCount,
|
|
lpBytes,
|
|
resName);
|
|
|
|
if ( resName != ResourceName ) {
|
|
LocalFree( resName );
|
|
}
|
|
|
|
return;
|
|
|
|
} // ClusResLogEventWithName0
|
|
|
|
|
|
VOID
|
|
ClusResLogEventWithName1(
|
|
IN HKEY hResourceKey,
|
|
IN DWORD LogLevel,
|
|
IN DWORD LogModule,
|
|
IN LPSTR FileName,
|
|
IN DWORD LineNumber,
|
|
IN DWORD MessageId,
|
|
IN DWORD dwByteCount,
|
|
IN PVOID lpBytes,
|
|
IN LPCWSTR Arg1
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Logs an event to the eventlog. The display name of the resource is retrieved
|
|
and passed as the first insertion string.
|
|
|
|
Arguments:
|
|
|
|
hResourceKey - Supplies the cluster resource key.
|
|
|
|
LogLevel - Supplies the logging level, one of
|
|
LOG_CRITICAL 1
|
|
LOG_UNUSUAL 2
|
|
LOG_NOISE 3
|
|
|
|
LogModule - Supplies the module ID.
|
|
|
|
FileName - Supplies the filename of the caller
|
|
|
|
LineNumber - Supplies the line number of the caller
|
|
|
|
MessageId - Supplies the message ID to be logged.
|
|
|
|
dwByteCount - Supplies the number of error-specific bytes to log. If this
|
|
is zero, lpBytes is ignored.
|
|
|
|
lpBytes - Supplies the error-specific bytes to log.
|
|
|
|
Arg1 - Supplies an insertion string
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS if successful
|
|
|
|
Win32 error code otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD BufSize;
|
|
DWORD Status;
|
|
WCHAR ResourceName[80];
|
|
PWCHAR resName = ResourceName;
|
|
DWORD dwType;
|
|
|
|
//
|
|
// Get the display name for this resource.
|
|
//
|
|
BufSize = sizeof( ResourceName );
|
|
|
|
again:
|
|
Status = ClusterRegQueryValue( hResourceKey,
|
|
CLUSREG_NAME_RES_NAME,
|
|
&dwType,
|
|
(LPBYTE)resName,
|
|
&BufSize );
|
|
|
|
if ( Status == ERROR_MORE_DATA ) {
|
|
resName = LocalAlloc( LMEM_FIXED, BufSize );
|
|
if ( resName != NULL ) {
|
|
goto again;
|
|
}
|
|
|
|
resName = ResourceName;
|
|
ResourceName[0] = UNICODE_NULL;
|
|
} else if ( Status != ERROR_SUCCESS ) {
|
|
ResourceName[0] = '\0';
|
|
}
|
|
|
|
ClusterLogEvent2(LogLevel,
|
|
LogModule,
|
|
FileName,
|
|
LineNumber,
|
|
MessageId,
|
|
dwByteCount,
|
|
lpBytes,
|
|
resName,
|
|
Arg1);
|
|
|
|
if ( resName != ResourceName ) {
|
|
LocalFree( resName );
|
|
}
|
|
|
|
return;
|
|
} // ClusResLogEventWithName1
|
|
|
|
VOID
|
|
ClusResLogEventWithName2(
|
|
IN HKEY hResourceKey,
|
|
IN DWORD LogLevel,
|
|
IN DWORD LogModule,
|
|
IN LPSTR FileName,
|
|
IN DWORD LineNumber,
|
|
IN DWORD MessageId,
|
|
IN DWORD dwByteCount,
|
|
IN PVOID lpBytes,
|
|
IN LPCWSTR Arg1,
|
|
IN LPCWSTR Arg2
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Logs an event to the eventlog. The display name of the resource is retrieved
|
|
and passed as the first insertion string.
|
|
|
|
Arguments:
|
|
|
|
hResourceKey - Supplies the cluster resource key.
|
|
|
|
LogLevel - Supplies the logging level, one of
|
|
LOG_CRITICAL 1
|
|
LOG_UNUSUAL 2
|
|
LOG_NOISE 3
|
|
|
|
LogModule - Supplies the module ID.
|
|
|
|
FileName - Supplies the filename of the caller
|
|
|
|
LineNumber - Supplies the line number of the caller
|
|
|
|
MessageId - Supplies the message ID to be logged.
|
|
|
|
dwByteCount - Supplies the number of error-specific bytes to log. If this
|
|
is zero, lpBytes is ignored.
|
|
|
|
lpBytes - Supplies the error-specific bytes to log.
|
|
|
|
Arg1 - Supplies an insertion string
|
|
|
|
Arg2 - Supplies the second insertion string
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS if successful
|
|
|
|
Win32 error code otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD BufSize;
|
|
DWORD Status;
|
|
WCHAR ResourceName[80];
|
|
PWCHAR resName = ResourceName;
|
|
DWORD dwType;
|
|
|
|
//
|
|
// Get the display name for this resource.
|
|
//
|
|
BufSize = sizeof( ResourceName );
|
|
|
|
again:
|
|
Status = ClusterRegQueryValue( hResourceKey,
|
|
CLUSREG_NAME_RES_NAME,
|
|
&dwType,
|
|
(LPBYTE)resName,
|
|
&BufSize );
|
|
|
|
if ( Status == ERROR_MORE_DATA ) {
|
|
resName = LocalAlloc( LMEM_FIXED, BufSize );
|
|
if ( resName != NULL ) {
|
|
goto again;
|
|
}
|
|
|
|
resName = ResourceName;
|
|
ResourceName[0] = UNICODE_NULL;
|
|
} else if ( Status != ERROR_SUCCESS ) {
|
|
ResourceName[0] = '\0';
|
|
}
|
|
|
|
ClusterLogEvent3(LogLevel,
|
|
LogModule,
|
|
FileName,
|
|
LineNumber,
|
|
MessageId,
|
|
dwByteCount,
|
|
lpBytes,
|
|
resName,
|
|
Arg1,
|
|
Arg2);
|
|
|
|
if ( resName != ResourceName ) {
|
|
LocalFree( resName );
|
|
}
|
|
|
|
return;
|
|
} // ClusResLogEventWithName2
|
|
|
|
VOID
|
|
ClusResLogEventWithName3(
|
|
IN HKEY hResourceKey,
|
|
IN DWORD LogLevel,
|
|
IN DWORD LogModule,
|
|
IN LPSTR FileName,
|
|
IN DWORD LineNumber,
|
|
IN DWORD MessageId,
|
|
IN DWORD dwByteCount,
|
|
IN PVOID lpBytes,
|
|
IN LPCWSTR Arg1,
|
|
IN LPCWSTR Arg2,
|
|
IN LPCWSTR Arg3
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Logs an event to the eventlog. The display name of the resource is retrieved
|
|
and passed as the first insertion string.
|
|
|
|
Arguments:
|
|
|
|
hResourceKey - Supplies the cluster resource key.
|
|
|
|
LogLevel - Supplies the logging level, one of
|
|
LOG_CRITICAL 1
|
|
LOG_UNUSUAL 2
|
|
LOG_NOISE 3
|
|
|
|
LogModule - Supplies the module ID.
|
|
|
|
FileName - Supplies the filename of the caller
|
|
|
|
LineNumber - Supplies the line number of the caller
|
|
|
|
MessageId - Supplies the message ID to be logged.
|
|
|
|
dwByteCount - Supplies the number of error-specific bytes to log. If this
|
|
is zero, lpBytes is ignored.
|
|
|
|
lpBytes - Supplies the error-specific bytes to log.
|
|
|
|
Arg1 - Supplies an insertion string
|
|
|
|
Arg2 - Supplies the second insertion string
|
|
|
|
Arg3 - Supplies the third insertion string
|
|
|
|
Return Value:
|
|
|
|
ERROR_SUCCESS if successful
|
|
|
|
Win32 error code otherwise
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD BufSize;
|
|
DWORD Status;
|
|
WCHAR ResourceName[80];
|
|
PWCHAR resName = ResourceName;
|
|
DWORD dwType;
|
|
|
|
//
|
|
// Get the display name for this resource.
|
|
//
|
|
BufSize = sizeof( ResourceName );
|
|
|
|
again:
|
|
Status = ClusterRegQueryValue( hResourceKey,
|
|
CLUSREG_NAME_RES_NAME,
|
|
&dwType,
|
|
(LPBYTE)resName,
|
|
&BufSize );
|
|
|
|
if ( Status == ERROR_MORE_DATA ) {
|
|
resName = LocalAlloc( LMEM_FIXED, BufSize );
|
|
if ( resName != NULL ) {
|
|
goto again;
|
|
}
|
|
|
|
resName = ResourceName;
|
|
ResourceName[0] = UNICODE_NULL;
|
|
} else if ( Status != ERROR_SUCCESS ) {
|
|
ResourceName[0] = '\0';
|
|
}
|
|
|
|
ClusterLogEvent4(LogLevel,
|
|
LogModule,
|
|
FileName,
|
|
LineNumber,
|
|
MessageId,
|
|
dwByteCount,
|
|
lpBytes,
|
|
resName,
|
|
Arg1,
|
|
Arg2,
|
|
Arg3);
|
|
|
|
if ( resName != ResourceName ) {
|
|
LocalFree( resName );
|
|
}
|
|
|
|
return;
|
|
}
|