https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4e0ce779d777901c082d9…
commit 4e0ce779d777901c082d9501f43aabdfa3502451
Author:     Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Mon May 17 12:07:26 2021 +0200
Commit:     Jérôme Gardou <zefklop(a)users.noreply.github.com>
CommitDate: Wed May 19 22:50:29 2021 +0200
    [NTDLL_APITEST] Add some tests for RtlUnicodeToOemN
    CORE-17571
---
 modules/rostests/apitests/ntdll/CMakeLists.txt     |   1 +
 modules/rostests/apitests/ntdll/RtlUnicodeToOemN.c | 237 +++++++++++++++++++++
 modules/rostests/apitests/ntdll/testlist.c         |   2 +
 3 files changed, 240 insertions(+)
diff --git a/modules/rostests/apitests/ntdll/CMakeLists.txt
b/modules/rostests/apitests/ntdll/CMakeLists.txt
index 684990e2df5..ef5f6a61302 100644
--- a/modules/rostests/apitests/ntdll/CMakeLists.txt
+++ b/modules/rostests/apitests/ntdll/CMakeLists.txt
@@ -81,6 +81,7 @@ list(APPEND SOURCE
     RtlReAllocateHeap.c
     RtlUnicodeStringToAnsiString.c
     RtlUnicodeStringToCountedOemString.c
+    RtlUnicodeToOemN.c
     RtlUpcaseUnicodeStringToCountedOemString.c
     RtlValidateUnicodeString.c
     RtlxUnicodeStringToAnsiSize.c
diff --git a/modules/rostests/apitests/ntdll/RtlUnicodeToOemN.c
b/modules/rostests/apitests/ntdll/RtlUnicodeToOemN.c
new file mode 100644
index 00000000000..ff20e9a7b82
--- /dev/null
+++ b/modules/rostests/apitests/ntdll/RtlUnicodeToOemN.c
@@ -0,0 +1,237 @@
+/*
+ * PROJECT:     ReactOS API tests
+ * LICENSE:     0BSD (
https://spdx.org/licenses/0BSD.html)
+ * PURPOSE:     Test for RtlUnicodeToOemN
+ * COPYRIGHT:   Copyright 2021 Jérôme Gardou <jerome.gardou(a)reactos.org>
+ */
+
+#include "precomp.h"
+
+static const struct
+{
+    ULONG AnsiCp;
+    ULONG OemCp;
+    struct
+    {
+        LPCWSTR StrW;
+        NTSTATUS Status;
+        ULONG ReturnedSize;
+        LPCSTR StrOem;
+    } Test[10];
+} TestData[] =
+{
+    {
+        1252, 1252, /* Western SBCS */
+        {
+            {
+                L"ABCDEF",
+                STATUS_SUCCESS,
+                6,
+                "ABCDEF"
+            },
+            {
+                L"ABCDEF",
+                STATUS_SUCCESS,
+                6,
+                "ABCDEF\xAA\xAA\xAA"
+            },
+            {
+                L"ABCDEF",
+                STATUS_BUFFER_OVERFLOW,
+                3,
+                "ABC"
+            },
+            {
+                L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7",
+                STATUS_SUCCESS,
+                6,
+                "??????"
+            },
+            {
+                L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7",
+                STATUS_BUFFER_OVERFLOW,
+                3,
+                "???"
+            },
+        }
+    },
+    {
+        1252, 932, /* Western SBCS - Modified SJIS */
+        {
+            {
+                L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7",
+                STATUS_SUCCESS,
+                12,
+                "\x83\x66\x83\x58\x83\x4e\x83\x67\x83\x62\x83\x76"
+            },
+            {
+                L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7",
+                STATUS_SUCCESS,
+                12,
+                "\x83\x66\x83\x58\x83\x4e\x83\x67\x83\x62\x83\x76\xAA\xAA\xAA"
+            },
+        }
+    },
+    {
+        932, 1252, /* Modified SJIS - Western SBCS */
+        {
+            {
+                L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7",
+                STATUS_SUCCESS,
+                6,
+                "??????"
+            },
+            {
+                L"\u30c7\u30b9\u30afABC",
+                STATUS_SUCCESS,
+                6,
+                "???ABC"
+            },
+            {
+                L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7",
+                STATUS_BUFFER_OVERFLOW,
+                3,
+                "???"
+            },
+        }
+    },
+    {
+        932, 932, /* Modified SJIS - Modified SJIS */
+        {
+            {
+                L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7",
+                STATUS_SUCCESS,
+                12,
+                "\x83\x66\x83\x58\x83\x4e\x83\x67\x83\x62\x83\x76"
+            }
+        }
+    },
+};
+
+START_TEST(RtlUnicodeToOemN)
+{
+    ULONG Length;
+    LPSTR StrOem;
+    ULONG ResultSize;
+    NTSTATUS Status;
+    CHAR OemBuffer[4];
+
+    /* Basic things */
+    Status = RtlUnicodeToOemN(NULL, 0, NULL, NULL, 0);
+    ok_ntstatus(Status, STATUS_SUCCESS);
+
+    Status = RtlUnicodeToOemN(NULL, 0, NULL, L"ABCDEF", 0);
+    ok_ntstatus(Status, STATUS_SUCCESS);
+
+    Status = RtlUnicodeToOemN(NULL, 0, NULL, NULL, 2);
+    ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW);
+
+    Status = RtlUnicodeToOemN(NULL, 0, NULL, L"A", 2);
+    ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW);
+
+    Status = RtlUnicodeToOemN(NULL, 0, NULL, L"A", 2);
+    ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW);
+
+    StartSeh()
+    Status = RtlUnicodeToOemN(NULL, 1, NULL, L"A", 2);
+    EndSeh(STATUS_ACCESS_VIOLATION)
+
+    OemBuffer[0] = 0xAA;
+    OemBuffer[1] = 0xAA;
+    Status = RtlUnicodeToOemN(OemBuffer, 1, NULL, L"A", 2);
+    ok_ntstatus(Status, STATUS_SUCCESS);
+    ok_char(OemBuffer[0], 'A');
+    ok_char(OemBuffer[1], (CHAR)0xAA);
+
+    OemBuffer[0] = 0xAA;
+    OemBuffer[1] = 0xAA;
+    Status = RtlUnicodeToOemN(OemBuffer, 1, NULL, L"AB", 4);
+    ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW);
+    ok_char(OemBuffer[0], 'A');
+    ok_char(OemBuffer[1], (CHAR)0xAA);
+
+    OemBuffer[0] = 0xAA;
+    OemBuffer[1] = 0xAA;
+    Status = RtlUnicodeToOemN(OemBuffer, 2, NULL, L"A", 4);
+    ok_ntstatus(Status, STATUS_SUCCESS);
+    ok_char(OemBuffer[0], 'A');
+    ok_char(OemBuffer[1], '\0');
+
+    /* RtlUnicodeToOemN doesn't care about string termination */
+    OemBuffer[0] = 0xAA;
+    OemBuffer[1] = 0xAA;
+    Status = RtlUnicodeToOemN(OemBuffer, 1, NULL, L"A", 4);
+    ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW);
+    ok_char(OemBuffer[0], 'A');
+    ok_char(OemBuffer[1], (CHAR)0xAA);
+
+    OemBuffer[0] = 0xAA;
+    OemBuffer[1] = 0xAA;
+    OemBuffer[2] = 0xAA;
+    OemBuffer[3] = 0xAA;
+    Status = RtlUnicodeToOemN(OemBuffer, 4, NULL, L"A\0B", 8);
+    ok_ntstatus(Status, STATUS_SUCCESS);
+    ok_char(OemBuffer[0], 'A');
+    ok_char(OemBuffer[1], '\0');
+    ok_char(OemBuffer[2], 'B');
+    ok_char(OemBuffer[3], '\0');
+
+    /* Odd Unicode buffer size */
+    OemBuffer[0] = 0xAA;
+    OemBuffer[1] = 0xAA;
+    OemBuffer[2] = 0xAA;
+    OemBuffer[3] = 0xAA;
+    Status = RtlUnicodeToOemN(OemBuffer, 2, NULL, L"AB", 5);
+    ok_ntstatus(Status, STATUS_SUCCESS);
+    ok_char(OemBuffer[0], 'A');
+    ok_char(OemBuffer[1], 'B');
+    ok_char(OemBuffer[2], (CHAR)0xAA);
+    ok_char(OemBuffer[3], (CHAR)0xAA);
+
+    /* Odd Unicode buffer size */
+    OemBuffer[0] = 0xAA;
+    OemBuffer[1] = 0xAA;
+    OemBuffer[2] = 0xAA;
+    OemBuffer[3] = 0xAA;
+    Status = RtlUnicodeToOemN(OemBuffer, 3, NULL, L"AB", 5);
+    ok_ntstatus(Status, STATUS_SUCCESS);
+    ok_char(OemBuffer[0], 'A');
+    ok_char(OemBuffer[1], 'B');
+    ok_char(OemBuffer[2], (CHAR)0xAA);
+    ok_char(OemBuffer[3], (CHAR)0xAA);
+
+    for (int i = 0; i < _countof(TestData); i++)
+    {
+        SetupLocale(TestData[i].AnsiCp, TestData[i].OemCp, -1);
+
+        for (int j = 0; TestData[i].Test[j].StrW != NULL; j++)
+        {
+            Length = strlen(TestData[i].Test[j].StrOem);
+            StrOem = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length + 1);
+
+            memset(StrOem, 0xAA, Length + 1);
+            ResultSize = 0x0BADF00D;
+
+            Status = RtlUnicodeToOemN(StrOem,
+                                      Length,
+                                      &ResultSize,
+                                      TestData[i].Test[j].StrW,
+                                      wcslen(TestData[i].Test[j].StrW) * sizeof(WCHAR));
+
+            ok_ntstatus(Status, TestData[i].Test[j].Status);
+            ok_long(ResultSize, TestData[i].Test[j].ReturnedSize);
+            for (int k = 0; k < ResultSize; k++)
+            {
+                ok(StrOem[k] == TestData[i].Test[j].StrOem[k],
+                   "Wrong char \\x%02x, expected TestData[%u].Test[%u].StrOem[%u]
(\\x%02x)\n",
+                   StrOem[k], i, j, k, TestData[i].Test[j].StrOem[k]);
+            }
+            for (int k = ResultSize; k < (Length + 1); k++)
+            {
+                ok_char(StrOem[k], (CHAR)0xAA);
+            }
+
+            RtlFreeHeap(RtlGetProcessHeap(), 0, StrOem);
+        }
+    }
+}
diff --git a/modules/rostests/apitests/ntdll/testlist.c
b/modules/rostests/apitests/ntdll/testlist.c
index 5d4b00b0cce..5a56ec6e987 100644
--- a/modules/rostests/apitests/ntdll/testlist.c
+++ b/modules/rostests/apitests/ntdll/testlist.c
@@ -77,6 +77,7 @@ extern void func_RtlQueryTimeZoneInformation(void);
 extern void func_RtlReAllocateHeap(void);
 extern void func_RtlUnicodeStringToAnsiString(void);
 extern void func_RtlUnicodeStringToCountedOemString(void);
+extern void func_RtlUnicodeToOemN(void);
 extern void func_RtlUpcaseUnicodeStringToCountedOemString(void);
 extern void func_RtlValidateUnicodeString(void);
 extern void func_RtlxUnicodeStringToAnsiSize(void);
@@ -162,6 +163,7 @@ const struct test winetest_testlist[] =
     { "RtlUnicodeStringToAnsiString",   func_RtlUnicodeStringToAnsiString },
     { "RtlUnicodeStringToCountedOemString",
func_RtlUnicodeStringToCountedOemString },
     { "RtlUnicodeStringToOemSize",      func_RtlxUnicodeStringToOemSize },
+    { "RtlUnicodeToOemN",               func_RtlUnicodeToOemN },
     { "RtlUpcaseUnicodeStringToCountedOemString",
func_RtlUpcaseUnicodeStringToCountedOemString },
     { "RtlValidateUnicodeString",       func_RtlValidateUnicodeString },
     { "StackOverflow",                  func_StackOverflow },