ReactOS 0.4.16-dev-91-g764881a
NtLoadUnloadKey.c File Reference
#include "precomp.h"
#include <debug.h>
Include dependency graph for NtLoadUnloadKey.c:

Go to the source code of this file.

Macros

#define REG_CREATED_NEW_KEY   1
 
#define REG_OPENED_EXISTING_KEY   2
 
#define REG_FORCE_UNLOAD   1
 
#define NDEBUG
 

Functions

static NTSTATUS (NTAPI *pNtUnloadKey2)(POBJECT_ATTRIBUTES
 
static BOOLEAN RetrieveCurrentModuleNTDirectory (OUT PUNICODE_STRING NtPath)
 
static NTSTATUS CreateRegKey (OUT PHANDLE KeyHandle, IN HANDLE RootKey OPTIONAL, IN PUNICODE_STRING KeyName, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
 
static NTSTATUS CreateProtoHive (OUT PHANDLE KeyHandle)
 
static VOID DestroyProtoHive (IN HANDLE KeyHandle)
 
static NTSTATUS OpenDirectoryByHandleOrPath (OUT PHANDLE RootPathHandle, IN HANDLE RootDirectory OPTIONAL, IN PUNICODE_STRING RootPath OPTIONAL)
 
static NTSTATUS CreateRegistryFile (IN HANDLE RootDirectory OPTIONAL, IN PUNICODE_STRING RootPath OPTIONAL, IN PCWSTR RegistryKey, IN HANDLE ProtoKeyHandle)
 
static NTSTATUS MyDeleteFile (IN HANDLE RootDirectory OPTIONAL, IN PUNICODE_STRING RootPath OPTIONAL, IN PCWSTR FileName, IN BOOLEAN ForceDelete)
 
static NTSTATUS ConnectRegistry (IN HANDLE RootKey OPTIONAL, IN PCWSTR RegMountPoint, IN HANDLE RootDirectory OPTIONAL, IN PUNICODE_STRING RootPath OPTIONAL, IN PCWSTR RegistryKey)
 
static NTSTATUS DisconnectRegistry (IN HANDLE RootKey OPTIONAL, IN PCWSTR RegMountPoint, IN ULONG Flags)
 
 START_TEST (NtLoadUnloadKey)
 

Variables

static ULONG
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 18 of file NtLoadUnloadKey.c.

◆ REG_CREATED_NEW_KEY

#define REG_CREATED_NEW_KEY   1

Definition at line 11 of file NtLoadUnloadKey.c.

◆ REG_FORCE_UNLOAD

#define REG_FORCE_UNLOAD   1

Definition at line 14 of file NtLoadUnloadKey.c.

◆ REG_OPENED_EXISTING_KEY

#define REG_OPENED_EXISTING_KEY   2

Definition at line 12 of file NtLoadUnloadKey.c.

Function Documentation

◆ ConnectRegistry()

static NTSTATUS ConnectRegistry ( IN HANDLE RootKey  OPTIONAL,
IN PCWSTR  RegMountPoint,
IN HANDLE RootDirectory  OPTIONAL,
IN PUNICODE_STRING RootPath  OPTIONAL,
IN PCWSTR  RegistryKey 
)
static

Definition at line 324 of file NtLoadUnloadKey.c.

330{
332 HANDLE RootPathHandle;
334 OBJECT_ATTRIBUTES KeyObjectAttributes;
336
337 /* Open the root directory */
338 Status = OpenDirectoryByHandleOrPath(&RootPathHandle, RootDirectory, RootPath);
339 if (!NT_SUCCESS(Status))
340 {
341 DPRINT1("OpenDirectoryByHandleOrPath failed, Status 0x%08lx\n", Status);
342 return Status;
343 }
344
345 RtlInitUnicodeString(&KeyName, RegMountPoint);
346 InitializeObjectAttributes(&KeyObjectAttributes,
347 &KeyName,
349 RootKey,
350 NULL);
351
352 RtlInitUnicodeString(&FileName, RegistryKey);
354 &FileName,
356 (HANDLE)((ULONG_PTR)RootPathHandle & ~1), // Remove the opened-locally flag
357 NULL);
358
359 /* Mount the registry hive in the registry namespace */
360 Status = NtLoadKey(&KeyObjectAttributes, &FileObjectAttributes);
361
362 /* Close the root directory (if opened locally), and return */
363 if ((ULONG_PTR)RootPathHandle & 1) NtClose((HANDLE)((ULONG_PTR)RootPathHandle & ~1));
364 return Status;
365}
static NTSTATUS OpenDirectoryByHandleOrPath(OUT PHANDLE RootPathHandle, IN HANDLE RootDirectory OPTIONAL, IN PUNICODE_STRING RootPath OPTIONAL)
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
struct _FileName FileName
Definition: fatprocs.h:897
Status
Definition: gdiplustypes.h:25
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSTATUS NTAPI NtLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes, IN POBJECT_ATTRIBUTES FileObjectAttributes)
Definition: ntapi.c:1129
static PMEMKEY RootKey
Definition: registry.c:55
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ PWDFDEVICE_INIT _In_ PWDF_FILEOBJECT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES FileObjectAttributes
Definition: wdfdevice.h:3400
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699

