/*++ 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; }