From: Eric Kohl Date: Sat, 17 Sep 2011 00:55:02 +0000 (+0000) Subject: [RTL] X-Git-Tag: backups/icu4ros-bringup@60647~270 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=dd81be1f25ba5006a71c33ce08eb3bc2cef2ec31 [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. svn path=/trunk/; revision=53726 --- diff --git a/reactos/lib/rtl/path.c b/reactos/lib/rtl/path.c index 470ac0917f3..d2ae4a9547f 100644 --- a/reactos/lib/rtl/path.c +++ b/reactos/lib/rtl/path.c @@ -45,11 +45,9 @@ ULONG 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 @@ RtlIsDosDeviceName_Ustr(IN PUNICODE_STRING PathString) } 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; - } + /* Find start of file name */ + for (Ptr = Start; *Ptr; Ptr++) + if (IS_PATH_SEPARATOR(*Ptr)) + Start = Ptr + 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; + /* Truncate at extension or stream */ + for (End = Start; *End; End++) + if (*End == L'.' || *End == L':') + break; + End--; - /* Fixup the lengths and get the next character */ - PathCopy.Length -= sizeof(WCHAR); - if (!--PathChars) c = PathCopy.Buffer[PathChars - 1]; + /* Remove trailing spaces */ + while (End >= Start && *End == L' ') + End--; - /* Remember this for later */ - ColonCount++; - } while (PathChars); + /* Build the device name string */ + DeviceNameLength = End - Start + 1; + DeviceName.Buffer = Start; + DeviceName.Length = (USHORT)DeviceNameLength * sizeof(WCHAR); + DeviceName.MaximumLength = DeviceName.Length; - /* Anything still left? */ - if (PathChars) + /* Check the device name */ + if (DeviceNameLength == 3) { - /* Loop from the end */ - for (End = &PathCopy.Buffer[PathChars - 1]; - End >= PathCopy.Buffer; - --End) + if (RtlPrefixUnicodeString(&RtlpDosAUXDevice, &DeviceName, TRUE) || + RtlPrefixUnicodeString(&RtlpDosCONDevice, &DeviceName, TRUE) || + RtlPrefixUnicodeString(&RtlpDosNULDevice, &DeviceName, TRUE) || + RtlPrefixUnicodeString(&RtlpDosPRNDevice, &DeviceName, TRUE)) { - /* 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; + return MAKELONG(DeviceNameLength * sizeof(WCHAR), (Start - PathString->Buffer) * sizeof(WCHAR)); } } - - /* Now skip past any extra extension or drive letter characters */ - Start = PathCopy.Buffer; - End = &Start[PathChars]; - while (Start < End) + else if (DeviceNameLength == 4) { - 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))) + if ((RtlPrefixUnicodeString(&RtlpDosCOMDevice, &DeviceName, TRUE) || + RtlPrefixUnicodeString(&RtlpDosLPTDevice, &DeviceName, TRUE)) && + iswdigit(DeviceName.Buffer[3]) && + DeviceName.Buffer[3] != L'0') { - /* Found it */ - ReturnLength = sizeof(L"COM1"); - return MAKELONG(ReturnOffset, ReturnLength); + return MAKELONG(DeviceNameLength * sizeof(WCHAR), (Start - PathString->Buffer) * sizeof(WCHAR)); } } - 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 */ + /* Otherwise, this is not a valid DOS device */ return 0; }