ReactOS 0.4.15-dev-8135-g1bc6c90
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
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
30VOID
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
45 OUT PCELL_DATA *CellData,
46 OUT BOOLEAN *IndexIsCached,
47 OUT PHCELL_INDEX ValueListToRelease)
48{
49 PHHIVE Hive;
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
97 IN PCELL_DATA CellData,
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;
107 HCELL_INDEX Cell;
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
141NTAPI
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;
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 */
183 ASSERT(*DataPointer == NULL);
184 return SearchFail;
185 }
186 }
187
188 /* We found the actual data, return success */
189 return SearchSuccess;
190}
191
193NTAPI
196 OUT PCM_CACHED_VALUE **CachedValue,
197 OUT ULONG *Index,
199 OUT BOOLEAN *ValueIsCached,
200 OUT PHCELL_INDEX CellToRelease)
201{
202 PHHIVE Hive;
204 LONG Result;
205 UNICODE_STRING SearchName;
206 PCELL_DATA CellData;
208 PCM_KEY_VALUE KeyValue;
209 BOOLEAN IndexIsCached;
210 ULONG i = 0;
211 HCELL_INDEX Cell = HCELL_NIL;
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
319Quickie:
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
326NTAPI
328 IN PCM_CACHED_VALUE *CachedValue,
329 IN PCM_KEY_VALUE ValueKey,
330 IN BOOLEAN ValueIsCached,
332 IN PVOID KeyValueInformation,
336{
338 PCELL_DATA CellData;
339 USHORT NameSize;
340 ULONG Size, MinimumSize, SizeLeft, KeySize, AlignedData = 0, DataOffset;
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 */
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 */
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 */
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!) */
578
579 /* Check if this is a small key and compute key size */
580 IsSmall = CmpIsKeyValueSmall(&KeySize,
581 CellData->u.KeyValue.DataLength);
582
583 /* Calculate the total size required and the least we can work with */
585 {
588 }
589 else
590 {
593 }
594
595 /* Tell the caller the size we'll finally need, and set success */
598
599 /* Check if the caller is giving us too little */
600 if (Length < MinimumSize)
601 {
602 /* Then fail right now */
604 break;
605 }
606
607 /* Fill out the basic information */
609 {
610 Info->KeyValuePartialInformationAlign64.Type = CellData->u.KeyValue.Type;
611 Info->KeyValuePartialInformationAlign64.DataLength = KeySize;
612 }
613 else
614 {
615 Info->KeyValuePartialInformation.TitleIndex = 0;
616 Info->KeyValuePartialInformation.Type = CellData->u.KeyValue.Type;
617 Info->KeyValuePartialInformation.DataLength = KeySize;
618 }
619
620 /* Now check if the key had any data */
621 if (KeySize > 0)
622 {
623 /* Was it a small key? */
624 if (IsSmall)
625 {
626 /* Then the data is directly into the cell */
627 Buffer = &CellData->u.KeyValue.Data;
628 }
629 else
630 {
631 /* Otherwise, we must retrieve it from the value cache */
633 CachedValue,
634 CellData,
635 ValueIsCached,
636 &Buffer,
637 &BufferAllocated,
638 &CellToRelease);
639 if (Result != SearchSuccess)
640 {
641 /* We failed, nothing should be allocated */
642 ASSERT(Buffer == NULL);
643 ASSERT(BufferAllocated == FALSE);
645 }
646 }
647
648 /* Only the data remains to be copied */
649 SizeLeft = Length - MinimumSize;
650 Size = KeySize;
651
652 /* Check if the caller has no space for it */
653 if (SizeLeft < Size)
654 {
655 /* Truncate what we'll copy, and tell the caller */
656 Size = SizeLeft;
658 }
659
660 /* Sanity check */
661 ASSERT(IsSmall ? (Size <= CM_KEY_VALUE_SMALL) : TRUE);
662
663 /* Make sure we have a valid buffer */
664 if (Buffer)
665 {
666 /* Copy the data into the aligned offset */
668 {
669 RtlCopyMemory(Info->KeyValuePartialInformationAlign64.Data,
670 Buffer,
671 Size);
672 }
673 else
674 {
675 RtlCopyMemory(Info->KeyValuePartialInformation.Data,
676 Buffer,
677 Size);
678 }
679 }
680 }
681
682 /* We're done! */
683 break;
684
685 /* Other information class */
686 default:
687
688 /* We got some class that we don't support */
689 DPRINT1("Caller requested unknown class: %lx\n", KeyValueInformationClass);
691 break;
692 }
693
694 /* Return the search result as well */
695 return Result;
696}
697
699NTAPI
702 IN ULONG Type,
703 IN PVOID Data,
705{
706 VALUE_SEARCH_RETURN_TYPE SearchResult;
707 PCM_KEY_NODE KeyNode;
708 PCM_CACHED_VALUE *CachedValue;
709 ULONG Index;
711 BOOLEAN ValueCached, BufferAllocated = FALSE;
713 HCELL_INDEX ValueCellToRelease = HCELL_NIL, CellToRelease = HCELL_NIL;
714 BOOLEAN IsSmall;
715 ULONG_PTR CompareResult;
716 PAGED_CODE();
717
718 /* Check if this is a symlink */
719 if (Kcb->Flags & KEY_SYM_LINK)
720 {
721 /* We need the exclusive lock */
722 if (!CmpIsKcbLockedExclusive(Kcb) &&
724 {
725 /* We need the exclusive lock */
727 }
728
729 /* Otherwise, get the key node */
730 KeyNode = (PCM_KEY_NODE)HvGetCell(Kcb->KeyHive, Kcb->KeyCell);
731 if (!KeyNode) return SearchFail;
732
733 /* Cleanup the KCB cache */
735
736 /* Sanity checks */
737 ASSERT(!CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList));
738 ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND));
739
740 /* Set the value cache */
741 Kcb->ValueCache.Count = KeyNode->ValueList.Count;
742 Kcb->ValueCache.ValueList = KeyNode->ValueList.List;
743
744 /* Release the cell */
745 HvReleaseCell(Kcb->KeyHive, Kcb->KeyCell);
746 }
747
748 /* Do the search */
749 SearchResult = CmpFindValueByNameFromCache(Kcb,
750 ValueName,
751 &CachedValue,
752 &Index,
753 &Value,
754 &ValueCached,
755 &ValueCellToRelease);
756 if (SearchResult == SearchNeedExclusiveLock)
757 {
758 /* We need the exclusive lock */
760 ASSERT(ValueCellToRelease == HCELL_NIL);
761 ASSERT(Value == NULL);
762 goto Quickie;
763 }
764 else if (SearchResult == SearchSuccess)
765 {
766 /* Sanity check */
767 ASSERT(Value);
768
769 /* First of all, check if the key size and type matches */
770 if ((Type == Value->Type) &&
771 (DataSize == (Value->DataLength & ~CM_KEY_VALUE_SPECIAL_SIZE)))
772 {
773 /* Check if this is a small key */
774 IsSmall = (DataSize <= CM_KEY_VALUE_SMALL) ? TRUE: FALSE;
775 if (IsSmall)
776 {
777 /* Compare against the data directly */
778 Buffer = &Value->Data;
779 }
780 else
781 {
782 /* Do a search */
783 SearchResult = CmpGetValueDataFromCache(Kcb,
784 CachedValue,
786 ValueCached,
787 &Buffer,
788 &BufferAllocated,
789 &CellToRelease);
790 if (SearchResult != SearchSuccess)
791 {
792 /* Sanity checks */
793 ASSERT(Buffer == NULL);
794 ASSERT(BufferAllocated == FALSE);
795 goto Quickie;
796 }
797 }
798
799 /* Now check the data size */
800 if (DataSize)
801 {
802 /* Do the compare */
803 CompareResult = RtlCompareMemory(Buffer,
804 Data,
805 DataSize &
807 }
808 else
809 {
810 /* It's equal */
811 CompareResult = 0;
812 }
813
814 /* Now check if the compare wasn't equal */
815 if (CompareResult != DataSize) SearchResult = SearchFail;
816 }
817 else
818 {
819 /* The length or type isn't equal */
820 SearchResult = SearchFail;
821 }
822 }
823
824Quickie:
825 /* Release the value cell */
826 if (ValueCellToRelease) HvReleaseCell(Kcb->KeyHive, ValueCellToRelease);
827
828 /* Free the buffer */
829 if (BufferAllocated) CmpFree(Buffer, 0);
830
831 /* Free the cell */
832 if (CellToRelease) HvReleaseCell(Kcb->KeyHive, CellToRelease);
833
834 /* Return the search result */
835 return SearchResult;
836}
#define PAGED_CODE()
unsigned char BOOLEAN
Type
Definition: Type.h:7
#define DPRINT1
Definition: precomp.h:8
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
Definition: bufpool.h:45
struct _KEY_VALUE_INFORMATION * PKEY_VALUE_INFORMATION
enum _VALUE_SEARCH_RETURN_TYPE VALUE_SEARCH_RETURN_TYPE
@ SearchSuccess
Definition: cm.h:139
@ SearchNeedExclusiveLock
Definition: cm.h:140
@ SearchFail
Definition: cm.h:141
#define CM_KCB_SYM_LINK_FOUND
Definition: cm.h:55
#define MAXIMUM_CACHED_DATA
Definition: cm.h:113
#define CMP_IS_CELL_CACHED(c)
Definition: cm_x.h:47
#define CmpIsKcbLockedExclusive(k)
Definition: cm_x.h:101
FORCEINLINE BOOLEAN CmpTryToConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
Definition: cm_x.h:173
struct _CELL_DATA * PCELL_DATA
struct _CM_KEY_NODE * PCM_KEY_NODE
#define CM_KEY_VALUE_BIG
Definition: cmdata.h:50
struct _CM_KEY_VALUE * PCM_KEY_VALUE
#define VALUE_COMP_NAME
Definition: cmdata.h:44
#define CM_KEY_VALUE_SPECIAL_SIZE
Definition: cmdata.h:51
#define CM_KEY_VALUE_SMALL
Definition: cmdata.h:49
#define KEY_SYM_LINK
Definition: cmdata.h:34
VOID NTAPI CmpCleanUpKcbValueCache(IN PCM_KEY_CONTROL_BLOCK Kcb)
Definition: cmkcbncb.c:431
#define HvReleaseCell(Hive, Cell)
Definition: cmlib.h:460
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
VOID NTAPI CmpCopyCompressedName(OUT PWCHAR Destination, IN ULONG DestinationLength, IN PWCHAR Source, IN ULONG SourceLength)
Definition: cmname.c:56
static BOOLEAN CmpIsKeyValueSmall(OUT PULONG RealLength, IN ULONG Length)
Definition: cmlib.h:395
LONG NTAPI CmpCompareCompressedName(IN PCUNICODE_STRING SearchName, IN PWCHAR CompressedName, IN ULONG NameLength)
Definition: cmname.c:109
USHORT NTAPI CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
Definition: cmname.c:95
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:457
FORCEINLINE BOOLEAN CmpIsValueCached(IN HCELL_INDEX CellIndex)
Definition: cmvalche.c:17
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
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
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
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
#define ASSERT_VALUE_CACHE()
Definition: cmvalche.c:37
FORCEINLINE VOID CmpSetValueCached(IN PHCELL_INDEX CellIndex)
Definition: cmvalche.c:31
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
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:700
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
IN PFCB IN VBO OUT PLBO OUT PULONG OUT PBOOLEAN Allocated
Definition: fatprocs.h:310
Status
Definition: gdiplustypes.h:25
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
ULONG * PHCELL_INDEX
Definition: hivedata.h:105
#define HCELL_NIL
Definition: hivedata.h:110
ULONG HCELL_INDEX
Definition: hivedata.h:105
#define ASSERT(a)
Definition: mode.c:44
* PNTSTATUS
Definition: strlen.c:14
@ KeyValuePartialInformationAlign64
Definition: reg.c:103
@ KeyValueFullInformationAlign64
Definition: reg.c:102
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
_In_ ULONG _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass
Definition: cmfuncs.h:94
@ KeyValueBasicInformation
Definition: nt_native.h:1180
@ KeyValuePartialInformation
Definition: nt_native.h:1182
@ KeyValueFullInformation
Definition: nt_native.h:1181
enum _KEY_VALUE_INFORMATION_CLASS KEY_VALUE_INFORMATION_CLASS
Definition: reg.c:135
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
union _CELL_DATA::@4308 u
CM_KEY_VALUE KeyValue
Definition: cmdata.h:201
HCELL_INDEX List
Definition: cmdata.h:75
ULONG Count
Definition: cmdata.h:74
CHILD_LIST ValueList
Definition: cmdata.h:103
ULONG Type
Definition: cmdata.h:128
HCELL_INDEX Data
Definition: cmdata.h:127
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:131
USHORT NameLength
Definition: cmdata.h:125
USHORT Flags
Definition: cmdata.h:129
ULONG DataLength
Definition: cmdata.h:126
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFCHILDLIST * ChildList
Definition: wdfchildlist.h:481
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define FORCEINLINE
Definition: wdftypes.h:67
_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:409