Referenced by START_TEST().

◆ CreateProtoHive()

static NTSTATUS CreateProtoHive ( OUT PHANDLE  KeyHandle)
static

Definition at line 73 of file NtLoadUnloadKey.c.

75{
78
79 RtlInitUnicodeString(&KeyName, L"\\Registry\\Machine\\SYSTEM\\$$$PROTO.HIV");
81 NULL,
82 &KeyName,
84 NULL);
85 if (!NT_SUCCESS(Status))
86 return Status;
87
89 return Status;
90}
static NTSTATUS CreateRegKey(OUT PHANDLE KeyHandle, IN HANDLE RootKey OPTIONAL, IN PUNICODE_STRING KeyName, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
NTSTATUS NTAPI NtFlushKey(IN HANDLE KeyHandle)
Definition: ntapi.c:1085
#define L(x)
Definition: ntvdm.h:50

Referenced by START_TEST().

◆ CreateRegistryFile()

static NTSTATUS CreateRegistryFile ( IN HANDLE RootDirectory  OPTIONAL,
IN PUNICODE_STRING RootPath  OPTIONAL,
IN PCWSTR  RegistryKey,
IN HANDLE  ProtoKeyHandle 
)
static

Definition at line 159 of file NtLoadUnloadKey.c.

164{
166 HANDLE RootPathHandle, FileHandle;
170
171 /* Open the root directory */
172 Status = OpenDirectoryByHandleOrPath(&RootPathHandle, RootDirectory, RootPath);
173 if (!NT_SUCCESS(Status))
174 {
175 DPRINT1("OpenDirectoryByHandleOrPath failed, Status 0x%08lx\n", Status);
176 return Status;
177 }
178
179 /* Create the file */
180 RtlInitUnicodeString(&FileName, RegistryKey);
182 &FileName,
184 (HANDLE)((ULONG_PTR)RootPathHandle & ~1), // Remove the opened-locally flag
185 NULL);
187 FILE_GENERIC_WRITE /* | DELETE */,
190 NULL,
191 FILE_ATTRIBUTE_NORMAL /* | FILE_FLAG_DELETE_ON_CLOSE */,
192 0,
195 NULL,
196 0);
197 if (!NT_SUCCESS(Status))
198 {
199 DPRINT1("NtCreateFile(%wZ) failed, Status 0x%08lx\n", &FileName, Status);
200 goto Cleanup;
201 }
202
203 /* Save the selected hive into the file */
205 if (!NT_SUCCESS(Status))
206 {
207 DPRINT1("NtSaveKeyEx(%wZ) failed, Status 0x%08lx\n", &FileName, Status);
208 }
209
210 /* Close the file, the root directory (if opened locally), and return */
212Cleanup:
213 if ((ULONG_PTR)RootPathHandle & 1) NtClose((HANDLE)((ULONG_PTR)RootPathHandle & ~1));
214 return Status;
215}
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
static const WCHAR Cleanup[]
Definition: register.c:80
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSTATUS NTAPI NtCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength)
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
NTSTATUS NTAPI NtSaveKeyEx(IN HANDLE KeyHandle, IN HANDLE FileHandle, IN ULONG Flags)
Definition: ntapi.c:1643
#define REG_LATEST_FORMAT
Definition: cmtypes.h:98

