`**********************************************************************` `* This is an include template file for tracewpp preprocessor. *` `* *` `* Copyright 1999-2001 Microsoft Corporation. All Rights Reserved. *` `**********************************************************************` // template `TemplateFile` // // Defines a set of functions that simplifies // kernel mode registration for tracing // #if !defined(WppDebug) # define WppDebug(a,b) #endif #define WMIREG_FLAG_CALLBACK 0x80000000 // not exposed in DDK #ifndef WPPINIT_EXPORT # define WPPINIT_EXPORT #endif #ifdef WPP_GLOBALLOGGER WPPINIT_EXPORT void WppIntToHex( LPWSTR Buf, unsigned int value, int digits ) { static LPCWSTR hexDigit = L"0123456789abcdef"; while (--digits >= 0) { Buf[digits] = hexDigit[ value & 15 ]; value /= 16; // compiler is smart enough to change it to bitshift } } #define WPP_TEXTGUID_LEN 37 // b1e5deaf-1524-4a04-82c4-c9dfbce6cf97 // 0 1 2 3 // 0123456789012345678901234567890123456 WPPINIT_EXPORT void WppGuidToStr(LPWSTR buf, LPCGUID guid) { WppIntToHex(buf + 0, guid->Data1, 8); buf[8] = '-'; WppIntToHex(buf + 9, guid->Data2, 4); buf[13] = '-'; WppIntToHex(buf + 14, guid->Data3, 4); buf[18] = '-'; WppIntToHex(buf + 19, guid->Data4[0], 2); WppIntToHex(buf + 21, guid->Data4[1], 2); buf[23] = '-'; WppIntToHex(buf + 24, guid->Data4[2], 2); WppIntToHex(buf + 26, guid->Data4[3], 2); WppIntToHex(buf + 28, guid->Data4[4], 2); WppIntToHex(buf + 30, guid->Data4[5], 2); WppIntToHex(buf + 32, guid->Data4[6], 2); WppIntToHex(buf + 34, guid->Data4[7], 2); buf[36] = 0; } #define GREGVALUENAMELENGTH 18 + WPP_TEXTGUID_LEN + 1 // wslen(L"WMI\\GlobalLogger\\") + GUIDLENGTH WPPINIT_EXPORT void WppInitGlobalLogger( LPCGUID pControlGuid, PTRACEHANDLE pLogger, PULONG pFlags, PUCHAR pLevel ) { WCHAR GRegValueName[GREGVALUENAMELENGTH] ; // L"WMI\\GlobalLogger\\d58c126f-b309-11d1-969e-0000f875a5bc" ; RTL_QUERY_REGISTRY_TABLE parms[3]; ULONG Lflags = 0, Llevel = 0, Lstart = 0; NTSTATUS status ; ULONG aZero = 0 ; WppDebug(0,("WPP checking Global Logger")); swprintf(GRegValueName,L"WMI\\GlobalLogger\\"); // // Fill in the query table to find out if the Global Logger is Started // // Trace Flags parms[0].QueryRoutine = NULL ; parms[0].Flags = RTL_QUERY_REGISTRY_DIRECT; parms[0].Name = L"Start"; parms[0].EntryContext = &Lstart; parms[0].DefaultType = REG_DWORD; parms[0].DefaultData = &aZero; parms[0].DefaultLength = sizeof(ULONG); // Termination parms[1].QueryRoutine = NULL ; parms[1].Flags = 0 ; // // Perform the query // status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL | RTL_REGISTRY_OPTIONAL, GRegValueName, parms, NULL, NULL); if (!NT_SUCCESS(status) || Lstart == 0 ) { return ; } // Fill in the query table to find out if we should use the Global logger // // Trace Flags parms[0].QueryRoutine = NULL ; parms[0].Flags = RTL_QUERY_REGISTRY_DIRECT; parms[0].Name = L"Flags"; parms[0].EntryContext = &Lflags; parms[0].DefaultType = REG_DWORD; parms[0].DefaultData = &aZero; parms[0].DefaultLength = sizeof(ULONG); // Trace level parms[1].QueryRoutine = NULL ; parms[1].Flags = RTL_QUERY_REGISTRY_DIRECT; parms[1].Name = L"Level"; parms[1].EntryContext = &Llevel; parms[1].DefaultType = REG_DWORD; parms[1].DefaultData = &aZero; parms[1].DefaultLength = sizeof(UCHAR); // Termination parms[2].QueryRoutine = NULL ; parms[2].Flags = 0 ; WppGuidToStr(&GRegValueName[wcslen(GRegValueName)], pControlGuid) ; // // Perform the query // status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL | RTL_REGISTRY_OPTIONAL, GRegValueName, parms, NULL, NULL); if (NT_SUCCESS(status)) { if (Lstart==1) { *pLogger= WMI_GLOBAL_LOGGER_ID ; *pFlags = Lflags & 0x7FFFFFFF ; *pLevel = (UCHAR)(Llevel & 0xFF) ; WppDebug(0,("WPP Enabled via Global Logger Flags=0x%08X Level=0x%02X",Lflags,Llevel)); } } } #endif //#ifdef WPP_GLOBALLOGGER WPPINIT_EXPORT NTSTATUS WppTraceCallback( IN UCHAR minorFunction, IN PVOID DataPath, IN ULONG BufferLength, IN PVOID Buffer, IN PVOID Context, OUT PULONG Size ) /*++ Routine Description: Callback routine for IoWMIRegistrationControl. Arguments: Return Value: status Comments: if return value is STATUS_BUFFER_TOO_SMALL and BufferLength >= 4, then first ulong of buffer contains required size --*/ { WPP_PROJECT_CONTROL_BLOCK *cb = (WPP_PROJECT_CONTROL_BLOCK*)Context; NTSTATUS status = STATUS_SUCCESS; UNREFERENCED_PARAMETER(DataPath); WppDebug(0,("WppTraceCallBack 0x%08X %p\n", minorFunction, Context)); *Size = 0; switch(minorFunction) { case IRP_MN_REGINFO: { PWMIREGINFOW wmiRegInfo; PCUNICODE_STRING regPath; PWCHAR stringPtr; ULONG registryPathOffset; ULONG bufferNeeded; UNICODE_STRING nullRegistryPath; #if defined(WPP_TRACE_W2K_COMPATABILITY) wmiRegInfo = (PWMIREGINFO)Buffer; if (wmiRegInfo->GuidCount >= 1) { // Replace the null trace GUID with the driver's trace control GUID wmiRegInfo->WmiRegGuid[wmiRegInfo->GuidCount-1].Guid = *cb->Registration.ControlGuid; wmiRegInfo->WmiRegGuid[wmiRegInfo->GuidCount-1].Flags = WMIREG_FLAG_TRACE_CONTROL_GUID | WMIREG_FLAG_TRACED_GUID; *Size= wmiRegInfo->BufferSize; status = STATUS_SUCCESS; #ifdef WPP_GLOBALLOGGER // Check if Global logger is active WppInitGlobalLogger(cb->Registration.ControlGuid, (PTRACEHANDLE)&cb->Control.Logger, &cb->Control.Flags[0], &cb->Control.Level); #endif //#ifdef WPP_GLOBALLOGGER break; } #endif regPath = cb->Registration.RegistryPath; if (regPath == NULL) { // No registry path specified. This is a bad thing for // the device to do, but is not fatal RtlInitUnicodeString(&nullRegistryPath, NULL); regPath = &nullRegistryPath; } registryPathOffset = FIELD_OFFSET(WMIREGINFOW, WmiRegGuid) + 1 * sizeof(WMIREGGUIDW); bufferNeeded = registryPathOffset + regPath->Length + sizeof(USHORT); if (bufferNeeded <= BufferLength) { RtlZeroMemory(Buffer, BufferLength); wmiRegInfo = (PWMIREGINFO)Buffer; wmiRegInfo->BufferSize = bufferNeeded; wmiRegInfo->RegistryPath = registryPathOffset; wmiRegInfo->GuidCount = 1; wmiRegInfo->WmiRegGuid[0].Guid = *cb->Registration.ControlGuid; wmiRegInfo->WmiRegGuid[0].Flags = WMIREG_FLAG_TRACE_CONTROL_GUID | WMIREG_FLAG_TRACED_GUID; stringPtr = (PWCHAR)((PUCHAR)Buffer + registryPathOffset); *stringPtr++ = regPath->Length; RtlCopyMemory(stringPtr, regPath->Buffer, regPath->Length); status = STATUS_SUCCESS; *Size = bufferNeeded; } else { status = STATUS_BUFFER_TOO_SMALL; if (BufferLength >= sizeof(ULONG)) { *((PULONG)Buffer) = bufferNeeded; *Size = sizeof(ULONG); } } #ifdef WPP_GLOBALLOGGER // Check if Global logger is active WppInitGlobalLogger(cb->Registration.ControlGuid, (PTRACEHANDLE)&cb->Control.Logger, &cb->Control.Flags[0], &cb->Control.Level); #endif //#ifdef WPP_GLOBALLOGGER break; } case IRP_MN_ENABLE_EVENTS: case IRP_MN_DISABLE_EVENTS: { PWNODE_HEADER Wnode = (PWNODE_HEADER)Buffer; ULONG Level; ULONG ReturnLength ; if (cb == NULL ) { status = STATUS_WMI_GUID_NOT_FOUND; break; } if (BufferLength >= sizeof(WNODE_HEADER)) { status = STATUS_SUCCESS; if (minorFunction == IRP_MN_DISABLE_EVENTS) { cb->Control.Level = 0; cb->Control.Flags[0] = 0; cb->Control.Logger = 0; } else { TRACEHANDLE lh; lh = (TRACEHANDLE)( Wnode->HistoricalContext ); cb->Control.Logger = lh; #if !defined(WPP_TRACE_W2K_COMPATABILITY) if ((status = WmiQueryTraceInformation( TraceEnableLevelClass, &Level, sizeof(Level), &ReturnLength, (PVOID)Wnode)) == STATUS_SUCCESS) { cb->Control.Level = (UCHAR)Level; } status = WmiQueryTraceInformation( TraceEnableFlagsClass, &cb->Control.Flags[0], sizeof(cb->Control.Flags[0]), &ReturnLength, (PVOID)Wnode); #else // #ifndef WPP_TRACE_W2K_COMPATABILITY cb->Control.Flags[0] = WmiGetLoggerEnableFlags(lh) ; cb->Control.Level = (UCHAR)WmiGetLoggerEnableLevel(lh) ; WppDebug(0,("Enable/Disable Logger = %p, Flags = 0x%8x, Level = %x08X\n", cb->Control.Logger,cb->Control.Flags[0],cb->Control.Level)); #endif // #ifndef WPP_TRACE_W2K_COMPATABILITY } } else { status = STATUS_INVALID_PARAMETER; } break; } case IRP_MN_ENABLE_COLLECTION: case IRP_MN_DISABLE_COLLECTION: { status = STATUS_SUCCESS; break; } case IRP_MN_QUERY_ALL_DATA: case IRP_MN_QUERY_SINGLE_INSTANCE: case IRP_MN_CHANGE_SINGLE_INSTANCE: case IRP_MN_CHANGE_SINGLE_ITEM: case IRP_MN_EXECUTE_METHOD: { status = STATUS_INVALID_DEVICE_REQUEST; break; } default: { status = STATUS_INVALID_DEVICE_REQUEST; break; } } // DbgPrintEx(XX_FLTR, DPFLTR_TRACE_LEVEL, // "%!FUNC!(%!SYSCTRL!) => %!status! (size = %d)", minorFunction, status, *Size); return(status); } WPPINIT_EXPORT void WppInitKm( #if defined(WPP_TRACE_W2K_COMPATABILITY) IN PDEVICE_OBJECT pDevObject, #endif // #if defined(WPP_TRACE_W2K_COMPATABILITY) IN PUNICODE_STRING RegistryPath, IN OUT WPP_REGISTRATION_BLOCK* WppReg ) { RegistryPath; // unused while(WppReg) { WPP_TRACE_CONTROL_BLOCK *cb = (WPP_TRACE_CONTROL_BLOCK*)WppReg; NTSTATUS status ; #if !defined(WPP_TRACE_W2K_COMPATABILITY) WppReg -> Callback = WppTraceCallback; #else // #if !defined(WPP_TRACE_W2K_COMPATABILITY) WppReg -> Callback = NULL ; #endif // #if !defined(WPP_TRACE_W2K_COMPATABILITY) WppReg -> RegistryPath = NULL; cb -> FlagsLen = WppReg -> FlagsLen; cb -> Level = 0; cb -> Flags[0] = 0; #if !defined(WPP_TRACE_W2K_COMPATABILITY) status = IoWMIRegistrationControl((PDEVICE_OBJECT)WppReg, WMIREG_ACTION_REGISTER | WMIREG_FLAG_CALLBACK #else // #if !defined(WPP_TRACE_W2K_COMPATABILITY) status = IoWMIRegistrationControl(pDevObject, WMIREG_ACTION_REGISTER #endif // #if !defined(WPP_TRACE_W2K_COMPATABILITY) ); WppDebug(0,("IoWMIRegistrationControl status = %08X\n")); WppReg = WppReg->Next; } } #if !defined(WPP_TRACE_W2K_COMPATABILITY) WPPINIT_EXPORT void WppCleanupKm( WPP_REGISTRATION_BLOCK* WppReg ) { while (WppReg) { IoWMIRegistrationControl((PDEVICE_OBJECT)WppReg, WMIREG_ACTION_DEREGISTER | WMIREG_FLAG_CALLBACK ); WppReg = WppReg -> Next; } } #else // #if !defined(WPP_TRACE_W2K_COMPATABILITY) WPPINIT_EXPORT void WppCleanupKm( PDEVICE_OBJECT pDO ) { IoWMIRegistrationControl(pDO, WMIREG_ACTION_DEREGISTER ); } #endif // #if !defined(WPP_TRACE_W2K_COMPATABILITY) #if !defined(WPP_TRACE_W2K_COMPATABILITY) #define WPP_SYSTEMCONTROL(PDO) #define WPP_SYSTEMCONTROL2(PDO, offset) #else // #if !defined(WPP_TRACE_W2K_COMPATABILITY) ULONG_PTR WPP_Global_NextDeviceOffsetInDeviceExtension = -1; #define WPP_SYSTEMCONTROL(PDO) \ PDO->MajorFunction[ IRP_MJ_SYSTEM_CONTROL ] = WPPSystemControlDispatch; #define WPP_SYSTEMCONTROL2(PDO, offset) \ WPP_SYSTEMCONTROL(PDO); WPP_Global_NextDeviceOffsetInDeviceExtension = (ULONG_PTR)offset; // Routine to handle the System Control in W2K NTSTATUS WPPSystemControlDispatch( IN PDEVICE_OBJECT pDO, IN PIRP Irp ); #ifdef ALLOC_PRAGMA #pragma alloc_text( PAGE, WPPSystemControlDispatch) #endif // ALLOC_PRAGMA // Routine to handle the System Control in W2K NTSTATUS WPPSystemControlDispatch( IN PDEVICE_OBJECT pDO, IN PIRP Irp ) { PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp); ULONG BufferSize = irpSp->Parameters.WMI.BufferSize; PVOID Buffer = irpSp->Parameters.WMI.Buffer; ULONG ReturnSize = 0; NTSTATUS Status = STATUS_SUCCESS; PWNODE_HEADER Wnode=NULL; HANDLE ThreadHandle; WppDebug(0,("WPPSYSTEMCONTROL\n")); if (pDO == (PDEVICE_OBJECT)irpSp->Parameters.WMI.ProviderId) { #if defined(WPP_TRACE_W2K_COMPATABILITY) //To differentiate between the case where wmilib has already filled in parts of the buffer if (irpSp->MinorFunction == IRP_MN_REGINFO) RtlZeroMemory(Buffer, BufferSize); #endif Status = WppTraceCallback((UCHAR)(irpSp->MinorFunction), NULL, BufferSize, Buffer, &WPP_CB[0], &ReturnSize); WppDebug(0,("WPPSYSTEMCONTROL Status 0x%08X\n",Status)); Irp->IoStatus.Status = Status; Irp->IoStatus.Information = ReturnSize; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return Status; } else if (WPP_Global_NextDeviceOffsetInDeviceExtension != -1) { ULONG_PTR t; WppDebug(0,("WPPSYSTEMCONTROL - not for us\n")); // // Set current stack back one. // IoSkipCurrentIrpStackLocation( Irp ); // // Pass the call to the next driver. // t = (ULONG_PTR)pDO->DeviceExtension; t += WPP_Global_NextDeviceOffsetInDeviceExtension; return IoCallDriver((PDEVICE_OBJECT)t,Irp); } else { //unable to pass down -- what to do? //don't change irp status - IO defaults to failure return Irp->IoStatus.Status; } } #endif // #if !defined(WPP_TRACE_W2K_COMPATABILITY)