📄 usbfx2lk_sysctrl.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright 2005 OSR Open Systems Resources, Inc.
// All Rights Reserved
//
// This sofware is supplied for instructional purposes only.
//
// OSR Open Systems Resources, Inc. (OSR) expressly disclaims any warranty
// for this software. THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
// THE IMPLIED WARRANTIES OF MECHANTABILITY OR FITNESS FOR A PARTICULAR
// PURPOSE. THE ENTIRE RISK ARISING FROM THE USE OF THIS SOFTWARE REMAINS
// WITH YOU. OSR's entire liability and your exclusive remedy shall not
// exceed the price paid for this material. In no event shall OSR or its
// suppliers be liable for any damages whatsoever (including, without
// limitation, damages for loss of business profit, business interruption,
// loss of business information, or any other pecuniary loss) arising out
// of the use or inability to use this software, even if OSR has been
// advised of the possibility of such damages. Because some states/
// jurisdictions do not allow the exclusion or limitation of liability for
// consequential or incidental damages, the above limitation may not apply
// to you.
//
// OSR Open Systems Resources, Inc.
// 105 Route 101A Suite 19
// Amherst, NH 03031 (603) 595-6500 FAX: (603) 595-6503
// email bugs to: bugs@osr.com
//
//
// MODULE:
//
// USBFx2LK_SysCtrl.cpp
//
// ABSTRACT:
//
// This file contains the routines that handle IRP_MJ_SYSTEM_CONTROL processing for the
// OSR USB FX2 Learning Kit Device
//
// AUTHOR(S):
//
// OSR Open Systems Resources, Inc.
//
///////////////////////////////////////////////////////////////////////////////
#include "usbfx2lk.h"
#define INITGUID
#include <wdmguid.h>
#ifdef WPP_TRACING
//
// Include the necessary tmh file - this is
// just a matter of course if you're using WPP tracing.
//
extern "C" {
#include "usbfx2lk_sysctrl.tmh"
}
#endif
#ifdef USE_BINARY_MOF_QUERY
UCHAR UsbFx2LkBinaryMofData[] = {
#include "UsbFx2Lk.dat"
};
#else
#define MOFRESOURCENAME L"MofResourceName"
#endif
extern UNICODE_STRING GlobalRegistryPath;
#define UsbFx2LkPerformanceCountGuidIndex 0
#define UsbFx2LkBinaryMofGuidGuidIndex 1
#define UsbFx2LkDeviceWakeEnableGuidIndex 2
#define UsbFx2LkSelectiveSuspendEnabledGuidIndex 3
GUID UsbFx2LkPerformanceGuid = USBFX2LK_STATISTICSGuid;
GUID UsbFx2LkBinaryMofGuid = MSWmi_MofDataGuid;
//
// Return the list of the GUID's we support of WMI.
//
//
// You'll notice that if we're building for Win2K
// and we're doing WPP tracing, we need to add
// the WPP_TRACE_CONTROL_NULL_GUID. What this
// does is simply reserve space within the
// GUID structure for the tracing GUID that the
// WPP code will add to the structure.
//
WMIGUIDREGINFO UsbFx2LkWmiGuidList[] =
{
{
&UsbFx2LkPerformanceGuid, 1, 0 // performance information
},
{
&UsbFx2LkBinaryMofGuid, 1,
#ifdef USE_BINARY_MOF_QUERY
0
#else
WMIREG_FLAG_REMOVE_GUID
#endif
},
{
&GUID_POWER_DEVICE_WAKE_ENABLE,1,0 // wait wake
},
{
&GUID_POWER_DEVICE_ENABLE, 1, 0 // Selective Suspend
}
#ifdef WPP_TRACING
#ifdef W2K
,
{
&WPP_TRACE_CONTROL_NULL_GUID, 1, 0
}
#endif
#endif
};
#define USBFX2LKGUIDCOUNT (sizeof(UsbFx2LkWmiGuidList) / sizeof(WMIGUIDREGINFO))
//
// Forward Definitions
//
NTSTATUS UsbFx2LkWmiQueryDataBlock(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG GuidIndex,
IN ULONG InstanceIndex,
IN ULONG InstanceCount,
IN OUT PULONG InstanceLengthArray,
IN ULONG OutBufferSize,
OUT PUCHAR Buffer);
NTSTATUS UsbFx2LkWmiQueryRegInfo(IN PDEVICE_OBJECT DeviceObject,
OUT ULONG *RegFlags,
OUT PUNICODE_STRING InstanceName,
OUT PUNICODE_STRING *RegistryPath,
OUT PUNICODE_STRING MofResourceName,
OUT PDEVICE_OBJECT *Pdo);
NTSTATUS UsbFx2LkWmiSetDataBlock(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN ULONG GuidIndex,
IN ULONG InstanceIndex,
IN ULONG BufferSize,
IN PUCHAR Buffer);
///////////////////////////////////////////////////////////////////////////////
//
// UsbFx2LkWmiRegistration
//
// Registers with WMI as a data provider for this instance of the device.
//
// Inputs:
//
// PDevExt - Device object extension for this request.
//
// Outputs:
// None.
//
// Returns:
//
// STATUS_SUCCESS if successful, error otherwise.
//
// IRQL:
//
// IRQL == PASSIVE_LEVEL.
//
// Notes:
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS UsbFx2LkWmiRegistration(PUSBFX2LK_EXT PDevExt)
{
NTSTATUS status;
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_WMI_INFO,("UsbFx2LkWmiRegistration: Entered\n"));
//
// Indicate how may GUID's we support.
//
PDevExt->WmiLibInfo.GuidCount = USBFX2LKGUIDCOUNT;
ASSERT(0 != PDevExt->WmiLibInfo.GuidCount);
//
// Register our WMI Handlers for each request.
//
PDevExt->WmiLibInfo.GuidList = UsbFx2LkWmiGuidList;
PDevExt->WmiLibInfo.QueryWmiRegInfo = UsbFx2LkWmiQueryRegInfo;
PDevExt->WmiLibInfo.QueryWmiDataBlock = UsbFx2LkWmiQueryDataBlock;
PDevExt->WmiLibInfo.SetWmiDataBlock = UsbFx2LkWmiSetDataBlock;
//
// We support SetWmiDataBlock, which is sufficient for our
// needs. The DDK recommends only supporting SetWmiDataItem
// if your application specifically requires support for it,
// so we're just not going to deal with it.
//
PDevExt->WmiLibInfo.SetWmiDataItem = NULL;
//
// We don't have any WMI methods.
//
PDevExt->WmiLibInfo.ExecuteWmiMethod = NULL;
//
// And we don't have any WMI events or "expensive data"
//
PDevExt->WmiLibInfo.WmiFunctionControl = NULL;
//
// Register with WMI
//
status = IoWMIRegistrationControl(PDevExt->FunctionalDeviceObject,
WMIREG_ACTION_REGISTER);
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_WMI_INFO,("UsbFx2LkWmiRegistration: Exit.\n"));
return status;
}
///////////////////////////////////////////////////////////////////////////////
//
// UsbFx2LkWmiDeRegistration
//
// Inform WMI to remove this DeviceObject from its
// list of providers. This function also
// decrements the reference count of the deviceobject.
//
// Inputs:
//
// FdoData - Device object extension for this request.
//
// Outputs:
// None.
//
// Returns:
//
// STATUS_SUCCESS if successful, error otherwise.
//
// IRQL:
//
// IRQL == PASSIVE_LEVEL.
//
// Notes:
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS UsbFx2LkWmiDeRegistration(PUSBFX2LK_EXT PDevExt)
{
NTSTATUS status;
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_WMI_INFO,("UsbFx2LkWmiDeRegistration: Entered\n"));
//
// We're finished with WMI (i.e. we're going away, so unregister
// ourselves.
//
status = IoWMIRegistrationControl(PDevExt->FunctionalDeviceObject,
WMIREG_ACTION_DEREGISTER
);
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_WMI_INFO,("UsbFx2LkWmiDeRegistration: Exit\n"));
return status;
}
///////////////////////////////////////////////////////////////////////////////
//
// UsbFx2LkSystemControl
//
// This routine is called by the IO Manager to process a IRP_MJ_SYSTEM_CONTROL
// Irp.
//
//
// INPUTS:
//
// DeviceObject - One of our Device Objects.
// Irp - The Irp to process.
//
// OUTPUTS:
//
// None
//
// RETURNS:
//
// None
//
// IRQL:
//
// IRQL == PASSIVE_LEVEL
//
// CONTEXT:
//
// User Context
//
// NOTES:
//
// This is where we handle WMI Requests.
//
///////////////////////////////////////////////////////////////////////////////
NTSTATUS UsbFx2LkSystemControl(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
PUSBFX2LK_EXT devExt;
SYSCTL_IRP_DISPOSITION disposition;
NTSTATUS status;
PIO_STACK_LOCATION stack;
ULONG bytesReturned;
OsrTracePrint(TRACE_LEVEL_VERBOSE,OSRDBG_WMI_INFO,("UsbFx2LkSystemControl: Entered\n"));
stack = IoGetCurrentIrpStackLocation (Irp);
devExt = (PUSBFX2LK_EXT) DeviceObject->DeviceExtension;
//
// Increment the count of Outstanding IOs
//
OsrIncrementOutstandingIoCount(devExt,__FILE__,__LINE__);
#ifdef WPP_TRACING
#ifdef W2K
//
// 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)stack->Parameters.WMI.ProviderId) {
//
// If this is a REG_INFO requst 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 (stack->MinorFunction == IRP_MN_REGINFO &&
!devExt->WmiRegistered) {
RtlZeroMemory(stack->Parameters.WMI.Buffer, stack->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 for 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.
//
// IRP_MN_REGINFO_EX isn't defined for Windows 2000, so we use
// its constant value of 0xb here.
//
if (stack->MinorFunction == 0xb) {
//
// Fail the request
//
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
OsrDecrementOutstandingIoCount(devExt,__FILE__,__LINE__);
return STATUS_INVALID_DEVICE_REQUEST;
}
}
#endif // W2K
#endif //WPP_TRACING
//
// Call WMILIB to process the request.
//
status = WmiSystemControl(&devExt->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.
break;
}
case IrpNotCompleted:
{
#ifdef WPP_TRACING
#ifdef W2K
//
// If the WMILIB didn't complete the IRP, then let's
// see if WPP will
//
NTSTATUS wppStatus;
wppStatus = WPP_TRACE_CONTROL(stack->MinorFunction,
stack->Parameters.WMI.Buffer,
stack->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 //WPP_TRACING
//
// 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 (devExt->DeviceToSendIrpsTo, Irp);
break;
}
default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -