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 } 260