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: subsystem/win32/win32k/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
,
36 Status
= ZwOpenKey(&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 cbDataSize
= cbInfoSize
- FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION
, Data
);
87 if (NT_SUCCESS(Status
))
89 /* Did we get the right type */
90 if (pInfo
->Type
== ulType
)
92 /* Copy the contents to the caller. Make sure strings are null terminated */
93 if (ulType
== REG_SZ
|| ulType
== REG_MULTI_SZ
|| ulType
== REG_EXPAND_SZ
)
94 RtlStringCbCopyNW((LPWSTR
)pvData
, *pcbValue
, (LPWSTR
)pInfo
->Data
, cbDataSize
);
96 RtlCopyMemory(pvData
, pInfo
->Data
, cbDataSize
);
99 Status
= STATUS_OBJECT_TYPE_MISMATCH
;
102 /* Return the data size to the caller */
103 *pcbValue
= cbDataSize
;
106 if (pInfo
!= (PVOID
)ajBuffer
)
107 ExFreePoolWithTag(pInfo
, TAG_TEMP
);
115 RegWriteSZ(HKEY hkey
, PWSTR pwszValue
, PWSTR pwszData
)
117 UNICODE_STRING ustrValue
;
118 UNICODE_STRING ustrData
;
120 RtlInitUnicodeString(&ustrValue
, pwszValue
);
121 RtlInitUnicodeString(&ustrData
, pwszData
);
122 ZwSetValueKey(hkey
, &ustrValue
, 0, REG_SZ
, &ustrData
, ustrData
.Length
+ sizeof(WCHAR
));
127 RegWriteDWORD(HKEY hkey
, PWSTR pwszValue
, DWORD dwData
)
129 UNICODE_STRING ustrValue
;
131 RtlInitUnicodeString(&ustrValue
, pwszValue
);
132 ZwSetValueKey(hkey
, &ustrValue
, 0, REG_DWORD
, &dwData
, sizeof(DWORD
));
137 RegReadDWORD(HKEY hkey
, PWSTR pwszValue
, PDWORD pdwData
)
140 ULONG cbSize
= sizeof(DWORD
);
141 Status
= RegQueryValue(hkey
, pwszValue
, REG_DWORD
, pdwData
, &cbSize
);
142 return NT_SUCCESS(Status
);
148 IN PCWSTR pwszKeyName
,
149 IN PCWSTR pwszValueName
,
155 OBJECT_ATTRIBUTES ObjectAttributes
;
156 UNICODE_STRING usCurrentUserKey
, usKeyName
, usValueName
;
157 WCHAR awcBuffer
[MAX_PATH
];
159 PKEY_VALUE_PARTIAL_INFORMATION pInfo
;
160 ULONG cbInfoSize
, cbReqSize
;
162 /* Get the path of the current user's profile */
163 Status
= RtlFormatCurrentUserKeyPath(&usCurrentUserKey
);
164 if (!NT_SUCCESS(Status
))
169 /* Initialize empty key name */
170 RtlInitEmptyUnicodeString(&usKeyName
, awcBuffer
, sizeof(awcBuffer
));
172 /* Append the current user key name */
173 Status
= RtlAppendUnicodeStringToString(&usKeyName
, &usCurrentUserKey
);
175 /* Free the current user key name */
176 RtlFreeUnicodeString(&usCurrentUserKey
);
178 /* Check for success */
179 if (!NT_SUCCESS(Status
))
184 /* Append a '\', we can trust in enough space left. */
185 usKeyName
.Buffer
[usKeyName
.Length
/ sizeof(WCHAR
)] = '\\';
186 usKeyName
.Length
+= sizeof(WCHAR
);
188 /* Append the subkey name */
189 Status
= RtlAppendUnicodeToString(&usKeyName
, pwszKeyName
);
190 if (!NT_SUCCESS(Status
))
195 /* Initialize object attributes */
196 InitializeObjectAttributes(&ObjectAttributes
,
198 OBJ_CASE_INSENSITIVE
,
203 Status
= ZwOpenKey(&hkey
, KEY_READ
, &ObjectAttributes
);
204 if (!NT_SUCCESS(Status
))
209 /* Check if the local buffer is sufficient */
210 cbInfoSize
= sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + cbDataSize
;
211 if (cbInfoSize
<= sizeof(awcBuffer
))
213 pInfo
= (PVOID
)awcBuffer
;
217 /* It's not, allocate a sufficient buffer */
218 pInfo
= ExAllocatePoolWithTag(PagedPool
, cbInfoSize
, TAG_TEMP
);
226 /* Query the value */
227 RtlInitUnicodeString(&usValueName
, pwszValueName
);
228 Status
= ZwQueryValueKey(hkey
,
230 KeyValuePartialInformation
,
234 if (NT_SUCCESS(Status
))
236 /* Did we get the right type */
237 if (pInfo
->Type
== ulType
)
239 /* Copy the contents to the caller */
240 RtlCopyMemory(pvData
, pInfo
->Data
, cbDataSize
);
246 if (pInfo
!= (PVOID
)awcBuffer
)
247 ExFreePoolWithTag(pInfo
, TAG_TEMP
);
249 return NT_SUCCESS(Status
);
255 IN PCWSTR pwszKeyName
,
256 IN PCWSTR pwszValueName
,
262 OBJECT_ATTRIBUTES ObjectAttributes
;
263 UNICODE_STRING usCurrentUserKey
, usKeyName
, usValueName
;
264 WCHAR awcBuffer
[MAX_PATH
];
267 // FIXME: logged in user versus current process user?
268 /* Get the path of the current user's profile */
269 Status
= RtlFormatCurrentUserKeyPath(&usCurrentUserKey
);
270 if (!NT_SUCCESS(Status
))
272 DPRINT1("RtlFormatCurrentUserKeyPath failed\n");
276 /* Initialize empty key name */
277 RtlInitEmptyUnicodeString(&usKeyName
, awcBuffer
, sizeof(awcBuffer
));
279 /* Append the current user key name */
280 Status
= RtlAppendUnicodeStringToString(&usKeyName
, &usCurrentUserKey
);
281 if (!NT_SUCCESS(Status
))
286 /* Free the current user key name */
287 RtlFreeUnicodeString(&usCurrentUserKey
);
289 /* Append a '\', we can trust in enough space left. */
290 usKeyName
.Buffer
[usKeyName
.Length
/ sizeof(WCHAR
)] = '\\';
291 usKeyName
.Length
+= sizeof(WCHAR
);
293 /* Append the subkey name */
294 Status
= RtlAppendUnicodeToString(&usKeyName
, pwszKeyName
);
295 if (!NT_SUCCESS(Status
))
297 DPRINT1("RtlAppendUnicodeToString failed with Status=%lx, buf:%d,%d\n",
298 Status
, usKeyName
.Length
, usKeyName
.MaximumLength
);
302 /* Initialize object attributes */
303 InitializeObjectAttributes(&ObjectAttributes
,
305 OBJ_CASE_INSENSITIVE
,
309 /* Open or create the key */
310 Status
= ZwCreateKey(&hkey
,
311 KEY_READ
| KEY_WRITE
,
317 if(!NT_SUCCESS(Status
))
319 DPRINT1("Failed to create key: 0x%x\n", Status
);
323 /* Initialize the value name string */
324 RtlInitUnicodeString(&usValueName
, pwszValueName
);
326 Status
= ZwSetValueKey(hkey
, &usValueName
, 0, ulType
, pvData
, cbDataSize
);
327 if(!NT_SUCCESS(Status
))
329 DPRINT1("Failed to write reg key '%S' value '%S', Status = %lx\n",
330 pwszKeyName
, pwszValueName
, Status
);
336 return NT_SUCCESS(Status
);