- Fix a bug spotted in RtlInsertUnicodePrefix's loop.
Modified: trunk/reactos/lib/rtl/unicodeprefix.c
_____
Modified: trunk/reactos/lib/rtl/unicodeprefix.c
--- trunk/reactos/lib/rtl/unicodeprefix.c 2005-11-08 00:19:01 UTC
(rev 19051)
+++ trunk/reactos/lib/rtl/unicodeprefix.c 2005-11-08 00:21:29 UTC
(rev 19052)
@@ -167,18 +167,7 @@
/* Get the splay links and loop */
while ((SplayLinks = &CurrentEntry->Links))
{
- /*
- * Implementation notes:
- * - get the entry
- * - compare the entry's prefix with the fullname:
- * if greater: restart on the left child
- * if lesser: restart on the right child
- * - else if equal:
- * for caseinsensitive, just return the entry and
- * splay it and set it as root if it's a child
- * for casesensitive, loop the circular case match list
and
- * keep comparing for each entry
- */
+ /* Get the entry */
Entry = CONTAINING_RECORD(SplayLinks,
UNICODE_PREFIX_TABLE_ENTRY,
Links);
@@ -374,8 +363,11 @@
/* Insert it into the circular list */
PrefixTableEntry->CaseMatch = Entry->CaseMatch;
Entry->CaseMatch = PrefixTableEntry;
+ break;
}
- else if (Result == GenericGreaterThan)
+
+ /* Check if the result was greater or lesser than */
+ if (Result == GenericGreaterThan)
{
/* Check out if we have a left child */
if (RtlLeftChild(&Entry->Links))
- Finish implementing RtlFindUnicodePrefix. The Windows NPFS driver
should load now (unless it needs other APIs..)
Modified: trunk/reactos/lib/rtl/unicodeprefix.c
_____
Modified: trunk/reactos/lib/rtl/unicodeprefix.c
--- trunk/reactos/lib/rtl/unicodeprefix.c 2005-11-07 23:52:26 UTC
(rev 19050)
+++ trunk/reactos/lib/rtl/unicodeprefix.c 2005-11-08 00:19:01 UTC
(rev 19051)
@@ -135,7 +135,7 @@
}
/*
- * @unimplemented
+ * @implemented
*/
PUNICODE_PREFIX_TABLE_ENTRY
NTAPI
@@ -144,8 +144,9 @@
ULONG CaseInsensitiveIndex)
{
ULONG NameCount;
- PUNICODE_PREFIX_TABLE_ENTRY CurrentEntry, PreviousEntry;
+ PUNICODE_PREFIX_TABLE_ENTRY CurrentEntry, PreviousEntry, Entry,
NextEntry;
PRTL_SPLAY_LINKS SplayLinks;
+ RTL_GENERIC_COMPARE_RESULTS Result;
/* Find out how many names there are */
NameCount = ComputeUnicodeNameLength(FullName);
@@ -178,6 +179,91 @@
* for casesensitive, loop the circular case match list
and
* keep comparing for each entry
*/
+ Entry = CONTAINING_RECORD(SplayLinks,
+ UNICODE_PREFIX_TABLE_ENTRY,
+ Links);
+
+ /* Do the comparison */
+ Result = CompareUnicodeStrings(Entry->Prefix, FullName, 0);
+ if (Result == GenericGreaterThan)
+ {
+ /* Prefix is greater, so restart on the left child */
+ SplayLinks = RtlLeftChild(SplayLinks);
+ continue;
+ }
+ else if (Result == GenericLessThan)
+ {
+ /* Prefix is smaller, so restart on the right child */
+ SplayLinks = RtlRightChild(SplayLinks);
+ continue;
+ }
+
+ /*
+ * We have a match, check if this was a case-sensitive
search
+ * NOTE: An index of 0 means case-insensitive(ie, we'll be
case
+ * insensitive since index 0, ie, all the time)
+ */
+ if (!CaseInsensitiveIndex)
+ {
+ /*
+ * Check if this entry was a child. We need to return
the root,
+ * so if this entry was a child, we'll splay the tree
and get
+ * the root, and set the current entry as a child.
+ */
+ if (Entry->NodeTypeCode == PFX_NTC_CHILD)
+ {
+ /* Get the next entry */
+ NextEntry = CurrentEntry->NextPrefixTree;
+
+ /* Make the current entry become a child */
+ CurrentEntry->NodeTypeCode = PFX_NTC_CHILD;
+ CurrentEntry->NextPrefixTree = NULL;
+
+ /* Splay the tree */
+ SplayLinks = RtlSplay(&Entry->Links);
+
+ /* Get the new root entry */
+ Entry = CONTAINING_RECORD(SplayLinks,
+
UNICODE_PREFIX_TABLE_ENTRY,
+ Links);
+
+ /* Set it as a root entry */
+ Entry->NodeTypeCode = PFX_NTC_ROOT;
+
+ /* Add it to the root entries list */
+ PreviousEntry->NextPrefixTree = Entry;
+ Entry->NextPrefixTree = NextEntry;
+ }
+
+ /* Return the entry */
+ return Entry;
+ }
+
+ /* We'll do a case-sensitive search if we've reached this
point */
+ NextEntry = Entry;
+ do
+ {
+ /* Do the case-sensitive search */
+ Result = CompareUnicodeStrings(NextEntry->Prefix,
+ FullName,
+ CaseInsensitiveIndex);
+ if ((Result != GenericLessThan) &&
+ (Result != GenericGreaterThan))
+ {
+ /* This is a positive match, return it */
+ return NextEntry;
+ }
+
+ /* No match yet, continue looping the circular list */
+ NextEntry = NextEntry->CaseMatch;
+ } while (NextEntry != Entry);
+
+ /*
+ * If we got here, then we found a non-case-sensitive
match, but
+ * we need to find a case-sensitive match, so we'll just
keep
+ * searching the next tree (NOTE: we need to break out for
this).
+ */
+ break;
}
/* Splay links exausted, move to next entry */
- Start implementing RtlFindUnicodePrefix
- Add case-insensitive compare to CompareUnicodeStrings
Modified: trunk/reactos/lib/rtl/unicodeprefix.c
_____
Modified: trunk/reactos/lib/rtl/unicodeprefix.c
--- trunk/reactos/lib/rtl/unicodeprefix.c 2005-11-07 23:09:53 UTC
(rev 19049)
+++ trunk/reactos/lib/rtl/unicodeprefix.c 2005-11-07 23:52:26 UTC
(rev 19050)
@@ -57,6 +57,7 @@
ULONG ScanLength = min(StringLength, PrefixLength);
ULONG i;
WCHAR FoundPrefix, FoundString;
+ PWCHAR p, p1;
/* Validate the Case Check Character Position */
if (CaseCheckChar > ScanLength) CaseCheckChar = ScanLength;
@@ -75,7 +76,29 @@
/* Check if we exausted the search above */
if (i == CaseCheckChar)
{
- /* FIXME: Do a case-insensitive search */
+ /* Do a case-insensitive search */
+ p = &Prefix->Buffer[i];
+ p1 = &String->Buffer[i];
+ do
+ {
+ /* Move to the next character */
+ FoundPrefix = *p++;
+ FoundString = *p1++;
+
+ /* Compare it */
+ if (FoundPrefix != FoundString)
+ {
+ /* Upcase the characters */
+ FoundPrefix = RtlUpcaseUnicodeChar(FoundPrefix);
+ FoundString = RtlUpcaseUnicodeChar(FoundString);
+
+ /* Compare them again */
+ if (FoundPrefix != FoundString) break;
+ }
+
+ /* Move to the next char */
+ i++;
+ } while (i < ScanLength);
}
/* Check if we weren't able to find a match in the loops */
@@ -120,8 +143,50 @@
PUNICODE_STRING FullName,
ULONG CaseInsensitiveIndex)
{
- UNIMPLEMENTED;
- return 0;
+ ULONG NameCount;
+ PUNICODE_PREFIX_TABLE_ENTRY CurrentEntry, PreviousEntry;
+ PRTL_SPLAY_LINKS SplayLinks;
+
+ /* Find out how many names there are */
+ NameCount = ComputeUnicodeNameLength(FullName);
+
+ /* Find the right spot where to start looking for this entry */
+ PreviousEntry = (PUNICODE_PREFIX_TABLE_ENTRY)PrefixTable;
+ CurrentEntry = PreviousEntry->NextPrefixTree;
+ while (CurrentEntry->NameLength > NameCount)
+ {
+ /* Not a match, move to the next entry */
+ PreviousEntry = CurrentEntry;
+ CurrentEntry = CurrentEntry->NextPrefixTree;
+ }
+
+ /* Loop every entry which has valid entries */
+ while (CurrentEntry->NameLength)
+ {
+ /* Get the splay links and loop */
+ while ((SplayLinks = &CurrentEntry->Links))
+ {
+ /*
+ * Implementation notes:
+ * - get the entry
+ * - compare the entry's prefix with the fullname:
+ * if greater: restart on the left child
+ * if lesser: restart on the right child
+ * - else if equal:
+ * for caseinsensitive, just return the entry and
+ * splay it and set it as root if it's a child
+ * for casesensitive, loop the circular case match list
and
+ * keep comparing for each entry
+ */
+ }
+
+ /* Splay links exausted, move to next entry */
+ PreviousEntry = CurrentEntry;
+ CurrentEntry = CurrentEntry->NextPrefixTree;
+ }
+
+ /* If we got here, nothing was found */
+ return NULL;
}
/*
Just realised I didn't add this last time.
This is the flyer Ge and I used for LWE UK 05
Added: trunk/press-media/flyers/ReactOS.doc
_____
Added: trunk/press-media/flyers/ReactOS.doc
(Binary files differ)
Property changes on: trunk/press-media/flyers/ReactOS.doc
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
- Oops.. fix a bug in RtlRemoveUnicodePrefix: edit the parent, not the
entry itself.
Modified: trunk/reactos/lib/rtl/unicodeprefix.c
_____
Modified: trunk/reactos/lib/rtl/unicodeprefix.c
--- trunk/reactos/lib/rtl/unicodeprefix.c 2005-11-07 22:05:46 UTC
(rev 19046)
+++ trunk/reactos/lib/rtl/unicodeprefix.c 2005-11-07 22:07:08 UTC
(rev 19047)
@@ -433,12 +433,12 @@
else if (RtlIsLeftChild(&PrefixTableEntry->Links))
{
/* We were the left child, so make us as well */
- PrefixTableEntry->Links.LeftChild = &Entry->Links;
+ RtlParent(&PrefixTableEntry->Links)->LeftChild =
&Entry->Links;
}
else
{
/* We were the right child, so make us as well */
- PrefixTableEntry->Links.RightChild = &Entry->Links;
+ RtlParent(&PrefixTableEntry->Links)->RightChild =
&Entry->Links;
}
/* Check if we have a left child */
- Implement more of RtlInsertUnicodePrefix: handle case where tree was
found, and a match in the tree was found (handle case-sensitive and
case-insensitve match).
- Partially umplement CompareUnicodeStrings to scan the two strings
(Can't use RtlCompareUnicodeString because we want control over how many
chars to case-compare.
Modified: trunk/reactos/lib/rtl/unicodeprefix.c
_____
Modified: trunk/reactos/lib/rtl/unicodeprefix.c
--- trunk/reactos/lib/rtl/unicodeprefix.c 2005-11-07 21:17:49 UTC
(rev 19044)
+++ trunk/reactos/lib/rtl/unicodeprefix.c 2005-11-07 21:57:50 UTC
(rev 19045)
@@ -44,6 +44,73 @@
return NamesFound;
}
+
+STATIC
+RTL_GENERIC_COMPARE_RESULTS
+NTAPI
+CompareUnicodeStrings(IN PUNICODE_STRING String,
+ IN PUNICODE_STRING Prefix,
+ IN ULONG CaseCheckChar)
+{
+ ULONG StringLength = String->Length / sizeof(WCHAR);
+ ULONG PrefixLength = Prefix->Length / sizeof(WCHAR);
+ ULONG ScanLength = min(StringLength, PrefixLength);
+ ULONG i;
+ WCHAR FoundPrefix, FoundString;
+
+ /* Validate the Case Check Character Position */
+ if (CaseCheckChar > ScanLength) CaseCheckChar = ScanLength;
+
+ /* Do the case sensitive comparison first */
+ for (i = 0; i < CaseCheckChar; i++)
+ {
+ /* Compare the two characters */
+ if (Prefix->Buffer[i] != String->Buffer[i]) break;
+ }
+
+ /* Save the characters we found */
+ FoundPrefix = Prefix->Buffer[i];
+ FoundString = String->Buffer[i];
+
+ /* Check if we exausted the search above */
+ if (i == CaseCheckChar)
+ {
+ /* FIXME: Do a case-insensitive search */
+ }
+
+ /* Check if we weren't able to find a match in the loops */
+ if (i < ScanLength)
+ {
+ /* If the prefix character found was a backslash, this is a
less */
+ if (FoundPrefix == '\\') return GenericLessThan;
+
+ /* If the string character found was a backslack, then this is
a more */
+ if (FoundString == '\\') return GenericGreaterThan;
+
+ /* None of those two special cases, do a normal check */
+ if (FoundPrefix < FoundString) return GenericLessThan;
+
+ /* The only choice left is that Prefix > String */
+ return GenericGreaterThan;
+ }
+
+ /* If we got here, a match was found. Check if the prefix is
smaller */
+ if (PrefixLength < StringLength)
+ {
+ /* Check if the string is actually a prefix */
+ if (String->Buffer[PrefixLength] == '\\') return -1;
+
+ /* It's not a prefix, and it's shorter, so it's a less */
+ return GenericLessThan;
+ }
+
+ /* Check if the prefix is longer */
+ if (PrefixLength > StringLength) return GenericGreaterThan;
+
+ /* If we got here, then they are 100% equal */
+ return GenericEqual;
+}
+
/*
* @unimplemented
*/
@@ -86,13 +153,15 @@
* - init splay links DONE
* - find a matching tree DONE
* - if !found, insert a new NTC_ROOT entry and return TRUE; DONE
- * - if found, loop tree and compare strings:
- * if equal, handle casematch/nomatch
+ * - if found, loop tree and compare strings: DONE
+ * if equal, handle casematch/nomatch DONE
* if greater or lesser equal, then add left/right childs
accordingly
- * - splay the tree
+ * - splay the tree DONE
*/
- PUNICODE_PREFIX_TABLE_ENTRY CurrentEntry, PreviousEntry;
+ PUNICODE_PREFIX_TABLE_ENTRY CurrentEntry, PreviousEntry, Entry,
NextEntry;
ULONG NameCount;
+ RTL_GENERIC_COMPARE_RESULTS Result;
+ PRTL_SPLAY_LINKS SplayLinks;
/* Find out how many names there are */
NameCount = ComputeUnicodeNameLength(Prefix);
@@ -127,9 +196,77 @@
return TRUE;
}
- /* FIXME */
- UNIMPLEMENTED;
- return FALSE;
+ /* We found a tree, so star thte search loop */
+ Entry = CurrentEntry;
+ while (TRUE)
+ {
+ /* Do a case-insensitive comparison to find out the match level
*/
+ Result = CompareUnicodeStrings(Entry->Prefix, Prefix, 0);
+ if (Result == GenericEqual)
+ {
+ /* We have a match, start doing a case-sensitive search */
+ NextEntry = Entry;
+
+ /* Search the circular case-match list */
+ do
+ {
+ /* Check if we found a match */
+ if (CompareUnicodeStrings(NextEntry->Prefix, Prefix,
-1) ==
+ (GenericEqual))
+ {
+ /* We must fail the insert: it already exists */
+ return FALSE;
+ }
+
+ /* Move to the next entry in the circular list */
+ NextEntry = NextEntry->CaseMatch;
+ }
+ while (NextEntry != Entry);
+
+ /*
+ * No match found, so we can safely insert it. Remember
that a
+ * case insensitive match was found, so this is not a ROOT
NTC
+ * but a Case Match NTC instead.
+ */
+ PrefixTableEntry->NodeTypeCode = PFX_NTC_CASE_MATCH;
+ PrefixTableEntry->NextPrefixTree = NULL;
+
+ /* Insert it into the circular list */
+ PrefixTableEntry->CaseMatch = Entry->CaseMatch;
+ Entry->CaseMatch = PrefixTableEntry;
+ }
+ else if (Result == GenericGreaterThan)
+ {
+ /* TODO: Check out the left child and add us */
+ }
+ else
+ {
+ /* TODO: Check out the right child and add us */
+ }
+ }
+
+ /* Get the next tree entry */
+ NextEntry = CurrentEntry->NextPrefixTree;
+
+ /* Set what was the current entry to a child entry */
+ CurrentEntry->NodeTypeCode = PFX_NTC_CHILD;
+ CurrentEntry->NextPrefixTree = NULL;
+
+ /* Splay the tree */
+ SplayLinks = RtlSplay(&Entry->Links);
+
+ /* The link points to the root, get it */
+ Entry = CONTAINING_RECORD(SplayLinks, UNICODE_PREFIX_TABLE_ENTRY,
Links);
+
+ /* Mark the root as a root entry */
+ Entry->NodeTypeCode = PFX_NTC_ROOT;
+
+ /* Add it to the tree list */
+ PreviousEntry->NextPrefixTree = Entry;
+ Entry->NextPrefixTree = NextEntry;
+
+ /* Return success */
+ return TRUE;
}
/*
- Correct which entry was being modified.
Modified: trunk/reactos/lib/rtl/unicodeprefix.c
_____
Modified: trunk/reactos/lib/rtl/unicodeprefix.c
--- trunk/reactos/lib/rtl/unicodeprefix.c 2005-11-07 21:16:30 UTC
(rev 19043)
+++ trunk/reactos/lib/rtl/unicodeprefix.c 2005-11-07 21:17:49 UTC
(rev 19044)
@@ -269,12 +269,12 @@
else if (RtlIsLeftChild(&PrefixTableEntry->Links))
{
/* We were the left child, so make us as well */
- Entry->Links.LeftChild = &Entry->Links;
+ PrefixTableEntry->Links.LeftChild = &Entry->Links;
}
else
{
/* We were the right child, so make us as well */
- Entry->Links.RightChild = &Entry->Links;
+ PrefixTableEntry->Links.RightChild = &Entry->Links;
}
/* Check if we have a left child */