- Fix function signature of CompareUnicodeStrings

- Add special case where we get a prefix itself and a name starting with a prefix character.
- Implement RtlInitializeGenericTable
This fixes the windows npfs.sys hang.

svn path=/trunk/; revision=19055
This commit is contained in:
Alex Ionescu 2005-11-08 16:41:58 +00:00
parent a485607cfc
commit 824fc6410b
2 changed files with 47 additions and 11 deletions

View file

@ -146,19 +146,26 @@ RtlGetElementGenericTableAvl (
} }
/* /*
* @unimplemented * @implemented
*/ */
VOID VOID
NTAPI NTAPI
RtlInitializeGenericTable ( RtlInitializeGenericTable(PRTL_GENERIC_TABLE Table,
PRTL_GENERIC_TABLE Table,
PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine, PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine,
PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine, PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine,
PRTL_GENERIC_FREE_ROUTINE FreeRoutine, PRTL_GENERIC_FREE_ROUTINE FreeRoutine,
PVOID TableContext PVOID TableContext)
)
{ {
UNIMPLEMENTED; /* Initialize the table to default and passed values */
InitializeListHead(&Table->InsertOrderList);
Table->TableRoot = NULL;
Table->NumberGenericTableElements = 0;
Table->WhichOrderedElement = 0;
Table->OrderedPointer = &Table->InsertOrderList;
Table->CompareRoutine = CompareRoutine;
Table->AllocateRoutine = AllocateRoutine;
Table->FreeRoutine = FreeRoutine;
Table->TableContext = TableContext;
} }

View file

