⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbfx2lk_sysctrl.cpp

📁 基于vc++6.0环境的cypress USB 驱动源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////
//
//    (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 + -