ReactOS  0.4.15-dev-1070-ge1a01de
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;
335  OBJECT_ATTRIBUTES FileObjectAttributes;
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);
353  InitializeObjectAttributes(&FileObjectAttributes,
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 }
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
static PMEMKEY RootKey
Definition: registry.c:55
static NTSTATUS OpenDirectoryByHandleOrPath(OUT PHANDLE RootPathHandle, IN HANDLE RootDirectory OPTIONAL, IN PUNICODE_STRING RootPath OPTIONAL)
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
LONG NTSTATUS
Definition: precomp.h:26
uint32_t ULONG_PTR
Definition: typedefs.h:65
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI NtLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes, IN POBJECT_ATTRIBUTES FileObjectAttributes)
Definition: ntapi.c:1129
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
Status
Definition: gdiplustypes.h:24
struct _FileName FileName
Definition: fatprocs.h:893
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106

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 }
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
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:4711
LONG NTSTATUS
Definition: precomp.h:26
smooth NULL
Definition: ftsmooth.c:416
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS NTAPI NtFlushKey(IN HANDLE KeyHandle)
Definition: ntapi.c:1085
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)

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 */,
189  &IoStatusBlock,
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 */
204  Status = NtSaveKeyEx(ProtoKeyHandle, FileHandle, REG_LATEST_FORMAT);
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 */
212 Cleanup:
213  if ((ULONG_PTR)RootPathHandle & 1) NtClose((HANDLE)((ULONG_PTR)RootPathHandle & ~1));
214  return Status;
215 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
static NTSTATUS OpenDirectoryByHandleOrPath(OUT PHANDLE RootPathHandle, IN HANDLE RootDirectory OPTIONAL, IN PUNICODE_STRING RootPath OPTIONAL)
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
LONG NTSTATUS
Definition: precomp.h:26
uint32_t ULONG_PTR
Definition: typedefs.h:65
HANDLE FileHandle
Definition: stats.c:38
smooth NULL
Definition: ftsmooth.c:416
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
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 NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
Status
Definition: gdiplustypes.h:24
#define REG_LATEST_FORMAT
Definition: cmtypes.h:98
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
static const WCHAR Cleanup[]
Definition: register.c:80
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
struct _FileName FileName
Definition: fatprocs.h:893
NTSTATUS NTAPI NtSaveKeyEx(IN HANDLE KeyHandle, IN HANDLE FileHandle, IN ULONG Flags)
Definition: ntapi.c:1643
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define DPRINT1
Definition: precomp.h:8
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106

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);
63  return NtCreateKey(KeyHandle,
66  0,
67  NULL,
69  Disposition);
70 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
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
static PMEMKEY RootKey
Definition: registry.c:55
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
smooth NULL
Definition: ftsmooth.c:416
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG CreateOptions
Definition: fltkernel.h:1230
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106

Referenced by CreateProtoHive(), and START_TEST().

◆ DestroyProtoHive()

static VOID DestroyProtoHive ( IN HANDLE  KeyHandle)
static

Definition at line 93 of file NtLoadUnloadKey.c.

