summaryrefslogtreecommitdiff
path: root/general/pcidrv/kmdf/wmi.c
blob: a0c5eba565f92de235bcff0c0384b6c122fb3237 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*++

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:

    WMI.C

Abstract:

    This module handle all the WMI Irps.

Environment:

    Kernel mode

--*/


#include "precomp.h"

#if defined(EVENT_TRACING)
#include "wmi.tmh"
#endif


#define MOFRESOURCENAME L"PciDrvWMI"

EVT_WDF_WMI_INSTANCE_QUERY_INSTANCE EvtWmiDeviceInfoQueryInstance;

EVT_WDF_WMI_INSTANCE_SET_INSTANCE EvtWmiDeviceInfoSetInstance;

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, PciDrvWmiRegistration)
#pragma alloc_text(PAGE, EvtWmiDeviceInfoQueryInstance)
#pragma alloc_text(PAGE, EvtWmiDeviceInfoSetInstance)
#endif

NTSTATUS
PciDrvWmiRegistration(
    WDFDEVICE      Device
    )
/*++
Routine Description

    Registers with WMI as a data provider for this
    instance of the device

--*/
{
    WDF_WMI_PROVIDER_CONFIG providerConfig;
    WDF_WMI_INSTANCE_CONFIG instanceConfig;
    NTSTATUS        status;
    DECLARE_CONST_UNICODE_STRING(mofRsrcName, MOFRESOURCENAME);

    PAGED_CODE();

    status = WdfDeviceAssignMofResourceName(Device, &mofRsrcName);
    if (!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                     "WdfDeviceAssignMofResourceName failed 0x%x", status);
        return status;
    }

    WDF_WMI_PROVIDER_CONFIG_INIT(&providerConfig, &PCIDRV_WMI_STD_DATA_GUID);
    providerConfig.MinInstanceBufferSize = sizeof(PCIDRV_WMI_STD_DATA);

    WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER_CONFIG(&instanceConfig, &providerConfig);
    instanceConfig.Register = TRUE;
    instanceConfig.EvtWmiInstanceQueryInstance = EvtWmiDeviceInfoQueryInstance;
    instanceConfig.EvtWmiInstanceSetInstance = EvtWmiDeviceInfoSetInstance;

    //
    // No need to get the newly creawted handle because we just reference data
    // from our device extension directly.
    //
    status = WdfWmiInstanceCreate(Device,
                                  &instanceConfig,
                                  WDF_NO_OBJECT_ATTRIBUTES,
                                  WDF_NO_HANDLE);
    if (!NT_SUCCESS(status)) {
        TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,
                     "WdfWmiInstanceCreate failed 0x%x", status);
        return status;
    }

    return status;
}

NTSTATUS
EvtWmiDeviceInfoQueryInstance(
    _In_  WDFWMIINSTANCE WmiInstance,
    _In_  ULONG OutBufferSize,
    _Out_writes_bytes_to_(OutBufferSize, *BufferUsed) PVOID OutBuffer,
    _Out_ PULONG BufferUsed
    )
{
    PFDO_DATA fdoData;

    PAGED_CODE();

    fdoData = FdoGetData(WdfWmiInstanceGetDevice(WmiInstance));

    *BufferUsed = sizeof(fdoData->CurrentAddress);
    
    if (OutBufferSize < sizeof(fdoData->CurrentAddress)) {
        return STATUS_BUFFER_TOO_SMALL;
    }

    RtlZeroMemory(OutBuffer, OutBufferSize);
    RtlCopyMemory(OutBuffer, fdoData->CurrentAddress, sizeof(fdoData->CurrentAddress));

    return STATUS_SUCCESS;
}

NTSTATUS
EvtWmiDeviceInfoSetInstance(
    _In_  WDFWMIINSTANCE WmiInstance,
    _In_  ULONG InBufferSize,
    _In_reads_bytes_(InBufferSize) PVOID InBuffer
    )
{
    PFDO_DATA fdoData;

    UNREFERENCED_PARAMETER(InBufferSize);

    PAGED_CODE();

    fdoData = FdoGetData(WdfWmiInstanceGetDevice(WmiInstance));

    if (InBufferSize < sizeof(fdoData->CurrentAddress)) {
        return STATUS_WMI_SET_FAILURE;
    }

    RtlCopyMemory(fdoData->CurrentAddress, InBuffer, sizeof(fdoData->CurrentAddress));

    return STATUS_SUCCESS;
}