Author: fireball
Date: Mon Sep 17 23:51:32 2007
New Revision: 29084
URL:
http://svn.reactos.org/svn/reactos?rev=29084&view=rev
Log:
- Change RtlIsDosDeviceName_U() implementation to a better Wine implementation
- Winesync RtlIsNameLegalDOS8Dot3()
- "ntdll_winetest.exe path" reduced to 3 failures (which happen on XP too), so
considering "path" done 100% now.
Modified:
trunk/reactos/lib/rtl/dos8dot3.c
trunk/reactos/lib/rtl/path.c
Modified: trunk/reactos/lib/rtl/dos8dot3.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/dos8dot3.c?rev=290…
==============================================================================
--- trunk/reactos/lib/rtl/dos8dot3.c (original)
+++ trunk/reactos/lib/rtl/dos8dot3.c Mon Sep 17 23:51:32 2007
@@ -238,79 +238,64 @@
IN OUT POEM_STRING AnsiName OPTIONAL,
IN OUT PBOOLEAN SpacesFound OPTIONAL)
{
- PANSI_STRING name = AnsiName;
- ANSI_STRING DummyString;
- CHAR Buffer[12];
- char *str;
- ULONG Length;
- ULONG i;
- NTSTATUS Status;
- BOOLEAN HasSpace = FALSE;
- BOOLEAN HasDot = FALSE;
-
- if (UnicodeName->Length > 24)
- {
- return(FALSE); /* name too long */
- }
-
- if (!name)
- {
- name = &DummyString;
- name->Length = 0;
- name->MaximumLength = 12;
- name->Buffer = Buffer;
- }
-
- Status = RtlUpcaseUnicodeStringToCountedOemString(name,
- UnicodeName,
- FALSE);
- if (!NT_SUCCESS(Status))
- {
- return(FALSE);
- }
-
- Length = name->Length;
- str = name->Buffer;
-
- if (!(Length == 1 && *str == '.') &&
- !(Length == 2 && *str == '.' && *(str + 1) ==
'.'))
- {
- for (i = 0; i < Length; i++, str++)
- {
- switch (*str)
- {
- case ' ':
- HasSpace = TRUE;
- break;
-
- case '.':
- if ((HasDot) || /* two or more dots */
- (i == 0) || /* dot is first char */
- (i + 1 == Length) || /* dot is last char */
- (Length - i > 4) || /* more than 3 chars of extension */
- (HasDot == FALSE && i > 8)) /* name is longer than 8
chars */
- return(FALSE);
- HasDot = TRUE;
- break;
- default:
- if (RtlpIsShortIllegal(*str))
- {
- return(FALSE);
- }
- }
- }
- }
-
- /* Name is longer than 8 chars and does not have an extension */
- if (Length > 8 && HasDot == FALSE)
- {
- return(FALSE);
- }
-
- if (SpacesFound)
- *SpacesFound = HasSpace;
-
- return(TRUE);
+ static const char Illegal[] = "*?<>|\"+=,;[]:/\\\345";
+ int Dot = -1;
+ int i;
+ char Buffer[12];
+ OEM_STRING OemString;
+ BOOLEAN GotSpace = FALSE;
+
+ if (!AnsiName)
+ {
+ OemString.Length = sizeof(Buffer);
+ OemString.MaximumLength = sizeof(Buffer);
+ OemString.Buffer = Buffer;
+ AnsiName = &OemString;
+ }
+ if (RtlUpcaseUnicodeStringToCountedOemString( AnsiName, UnicodeName, FALSE ) !=
STATUS_SUCCESS)
+ return FALSE;
+
+ if (AnsiName->Length > 12) return FALSE;
+
+ /* a starting . is invalid, except for . and .. */
+ if (AnsiName->Buffer[0] == '.')
+ {
+ if (AnsiName->Length != 1 && (AnsiName->Length != 2 ||
AnsiName->Buffer[1] != '.')) return FALSE;
+ if (SpacesFound) *SpacesFound = FALSE;
+ return TRUE;
+ }
+
+ for (i = 0; i < AnsiName->Length; i++)
+ {
+ switch (AnsiName->Buffer[i])
+ {
+ case ' ':
+ /* leading/trailing spaces not allowed */
+ if (!i || i == AnsiName->Length-1 || AnsiName->Buffer[i+1] ==
'.') return FALSE;
+ GotSpace = TRUE;
+ break;
+ case '.':
+ if (Dot != -1) return FALSE;
+ Dot = i;
+ break;
+ default:
+ if (strchr(Illegal, AnsiName->Buffer[i])) return FALSE;
+ break;
+ }
+ }
+ /* check file part is shorter than 8, extension shorter than 3
+ * dot cannot be last in string
+ */
+ if (Dot == -1)
+ {
+ if (AnsiName->Length > 8) return FALSE;
+ }
+ else
+ {
+ if (Dot > 8 || (AnsiName->Length - Dot > 4) || Dot ==
AnsiName->Length - 1) return FALSE;
+ }
+ if (SpacesFound) *SpacesFound = GotSpace;
+ return TRUE;
}
/*
Modified: trunk/reactos/lib/rtl/path.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/path.c?rev=29084&a…
==============================================================================
--- trunk/reactos/lib/rtl/path.c (original)
+++ trunk/reactos/lib/rtl/path.c Mon Sep 17 23:51:32 2007
@@ -91,92 +91,69 @@
* @implemented
*/
ULONG NTAPI
-RtlIsDosDeviceName_U(PWSTR DeviceName)
-{
- ULONG Type;
- ULONG Length = 0;
- ULONG Offset;
- PWCHAR wc;
- UNICODE_STRING DeviceNameU;
-
- if (DeviceName == NULL)
- {
- return 0;
- }
-
- while (DeviceName[Length])
- {
- Length++;
- }
-
- Type = RtlDetermineDosPathNameType_U(DeviceName);
- if (Type <= 1)
- {
- return 0;
- }
-
- if (Type == 6)
- {
- DeviceNameU.Length = DeviceNameU.MaximumLength = Length * sizeof(WCHAR);
- DeviceNameU.Buffer = DeviceName;
- if (Length == 7 &&
- RtlEqualUnicodeString(&DeviceNameU, (PUNICODE_STRING)&_condev, TRUE))
- return 0x00080006;
- return 0;
- }
-
- /* name can end with ':' */
- if (Length && DeviceName[Length - 1 ] == L':')
- {
- Length--;
- }
-
- /* there can be spaces or points at the end of name */
- wc = DeviceName + Length - 1;
- while (Length && (*wc == L'.' || *wc == L' '))
- {
- Length--;
- wc--;
- }
-
- /* let's find a beginning of name */
- wc = DeviceName + Length - 1;
- while (wc > DeviceName && !IS_PATH_SEPARATOR(*(wc - 1)))
- {
- wc--;
- }
- Offset = wc - DeviceName;
- Length -= Offset;
- DeviceNameU.Length = DeviceNameU.MaximumLength = 3 * sizeof(WCHAR);
- DeviceNameU.Buffer = wc;
-
- /* check for LPTx or COMx */
- if (Length == 4 && wc[3] >= L'0' && wc[3] <=
L'9')
- {
- if (wc[3] == L'0')
- {
- return 0;
- }
-
- if (RtlEqualUnicodeString(&DeviceNameU, (PUNICODE_STRING)&_lpt, TRUE) ||
- RtlEqualUnicodeString(&DeviceNameU, (PUNICODE_STRING)&_com, TRUE))
- {
- return ((Offset * 2) << 16 ) | 8;
- }
- return 0;
- }
-
- /* check for PRN,AUX,NUL or CON */
- if (Length == 3 &&
- (RtlEqualUnicodeString(&DeviceNameU, (PUNICODE_STRING)&_prn, TRUE) ||
- RtlEqualUnicodeString(&DeviceNameU, (PUNICODE_STRING)&_aux, TRUE) ||
- RtlEqualUnicodeString(&DeviceNameU, (PUNICODE_STRING)&_nul, TRUE) ||
- RtlEqualUnicodeString(&DeviceNameU, (PUNICODE_STRING)&_con, TRUE)))
- {
- return ((Offset * 2) << 16) | 6;
- }
-
- return 0;
+RtlIsDosDeviceName_U(PWSTR dos_name)
+{
+ static const WCHAR consoleW[] =
{'\\','\\','.','\\','C','O','N',0};
+ static const WCHAR auxW[3] = {'A','U','X'};
+ static const WCHAR comW[3] = {'C','O','M'};
+ static const WCHAR conW[3] = {'C','O','N'};
+ static const WCHAR lptW[3] = {'L','P','T'};
+ static const WCHAR nulW[3] = {'N','U','L'};
+ static const WCHAR prnW[3] = {'P','R','N'};
+
+ const WCHAR *start, *end, *p;
+
+ switch(RtlDetermineDosPathNameType_U( dos_name ))
+ {
+ case RtlPathTypeUnknown:
+ case RtlPathTypeUncAbsolute:
+ return 0;
+ case RtlPathTypeLocalDevice:
+ if (!_wcsicmp( dos_name, consoleW ))
+ return MAKELONG( sizeof(conW), 4 * sizeof(WCHAR) ); /* 4 is length of \\.\
prefix */
+ return 0;
+ default:
+ break;
+ }
+
+ end = dos_name + wcslen(dos_name) - 1;
+ while (end >= dos_name && *end == ':') end--; /* remove all
trailing ':' */
+
+ /* find start of file name */
+ for (start = end; start >= dos_name; start--)
+ {
+ if (IS_PATH_SEPARATOR(start[0])) break;
+ /* check for ':' but ignore if before extension (for things like
NUL:.txt) */
+ if (start[0] == ':' && start[1] != '.') break;
+ }
+ start++;
+
+ /* remove extension */
+ if ((p = wcschr( start, '.' )))
+ {
+ end = p - 1;
+ if (end >= dos_name && *end == ':') end--; /* remove trailing
':' before extension */
+ }
+ /* remove trailing spaces */
+ while (end >= dos_name && *end == ' ') end--;
+
+ /* now we have a potential device name between start and end, check it */
+ switch(end - start + 1)
+ {
+ case 3:
+ if (_wcsnicmp( start, auxW, 3 ) &&
+ _wcsnicmp( start, conW, 3 ) &&
+ _wcsnicmp( start, nulW, 3 ) &&
+ _wcsnicmp( start, prnW, 3 )) break;
+ return MAKELONG( 3 * sizeof(WCHAR), (start - dos_name) * sizeof(WCHAR) );
+ case 4:
+ if (_wcsnicmp( start, comW, 3 ) && _wcsnicmp( start, lptW, 3 )) break;
+ if (*end <= '0' || *end > '9') break;
+ return MAKELONG( 4 * sizeof(WCHAR), (start - dos_name) * sizeof(WCHAR) );
+ default: /* can't match anything */
+ break;
+ }
+ return 0;
}
@@ -389,7 +366,12 @@
}
/* skip to the next component */
while (*p && *p != '\\') p++;
- if (*p == '\\') p++;
+ if (*p == '\\')
+ {
+ /* remove last dot in previous dir name */
+ if (p > path + mark && p[-1] == '.') memmove( p-1, p,
(wcslen(p) + 1) * sizeof(WCHAR) );
+ else p++;
+ }
}
/* remove trailing spaces and dots (yes, Windows really does that, don't ask) */
@@ -439,7 +421,8 @@
RtlAcquirePebLock();
- cd =
&((PCURDIR)&NtCurrentTeb()->ProcessEnvironmentBlock->ProcessParameters->CurrentDirectory.DosPath)->DosPath;
+ //cd =
&((PCURDIR)&NtCurrentTeb()->ProcessEnvironmentBlock->ProcessParameters->CurrentDirectory.DosPath)->DosPath;
+ cd =
&NtCurrentTeb()->ProcessEnvironmentBlock->ProcessParameters->CurrentDirectory.DosPath;
switch (type = RtlDetermineDosPathNameType_U(name))
{