From fc32eb9533e943c1468dfb946d39f8586feb53fd Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Thu, 2 Mar 2017 20:43:09 +0000 Subject: [PATCH] [NTDLL_APITEST] Add tests for RtlNtPathNameToDosPathName. CORE-12847 svn path=/trunk/; revision=74030 --- rostests/apitests/ntdll/CMakeLists.txt | 1 + .../ntdll/RtlNtPathNameToDosPathName.c | 447 ++++++++++++++++++ rostests/apitests/ntdll/testlist.c | 2 + 3 files changed, 450 insertions(+) create mode 100644 rostests/apitests/ntdll/RtlNtPathNameToDosPathName.c diff --git a/rostests/apitests/ntdll/CMakeLists.txt b/rostests/apitests/ntdll/CMakeLists.txt index 538261f0240..f5f89d001f3 100644 --- a/rostests/apitests/ntdll/CMakeLists.txt +++ b/rostests/apitests/ntdll/CMakeLists.txt @@ -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 index 00000000000..b1a01099271 --- /dev/null +++ b/rostests/apitests/ntdll/RtlNtPathNameToDosPathName.c @@ -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 + +#define WIN32_NO_STATUS +#include + +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); + } +} diff --git a/rostests/apitests/ntdll/testlist.c b/rostests/apitests/ntdll/testlist.c index a8300288e35..aed17f10666 100644 --- a/rostests/apitests/ntdll/testlist.c +++ b/rostests/apitests/ntdll/testlist.c @@ -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 },