Referenced by START_TEST().

◆ CreateRegKey()

static NTSTATUS CreateRegKey ( OUT PHANDLE  KeyHandle,
IN HANDLE RootKey  OPTIONAL,
IN PUNICODE_STRING  KeyName,
IN ULONG  CreateOptions,
OUT PULONG Disposition  OPTIONAL 
)
static

Definition at line 49 of file NtLoadUnloadKey.c.

55{
57
59 KeyName,
61 RootKey,
62 NULL);
66 0,
67 NULL,
70}
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
NTSTATUS NTAPI NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: ntapi.c:240
_Must_inspect_result_ _In_opt_ WDFKEY _In_ PCUNICODE_STRING _In_ ACCESS_MASK _In_ ULONG CreateOptions
Definition: wdfregistry.h:118

Referenced by CreateProtoHive(), and START_TEST().

◆ DestroyProtoHive()

static VOID DestroyProtoHive ( IN HANDLE  KeyHandle)
static

Definition at line 93 of file NtLoadUnloadKey.c.

95{
98}
NTSTATUS NTAPI NtDeleteKey(IN HANDLE KeyHandle)
Definition: ntapi.c:408

Referenced by START_TEST().

◆ DisconnectRegistry()

static NTSTATUS DisconnectRegistry ( IN HANDLE RootKey  OPTIONAL,
IN PCWSTR  RegMountPoint,
IN ULONG  Flags 
)
static

Definition at line 371 of file NtLoadUnloadKey.c.

375{
378
379 RtlInitUnicodeString(&KeyName, RegMountPoint);
381 &KeyName,
383 RootKey,
384 NULL);
385 if (!pNtUnloadKey2)
386 {
387 win_skip("NtUnloadKey2 unavailable, using NtUnloadKey. Flags %lu\n", Flags);
389 }
390 return pNtUnloadKey2(&ObjectAttributes, Flags);
391}
NTSTATUS NTAPI NtUnloadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes)
Definition: ntapi.c:1789
#define win_skip
Definition: test.h:163
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by START_TEST().

◆ MyDeleteFile()

static NTSTATUS MyDeleteFile ( IN HANDLE RootDirectory  OPTIONAL,
IN PUNICODE_STRING RootPath  OPTIONAL,
IN PCWSTR  FileName,
IN BOOLEAN  ForceDelete 
)
static

Definition at line 221 of file NtLoadUnloadKey.c.

