00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
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
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
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
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
00151
00152
List =
CMP_GET_CACHED_CELLDATA(ChildList->ValueList);
00153 }
else {
00154
00155
00156
00157
List = (
PCELL_DATA)
HvGetCell(
Hive,
CMP_GET_CACHED_CELL_INDEX(ChildList->ValueList));
00158
00159
00160
00161
00162 AllocSize = ChildList->Count *
sizeof(ULONG_PTR) + FIELD_OFFSET(
CM_CACHED_VALUE_INDEX, Data);
00163
00164
00165
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
00178
CmpMakeSpecialPoolReadOnly( CachedValueIndex );
00179
00180
00181
00182
00183
List =
CMP_GET_CACHED_CELLDATA(ChildList->ValueList);
00184 }
else {
00185
00186
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
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
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
00244
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
00255
00256 CopySize = (ULONG)
HvGetCellSize(
Hive, pchild);
00257 AllocSize = CopySize + FIELD_OFFSET(
CM_CACHED_VALUE, KeyValue);
00258
00259
00260
00261
00262 CachedValue = (
PCM_CACHED_VALUE)
ExAllocatePoolWithTag(
PagedPool, AllocSize, CM_CACHE_VALUE_TAG);
00263
00264
if (CachedValue) {
00265
00266
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
00275
CmpMakeSpecialPoolReadWrite(
CMP_GET_CACHED_ADDRESS(CachedList) );
00276
00277 CachedList[
Index] =
CMP_MARK_CELL_CACHED(CachedValue);
00278
00279
00280
CmpMakeSpecialPoolReadOnly(
CMP_GET_CACHED_ADDRESS(CachedList) );
00281
00282
00283
00284
CmpMakeSpecialPoolReadOnly(CachedValue);
00285
00286 *ContainingList = &((
PCM_CACHED_VALUE) CachedList[
Index]);
00287
00288
00289
00290 pchild =
CMP_GET_CACHED_KEYVALUE(CachedValue);
00291 }
else {
00292
00293
00294
00295 *ValueCached =
FALSE;
00296 }
00297 }
00298 }
else {
00299
00300
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
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
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
00376
00377 *
Index = i;
00378
return(pchild);
00379 }
00380 }
00381 }
00382
00383
return NULL;
00384 }
00385
00386
#endif