1 /*++
2 
3 Copyright (c) Microsoft Corporation
4 
5 Module Name:
6 
7     FxRegKey.hpp
8 
9 Abstract:
10 
11     This is the C++ header for FxRegKey which represents a key into the registry
12 
13 Author:
14 
15 
16 
17 
18 Revision History:
19 
20 --*/
21 
22 #ifndef _FXREGKEY_H_
23 #define _FXREGKEY_H_
24 
25 class FxRegKey : public FxPagedObject {
26 
27 public:
28     FxRegKey(
29         PFX_DRIVER_GLOBALS FxDriverGlobals
30         );
31 
32     __drv_maxIRQL(PASSIVE_LEVEL)
33     ~FxRegKey(
34         VOID
35         );
36 
37     _Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)38     __drv_maxIRQL(PASSIVE_LEVEL)
39     NTSTATUS
40     Create(
41         __in_opt  HANDLE ParentKey,
42         __in      PCUNICODE_STRING KeyName,
43         __in      ACCESS_MASK DesiredAccess = KEY_ALL_ACCESS,
44         __in      ULONG CreateOptions = REG_OPTION_NON_VOLATILE,
45         __out_opt PULONG CreateDisposition = NULL
46         )
47     {
48         return _Create(ParentKey,
49                        KeyName,
50                        &m_Key,
51                        DesiredAccess,
52                        CreateOptions,
53                        CreateDisposition);
54     }
55 
56     static
57     _Must_inspect_result_
58     __drv_maxIRQL(PASSIVE_LEVEL)
59     NTSTATUS
60     _Create(
61         __in_opt  HANDLE ParentKey,
62         __in      PCUNICODE_STRING KeyName,
63         __out     HANDLE* NewKey,
64         __in      ACCESS_MASK DesiredAccess = KEY_ALL_ACCESS,
65         __in      ULONG CreateOptions = REG_OPTION_NON_VOLATILE,
66         __out_opt PULONG CreateDisposition = NULL
67         );
68 
69     _Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)70     __drv_maxIRQL(PASSIVE_LEVEL)
71     NTSTATUS
72     Open(
73         __in_opt HANDLE ParentKey,
74         __in     PCUNICODE_STRING KeyName,
75         __in     ACCESS_MASK DesiredAccess = KEY_ALL_ACCESS
76         )
77     {
78         return _OpenKey(ParentKey, KeyName, &m_Key, DesiredAccess);
79     }
80 
81     static
82     _Must_inspect_result_
83     __drv_maxIRQL(PASSIVE_LEVEL)
84     NTSTATUS
85     _OpenKey(
86         __in_opt HANDLE ParentKey,
87         __in     PCUNICODE_STRING KeyName,
88         __out    HANDLE* Key,
89         __in     ACCESS_MASK DesiredAccess = KEY_ALL_ACCESS
90         );
91 
92     __inline
93     VOID
SetHandle(__in HANDLE Key)94     SetHandle(
95         __in HANDLE Key
96         )
97     {
98         m_Key = Key;
99     }
100 
101     __inline
102     HANDLE
GetHandle(VOID)103     GetHandle(
104         VOID
105         )
106     {
107         return m_Key;
108     }
109 
__drv_maxIRQL(PASSIVE_LEVEL)110     __drv_maxIRQL(PASSIVE_LEVEL)
111     NTSTATUS
112     Close(
113         VOID
114         )
115     {
116         HANDLE key;
117 
118         key = m_Key;
119         m_Key = NULL;
120 
121 #if (FX_CORE_MODE == FX_CORE_USER_MODE)
122         //
123         // For special cases where, due to user-mode restrictions,
124         // we cannot open a specific handle for write access,
125         // so we reuse a pre-opened one multiple times.
126         //
127         // In this case we do not want to close it when we close
128         // the FxRegKey object.
129         //
130         if (m_CanCloseHandle == FALSE) {
131             return STATUS_SUCCESS;
132         }
133 #endif
134         return _Close(key);
135     }
136 
137     static
138     __drv_maxIRQL(PASSIVE_LEVEL)
139     NTSTATUS
140     _Close(
141         __in HANDLE Key
142         );
143 
144     _Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)145     __drv_maxIRQL(PASSIVE_LEVEL)
146     NTSTATUS
147     SetValue(
148         __in PCUNICODE_STRING ValueName,
149         __in ULONG ValueType,
150         __in_bcount(ValueLength) PVOID Value,
151         __in ULONG ValueLength
152         )
153     {
154         return _SetValue(m_Key,
155                          ValueName,
156                          ValueType,
157                          Value,
158                          ValueLength);
159     }
160 
161     static
162     _Must_inspect_result_
163     __drv_maxIRQL(PASSIVE_LEVEL)
164     NTSTATUS
165     _SetValue(
166         _In_ HANDLE Key,
167         _In_ PCUNICODE_STRING ValueName,
168         _In_ ULONG ValueType,
169         _In_reads_bytes_(ValueLength) PVOID Value,
170         _In_ ULONG ValueLength
171         );
172 
173     _Must_inspect_result_
__drv_maxIRQL(PASSIVE_LEVEL)174     __drv_maxIRQL(PASSIVE_LEVEL)
175     NTSTATUS
176     QueryValue(
177         __in PCUNICODE_STRING ValueName,
178         __in ULONG ValueLength,
179         __out_bcount_opt(ValueLength) PVOID Value,
180         __out_opt PULONG ValueLengthQueried,
181         __out_opt PULONG ValueType
182         )
183     {
184         return _QueryValue(m_Globals,
185                            m_Key,
186                            ValueName,
187                            ValueLength,
188                            Value,
189                            ValueLengthQueried,
190                            ValueType);
191     }
192 
193     static
194     _Must_inspect_result_
195     __drv_maxIRQL(PASSIVE_LEVEL)
196     NTSTATUS
197     _QueryValue(
198         __in PFX_DRIVER_GLOBALS FxDriverGlobals,
199         __in HANDLE Key,
200         __in PCUNICODE_STRING ValueName,
201         __in ULONG ValueLength,
202         __out_bcount_opt(ValueLength) PVOID Value,
203         __out_opt PULONG ValueLengthQueried,
204         __out_opt PULONG ValueType
205         );
206 
207     static
208     _Must_inspect_result_
209     __drv_maxIRQL(PASSIVE_LEVEL)
210     NTSTATUS
211     _QueryULong(
212         __in  HANDLE Key,
213         __in  PCUNICODE_STRING ValueName,
214         __out PULONG Value
215         );
216 
217     static
218     _Must_inspect_result_
219     __drv_maxIRQL(PASSIVE_LEVEL)
220     NTSTATUS
221     _QueryQuadWord(
222         __in  HANDLE Key,
223         __in  PCUNICODE_STRING ValueName,
224         __out PLARGE_INTEGER Value
225         );
226 
227     static
228     BOOLEAN
229     __inline
_IsValidSzType(__in ULONG RegValueType)230     _IsValidSzType(
231         __in ULONG RegValueType
232         )
233     {
234         return (RegValueType == REG_SZ) || (RegValueType == REG_EXPAND_SZ);
235     }
236 
237     static
238     _Must_inspect_result_
239     NTSTATUS
240     _VerifyMultiSzString(
241         __in PFX_DRIVER_GLOBALS FxDriverGlobals,
242         __in PCUNICODE_STRING RegValueName,
243         __in_bcount(DataLength) PWCHAR DataString,
244         __in ULONG DataLength
245         );
246 
247 private:
248 
249     static
250     __out_range(Length, (Length+sizeof(KEY_VALUE_PARTIAL_INFORMATION)-1))
251     ULONG
_ComputePartialSize(__in_bound ULONG Length)252     _ComputePartialSize(
253         __in_bound ULONG Length
254         )
255     {
256         return FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + Length;
257     }
258 
259 protected:
260 
261     HANDLE m_Key;
262     PFX_DRIVER_GLOBALS m_Globals;
263 
264 #if (FX_CORE_MODE == FX_CORE_USER_MODE)
265 private:
266 
267     //
268     // If FALSE, then closing or destroying the FxRegKey
269     // will have no effect on the HKEY m_Key.
270     //
271     BOOLEAN m_CanCloseHandle;
272 
273 public:
274 
275     VOID
276     __inline
SetCanCloseHandle(BOOLEAN CanCloseHandle)277     SetCanCloseHandle(
278         BOOLEAN CanCloseHandle
279         )
280     {
281         m_CanCloseHandle = CanCloseHandle;
282     }
283 #endif
284 };
285 
286 #endif // _FXREGKEY_H_
287