Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

cmdata.h

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1999 Microsoft Corporation 00004 00005 Module Name: 00006 00007 cmdata.h 00008 00009 Abstract: 00010 00011 This module contains data structures used by the 00012 configuration manager. 00013 00014 Author: 00015 00016 Dragos C. Sambotin (dragoss) 13-Jan-99 00017 00018 Revision History: 00019 00020 --*/ 00021 00022 #ifndef __CM_DATA__ 00023 #define __CM_DATA__ 00024 00025 // \nt\private\ntos\inc\hivedata.h 00026 #include "hivedata.h" 00027 00028 00029 // 00030 // Limits on lengths of names, all in BYTES, all INCLUDING nulls. 00031 // 00032 00033 #define MAX_KEY_PATH_LENGTH 65535 00034 #define MAX_KEY_NAME_LENGTH 512 // allow for 256 unicode, as promise 00035 #define MAX_FRIENDLY_NAME_LENGTH 160 // allow for 80 unicode chars in FriendlyNames 00036 #define MAX_KEY_VALUE_NAME_LENGTH 32767 // 32k - sanity limit for value name 00037 00038 00039 // 00040 // ----- Control structures, object manager structures ------ 00041 // 00042 00043 00044 // 00045 // CM_KEY_CONTROL_BLOCK 00046 // 00047 // One key control block exists for each open key. All of the key objects 00048 // (open instances) for the key refer to the key control block. 00049 // 00050 00051 00052 typedef ULONG HASH_VALUE; 00053 00054 typedef struct _CM_KEY_HASH { 00055 ULONG ConvKey; 00056 struct _CM_KEY_HASH *NextHash; 00057 PHHIVE KeyHive; // Hive containing CM_KEY_NODE 00058 HCELL_INDEX KeyCell; // Cell containing CM_KEY_NODE 00059 } CM_KEY_HASH, *PCM_KEY_HASH; 00060 00061 #ifdef CM_DEBUG_KCB 00062 #define KCB_SIGNATURE 'bKmC' 00063 00064 #define SET_KCB_SIGNATURE(_kcb_,_sig_) (_kcb_)->Signature = (_sig_) 00065 #define ASSERT_KCB(_kcb_) ASSERT((_kcb_)->Signature == KCB_SIGNATURE) 00066 #define ASSERT_KEY_HASH(_keyhash_) ASSERT_KCB(CONTAINING_RECORD((_keyhash_), CM_KEY_CONTROL_BLOCK, KeyHash)) 00067 #else 00068 #define SET_KCB_SIGNATURE(_kcb_,_sig_) 00069 #define ASSERT_KCB(_kcb_) 00070 #define ASSERT_KEY_HASH(_keyhash_) 00071 #endif 00072 00073 00074 00075 // 00076 // The registry is a large data structure that has had poor locality. 00077 // To improve performance without changing the on disk structure, we 00078 // cache the frequently used registry data to minimize reference on 00079 // registry data. 00080 // 00081 // A KCB (Key Control Block) is the core structure for registry cache. 00082 // It uses HashValue for quick cache lookup and contains the most 00083 // frequently used data in a key node. 00084 // 00085 // It contains the most frequently used data in a key node: 00086 // Security, Flags, and Value index. 00087 // 00088 // A KCB may also contains additional information 00089 // (which are cached lazily) about its subkeys, value nodes and values' data. 00090 // 00091 // The subkey information is distinquished by ExtFlags. See CM_KCB_* below. 00092 // The value nodes and data are distinguished by a bit in the vairable. 00093 // See CMP_IS_CELL_CACHED. 00094 // 00095 // Caches for value data will be created during query process, the cached 00096 // structure is shown as the following picture. The structure is almost 00097 // the same as the registry structure 00098 // except they are pointers to the allocation instead of offset index on hive. 00099 // 00100 // To minimize the name string storage space KCB's, we do not store the complete 00101 // path name of the key in the kcb, instead, we implemented the tree structure 00102 // (like the registry hive structure) to share name prefix. 00103 // Also, knowing that there are lots of keys sharing same names, 00104 // we create NameBlock strucuture so KCB's of same names 00105 // can share the NameBlock. NameBlock is compressed. 00106 // 00107 // Meanings when the following bits are set in ExtFlags: 00108 // 1. The following bits are used for Parse and are for 00109 // non-symbolic keys. Also, at most one bit can be set at any given time. 00110 // CM_KCB_KEY_NON_EXIST : This key is a fake key (no such key in the hive). 00111 // CM_KCB_NO_SUBKEY : This key is has no subkey. 00112 // CM_KCB_SUBKEY_ONE : This key has only one subkey and IndexHint is 00113 // the first four characters of this subkey. 00114 // CM_KCB_SUBKEY_HINT : This key has the first four characters of all 00115 // its subkeys (buffer pointed by IndexHint). 00116 // 00117 // 2. CM_KCB_SYM_LINK_FOUND: This bit is only for symbolic keys. It 00118 // indicates that the symbolic link has been 00119 // resolved and the KCB for the link is pointed to 00120 // by ValueCache.RealKcb. 00121 // In this case, the Value Index of this key is no longer 00122 // available in the KCB. (We hardly query the value 00123 // of a symbolic link key other than finding the path 00124 // of the real key anyway). 00125 // 00126 // 3. CM_KCB_NO_DELAY_CLOSE: This bit is only used for non-symbolic keys and is 00127 // independent of bits on item 1. When set, it indicates that 00128 // key should not be kept in delay close when the refererence 00129 // count goes to zero. 00130 // This is for the case when a key has no open handles but 00131 // still has subkeys in the cache. 00132 // When its last subkey is kicked out of cache, we do not 00133 // want to keep this key around. 00134 // This is done so CmpSearchForOpenSubKeysInCachen can clean 00135 // up the cache properly before a key can be unloaded. 00136 // 00137 // 00138 // KCB 00139 // +-------------------+ 00140 // | ... | (Typical case) 00141 // +-------------------+ Value Index 00142 // | ValueCache | +-->+---------+ Value Key (with small data) 00143 // + +----------------+ | | o--------->+-----------+ 00144 // | | ValueList o---+ +---------+ | .... | 00145 // | +---- Union -----| | | +-----------+ 00146 // | | RealKcb o---+ +---------+ | Data (S) | 00147 // | +----------------| | | | +-----------+ 00148 // | | | +---------+ 00149 // | | | | | 00150 // | | | +---------+ Value Key (with large data) 00151 // | | | | o--------->+-----------+ 00152 // | | | +---------+ | ... | 00153 // | | | | | +-----------+ 00154 // | | | +---------+ | Data (L) o------+ 00155 // | | | +-----------+ | 00156 // | | | | | <---+ (Append at the end of Value Node) 00157 // | | | | | 00158 // | | | | | 00159 // | | | +-----------+ 00160 // | | | 00161 // | | | KCB (Symbolic link key, CM_KCB_SYM_LINK_FOUND set). 00162 // | | +-->+---------+ 00163 // | | | | 00164 // | | | | 00165 // | | | | 00166 // | | | | 00167 // | | | | 00168 // | | +---------+ 00169 // | | 00170 // | ... | 00171 // +-------------------+ Index Hint 00172 // | IndexHint o------>+---------+ 00173 // +-------------------+ | 4 char | 00174 // | | +---------+ 00175 // | | | 4 char | 00176 // +-------------------+ +---------+ 00177 // | | (CM_KCB_SUBKEY_HINT) 00178 // | | 00179 // | | 00180 // +-------------------+ Name Block 00181 // | NameBlock o----------------->+----------+ 00182 // +-------------------+ | | 00183 // +----------+ 00184 // 00185 // 00186 // The TotalLevels is used for quick comparison for notification and cache lookup. 00187 // 00188 // *** MP Synchronization *** 00189 // The KCB lock is held for any write to KCB unless the registry is locked exclusively. 00190 // KCB is also locked while reading fields that can be modified by another thread 00191 // during a read operation, i.e., when the registry lock is held shared. 00192 // 00193 // The fields are the follows: ExtFlags, ValueCache, IndexInfo, IndexHint, or NameHint. 00194 // 00195 // Reading of other entries in the KCB does not need to hold the KCB lock since 00196 // these entries will not change for any registry read operation. When there 00197 // are changes to these entries, registry must be locked exclusively. 00198 // 00199 // NOTE: the KCB size is 56 bytes now, plus the pool header of 8 bytes, 00200 // it fits into a 64byte allocation. Think carefully if you want to 00201 // enlarge the data structure. Also, watch it if the pool allocation code changes. 00202 // 00203 // The RefCount in KCB is the number of open handles plus the number of cached subkeys. 00204 // We can change this by having a RefCount and a CachedSubKeyCount. To not grow the 00205 // structure size, we can merge the boolean Delete into ExtFlags. 00206 00207 typedef struct _CM_NAME_HASH { 00208 ULONG ConvKey; 00209 struct _CM_NAME_HASH *NextHash; 00210 USHORT NameLength; // Length of string value 00211 WCHAR Name[1] ; // The actual string value 00212 } CM_NAME_HASH, *PCM_NAME_HASH; 00213 00214 typedef struct _CM_NAME_CONTROL_BLOCK { 00215 BOOLEAN Compressed; // Flags to indicate which extension we have. 00216 USHORT RefCount; 00217 union { 00218 CM_NAME_HASH NameHash; 00219 struct { 00220 ULONG ConvKey; 00221 struct _CM_KEY_HASH *NextHash; 00222 USHORT NameLength; // Length of string value 00223 WCHAR Name[1] ; // The actual string value 00224 }; 00225 }; 00226 } CM_NAME_CONTROL_BLOCK, *PCM_NAME_CONTROL_BLOCK; 00227 00228 typedef struct _CM_INDEX_HINT_BLOCK { 00229 ULONG Count; 00230 UCHAR NameHint[1]; 00231 } CM_INDEX_HINT_BLOCK, *PCM_INDEX_HINT_BLOCK; 00232 00233 typedef struct _CACHED_CHILD_LIST { 00234 ULONG Count; // 0 for empty list 00235 union { 00236 ULONG_PTR ValueList; 00237 struct _CM_KEY_CONTROL_BLOCK *RealKcb; 00238 }; 00239 } CACHED_CHILD_LIST, *PCACHED_CHILD_LIST; 00240 00241 // 00242 // Define the HINT Length used 00243 // 00244 #define CM_SUBKEY_HINT_LENGTH 4 00245 #define CM_MAX_CACHE_HINT_SIZE 14 00246 00247 // 00248 // Bits used in the ExtFlags in KCB. 00249 // 00250 00251 #define CM_KCB_NO_SUBKEY 0x0001 // This key has no subkeys 00252 #define CM_KCB_SUBKEY_ONE 0x0002 // This key has only one subkey and the 00253 // first 4 char 00254 // 00255 #define CM_KCB_SUBKEY_HINT 0x0004 00256 #define CM_KCB_SYM_LINK_FOUND 0x0008 00257 #define CM_KCB_KEY_NON_EXIST 0x0010 00258 #define CM_KCB_NO_DELAY_CLOSE 0x0020 00259 00260 #define CM_KCB_CACHE_MASK (CM_KCB_NO_SUBKEY | \ 00261 CM_KCB_KEY_NON_EXIST | \ 00262 CM_KCB_SUBKEY_ONE | \ 00263 CM_KCB_SUBKEY_HINT) 00264 00265 00266 #define KCB_TO_KEYBODY_LINK 00267 00268 typedef struct _CM_KEY_CONTROL_BLOCK { 00269 #ifdef CM_DEBUG_KCB 00270 ULONG Signature; 00271 #endif 00272 BOOLEAN Delete; 00273 USHORT RefCount; 00274 union { 00275 CM_KEY_HASH KeyHash; 00276 struct { 00277 ULONG ConvKey; 00278 struct _CM_KEY_HASH *NextHash; 00279 PHHIVE KeyHive; // Hive containing CM_KEY_NODE 00280 HCELL_INDEX KeyCell; // Cell containing CM_KEY_NODE 00281 }; 00282 }; 00283 USHORT ExtFlags; // Flags to indicate which extension we have. 00284 USHORT Flags; // Same Flags as KeyNode 00285 struct _CM_KEY_CONTROL_BLOCK *ParentKcb; 00286 PCM_NAME_CONTROL_BLOCK NameBlock; 00287 HCELL_INDEX Security; 00288 struct _CACHED_CHILD_LIST ValueCache; 00289 union { 00290 PCM_INDEX_HINT_BLOCK IndexHint; // CM_KCB_SUBKEY_HINT 00291 UCHAR NameHint[CM_SUBKEY_HINT_LENGTH]; // CM_KCB_SUBKEY_ONE 00292 }; 00293 USHORT DelayedCloseIndex; 00294 USHORT TotalLevels; 00295 struct _CM_KEY_NODE *KeyNode; // pointer to CM_KEY_NODE 00296 #ifdef KCB_TO_KEYBODY_LINK 00297 LIST_ENTRY KeyBodyListHead; // head of the list with all key_nodes using this kcb 00298 #endif 00299 } CM_KEY_CONTROL_BLOCK, *PCM_KEY_CONTROL_BLOCK; 00300 00301 00302 // 00303 // ----- Structures used to implement registry hierarchy ----- 00304 // 00305 00306 typedef enum _NODE_TYPE { 00307 KeyBodyNode, 00308 KeyValueNode 00309 } NODE_TYPE; 00310 00311 00312 typedef enum _CMP_COPY_TYPE { 00313 Copy, 00314 Sync, 00315 Merge 00316 } CMP_COPY_TYPE; 00317 00318 typedef enum _SUBKEY_SEARCH_TYPE { 00319 SearchIfExist, 00320 SearchAndDeref, 00321 SearchAndCount 00322 } SUBKEY_SEARCH_TYPE; 00323 00324 // 00325 // ChildList 00326 // 00327 // NOTE: CHILD_LIST structures are normally refered to 00328 // with HCELL_INDEX, not PCHILD_LIST vars. 00329 // 00330 00331 typedef struct _CHILD_LIST { 00332 ULONG Count; // 0 for empty list 00333 HCELL_INDEX List; 00334 } CHILD_LIST, *PCHILD_LIST; 00335 00336 // 00337 // CM_KEY_REFERENCE 00338 // 00339 00340 typedef struct _CM_KEY_REFERENCE { 00341 HCELL_INDEX KeyCell; 00342 PHHIVE KeyHive; 00343 } CM_KEY_REFERENCE , *PCM_KEY_REFERENCE; 00344 00345 // 00346 // ----- CM_KEY_INDEX ----- 00347 // 00348 // A leaf index may be one of two types. The "old" CM_KEY_INDEX type is used for 00349 // hives circa NT3.1, 3.5, and 3.51. NT4.0 introduces the newer CM_KEY_FAST_INDEX 00350 // which is used for all leaf indexes that have less than CM_MAX_FAST_INDEX leaves. 00351 // 00352 // The main advantage of the fast index is that the first four characters of the 00353 // names are stored within the index itself. This almost always saves us from having 00354 // to fault in a number of unneccessary pages when searching for a given key. 00355 // 00356 // The main disadvantage is that each subkey requires twice as much storage. One dword 00357 // for the HCELL_INDEX and one dword to hold the first four characters of the subkey 00358 // name. If one of the first four characters in the subkey name is a unicode character 00359 // where the high byte is non-zero, the actual subkey must be examined to determine the 00360 // name. 00361 // 00362 // Hive version 1 & 2 do not support the fast index. Version 3 adds support for the 00363 // fast index. All hives that are newly created on a V3-capable system are therefore 00364 // unreadable on V1 & 2 systems. 00365 // 00366 // N.B. There is code in cmindex.c that relies on the Signature and Count fields of 00367 // CM_KEY_INDEX and CM_KEY_FAST_INDEX being at the same offset in the structure! 00368 00369 #define UseFastIndex(Hive) ((Hive)->Version>=3) 00370 00371 #define CM_KEY_INDEX_ROOT 0x6972 // ir 00372 #define CM_KEY_INDEX_LEAF 0x696c // il 00373 #define CM_KEY_FAST_LEAF 0x666c // fl 00374 00375 typedef struct _CM_INDEX { 00376 HCELL_INDEX Cell; 00377 UCHAR NameHint[4]; // upcased first four chars of name 00378 } CM_INDEX, *PCM_INDEX; 00379 00380 typedef struct _CM_KEY_FAST_INDEX { 00381 USHORT Signature; // also type selector 00382 USHORT Count; 00383 CM_INDEX List[1]; // Variable sized array 00384 } CM_KEY_FAST_INDEX, *PCM_KEY_FAST_INDEX; 00385 00386 typedef struct _CM_KEY_INDEX { 00387 USHORT Signature; // also type selector 00388 USHORT Count; 00389 HCELL_INDEX List[1]; // Variable sized array 00390 } CM_KEY_INDEX, *PCM_KEY_INDEX; 00391 00392 // 00393 // Allow index to grow to size that will cause allocation of exactly 00394 // one logical block. Works out to be 1013 entries. 00395 // 00396 #define CM_MAX_INDEX \ 00397 ( (HBLOCK_SIZE- \ 00398 (sizeof(HBIN)+FIELD_OFFSET(HCELL,u)+FIELD_OFFSET(CM_KEY_INDEX,List))) / \ 00399 sizeof(HCELL_INDEX) ) 00400 00401 #define CM_MAX_LEAF_SIZE ((sizeof(HCELL_INDEX)*CM_MAX_INDEX) + \ 00402 (FIELD_OFFSET(CM_KEY_INDEX, List))) 00403 00404 // 00405 // Allow index to grow to size that will cause allocation of exactly 00406 // one logical block. Works out to be approx. 500 entries. 00407 // 00408 #define CM_MAX_FAST_INDEX \ 00409 ( (HBLOCK_SIZE- \ 00410 (sizeof(HBIN)+FIELD_OFFSET(HCELL,u)+FIELD_OFFSET(CM_KEY_FAST_INDEX,List))) / \ 00411 sizeof(CM_INDEX) ) 00412 00413 #define CM_MAX_FAST_LEAF_SIZE ((sizeof(CM_INDEX)*CM_MAX_FAST_INDEX) + \ 00414 (FIELD_OFFSET(CM_KEY_FAST_INDEX, List))) 00415 00416 00417 00418 // 00419 // ----- CM_KEY_NODE ----- 00420 // 00421 00422 #define CM_KEY_NODE_SIGNATURE 0x6b6e // "kn" 00423 #define CM_LINK_NODE_SIGNATURE 0x6b6c // "kl" 00424 00425 #define KEY_VOLATILE 0x0001 // This key (and all its children) 00426 // is volatile. 00427 00428 #define KEY_HIVE_EXIT 0x0002 // This key marks a bounary to another 00429 // hive (sort of a link). The null 00430 // value entry contains the hive 00431 // and hive index of the root of the 00432 // child hive. 00433 00434 #define KEY_HIVE_ENTRY 0x0004 // This key is the root of a particular 00435 // hive. 00436 00437 #define KEY_NO_DELETE 0x0008 // This key cannot be deleted, period. 00438 00439 #define KEY_SYM_LINK 0x0010 // This key is really a symbolic link. 00440 #define KEY_COMP_NAME 0x0020 // The name for this key is stored in a 00441 // compressed form. 00442 #define KEY_PREDEF_HANDLE 0x0040 // There is no real key backing this, 00443 // return the predefined handle. 00444 // Predefined handles are stashed in 00445 // ValueList.Count. 00446 00447 #pragma pack(4) 00448 typedef struct _CM_KEY_NODE { 00449 USHORT Signature; 00450 USHORT Flags; 00451 LARGE_INTEGER LastWriteTime; 00452 ULONG Spare; // used to be TitleIndex 00453 HCELL_INDEX Parent; 00454 ULONG SubKeyCounts[HTYPE_COUNT]; // Stable and Volatile 00455 union { 00456 struct { 00457 HCELL_INDEX SubKeyLists[HTYPE_COUNT]; // Stable and Volatile 00458 CHILD_LIST ValueList; 00459 }; 00460 CM_KEY_REFERENCE ChildHiveReference; 00461 }; 00462 00463 HCELL_INDEX Security; 00464 HCELL_INDEX Class; 00465 ULONG MaxNameLen; 00466 ULONG MaxClassLen; 00467 ULONG MaxValueNameLen; 00468 ULONG MaxValueDataLen; 00469 00470 ULONG WorkVar; // WARNING: This DWORD is used 00471 // by the system at run 00472 // time, do attempt to 00473 // store user data in it. 00474 00475 USHORT NameLength; 00476 USHORT ClassLength; 00477 WCHAR Name[1]; // Variable sized array 00478 } CM_KEY_NODE, *PCM_KEY_NODE; 00479 #pragma pack() 00480 00481 // 00482 // ----- CM_KEY_VALUE ----- 00483 // 00484 00485 #define CM_KEY_VALUE_SIGNATURE 0x6b76 // "kv" 00486 00487 #define CM_KEY_VALUE_SPECIAL_SIZE 0x80000000 // 2 gig 00488 00489 #define CM_KEY_VALUE_SMALL 4 00490 00491 #define VALUE_COMP_NAME 0x0001 // The name for this value is stored in a 00492 // compressed form. 00493 00494 typedef struct _CM_KEY_VALUE { 00495 USHORT Signature; 00496 USHORT NameLength; 00497 ULONG DataLength; 00498 HCELL_INDEX Data; 00499 ULONG Type; 00500 USHORT Flags; // Used to be TitleIndex 00501 USHORT Spare; // Used to be TitleIndex 00502 WCHAR Name[1]; // Variable sized array 00503 } CM_KEY_VALUE, *PCM_KEY_VALUE; 00504 00505 // 00506 // realsize is set to real size, returns TRUE if small, else FALSE 00507 // 00508 #define CmpIsHKeyValueSmall(realsize, size) \ 00509 ((size >= CM_KEY_VALUE_SPECIAL_SIZE) ? \ 00510 ((realsize) = size - CM_KEY_VALUE_SPECIAL_SIZE, TRUE) : \ 00511 ((realsize) = size, FALSE)) 00512 00513 // 00514 // ----- CM_KEY_SECURITY ----- 00515 // 00516 00517 #define CM_KEY_SECURITY_SIGNATURE 0x6b73 // "ks" 00518 00519 typedef struct _CM_KEY_SECURITY { 00520 USHORT Signature; 00521 USHORT Reserved; 00522 HCELL_INDEX Flink; 00523 HCELL_INDEX Blink; 00524 ULONG ReferenceCount; 00525 ULONG DescriptorLength; 00526 SECURITY_DESCRIPTOR_RELATIVE Descriptor; // Variable length 00527 } CM_KEY_SECURITY, *PCM_KEY_SECURITY; 00528 00529 // 00530 // ----- CELL_DATA ----- 00531 // 00532 // Union of types of data that could be in a cell 00533 // 00534 00535 typedef struct _CELL_DATA { 00536 union _u { 00537 CM_KEY_NODE KeyNode; 00538 CM_KEY_VALUE KeyValue; 00539 CM_KEY_SECURITY KeySecurity; // Variable security descriptor length 00540 CM_KEY_INDEX KeyIndex; // Variable sized structure 00541 HCELL_INDEX KeyList[1]; // Variable sized array 00542 WCHAR KeyString[1]; // Variable sized array 00543 } u; 00544 } CELL_DATA, *PCELL_DATA; 00545 00546 00547 // 00548 // Unions for KEY_INFORMATION, KEY_VALUE_INFORMATION 00549 // 00550 00551 typedef union _KEY_INFORMATION { 00552 KEY_BASIC_INFORMATION KeyBasicInformation; 00553 KEY_NODE_INFORMATION KeyNodeInformation; 00554 KEY_FULL_INFORMATION KeyFullInformation; 00555 KEY_NAME_INFORMATION KeyNameInformation; 00556 } KEY_INFORMATION, *PKEY_INFORMATION; 00557 00558 typedef union _KEY_VALUE_INFORMATION { 00559 KEY_VALUE_BASIC_INFORMATION KeyValueBasicInformation; 00560 KEY_VALUE_FULL_INFORMATION KeyValueFullInformation; 00561 KEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInformation; 00562 KEY_VALUE_PARTIAL_INFORMATION_ALIGN64 KeyValuePartialInformationAlign64; 00563 } KEY_VALUE_INFORMATION, *PKEY_VALUE_INFORMATION; 00564 00565 00566 00567 // 00568 // ----- CACHED_DATA ----- 00569 // 00570 // When values are not cached, List in ValueCache is the Hive cell index to the value list. 00571 // When they are cached, List will be pointer to the allocation. We distinguish them by 00572 // marking the lowest bit in the variable to indicate it is a cached allocation. 00573 // 00574 // Note that the cell index for value list 00575 // is stored in the cached allocation. It is not used now but may be in further performance 00576 // optimization. 00577 // 00578 // When value key and vaule data are cached, there is only one allocation for both. 00579 // Value data is appended that the end of value key. DataCacheType indicates 00580 // whether data is cached and ValueKeySize tells how big is the value key (so 00581 // we can calculate the address of cached value data) 00582 // 00583 // 00584 00585 #define CM_CACHE_DATA_NOT_CACHED 0 00586 #define CM_CACHE_DATA_CACHED 1 00587 #define CM_CACHE_DATA_TOO_BIG 2 00588 #define MAXIMUM_CACHED_DATA 2048 // Maximum data size to be cached. 00589 00590 typedef struct _CM_CACHED_VALUE_INDEX { 00591 HCELL_INDEX CellIndex; 00592 union { 00593 CELL_DATA CellData; 00594 ULONG_PTR List[1]; 00595 } Data; 00596 } CM_CACHED_VALUE_INDEX, *PCM_CACHED_VALUE_INDEX; // This is only used as a pointer. 00597 00598 typedef struct _CM_CACHED_VALUE { 00599 USHORT DataCacheType; 00600 USHORT ValueKeySize; 00601 CM_KEY_VALUE KeyValue; 00602 } CM_CACHED_VALUE, *PCM_CACHED_VALUE; // This is only used as a pointer. 00603 00604 typedef PCM_CACHED_VALUE *PPCM_CACHED_VALUE; 00605 00606 #define CMP_CELL_CACHED_MASK 1 00607 00608 #define CMP_IS_CELL_CACHED(Cell) (((ULONG_PTR) (Cell) & CMP_CELL_CACHED_MASK) && ((Cell) != (ULONG_PTR) HCELL_NIL)) 00609 #define CMP_GET_CACHED_ADDRESS(Cell) (((ULONG_PTR) (Cell)) & ~CMP_CELL_CACHED_MASK) 00610 #define CMP_GET_CACHED_CELLDATA(Cell) (&(((PCM_CACHED_VALUE_INDEX)(((ULONG_PTR) (Cell)) & ~CMP_CELL_CACHED_MASK))->Data.CellData)) 00611 #define CMP_GET_CACHED_KEYVALUE(Cell) (&(((PCM_CACHED_VALUE)(((ULONG_PTR) (Cell)) & ~CMP_CELL_CACHED_MASK))->KeyValue)) 00612 #define CMP_GET_CACHED_CELL(Cell) (((PCM_CACHED_ENTRY)(((ULONG_PTR) (Cell)) & ~CMP_CELL_CACHED_MASK))->CellIndex) 00613 #define CMP_MARK_CELL_CACHED(Cell) (((ULONG_PTR) (Cell)) | CMP_CELL_CACHED_MASK) 00614 00615 #define CMP_GET_CACHED_CELL_INDEX(Cell) (PtrToUlong((PVOID) (Cell))) 00616 00617 00618 #endif //__CM_DATA__ 00619 00620

Generated on Sat May 15 19:39:27 2004 for test by doxygen 1.3.7