https://git.reactos.org/?p=reactos.git;a=commitdiff;h=53a6c44f74efc7576e47e…
commit 53a6c44f74efc7576e47e7da11bbfc5483e9e788
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Wed May 12 23:31:20 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 RtlUnicodeStringToCountedOemString
CORE-17571
---
modules/rostests/apitests/ntdll/CMakeLists.txt | 1 +
.../ntdll/RtlUnicodeStringToCountedOemString.c | 136 +++++++++++++++++++++
modules/rostests/apitests/ntdll/testlist.c | 2 +
sdk/include/ndk/rtlfuncs.h | 8 ++
4 files changed, 147 insertions(+)
diff --git a/modules/rostests/apitests/ntdll/CMakeLists.txt
b/modules/rostests/apitests/ntdll/CMakeLists.txt
index d1e4499fb68..684990e2df5 100644
--- a/modules/rostests/apitests/ntdll/CMakeLists.txt
+++ b/modules/rostests/apitests/ntdll/CMakeLists.txt
@@ -80,6 +80,7 @@ list(APPEND SOURCE
RtlQueryTimeZoneInfo.c
RtlReAllocateHeap.c
RtlUnicodeStringToAnsiString.c
+ RtlUnicodeStringToCountedOemString.c
RtlUpcaseUnicodeStringToCountedOemString.c
RtlValidateUnicodeString.c
RtlxUnicodeStringToAnsiSize.c
diff --git a/modules/rostests/apitests/ntdll/RtlUnicodeStringToCountedOemString.c
b/modules/rostests/apitests/ntdll/RtlUnicodeStringToCountedOemString.c
new file mode 100644
index 00000000000..30393fc0ea6
--- /dev/null
+++ b/modules/rostests/apitests/ntdll/RtlUnicodeStringToCountedOemString.c
@@ -0,0 +1,136 @@
+/*
+ * PROJECT: ReactOS API tests
+ * LICENSE: LGPL-2.1-or-later (
https://spdx.org/licenses/LGPL-2.1-or-later.html)
+ * PURPOSE: Test for RtlUnicodeStringToCountedOemString
+ * COPYRIGHT: Copyright 2021 Jérôme Gardou <jerome.gardou(a)reactos.org>
+ */
+
+#include "precomp.h"
+
+static const struct
+{
+ ULONG AnsiCp;
+ ULONG OemCp;
+ const UNICODE_STRING StrU;
+ NTSTATUS Status;
+ const OEM_STRING StrOem;
+} TestData[] =
+{
+ {
+ 1252, 932, /* Western SBCS - Modified SJIS */
+ RTL_CONSTANT_STRING(L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7"),
+ STATUS_BUFFER_OVERFLOW,
+ RTL_CONSTANT_STRING("\x83\x66\x83\x58\x83\x4e")
+ },
+ {
+ 932, 1252, /* Modified SJIS - Western SBCS */
+ RTL_CONSTANT_STRING(L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7"),
+ STATUS_UNMAPPABLE_CHARACTER,
+ RTL_CONSTANT_STRING("??????")
+ },
+ {
+ 932, 932, /* Modified SJIS - Modified SJIS */
+ RTL_CONSTANT_STRING(L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7"),
+ STATUS_SUCCESS,
+
RTL_CONSTANT_STRING("\x83\x66\x83\x58\x83\x4e\x83\x67\x83\x62\x83\x76")
+ },
+ {
+ 1252, 1252, /* Western SBCS */
+ RTL_CONSTANT_STRING(L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7"), /* Some
japanese characters */
+ STATUS_UNMAPPABLE_CHARACTER,
+ RTL_CONSTANT_STRING("??????")
+ },
+};
+
+START_TEST(RtlUnicodeStringToCountedOemString)
+{
+ WCHAR BufferU[10];
+ CHAR BufferOem[10];
+ UNICODE_STRING StringU;
+ OEM_STRING StringOem;
+ NTSTATUS Status;
+ int i;
+
+ memset(BufferU, 0xAA, sizeof(BufferU));
+ memset(BufferOem, 0xAA, sizeof(BufferOem));
+
+ BufferU[0] = L'A';
+ BufferU[1] = UNICODE_NULL;
+
+ StringU.Buffer = BufferU;
+ StringU.MaximumLength = 10 * sizeof(WCHAR);
+
+ RtlInitUnicodeString(&StringU, BufferU);
+ ok(StringU.Length == 1 * sizeof(WCHAR), "Invalid size: %d\n",
StringU.Length);
+ ok(StringU.MaximumLength == 2 * sizeof(WCHAR), "Invalid size: %d\n",
StringU.MaximumLength);
+ ok(StringU.Buffer == BufferU, "Invalid buffer: %p\n", StringU.Buffer);
+
+ StringOem.Buffer = BufferOem;
+ StringOem.Length = 0;
+ StringOem.MaximumLength = 10 * sizeof(CHAR);
+
+ Status = RtlUnicodeStringToCountedOemString(&StringOem, &StringU, FALSE);
+ ok(NT_SUCCESS(Status), "RtlUnicodeStringToCountedOemString failed: %lx\n",
Status);
+ ok(StringOem.Length == 1 * sizeof(CHAR), "Invalid size: %d\n",
StringOem.Length);
+ ok(StringOem.MaximumLength == 10 * sizeof(CHAR), "Invalid size: %d\n",
StringOem.MaximumLength);
+ ok(StringOem.Buffer == BufferOem, "Invalid buffer: %p\n",
StringOem.Buffer);
+
+ ok(BufferOem[0] == 'A', "Unexpected first char 0x%02x for OEM
string.\n", BufferOem[0]);
+ for (i = 1; i < 10; ++i)
+ {
+ ok(BufferOem[i] == (CHAR)0xAA, "Unexpected char 0x%02x at position
%d.\n", BufferOem[i], i);
+ }
+
+ ok(i == 10, "String was not null terminated!\n");
+
+ /* Test buffer overflow */
+ wcsncpy(BufferU, L"Test", _countof(BufferU));
+ RtlInitUnicodeString(&StringU, BufferU);
+ StringU.MaximumLength = sizeof(BufferU);
+ StringOem.Buffer = BufferOem;
+ StringOem.MaximumLength = 1 * sizeof(CHAR);
+ StringOem.Length = 0;
+ memset(BufferOem, 0xAA, sizeof(BufferOem));
+
+ Status = RtlUnicodeStringToCountedOemString(&StringOem, &StringU, FALSE);
+ ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW);
+ ok(StringOem.Length == 4 * sizeof(CHAR), "Invalid size: %d\n",
StringOem.Length);
+ ok(StringOem.MaximumLength == 1 * sizeof(CHAR), "Invalid size: %d\n",
StringOem.MaximumLength);
+ ok(StringOem.Buffer == BufferOem, "Invalid buffer: %p\n",
StringOem.Buffer);
+
+ for (i = 0; i < 10; ++i)
+ {
+ ok(BufferOem[i] == (CHAR)0xAA, "Unexpected char 0x%02x at position
%d.\n", BufferOem[i], i);
+ }
+
+ for (i = 0; i < _countof(TestData); i++)
+ {
+ SetupLocale(TestData[i].AnsiCp, TestData[i].OemCp, -1);
+
+ trace("Testing locale %u. ANSI: %u, OEM %u\n", i,
(UINT)TestData[i].AnsiCp, (UINT)TestData[i].OemCp);
+
+ /* Get the right length */
+ StringOem.Buffer = NULL;
+ StringOem.Length = 0;
+ StringOem.MaximumLength = 0;
+
+ Status = RtlUnicodeStringToCountedOemString(&StringOem,
&TestData[i].StrU, FALSE);
+ ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW);
+ ok_long(StringOem.Length, TestData[i].StrOem.Length);
+ ok_long(StringOem.MaximumLength, 0);
+
+ StringOem.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
StringOem.Length);
+ StringOem.MaximumLength = StringOem.Length;
+ StringOem.Length = 0;
+
+ Status = RtlUnicodeStringToCountedOemString(&StringOem,
&TestData[i].StrU, FALSE);
+ ok_ntstatus(Status, TestData[i].Status);
+
+ ok_long(StringOem.Length, TestData[i].StrOem.Length);
+ ok_long(StringOem.MaximumLength, TestData[i].StrOem.Length); /* Untouched */
+ ok_long(memcmp(StringOem.Buffer, TestData[i].StrOem.Buffer, min(StringOem.Length,
TestData[i].StrOem.Length)), 0);
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, StringOem.Buffer);
+ }
+}
+
diff --git a/modules/rostests/apitests/ntdll/testlist.c
b/modules/rostests/apitests/ntdll/testlist.c
index 78a8af20a05..5d4b00b0cce 100644
--- a/modules/rostests/apitests/ntdll/testlist.c
+++ b/modules/rostests/apitests/ntdll/testlist.c
@@ -76,6 +76,7 @@ extern void func_RtlpEnsureBufferSize(void);
extern void func_RtlQueryTimeZoneInformation(void);
extern void func_RtlReAllocateHeap(void);
extern void func_RtlUnicodeStringToAnsiString(void);
+extern void func_RtlUnicodeStringToCountedOemString(void);
extern void func_RtlUpcaseUnicodeStringToCountedOemString(void);
extern void func_RtlValidateUnicodeString(void);
extern void func_RtlxUnicodeStringToAnsiSize(void);
@@ -159,6 +160,7 @@ const struct test winetest_testlist[] =
{ "RtlReAllocateHeap", func_RtlReAllocateHeap },
{ "RtlUnicodeStringToAnsiSize", func_RtlxUnicodeStringToAnsiSize }, /*
For some reason, starting test name with Rtlx hides it */
{ "RtlUnicodeStringToAnsiString", func_RtlUnicodeStringToAnsiString },
+ { "RtlUnicodeStringToCountedOemString",
func_RtlUnicodeStringToCountedOemString },
{ "RtlUnicodeStringToOemSize", func_RtlxUnicodeStringToOemSize },
{ "RtlUpcaseUnicodeStringToCountedOemString",
func_RtlUpcaseUnicodeStringToCountedOemString },
{ "RtlValidateUnicodeString", func_RtlValidateUnicodeString },
diff --git a/sdk/include/ndk/rtlfuncs.h b/sdk/include/ndk/rtlfuncs.h
index 513fc195b5f..60e1308b964 100644
--- a/sdk/include/ndk/rtlfuncs.h
+++ b/sdk/include/ndk/rtlfuncs.h
@@ -1879,6 +1879,14 @@ RtlUnicodeStringToOemString(
BOOLEAN AllocateDestinationString
);
+NTSYSAPI
+NTSTATUS
+NTAPI
+RtlUnicodeStringToCountedOemString(
+ _Inout_ POEM_STRING OemDest,
+ _In_ PCUNICODE_STRING UniSource,
+ _In_ BOOLEAN AllocateDestinationString);
+
NTSYSAPI
NTSTATUS
NTAPI