summaryrefslogtreecommitdiff
path: root/wmi/wmisamp/WmiHandler.c
diff options
context:
space:
mode:
authorDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
committerDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
commit97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch)
tree46f3701832d70b420eb0fc0eb93261f9da45db3f /wmi/wmisamp/WmiHandler.c
parentef1905bf1e8825bb31120dfb27e0daf3154d859a (diff)
Initial publish
Diffstat (limited to 'wmi/wmisamp/WmiHandler.c')
-rw-r--r--wmi/wmisamp/WmiHandler.c959
1 files changed, 959 insertions, 0 deletions
diff --git a/wmi/wmisamp/WmiHandler.c b/wmi/wmisamp/WmiHandler.c
new file mode 100644
index 00000000..0ffef3a6
--- /dev/null
+++ b/wmi/wmisamp/WmiHandler.c
@@ -0,0 +1,959 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
+ EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Module Name:
+
+ WmiHandler.c
+
+Abstract:
+
+ --
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include "WmiSamp.h"
+
+#define MOFRESOURCENAME L"MofResourceName"
+
+//
+// Private methods.
+//
+
+EVT_WDF_WMI_INSTANCE_QUERY_INSTANCE EvtWmiClass1DataQueryInstance;
+EVT_WDF_WMI_INSTANCE_QUERY_INSTANCE EvtWmiClass2DataQueryInstance;
+EVT_WDF_WMI_INSTANCE_QUERY_INSTANCE EvtWmiClass3DataQueryInstance;
+EVT_WDF_WMI_INSTANCE_QUERY_INSTANCE EvtWmiClass5DataQueryInstance;
+EVT_WDF_WMI_INSTANCE_QUERY_INSTANCE EvtWmiClass6DataQueryInstance;
+
+EVT_WDF_WMI_INSTANCE_SET_ITEM EvtWmiClass1DataSetItem;
+
+EVT_WDF_WMI_INSTANCE_SET_INSTANCE EvtWmiClass1DataSetInstance;
+EVT_WDF_WMI_INSTANCE_SET_INSTANCE EvtWmiClass2DataSetInstance;
+EVT_WDF_WMI_INSTANCE_SET_INSTANCE EvtWmiClass3DataSetInstance;
+EVT_WDF_WMI_INSTANCE_SET_INSTANCE EvtWmiClass5DataSetInstance;
+EVT_WDF_WMI_INSTANCE_SET_INSTANCE EvtWmiClass6DataSetInstance;
+
+EVT_WDF_WMI_INSTANCE_EXECUTE_METHOD EvtWmiClass1ExecuteMethod;
+
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text (PAGE, WmiSampWmiRegistration)
+
+#pragma alloc_text (PAGE, EvtWmiClass1DataQueryInstance)
+#pragma alloc_text (PAGE, EvtWmiClass1DataSetInstance)
+#pragma alloc_text (PAGE, EvtWmiClass1DataSetItem)
+#pragma alloc_text (PAGE, EvtWmiClass1ExecuteMethod)
+
+#pragma alloc_text (PAGE, EvtWmiClass2DataQueryInstance)
+#pragma alloc_text (PAGE, EvtWmiClass2DataSetInstance)
+
+#pragma alloc_text (PAGE, EvtWmiClass3DataQueryInstance)
+#pragma alloc_text (PAGE, EvtWmiClass3DataSetInstance)
+
+#pragma alloc_text (PAGE, EvtWmiClass5DataQueryInstance)
+#pragma alloc_text (PAGE, EvtWmiClass5DataSetInstance)
+
+#pragma alloc_text (PAGE, EvtWmiClass6DataQueryInstance)
+#pragma alloc_text (PAGE, EvtWmiClass6DataSetInstance)
+#endif
+
+
+//
+// The SampleInstanceConfig defines an array of data set used for the creation
+// of WMI instances.
+//
+WMI_SAMPLE_INSTANCE_CONFIG SampleInstanceConfig[] = {
+ {
+ WmiSampleClass1Guid,
+ WmiSampleClass1_SIZE,
+ EvtWmiClass1DataQueryInstance,
+ EvtWmiClass1DataSetInstance,
+ EvtWmiClass1DataSetItem,
+ EvtWmiClass1ExecuteMethod
+ },
+
+ {
+ WmiSampleClass2Guid,
+ WmiSampleClass2_SIZE,
+ EvtWmiClass2DataQueryInstance,
+ EvtWmiClass2DataSetInstance,
+ NULL,
+ NULL
+ },
+
+ {
+ WmiSampleClass5Guid,
+ WmiSampleClass5_SIZE,
+ EvtWmiClass5DataQueryInstance,
+ EvtWmiClass5DataSetInstance,
+ NULL,
+ NULL
+ },
+
+ {
+ WmiSampleClass6Guid,
+ WmiSampleClass6_SIZE,
+ EvtWmiClass6DataQueryInstance,
+ EvtWmiClass6DataSetInstance,
+ NULL,
+ NULL
+ },
+};
+
+//
+// The DynamicInstanceConfig defines the data set used for the dynamic creation
+// of WMI instances.
+//
+
+WMI_SAMPLE_INSTANCE_CONFIG DynamicInstanceConfig = {
+
+ WmiSampleClass3Guid,
+ WmiSampleClass3_SIZE,
+ EvtWmiClass3DataQueryInstance,
+ EvtWmiClass3DataSetInstance,
+ NULL,
+ NULL
+};
+
+
+NTSTATUS
+WmiSampWmiRegistration(
+ _In_ WDFDEVICE Device
+ )
+
+/*++
+
+Routine Description:
+
+ This function creates WMI provider instances for handling the WMI irps to
+ the driver.
+
+Arguments:
+
+ Device - The Framework device object for which the WMI provider instances
+ are to be created and registered. This device object will be the parent
+ object of the new WMI instance objects.
+
+Return Value:
+
+ NT Status code.
+
+--*/
+
+{
+ NTSTATUS status;
+ ULONG i;
+ WDF_WMI_PROVIDER_CONFIG providerConfig;
+ WDF_WMI_INSTANCE_CONFIG instanceConfig;
+ DECLARE_CONST_UNICODE_STRING(mofResourceName, MOFRESOURCENAME);
+
+ PAGED_CODE();
+
+ //
+ // Register the MOF resource names of any customized WMI data providers
+ // that are not defined in wmicore.mof.
+ //
+ status = WdfDeviceAssignMofResourceName(Device, &mofResourceName);
+ if (!NT_SUCCESS(status)) {
+
+ DebugPrint(("[WmiSamp] Status = 0x%08x, WmiSampWmiRegistration\n", status));
+ return status;
+ }
+
+ //
+ // Create a WMI instance object for each instance of each data block that
+ // the driver supports for a device.
+ //
+ for (i = 0; i < ARRAYSIZE(SampleInstanceConfig); i++) {
+
+ //
+ // Initialize the config structures for the Provider and the Instance
+ // and define event callback functions that support a WMI client's
+ // requests to access the driver's WMI data blocks.
+ //
+
+ WDF_WMI_PROVIDER_CONFIG_INIT(&providerConfig, &SampleInstanceConfig[i].Guid);
+ providerConfig.MinInstanceBufferSize = SampleInstanceConfig[i].MinSize;
+
+ //
+ // The WDFWMIPROVIDER handle is needed if multiple instances for the provider
+ // has to be created or if the instances have to be created sometime after
+ // the provider is created. In case below, the provider handle is not needed
+ // because only one instance is needed and can be created when the provider
+ // is created.
+ //
+ WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER_CONFIG(&instanceConfig, &providerConfig);
+
+ //
+ // Create a Provider object as part of the Instance creation call by setting
+ // the Register value in the Instance Config to TRUE. This eliminates the
+ // need to call WdfWmiProviderRegister.
+ //
+ instanceConfig.Register = TRUE;
+
+ instanceConfig.EvtWmiInstanceQueryInstance = SampleInstanceConfig[i].EvtWmiInstanceQueryInstance;
+ instanceConfig.EvtWmiInstanceSetInstance = SampleInstanceConfig[i].EvtWmiInstanceSetInstance;
+ instanceConfig.EvtWmiInstanceSetItem = SampleInstanceConfig[i].EvtWmiInstanceSetItem;
+ instanceConfig.EvtWmiInstanceExecuteMethod = SampleInstanceConfig[i].EvtWmiInstanceExecuteMethod;
+
+ //
+ // Create the WMI instance object for this data block.
+ //
+ status = WdfWmiInstanceCreate(Device,
+ &instanceConfig,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ WDF_NO_HANDLE);
+
+ if (!NT_SUCCESS(status)) {
+
+ DebugPrint(("[WmiSamp] Status = 0x%08x, WmiSampWmiRegistration\n", status));
+ return status;
+ }
+
+ }
+
+ return status;
+}
+
+
+NTSTATUS
+WmiSampDynamicWmiRegistration(
+ _In_ WDFDEVICE Device
+ )
+
+/*++
+
+Routine Description:
+
+ This function creates WMI provider instance if the dynamic instance does not
+ already exist. If it does exist, this funciton deregisters and deletes the
+ WMI instance. This function assumes that the mof has already been registered
+ with the given Framework device object (by a previous call to WmiSampWmiRegistration).
+
+Arguments:
+
+ Device - The Framework device object for which a WMI provider instance
+ has to be created if the instance does not exist or deleted if the
+ instance exists.
+
+Return Value:
+
+ NT Status code.
+
+--*/
+
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PWMI_SAMPLE_DEVICE_DATA wmiDeviceData;
+ WDF_WMI_PROVIDER_CONFIG providerConfig;
+ WDF_WMI_INSTANCE_CONFIG instanceConfig;
+
+ wmiDeviceData = GetWmiSampleDeviceData(Device);
+
+ //
+ // If the dynamic provider already exists, then delete the dynamic provider
+ // and all of its instances.
+ //
+ if (wmiDeviceData->DynamicInstance) {
+
+ DebugPrint(("Delete Dynamic instance.\n"));
+
+ //
+ // Deregister the dynamic WMI Instance so that this instance does not
+ // receive any more WMI query callbacks.
+ //
+ WdfWmiInstanceDeregister(wmiDeviceData->DynamicInstance);
+
+ //
+ // Delete the dynamic WMI Instance object.
+ //
+ WdfObjectDelete(wmiDeviceData->DynamicInstance);
+ wmiDeviceData->DynamicInstance = NULL;
+
+ } else {
+
+ DebugPrint(("Create Dynamic instance.\n"));
+
+ //
+ // Initialize the config structures for the Provider and the Instance
+ // and define event callback functions that support a WMI client's
+ // requests to access the driver's WMI data blocks.
+ //
+
+ WDF_WMI_PROVIDER_CONFIG_INIT(&providerConfig, &DynamicInstanceConfig.Guid);
+ providerConfig.MinInstanceBufferSize = DynamicInstanceConfig.MinSize;
+
+ //
+ // You would want to create a WDFWMIPROVIDER handle separately if you are
+ // going to dynamically create instances on the provider. Since we are
+ // statically creating one instance, there is no need to create the provider
+ // handle.
+ //
+ WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER_CONFIG(&instanceConfig, &providerConfig);
+
+ //
+ // Create a Provider object as part of the Instance creation call by setting
+ // the Register value in the Instance Config to TRUE. This eliminates the
+ // need to call WdfWmiProviderRegister.
+ //
+ instanceConfig.Register = TRUE;
+
+ instanceConfig.EvtWmiInstanceQueryInstance = DynamicInstanceConfig.EvtWmiInstanceQueryInstance;
+ instanceConfig.EvtWmiInstanceSetInstance = DynamicInstanceConfig.EvtWmiInstanceSetInstance;
+ instanceConfig.EvtWmiInstanceSetItem = DynamicInstanceConfig.EvtWmiInstanceSetItem;
+ instanceConfig.EvtWmiInstanceExecuteMethod = DynamicInstanceConfig.EvtWmiInstanceExecuteMethod;
+
+ //
+ // Create the WMI instance object for this data block.
+ //
+ status = WdfWmiInstanceCreate(Device,
+ &instanceConfig,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &(wmiDeviceData->DynamicInstance));
+
+ if (!NT_SUCCESS(status)) {
+
+ DebugPrint(("[WmiSamp] Status = 0x%08x, WmiSampDynamicWmiRegistration\n", status));
+ return status;
+ }
+
+ //
+ // Increment the Create count if the dynamic WMI Instance was created.
+ //
+ wmiDeviceData->CreateCount++;
+
+ }
+
+ return status;
+}
+
+
+NTSTATUS
+EvtWmiClass1DataQueryInstance(
+ WDFWMIINSTANCE WmiInstance,
+ ULONG OutBufferSize,
+ PVOID OutBuffer,
+ PULONG BufferUsed
+ )
+
+/*++
+
+Routine Description:
+
+ This is the callback routine for the WMI Query irp on the Instance representing
+ the sample class 1. This routine gets the current value for the data members
+ of the sample class and copies it to the given output buffer. The sample class1
+ is made up of the same parameters as the Embedded Class EC1.
+
+Arguments:
+
+ WmiInstance - The handle to the WMI instance object.
+
+ OutBufferSize - The size (in bytes) of the output buffer into which the
+ instance data is to be copied.
+
+ OutBuffer - Pointer to the output buffer.
+
+ BufferUsed - Pointer to the location that receives the number of bytes that
+ were copied into the output buffer.
+
+Return Value:
+
+ NT Status code.
+
+--*/
+
+{
+ WDFDEVICE device;
+ PWMI_SAMPLE_DEVICE_DATA wmiDeviceData;
+
+ UNREFERENCED_PARAMETER(OutBufferSize);
+ PAGED_CODE();
+
+ device = WdfWmiInstanceGetDevice(WmiInstance);
+ wmiDeviceData = GetWmiSampleDeviceData(device);
+
+ //
+ // Plain EC1.
+ //
+ *BufferUsed = WmiSampGetEc1(wmiDeviceData,
+ OutBuffer,
+ 0);
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+EvtWmiClass1DataSetInstance(
+ WDFWMIINSTANCE WmiInstance,
+ ULONG InBufferSize,
+ PVOID InBuffer
+ )
+{
+ WDFDEVICE device;
+ PWMI_SAMPLE_DEVICE_DATA wmiDeviceData;
+
+ PAGED_CODE();
+
+ //
+ // InBufferSize is guaranteed to be at least WmiSampleClass1_SIZE
+ // which in this case is EC1_SIZE.
+ //
+ UNREFERENCED_PARAMETER(InBufferSize);
+
+ device = WdfWmiInstanceGetDevice(WmiInstance);
+ wmiDeviceData = GetWmiSampleDeviceData(device);
+
+ //
+ // Plain EC1.
+ //
+ WmiSampSetEc1(wmiDeviceData,
+ InBuffer,
+ EC1_SIZE,
+ 0);
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+EvtWmiClass1DataSetItem(
+ WDFWMIINSTANCE WmiInstance,
+ ULONG DataItemId,
+ ULONG InBufferSize,
+ PVOID InBuffer
+ )
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ PAGED_CODE();
+
+ UNREFERENCED_PARAMETER(WmiInstance);
+ UNREFERENCED_PARAMETER(DataItemId);
+ UNREFERENCED_PARAMETER(InBufferSize);
+ UNREFERENCED_PARAMETER(InBuffer);
+
+ return status;
+}
+
+
+NTSTATUS
+EvtWmiClass1ExecuteMethod(
+ WDFWMIINSTANCE WmiInstance,
+ ULONG MethodId,
+ ULONG InBufferSize,
+ ULONG OutBufferSize,
+ PVOID Buffer,
+ PULONG BufferUsed
+ )
+{
+ NTSTATUS status;
+ WDFDEVICE device;
+ PWMI_SAMPLE_DEVICE_DATA wmiDeviceData;
+
+ UNREFERENCED_PARAMETER(OutBufferSize);
+ PAGED_CODE();
+
+ device = WdfWmiInstanceGetDevice(WmiInstance);
+ wmiDeviceData = GetWmiSampleDeviceData(device);
+
+ switch (MethodId) {
+ case SetEC1:
+ {
+ if (InBufferSize >= EC1_SIZE) {
+
+ WmiSampSetEc1(wmiDeviceData,
+ Buffer,
+ EC1_SIZE,
+ 0);
+ status = STATUS_SUCCESS;
+
+ } else {
+
+ status = STATUS_INVALID_PARAMETER_MIX;
+ DebugPrint(("[WmiSamp] Status = 0x%08x, EvtWmiClass1ExecuteMethod\n", status));
+ }
+ }
+ break;
+
+ case DummyMethod:
+ status = STATUS_SUCCESS;
+ break;
+
+ default:
+ status = STATUS_WMI_ITEMID_NOT_FOUND;
+ DebugPrint(("[WmiSamp] Status = 0x%08x, EvtWmiClass1ExecuteMethod\n", status));
+ break;
+ }
+
+ *BufferUsed = 0;
+ return status;
+}
+
+
+NTSTATUS
+EvtWmiClass2DataQueryInstance(
+ WDFWMIINSTANCE WmiInstance,
+ ULONG OutBufferSize,
+ PVOID OutBuffer,
+ PULONG BufferUsed
+ )
+
+/*++
+
+Routine Description:
+
+ This is the callback routine for the WMI Query irp on the Instance representing
+ the sample class 2. This routine gets the current value for the data members
+ of the sample class and copies it to the given output buffer. The sample class2
+ contains an embedded class.
+
+Arguments:
+
+ WmiInstance - The handle to the WMI instance object.
+
+ OutBufferSize - The size (in bytes) of the output buffer into which the
+ instance data is to be copied.
+
+ OutBuffer - Pointer to the output buffer.
+
+ BufferUsed - Pointer to the location that receives the number of bytes that
+ were copied into the output buffer.
+
+Return Value:
+
+ NT Status code.
+
+--*/
+
+{
+ WDFDEVICE device;
+ PWMI_SAMPLE_DEVICE_DATA wmiDeviceData;
+
+ UNREFERENCED_PARAMETER(OutBufferSize);
+ PAGED_CODE();
+
+ device = WdfWmiInstanceGetDevice(WmiInstance);
+ wmiDeviceData = GetWmiSampleDeviceData(device);
+
+ //
+ // Plain (Embedded) EC1.
+ //
+ *BufferUsed = WmiSampGetEc1(wmiDeviceData,
+ OutBuffer,
+ 0);
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+EvtWmiClass2DataSetInstance(
+ WDFWMIINSTANCE WmiInstance,
+ ULONG InBufferSize,
+ PVOID InBuffer
+ )
+{
+ WDFDEVICE device;
+ PWMI_SAMPLE_DEVICE_DATA wmiDeviceData;
+
+ PAGED_CODE();
+
+ //
+ // InBufferSize is guaranteed to be at least WmiSampleClass2_SIZE
+ // which in this case is EC1_SIZE.
+ //
+ UNREFERENCED_PARAMETER(InBufferSize);
+
+ device = WdfWmiInstanceGetDevice(WmiInstance);
+ wmiDeviceData = GetWmiSampleDeviceData(device);
+
+ //
+ // Plain (Embedded) EC1.
+ //
+ WmiSampSetEc1(wmiDeviceData,
+ InBuffer,
+ EC1_SIZE,
+ 0);
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+EvtWmiClass3DataQueryInstance(
+ WDFWMIINSTANCE WmiInstance,
+ ULONG OutBufferSize,
+ PVOID OutBuffer,
+ PULONG BufferUsed
+ )
+
+/*++
+
+Routine Description:
+
+ This is the callback routine for the WMI Query irp on the Instance representing
+ the sample class 3. This routine gets the current value for the data members
+ of the sample class and copies it to the given output buffer. The sample class3
+ contains a fixed array of embedded class EC1.
+
+Arguments:
+
+ WmiInstance - The handle to the WMI instance object.
+
+ OutBufferSize - The size (in bytes) of the output buffer into which the
+ instance data is to be copied.
+
+ OutBuffer - Pointer to the output buffer.
+
+ BufferUsed - Pointer to the location that receives the number of bytes that
+ were copied into the output buffer.
+
+Return Value:
+
+ NT Status code.
+
+--*/
+
+{
+ NTSTATUS status;
+ WDFDEVICE device;
+ PWMI_SAMPLE_DEVICE_DATA wmiDeviceData;
+ ULONG sizeNeeded;
+ ULONG sizeUsed;
+ ULONG i;
+
+ UNREFERENCED_PARAMETER(OutBufferSize);
+ PAGED_CODE();
+
+ device = WdfWmiInstanceGetDevice(WmiInstance);
+ wmiDeviceData = GetWmiSampleDeviceData(device);
+
+ //
+ // Fixed array of EC1.
+ //
+ sizeNeeded = 0;
+ for (i = 0; i < EC1_COUNT; i++) {
+ sizeNeeded += ALIGN_UP(wmiDeviceData->Ec1Length[i], PVOID);
+ }
+
+ if (OutBufferSize < sizeNeeded) {
+
+ *BufferUsed = 0;
+ status = STATUS_BUFFER_TOO_SMALL;
+
+ } else {
+
+ *BufferUsed = 0;
+ for (i = 0; i < EC1_COUNT; i++) {
+
+ sizeUsed = WmiSampGetEc1(wmiDeviceData, OutBuffer, i);
+ OutBuffer = Add2Ptr(OutBuffer, ALIGN_UP(sizeUsed, PVOID));
+ *BufferUsed += sizeUsed;
+ }
+ status = STATUS_SUCCESS;
+ }
+
+ return status;
+}
+
+
+NTSTATUS
+EvtWmiClass3DataSetInstance(
+ WDFWMIINSTANCE WmiInstance,
+ ULONG InBufferSize,
+ PVOID InBuffer
+ )
+
+/*++
+
+Routine Description:
+
+ ---
+
+Arguments:
+
+ WmiInstance -
+ InBufferSize -
+ InBuffer -
+
+Return Value:
+
+ NT Status code.
+
+--*/
+
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ WDFDEVICE device;
+ PWMI_SAMPLE_DEVICE_DATA wmiDeviceData;
+ ULONG i;
+ PEC1 Ec1;
+
+ PAGED_CODE();
+
+ device = WdfWmiInstanceGetDevice(WmiInstance);
+ wmiDeviceData = GetWmiSampleDeviceData(device);
+
+ //
+ // Fixed array of EC1.
+ //
+ Ec1 = (PEC1)InBuffer;
+ for (i = 0; i < EC1_COUNT; i++) {
+
+ if (InBufferSize >= EC1_SIZE) {
+
+ WmiSampSetEc1(wmiDeviceData, Ec1, EC1_SIZE, i);
+ InBufferSize -= EC1_SIZE;
+ Ec1++;
+
+ } else {
+
+ status = STATUS_INVALID_PARAMETER_MIX;
+ DebugPrint(("[WmiSamp] Status = 0x%08x, EvtWmiClass3DataSetInstance\n", status));
+ }
+ }
+ return status;
+}
+
+
+NTSTATUS
+EvtWmiClass5DataQueryInstance(
+ WDFWMIINSTANCE WmiInstance,
+ ULONG OutBufferSize,
+ PVOID OutBuffer,
+ PULONG BufferUsed
+ )
+
+/*++
+
+Routine Description:
+
+ This is the callback routine for the WMI Query irp on the Instance representing
+ the sample class 5. This routine gets the current value for the data members
+ of the sample class and copies it to the given output buffer. The sample class5
+ contains an embedded class.
+
+Arguments:
+
+ WmiInstance - The handle to the WMI instance object.
+
+ OutBufferSize - The size (in bytes) of the output buffer into which the
+ instance data is to be copied.
+
+ OutBuffer - Pointer to the output buffer.
+
+ BufferUsed - Pointer to the location that receives the number of bytes that
+ were copied into the output buffer.
+
+Return Value:
+
+ NT Status code.
+
+--*/
+
+{
+ WDFDEVICE device;
+ PWMI_SAMPLE_DEVICE_DATA wmiDeviceData;
+
+ UNREFERENCED_PARAMETER(OutBufferSize);
+ PAGED_CODE();
+
+ device = WdfWmiInstanceGetDevice(WmiInstance);
+ wmiDeviceData = GetWmiSampleDeviceData(device);
+
+ //
+ // Plain (Embedded) EC2.
+ //
+ *BufferUsed = WmiSampGetEc2(wmiDeviceData,
+ OutBuffer,
+ 0);
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+EvtWmiClass5DataSetInstance(
+ WDFWMIINSTANCE WmiInstance,
+ ULONG InBufferSize,
+ PVOID InBuffer
+ )
+{
+ WDFDEVICE device;
+ PWMI_SAMPLE_DEVICE_DATA wmiDeviceData;
+
+ PAGED_CODE();
+
+ //
+ // InBufferSize is guaranteed to be at least WmiSampleClass5_SIZE
+ // which in this case is EC2_SIZE.
+ //
+ UNREFERENCED_PARAMETER(InBufferSize);
+
+ device = WdfWmiInstanceGetDevice(WmiInstance);
+ wmiDeviceData = GetWmiSampleDeviceData(device);
+
+ //
+ // Plain (Embedded) EC2.
+ //
+ WmiSampSetEc2(wmiDeviceData,
+ InBuffer,
+ EC2_SIZE,
+ 0);
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+EvtWmiClass6DataQueryInstance(
+ WDFWMIINSTANCE WmiInstance,
+ ULONG OutBufferSize,
+ PVOID OutBuffer,
+ PULONG BufferUsed
+ )
+
+/*++
+
+Routine Description:
+
+ This is the callback routine for the WMI Query irp on the Instance representing
+ the sample class 6. This routine gets the current value for the data members
+ of the sample class and copies it to the given output buffer. The sample class6
+ contains a fixed array of embedded class EC2.
+
+Arguments:
+
+ WmiInstance - The handle to the WMI instance object.
+
+ OutBufferSize - The size (in bytes) of the output buffer into which the
+ instance data is to be copied.
+
+ OutBuffer - Pointer to the output buffer.
+
+ BufferUsed - Pointer to the location that receives the number of bytes that
+ were copied into the output buffer.
+
+Return Value:
+
+ NT Status code.
+
+--*/
+
+{
+ NTSTATUS status;
+ WDFDEVICE device;
+ PWMI_SAMPLE_DEVICE_DATA wmiDeviceData;
+ ULONG sizeNeeded;
+ ULONG sizeUsed;
+ ULONG i;
+
+ UNREFERENCED_PARAMETER(OutBufferSize);
+ PAGED_CODE();
+
+ device = WdfWmiInstanceGetDevice(WmiInstance);
+ wmiDeviceData = GetWmiSampleDeviceData(device);
+
+ //
+ // Fixed array of EC2.
+ //
+ sizeNeeded = 0;
+ for (i = 0; i < EC2_COUNT; i++) {
+ sizeNeeded += ALIGN_UP(wmiDeviceData->Ec2Length[i], PVOID);
+ }
+
+ if (OutBufferSize < sizeNeeded) {
+
+ *BufferUsed = 0;
+ status = STATUS_BUFFER_TOO_SMALL;
+
+ } else {
+
+ *BufferUsed = 0;
+ for (i = 0; i < EC2_COUNT; i++) {
+
+ sizeUsed = WmiSampGetEc2(wmiDeviceData, OutBuffer, i);
+ OutBuffer = Add2Ptr(OutBuffer, ALIGN_UP(sizeUsed, PVOID));
+ *BufferUsed += sizeUsed;
+ }
+ status = STATUS_SUCCESS;
+ }
+
+ return status;
+}
+
+
+NTSTATUS
+EvtWmiClass6DataSetInstance(
+ WDFWMIINSTANCE WmiInstance,
+ ULONG InBufferSize,
+ PVOID InBuffer
+ )
+
+/*++
+
+Routine Description:
+
+ This is the callback routine for setting the WMI data provider's instance
+ data supplied by a WMI client. This routine copies the data in the input
+ buffer and updates the sample class6 data which contains a fixed array of
+ embedded class EC2.
+
+Arguments:
+
+ WmiInstance - The handle to the WMI instance object.
+
+ InBufferSize - The size (in bytes) of the input buffer from which the
+ instance data is to be copied.
+
+ InBuffer - Pointer to the input buffer.
+
+Return Value:
+
+ NT Status code.
+
+--*/
+
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ WDFDEVICE device;
+ PWMI_SAMPLE_DEVICE_DATA wmiDeviceData;
+ ULONG i;
+ PEC2 Ec2;
+
+ PAGED_CODE();
+
+ device = WdfWmiInstanceGetDevice(WmiInstance);
+ wmiDeviceData = GetWmiSampleDeviceData(device);
+
+ //
+ // Fixed array of EC2.
+ //
+ Ec2 = (PEC2)InBuffer;
+ for (i = 0; i < EC2_COUNT; i++) {
+
+ if (InBufferSize >= EC2_SIZE) {
+
+ WmiSampSetEc2(wmiDeviceData, Ec2, EC2_SIZE, i);
+ InBufferSize -= EC2_SIZE;
+ Ec2++;
+
+ } else {
+
+ status = STATUS_INVALID_PARAMETER_MIX;
+ DebugPrint(("[WmiSamp] Status = 0x%08x, EvtWmiClass6DataSetInstance\n", status));
+ }
+ }
+ return status;
+}