ReactOS  0.4.14-dev-293-g2b39b42
regutil.c File Reference
#include "precomp.h"
#include "filesup.h"
#include "regutil.h"
#include <debug.h>
Include dependency graph for regutil.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS CreateNestedKey (PHANDLE KeyHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, ULONG CreateOptions)
 
NTSTATUS CreateRegistryFile (IN PUNICODE_STRING NtSystemRoot, IN PCWSTR RegistryKey, IN BOOLEAN IsHiveNew, IN HANDLE ProtoKeyHandle)
 
NTSTATUS CreateSymLinkKey (IN HANDLE RootKey OPTIONAL, IN PCWSTR LinkKeyName, IN PCWSTR TargetKeyName)
 
NTSTATUS DeleteSymLinkKey (IN HANDLE RootKey OPTIONAL, IN PCWSTR LinkKeyName)
 
NTSTATUS ConnectRegistry (IN HANDLE RootKey OPTIONAL, IN PCWSTR RegMountPoint, IN PUNICODE_STRING NtSystemRoot, IN PCWSTR RegistryKey)
 
NTSTATUS DisconnectRegistry (IN HANDLE RootKey OPTIONAL, IN PCWSTR RegMountPoint, IN ULONG Flags)
 
NTSTATUS VerifyRegistryHive (IN PUNICODE_STRING NtSystemRoot, IN PCWSTR RegistryKey)
 

Variables

static UNICODE_STRING SymbolicLinkValueName
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 16 of file regutil.c.

Function Documentation

◆ ConnectRegistry()

NTSTATUS ConnectRegistry ( IN HANDLE RootKey  OPTIONAL,
IN PCWSTR  RegMountPoint,
IN PUNICODE_STRING  NtSystemRoot,
IN PCWSTR  RegistryKey 
)

Definition at line 391 of file regutil.c.