95 {
98 }
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
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);
388  return NtUnloadKey(&ObjectAttributes);
389  }
390  return pNtUnloadKey2(&ObjectAttributes, Flags);
391 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
static PMEMKEY RootKey
Definition: registry.c:55
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI NtUnloadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes)
Definition: ntapi.c:1789
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define win_skip
Definition: test.h:149

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 */
245  RtlInitUnicodeString(&NtPath, FileName);
247  &NtPath,
249  RootPathHandle,
250  NULL);
251 
252 Retry: /* We go back there once if RetryOnce == TRUE */
255  (RetryOnce ? FILE_WRITE_ATTRIBUTES : 0),
257  &IoStatusBlock,
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 
271  &IoStatusBlock,
273  sizeof(FILE_BASIC_INFORMATION),
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;
284  &IoStatusBlock,
286  sizeof(FILE_BASIC_INFORMATION),
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;
299  &IoStatusBlock,
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 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
NTSTATUS NTAPI NtSetInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass)
static NTSTATUS OpenDirectoryByHandleOrPath(OUT PHANDLE RootPathHandle, IN HANDLE RootDirectory OPTIONAL, IN PUNICODE_STRING RootPath OPTIONAL)
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define FILE_SHARE_READ
Definition: compat.h:136
HANDLE FileHandle
Definition: stats.c:38
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
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:3951
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
Status
Definition: gdiplustypes.h:24
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass)
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#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,
134  &IoStatusBlock,
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 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_READ
Definition: compat.h:136
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FILE_TRAVERSE
Definition: nt_native.h:643
#define FILE_ADD_FILE
Definition: nt_native.h:632
smooth NULL
Definition: ftsmooth.c:416
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:3951
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PVOID HANDLE
Definition: typedefs.h:73
Status
Definition: gdiplustypes.h:24
#define SYNCHRONIZE
Definition: nt_native.h:61
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define DPRINT1
Definition: precomp.h:8
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
return STATUS_SUCCESS
Definition: btrfs.c:3014

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 }
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
uint16_t * PWSTR
Definition: typedefs.h:56
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define _countof(array)
Definition: sndvol32.h:68
#define MAX_PATH
Definition: compat.h:34
static const WCHAR L[]
Definition: oid.c:1250
#define wcsrchr
Definition: compat.h:16
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)

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;
400  } HIVE_LIST_ENTRY;
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 */
434  Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE, TRUE, FALSE, &PrivilegeSet[1]);
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 
612 Cleanup:
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 }
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
const uint16_t * PCWSTR
Definition: typedefs.h:57
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:4711
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
static VOID DestroyProtoHive(IN HANDLE KeyHandle)
LONG NTSTATUS
Definition: precomp.h:26
#define SE_RESTORE_PRIVILEGE
Definition: security.c:672
NTSYSAPI NTSTATUS NTAPI RtlAdjustPrivilege(_In_ ULONG Privilege, _In_ BOOLEAN NewValue, _In_ BOOLEAN ForThread, _Out_ PBOOLEAN OldValue)
#define STATUS_HIVE_UNLOADED
Definition: ntstatus.h:962
#define ok_hex(expression, result)
Definition: atltest.h:94
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
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 FALSE
Definition: types.h:117
static NTSTATUS ConnectRegistry(IN HANDLE RootKey OPTIONAL, IN PCWSTR RegMountPoint, IN HANDLE RootDirectory OPTIONAL, IN PUNICODE_STRING RootPath OPTIONAL, IN PCWSTR RegistryKey)
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static BOOLEAN RetrieveCurrentModuleNTDirectory(OUT PUNICODE_STRING NtPath)
#define STATUS_KEY_DELETED
Definition: ntstatus.h:613
void * PVOID
Definition: retypes.h:9
static NTSTATUS CreateProtoHive(OUT PHANDLE KeyHandle)
static NTSTATUS MyDeleteFile(IN HANDLE RootDirectory OPTIONAL, IN PUNICODE_STRING RootPath OPTIONAL, IN PCWSTR FileName, IN BOOLEAN ForceDelete)
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
static NTSTATUS CreateRegistryFile(IN HANDLE RootDirectory OPTIONAL, IN PUNICODE_STRING RootPath OPTIONAL, IN PCWSTR RegistryKey, IN HANDLE ProtoKeyHandle)
Definition: registry.c:568
PCWSTR HiveName
Definition: registry.c:570
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define _countof(array)
Definition: sndvol32.h:68
#define MAX_PATH
Definition: compat.h:34
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
Status
Definition: gdiplustypes.h:24
static const WCHAR L[]
Definition: oid.c:1250
static const WCHAR Cleanup[]
Definition: register.c:80
NTSTATUS NTAPI NtDeleteKey(IN HANDLE KeyHandle)
Definition: ntapi.c:408
#define REG_FORCE_UNLOAD
NTSTATUS NTAPI NtFlushKey(IN HANDLE KeyHandle)
Definition: ntapi.c:1085
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
unsigned int UINT
Definition: ndis.h:50
HIVE_LIST_ENTRY RegistryHives[]
Definition: registry.c:581
#define DPRINT1
Definition: precomp.h:8
#define skip(...)
Definition: atltest.h:64
#define ok_ntstatus(status, expected)
Definition: atltest.h:135
unsigned int ULONG
Definition: retypes.h:1
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
#define SE_BACKUP_PRIVILEGE
Definition: security.c:671
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define REG_CREATED_NEW_KEY
#define GetProcAddress(x, y)
Definition: compat.h:501
static NTSTATUS DisconnectRegistry(IN HANDLE RootKey OPTIONAL, IN PCWSTR RegMountPoint, IN ULONG Flags)
return STATUS_SUCCESS
Definition: btrfs.c:3014
struct _HIVE_LIST_ENTRY HIVE_LIST_ENTRY

Variable Documentation

◆ ULONG

Definition at line 28 of file NtLoadUnloadKey.c.