Author: ion
Date: Sun Jul 17 13:15:50 2011
New Revision: 52713

URL: http://svn.reactos.org/svn/reactos?rev=52713&view=rev
Log:
[RTL]: Implement RtlGetFullPathName_Ustr, not yet used.
[RTL]: Simplify RtlDosSearchPath_U by not using a temporary "char" value, and 
just reading straight from the string buffer.

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=52713&r1=52712&r2=52713&view=diff
==============================================================================
--- trunk/reactos/lib/rtl/path.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/path.c [iso-8859-1] Sun Jul 17 13:15:50 2011
@@ -29,7 +29,6 @@
 static const UNICODE_STRING _unc = RTL_CONSTANT_STRING(L"\\??\\UNC\\");
 
 const UNICODE_STRING DeviceRootString = RTL_CONSTANT_STRING(L"\\\\.\\");
-
 const UNICODE_STRING RtlpDosLPTDevice = RTL_CONSTANT_STRING(L"LPT");
 const UNICODE_STRING RtlpDosCOMDevice = RTL_CONSTANT_STRING(L"COM");
 const UNICODE_STRING RtlpDosPRNDevice = RTL_CONSTANT_STRING(L"PRN");
@@ -325,6 +324,135 @@
         if ((Chars < 3) || (IS_PATH_SEPARATOR(Path[2]))) return 
RtlPathTypeDriveAbsolute;          /* x:\            */
         return RtlPathTypeDriveRelative;                                       
                    /* x:             */
     }