402 {
404  OBJECT_ATTRIBUTES KeyObjectAttributes;
405  OBJECT_ATTRIBUTES FileObjectAttributes;
406  WCHAR PathBuffer[MAX_PATH];
407 
408  RtlInitUnicodeString(&KeyName, RegMountPoint);
409  InitializeObjectAttributes(&KeyObjectAttributes,
410  &KeyName,
412  RootKey,
413  NULL); // Descriptor
414 
415  CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3,
416  NtSystemRoot->Buffer, L"System32\\config", RegistryKey);
417  RtlInitUnicodeString(&FileName, PathBuffer);
418  InitializeObjectAttributes(&FileObjectAttributes,
419  &FileName,
421  NULL, // RootDirectory,
422  NULL);
423 
424  /* Mount the registry hive in the registry namespace */
425  return NtLoadKey(&KeyObjectAttributes, &FileObjectAttributes);
426 }
_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
UNICODE_STRING NtSystemRoot
Definition: init.c:72
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI NtLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes, IN POBJECT_ATTRIBUTES FileObjectAttributes)
Definition: ntapi.c:1109
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:26
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const WCHAR L[]
Definition: oid.c:1250
struct _FileName FileName
Definition: fatprocs.h:884
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSTATUS CombinePaths(OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:681

Referenced by VerifyRegistryHive().

◆ CreateNestedKey()

NTSTATUS CreateNestedKey ( PHANDLE  KeyHandle,
ACCESS_MASK  DesiredAccess,
POBJECT_ATTRIBUTES  ObjectAttributes,
ULONG  CreateOptions 
)

Definition at line 33 of file regutil.c.

37 {
38  OBJECT_ATTRIBUTES LocalObjectAttributes;
39  UNICODE_STRING LocalKeyName;
42  USHORT FullNameLength;
43  PWCHAR Ptr;
44  HANDLE LocalKeyHandle;
45 
49  0,
50  NULL,
52  &Disposition);
53  DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", ObjectAttributes->ObjectName, Status);
55  {
56  if (!NT_SUCCESS(Status))
57  DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n", ObjectAttributes->ObjectName, Status);
58 
59  return Status;
60  }
61 
62  /* Copy object attributes */
63  RtlCopyMemory(&LocalObjectAttributes,
65  sizeof(OBJECT_ATTRIBUTES));
66  RtlCreateUnicodeString(&LocalKeyName,
67  ObjectAttributes->ObjectName->Buffer);
68  LocalObjectAttributes.ObjectName = &LocalKeyName;
69  FullNameLength = LocalKeyName.Length;
70 
71  /* Remove the last part of the key name and try to create the key again. */
73  {
74  Ptr = wcsrchr(LocalKeyName.Buffer, '\\');
75  if (Ptr == NULL || Ptr == LocalKeyName.Buffer)
76  {
78  break;
79  }
80  *Ptr = (WCHAR)0;
81  LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR);
82 
83  Status = NtCreateKey(&LocalKeyHandle,
85  &LocalObjectAttributes,
86  0,
87  NULL,
88  REG_OPTION_NON_VOLATILE, // FIXME ?
89  &Disposition);
90  DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status);
92  DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n", LocalObjectAttributes.ObjectName, Status);
93  }
94 
95  if (!NT_SUCCESS(Status))
96  {
97  RtlFreeUnicodeString(&LocalKeyName);
98  return Status;
99  }
100 
101  /* Add removed parts of the key name and create them too. */
102  while (TRUE)
103  {
104  if (LocalKeyName.Length == FullNameLength)
105  {
107  *KeyHandle = LocalKeyHandle;
108  break;
109  }
110  NtClose(LocalKeyHandle);
111 
112  LocalKeyName.Buffer[LocalKeyName.Length / sizeof(WCHAR)] = L'\\';
113  LocalKeyName.Length = wcslen(LocalKeyName.Buffer) * sizeof(WCHAR);
114 
115  Status = NtCreateKey(&LocalKeyHandle,
117  &LocalObjectAttributes,
118  0,
119  NULL,
121  &Disposition);
122  DPRINT("NtCreateKey(%wZ) called (Status %lx)\n", &LocalKeyName, Status);
123  if (!NT_SUCCESS(Status))
124  {
125  DPRINT1("CreateNestedKey: NtCreateKey(%wZ) failed (Status %lx)\n", LocalObjectAttributes.ObjectName, Status);
126  break;
127  }
128  }
129 
130  RtlFreeUnicodeString(&LocalKeyName);
131 
132  return Status;
133 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
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_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
LONG NTSTATUS
Definition: precomp.h:26
uint16_t * PWCHAR
Definition: typedefs.h:54
_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
void DPRINT(...)
Definition: polytest.cpp:61
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_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
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
unsigned short USHORT
Definition: pedump.c:61
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define DPRINT1
Definition: precomp.h:8
PUNICODE_STRING ObjectName
Definition: umtypes.h:185
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define KEY_CREATE_SUB_KEY
Definition: nt_native.h:1018
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)

Referenced by registry_callback().

◆ CreateRegistryFile()

NTSTATUS CreateRegistryFile ( IN PUNICODE_STRING  NtSystemRoot,
IN PCWSTR  RegistryKey,
IN BOOLEAN  IsHiveNew,
IN HANDLE  ProtoKeyHandle 
)

Definition at line 140 of file regutil.c.

