ReactOS 0.4.15-dev-8109-gd7be748
cmvalche.c File Reference
#include "ntoskrnl.h"
#include "debug.h"
Include dependency graph for cmvalche.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define ASSERT_VALUE_CACHE()    ASSERTMSG("Cached Values Not Yet Supported!\n", FALSE);
 

Functions

FORCEINLINE BOOLEAN CmpIsValueCached (IN HCELL_INDEX CellIndex)
 
FORCEINLINE VOID CmpSetValueCached (IN PHCELL_INDEX CellIndex)
 
VALUE_SEARCH_RETURN_TYPE NTAPI CmpGetValueListFromCache (IN PCM_KEY_CONTROL_BLOCK Kcb, OUT PCELL_DATA *CellData, OUT BOOLEAN *IndexIsCached, OUT PHCELL_INDEX ValueListToRelease)
 
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)
 
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)
 
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)
 
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)
 
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)
 

Macro Definition Documentation

◆ ASSERT_VALUE_CACHE

#define ASSERT_VALUE_CACHE ( )     ASSERTMSG("Cached Values Not Yet Supported!\n", FALSE);

Definition at line 37 of file cmvalche.c.

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file cmvalche.c.

Function Documentation

◆ CmpCompareNewValueDataAgainstKCBCache()

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 at line 700 of file cmvalche.c.

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
VOID NTAPI CmpFree(_In_ PVOID Ptr, _In_ ULONG Quota)
Definition: bootreg.c:105
Definition: bufpool.h:45
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 CMP_IS_CELL_CACHED(c)
Definition: cm_x.h:34
#define CmpIsKcbLockedExclusive(k)
Definition: cm_x.h:88
FORCEINLINE BOOLEAN CmpTryToConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
Definition: cm_x.h:156
struct _CM_KEY_NODE * PCM_KEY_NODE
#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
#define HvGetCell(Hive, Cell)
Definition: cmlib.h:457
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 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
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define HCELL_NIL
Definition: hivedata.h:110
ULONG HCELL_INDEX
Definition: hivedata.h:105
#define ASSERT(a)
Definition: mode.c:44
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
HCELL_INDEX List
Definition: cmdata.h:75
ULONG Count
Definition: cmdata.h:74
CHILD_LIST ValueList
Definition: cmdata.h:103
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index
_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

Referenced by CmSetValueKey().

◆ CmpFindValueByNameFromCache()

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 at line 194 of file cmvalche.c.

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}
#define VALUE_COMP_NAME
Definition: cmdata.h:44
LONG NTAPI CmpCompareCompressedName(IN PCUNICODE_STRING SearchName, IN PWCHAR CompressedName, IN ULONG NameLength)
Definition: cmname.c:109
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
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
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
long LONG
Definition: pedump.c:60
WCHAR Name[ANYSIZE_ARRAY]
Definition: cmdata.h:131
USHORT NameLength
Definition: cmdata.h:125
USHORT Flags
Definition: cmdata.h:129
USHORT MaximumLength
Definition: env_spec_w32.h:370
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFCHILDLIST * ChildList
Definition: wdfchildlist.h:481
_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

Referenced by CmpCompareNewValueDataAgainstKCBCache(), and CmQueryValueKey().

◆ CmpGetValueDataFromCache()

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 at line 142 of file cmvalche.c.

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}
#define MAXIMUM_CACHED_DATA
Definition: cm.h:113
#define CM_KEY_VALUE_BIG
Definition: cmdata.h:50
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
IN PFCB IN VBO OUT PLBO OUT PULONG OUT PBOOLEAN Allocated
Definition: fatprocs.h:310
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102

Referenced by CmpCompareNewValueDataAgainstKCBCache(), and CmpQueryKeyValueData().

◆ CmpGetValueKeyFromCache()

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 at line 96 of file cmvalche.c.

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}
struct _CM_KEY_VALUE * PCM_KEY_VALUE

Referenced by CmEnumerateValueKey(), and CmpFindValueByNameFromCache().

◆ CmpGetValueListFromCache()

VALUE_SEARCH_RETURN_TYPE NTAPI CmpGetValueListFromCache ( IN PCM_KEY_CONTROL_BLOCK  Kcb,
OUT PCELL_DATA CellData,
OUT BOOLEAN IndexIsCached,
OUT PHCELL_INDEX  ValueListToRelease 
)

Definition at line 44 of file cmvalche.c.

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}
struct _CELL_DATA * PCELL_DATA
FORCEINLINE BOOLEAN CmpIsValueCached(IN HCELL_INDEX CellIndex)
Definition: cmvalche.c:17

Referenced by CmEnumerateValueKey(), and CmpFindValueByNameFromCache().

◆ CmpIsValueCached()

FORCEINLINE BOOLEAN CmpIsValueCached ( IN HCELL_INDEX  CellIndex)

Definition at line 17 of file cmvalche.c.

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}

Referenced by CmpGetValueListFromCache().

◆ CmpQueryKeyValueData()

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 at line 327 of file cmvalche.c.

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}
#define DPRINT1
Definition: precomp.h:8
struct _KEY_VALUE_INFORMATION * PKEY_VALUE_INFORMATION
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
USHORT NTAPI CmpCompressedNameSize(IN PWCHAR Name, IN ULONG Length)
Definition: cmname.c:95
Status
Definition: gdiplustypes.h:25
@ KeyValuePartialInformationAlign64
Definition: reg.c:103
@ KeyValueFullInformationAlign64
Definition: reg.c:102
_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
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
ULONG Type
Definition: cmdata.h:128
HCELL_INDEX Data
Definition: cmdata.h:127
ULONG DataLength
Definition: cmdata.h:126
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint64_t ULONGLONG
Definition: typedefs.h:67
#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_ 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

Referenced by CmEnumerateValueKey(), and CmQueryValueKey().

◆ CmpSetValueCached()

FORCEINLINE VOID CmpSetValueCached ( IN PHCELL_INDEX  CellIndex)

Definition at line 31 of file cmvalche.c.

32{
33 /* Set the cached bit */
34 *CellIndex |= 1;
35}