ReactOS  0.4.12-dev-934-g9a4676f
cmhvlist.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/config/cmhvlist.c
5  * PURPOSE: Configuration Manager - Hives file list management
6  * PROGRAMMERS: Hermes BELUSCA - MAITO
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "ntoskrnl.h"
12 #define NDEBUG
13 #include "debug.h"
14 
15 /* GLOBALS ********************************************************************/
16 
17 UNICODE_STRING HiveListValueName = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\hivelist");
18 
19 /* FUNCTIONS ******************************************************************/
20 
21 /* Note: the caller is expected to free the HiveName string buffer */
22 BOOLEAN
23 NTAPI
25  OUT PUNICODE_STRING HiveName)
26 {
27  HCELL_INDEX RootCell, LinkCell;
28  PCELL_DATA RootData, LinkData, ParentData;
29  ULONG ParentNameSize, LinkNameSize;
30  SIZE_T NameSize;
31  PWCHAR p;
32  UNICODE_STRING RegistryName = RTL_CONSTANT_STRING(L"\\REGISTRY\\");
33 
34  /* Get the root cell of this hive */
35  RootCell = Hive->Hive.BaseBlock->RootCell;
36  RootData = HvGetCell(&Hive->Hive, RootCell);
37  if (!RootData) return FALSE;
38 
39  /* Get the cell index at which this hive is linked to, and its parent */
40  LinkCell = RootData->u.KeyNode.Parent;
41  HvReleaseCell(&Hive->Hive, RootCell);
42 
43  /* Sanity check */
44  ASSERT((&CmiVolatileHive->Hive)->ReleaseCellRoutine == NULL);
45 
46  /* Get the cell data for link and parent */
47  LinkData = HvGetCell(&CmiVolatileHive->Hive, LinkCell);
48  if (!LinkData) return FALSE;
49  ParentData = HvGetCell(&CmiVolatileHive->Hive, LinkData->u.KeyNode.Parent);
50  if (!ParentData) return FALSE;
51 
52  /* Get the size of the parent name */
53  if (ParentData->u.KeyNode.Flags & KEY_COMP_NAME)
54  {
55  ParentNameSize = CmpCompressedNameSize(ParentData->u.KeyNode.Name,
56  ParentData->u.KeyNode.NameLength);
57  }
58  else
59  {
60  ParentNameSize = ParentData->u.KeyNode.NameLength;
61  }
62 
63  /* Get the size of the link name */
64  if (LinkData->u.KeyNode.Flags & KEY_COMP_NAME)
65  {
66  LinkNameSize = CmpCompressedNameSize(LinkData->u.KeyNode.Name,
67  LinkData->u.KeyNode.NameLength);
68  }
69  else
70  {
71  LinkNameSize = LinkData->u.KeyNode.NameLength;
72  }
73 
74  /* No need to account for terminal NULL character since we deal with counted UNICODE strings */
75  NameSize = RegistryName.Length + ParentNameSize + sizeof(WCHAR) + LinkNameSize;
76 
77  /* Allocate the memory */
78  HiveName->Buffer = ExAllocatePoolWithTag(PagedPool, NameSize, TAG_CM);
79  if (!HiveName->Buffer)
80  {
81  /* Fail */
82  DPRINT1("CmpGetHiveName: Unable to allocate memory\n");
83  return FALSE;
84  }
85 
86  /* Build the string for it */
87  HiveName->Length = HiveName->MaximumLength = (USHORT)NameSize;
88  p = HiveName->Buffer;
89 
90  /* Copy the parent name */
91  RtlCopyMemory(p, RegistryName.Buffer, RegistryName.Length);
92  p += RegistryName.Length / sizeof(WCHAR);
93  if (ParentData->u.KeyNode.Flags & KEY_COMP_NAME)
94  {
96  ParentNameSize,
97  ParentData->u.KeyNode.Name,
98  ParentData->u.KeyNode.NameLength);
99  }
100  else
101  {
102  RtlCopyMemory(p, ParentData->u.KeyNode.Name, ParentNameSize);
103  }
104 
105  /* Add a path separator between parent and link */
106  p += ParentNameSize / sizeof(WCHAR);
108  ++p;
109 
110  /* Now copy the link name */
111  if (LinkData->u.KeyNode.Flags & KEY_COMP_NAME)
112  {
114  LinkNameSize,
115  LinkData->u.KeyNode.Name,
116  LinkData->u.KeyNode.NameLength);
117 
118  }
119  else
120  {
121  RtlCopyMemory(p, LinkData->u.KeyNode.Name, LinkNameSize);
122  }
123 
124  /* All done */
125  return TRUE;
126 }
127 
128 NTSTATUS
129 NTAPI
131 {
135  UNICODE_STRING HivePath;
137  UCHAR Buffer[sizeof(OBJECT_NAME_INFORMATION) + MAX_PATH * sizeof(WCHAR)];
138  ULONG Length = sizeof(Buffer);
140 
141  HivePath.Buffer = NULL;
142 
143  /* Create or open the hive list key */
147  NULL,
148  NULL);
149  Status = ZwCreateKey(&KeyHandle,
152  0,
153  NULL,
155  NULL);
156  if (!NT_SUCCESS(Status))
157  {
158  /* Fail */
159  DPRINT1("CmpAddToHiveFileList: Creation or opening of the hive list failed, status = 0x%08lx\n", Status);
160  return Status;
161  }
162 
163  /* Retrieve the name of the hive */
164  if (!CmpGetHiveName(Hive, &HivePath))
165  {
166  /* Fail */
167  DPRINT1("CmpAddToHiveFileList: Unable to retrieve the hive name\n");
169  goto Quickie;
170  }
171 
172  /* Get the name of the corresponding file */
173  if (!(Hive->Hive.HiveFlags & HIVE_VOLATILE))
174  {
175  /* Try to get the value */
176  Status = ZwQueryObject(Hive->FileHandles[HFILE_TYPE_PRIMARY],
178  FileNameInfo,
179  Length,
180  &Length);
181  if (NT_SUCCESS(Status))
182  {
183  /* Null-terminate and add the length of the terminator */
184  Length -= sizeof(OBJECT_NAME_INFORMATION);
185  FilePath = FileNameInfo->Name.Buffer;
186  FilePath[Length / sizeof(WCHAR)] = UNICODE_NULL;
187  Length += sizeof(UNICODE_NULL);
188  }
189  else
190  {
191  /* Fail */
192  DPRINT1("CmpAddToHiveFileList: Hive file name query failed, status = 0x%08lx\n", Status);
193  goto Quickie;
194  }
195  }
196  else
197  {
198  /* No name */
199  FilePath = L"";
200  Length = sizeof(UNICODE_NULL);
201  }
202 
203  /* Set the entry in the hive list */
204  Status = ZwSetValueKey(KeyHandle,
205  &HivePath,
206  0,
207  REG_SZ,
208  FilePath,
209  Length);
210  if (!NT_SUCCESS(Status))
211  {
212  /* Fail */
213  DPRINT1("CmpAddToHiveFileList: Setting of entry in the hive list failed, status = 0x%08lx\n", Status);
214  }
215 
216 Quickie:
217  /* Cleanup and return status */
218  if (HivePath.Buffer) ExFreePoolWithTag(HivePath.Buffer, TAG_CM);
220  return Status;
221 }
222 
223 VOID
224 NTAPI
226 {
230  UNICODE_STRING HivePath;
231 
232  /* Open the hive list key */
236  NULL,
237  NULL);
238  Status = ZwOpenKey(&KeyHandle,
241  if (!NT_SUCCESS(Status))
242  {
243  /* Fail */
244  DPRINT1("CmpRemoveFromHiveFileList: Opening of the hive list failed, status = 0x%08lx\n", Status);
245  return;
246  }
247 
248  /* Get the hive path name */
249  CmpGetHiveName(Hive, &HivePath);
250 
251  /* Delete the hive path name from the list */
252  ZwDeleteValueKey(KeyHandle, &HivePath);
253 
254  /* Cleanup allocation and handle */
255  ExFreePoolWithTag(HivePath.Buffer, TAG_CM);
257 }
258 
259 /* EOF */
#define KEY_COMP_NAME
Definition: cmdata.h:35
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define IN
Definition: typedefs.h:38
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:116
CM_KEY_NODE KeyNode
Definition: cmdata.h:200
BOOLEAN NTAPI CmpGetHiveName(IN PCMHIVE Hive, OUT PUNICODE_STRING HiveName)
Definition: cmhvlist.c:24
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4693
#define KEY_READ
Definition: nt_native.h:1023
#define HIVE_VOLATILE
Definition: hivedata.h:23
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
LONG NTSTATUS
Definition: precomp.h:26
UNICODE_STRING HiveListValueName
Definition: cmhvlist.c:17
uint16_t * PWCHAR
Definition: typedefs.h:54
UNICODE_STRING Name
Definition: nt_native.h:1270
USHORT NameLength
Definition: cmdata.h:114
PCWSTR FilePath
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
union _CELL_DATA::@3892 u
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
VOID NTAPI CmpCopyCompressedName(OUT PWCHAR Destination, IN ULONG DestinationLength, IN PWCHAR Source, IN ULONG SourceLength)
Definition: cmname.c:56
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
unsigned char BOOLEAN
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
smooth NULL
Definition: ftsmooth.c:416
HHIVE Hive
Definition: cm.h:393
Definition: bufpool.h:45
PCMHIVE CmiVolatileHive
Definition: cmsysini.c:17
#define KEY_WRITE
Definition: nt_native.h:1031
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
HCELL_INDEX Parent
Definition: cmdata.h:96
ULONG HCELL_INDEX
Definition: hivedata.h:80
VOID NTAPI CmpRemoveFromHiveFileList(IN PCMHIVE Hive)
Definition: cmhvlist.c:225
#define MAX_PATH
Definition: compat.h:26
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
#define TAG_CM
Definition: cmlib.h:203
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3376
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define HFILE_TYPE_PRIMARY
Definition: hivedata.h:33
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define DPRINT1
Definition: precomp.h:8
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
GLfloat GLfloat p
Definition: glext.h:8902
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
USHORT NTAPI CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
Definition: cmname.c:95
NTSTATUS NTAPI CmpAddToHiveFileList(IN PCMHIVE Hive)
Definition: cmhvlist.c:130
Definition: cm.h:391
USHORT Flags
Definition: cmdata.h:93
struct _OBJECT_NAME_INFORMATION * POBJECT_NAME_INFORMATION
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22