150 {
151  /* '.old' is for old valid hives, while '.brk' is for old broken hives */
152  static PCWSTR Extensions[] = {L"old", L"brk"};
153 
160  WCHAR PathBuffer[MAX_PATH];
161  WCHAR PathBuffer2[MAX_PATH];
162 
163  CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 3,
164  NtSystemRoot->Buffer, L"System32\\config", RegistryKey);
165 
166  Extension = Extensions[IsHiveNew ? 0 : 1];
167 
168  //
169  // FIXME: The best, actually, would be to rename (move) the existing
170  // System32\config\RegistryKey file to System32\config\RegistryKey.old,
171  // and if it already existed some System32\config\RegistryKey.old, we should
172  // first rename this one into System32\config\RegistryKey_N.old before
173  // performing the original rename.
174  //
175 
176  /* Check whether the registry hive file already existed, and if so, rename it */
177  if (DoesFileExist(NULL, PathBuffer))
178  {
179  // UINT i;
180 
181  DPRINT1("Registry hive '%S' already exists, rename it\n", PathBuffer);
182 
183  // i = 1;
184  /* Try first by just appending the '.old' extension */
185  RtlStringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2),
186  L"%s.%s", PathBuffer, Extension);
187 #if 0
188  while (DoesFileExist(NULL, PathBuffer2))
189  {
190  /* An old file already exists, increments its index, but not too much */
191  if (i <= 0xFFFF)
192  {
193  /* Append '_N.old' extension */
194  RtlStringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2),
195  L"%s_%lu.%s", PathBuffer, i, Extension);
196  ++i;
197  }
198  else
199  {
200  /*
201  * Too many old files exist, we will rename the file
202  * using the name of the oldest one.
203  */
204  RtlStringCchPrintfW(PathBuffer2, ARRAYSIZE(PathBuffer2),
205  L"%s.%s", PathBuffer, Extension);
206  break;
207  }
208  }
209 #endif
210 
211  /* Now rename the file (force the move) */
212  Status = SetupMoveFile(PathBuffer, PathBuffer2, MOVEFILE_REPLACE_EXISTING);
213  }
214 
215  /* Create the file */
216  RtlInitUnicodeString(&FileName, PathBuffer);
218  &FileName,
220  NULL, // Could have been NtSystemRoot, etc...
221  NULL); // Descriptor
222 
226  &IoStatusBlock,
227  NULL,
229  0,
232  NULL,
233  0);
234  if (!NT_SUCCESS(Status))
235  {
236  DPRINT1("NtCreateFile(%wZ) failed, Status 0x%08lx\n", &FileName, Status);
237  return Status;
238  }
239 
240  /* Save the selected hive into the file */
241  Status = NtSaveKeyEx(ProtoKeyHandle, FileHandle, REG_LATEST_FORMAT);
242  if (!NT_SUCCESS(Status))
243  {
244  DPRINT1("NtSaveKeyEx(%wZ) failed, Status 0x%08lx\n", &FileName, Status);
245  }
246 
247  /* Close the file and return */
249  return Status;
250 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
const uint16_t * PCWSTR
Definition: typedefs.h:55
UNICODE_STRING NtSystemRoot
Definition: init.c:72
#define MOVEFILE_REPLACE_EXISTING
Definition: filesup.h:28
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
HANDLE FileHandle
Definition: stats.c:38
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
NTSTATUS SetupMoveFile(IN PCWSTR ExistingFileName, IN PCWSTR NewFileName, IN ULONG Flags)
Definition: filesup.c:480
smooth NULL
Definition: ftsmooth.c:416
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define DoesFileExist(RootDirectory, FileName)
Definition: filesup.h:77
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)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:26
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
static const WCHAR L[]
Definition: oid.c:1250
#define REG_LATEST_FORMAT
Definition: cmtypes.h:98
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
Status
Definition: gdiplustypes.h:24
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
struct _FileName FileName
Definition: fatprocs.h:884
NTSTATUS NTAPI NtSaveKeyEx(IN HANDLE KeyHandle, IN HANDLE FileHandle, IN ULONG Flags)
Definition: ntapi.c:1611
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
NTSTATUS CombinePaths(OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:681
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092

Referenced by RegInitializeRegistry().

◆ CreateSymLinkKey()

NTSTATUS CreateSymLinkKey ( IN HANDLE RootKey  OPTIONAL,
IN PCWSTR  LinkKeyName,
IN PCWSTR  TargetKeyName 
)

Definition at line 254 of file regutil.c.

258 {
262  HANDLE LinkKeyHandle;
264 
265  /* Initialize the object attributes */
266  RtlInitUnicodeString(&KeyName, LinkKeyName);
268  &KeyName,
270  RootKey,
271  NULL);
272 
273  /* Create the link key */
274  Status = NtCreateKey(&LinkKeyHandle,
277  0,
278  NULL,
280  &Disposition);
281  if (!NT_SUCCESS(Status))
282  {
283  DPRINT1("CreateSymLinkKey: couldn't create '%S', Status = 0x%08lx\n",
284  LinkKeyName, Status);
285  return Status;
286  }
287 
288  /* Check if the new key was actually created */
290  {
291  DPRINT1("CreateSymLinkKey: %S already exists!\n", LinkKeyName);
292  NtClose(LinkKeyHandle);
293  return STATUS_OBJECT_NAME_EXISTS; // STATUS_OBJECT_NAME_COLLISION;
294  }
295 
296  /* Set the target key name as link target */
297  RtlInitUnicodeString(&KeyName, TargetKeyName);
298  Status = NtSetValueKey(LinkKeyHandle,
300  0,
301  REG_LINK,
302  KeyName.Buffer,
303  KeyName.Length);
304 
305  /* Close the link key handle */
306  NtClose(LinkKeyHandle);
307 
308  if (!NT_SUCCESS(Status))
309  {
310  DPRINT1("CreateSymLinkKey: couldn't create symbolic link '%S' for '%S', Status = 0x%08lx\n",
311  LinkKeyName, TargetKeyName, Status);
312  }
313 
314  return Status;
315 }
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 KEY_SET_VALUE
Definition: nt_native.h:1017
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
LONG NTSTATUS
Definition: precomp.h:26
#define REG_OPTION_CREATE_LINK
Definition: nt_native.h:1063
_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
#define REG_CREATED_NEW_KEY
Definition: nt_native.h:1084
#define REG_LINK
Definition: nt_native.h:1500
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static UNICODE_STRING SymbolicLinkValueName
Definition: regutil.c:21
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
Status
Definition: gdiplustypes.h:24
#define KEY_CREATE_LINK
Definition: nt_native.h:1021
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060

