ReactOS 0.4.15-dev-5666-gc548b97
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}
125
126VOID
127NTAPI
128RegWriteSZ(HKEY hkey, PWSTR pwszValue, PWSTR pwszData)
129{
130 UNICODE_STRING ustrValue;
131 UNICODE_STRING ustrData;
132
133 RtlInitUnicodeString(&ustrValue, pwszValue);
134 RtlInitUnicodeString(&ustrData, pwszData);
135 ZwSetValueKey(hkey, &ustrValue, 0, REG_SZ, &ustrData, ustrData.Length + sizeof(WCHAR));
136}
137
138VOID
139NTAPI
141{
142 UNICODE_STRING ustrValue;
143
144 RtlInitUnicodeString(&ustrValue, pwszValue);
145 ZwSetValueKey(hkey, &ustrValue, 0, REG_DWORD, &dwData, sizeof(DWORD));
146}
147
148BOOL
149NTAPI
150RegReadDWORD(HKEY hkey, PWSTR pwszValue, PDWORD pdwData)
151{
153 ULONG cbSize = sizeof(DWORD);
154 Status = RegQueryValue(hkey, pwszValue, REG_DWORD, pdwData, &cbSize);
155 return NT_SUCCESS(Status);
156}
157
159NTAPI
161 LPCWSTR pszSection,
162 PHKEY phkey)
163{
164 WCHAR szKey[MAX_PATH] =
165 L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\";
166
167 RtlStringCchCatW(szKey, _countof(szKey), pszSection);
168 return RegOpenKey(szKey, phkey);
169}
170
171DWORD
172NTAPI
173RegGetSectionDWORD(LPCWSTR pszSection, LPWSTR pszValue, DWORD dwDefault)
174{
175 HKEY hKey;
176 DWORD dwValue;
177
178 if (NT_ERROR(RegOpenSectionKey(pszSection, &hKey)))
179 return dwDefault;
180
181 if (!RegReadDWORD(hKey, pszValue, &dwValue))
182 dwValue = dwDefault;
183
184 ZwClose(hKey);
185 return dwValue;
186}
187
189BOOL
190NTAPI
191RegReadUserSetting(
192 _In_z_ PCWSTR pwszKeyName,
196 _In_ ULONG cbDataSize)
197{
200 UNICODE_STRING usCurrentUserKey, usKeyName, usValueName;
201 WCHAR awcBuffer[MAX_PATH];
202 HKEY hkey;
204 ULONG cbInfoSize, cbReqSize;
205
206 /* Get the path of the current user's profile */
207 Status = RtlFormatCurrentUserKeyPath(&usCurrentUserKey);
208 if (!NT_SUCCESS(Status))
209 {
210 return FALSE;
211 }
212
213 /* Initialize empty key name */
214 RtlInitEmptyUnicodeString(&usKeyName, awcBuffer, sizeof(awcBuffer));
215
216 /* Append the current user key name */
217 Status = RtlAppendUnicodeStringToString(&usKeyName, &usCurrentUserKey);
218
219 /* Free the current user key name */
220 RtlFreeUnicodeString(&usCurrentUserKey);
221
222 /* Check for success */
223 if (!NT_SUCCESS(Status))
224 {
225 return FALSE;
226 }
227
228 /* Append a '\', we can trust in enough space left. */
229 usKeyName.Buffer[usKeyName.Length / sizeof(WCHAR)] = '\\';
230 usKeyName.Length += sizeof(WCHAR);
231
232 /* Append the subkey name */
233 Status = RtlAppendUnicodeToString(&usKeyName, pwszKeyName);
234 if (!NT_SUCCESS(Status))
235 {
236 return FALSE;
237 }
238
239 /* Initialize object attributes */
241 &usKeyName,
243 NULL,
244 NULL);
245
246 /* Open the key */
247 Status = ZwOpenKey((PHANDLE)&hkey, KEY_READ, &ObjectAttributes);
248 if (!NT_SUCCESS(Status))
249 {
250 return FALSE;
251 }
252
253 /* Check if the local buffer is sufficient */
254 cbInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + cbDataSize;
255 if (cbInfoSize <= sizeof(awcBuffer))
256 {
257 pInfo = (PVOID)awcBuffer;
258 }
259 else
260 {
261 /* It's not, allocate a sufficient buffer */
262 pInfo = ExAllocatePoolWithTag(PagedPool, cbInfoSize, TAG_TEMP);
263 if (!pInfo)
264 {
265 ZwClose(hkey);
266 return FALSE;
267 }
268 }
269
270 /* Query the value */
271 RtlInitUnicodeString(&usValueName, pwszValueName);
272 Status = ZwQueryValueKey(hkey,
273 &usValueName,
275 (PVOID)pInfo,
276 cbInfoSize,
277 &cbReqSize);
278 if (NT_SUCCESS(Status))
279 {
280 /* Did we get the right type */
281 if (pInfo->Type == ulType)
282 {
283 /* Copy the contents to the caller */
284 RtlCopyMemory(pvData, pInfo->Data, cbDataSize);
285 }
286 }
287
288 /* Cleanup */
289 ZwClose(hkey);
290 if (pInfo != (PVOID)awcBuffer)
292
293 return NT_SUCCESS(Status);
294}
295
296_Success_(return != FALSE)
297BOOL
298NTAPI
299RegWriteUserSetting(
300 _In_z_ PCWSTR pwszKeyName,
304 _In_ ULONG cbDataSize)
305{
308 UNICODE_STRING usCurrentUserKey, usKeyName, usValueName;
309 WCHAR awcBuffer[MAX_PATH];
310 HKEY hkey;
311
312 // FIXME: Logged in user versus current process user?
313 /* Get the path of the current user's profile */
314 Status = RtlFormatCurrentUserKeyPath(&usCurrentUserKey);
315 if (!NT_SUCCESS(Status))
316 {
317 DPRINT1("RtlFormatCurrentUserKeyPath failed\n");
318 return FALSE;
319 }
320
321 /* Initialize empty key name */
322 RtlInitEmptyUnicodeString(&usKeyName, awcBuffer, sizeof(awcBuffer));
323
324 /* Append the current user key name */
325 Status = RtlAppendUnicodeStringToString(&usKeyName, &usCurrentUserKey);
326 if (!NT_SUCCESS(Status))
327 {
328 return FALSE;
329 }
330
331 /* Free the current user key name */
332 RtlFreeUnicodeString(&usCurrentUserKey);
333
334 /* Append a '\', we can trust in enough space left. */
335 usKeyName.Buffer[usKeyName.Length / sizeof(WCHAR)] = '\\';
336 usKeyName.Length += sizeof(WCHAR);
337
338 /* Append the subkey name */
339 Status = RtlAppendUnicodeToString(&usKeyName, pwszKeyName);
340 if (!NT_SUCCESS(Status))
341 {
342 DPRINT1("RtlAppendUnicodeToString failed with Status=0x%lx, buf:%u,%u\n",
343 Status, usKeyName.Length, usKeyName.MaximumLength);
344 return FALSE;
345 }
346
347 /* Initialize object attributes */
349 &usKeyName,
351 NULL,
352 NULL);
353
354 /* Open or create the key */
355 Status = ZwCreateKey((PHANDLE)&hkey,
358 0,
359 NULL,
360 0,
361 NULL);
362 if(!NT_SUCCESS(Status))
363 {
364 DPRINT1("Failed to create key: 0x%x\n", Status);
365 return FALSE;
366 }
367
368 /* Initialize the value name string */
369 RtlInitUnicodeString(&usValueName, pwszValueName);
370
371 Status = ZwSetValueKey(hkey, &usValueName, 0, ulType, (PVOID)pvData, cbDataSize);
372 if(!NT_SUCCESS(Status))
373 {
374 DPRINT1("Failed to write reg key '%S' value '%S', Status = %lx\n",
375 pwszKeyName, pwszValueName, Status);
376 }
377
378 /* Cleanup */
379 ZwClose(hkey);
380
381 return NT_SUCCESS(Status);
382}
383
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:32
#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
unsigned int * PULONG
Definition: retypes.h:1
void * PVOID
Definition: retypes.h:9
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
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:68
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define _PRAGMA_WARNING_SUPPRESS(x)
Definition: suppress.h:28
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define IN
Definition: typedefs.h:39
#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:50
_In_z_ PCWSTR pwszValueName
Definition: ntuser.h:47
_In_z_ PCWSTR _In_ ULONG ulType
Definition: ntuser.h:48
NTSTATUS NTAPI RegOpenSectionKey(LPCWSTR pszSection, PHKEY phkey)
Definition: registry.c:160
BOOL NTAPI RegReadDWORD(HKEY hkey, PWSTR pwszValue, PDWORD pdwData)
Definition: registry.c:150
VOID NTAPI RegWriteSZ(HKEY hkey, PWSTR pwszValue, PWSTR pwszData)
Definition: registry.c:128
DWORD NTAPI RegGetSectionDWORD(LPCWSTR pszSection, LPWSTR pszValue, DWORD dwDefault)
Definition: registry.c:173
VOID NTAPI RegWriteDWORD(HKEY hkey, PWSTR pwszValue, DWORD dwData)
Definition: registry.c:140
#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
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193