@ -48,8 +48,8 @@ ComputeUnicodeNameLength(IN PUNICODE_STRING UnicodeName)
STATIC STATIC
RTL_GENERIC_COMPARE_RESULTS RTL_GENERIC_COMPARE_RESULTS
NTAPI NTAPI
CompareUnicodeStrings(IN PUNICODE_STRING String, CompareUnicodeStrings(IN PUNICODE_STRING Prefix,
IN PUNICODE_STRING Prefix, IN PUNICODE_STRING String,
IN ULONG CaseCheckChar) IN ULONG CaseCheckChar)
{ {
ULONG StringLength = String->Length / sizeof(WCHAR); ULONG StringLength = String->Length / sizeof(WCHAR);
@ -58,6 +58,17 @@ CompareUnicodeStrings(IN PUNICODE_STRING String,
ULONG i; ULONG i;
WCHAR FoundPrefix, FoundString; WCHAR FoundPrefix, FoundString;
PWCHAR p, p1; PWCHAR p, p1;
DPRINT("CompareUnicodeStrings: %wZ %wZ\n", String, Prefix);
/* Handle case noticed in npfs when Prefix = '\' and name starts with '\' */
if ((PrefixLength == 1) &&
(Prefix->Buffer[0] == '\\') &&
(StringLength > 1) &&
(String->Buffer[0] == '\\'))
{
/* The string is actually a prefix */
return -1;
}
/* Validate the Case Check Character Position */ /* Validate the Case Check Character Position */
if (CaseCheckChar > ScanLength) CaseCheckChar = ScanLength; if (CaseCheckChar > ScanLength) CaseCheckChar = ScanLength;
@ -147,6 +158,7 @@ RtlFindUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable,
PUNICODE_PREFIX_TABLE_ENTRY CurrentEntry, PreviousEntry, Entry, NextEntry; PUNICODE_PREFIX_TABLE_ENTRY CurrentEntry, PreviousEntry, Entry, NextEntry;
PRTL_SPLAY_LINKS SplayLinks; PRTL_SPLAY_LINKS SplayLinks;
RTL_GENERIC_COMPARE_RESULTS Result; RTL_GENERIC_COMPARE_RESULTS Result;
DPRINT("RtlFindUnicodePrefix\n");
/* Find out how many names there are */ /* Find out how many names there are */
NameCount = ComputeUnicodeNameLength(FullName); NameCount = ComputeUnicodeNameLength(FullName);
@ -164,16 +176,20 @@ RtlFindUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable,
/* Loop every entry which has valid entries */ /* Loop every entry which has valid entries */
while (CurrentEntry->NameLength) while (CurrentEntry->NameLength)
{ {
DPRINT("CurrentEntry->NameLength %lx\n", CurrentEntry->NameLength);
/* Get the splay links and loop */ /* Get the splay links and loop */
while ((SplayLinks = &CurrentEntry->Links)) while ((SplayLinks = &CurrentEntry->Links))
{ {
/* Get the entry */ /* Get the entry */
DPRINT("SplayLinks %p\n", SplayLinks);
Entry = CONTAINING_RECORD(SplayLinks, Entry = CONTAINING_RECORD(SplayLinks,
UNICODE_PREFIX_TABLE_ENTRY, UNICODE_PREFIX_TABLE_ENTRY,
Links); Links);
/* Do the comparison */ /* Do the comparison */
Result = CompareUnicodeStrings(Entry->Prefix, FullName, 0); Result = CompareUnicodeStrings(Entry->Prefix, FullName, 0);
DPRINT("Result %lx\n", Result);
if (Result == GenericGreaterThan) if (Result == GenericGreaterThan)
{ {
/* Prefix is greater, so restart on the left child */ /* Prefix is greater, so restart on the left child */
@ -192,6 +208,7 @@ RtlFindUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable,
* NOTE: An index of 0 means case-insensitive(ie, we'll be case * NOTE: An index of 0 means case-insensitive(ie, we'll be case
* insensitive since index 0, ie, all the time) * insensitive since index 0, ie, all the time)
*/ */
DPRINT("CaseInsensitiveIndex %lx\n", CaseInsensitiveIndex);
if (!CaseInsensitiveIndex) if (!CaseInsensitiveIndex)
{ {
/* /*
@ -225,6 +242,7 @@ RtlFindUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable,
} }
/* Return the entry */ /* Return the entry */
DPRINT("RtlFindUnicodePrefix: %p\n", Entry);
return Entry; return Entry;
} }
@ -240,11 +258,13 @@ RtlFindUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable,
(Result != GenericGreaterThan)) (Result != GenericGreaterThan))
{ {
/* This is a positive match, return it */ /* This is a positive match, return it */
DPRINT("RtlFindUnicodePrefix: %p\n", NextEntry);
return NextEntry; return NextEntry;
} }
/* No match yet, continue looping the circular list */ /* No match yet, continue looping the circular list */
NextEntry = NextEntry->CaseMatch; NextEntry = NextEntry->CaseMatch;
DPRINT("NextEntry %p\n", NextEntry);
} while (NextEntry != Entry); } while (NextEntry != Entry);
/* /*
@ -258,9 +278,11 @@ RtlFindUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable,
/* Splay links exausted, move to next entry */ /* Splay links exausted, move to next entry */
PreviousEntry = CurrentEntry; PreviousEntry = CurrentEntry;
CurrentEntry = CurrentEntry->NextPrefixTree; CurrentEntry = CurrentEntry->NextPrefixTree;
DPRINT("CurrentEntry %p\n", CurrentEntry);
} }
/* If we got here, nothing was found */ /* If we got here, nothing was found */
DPRINT("RtlFindUnicodePrefix: %p\n", NULL);
return NULL; return NULL;
} }
@ -291,6 +313,7 @@ RtlInsertUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable,
ULONG NameCount; ULONG NameCount;
RTL_GENERIC_COMPARE_RESULTS Result; RTL_GENERIC_COMPARE_RESULTS Result;
PRTL_SPLAY_LINKS SplayLinks; PRTL_SPLAY_LINKS SplayLinks;
DPRINT("RtlInsertUnicodePrefix\n");
/* Find out how many names there are */ /* Find out how many names there are */
NameCount = ComputeUnicodeNameLength(Prefix); NameCount = ComputeUnicodeNameLength(Prefix);
@ -322,6 +345,7 @@ RtlInsertUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable,
PrefixTableEntry->CaseMatch = PrefixTableEntry; PrefixTableEntry->CaseMatch = PrefixTableEntry;
/* Quick return */ /* Quick return */
DPRINT("RtlInsertUnicodePrefix TRUE\n");
return TRUE; return TRUE;
} }
@ -344,6 +368,7 @@ RtlInsertUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable,
(GenericEqual)) (GenericEqual))
{ {
/* We must fail the insert: it already exists */ /* We must fail the insert: it already exists */
DPRINT("RtlInsertUnicodePrefix FALSE\n");
return FALSE; return FALSE;
} }
@ -436,6 +461,7 @@ RtlInsertUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable,
Entry->NextPrefixTree = NextEntry; Entry->NextPrefixTree = NextEntry;
/* Return success */ /* Return success */
DPRINT("RtlInsertUnicodePrefix TRUE\n");
return TRUE; return TRUE;
} }
@ -449,6 +475,7 @@ RtlNextUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable,
{ {
PRTL_SPLAY_LINKS SplayLinks; PRTL_SPLAY_LINKS SplayLinks;
PUNICODE_PREFIX_TABLE_ENTRY Entry, CaseMatchEntry; PUNICODE_PREFIX_TABLE_ENTRY Entry, CaseMatchEntry;
DPRINT("RtlNextUnicodePrefix\n");
/* We might need this entry 2/3rd of the time, so cache it now */ /* We might need this entry 2/3rd of the time, so cache it now */
CaseMatchEntry = PrefixTable->LastNextEntry->CaseMatch; CaseMatchEntry = PrefixTable->LastNextEntry->CaseMatch;
@ -507,6 +534,7 @@ RtlNextUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable,
/* Save this entry as the last one returned, and return it */ /* Save this entry as the last one returned, and return it */
PrefixTable->LastNextEntry = Entry; PrefixTable->LastNextEntry = Entry;
DPRINT("RtlNextUnicodePrefix: %p\n", Entry);
return Entry; return Entry;
} }
@ -520,6 +548,7 @@ RtlRemoveUnicodePrefix(PUNICODE_PREFIX_TABLE PrefixTable,
{ {
PUNICODE_PREFIX_TABLE_ENTRY Entry, RefEntry, NewEntry; PUNICODE_PREFIX_TABLE_ENTRY Entry, RefEntry, NewEntry;
PRTL_SPLAY_LINKS SplayLinks; PRTL_SPLAY_LINKS SplayLinks;
DPRINT("RtlRemoveUnicodePrefix\n");
/* Erase the last entry */ /* Erase the last entry */
PrefixTable->LastNextEntry = NULL; PrefixTable->LastNextEntry = NULL;