[NTDLL_APITEST] Add test for RtlComputePrivatizedDllName_U
authorMark Jansen <mark.jansen@reactos.org>
Sat, 2 Feb 2019 01:31:48 +0000 (02:31 +0100)
committerMark Jansen <mark.jansen@reactos.org>
Thu, 7 Feb 2019 17:48:49 +0000 (18:48 +0100)
modules/rostests/apitests/ntdll/CMakeLists.txt
modules/rostests/apitests/ntdll/RtlComputePrivatizedDllName_U.c [new file with mode: 0644]
modules/rostests/apitests/ntdll/testlist.c

index e3a2725..8e8f2fc 100644 (file)
@@ -38,6 +38,7 @@ list(APPEND SOURCE
     NtWriteFile.c
     RtlAllocateHeap.c
     RtlBitmap.c
+    RtlComputePrivatizedDllName_U.c
     RtlCopyMappedMemory.c
     RtlDeleteAce.c
     RtlDetermineDosPathNameType.c
diff --git a/modules/rostests/apitests/ntdll/RtlComputePrivatizedDllName_U.c b/modules/rostests/apitests/ntdll/RtlComputePrivatizedDllName_U.c
new file mode 100644 (file)
index 0000000..ee91ca6
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * PROJECT:     ReactOS api tests
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Test for RtlComputePrivatizedDllName_U
+ * COPYRIGHT:   Copyright 2019 Mark Jansen (mark.jansen@reactos.org)
+ */
+
+#include "precomp.h"
+
+
+static WCHAR ProcessDir[MAX_PATH];
+static WCHAR LocalDir[MAX_PATH + 10];
+
+static BOOL InitTestData()
+{
+    static const UNICODE_STRING PathDividerFind = RTL_CONSTANT_STRING(L"\\/");
+    UNICODE_STRING StrU;
+    USHORT PathDivider;
+
+    GetModuleFileNameW(NULL, ProcessDir, RTL_NUMBER_OF(ProcessDir));
+    GetModuleFileNameW(NULL, LocalDir, RTL_NUMBER_OF(LocalDir));
+
+    RtlInitUnicodeString(&StrU, ProcessDir);
+
+    if (!NT_SUCCESS(RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END,
+                                               &StrU, &PathDividerFind, &PathDivider)))
+    {
+        skip("Failed to find path divider\n");
+        return FALSE;
+    }
+    ProcessDir[PathDivider / sizeof(WCHAR) + 1] = UNICODE_NULL;
+
+    RtlInitUnicodeString(&StrU, LocalDir);
+    StrU.MaximumLength = sizeof(LocalDir);
+
+    if (!NT_SUCCESS(RtlAppendUnicodeToString(&StrU, L".Local\\")))
+    {
+        skip("Failed to append .Local\\\n");
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static void ok_strings_(PCUNICODE_STRING RealName, PCUNICODE_STRING LocalName, LPCWSTR DllName, int line)
+{
+    WCHAR ExpectReal[MAX_PATH*2];
+    WCHAR ExpectLocal[MAX_PATH*2];
+    int RealLen;
+    int ExpectLen;
+
+    RealLen = swprintf(ExpectReal, L"%s%s", ProcessDir, DllName) * sizeof(WCHAR);
+    ExpectLen = swprintf(ExpectLocal, L"%s%s", LocalDir, DllName) * sizeof(WCHAR);
+
+    ok_(__FILE__, line)(RealLen == RealName->Length, "Expected Real %u, got %u\n",
+                        (UINT)RealLen, (UINT)RealName->Length);
+    ok_(__FILE__, line)(ExpectLen == LocalName->Length, "Expected Local %u, got %u\n",
+                        (UINT)ExpectLen, (UINT)LocalName->Length);
+
+    ok_(__FILE__, line)(!wcscmp(RealName->Buffer, ExpectReal), "Expected Real %s, got %s\n",
+                        wine_dbgstr_w(ExpectReal), wine_dbgstr_w(RealName->Buffer));
+    ok_(__FILE__, line)(!wcscmp(LocalName->Buffer, ExpectLocal), "Expected Local %s, got %s\n",
+                        wine_dbgstr_w(ExpectLocal), wine_dbgstr_w(LocalName->Buffer));
+}
+#define ok_strings(Real, Local, Dll)    ok_strings_(Real, Local, Dll, __LINE__)
+
+
+static void cleanup(PUNICODE_STRING String, WCHAR* Buffer, USHORT BufferSize)
+{
+    if (String->Buffer != Buffer)
+    {
+        RtlFreeUnicodeString(String);
+        RtlInitEmptyUnicodeString(String, Buffer, BufferSize);
+    }
+}
+
+
+static void test_dllnames(void)
+{
+    WCHAR Buf1[MAX_PATH];
+    WCHAR Buf2[MAX_PATH];
+
+    UNICODE_STRING Str1, Str2;
+    UNICODE_STRING DllName;
+    NTSTATUS Status;
+
+    RtlInitEmptyUnicodeString(&Str1, Buf1, sizeof(Buf1));
+    RtlInitEmptyUnicodeString(&Str2, Buf2, sizeof(Buf2));
+
+    RtlInitUnicodeString(&DllName, L"kernel32.dll");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L"kernel32.dll");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+
+
+    RtlInitUnicodeString(&DllName, L"kernel32");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L"kernel32.DLL");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+
+    RtlInitUnicodeString(&DllName, L"kernel32.dll.dll");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L"kernel32.dll.dll");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+
+    RtlInitUnicodeString(&DllName, L"kernel32.dll.exe");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L"kernel32.dll.exe");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+
+    RtlInitUnicodeString(&DllName, L"kernel32.");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L"kernel32.");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+
+    RtlInitUnicodeString(&DllName, L".kernel32");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L".kernel32.DLL");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+
+    RtlInitUnicodeString(&DllName, L"..kernel32");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L"..kernel32");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+
+    RtlInitUnicodeString(&DllName, L".kernel32.");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L".kernel32.");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+
+
+    RtlInitUnicodeString(&DllName, L"test\\kernel32.dll");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L"kernel32.dll");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+
+    RtlInitUnicodeString(&DllName, L"test/kernel32.dll");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L"kernel32.dll");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+
+    RtlInitUnicodeString(&DllName, L"test.dll/kernel32");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L"kernel32.DLL");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+
+    RtlInitUnicodeString(&DllName, L"test.dll\\kernel32");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L"kernel32.DLL");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+
+    RtlInitUnicodeString(&DllName, L"//");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L".DLL");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+
+    // Bug :)
+    RtlInitUnicodeString(&DllName, L"\\");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    if (wcsstr(Str1.Buffer, L"\\\\"))
+    {
+        trace("Allowing bug found in windows' implementation\n");
+        ok_strings(&Str1, &Str2, L"\\.DLL");
+    }
+    else
+    {
+        ok_strings(&Str1, &Str2, L".DLL");
+    }
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+
+    RtlInitUnicodeString(&DllName, L"");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L".DLL");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+}
+
+static void test_allocations(void)
+{
+    WCHAR Buf1[10];
+    WCHAR Buf2[10];
+
+    UNICODE_STRING Str1, Str2;
+    UNICODE_STRING DllName;
+    NTSTATUS Status;
+
+    RtlInitEmptyUnicodeString(&Str1, Buf1, sizeof(Buf1));
+    RtlInitEmptyUnicodeString(&Str2, Buf2, sizeof(Buf2));
+
+    RtlInitUnicodeString(&DllName, L"kernel32.dll");
+    Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2);
+    ok(Status == STATUS_SUCCESS, "0x%lx\n", Status);
+    ok_strings(&Str1, &Str2, L"kernel32.dll");
+    ok(Str1.Buffer != Buf1, "Expected a changed buffer\n");
+    ok(Str2.Buffer != Buf2, "Expected a changed buffer\n");
+    cleanup(&Str1, Buf1, sizeof(Buf1));
+    cleanup(&Str2, Buf2, sizeof(Buf2));
+}
+
+
+START_TEST(RtlComputePrivatizedDllName_U)
+{
+    if (!InitTestData())
+        return;
+
+    test_dllnames();
+    test_allocations();
+}
index a828865..bfaf8b4 100644 (file)
@@ -37,6 +37,7 @@ extern void func_NtSystemInformation(void);
 extern void func_NtWriteFile(void);
 extern void func_RtlAllocateHeap(void);
 extern void func_RtlBitmap(void);
+extern void func_RtlComputePrivatizedDllName_U(void);
 extern void func_RtlCopyMappedMemory(void);
 extern void func_RtlDeleteAce(void);
 extern void func_RtlDetermineDosPathNameType(void);
@@ -102,6 +103,7 @@ const struct test winetest_testlist[] =
     { "NtWriteFile",                    func_NtWriteFile },
     { "RtlAllocateHeap",                func_RtlAllocateHeap },
     { "RtlBitmapApi",                   func_RtlBitmap },
+    { "RtlComputePrivatizedDllName_U",  func_RtlComputePrivatizedDllName_U },
     { "RtlCopyMappedMemory",            func_RtlCopyMappedMemory },
     { "RtlDeleteAce",                   func_RtlDeleteAce },
     { "RtlDetermineDosPathNameType",    func_RtlDetermineDosPathNameType },