1 /* 2 * PROJECT: ReactOS API tests 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: Test for RtlUnicodeStringToCountedOemString 5 * COPYRIGHT: Copyright 2021 Jérôme Gardou <jerome.gardou@reactos.org> 6 */ 7 8 #include "precomp.h" 9 10 static const struct 11 { 12 ULONG AnsiCp; 13 ULONG OemCp; 14 const UNICODE_STRING StrU; 15 NTSTATUS Status; 16 const OEM_STRING StrOem; 17 } TestData[] = 18 { 19 { 20 1252, 932, /* Western SBCS - Modified SJIS */ 21 RTL_CONSTANT_STRING(L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7"), 22 STATUS_BUFFER_OVERFLOW, 23 RTL_CONSTANT_STRING("\x83\x66\x83\x58\x83\x4e") 24 }, 25 { 26 932, 1252, /* Modified SJIS - Western SBCS */ 27 RTL_CONSTANT_STRING(L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7"), 28 STATUS_UNMAPPABLE_CHARACTER, 29 RTL_CONSTANT_STRING("??????") 30 }, 31 { 32 932, 932, /* Modified SJIS - Modified SJIS */ 33 RTL_CONSTANT_STRING(L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7"), 34 STATUS_SUCCESS, 35 RTL_CONSTANT_STRING("\x83\x66\x83\x58\x83\x4e\x83\x67\x83\x62\x83\x76") 36 }, 37 { 38 1252, 1252, /* Western SBCS */ 39 RTL_CONSTANT_STRING(L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7"), /* Some japanese characters */ 40 STATUS_UNMAPPABLE_CHARACTER, 41 RTL_CONSTANT_STRING("??????") 42 }, 43 }; 44 45 START_TEST(RtlUnicodeStringToCountedOemString) 46 { 47 WCHAR BufferU[10]; 48 CHAR BufferOem[10]; 49 UNICODE_STRING StringU; 50 OEM_STRING StringOem; 51 NTSTATUS Status; 52 int i; 53 54 memset(BufferU, 0xAA, sizeof(BufferU)); 55 memset(BufferOem, 0xAA, sizeof(BufferOem)); 56 57 BufferU[0] = L'A'; 58 BufferU[1] = UNICODE_NULL; 59 60 StringU.Buffer = BufferU; 61 StringU.MaximumLength = 10 * sizeof(WCHAR); 62 63 RtlInitUnicodeString(&StringU, BufferU); 64 ok(StringU.Length == 1 * sizeof(WCHAR), "Invalid size: %d\n", StringU.Length); 65 ok(StringU.MaximumLength == 2 * sizeof(WCHAR), "Invalid size: %d\n", StringU.MaximumLength); 66 ok(StringU.Buffer == BufferU, "Invalid buffer: %p\n", StringU.Buffer); 67 68 StringOem.Buffer = BufferOem; 69 StringOem.Length = 0; 70 StringOem.MaximumLength = 10 * sizeof(CHAR); 71 72 Status = RtlUnicodeStringToCountedOemString(&StringOem, &StringU, FALSE); 73 ok(NT_SUCCESS(Status), "RtlUnicodeStringToCountedOemString failed: %lx\n", Status); 74 ok(StringOem.Length == 1 * sizeof(CHAR), "Invalid size: %d\n", StringOem.Length); 75 ok(StringOem.MaximumLength == 10 * sizeof(CHAR), "Invalid size: %d\n", StringOem.MaximumLength); 76 ok(StringOem.Buffer == BufferOem, "Invalid buffer: %p\n", StringOem.Buffer); 77 78 ok(BufferOem[0] == 'A', "Unexpected first char 0x%02x for OEM string.\n", BufferOem[0]); 79 for (i = 1; i < 10; ++i) 80 { 81 ok(BufferOem[i] == (CHAR)0xAA, "Unexpected char 0x%02x at position %d.\n", BufferOem[i], i); 82 } 83 84 ok(i == 10, "String was not null terminated!\n"); 85 86 /* Test buffer overflow */ 87 wcsncpy(BufferU, L"Test", _countof(BufferU)); 88 RtlInitUnicodeString(&StringU, BufferU); 89 StringU.MaximumLength = sizeof(BufferU); 90 StringOem.Buffer = BufferOem; 91 StringOem.MaximumLength = 1 * sizeof(CHAR); 92 StringOem.Length = 0; 93 memset(BufferOem, 0xAA, sizeof(BufferOem)); 94 95 Status = RtlUnicodeStringToCountedOemString(&StringOem, &StringU, FALSE); 96 ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); 97 ok(StringOem.Length == 4 * sizeof(CHAR), "Invalid size: %d\n", StringOem.Length); 98 ok(StringOem.MaximumLength == 1 * sizeof(CHAR), "Invalid size: %d\n", StringOem.MaximumLength); 99 ok(StringOem.Buffer == BufferOem, "Invalid buffer: %p\n", StringOem.Buffer); 100 101 for (i = 0; i < 10; ++i) 102 { 103 ok(BufferOem[i] == (CHAR)0xAA, "Unexpected char 0x%02x at position %d.\n", BufferOem[i], i); 104 } 105 106 for (i = 0; i < _countof(TestData); i++) 107 { 108 SetupLocale(TestData[i].AnsiCp, TestData[i].OemCp, -1); 109 110 trace("Testing locale %u. ANSI: %u, OEM %u\n", i, (UINT)TestData[i].AnsiCp, (UINT)TestData[i].OemCp); 111 112 /* Get the right length */ 113 StringOem.Buffer = NULL; 114 StringOem.Length = 0; 115 StringOem.MaximumLength = 0; 116 117 Status = RtlUnicodeStringToCountedOemString(&StringOem, &TestData[i].StrU, FALSE); 118 ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); 119 ok_long(StringOem.Length, TestData[i].StrOem.Length); 120 ok_long(StringOem.MaximumLength, 0); 121 122 StringOem.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, StringOem.Length); 123 StringOem.MaximumLength = StringOem.Length; 124 StringOem.Length = 0; 125 126 Status = RtlUnicodeStringToCountedOemString(&StringOem, &TestData[i].StrU, FALSE); 127 ok_ntstatus(Status, TestData[i].Status); 128 129 ok_long(StringOem.Length, TestData[i].StrOem.Length); 130 ok_long(StringOem.MaximumLength, TestData[i].StrOem.Length); /* Untouched */ 131 ok_long(memcmp(StringOem.Buffer, TestData[i].StrOem.Buffer, min(StringOem.Length, TestData[i].StrOem.Length)), 0); 132 133 RtlFreeHeap(RtlGetProcessHeap(), 0, StringOem.Buffer); 134 } 135 } 136 137