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
START_TEST(RtlUnicodeToOemN)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