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

cmtree.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 cmtree.c 00008 00009 Abstract: 00010 00011 This module contains cm routines that understand the structure 00012 of the registry tree. 00013 00014 Author: 00015 00016 Bryan M. Willman (bryanwi) 12-Sep-1991 00017 00018 Revision History: 00019 00020 --*/ 00021 00022 #include "cmp.h" 00023 00024 #ifdef ALLOC_PRAGMA 00025 #pragma alloc_text(PAGE,CmpFindNameInList) 00026 #pragma alloc_text(PAGE,CmpGetValueListFromCache) 00027 #pragma alloc_text(PAGE,CmpGetValueKeyFromCache) 00028 #pragma alloc_text(PAGE,CmpFindValueByNameFromCache) 00029 #endif 00030 00031 00032 HCELL_INDEX 00033 CmpFindNameInList( 00034 IN PHHIVE Hive, 00035 IN PCHILD_LIST ChildList, 00036 IN PUNICODE_STRING Name, 00037 IN OPTIONAL PCELL_DATA *ChildAddress, 00038 IN OPTIONAL PULONG ChildIndex 00039 ) 00040 /*++ 00041 00042 Routine Description: 00043 00044 Find a child object in an object list. 00045 00046 Arguments: 00047 00048 Hive - pointer to hive control structure for hive of interest 00049 00050 List - pointer to mapped in list structure 00051 00052 Count - number of elements in list structure 00053 00054 Name - name of child object to find 00055 00056 ChildAddress - pointer to variable to receive address of mapped in child 00057 00058 ChildIndex - pointer to variable to receive index for child 00059 00060 Return Value: 00061 00062 HCELL_INDEX for the found cell 00063 HCELL_NIL if not found 00064 00065 --*/ 00066 { 00067 NTSTATUS status; 00068 ULONG i; 00069 PCM_KEY_VALUE pchild; 00070 UNICODE_STRING Candidate; 00071 BOOLEAN Success; 00072 PCELL_DATA List; 00073 00074 if (ChildList->Count != 0) { 00075 List = (PCELL_DATA)HvGetCell(Hive,ChildList->List); 00076 for (i = 0; i < ChildList->Count; i++) { 00077 00078 pchild = (PCM_KEY_VALUE)HvGetCell(Hive, List->u.KeyList[i]); 00079 00080 if (pchild->Flags & VALUE_COMP_NAME) { 00081 Success = (CmpCompareCompressedName(Name, 00082 pchild->Name, 00083 pchild->NameLength)==0); 00084 } else { 00085 Candidate.Length = pchild->NameLength; 00086 Candidate.MaximumLength = Candidate.Length; 00087 Candidate.Buffer = pchild->Name; 00088 Success = (RtlCompareUnicodeString(Name, 00089 &Candidate, 00090 TRUE)==0); 00091 } 00092 00093 if (Success) { 00094 // 00095 // Success, return data to caller and exit 00096 // 00097 00098 if (ARGUMENT_PRESENT(ChildIndex)) { 00099 *ChildIndex = i; 00100 } 00101 if (ARGUMENT_PRESENT(ChildAddress)) { 00102 *ChildAddress = (PCELL_DATA)pchild; 00103 } 00104 return(List->u.KeyList[i]); 00105 } 00106 } 00107 } 00108 00109 return HCELL_NIL; 00110 } 00111 00112 #ifndef _CM_LDR_ 00113 00114 PCELL_DATA 00115 CmpGetValueListFromCache( 00116 IN PHHIVE Hive, 00117 IN PCACHED_CHILD_LIST ChildList, 00118 OUT BOOLEAN *IndexCached 00119 ) 00120 /*++ 00121 00122 Routine Description: 00123 00124 Get the Valve Index Array. Check if it is already cached, if not, cache it and return 00125 the cached entry. 00126 00127 Arguments: 00128 00129 Hive - pointer to hive control structure for hive of interest 00130 00131 ChildList - pointer/index to the Value Index array 00132 00133 IndexCached - Indicating whether Value Index list is cached or not. 00134 00135 Return Value: 00136 00137 Pointer to the Valve Index Array. 00138 00139 --*/ 00140 { 00141 PCELL_DATA List; 00142 ULONG AllocSize; 00143 PCM_CACHED_VALUE_INDEX CachedValueIndex; 00144 ULONG i; 00145 00146 #ifndef _WIN64 00147 *IndexCached = TRUE; 00148 if (CMP_IS_CELL_CACHED(ChildList->ValueList)) { 00149 // 00150 // The entry is already cached. 00151 // 00152 List = CMP_GET_CACHED_CELLDATA(ChildList->ValueList); 00153 } else { 00154 // 00155 // The entry is not cached. The element contains the hive index. 00156 // 00157 List = (PCELL_DATA) HvGetCell(Hive, CMP_GET_CACHED_CELL_INDEX(ChildList->ValueList)); 00158 // 00159 // Allocate a PagedPool to cache the value index cell. 00160 // 00161 00162 AllocSize = ChildList->Count * sizeof(ULONG_PTR) + FIELD_OFFSET(CM_CACHED_VALUE_INDEX, Data); 00163 // Dragos: Changed to catch the memory violator 00164 // it didn't work 00165 //CachedValueIndex = (PCM_CACHED_VALUE_INDEX) ExAllocatePoolWithTagPriority(PagedPool, AllocSize, CM_CACHE_VALUE_INDEX_TAG,NormalPoolPrioritySpecialPoolUnderrun); 00166 CachedValueIndex = (PCM_CACHED_VALUE_INDEX) ExAllocatePoolWithTag(PagedPool, AllocSize, CM_CACHE_VALUE_INDEX_TAG); 00167 00168 if (CachedValueIndex) { 00169 00170 CachedValueIndex->CellIndex = CMP_GET_CACHED_CELL_INDEX(ChildList->ValueList); 00171 for (i=0; i<ChildList->Count; i++) { 00172 CachedValueIndex->Data.List[i] = (ULONG_PTR) List->u.KeyList[i]; 00173 } 00174 00175 ChildList->ValueList = CMP_MARK_CELL_CACHED(CachedValueIndex); 00176 00177 // Trying to catch the BAD guy who writes over our pool. 00178 CmpMakeSpecialPoolReadOnly( CachedValueIndex ); 00179 00180 // 00181 // Now we have the stuff cached, use the cache data. 00182 // 00183 List = CMP_GET_CACHED_CELLDATA(ChildList->ValueList); 00184 } else { 00185 // 00186 // If the allocation fails, just do not cache it. continue. 00187 // 00188 *IndexCached = FALSE; 00189 } 00190 } 00191 #else 00192 List = (PCELL_DATA) HvGetCell(Hive, CMP_GET_CACHED_CELL_INDEX(ChildList->ValueList)); 00193 *IndexCached = FALSE; 00194 #endif 00195 00196 return (List); 00197 } 00198 00199 PCM_KEY_VALUE 00200 CmpGetValueKeyFromCache( 00201 IN PHHIVE Hive, 00202 IN PCELL_DATA List, 00203 IN ULONG Index, 00204 OUT PPCM_CACHED_VALUE *ContainingList, 00205 IN BOOLEAN IndexCached, 00206 OUT BOOLEAN *ValueCached 00207 ) 00208 /*++ 00209 00210 Routine Description: 00211 00212 Get the Valve Node. Check if it is already cached, if not but the index is cached, 00213 cache and return the value node. 00214 00215 Arguments: 00216 00217 Hive - pointer to hive control structure for hive of interest. 00218 00219 List - pointer to the Value Index Array (of ULOONG_PTR if cached and ULONG if non-cached) 00220 00221 Index - Index in the Value index array 00222 00223 ContainlingList - The address of the entry that will receive the found cached value. 00224 00225 IndexCached - Indicate if the index list is cached. If not, everything is from the 00226 original registry data. 00227 00228 ValueCached - Indicating whether Value is cached or not. 00229 00230 Return Value: 00231 00232 Pointer to the Valve Node. 00233 --*/ 00234 { 00235 PCM_KEY_VALUE pchild; 00236 PULONG_PTR CachedList; 00237 ULONG AllocSize; 00238 ULONG CopySize; 00239 PCM_CACHED_VALUE CachedValue; 00240 00241 if (IndexCached) { 00242 // 00243 // The index array is cached, so List is pointing to an array of ULONG_PTR. 00244 // Use CachedList. 00245 // 00246 CachedList = (PULONG_PTR) List; 00247 *ValueCached = TRUE; 00248 if (CMP_IS_CELL_CACHED(CachedList[Index])) { 00249 pchild = CMP_GET_CACHED_KEYVALUE(CachedList[Index]); 00250 *ContainingList = &((PCM_CACHED_VALUE) CachedList[Index]); 00251 } else { 00252 pchild = (PCM_KEY_VALUE) HvGetCell(Hive, List->u.KeyList[Index]); 00253 // 00254 // Allocate a PagedPool to cache the value node. 00255 // 00256 CopySize = (ULONG) HvGetCellSize(Hive, pchild); 00257 AllocSize = CopySize + FIELD_OFFSET(CM_CACHED_VALUE, KeyValue); 00258 00259 // Dragos: Changed to catch the memory violator 00260 // it didn't work 00261 //CachedValue = (PCM_CACHED_VALUE) ExAllocatePoolWithTagPriority(PagedPool, AllocSize, CM_CACHE_VALUE_TAG,NormalPoolPrioritySpecialPoolUnderrun); 00262 CachedValue = (PCM_CACHED_VALUE) ExAllocatePoolWithTag(PagedPool, AllocSize, CM_CACHE_VALUE_TAG); 00263 00264 if (CachedValue) { 00265 // 00266 // Set the information for later use if we need to cache data as well. 00267 // 00268 CachedValue->DataCacheType = CM_CACHE_DATA_NOT_CACHED; 00269 CachedValue->ValueKeySize = (USHORT) CopySize; 00270 00271 RtlCopyMemory((PVOID)&(CachedValue->KeyValue), pchild, CopySize); 00272 00273 00274 // Trying to catch the BAD guy who writes over our pool. 00275 CmpMakeSpecialPoolReadWrite( CMP_GET_CACHED_ADDRESS(CachedList) ); 00276 00277 CachedList[Index] = CMP_MARK_CELL_CACHED(CachedValue); 00278 00279 // Trying to catch the BAD guy who writes over our pool. 00280 CmpMakeSpecialPoolReadOnly( CMP_GET_CACHED_ADDRESS(CachedList) ); 00281 00282 00283 // Trying to catch the BAD guy who writes over our pool. 00284 CmpMakeSpecialPoolReadOnly(CachedValue); 00285 00286 *ContainingList = &((PCM_CACHED_VALUE) CachedList[Index]); 00287 // 00288 // Now we have the stuff cached, use the cache data. 00289 // 00290 pchild = CMP_GET_CACHED_KEYVALUE(CachedValue); 00291 } else { 00292 // 00293 // If the allocation fails, just do not cache it. continue. 00294 // 00295 *ValueCached = FALSE; 00296 } 00297 } 00298 } else { 00299 // 00300 // The Valve Index Array is from the registry hive, just get the cell and move on. 00301 // 00302 pchild = (PCM_KEY_VALUE) HvGetCell(Hive, List->u.KeyList[Index]); 00303 *ValueCached = FALSE; 00304 } 00305 return (pchild); 00306 } 00307 00308 PCM_KEY_VALUE 00309 CmpFindValueByNameFromCache( 00310 IN PHHIVE Hive, 00311 IN PCACHED_CHILD_LIST ChildList, 00312 IN PUNICODE_STRING Name, 00313 OUT PPCM_CACHED_VALUE *ContainingList, 00314 OUT ULONG *Index, 00315 OUT BOOLEAN *ValueCached 00316 ) 00317 /*++ 00318 00319 Routine Description: 00320 00321 Find a value node given a value list array and a value name. It sequentially walk 00322 through each value node to look for a match. If the array and 00323 value nodes touched are not already cached, cache them. 00324 00325 Arguments: 00326 00327 Hive - pointer to hive control structure for hive of interest 00328 00329 ChildList - pointer/index to the Value Index array 00330 00331 Name - name of value to find 00332 00333 ContainlingList - The address of the entry that will receive the found cached value. 00334 00335 Index - pointer to variable to receive index for child 00336 00337 ValueCached - Indicate if the value node is cached. 00338 00339 Return Value: 00340 00341 HCELL_INDEX for the found cell 00342 HCELL_NIL if not found 00343 00344 --*/ 00345 { 00346 NTSTATUS status; 00347 ULONG i; 00348 PCM_KEY_VALUE pchild; 00349 UNICODE_STRING Candidate; 00350 BOOLEAN Success; 00351 PCELL_DATA List; 00352 BOOLEAN IndexCached; 00353 00354 if (ChildList->Count != 0) { 00355 List = CmpGetValueListFromCache(Hive, ChildList, &IndexCached); 00356 00357 for (i = 0; i < ChildList->Count; i++) { 00358 pchild = CmpGetValueKeyFromCache(Hive, List, i, ContainingList, IndexCached, ValueCached); 00359 00360 if (pchild->Flags & VALUE_COMP_NAME) { 00361 Success = (CmpCompareCompressedName(Name, 00362 pchild->Name, 00363 pchild->NameLength)==0); 00364 } else { 00365 Candidate.Length = pchild->NameLength; 00366 Candidate.MaximumLength = Candidate.Length; 00367 Candidate.Buffer = pchild->Name; 00368 Success = (RtlCompareUnicodeString(Name, 00369 &Candidate, 00370 TRUE)==0); 00371 } 00372 00373 if (Success) { 00374 // 00375 // Success, fill the index, return data to caller and exit 00376 // 00377 *Index = i; 00378 return(pchild); 00379 } 00380 } 00381 } 00382 00383 return NULL; 00384 } 00385 00386 #endif

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