mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 19:03:00 +00:00
[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
This commit is contained in:
parent
b2908d6d6f
commit
dd81be1f25
1 changed files with 45 additions and 115 deletions
|
@ -45,11 +45,9 @@ ULONG
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlIsDosDeviceName_Ustr(IN PUNICODE_STRING PathString)
|
RtlIsDosDeviceName_Ustr(IN PUNICODE_STRING PathString)
|
||||||
{
|
{
|
||||||
UNICODE_STRING PathCopy;
|
UNICODE_STRING DeviceName;
|
||||||
PWCHAR Start, End;
|
PWCHAR Start, End, Ptr;
|
||||||
ULONG PathChars, ColonCount = 0;
|
ULONG DeviceNameLength;
|
||||||
USHORT ReturnOffset = 0, ReturnLength;
|
|
||||||
WCHAR c;
|
|
||||||
|
|
||||||
/* Validate the input */
|
/* Validate the input */
|
||||||
if (!PathString) return 0;
|
if (!PathString) return 0;
|
||||||
|
@ -71,129 +69,61 @@ RtlIsDosDeviceName_Ustr(IN PUNICODE_STRING PathString)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* Skip the drive name for drive relative or absolute paths */
|
||||||
|
case RtlPathTypeDriveAbsolute:
|
||||||
|
case RtlPathTypeDriveRelative:
|
||||||
|
Start = PathString->Buffer + 2;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
Start = PathString->Buffer;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make a copy of the string */
|
/* Find start of file name */
|
||||||
PathCopy = *PathString;
|
for (Ptr = Start; *Ptr; Ptr++)
|
||||||
|
if (IS_PATH_SEPARATOR(*Ptr))
|
||||||
|
Start = Ptr + 1;
|
||||||
|
|
||||||
/* Return if there's no characters */
|
/* Truncate at extension or stream */
|
||||||
PathChars = PathCopy.Length / sizeof(WCHAR);
|
for (End = Start; *End; End++)
|
||||||
if (!PathChars) return 0;
|
if (*End == L'.' || *End == L':')
|
||||||
|
break;
|
||||||
|
End--;
|
||||||
|
|
||||||
/* Check for drive path and truncate */
|
/* Remove trailing spaces */
|
||||||
if (PathCopy.Buffer[PathChars - 1] == L':')
|
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)
|
||||||
{
|
{
|
||||||
/* Fixup the lengths */
|
if (RtlPrefixUnicodeString(&RtlpDosAUXDevice, &DeviceName, TRUE) ||
|
||||||
PathCopy.Length -= sizeof(WCHAR);
|
RtlPrefixUnicodeString(&RtlpDosCONDevice, &DeviceName, TRUE) ||
|
||||||
if (!--PathChars) return 0;
|
RtlPrefixUnicodeString(&RtlpDosNULDevice, &DeviceName, TRUE) ||
|
||||||
|
RtlPrefixUnicodeString(&RtlpDosPRNDevice, &DeviceName, TRUE))
|
||||||
/* 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 */
|
return MAKELONG(DeviceNameLength * sizeof(WCHAR), (Start - PathString->Buffer) * sizeof(WCHAR));
|
||||||
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 */
|
else if (DeviceNameLength == 4)
|
||||||
c = *PathCopy.Buffer | ' '; // ' ' == ('z' - 'Z')
|
{
|
||||||
if ((c != 'l') && (c != 'c') && (c != 'p') && (c != 'a') && (c != 'n'))
|
if ((RtlPrefixUnicodeString(&RtlpDosCOMDevice, &DeviceName, TRUE) ||
|
||||||
|
RtlPrefixUnicodeString(&RtlpDosLPTDevice, &DeviceName, TRUE)) &&
|
||||||
|
iswdigit(DeviceName.Buffer[3]) &&
|
||||||
|
DeviceName.Buffer[3] != L'0')
|
||||||
{
|
{
|
||||||
/* Not LPT, COM, PRN, AUX, or NUL */
|
return MAKELONG(DeviceNameLength * sizeof(WCHAR), (Start - PathString->Buffer) * sizeof(WCHAR));
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now skip past any extra extension or drive letter characters */
|
/* Otherwise, this is not a valid DOS device */
|
||||||
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 */
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue