// system control NTSTATUS AppleKeyboardSystemControl(__in PDEVICE_OBJECT pDeviceObject,__in PIRP pIrp) { CDeviceExtension* pDevExt = static_cast<CDeviceExtension*>(pDeviceObject->DeviceExtension); AppleDebugPrint(DBGLEVEL_INFO,"Enter AppleKeyboardSystemControl %p,%p\n",pDeviceObject,pIrp); SYSCTL_IRP_DISPOSITION disposition; NTSTATUS statusRet = WmiSystemControl(&pDevExt->m_wmiLibContext,pDeviceObject,pIrp,&disposition); switch(disposition) { case IrpProcessed: break; case IrpNotCompleted: IoCompleteRequest(pIrp,IO_NO_INCREMENT); break; case IrpNotWmi: case IrpForward: IoSkipCurrentIrpStackLocation(pIrp); statusRet = IoCallDriver(pDevExt->m_pLowerDevice,pIrp); break; default: ASSERT(FALSE); break; } AppleDebugPrint(DBGLEVEL_INFO,"Leave AppleKeyboardSystemControl 0x%08x\n",statusRet); return statusRet; }
NTSTATUS BulkUsb_DispatchSysCtrl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PTDeviceExtension deviceExtension; SYSCTL_IRP_DISPOSITION disposition; NTSTATUS ntStatus; PIO_STACK_LOCATION irpStack; PAGED_CODE(); irpStack = IoGetCurrentIrpStackLocation (Irp); deviceExtension = (PTDeviceExtension) DeviceObject->DeviceExtension; if(REMOVED == deviceExtension->DeviceState) { ntStatus = STATUS_DELETE_PENDING; Irp->IoStatus.Status = ntStatus; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return ntStatus; } BulkUsb_DbgPrint(3, ("file bulkwmi: BulkUsb_DispatchSysCtrl::\n")); BulkUsb_IoIncrement(deviceExtension); ntStatus = WmiSystemControl(&deviceExtension->WmiLibInfo, DeviceObject, Irp, &disposition); switch(disposition) { case IrpProcessed: break; case IrpNotCompleted: IoCompleteRequest(Irp, IO_NO_INCREMENT); break; case IrpForward: case IrpNotWmi: IoSkipCurrentIrpStackLocation (Irp); ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); break; default: IoSkipCurrentIrpStackLocation (Irp); ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); break; } BulkUsb_DbgPrint(3, ("file bulkwmi: BulkUsb_DispatchSysCtrl::\n")); BulkUsb_IoDecrement(deviceExtension); return ntStatus; }
NTSTATUS Bus_SystemControl ( __in PDEVICE_OBJECT DeviceObject, __in PIRP Irp ) /*++ Routine Description We have just received a System Control IRP. Assume that this is a WMI IRP and call into the WMI system library and let it handle this IRP for us. --*/ { PFDO_DEVICE_DATA fdoData; SYSCTL_IRP_DISPOSITION disposition; NTSTATUS status; PIO_STACK_LOCATION stack; PCOMMON_DEVICE_DATA commonData; PAGED_CODE(); KdPrint(("Bus SystemControl\r\n")); stack = IoGetCurrentIrpStackLocation (Irp); commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension; if (!commonData->IsFDO) { // // The PDO, just complete the request with the current status // Bus_KdPrint (commonData, BUS_DBG_WMI_TRACE, ("PDO %s\n", WMIMinorFunctionString(stack->MinorFunction))); status = Irp->IoStatus.Status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } fdoData = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension; Bus_KdPrint (fdoData, BUS_DBG_WMI_TRACE, ("FDO: %s\n", WMIMinorFunctionString(stack->MinorFunction))); Bus_IncIoCount (fdoData); if (fdoData->DevicePnPState == Deleted) { Irp->IoStatus.Status = status = STATUS_NO_SUCH_DEVICE ; IoCompleteRequest (Irp, IO_NO_INCREMENT); Bus_DecIoCount (fdoData); return status; } status = WmiSystemControl(&fdoData->WmiLibInfo, DeviceObject, Irp, &disposition); switch(disposition) { case IrpProcessed: { // // This irp has been processed and may be completed or pending. break; } case IrpNotCompleted: { // // This irp has not been completed, but has been fully processed. // we will complete it now IoCompleteRequest(Irp, IO_NO_INCREMENT); break; } case IrpForward: case IrpNotWmi: { // // This irp is either not a WMI irp or is a WMI irp targetted // at a device lower in the stack. IoSkipCurrentIrpStackLocation (Irp); status = IoCallDriver (fdoData->NextLowerDriver, Irp); break; } default: { // // We really should never get here, but if we do just forward.... ASSERT(FALSE); IoSkipCurrentIrpStackLocation (Irp); status = IoCallDriver (fdoData->NextLowerDriver, Irp); break; } } Bus_DecIoCount (fdoData); return(status); }
NTSTATUS NTAPI FreeBT_DispatchSysCtrl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PDEVICE_EXTENSION deviceExtension; SYSCTL_IRP_DISPOSITION disposition; NTSTATUS ntStatus; PIO_STACK_LOCATION irpStack; PAGED_CODE(); irpStack = IoGetCurrentIrpStackLocation (Irp); deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; FreeBT_DbgPrint(3, ("FBTUSB: ")); FreeBT_DbgPrint(3, (WMIMinorFunctionString(irpStack->MinorFunction))); if (Removed == deviceExtension->DeviceState) { ntStatus = STATUS_DELETE_PENDING; Irp->IoStatus.Status = ntStatus; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return ntStatus; } FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchSysCtrl::")); FreeBT_IoIncrement(deviceExtension); ntStatus = WmiSystemControl(&deviceExtension->WmiLibInfo, DeviceObject, Irp, &disposition); switch(disposition) { case IrpProcessed: { // This irp has been processed and may be completed or pending. break; } case IrpNotCompleted: { // This irp has not been completed, but has been fully processed. // we will complete it now IoCompleteRequest(Irp, IO_NO_INCREMENT); break; } case IrpForward: case IrpNotWmi: { // This irp is either not a WMI irp or is a WMI irp targeted // at a device lower in the stack. IoSkipCurrentIrpStackLocation (Irp); ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); break; } default: { // We really should never get here, but if we do just forward.... ASSERT(FALSE); IoSkipCurrentIrpStackLocation (Irp); ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject, Irp); break; } } FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_DispatchSysCtrl::")); FreeBT_IoDecrement(deviceExtension); return ntStatus; }
NTSTATUS NdasPortFdoDispatchSystemControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS status; PNDASPORT_FDO_EXTENSION FdoExtension; SYSCTL_IRP_DISPOSITION disposition; PIO_STACK_LOCATION irpStack; ULONG isRemoved; FdoExtension = (PNDASPORT_FDO_EXTENSION) DeviceObject->DeviceExtension; irpStack = IoGetCurrentIrpStackLocation(Irp); isRemoved = NpAcquireRemoveLock(FdoExtension->CommonExtension, Irp); if (isRemoved) { return NpReleaseRemoveLockAndCompleteIrp( FdoExtension->CommonExtension, Irp, STATUS_NO_SUCH_DEVICE); } #ifdef RUN_WPP #ifdef WPP_TRACE_W2K_COMPATABILITY // // One of the mythical things that people tell you that // you need to do to get WPP tracing to work on Windows // 2000 is to call the WPP_SYSTEMCONTROL macro in your // DriverEntry entry point. The problem with this is that // what is does is actually trash your IRP_MJ_SYSTEM_CONTROL // entry point, meaning that you can no longer expose your // driver through WMI. What we will do to get around this // is to incorporate a call to the function that the WPP // IRP_MJ_SYSTEM_CONTROL handler calls in order to handle // WPP data. By doing this, we can satisfy WPP while // also supporting our own WMI data. // // You can find the code for the WPP SYSTEM_CONTROL // handler (WPPSystemControlDispatch) in the km-init.tpl // file located in the DDK's bin\wppconfig directory. // if (DeviceObject == (PDEVICE_OBJECT)irpStack->Parameters.WMI.ProviderId) { // // If this is a REG_INFO request and we have not registered // with WMI yet, we must zero the buffer. The reason for this // is that the WPP code will just blindly use it without // verifying any of the members of the structure. We learned // this trick from the WPPSystemControl handler code in // km-init.tpl // if (irpStack->MinorFunction == IRP_MN_REGINFO && !FdoExtension->IsWmiRegistered) { RtlZeroMemory( irpStack->Parameters.WMI.Buffer, irpStack->Parameters.WMI.BufferSize); } // // Yet another nice thing about trying to get tracing and WMI // support working is that we can NOT allow an IRP_MN_REGINFO_EX // request to get to the WMI library, we must do the registering // of WMI through an IRP_MN_REGINFO request. // // Why? Because the W2K tracing code has no idea what an // IRP_MN_REGINFO_EX is, so it will refuse to setup the // parts necessary for WPP tracing support. So, if // we see an IRP_MN_REGINFO_EX request come in and we're // built for Windows 2000, that means that we need to // reject it to force the code to send us an IRP_MN_REGINFO // request instead. // // IRP_MN_REGINFO_EX isn't defined for Windows 2000, so we use // its constant value of 0xb here. // if (IRP_MN_REGINFO_EX == irpStack->MinorFunction) { // // Fail the request // return NpReleaseRemoveLockAndCompleteIrpEx( FdoExtension->CommonExtension, Irp, STATUS_INVALID_DEVICE_REQUEST, 0, IO_NO_INCREMENT); } } #endif // W2K #endif //RUN_WPP // // Call WMILIB to process the request. // status = WmiSystemControl( &FdoExtension->WmiLibInfo, DeviceObject, Irp, &disposition); // // Check the disposition of the request, so that we can determine // what to do. // switch(disposition) { case IrpProcessed: { // // This IRP has been processed and may be completed or pending. // // // DispatchWmiXXXX routine is responsible to hold the remove lock. // WmiRoutine or our DispatchWmiXXX may later complete the IRP. // We just release our remove lock here. // NpReleaseRemoveLock( FdoExtension->CommonExtension, Irp); return status; } case IrpNotCompleted: { NTSTATUS wppStatus = STATUS_SUCCESS; #ifdef RUN_WPP #ifdef WPP_TRACE_W2K_COMPATABILITY ULONG bytesReturned; // // If the WMILIB didn't complete the IRP, then let's // see if WPP will. // KdPrint(("NDASPORT.SYS: WPP_TRACE_CONTROL (MN=%X)\n", irpStack->MinorFunction)); wppStatus = WPP_TRACE_CONTROL( irpStack->MinorFunction, irpStack->Parameters.WMI.Buffer, irpStack->Parameters.WMI.BufferSize, bytesReturned); if (!NT_SUCCESS(status) && NT_SUCCESS(wppStatus)) { // // WMILIB failed the IRP, but WPP completed it // with success. Therefore, we'll change the IRP's // status and bytes returned count to what WPP // would like them to be. // Irp->IoStatus.Status = wppStatus; Irp->IoStatus.Information = bytesReturned; status = wppStatus; } #endif // W2K #endif //RUN_WPP // // This IRP has not been completed, but has been fully processed. // we will complete it now. // return NpReleaseRemoveLockAndCompleteIrp( FdoExtension->CommonExtension, Irp, wppStatus); } case IrpForward: case IrpNotWmi: { // // This IRP is either not a WMI IRP or is a WMI IRP targeted // at a device lower in the stack. return NpReleaseRemoveLockAndForwardIrp( FdoExtension->CommonExtension, Irp); } default: { // // We really should never get here, but if we do just forward.... // ASSERTMSG("Unkown SYSCTL_IRP_DISPOSITION from WmiSystemControl", FALSE); return NpReleaseRemoveLockAndForwardIrp( FdoExtension->CommonExtension, Irp); } } }
NTSTATUS PciDrvSystemControl ( PDEVICE_OBJECT DeviceObject, PIRP Irp ) /*++ Routine Description We have just received a System Control IRP. Assume that this is a WMI IRP and call into the WMI system library and let it handle this IRP for us. --*/ { PFDO_DATA fdoData; SYSCTL_IRP_DISPOSITION disposition; NTSTATUS status; PIO_STACK_LOCATION stack; PAGED_CODE(); stack = IoGetCurrentIrpStackLocation (Irp); DebugPrint(TRACE, DBG_WMI, "FDO %s\n", WMIMinorFunctionString(stack->MinorFunction)); fdoData = (PFDO_DATA) DeviceObject->DeviceExtension; PciDrvPowerUpDevice(fdoData, TRUE); PciDrvIoIncrement (fdoData); if (fdoData->DevicePnPState == Deleted) { Irp->IoStatus.Status = status = STATUS_NO_SUCH_DEVICE; IoCompleteRequest (Irp, IO_NO_INCREMENT); PciDrvIoDecrement (fdoData); return status; } status = WmiSystemControl(&fdoData->WmiLibInfo, DeviceObject, Irp, &disposition); // // Following code is required if we want to do tracing in WIN2K. // Tracing is enabled or disabled explicitly by sending WMI // control events on Win2K. // #if defined(WIN2K) && defined(EVENT_TRACING) if (disposition != IrpProcessed && DeviceObject == (PDEVICE_OBJECT)stack->Parameters.WMI.ProviderId) { ULONG returnSize = 0; DebugPrint(INFO, DBG_WMI, "Calling WPP_TRACE_CONTROL\n"); WPP_TRACE_CONTROL(stack->MinorFunction, stack->Parameters.WMI.Buffer, stack->Parameters.WMI.BufferSize, returnSize); } #endif switch(disposition) { case IrpProcessed: { // // This irp has been processed and may be completed or pending. break; } case IrpNotCompleted: { // // This irp has not been completed, but has been fully processed. // we will complete it now IoCompleteRequest(Irp, IO_NO_INCREMENT); break; } case IrpForward: case IrpNotWmi: { // // This irp is either not a WMI irp or is a WMI irp targeted // at a device lower in the stack. IoSkipCurrentIrpStackLocation (Irp); status = IoCallDriver (fdoData->NextLowerDriver, Irp); break; } default: { // // We really should never get here, but if we do just forward.... ASSERT(FALSE); IoSkipCurrentIrpStackLocation (Irp); status = IoCallDriver (fdoData->NextLowerDriver, Irp); break; } } PciDrvIoDecrement(fdoData); return(status); }