1 /* 2 * PROJECT: ReactOS API tests 3 * LICENSE: 0BSD (https://spdx.org/licenses/0BSD) 4 * PURPOSE: Test for RtlUnicodeToOemN 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 struct 15 { 16 LPCWSTR StrW; 17 NTSTATUS Status; 18 ULONG ReturnedSize; 19 LPCSTR StrOem; 20 } Test[10]; 21 } TestData[] = 22 { 23 { 24 1252, 1252, /* Western SBCS */ 25 { 26 { 27 L"ABCDEF", 28 STATUS_SUCCESS, 29 6, 30 "ABCDEF" 31 }, 32 { 33 L"ABCDEF", 34 STATUS_SUCCESS, 35 6, 36 "ABCDEF\xAA\xAA\xAA" 37 }, 38 { 39 L"ABCDEF", 40 STATUS_BUFFER_OVERFLOW, 41 3, 42 "ABC" 43 }, 44 { 45 L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7", 46 STATUS_SUCCESS, 47 6, 48 "??????" 49 }, 50 { 51 L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7", 52 STATUS_BUFFER_OVERFLOW, 53 3, 54 "???" 55 }, 56 } 57 }, 58 { 59 1252, 932, /* Western SBCS - Modified SJIS */ 60 { 61 { 62 L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7", 63 STATUS_SUCCESS, 64 12, 65 "\x83\x66\x83\x58\x83\x4e\x83\x67\x83\x62\x83\x76" 66 }, 67 { 68 L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7", 69 STATUS_SUCCESS, 70 12, 71 "\x83\x66\x83\x58\x83\x4e\x83\x67\x83\x62\x83\x76\xAA\xAA\xAA" 72 }, 73 } 74 }, 75 { 76 932, 1252, /* Modified SJIS - Western SBCS */ 77 { 78 { 79 L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7", 80 STATUS_SUCCESS, 81 6, 82 "??????" 83 }, 84 { 85 L"\u30c7\u30b9\u30afABC", 86 STATUS_SUCCESS, 87 6, 88 "???ABC" 89 }, 90 { 91 L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7", 92 STATUS_BUFFER_OVERFLOW, 93 3, 94 "???" 95 }, 96 } 97 }, 98 { 99 932, 932, /* Modified SJIS - Modified SJIS */ 100 { 101 { 102 L"\u30c7\u30b9\u30af\u30c8\u30c3\u30d7", 103 STATUS_SUCCESS, 104 12, 105 "\x83\x66\x83\x58\x83\x4e\x83\x67\x83\x62\x83\x76" 106 } 107 } 108 }, 109 }; 110 111 START_TEST(RtlUnicodeToOemN) 112 { 113 ULONG Length; 114 LPSTR StrOem; 115 ULONG ResultSize; 116 NTSTATUS Status; 117 CHAR OemBuffer[4]; 118 119 /* Basic things */ 120 Status = RtlUnicodeToOemN(NULL, 0, NULL, NULL, 0); 121 ok_ntstatus(Status, STATUS_SUCCESS); 122 123 Status = RtlUnicodeToOemN(NULL, 0, NULL, L"ABCDEF", 0); 124 ok_ntstatus(Status, STATUS_SUCCESS); 125 126 Status = RtlUnicodeToOemN(NULL, 0, NULL, NULL, 2); 127 ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); 128 129 Status = RtlUnicodeToOemN(NULL, 0, NULL, L"A", 2); 130 ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); 131 132 Status = RtlUnicodeToOemN(NULL, 0, NULL, L"A", 2); 133 ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); 134 135 StartSeh() 136 Status = RtlUnicodeToOemN(NULL, 1, NULL, L"A", 2); 137 EndSeh(STATUS_ACCESS_VIOLATION) 138 139 OemBuffer[0] = 0xAA; 140 OemBuffer[1] = 0xAA; 141 Status = RtlUnicodeToOemN(OemBuffer, 1, NULL, L"A", 2); 142 ok_ntstatus(Status, STATUS_SUCCESS); 143 ok_char(OemBuffer[0], 'A'); 144 ok_char(OemBuffer[1], (CHAR)0xAA); 145 146 OemBuffer[0] = 0xAA; 147 OemBuffer[1] = 0xAA; 148 Status = RtlUnicodeToOemN(OemBuffer, 1, NULL, L"AB", 4); 149 ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); 150 ok_char(OemBuffer[0], 'A'); 151 ok_char(OemBuffer[1], (CHAR)0xAA); 152 153 OemBuffer[0] = 0xAA; 154 OemBuffer[1] = 0xAA; 155 Status = RtlUnicodeToOemN(OemBuffer, 2, NULL, L"A", 4); 156 ok_ntstatus(Status, STATUS_SUCCESS); 157 ok_char(OemBuffer[0], 'A'); 158 ok_char(OemBuffer[1], '\0'); 159 160 /* RtlUnicodeToOemN doesn't care about string termination */ 161 OemBuffer[0] = 0xAA; 162 OemBuffer[1] = 0xAA; 163 Status = RtlUnicodeToOemN(OemBuffer, 1, NULL, L"A", 4); 164 ok_ntstatus(Status, STATUS_BUFFER_OVERFLOW); 165 ok_char(OemBuffer[0], 'A'); 166 ok_char(OemBuffer[1], (CHAR)0xAA); 167 168 OemBuffer[0] = 0xAA; 169 OemBuffer[1] = 0xAA; 170 OemBuffer[2] = 0xAA; 171 OemBuffer[3] = 0xAA; 172 Status = RtlUnicodeToOemN(OemBuffer, 4, NULL, L"A\0B", 8); 173 ok_ntstatus(Status, STATUS_SUCCESS); 174 ok_char(OemBuffer[0], 'A'); 175 ok_char(OemBuffer[1], '\0'); 176 ok_char(OemBuffer[2], 'B'); 177 ok_char(OemBuffer[3], '\0'); 178 179 /* Odd Unicode buffer size */ 180 OemBuffer[0] = 0xAA; 181 OemBuffer[1] = 0xAA; 182 OemBuffer[2] = 0xAA; 183 OemBuffer[3] = 0xAA; 184 Status = RtlUnicodeToOemN(OemBuffer, 2, NULL, L"AB", 5); 185 ok_ntstatus(Status, STATUS_SUCCESS); 186 ok_char(OemBuffer[0], 'A'); 187 ok_char(OemBuffer[1], 'B'); 188 ok_char(OemBuffer[2], (CHAR)0xAA); 189 ok_char(OemBuffer[3], (CHAR)0xAA); 190 191 /* Odd Unicode buffer size */ 192 OemBuffer[0] = 0xAA; 193 OemBuffer[1] = 0xAA; 194 OemBuffer[2] = 0xAA; 195 OemBuffer[3] = 0xAA; 196 Status = RtlUnicodeToOemN(OemBuffer, 3, NULL, L"AB", 5); 197 ok_ntstatus(Status, STATUS_SUCCESS); 198 ok_char(OemBuffer[0], 'A'); 199 ok_char(OemBuffer[1], 'B'); 200 ok_char(OemBuffer[2], (CHAR)0xAA); 201 ok_char(OemBuffer[3], (CHAR)0xAA); 202 203 for (int i = 0; i < _countof(TestData); i++) 204 { 205 SetupLocale(TestData[i].AnsiCp, TestData[i].OemCp, -1); 206 207 for (int j = 0; TestData[i].Test[j].StrW != NULL; j++) 208 { 209 Length = strlen(TestData[i].Test[j].StrOem); 210 StrOem = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length + 1); 211 212 memset(StrOem, 0xAA, Length + 1); 213 ResultSize = 0x0BADF00D; 214 215 Status = RtlUnicodeToOemN(StrOem, 216 Length, 217 &ResultSize, 218 TestData[i].Test[j].StrW, 219 wcslen(TestData[i].Test[j].StrW) * sizeof(WCHAR)); 220 221 ok_ntstatus(Status, TestData[i].Test[j].Status); 222 ok_long(ResultSize, TestData[i].Test[j].ReturnedSize); 223 for (int k = 0; k < ResultSize; k++) 224 { 225 ok(StrOem[k] == TestData[i].Test[j].StrOem[k], 226 "Wrong char \\x%02x, expected TestData[%u].Test[%u].StrOem[%u] (\\x%02x)\n", 227 StrOem[k], i, j, k, TestData[i].Test[j].StrOem[k]); 228 } 229 for (int k = ResultSize; k < (Length + 1); k++) 230 { 231 ok_char(StrOem[k], (CHAR)0xAA); 232 } 233 234 RtlFreeHeap(RtlGetProcessHeap(), 0, StrOem); 235 } 236 } 237 } 238