Author: ekohl
Date: Sat Sep 17 00:55:02 2011
New Revision: 53726
URL:
http://svn.reactos.org/svn/reactos?rev=53726&view=rev
Log:
[RTL]
Fix the overly complicated and buggy implementation of RtlIsDosDeviceName_Ustr based on
the simple pre-r52687 implementation of RtlIsDosDeviceName_U. This fixes 14(!) wine
tests.
Modified:
trunk/reactos/lib/rtl/path.c
Modified: trunk/reactos/lib/rtl/path.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/path.c?rev=53726&a…
==============================================================================
--- trunk/reactos/lib/rtl/path.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/path.c [iso-8859-1] Sat Sep 17 00:55:02 2011
@@ -45,11 +45,9 @@
NTAPI
RtlIsDosDeviceName_Ustr(IN PUNICODE_STRING PathString)
{
- UNICODE_STRING PathCopy;
- PWCHAR Start, End;
- ULONG PathChars, ColonCount = 0;
- USHORT ReturnOffset = 0, ReturnLength;
- WCHAR c;
+ UNICODE_STRING DeviceName;
+ PWCHAR Start, End, Ptr;
+ ULONG DeviceNameLength;
/* Validate the input */
if (!PathString) return 0;
@@ -71,129 +69,61 @@
}
return 0;
+ /* Skip the drive name for drive relative or absolute paths */
+ case RtlPathTypeDriveAbsolute:
+ case RtlPathTypeDriveRelative:
+ Start = PathString->Buffer + 2;
+ break;
+
default:
+ Start = PathString->Buffer;
break;
}
- /* Make a copy of the string */
- PathCopy = *PathString;
-
- /* Return if there's no characters */
- PathChars = PathCopy.Length / sizeof(WCHAR);
- if (!PathChars) return 0;
-
- /* Check for drive path and truncate */
- if (PathCopy.Buffer[PathChars - 1] == L':')
- {
- /* Fixup the lengths */
- PathCopy.Length -= sizeof(WCHAR);
- if (!--PathChars) return 0;
-
- /* Remember this for later */
- ColonCount = 1;
- }
-
- /* Check for extension or space, and truncate */
- c = PathCopy.Buffer[PathChars - 1];
- do
- {
- /* Stop if we hit a space or period */
- if ((c != '.') && (c != ' ')) break;
-
- /* Fixup the lengths and get the next character */
- PathCopy.Length -= sizeof(WCHAR);
- if (!--PathChars) c = PathCopy.Buffer[PathChars - 1];
-
- /* Remember this for later */
- ColonCount++;
- } while (PathChars);
-
- /* Anything still left? */
- if (PathChars)
- {
- /* Loop from the end */
- for (End = &PathCopy.Buffer[PathChars - 1];
- End >= PathCopy.Buffer;
- --End)
- {
- /* Check if the character is a path or drive separator */
- c = *End;
- if ((c == '\\') || (c == '/') || ((c == ':')
&& (End == PathCopy.Buffer + 1)))
- {
- /* Get the next lower case character */
- End++;
- c = *End | ' '; // ' ' == ('z' - 'Z')
-
- /* Check if it's a DOS device (LPT, COM, PRN, AUX, or NUL) */
- if ((End < &PathCopy.Buffer[PathCopy.Length / sizeof(WCHAR)])
&&
- ((c == 'l') || (c == 'c') || (c == 'p') || (c
== 'a') || (c == 'n')))
- {
- /* Calculate the offset */
- ReturnOffset = (PCHAR)End - (PCHAR)PathCopy.Buffer;
-
- /* Build the final string */
- PathCopy.Length -= ReturnOffset;
- PathCopy.Length -= (ColonCount * sizeof(WCHAR));
- PathCopy.Buffer = End;
- break;
- }
- }
-
- return 0;
- }
-
- /* Get the next lower case character and check if it's a DOS device */
- c = *PathCopy.Buffer | ' '; // ' ' == ('z' -
'Z')
- if ((c != 'l') && (c != 'c') && (c !=
'p') && (c != 'a') && (c != 'n'))
- {
- /* Not LPT, COM, PRN, AUX, or NUL */
- return 0;
- }
- }
-
- /* Now skip past any extra extension or drive letter characters */
- Start = PathCopy.Buffer;
- End = &Start[PathChars];
- while (Start < End)
- {
- c = *Start;
- if ((c == '.') || (c == ':')) break;
- Start++;
- }
-
- /* And then go backwards to get rid of spaces */
- while ((Start > PathCopy.Buffer) && (Start[-1] == ' ')) --Start;
-
- /* Finally see how many characters are left, and that's our size */
- PathChars = Start - PathCopy.Buffer;
- PathCopy.Length = PathChars * sizeof(WCHAR);
-
- /* Check if this is a COM or LPT port, which has a digit after it */
- if ((PathChars == 4) &&
- (iswdigit(PathCopy.Buffer[3]) && (PathCopy.Buffer[3] != '0')))
- {
- /* Don't compare the number part, just check for LPT or COM */
- PathCopy.Length -= sizeof(WCHAR);
- if ((RtlEqualUnicodeString(&PathCopy, &RtlpDosLPTDevice, TRUE)) ||
- (RtlEqualUnicodeString(&PathCopy, &RtlpDosCOMDevice, TRUE)))
- {
- /* Found it */
- ReturnLength = sizeof(L"COM1");
- return MAKELONG(ReturnOffset, ReturnLength);
- }
- }
- else if ((PathChars == 3) &&
- ((RtlEqualUnicodeString(&PathCopy, &RtlpDosPRNDevice, TRUE)) ||
- (RtlEqualUnicodeString(&PathCopy, &RtlpDosAUXDevice, TRUE)) ||
- (RtlEqualUnicodeString(&PathCopy, &RtlpDosNULDevice, TRUE)) ||
- (RtlEqualUnicodeString(&PathCopy, &RtlpDosCONDevice, TRUE))))
- {
- /* Otherwise this was something like AUX, NUL, PRN, or CON */
- ReturnLength = sizeof(L"AUX");
- return MAKELONG(ReturnOffset, ReturnLength);
- }
-
- /* Otherwise, this isn't a valid DOS device */
+ /* Find start of file name */
+ for (Ptr = Start; *Ptr; Ptr++)
+ if (IS_PATH_SEPARATOR(*Ptr))
+ Start = Ptr + 1;
+
+ /* Truncate at extension or stream */
+ for (End = Start; *End; End++)
+ if (*End == L'.' || *End == L':')
+ break;
+ End--;
+
+ /* Remove trailing spaces */
+ while (End >= Start && *End == L' ')
+ End--;
+
+ /* Build the device name string */
+ DeviceNameLength = End - Start + 1;
+ DeviceName.Buffer = Start;
+ DeviceName.Length = (USHORT)DeviceNameLength * sizeof(WCHAR);
+ DeviceName.MaximumLength = DeviceName.Length;
+
+ /* Check the device name */
+ if (DeviceNameLength == 3)
+ {
+ if (RtlPrefixUnicodeString(&RtlpDosAUXDevice, &DeviceName, TRUE) ||
+ RtlPrefixUnicodeString(&RtlpDosCONDevice, &DeviceName, TRUE) ||
+ RtlPrefixUnicodeString(&RtlpDosNULDevice, &DeviceName, TRUE) ||
+ RtlPrefixUnicodeString(&RtlpDosPRNDevice, &DeviceName, TRUE))
+ {
+ return MAKELONG(DeviceNameLength * sizeof(WCHAR), (Start -
PathString->Buffer) * sizeof(WCHAR));
+ }
+ }
+ else if (DeviceNameLength == 4)
+ {
+ if ((RtlPrefixUnicodeString(&RtlpDosCOMDevice, &DeviceName, TRUE) ||
+ RtlPrefixUnicodeString(&RtlpDosLPTDevice, &DeviceName, TRUE))
&&
+ iswdigit(DeviceName.Buffer[3]) &&
+ DeviceName.Buffer[3] != L'0')
+ {
+ return MAKELONG(DeviceNameLength * sizeof(WCHAR), (Start -
PathString->Buffer) * sizeof(WCHAR));
+ }
+ }
+
+ /* Otherwise, this is not a valid DOS device */
return 0;
}