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)
21 OBJECT_ATTRIBUTES ObjectAttributes
;
22 UNICODE_STRING ustrKeyName
;
25 /* Initialize the key name */
26 RtlInitUnicodeString(&ustrKeyName
, pwszKeyName
);
28 /* Initialize object attributes */
29 InitializeObjectAttributes(&ObjectAttributes
,
31 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
36 Status
= ZwOpenKey((PHANDLE
)&hkey
, KEY_READ
, &ObjectAttributes
);
37 if (NT_SUCCESS(Status
))
49 IN PCWSTR pwszValueName
,
52 IN OUT PULONG pcbValue
)
55 UNICODE_STRING ustrValueName
;
57 PKEY_VALUE_PARTIAL_INFORMATION pInfo
;
58 ULONG cbInfoSize
, cbDataSize
;
60 /* Check if the local buffer is sufficient */
61 cbInfoSize
= FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
[*pcbValue
]);
62 if (cbInfoSize
<= sizeof(ajBuffer
))
64 pInfo
= (PVOID
)ajBuffer
;
68 /* It's not, allocate a sufficient buffer */
69 pInfo
= ExAllocatePoolWithTag(PagedPool
, cbInfoSize
, TAG_TEMP
);
72 return STATUS_INSUFFICIENT_RESOURCES
;
77 RtlInitUnicodeString(&ustrValueName
, pwszValueName
);
78 Status
= ZwQueryValueKey(hkey
,
80 KeyValuePartialInformation
,
85 /* Note: STATUS_BUFFER_OVERFLOW is not a success */
86 if (NT_SUCCESS(Status
))
88 cbDataSize
= pInfo
->DataLength
;
90 /* Did we get the right type */
91 if (pInfo
->Type
!= ulType
)
93 Status
= STATUS_OBJECT_TYPE_MISMATCH
;
95 else if (cbDataSize
> *pcbValue
)
97 Status
= STATUS_BUFFER_TOO_SMALL
;
101 /* Copy the contents to the caller */
102 RtlCopyMemory(pvData
, pInfo
->Data
, cbDataSize
);
105 else if ((Status
== STATUS_BUFFER_OVERFLOW
) || (Status
== STATUS_BUFFER_TOO_SMALL
))
107 _PRAGMA_WARNING_SUPPRESS(6102); /* cbInfoSize is initialized here! */
108 cbDataSize
= cbInfoSize
- FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
);
115 /* Return the data size to the caller */
116 *pcbValue
= cbDataSize
;
119 if (pInfo
!= (PVOID
)ajBuffer
)
120 ExFreePoolWithTag(pInfo
, TAG_TEMP
);
128 RegWriteSZ(HKEY hkey
, PWSTR pwszValue
, PWSTR pwszData
)
130 UNICODE_STRING ustrValue
;
131 UNICODE_STRING ustrData
;
133 RtlInitUnicodeString(&ustrValue
, pwszValue
);
134 RtlInitUnicodeString(&ustrData
, pwszData
);
135 ZwSetValueKey(hkey
, &ustrValue
, 0, REG_SZ
, &ustrData
, ustrData
.Length
+ sizeof(WCHAR
));
140 RegWriteDWORD(HKEY hkey
, PWSTR pwszValue
, DWORD dwData
)
142 UNICODE_STRING ustrValue
;
144 RtlInitUnicodeString(&ustrValue
, pwszValue
);
145 ZwSetValueKey(hkey
, &ustrValue
, 0, REG_DWORD
, &dwData
, sizeof(DWORD
));
150 RegReadDWORD(HKEY hkey
, PWSTR pwszValue
, PDWORD pdwData
)
153 ULONG cbSize
= sizeof(DWORD
);
154 Status
= RegQueryValue(hkey
, pwszValue
, REG_DWORD
, pdwData
, &cbSize
);
155 return NT_SUCCESS(Status
);
158 _Success_(return!=FALSE
)
162 _In_z_ PCWSTR pwszKeyName
,
163 _In_z_ PCWSTR pwszValueName
,
165 _Out_writes_(cbDataSize
) _When_(ulType
== REG_SZ
, _Post_z_
) PVOID pvData
,
166 _In_ ULONG cbDataSize
)
169 OBJECT_ATTRIBUTES ObjectAttributes
;
170 UNICODE_STRING usCurrentUserKey
, usKeyName
, usValueName
;
171 WCHAR awcBuffer
[MAX_PATH
];
173 PKEY_VALUE_PARTIAL_INFORMATION pInfo
;
174 ULONG cbInfoSize
, cbReqSize
;
176 /* Get the path of the current user's profile */
177 Status
= RtlFormatCurrentUserKeyPath(&usCurrentUserKey
);
178 if (!NT_SUCCESS(Status
))
183 /* Initialize empty key name */
184 RtlInitEmptyUnicodeString(&usKeyName
, awcBuffer
, sizeof(awcBuffer
));
186 /* Append the current user key name */
187 Status
= RtlAppendUnicodeStringToString(&usKeyName
, &usCurrentUserKey
);
189 /* Free the current user key name */
190 RtlFreeUnicodeString(&usCurrentUserKey
);
192 /* Check for success */
193 if (!NT_SUCCESS(Status
))
198 /* Append a '\', we can trust in enough space left. */
199 usKeyName
.Buffer
[usKeyName
.Length
/ sizeof(WCHAR
)] = '\\';
200 usKeyName
.Length
+= sizeof(WCHAR
);
202 /* Append the subkey name */
203 Status
= RtlAppendUnicodeToString(&usKeyName
, pwszKeyName
);
204 if (!NT_SUCCESS(Status
))
209 /* Initialize object attributes */
210 InitializeObjectAttributes(&ObjectAttributes
,
212 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
217 Status
= ZwOpenKey((PHANDLE
)&hkey
, KEY_READ
, &ObjectAttributes
);
218 if (!NT_SUCCESS(Status
))
223 /* Check if the local buffer is sufficient */
224 cbInfoSize
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + cbDataSize
;
225 if (cbInfoSize
<= sizeof(awcBuffer
))
227 pInfo
= (PVOID
)awcBuffer
;
231 /* It's not, allocate a sufficient buffer */
232 pInfo
= ExAllocatePoolWithTag(PagedPool
, cbInfoSize
, TAG_TEMP
);
240 /* Query the value */
241 RtlInitUnicodeString(&usValueName
, pwszValueName
);
242 Status
= ZwQueryValueKey(hkey
,
244 KeyValuePartialInformation
,
248 if (NT_SUCCESS(Status
))
250 /* Did we get the right type */
251 if (pInfo
->Type
== ulType
)
253 /* Copy the contents to the caller */
254 RtlCopyMemory(pvData
, pInfo
->Data
, cbDataSize
);
260 if (pInfo
!= (PVOID
)awcBuffer
)
261 ExFreePoolWithTag(pInfo
, TAG_TEMP
);
263 return NT_SUCCESS(Status
);
269 IN PCWSTR pwszKeyName
,
270 IN PCWSTR pwszValueName
,
276 OBJECT_ATTRIBUTES ObjectAttributes
;
277 UNICODE_STRING usCurrentUserKey
, usKeyName
, usValueName
;
278 WCHAR awcBuffer
[MAX_PATH
];
281 // FIXME: Logged in user versus current process user?
282 /* Get the path of the current user's profile */
283 Status
= RtlFormatCurrentUserKeyPath(&usCurrentUserKey
);
284 if (!NT_SUCCESS(Status
))
286 DPRINT1("RtlFormatCurrentUserKeyPath failed\n");
290 /* Initialize empty key name */
291 RtlInitEmptyUnicodeString(&usKeyName
, awcBuffer
, sizeof(awcBuffer
));
293 /* Append the current user key name */
294 Status
= RtlAppendUnicodeStringToString(&usKeyName
, &usCurrentUserKey
);
295 if (!NT_SUCCESS(Status
))
300 /* Free the current user key name */
301 RtlFreeUnicodeString(&usCurrentUserKey
);
303 /* Append a '\', we can trust in enough space left. */
304 usKeyName
.Buffer
[usKeyName
.Length
/ sizeof(WCHAR
)] = '\\';
305 usKeyName
.Length
+= sizeof(WCHAR
);
307 /* Append the subkey name */
308 Status
= RtlAppendUnicodeToString(&usKeyName
, pwszKeyName
);
309 if (!NT_SUCCESS(Status
))
311 DPRINT1("RtlAppendUnicodeToString failed with Status=0x%lx, buf:%u,%u\n",
312 Status
, usKeyName
.Length
, usKeyName
.MaximumLength
);
316 /* Initialize object attributes */
317 InitializeObjectAttributes(&ObjectAttributes
,
319 OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
,
323 /* Open or create the key */
324 Status
= ZwCreateKey((PHANDLE
)&hkey
,
325 KEY_READ
| KEY_WRITE
,
331 if(!NT_SUCCESS(Status
))
333 DPRINT1("Failed to create key: 0x%x\n", Status
);
337 /* Initialize the value name string */
338 RtlInitUnicodeString(&usValueName
, pwszValueName
);
340 Status
= ZwSetValueKey(hkey
, &usValueName
, 0, ulType
, pvData
, cbDataSize
);
341 if(!NT_SUCCESS(Status
))
343 DPRINT1("Failed to write reg key '%S' value '%S', Status = %lx\n",
344 pwszKeyName
, pwszValueName
, Status
);
350 return NT_SUCCESS(Status
);