1 /*++
2
3 Copyright (c) Microsoft Corporation
4
5 Module Name:
6
7 FxRegKey.cpp
8
9 Abstract:
10
11 Author:
12
13 Environment:
14
15 user mode only
16
17 Revision History:
18
19 --*/
20
21 #include "FxSupportPch.hpp"
22
23 //#define UNICODE
24 //#define _UNICODE
25 #include <Winreg.h>
26
27 extern "C" {
28 #if defined(EVENT_TRACING)
29 #include "FxRegKeyUM.tmh"
30 #endif
31 }
32
FxRegKey(PFX_DRIVER_GLOBALS FxDriverGlobals)33 FxRegKey::FxRegKey(
34 PFX_DRIVER_GLOBALS FxDriverGlobals
35 ) :
36 FxPagedObject(FX_TYPE_REG_KEY, sizeof(FxRegKey), FxDriverGlobals),
37 m_Key(NULL),
38 m_Globals(FxDriverGlobals),
39 m_CanCloseHandle(TRUE)
40 {
41 }
42
__drv_maxIRQL(PASSIVE_LEVEL)43 __drv_maxIRQL(PASSIVE_LEVEL)
44 #pragma prefast(suppress:__WARNING_UNMATCHED_DECL_ANNO, "Can't apply kernel mode annotations.");
45 FxRegKey::~FxRegKey()
46 {
47 if (m_Key != NULL) {
48 if (m_CanCloseHandle == TRUE) {
49 RegCloseKey((HKEY)m_Key);
50 }
51 m_Key = NULL;
52 }
53 }
54
55 NTSTATUS
56 #pragma prefast(suppress:__WARNING_UNMATCHED_DECL_ANNO, "Can't apply kernel mode annotations.");
_Close(__in HANDLE Key)57 FxRegKey::_Close(
58 __in HANDLE Key
59 )
60 {
61 DWORD err = RegCloseKey((HKEY)Key);
62
63 if (ERROR_SUCCESS == err) {
64 return STATUS_SUCCESS;
65 }
66 else {
67 return WinErrorToNtStatus(err);
68 }
69 }
70
71 _Must_inspect_result_
72 NTSTATUS
73 #pragma prefast(suppress:__WARNING_UNMATCHED_DECL_ANNO, "Can't apply kernel mode annotations.");
_Create(__in_opt HANDLE ParentKey,__in PCUNICODE_STRING KeyName,__out HANDLE * NewKey,__in ACCESS_MASK DesiredAccess,__in ULONG CreateOptions,__out_opt PULONG CreateDisposition)74 FxRegKey::_Create(
75 __in_opt HANDLE ParentKey,
76 __in PCUNICODE_STRING KeyName,
77 __out HANDLE* NewKey,
78 __in ACCESS_MASK DesiredAccess,
79 __in ULONG CreateOptions,
80 __out_opt PULONG CreateDisposition
81 )
82 {
83 HKEY parentKey;
84
85 if (NULL == ParentKey)
86 {
87 parentKey = HKEY_LOCAL_MACHINE;
88 }
89 else
90 {
91 parentKey = (HKEY) ParentKey;
92 }
93
94 DWORD err = RegCreateKeyEx(parentKey,
95 KeyName->Buffer,
96 0,
97 NULL,
98 CreateOptions,
99 DesiredAccess,
100 NULL,
101 (PHKEY)NewKey,
102 CreateDisposition);
103
104 if (ERROR_SUCCESS == err) {
105 return STATUS_SUCCESS;
106 }
107 else {
108 return WinErrorToNtStatus(err);
109 }
110 }
111
112 _Must_inspect_result_
113 NTSTATUS
114 #pragma prefast(suppress:__WARNING_UNMATCHED_DECL_ANNO, "Can't apply kernel mode annotations.");
_OpenKey(__in_opt HANDLE ParentKey,__in PCUNICODE_STRING KeyName,__out HANDLE * Key,__in ACCESS_MASK DesiredAccess)115 FxRegKey::_OpenKey(
116 __in_opt HANDLE ParentKey,
117 __in PCUNICODE_STRING KeyName,
118 __out HANDLE* Key,
119 __in ACCESS_MASK DesiredAccess
120 )
121 {
122 HKEY parentKey;
123
124 if (NULL == ParentKey)
125 {
126 parentKey = HKEY_LOCAL_MACHINE;
127 }
128 else
129 {
130 parentKey = (HKEY) ParentKey;
131 }
132
133 DWORD err = RegOpenKeyEx(parentKey,
134 KeyName->Buffer,
135 0,
136 DesiredAccess,
137 (PHKEY)Key);
138
139 if (ERROR_SUCCESS == err) {
140 return STATUS_SUCCESS;
141 }
142 else {
143 return WinErrorToNtStatus(err);
144 }
145 }
146
147 _Must_inspect_result_
148 NTSTATUS
149 #pragma prefast(suppress:__WARNING_UNMATCHED_DECL_ANNO, "Can't apply kernel mode annotations.");
_SetValue(_In_ HANDLE Key,_In_ PCUNICODE_STRING ValueName,_In_ ULONG ValueType,_In_reads_bytes_ (ValueLength)PVOID Value,_In_ ULONG ValueLength)150 FxRegKey::_SetValue(
151 _In_ HANDLE Key,
152 _In_ PCUNICODE_STRING ValueName,
153 _In_ ULONG ValueType,
154 _In_reads_bytes_(ValueLength) PVOID Value,
155 _In_ ULONG ValueLength
156 )
157 {
158 DWORD err;
159
160 err = RegSetValueEx((HKEY)Key,
161 ValueName->Buffer,
162 0,
163 ValueType,
164 (BYTE*)Value,
165 ValueLength);
166 if (ERROR_SUCCESS == err) {
167 return STATUS_SUCCESS;
168 }
169 else {
170 return WinErrorToNtStatus(err);
171 }
172 }
173
174 _Must_inspect_result_
175 NTSTATUS
176 #pragma prefast(suppress:__WARNING_UNMATCHED_DECL_ANNO, "Can't apply kernel mode annotations.");
_QueryValue(__in PFX_DRIVER_GLOBALS FxDriverGlobals,__in HANDLE Key,__in PCUNICODE_STRING ValueName,__in ULONG ValueLength,__out_bcount_opt (ValueLength)PVOID Value,__out_opt PULONG ValueLengthQueried,__out_opt PULONG ValueType)177 FxRegKey::_QueryValue(
178 __in PFX_DRIVER_GLOBALS FxDriverGlobals,
179 __in HANDLE Key,
180 __in PCUNICODE_STRING ValueName,
181 __in ULONG ValueLength,
182 __out_bcount_opt(ValueLength) PVOID Value,
183 __out_opt PULONG ValueLengthQueried,
184 __out_opt PULONG ValueType
185 )
186 {
187 DWORD err;
188 NTSTATUS status;
189 ULONG length;
190
191 UNREFERENCED_PARAMETER(FxDriverGlobals);
192 ASSERT(Key != HKEY_PERFORMANCE_DATA);
193
194 length = ValueLength;
195
196 err = RegQueryValueEx((HKEY)Key,
197 ValueName->Buffer,
198 NULL,
199 ValueType,
200 (LPBYTE)Value,
201 &length);
202
203 if (ValueLengthQueried != NULL) {
204 *ValueLengthQueried = length;
205 }
206
207 //
208 // Please see the comment in FxRegKeyKm.cpp FxRegKey::_QueryValue about
209 // the call to ZwQueryValueKey.
210 //
211 // If the user supplies a NULL data buffer, RegQueryValueEx will return
212 // ERROR_SUCCESS. However, in order to satisfy UMDF-KMDF DDI parity as well
213 // as internal mode-agnostic code, we must overwrite RegQueryValueEx's
214 // return value of ERROR_SUCCESS (STATUS_SUCCESS) with STATUS_BUFFER_OVERFLOW.
215 //
216 // Other return values are overwritten because WinErrorToNtStatus does not map
217 // all Win32 error codes that RegQueryValueEx returns to the same NTSTATUS
218 // values that ZwQueryValueKey would return in the KM implementation of
219 // FxRegKey::_QueryValue.
220 //
221 if (err == ERROR_SUCCESS) {
222 if (Value != NULL) {
223 status = STATUS_SUCCESS;
224 }
225 else {
226 status = STATUS_BUFFER_OVERFLOW;
227 }
228 }
229 else if (err == ERROR_MORE_DATA) {
230 status = STATUS_BUFFER_OVERFLOW;
231 }
232 else if (err == ERROR_FILE_NOT_FOUND) {
233 status = STATUS_OBJECT_NAME_NOT_FOUND;
234 }
235 else {
236 status = WinErrorToNtStatus(err);
237 }
238
239 return status;
240 }
241
242 _Must_inspect_result_
243 NTSTATUS
244 #pragma prefast(suppress:__WARNING_UNMATCHED_DECL_ANNO, "Can't apply kernel mode annotations.");
_QueryULong(__in HANDLE Key,__in PCUNICODE_STRING ValueName,__out PULONG Value)245 FxRegKey::_QueryULong(
246 __in HANDLE Key,
247 __in PCUNICODE_STRING ValueName,
248 __out PULONG Value
249 )
250 {
251 DWORD err;
252 NTSTATUS status;
253 ULONG length, type;
254
255 ASSERT(Key != HKEY_PERFORMANCE_DATA);
256
257 type = REG_DWORD;
258 length = sizeof(ULONG);
259
260 err = RegQueryValueEx((HKEY)Key,
261 ValueName->Buffer,
262 NULL,
263 &type,
264 (LPBYTE)Value,
265 &length);
266
267 if ((err == ERROR_SUCCESS || err == ERROR_MORE_DATA) &&
268 type != REG_DWORD) {
269
270 ASSERT(FALSE);
271
272 status = STATUS_OBJECT_TYPE_MISMATCH;
273 }
274 else {
275 if (ERROR_SUCCESS == err) {
276 status = STATUS_SUCCESS;
277 }
278 else {
279 status = WinErrorToNtStatus(err);
280 }
281 }
282
283 return status;
284 }
285
286 _Must_inspect_result_
287 #pragma prefast(suppress:__WARNING_UNMATCHED_DECL_ANNO, "Can't apply kernel mode annotations.");
288 NTSTATUS
_QueryQuadWord(__in HANDLE Key,__in PCUNICODE_STRING ValueName,__out PLARGE_INTEGER Value)289 FxRegKey::_QueryQuadWord(
290 __in HANDLE Key,
291 __in PCUNICODE_STRING ValueName,
292 __out PLARGE_INTEGER Value
293 )
294 {
295 UNREFERENCED_PARAMETER(Key);
296 UNREFERENCED_PARAMETER(ValueName);
297 UNREFERENCED_PARAMETER(Value);
298
299 return STATUS_UNSUCCESSFUL;
300 }
301
302
303