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.

720 lines
28 KiB

  1. //depot/main/Base/ntos/inc/cmdata.h#8 - integrate change 19035 (text)
  2. /*++
  3. Copyright (c) 1999 Microsoft Corporation
  4. Module Name:
  5. cmdata.h
  6. Abstract:
  7. This module contains data structures used by the
  8. configuration manager.
  9. Author:
  10. Dragos C. Sambotin (dragoss) 13-Jan-99
  11. Revision History:
  12. --*/
  13. #ifndef __CM_DATA__
  14. #define __CM_DATA__
  15. // \nt\private\ntos\inc\hivedata.h
  16. #include "hivedata.h"
  17. //
  18. // Limits on lengths of names, all in BYTES, all INCLUDING nulls.
  19. //
  20. #define MAX_KEY_PATH_LENGTH 65535
  21. #define MAX_FRIENDLY_NAME_LENGTH 160 // allow for 80 unicode chars in FriendlyNames
  22. //
  23. // ----- Control structures, object manager structures ------
  24. //
  25. //
  26. // CM_KEY_CONTROL_BLOCK
  27. //
  28. // One key control block exists for each open key. All of the key objects
  29. // (open instances) for the key refer to the key control block.
  30. //
  31. typedef ULONG HASH_VALUE;
  32. typedef struct _CM_KEY_HASH {
  33. ULONG ConvKey;
  34. struct _CM_KEY_HASH *NextHash;
  35. PHHIVE KeyHive; // Hive containing CM_KEY_NODE
  36. HCELL_INDEX KeyCell; // Cell containing CM_KEY_NODE
  37. } CM_KEY_HASH, *PCM_KEY_HASH;
  38. #ifdef CM_DEBUG_KCB
  39. #define KCB_SIGNATURE 'bKmC'
  40. #define SET_KCB_SIGNATURE(_kcb_,_sig_) (_kcb_)->Signature = (_sig_)
  41. #define ASSERT_KCB(_kcb_) ASSERT((_kcb_)->Signature == KCB_SIGNATURE)
  42. #define ASSERT_KEY_HASH(_keyhash_) ASSERT_KCB(CONTAINING_RECORD((_keyhash_), CM_KEY_CONTROL_BLOCK, KeyHash))
  43. #else
  44. #define SET_KCB_SIGNATURE(_kcb_,_sig_)
  45. #define ASSERT_KCB(_kcb_)
  46. #define ASSERT_KEY_HASH(_keyhash_)
  47. #endif
  48. //
  49. // The registry is a large data structure that has had poor locality.
  50. // To improve performance without changing the on disk structure, we
  51. // cache the frequently used registry data to minimize reference on
  52. // registry data.
  53. //
  54. // A KCB (Key Control Block) is the core structure for registry cache.
  55. // It uses HashValue for quick cache lookup and contains the most
  56. // frequently used data in a key node.
  57. //
  58. // It contains the most frequently used data in a key node:
  59. // Security, Flags, and Value index.
  60. //
  61. // A KCB may also contains additional information
  62. // (which are cached lazily) about its subkeys, value nodes and values' data.
  63. //
  64. // The subkey information is distinquished by ExtFlags. See CM_KCB_* below.
  65. // The value nodes and data are distinguished by a bit in the vairable.
  66. // See CMP_IS_CELL_CACHED.
  67. //
  68. // Caches for value data will be created during query process, the cached
  69. // structure is shown as the following picture. The structure is almost
  70. // the same as the registry structure
  71. // except they are pointers to the allocation instead of offset index on hive.
  72. //
  73. // To minimize the name string storage space KCB's, we do not store the complete
  74. // path name of the key in the kcb, instead, we implemented the tree structure
  75. // (like the registry hive structure) to share name prefix.
  76. // Also, knowing that there are lots of keys sharing same names,
  77. // we create NameBlock strucuture so KCB's of same names
  78. // can share the NameBlock. NameBlock is compressed.
  79. //
  80. // Meanings when the following bits are set in ExtFlags:
  81. // 1. The following bits are used for Parse and are for
  82. // non-symbolic keys. Also, at most one bit can be set at any given time.
  83. // CM_KCB_KEY_NON_EXIST : This key is a fake key (no such key in the hive).
  84. // CM_KCB_NO_SUBKEY : This key is has no subkey.
  85. // CM_KCB_SUBKEY_ONE : This key has only one subkey and IndexHint is
  86. // the first four characters of this subkey.
  87. // CM_KCB_SUBKEY_HINT : This key has the first four characters of all
  88. // its subkeys (buffer pointed by IndexHint).
  89. //
  90. // 2. CM_KCB_SYM_LINK_FOUND: This bit is only for symbolic keys. It
  91. // indicates that the symbolic link has been
  92. // resolved and the KCB for the link is pointed to
  93. // by ValueCache.RealKcb.
  94. // In this case, the Value Index of this key is no longer
  95. // available in the KCB. (We hardly query the value
  96. // of a symbolic link key other than finding the path
  97. // of the real key anyway).
  98. //
  99. // 3. CM_KCB_NO_DELAY_CLOSE: This bit is only used for non-symbolic keys and is
  100. // independent of bits on item 1. When set, it indicates that
  101. // key should not be kept in delay close when the refererence
  102. // count goes to zero.
  103. // This is for the case when a key has no open handles but
  104. // still has subkeys in the cache.
  105. // When its last subkey is kicked out of cache, we do not
  106. // want to keep this key around.
  107. // This is done so CmpSearchForOpenSubKeysInCachen can clean
  108. // up the cache properly before a key can be unloaded.
  109. //
  110. //
  111. // KCB
  112. // +-------------------+
  113. // | ... | (Typical case)
  114. // +-------------------+ Value Index
  115. // | ValueCache | +-->+---------+ Value Key (with small data)
  116. // + +----------------+ | | o--------->+-----------+
  117. // | | ValueList o---+ +---------+ | .... |
  118. // | +---- Union -----| | | +-----------+
  119. // | | RealKcb o---+ +---------+ | Data (S) |
  120. // | +----------------| | | | +-----------+
  121. // | | | +---------+
  122. // | | | | |
  123. // | | | +---------+ Value Key (with large data)
  124. // | | | | o--------->+-----------+
  125. // | | | +---------+ | ... |
  126. // | | | | | +-----------+
  127. // | | | +---------+ | Data (L) o------+
  128. // | | | +-----------+ |
  129. // | | | | | <---+ (Append at the end of Value Node)
  130. // | | | | |
  131. // | | | | |
  132. // | | | +-----------+
  133. // | | |
  134. // | | | KCB (Symbolic link key, CM_KCB_SYM_LINK_FOUND set).
  135. // | | +-->+---------+
  136. // | | | |
  137. // | | | |
  138. // | | | |
  139. // | | | |
  140. // | | | |
  141. // | | +---------+
  142. // | |
  143. // | ... |
  144. // +-------------------+ Index Hint
  145. // | IndexHint o------>+---------+
  146. // +-------------------+ | 4 char |
  147. // | | +---------+
  148. // | | | 4 char |
  149. // +-------------------+ +---------+
  150. // | | (CM_KCB_SUBKEY_HINT)
  151. // | |
  152. // | |
  153. // +-------------------+ Name Block
  154. // | NameBlock o----------------->+----------+
  155. // +-------------------+ | |
  156. // +----------+
  157. //
  158. //
  159. // The TotalLevels is used for quick comparison for notification and cache lookup.
  160. //
  161. // *** MP Synchronization ***
  162. // The KCB lock is held for any write to KCB unless the registry is locked exclusively.
  163. // KCB is also locked while reading fields that can be modified by another thread
  164. // during a read operation, i.e., when the registry lock is held shared.
  165. //
  166. // The fields are the follows: ExtFlags, ValueCache, IndexInfo, IndexHint, or NameHint.
  167. //
  168. // Reading of other entries in the KCB does not need to hold the KCB lock since
  169. // these entries will not change for any registry read operation. When there
  170. // are changes to these entries, registry must be locked exclusively.
  171. //
  172. // NOTE: the KCB size is 56 bytes now, plus the pool header of 8 bytes,
  173. // it fits into a 64byte allocation. Think carefully if you want to
  174. // enlarge the data structure. Also, watch it if the pool allocation code changes.
  175. //
  176. // The RefCount in KCB is the number of open handles plus the number of cached subkeys.
  177. // We can change this by having a RefCount and a CachedSubKeyCount. To not grow the
  178. // structure size, we can merge the boolean Delete into ExtFlags.
  179. typedef struct _CM_NAME_HASH {
  180. ULONG ConvKey;
  181. struct _CM_NAME_HASH *NextHash;
  182. USHORT NameLength; // Length of string value
  183. WCHAR Name[1] ; // The actual string value
  184. } CM_NAME_HASH, *PCM_NAME_HASH;
  185. //
  186. // !!! In Whistler, the Name in the NameBlock is Always UpperCase !!!
  187. //
  188. typedef struct _CM_NAME_CONTROL_BLOCK {
  189. BOOLEAN Compressed; // Flags to indicate which extension we have.
  190. USHORT RefCount;
  191. union {
  192. CM_NAME_HASH NameHash;
  193. struct {
  194. ULONG ConvKey;
  195. struct _CM_KEY_HASH *NextHash;
  196. USHORT NameLength; // Length of string value
  197. WCHAR Name[1] ; // The actual string value
  198. };
  199. };
  200. } CM_NAME_CONTROL_BLOCK, *PCM_NAME_CONTROL_BLOCK;
  201. typedef struct _CM_INDEX_HINT_BLOCK {
  202. ULONG Count;
  203. ULONG HashKey[1]; // hash key of name
  204. } CM_INDEX_HINT_BLOCK, *PCM_INDEX_HINT_BLOCK;
  205. typedef struct _CACHED_CHILD_LIST {
  206. ULONG Count; // 0 for empty list
  207. union {
  208. ULONG_PTR ValueList;
  209. struct _CM_KEY_CONTROL_BLOCK *RealKcb;
  210. };
  211. } CACHED_CHILD_LIST, *PCACHED_CHILD_LIST;
  212. //
  213. // Define the HINT Length used
  214. //
  215. #define CM_SUBKEY_HINT_LENGTH 4
  216. #define CM_MAX_CACHE_HINT_SIZE 14
  217. //
  218. // ----- Structures used to implement registry hierarchy -----
  219. //
  220. typedef enum _NODE_TYPE {
  221. KeyBodyNode,
  222. KeyValueNode
  223. } NODE_TYPE;
  224. typedef enum _CMP_COPY_TYPE {
  225. Copy,
  226. Sync,
  227. Merge
  228. } CMP_COPY_TYPE;
  229. typedef enum _SUBKEY_SEARCH_TYPE {
  230. SearchIfExist,
  231. SearchAndDeref,
  232. SearchAndCount,
  233. SearchAndRehash,
  234. SearchAndTagNoDelayClose
  235. } SUBKEY_SEARCH_TYPE;
  236. //
  237. // ChildList
  238. //
  239. // NOTE: CHILD_LIST structures are normally refered to
  240. // with HCELL_INDEX, not PCHILD_LIST vars.
  241. //
  242. typedef struct _CHILD_LIST {
  243. ULONG Count; // 0 for empty list
  244. HCELL_INDEX List;
  245. } CHILD_LIST, *PCHILD_LIST;
  246. //
  247. // CM_KEY_REFERENCE
  248. //
  249. typedef struct _CM_KEY_REFERENCE {
  250. HCELL_INDEX KeyCell;
  251. PHHIVE KeyHive;
  252. } CM_KEY_REFERENCE , *PCM_KEY_REFERENCE;
  253. //
  254. // ----- CM_KEY_INDEX -----
  255. //
  256. // A leaf index may be one of two types. The "old" CM_KEY_INDEX type is used for
  257. // hives circa NT3.1, 3.5, and 3.51. NT4.0 introduces the newer CM_KEY_FAST_INDEX
  258. // which is used for all leaf indexes that have less than CM_MAX_FAST_INDEX leaves.
  259. //
  260. // The main advantage of the fast index is that the first four characters of the
  261. // names are stored within the index itself. This almost always saves us from having
  262. // to fault in a number of unneccessary pages when searching for a given key.
  263. //
  264. // The main disadvantage is that each subkey requires twice as much storage. One dword
  265. // for the HCELL_INDEX and one dword to hold the first four characters of the subkey
  266. // name. If one of the first four characters in the subkey name is a unicode character
  267. // where the high byte is non-zero, the actual subkey must be examined to determine the
  268. // name.
  269. //
  270. // Hive version 1 & 2 do not support the fast index. Version 3 adds support for the
  271. // fast index. All hives that are newly created on a V3-capable system are therefore
  272. // unreadable on V1 & 2 systems.
  273. //
  274. // N.B. There is code in cmindex.c that relies on the Signature and Count fields of
  275. // CM_KEY_INDEX and CM_KEY_FAST_INDEX being at the same offset in the structure!
  276. #define INVALID_INDEX 0x80000000 // index is not valid
  277. #define UseFastIndex(Hive) ((Hive)->Version >= 3)
  278. #define UseHashIndex(Hive) ((Hive)->Version >= HSYS_WHISTLER)
  279. #define CM_KEY_INDEX_ROOT 0x6972 // ir
  280. #define CM_KEY_INDEX_LEAF 0x696c // il
  281. #define CM_KEY_FAST_LEAF 0x666c // fl
  282. #define CM_KEY_HASH_LEAF 0x686c // hl
  283. typedef struct _CM_INDEX {
  284. HCELL_INDEX Cell;
  285. union {
  286. UCHAR NameHint[4]; // upcased first four chars of name
  287. ULONG HashKey; // hash key of name
  288. };
  289. } CM_INDEX, *PCM_INDEX;
  290. typedef struct _CM_KEY_FAST_INDEX {
  291. USHORT Signature; // also type selector
  292. USHORT Count;
  293. CM_INDEX List[1]; // Variable sized array
  294. } CM_KEY_FAST_INDEX, *PCM_KEY_FAST_INDEX;
  295. typedef struct _CM_KEY_INDEX {
  296. USHORT Signature; // also type selector
  297. USHORT Count;
  298. HCELL_INDEX List[1]; // Variable sized array
  299. } CM_KEY_INDEX, *PCM_KEY_INDEX;
  300. //
  301. // Allow index to grow to size that will cause allocation of exactly
  302. // one logical block. Works out to be 1013 entries.
  303. //
  304. #define CM_MAX_INDEX \
  305. ( (HBLOCK_SIZE- \
  306. (sizeof(HBIN)+FIELD_OFFSET(HCELL,u)+FIELD_OFFSET(CM_KEY_INDEX,List))) / \
  307. sizeof(HCELL_INDEX) )
  308. #define CM_MAX_LEAF_SIZE ((sizeof(HCELL_INDEX)*CM_MAX_INDEX) + \
  309. (FIELD_OFFSET(CM_KEY_INDEX, List)))
  310. //
  311. // Allow index to grow to size that will cause allocation of exactly
  312. // one logical block. Works out to be approx. 500 entries.
  313. //
  314. #define CM_MAX_FAST_INDEX \
  315. ( (HBLOCK_SIZE- \
  316. (sizeof(HBIN)+FIELD_OFFSET(HCELL,u)+FIELD_OFFSET(CM_KEY_FAST_INDEX,List))) / \
  317. sizeof(CM_INDEX) )
  318. #define CM_MAX_FAST_LEAF_SIZE ((sizeof(CM_INDEX)*CM_MAX_FAST_INDEX) + \
  319. (FIELD_OFFSET(CM_KEY_FAST_INDEX, List)))
  320. //
  321. // ----- CM_KEY_NODE -----
  322. //
  323. #define CM_KEY_NODE_SIGNATURE 0x6b6e // "kn"
  324. #define CM_LINK_NODE_SIGNATURE 0x6b6c // "kl"
  325. #define KEY_VOLATILE 0x0001 // This key (and all its children)
  326. // is volatile.
  327. #define KEY_HIVE_EXIT 0x0002 // This key marks a bounary to another
  328. // hive (sort of a link). The null
  329. // value entry contains the hive
  330. // and hive index of the root of the
  331. // child hive.
  332. #define KEY_HIVE_ENTRY 0x0004 // This key is the root of a particular
  333. // hive.
  334. #define KEY_NO_DELETE 0x0008 // This key cannot be deleted, period.
  335. #define KEY_SYM_LINK 0x0010 // This key is really a symbolic link.
  336. #define KEY_COMP_NAME 0x0020 // The name for this key is stored in a
  337. // compressed form.
  338. #define KEY_PREDEF_HANDLE 0x0040 // There is no real key backing this,
  339. // return the predefined handle.
  340. // Predefined handles are stashed in
  341. // ValueList.Count.
  342. #define KEY_USER_FLAGS_CLEAR_MASK 0x0FFF // used to clear the user defined flags
  343. #define KEY_USER_FLAGS_VALID_MASK 0x000F // we only allow 4 bits for the user defined flags
  344. // (this is just for the time being) - we may extend
  345. // this as we see fit)
  346. #define KEY_USER_FLAGS_SHIFT 12 // shift count (to be updated if we change the number of flags)
  347. #define KEY_BREAK_ON_OPEN 0x8000 // used to determine if we need to break to dbg
  348. #pragma pack(4)
  349. typedef struct _CM_KEY_NODE {
  350. USHORT Signature;
  351. USHORT Flags; // first 4 bits are User defined flags !!!!
  352. LARGE_INTEGER LastWriteTime;
  353. ULONG Spare; // not used, yet
  354. HCELL_INDEX Parent;
  355. ULONG SubKeyCounts[HTYPE_COUNT]; // Stable and Volatile
  356. union {
  357. struct {
  358. HCELL_INDEX SubKeyLists[HTYPE_COUNT]; // Stable and Volatile
  359. CHILD_LIST ValueList;
  360. };
  361. CM_KEY_REFERENCE ChildHiveReference;
  362. };
  363. HCELL_INDEX Security;
  364. HCELL_INDEX Class;
  365. ULONG MaxNameLen;
  366. ULONG MaxClassLen;
  367. ULONG MaxValueNameLen;
  368. ULONG MaxValueDataLen;
  369. ULONG WorkVar; // WARNING: This DWORD is used
  370. // by the system at run
  371. // time, do attempt to
  372. // store user data in it.
  373. USHORT NameLength;
  374. USHORT ClassLength;
  375. WCHAR Name[1]; // Variable sized array
  376. } CM_KEY_NODE, *PCM_KEY_NODE;
  377. #pragma pack()
  378. //
  379. // ----- CM_KEY_VALUE -----
  380. //
  381. #define CM_KEY_VALUE_SIGNATURE 0x6b76 // "kv"
  382. #define CM_KEY_VALUE_SPECIAL_SIZE 0x80000000 // 2 gig
  383. #define CM_KEY_VALUE_SMALL 4
  384. #define CM_KEY_VALUE_BIG 0x3fd8 // 16K ; Only new hive formats will have this
  385. //
  386. // The above comes from this:
  387. // (0x4000 - sizeof(HBIN) - ROUND_UP(FIELD_OFFSET(HCELL, u.NewCell.u.UserData),8) )
  388. //
  389. #define VALUE_COMP_NAME 0x0001 // The name for this value is stored in a
  390. // compressed form.
  391. typedef struct _CM_KEY_VALUE {
  392. USHORT Signature;
  393. USHORT NameLength;
  394. ULONG DataLength;
  395. HCELL_INDEX Data;
  396. ULONG Type;
  397. USHORT Flags; // Used to be TitleIndex
  398. USHORT Spare; // Used to be TitleIndex
  399. WCHAR Name[1]; // Variable sized array
  400. } CM_KEY_VALUE, *PCM_KEY_VALUE;
  401. //
  402. // realsize is set to real size, returns TRUE if small, else FALSE
  403. //
  404. #define CmpIsHKeyValueSmall(realsize, size) \
  405. ((size >= CM_KEY_VALUE_SPECIAL_SIZE) ? \
  406. ((realsize) = size - CM_KEY_VALUE_SPECIAL_SIZE, TRUE) : \
  407. ((realsize) = size, FALSE))
  408. #define CmpIsHKeyValueBig(Hive,size) ( (Hive->Version >= HSYS_WHISTLER_BETA1) && ((size) < CM_KEY_VALUE_SPECIAL_SIZE) && ((size) > CM_KEY_VALUE_BIG ) )
  409. #define ASSERT_KEY_VALUE(Value) ASSERT( (Value)->Signature == CM_KEY_VALUE_SIGNATURE )
  410. //
  411. // ----- CM_BIG_DATA ------
  412. //
  413. #define CM_BIG_DATA_SIGNATURE 0x6264 // "bd"
  414. typedef struct _CM_BIG_DATA {
  415. USHORT Signature;
  416. USHORT Count; // 0 for empty list; this shouldn't happen
  417. HCELL_INDEX List; // HCELL_NIL for empty list; this shouldn't happen
  418. } CM_BIG_DATA, *PCM_BIG_DATA;
  419. #define ASSERT_BIG_DATA(BigData) ASSERT( ((BigData)->Signature == CM_BIG_DATA_SIGNATURE) && ((BigData)->Count > 0 ) && ((BigData)->List != HCELL_NIL) );
  420. //
  421. // ----- CM_KEY_SECURITY -----
  422. //
  423. #define CM_KEY_SECURITY_SIGNATURE 0x6b73 // "ks"
  424. typedef struct _CM_KEY_SECURITY {
  425. USHORT Signature;
  426. USHORT Reserved;
  427. HCELL_INDEX Flink;
  428. HCELL_INDEX Blink;
  429. ULONG ReferenceCount;
  430. ULONG DescriptorLength;
  431. SECURITY_DESCRIPTOR_RELATIVE Descriptor; // Variable length
  432. } CM_KEY_SECURITY, *PCM_KEY_SECURITY;
  433. //
  434. // ----- CM_KEY_SECURITY_CACHE ----
  435. //
  436. typedef struct _CM_KEY_SECURITY_CACHE {
  437. HCELL_INDEX Cell; // security cellindex (inside the hive)
  438. ULONG ConvKey;
  439. LIST_ENTRY List;
  440. ULONG DescriptorLength;
  441. SECURITY_DESCRIPTOR_RELATIVE Descriptor; // Variable length
  442. } CM_KEY_SECURITY_CACHE, *PCM_KEY_SECURITY_CACHE;
  443. typedef struct _CM_KEY_SECURITY_CACHE_ENTRY {
  444. HCELL_INDEX Cell; // security cellindex (inside the hive) -
  445. // this is to avoid touching the Security pages
  446. // at lookup operations
  447. PCM_KEY_SECURITY_CACHE CachedSecurity; // actual security cell (cached)
  448. } CM_KEY_SECURITY_CACHE_ENTRY, *PCM_KEY_SECURITY_CACHE_ENTRY;
  449. //
  450. // ----- CELL_DATA -----
  451. //
  452. // Union of types of data that could be in a cell
  453. //
  454. typedef struct _CELL_DATA {
  455. union _u {
  456. CM_KEY_NODE KeyNode;
  457. CM_KEY_VALUE KeyValue;
  458. CM_KEY_SECURITY KeySecurity; // Variable security descriptor length
  459. CM_KEY_INDEX KeyIndex; // Variable sized structure
  460. CM_BIG_DATA ValueData; // This is only for big cells; a list of cells
  461. // all of the length CM_KEY_VALUE_BIG
  462. HCELL_INDEX KeyList[1]; // Variable sized array
  463. WCHAR KeyString[1]; // Variable sized array
  464. } u;
  465. } CELL_DATA, *PCELL_DATA;
  466. //
  467. // Unions for KEY_INFORMATION, KEY_VALUE_INFORMATION
  468. //
  469. typedef union _KEY_INFORMATION {
  470. KEY_BASIC_INFORMATION KeyBasicInformation;
  471. KEY_NODE_INFORMATION KeyNodeInformation;
  472. KEY_FULL_INFORMATION KeyFullInformation;
  473. KEY_NAME_INFORMATION KeyNameInformation;
  474. KEY_CACHED_INFORMATION KeyCachedInformation;
  475. KEY_FLAGS_INFORMATION KeyFlagsInformation;
  476. } KEY_INFORMATION, *PKEY_INFORMATION;
  477. typedef union _KEY_VALUE_INFORMATION {
  478. KEY_VALUE_BASIC_INFORMATION KeyValueBasicInformation;
  479. KEY_VALUE_FULL_INFORMATION KeyValueFullInformation;
  480. KEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInformation;
  481. KEY_VALUE_PARTIAL_INFORMATION_ALIGN64 KeyValuePartialInformationAlign64;
  482. } KEY_VALUE_INFORMATION, *PKEY_VALUE_INFORMATION;
  483. //
  484. // ----- CACHED_DATA -----
  485. //
  486. // When values are not cached, List in ValueCache is the Hive cell index to the value list.
  487. // When they are cached, List will be pointer to the allocation. We distinguish them by
  488. // marking the lowest bit in the variable to indicate it is a cached allocation.
  489. //
  490. // Note that the cell index for value list
  491. // is stored in the cached allocation. It is not used now but may be in further performance
  492. // optimization.
  493. //
  494. // When value key and vaule data are cached, there is only one allocation for both.
  495. // Value data is appended that the end of value key. DataCacheType indicates
  496. // whether data is cached and ValueKeySize tells how big is the value key (so
  497. // we can calculate the address of cached value data)
  498. //
  499. //
  500. #define CM_CACHE_DATA_NOT_CACHED 0
  501. #define CM_CACHE_DATA_CACHED 1
  502. #define CM_CACHE_DATA_TOO_BIG 2
  503. #define MAXIMUM_CACHED_DATA 2048 // Maximum data size to be cached.
  504. typedef struct _CM_CACHED_VALUE_INDEX {
  505. HCELL_INDEX CellIndex;
  506. union {
  507. CELL_DATA CellData;
  508. ULONG_PTR List[1];
  509. } Data;
  510. } CM_CACHED_VALUE_INDEX, *PCM_CACHED_VALUE_INDEX; // This is only used as a pointer.
  511. typedef struct _CM_CACHED_VALUE {
  512. USHORT DataCacheType;
  513. USHORT ValueKeySize;
  514. CM_KEY_VALUE KeyValue;
  515. } CM_CACHED_VALUE, *PCM_CACHED_VALUE; // This is only used as a pointer.
  516. typedef PCM_CACHED_VALUE *PPCM_CACHED_VALUE;
  517. #define CMP_CELL_CACHED_MASK 1
  518. #define CMP_IS_CELL_CACHED(Cell) (((ULONG_PTR) (Cell) & CMP_CELL_CACHED_MASK) && ((Cell) != (ULONG_PTR) HCELL_NIL))
  519. #define CMP_GET_CACHED_ADDRESS(Cell) (((ULONG_PTR) (Cell)) & ~CMP_CELL_CACHED_MASK)
  520. #define CMP_GET_CACHED_CELLDATA(Cell) (&(((PCM_CACHED_VALUE_INDEX)(((ULONG_PTR) (Cell)) & ~CMP_CELL_CACHED_MASK))->Data.CellData))
  521. #define CMP_GET_CACHED_KEYVALUE(Cell) (&(((PCM_CACHED_VALUE)(((ULONG_PTR) (Cell)) & ~CMP_CELL_CACHED_MASK))->KeyValue))
  522. #define CMP_GET_CACHED_CELL(Cell) (((PCM_CACHED_ENTRY)(((ULONG_PTR) (Cell)) & ~CMP_CELL_CACHED_MASK))->CellIndex)
  523. #define CMP_MARK_CELL_CACHED(Cell) (((ULONG_PTR) (Cell)) | CMP_CELL_CACHED_MASK)
  524. #define CMP_GET_CACHED_CELL_INDEX(Cell) (PtrToUlong((PVOID) (Cell)))
  525. // Dragos: From here start the changes!!!
  526. //
  527. // Bits used in the ExtFlags in KCB.
  528. //
  529. #define CM_KCB_NO_SUBKEY 0x0001 // This key has no subkeys
  530. #define CM_KCB_SUBKEY_ONE 0x0002 // This key has only one subkey and the
  531. // first 4 char
  532. //
  533. #define CM_KCB_SUBKEY_HINT 0x0004
  534. #define CM_KCB_SYM_LINK_FOUND 0x0008
  535. #define CM_KCB_KEY_NON_EXIST 0x0010
  536. #define CM_KCB_NO_DELAY_CLOSE 0x0020
  537. #define CM_KCB_INVALID_CACHED_INFO 0x0040 // info stored in SubKeyCount is not valid, so we shouldn't rely on it
  538. #define CM_KCB_CACHE_MASK (CM_KCB_NO_SUBKEY | \
  539. CM_KCB_KEY_NON_EXIST | \
  540. CM_KCB_SUBKEY_ONE | \
  541. CM_KCB_SUBKEY_HINT)
  542. #define CM_KCB_READ_ONLY_KEY 0x0080 // this kcb is read-only all write operations onto it are denied.
  543. typedef struct _CM_KEY_CONTROL_BLOCK {
  544. #ifdef CM_DEBUG_KCB
  545. ULONG Signature;
  546. #endif
  547. USHORT RefCount;
  548. USHORT Flags; // Same Flags as KeyNode
  549. struct {
  550. ULONG ExtFlags : 8; // 00000000 00000000 00000000 ???????? Flags to indicate which extension we have.
  551. ULONG PrivateAlloc : 1; // 00000000 00000000 0000000? 00000000 are we allocated from our private pool?
  552. ULONG Delete : 1; // 00000000 00000000 000000?0 00000000
  553. ULONG DelayedCloseIndex : 12; // 00000000 00?????? ??????00 00000000 CmpDelayedCloseSize means it is
  554. // not in the delay close table
  555. ULONG TotalLevels : 10; // ???????? ??000000 00000000 00000000 max 512
  556. };
  557. union {
  558. CM_KEY_HASH KeyHash;
  559. struct {
  560. ULONG ConvKey;
  561. struct _CM_KEY_HASH *NextHash;
  562. PHHIVE KeyHive; // Hive containing CM_KEY_NODE
  563. HCELL_INDEX KeyCell; // Cell containing CM_KEY_NODE
  564. };
  565. };
  566. struct _CM_KEY_CONTROL_BLOCK *ParentKcb;
  567. PCM_NAME_CONTROL_BLOCK NameBlock;
  568. PCM_KEY_SECURITY_CACHE CachedSecurity; // pointer to cached security
  569. struct _CACHED_CHILD_LIST ValueCache;
  570. union { // The hint is always stored in uppercase.
  571. PCM_INDEX_HINT_BLOCK IndexHint; // CM_KCB_SUBKEY_HINT
  572. ULONG HashKey; // CM_KCB_SUBKEY_ONE
  573. ULONG SubKeyCount; // when none of the CM_KCB_NO_SUBKEY | CM_KCB_SUBKEY_ONE | CM_KCB_SUBKEY_HINT
  574. // is set in ExtFlags, we cache here the number of subkeys
  575. // (Node->SubKeyCounts[Stable] + Node->SubKeyCounts[Volatile])
  576. };
  577. union {
  578. LIST_ENTRY KeyBodyListHead; // head of the list with all key_nodes using this kcb
  579. LIST_ENTRY FreeListEntry; // entry in the free kcbs list inside a page - when we use the private allocator
  580. };
  581. //
  582. // Bellow is information cached from KEY_NODE for performance reasons.
  583. // Values here should be IDENTICAL with the ones in the corresponding KEY_NODE
  584. //
  585. LARGE_INTEGER KcbLastWriteTime;
  586. USHORT KcbMaxNameLen;
  587. USHORT KcbMaxValueNameLen;
  588. ULONG KcbMaxValueDataLen;
  589. } CM_KEY_CONTROL_BLOCK, *PCM_KEY_CONTROL_BLOCK;
  590. #endif //__CM_DATA__