Referenced by RegInitializeRegistry().

◆ DeleteSymLinkKey()

NTSTATUS DeleteSymLinkKey ( IN HANDLE RootKey  OPTIONAL,
IN PCWSTR  LinkKeyName 
)

Definition at line 318 of file regutil.c.

321 {
325  HANDLE LinkKeyHandle;
326  // ULONG Disposition;
327 
328  /* Initialize the object attributes */
329  RtlInitUnicodeString(&KeyName, LinkKeyName);
331  &KeyName,
332  /* Open the symlink key itself if it exists, and not its target */
334  RootKey,
335  NULL);
336 
337  /*
338  * Note: We could use here NtOpenKey() but it does not allow to pass
339  * opening options. NtOpenKeyEx() could do it but is Windows 7+.
340  * So we use the good old NtCreateKey() that can open the key.
341  */
342 #if 0
343  Status = NtCreateKey(&LinkKeyHandle,
346  0,
347  NULL,
348  /*REG_OPTION_VOLATILE |*/ REG_OPTION_OPEN_LINK,
349  &Disposition);
350 #else
351  Status = NtOpenKey(&LinkKeyHandle,
354 #endif
355  if (!NT_SUCCESS(Status))
356  {
357  DPRINT1("NtOpenKey(%wZ) failed (Status %lx)\n", &KeyName, Status);
358  return Status;
359  }
360 
361  /*
362  * Delete the special "SymbolicLinkValue" value.
363  * This is technically not needed since we are going to remove
364  * the key anyways, but it is good practice to do it.
365  */
366  Status = NtDeleteValueKey(LinkKeyHandle, &SymbolicLinkValueName);
367  if (!NT_SUCCESS(Status))
368  {
369  DPRINT1("NtDeleteValueKey(%wZ) failed (Status %lx)\n", &KeyName, Status);
370  NtClose(LinkKeyHandle);
371  return Status;
372  }
373 
374  /* Finally delete the key itself and close the link key handle */
375  Status = NtDeleteKey(LinkKeyHandle);
376  NtClose(LinkKeyHandle);
377 
378  if (!NT_SUCCESS(Status))
379  {
380  DPRINT1("DeleteSymLinkKey: couldn't delete symbolic link '%S', Status = 0x%08lx\n",
381  LinkKeyName, Status);
382  }
383 
384  return Status;
385 }
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 KEY_SET_VALUE
Definition: nt_native.h:1017
#define REG_OPTION_OPEN_LINK
Definition: nt_native.h:1070
LONG NTSTATUS
Definition: precomp.h:26
#define OBJ_OPENLINK
Definition: winternl.h:230
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
#define OBJ_OPENIF
Definition: winternl.h:229
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI NTSTATUS NTAPI NtDeleteValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName)
Definition: ntapi.c:994
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static UNICODE_STRING SymbolicLinkValueName
Definition: regutil.c:21
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI NtDeleteKey(IN HANDLE KeyHandle)
Definition: ntapi.c:408
#define KEY_CREATE_LINK
Definition: nt_native.h:1021
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
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 RegCleanupRegistry().

