[NTDLL_APITEST] Add tests for RtlNtPathNameToDosPathName. CORE-12847
authorMark Jansen <mark.jansen@reactos.org>
Thu, 2 Mar 2017 20:43:09 +0000 (20:43 +0000)
committerMark Jansen <mark.jansen@reactos.org>
Thu, 2 Mar 2017 20:43:09 +0000 (20:43 +0000)
svn path=/trunk/; revision=74030

rostests/apitests/ntdll/CMakeLists.txt
rostests/apitests/ntdll/RtlNtPathNameToDosPathName.c [new file with mode: 0644]
rostests/apitests/ntdll/testlist.c

index 538261f..f5f89d0 100644 (file)
@@ -43,6 +43,7 @@ list(APPEND SOURCE
     RtlInitializeBitMap.c
     RtlIsNameLegalDOS8Dot3.c
     RtlMemoryStream.c
+    RtlNtPathNameToDosPathName.c
     RtlpEnsureBufferSize.c
     RtlReAllocateHeap.c
     RtlUpcaseUnicodeStringToCountedOemString.c
diff --git a/rostests/apitests/ntdll/RtlNtPathNameToDosPathName.c b/rostests/apitests/ntdll/RtlNtPathNameToDosPathName.c
new file mode 100644 (file)
index 0000000..b1a0109
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * PROJECT:         ReactOS api tests
+ * LICENSE:         GPLv2+ - See COPYING in the top level directory
+ * PURPOSE:         Test for RtlNtPathNameToDosPathName
+ * PROGRAMMER:      Mark Jansen
+ */
+
+#include <apitest.h>
+
+#define WIN32_NO_STATUS
+#include <ndk/rtlfuncs.h>
+
+NTSTATUS (NTAPI *pRtlNtPathNameToDosPathName)(ULONG Flags, RTL_UNICODE_STRING_BUFFER* Path, ULONG* Type, ULONG* Unknown4);
+
+#define ok_hex_(expression, result) \
+    do { \
+        int _value = (expression); \
+        winetest_ok(_value == (result), "Wrong value for '%s', expected: " #result " (0x%x), got: 0x%x\n", \
+           #expression, (int)(result), _value); \
+    } while (0)
+
+
+#define ok_ptr_(expression, result) \
+    do { \
+        void *_value = (expression); \
+        winetest_ok(_value == (result), "Wrong value for '%s', expected: " #result " (%p), got: %p\n", \
+           #expression, (void*)(result), _value); \
+    } while (0)
+
+#define ok_wstr_(x, y) \
+    winetest_ok(wcscmp(x, y) == 0, "Wrong string. Expected '%S', got '%S'\n", y, x)
+
+
+
+struct test_entry
+{
+    WCHAR* InputPath;
+    WCHAR* OutputPath;
+    ULONG Type;
+
+    const char* File;
+    int Line;
+};
+
+
+#define RTL_UNCHANGED_UNK_PATH  1
+#define RTL_CONVERTED_UNC_PATH  2
+#define RTL_CONVERTED_NT_PATH   3
+#define RTL_UNCHANGED_DOS_PATH  4
+
+static struct test_entry test_data[] =
+{
+    /* Originally from RtlGetFullPathName_*.c (edited) */
+    { L"",                      L"",                            RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L".\\test",               L".\\test",                     RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"/test",                 L"/test",                       RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"??\\",                  L"??\\",                        RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"??\\C:",                L"??\\C:",                      RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"??\\C:\\",              L"??\\C:\\",                    RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"??\\C:\\test",          L"??\\C:\\test",                RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"??\\C:\\test\\",        L"??\\C:\\test\\",              RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"C:",                    L"C:",                          RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"C:/test/",              L"C:/test/",                    RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"C:\\",                  L"C:\\",                        RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"C:\\",                  L"C:\\",                        RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"C:\\\\test",            L"C:\\\\test",                  RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"C:\\test",              L"C:\\test",                    RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"C:\\test",              L"C:\\test",                    RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"C:\\test",              L"C:\\test",                    RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"C:\\test\\",            L"C:\\test\\",                  RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"C:\\test\\",            L"C:\\test\\",                  RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"C:\\test\\",            L"C:\\test\\",                  RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\.",                   L"\\.",                         RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\",                 L"\\.\\",                       RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\??\\",                L"",                            RTL_CONVERTED_NT_PATH,          __FILE__, __LINE__ },
+    { L"\\??\\C:",              L"C:",                          RTL_CONVERTED_NT_PATH,          __FILE__, __LINE__ },
+    { L"\\??\\C:\\",            L"C:\\",                        RTL_CONVERTED_NT_PATH,          __FILE__, __LINE__ },
+    { L"\\??\\C:\\test",        L"C:\\test",                    RTL_CONVERTED_NT_PATH,          __FILE__, __LINE__ },
+    { L"\\??\\C:\\test\\",      L"C:\\test\\",                  RTL_CONVERTED_NT_PATH,          __FILE__, __LINE__ },
+    { L"\\\\.",                 L"\\\\.",                       RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\.\\",               L"\\\\.\\",                     RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\.\\",               L"\\\\.\\",                     RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\.\\",               L"\\\\.\\",                     RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\.\\Something\\",    L"\\\\.\\Something\\",          RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\.\\Something\\",    L"\\\\.\\Something\\",          RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\??\\",              L"\\\\??\\",                    RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\??\\",              L"\\\\??\\",                    RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\??\\C:",            L"\\\\??\\C:",                  RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\??\\C:",            L"\\\\??\\C:",                  RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\??\\C:\\",          L"\\\\??\\C:\\",                RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\??\\C:\\",          L"\\\\??\\C:\\",                RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\??\\C:\\test",      L"\\\\??\\C:\\test",            RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\??\\C:\\test",      L"\\\\??\\C:\\test",            RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\??\\C:\\test\\",    L"\\\\??\\C:\\test\\",          RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\??\\C:\\test\\",    L"\\\\??\\C:\\test\\",          RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\test",                L"\\test",                      RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\test",                L"\\test",                      RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\test",                L"\\test",                      RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"test",                  L"test",                        RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"test",                  L"test",                        RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"test",                  L"test",                        RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+
+    /* Originally from RtlDetermineDosPathNameType.c (edited) */
+    { L"",                      L"",                            RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L" ",                     L" ",                           RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"xyz",                   L"xyz",                         RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"CON",                   L"CON",                         RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"NUL",                   L"NUL",                         RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L":",                     L":",                           RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"::",                    L"::",                          RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L":::",                   L":::",                         RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"::::",                  L"::::",                        RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"::\\",                  L"::\\",                        RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\",                    L"\\",                          RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\:",                   L"\\:",                         RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\C:",                  L"\\C:",                        RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\C:\\",                L"\\C:\\",                      RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"/",                     L"/",                           RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"/:",                    L"/:",                          RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"/C:",                   L"/C:",                         RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"/C:/",                  L"/C:/",                        RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"C",                     L"C",                           RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"C:",                    L"C:",                          RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"C:a",                   L"C:a",                         RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"C:a\\",                 L"C:a\\",                       RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"C:\\",                  L"C:\\",                        RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"C:/",                   L"C:/",                         RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"C:\\a",                 L"C:\\a",                       RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"C:/a",                  L"C:/a",                        RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"C:\\\\",                L"C:\\\\",                      RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\",                  L"\\\\",                        RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\\\",                L"\\\\\\",                      RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\;",                 L"\\\\;",                       RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\f\\b\\",            L"\\\\f\\b\\",                  RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\f\\b",              L"\\\\f\\b",                    RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\f\\",               L"\\\\f\\",                     RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\f",                 L"\\\\f",                       RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\??\\UNC",             L"UNC",                         RTL_CONVERTED_NT_PATH,          __FILE__, __LINE__ },
+    { L"\\??\\UNC\\",           L"\\\\",                        RTL_CONVERTED_UNC_PATH,         __FILE__, __LINE__ },
+    { L"\\??\\UNC\\pth1\\pth2", L"\\\\pth1\\pth2",              RTL_CONVERTED_UNC_PATH,         __FILE__, __LINE__ },
+    { L"\\??\\UNC\\path1",      L"\\\\path1",                   RTL_CONVERTED_UNC_PATH,         __FILE__, __LINE__ },
+    { L"\\?",                   L"\\?",                         RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\?\\",                 L"\\?\\",                       RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\?\\UNC",              L"\\?\\UNC",                    RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\?\\UNC\\",            L"\\?\\UNC\\",                  RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\\\?\\UNC\\",          L"\\\\?\\UNC\\",                RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\??\\unc",             L"unc",                         RTL_CONVERTED_NT_PATH,          __FILE__, __LINE__ },
+    { L"\\??\\unc\\",           L"\\\\",                        RTL_CONVERTED_UNC_PATH,         __FILE__, __LINE__ },
+    { L"\\??\\unc\\pth1\\pth2", L"\\\\pth1\\pth2",              RTL_CONVERTED_UNC_PATH,         __FILE__, __LINE__ },
+    { L"\\??\\unc\\path1",      L"\\\\path1",                   RTL_CONVERTED_UNC_PATH,         __FILE__, __LINE__ },
+    { L"\\?",                   L"\\?",                         RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\?\\",                 L"\\?\\",                       RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\?\\unc",              L"\\?\\unc",                    RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\?\\unc\\",            L"\\?\\unc\\",                  RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\\\?\\unc\\",          L"\\\\?\\unc\\",                RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\?",                 L"\\\\?",                       RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\??",                L"\\\\??",                      RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\??\\",              L"\\\\??\\",                    RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\??\\C:\\",          L"\\\\??\\C:\\",                RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\.",                 L"\\\\.",                       RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\.\\",               L"\\\\.\\",                     RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\\\.\\C:\\",           L"\\\\.\\C:\\",                 RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\/",                   L"\\/",                         RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"/\\",                   L"/\\",                         RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"//",                    L"//",                          RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"///",                   L"///",                         RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"//;",                   L"//;",                         RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"//?",                   L"//?",                         RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"/\\?",                  L"/\\?",                        RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\/?",                  L"\\/?",                        RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"//??",                  L"//??",                        RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"//?" L"?/",             L"//?" L"?/",                   RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"//?" L"?/C:/",          L"//?" L"?/C:/",                RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"//.",                   L"//.",                         RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"\\/.",                  L"\\/.",                        RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"/\\.",                  L"/\\.",                        RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"//./",                  L"//./",                        RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"//./C:/",               L"//./C:/",                     RTL_UNCHANGED_DOS_PATH,         __FILE__, __LINE__ },
+    { L"%SystemRoot%",          L"%SystemRoot%",                RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+
+
+    /* Tests from RtlGetLengthWithoutTrailingPathSeperators.c */
+    { L"",                      L"",                            RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"T",                     L"T",                           RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"Te",                    L"Te",                          RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"Tes",                   L"Tes",                         RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"Test",                  L"Test",                        RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+
+    /* Separators tests */
+    { L"\\.",                   L"\\.",                         RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.",                   L"\\.",                         RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\",                 L"\\.\\",                       RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\T",                L"\\.\\T",                      RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\Te",               L"\\.\\Te",                     RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\Tes",              L"\\.\\Tes",                    RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\Test",             L"\\.\\Test",                   RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\Test\\",           L"\\.\\Test\\",                 RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\Test\\s",          L"\\.\\Test\\s",                RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\T\\est",           L"\\.\\T\\est",                 RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\T\\e\\st",         L"\\.\\T\\e\\st",               RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\T\\e\\s\\t",       L"\\.\\T\\e\\s\\t",             RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\T\\e\\s\\t\\",     L"\\.\\T\\e\\s\\t\\",           RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\Tests\\String\\",     L"\\Tests\\String\\",           RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\Test\\String\\",   L"\\.\\Test\\String\\",         RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\Tests\\String\\",  L"\\.\\Tests\\String\\",        RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\Tests\\String\\s", L"\\.\\Tests\\String\\s",       RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+
+    /* Separator-only tests */
+    { L"\\",                    L"\\",                          RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"/",                     L"/",                           RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+
+    /* Mixed separators tests */
+    { L"/Test/String",          L"/Test/String",                RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\Test/String",         L"\\Test/String",               RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"/Test\\String",         L"/Test\\String",               RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\Test/String",         L"\\Test/String",               RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"/Test/String\\",        L"/Test/String\\",              RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\Test/String\\",       L"\\Test/String\\",             RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"/Test\\String\\",       L"/Test\\String\\",             RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\Test/String\\",       L"\\Test/String\\",             RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"/Test/String/",         L"/Test/String/",               RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\Test/String/",        L"\\Test/String/",              RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"/Test\\String/",        L"/Test\\String/",              RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\Test/String/",        L"\\Test/String/",              RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\Test/String/",        L"\\Test/String/",              RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\Test\\\\String/",     L"\\Test\\\\String/",           RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+
+    /* Common path formats tests */
+    { L"Test\\String",          L"Test\\String",                RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\Test\\String",        L"\\Test\\String",              RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L".\\Test\\String",       L".\\Test\\String",             RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\.\\Test\\String",     L"\\.\\Test\\String",           RTL_UNCHANGED_UNK_PATH,         __FILE__, __LINE__ },
+    { L"\\??\\Test\\String",    L"Test\\String",                RTL_CONVERTED_NT_PATH,          __FILE__, __LINE__ },
+
+    /* Redundant trailing tests */
+    { L"\\??\\Test\\String\\",  L"Test\\String\\",              RTL_CONVERTED_NT_PATH,          __FILE__, __LINE__ },
+    { L"\\??\\Test\\String\\\\",L"Test\\String\\\\",            RTL_CONVERTED_NT_PATH,          __FILE__, __LINE__ },
+    { L"\\??\\Test\\String\\\\\\\\\\", L"Test\\String\\\\\\\\\\",RTL_CONVERTED_NT_PATH,         __FILE__, __LINE__ },
+};
+
+
+static void test_specialhandling()
+{
+    RTL_UNICODE_STRING_BUFFER Buffer;
+    const WCHAR TestString[] = L"\\??\\C:\\Test";
+    WCHAR StaticBuffer[_countof(TestString)];
+    ULONG Type;
+    //PUCHAR Ptr;
+
+    /* Just initializing the ByteBuffer does not work */
+    memset(&Buffer, 0, sizeof(Buffer));
+    RtlInitBuffer(&Buffer.ByteBuffer, (PUCHAR)StaticBuffer, sizeof(StaticBuffer));
+    memcpy(StaticBuffer, TestString, sizeof(TestString));
+    Type = 0x12345;
+
+    ok_hex(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
+    ok_hex(Type, RTL_UNCHANGED_UNK_PATH);
+    ok_ptr(Buffer.String.Buffer, NULL);
+    ok_int(Buffer.String.Length, 0);
+    ok_int(Buffer.String.MaximumLength, 0);
+    ok_ptr(Buffer.ByteBuffer.Buffer, Buffer.ByteBuffer.StaticBuffer);
+    ok_int(Buffer.ByteBuffer.Size, Buffer.ByteBuffer.StaticSize);
+    RtlFreeBuffer(&Buffer.ByteBuffer);
+
+    /* Different strings in the String and ByteBuffer part */
+    memset(&Buffer, 0, sizeof(Buffer));
+    RtlInitBuffer(&Buffer.ByteBuffer, (PUCHAR)StaticBuffer, sizeof(StaticBuffer));
+    memcpy(StaticBuffer, TestString, sizeof(TestString));
+    Type = 0x12345;
+
+    RtlInitUnicodeString(&Buffer.String, L"\\??\\D:\\1234");
+
+    ok_hex(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
+    ok_hex(Type, RTL_CONVERTED_NT_PATH);
+    ok_wstr(Buffer.String.Buffer, L"C:\\Test");
+    ok_int(Buffer.String.Length, 14);
+    ok_int(Buffer.String.MaximumLength, 24);
+    ok_ptr(Buffer.ByteBuffer.Buffer, Buffer.ByteBuffer.StaticBuffer);
+    ok_int(Buffer.ByteBuffer.Size, Buffer.ByteBuffer.StaticSize);
+    RtlFreeBuffer(&Buffer.ByteBuffer);
+
+
+    /* Different strings, Buffer.String is not prefixed with \??\ */
+    memset(&Buffer, 0, sizeof(Buffer));
+    RtlInitBuffer(&Buffer.ByteBuffer, (PUCHAR)StaticBuffer, sizeof(StaticBuffer));
+    memcpy(StaticBuffer, TestString, sizeof(TestString));
+    Type = 0x12345;
+
+    RtlInitUnicodeString(&Buffer.String, L"D:\\1234");
+
+    ok_hex(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
+    ok_hex(Type, RTL_UNCHANGED_DOS_PATH);
+    ok_wstr(Buffer.String.Buffer, L"D:\\1234");
+    ok_int(Buffer.String.Length, 14);
+    ok_int(Buffer.String.MaximumLength, 16);
+    ok_ptr(Buffer.ByteBuffer.Buffer, Buffer.ByteBuffer.StaticBuffer);
+    ok_int(Buffer.ByteBuffer.Size, Buffer.ByteBuffer.StaticSize);
+    RtlFreeBuffer(&Buffer.ByteBuffer);
+
+
+    /* Different strings, smaller ByteBuffer */
+    memset(&Buffer, 0, sizeof(Buffer));
+    RtlInitBuffer(&Buffer.ByteBuffer, (PUCHAR)StaticBuffer, sizeof(StaticBuffer));
+    memcpy(StaticBuffer, TestString, sizeof(TestString));
+    Type = 0x12345;
+
+    RtlInitUnicodeString(&Buffer.String, L"\\??\\D:\\1234");
+    Buffer.ByteBuffer.Size -= 4 * sizeof(WCHAR);
+
+    ok_hex(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
+    ok_hex(Type, RTL_CONVERTED_NT_PATH);
+    ok_wstr(Buffer.String.Buffer, L"C:\\Test");
+    ok_int(Buffer.String.Length, 14);
+    ok_ptr(Buffer.ByteBuffer.Buffer, Buffer.ByteBuffer.StaticBuffer);
+    ok_int(Buffer.ByteBuffer.Size, Buffer.ByteBuffer.StaticSize - 4 * sizeof(WCHAR));
+    RtlFreeBuffer(&Buffer.ByteBuffer);
+
+
+    /* These tests show that the size of the ByteBuffer should
+        at least equal the size of the string (minus 4, in case of \??\)!
+        The results are all over the place, and are most likely the result of implementation details.. */
+
+#if 0
+    /* Different strings, too small ByteBuffer
+        --> corrupt buffer, but none of the output params suggests so? */
+    memset(&Buffer, 0, sizeof(Buffer));
+    Buffer.ByteBuffer.Size = wcslen(TestString) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
+    Buffer.ByteBuffer.Buffer = Ptr = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Buffer.ByteBuffer.Size);
+    memcpy(Buffer.ByteBuffer.Buffer, TestString, Buffer.ByteBuffer.Size);
+    Type = 0x12345;
+
+    RtlInitUnicodeString(&Buffer.String, L"\\??\\D:\\1234");
+    Buffer.ByteBuffer.Size -= 5 * sizeof(WCHAR);
+
+    ok_hex(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
+    ok_hex(Type, RTL_CONVERTED_NT_PATH);
+    //ok_wstr(Buffer.String.Buffer, L"C:\\");
+    ok_int(Buffer.String.Length, 14);
+    ok_int(Buffer.String.MaximumLength, 16);
+    //ok_ptr(Buffer.ByteBuffer.Buffer, Ptr);    // An attempt is made at allocating a buffer, but the move fails because the size of ByteBuffer seems to be used??
+    ok_int(Buffer.ByteBuffer.Size, 16);
+
+    RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer.ByteBuffer.Buffer);
+
+    /* Different strings, too small ByteBuffer, different path separators
+        --> corrupt buffer, but none of the output params suggests so? */
+    memset(&Buffer, 0, sizeof(Buffer));
+    Buffer.ByteBuffer.Size = wcslen(L"\\??\\C://Test") * sizeof(WCHAR) + sizeof(UNICODE_NULL);
+    Buffer.ByteBuffer.Buffer = Ptr = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Buffer.ByteBuffer.Size);
+    memcpy(Buffer.ByteBuffer.Buffer, L"\\??\\C://Test", Buffer.ByteBuffer.Size);
+    Type = 0x12345;
+
+    RtlInitUnicodeString(&Buffer.String, L"\\??\\D:\\1234");
+    Buffer.ByteBuffer.Size -= 5 * sizeof(WCHAR);
+
+    ok_hex(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
+    ok_hex(Type, RTL_CONVERTED_NT_PATH);
+    //ok_wstr(Buffer.String.Buffer, L"C:\\");
+    ok_int(Buffer.String.Length, 14);
+    ok_int(Buffer.String.MaximumLength, 16);
+    ok_ptr(Buffer.ByteBuffer.Buffer, Ptr);
+    ok_int(Buffer.ByteBuffer.Size, 16);
+
+    RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer.ByteBuffer.Buffer);
+#endif
+}
+
+static void test_table(struct test_entry* Entry)
+{
+    RTL_UNICODE_STRING_BUFFER Buffer = { { 0 } };
+    WCHAR StaticBuffer[MAX_PATH];
+    ULONG Type = 0x12345;
+
+    RtlInitBuffer(&Buffer.ByteBuffer, (PUCHAR)StaticBuffer, sizeof(StaticBuffer));
+
+    RtlInitUnicodeString(&Buffer.String, Entry->InputPath);
+    RtlEnsureBufferSize(RTL_SKIP_BUFFER_COPY, &Buffer.ByteBuffer, Buffer.String.MaximumLength);
+    memcpy(Buffer.ByteBuffer.Buffer, Buffer.String.Buffer, Buffer.String.MaximumLength);
+
+    ok_hex_(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
+
+    ok_hex_(Type, Entry->Type);
+    ok_wstr_(Buffer.String.Buffer, Entry->OutputPath);
+    /* If there is no change in the path, the pointer is unchanged */
+    if (!wcscmp(Entry->InputPath, Entry->OutputPath))
+    {
+        ok_ptr_(Buffer.String.Buffer, Entry->InputPath);
+    }
+    else
+    {
+        /* If there is a change in the path, the 'ByteBuffer' is used */
+        winetest_ok((PUCHAR)Buffer.String.Buffer >= Buffer.ByteBuffer.StaticBuffer &&
+                    (PUCHAR)Buffer.String.Buffer <= (Buffer.ByteBuffer.StaticBuffer + Buffer.ByteBuffer.StaticSize),
+                    "Expected Buffer to point inside StaticBuffer\n");
+    }
+    ok_wstr_((const WCHAR *)Buffer.ByteBuffer.Buffer, Entry->OutputPath);
+
+    ok_hex_(Buffer.MinimumStaticBufferForTerminalNul, 0);
+
+    /* For none of our tests should we exceed the StaticBuffer size! */
+    ok_ptr_(Buffer.ByteBuffer.Buffer, Buffer.ByteBuffer.StaticBuffer);
+    ok_hex_(Buffer.ByteBuffer.Size, Buffer.ByteBuffer.StaticSize);
+
+    ok_hex_(Buffer.ByteBuffer.ReservedForAllocatedSize, 0);
+    ok_ptr_(Buffer.ByteBuffer.ReservedForIMalloc, NULL);
+
+    RtlFreeBuffer(&Buffer.ByteBuffer);
+}
+
+
+START_TEST(RtlNtPathNameToDosPathName)
+{
+    RTL_UNICODE_STRING_BUFFER Buffer = { { 0 } };
+    ULONG Type;
+    size_t n;
+
+    HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
+    pRtlNtPathNameToDosPathName = (void *)GetProcAddress(ntdll, "RtlNtPathNameToDosPathName");
+
+    if (!pRtlNtPathNameToDosPathName)
+    {
+        skip("RtlNtPathNameToDosPathName not found?\n");
+        return;
+    }
+
+    ok_ntstatus(pRtlNtPathNameToDosPathName(0, NULL, NULL, NULL), STATUS_INVALID_PARAMETER);
+    ok_ntstatus(pRtlNtPathNameToDosPathName(0, &Buffer, NULL, NULL), STATUS_SUCCESS);
+    ok_ntstatus(pRtlNtPathNameToDosPathName(1, &Buffer, NULL, NULL), STATUS_INVALID_PARAMETER);
+
+    Type = 0x12345;
+    ok_ntstatus(pRtlNtPathNameToDosPathName(0, NULL, &Type, NULL), STATUS_INVALID_PARAMETER);
+    ok_int(Type, 0);
+    Type = 0x12345;
+    ok_ntstatus(pRtlNtPathNameToDosPathName(0, &Buffer, &Type, NULL), STATUS_SUCCESS);
+    ok_int(Type, RTL_UNCHANGED_UNK_PATH);
+    Type = 0x12345;
+    ok_ntstatus(pRtlNtPathNameToDosPathName(1, &Buffer, &Type, NULL), STATUS_INVALID_PARAMETER);
+    ok_int(Type, 0);
+
+    test_specialhandling();
+
+    for (n = 0; n < _countof(test_data); ++n)
+    {
+        winetest_set_location(test_data[n].File, test_data[n].Line);
+        test_table(test_data + n);
+    }
+}
index a830028..aed17f1 100644 (file)
@@ -47,6 +47,7 @@ extern void func_RtlImageRvaToVa(void);
 extern void func_RtlInitializeBitMap(void);
 extern void func_RtlIsNameLegalDOS8Dot3(void);
 extern void func_RtlMemoryStream(void);
+extern void func_RtlNtPathNameToDosPathName(void);
 extern void func_RtlpEnsureBufferSize(void);
 extern void func_RtlReAllocateHeap(void);
 extern void func_RtlUpcaseUnicodeStringToCountedOemString(void);
@@ -99,6 +100,7 @@ const struct test winetest_testlist[] =
     { "RtlInitializeBitMap",            func_RtlInitializeBitMap },
     { "RtlIsNameLegalDOS8Dot3",         func_RtlIsNameLegalDOS8Dot3 },
     { "RtlMemoryStream",                func_RtlMemoryStream },
+    { "RtlNtPathNameToDosPathName",     func_RtlNtPathNameToDosPathName },
     { "RtlpEnsureBufferSize",           func_RtlpEnsureBufferSize },
     { "RtlReAllocateHeap",              func_RtlReAllocateHeap },
     { "RtlUpcaseUnicodeStringToCountedOemString", func_RtlUpcaseUnicodeStringToCountedOemString },