[SHELL32_APITEST] -Add tests for Control_RunDLLW.
[reactos.git] / rostests / kmtests / rtl / RtlUnicodeString.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Runtime library unicode string functions test
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #define KMT_EMULATE_KERNEL
9 #include <kmt_test.h>
10
11 static
12 VOID
13 TestFindCharInUnicodeString(VOID)
14 {
15 #ifdef KMT_USER_MODE
16 NTSTATUS Status;
17 UNICODE_STRING String = RTL_CONSTANT_STRING(L"I am a string");
18 UNICODE_STRING Chars = RTL_CONSTANT_STRING(L"a");
19 UNICODE_STRING Chars2 = RTL_CONSTANT_STRING(L"A");
20 UNICODE_STRING Chars3 = RTL_CONSTANT_STRING(L"i");
21 UNICODE_STRING Chars4 = RTL_CONSTANT_STRING(L"G");
22 UNICODE_STRING ZeroLengthString;
23 USHORT Position;
24 ULONG LongPosition;
25
26 RtlInitUnicodeString(&ZeroLengthString, NULL);
27
28 /* Basic checks. Covered by Winetests */
29 Position = 123;
30 Status = RtlFindCharInUnicodeString(0, &String, &Chars, &Position);
31 ok_eq_hex(Status, STATUS_SUCCESS);
32 ok_eq_uint(Position, 6);
33
34 Position = 123;
35 Status = RtlFindCharInUnicodeString(1, &String, &Chars, &Position);
36 ok_eq_hex(Status, STATUS_SUCCESS);
37 ok_eq_uint(Position, 10);
38
39 Position = 123;
40 Status = RtlFindCharInUnicodeString(2, &String, &Chars, &Position);
41 ok_eq_hex(Status, STATUS_SUCCESS);
42 ok_eq_uint(Position, 2);
43
44 Position = 123;
45 Status = RtlFindCharInUnicodeString(3, &String, &Chars, &Position);
46 ok_eq_hex(Status, STATUS_SUCCESS);
47 ok_eq_uint(Position, 24);
48
49 /* Show that checks are case sensitive by default */
50 Position = 123;
51 Status = RtlFindCharInUnicodeString(0, &String, &Chars2, &Position);
52 ok_eq_hex(Status, STATUS_NOT_FOUND);
53 ok_eq_uint(Position, 0);
54
55 Position = 123;
56 Status = RtlFindCharInUnicodeString(1, &String, &Chars2, &Position);
57 ok_eq_hex(Status, STATUS_NOT_FOUND);
58 ok_eq_uint(Position, 0);
59
60 Position = 123;
61 Status = RtlFindCharInUnicodeString(2, &String, &Chars3, &Position);
62 ok_eq_hex(Status, STATUS_SUCCESS);
63 ok_eq_uint(Position, 2);
64
65 Position = 123;
66 Status = RtlFindCharInUnicodeString(3, &String, &Chars4, &Position);
67 ok_eq_hex(Status, STATUS_SUCCESS);
68 ok_eq_uint(Position, 24);
69
70 /* Show that 4 means case insensitive */
71 Position = 123;
72 Status = RtlFindCharInUnicodeString(4, &String, &Chars2, &Position);
73 ok_eq_hex(Status, STATUS_SUCCESS);
74 ok_eq_uint(Position, 6);
75
76 Position = 123;
77 Status = RtlFindCharInUnicodeString(5, &String, &Chars2, &Position);
78 ok_eq_hex(Status, STATUS_SUCCESS);
79 ok_eq_uint(Position, 10);
80
81 Position = 123;
82 Status = RtlFindCharInUnicodeString(6, &String, &Chars3, &Position);
83 ok_eq_hex(Status, STATUS_SUCCESS);
84 ok_eq_uint(Position, 4);
85
86 Position = 123;
87 Status = RtlFindCharInUnicodeString(7, &String, &Chars4, &Position);
88 ok_eq_hex(Status, STATUS_SUCCESS);
89 ok_eq_uint(Position, 22);
90
91 /* Show that Position is USHORT */
92 LongPosition = 0x55555555;
93 Status = RtlFindCharInUnicodeString(8, &String, &String, (PUSHORT)&LongPosition);
94 ok_eq_hex(Status, STATUS_INVALID_PARAMETER);
95 ok_eq_ulong(LongPosition, 0x55550000UL);
96
97 /* Invalid flags */
98 Position = 123;
99 Status = RtlFindCharInUnicodeString(8, &String, &String, &Position);
100 ok_eq_hex(Status, STATUS_INVALID_PARAMETER);
101 ok_eq_uint(Position, 0);
102
103 Position = 123;
104 Status = RtlFindCharInUnicodeString(0xFFFFFFF8, &String, &String, &Position);
105 ok_eq_hex(Status, STATUS_INVALID_PARAMETER);
106 ok_eq_uint(Position, 0);
107
108 Position = 123;
109 Status = RtlFindCharInUnicodeString(0xFFFFFFFF, &String, &String, &Position);
110 ok_eq_hex(Status, STATUS_INVALID_PARAMETER);
111 ok_eq_uint(Position, 0);
112
113 /* NULL for SearchString */
114 Position = 123;
115 KmtStartSeh()
116 Status = RtlFindCharInUnicodeString(0, NULL, &String, &Position);
117 KmtEndSeh(STATUS_ACCESS_VIOLATION);
118 ok_eq_uint(Position, 0);
119
120 /* NULL for SearchString and invalid flags */
121 Position = 123;
122 KmtStartSeh()
123 Status = RtlFindCharInUnicodeString(8, NULL, &String, &Position);
124 KmtEndSeh(STATUS_SUCCESS);
125 ok_eq_hex(Status, STATUS_INVALID_PARAMETER);
126 ok_eq_uint(Position, 0);
127 ok_eq_uint(Position, 0);
128
129 /* NULL for SearchString with zero-length MatchString */
130 Position = 123;
131 KmtStartSeh()
132 Status = RtlFindCharInUnicodeString(0, NULL, &ZeroLengthString, &Position);
133 KmtEndSeh(STATUS_ACCESS_VIOLATION);
134 ok_eq_uint(Position, 0);
135
136 /* NULL for MatchString */
137 Position = 123;
138 KmtStartSeh()
139 Status = RtlFindCharInUnicodeString(0, &String, NULL, &Position);
140 KmtEndSeh(STATUS_ACCESS_VIOLATION);
141 ok_eq_uint(Position, 0);
142
143 /* This crashes in Windows, but not in ROS. I see no reason to add
144 * additional code or redesign the function to replicate that */
145 #if 0
146 /* NULL for MatchString with zero-length SearchString */
147 Position = 123;
148 KmtStartSeh()
149 Status = RtlFindCharInUnicodeString(0, &ZeroLengthString, NULL, &Position);
150 KmtEndSeh(STATUS_ACCESS_VIOLATION);
151 ok_eq_uint(Position, 0);
152 #endif
153
154 /* NULL for MatchString and invalid flags */
155 Position = 123;
156 KmtStartSeh()
157 Status = RtlFindCharInUnicodeString(8, &String, NULL, &Position);
158 KmtEndSeh(STATUS_SUCCESS);
159 ok_eq_hex(Status, STATUS_INVALID_PARAMETER);
160 ok_eq_uint(Position, 0);
161
162 /* NULL for Position */
163 KmtStartSeh()
164 Status = RtlFindCharInUnicodeString(0, &String, &String, NULL);
165 KmtEndSeh(STATUS_SUCCESS);
166 ok_eq_hex(Status, STATUS_INVALID_PARAMETER);
167
168 /* NULL for all three */
169 KmtStartSeh()
170 Status = RtlFindCharInUnicodeString(0, NULL, NULL, NULL);
171 KmtEndSeh(STATUS_SUCCESS);
172 ok_eq_hex(Status, STATUS_INVALID_PARAMETER);
173 #endif
174 }
175
176 static
177 VOID
178 TestUpcaseUnicodeString(VOID)
179 {
180 NTSTATUS Status;
181 UNICODE_STRING Lower;
182 UNICODE_STRING Upper;
183 PWCHAR Buffer;
184
185 Buffer = KmtAllocateGuarded(sizeof(WCHAR));
186
187 if (!KmtIsCheckedBuild)
188 {
189 RtlInitEmptyUnicodeString(&Lower, NULL, 0);
190 RtlFillMemory(&Upper, sizeof(Upper), 0x55);
191 Status = RtlUpcaseUnicodeString(&Upper, &Lower, TRUE);
192 ok_eq_hex(Status, STATUS_SUCCESS);
193 ok_eq_uint(Upper.Length, 0);
194 ok_eq_uint(Upper.MaximumLength, 0);
195 ok(Upper.Buffer != NULL, "Buffer = %p\n", Upper.Buffer);
196 RtlFreeUnicodeString(&Upper);
197
198 RtlInitEmptyUnicodeString(&Lower, Buffer, 0);
199 RtlFillMemory(&Upper, sizeof(Upper), 0x55);
200 Status = RtlUpcaseUnicodeString(&Upper, &Lower, TRUE);
201 ok_eq_hex(Status, STATUS_SUCCESS);
202 ok_eq_uint(Upper.Length, 0);
203 ok_eq_uint(Upper.MaximumLength, 0);
204 ok(Upper.Buffer != NULL, "Buffer = %p\n", Upper.Buffer);
205 RtlFreeUnicodeString(&Upper);
206
207 RtlInitEmptyUnicodeString(&Lower, Buffer, sizeof(WCHAR));
208 Buffer[0] = UNICODE_NULL;
209 RtlFillMemory(&Upper, sizeof(Upper), 0x55);
210 Status = RtlUpcaseUnicodeString(&Upper, &Lower, TRUE);
211 ok_eq_hex(Status, STATUS_SUCCESS);
212 ok_eq_uint(Upper.Length, 0);
213 ok_eq_uint(Upper.MaximumLength, 0);
214 ok(Upper.Buffer != NULL, "Buffer = %p\n", Upper.Buffer);
215 RtlFreeUnicodeString(&Upper);
216 }
217
218 RtlInitEmptyUnicodeString(&Lower, Buffer, sizeof(WCHAR));
219 Lower.Length = sizeof(WCHAR);
220 Buffer[0] = UNICODE_NULL;
221 RtlFillMemory(&Upper, sizeof(Upper), 0x55);
222 Status = RtlUpcaseUnicodeString(&Upper, &Lower, TRUE);
223 ok_eq_hex(Status, STATUS_SUCCESS);
224 ok_eq_uint(Upper.Length, sizeof(WCHAR));
225 ok_eq_uint(Upper.MaximumLength, sizeof(WCHAR));
226 ok(Upper.Buffer != NULL, "Buffer = %p\n", Upper.Buffer);
227 ok_eq_hex(Upper.Buffer[0], UNICODE_NULL);
228 RtlFreeUnicodeString(&Upper);
229
230 RtlInitEmptyUnicodeString(&Lower, Buffer, sizeof(WCHAR));
231 Lower.Length = sizeof(WCHAR);
232 Buffer[0] = 'a';
233 RtlFillMemory(&Upper, sizeof(Upper), 0x55);
234 Status = RtlUpcaseUnicodeString(&Upper, &Lower, TRUE);
235 ok_eq_hex(Status, STATUS_SUCCESS);
236 ok_eq_uint(Upper.Length, sizeof(WCHAR));
237 ok_eq_uint(Upper.MaximumLength, sizeof(WCHAR));
238 ok(Upper.Buffer != NULL, "Buffer = %p\n", Upper.Buffer);
239 ok_eq_hex(Upper.Buffer[0], 'A');
240 RtlFreeUnicodeString(&Upper);
241
242 RtlInitUnicodeString(&Lower, L"a");
243 RtlFillMemory(&Upper, sizeof(Upper), 0x55);
244 Status = RtlUpcaseUnicodeString(&Upper, &Lower, TRUE);
245 ok_eq_hex(Status, STATUS_SUCCESS);
246 ok_eq_uint(Upper.Length, sizeof(WCHAR));
247 ok_eq_uint(Upper.MaximumLength, sizeof(WCHAR));
248 ok(Upper.Buffer != NULL, "Buffer = %p\n", Upper.Buffer);
249 ok_eq_hex(Upper.Buffer[0], 'A');
250 RtlFreeUnicodeString(&Upper);
251
252 KmtFreeGuarded(Buffer);
253 }
254
255 START_TEST(RtlUnicodeString)
256 {
257 TestFindCharInUnicodeString();
258 TestUpcaseUnicodeString();
259 }