◆ DisconnectRegistry()

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

Definition at line 432 of file regutil.c.

436 {
439 
440  RtlInitUnicodeString(&KeyName, RegMountPoint);
442  &KeyName,
444  RootKey,
445  NULL);
446 
447  // NOTE: NtUnloadKey == NtUnloadKey2 with Flags == 0.
449 }
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 NtUnloadKey2(IN POBJECT_ATTRIBUTES TargetKey, IN ULONG Flags)
Definition: ntapi.c:1764
static PMEMKEY RootKey
Definition: registry.c:55
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
smooth NULL
Definition: ftsmooth.c:416
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106

Referenced by RegCleanupRegistry(), and VerifyRegistryHive().

◆ VerifyRegistryHive()

NTSTATUS VerifyRegistryHive ( IN PUNICODE_STRING  NtSystemRoot,
IN PCWSTR  RegistryKey 
)

Definition at line 455 of file regutil.c.

461 {
463 
464  /* Try to mount the specified registry hive */
466  L"\\Registry\\Machine\\USetup_VerifyHive",
467  NtSystemRoot,
468  RegistryKey
469  /* NULL, 0 */);
470  if (!NT_SUCCESS(Status))
471  {
472  DPRINT1("ConnectRegistry(%S) failed, Status 0x%08lx\n", RegistryKey, Status);
473  }
474 
475  DPRINT1("VerifyRegistryHive: ConnectRegistry(%S) returns Status 0x%08lx\n", RegistryKey, Status);
476 
477  //
478  // TODO: Check the Status error codes: STATUS_SUCCESS, STATUS_REGISTRY_RECOVERED,
479  // STATUS_REGISTRY_HIVE_RECOVERED, STATUS_REGISTRY_CORRUPT, STATUS_REGISTRY_IO_FAILED,
480  // STATUS_NOT_REGISTRY_FILE, STATUS_CANNOT_LOAD_REGISTRY_FILE ;
481  //(STATUS_HIVE_UNLOADED) ; STATUS_SYSTEM_HIVE_TOO_LARGE
482  //
483 
484  if (Status == STATUS_REGISTRY_HIVE_RECOVERED) // NT_SUCCESS is still FALSE in this case!
485  DPRINT1("VerifyRegistryHive: Registry hive %S was recovered but some data may be lost (Status 0x%08lx)\n", RegistryKey, Status);
486 
487  if (!NT_SUCCESS(Status))
488  {
489  DPRINT1("VerifyRegistryHive: Registry hive %S is corrupted (Status 0x%08lx)\n", RegistryKey, Status);
490  return Status;
491  }
492 
494  DPRINT1("VerifyRegistryHive: Registry hive %S succeeded recovered (Status 0x%08lx)\n", RegistryKey, Status);
495 
496  /* Unmount the hive */
498  L"\\Registry\\Machine\\USetup_VerifyHive",
499  0);
500  if (!NT_SUCCESS(Status))
501  {
502  DPRINT1("DisconnectRegistry(%S) failed, Status 0x%08lx\n", RegistryKey, Status);
503  }
504 
505  return Status;
506 }
UNICODE_STRING NtSystemRoot
Definition: init.c:72
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_REGISTRY_RECOVERED
Definition: ntstatus.h:123
NTSTATUS DisconnectRegistry(IN HANDLE RootKey OPTIONAL, IN PCWSTR RegMountPoint, IN ULONG Flags)
Definition: regutil.c:432
NTSTATUS ConnectRegistry(IN HANDLE RootKey OPTIONAL, IN PCWSTR RegMountPoint, IN PUNICODE_STRING NtSystemRoot, IN PCWSTR RegistryKey)
Definition: regutil.c:391
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
#define DPRINT1
Definition: precomp.h:8
#define STATUS_REGISTRY_HIVE_RECOVERED
Definition: ntstatus.h:209

Referenced by VerifyRegistryHives().

Variable Documentation

◆ SymbolicLinkValueName

UNICODE_STRING SymbolicLinkValueName
static
Initial value:
=
RTL_CONSTANT_STRING(L"SymbolicLinkValue")
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Definition at line 21 of file regutil.c.

Referenced by CreateSymLinkKey(), and DeleteSymLinkKey().