319 lines
6.1 KiB
C
319 lines
6.1 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1992 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
cmname.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Provides routines for handling name comparisons and converting to/from the registry
|
|||
|
compressed name format.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
John Vert (jvert) 28-Oct-1993
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
#include "cmp.h"
|
|||
|
#ifdef ALLOC_PRAGMA
|
|||
|
#pragma alloc_text(PAGE,CmpNameSize)
|
|||
|
#pragma alloc_text(PAGE,CmpCopyName)
|
|||
|
#pragma alloc_text(PAGE,CmpCompressedNameSize)
|
|||
|
#pragma alloc_text(PAGE,CmpCopyCompressedName)
|
|||
|
#pragma alloc_text(PAGE,CmpCompareCompressedName)
|
|||
|
#pragma alloc_text(PAGE,CmpCompareUnicodeString)
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
USHORT
|
|||
|
CmpNameSize(
|
|||
|
IN PHHIVE Hive,
|
|||
|
IN PUNICODE_STRING Name
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Determines the space needed to store a given string in the registry. May apply
|
|||
|
any relevant compression to compute the length, but the compression used is
|
|||
|
guaranteed to be the same as CmpCopyName.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Hive - supplies the hive control structure (for version checking)
|
|||
|
|
|||
|
Name - Supplies the unicode string to be copied into the registry.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The number of bytes of storage required to store this name.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
ULONG i;
|
|||
|
|
|||
|
if (Hive->Version == 1) {
|
|||
|
return(Name->Length);
|
|||
|
}
|
|||
|
for (i=0;i<Name->Length/sizeof(WCHAR);i++) {
|
|||
|
if ((USHORT)Name->Buffer[i] > (UCHAR)-1) {
|
|||
|
return(Name->Length);
|
|||
|
}
|
|||
|
}
|
|||
|
return(Name->Length / sizeof(WCHAR));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
USHORT
|
|||
|
CmpCopyName(
|
|||
|
IN PHHIVE Hive,
|
|||
|
IN PWCHAR Destination,
|
|||
|
IN PUNICODE_STRING Source
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Copies the given unicode name into the registry, applying any relevant compression
|
|||
|
at the same time.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Hive - supplies the hive control structure (For version checking)
|
|||
|
|
|||
|
Destination - Supplies the destination of the given string.
|
|||
|
|
|||
|
Source - Supplies the unicode string to copy into the registry.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Number of bytes of storage copied
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
ULONG i;
|
|||
|
|
|||
|
if (Hive->Version==1) {
|
|||
|
RtlCopyMemory(Destination,Source->Buffer, Source->Length);
|
|||
|
return(Source->Length);
|
|||
|
}
|
|||
|
|
|||
|
for (i=0;i<Source->Length/sizeof(WCHAR);i++) {
|
|||
|
if ((USHORT)Source->Buffer[i] > (UCHAR)-1) {
|
|||
|
RtlCopyMemory(Destination,Source->Buffer, Source->Length);
|
|||
|
return(Source->Length);
|
|||
|
}
|
|||
|
((PUCHAR)Destination)[i] = (UCHAR)(Source->Buffer[i]);
|
|||
|
}
|
|||
|
return(Source->Length / sizeof(WCHAR));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
USHORT
|
|||
|
CmpCompressedNameSize(
|
|||
|
IN PWCHAR Name,
|
|||
|
IN ULONG Length
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Computes the length of the unicode string that the given compressed name
|
|||
|
expands into.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Name - Supplies the compressed name.
|
|||
|
|
|||
|
Length - Supplies the length in bytes of the compressed name
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The number of bytes of storage required to hold the Unicode expanded name.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return((USHORT)Length*sizeof(WCHAR));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
CmpCopyCompressedName(
|
|||
|
IN PWCHAR Destination,
|
|||
|
IN ULONG DestinationLength,
|
|||
|
IN PWCHAR Source,
|
|||
|
IN ULONG SourceLength
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Copies a compressed name from the registry and expands it to Unicode.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Destination - Supplies the destination Unicode buffer
|
|||
|
|
|||
|
DestinationLength - Supplies the max length of the destination buffer in bytes
|
|||
|
|
|||
|
Source - Supplies the compressed string.
|
|||
|
|
|||
|
SourceLength - Supplies the length of the compressed string in bytes
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
ULONG i;
|
|||
|
ULONG Chars;
|
|||
|
|
|||
|
Chars = (DestinationLength/sizeof(WCHAR) < SourceLength)
|
|||
|
? DestinationLength/sizeof(WCHAR)
|
|||
|
: SourceLength;
|
|||
|
|
|||
|
for (i=0;i<Chars;i++) {
|
|||
|
Destination[i] = (WCHAR)(((PUCHAR)Source)[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
LONG
|
|||
|
CmpCompareCompressedName(
|
|||
|
IN PUNICODE_STRING SearchName,
|
|||
|
IN PWCHAR CompressedName,
|
|||
|
IN ULONG NameLength,
|
|||
|
IN ULONG CompareFlags
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Compares a compressed registry string to a Unicode string. Does a case-insensitive
|
|||
|
comparison.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
SearchName - Supplies the Unicode string to be compared
|
|||
|
|
|||
|
CompressedName - Supplies the compressed string to be compared
|
|||
|
|
|||
|
NameLength - Supplies the length of the compressed string
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
0 = SearchName == CompressedName (of Cell)
|
|||
|
|
|||
|
< 0 = SearchName < CompressedName
|
|||
|
|
|||
|
> 0 = SearchName > CompressedName
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
WCHAR *s1;
|
|||
|
UCHAR *s2;
|
|||
|
USHORT n1, n2;
|
|||
|
WCHAR c1;
|
|||
|
WCHAR c2;
|
|||
|
LONG cDiff;
|
|||
|
|
|||
|
s1 = SearchName->Buffer;
|
|||
|
s2 = (UCHAR *)CompressedName;
|
|||
|
n1 = (USHORT )(SearchName->Length / sizeof(WCHAR));
|
|||
|
n2 = (USHORT )(NameLength);
|
|||
|
while (n1 && n2) {
|
|||
|
c1 = *s1++;
|
|||
|
c2 = (WCHAR)(*s2++);
|
|||
|
|
|||
|
c1 = (CompareFlags&CMP_SOURCE_UP)?c1:RtlUpcaseUnicodeChar(c1);
|
|||
|
c2 = (CompareFlags&CMP_DEST_UP)?c2:RtlUpcaseUnicodeChar(c2);
|
|||
|
|
|||
|
if ((cDiff = ((LONG)c1 - (LONG)c2)) != 0) {
|
|||
|
return( cDiff );
|
|||
|
}
|
|||
|
|
|||
|
n1--;
|
|||
|
n2--;
|
|||
|
}
|
|||
|
|
|||
|
return( n1 - n2 );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
LONG
|
|||
|
CmpCompareUnicodeString(
|
|||
|
IN PUNICODE_STRING SourceName,
|
|||
|
IN PUNICODE_STRING DestName,
|
|||
|
IN ULONG CompareFlags
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Compares 2 unicode strings; Case insensitive comparison.
|
|||
|
Uses flags to avoid UpCasing strings again.
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
SourceName - Supplies the Unicode string to be compared
|
|||
|
|
|||
|
DestName - Supplies the compressed string to be compared
|
|||
|
|
|||
|
CompareFlags - Supplies the flags to control comparison (see cmp.h)
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
0 = SearchName == CompressedName (of Cell)
|
|||
|
|
|||
|
< 0 = SearchName < CompressedName
|
|||
|
|
|||
|
> 0 = SearchName > CompressedName
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
WCHAR *s1, *s2;
|
|||
|
USHORT n1, n2;
|
|||
|
WCHAR c1, c2;
|
|||
|
LONG cDiff;
|
|||
|
|
|||
|
s1 = SourceName->Buffer;
|
|||
|
s2 = DestName->Buffer;
|
|||
|
n1 = (USHORT )(SourceName->Length / sizeof(WCHAR));
|
|||
|
n2 = (USHORT )(DestName->Length / sizeof(WCHAR));
|
|||
|
while (n1 && n2) {
|
|||
|
c1 = *s1++;
|
|||
|
c2 = *s2++;
|
|||
|
|
|||
|
c1 = (CompareFlags&CMP_SOURCE_UP)?c1:RtlUpcaseUnicodeChar(c1);
|
|||
|
c2 = (CompareFlags&CMP_DEST_UP)?c2:RtlUpcaseUnicodeChar(c2);
|
|||
|
|
|||
|
if ((cDiff = ((LONG)c1 - (LONG)c2)) != 0) {
|
|||
|
return( cDiff );
|
|||
|
}
|
|||
|
|
|||
|
n1--;
|
|||
|
n2--;
|
|||
|
}
|
|||
|
|
|||
|
return( n1 - n2 );
|
|||
|
}
|
|||
|
|