226{
228 HANDLE RootPathHandle;
229 UNICODE_STRING NtPath;
233 FILE_DISPOSITION_INFORMATION FileDispInfo;
234 BOOLEAN RetryOnce = FALSE;
235
236 /* Open the root directory */
237 Status = OpenDirectoryByHandleOrPath(&RootPathHandle, RootDirectory, RootPath);
238 if (!NT_SUCCESS(Status))
239 {
240 DPRINT1("OpenDirectoryByHandleOrPath failed, Status 0x%08lx\n", Status);
241 return Status;
242 }
243
244 /* Open the directory name that was passed in */
247 &NtPath,
249 RootPathHandle,
250 NULL);
251
252Retry: /* We go back there once if RetryOnce == TRUE */
255 (RetryOnce ? FILE_WRITE_ATTRIBUTES : 0),
260 if (!NT_SUCCESS(Status))
261 {
262 DPRINT1("NtOpenFile failed with Status 0x%08lx\n", Status);
263 return Status;
264 }
265
266 if (RetryOnce)
267 {
269
275 if (!NT_SUCCESS(Status))
276 {
277 DPRINT1("NtQueryInformationFile failed with Status 0x%08lx\n", Status);
279 return Status;
280 }
281
282 FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;
289 if (!NT_SUCCESS(Status))
290 {
291 DPRINT1("NtSetInformationFile failed with Status 0x%08lx\n", Status);
292 return Status;
293 }
294 }
295
296 /* Ask for the file to be deleted */
297 FileDispInfo.DeleteFile = TRUE;
300 &FileDispInfo,
304
305 if (!NT_SUCCESS(Status))
306 DPRINT1("Deletion of file '%S' failed, Status 0x%08lx\n", FileName, Status);
307
308 // FIXME: Check the precise value of Status!
309 if (!NT_SUCCESS(Status) && ForceDelete && !RetryOnce)
310 {
311 /* Retry once */
312 RetryOnce = TRUE;
313 goto Retry;
314 }
315
316 /* Return result to the caller */
317 return Status;
318}
unsigned char BOOLEAN
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:312
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define FILE_SHARE_READ
Definition: compat.h:136
@ FileBasicInformation
Definition: from_kernel.h:65
@ FileDispositionInformation
Definition: from_kernel.h:74
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
Definition: iofunc.c:3096
NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define DELETE
Definition: nt_native.h:57

Referenced by START_TEST().

◆ NTSTATUS()

static NTSTATUS ( NTAPI pNtUnloadKey2)
static

◆ OpenDirectoryByHandleOrPath()

static NTSTATUS OpenDirectoryByHandleOrPath ( OUT PHANDLE  RootPathHandle,
IN HANDLE RootDirectory  OPTIONAL,
IN PUNICODE_STRING RootPath  OPTIONAL 
)
static

Definition at line 101 of file NtLoadUnloadKey.c.

105{
109
110 *RootPathHandle = NULL;
111
112 /*
113 * RootDirectory and RootPath cannot be either both NULL
114 * or both non-NULL, when being specified.
115 */
116 if ((!RootDirectory && !RootPath) ||
117 ( RootDirectory && RootPath))
118 {
120 }
121
122 if (!RootDirectory && RootPath)
123 {
124 /* Open the root directory path */
126 RootPath,
128 NULL,
129 NULL);
130 Status = NtOpenFile(RootPathHandle,
131 // FILE_TRAVERSE is needed to be able to use the handle as RootDirectory for future InitializeObjectAttributes calls.
132 FILE_LIST_DIRECTORY | FILE_ADD_FILE /* | FILE_ADD_SUBDIRECTORY */ | FILE_TRAVERSE | SYNCHRONIZE,
136 FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE /* | FILE_OPEN_FOR_BACKUP_INTENT */);
137 if (!NT_SUCCESS(Status))
138 {
139 DPRINT1("NtOpenFile(%wZ) failed, Status 0x%08lx\n", RootPath, Status);
140 return Status;
141 }
142
143 /* Mark the handle as being opened locally */
144 *RootPathHandle = (HANDLE)((ULONG_PTR)*RootPathHandle | 1);
145 }
146 else if (RootDirectory && !RootPath)
147 {
148 *RootPathHandle = RootDirectory;
149 }
150 // No other cases possible
151
152 return STATUS_SUCCESS;
153}
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
#define FILE_TRAVERSE
Definition: nt_native.h:643
#define FILE_ADD_FILE
Definition: nt_native.h:632
#define STATUS_SUCCESS
Definition: shellext.h:65
PVOID HANDLE
Definition: typedefs.h:73
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by ConnectRegistry(), CreateRegistryFile(), and MyDeleteFile().

