2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/config/cmname.c
5 * PURPOSE: Configuration Manager - Name Management
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
15 /* GLOBALS *******************************************************************/
17 /* FUNCTIONS *****************************************************************/
21 CmpCopyName(IN PHHIVE Hive
,
22 IN PWCHAR Destination
,
23 IN PUNICODE_STRING Source
)
27 /* Check for old hives */
28 if (Hive
->Version
== 1)
30 /* Just copy the source directly */
31 RtlCopyMemory(Destination
, Source
->Buffer
, Source
->Length
);
32 return Source
->Length
;
35 /* For new versions, check for compressed name */
36 for (i
= 0; i
< (Source
->Length
/ sizeof(WCHAR
)); i
++)
38 /* Check if the name is non compressed */
39 if (Source
->Buffer
[i
] > (UCHAR
)-1)
42 RtlCopyMemory(Destination
, Source
->Buffer
, Source
->Length
);
43 return Source
->Length
;
46 /* Copy this character */
47 ((PCHAR
)Destination
)[i
] = (CHAR
)(Source
->Buffer
[i
]);
50 /* Compressed name, return length */
51 return Source
->Length
/ sizeof(WCHAR
);
56 CmpCopyCompressedName(IN PWCHAR Destination
,
57 IN ULONG DestinationLength
,
59 IN ULONG SourceLength
)
63 /* Get the actual length to copy */
64 Length
= min(DestinationLength
/ sizeof(WCHAR
), SourceLength
);
65 for (i
= 0; i
< Length
; i
++)
67 /* Copy each character */
68 Destination
[i
] = (WCHAR
)((PCHAR
)Source
)[i
];
74 CmpNameSize(IN PHHIVE Hive
,
75 IN PUNICODE_STRING Name
)
79 /* For old hives, just retun the length */
80 if (Hive
->Version
== 1) return Name
->Length
;
82 /* For new versions, check for compressed name */
83 for (i
= 0; i
< (Name
->Length
/ sizeof(WCHAR
)); i
++)
85 /* Check if the name is non compressed */
86 if (Name
->Buffer
[i
] > (UCHAR
)-1) return Name
->Length
;
89 /* Compressed name, return length */
90 return Name
->Length
/ sizeof(WCHAR
);
95 CmpCompressedNameSize(IN PWCHAR Name
,
99 * Don't remove this: compressed names are "opaque" and just because
100 * the current implementation turns them into ansi-names doesn't mean
101 * that it will remain that way forever, so -never- assume this code
104 return (USHORT
)Length
* sizeof(WCHAR
);
109 CmpCompareCompressedName(IN PCUNICODE_STRING SearchName
,
110 IN PWCHAR CompressedName
,
119 /* Set the pointers and length and then loop */
120 p
= SearchName
->Buffer
;
121 pp
= (PCHAR
)CompressedName
;
122 SearchLength
= (SearchName
->Length
/ sizeof(WCHAR
));
123 while ((SearchLength
) && (NameLength
))
125 /* Get the characters */
129 /* Check if we have a direct match */
132 /* See if they match and return result if they don't */
133 Result
= (LONG
)RtlUpcaseUnicodeChar(p1
) -
134 (LONG
)RtlUpcaseUnicodeChar(p2
);
135 if (Result
) return Result
;
143 /* Return the difference directly */
144 return SearchLength
- NameLength
;
149 CmpFindNameInList(IN PHHIVE Hive
,
150 IN PCHILD_LIST ChildList
,
151 IN PUNICODE_STRING Name
,
152 IN PULONG ChildIndex
,
153 IN PHCELL_INDEX CellIndex
)
156 HCELL_INDEX CellToRelease
= HCELL_NIL
;
158 PCM_KEY_VALUE KeyValue
;
160 UNICODE_STRING SearchName
;
163 /* Make sure there's actually something on the list */
164 if (ChildList
->Count
!= 0)
166 /* Get the cell data */
167 CellData
= (PCELL_DATA
)HvGetCell(Hive
, ChildList
->List
);
170 /* Couldn't get the cell... tell the caller */
171 *CellIndex
= HCELL_NIL
;
175 /* Now loop every entry */
176 for (i
= 0; i
< ChildList
->Count
; i
++)
178 /* Check if we have a cell to release */
179 if (CellToRelease
!= HCELL_NIL
)
182 HvReleaseCell(Hive
, CellToRelease
);
183 CellToRelease
= HCELL_NIL
;
187 KeyValue
= (PCM_KEY_VALUE
)HvGetCell(Hive
, CellData
->u
.KeyList
[i
]);
190 /* Return with no data found */
191 *CellIndex
= HCELL_NIL
;
196 /* Save the cell to release */
197 CellToRelease
= CellData
->u
.KeyList
[i
];
199 /* Check if it's a compressed value name */
200 if (KeyValue
->Flags
& VALUE_COMP_NAME
)
202 /* Use the compressed name check */
203 Result
= CmpCompareCompressedName(Name
,
205 KeyValue
->NameLength
);
209 /* Setup the Unicode string */
210 SearchName
.Length
= KeyValue
->NameLength
;
211 SearchName
.MaximumLength
= SearchName
.Length
;
212 SearchName
.Buffer
= KeyValue
->Name
;
213 Result
= RtlCompareUnicodeString(Name
, &SearchName
, TRUE
);
216 /* Check if we found it */
219 /* We did...return info to caller */
220 if (ChildIndex
) *ChildIndex
= i
;
221 *CellIndex
= CellData
->u
.KeyList
[i
];
223 /* Set success state */
229 /* Got to the end of the list */
230 if (ChildIndex
) *ChildIndex
= i
;
231 *CellIndex
= HCELL_NIL
;
233 /* Nothing found if we got here */
238 /* Nothing found...check if the caller wanted more info */
239 ASSERT(ChildList
->Count
== 0);
240 if (ChildIndex
) *ChildIndex
= 0;
241 *CellIndex
= HCELL_NIL
;
243 /* Nothing found if we got here */
247 /* Release the first cell we got */
248 if (CellData
) HvReleaseCell(Hive
, ChildList
->List
);
250 /* Release the secondary one, if we have one */
251 if (CellToRelease
) HvReleaseCell(Hive
, CellToRelease
);