Leaked source code of windows server 2003
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.

542 lines
11 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. cmwraper.c
  5. Abstract:
  6. Provides wrapper routines to support ntos\config routines called from
  7. user-mode.
  8. Author:
  9. John Vert (jvert) 26-Mar-1992
  10. Revision History:
  11. --*/
  12. #include "edithive.h"
  13. #include "nturtl.h"
  14. #include "stdlib.h"
  15. #include "stdio.h"
  16. extern ULONG UsedStorage;
  17. CCHAR KiFindFirstSetRight[256] = {
  18. 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  19. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  20. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  21. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  22. 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  23. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  24. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  25. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  26. 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  27. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  28. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  29. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  30. 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  31. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  32. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  33. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};
  34. ULONG MmSizeOfPagedPoolInBytes = 0xffffffff; // stub out
  35. ULONG
  36. DbgPrint (
  37. IN PCH Format,
  38. ...
  39. )
  40. {
  41. va_list arglist;
  42. UCHAR Buffer[512];
  43. STRING Output;
  44. //
  45. // Format the output into a buffer and then print it.
  46. //
  47. va_start(arglist, Format);
  48. Output.Length = _vsnprintf(Buffer, sizeof(Buffer), Format, arglist);
  49. Output.Buffer = Buffer;
  50. printf("%s", Buffer);
  51. return 0;
  52. }
  53. //
  54. // Structure that describes the mapping of generic access rights to object
  55. // specific access rights for registry key and keyroot objects.
  56. //
  57. GENERIC_MAPPING CmpKeyMapping = {
  58. KEY_READ,
  59. KEY_WRITE,
  60. KEY_EXECUTE,
  61. KEY_ALL_ACCESS
  62. };
  63. BOOLEAN CmpNoWrite = FALSE;
  64. PCMHIVE CmpMasterHive = NULL;
  65. LIST_ENTRY CmpHiveListHead; // List of CMHIVEs
  66. NTSTATUS
  67. MyCmpInitHiveFromFile(
  68. IN PUNICODE_STRING FileName,
  69. OUT PCMHIVE *CmHive,
  70. OUT PBOOLEAN Allocate
  71. );
  72. VOID
  73. CmpLazyFlush(
  74. VOID
  75. )
  76. {
  77. }
  78. VOID
  79. CmpFreeSecurityDescriptor(
  80. IN PHHIVE Hive,
  81. IN HCELL_INDEX Cell
  82. )
  83. {
  84. return;
  85. }
  86. VOID
  87. CmpReportNotify(
  88. UNICODE_STRING Name,
  89. PHHIVE Hive,
  90. HCELL_INDEX Cell,
  91. ULONG Filter
  92. )
  93. {
  94. }
  95. VOID
  96. CmpLockRegistry(VOID)
  97. {
  98. return;
  99. }
  100. BOOLEAN
  101. CmpTryLockRegistryExclusive(
  102. IN BOOLEAN CanWait
  103. )
  104. {
  105. return TRUE;
  106. }
  107. VOID
  108. CmpUnlockRegistry(
  109. )
  110. {
  111. }
  112. BOOLEAN
  113. CmpTestRegistryLock()
  114. {
  115. return TRUE;
  116. }
  117. BOOLEAN
  118. CmpTestRegistryLockExclusive()
  119. {
  120. return TRUE;
  121. }
  122. LONG
  123. KeReleaseMutex (
  124. IN PKMUTEX Mutex,
  125. IN BOOLEAN Wait
  126. )
  127. {
  128. return(0);
  129. }
  130. NTSTATUS
  131. KeWaitForSingleObject (
  132. IN PVOID Object,
  133. IN KWAIT_REASON WaitReason,
  134. IN KPROCESSOR_MODE WaitMode,
  135. IN BOOLEAN Alertable,
  136. IN PLARGE_INTEGER Timeout OPTIONAL
  137. )
  138. {
  139. return(STATUS_SUCCESS);
  140. }
  141. BOOLEAN
  142. CmpValidateHiveSecurityDescriptors(
  143. IN PHHIVE Hive
  144. )
  145. {
  146. PCM_KEY_NODE RootNode;
  147. PCM_KEY_SECURITY SecurityCell;
  148. HCELL_INDEX ListAnchor;
  149. HCELL_INDEX NextCell;
  150. HCELL_INDEX LastCell;
  151. BOOLEAN ValidHive = TRUE;
  152. KdPrint(("CmpValidateHiveSecurityDescriptor: Hive = %lx\n",(ULONG)Hive));
  153. RootNode = (PCM_KEY_NODE) HvGetCell(Hive, Hive->BaseBlock->RootCell);
  154. ListAnchor = NextCell = RootNode->u1.s1.Security;
  155. do {
  156. SecurityCell = (PCM_KEY_SECURITY) HvGetCell(Hive, NextCell);
  157. if (NextCell != ListAnchor) {
  158. //
  159. // Check to make sure that our Blink points to where we just
  160. // came from.
  161. //
  162. if (SecurityCell->Blink != LastCell) {
  163. KdPrint((" Invalid Blink (%ld) on security cell %ld\n",SecurityCell->Blink, NextCell));
  164. KdPrint((" should point to %ld\n", LastCell));
  165. ValidHive = FALSE;
  166. }
  167. }
  168. KdPrint(("CmpValidSD: SD shared by %d nodes\n",SecurityCell->ReferenceCount));
  169. // SetUsed(Hive, NextCell);
  170. LastCell = NextCell;
  171. NextCell = SecurityCell->Flink;
  172. } while ( NextCell != ListAnchor );
  173. return(TRUE);
  174. }
  175. VOID
  176. KeBugCheck(
  177. IN ULONG BugCheckCode
  178. )
  179. {
  180. printf("BugCheck: code = %08lx\n", BugCheckCode);
  181. exit(1);
  182. }
  183. VOID
  184. KeBugCheckEx(
  185. IN ULONG BugCheckCode,
  186. IN ULONG Arg1,
  187. IN ULONG Arg2,
  188. IN ULONG Arg3,
  189. IN ULONG Arg4
  190. )
  191. {
  192. printf("BugCheck: code = %08lx\n", BugCheckCode);
  193. printf("Args =%08lx %08lx %08lx %08lx\n", Arg1, Arg2, Arg3, Arg4);
  194. exit(1);
  195. }
  196. VOID
  197. KeQuerySystemTime(
  198. OUT PLARGE_INTEGER SystemTime
  199. )
  200. {
  201. NtQuerySystemTime(SystemTime);
  202. }
  203. #ifdef POOL_TAGGING
  204. PVOID
  205. ExAllocatePoolWithTag(
  206. IN POOL_TYPE PoolType,
  207. IN ULONG NumberOfBytes,
  208. IN ULONG Tag
  209. )
  210. {
  211. PVOID Address = NULL;
  212. ULONG Size;
  213. NTSTATUS status;
  214. Size = ROUND_UP(NumberOfBytes, HBLOCK_SIZE);
  215. status = NtAllocateVirtualMemory(
  216. NtCurrentProcess(),
  217. &Address,
  218. 0,
  219. &Size,
  220. MEM_COMMIT,
  221. PAGE_READWRITE
  222. );
  223. if (!NT_SUCCESS(status)) {
  224. return NULL;
  225. }
  226. return Address;
  227. }
  228. #else
  229. PVOID
  230. ExAllocatePool(
  231. IN POOL_TYPE PoolType,
  232. IN ULONG NumberOfBytes
  233. )
  234. {
  235. PVOID Address = NULL;
  236. ULONG Size;
  237. NTSTATUS status;
  238. Size = ROUND_UP(NumberOfBytes, HBLOCK_SIZE);
  239. status = NtAllocateVirtualMemory(
  240. NtCurrentProcess(),
  241. &Address,
  242. 0,
  243. &Size,
  244. MEM_COMMIT,
  245. PAGE_READWRITE
  246. );
  247. if (!NT_SUCCESS(status)) {
  248. return NULL;
  249. }
  250. return Address;
  251. }
  252. #endif
  253. VOID
  254. ExFreePool(
  255. IN PVOID P
  256. )
  257. {
  258. ULONG size;
  259. size = HBLOCK_SIZE;
  260. // if it was really more than 1 page, well, too bad
  261. NtFreeVirtualMemory(
  262. NtCurrentProcess(),
  263. &P,
  264. &size,
  265. MEM_DECOMMIT
  266. );
  267. return;
  268. }
  269. NTSTATUS
  270. CmpWorkerCommand(
  271. IN OUT PREGISTRY_COMMAND Command
  272. )
  273. /*++
  274. Routine Description:
  275. This routine just encapsulates all the necessary synchronization for
  276. sending a command to the worker thread.
  277. Arguments:
  278. Command - Supplies a pointer to an initialized REGISTRY_COMMAND structure
  279. which will be copied into the global communication structure.
  280. Return Value:
  281. NTSTATUS = Command.Status
  282. --*/
  283. {
  284. PCMHIVE CmHive;
  285. PUNICODE_STRING FileName;
  286. ULONG i;
  287. switch (Command->Command) {
  288. case REG_CMD_FLUSH_KEY:
  289. return CmFlushKey(Command->Hive, Command->Cell);
  290. break;
  291. case REG_CMD_FILE_SET_SIZE:
  292. return CmpDoFileSetSize(
  293. Command->Hive,
  294. Command->FileType,
  295. Command->FileSize
  296. );
  297. break;
  298. case REG_CMD_HIVE_OPEN:
  299. //
  300. // Open the file.
  301. //
  302. FileName = Command->FileAttributes->ObjectName;
  303. return MyCmpInitHiveFromFile(FileName,
  304. &Command->CmHive,
  305. &Command->Allocate);
  306. break;
  307. case REG_CMD_HIVE_CLOSE:
  308. //
  309. // Close the files associated with this hive.
  310. //
  311. CmHive = Command->CmHive;
  312. for (i=0; i<HFILE_TYPE_MAX; i++) {
  313. if (CmHive->FileHandles[i] != NULL) {
  314. NtClose(CmHive->FileHandles[i]);
  315. }
  316. }
  317. return STATUS_SUCCESS;
  318. break;
  319. case REG_CMD_SHUTDOWN:
  320. //
  321. // shut down the registry
  322. //
  323. break;
  324. default:
  325. return STATUS_INVALID_PARAMETER;
  326. }
  327. }
  328. NTSTATUS
  329. MyCmpInitHiveFromFile(
  330. IN PUNICODE_STRING FileName,
  331. OUT PCMHIVE *CmHive,
  332. OUT PBOOLEAN Allocate
  333. )
  334. /*++
  335. Routine Description:
  336. This routine opens a file and log, allocates a CMHIVE, and initializes
  337. it.
  338. Arguments:
  339. FileName - Supplies name of file to be loaded.
  340. CmHive - Returns pointer to initialized hive (if successful)
  341. Allocate - Returns whether the hive was allocated or existing.
  342. Return Value:
  343. NTSTATUS
  344. --*/
  345. {
  346. PCMHIVE NewHive;
  347. ULONG Disposition;
  348. ULONG SecondaryDisposition;
  349. HANDLE PrimaryHandle;
  350. HANDLE LogHandle;
  351. NTSTATUS Status;
  352. ULONG FileType;
  353. ULONG Operation;
  354. BOOLEAN Success;
  355. *CmHive = NULL;
  356. Status = CmpOpenHiveFiles(FileName,
  357. L".log",
  358. &PrimaryHandle,
  359. &LogHandle,
  360. &Disposition,
  361. &SecondaryDisposition,
  362. TRUE,
  363. NULL
  364. );
  365. if (!NT_SUCCESS(Status)) {
  366. return(Status);
  367. }
  368. if (LogHandle == NULL) {
  369. FileType = HFILE_TYPE_PRIMARY;
  370. } else {
  371. FileType = HFILE_TYPE_LOG;
  372. }
  373. if (Disposition == FILE_CREATED) {
  374. Operation = HINIT_CREATE;
  375. *Allocate = TRUE;
  376. } else {
  377. Operation = HINIT_FILE;
  378. *Allocate = FALSE;
  379. }
  380. Success = CmpInitializeHive(&NewHive,
  381. Operation,
  382. FALSE,
  383. FileType,
  384. NULL,
  385. PrimaryHandle,
  386. NULL,
  387. LogHandle,
  388. NULL,
  389. NULL);
  390. if (!Success) {
  391. NtClose(PrimaryHandle);
  392. if (LogHandle != NULL) {
  393. NtClose(LogHandle);
  394. }
  395. return(STATUS_REGISTRY_CORRUPT);
  396. } else {
  397. *CmHive = NewHive;
  398. return(STATUS_SUCCESS);
  399. }
  400. }
  401. NTSTATUS
  402. CmpLinkHiveToMaster(
  403. PUNICODE_STRING LinkName,
  404. HANDLE RootDirectory,
  405. PCMHIVE CmHive,
  406. BOOLEAN Allocate,
  407. PSECURITY_DESCRIPTOR SecurityDescriptor
  408. )
  409. {
  410. return( STATUS_SUCCESS );
  411. }
  412. BOOLEAN
  413. CmpFileSetSize(
  414. PHHIVE Hive,
  415. ULONG FileType,
  416. ULONG FileSize
  417. )
  418. /*++
  419. Routine Description:
  420. This routine sets the size of a file. It must not return until
  421. the size is guaranteed, therefore, it does a flush.
  422. It is environment specific.
  423. This routine will force execution to the correct thread context.
  424. Arguments:
  425. Hive - Hive we are doing I/O for
  426. FileType - which supporting file to use
  427. FileSize - 32 bit value to set the file's size to
  428. Return Value:
  429. FALSE if failure
  430. TRUE if success
  431. --*/
  432. {
  433. NTSTATUS status;
  434. status = CmpDoFileSetSize(Hive, FileType, FileSize);
  435. if (!NT_SUCCESS(status)) {
  436. KdPrint(("CmpFileSetSize:\n\t"));
  437. KdPrint(("Failure: status = %08lx ", status));
  438. return FALSE;
  439. }
  440. return TRUE;
  441. }