ReactOS  0.4.13-dev-961-g238ea69
cmvalche.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/config/cmvalche.c
5  * PURPOSE: Configuration Manager - Value Cell Cache
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include "ntoskrnl.h"
12 #define NDEBUG
13 #include "debug.h"
14 
16 BOOLEAN
18 {
19  /* Make sure that the cell is valid in the first place */
20  if (CellIndex == HCELL_NIL) return FALSE;
21 
22  /*Is this cell actually a pointer to the cached value data? */
23  if (CellIndex & 1) return TRUE;
24 
25  /* This is a regular cell */
26  return FALSE;
27 }
28 
30 VOID
32 {
33  /* Set the cached bit */
34  *CellIndex |= 1;
35 }
36 
37 #define ASSERT_VALUE_CACHE() \
38  ASSERTMSG("Cached Values Not Yet Supported!\n", FALSE);
39 
40 /* FUNCTIONS *****************************************************************/
41 
43 NTAPI
45  OUT PCELL_DATA *CellData,
46  OUT BOOLEAN *IndexIsCached,
47  OUT PHCELL_INDEX ValueListToRelease)
48 {
49  PHHIVE Hive;
50  PCACHED_CHILD_LIST ChildList;
51  HCELL_INDEX CellToRelease;
52 
53  /* Set defaults */
54  *ValueListToRelease = HCELL_NIL;
55  *IndexIsCached = FALSE;
56 
57  /* Get the hive and value cache */
58  Hive = Kcb->KeyHive;
59  ChildList = &Kcb->ValueCache;
60 
61  /* Check if the value is cached */
62  if (CmpIsValueCached(ChildList->ValueList))
63  {
64  /* It is: we don't expect this yet! */
66  *IndexIsCached = TRUE;
67  *CellData = NULL;
68  }
69  else
70  {
71  /* Make sure the KCB is locked exclusive */
72  if (!(CmpIsKcbLockedExclusive(Kcb)) &&
74  {
75  /* We need the exclusive lock */
77  }
78 
79  /* Select the value list as our cell, and get the actual list array */
80  CellToRelease = ChildList->ValueList;
81  *CellData = (PCELL_DATA)HvGetCell(Hive, CellToRelease);
82  if (!(*CellData)) return SearchFail;
83 
84  /* FIXME: Here we would cache the value */
85 
86  /* Return the cell to be released */
87  *ValueListToRelease = CellToRelease;
88  }
89 
90  /* If we got here, then the value list was found */
91  return SearchSuccess;
92 }
93 
95 NTAPI
97  IN PCELL_DATA CellData,
98  IN ULONG Index,
99  OUT PCM_CACHED_VALUE **CachedValue,
101  IN BOOLEAN IndexIsCached,
102  OUT BOOLEAN *ValueIsCached,
103  OUT PHCELL_INDEX CellToRelease)
104 {
105  PHHIVE Hive;
106  PCM_KEY_VALUE KeyValue;
108 
109  /* Set defaults */
110  *CellToRelease = HCELL_NIL;
111  *Value = NULL;
112  *ValueIsCached = FALSE;
113 
114  /* Get the hive */
115  Hive = Kcb->KeyHive;
116 
117  /* Check if the index was cached */
118  if (IndexIsCached)
119  {
120  /* Not expected yet! */
122  *ValueIsCached = TRUE;
123  }
124  else
125  {
126  /* Get the cell index and the key value associated to it */
127  Cell = CellData->u.KeyList[Index];
128  KeyValue = (PCM_KEY_VALUE)HvGetCell(Hive, Cell);
129  if (!KeyValue) return SearchFail;
130 
131  /* Return the cell and the actual key value */
132  *CellToRelease = Cell;
133  *Value = KeyValue;
134  }
135 
136  /* If we got here, then we found the key value */
137  return SearchSuccess;
138 }
139 
141 NTAPI
143  IN PCM_CACHED_VALUE *CachedValue,
144  IN PCELL_DATA ValueKey,
145  IN BOOLEAN ValueIsCached,
146  OUT PVOID *DataPointer,
148  OUT PHCELL_INDEX CellToRelease)
149 {
150  PHHIVE Hive;
151  ULONG Length;
152 
153  /* Sanity checks */
155  ASSERT((ValueKey->u.KeyValue.DataLength & CM_KEY_VALUE_SPECIAL_SIZE) == 0);
156 
157  /* Set defaults */
158  *DataPointer = NULL;
159  *Allocated = FALSE;
160  *CellToRelease = HCELL_NIL;
161 
162  /* Get the hive */
163  Hive = Kcb->KeyHive;
164 
165  /* Check it the value is cached */
166  if (ValueIsCached)
167  {
168  /* This isn't expected! */
170  }
171  else
172  {
173  /* It's not, get the value data using the typical routine */
174  if (!CmpGetValueData(Hive,
175  &ValueKey->u.KeyValue,
176  &Length,
177  DataPointer,
178  Allocated,
179  CellToRelease))
180  {
181  /* Nothing found: make sure no data was allocated */
182  ASSERT(*Allocated == FALSE);
183  ASSERT(*DataPointer == NULL);
184  return SearchFail;
185  }
186  }
187 
188  /* We found the actual data, return success */
189  return SearchSuccess;
190 }
191 
193 NTAPI
196  OUT PCM_CACHED_VALUE **CachedValue,
197  OUT ULONG *Index,
199  OUT BOOLEAN *ValueIsCached,
200  OUT PHCELL_INDEX CellToRelease)
201 {
202  PHHIVE Hive;
203  VALUE_SEARCH_RETURN_TYPE SearchResult = SearchFail;
204  LONG Result;
205  UNICODE_STRING SearchName;
206  PCELL_DATA CellData;
207  PCACHED_CHILD_LIST ChildList;
208  PCM_KEY_VALUE KeyValue;
209  BOOLEAN IndexIsCached;
210  ULONG i = 0;
212 
213  /* Set defaults */
214  *CellToRelease = HCELL_NIL;
215  *Value = NULL;
216 
217  /* Get the hive and child list */
218  Hive = Kcb->KeyHive;
219  ChildList = &Kcb->ValueCache;
220 
221  /* Check if the child list has any entries */
222  if (ChildList->Count != 0)
223  {
224  /* Get the value list associated to this child list */
225  SearchResult = CmpGetValueListFromCache(Kcb,
226  &CellData,
227  &IndexIsCached,
228  &Cell);
229  if (SearchResult != SearchSuccess)
230  {
231  /* We either failed or need the exclusive lock */
232  ASSERT((SearchResult == SearchFail) || !(CmpIsKcbLockedExclusive(Kcb)));
233  ASSERT(Cell == HCELL_NIL);
234  return SearchResult;
235  }
236 
237  /* The index shouldn't be cached right now */
238  if (IndexIsCached) ASSERT_VALUE_CACHE();
239 
240  /* Loop every value */
241  while (TRUE)
242  {
243  /* Check if there's any cell to release */
244  if (*CellToRelease != HCELL_NIL)
245  {
246  /* Release it now */
247  HvReleaseCell(Hive, *CellToRelease);
248  *CellToRelease = HCELL_NIL;
249  }
250 
251  /* Get the key value for this index */
252  SearchResult = CmpGetValueKeyFromCache(Kcb,
253  CellData,
254  i,
255  CachedValue,
256  Value,
257  IndexIsCached,
258  ValueIsCached,
259  CellToRelease);
260  if (SearchResult != SearchSuccess)
261  {
262  /* We either failed or need the exclusive lock */
263  ASSERT((SearchResult == SearchFail) || !(CmpIsKcbLockedExclusive(Kcb)));
264  ASSERT(Cell == HCELL_NIL);
265  return SearchResult;
266  }
267 
268  /* Check if the both the index and the value are cached */
269  if (IndexIsCached && *ValueIsCached)
270  {
271  /* We don't expect this yet */
273  Result = -1;
274  }
275  else
276  {
277  /* No cache, so try to compare the name. Is it compressed? */
278  KeyValue = *Value;
279  if (KeyValue->Flags & VALUE_COMP_NAME)
280  {
281  /* It is, do a compressed name comparison */
283  KeyValue->Name,
284  KeyValue->NameLength);
285  }
286  else
287  {
288  /* It's not compressed, so do a standard comparison */
289  SearchName.Length = KeyValue->NameLength;
290  SearchName.MaximumLength = SearchName.Length;
291  SearchName.Buffer = KeyValue->Name;
292  Result = RtlCompareUnicodeString(Name, &SearchName, TRUE);
293  }
294  }
295 
296  /* Check if we found the value data */
297  if (!Result)
298  {
299  /* We have, return the index of the value and success */
300  *Index = i;
301  SearchResult = SearchSuccess;
302  goto Quickie;
303  }
304 
305  /* We didn't find it, try the next entry */
306  if (++i == ChildList->Count)
307  {
308  /* The entire list was parsed, fail */
309  *Value = NULL;
310  SearchResult = SearchFail;
311  goto Quickie;
312  }
313  }
314  }
315 
316  /* We should only get here if the child list is empty */
317  ASSERT(ChildList->Count == 0);
318 
319 Quickie:
320  /* Release the value list cell if required, and return search result */
321  if (Cell != HCELL_NIL) HvReleaseCell(Hive, Cell);
322  return SearchResult;
323 }
324 
326 NTAPI
328  IN PCM_CACHED_VALUE *CachedValue,
329  IN PCM_KEY_VALUE ValueKey,
330  IN BOOLEAN ValueIsCached,
332  IN PVOID KeyValueInformation,
333  IN ULONG Length,
336 {
337  PKEY_VALUE_INFORMATION Info = (PKEY_VALUE_INFORMATION)KeyValueInformation;
338  PCELL_DATA CellData;
339  USHORT NameSize;
340  ULONG Size, MinimumSize, SizeLeft, KeySize, AlignedData = 0, DataOffset;
341  PVOID Buffer;
342  BOOLEAN IsSmall, BufferAllocated = FALSE;
343  HCELL_INDEX CellToRelease = HCELL_NIL;
345 
346  /* Get the value data */
347  CellData = (PCELL_DATA)ValueKey;
348 
349  /* Check if the value is compressed */
350  if (CellData->u.KeyValue.Flags & VALUE_COMP_NAME)
351  {
352  /* Get the compressed name size */
353  NameSize = CmpCompressedNameSize(CellData->u.KeyValue.Name,
354  CellData->u.KeyValue.NameLength);
355  }
356  else
357  {
358  /* Get the real size */
359  NameSize = CellData->u.KeyValue.NameLength;
360  }
361 
362  /* Check what kind of information the caller is requesting */
363  switch (KeyValueInformationClass)
364  {
365  /* Basic information */
367 
368  /* This is how much size we'll need */
370 
371  /* This is the minimum we can work with */
373 
374  /* Return the size we'd like, and assume success */
375  *ResultLength = Size;
377 
378  /* Check if the caller gave us below our minimum */
379  if (Length < MinimumSize)
380  {
381  /* Then we must fail */
383  break;
384  }
385 
386  /* Fill out the basic information */
387  Info->KeyValueBasicInformation.TitleIndex = 0;
388  Info->KeyValueBasicInformation.Type = CellData->u.KeyValue.Type;
389  Info->KeyValueBasicInformation.NameLength = NameSize;
390 
391  /* Now only the name is left */
392  SizeLeft = Length - MinimumSize;
393  Size = NameSize;
394 
395  /* Check if the remaining buffer is too small for the name */
396  if (SizeLeft < Size)
397  {
398  /* Copy only as much as can fit, and tell the caller */
399  Size = SizeLeft;
401  }
402 
403  /* Check if this is a compressed name */
404  if (CellData->u.KeyValue.Flags & VALUE_COMP_NAME)
405  {
406  /* Copy as much as we can of the compressed name */
407  CmpCopyCompressedName(Info->KeyValueBasicInformation.Name,
408  Size,
409  CellData->u.KeyValue.Name,
410  CellData->u.KeyValue.NameLength);
411  }
412  else
413  {
414  /* Copy as much as we can of the raw name */
415  RtlCopyMemory(Info->KeyValueBasicInformation.Name,
416  CellData->u.KeyValue.Name,
417  Size);
418  }
419 
420  /* We're all done */
421  break;
422 
423  /* Full key information */
426 
427  /* Check if this is a small key and compute key size */
428  IsSmall = CmpIsKeyValueSmall(&KeySize,
429  CellData->u.KeyValue.DataLength);
430 
431  /* Calculate the total size required */
433  NameSize +
434  KeySize;
435 
436  /* And this is the least we can work with */
438 
439  /* Check if there's any key data */
440  if (KeySize > 0)
441  {
442  /* Calculate the data offset */
443  DataOffset = Size - KeySize;
444 
445 #ifdef _WIN64
446  /* On 64-bit, always align to 8 bytes */
447  AlignedData = ALIGN_UP(DataOffset, ULONGLONG);
448 #else
449  /* On 32-bit, align the offset to 4 or 8 bytes */
451  {
452  AlignedData = ALIGN_UP(DataOffset, ULONGLONG);
453  }
454  else
455  {
456  AlignedData = ALIGN_UP(DataOffset, ULONG);
457  }
458 #endif
459  /* If alignment was required, we'll need more space */
460  if (AlignedData > DataOffset) Size += (AlignedData-DataOffset);
461  }
462 
463  /* Tell the caller the size we'll finally need, and set success */
464  *ResultLength = Size;
466 
467  /* Check if the caller is giving us too little */
468  if (Length < MinimumSize)
469  {
470  /* Then fail right now */
472  break;
473  }
474 
475  /* Fill out the basic information */
476  Info->KeyValueFullInformation.TitleIndex = 0;
477  Info->KeyValueFullInformation.Type = CellData->u.KeyValue.Type;
478  Info->KeyValueFullInformation.DataLength = KeySize;
479  Info->KeyValueFullInformation.NameLength = NameSize;
480 
481  /* Only the name is left now */
482  SizeLeft = Length - MinimumSize;
483  Size = NameSize;
484 
485  /* Check if the name fits */
486  if (SizeLeft < Size)
487  {
488  /* It doesn't, truncate what we'll copy, and tell the caller */
489  Size = SizeLeft;
491  }
492 
493  /* Check if this key value is compressed */
494  if (CellData->u.KeyValue.Flags & VALUE_COMP_NAME)
495  {
496  /* It is, copy the compressed name */
497  CmpCopyCompressedName(Info->KeyValueFullInformation.Name,
498  Size,
499  CellData->u.KeyValue.Name,
500  CellData->u.KeyValue.NameLength);
501  }
502  else
503  {
504  /* It's not, copy the raw name */
505  RtlCopyMemory(Info->KeyValueFullInformation.Name,
506  CellData->u.KeyValue.Name,
507  Size);
508  }
509 
510  /* Now check if the key had any data */
511  if (KeySize > 0)
512  {
513  /* Was it a small key? */
514  if (IsSmall)
515  {
516  /* Then the data is directly into the cell */
517  Buffer = &CellData->u.KeyValue.Data;
518  }
519  else
520  {
521  /* Otherwise, we must retrieve it from the value cache */
523  CachedValue,
524  CellData,
525  ValueIsCached,
526  &Buffer,
527  &BufferAllocated,
528  &CellToRelease);
529  if (Result != SearchSuccess)
530  {
531  /* We failed, nothing should be allocated */
532  ASSERT(Buffer == NULL);
533  ASSERT(BufferAllocated == FALSE);
535  }
536  }
537 
538  /* Now that we know we truly have data, set its offset */
539  Info->KeyValueFullInformation.DataOffset = AlignedData;
540 
541  /* Only the data remains to be copied */
542  SizeLeft = (((LONG)Length - (LONG)AlignedData) < 0) ?
543  0 : (Length - AlignedData);
544  Size = KeySize;
545 
546  /* Check if the caller has no space for it */
547  if (SizeLeft < Size)
548  {
549  /* Truncate what we'll copy, and tell the caller */
550  Size = SizeLeft;
552  }
553 
554  /* Sanity check */
555  ASSERT((IsSmall ? (Size <= CM_KEY_VALUE_SMALL) : TRUE));
556 
557  /* Make sure we have a valid buffer */
558  if (Buffer)
559  {
560  /* Copy the data into the aligned offset */
561  RtlCopyMemory((PVOID)((ULONG_PTR)Info + AlignedData),
562  Buffer,
563  Size);
564  }
565  }
566  else
567  {
568  /* We don't have any data, set the offset to -1, not 0! */
569  Info->KeyValueFullInformation.DataOffset = 0xFFFFFFFF;
570  }
571 
572  /* We're done! */
573  break;
574 
575  /* Partial information requested (no name or alignment!) */
577 
578  /* Check if this is a small key and compute key size */
579  IsSmall = CmpIsKeyValueSmall(&KeySize,
580  CellData->u.KeyValue.DataLength);
581 
582  /* Calculate the total size required */
584 
585  /* And this is the least we can work with */
587 
588  /* Tell the caller the size we'll finally need, and set success */
589  *ResultLength = Size;
591 
592  /* Check if the caller is giving us too little */
593  if (Length < MinimumSize)
594  {
595  /* Then fail right now */
597  break;
598  }
599 
600  /* Fill out the basic information */
601  Info->KeyValuePartialInformation.TitleIndex = 0;
602  Info->KeyValuePartialInformation.Type = CellData->u.KeyValue.Type;
603  Info->KeyValuePartialInformation.DataLength = KeySize;
604 
605  /* Now check if the key had any data */
606  if (KeySize > 0)
607  {
608  /* Was it a small key? */
609  if (IsSmall)
610  {
611  /* Then the data is directly into the cell */
612  Buffer = &CellData->u.KeyValue.Data;
613  }
614  else
615  {
616  /* Otherwise, we must retrieve it from the value cache */
618  CachedValue,
619  CellData,
620  ValueIsCached,
621  &Buffer,
622  &BufferAllocated,
623  &CellToRelease);
624  if (Result != SearchSuccess)
625  {
626  /* We failed, nothing should be allocated */
627  ASSERT(Buffer == NULL);
628  ASSERT(BufferAllocated == FALSE);
630  }
631  }
632 
633  /* Only the data remains to be copied */
634  SizeLeft = Length - MinimumSize;
635  Size = KeySize;
636 
637  /* Check if the caller has no space for it */
638  if (SizeLeft < Size)
639  {
640  /* Truncate what we'll copy, and tell the caller */
641  Size = SizeLeft;
643  }
644 
645  /* Sanity check */
646  ASSERT((IsSmall ? (Size <= CM_KEY_VALUE_SMALL) : TRUE));
647 
648  /* Make sure we have a valid buffer */
649  if (Buffer)
650  {
651  /* Copy the data into the aligned offset */
652  RtlCopyMemory(Info->KeyValuePartialInformation.Data,
653  Buffer,
654  Size);
655  }
656  }
657 
658  /* We're done! */
659  break;
660 
661  /* Other information class */
662  default:
663 
664  /* We got some class that we don't support */
665  DPRINT1("Caller requested unknown class: %lx\n", KeyValueInformationClass);
667  break;
668  }
669 
670  /* Return the search result as well */
671  return Result;
672 }
673 
675 NTAPI
678  IN ULONG Type,
679  IN PVOID Data,
680  IN ULONG DataSize)
681 {
682  VALUE_SEARCH_RETURN_TYPE SearchResult;
683  PCM_KEY_NODE KeyNode;
684  PCM_CACHED_VALUE *CachedValue;
685  ULONG Index;
687  BOOLEAN ValueCached, BufferAllocated = FALSE;
688  PVOID Buffer;
689  HCELL_INDEX ValueCellToRelease = HCELL_NIL, CellToRelease = HCELL_NIL;
690  BOOLEAN IsSmall;
691  ULONG_PTR CompareResult;
692  PAGED_CODE();
693 
694  /* Check if this is a symlink */
695  if (Kcb->Flags & KEY_SYM_LINK)
696  {
697  /* We need the exclusive lock */
698  if (!(CmpIsKcbLockedExclusive(Kcb)) &&
700  {
701  /* We need the exclusive lock */
703  }
704 
705  /* Otherwise, get the key node */
706  KeyNode = (PCM_KEY_NODE)HvGetCell(Kcb->KeyHive, Kcb->KeyCell);
707  if (!KeyNode) return SearchFail;
708 
709  /* Cleanup the KCB cache */
711 
712  /* Sanity checks */
713  ASSERT(!(CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList)));
714  ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND));
715 
716  /* Set the value cache */
717  Kcb->ValueCache.Count = KeyNode->ValueList.Count;
718  Kcb->ValueCache.ValueList = KeyNode->ValueList.List;
719 
720  /* Release the cell */
721  HvReleaseCell(Kcb->KeyHive, Kcb->KeyCell);
722  }
723 
724  /* Do the search */
725  SearchResult = CmpFindValueByNameFromCache(Kcb,
726  ValueName,
727  &CachedValue,
728  &Index,
729  &Value,
730  &ValueCached,
731  &ValueCellToRelease);
732  if (SearchResult == SearchNeedExclusiveLock)
733  {
734  /* We need the exclusive lock */
736  ASSERT(ValueCellToRelease == HCELL_NIL);
737  ASSERT(Value == NULL);
738  goto Quickie;
739  }
740  else if (SearchResult == SearchSuccess)
741  {
742  /* Sanity check */
743  ASSERT(Value);
744 
745  /* First of all, check if the key size and type matches */
746  if ((Type == Value->Type) &&
747  (DataSize == (Value->DataLength & ~CM_KEY_VALUE_SPECIAL_SIZE)))
748  {
749  /* Check if this is a small key */
750  IsSmall = (DataSize <= CM_KEY_VALUE_SMALL) ? TRUE: FALSE;
751  if (IsSmall)
752  {
753  /* Compare against the data directly */
754  Buffer = &Value->Data;
755  }
756  else
757  {
758  /* Do a search */
759  SearchResult = CmpGetValueDataFromCache(Kcb,
760  CachedValue,
761  (PCELL_DATA)Value,
762  ValueCached,
763  &Buffer,
764  &BufferAllocated,
765  &CellToRelease);
766  if (SearchResult != SearchSuccess)
767  {
768  /* Sanity checks */
769  ASSERT(Buffer == NULL);
770  ASSERT(BufferAllocated == FALSE);
771  goto Quickie;
772  }
773  }
774 
775  /* Now check the data size */
776  if (DataSize)
777  {
778  /* Do the compare */
779  CompareResult = RtlCompareMemory(Buffer,
780  Data,
781  DataSize &
783  }
784  else
785  {
786  /* It's equal */
787  CompareResult = 0;
788  }
789 
790  /* Now check if the compare wasn't equal */
791  if (CompareResult != DataSize) SearchResult = SearchFail;
792  }
793  else
794  {
795  /* The length or type isn't equal */
796  SearchResult = SearchFail;
797  }
798  }
799 
800 Quickie:
801  /* Release the value cell */
802  if (ValueCellToRelease) HvReleaseCell(Kcb->KeyHive, ValueCellToRelease);
803 
804  /* Free the buffer */
805  if (BufferAllocated) CmpFree(Buffer, 0);
806 
807  /* Free the cell */
808  if (CellToRelease) HvReleaseCell(Kcb->KeyHive, CellToRelease);
809 
810  /* Return the search result */
811  return SearchResult;
812 }
VALUE_SEARCH_RETURN_TYPE NTAPI CmpGetValueKeyFromCache(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCELL_DATA CellData, IN ULONG Index, OUT PCM_CACHED_VALUE **CachedValue, OUT PCM_KEY_VALUE *Value, IN BOOLEAN IndexIsCached, OUT BOOLEAN *ValueIsCached, OUT PHCELL_INDEX CellToRelease)
Definition: cmvalche.c:96
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
* PNTSTATUS
Definition: strlen.c:14
HCELL_INDEX Data
Definition: cmdata.h:127
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VALUE_SEARCH_RETURN_TYPE NTAPI CmpCompareNewValueDataAgainstKCBCache(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PUNICODE_STRING ValueName, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: cmvalche.c:676
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Definition: cm.h:136
HCELL_INDEX List
Definition: cmdata.h:75
Type
Definition: Type.h:6
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
USHORT Flags
Definition: cmdata.h:129
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
VALUE_SEARCH_RETURN_TYPE NTAPI CmpQueryKeyValueData(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCM_CACHED_VALUE *CachedValue, IN PCM_KEY_VALUE ValueKey, IN BOOLEAN ValueIsCached, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, OUT PULONG ResultLength, OUT PNTSTATUS Status)
Definition: cmvalche.c:327
BOOLEAN NTAPI CmpGetValueData(IN PHHIVE Hive, IN PCM_KEY_VALUE Value, OUT PULONG Length, OUT PVOID *Buffer, OUT PBOOLEAN BufferAllocated, OUT PHCELL_INDEX CellToRelease)
Definition: cmvalue.c:125
#define HvReleaseCell(h, c)
Definition: cmlib.h:390
#define HCELL_NIL
Definition: hivedata.h:85
#define CMP_IS_CELL_CACHED(c)
Definition: cm_x.h:28
CM_KEY_VALUE KeyValue
Definition: cmdata.h:201
ULONG ValueList
Definition: cm.h:209
#define CM_KEY_VALUE_SPECIAL_SIZE
Definition: cm.h:73
struct TraceInfo Info
#define PAGED_CODE()
Definition: video.h:57
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG DataLength
Definition: cmdata.h:126
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct _CELL_DATA * PCELL_DATA
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
USHORT NameLength
Definition: cmdata.h:125
ULONG Count
Definition: cm.h:206
long LONG
Definition: pedump.c:60
VOID NTAPI CmpCopyCompressedName(OUT PWCHAR Destination, IN ULONG DestinationLength, IN PWCHAR Source, IN ULONG SourceLength)
Definition: cmname.c:56
PVOID CMAPI HvGetCell(PHHIVE RegistryHive, HCELL_INDEX CellOffset)
Definition: hivecell.c:67
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:131
VALUE_SEARCH_RETURN_TYPE NTAPI CmpGetValueListFromCache(IN PCM_KEY_CONTROL_BLOCK Kcb, OUT PCELL_DATA *CellData, OUT BOOLEAN *IndexIsCached, OUT PHCELL_INDEX ValueListToRelease)
Definition: cmvalche.c:44
static BOOLEAN CmpIsKeyValueSmall(OUT PULONG RealLength, IN ULONG Length)
Definition: cmlib.h:323
unsigned char BOOLEAN
IN PFCB IN VBO OUT PLBO OUT PULONG OUT PBOOLEAN Allocated
Definition: fatprocs.h:297
smooth NULL
Definition: ftsmooth.c:416
struct _CM_KEY_NODE * PCM_KEY_NODE
struct _KEY_VALUE_INFORMATION * PKEY_VALUE_INFORMATION
ULONG * PHCELL_INDEX
Definition: hivedata.h:80
#define FORCEINLINE
Definition: ntbasedef.h:221
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define MAXIMUM_CACHED_DATA
Definition: cm.h:114
Definition: bufpool.h:45
struct zzzz Cell
CHILD_LIST ValueList
Definition: cmdata.h:103
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
ULONG HCELL_INDEX
Definition: hivedata.h:80
#define VALUE_COMP_NAME
Definition: cmdata.h:44
uint64_t ULONGLONG
Definition: typedefs.h:65
Definition: bzip2.c:1694
static const UCHAR Index[8]
Definition: usbohci.c:18
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define CM_KEY_VALUE_SMALL
Definition: cm.h:71
char * PBOOLEAN
Definition: retypes.h:11
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
ULONG Count
Definition: cmdata.h:74
union _CELL_DATA::@3900 u
Status
Definition: gdiplustypes.h:24
#define KEY_SYM_LINK
Definition: cmdata.h:34
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
FORCEINLINE BOOLEAN CmpTryToConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
Definition: cm_x.h:140
unsigned short USHORT
Definition: pedump.c:61
struct _CM_KEY_VALUE * PCM_KEY_VALUE
#define ASSERT_VALUE_CACHE()
Definition: cmvalche.c:37
FORCEINLINE VOID CmpSetValueCached(IN PHCELL_INDEX CellIndex)
Definition: cmvalche.c:31
LONG NTAPI CmpCompareCompressedName(IN PCUNICODE_STRING SearchName, IN PWCHAR CompressedName, IN ULONG NameLength)
Definition: cmname.c:109
ULONG Type
Definition: cmdata.h:128
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define CM_KEY_VALUE_BIG
Definition: cm.h:72
unsigned int * PULONG
Definition: retypes.h:1
#define DPRINT1
Definition: precomp.h:8
VALUE_SEARCH_RETURN_TYPE NTAPI CmpFindValueByNameFromCache(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCUNICODE_STRING Name, OUT PCM_CACHED_VALUE **CachedValue, OUT ULONG *Index, OUT PCM_KEY_VALUE *Value, OUT BOOLEAN *ValueIsCached, OUT PHCELL_INDEX CellToRelease)
Definition: cmvalche.c:194
#define CmpIsKcbLockedExclusive(k)
Definition: cm_x.h:82
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI CmpCleanUpKcbValueCache(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:431
enum _VALUE_SEARCH_RETURN_TYPE VALUE_SEARCH_RETURN_TYPE
_In_ ULONG _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
Definition: cmfuncs.h:93
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2777
VALUE_SEARCH_RETURN_TYPE NTAPI CmpGetValueDataFromCache(IN PCM_KEY_CONTROL_BLOCK Kcb, IN PCM_CACHED_VALUE *CachedValue, IN PCELL_DATA ValueKey, IN BOOLEAN ValueIsCached, OUT PVOID *DataPointer, OUT PBOOLEAN Allocated, OUT PHCELL_INDEX CellToRelease)
Definition: cmvalche.c:142
USHORT NTAPI CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
Definition: cmname.c:95
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
enum _KEY_VALUE_INFORMATION_CLASS KEY_VALUE_INFORMATION_CLASS
Definition: reg.c:135
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
FORCEINLINE BOOLEAN CmpIsValueCached(IN HCELL_INDEX CellIndex)
Definition: cmvalche.c:17
#define CM_KCB_SYM_LINK_FOUND
Definition: cm.h:57