[RTL] Make a RtlQueryEnvironmentVariable_U() DPRINT a little bit more useful.
[reactos.git] / sdk / lib / rtl / path.c
index 5e9e597..7639424 100644 (file)
@@ -45,6 +45,8 @@ const UNICODE_STRING RtlpDosAUXDevice = RTL_CONSTANT_STRING(L"AUX");
 const UNICODE_STRING RtlpDosCONDevice = RTL_CONSTANT_STRING(L"CON");
 const UNICODE_STRING RtlpDosNULDevice = RTL_CONSTANT_STRING(L"NUL");
 
+const UNICODE_STRING RtlpDoubleSlashPrefix   = RTL_CONSTANT_STRING(L"\\\\");
+
 PRTLP_CURDIR_REF RtlpCurDirRef;
 
 /* PRIVATE FUNCTIONS **********************************************************/
@@ -163,7 +165,7 @@ RtlIsDosDeviceName_Ustr(IN PCUNICODE_STRING PathString)
             {
                 /* Get the next lower case character */
                 End++;
-                c = RtlDowncaseUnicodeChar(*End);
+                c = RtlpDowncaseUnicodeChar(*End);
 
                 /* Check if it's a DOS device (LPT, COM, PRN, AUX, or NUL) */
                 if ((End < &PathCopy.Buffer[OriginalLength / sizeof(WCHAR)]) &&
@@ -189,7 +191,7 @@ RtlIsDosDeviceName_Ustr(IN PCUNICODE_STRING PathString)
         }
 
         /* Get the next lower case character and check if it's a DOS device */
-        c = RtlDowncaseUnicodeChar(*PathCopy.Buffer);
+        c = RtlpDowncaseUnicodeChar(*PathCopy.Buffer);
         if ((c != L'l') && (c != L'c') && (c != L'p') && (c != L'a') && (c != L'n'))
         {
             /* Not LPT, COM, PRN, AUX, or NUL */
@@ -614,7 +616,7 @@ RtlGetFullPathName_Ustr(
             ASSERT(FileNameBuffer[1] == L':');
             ASSERT(IS_PATH_SEPARATOR(FileNameBuffer[2]));
 
-            // FileNameBuffer[0] = RtlUpcaseUnicodeChar(FileNameBuffer[0]);
+            // FileNameBuffer[0] = RtlpUpcaseUnicodeChar(FileNameBuffer[0]);
             Prefix = FileNameBuffer;
             PrefixLength = 3 * sizeof(WCHAR);
             Source += 3;
@@ -631,8 +633,8 @@ RtlGetFullPathName_Ustr(
             Source += 2;
             SourceLength -= 2 * sizeof(WCHAR);
 
-            CurDrive = RtlUpcaseUnicodeChar(CurDirName->Buffer[0]);
-            NewDrive = RtlUpcaseUnicodeChar(FileNameBuffer[0]);
+            CurDrive = RtlpUpcaseUnicodeChar(CurDirName->Buffer[0]);
+            NewDrive = RtlpUpcaseUnicodeChar(FileNameBuffer[0]);
 
             if ((NewDrive != CurDrive) || CurDirName->Buffer[1] != L':')
             {
@@ -679,7 +681,7 @@ RtlGetFullPathName_Ustr(
                         goto Quit;
 
                     default:
-                        DPRINT1("RtlQueryEnvironmentVariable_U returned 0x%08lx\n", Status);
+                        DPRINT1("RtlQueryEnvironmentVariable_U(\"%wZ\") returned 0x%08lx\n", &EnvVarName, Status);
 
                         EnvVarNameBuffer[0] = NewDrive;
                         EnvVarNameBuffer[1] = L':';
@@ -1787,13 +1789,89 @@ RtlDosPathNameToRelativeNtPathName_U_WithStatus(IN PCWSTR DosName,
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
-NTSTATUS NTAPI
-RtlNtPathNameToDosPathName(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3, ULONG Unknown4)
+NTSTATUS NTAPI RtlNtPathNameToDosPathName(IN ULONG Flags,
+                                          IN OUT PRTL_UNICODE_STRING_BUFFER Path,
+                                          OUT PULONG PathType,
+                                          PULONG Unknown)
 {
-    DPRINT1("RtlNtPathNameToDosPathName: stub\n");
-    return STATUS_NOT_IMPLEMENTED;
+    PCUNICODE_STRING UsePrefix = NULL, AlternatePrefix = NULL;
+
+    if (PathType)
+        *PathType = 0;
+
+    if (!Path || Flags)
+        return STATUS_INVALID_PARAMETER;
+
+    /* The initial check is done on Path->String */
+    if (RtlPrefixUnicodeString(&RtlpDosDevicesUncPrefix, &Path->String, TRUE))
+    {
+        UsePrefix = &RtlpDosDevicesUncPrefix;
+        AlternatePrefix = &RtlpDoubleSlashPrefix;
+        if (PathType)
+            *PathType = RTL_CONVERTED_UNC_PATH;
+    }
+    else if (RtlPrefixUnicodeString(&RtlpDosDevicesPrefix, &Path->String, FALSE))
+    {
+        UsePrefix = &RtlpDosDevicesPrefix;
+        if (PathType)
+            *PathType = RTL_CONVERTED_NT_PATH;
+    }
+
+    if (UsePrefix)
+    {
+        NTSTATUS Status;
+
+        USHORT Len = Path->String.Length - UsePrefix->Length;
+        if (AlternatePrefix)
+            Len += AlternatePrefix->Length;
+
+        Status = RtlEnsureBufferSize(0, &Path->ByteBuffer, Len);
+        if (!NT_SUCCESS(Status))
+            return Status;
+
+        if (Len + sizeof(UNICODE_NULL) <= Path->ByteBuffer.Size)
+        {
+            /* Then, the contents of Path->ByteBuffer are always used... */
+            if (AlternatePrefix)
+            {
+                memcpy(Path->ByteBuffer.Buffer, AlternatePrefix->Buffer, AlternatePrefix->Length);
+                memmove(Path->ByteBuffer.Buffer + AlternatePrefix->Length, Path->ByteBuffer.Buffer + UsePrefix->Length,
+                    Len - AlternatePrefix->Length);
+            }
+            else
+            {
+                memmove(Path->ByteBuffer.Buffer, Path->ByteBuffer.Buffer + UsePrefix->Length, Len);
+            }
+            Path->String.Buffer = (PWSTR)Path->ByteBuffer.Buffer;
+            Path->String.Length = Len;
+            Path->String.MaximumLength = Path->ByteBuffer.Size;
+            Path->String.Buffer[Len / sizeof(WCHAR)] = UNICODE_NULL;
+        }
+        return STATUS_SUCCESS;
+    }
+
+    if (PathType)
+    {
+        switch (RtlDetermineDosPathNameType_Ustr(&Path->String))
+        {
+        case RtlPathTypeUncAbsolute:
+        case RtlPathTypeDriveAbsolute:
+        case RtlPathTypeLocalDevice:
+        case RtlPathTypeRootLocalDevice:
+            *PathType = RTL_UNCHANGED_DOS_PATH;
+            break;
+        case RtlPathTypeUnknown:
+        case RtlPathTypeDriveRelative:
+        case RtlPathTypeRooted:
+        case RtlPathTypeRelative:
+            *PathType = RTL_UNCHANGED_UNK_PATH;
+            break;
+        }
+    }
+
+    return STATUS_SUCCESS;
 }
 
 /*