◆ RetrieveCurrentModuleNTDirectory()

static BOOLEAN RetrieveCurrentModuleNTDirectory ( OUT PUNICODE_STRING  NtPath)
static

Definition at line 31 of file NtLoadUnloadKey.c.

33{
34 WCHAR ModulePath[MAX_PATH];
35 PWSTR PathSep;
36
37 /* Retrieve the current path where the test is running */
38 GetModuleFileNameW(NULL, ModulePath, _countof(ModulePath));
39 PathSep = wcsrchr(ModulePath, L'\\');
40 if (!PathSep)
41 PathSep = ModulePath + wcslen(ModulePath);
42 *PathSep = UNICODE_NULL;
43
44 /* Convert the path to NT format and work with it for now on */
45 return RtlDosPathNameToNtPathName_U(ModulePath, NtPath, NULL, NULL);
46}
#define wcsrchr
Definition: compat.h:16
#define MAX_PATH
Definition: compat.h:34
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)
#define UNICODE_NULL
#define _countof(array)
Definition: sndvol32.h:70
uint16_t * PWSTR
Definition: typedefs.h:56
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( NtLoadUnloadKey  )

Definition at line 394 of file NtLoadUnloadKey.c.

395{
396 typedef struct _HIVE_LIST_ENTRY
397 {
399 PCWSTR RegMountPoint;
401
402 static const HIVE_LIST_ENTRY RegistryHives[] =
403 {
404 { L"TestHive1", L"\\Registry\\Machine\\TestHive1" },
405 { L"TestHive2", L"\\Registry\\Machine\\TestHive2" },
406 };
407
409 UNICODE_STRING NtTestPath;
413 UINT i;
414 BOOLEAN PrivilegeSet[2] = {FALSE, FALSE};
415 WCHAR PathBuffer[MAX_PATH];
416
417 pNtUnloadKey2 = (PVOID)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtUnloadKey2");
418
419 /* Retrieve our current directory */
421
422 /* Acquire restore privilege */
424 if (!NT_SUCCESS(Status))
425 {
426 skip("RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE) failed (Status 0x%08lx)\n", Status);
427 /* Exit prematurely here.... */
428 // goto Cleanup;
429 RtlFreeUnicodeString(&NtTestPath);
430 return;
431 }
432
433 /* Acquire backup privilege */
435 if (!NT_SUCCESS(Status))
436 {
437 skip("RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE) failed (Status 0x%08lx)\n", Status);
438 RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]);
439 /* Exit prematurely here.... */
440 // goto Cleanup;
441 RtlFreeUnicodeString(&NtTestPath);
442 return;
443 }
444
445 /* Create the template proto-hive */
447 if (!NT_SUCCESS(Status))
448 {
449 skip("CreateProtoHive() failed to create the proto-hive; Status 0x%08lx\n", Status);
450 goto Cleanup;
451 }
452
453 /* Create two registry hive files from it */
454 for (i = 0; i < _countof(RegistryHives); ++i)
455 {
456 Status = CreateRegistryFile(NULL, &NtTestPath,
457 RegistryHives[i].HiveName,
458 KeyHandle);
459 if (!NT_SUCCESS(Status))
460 {
461 DPRINT1("CreateRegistryFile(%S) failed, Status 0x%08lx\n", RegistryHives[i].HiveName, Status);
462 /* Exit prematurely here.... */
463 break;
464 }
465 }
466
467 /* That is now done, remove the proto-hive */
469
470 /* Exit prematurely here if we failed */
471 if (!NT_SUCCESS(Status))
472 goto Cleanup;
473
474
475/***********************************************************************************************/
476
477
478 /* Now, mount the first hive */
479 Status = ConnectRegistry(NULL, RegistryHives[0].RegMountPoint,
480 NULL, &NtTestPath,
481 RegistryHives[0].HiveName);
482 if (!NT_SUCCESS(Status))
483 {
484 DPRINT1("ConnectRegistry('%wZ\\%S', '%S') failed, Status 0x%08lx\n",
485 &NtTestPath, RegistryHives[0].HiveName, RegistryHives[0].RegMountPoint, Status);
486 }
487
488 /* Create or open a key inside the mounted hive */
489 StringCchPrintfW(PathBuffer, _countof(PathBuffer), L"%s\\%s", RegistryHives[0].RegMountPoint, L"MyKey_1");
490 RtlInitUnicodeString(&KeyName, PathBuffer);
491
492 KeyHandle = NULL;
494 NULL,
495 &KeyName,
497 &Disposition);
498 if (!NT_SUCCESS(Status))
499 {
500 DPRINT1("CreateRegKey(%wZ) failed (Status %lx)\n", &KeyName, Status);
501 }
502 else
503 {
504 DPRINT1("CreateRegKey(%wZ) succeeded to %s the key (Status %lx)\n",
505 &KeyName,
506 Disposition == REG_CREATED_NEW_KEY ? "create" : /* REG_OPENED_EXISTING_KEY */ "open",
507 Status);
508 }
509
510 /* The key handle must be valid here */
513
514 /* Attempt to unmount the hive, with the handle key still opened */
515 Status = DisconnectRegistry(NULL, RegistryHives[0].RegMountPoint, 0); // Same as NtUnloadKey(&ObjectAttributes);
516 DPRINT1("Unmounting '%S' %s\n", RegistryHives[0].RegMountPoint, NT_SUCCESS(Status) ? "succeeded" : "failed");
518
519 /* The key handle should still be valid here */
522
523 /* Force-unmount the hive, with the handle key still opened */
525 DPRINT1("Force-unmounting '%S' %s\n", RegistryHives[0].RegMountPoint, NT_SUCCESS(Status) ? "succeeded" : "failed");
527
528 /* The key handle should not be valid anymore */
530 if (Status != STATUS_KEY_DELETED /* Win2k3 */ &&
531 Status != STATUS_HIVE_UNLOADED /* Win7+ */)
532 {
534 }
535
536 /* The key handle should not be valid anymore */
539
540 /* Close by principle the handle, but should this fail? */
543
544
545/***********************************************************************************************/
546
547
548 /* Now, mount the first hive, again */
549 Status = ConnectRegistry(NULL, RegistryHives[0].RegMountPoint,
550 NULL, &NtTestPath,
551 RegistryHives[0].HiveName);
552 if (!NT_SUCCESS(Status))
553 {
554 DPRINT1("ConnectRegistry('%wZ\\%S', '%S') failed, Status 0x%08lx\n",
555 &NtTestPath, RegistryHives[0].HiveName, RegistryHives[0].RegMountPoint, Status);
556 }
557
558 /* Create or open a key inside the mounted hive */
559 StringCchPrintfW(PathBuffer, _countof(PathBuffer), L"%s\\%s", RegistryHives[0].RegMountPoint, L"MyKey_2");
560 RtlInitUnicodeString(&KeyName, PathBuffer);
561
562 KeyHandle = NULL;
564 NULL,
565 &KeyName,
567 &Disposition);
568 if (!NT_SUCCESS(Status))
569 {
570 DPRINT1("CreateRegKey(%wZ) failed (Status %lx)\n", &KeyName, Status);
571 }
572 else
573 {
574 DPRINT1("CreateRegKey(%wZ) succeeded to %s the key (Status %lx)\n",
575 &KeyName,
576 Disposition == REG_CREATED_NEW_KEY ? "create" : /* REG_OPENED_EXISTING_KEY */ "open",
577 Status);
578 }
579
580 /* The key handle must be valid here */
583
584 /* Delete the key, this should succeed */
587
588 /* Close the handle, this should succeed */
591
592 /* Attempt to unmount the hive (no forcing), this should succeed */
593 Status = DisconnectRegistry(NULL, RegistryHives[0].RegMountPoint, 0); // Same as NtUnloadKey(&ObjectAttributes);
594 DPRINT1("Unmounting '%S' %s\n", RegistryHives[0].RegMountPoint, NT_SUCCESS(Status) ? "succeeded" : "failed");
596
597 /* Force-unmount the hive (it is already unmounted), this should fail */
599 DPRINT1("Force-unmounting '%S' %s\n", RegistryHives[0].RegMountPoint, NT_SUCCESS(Status) ? "succeeded" : "failed");
601
602#if 0
603 /* Close by principle the handle, but should this fail? */
606#endif
607
608
609/***********************************************************************************************/
610
611
612Cleanup:
613
614 /* Destroy the hive files */
615 for (i = 0; i < _countof(RegistryHives); ++i)
616 {
617 Status = MyDeleteFile(NULL, &NtTestPath,
618 RegistryHives[i].HiveName, TRUE);
619 if (!NT_SUCCESS(Status))
620 DPRINT1("MyDeleteFile(%S) failed, Status 0x%08lx\n", RegistryHives[i].HiveName, Status);
621 }
622
623 /* Remove restore and backup privileges */
624 RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, PrivilegeSet[1], FALSE, &PrivilegeSet[1]);
625 RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE, PrivilegeSet[0], FALSE, &PrivilegeSet[0]);
626
627 RtlFreeUnicodeString(&NtTestPath);
628}
static NTSTATUS ConnectRegistry(IN HANDLE RootKey OPTIONAL, IN PCWSTR RegMountPoint, IN HANDLE RootDirectory OPTIONAL, IN PUNICODE_STRING RootPath OPTIONAL, IN PCWSTR RegistryKey)
static NTSTATUS MyDeleteFile(IN HANDLE RootDirectory OPTIONAL, IN PUNICODE_STRING RootPath OPTIONAL, IN PCWSTR FileName, IN BOOLEAN ForceDelete)
static NTSTATUS CreateRegistryFile(IN HANDLE RootDirectory OPTIONAL, IN PUNICODE_STRING RootPath OPTIONAL, IN PCWSTR RegistryKey, IN HANDLE ProtoKeyHandle)
static VOID DestroyProtoHive(IN HANDLE KeyHandle)
#define REG_CREATED_NEW_KEY
static NTSTATUS CreateProtoHive(OUT PHANDLE KeyHandle)
static NTSTATUS DisconnectRegistry(IN HANDLE RootKey OPTIONAL, IN PCWSTR RegMountPoint, IN ULONG Flags)
#define REG_FORCE_UNLOAD
static BOOLEAN RetrieveCurrentModuleNTDirectory(OUT PUNICODE_STRING NtPath)
#define ok_hex(expression, result)
Definition: atltest.h:94
#define ok_ntstatus(status, expected)
Definition: atltest.h:135
#define skip(...)
Definition: atltest.h:64
HIVE_LIST_ENTRY RegistryHives[]
Definition: registry.c:581
struct _HIVE_LIST_ENTRY HIVE_LIST_ENTRY
#define GetProcAddress(x, y)
Definition: compat.h:753
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define SE_BACKUP_PRIVILEGE
Definition: security.c:671
#define SE_RESTORE_PRIVILEGE
Definition: security.c:672
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI NTSTATUS NTAPI RtlAdjustPrivilege(_In_ ULONG Privilege, _In_ BOOLEAN NewValue, _In_ BOOLEAN ForThread, _Out_ PBOOLEAN OldValue)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define STATUS_KEY_DELETED
Definition: ntstatus.h:613
#define STATUS_HIVE_UNLOADED
Definition: ntstatus.h:962
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
Definition: registry.c:569
PCWSTR HiveName
Definition: registry.c:570
const uint16_t * PCWSTR
Definition: typedefs.h:57
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG
Definition: typedefs.h:59

Variable Documentation

◆ ULONG

Definition at line 28 of file NtLoadUnloadKey.c.