+}
+
+NTSTATUS
+NTAPI
+RtlpCheckDeviceName(IN PUNICODE_STRING FileName,
+                    IN ULONG Length,
+                    OUT PBOOLEAN NameInvalid)
+{
+    PWCHAR Buffer;
+    NTSTATUS Status;
+
+    /* Allocate a large enough buffer */
+    Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, FileName->Length);
+    if (Buffer)
+    {
+        /* Assume failure */
+        *NameInvalid = TRUE;
+
+        /* Copy the filename */
+        RtlCopyMemory(Buffer, FileName->Buffer, FileName->Length);
+
+        /* And add a dot at the end */
+        Buffer[Length / sizeof(WCHAR)] = L'.';
+        Buffer[(Length / sizeof(WCHAR)) + 1] = UNICODE_NULL;
+
+        /* Check if the file exists or not */
+        *NameInvalid = RtlDoesFileExists_U(Buffer) ? FALSE: TRUE;
+
+        /* Get rid of the buffer now */
+        Status = RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+    }
+    else
+    {
+        /* Assume the name is ok, but fail the call */
+        *NameInvalid = FALSE;
+        Status = STATUS_NO_MEMORY;
+    }
+
+    /* Return the status */
+    return Status;
+}
+
+ULONG
+NTAPI
+RtlGetFullPathName_Ustr(IN PUNICODE_STRING FileName,
+                        IN ULONG Size,
+                        IN PWSTR Buffer,
+                        OUT PCWSTR *ShortName,
+                        OUT PBOOLEAN InvalidName,
+                        OUT RTL_PATH_TYPE *PathType)
+{
+    PWCHAR FileNameBuffer;
+    ULONG FileNameLength, FileNameChars, DosLength, DosLengthOffset, 
FullLength;
+    WCHAR c;
+    NTSTATUS Status;
+
+    /* For now, assume the name is valid */
+    if (InvalidName) *InvalidName = FALSE;
+
+    /* Handle initial path type and failure case */
+    *PathType = RtlPathTypeUnknown;
+    if (!(Size) || (FileName->Buffer[0] == UNICODE_NULL)) return 0;
+
+    /* Break filename into component parts */
+    FileNameBuffer = FileName->Buffer;
+    FileNameLength = FileName->Length;
+    FileNameChars = FileNameLength / sizeof(WCHAR);
+
+    /* Kill trailing spaces */
+    c = FileNameBuffer[FileNameChars - 1];
+    while ((FileNameLength) && (c != L' '))
+    {
+        /* Keep going, ignoring the spaces */
+        FileNameLength -= sizeof(WCHAR);
+        if (FileNameLength) c = FileNameBuffer[FileNameLength / sizeof(WCHAR) 
- 1];
+    }
+
+    /* Check if anything is left */
+    if (!FileNameLength ) return 0;
+
+    /* Check if this is a DOS name */
+    DosLength = RtlIsDosDeviceName_Ustr(FileName);
+    if (DosLength)
+    {
+        /* Zero out the short name */
+        if (ShortName) *ShortName = NULL;
+
+        /* See comment for RtlIsDosDeviceName_Ustr if this is confusing... */
+        DosLengthOffset = DosLength >> 16;
+        DosLength = DosLength & 0xFFFF;
+
+        /* Do we have a DOS length, and does the caller want validity? */
+        if ((InvalidName) && (DosLengthOffset))
+        {
+            /* Do the check */
+            Status = RtlpCheckDeviceName(FileName, DosLengthOffset, 
InvalidName);
+
+            /* If the check failed, or the name is invalid, fail here */
+            if (!NT_SUCCESS(Status)) return 0;
+            if (*InvalidName) return 0;
+        }
+
+        /* Add the size of the device root and check if it fits in the size */
+        FullLength = DosLength + DeviceRootString.Length;
+        if (FullLength < Size)
+        {
+            /* Add the device string */
+            RtlMoveMemory(Buffer, DeviceRootString.Buffer, 
DeviceRootString.Length);
+
+            /* Now add the DOS device name */
+            RtlMoveMemory((PCHAR)Buffer + DeviceRootString.Length,
+                          (PCHAR)FileNameBuffer + DosLengthOffset,
+                          DosLength);
+
+            /* Null terminate */
+            *(PWCHAR)((ULONG_PTR)Buffer + FullLength) = UNICODE_NULL;
+            return FullLength;
+        }
+
+        /* Otherwise, there's no space, so return the buffer size needed */
+        if ((FullLength + sizeof(UNICODE_NULL)) > UNICODE_STRING_MAX_BYTES) 
return 0;
+        return FullLength + sizeof(UNICODE_NULL);
+    }
+
+    /* This should work well enough for our current needs */
+    *PathType = RtlDetermineDosPathNameType_U(FileNameBuffer);
+
+    /* This is disgusting... but avoids re-writing everything */
+    return RtlGetFullPathName_U(FileNameBuffer, Size, Buffer, 
(PWSTR*)ShortName);
 }
 
 /* PUBLIC FUNCTIONS 
***********************************************************/
@@ -1111,11 +1239,10 @@
                    OUT PWSTR *PartName)
 {
     NTSTATUS Status;
-    WCHAR c;
     ULONG ExtensionLength, Length, FileNameLength, PathLength;
     UNICODE_STRING TempString;
     PWCHAR NewBuffer, BufferStart;
-    PCWSTR TempPtr;
+    PCWSTR p;
 
     /* Check if this is an absolute path */
     if (RtlDetermineDosPathNameType_U(FileName) != RtlPathTypeRelative)
@@ -1132,20 +1259,19 @@
     }
 
     /* Scan the filename */
-    TempPtr = FileName;
-    c = *TempPtr;
-    while (c)
+    p = FileName;
+    while (*p)
     {
         /* Looking for an extension */
-        if (c == '.')
+        if (*p == '.')
         {
             /* No extension string needed -- it's part of the filename */
             Extension = NULL;
             break;
         }
-
+        
         /* Next character */
-        c = *++TempPtr;
+        p++;
     }
 
     /* Do we have an extension? */
@@ -1191,21 +1317,19 @@
     while (TRUE)
     {
         /* Check if we have a valid character */
-        c = *Path;
         BufferStart = NewBuffer;
-        if (c)
+        if (*Path)
         {
             /* Loop as long as there's no semicolon */
-            while (c != ';')
+            while (*Path != ';')
             {
                 /* Copy the next character */
-                *BufferStart++ = c;
-                c = *++Path;
-                if (!c) break;
+                *BufferStart++ = *Path++;
+                if (!*Path) break;
             }
 
             /* We found a semi-colon, to stop path processing on this loop */
-            if (c == ';') ++Path;
+            if (*Path == ';') ++Path;
         }
 
         /* Add a terminating slash if needed */
@@ -1215,7 +1339,7 @@
         }
 
         /* Bail out if we reached the end */
-        if (!c) Path = NULL;
+        if (!*Path) Path = NULL;
 
         /* Copy the file name and check if an extension is needed */
         RtlCopyMemory(BufferStart, FileName, FileNameLength);


Reply via email to