wmi.c
上传用户:zanmei2
上传日期:2010-03-06
资源大小:775k
文件大小:15k
源码类别:

通讯编程文档

开发平台:

C/C++

  1. /*++
  2. Copyright (c) 1990-2000 Microsoft Corporation All Rights Reserved
  3. Module Name:
  4.     WMI.C
  5. Abstract:
  6.     This module handle all the WMI Irps.
  7. Environment:
  8.     Kernel mode
  9. Revision History:
  10.     Eliyas Yakub Oct 26, 1998
  11. --*/
  12. #include <ntddk.h>
  13. #include <initguid.h>
  14. #include <wdmguid.h>
  15. #include <wmistr.h>
  16. #include <wmilib.h>
  17. #include "main.h"
  18. NTSTATUS
  19. ToasterSystemControl (
  20.     IN  PDEVICE_OBJECT  DeviceObject,
  21.     IN  PIRP            Irp
  22.     )
  23. /*++
  24. Routine Description
  25.     We have just received a System Control IRP.
  26.     Assume that this is a WMI IRP and
  27.     call into the WMI system library and let it handle this IRP for us.
  28. --*/
  29. {
  30. PDEVICE_EXTENSION fdoData;
  31.     SYSCTL_IRP_DISPOSITION  disposition;
  32.     NTSTATUS                status;
  33.     PIO_STACK_LOCATION      stack;
  34.     PAGED_CODE();
  35.     stack = IoGetCurrentIrpStackLocation (Irp);
  36.     fdoData = ( PDEVICE_EXTENSION ) DeviceObject->DeviceExtension;
  37.     
  38.     if ( fdoData->DevicePnPState == Removed) {
  39.         Irp->IoStatus.Status = status = STATUS_DELETE_PENDING;
  40.         IoCompleteRequest (Irp, IO_NO_INCREMENT);
  41.         return status;
  42.     }
  43.     
  44.     status = WmiSystemControl(&fdoData->WmiLibInfo, 
  45.                                  DeviceObject, 
  46.                                  Irp,
  47.                                  &disposition);
  48.     switch(disposition)
  49.     {
  50.         case IrpProcessed:
  51.         {
  52.             //
  53.             // This irp has been processed and may be completed or pending.
  54.             break;
  55.         }
  56.         
  57.         case IrpNotCompleted:
  58.         {
  59.             //
  60.             // This irp has not been completed, but has been fully processed.
  61.             // we will complete it now
  62.             IoCompleteRequest(Irp, IO_NO_INCREMENT);                
  63.             break;
  64.         }
  65.         
  66.         case IrpForward:
  67.         case IrpNotWmi:
  68.         {
  69.             //
  70.             // This irp is either not a WMI irp or is a WMI irp targeted
  71.             // at a device lower in the stack.
  72.             IoSkipCurrentIrpStackLocation (Irp);
  73.             status = IoCallDriver (fdoData->NextLowerDriver, Irp);
  74.             break;
  75.         }
  76.                                     
  77.         default:
  78.         {
  79.             //
  80.             // We really should never get here, but if we do just forward....
  81.             ASSERT(FALSE);
  82.             IoSkipCurrentIrpStackLocation (Irp);
  83.             status = IoCallDriver (fdoData->NextLowerDriver, Irp);
  84.             break;
  85.         }        
  86.     }
  87.     return(status);
  88. }
  89. //--- The End   ---
  90. #if 0
  91. PCHAR
  92. WMIMinorFunctionString (
  93.     UCHAR MinorFunction
  94. );
  95. #ifdef ALLOC_PRAGMA
  96. #pragma alloc_text(PAGE,ToasterWmiRegistration)
  97. #pragma alloc_text(PAGE,ToasterWmiDeRegistration)
  98. #pragma alloc_text(PAGE,ToasterSystemControl)
  99. #pragma alloc_text(PAGE,ToasterSetWmiDataItem)
  100. #pragma alloc_text(PAGE,ToasterSetWmiDataBlock)
  101. #pragma alloc_text(PAGE,ToasterQueryWmiDataBlock)
  102. #pragma alloc_text(PAGE,ToasterQueryWmiRegInfo)
  103. #endif
  104. #define MOFRESOURCENAME L"MofResourceName"
  105. #define WMI_TOASTER_DRIVER_INFORMATION 0
  106. DEFINE_GUID (TOASTER_WMI_STD_DATA_GUID, 
  107. 0xBBA21300, 0x6DD3, 0x11d2, 0xB8, 0x44, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71);
  108. WMIGUIDREGINFO ToasterWmiGuidList[1] =
  109. {
  110.     {
  111.         &TOASTER_WMI_STD_DATA_GUID, 1, 0 // driver information
  112.     }
  113. };
  114. //
  115. // Global debug error level 
  116. //
  117. extern ULONG DebugLevel;
  118. NTSTATUS
  119. ToasterWmiRegistration(
  120.     PFDO_DATA               FdoData
  121. )
  122. /*++
  123. Routine Description
  124.     Registers with WMI as a data provider for this
  125.     instance of the device
  126. --*/
  127. {
  128.     NTSTATUS status;
  129.     
  130.     PAGED_CODE();
  131.     FdoData->WmiLibInfo.GuidCount = sizeof (ToasterWmiGuidList) /
  132.                                  sizeof (WMIGUIDREGINFO);
  133.     ASSERT (1 == FdoData->WmiLibInfo.GuidCount);
  134.     FdoData->WmiLibInfo.GuidList = ToasterWmiGuidList;
  135.     FdoData->WmiLibInfo.QueryWmiRegInfo = ToasterQueryWmiRegInfo;
  136.     FdoData->WmiLibInfo.QueryWmiDataBlock = ToasterQueryWmiDataBlock;
  137.     FdoData->WmiLibInfo.SetWmiDataBlock = ToasterSetWmiDataBlock;
  138.     FdoData->WmiLibInfo.SetWmiDataItem = ToasterSetWmiDataItem;
  139.     FdoData->WmiLibInfo.ExecuteWmiMethod = NULL;
  140.     FdoData->WmiLibInfo.WmiFunctionControl = NULL;
  141.     //
  142.     // Register with WMI
  143.     //
  144.     
  145.     status = IoWMIRegistrationControl(FdoData->Self,
  146.                              WMIREG_ACTION_REGISTER
  147.                              );
  148.     //
  149.     // Initialize the Std device data structure
  150.     //
  151.                     
  152.     FdoData->StdDeviceData.ConnectorType = TOASTER_WMI_STD_USB;
  153.     FdoData->StdDeviceData.Capacity = 2000;
  154.     FdoData->StdDeviceData.ErrorCount = 0; 
  155.     FdoData->StdDeviceData.Controls = 5;
  156.     FdoData->StdDeviceData.DebugPrintLevel = DebugLevel;
  157.     return status;
  158.     
  159. }
  160. NTSTATUS
  161. ToasterWmiDeRegistration(
  162.     PFDO_DATA               FdoData
  163. )
  164. /*++
  165. Routine Description
  166.      Inform WMI to remove this DeviceObject from its 
  167.      list of providers. This function also 
  168.      decrements the reference count of the deviceobject.
  169. --*/
  170. {
  171.     PAGED_CODE();
  172.     return IoWMIRegistrationControl(FdoData->Self,
  173.                                  WMIREG_ACTION_DEREGISTER
  174.                                  );
  175. }
  176. //
  177. // WMI System Call back functions
  178. //
  179. NTSTATUS
  180. ToasterSetWmiDataItem(
  181.     IN PDEVICE_OBJECT DeviceObject,
  182.     IN PIRP Irp,
  183.     IN ULONG GuidIndex,
  184.     IN ULONG InstanceIndex,
  185.     IN ULONG DataItemId,
  186.     IN ULONG BufferSize,
  187.     IN PUCHAR Buffer
  188.     )
  189. /*++
  190. Routine Description:
  191.     This routine is a callback into the driver to set for the contents of
  192.     a data block. When the driver has finished filling the data block it
  193.     must call WmiCompleteRequest to complete the irp. The driver can
  194.     return STATUS_PENDING if the irp cannot be completed immediately.
  195. Arguments:
  196.     DeviceObject is the device whose data block is being queried
  197.     Irp is the Irp that makes this request
  198.     GuidIndex is the index into the list of guids provided when the
  199.         device registered
  200.     InstanceIndex is the index that denotes which instance of the data block
  201.         is being queried.
  202.             
  203.     DataItemId has the id of the data item being set
  204.     BufferSize has the size of the data item passed
  205.     Buffer has the new values for the data item
  206. Return Value:
  207.     status
  208. --*/
  209. {
  210.     PFDO_DATA    fdoData;
  211.     NTSTATUS status;
  212.     
  213.     PAGED_CODE();
  214.     ToasterDebugPrint ((3, "Entered ToasterSetWmiDataItemn"));
  215.     fdoData = (PFDO_DATA) DeviceObject->DeviceExtension;
  216.     switch(GuidIndex) {
  217.     
  218.     case WMI_TOASTER_DRIVER_INFORMATION:
  219.         if(DataItemId == 5)
  220.         {
  221.            DebugLevel = fdoData->StdDeviceData.DebugPrintLevel = 
  222.                                     *((PULONG)Buffer);
  223.            status = STATUS_SUCCESS;
  224.         }
  225.         else
  226.             status = STATUS_WMI_READ_ONLY;
  227.         break;
  228.     default:
  229.         status = STATUS_WMI_GUID_NOT_FOUND;
  230.     }
  231.     status = WmiCompleteRequest(  DeviceObject,
  232.                                   Irp,
  233.                                   status,
  234.                                   0,
  235.                                   IO_NO_INCREMENT);
  236.     return status;
  237. }
  238. NTSTATUS
  239. ToasterSetWmiDataBlock(
  240.     IN PDEVICE_OBJECT DeviceObject,
  241.     IN PIRP Irp,
  242.     IN ULONG GuidIndex,
  243.     IN ULONG InstanceIndex,
  244.     IN ULONG BufferSize,
  245.     IN PUCHAR Buffer
  246.     )
  247. /*++
  248. Routine Description:
  249.     This routine is a callback into the driver to set the contents of
  250.     a data block. When the driver has finished filling the data block it
  251.     must call WmiCompleteRequest to complete the irp. The driver can
  252.     return STATUS_PENDING if the irp cannot be completed immediately.
  253. Arguments:
  254.     DeviceObject is the device whose data block is being queried
  255.     Irp is the Irp that makes this request
  256.     GuidIndex is the index into the list of guids provided when the
  257.         device registered
  258.     InstanceIndex is the index that denotes which instance of the data block
  259.         is being queried.
  260.             
  261.     BufferSize has the size of the data block passed
  262.     Buffer has the new values for the data block
  263. Return Value:
  264.     status
  265. --*/
  266. {
  267.     PFDO_DATA   fdoData;
  268.     NTSTATUS status;
  269.     PAGED_CODE();
  270.     fdoData = (PFDO_DATA) DeviceObject->DeviceExtension;
  271.     ToasterDebugPrint ((3, "Entered ToasterSetWmiDataBlockn"));
  272.     switch(GuidIndex) {
  273.     case WMI_TOASTER_DRIVER_INFORMATION:
  274.        //
  275.        // We will update only writable elements.
  276.        //
  277.        
  278.        DebugLevel = fdoData->StdDeviceData.DebugPrintLevel = 
  279.                     ((PTOASTER_WMI_STD_DATA)Buffer)->DebugPrintLevel;
  280.                     
  281.        status = STATUS_SUCCESS;
  282.         //status = STATUS_WMI_READ_ONLY;
  283.         break;
  284.     default:
  285.         status = STATUS_WMI_GUID_NOT_FOUND;
  286.     }
  287.     status = WmiCompleteRequest(  DeviceObject,
  288.                                   Irp,
  289.                                   status,
  290.                                   0,
  291.                                   IO_NO_INCREMENT);
  292.     return(status);
  293. }
  294. NTSTATUS
  295. ToasterQueryWmiDataBlock(
  296.     IN PDEVICE_OBJECT DeviceObject,
  297.     IN PIRP Irp,
  298.     IN ULONG GuidIndex,
  299.     IN ULONG InstanceIndex,
  300.     IN ULONG InstanceCount,
  301.     IN OUT PULONG InstanceLengthArray,
  302.     IN ULONG OutBufferSize,
  303.     OUT PUCHAR Buffer
  304.     )
  305. /*++
  306. Routine Description:
  307.     This routine is a callback into the driver to query for the contents of
  308.     a data block. When the driver has finished filling the data block it
  309.     must call WmiCompleteRequest to complete the irp. The driver can
  310.     return STATUS_PENDING if the irp cannot be completed immediately.
  311. Arguments:
  312.     DeviceObject is the device whose data block is being queried
  313.     Irp is the Irp that makes this request
  314.     GuidIndex is the index into the list of guids provided when the
  315.         device registered
  316.     InstanceIndex is the index that denotes which instance of the data block
  317.         is being queried.
  318.             
  319.     InstanceCount is the number of instances expected to be returned for
  320.         the data block.
  321.             
  322.     InstanceLengthArray is a pointer to an array of ULONG that returns the 
  323.         lengths of each instance of the data block. If this is NULL then
  324.         there was not enough space in the output buffer to fulfill the request
  325.         so the irp should be completed with the buffer needed.        
  326.             
  327.     BufferAvail on has the maximum size available to write the data
  328.         block.
  329.     Buffer on return is filled with the returned data block
  330. Return Value:
  331.     status
  332. --*/
  333. {
  334.     PFDO_DATA               fdoData;    
  335.     NTSTATUS    status;
  336.     ULONG       size = 0;
  337.     WCHAR       modelName[]=L"Aishverya";
  338.     USHORT      modelNameLen = (wcslen(modelName) + 1) * sizeof(WCHAR);
  339.     PAGED_CODE();
  340.     ToasterDebugPrint ((3, "Entered ToasterQueryWmiDataBlockn"));
  341.     //
  342.     // Only ever registers 1 instance per guid
  343.     ASSERT((InstanceIndex == 0) &&
  344.            (InstanceCount == 1));
  345.     
  346.     fdoData = (PFDO_DATA) DeviceObject->DeviceExtension;
  347.     switch (GuidIndex) {
  348.     case WMI_TOASTER_DRIVER_INFORMATION:
  349.         size = sizeof (TOASTER_WMI_STD_DATA) + modelNameLen + sizeof(USHORT);
  350.         if (OutBufferSize < size ) {
  351.             status = STATUS_BUFFER_TOO_SMALL;
  352.             break;
  353.         }
  354.         * (PTOASTER_WMI_STD_DATA) Buffer = fdoData->StdDeviceData;
  355.         Buffer += sizeof (TOASTER_WMI_STD_DATA);
  356.         *((PUSHORT)Buffer) = modelNameLen ;// put length of string ahead of string
  357.         Buffer = (PUCHAR)Buffer + sizeof(USHORT);   // advance past string length
  358.         RtlCopyBytes((PVOID)Buffer, (PVOID)modelName, modelNameLen);
  359.         *InstanceLengthArray = size ;
  360.         status = STATUS_SUCCESS;
  361.         break;
  362.     default:
  363.         status = STATUS_WMI_GUID_NOT_FOUND;
  364.     }
  365.     status = WmiCompleteRequest(  DeviceObject,
  366.                                   Irp,
  367.                                   status,
  368.                                   size,
  369.                                   IO_NO_INCREMENT);
  370.     return status;
  371. }
  372. NTSTATUS
  373. ToasterQueryWmiRegInfo(
  374.     IN PDEVICE_OBJECT DeviceObject,
  375.     OUT ULONG *RegFlags,
  376.     OUT PUNICODE_STRING InstanceName,
  377.     OUT PUNICODE_STRING *RegistryPath,
  378.     OUT PUNICODE_STRING MofResourceName,
  379.     OUT PDEVICE_OBJECT *Pdo     
  380.     )
  381. /*++
  382. Routine Description:
  383.     This routine is a callback into the driver to retrieve the list of
  384.     guids or data blocks that the driver wants to register with WMI. This
  385.     routine may not pend or block. Driver should NOT call
  386.     WmiCompleteRequest.
  387. Arguments:
  388.     DeviceObject is the device whose data block is being queried
  389.     *RegFlags returns with a set of flags that describe the guids being
  390.         registered for this device. If the device wants enable and disable
  391.         collection callbacks before receiving queries for the registered
  392.         guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the
  393.         returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case
  394.         the instance name is determined from the PDO associated with the
  395.         device object. Note that the PDO must have an associated devnode. If
  396.         WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique
  397.         name for the device.
  398.     InstanceName returns with the instance name for the guids if
  399.         WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The
  400.         caller will call ExFreePool with the buffer returned.
  401.     *RegistryPath returns with the registry path of the driver
  402.     *MofResourceName returns with the name of the MOF resource attached to
  403.         the binary file. If the driver does not have a mof resource attached
  404.         then this can be returned as NULL.
  405.     *Pdo returns with the device object for the PDO associated with this
  406.         device if the WMIREG_FLAG_INSTANCE_PDO flag is returned in 
  407.         *RegFlags.
  408. Return Value:
  409.     status
  410. --*/
  411. {
  412.     PFDO_DATA fdoData;
  413.     PAGED_CODE();
  414.     ToasterDebugPrint ((3, "Entered ToasterQueryWmiRegInfon"));
  415.     fdoData = DeviceObject->DeviceExtension;
  416.     *RegFlags = WMIREG_FLAG_INSTANCE_PDO;
  417.     *RegistryPath = &Globals.RegistryPath;
  418.     *Pdo = fdoData->UnderlyingPDO;
  419.     RtlInitUnicodeString(MofResourceName, MOFRESOURCENAME);
  420.     
  421.     return STATUS_SUCCESS;
  422. }
  423. #if DBG
  424. PCHAR
  425. WMIMinorFunctionString (
  426.     UCHAR MinorFunction
  427. )
  428. {
  429.     switch (MinorFunction)
  430.     {
  431.         case IRP_MN_CHANGE_SINGLE_INSTANCE:
  432.             return "IRP_MN_CHANGE_SINGLE_INSTANCE";
  433.         case IRP_MN_CHANGE_SINGLE_ITEM:
  434.             return "IRP_MN_CHANGE_SINGLE_ITEM";
  435.         case IRP_MN_DISABLE_COLLECTION:
  436.             return "IRP_MN_DISABLE_COLLECTION";
  437.         case IRP_MN_DISABLE_EVENTS:
  438.             return "IRP_MN_DISABLE_EVENTS";
  439.         case IRP_MN_ENABLE_COLLECTION:
  440.             return "IRP_MN_ENABLE_COLLECTION";
  441.         case IRP_MN_ENABLE_EVENTS:
  442.             return "IRP_MN_ENABLE_EVENTS";
  443.         case IRP_MN_EXECUTE_METHOD:
  444.             return "IRP_MN_EXECUTE_METHOD";
  445.         case IRP_MN_QUERY_ALL_DATA:
  446.             return "IRP_MN_QUERY_ALL_DATA";
  447.         case IRP_MN_QUERY_SINGLE_INSTANCE:
  448.             return "IRP_MN_QUERY_SINGLE_INSTANCE";
  449.         case IRP_MN_REGINFO:
  450.             return "IRP_MN_REGINFO";
  451.         default:
  452.             return "IRP_MN_?????";
  453.     }
  454. }
  455. #endif
  456. #endif