/*++ Copyright (c) 2000 Microsoft Corporation Module Name: vfwmi.c Abstract: This module handles System Control Irp verification. Author: Adrian J. Oney (adriao) 20-Apr-1998 Environment: Kernel mode Revision History: AdriaO 06/15/2000 - Seperated out from ntos\io\flunkirp.c --*/ #include "vfdef.h" #ifdef ALLOC_PRAGMA #pragma alloc_text(INIT, VfWmiInit) #pragma alloc_text(PAGEVRFY, VfWmiDumpIrpStack) #pragma alloc_text(PAGEVRFY, VfWmiVerifyNewRequest) #pragma alloc_text(PAGEVRFY, VfWmiVerifyIrpStackDownward) #pragma alloc_text(PAGEVRFY, VfWmiVerifyIrpStackUpward) #pragma alloc_text(PAGEVRFY, VfWmiTestStartedPdoStack) #endif #ifdef ALLOC_DATA_PRAGMA #pragma const_seg("PAGEVRFC") #endif const PCHAR WmiIrpNames[] = { "IRP_MN_QUERY_ALL_DATA", // 0x00 "IRP_MN_QUERY_SINGLE_INSTANCE", // 0x01 "IRP_MN_CHANGE_SINGLE_INSTANCE", // 0x02 "IRP_MN_CHANGE_SINGLE_ITEM", // 0x03 "IRP_MN_ENABLE_EVENTS", // 0x04 "IRP_MN_DISABLE_EVENTS", // 0x05 "IRP_MN_ENABLE_COLLECTION", // 0x06 "IRP_MN_DISABLE_COLLECTION", // 0x07 "IRP_MN_REGINFO", // 0x08 "IRP_MN_EXECUTE_METHOD", // 0x09 NULL }; #define MAX_NAMED_WMI_IRP 0x9 #ifdef ALLOC_DATA_PRAGMA #pragma const_seg() #endif // ALLOC_DATA_PRAGMA VOID VfWmiInit( VOID ) { VfMajorRegisterHandlers( IRP_MJ_SYSTEM_CONTROL, VfWmiDumpIrpStack, VfWmiVerifyNewRequest, VfWmiVerifyIrpStackDownward, VfWmiVerifyIrpStackUpward, NULL, NULL, NULL, NULL, NULL, NULL, VfWmiTestStartedPdoStack ); } VOID FASTCALL VfWmiVerifyNewRequest( IN PIOV_REQUEST_PACKET IovPacket, IN PDEVICE_OBJECT DeviceObject, IN PIO_STACK_LOCATION IrpLastSp OPTIONAL, IN PIO_STACK_LOCATION IrpSp, IN PIOV_STACK_LOCATION StackLocationData, IN PVOID CallerAddress OPTIONAL ) { PIRP irp = IovPacket->TrackedIrp; NTSTATUS currentStatus; UNREFERENCED_PARAMETER (IrpSp); UNREFERENCED_PARAMETER (IrpLastSp); UNREFERENCED_PARAMETER (DeviceObject); currentStatus = irp->IoStatus.Status; // // Verify new IRPs start out life accordingly // if (currentStatus!=STATUS_NOT_SUPPORTED) { WDM_FAIL_ROUTINE(( DCERROR_WMI_IRP_BAD_INITIAL_STATUS, DCPARAM_IRP + DCPARAM_ROUTINE, CallerAddress, irp )); // // Don't blame anyone else for this guy's mistake. // if (!NT_SUCCESS(currentStatus)) { StackLocationData->Flags |= STACKFLAG_FAILURE_FORWARDED; } } } VOID FASTCALL VfWmiVerifyIrpStackDownward( IN PIOV_REQUEST_PACKET IovPacket, IN PDEVICE_OBJECT DeviceObject, IN PIO_STACK_LOCATION IrpLastSp OPTIONAL, IN PIO_STACK_LOCATION IrpSp, IN PIOV_STACK_LOCATION RequestHeadLocationData, IN PIOV_STACK_LOCATION StackLocationData, IN PVOID CallerAddress OPTIONAL ) { PIRP irp = IovPacket->TrackedIrp; PDRIVER_OBJECT driverObject; PIOV_SESSION_DATA iovSessionData; UNREFERENCED_PARAMETER (IrpSp); UNREFERENCED_PARAMETER (IrpLastSp); iovSessionData = VfPacketGetCurrentSessionData(IovPacket); // // Verify the IRP was forwarded properly // if (iovSessionData->ForwardMethod == SKIPPED_A_DO) { WDM_FAIL_ROUTINE(( DCERROR_SKIPPED_DEVICE_OBJECT, DCPARAM_IRP + DCPARAM_ROUTINE, CallerAddress, irp )); } // // For some IRP major's going down a stack, there *must* be a handler // driverObject = DeviceObject->DriverObject; if (!IovUtilHasDispatchHandler(driverObject, IRP_MJ_SYSTEM_CONTROL)) { RequestHeadLocationData->Flags |= STACKFLAG_BOGUS_IRP_TOUCHED; WDM_FAIL_ROUTINE(( DCERROR_MISSING_DISPATCH_FUNCTION, DCPARAM_IRP + DCPARAM_ROUTINE, driverObject->DriverInit, irp )); StackLocationData->Flags |= STACKFLAG_NO_HANDLER; } } VOID FASTCALL VfWmiVerifyIrpStackUpward( IN PIOV_REQUEST_PACKET IovPacket, IN PIO_STACK_LOCATION IrpSp, IN PIOV_STACK_LOCATION RequestHeadLocationData, IN PIOV_STACK_LOCATION StackLocationData, IN BOOLEAN IsNewlyCompleted, IN BOOLEAN RequestFinalized ) { PIRP irp; BOOLEAN mustPassDown, isBogusIrp, isPdo; PVOID routine; UNREFERENCED_PARAMETER (RequestHeadLocationData); UNREFERENCED_PARAMETER (RequestFinalized); // // Who'd we call for this one? // irp = IovPacket->TrackedIrp; routine = StackLocationData->LastDispatch; ASSERT(routine) ; // // If this "Request" has been "Completed", perform some checks // if (IsNewlyCompleted) { // // Remember bogosity... // isBogusIrp = (BOOLEAN)((IovPacket->Flags&TRACKFLAG_BOGUS)!=0); // // Is this a PDO? // isPdo = (BOOLEAN)((StackLocationData->Flags&STACKFLAG_REACHED_PDO)!=0); // // Was anything completed too early? // A driver may outright fail almost anything but a bogus IRP // mustPassDown = (BOOLEAN)(!(StackLocationData->Flags&STACKFLAG_NO_HANDLER)); mustPassDown &= (!isPdo); mustPassDown &= ((PDEVICE_OBJECT) IrpSp->Parameters.WMI.ProviderId != IrpSp->DeviceObject); if (mustPassDown) { WDM_FAIL_ROUTINE(( DCERROR_WMI_IRP_NOT_FORWARDED, DCPARAM_IRP + DCPARAM_ROUTINE + DCPARAM_DEVOBJ, routine, irp, IrpSp->Parameters.WMI.ProviderId )); } } } VOID FASTCALL VfWmiDumpIrpStack( IN PIO_STACK_LOCATION IrpSp ) { DbgPrint("IRP_MJ_SYSTEM_CONTROL."); if (IrpSp->MinorFunction <= MAX_NAMED_WMI_IRP) { DbgPrint(WmiIrpNames[IrpSp->MinorFunction]); } else if (IrpSp->MinorFunction == 0xFF) { DbgPrint("IRP_MN_BOGUS"); } else { DbgPrint("(Bogus)"); } } VOID FASTCALL VfWmiTestStartedPdoStack( IN PDEVICE_OBJECT PhysicalDeviceObject ) /*++ Description: As per the title, we are going to throw some IRPs at the stack to see if they are handled correctly. Returns: Nothing --*/ { IO_STACK_LOCATION irpSp; PAGED_CODE(); // // Initialize the stack location to pass to IopSynchronousCall() // RtlZeroMemory(&irpSp, sizeof(IO_STACK_LOCATION)); if (VfSettingsIsOptionEnabled(NULL, VERIFIER_OPTION_SEND_BOGUS_WMI_IRPS)) { // // Send a bogus WMI IRP // // Note that we shouldn't be sending this IRP to any stack that doesn't // terminate with a devnode. The WmiSystemControl export from WmiLib // says "NotWmiIrp if it sees these. The callers should still pass down // the IRP. // ASSERT(IovUtilIsPdo(PhysicalDeviceObject)); irpSp.MajorFunction = IRP_MJ_SYSTEM_CONTROL; irpSp.MinorFunction = 0xff; irpSp.Parameters.WMI.ProviderId = (ULONG_PTR) PhysicalDeviceObject; VfIrpSendSynchronousIrp( PhysicalDeviceObject, &irpSp, TRUE, STATUS_NOT_SUPPORTED, 0, NULL, NULL ); } }