ReactOS 0.4.16-dev-91-g764881a
registry.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: GPL, see COPYING in the top level directory
3 * PROJECT: ReactOS win32 kernel mode subsystem server
4 * PURPOSE: Registry loading and storing
5 * FILE: win32ss/user/ntuser/misc/registry.c
6 * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
7 */
8
9#include <win32k.h>
10
11#define NDEBUG
12#include <debug.h>
13
17 LPCWSTR pwszKeyName,
18 PHKEY phkey)
19{
22 UNICODE_STRING ustrKeyName;
23 HKEY hkey;
24
25 /* Initialize the key name */
26 RtlInitUnicodeString(&ustrKeyName, pwszKeyName);
27
28 /* Initialize object attributes */
30 &ustrKeyName,
32 NULL,
33 NULL);
34
35 /* Open the key */
36 Status = ZwOpenKey((PHANDLE)&hkey, KEY_READ, &ObjectAttributes);
37 if (NT_SUCCESS(Status))
38 {
39 *phkey = hkey;
40 }
41
42 return Status;
43}
44
48 IN HKEY hkey,
52 IN OUT PULONG pcbValue)
53{
55 UNICODE_STRING ustrValueName;
56 BYTE ajBuffer[100];
58 ULONG cbInfoSize, cbDataSize;
59
60 /* Check if the local buffer is sufficient */
61 cbInfoSize = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[*pcbValue]);
62 if (cbInfoSize <= sizeof(ajBuffer))
63 {
64 pInfo = (PVOID)ajBuffer;
65 }
66 else
67 {
68 /* It's not, allocate a sufficient buffer */
69 pInfo = ExAllocatePoolWithTag(PagedPool, cbInfoSize, TAG_TEMP);
70 if (!pInfo)
71 {
73 }
74 }
75
76 /* Query the value */
77 RtlInitUnicodeString(&ustrValueName, pwszValueName);
78 Status = ZwQueryValueKey(hkey,
79 &ustrValueName,
81 (PVOID)pInfo,
82 cbInfoSize,
83 &cbInfoSize);
84
85 /* Note: STATUS_BUFFER_OVERFLOW is not a success */
86 if (NT_SUCCESS(Status))
87 {
88 cbDataSize = pInfo->DataLength;
89
90 /* Did we get the right type */
91 if (pInfo->Type != ulType)
92 {
94 }
95 else if (cbDataSize > *pcbValue)
96 {
98 }
99 else
100 {
101 /* Copy the contents to the caller */
102 RtlCopyMemory(pvData, pInfo->Data, cbDataSize);
103 }
104 }
106 {
107 _PRAGMA_WARNING_SUPPRESS(6102); /* cbInfoSize is initialized here! */
108 cbDataSize = cbInfoSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
109 }
110 else
111 {
112 cbDataSize = 0;
113 }
114
115 /* Return the data size to the caller */
116 *pcbValue = cbDataSize;
117
118 /* Cleanup */
119 if (pInfo != (PVOID)ajBuffer)
121
122 return Status;
123}
124
125VOID
126NTAPI
127RegWriteSZ(HKEY hkey, PCWSTR pwszValue, PWSTR pwszData)
128{
129 UNICODE_STRING ustrValue;
130 UNICODE_STRING ustrData;
131
132 RtlInitUnicodeString(&ustrValue, pwszValue);
133 RtlInitUnicodeString(&ustrData, pwszData);
134 ZwSetValueKey(hkey, &ustrValue, 0, REG_SZ, &ustrData, ustrData.Length + sizeof(WCHAR));
135}
136
137VOID
138NTAPI
140{
141 UNICODE_STRING ustrValue;
142
143 RtlInitUnicodeString(&ustrValue, pwszValue);
144 ZwSetValueKey(hkey, &ustrValue, 0, REG_DWORD, &dwData, sizeof(DWORD));
145}
146
147BOOL
148NTAPI
149RegReadDWORD(HKEY hkey, PCWSTR pwszValue, PDWORD pdwData)
150{
152 ULONG cbSize = sizeof(DWORD);
153 Status = RegQueryValue(hkey, pwszValue, REG_DWORD, pdwData, &cbSize);
154 return NT_SUCCESS(Status);
155}
156
158NTAPI
160 LPCWSTR pszSection,
161 PHKEY phkey)
162{
163 WCHAR szKey[MAX_PATH] =
164 L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\";
165
166 RtlStringCchCatW(szKey, _countof(szKey), pszSection);
167 return RegOpenKey(szKey, phkey);
168}
169
170DWORD
171NTAPI
172RegGetSectionDWORD(LPCWSTR pszSection, PCWSTR pszValue, DWORD dwDefault)
173{
174 HKEY hKey;
175 DWORD dwValue;
176
177 if (NT_ERROR(RegOpenSectionKey(pszSection, &hKey)))
178 return dwDefault;
179
180 if (!RegReadDWORD(hKey, pszValue, &dwValue))
181 dwValue = dwDefault;
182
183 ZwClose(hKey);
184 return dwValue;
185}
186
188BOOL
189NTAPI
190RegReadUserSetting(
191 _In_z_ PCWSTR pwszKeyName,
195 _In_ ULONG cbDataSize)
196{
199 UNICODE_STRING usCurrentUserKey, usKeyName, usValueName;
200 WCHAR awcBuffer[MAX_PATH];
201 HKEY hkey;
203 ULONG cbInfoSize, cbReqSize;
204
205 /* Get the path of the current user's profile */
206 Status = RtlFormatCurrentUserKeyPath(&usCurrentUserKey);
207 if (!NT_SUCCESS(Status))
208 {
209 return FALSE;
210 }
211
212 /* Initialize empty key name */
213 RtlInitEmptyUnicodeString(&usKeyName, awcBuffer, sizeof(awcBuffer));
214
215 /* Append the current user key name */
216 Status = RtlAppendUnicodeStringToString(&usKeyName, &usCurrentUserKey);
217
218 /* Free the current user key name */
219 RtlFreeUnicodeString(&usCurrentUserKey);
220
221 /* Check for success */
222 if (!NT_SUCCESS(Status))
223 {
224 return FALSE;
225 }
226
227 /* Append a '\', we can trust in enough space left. */
228 usKeyName.Buffer[usKeyName.Length / sizeof(WCHAR)] = '\\';
229 usKeyName.Length += sizeof(WCHAR);
230
231 /* Append the subkey name */
232 Status = RtlAppendUnicodeToString(&usKeyName, pwszKeyName);
233 if (!NT_SUCCESS(Status))
234 {
235 return FALSE;
236 }
237
238 /* Initialize object attributes */
240 &usKeyName,
242 NULL,
243 NULL);
244
245 /* Open the key */
246 Status = ZwOpenKey((PHANDLE)&hkey, KEY_READ, &ObjectAttributes);
247 if (!NT_SUCCESS(Status))
248 {
249 return FALSE;
250 }
251
252 /* Check if the local buffer is sufficient */
253 cbInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + cbDataSize;
254 if (cbInfoSize <= sizeof(awcBuffer))
255 {
256 pInfo = (PVOID)awcBuffer;
257 }
258 else
259 {
260 /* It's not, allocate a sufficient buffer */
261 pInfo = ExAllocatePoolWithTag(PagedPool, cbInfoSize, TAG_TEMP);
262 if (!pInfo)
263 {
264 ZwClose(hkey);
265 return FALSE;
266 }
267 }
268
269 /* Query the value */
270 RtlInitUnicodeString(&usValueName, pwszValueName);
271 Status = ZwQueryValueKey(hkey,
272 &usValueName,
274 (PVOID)pInfo,
275 cbInfoSize,
276 &cbReqSize);
277 if (NT_SUCCESS(Status))
278 {
279 /* Did we get the right type */
280 if (pInfo->Type == ulType)
281 {
282 /* Copy the contents to the caller */
283 RtlCopyMemory(pvData, pInfo->Data, cbDataSize);
284 }
285 }
286
287 /* Cleanup */
288 ZwClose(hkey);
289 if (pInfo != (PVOID)awcBuffer)
291
292 return NT_SUCCESS(Status);
293}
294
295_Success_(return != FALSE)
296BOOL
297NTAPI
298RegWriteUserSetting(
299 _In_z_ PCWSTR pwszKeyName,
303 _In_ ULONG cbDataSize)
304{
307 UNICODE_STRING usCurrentUserKey, usKeyName, usValueName;
308 WCHAR awcBuffer[MAX_PATH];
309 HKEY hkey;
310
311 // FIXME: Logged in user versus current process user?
312 /* Get the path of the current user's profile */
313 Status = RtlFormatCurrentUserKeyPath(&usCurrentUserKey);
314 if (!NT_SUCCESS(Status))
315 {
316 DPRINT1("RtlFormatCurrentUserKeyPath failed\n");
317 return FALSE;
318 }
319
320 /* Initialize empty key name */
321 RtlInitEmptyUnicodeString(&usKeyName, awcBuffer, sizeof(awcBuffer));
322
323 /* Append the current user key name */
324 Status = RtlAppendUnicodeStringToString(&usKeyName, &usCurrentUserKey);
325 if (!NT_SUCCESS(Status))
326 {
327 return FALSE;
328 }
329
330 /* Free the current user key name */
331 RtlFreeUnicodeString(&usCurrentUserKey);
332
333 /* Append a '\', we can trust in enough space left. */
334 usKeyName.Buffer[usKeyName.Length / sizeof(WCHAR)] = '\\';
335 usKeyName.Length += sizeof(WCHAR);
336
337 /* Append the subkey name */
338 Status = RtlAppendUnicodeToString(&usKeyName, pwszKeyName);
339 if (!NT_SUCCESS(Status))
340 {
341 DPRINT1("RtlAppendUnicodeToString failed with Status=0x%lx, buf:%u,%u\n",
342 Status, usKeyName.Length, usKeyName.MaximumLength);
343 return FALSE;
344 }
345
346 /* Initialize object attributes */
348 &usKeyName,
350 NULL,
351 NULL);
352
353 /* Open or create the key */
354 Status = ZwCreateKey((PHANDLE)&hkey,
357 0,
358 NULL,
359 0,
360 NULL);
361 if(!NT_SUCCESS(Status))
362 {
363 DPRINT1("Failed to create key: 0x%x\n", Status);
364 return FALSE;
365 }
366
367 /* Initialize the value name string */
368 RtlInitUnicodeString(&usValueName, pwszValueName);
369
370 Status = ZwSetValueKey(hkey, &usValueName, 0, ulType, (PVOID)pvData, cbDataSize);
371 if(!NT_SUCCESS(Status))
372 {
373 DPRINT1("Failed to write reg key '%S' value '%S', Status = %lx\n",
374 pwszKeyName, pwszValueName, Status);
375 }
376
377 /* Cleanup */
378 ZwClose(hkey);
379
380 return NT_SUCCESS(Status);
381}
382
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define MAX_PATH
Definition: compat.h:34
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define PagedPool
Definition: env_spec_w32.h:308
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define REG_SZ
Definition: layer.c:22
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static HANDLE ULONG_PTR dwData
Definition: file.c:35
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _Post_z_
Definition: ms_sal.h:691
#define _Success_(expr)
Definition: ms_sal.h:259
#define _In_reads_bytes_(size)
Definition: ms_sal.h:321
#define _In_z_
Definition: ms_sal.h:313
#define _Out_writes_(size)
Definition: ms_sal.h:348
#define _When_(expr, annos)
Definition: ms_sal.h:254
#define _In_
Definition: ms_sal.h:308
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
@ KeyValuePartialInformation
Definition: nt_native.h:1182
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define KEY_WRITE
Definition: nt_native.h:1031
#define DWORD
Definition: nt_native.h:44
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
NTSTRSAFEAPI RtlStringCchCatW(_Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:601
#define L(x)
Definition: ntvdm.h:50
DWORD * PDWORD
Definition: pedump.c:68
#define REG_DWORD
Definition: sdbapi.c:596
NTSTATUS NTAPI RtlFormatCurrentUserKeyPath(OUT PUNICODE_STRING KeyPath)
Definition: registry.c:742
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define _countof(array)
Definition: sndvol32.h:70
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define _PRAGMA_WARNING_SUPPRESS(x)
Definition: suppress.h:28
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define NT_ERROR(Status)
Definition: umtypes.h:106
_In_z_ PCWSTR _In_ ULONG _Post_z_ PVOID _In_ ULONG cjDataSize
Definition: ntuser.h:45
_In_z_ PCWSTR pwszValueName
Definition: ntuser.h:42
_In_z_ PCWSTR _In_ ULONG ulType
Definition: ntuser.h:43
VOID NTAPI RegWriteDWORD(HKEY hkey, PCWSTR pwszValue, DWORD dwData)
Definition: registry.c:139
NTSTATUS NTAPI RegOpenSectionKey(LPCWSTR pszSection, PHKEY phkey)
Definition: registry.c:159
DWORD NTAPI RegGetSectionDWORD(LPCWSTR pszSection, PCWSTR pszValue, DWORD dwDefault)
Definition: registry.c:172
BOOL NTAPI RegReadDWORD(HKEY hkey, PCWSTR pwszValue, PDWORD pdwData)
Definition: registry.c:149
VOID NTAPI RegWriteSZ(HKEY hkey, PCWSTR pwszValue, PWSTR pwszData)
Definition: registry.c:127
#define TAG_TEMP
Definition: tags.h:43
_In_ ULONG _In_opt_ PVOID pvData
Definition: winddi.h:3749
#define RegOpenKey
Definition: winreg.h:519
#define RegQueryValue
Definition: winreg.h:523
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193