|
|
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
wow64log.c
Abstract: Main entrypoints for wow64log.dll. To add a data type handler : 1- Define a LOGDATATYPE for the data to log in w64logp.h 2- Implement the data type handler using the standard interface NTSTATUS LogDataType(IN OUT PLOGINFO LogInfo, IN ULONG_PTR Data, IN PSZ FieldName, IN BOOLEAN ServiceReturn); 3- Insert the handler into LogDataType[] below.
Author:
03-Oct-1999 SamerA
Revision History:
--*/
#include "w64logp.h"
#include <cathelper.h>
extern API_CATEGORY Wow64ApiCategories[]; extern API_CATEGORY_MAPPING Wow64ApiCategoryMappings[];
extern ULONG GetApiCategoryTableSize( void );
extern PAPI_CATEGORY_MAPPING FindApiInMappingTable( IN PTHUNK_DEBUG_INFO DebugInfoEntry, IN ULONG TableNumber);
/// Public
//
// Control logging flags
//
UINT_PTR Wow64LogFlags; HANDLE Wow64LogFileHandle;
/// Private
//
// Hold an array of pointers to each system service DebugThunkInfo
//
PULONG_PTR *LogNtBase; PULONG_PTR *LogWin32; PULONG_PTR *LogConsole; PULONG_PTR *LogBase;
//
// Hold an array of pointers to each system service api/category info
//
PULONG_PTR *ApiInfoNtBase; PULONG_PTR *ApiInfoWin32; PULONG_PTR *ApiInfoConsole; PULONG_PTR *ApiInfoBase;
//
// NOTE : The order entries in this table should match the LOGTYPE enum in
// w64logp.h.
//
LOGDATATYPE LogDataType[] = { {LogTypeValue}, // TypeHex
{LogTypePULongInOut}, // TypePULongPtrInOut
{LogTypePULongOut}, // TypePULONGOut
{LogTypePULongOut}, // TypePHandleOut
{LogTypeUnicodeString}, // TypeUnicodeStringIn
{LogTypeObjectAttrbiutes}, // TypeObjectAttributesIn
{LogTypeIoStatusBlock}, // TypeIoStatusBlockOut
{LogTypePWStr}, // TypePwstrIn
{LogTypePRectIn}, // TypePRectIn
{LogTypePLargeIntegerIn}, // TypePLargeIntegerIn
};
WOW64LOGAPI NTSTATUS Wow64LogInitialize( VOID) /*++
Routine Description:
This function is called by wow64.dll to initialize wow64 logging subsystem.
Arguments:
None
Return Value:
NTSTATUS --*/ { ULONG NtBaseTableSize, Win32TableSize, ConsoleTableSize, BaseTableSize; PULONG_PTR *Win32ThunkDebugInfo; PULONG_PTR *ConsoleThunkDebugInfo; UNICODE_STRING Log2Name; PVOID Log2Handle = NULL; NTSTATUS st;
//
// Initialize the logging file handle
//
Wow64LogFileHandle = INVALID_HANDLE_VALUE;
//
// Initialize the logging flags
//
LogInitializeFlags(&Wow64LogFlags); WOW64LOGOUTPUT((LF_TRACE, "Wow64LogInitialize - Wow64LogFlags = %I64x\n", Wow64LogFlags));
//
// Load the Win32 logging DLL if available.
//
RtlInitUnicodeString(&Log2Name, L"wow64lg2.dll"); st = LdrLoadDll(NULL, NULL, &Log2Name, &Log2Handle); if (NT_SUCCESS(st)) { ANSI_STRING ExportName;
RtlInitAnsiString(&ExportName, "Win32ThunkDebugInfo"); st = LdrGetProcedureAddress(Log2Handle, &ExportName, 0, &(PVOID)Win32ThunkDebugInfo); if (NT_SUCCESS(st)) { RtlInitAnsiString(&ExportName, "ConsoleThunkDebugInfo"); st = LdrGetProcedureAddress(Log2Handle, &ExportName, 0, &(PVOID)ConsoleThunkDebugInfo); } } if (!NT_SUCCESS(st)) { Log2Handle = NULL; Win32ThunkDebugInfo = NULL; ConsoleThunkDebugInfo = NULL; }
//
// Build pointers to the debug thunk info for each
// system service
//
NtBaseTableSize = GetThunkDebugTableSize( (PTHUNK_DEBUG_INFO)NtThunkDebugInfo); BaseTableSize = GetThunkDebugTableSize( (PTHUNK_DEBUG_INFO)BaseThunkDebugInfo); if (Log2Handle != NULL) { Win32TableSize = GetThunkDebugTableSize( (PTHUNK_DEBUG_INFO)Win32ThunkDebugInfo); ConsoleTableSize = GetThunkDebugTableSize( (PTHUNK_DEBUG_INFO)ConsoleThunkDebugInfo); } else { Win32TableSize = 0; ConsoleTableSize = 0; } LogNtBase = (PULONG_PTR *)Wow64AllocateHeap((NtBaseTableSize + Win32TableSize + ConsoleTableSize + BaseTableSize) * sizeof(PULONG_PTR) * 2 );
if (!LogNtBase) { WOW64LOGOUTPUT((LF_ERROR, "Wow64LogInitialize - Wow64AllocateHeap failed\n")); return STATUS_UNSUCCESSFUL; } LogWin32 = LogNtBase + NtBaseTableSize; LogConsole = LogWin32 + Win32TableSize; LogBase = LogConsole + ConsoleTableSize;
ApiInfoNtBase = LogBase + BaseTableSize; ApiInfoWin32 = ApiInfoNtBase + NtBaseTableSize; ApiInfoConsole = ApiInfoWin32 + Win32TableSize; ApiInfoBase = ApiInfoConsole + ConsoleTableSize;
BuildDebugThunkInfo(WHNT32_INDEX,(PTHUNK_DEBUG_INFO)NtThunkDebugInfo,LogNtBase,ApiInfoNtBase); BuildDebugThunkInfo(WHBASE_INDEX,(PTHUNK_DEBUG_INFO)BaseThunkDebugInfo,LogBase,ApiInfoBase); if (Log2Handle) { BuildDebugThunkInfo(WHWIN32_INDEX,(PTHUNK_DEBUG_INFO)Win32ThunkDebugInfo,LogWin32,ApiInfoWin32); BuildDebugThunkInfo(WHCON_INDEX,(PTHUNK_DEBUG_INFO)ConsoleThunkDebugInfo,LogConsole,ApiInfoConsole); } else { LogConsole = NULL; LogWin32 = NULL; }
return STATUS_SUCCESS; }
WOW64LOGAPI NTSTATUS Wow64LogTerminate( VOID) /*++
Routine Description:
This function is called by wow64.dll when the process is exiting.
Arguments:
None
Return Value:
NTSTATUS --*/ { IO_STATUS_BLOCK IoStatusBlock; if (Wow64LogFileHandle != INVALID_HANDLE_VALUE) { NtFlushBuffersFile(Wow64LogFileHandle, &IoStatusBlock); NtClose(Wow64LogFileHandle); }
return STATUS_SUCCESS; }
NTSTATUS LogInitializeFlags( IN OUT PUINT_PTR Flags) /*++
Routine Description:
Reads the logging flags from the registry
Arguments:
Flags - Pointer to receive logging flags
Return Value:
NTSTATUS --*/ { HANDLE Key; UNICODE_STRING KeyName, ValueName, ResultValue; OBJECT_ATTRIBUTES ObjectAttributes; WCHAR KeyValueBuffer[ 128 ]; PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation; ULONG ResultLength, RegFlags; NTSTATUS NtStatus;
//
// Punch in the default
//
*Flags = LF_DEFAULT;
KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager");
InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
NtStatus = NtOpenKey(&Key, KEY_READ, &ObjectAttributes);
if (NT_SUCCESS(NtStatus)) { RtlInitUnicodeString(&ValueName, L"WOW64LOGFLAGS"); NtStatus = NtQueryValueKey(Key, &ValueName, KeyValuePartialInformation, KeyValueInformation, sizeof(KeyValueBuffer), &ResultLength);
if (NT_SUCCESS(NtStatus)) { if ((KeyValueInformation->Type == REG_DWORD) && (KeyValueInformation->DataLength == sizeof(DWORD))) { *Flags = *((PULONG)KeyValueInformation->Data); } } }
return NtStatus; }
ULONG GetThunkDebugTableSize( IN PTHUNK_DEBUG_INFO DebugInfoTable) /*++
Routine Description:
This routine retreives the number of DebugThunkInfo entries in the passed table.
Arguments:
DebugInfoTable - Pointer to services debug info
Return Value:
Number of entries --*/ { BOOLEAN InvalidArgumentPresent; ULONG ArgIndex; ULONG Count = 0;
while (DebugInfoTable && DebugInfoTable->ApiName) { //
// Walk the argument list to make sure there aren't any NULLs in them, which would
// terminate the table.
//
ArgIndex = 0; InvalidArgumentPresent = FALSE; while (ArgIndex < DebugInfoTable->NumberOfArg) { if (!ARGUMENT_PRESENT (DebugInfoTable->Arg[ArgIndex++].Name)) { InvalidArgumentPresent = TRUE; break; } }
if (InvalidArgumentPresent == TRUE) { break; } Count++; DebugInfoTable = (PTHUNK_DEBUG_INFO) &DebugInfoTable->Arg[DebugInfoTable->NumberOfArg]; }
return Count; }
NTSTATUS BuildDebugThunkInfo( IN ULONG TableNumber, IN PTHUNK_DEBUG_INFO DebugInfoTable, OUT PULONG_PTR *LogTable, OUT PULONG_PTR *ApiInfoTable) /*++
Routine Description:
This routine fills a service-table-indexed with pointers to the corresponding DebugThunkInfo
Arguments:
DebugInfoTable - Services debug info LogTable - Table of pointers to fill ApiInfoTable - Table of pointers to fill
Return Value:
NTSTATUS --*/ { BOOLEAN InvalidArgumentPresent; ULONG ArgIndex; ULONG i=0;
while (DebugInfoTable && DebugInfoTable->ApiName) { LogTable[i] = (PULONG_PTR) DebugInfoTable;
ApiInfoTable[i++] = (PULONG_PTR) FindApiInMappingTable(DebugInfoTable,TableNumber);
//
// Walk the argument list to make sure there aren't any NULLs in them, which would
// terminate the table.
//
ArgIndex = 0; InvalidArgumentPresent = FALSE; while (ArgIndex < DebugInfoTable->NumberOfArg) { if (!ARGUMENT_PRESENT (DebugInfoTable->Arg[ArgIndex++].Name)) { InvalidArgumentPresent = TRUE; break; } }
if (InvalidArgumentPresent == TRUE) { break; }
DebugInfoTable = (PTHUNK_DEBUG_INFO) &DebugInfoTable->Arg[DebugInfoTable->NumberOfArg]; }
return STATUS_SUCCESS; }
NTSTATUS LogApiHeader( PTHUNK_DEBUG_INFO ThunkDebugInfo, PLOGINFO LogInfo, BOOLEAN ServiceReturn, ULONG_PTR ReturnResult, ULONG_PTR ReturnAddress) /*++
Routine Description:
Log the Thunked API header
Arguments:
ThunkDebugInfo - Pointer to service log info LogInfo - Logging Info ServiceReturn - TRUE if called after the thunk API has executed ReturnResult - Result code returned from the API ReturnAddress - Return address of for this thunked call
Return Value:
NTSTATUS --*/ { if (ServiceReturn) { return LogFormat(LogInfo, "wh%s: Ret=%lx-%lx: ", ThunkDebugInfo->ApiName, ReturnResult, ReturnAddress); }
return LogFormat(LogInfo, "%8.8X-wh%s: ", PtrToUlong(NtCurrentTeb()->ClientId.UniqueThread), ThunkDebugInfo->ApiName); }
NTSTATUS LogApiParameters( IN OUT PLOGINFO LogInfo, IN PULONG Stack32, IN PTHUNK_DEBUG_INFO ThunkDebugInfo, IN BOOLEAN ServiceReturn) /*++
Routine Description:
Log the Thunked API Parameters
Arguments:
LogInfo - Output log buffer Stack32 - Pointer to 32-bit arg stack ThunkDebugInfo - Pointer to service log info for the API ServiceReturn - TRUE if called after the Thunk API has executed
Return Value:
NTSTATUS --*/ { UINT_PTR i=0;
//
// Loops thru the parameters
//
while (i < ThunkDebugInfo->NumberOfArg) { _try { LogDataType[ThunkDebugInfo->Arg[i].Type].Handler( LogInfo, Stack32[i], ThunkDebugInfo->Arg[i].Name, ServiceReturn); } _except(EXCEPTION_EXECUTE_HANDLER) { //
// Log the bad parameters
//
LogFormat(LogInfo, "%s=%lx-%ws ", ThunkDebugInfo->Arg[i].Name, Stack32[i], L"(BAD)"); } i++; }
return STATUS_SUCCESS; }
NTSTATUS LogThunkApi( IN PTHUNK_LOG_CONTEXT ThunkLogContext, IN PTHUNK_DEBUG_INFO ThunkDebugInfo, IN UINT_PTR LogFullInfo) /*++
Routine Description:
Log the Thunked API
Arguments:
ThunkLogContext - Thunk API log context ThunkDebugInfo - Pointer to service log info for the API LogFullInfo - Flag whther to log all the API info or just the name
Return Value:
NTSTATUS --*/ { NTSTATUS NtStatus; CHAR szBuf[ MAX_LOG_BUFFER ]; LOGINFO LogInfo; PULONG Stack32 = ThunkLogContext->Stack32; BOOLEAN ServiceReturn = ThunkLogContext->ServiceReturn; //
// Initialize the log buffer
//
LogInfo.OutputBuffer = szBuf; LogInfo.BufferSize = MAX_LOG_BUFFER - 1; //
// Log API header
//
NtStatus = LogApiHeader(ThunkDebugInfo, &LogInfo, ServiceReturn, ThunkLogContext->ReturnResult, *(Stack32-1));
if (!NT_SUCCESS(NtStatus)) { return NtStatus; }
// Log Parameters
if (LogFullInfo) { NtStatus = LogApiParameters(&LogInfo, Stack32, ThunkDebugInfo, ServiceReturn); if (!NT_SUCCESS(NtStatus)) { return NtStatus; } }
//
// Do actual output
//
LogInfo.OutputBuffer[0] = '\0'; LogOut(szBuf, Wow64LogFlags); LogOut("\r\n", Wow64LogFlags);
return NtStatus; }
WOW64LOGAPI NTSTATUS Wow64LogSystemService( IN PTHUNK_LOG_CONTEXT ThunkLogContext) /*++
Routine Description:
Logs information for the specified system service.
Arguments:
LogContext - Thunk API log context
Return Value:
NTSTATUS --*/ { NTSTATUS NtStatus; PTHUNK_DEBUG_INFO ThunkDebugInfo; ULONG_PTR TableNumber = ThunkLogContext->TableNumber; ULONG_PTR ServiceNumber = ThunkLogContext->ServiceNumber; UINT_PTR LogFullInfo; PAPI_CATEGORY_MAPPING ApiCategoryMapping;
//
// Use try except !!
//
_try { switch(TableNumber) { case WHNT32_INDEX: if (!LF_NTBASE_ENABLED(Wow64LogFlags)) { return STATUS_SUCCESS; } LogFullInfo = (Wow64LogFlags & LF_NTBASE_FULL); ThunkDebugInfo = (PTHUNK_DEBUG_INFO)LogNtBase[ServiceNumber]; ApiCategoryMapping = (PAPI_CATEGORY_MAPPING)(ApiInfoNtBase[ServiceNumber]);
if( LF_CATLOG_ENABLED(Wow64LogFlags) ) { if(NULL == ApiCategoryMapping) { return STATUS_SUCCESS; } else { // api enabled check
if( 0 == (ApiCategoryMapping->ApiFlags & APIFLAG_ENABLED) ) { return STATUS_SUCCESS; }
// category enabled check
if( 0 == (Wow64ApiCategories[ApiCategoryMapping->ApiCategoryIndex].CategoryFlags & CATFLAG_ENABLED) ) { return STATUS_SUCCESS; }
// log on fail check
if( APIFLAG_LOGONFAIL == (ApiCategoryMapping->ApiFlags & APIFLAG_LOGONFAIL) ) { if( FALSE == ThunkLogContext->ServiceReturn ) { return STATUS_SUCCESS; }
if( NT_SUCCESS(ThunkLogContext->ReturnResult) ) { return STATUS_SUCCESS; } } } } break;
case WHCON_INDEX: if (!LF_NTCON_ENABLED(Wow64LogFlags) || LogConsole == NULL) { return STATUS_SUCCESS; } LogFullInfo = (Wow64LogFlags & LF_NTCON_FULL); ThunkDebugInfo = (PTHUNK_DEBUG_INFO)LogConsole[ServiceNumber]; ApiCategoryMapping = (PAPI_CATEGORY_MAPPING)(ApiInfoConsole[ServiceNumber]); if( LF_CATLOG_ENABLED(Wow64LogFlags) ) { if(NULL == ApiCategoryMapping) { return STATUS_SUCCESS; } else { // api enabled check
if( 0 == (ApiCategoryMapping->ApiFlags & APIFLAG_ENABLED) ) { return STATUS_SUCCESS; }
// category enabled check
if( 0 == (Wow64ApiCategories[ApiCategoryMapping->ApiCategoryIndex].CategoryFlags & CATFLAG_ENABLED) ) { return STATUS_SUCCESS; }
// log on fail check
if( APIFLAG_LOGONFAIL == (ApiCategoryMapping->ApiFlags & APIFLAG_LOGONFAIL) ) { if( FALSE == ThunkLogContext->ServiceReturn ) { return STATUS_SUCCESS; }
if( NT_SUCCESS(ThunkLogContext->ReturnResult) ) { return STATUS_SUCCESS; } } } } break;
case WHWIN32_INDEX: if (!LF_WIN32_ENABLED(Wow64LogFlags) || LogWin32 == NULL) { return STATUS_SUCCESS; } LogFullInfo = (Wow64LogFlags & LF_WIN32_FULL); ThunkDebugInfo = (PTHUNK_DEBUG_INFO)LogWin32[ServiceNumber]; ApiCategoryMapping = (PAPI_CATEGORY_MAPPING)(ApiInfoWin32[ServiceNumber]); if( LF_CATLOG_ENABLED(Wow64LogFlags) ) { if(NULL == ApiCategoryMapping) { return STATUS_SUCCESS; } else { // api enabled check
if( 0 == (ApiCategoryMapping->ApiFlags & APIFLAG_ENABLED) ) { return STATUS_SUCCESS; }
// category enabled check
if( 0 == (Wow64ApiCategories[ApiCategoryMapping->ApiCategoryIndex].CategoryFlags & CATFLAG_ENABLED) ) { return STATUS_SUCCESS; }
// log on fail check
if( APIFLAG_LOGONFAIL == (ApiCategoryMapping->ApiFlags & APIFLAG_LOGONFAIL) ) { if( FALSE == ThunkLogContext->ServiceReturn ) { return STATUS_SUCCESS; }
if( NT_SUCCESS(ThunkLogContext->ReturnResult) ) { return STATUS_SUCCESS; } } } } break;
case WHBASE_INDEX: if (!LF_BASE_ENABLED(Wow64LogFlags)) { return STATUS_SUCCESS; } LogFullInfo = (Wow64LogFlags & LF_BASE_FULL); ThunkDebugInfo = (PTHUNK_DEBUG_INFO)LogBase[ServiceNumber]; ApiCategoryMapping = (PAPI_CATEGORY_MAPPING)(ApiInfoBase[ServiceNumber]); if( LF_CATLOG_ENABLED(Wow64LogFlags) ) { if(NULL == ApiCategoryMapping) { return STATUS_SUCCESS; } else { // api enabled check
if( 0 == (ApiCategoryMapping->ApiFlags & APIFLAG_ENABLED) ) { return STATUS_SUCCESS; }
// category enabled check
if( 0 == (Wow64ApiCategories[ApiCategoryMapping->ApiCategoryIndex].CategoryFlags & CATFLAG_ENABLED) ) { return STATUS_SUCCESS; }
// log on fail check
if( APIFLAG_LOGONFAIL == (ApiCategoryMapping->ApiFlags & APIFLAG_LOGONFAIL) ) { if( FALSE == ThunkLogContext->ServiceReturn ) { return STATUS_SUCCESS; }
if( NT_SUCCESS(ThunkLogContext->ReturnResult) ) { return STATUS_SUCCESS; } } } } break;
default: // invalid service table
WOW64LOGOUTPUT((LF_ERROR, "Wow64LogSystemService: Not supported table number - %lx\n", TableNumber)); return STATUS_UNSUCCESSFUL; break; }
NtStatus = LogThunkApi(ThunkLogContext, ThunkDebugInfo, LogFullInfo); } _except(EXCEPTION_EXECUTE_HANDLER) { WOW64LOGOUTPUT((LF_EXCEPTION, "Wow64LogSystemService : Invalid Service ServiceTable = %lx, ServiceNumber = %lx. Status=%lx\n", TableNumber, ServiceNumber, GetExceptionCode())); NtStatus = GetExceptionCode(); }
return NtStatus; }
//////////////////////////////////////////////////////////////////////////
//
// DATA TYPE LOGGING ROUTINES
//
///////////////////////////////////////////////////////////////////////////
NTSTATUS LogTypeValue( IN OUT PLOGINFO LogInfo, IN ULONG_PTR Data, IN PSZ FieldName, IN BOOLEAN ServiceReturn) /*++
Routine Description:
Log Data as ULONG
Arguments:
LogInfo - Output log buffer Data - Value to log FieldName - Descriptive name of value to log ServiceReturn - TRUE if called after the thunk API has executed
Return Value:
NTSTATUS --*/ { if (ServiceReturn) { return STATUS_SUCCESS; }
return LogFormat(LogInfo, "%s=%lx ", FieldName, (ULONG)Data); }
NTSTATUS LogTypeUnicodeString( IN OUT PLOGINFO LogInfo, IN ULONG_PTR Data, IN PSZ FieldName, IN BOOLEAN ServiceReturn) /*++
Routine Description:
Log Data as UNICODE_STRING32
Arguments:
LogInfo - Output log buffer Data - Value to log FieldName - Descriptive name of value to log ServiceReturn - TRUE if called after the thunk API has executed
Return Value:
NTSTATUS --*/ { UNICODE_STRING32 *Name32; PWCHAR Buffer = L" ";
if (ServiceReturn) { return STATUS_SUCCESS; }
Name32 = (UNICODE_STRING32 *)Data; if (Data > 0xffff) { if (Name32->Buffer) { Buffer = (PWCHAR)Name32->Buffer; } if (Name32->Length && Name32->Buffer > 0xffff) { return LogFormat(LogInfo, "%s=%ws ", FieldName, Buffer); } else { return LogFormat(LogInfo, "%s={L=%x,M=%x,B=%x}", FieldName, Name32->Length, Name32->MaximumLength, Name32->Buffer); } }
return LogFormat(LogInfo, "%s=%x", FieldName, Name32); }
NTSTATUS LogTypePULongInOut( IN OUT PLOGINFO LogInfo, IN ULONG_PTR Data, IN PSZ FieldName, IN BOOLEAN ServiceReturn) /*++
Routine Description:
Log Data as PULONG
Arguments:
LogInfo - Output log buffer Data - Value to log FieldName - Descriptive name of value to log ServiceReturn - TRUE if called after the thunk API has executed
Return Value:
NTSTATUS --*/ { return LogFormat(LogInfo, "[%s-%lx]=%lx ", FieldName, (ULONG)Data, ((PULONG)Data ? *((PULONG)Data) : 0)); }
NTSTATUS LogTypePULongOut( IN OUT PLOGINFO LogInfo, IN ULONG_PTR Data, IN PSZ FieldName, IN BOOLEAN ServiceReturn) /*++
Routine Description:
Log Data as PULONG (Out field)
Arguments:
LogInfo - Output log buffer Data - Value to log FieldName - Descriptive name of value to log ServiceReturn - TRUE if called after the thunk API has executed
Return Value:
NTSTATUS --*/ { if (ServiceReturn) { return LogFormat(LogInfo, "[%s-%lx]=%lx ", FieldName, (PULONG)Data, ((PULONG)Data ? *(PULONG)Data : 0)); }
return LogFormat(LogInfo, "%s=%lx ", FieldName, (PULONG)Data); }
NTSTATUS LogTypeObjectAttrbiutes( IN OUT PLOGINFO LogInfo, IN ULONG_PTR Data, IN PSZ FieldName, IN BOOLEAN ServiceReturn) /*++
Routine Description:
Log Data as POBJECT_ATTRIBUTES
Arguments:
LogInfo - Output log buffer Data - Value to log FieldName - Descriptive name of value to log ServiceReturn - TRUE if called after the thunk API has executed
Return Value:
NTSTATUS --*/ { NT32OBJECT_ATTRIBUTES *ObjA32; UNICODE_STRING32 *ObjectName = NULL; PWCHAR Buffer = L"";
if (ServiceReturn) { return STATUS_SUCCESS; }
ObjA32 = (NT32OBJECT_ATTRIBUTES *)Data; if (ObjA32) { ObjectName = (UNICODE_STRING32 *)ObjA32->ObjectName; if (ObjectName) { if (ObjectName->Buffer) { Buffer = (PWCHAR)ObjectName->Buffer; } } }
return LogFormat(LogInfo, "%s=%lx {N=%ws,A=%lx} ", FieldName, (PULONG)Data, Buffer, (ObjA32 ? ObjA32->Attributes : 0)); }
NTSTATUS LogTypeIoStatusBlock( IN OUT PLOGINFO LogInfo, IN ULONG_PTR Data, IN PSZ FieldName, IN BOOLEAN ServiceReturn) /*++
Routine Description:
Log Data as IO_STATUS_BLOCK
Arguments:
LogInfo - Output log buffer Data - Value to log FieldName - Descriptive name of value to log ServiceReturn - TRUE if called after the thunk API has executed
Return Value:
NTSTATUS --*/ { if (ServiceReturn) { PIO_STATUS_BLOCK32 StatusBlock32 = (PIO_STATUS_BLOCK32)Data; return LogFormat(LogInfo, "%s={S=%lx,I=%lx} ", FieldName, (PULONG)Data, (StatusBlock32 ? StatusBlock32->Status : 0), (StatusBlock32 ? StatusBlock32->Information : 0)); }
return LogFormat(LogInfo, "%s=%lx ", FieldName, (PULONG)Data); }
NTSTATUS LogTypePWStr( IN OUT PLOGINFO LogInfo, IN ULONG_PTR Data, IN PSZ FieldName, IN BOOLEAN ServiceReturn) /*++
Routine Description:
Log Data as PWSTR
Arguments:
LogInfo - Output log buffer Data - Value to log FieldName - Descriptive name of value to log ServiceReturn - TRUE if called after the thunk API has executed
Return Value:
NTSTATUS --*/ { ULONG_PTR i; WCHAR Buffer[ 14 ]; PWSTR String = (PWSTR) Data;
if (ServiceReturn) { return STATUS_SUCCESS; }
//
// Sometime this type is treated as a pointer
// to WCHARs without NULL terminating it, like
// how it's used in NtGdiExtTextOutW, so let's dump
// a minimal string
//
if (Data) { i = 0; while((i < ((sizeof(Buffer) / sizeof(WCHAR)) - 4)) && (String[i])) { Buffer[i] = String[i]; i++; }
if (i == ((sizeof(Buffer) / sizeof(WCHAR)) - 4)) { Buffer[i++] = L'.'; Buffer[i++] = L'.'; Buffer[i++] = L'.'; } Buffer[i++] = UNICODE_NULL; }
return LogFormat(LogInfo, "%s=%ws ", FieldName, (Data > 0xffff) ? Buffer : L""); }
NTSTATUS LogTypePRectIn( IN OUT PLOGINFO LogInfo, IN ULONG_PTR Data, IN PSZ FieldName, IN BOOLEAN ServiceReturn) /*++
Routine Description:
Log Data as PWSTR
Arguments:
LogInfo - Output log buffer Data - Value to log FieldName - Descriptive name of value to log ServiceReturn - TRUE if called after the thunk API has executed
Return Value:
NTSTATUS --*/ { if (ServiceReturn) { return STATUS_SUCCESS; }
if (Data) { PRECT Rect = (PRECT)Data; return LogFormat(LogInfo, "%s={%lx,%lx,%lx,%lx} ", FieldName, Rect->left, Rect->top, Rect->right, Rect->bottom);
} return LogTypeValue(LogInfo, Data, FieldName, ServiceReturn); }
NTSTATUS LogTypePLargeIntegerIn( IN OUT PLOGINFO LogInfo, IN ULONG_PTR Data, IN PSZ FieldName, IN BOOLEAN ServiceReturn) /*++
Routine Description:
Log Data as PLARGE_INTEGER
Arguments:
LogInfo - Output log buffer Data - Value to log FieldName - Descriptive name of value to log ServiceReturn - TRUE if called after the thunk API has executed
Return Value:
NTSTATUS --*/ { if (ServiceReturn) { return STATUS_SUCCESS; }
if (Data) { NT32ULARGE_INTEGER *ULargeInt = (NT32ULARGE_INTEGER *)Data; return LogFormat(LogInfo, "%s={H=%lx,L=%lx} ", FieldName, ULargeInt->HighPart, ULargeInt->LowPart);
} return LogTypeValue(LogInfo, Data, FieldName, ServiceReturn); }
|