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.

2954 lines
79 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. cmp.h
  5. Abstract:
  6. This module contains the private (internal) header file for the
  7. configuration manager.
  8. Author:
  9. Bryan M. Willman (bryanwi) 10-Sep-91
  10. Environment:
  11. Kernel mode only.
  12. Revision History:
  13. 13-Jan-99 Dragos C. Sambotin (dragoss) - factoring the data structure declarations
  14. in \nt\private\ntos\inc\cmdata.h :: to be available from outside.
  15. --*/
  16. #ifndef _CMP_
  17. #define _CMP_
  18. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  19. // Begin SCS (Switch Control Section)
  20. //
  21. // 1. Code to check consistency and to help catch bugs: To be turned on when problems
  22. // appear in that area; Word of caution: some of these switches may affect performance
  23. //
  24. #if DBG
  25. #define CMP_NOTIFY_POSTBLOCK_CHECK // controls the CmpCheckPostBlock macro, used to check
  26. // validity and consistency of a notify post block
  27. #define CMP_ENTRYLIST_MANIPULATION // controls the removal of an element from a LIST_ENTRY
  28. // by setting the Blink and Flink to NULL;
  29. // macros affected : IsListEmpty and RemoveEmptyList
  30. // WARNING : to be defined only when not linking against the loader
  31. #define CMP_KCB_CACHE_VALIDATION // validates KCB cached members changes by comparing against the knode values.
  32. // We shall disable this after proven the caching mechanism works OK
  33. //#define CMP_CMVIEW_VALIDATION // validates the view mapping mechanism
  34. #define CHECK_REGISTRY_USECOUNT // Validates the GetCell/ReleaseCell call matching, to ensure mapped views
  35. // don't get unmapped while in use
  36. //#define SYNC_HIVE_VALIDATION // validate the HvpDoWriteHive paged dirty data algorithm
  37. // We shall disable this after we catch saving alternate problem
  38. //#define HIVE_SECURITY_STATS // collect statistics about security cells
  39. //#define CMP_STATS // collect statistics about kcbs
  40. //#define WRITE_PROTECTED_REGISTRY_POOL // applies only for registry hives stored in paged pool
  41. // controls access over registry bins
  42. //#define WRITE_PROTECTED_VALUE_CACHE // protects pool allocations used for kcb value cache
  43. //#define DRAGOSS_PRIVATE_DEBUG // private debug session
  44. //#define CM_CHECK_MAP_NO_READ_SCHEME // validates the mapping code assumption (i.e. each bin map should start
  45. // with HMAP_NEW_ALLOC; this is true only for mapped bins
  46. #define REGISTRY_LOCK_CHECKING // on each Nt API level call, checks the thread has released all locks
  47. // acquired. We may want to remove it, as it can hide bugs in other components
  48. // bellow registry (Ob, Se, Ps, Mm)
  49. //#define CM_PERF_ISSUES // keep track of how long CmpInitializeHiveList and CmpConvertHiveToMapped takes
  50. #define CM_CHECK_FOR_ORPHANED_KCBS // check for orphaned kcbs every time we free a hive.
  51. #endif //DBG
  52. //#define CM_RETRY_CREATE_FILE // when an error is returned from ZwCreateFile calls, retry the call
  53. //#define CM_NOTIFY_CHANGED_KCB_FULLPATH // return the full qualified path of the changed kcb in the Buffer arg of NtNotifyChangeKey
  54. #if defined(_X86_)
  55. #define CM_LEAK_STACK_TRACES // keeps stacks traces for opened handles
  56. #endif //_X86_
  57. //
  58. // 2. these section controls whether or not a certain feature goes into product or not;
  59. // The goal is to remove these switches as new features are accepted, tested and proven to work
  60. //
  61. #ifndef _CM_LDR_
  62. #define NT_RENAME_KEY // NtRenameKey API
  63. #define NT_UNLOAD_KEY_EX // NtUnloadKeyEx API
  64. #endif //_CM_LDR_
  65. #define CM_ENABLE_MAPPED_VIEWS // controls whether the mapped views feature (using Cc interfaces) is used
  66. // by commenting this, registry hives are reverted to paged pool
  67. // WARNING: This should be always on !!!
  68. //#define CM_ENABLE_WRITE_ONLY_BINS // use MmSetPageProtection to catch writes on data not marked dirty
  69. #define CM_MAP_NO_READ // this switch contols whether we map (touch all pages) or just pin_no_read
  70. // now it makes sense to use this as mm will fault in one page at a time for
  71. // MNW streams
  72. #define CM_BREAK_ON_KEY_OPEN // breaks when a key with Flags & KEY_BREAK_ON_OPEN is opened or a subkey is added
  73. //#define CM_SAVE_KCB_CACHE // at shutdown, save the kcb cache into a file
  74. //#define CM_DYN_SYM_LINK // dynamic symbolic links enabled.
  75. //#define HV_TRACK_FREE_SPACE // keep track of the actual free space inside the hive
  76. //
  77. // End SCS
  78. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  79. #ifdef CM_DYN_SYM_LINK
  80. #define REG_DYN_LINK 21 // this should be moved to the proper place
  81. #endif
  82. #include "ntos.h"
  83. #include "hive.h"
  84. #include "wchar.h"
  85. #include "zwapi.h"
  86. #include <stdio.h>
  87. #include <profiles.h>
  88. // bugcheck description and defines
  89. #include "cmpbug.h"
  90. #include "kddll.h"
  91. // CM data structure declarations
  92. // file location: \nt\private\ntos\inc
  93. #include "cmdata.h"
  94. #ifdef CMP_STATS
  95. VOID
  96. CmpKcbStat(
  97. VOID
  98. );
  99. #endif
  100. #ifndef _CM_LDR_
  101. #define CmKdPrintEx(_x_) KdPrintEx(_x_)
  102. #else
  103. #define CmKdPrintEx(_x_) //nothing
  104. #endif //_CM_LDR_
  105. #define _64K 64L*1024L //64K
  106. #define _256K 256L*1024L //256K
  107. //
  108. // this constant defines the size of a Cc view that is mapped -in every time a cell
  109. // is accessed; It can be any power of 2, no less than 16K and no bigger than 256K
  110. //
  111. #define CM_VIEW_SIZE 16L*1024L //16K
  112. //
  113. // control the granularity the primary file grows;
  114. // Warning: this should be multiple of 4K (HBLOCK_SIZE) !!!
  115. //
  116. #define CM_FILE_GROW_INCREMENT 256L*1024L //256K
  117. //
  118. // this controls the maximmum adress space allowed per hive. It should be specified in
  119. // multiples of 256K
  120. //
  121. // 4 means 1 MB
  122. // 6 means 1.5 MB
  123. // 12 means 3 MB
  124. // .....
  125. //
  126. #define MAX_MB_PER_HIVE 16 // 4MB
  127. #define MAX_NAME 128
  128. #ifdef CMP_ENTRYLIST_MANIPULATION
  129. #define CmpRemoveEntryList(a) \
  130. if(((a)->Flink == NULL) && ((a)->Blink == NULL) ) {\
  131. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_ERROR_LEVEL,"CmpRemoveEntryList: Entry %08lx\n",a);\
  132. DbgBreakPoint();\
  133. }\
  134. RemoveEntryList(a);\
  135. (a)->Flink = (a)->Blink = NULL
  136. #define CmpClearListEntry(a) (a)->Flink = (a)->Blink = NULL
  137. #define CmpIsListEmpty(a) ( ( ((a)->Flink == NULL) && ((a)->Blink == NULL) ) || ( ((a)->Flink != NULL) && ((a)->Blink != NULL) && IsListEmpty(a) ) )
  138. #else
  139. #define CmpRemoveEntryList(a) RemoveEntryList(a)
  140. #define CmpClearListEntry(a) //nothing
  141. #define CmpIsListEmpty(a) IsListEmpty(a)
  142. #endif // CMP_ENTRYLIST_MANIPULATION
  143. extern PCM_TRACE_NOTIFY_ROUTINE CmpTraceRoutine;
  144. VOID
  145. CmpWmiDumpKcb(
  146. PCM_KEY_CONTROL_BLOCK kcb
  147. );
  148. #define CmpWmiFireEvent(Status,Kcb,ElapsedTime,Index,KeyName,Type) \
  149. try { \
  150. PCM_TRACE_NOTIFY_ROUTINE TraceRoutine = CmpTraceRoutine; \
  151. if( TraceRoutine != NULL ) { \
  152. (*TraceRoutine)(Status,Kcb,ElapsedTime,Index,KeyName,Type); \
  153. } \
  154. } except (EXCEPTION_EXECUTE_HANDLER) { }
  155. #define StartWmiCmTrace()\
  156. LARGE_INTEGER StartSystemTime;\
  157. LARGE_INTEGER EndSystemTime;\
  158. PVOID HookKcb = NULL;\
  159. if (CmpTraceRoutine) {\
  160. PerfTimeStamp(StartSystemTime); \
  161. }
  162. #define EndWmiCmTrace(Status,Index,KeyName,Type)\
  163. if (CmpTraceRoutine) {\
  164. try {\
  165. PerfTimeStamp(EndSystemTime); \
  166. CmpWmiFireEvent(Status,HookKcb,EndSystemTime.QuadPart - StartSystemTime.QuadPart,Index,KeyName,Type);\
  167. } except (EXCEPTION_EXECUTE_HANDLER) {\
  168. }\
  169. }
  170. #define HookKcbForWmiCmTrace(KeyBody) \
  171. if (CmpTraceRoutine) {\
  172. if(KeyBody) {\
  173. HookKcb = KeyBody->KeyControlBlock;\
  174. }\
  175. }
  176. #define HookKcbFromHandleForWmiCmTrace(KeyHandle) \
  177. if (CmpTraceRoutine) {\
  178. PCM_KEY_BODY KeyBody;\
  179. NTSTATUS status;\
  180. status = ObReferenceObjectByHandle(\
  181. KeyHandle,\
  182. 0,\
  183. CmpKeyObjectType,\
  184. KeGetPreviousMode(),\
  185. (PVOID *)(&KeyBody),\
  186. NULL\
  187. );\
  188. if (NT_SUCCESS(status)) {\
  189. HookKcb = KeyBody->KeyControlBlock;\
  190. ObDereferenceObject((PVOID)KeyBody);\
  191. }\
  192. }
  193. #define CmpTraceKcbCreate(kcb) \
  194. if (CmpTraceRoutine) {\
  195. CmpWmiDumpKcb(kcb);\
  196. }
  197. #ifdef WRITE_PROTECTED_VALUE_CACHE
  198. #define CmpMakeSpecialPoolReadOnly(PoolAddress) \
  199. { \
  200. if( !MmProtectSpecialPool( (PVOID) PoolAddress, PAGE_READONLY) ) \
  201. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_POOL,"[CmpMakeSpecialPoolReadOnly]: Failed to Mark SpecialPool %p as ReadOnly", PoolAddress )); \
  202. }
  203. #define CmpMakeSpecialPoolReadWrite(PoolAddress) \
  204. { \
  205. if( !MmProtectSpecialPool( (PVOID) PoolAddress, PAGE_READWRITE) ) { \
  206. CmKdPrintEx((DPFLTR_CONFIG_ID,CML_POOL,"[CmpMakeSpecialPoolReadWrite]: Failed to Mark SpecialPool %p as ReadWrite", PoolAddress )); \
  207. } \
  208. }
  209. #define CmpMakeValueCacheReadOnly(ValueCached,PoolAddress) \
  210. if(ValueCached) { \
  211. CmpMakeSpecialPoolReadOnly( PoolAddress );\
  212. }
  213. #define CmpMakeValueCacheReadWrite(ValueCached,PoolAddress) \
  214. if(ValueCached) { \
  215. CmpMakeSpecialPoolReadWrite( PoolAddress );\
  216. }
  217. #else
  218. #define CmpMakeSpecialPoolReadOnly(a) //nothing
  219. #define CmpMakeSpecialPoolReadWrite(a) //nothing
  220. #define CmpMakeValueCacheReadOnly(a,b) //nothing
  221. #define CmpMakeValueCacheReadWrite(a,b) //nothing
  222. #endif
  223. #ifdef WRITE_PROTECTED_REGISTRY_POOL
  224. VOID
  225. HvpMarkBinReadWrite(
  226. PHHIVE Hive,
  227. HCELL_INDEX Cell
  228. );
  229. VOID
  230. HvpChangeBinAllocation(
  231. PHBIN Bin,
  232. BOOLEAN ReadOnly
  233. );
  234. VOID
  235. CmpMarkAllBinsReadOnly(
  236. PHHIVE Hive
  237. );
  238. #else
  239. #define HvpChangeBinAllocation(a,b) //nothing
  240. #define HvpMarkBinReadWrite(a,b) //nothing
  241. #define CmpMarkAllBinsReadOnly(a) //nothing
  242. #endif
  243. #ifdef POOL_TAGGING
  244. //
  245. // Pool Tag
  246. //
  247. #define CM_POOL_TAG ' MC'
  248. #define CM_KCB_TAG 'bkMC'
  249. #define CM_POSTBLOCK_TAG 'bpMC'
  250. #define CM_NOTIFYBLOCK_TAG 'bnMC'
  251. #define CM_POSTEVENT_TAG 'epMC'
  252. #define CM_POSTAPC_TAG 'apMC'
  253. #define CM_MAPPEDVIEW_TAG 'wVMC'
  254. #define CM_SECCACHE_TAG 'cSMC'
  255. #define CM_DELAYCLOSE_TAG 'cDMC'
  256. #define CM_STASHBUFFER_TAG 'bSMC'
  257. #define CM_HVBIN_TAG 'bHMC'
  258. #define CM_ALLOCATE_TAG 'lAMC'
  259. //
  260. // Find leaks
  261. //
  262. #define CM_FIND_LEAK_TAG1 ' 1MC'
  263. #define CM_FIND_LEAK_TAG2 ' 2MC'
  264. #define CM_FIND_LEAK_TAG3 ' 3MC'
  265. #define CM_FIND_LEAK_TAG4 ' 4MC'
  266. #define CM_FIND_LEAK_TAG5 ' 5MC'
  267. #define CM_FIND_LEAK_TAG6 ' 6MC'
  268. #define CM_FIND_LEAK_TAG7 ' 7MC'
  269. #define CM_FIND_LEAK_TAG8 ' 8MC'
  270. #define CM_FIND_LEAK_TAG9 ' 9MC'
  271. #define CM_FIND_LEAK_TAG10 '01MC'
  272. #define CM_FIND_LEAK_TAG11 '11MC'
  273. #define CM_FIND_LEAK_TAG12 '21MC'
  274. #define CM_FIND_LEAK_TAG13 '31MC'
  275. #define CM_FIND_LEAK_TAG14 '41MC'
  276. #define CM_FIND_LEAK_TAG15 '51MC'
  277. #define CM_FIND_LEAK_TAG16 '61MC'
  278. #define CM_FIND_LEAK_TAG17 '71MC'
  279. #define CM_FIND_LEAK_TAG18 '81MC'
  280. #define CM_FIND_LEAK_TAG19 '91MC'
  281. #define CM_FIND_LEAK_TAG20 '02MC'
  282. #define CM_FIND_LEAK_TAG21 '12MC'
  283. #define CM_FIND_LEAK_TAG22 '22MC'
  284. #define CM_FIND_LEAK_TAG23 '32MC'
  285. #define CM_FIND_LEAK_TAG24 '42MC'
  286. #define CM_FIND_LEAK_TAG25 '52MC'
  287. #define CM_FIND_LEAK_TAG26 '62MC'
  288. #define CM_FIND_LEAK_TAG27 '72MC'
  289. #define CM_FIND_LEAK_TAG28 '82MC'
  290. #define CM_FIND_LEAK_TAG29 '92MC'
  291. #define CM_FIND_LEAK_TAG30 '03MC'
  292. #define CM_FIND_LEAK_TAG31 '13MC'
  293. #define CM_FIND_LEAK_TAG32 '23MC'
  294. #define CM_FIND_LEAK_TAG33 '33MC'
  295. #define CM_FIND_LEAK_TAG34 '43MC'
  296. #define CM_FIND_LEAK_TAG35 '53MC'
  297. #define CM_FIND_LEAK_TAG36 '63MC'
  298. #define CM_FIND_LEAK_TAG37 '73MC'
  299. #define CM_FIND_LEAK_TAG38 '83MC'
  300. #define CM_FIND_LEAK_TAG39 '93MC'
  301. #define CM_FIND_LEAK_TAG40 '04MC'
  302. #define CM_FIND_LEAK_TAG41 '14MC'
  303. #define CM_FIND_LEAK_TAG42 '24MC'
  304. #define CM_FIND_LEAK_TAG43 '34MC'
  305. #define CM_FIND_LEAK_TAG44 '44MC'
  306. #define CM_FIND_LEAK_TAG45 '54MC'
  307. #ifdef _WANT_MACHINE_IDENTIFICATION
  308. #define CM_PARSEINI_TAG 'ipMC'
  309. #define CM_GENINST_TAG 'igMC'
  310. #endif
  311. //
  312. // Extra Tags for cache.
  313. // We may want to merge these tags later.
  314. //
  315. #define CM_CACHE_VALUE_INDEX_TAG 'IVMC'
  316. #define CM_CACHE_VALUE_TAG 'aVMC'
  317. #define CM_CACHE_INDEX_TAG 'nIMC'
  318. #define CM_CACHE_VALUE_DATA_TAG 'aDMC'
  319. #define CM_NAME_TAG 'bNMC'
  320. #define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,CM_POOL_TAG)
  321. #define ExAllocatePoolWithQuota(a,b) ExAllocatePoolWithQuotaTag(a,b,CM_POOL_TAG)
  322. PVOID
  323. CmpAllocateTag(
  324. ULONG Size,
  325. BOOLEAN UseForIo,
  326. ULONG Tag
  327. );
  328. #else
  329. #define CmpAllocateTag(a,b,c) CmpAllocate(a,b,c)
  330. #endif
  331. //
  332. // A variable so can turn on/off certain performance features.
  333. //
  334. extern const ULONG CmpCacheOnFlag;
  335. #define CM_CACHE_FAKE_KEY 0x00000001 // Create Fake key KCB
  336. //
  337. // This lock protects the KCB cache, including the KCB structures,
  338. // NameBlock and Value Index.
  339. //
  340. extern ERESOURCE CmpKcbLock;
  341. //
  342. // This is \REGISTRY
  343. //
  344. extern HANDLE CmpRegistryRootHandle;
  345. #if 0
  346. #define CmpLockKCBTree() ExAcquireResourceShared(&CmpKcbLock, TRUE)
  347. #define CmpLockKCBTreeExclusive() ExAcquireResourceExclusive(&CmpKcbLock);
  348. #else
  349. VOID
  350. CmpLockKCBTreeExclusive(
  351. VOID
  352. );
  353. VOID
  354. CmpLockKCBTree(
  355. VOID
  356. );
  357. #endif
  358. VOID
  359. CmpUnlockKCBTree(
  360. );
  361. #if DBG
  362. BOOLEAN
  363. CmpTestKCBLock(
  364. VOID
  365. );
  366. BOOLEAN
  367. CmpTestKCBLockExclusive(
  368. VOID
  369. );
  370. #define ASSERT_KCB_LOCK_OWNED() \
  371. ASSERT(CmpTestKCBLock() == TRUE)
  372. #define ASSERT_KCB_LOCK_OWNED_EXCLUSIVE() \
  373. ASSERT(CmpTestKCBLockExclusive() == TRUE)
  374. #else
  375. #define ASSERT_KCB_LOCK_OWNED()
  376. #define ASSERT_KCB_LOCK_OWNED_EXCLUSIVE()
  377. #endif
  378. //
  379. // Logging: remember, first 4 levels (0-3) are reserved system-wide
  380. //
  381. #define CML_BUGCHECK 4 // fatal errors
  382. #define CML_EXCEPTION 5 // all exception's
  383. #define CML_NTAPI 6 // NtApi calls
  384. #define CML_NTAPI_ARGS 7 // NtApi parameters
  385. #define CML_CM 8 // Cm level, general
  386. #define CML_NOTIFY 9 // Notify level, general
  387. #define CML_HIVE 10 // Hv level, general
  388. #define CML_IO 11 // IO level
  389. #define CML_SEC 12 // Security level
  390. #define CML_INIT 13 // Init level, general
  391. #define CML_INDEX 14 // Index level, general
  392. #define CML_BIN_MAP 15 // bin mapping level
  393. #define CML_FREECELL 16 // Free cell hints
  394. #define CML_POOL 17 // Pool
  395. #define CML_LOCKING 18 // Lock/unlock level
  396. #define CML_FLOW 19 // General flow
  397. #define CML_PARSE 20 // Parse algorithm
  398. #define CML_SAVRES 21 // SavRes operations
  399. #define REGCHECKING 1
  400. #if DBG
  401. #if REGCHECKING
  402. #define DCmCheckRegistry(a) if(HvHiveChecking) ASSERT(CmCheckRegistry(a, CM_CHECK_REGISTRY_HIVE_CHECK) == 0)
  403. #else
  404. #define DCmCheckRegistry(a)
  405. #endif
  406. #else
  407. #define DCmCheckRegistry(a)
  408. #endif
  409. #ifdef CHECK_REGISTRY_USECOUNT
  410. VOID
  411. CmpCheckRegistryUseCount( );
  412. #endif //CHECK_REGISTRY_USECOUNT
  413. #ifdef REGISTRY_LOCK_CHECKING
  414. ULONG
  415. CmpCheckLockExceptionFilter(
  416. IN PEXCEPTION_POINTERS ExceptionPointers
  417. );
  418. //
  419. // updated to check both registry and kcb
  420. //
  421. #define BEGIN_LOCK_CHECKPOINT \
  422. { \
  423. ULONG RegistryLockCountBefore,RegistryLockCountAfter; \
  424. ULONG KCBLockCountBefore,KCBLockCountAfter; \
  425. RegistryLockCountBefore = ExIsResourceAcquiredShared(&CmpRegistryLock); \
  426. RegistryLockCountBefore += ExIsResourceAcquiredExclusive(&CmpRegistryLock); \
  427. KCBLockCountBefore = ExIsResourceAcquiredShared(&CmpKcbLock); \
  428. KCBLockCountBefore += ExIsResourceAcquiredExclusive(&CmpKcbLock); \
  429. try {
  430. #define END_LOCK_CHECKPOINT \
  431. } except(CmpCheckLockExceptionFilter(GetExceptionInformation())) {} \
  432. RegistryLockCountAfter = ExIsResourceAcquiredShared(&CmpRegistryLock); \
  433. RegistryLockCountAfter += ExIsResourceAcquiredExclusive(&CmpRegistryLock); \
  434. KCBLockCountAfter = ExIsResourceAcquiredShared(&CmpKcbLock); \
  435. KCBLockCountAfter += ExIsResourceAcquiredExclusive(&CmpKcbLock); \
  436. if( RegistryLockCountBefore != RegistryLockCountAfter ) { \
  437. CM_BUGCHECK(REGISTRY_ERROR,REGISTRY_LOCK_CHECKPOINT,0,RegistryLockCountBefore,RegistryLockCountAfter); \
  438. } \
  439. if( KCBLockCountBefore != KCBLockCountAfter ) { \
  440. CM_BUGCHECK(REGISTRY_ERROR,REGISTRY_LOCK_CHECKPOINT,1,KCBLockCountBefore,KCBLockCountAfter); \
  441. } \
  442. }
  443. #define BEGIN_KCB_LOCK_GUARD \
  444. try {
  445. #define END_KCB_LOCK_GUARD \
  446. } except(CmpCheckLockExceptionFilter(GetExceptionInformation())) {}
  447. #else
  448. #define BEGIN_LOCK_CHECKPOINT
  449. #define END_LOCK_CHECKPOINT
  450. #define BEGIN_KCB_LOCK_GUARD
  451. #define END_KCB_LOCK_GUARD
  452. #endif //REGISTRY_LOCK_CHECKING
  453. extern BOOLEAN CmpSpecialBootCondition;
  454. #if DBG
  455. #define ASSERT_CM_LOCK_OWNED() \
  456. ASSERT( (CmpSpecialBootCondition == TRUE) || (CmpTestRegistryLock() == TRUE) )
  457. #define ASSERT_CM_LOCK_OWNED_EXCLUSIVE() \
  458. ASSERT((CmpSpecialBootCondition == TRUE) || (CmpTestRegistryLockExclusive() == TRUE) )
  459. #define ASSERT_CM_EXCLUSIVE_HIVE_ACCESS(Hive) \
  460. ASSERT((CmpSpecialBootCondition == TRUE) || (CmpTestRegistryLockExclusive() == TRUE) || (Hive->ReleaseCellRoutine == NULL) )
  461. #else
  462. #define ASSERT_CM_LOCK_OWNED()
  463. #define ASSERT_CM_LOCK_OWNED_EXCLUSIVE()
  464. #define ASSERT_CM_EXCLUSIVE_HIVE_ACCESS(Hive)
  465. #endif
  466. #if DBG
  467. #ifndef _CM_LDR_
  468. #define ASSERT_PASSIVE_LEVEL() \
  469. { \
  470. KIRQL Irql; \
  471. Irql = KeGetCurrentIrql(); \
  472. if( KeGetCurrentIrql() != PASSIVE_LEVEL ) { \
  473. DbgPrintEx(DPFLTR_CONFIG_ID,DPFLTR_ERROR_LEVEL,"ASSERT_PASSIVE_LEVEL failed ... Irql = %lu\n",Irql); \
  474. ASSERT( FALSE ); \
  475. } \
  476. }
  477. #endif //_CM_LDR_
  478. #else
  479. #define ASSERT_PASSIVE_LEVEL()
  480. #endif
  481. #define VALIDATE_CELL_MAP(LINE,Map,Hive,Address) \
  482. if( Map == NULL ) { \
  483. CM_BUGCHECK (REGISTRY_ERROR,BAD_CELL_MAP,(ULONG_PTR)(Hive),(ULONG)(Address),(ULONG)(LINE)) ; \
  484. }
  485. #if DBG
  486. VOID
  487. SepDumpSecurityDescriptor(
  488. IN PSECURITY_DESCRIPTOR SecurityDescriptor,
  489. IN PSZ TitleString
  490. );
  491. extern BOOLEAN SepDumpSD;
  492. #define CmpDumpSecurityDescriptor(x,y) \
  493. { \
  494. SepDumpSD=TRUE; \
  495. SepDumpSecurityDescriptor(x, y); \
  496. SepDumpSD=FALSE; \
  497. }
  498. #else
  499. #define CmpDumpSecurityDescriptor(x,y)
  500. #endif
  501. //
  502. // misc stuff
  503. //
  504. extern UNICODE_STRING CmRegistrySystemCloneName;
  505. //
  506. // Determines whether the Current Control Set used during booting
  507. // is cloned in order to fully preserve it for being saved
  508. // as the LKG Control Set.
  509. //
  510. #define CLONE_CONTROL_SET FALSE
  511. #if CLONE_CONTROL_SET
  512. #define CM_NUMBER_OF_MACHINE_HIVES 7
  513. #else
  514. #define CM_NUMBER_OF_MACHINE_HIVES 6
  515. #endif
  516. #define NUMBER_TYPES (MaximumType + 1)
  517. #define CM_WRAP_LIMIT 0x7fffffff
  518. //
  519. // Tuning and control constants
  520. //
  521. #define CM_MAX_STASH 1024*1024 // If size of data for a set
  522. // is bigger than this,
  523. #define CM_MAX_REASONABLE_VALUES 100 // If number of values for a
  524. // key is greater than this,
  525. // round up value list size
  526. //
  527. // Limit on the number of layers of hive there may be. We allow only
  528. // the master hive and hives directly linked into it for now, for currently
  529. // value is always 2..
  530. //
  531. #define MAX_HIVE_LAYERS 2
  532. //
  533. // structure used to create and sort ordered list of drivers to be loaded.
  534. // This is also used by the OS Loader when loading the boot drivers.
  535. // (Particularly the ErrorControl field)
  536. //
  537. typedef struct _BOOT_DRIVER_NODE {
  538. BOOT_DRIVER_LIST_ENTRY ListEntry;
  539. UNICODE_STRING Group;
  540. UNICODE_STRING Name;
  541. ULONG Tag;
  542. ULONG ErrorControl;
  543. } BOOT_DRIVER_NODE, *PBOOT_DRIVER_NODE;
  544. //
  545. // extern for object type pointer
  546. //
  547. extern POBJECT_TYPE CmpKeyObjectType;
  548. extern POBJECT_TYPE IoFileObjectType;
  549. //
  550. // indexes in CmpMachineHiveList
  551. //
  552. #define SYSTEM_HIVE_INDEX 3
  553. #define CLONE_HIVE_INDEX 6
  554. //
  555. // Miscelaneous Hash routines
  556. //
  557. #define RNDM_CONSTANT 314159269 /* default value for "scrambling constant" */
  558. #define RNDM_PRIME 1000000007 /* prime number, also used for scrambling */
  559. #define HASH_KEY(_convkey_) ((RNDM_CONSTANT * (_convkey_)) % RNDM_PRIME)
  560. #define GET_HASH_INDEX(Key) HASH_KEY(Key) % CmpHashTableSize
  561. #define GET_HASH_ENTRY(Table, Key) Table[GET_HASH_INDEX(Key)]
  562. //
  563. // CM_KEY_BODY
  564. //
  565. // Same structure used for KEY_ROOT and KEY objects. This is the
  566. // Cm defined part of the object.
  567. //
  568. // This object represents an open instance, several of them could refer
  569. // to a single key control block.
  570. //
  571. #define KEY_BODY_TYPE 0x6b793032 // "ky02"
  572. struct _CM_NOTIFY_BLOCK; //forward
  573. typedef struct _CM_KEY_BODY {
  574. ULONG Type;
  575. PCM_KEY_CONTROL_BLOCK KeyControlBlock;
  576. struct _CM_NOTIFY_BLOCK *NotifyBlock;
  577. PEPROCESS Process; // the owner process
  578. #ifdef CM_LEAK_STACK_TRACES
  579. ULONG Callers;
  580. PVOID CallerAddress[10];
  581. #endif //CM_LEAK_STACK_TRACES
  582. LIST_ENTRY KeyBodyList; // key_nodes using the same kcb
  583. } CM_KEY_BODY, *PCM_KEY_BODY;
  584. #ifdef CM_LEAK_STACK_TRACES
  585. // just because we need this #define code inside a macro !
  586. #define CmpSetNoCallers(KeyBody) KeyBody->Callers = 0
  587. #define CmpAddKeyTracker(KeyHandle,mode) \
  588. if(PoCleanShutdownEnabled() & PO_CLEAN_SHUTDOWN_REGISTRY) { \
  589. PCM_KEY_BODY KeyBody; \
  590. NTSTATUS status; \
  591. status = ObReferenceObjectByHandle( \
  592. KeyHandle, \
  593. 0, \
  594. CmpKeyObjectType, \
  595. mode, \
  596. (PVOID *)(&KeyBody), \
  597. NULL \
  598. ); \
  599. if( NT_SUCCESS(status) ) { \
  600. KeyBody->Callers = RtlWalkFrameChain(&(KeyBody->CallerAddress[0]), 10, 0); \
  601. ObDereferenceObject((PVOID)KeyBody); \
  602. } \
  603. }
  604. #else
  605. #define CmpSetNoCallers(KeyBody) // nothing
  606. #define CmpAddKeyTracker(KeyHandle,mode) // nothing yet
  607. #endif //CM_LEAK_STACK_TRACES
  608. #define INIT_KCB_KEYBODY_LIST(kcb) InitializeListHead(&(kcb->KeyBodyListHead))
  609. #define ASSERT_KEYBODY_LIST_EMPTY(kcb) ASSERT(IsListEmpty(&(kcb->KeyBodyListHead)) == TRUE)
  610. #define ENLIST_KEYBODY_IN_KEYBODY_LIST(KeyBody) \
  611. ASSERT( KeyBody->KeyControlBlock != NULL ); \
  612. BEGIN_KCB_LOCK_GUARD; \
  613. CmpLockKCBTreeExclusive(); \
  614. InsertTailList(&(KeyBody->KeyControlBlock->KeyBodyListHead),&(KeyBody->KeyBodyList)); \
  615. CmpSetNoCallers(KeyBody); \
  616. CmpUnlockKCBTree(); \
  617. END_KCB_LOCK_GUARD
  618. #define DELIST_KEYBODY_FROM_KEYBODY_LIST(KeyBody) \
  619. ASSERT( KeyBody->KeyControlBlock != NULL ); \
  620. ASSERT(IsListEmpty(&(KeyBody->KeyControlBlock->KeyBodyListHead)) == FALSE); \
  621. BEGIN_KCB_LOCK_GUARD; \
  622. CmpLockKCBTreeExclusive(); \
  623. RemoveEntryList(&(KeyBody->KeyBodyList)); \
  624. CmpUnlockKCBTree(); \
  625. END_KCB_LOCK_GUARD
  626. #define ASSERT_KEY_OBJECT(x) ASSERT(((PCM_KEY_BODY)x)->Type == KEY_BODY_TYPE)
  627. #define ASSERT_NODE(x) ASSERT(((PCM_KEY_NODE)x)->Signature == CM_KEY_NODE_SIGNATURE)
  628. #define ASSERT_SECURITY(x) ASSERT(((PCM_KEY_SECURITY)x)->Signature == CM_KEY_SECURITY_SIGNATURE)
  629. //
  630. // CM_POST_KEY_BODY
  631. //
  632. // A post block can have attached a keybody which has to be dereferenced
  633. // when the post block goes out of scope. This structure allows the
  634. // implementation of keybody "delayed dereferencing". (see CmpPostNotify for comments)
  635. //
  636. typedef struct _CM_POST_KEY_BODY {
  637. LIST_ENTRY KeyBodyList;
  638. struct _CM_KEY_BODY *KeyBody; // this key body object
  639. } CM_POST_KEY_BODY, *PCM_POST_KEY_BODY;
  640. //
  641. // CM_NOTIFY_BLOCK
  642. //
  643. // A notify block tracks an active notification waiting for notification.
  644. // Any one open instance (CM_KEY_BODY) will refer to at most one
  645. // notify block. A given key control block may have as many notify
  646. // blocks refering to it as there are CM_KEY_BODYs refering to it.
  647. // Notify blocks are attached to hives and sorted by length of name.
  648. //
  649. typedef struct _CM_NOTIFY_BLOCK {
  650. LIST_ENTRY HiveList; // sorted list of notifies
  651. LIST_ENTRY PostList; // Posts to fill
  652. PCM_KEY_CONTROL_BLOCK KeyControlBlock; // Open instance notify is on
  653. struct _CM_KEY_BODY *KeyBody; // our owning key handle object
  654. struct {
  655. ULONG Filter : 30; // Events of interest
  656. ULONG WatchTree : 1;
  657. ULONG NotifyPending : 1;
  658. };
  659. SECURITY_SUBJECT_CONTEXT SubjectContext; // Security stuff
  660. } CM_NOTIFY_BLOCK, *PCM_NOTIFY_BLOCK;
  661. //
  662. // CM_POST_BLOCK
  663. //
  664. // Whenever a notify call is made, a post block is created and attached
  665. // to the notify block. Each time an event is posted against the notify,
  666. // the waiter described by the post block is signaled. (i.e. APC enqueued,
  667. // event signalled, etc.)
  668. //
  669. //
  670. // The NotifyType ULONG is a combination of POST_BLOCK_TYPE enum and flags
  671. //
  672. typedef enum _POST_BLOCK_TYPE {
  673. PostSynchronous = 1,
  674. PostAsyncUser = 2,
  675. PostAsyncKernel = 3
  676. } POST_BLOCK_TYPE;
  677. typedef struct _CM_SYNC_POST_BLOCK {
  678. PKEVENT SystemEvent;
  679. NTSTATUS Status;
  680. } CM_SYNC_POST_BLOCK, *PCM_SYNC_POST_BLOCK;
  681. typedef struct _CM_ASYNC_USER_POST_BLOCK {
  682. PKEVENT UserEvent;
  683. PKAPC Apc;
  684. PIO_STATUS_BLOCK IoStatusBlock;
  685. } CM_ASYNC_USER_POST_BLOCK, *PCM_ASYNC_USER_POST_BLOCK;
  686. typedef struct _CM_ASYNC_KERNEL_POST_BLOCK {
  687. PKEVENT Event;
  688. PWORK_QUEUE_ITEM WorkItem;
  689. WORK_QUEUE_TYPE QueueType;
  690. } CM_ASYNC_KERNEL_POST_BLOCK, *PCM_ASYNC_KERNEL_POST_BLOCK;
  691. typedef union _CM_POST_BLOCK_UNION {
  692. CM_SYNC_POST_BLOCK Sync;
  693. CM_ASYNC_USER_POST_BLOCK AsyncUser;
  694. CM_ASYNC_KERNEL_POST_BLOCK AsyncKernel;
  695. } CM_POST_BLOCK_UNION, *PCM_POST_BLOCK_UNION;
  696. typedef struct _CM_POST_BLOCK {
  697. #if DBG
  698. BOOLEAN TraceIntoDebugger;
  699. #endif
  700. LIST_ENTRY NotifyList;
  701. LIST_ENTRY ThreadList;
  702. LIST_ENTRY CancelPostList; // slave notifications that are attached to this notification
  703. struct _CM_POST_KEY_BODY *PostKeyBody;
  704. #ifdef CM_NOTIFY_CHANGED_KCB_FULLPATH
  705. PUNICODE_STRING ChangedKcbFullName; // full qualified name of the kcb that triggered this notification
  706. PVOID CallerBuffer; // used to return full qualified name of the changed kcb to the caller
  707. ULONG CallerBufferSize; // these are supposed to be filled by CmpAllocatePostBlock
  708. #endif //CM_NOTIFY_CHANGED_KCB_FULLPATH
  709. ULONG NotifyType;
  710. PCM_POST_BLOCK_UNION u;
  711. } CM_POST_BLOCK, *PCM_POST_BLOCK;
  712. #define REG_NOTIFY_POST_TYPE_MASK (0x0000FFFFL) // mask for finding out the type of the post block
  713. #define REG_NOTIFY_MASTER_POST (0x00010000L) // The current post block is a master one
  714. //
  715. // Usefull macros to manipulate the NotifyType field in CM_POST_BLOCK
  716. //
  717. #define PostBlockType(_post_) ((POST_BLOCK_TYPE)( ((_post_)->NotifyType) & REG_NOTIFY_POST_TYPE_MASK ))
  718. #define IsMasterPostBlock(_post_) ( ((_post_)->NotifyType) & REG_NOTIFY_MASTER_POST )
  719. #define SetMasterPostBlockFlag(_post_) ( ((_post_)->NotifyType) |= REG_NOTIFY_MASTER_POST )
  720. #define ClearMasterPostBlockFlag(_post_) ( ((_post_)->NotifyType) &= ~REG_NOTIFY_MASTER_POST )
  721. //
  722. // This lock protects the PostList(s) in Notification objects.
  723. // It is used to prevent attempts for simultaneous changes of
  724. // CancelPostList list in PostBlocks
  725. //
  726. extern FAST_MUTEX CmpPostLock;
  727. #define LOCK_POST_LIST() ExAcquireFastMutexUnsafe(&CmpPostLock)
  728. #define UNLOCK_POST_LIST() ExReleaseFastMutexUnsafe(&CmpPostLock)
  729. extern FAST_MUTEX CmpStashBufferLock;
  730. #define LOCK_STASH_BUFFER() ExAcquireFastMutexUnsafe(&CmpStashBufferLock)
  731. #define UNLOCK_STASH_BUFFER() ExReleaseFastMutexUnsafe(&CmpStashBufferLock)
  732. //
  733. // protection for CmpHiveListHead
  734. //
  735. extern FAST_MUTEX CmpHiveListHeadLock;
  736. #ifndef _CM_LDR_
  737. #define LOCK_HIVE_LIST() ExAcquireFastMutexUnsafe(&CmpHiveListHeadLock)
  738. #define UNLOCK_HIVE_LIST() ExReleaseFastMutexUnsafe(&CmpHiveListHeadLock)
  739. #else
  740. #define LOCK_HIVE_LIST() //nothing
  741. #define UNLOCK_HIVE_LIST() //nothing
  742. #endif
  743. //
  744. // used by CmpFileWrite, so it doesn't take up so much stack.
  745. //
  746. typedef struct _CM_WRITE_BLOCK {
  747. HANDLE EventHandles[MAXIMUM_WAIT_OBJECTS];
  748. PKEVENT EventObjects[MAXIMUM_WAIT_OBJECTS];
  749. KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
  750. IO_STATUS_BLOCK IoStatus[MAXIMUM_WAIT_OBJECTS];
  751. } CM_WRITE_BLOCK, *PCM_WRITE_BLOCK;
  752. //
  753. // CM data to manipulate views inside the primary hive file
  754. //
  755. //#define MAPPED_VIEWS_PER_HIVE 12 * (_256K / CM_VIEW_SIZE ) // max 3 MB per hive ; we don't really need this
  756. #define MAX_VIEWS_PER_HIVE MAX_MB_PER_HIVE * ( (_256K) / (CM_VIEW_SIZE) )
  757. #define ASSERT_VIEW_MAPPED(a) \
  758. ASSERT((a)->Size != 0); \
  759. ASSERT((a)->ViewAddress != 0); \
  760. ASSERT((a)->Bcb != 0); \
  761. ASSERT( IsListEmpty(&((a)->LRUViewList)) == FALSE); \
  762. ASSERT( IsListEmpty(&((a)->PinViewList)) == TRUE)
  763. #define ASSERT_VIEW_PINNED(a) \
  764. ASSERT((a)->Size != 0); \
  765. ASSERT((a)->ViewAddress != 0); \
  766. ASSERT((a)->Bcb != 0); \
  767. ASSERT( IsListEmpty(&((a)->LRUViewList)) == TRUE)
  768. typedef struct _CM_VIEW_OF_FILE {
  769. LIST_ENTRY LRUViewList; // LRU connection ==> when this is empty, the view is pinned
  770. LIST_ENTRY PinViewList; // list of views pinned into memory ==> when this is empty, the view is in LRU list
  771. ULONG FileOffset; // file offset at which the mapping starts
  772. ULONG Size; // size the view maps
  773. PULONG_PTR ViewAddress; // memory address containing the mapping
  774. PVOID Bcb; // BCB needed for map/pin/unpin access
  775. ULONG UseCount; // how many cells are currently in use inside this view
  776. } CM_VIEW_OF_FILE, *PCM_VIEW_OF_FILE;
  777. //
  778. // security hash manipulation
  779. //
  780. #define CmpSecHashTableSize 64 // size of the hash table
  781. typedef struct _CM_KCB_REMAP_BLOCK {
  782. LIST_ENTRY RemapList;
  783. PCM_KEY_CONTROL_BLOCK KeyControlBlock;
  784. HCELL_INDEX OldCellIndex;
  785. HCELL_INDEX NewCellIndex;
  786. ULONG ValueCount;
  787. HCELL_INDEX ValueList;
  788. } CM_KCB_REMAP_BLOCK, *PCM_KCB_REMAP_BLOCK;
  789. typedef struct _CM_CELL_REMAP_BLOCK {
  790. HCELL_INDEX OldCell;
  791. HCELL_INDEX NewCell;
  792. } CM_CELL_REMAP_BLOCK, *PCM_CELL_REMAP_BLOCK;
  793. typedef struct _CM_KNODE_REMAP_BLOCK {
  794. LIST_ENTRY RemapList;
  795. PCM_KEY_NODE KeyNode;
  796. HCELL_INDEX NewParent;
  797. } CM_KNODE_REMAP_BLOCK, *PCM_KNODE_REMAP_BLOCK;
  798. // ----- Cm version of Hive structure (CMHIVE) -----
  799. //
  800. typedef struct _CMHIVE {
  801. HHIVE Hive;
  802. HANDLE FileHandles[HFILE_TYPE_MAX];
  803. LIST_ENTRY NotifyList;
  804. LIST_ENTRY HiveList; // Used to find hives at shutdown
  805. PFAST_MUTEX HiveLock; // Used to synchronize operations on the hive (NotifyList and Flush)
  806. PFAST_MUTEX ViewLock; // Used to control access over the view list, UseCount
  807. LIST_ENTRY LRUViewListHead; // Head of the same list as above but ordered (LRU)
  808. LIST_ENTRY PinViewListHead; // Head of the List of Views pinned into memory inside the primary hive file
  809. #if 0 // it didn't work
  810. LIST_ENTRY FakeViewListHead; // Used to optimize boot process (fault all the data in in 256K chunks at once)
  811. #endif
  812. PFILE_OBJECT FileObject; // FileObject needed for Cc operations on the mapped views
  813. UNICODE_STRING FileFullPath; // full path of the hive file- needed for CmPrefetchHivePages
  814. UNICODE_STRING FileUserName; // file name as passed onto NtLoadKey
  815. USHORT MappedViews; // number of mapped (but not pinned views) i.e. the number of elements in LRUViewList
  816. USHORT PinnedViews; // number of pinned views i.e. the number of elements in PinViewList
  817. ULONG UseCount; // how many cells are currently in use inside this hive
  818. #if 0
  819. ULONG FakeViews; // number of FakeViews (debug-only)
  820. #endif
  821. ULONG SecurityCount; // number of security cells cached
  822. ULONG SecurityCacheSize; // number of entries in the cache (to avoid memory fragmentation)
  823. LONG SecurityHitHint; // index of the last cell we've searched on
  824. PCM_KEY_SECURITY_CACHE_ENTRY SecurityCache; // the security cache
  825. // hash table (to retrieve the security cells by descriptor)
  826. LIST_ENTRY SecurityHash[CmpSecHashTableSize];
  827. #ifdef NT_UNLOAD_KEY_EX
  828. PKEVENT UnloadEvent; // the event to be signaled when the hive unloads
  829. // this may be valid (not NULL) only in conjunction with
  830. // a not NULL RootKcb and a TRUE Frozen (bellow)
  831. PCM_KEY_CONTROL_BLOCK RootKcb; // kcb to the root of the hive. We keep a reference on it, which
  832. // will be released at the time the hive unloads (i.e. it is the last
  833. // reference somebody has on this kcb); This is should be valid (not NULL)
  834. // only when the Frozen flag is set to TRUE
  835. BOOLEAN Frozen; // set to TRUE when the hive is frozen (no further operations are allowed on
  836. // this hive
  837. PWORK_QUEUE_ITEM UnloadWorkItem; // Work Item to actually perform the late unload
  838. #endif //NT_UNLOAD_KEY_EX
  839. BOOLEAN GrowOnlyMode; // the hive is in "grow only" mode; new cells are allocated past GrowOffset
  840. ULONG GrowOffset;
  841. LIST_ENTRY KcbConvertListHead; // list of CM_KCB_REMAP_BLOCK storing the associations to the new hive.
  842. LIST_ENTRY KnodeConvertListHead;
  843. PCM_CELL_REMAP_BLOCK CellRemapArray; // array of mappings used for security cells
  844. } CMHIVE, *PCMHIVE;
  845. #ifdef NT_UNLOAD_KEY_EX
  846. #define IsHiveFrozen(_CmHive_) (((PCMHIVE)(_CmHive_))->Frozen == TRUE)
  847. #endif
  848. #define HiveWritesThroughCache(Hive,FileType) ((FileType == HFILE_TYPE_PRIMARY) && (((PCMHIVE)CONTAINING_RECORD(Hive, CMHIVE, Hive))->FileObject != NULL))
  849. //
  850. // Delayed close kcb list
  851. //
  852. typedef struct _CM_DELAYED_CLOSE_ENTRY {
  853. LIST_ENTRY DelayedLRUList; // LRU list of entries in the Delayed Close Table
  854. PCM_KEY_CONTROL_BLOCK KeyControlBlock; // KCB in this entry; NULL if the entry is available
  855. } CM_DELAYED_CLOSE_ENTRY, *PCM_DELAYED_CLOSE_ENTRY;
  856. //
  857. // Hive locking support
  858. //
  859. //
  860. #define CmLockHive(_hive_) ASSERT( (_hive_)->HiveLock );\
  861. ExAcquireFastMutexUnsafe((_hive_)->HiveLock)
  862. #define CmUnlockHive(_hive_) ASSERT( (_hive_)->HiveLock );\
  863. ExReleaseFastMutexUnsafe((_hive_)->HiveLock)
  864. //
  865. // View locking support
  866. //
  867. #define CmLockHiveViews(_hive_) ASSERT( (_hive_)->ViewLock );\
  868. ExAcquireFastMutexUnsafe((_hive_)->ViewLock)
  869. #define CmUnlockHiveViews(_hive_) ASSERT( (_hive_)->ViewLock );\
  870. ExReleaseFastMutexUnsafe((_hive_)->ViewLock)
  871. //
  872. // Macros
  873. //
  874. //
  875. // ----- CM_KEY_NODE -----
  876. //
  877. #define CmpHKeyNameLen(Key) \
  878. (((Key)->Flags & KEY_COMP_NAME) ? \
  879. CmpCompressedNameSize((Key)->Name,(Key)->NameLength) : \
  880. (Key)->NameLength)
  881. #define CmpNcbNameLen(Ncb) \
  882. (((Ncb)->Compressed) ? \
  883. CmpCompressedNameSize((Ncb)->Name,(Ncb)->NameLength) : \
  884. (Ncb)->NameLength)
  885. #define CmpHKeyNodeSize(Hive, KeyName) \
  886. (FIELD_OFFSET(CM_KEY_NODE, Name) + CmpNameSize(Hive, KeyName))
  887. //
  888. // ----- CM_KEY_VALUE -----
  889. //
  890. #define CmpValueNameLen(Value) \
  891. (((Value)->Flags & VALUE_COMP_NAME) ? \
  892. CmpCompressedNameSize((Value)->Name,(Value)->NameLength) : \
  893. (Value)->NameLength)
  894. #define CmpHKeyValueSize(Hive, ValueName) \
  895. (FIELD_OFFSET(CM_KEY_VALUE, Name) + CmpNameSize(Hive, ValueName))
  896. //
  897. // ----- Procedure Prototypes -----
  898. //
  899. //
  900. // Configuration Manager private procedure prototypes
  901. //
  902. #define REG_OPTION_PREDEF_HANDLE (0x01000000L)
  903. #define REG_PREDEF_HANDLE_MASK (0x80000000L)
  904. typedef struct _CM_PARSE_CONTEXT {
  905. ULONG TitleIndex;
  906. UNICODE_STRING Class;
  907. ULONG CreateOptions;
  908. ULONG Disposition;
  909. BOOLEAN CreateLink;
  910. CM_KEY_REFERENCE ChildHive;
  911. HANDLE PredefinedHandle;
  912. } CM_PARSE_CONTEXT, *PCM_PARSE_CONTEXT;
  913. NTSTATUS
  914. CmpParseKey(
  915. IN PVOID ParseObject,
  916. IN PVOID ObjectType,
  917. IN OUT PACCESS_STATE AccessState,
  918. IN KPROCESSOR_MODE AccessMode,
  919. IN ULONG Attributes,
  920. IN OUT PUNICODE_STRING CompleteName,
  921. IN OUT PUNICODE_STRING RemainingName,
  922. IN OUT PVOID Context OPTIONAL,
  923. IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
  924. OUT PVOID *Object
  925. );
  926. NTSTATUS
  927. CmpDoCreate(
  928. IN PHHIVE Hive,
  929. IN HCELL_INDEX Cell,
  930. IN PACCESS_STATE AccessState,
  931. IN PUNICODE_STRING Name,
  932. IN KPROCESSOR_MODE AccessMode,
  933. IN PCM_PARSE_CONTEXT Context,
  934. IN PCM_KEY_CONTROL_BLOCK ParentKcb,
  935. OUT PVOID *Object
  936. );
  937. NTSTATUS
  938. CmpDoCreateChild(
  939. IN PHHIVE Hive,
  940. IN HCELL_INDEX ParentCell,
  941. IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
  942. IN PACCESS_STATE AccessState,
  943. IN PUNICODE_STRING Name,
  944. IN KPROCESSOR_MODE AccessMode,
  945. IN PCM_PARSE_CONTEXT Context,
  946. IN PCM_KEY_CONTROL_BLOCK ParentKcb,
  947. IN USHORT Flags,
  948. OUT PHCELL_INDEX KeyCell,
  949. OUT PVOID *Object
  950. );
  951. NTSTATUS
  952. CmpQueryKeyName(
  953. IN PVOID Object,
  954. IN BOOLEAN HasObjectName,
  955. OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
  956. IN ULONG Length,
  957. OUT PULONG ReturnLength
  958. );
  959. VOID
  960. CmpDeleteKeyObject(
  961. IN PVOID Object
  962. );
  963. VOID
  964. CmpCloseKeyObject(
  965. IN PEPROCESS Process OPTIONAL,
  966. IN PVOID Object,
  967. IN ACCESS_MASK GrantedAccess,
  968. IN ULONG ProcessHandleCount,
  969. IN ULONG SystemHandleCount
  970. );
  971. NTSTATUS
  972. CmpSecurityMethod (
  973. IN PVOID Object,
  974. IN SECURITY_OPERATION_CODE OperationCode,
  975. IN PSECURITY_INFORMATION SecurityInformation,
  976. IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
  977. IN OUT PULONG CapturedLength,
  978. IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
  979. IN POOL_TYPE PoolType,
  980. IN PGENERIC_MAPPING GenericMapping
  981. );
  982. #define KCB_WORKER_CONTINUE 0
  983. #define KCB_WORKER_DONE 1
  984. #define KCB_WORKER_DELETE 2
  985. #define KCB_WORKER_ERROR 3
  986. typedef
  987. ULONG
  988. (*PKCB_WORKER_ROUTINE) (
  989. PCM_KEY_CONTROL_BLOCK Current,
  990. PVOID Context1,
  991. PVOID Context2
  992. );
  993. BOOLEAN
  994. CmpSearchKeyControlBlockTree(
  995. PKCB_WORKER_ROUTINE WorkerRoutine,
  996. PVOID Context1,
  997. PVOID Context2
  998. );
  999. //
  1000. // Wrappers
  1001. //
  1002. PVOID
  1003. CmpAllocate(
  1004. ULONG Size,
  1005. BOOLEAN UseForIo,
  1006. ULONG Tag
  1007. );
  1008. VOID
  1009. CmpFree(
  1010. PVOID MemoryBlock,
  1011. ULONG GlobalQuotaSize
  1012. );
  1013. BOOLEAN
  1014. CmpFileSetSize(
  1015. PHHIVE Hive,
  1016. ULONG FileType,
  1017. ULONG FileSize,
  1018. ULONG OldFileSize
  1019. );
  1020. NTSTATUS
  1021. CmpDoFileSetSize(
  1022. PHHIVE Hive,
  1023. ULONG FileType,
  1024. ULONG FileSize,
  1025. ULONG OldFileSize
  1026. );
  1027. BOOLEAN
  1028. CmpFileWrite(
  1029. PHHIVE Hive,
  1030. ULONG FileType,
  1031. PCMP_OFFSET_ARRAY offsetArray,
  1032. ULONG offsetArrayCount,
  1033. PULONG FileOffset
  1034. );
  1035. BOOLEAN
  1036. CmpFileWriteThroughCache(
  1037. PHHIVE Hive,
  1038. ULONG FileType,
  1039. PCMP_OFFSET_ARRAY offsetArray,
  1040. ULONG offsetArrayCount
  1041. );
  1042. BOOLEAN
  1043. CmpFileRead (
  1044. PHHIVE Hive,
  1045. ULONG FileType,
  1046. PULONG FileOffset,
  1047. PVOID DataBuffer,
  1048. ULONG DataLength
  1049. );
  1050. BOOLEAN
  1051. CmpFileFlush (
  1052. PHHIVE Hive,
  1053. ULONG FileType,
  1054. PLARGE_INTEGER FileOffset,
  1055. ULONG Length
  1056. );
  1057. NTSTATUS
  1058. CmpCreateEvent(
  1059. IN EVENT_TYPE eventType,
  1060. OUT PHANDLE eventHandle,
  1061. OUT PKEVENT *event
  1062. );
  1063. //
  1064. // Configuration Manager CM level registry functions
  1065. //
  1066. NTSTATUS
  1067. CmDeleteKey(
  1068. IN PCM_KEY_BODY KeyBody
  1069. );
  1070. NTSTATUS
  1071. CmDeleteValueKey(
  1072. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1073. IN UNICODE_STRING ValueName
  1074. );
  1075. NTSTATUS
  1076. CmEnumerateKey(
  1077. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1078. IN ULONG Index,
  1079. IN KEY_INFORMATION_CLASS KeyInformationClass,
  1080. IN PVOID KeyInformation,
  1081. IN ULONG Length,
  1082. IN PULONG ResultLength
  1083. );
  1084. NTSTATUS
  1085. CmEnumerateValueKey(
  1086. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1087. IN ULONG Index,
  1088. IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
  1089. IN PVOID KeyValueInformation,
  1090. IN ULONG Length,
  1091. IN PULONG ResultLength
  1092. );
  1093. NTSTATUS
  1094. CmFlushKey(
  1095. IN PHHIVE Hive,
  1096. IN HCELL_INDEX Cell
  1097. );
  1098. NTSTATUS
  1099. CmQueryKey(
  1100. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1101. IN KEY_INFORMATION_CLASS KeyInformationClass,
  1102. IN PVOID KeyInformation,
  1103. IN ULONG Length,
  1104. IN PULONG ResultLength
  1105. );
  1106. NTSTATUS
  1107. CmQueryValueKey(
  1108. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1109. IN UNICODE_STRING ValueName,
  1110. IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
  1111. IN PVOID KeyValueInformation,
  1112. IN ULONG Length,
  1113. IN PULONG ResultLength
  1114. );
  1115. NTSTATUS
  1116. CmQueryMultipleValueKey(
  1117. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1118. IN PKEY_VALUE_ENTRY ValueEntries,
  1119. IN ULONG EntryCount,
  1120. IN PVOID ValueBuffer,
  1121. IN OUT PULONG BufferLength,
  1122. IN OPTIONAL PULONG ResultLength
  1123. );
  1124. NTSTATUS
  1125. CmRenameValueKey(
  1126. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1127. IN UNICODE_STRING SourceValueName,
  1128. IN UNICODE_STRING TargetValueName,
  1129. IN ULONG TargetIndex
  1130. );
  1131. NTSTATUS
  1132. CmReplaceKey(
  1133. IN PHHIVE Hive,
  1134. IN HCELL_INDEX Cell,
  1135. IN PUNICODE_STRING NewHiveName,
  1136. IN PUNICODE_STRING OldFileName
  1137. );
  1138. NTSTATUS
  1139. CmRestoreKey(
  1140. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1141. IN HANDLE FileHandle,
  1142. IN ULONG Flags
  1143. );
  1144. NTSTATUS
  1145. CmSaveKey(
  1146. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1147. IN HANDLE FileHandle,
  1148. IN ULONG HiveVersion
  1149. );
  1150. NTSTATUS
  1151. CmDumpKey(
  1152. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1153. IN HANDLE FileHandle
  1154. );
  1155. NTSTATUS
  1156. CmSaveMergedKeys(
  1157. IN PCM_KEY_CONTROL_BLOCK HighPrecedenceKcb,
  1158. IN PCM_KEY_CONTROL_BLOCK LowPrecedenceKcb,
  1159. IN HANDLE FileHandle
  1160. );
  1161. NTSTATUS
  1162. CmpShiftHiveFreeBins(
  1163. PCMHIVE CmHive,
  1164. PCMHIVE *NewHive
  1165. );
  1166. NTSTATUS
  1167. CmpOverwriteHive(
  1168. PCMHIVE CmHive,
  1169. PCMHIVE NewHive,
  1170. HCELL_INDEX LinkCell
  1171. );
  1172. VOID
  1173. CmpSwitchStorageAndRebuildMappings(PCMHIVE OldCmHive,
  1174. PCMHIVE NewHive
  1175. );
  1176. NTSTATUS
  1177. CmSetValueKey(
  1178. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1179. IN PUNICODE_STRING ValueName,
  1180. IN ULONG Type,
  1181. IN PVOID Data,
  1182. IN ULONG DataSize
  1183. );
  1184. NTSTATUS
  1185. CmSetLastWriteTimeKey(
  1186. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1187. IN PLARGE_INTEGER LastWriteTime
  1188. );
  1189. NTSTATUS
  1190. CmSetKeyUserFlags(
  1191. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1192. IN ULONG UserFlags
  1193. );
  1194. NTSTATUS
  1195. CmpNotifyChangeKey(
  1196. IN PCM_KEY_BODY KeyBody,
  1197. IN PCM_POST_BLOCK PostBlock,
  1198. IN ULONG CompletionFilter,
  1199. IN BOOLEAN WatchTree,
  1200. IN PVOID Buffer,
  1201. IN ULONG BufferSize,
  1202. IN PCM_POST_BLOCK MasterPostBlock
  1203. );
  1204. NTSTATUS
  1205. CmLoadKey(
  1206. IN POBJECT_ATTRIBUTES TargetKey,
  1207. IN POBJECT_ATTRIBUTES SourceFile,
  1208. IN ULONG Flags
  1209. );
  1210. NTSTATUS
  1211. CmUnloadKey(
  1212. IN PHHIVE Hive,
  1213. IN HCELL_INDEX Cell,
  1214. IN PCM_KEY_CONTROL_BLOCK Kcb
  1215. );
  1216. NTSTATUS
  1217. CmMoveKey(
  1218. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock
  1219. );
  1220. NTSTATUS
  1221. CmCompressKey(
  1222. IN PHHIVE Hive
  1223. );
  1224. //
  1225. // Procedures private to CM
  1226. //
  1227. BOOLEAN
  1228. CmpMarkKeyDirty(
  1229. PHHIVE Hive,
  1230. HCELL_INDEX Cell
  1231. #if DBG
  1232. ,
  1233. BOOLEAN CheckNoSubkeys
  1234. #endif
  1235. );
  1236. BOOLEAN
  1237. CmpDoFlushAll(
  1238. BOOLEAN ForceFlush
  1239. );
  1240. VOID
  1241. CmpFixHiveUsageCount(
  1242. IN PCMHIVE CmHive
  1243. );
  1244. VOID
  1245. CmpLazyFlush(
  1246. VOID
  1247. );
  1248. VOID
  1249. CmpQuotaWarningWorker(
  1250. IN PVOID WorkItem
  1251. );
  1252. VOID
  1253. CmpComputeGlobalQuotaAllowed(
  1254. VOID
  1255. );
  1256. BOOLEAN
  1257. CmpClaimGlobalQuota(
  1258. IN ULONG Size
  1259. );
  1260. VOID
  1261. CmpReleaseGlobalQuota(
  1262. IN ULONG Size
  1263. );
  1264. VOID
  1265. CmpSetGlobalQuotaAllowed(
  1266. VOID
  1267. );
  1268. VOID
  1269. CmpSystemQuotaWarningWorker(
  1270. IN PVOID WorkItem
  1271. );
  1272. BOOLEAN
  1273. CmpCanGrowSystemHive(
  1274. IN PHHIVE Hive,
  1275. IN ULONG NewLength
  1276. );
  1277. //
  1278. // security functions (cmse.c)
  1279. //
  1280. NTSTATUS
  1281. CmpAssignSecurityDescriptor(
  1282. IN PHHIVE Hive,
  1283. IN HCELL_INDEX Cell,
  1284. IN PCM_KEY_NODE Node,
  1285. IN PSECURITY_DESCRIPTOR SecurityDescriptor
  1286. );
  1287. BOOLEAN
  1288. CmpCheckCreateAccess(
  1289. IN PUNICODE_STRING RelativeName,
  1290. IN PSECURITY_DESCRIPTOR Descriptor,
  1291. IN PACCESS_STATE AccessState,
  1292. IN KPROCESSOR_MODE PreviousMode,
  1293. IN ACCESS_MASK AdditionalAccess,
  1294. OUT PNTSTATUS AccessStatus
  1295. );
  1296. BOOLEAN
  1297. CmpCheckNotifyAccess(
  1298. IN PCM_NOTIFY_BLOCK NotifyBlock,
  1299. IN PHHIVE Hive,
  1300. IN PCM_KEY_NODE Node
  1301. );
  1302. PSECURITY_DESCRIPTOR
  1303. CmpHiveRootSecurityDescriptor(
  1304. VOID
  1305. );
  1306. VOID
  1307. CmpFreeSecurityDescriptor(
  1308. IN PHHIVE Hive,
  1309. IN HCELL_INDEX Cell
  1310. );
  1311. //
  1312. // Access to the registry is serialized by a shared resource, CmpRegistryLock.
  1313. //
  1314. extern ERESOURCE CmpRegistryLock;
  1315. //
  1316. // Support for "StarveExclusive" mode suring a flush
  1317. //
  1318. extern ULONG CmpFlushStarveWriters;
  1319. #define ENTER_FLUSH_MODE() InterlockedIncrement (&CmpFlushStarveWriters);
  1320. #if DBG
  1321. #define EXIT_FLUSH_MODE() \
  1322. { \
  1323. LONG LocalIncrement = (LONG)InterlockedDecrement (&CmpFlushStarveWriters); \
  1324. ASSERT( LocalIncrement >= 0 ); \
  1325. }
  1326. #else
  1327. #define EXIT_FLUSH_MODE() InterlockedDecrement (&CmpFlushStarveWriters)
  1328. #endif
  1329. #if 0
  1330. #define CmpLockRegistry() KeEnterCriticalRegion(); \
  1331. ExAcquireResourceShared(&CmpRegistryLock, TRUE)
  1332. #define CmpLockRegistryExclusive() KeEnterCriticalRegion(); \
  1333. ExAcquireResourceExclusive(&CmpRegistryLock,TRUE)
  1334. #else
  1335. VOID
  1336. CmpLockRegistryExclusive(
  1337. VOID
  1338. );
  1339. VOID
  1340. CmpLockRegistry(
  1341. VOID
  1342. );
  1343. #endif
  1344. VOID
  1345. CmpUnlockRegistry(
  1346. );
  1347. #if DBG
  1348. BOOLEAN
  1349. CmpTestRegistryLock(
  1350. VOID
  1351. );
  1352. BOOLEAN
  1353. CmpTestRegistryLockExclusive(
  1354. VOID
  1355. );
  1356. #endif
  1357. NTSTATUS
  1358. CmpQueryKeyData(
  1359. PHHIVE Hive,
  1360. PCM_KEY_NODE Node,
  1361. KEY_INFORMATION_CLASS KeyInformationClass,
  1362. PVOID KeyInformation,
  1363. ULONG Length,
  1364. PULONG ResultLength
  1365. #if defined(CMP_STATS) || defined(CMP_KCB_CACHE_VALIDATION)
  1366. ,
  1367. PCM_KEY_CONTROL_BLOCK Kcb
  1368. #endif
  1369. );
  1370. NTSTATUS
  1371. CmpQueryKeyDataFromCache(
  1372. PCM_KEY_CONTROL_BLOCK Kcb,
  1373. KEY_INFORMATION_CLASS KeyInformationClass,
  1374. PVOID KeyInformation,
  1375. ULONG Length,
  1376. PULONG ResultLength
  1377. );
  1378. BOOLEAN
  1379. CmpFreeKeyBody(
  1380. PHHIVE Hive,
  1381. HCELL_INDEX Cell
  1382. );
  1383. BOOLEAN
  1384. CmpFreeValue(
  1385. PHHIVE Hive,
  1386. HCELL_INDEX Cell
  1387. );
  1388. HCELL_INDEX
  1389. CmpFindValueByName(
  1390. PHHIVE Hive,
  1391. PCM_KEY_NODE KeyNode,
  1392. PUNICODE_STRING Name
  1393. );
  1394. NTSTATUS
  1395. CmpDeleteChildByName(
  1396. PHHIVE Hive,
  1397. HCELL_INDEX Cell,
  1398. UNICODE_STRING Name,
  1399. PHCELL_INDEX ChildCell
  1400. );
  1401. NTSTATUS
  1402. CmpFreeKeyByCell(
  1403. PHHIVE Hive,
  1404. HCELL_INDEX Cell,
  1405. BOOLEAN Unlink
  1406. );
  1407. BOOLEAN
  1408. CmpFindNameInList(
  1409. IN PHHIVE Hive,
  1410. IN PCHILD_LIST ChildList,
  1411. IN PUNICODE_STRING Name,
  1412. IN OPTIONAL PULONG ChildIndex,
  1413. OUT PHCELL_INDEX CellIndex
  1414. );
  1415. HCELL_INDEX
  1416. CmpCopyCell(
  1417. PHHIVE SourceHive,
  1418. HCELL_INDEX SourceCell,
  1419. PHHIVE TargetHive,
  1420. HSTORAGE_TYPE Type
  1421. );
  1422. HCELL_INDEX
  1423. CmpCopyValue(
  1424. PHHIVE SourceHive,
  1425. HCELL_INDEX SourceValueCell,
  1426. PHHIVE TargetHive,
  1427. HSTORAGE_TYPE Type
  1428. );
  1429. HCELL_INDEX
  1430. CmpCopyKeyPartial(
  1431. PHHIVE SourceHive,
  1432. HCELL_INDEX SourceKeyCell,
  1433. PHHIVE TargetHive,
  1434. HCELL_INDEX Parent,
  1435. BOOLEAN CopyValues
  1436. );
  1437. BOOLEAN
  1438. CmpCopySyncTree(
  1439. PHHIVE SourceHive,
  1440. HCELL_INDEX SourceCell,
  1441. PHHIVE TargetHive,
  1442. HCELL_INDEX TargetCell,
  1443. BOOLEAN CopyVolatile,
  1444. CMP_COPY_TYPE CopyType
  1445. );
  1446. //
  1447. // BOOLEAN
  1448. // CmpCopyTree(
  1449. // PHHIVE SourceHive,
  1450. // HCELL_INDEX SourceCell,
  1451. // PHHIVE TargetHive,
  1452. // HCELL_INDEX TargetCell
  1453. // );
  1454. //
  1455. #define CmpCopyTree(s,c,t,l) CmpCopySyncTree(s,c,t,l,FALSE,Copy)
  1456. //
  1457. // BOOLEAN
  1458. // CmpCopyTreeEx(
  1459. // PHHIVE SourceHive,
  1460. // HCELL_INDEX SourceCell,
  1461. // PHHIVE TargetHive,
  1462. // HCELL_INDEX TargetCell,
  1463. // BOOLEAN CopyVolatile
  1464. // );
  1465. //
  1466. #define CmpCopyTreeEx(s,c,t,l,f) CmpCopySyncTree(s,c,t,l,f,Copy)
  1467. //
  1468. // BOOLEAN
  1469. // CmpSyncTrees(
  1470. // PHHIVE SourceHive,
  1471. // HCELL_INDEX SourceCell,
  1472. // PHHIVE TargetHive,
  1473. // HCELL_INDEX TargetCell,
  1474. // BOOLEAN CopyVolatile);
  1475. //
  1476. #define CmpSyncTrees(s,c,t,l,f) CmpCopySyncTree(s,c,t,l,f,Sync)
  1477. //
  1478. // BOOLEAN
  1479. // CmpMergeTrees(
  1480. // PHHIVE SourceHive,
  1481. // HCELL_INDEX SourceCell,
  1482. // PHHIVE TargetHive,
  1483. // HCELL_INDEX TargetCell);
  1484. //
  1485. #define CmpMergeTrees(s,c,t,l) CmpCopySyncTree(s,c,t,l,FALSE,Merge)
  1486. VOID
  1487. CmpDeleteTree(
  1488. PHHIVE Hive,
  1489. HCELL_INDEX Cell
  1490. );
  1491. VOID
  1492. CmpSetVersionData(
  1493. VOID
  1494. );
  1495. NTSTATUS
  1496. CmpInitializeHardwareConfiguration(
  1497. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  1498. );
  1499. NTSTATUS
  1500. CmpInitializeMachineDependentConfiguration(
  1501. IN PLOADER_PARAMETER_BLOCK LoaderBlock
  1502. );
  1503. NTSTATUS
  1504. CmpInitializeRegistryNode(
  1505. IN PCONFIGURATION_COMPONENT_DATA CurrentEntry,
  1506. IN HANDLE ParentHandle,
  1507. OUT PHANDLE NewHandle,
  1508. IN INTERFACE_TYPE InterfaceType,
  1509. IN ULONG BusNumber,
  1510. IN PUSHORT DeviceIndexTable
  1511. );
  1512. NTSTATUS
  1513. CmpInitializeHive(
  1514. PCMHIVE *CmHive,
  1515. ULONG OperationType,
  1516. ULONG HiveFlags,
  1517. ULONG FileType,
  1518. PVOID HiveData OPTIONAL,
  1519. HANDLE Primary,
  1520. HANDLE Log,
  1521. HANDLE External,
  1522. PUNICODE_STRING FileName OPTIONAL,
  1523. ULONG CheckFlags
  1524. );
  1525. BOOLEAN
  1526. CmpDestroyHive(
  1527. IN PHHIVE Hive,
  1528. IN HCELL_INDEX Cell
  1529. );
  1530. VOID
  1531. CmpInitializeRegistryNames(
  1532. VOID
  1533. );
  1534. VOID
  1535. CmpInitializeCache(
  1536. VOID
  1537. );
  1538. PCM_KEY_CONTROL_BLOCK
  1539. CmpCreateKeyControlBlock(
  1540. PHHIVE Hive,
  1541. HCELL_INDEX Cell,
  1542. PCM_KEY_NODE Node,
  1543. PCM_KEY_CONTROL_BLOCK ParentKcb,
  1544. BOOLEAN FakeKey,
  1545. PUNICODE_STRING KeyName
  1546. );
  1547. VOID CmpCleanUpKCBCacheTable();
  1548. ULONG
  1549. CmpSearchForOpenSubKeys(
  1550. IN PCM_KEY_CONTROL_BLOCK SearchKey,
  1551. IN SUBKEY_SEARCH_TYPE SearchType
  1552. );
  1553. VOID
  1554. CmpDereferenceKeyControlBlock(
  1555. PCM_KEY_CONTROL_BLOCK KeyControlBlock
  1556. );
  1557. VOID
  1558. CmpRemoveKeyControlBlock(
  1559. PCM_KEY_CONTROL_BLOCK KeyControlBlock
  1560. );
  1561. VOID
  1562. CmpReportNotify(
  1563. PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1564. PHHIVE Hive,
  1565. HCELL_INDEX Cell,
  1566. ULONG NotifyMask
  1567. );
  1568. VOID
  1569. CmpPostNotify(
  1570. PCM_NOTIFY_BLOCK NotifyBlock,
  1571. PUNICODE_STRING Name OPTIONAL,
  1572. ULONG Filter,
  1573. NTSTATUS Status,
  1574. PLIST_ENTRY ExternalKeyDeref OPTIONAL
  1575. #ifdef CM_NOTIFY_CHANGED_KCB_FULLPATH
  1576. ,
  1577. PUNICODE_STRING ChangedKcbName OPTIONAL
  1578. #endif //CM_NOTIFY_CHANGED_KCB_FULLPATH
  1579. );
  1580. PCM_POST_BLOCK
  1581. CmpAllocatePostBlock(
  1582. IN POST_BLOCK_TYPE BlockType,
  1583. IN ULONG PostFlags,
  1584. IN PCM_KEY_BODY KeyBody,
  1585. IN PCM_POST_BLOCK MasterBlock
  1586. );
  1587. //
  1588. //PCM_POST_BLOCK
  1589. //CmpAllocateMasterPostBlock(
  1590. // IN POST_BLOCK_TYPE BlockType
  1591. // );
  1592. //
  1593. #define CmpAllocateMasterPostBlock(b) CmpAllocatePostBlock(b,REG_NOTIFY_MASTER_POST,NULL,NULL)
  1594. //
  1595. //PCM_POST_BLOCK
  1596. //CmpAllocateSlavePostBlock(
  1597. // IN POST_BLOCK_TYPE BlockType,
  1598. // IN PCM_KEY_BODY KeyBody,
  1599. // IN PCM_POST_BLOCK MasterBlock
  1600. // );
  1601. //
  1602. #define CmpAllocateSlavePostBlock(b,k,m) CmpAllocatePostBlock(b,0,k,m)
  1603. VOID
  1604. CmpFreePostBlock(
  1605. IN PCM_POST_BLOCK PostBlock
  1606. );
  1607. VOID
  1608. CmpPostApc(
  1609. struct _KAPC *Apc,
  1610. PKNORMAL_ROUTINE *NormalRoutine,
  1611. PVOID *NormalContext,
  1612. PVOID *SystemArgument1,
  1613. PVOID *SystemArgument2
  1614. );
  1615. VOID
  1616. CmpFlushNotify(
  1617. PCM_KEY_BODY KeyBody
  1618. );
  1619. VOID
  1620. CmpPostApcRunDown(
  1621. struct _KAPC *Apc
  1622. );
  1623. NTSTATUS
  1624. CmpOpenHiveFiles(
  1625. PUNICODE_STRING BaseName,
  1626. PWSTR Extension OPTIONAL,
  1627. PHANDLE Primary,
  1628. PHANDLE Secondary,
  1629. PULONG PrimaryDisposition,
  1630. PULONG SecondaryDispoition,
  1631. BOOLEAN CreateAllowed,
  1632. BOOLEAN MarkAsSystemHive,
  1633. BOOLEAN NoBuffering,
  1634. PULONG ClusterSize
  1635. );
  1636. NTSTATUS
  1637. CmpLinkHiveToMaster(
  1638. PUNICODE_STRING LinkName,
  1639. HANDLE RootDirectory,
  1640. PCMHIVE CmHive,
  1641. BOOLEAN Allocate,
  1642. PSECURITY_DESCRIPTOR SecurityDescriptor
  1643. );
  1644. NTSTATUS
  1645. CmpSaveBootControlSet(
  1646. IN USHORT ControlSetNum
  1647. );
  1648. //
  1649. // checkout procedure
  1650. //
  1651. //
  1652. // Flags to be passed to CmCheckRegistry
  1653. //
  1654. #define CM_CHECK_REGISTRY_CHECK_CLEAN 0x00000001
  1655. #define CM_CHECK_REGISTRY_FORCE_CLEAN 0x00000002
  1656. #define CM_CHECK_REGISTRY_LOADER_CLEAN 0x00000004
  1657. #define CM_CHECK_REGISTRY_SYSTEM_CLEAN 0x00000008
  1658. #define CM_CHECK_REGISTRY_HIVE_CHECK 0x00010000
  1659. ULONG
  1660. CmCheckRegistry(
  1661. PCMHIVE CmHive,
  1662. ULONG Flags
  1663. );
  1664. BOOLEAN
  1665. CmpValidateHiveSecurityDescriptors(
  1666. IN PHHIVE Hive,
  1667. OUT PBOOLEAN ResetSD
  1668. );
  1669. //
  1670. // cmboot - functions for determining driver load lists
  1671. //
  1672. #define CM_HARDWARE_PROFILE_STR_DATABASE L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\IDConfigDB"
  1673. #define CM_HARDWARE_PROFILE_STR_CCS_HWPROFILE L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles"
  1674. #define CM_HARDWARE_PROFILE_STR_CCS_CURRENT L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current"
  1675. //
  1676. // Alias table key names in IDConfigDB
  1677. //
  1678. #define CM_HARDWARE_PROFILE_STR_ALIAS L"Alias"
  1679. #define CM_HARDWARE_PROFILE_STR_ACPI_ALIAS L"AcpiAlias"
  1680. #define CM_HARDWARE_PROFILE_STR_HARDWARE_PROFILES L"Hardware Profiles"
  1681. //
  1682. // Entries in the alias tables (value names)
  1683. //
  1684. #define CM_HARDWARE_PROFILE_STR_DOCKING_STATE L"DockingState"
  1685. #define CM_HARDWARE_PROFILE_STR_CAPABILITIES L"Capabilities"
  1686. #define CM_HARDWARE_PROFILE_STR_DOCKID L"DockID"
  1687. #define CM_HARDWARE_PROFILE_STR_SERIAL_NUMBER L"SerialNumber"
  1688. #define CM_HARDWARE_PROFILE_STR_ACPI_SERIAL_NUMBER L"AcpiSerialNumber"
  1689. #define CM_HARDWARE_PROFILE_STR_PROFILE_NUMBER L"ProfileNumber"
  1690. #define CM_HARDWARE_PROFILE_STR_ALIASABLE L"Aliasable"
  1691. #define CM_HARDWARE_PROFILE_STR_CLONED L"Cloned"
  1692. //
  1693. // Entries in the profile tables.
  1694. //
  1695. #define CM_HARDWARE_PROFILE_STR_PRISTINE L"Pristine"
  1696. #define CM_HARDWARE_PROFILE_STR_PREFERENCE_ORDER L"PreferenceOrder"
  1697. #define CM_HARDWARE_PROFILE_STR_FRIENDLY_NAME L"FriendlyName"
  1698. #define CM_HARDWARE_PROFILE_STR_CURRENT_DOCK_INFO L"CurrentDockInfo"
  1699. #define CM_HARDWARE_PROFILE_STR_HW_PROFILE_GUID L"HwProfileGuid"
  1700. //
  1701. // Entries for the root Hardware Profiles key.
  1702. //
  1703. #define CM_HARDWARE_PROFILE_STR_DOCKED L"Docked"
  1704. #define CM_HARDWARE_PROFILE_STR_UNDOCKED L"Undocked"
  1705. #define CM_HARDWARE_PROFILE_STR_UNKNOWN L"Unknown"
  1706. //
  1707. // List structure used in config manager init
  1708. //
  1709. typedef struct _HIVE_LIST_ENTRY {
  1710. PWSTR Name;
  1711. PWSTR BaseName; // MACHINE or USER
  1712. PCMHIVE CmHive;
  1713. ULONG Flags;
  1714. PCMHIVE CmHive2;
  1715. BOOLEAN ThreadFinished;
  1716. BOOLEAN ThreadStarted;
  1717. BOOLEAN Allocate;
  1718. } HIVE_LIST_ENTRY, *PHIVE_LIST_ENTRY;
  1719. //
  1720. // structure definitions shared with the boot loader
  1721. // to select the hardware profile.
  1722. //
  1723. typedef struct _CM_HARDWARE_PROFILE {
  1724. ULONG NameLength;
  1725. PWSTR FriendlyName;
  1726. ULONG PreferenceOrder;
  1727. ULONG Id;
  1728. ULONG Flags;
  1729. } CM_HARDWARE_PROFILE, *PCM_HARDWARE_PROFILE;
  1730. #define CM_HP_FLAGS_ALIASABLE 1
  1731. #define CM_HP_FLAGS_TRUE_MATCH 2
  1732. #define CM_HP_FLAGS_PRISTINE 4
  1733. #define CM_HP_FLAGS_DUPLICATE 8
  1734. typedef struct _CM_HARDWARE_PROFILE_LIST {
  1735. ULONG MaxProfileCount;
  1736. ULONG CurrentProfileCount;
  1737. CM_HARDWARE_PROFILE Profile[1];
  1738. } CM_HARDWARE_PROFILE_LIST, *PCM_HARDWARE_PROFILE_LIST;
  1739. typedef struct _CM_HARDWARE_PROFILE_ALIAS {
  1740. ULONG ProfileNumber;
  1741. ULONG DockState;
  1742. ULONG DockID;
  1743. ULONG SerialNumber;
  1744. } CM_HARDWARE_PROFILE_ALIAS, *PCM_HARDWARE_PROFILE_ALIAS;
  1745. typedef struct _CM_HARDWARE_PROFILE_ALIAS_LIST {
  1746. ULONG MaxAliasCount;
  1747. ULONG CurrentAliasCount;
  1748. CM_HARDWARE_PROFILE_ALIAS Alias[1];
  1749. } CM_HARDWARE_PROFILE_ALIAS_LIST, *PCM_HARDWARE_PROFILE_ALIAS_LIST;
  1750. typedef struct _CM_HARDWARE_PROFILE_ACPI_ALIAS {
  1751. ULONG ProfileNumber;
  1752. ULONG DockState;
  1753. ULONG SerialLength;
  1754. PCHAR SerialNumber;
  1755. } CM_HARDWARE_PROFILE_ACPI_ALIAS, *PCM_HARDWARE_PROFILE_ACPI_ALIAS;
  1756. typedef struct _CM_HARDWARE_PROFILE_ACPI_ALIAS_LIST {
  1757. ULONG MaxAliasCount;
  1758. ULONG CurrentAliasCount;
  1759. CM_HARDWARE_PROFILE_ACPI_ALIAS Alias[1];
  1760. } CM_HARDWARE_PROFILE_ACPI_ALIAS_LIST, *PCM_HARDWARE_PROFILE_ACPI_ALIAS_LIST;
  1761. HCELL_INDEX
  1762. CmpFindControlSet(
  1763. IN PHHIVE SystemHive,
  1764. IN HCELL_INDEX RootCell,
  1765. IN PUNICODE_STRING SelectName,
  1766. OUT PBOOLEAN AutoSelect
  1767. );
  1768. BOOLEAN
  1769. CmpValidateSelect(
  1770. IN PHHIVE SystemHive,
  1771. IN HCELL_INDEX RootCell
  1772. );
  1773. BOOLEAN
  1774. CmpFindDrivers(
  1775. IN PHHIVE Hive,
  1776. IN HCELL_INDEX ControlSet,
  1777. IN SERVICE_LOAD_TYPE LoadType,
  1778. IN PWSTR BootFileSystem OPTIONAL,
  1779. IN PLIST_ENTRY DriverListHead
  1780. );
  1781. BOOLEAN
  1782. CmpFindNLSData(
  1783. IN PHHIVE Hive,
  1784. IN HCELL_INDEX ControlSet,
  1785. OUT PUNICODE_STRING AnsiFilename,
  1786. OUT PUNICODE_STRING OemFilename,
  1787. OUT PUNICODE_STRING CaseTableFilename,
  1788. OUT PUNICODE_STRING OemHalFilename
  1789. );
  1790. HCELL_INDEX
  1791. CmpFindProfileOption(
  1792. IN PHHIVE Hive,
  1793. IN HCELL_INDEX ControlSet,
  1794. OUT PCM_HARDWARE_PROFILE_LIST *ProfileList,
  1795. OUT PCM_HARDWARE_PROFILE_ALIAS_LIST *AliasList,
  1796. OUT PULONG Timeout
  1797. );
  1798. VOID
  1799. CmpSetCurrentProfile(
  1800. IN PHHIVE Hive,
  1801. IN HCELL_INDEX ControlSet,
  1802. IN PCM_HARDWARE_PROFILE Profile
  1803. );
  1804. BOOLEAN
  1805. CmpResolveDriverDependencies(
  1806. IN PLIST_ENTRY DriverListHead
  1807. );
  1808. BOOLEAN
  1809. CmpSortDriverList(
  1810. IN PHHIVE Hive,
  1811. IN HCELL_INDEX ControlSet,
  1812. IN PLIST_ENTRY DriverListHead
  1813. );
  1814. HCELL_INDEX
  1815. CmpFindSubKeyByName(
  1816. PHHIVE Hive,
  1817. PCM_KEY_NODE Parent,
  1818. PUNICODE_STRING SearchName
  1819. );
  1820. HCELL_INDEX
  1821. CmpFindSubKeyByNumber(
  1822. PHHIVE Hive,
  1823. PCM_KEY_NODE Parent,
  1824. ULONG Number
  1825. );
  1826. BOOLEAN
  1827. CmpAddSubKey(
  1828. PHHIVE Hive,
  1829. HCELL_INDEX Parent,
  1830. HCELL_INDEX Child
  1831. );
  1832. BOOLEAN
  1833. CmpMarkIndexDirty(
  1834. PHHIVE Hive,
  1835. HCELL_INDEX ParentKey,
  1836. HCELL_INDEX TargetKey
  1837. );
  1838. BOOLEAN
  1839. CmpRemoveSubKey(
  1840. PHHIVE Hive,
  1841. HCELL_INDEX ParentKey,
  1842. HCELL_INDEX TargetKey
  1843. );
  1844. BOOLEAN
  1845. CmpGetNextName(
  1846. IN OUT PUNICODE_STRING RemainingName,
  1847. OUT PUNICODE_STRING NextName,
  1848. OUT PBOOLEAN Last
  1849. );
  1850. NTSTATUS
  1851. CmpAddToHiveFileList(
  1852. PCMHIVE CmHive
  1853. );
  1854. VOID
  1855. CmpRemoveFromHiveFileList(
  1856. );
  1857. NTSTATUS
  1858. CmpInitHiveFromFile(
  1859. IN PUNICODE_STRING FileName,
  1860. IN ULONG HiveFlags,
  1861. OUT PCMHIVE *CmHive,
  1862. IN OUT PBOOLEAN Allocate,
  1863. IN OUT PBOOLEAN RegistryLocked,
  1864. IN ULONG CheckFlags
  1865. );
  1866. NTSTATUS
  1867. CmpCloneHwProfile (
  1868. IN HANDLE IDConfigDB,
  1869. IN HANDLE Parent,
  1870. IN HANDLE OldProfile,
  1871. IN ULONG OldProfileNumber,
  1872. IN USHORT DockingState,
  1873. OUT PHANDLE NewProfile,
  1874. OUT PULONG NewProfileNumber
  1875. );
  1876. NTSTATUS
  1877. CmpCreateHwProfileFriendlyName (
  1878. IN HANDLE IDConfigDB,
  1879. IN ULONG DockingState,
  1880. IN ULONG NewProfileNumber,
  1881. OUT PUNICODE_STRING FriendlyName
  1882. );
  1883. typedef
  1884. NTSTATUS
  1885. (*PCM_ACPI_SELECTION_ROUTINE) (
  1886. IN PCM_HARDWARE_PROFILE_LIST ProfileList,
  1887. OUT PULONG ProfileIndexToUse, // Set to -1 for none.
  1888. IN PVOID Context
  1889. );
  1890. NTSTATUS
  1891. CmSetAcpiHwProfile (
  1892. IN PPROFILE_ACPI_DOCKING_STATE DockState,
  1893. IN PCM_ACPI_SELECTION_ROUTINE,
  1894. IN PVOID Context,
  1895. OUT PHANDLE NewProfile,
  1896. OUT PBOOLEAN ProfileChanged
  1897. );
  1898. NTSTATUS
  1899. CmpAddAcpiAliasEntry (
  1900. IN HANDLE IDConfigDB,
  1901. IN PPROFILE_ACPI_DOCKING_STATE NewDockState,
  1902. IN ULONG ProfileNumber,
  1903. IN PWCHAR nameBuffer,
  1904. IN PVOID valueBuffer,
  1905. IN ULONG valueBufferLength,
  1906. IN BOOLEAN PreventDuplication
  1907. );
  1908. //
  1909. // Routines for handling registry compressed names
  1910. //
  1911. USHORT
  1912. CmpNameSize(
  1913. IN PHHIVE Hive,
  1914. IN PUNICODE_STRING Name
  1915. );
  1916. USHORT
  1917. CmpCopyName(
  1918. IN PHHIVE Hive,
  1919. IN PWCHAR Destination,
  1920. IN PUNICODE_STRING Source
  1921. );
  1922. VOID
  1923. CmpCopyCompressedName(
  1924. IN PWCHAR Destination,
  1925. IN ULONG DestinationLength,
  1926. IN PWCHAR Source,
  1927. IN ULONG SourceLength
  1928. );
  1929. USHORT
  1930. CmpCompressedNameSize(
  1931. IN PWCHAR Name,
  1932. IN ULONG Length
  1933. );
  1934. //
  1935. // ----- CACHED_DATA -----
  1936. //
  1937. // When values are not cached, List in ValueCache is the Hive cell index to the value list.
  1938. // When they are cached, List will be pointer to the allocation. We distinguish them by
  1939. // marking the lowest bit in the variable to indicate it is a cached allocation.
  1940. //
  1941. // Note that the cell index for value list
  1942. // is stored in the cached allocation. It is not used now but may be in further performance
  1943. // optimization.
  1944. //
  1945. // When value key and vaule data are cached, there is only one allocation for both.
  1946. // Value data is appended that the end of value key. DataCacheType indicates
  1947. // whether data is cached and ValueKeySize tells how big is the value key (so
  1948. // we can calculate the address of cached value data)
  1949. //
  1950. //
  1951. PCM_NAME_CONTROL_BLOCK
  1952. CmpGetNameControlBlock(
  1953. PUNICODE_STRING NodeName
  1954. );
  1955. VOID
  1956. CmpDereferenceKeyControlBlockWithLock(
  1957. PCM_KEY_CONTROL_BLOCK KeyControlBlock
  1958. );
  1959. VOID
  1960. CmpCleanUpSubKeyInfo(
  1961. PCM_KEY_CONTROL_BLOCK KeyControlBlock
  1962. );
  1963. VOID
  1964. CmpCleanUpKcbValueCache(
  1965. PCM_KEY_CONTROL_BLOCK KeyControlBlock
  1966. );
  1967. VOID
  1968. CmpRebuildKcbCache(
  1969. PCM_KEY_CONTROL_BLOCK KeyControlBlock
  1970. );
  1971. /*
  1972. VOID
  1973. CmpSetUpKcbValueCache(
  1974. PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  1975. ULONG Count,
  1976. ULONG_PTR ValueList
  1977. )
  1978. */
  1979. #define CmpSetUpKcbValueCache(KeyControlBlock,_Count,_List) \
  1980. ASSERT( !(CMP_IS_CELL_CACHED(KeyControlBlock->ValueCache.ValueList)) ); \
  1981. ASSERT( !(KeyControlBlock->ExtFlags & CM_KCB_SYM_LINK_FOUND) ); \
  1982. KeyControlBlock->ValueCache.Count = (ULONG)(_Count); \
  1983. KeyControlBlock->ValueCache.ValueList = (ULONG_PTR)(_List)
  1984. VOID
  1985. CmpCleanUpKcbCacheWithLock(
  1986. PCM_KEY_CONTROL_BLOCK KeyControlBlock
  1987. );
  1988. VOID
  1989. CmpRemoveFromDelayedClose(
  1990. IN PCM_KEY_CONTROL_BLOCK kcb
  1991. );
  1992. PUNICODE_STRING
  1993. CmpConstructName(
  1994. PCM_KEY_CONTROL_BLOCK kcb
  1995. );
  1996. PCELL_DATA
  1997. CmpGetValueListFromCache(
  1998. IN PHHIVE Hive,
  1999. IN PCACHED_CHILD_LIST ChildList,
  2000. IN OUT BOOLEAN *IndexCached
  2001. );
  2002. PCM_KEY_VALUE
  2003. CmpGetValueKeyFromCache(
  2004. IN PHHIVE Hive,
  2005. IN PCELL_DATA List,
  2006. IN ULONG Index,
  2007. OUT PPCM_CACHED_VALUE *ContainingList,
  2008. IN BOOLEAN IndexCached,
  2009. OUT BOOLEAN *ValueCached,
  2010. OUT PHCELL_INDEX CellToRelease
  2011. );
  2012. PCM_KEY_VALUE
  2013. CmpFindValueByNameFromCache(
  2014. IN PHHIVE Hive,
  2015. IN PCACHED_CHILD_LIST ChildList,
  2016. IN PUNICODE_STRING Name,
  2017. OUT PPCM_CACHED_VALUE *ContainingList,
  2018. OUT ULONG *Index,
  2019. OUT BOOLEAN *ValueCached,
  2020. OUT PHCELL_INDEX CellToRelease
  2021. );
  2022. NTSTATUS
  2023. CmpQueryKeyValueData(
  2024. PHHIVE Hive,
  2025. PCM_CACHED_VALUE *ContainingList,
  2026. PCM_KEY_VALUE ValueKey,
  2027. BOOLEAN ValueCached,
  2028. KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
  2029. PVOID KeyValueInformation,
  2030. ULONG Length,
  2031. PULONG ResultLength
  2032. );
  2033. BOOLEAN
  2034. CmpReferenceKeyControlBlock(
  2035. PCM_KEY_CONTROL_BLOCK KeyControlBlock
  2036. );
  2037. VOID
  2038. CmpInitializeKeyNameString(PCM_KEY_NODE Cell,
  2039. PUNICODE_STRING KeyName,
  2040. WCHAR *NameBuffer
  2041. );
  2042. VOID
  2043. CmpInitializeValueNameString(PCM_KEY_VALUE Cell,
  2044. PUNICODE_STRING ValueName,
  2045. WCHAR *NameBuffer
  2046. );
  2047. VOID
  2048. CmpFlushNotifiesOnKeyBodyList(
  2049. IN PCM_KEY_CONTROL_BLOCK kcb
  2050. );
  2051. #ifdef CM_NOTIFY_CHANGED_KCB_FULLPATH
  2052. VOID
  2053. CmpFillCallerBuffer(
  2054. PCM_POST_BLOCK PostBlock,
  2055. PUNICODE_STRING ChangedKcbName
  2056. );
  2057. #endif //CM_NOTIFY_CHANGED_KCB_FULLPATH
  2058. extern ULONG CmpHashTableSize;
  2059. extern PCM_KEY_HASH *CmpCacheTable;
  2060. #ifdef _WANT_MACHINE_IDENTIFICATION
  2061. BOOLEAN
  2062. CmpGetBiosDateFromRegistry(
  2063. IN PHHIVE Hive,
  2064. IN HCELL_INDEX ControlSet,
  2065. OUT PUNICODE_STRING Date
  2066. );
  2067. BOOLEAN
  2068. CmpGetBiosinfoFileNameFromRegistry(
  2069. IN PHHIVE Hive,
  2070. IN HCELL_INDEX ControlSet,
  2071. OUT PUNICODE_STRING InfName
  2072. );
  2073. #endif
  2074. // Utility macro to set the fields of an IO_STATUS_BLOCK. On sundown, 32bit processes
  2075. // will pass in a 32bit Iosb, and 64bit processes will pass in a 64bit Iosb.
  2076. #if defined(_WIN64)
  2077. #define CmpSetIoStatus(Iosb, s, i, UseIosb32) \
  2078. if ((UseIosb32)) { \
  2079. ((PIO_STATUS_BLOCK32)(Iosb))->Status = (NTSTATUS)(s); \
  2080. ((PIO_STATUS_BLOCK32)(Iosb))->Information = (ULONG)(i); \
  2081. } \
  2082. else { \
  2083. (Iosb)->Status = (s); \
  2084. (Iosb)->Information = (i); \
  2085. } \
  2086. #else
  2087. #define CmpSetIoStatus(Iosb, s, i, UseIosb32) \
  2088. (Iosb)->Status = (s); \
  2089. (Iosb)->Information = (i); \
  2090. #endif
  2091. // Dragos: new functions (prototyping)
  2092. NTSTATUS
  2093. CmpAquireFileObjectForFile(
  2094. IN PCMHIVE CmHive,
  2095. IN HANDLE FileHandle,
  2096. OUT PFILE_OBJECT *FileObject
  2097. );
  2098. VOID
  2099. CmpDropFileObjectForHive(
  2100. IN PCMHIVE CmHive
  2101. );
  2102. VOID
  2103. CmpTouchView(
  2104. IN PCMHIVE CmHive,
  2105. IN PCM_VIEW_OF_FILE CmView,
  2106. IN ULONG Cell
  2107. );
  2108. NTSTATUS
  2109. CmpMapCmView(
  2110. IN PCMHIVE CmHive,
  2111. IN ULONG FileOffset,
  2112. OUT PCM_VIEW_OF_FILE *CmView,
  2113. IN BOOLEAN MapInited
  2114. );
  2115. VOID
  2116. CmpInitHiveViewList (
  2117. IN PCMHIVE CmHive
  2118. );
  2119. VOID
  2120. CmpDestroyHiveViewList (
  2121. IN PCMHIVE CmHive
  2122. );
  2123. NTSTATUS
  2124. CmpPinCmView (
  2125. IN PCMHIVE CmHive,
  2126. PCM_VIEW_OF_FILE CmView
  2127. );
  2128. VOID
  2129. CmpUnPinCmView (
  2130. IN PCMHIVE CmHive,
  2131. IN PCM_VIEW_OF_FILE CmView,
  2132. IN BOOLEAN SetClean,
  2133. IN BOOLEAN MapIsValid
  2134. );
  2135. NTSTATUS
  2136. CmpMapThisBin(
  2137. PCMHIVE CmHive,
  2138. HCELL_INDEX Cell,
  2139. BOOLEAN Touch
  2140. );
  2141. #if 0
  2142. VOID
  2143. CmpUnmapAditionalViews(
  2144. IN PCMHIVE CmHive
  2145. );
  2146. VOID
  2147. CmpUnmapFakeViews(
  2148. IN PCMHIVE CmHive
  2149. );
  2150. VOID
  2151. CmpMapEntireFileInFakeViews(
  2152. IN PCMHIVE CmHive,
  2153. IN ULONG Length
  2154. );
  2155. #endif
  2156. VOID
  2157. CmpInitializeDelayedCloseTable();
  2158. VOID
  2159. CmpAddToDelayedClose(
  2160. IN PCM_KEY_CONTROL_BLOCK kcb
  2161. );
  2162. NTSTATUS
  2163. CmpAddValueToList(
  2164. IN PHHIVE Hive,
  2165. IN HCELL_INDEX ValueCell,
  2166. IN ULONG Index,
  2167. IN ULONG Type,
  2168. IN OUT PCHILD_LIST ChildList
  2169. );
  2170. NTSTATUS
  2171. CmpRemoveValueFromList(
  2172. IN PHHIVE Hive,
  2173. IN ULONG Index,
  2174. IN OUT PCHILD_LIST ChildList
  2175. );
  2176. BOOLEAN
  2177. CmpGetValueData(IN PHHIVE Hive,
  2178. IN PCM_KEY_VALUE Value,
  2179. OUT PULONG realsize,
  2180. IN OUT PVOID *Buffer,
  2181. OUT PBOOLEAN Allocated,
  2182. OUT PHCELL_INDEX CellToRelease
  2183. );
  2184. PCELL_DATA
  2185. CmpValueToData(IN PHHIVE Hive,
  2186. IN PCM_KEY_VALUE Value,
  2187. OUT PULONG realsize
  2188. );
  2189. BOOLEAN
  2190. CmpMarkValueDataDirty( IN PHHIVE Hive,
  2191. IN PCM_KEY_VALUE Value
  2192. );
  2193. NTSTATUS
  2194. CmpSetValueDataNew(
  2195. IN PHHIVE Hive,
  2196. IN PVOID Data,
  2197. IN ULONG DataSize,
  2198. IN ULONG StorageType,
  2199. IN HCELL_INDEX ValueCell,
  2200. OUT PHCELL_INDEX DataCell
  2201. );
  2202. NTSTATUS
  2203. CmpSetValueDataExisting(
  2204. IN PHHIVE Hive,
  2205. IN PVOID Data,
  2206. IN ULONG DataSize,
  2207. IN ULONG StorageType,
  2208. IN HCELL_INDEX OldDataCell
  2209. );
  2210. BOOLEAN
  2211. CmpFreeValueData(
  2212. PHHIVE Hive,
  2213. HCELL_INDEX DataCell,
  2214. ULONG DataLength
  2215. );
  2216. NTSTATUS
  2217. CmpAddSecurityCellToCache (
  2218. IN OUT PCMHIVE CmHive,
  2219. IN HCELL_INDEX SecurityCell,
  2220. IN BOOLEAN BuildUp
  2221. );
  2222. BOOLEAN
  2223. CmpFindSecurityCellCacheIndex (
  2224. IN PCMHIVE CmHive,
  2225. IN HCELL_INDEX SecurityCell,
  2226. OUT PULONG Index
  2227. );
  2228. BOOLEAN
  2229. CmpAdjustSecurityCacheSize (
  2230. IN PCMHIVE CmHive
  2231. );
  2232. VOID
  2233. CmpRemoveFromSecurityCache (
  2234. IN OUT PCMHIVE CmHive,
  2235. IN HCELL_INDEX SecurityCell
  2236. );
  2237. VOID
  2238. CmpDestroySecurityCache (
  2239. IN OUT PCMHIVE CmHive
  2240. );
  2241. VOID
  2242. CmpInitSecurityCache(
  2243. IN OUT PCMHIVE CmHive
  2244. );
  2245. BOOLEAN
  2246. CmpRebuildSecurityCache(
  2247. IN OUT PCMHIVE CmHive
  2248. );
  2249. ULONG
  2250. CmpSecConvKey(
  2251. IN ULONG DescriptorLength,
  2252. IN PULONG Descriptor
  2253. );
  2254. VOID
  2255. CmpAssignSecurityToKcb(
  2256. IN PCM_KEY_CONTROL_BLOCK Kcb,
  2257. IN HCELL_INDEX SecurityCell
  2258. );
  2259. BOOLEAN
  2260. CmpBuildSecurityCellMappingArray(
  2261. IN PCMHIVE CmHive
  2262. );
  2263. //
  2264. // new function replacing CmpWorker
  2265. //
  2266. VOID
  2267. CmpCmdHiveClose(
  2268. PCMHIVE CmHive
  2269. );
  2270. VOID
  2271. CmpCmdInit(
  2272. BOOLEAN SetupBoot
  2273. );
  2274. NTSTATUS
  2275. CmpCmdRenameHive(
  2276. PCMHIVE CmHive,
  2277. POBJECT_NAME_INFORMATION OldName,
  2278. PUNICODE_STRING NewName,
  2279. ULONG NameInfoLength
  2280. );
  2281. NTSTATUS
  2282. CmpCmdHiveOpen(
  2283. POBJECT_ATTRIBUTES FileAttributes,
  2284. PSECURITY_CLIENT_CONTEXT ImpersonationContext,
  2285. PBOOLEAN Allocate,
  2286. PBOOLEAN RegistryLockAquired,
  2287. PCMHIVE *NewHive,
  2288. ULONG CheckFlags
  2289. );
  2290. #ifdef NT_RENAME_KEY
  2291. HCELL_INDEX
  2292. CmpDuplicateIndex(
  2293. PHHIVE Hive,
  2294. HCELL_INDEX IndexCell,
  2295. ULONG StorageType
  2296. );
  2297. NTSTATUS
  2298. CmRenameKey(
  2299. IN PCM_KEY_CONTROL_BLOCK KeyControlBlock,
  2300. IN UNICODE_STRING NewKeyName
  2301. );
  2302. BOOLEAN
  2303. CmpUpdateParentForEachSon(
  2304. PHHIVE Hive,
  2305. HCELL_INDEX Parent
  2306. );
  2307. #endif //NT_RENAME_KEY
  2308. #ifdef NT_UNLOAD_KEY_EX
  2309. NTSTATUS
  2310. CmUnloadKeyEx(
  2311. IN PCM_KEY_CONTROL_BLOCK Kcb,
  2312. IN PKEVENT UserEvent
  2313. );
  2314. #endif //NT_UNLOAD_KEY_EX
  2315. VOID
  2316. CmpShutdownWorkers(
  2317. VOID
  2318. );
  2319. VOID
  2320. CmpPrefetchHiveFile(
  2321. IN PFILE_OBJECT FileObject,
  2322. IN ULONG Length
  2323. );
  2324. #ifdef CM_CHECK_FOR_ORPHANED_KCBS
  2325. VOID
  2326. CmpCheckForOrphanedKcbs(
  2327. PHHIVE Hive
  2328. );
  2329. #else
  2330. #define CmpCheckForOrphanedKcbs(Hive) //nothing
  2331. #endif //CM_CHECK_FOR_ORPHANED_KCBS
  2332. #define CM_HIVE_COMPRESS_LEVEL (25)
  2333. #define CMP_MAX_REGISTRY_DEPTH 512 // levels
  2334. typedef struct {
  2335. HCELL_INDEX Cell;
  2336. HCELL_INDEX ParentCell;
  2337. ULONG ChildIndex;
  2338. BOOLEAN CellChecked;
  2339. } CMP_CHECK_REGISTRY_STACK_ENTRY, *PCMP_CHECK_REGISTRY_STACK_ENTRY;
  2340. #define CmIsKcbReadOnly(kcb) ((kcb)->ExtFlags & CM_KCB_READ_ONLY_KEY)
  2341. NTSTATUS
  2342. CmLockKcbForWrite(PCM_KEY_CONTROL_BLOCK KeyControlBlock);
  2343. //
  2344. // Wrapper to RtlCompareUnicodeString; uses CompareFlags to avoid upcasing names
  2345. //
  2346. #define CMP_SOURCE_UP 0x00000001
  2347. #define CMP_DEST_UP 0x00000002
  2348. LONG
  2349. CmpCompareUnicodeString(
  2350. IN PUNICODE_STRING SourceName,
  2351. IN PUNICODE_STRING DestName,
  2352. IN ULONG CompareFlags
  2353. );
  2354. LONG
  2355. CmpCompareCompressedName(
  2356. IN PUNICODE_STRING SearchName,
  2357. IN PWCHAR CompressedName,
  2358. IN ULONG NameLength,
  2359. IN ULONG CompareFlags
  2360. );
  2361. #define INIT_SYSTEMROOT_HIVEPATH L"\\SystemRoot\\System32\\Config\\"
  2362. ULONG
  2363. CmpComputeHashKey(
  2364. PUNICODE_STRING Name
  2365. );
  2366. ULONG
  2367. CmpComputeHashKeyForCompressedName(
  2368. IN PWCHAR Source,
  2369. IN ULONG SourceLength
  2370. );
  2371. //
  2372. // KCB allocator routines
  2373. //
  2374. VOID CmpInitCmPrivateAlloc();
  2375. VOID CmpDestroyCmPrivateAlloc();
  2376. PCM_KEY_CONTROL_BLOCK CmpAllocateKeyControlBlock( );
  2377. VOID CmpFreeKeyControlBlock( PCM_KEY_CONTROL_BLOCK kcb );
  2378. //
  2379. // make handles protected, so we control handle closure
  2380. //
  2381. #define CmpSetHandleProtection(Handle,Protection) \
  2382. { \
  2383. OBJECT_HANDLE_FLAG_INFORMATION Ohfi = { FALSE, \
  2384. FALSE \
  2385. }; \
  2386. Ohfi.ProtectFromClose = Protection; \
  2387. ZwSetInformationObject( Handle, \
  2388. ObjectHandleFlagInformation, \
  2389. &Ohfi, \
  2390. sizeof (OBJECT_HANDLE_FLAG_INFORMATION)); \
  2391. }
  2392. #define CmCloseHandle(Handle) \
  2393. CmpSetHandleProtection(Handle,FALSE); \
  2394. ZwClose(Handle)
  2395. VOID
  2396. CmpUpdateSystemHiveHysteresis( PHHIVE Hive,
  2397. ULONG NewLength,
  2398. ULONG OldLength
  2399. );
  2400. NTSTATUS
  2401. CmpCallCallBacks (
  2402. IN REG_NOTIFY_CLASS Type,
  2403. IN PVOID Argument
  2404. );
  2405. extern ULONG CmpCallBackCount;
  2406. #define CmAreCallbacksRegistered() (CmpCallBackCount != 0)
  2407. //
  2408. // Self healing hives control switch
  2409. //
  2410. extern BOOLEAN CmpSelfHeal;
  2411. extern ULONG CmpBootType;
  2412. #define CmDoSelfHeal() (CmpSelfHeal || (CmpBootType & (HBOOT_BACKUP|HBOOT_SELFHEAL)))
  2413. #ifndef _CM_LDR_
  2414. #if DBG
  2415. #define CmMarkSelfHeal(Hive) ( (Hive)->BaseBlock->BootType |= HBOOT_SELFHEAL ); \
  2416. DbgBreakPoint()
  2417. #else
  2418. #define CmMarkSelfHeal(Hive) ( (Hive)->BaseBlock->BootType |= HBOOT_SELFHEAL )
  2419. #endif
  2420. #else
  2421. #define CmMarkSelfHeal(Hive) ( (Hive)->BaseBlock->BootType |= HBOOT_SELFHEAL )
  2422. #endif
  2423. BOOLEAN
  2424. CmpRemoveSubKeyCellNoCellRef(
  2425. PHHIVE Hive,
  2426. HCELL_INDEX Parent,
  2427. HCELL_INDEX Child
  2428. );
  2429. VOID
  2430. CmpRaiseSelfHealWarning(
  2431. IN PUNICODE_STRING HiveName
  2432. );
  2433. VOID
  2434. CmpRaiseSelfHealWarningForSystemHives();
  2435. //
  2436. // Mini NT boot indicator
  2437. //
  2438. extern BOOLEAN CmpMiniNTBoot;
  2439. extern BOOLEAN CmpShareSystemHives;
  2440. #endif //_CMP_