1 //
2 // Copyright (C) Microsoft. All rights reserved.
3 //
4 #include "fxobjectpch.hpp"
5
6 // Tracing support
7 extern "C" {
8 #if defined(EVENT_TRACING)
9 #include "globalskm.tmh"
10 #endif
11
12 // #include <wdfcxbase.h>
13 #include <fxldr.h>
14
15
16 }
17 extern "C" {
18
19 VOID
FxFreeAllocatedMdlsDebugInfo(__in FxDriverGlobalsDebugExtension * DebugExtension)20 FxFreeAllocatedMdlsDebugInfo(
21 __in FxDriverGlobalsDebugExtension* DebugExtension
22 )
23 {
24 FxAllocatedMdls* pNext, *pCur;
25
26 pNext = DebugExtension->AllocatedMdls.Next;
27
28 //
29 // MDL leaks were already checked for in FxPoolDestroy, just free all
30 // the tables here.
31 //
32 while (pNext != NULL) {
33 pCur = pNext;
34 pNext = pCur->Next;
35
36 ExFreePool(pCur);
37 }
38 }
39
40 KDEFERRED_ROUTINE FxFlushDpc;
41
42 __drv_functionClass(KDEFERRED_ROUTINE)
__drv_maxIRQL(DISPATCH_LEVEL)43 __drv_maxIRQL(DISPATCH_LEVEL)
44 __drv_minIRQL(DISPATCH_LEVEL)
45 __drv_requiresIRQL(DISPATCH_LEVEL)
46 __drv_sameIRQL
47 VOID
48 STDCALL
49 FxFlushDpc (
50 __in struct _KDPC *Dpc,
51 __in_opt PVOID DeferredContext,
52 __in_opt PVOID SystemArgument1,
53 __in_opt PVOID SystemArgument2
54 )
55
56 /*++
57
58 Routine Description:
59
60 This DPC is called on a processor to assist in flushing previous DPC's
61
62 Arguments:
63
64 Dpc - Supplies a pointer to DPC object.
65
66 DeferredContext - Supplies the deferred context (event object address).
67
68 SystemArgument1 - Supplies the first system context parameter (not used).
69
70 SystemArgument2 - Supplies the second system context parameter (not used).
71
72 Return Value:
73
74 None.
75
76 --*/
77
78 {
79
80 UNREFERENCED_PARAMETER(Dpc);
81 UNREFERENCED_PARAMETER(SystemArgument1);
82 UNREFERENCED_PARAMETER(SystemArgument2);
83
84 //
85 // Signal that this routine has been called.
86 //
87 ((FxCREvent*)DeferredContext)->Set();
88 }
89
90 _Must_inspect_result_
91 BOOLEAN
IsVersionGreaterThanOrEqualTo(__in ULONG Major,__in ULONG Minor)92 FX_DRIVER_GLOBALS::IsVersionGreaterThanOrEqualTo(
93 __in ULONG Major,
94 __in ULONG Minor
95 )
96 {
97 if ((WdfBindInfo->Version.Major > Major) ||
98 (WdfBindInfo->Version.Major == Major &&
99 WdfBindInfo->Version.Minor >= Minor)) {
100 return TRUE;
101 }
102 else {
103 return FALSE;
104 }
105 }
106
107 #define WDF_MAJOR_VERSION_VALUE L"WdfMajorVersion"
108 #define WDF_MINOR_VERSION_VALUE L"WdfMinorVersion"
109
110 _Must_inspect_result_
111 BOOLEAN
IsCorrectVersionRegistered(_In_ PCUNICODE_STRING ServiceKeyName)112 FX_DRIVER_GLOBALS::IsCorrectVersionRegistered(
113 _In_ PCUNICODE_STRING ServiceKeyName
114 )
115 {
116 FxAutoRegKey hDriver, hWdf;
117 DECLARE_CONST_UNICODE_STRING(parametersPath, L"Parameters\\Wdf");
118 DECLARE_CONST_UNICODE_STRING(wdfMajorValue, WDF_MAJOR_VERSION_VALUE);
119 DECLARE_CONST_UNICODE_STRING(wdfMinorValue, WDF_MINOR_VERSION_VALUE);
120 ULONG registeredMajor = 0, registeredMinor = 0;
121 NTSTATUS status;
122
123 status = FxRegKey::_OpenKey(NULL,
124 ServiceKeyName,
125 &hDriver.m_Key,
126 KEY_READ
127 );
128 if (!NT_SUCCESS(status)) {
129 return FALSE;
130 }
131
132 status = FxRegKey::_OpenKey(hDriver.m_Key,
133 ¶metersPath,
134 &hWdf.m_Key,
135 KEY_READ
136 );
137 if (!NT_SUCCESS(status)) {
138 return FALSE;
139 }
140
141 status = FxRegKey::_QueryULong(hWdf.m_Key,
142 &wdfMajorValue,
143 ®isteredMajor);
144
145 if (!NT_SUCCESS(status) || registeredMajor != WdfBindInfo->Version.Major) {
146 return FALSE;
147 }
148
149 status = FxRegKey::_QueryULong(hWdf.m_Key,
150 &wdfMinorValue,
151 ®isteredMinor);
152
153 if (!NT_SUCCESS(status) || registeredMinor != WdfBindInfo->Version.Minor){
154 return FALSE;
155 }
156 else {
157 return TRUE;
158 }
159 }
160
161 VOID
RegisterClientVersion(_In_ PCUNICODE_STRING ServiceKeyName)162 FX_DRIVER_GLOBALS::RegisterClientVersion(
163 _In_ PCUNICODE_STRING ServiceKeyName
164 )
165 {
166 FxAutoRegKey hDriver, hParameters, hWdf;
167 DECLARE_CONST_UNICODE_STRING(parametersPart, L"Parameters");
168 DECLARE_CONST_UNICODE_STRING(wdfPart, L"Wdf");
169 //
170 // Not defined with the macro because ZwSetValue doesn't use PCUNICODE_STRING
171 //
172 UNICODE_STRING wdfMajorValue;
173 UNICODE_STRING wdfMinorValue;
174 NTSTATUS status;
175
176 RtlInitUnicodeString(&wdfMajorValue, WDF_MAJOR_VERSION_VALUE);
177 RtlInitUnicodeString(&wdfMinorValue, WDF_MINOR_VERSION_VALUE);
178
179 status = FxRegKey::_OpenKey(NULL,
180 ServiceKeyName,
181 &hDriver.m_Key,
182 KEY_WRITE | KEY_READ
183 );
184 if (!NT_SUCCESS(status)) {
185 DoTraceLevelMessage(this, TRACE_LEVEL_VERBOSE, TRACINGDRIVER,
186 "Unable to open driver's service key, status %!STATUS!", status);
187 return;
188 }
189 //
190 // Key creation, unlike user mode, must happen one level at a time, since
191 // create will also open take both steps instead of trying open first
192 //
193 status = FxRegKey::_Create(hDriver.m_Key,
194 ¶metersPart,
195 &hParameters.m_Key,
196 KEY_WRITE | KEY_READ
197 );
198 if (!NT_SUCCESS(status)) {
199 DoTraceLevelMessage(this, TRACE_LEVEL_VERBOSE, TRACINGDRIVER,
200 "Unable to write Parameters key, status %!STATUS!", status);
201 return;
202 }
203
204 status = FxRegKey::_Create(hParameters.m_Key,
205 &wdfPart,
206 &hWdf.m_Key,
207 KEY_WRITE | KEY_READ
208 );
209 if (!NT_SUCCESS(status)) {
210 DoTraceLevelMessage(this, TRACE_LEVEL_VERBOSE, TRACINGDRIVER,
211 "Unable to write Parameters key, status %!STATUS!", status);
212 return;
213 }
214
215 //
216 // Using ZwSetValueKey here to avoid having to change the implementation
217 // in FxRegKey of SetValue to a static / thiscall pair
218 //
219 status = ZwSetValueKey(hWdf.m_Key,
220 &wdfMajorValue,
221 0,
222 REG_DWORD,
223 &WdfBindInfo->Version.Major,
224 sizeof(WdfBindInfo->Version.Major)
225 );
226
227 if (!NT_SUCCESS(status)) {
228 DoTraceLevelMessage(this, TRACE_LEVEL_VERBOSE, TRACINGDRIVER,
229 "Failed to record driver major version value, status %!STATUS!", status);
230 }
231
232 status = ZwSetValueKey(hWdf.m_Key,
233 &wdfMinorValue,
234 0,
235 REG_DWORD,
236 &WdfBindInfo->Version.Minor,
237 sizeof(WdfBindInfo->Version.Minor)
238 );
239
240 if (!NT_SUCCESS(status)) {
241 DoTraceLevelMessage(this, TRACE_LEVEL_VERBOSE, TRACINGDRIVER,
242 "Failed to record driver version value, status %!STATUS!", status);
243 }
244 }
245
246 } // extern "C"
247
248 _Must_inspect_result_
249 BOOLEAN
IsDebuggerAttached(VOID)250 FX_DRIVER_GLOBALS::IsDebuggerAttached(
251 VOID
252 )
253 {
254 return (FALSE == KdRefreshDebuggerNotPresent());
255 }
256