Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

375 lines
8.4 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. cmhvlist.c
  5. Abstract:
  6. Code to maintain registry node that lists where the roots of
  7. hives are and what files they map to.
  8. Author:
  9. Bryan M. Willman (bryanwi) 14-May-1992
  10. Revision History:
  11. --*/
  12. #include "cmp.h"
  13. #define HIVE_LIST L"\\registry\\machine\\system\\currentcontrolset\\control\\hivelist"
  14. extern PCMHIVE CmpMasterHive;
  15. BOOLEAN
  16. CmpGetHiveName(
  17. PCMHIVE CmHive,
  18. PUNICODE_STRING HiveName
  19. );
  20. #ifdef ALLOC_PRAGMA
  21. #pragma alloc_text(PAGE,CmpAddToHiveFileList)
  22. #pragma alloc_text(PAGE,CmpRemoveFromHiveFileList)
  23. #pragma alloc_text(PAGE,CmpGetHiveName)
  24. #endif
  25. NTSTATUS
  26. CmpAddToHiveFileList(
  27. PCMHIVE CmHive
  28. )
  29. /*++
  30. Routine Description:
  31. Add Hive to list of hives and their files in
  32. \registry\machine\system\currentcontrolset\control\hivelist
  33. Arguments:
  34. HivePath - path to root of hive (e.g. \registry\machine\system)
  35. CmHive - pointer to CM_HIVE structure for hive.
  36. Return Value:
  37. ntstatus
  38. --*/
  39. {
  40. //
  41. // PERFNOTE - allocate small instead of large buffers after
  42. // NtQueryObject is fixec - bryanwi 15may92
  43. //
  44. #define NAME_BUFFER_SIZE 512
  45. OBJECT_ATTRIBUTES ObjectAttributes;
  46. HANDLE KeyHandle;
  47. NTSTATUS Status;
  48. PUCHAR Buffer;
  49. ULONG Length;
  50. PWSTR FilePath;
  51. WCHAR UnicodeNull=UNICODE_NULL;
  52. UNICODE_STRING TempName;
  53. UNICODE_STRING HivePath;
  54. //
  55. // create/open the hive list key
  56. //
  57. RtlInitUnicodeString(
  58. &TempName,
  59. HIVE_LIST
  60. );
  61. InitializeObjectAttributes(
  62. &ObjectAttributes,
  63. &TempName,
  64. OBJ_CASE_INSENSITIVE,
  65. (HANDLE)NULL,
  66. NULL
  67. );
  68. Status = ZwCreateKey(
  69. &KeyHandle,
  70. KEY_READ | KEY_WRITE,
  71. &ObjectAttributes,
  72. 0,
  73. NULL,
  74. REG_OPTION_VOLATILE,
  75. NULL
  76. );
  77. if (!NT_SUCCESS(Status)) {
  78. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"CmpAddToHiveFileList: "));
  79. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"Create/Open of Hive list failed status = %08lx\n", Status));
  80. return Status;
  81. }
  82. //
  83. // allocate work buffers
  84. //
  85. Buffer = ExAllocatePool(PagedPool, NAME_BUFFER_SIZE);
  86. if (Buffer == NULL) {
  87. NtClose(KeyHandle);
  88. return STATUS_NO_MEMORY;
  89. }
  90. //
  91. // compute name of hive
  92. //
  93. if (! CmpGetHiveName(CmHive, &HivePath)) {
  94. NtClose(KeyHandle);
  95. ExFreePool(Buffer);
  96. return STATUS_NO_MEMORY;
  97. }
  98. //
  99. // get name of file
  100. //
  101. if (!(CmHive->Hive.HiveFlags & HIVE_VOLATILE)) {
  102. Status = ZwQueryObject(
  103. CmHive->FileHandles[HFILE_TYPE_PRIMARY],
  104. ObjectNameInformation,
  105. (PVOID)Buffer,
  106. NAME_BUFFER_SIZE,
  107. &Length
  108. );
  109. Length -= sizeof(UNICODE_STRING);
  110. if (!NT_SUCCESS(Status)) {
  111. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"CmpAddToHiveFileList: "));
  112. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"Query of name2 failed status = %08lx\n", Status));
  113. NtClose(KeyHandle);
  114. ExFreePool(HivePath.Buffer);
  115. ExFreePool(Buffer);
  116. return Status;
  117. }
  118. FilePath = ((POBJECT_NAME_INFORMATION)Buffer)->Name.Buffer;
  119. FilePath[Length/sizeof(WCHAR)] = UNICODE_NULL;
  120. Length+=sizeof(WCHAR);
  121. } else {
  122. FilePath = &UnicodeNull;
  123. Length = sizeof(UnicodeNull);
  124. }
  125. //
  126. // set entry in list
  127. //
  128. Status = ZwSetValueKey(
  129. KeyHandle,
  130. &HivePath,
  131. 0,
  132. REG_SZ,
  133. FilePath,
  134. Length
  135. );
  136. if (!NT_SUCCESS(Status)) {
  137. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"CmpAddToHiveFileList: "));
  138. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_BUGCHECK,"Set of entry in Hive list failed status = %08lx\n", Status));
  139. }
  140. NtClose(KeyHandle);
  141. ExFreePool(HivePath.Buffer);
  142. ExFreePool(Buffer);
  143. return Status;
  144. }
  145. VOID
  146. CmpRemoveFromHiveFileList(
  147. PCMHIVE CmHive
  148. )
  149. /*++
  150. Routine Description:
  151. Remove hive name from hive file list key
  152. Arguments:
  153. CmHive - pointer to CM_HIVE structure for hive.
  154. Return Value:
  155. ntstatus
  156. --*/
  157. {
  158. NTSTATUS Status;
  159. UNICODE_STRING EntryName;
  160. UNICODE_STRING TempName;
  161. OBJECT_ATTRIBUTES ObjectAttributes;
  162. HANDLE KeyHandle;
  163. //
  164. // open the hive list key
  165. //
  166. RtlInitUnicodeString(
  167. &TempName,
  168. HIVE_LIST
  169. );
  170. InitializeObjectAttributes(
  171. &ObjectAttributes,
  172. &TempName,
  173. OBJ_CASE_INSENSITIVE,
  174. (HANDLE)NULL,
  175. NULL
  176. );
  177. Status = ZwOpenKey(
  178. &KeyHandle,
  179. KEY_READ | KEY_WRITE,
  180. &ObjectAttributes
  181. );
  182. if (!NT_SUCCESS(Status)) {
  183. return;
  184. }
  185. if( CmpGetHiveName(CmHive, &EntryName) ) {
  186. ZwDeleteValueKey(KeyHandle, &EntryName);
  187. ExFreePool(EntryName.Buffer);
  188. }
  189. NtClose(KeyHandle);
  190. return;
  191. }
  192. BOOLEAN
  193. CmpGetHiveName(
  194. PCMHIVE CmHive,
  195. PUNICODE_STRING HiveName
  196. )
  197. /*++
  198. Routine Description:
  199. Compute full path to a hive.
  200. Arguments:
  201. CmHive - pointer to CmHive structure
  202. HiveName - supplies pointer to unicode string structure that
  203. will be filled in with pointer to name.
  204. CALL IS EXPECTED TO FREE BUFFER
  205. Return Value:
  206. TRUE = it worked, FALSE = it failed (memory)
  207. --*/
  208. {
  209. HCELL_INDEX RootCell;
  210. HCELL_INDEX LinkCell;
  211. PCM_KEY_NODE LinkKey;
  212. PCM_KEY_NODE LinkParent;
  213. ULONG size;
  214. ULONG rsize;
  215. ULONG KeySize;
  216. ULONG ParentSize;
  217. PWCHAR p;
  218. PCM_KEY_NODE EntryKey;
  219. //
  220. // First find the link cell.
  221. //
  222. RootCell = CmHive->Hive.BaseBlock->RootCell;
  223. EntryKey = (PCM_KEY_NODE)HvGetCell((PHHIVE)CmHive, RootCell);
  224. if( EntryKey == NULL ) {
  225. //
  226. // we couldn't map a view for the bin containing this cell
  227. //
  228. return FALSE;
  229. }
  230. LinkCell = EntryKey->Parent;
  231. HvReleaseCell((PHHIVE)CmHive, RootCell);
  232. // for master we don't need to count cell usage
  233. ASSERT( ((PHHIVE)CmpMasterHive)->ReleaseCellRoutine == NULL );
  234. //
  235. // Compute the value entry name, which is of the form:
  236. // \registry\<parent of link node name>\<link node name>
  237. //
  238. LinkKey = (PCM_KEY_NODE)HvGetCell((PHHIVE)CmpMasterHive, LinkCell);
  239. if( LinkKey == NULL ) {
  240. //
  241. // we couldn't map a view for the bin containing this cell
  242. //
  243. return FALSE;
  244. }
  245. LinkParent = (PCM_KEY_NODE)HvGetCell(
  246. (PHHIVE)CmpMasterHive,
  247. LinkKey->Parent
  248. );
  249. if( LinkParent == NULL ) {
  250. //
  251. // we couldn't map a view for the bin containing this cell
  252. //
  253. return FALSE;
  254. }
  255. rsize = wcslen(L"\\REGISTRY\\");
  256. KeySize = CmpHKeyNameLen(LinkKey);
  257. ParentSize = CmpHKeyNameLen(LinkParent);
  258. size = KeySize + ParentSize +
  259. (rsize * sizeof(WCHAR)) + sizeof(WCHAR);
  260. HiveName->Buffer = ExAllocatePool(PagedPool, size);
  261. if (HiveName->Buffer == NULL) {
  262. return FALSE;
  263. }
  264. HiveName->Length = (USHORT)size;
  265. HiveName->MaximumLength = (USHORT)size;
  266. p = HiveName->Buffer;
  267. RtlCopyMemory(
  268. (PVOID)p,
  269. (PVOID)L"\\REGISTRY\\",
  270. rsize * sizeof(WCHAR)
  271. );
  272. p += rsize;
  273. if (LinkParent->Flags & KEY_COMP_NAME) {
  274. CmpCopyCompressedName(p,
  275. ParentSize,
  276. LinkParent->Name,
  277. LinkParent->NameLength);
  278. } else {
  279. RtlCopyMemory(
  280. (PVOID)p,
  281. (PVOID)&(LinkParent->Name[0]),
  282. ParentSize
  283. );
  284. }
  285. p += ParentSize / sizeof(WCHAR);
  286. *p = OBJ_NAME_PATH_SEPARATOR;
  287. p++;
  288. if (LinkKey->Flags & KEY_COMP_NAME) {
  289. CmpCopyCompressedName(p,
  290. KeySize,
  291. LinkKey->Name,
  292. LinkKey->NameLength);
  293. } else {
  294. RtlCopyMemory(
  295. (PVOID)p,
  296. (PVOID)&(LinkKey->Name[0]),
  297. KeySize
  298. );
  299. }
  300. return TRUE;
  301. }