combase: Move length from hstring_private to hstring_header.
[wine.git] / dlls / combase / tests / string.c
blob9e4c628186675520b7fc1a5ed2342546582098bc
1 /*
2 * Unit tests for Windows String functions
4 * Copyright (c) 2014 Martin Storsjo
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winerror.h"
26 #include "winstring.h"
28 #include "wine/test.h"
30 #define check_string(str, content, length, has_null) _check_string(__LINE__, str, content, length, has_null)
31 static void _check_string(int line, HSTRING str, LPCWSTR content, UINT32 length, BOOL has_null)
33 BOOL out_null;
34 BOOL empty = length == 0;
35 UINT32 out_length;
36 LPCWSTR ptr;
38 ok_(__FILE__, line)(WindowsIsStringEmpty(str) == empty, "WindowsIsStringEmpty failed\n");
39 ok_(__FILE__, line)(WindowsStringHasEmbeddedNull(str, &out_null) == S_OK, "WindowsStringHasEmbeddedNull failed\n");
40 ok_(__FILE__, line)(out_null == has_null, "WindowsStringHasEmbeddedNull failed\n");
41 ok_(__FILE__, line)(WindowsGetStringLen(str) == length, "WindowsGetStringLen failed\n");
42 ptr = WindowsGetStringRawBuffer(str, &out_length);
43 /* WindowsGetStringRawBuffer should return a non-null, null terminated empty string
44 * even if str is NULL. */
45 ok_(__FILE__, line)(ptr != NULL, "WindowsGetStringRawBuffer returned null\n");
46 ok_(__FILE__, line)(out_length == length, "WindowsGetStringRawBuffer returned incorrect length\n");
47 ptr = WindowsGetStringRawBuffer(str, NULL);
48 ok_(__FILE__, line)(ptr != NULL, "WindowsGetStringRawBuffer returned null\n");
49 ok_(__FILE__, line)(ptr[length] == '\0', "WindowsGetStringRawBuffer doesn't return a null terminated buffer\n");
50 ok_(__FILE__, line)(memcmp(ptr, content, sizeof(*content) * length) == 0, "Incorrect string content\n");
53 static const WCHAR input_string[] = L"abcdef\0";
54 static const WCHAR input_string1[] = L"abc";
55 static const WCHAR input_string2[] = L"def";
56 static const WCHAR input_embed_null[] = L"a\0c\0ef";
57 static const WCHAR output_substring[] = L"cdef";
59 static void test_create_delete(void)
61 HSTRING str;
62 HSTRING_HEADER header;
64 /* Test normal creation of a string */
65 ok(WindowsCreateString(input_string, 6, &str) == S_OK, "Failed to create string\n");
66 check_string(str, input_string, 6, FALSE);
67 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
68 /* Test error handling in WindowsCreateString */
69 ok(WindowsCreateString(input_string, 6, NULL) == E_INVALIDARG, "Incorrect error handling\n");
70 ok(WindowsCreateString(NULL, 6, &str) == E_POINTER, "Incorrect error handling\n");
72 /* Test handling of a NULL string */
73 ok(WindowsDeleteString(NULL) == S_OK, "Failed to delete null string\n");
75 /* Test creation of a string reference */
76 ok(WindowsCreateStringReference(input_string, 6, &header, &str) == S_OK, "Failed to create string ref\n");
77 check_string(str, input_string, 6, FALSE);
78 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string ref\n");
80 /* Test error handling in WindowsCreateStringReference */
81 /* Strings to CreateStringReference must be null terminated with the correct
82 * length. According to MSDN this should be E_INVALIDARG, but it returns
83 * 0x80000017 in practice. */
84 ok(FAILED(WindowsCreateStringReference(input_string, 5, &header, &str)), "Incorrect error handling\n");
85 /* If the input string is non-null, it must be null-terminated even if the
86 * length is zero. */
87 ok(FAILED(WindowsCreateStringReference(input_string, 0, &header, &str)), "Incorrect error handling\n");
88 ok(WindowsCreateStringReference(input_string, 6, NULL, &str) == E_INVALIDARG, "Incorrect error handling\n");
89 ok(WindowsCreateStringReference(input_string, 6, &header, NULL) == E_INVALIDARG, "Incorrect error handling\n");
90 ok(WindowsCreateStringReference(NULL, 6, &header, &str) == E_POINTER, "Incorrect error handling\n");
92 /* Test creating a string without a null-termination at the specified length */
93 ok(WindowsCreateString(input_string, 3, &str) == S_OK, "Failed to create string\n");
94 check_string(str, input_string, 3, FALSE);
95 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
97 /* Test an empty string */
98 ok(WindowsCreateString(L"", 0, &str) == S_OK, "Failed to create string\n");
99 ok(str == NULL, "Empty string not a null string\n");
100 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
102 ok(WindowsCreateString(input_string, 0, &str) == S_OK, "Failed to create string\n");
103 ok(str == NULL, "Empty string not a null string\n");
104 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
106 ok(WindowsCreateStringReference(L"", 0, &header, &str) == S_OK, "Failed to create string\n");
107 ok(str == NULL, "Empty string not a null string\n");
108 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
110 ok(WindowsCreateString(NULL, 0, &str) == S_OK, "Failed to create string\n");
111 ok(str == NULL, "Empty string not a null string\n");
112 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
114 ok(WindowsCreateStringReference(NULL, 0, &header, &str) == S_OK, "Failed to create string\n");
115 ok(str == NULL, "Empty string not a null string\n");
116 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
119 static void test_duplicate(void)
121 HSTRING str, str2;
122 HSTRING_HEADER header;
123 ok(WindowsCreateString(input_string, 6, &str) == S_OK, "Failed to create string\n");
124 ok(WindowsDuplicateString(str, NULL) == E_INVALIDARG, "Incorrect error handling\n");
125 ok(WindowsDuplicateString(str, &str2) == S_OK, "Failed to duplicate string\n");
126 ok(str == str2, "Duplicated string created new string\n");
127 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
128 ok(WindowsDeleteString(str2) == S_OK, "Failed to delete string\n");
130 ok(WindowsCreateStringReference(input_string, 6, &header, &str) == S_OK, "Failed to create string ref\n");
131 ok(WindowsDuplicateString(str, &str2) == S_OK, "Failed to duplicate string\n");
132 ok(str != str2, "Duplicated string ref didn't create new string\n");
133 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
134 ok(WindowsDeleteString(str2) == S_OK, "Failed to delete string ref\n");
136 ok(WindowsDuplicateString(NULL, &str2) == S_OK, "Failed to duplicate NULL string\n");
137 ok(str2 == NULL, "Duplicated string created new string\n");
138 ok(WindowsDeleteString(str2) == S_OK, "Failed to delete string\n");
141 static void test_access(void)
143 HSTRING str;
144 HSTRING_HEADER header;
146 /* Test handling of a NULL string */
147 check_string(NULL, NULL, 0, FALSE);
149 /* Test strings with embedded null chars */
150 ok(WindowsCreateString(input_embed_null, 6, &str) == S_OK, "Failed to create string\n");
151 check_string(str, input_embed_null, 6, TRUE);
152 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
154 ok(WindowsCreateStringReference(input_embed_null, 6, &header, &str) == S_OK, "Failed to create string ref\n");
155 check_string(str, input_embed_null, 6, TRUE);
156 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string ref\n");
158 /* Test normal creation of a string with trailing null */
159 ok(WindowsCreateString(input_string, 7, &str) == S_OK, "Failed to create string\n");
160 check_string(str, input_string, 7, TRUE);
161 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
163 ok(WindowsCreateStringReference(input_string, 7, &header, &str) == S_OK, "Failed to create string ref\n");
164 check_string(str, input_string, 7, TRUE);
165 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string ref\n");
168 static void test_string_buffer(void)
170 /* Initialize ptr to NULL to make sure it actually is set in the first
171 * test below. */
172 HSTRING_BUFFER buf = NULL;
173 WCHAR *ptr = NULL;
174 HSTRING str;
176 /* Test creation of an empty buffer */
177 ok(WindowsPreallocateStringBuffer(0, &ptr, &buf) == S_OK, "Failed to preallocate string buffer\n");
178 ok(ptr != NULL, "Empty string didn't return a buffer pointer\n");
179 ok(WindowsPromoteStringBuffer(buf, &str) == S_OK, "Failed to promote string buffer\n");
180 ok(str == NULL, "Empty string isn't a null string\n");
181 check_string(str, L"", 0, FALSE);
182 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
184 ok(WindowsDeleteStringBuffer(NULL) == S_OK, "Failed to delete null string buffer\n");
186 /* Test creation and deletion of string buffers */
187 ok(WindowsPreallocateStringBuffer(6, &ptr, &buf) == S_OK, "Failed to preallocate string buffer\n");
188 ok(WindowsDeleteStringBuffer(buf) == S_OK, "Failed to delete string buffer\n");
190 /* Test creation and promotion of string buffers */
191 ok(WindowsPreallocateStringBuffer(6, &ptr, &buf) == S_OK, "Failed to preallocate string buffer\n");
192 ok(ptr[6] == '\0', "Preallocated string buffer didn't have null termination\n");
193 memcpy(ptr, input_string, 6 * sizeof(*input_string));
194 ok(WindowsPromoteStringBuffer(buf, NULL) == E_POINTER, "Incorrect error handling\n");
195 ok(WindowsPromoteStringBuffer(buf, &str) == S_OK, "Failed to promote string buffer\n");
196 check_string(str, input_string, 6, FALSE);
197 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
199 /* Test error handling in preallocation */
200 ok(WindowsPreallocateStringBuffer(6, NULL, &buf) == E_POINTER, "Incorrect error handling\n");
201 ok(WindowsPreallocateStringBuffer(6, &ptr, NULL) == E_POINTER, "Incorrect error handling\n");
203 ok(WindowsPreallocateStringBuffer(6, &ptr, &buf) == S_OK, "Failed to preallocate string buffer\n");
204 ptr[6] = 'a'; /* Overwrite the buffer's null termination, promotion should fail */
205 ok(WindowsPromoteStringBuffer(buf, &str) == E_INVALIDARG, "Incorrect error handling\n");
206 ok(WindowsDeleteStringBuffer(buf) == S_OK, "Failed to delete string buffer\n");
208 /* Test strings with trailing null chars */
209 ok(WindowsPreallocateStringBuffer(7, &ptr, &buf) == S_OK, "Failed to preallocate string buffer\n");
210 memcpy(ptr, input_string, 7 * sizeof(*input_string));
211 ok(WindowsPromoteStringBuffer(buf, &str) == S_OK, "Failed to promote string buffer\n");
212 check_string(str, input_string, 7, TRUE);
213 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
216 static void test_substring(void)
218 HSTRING str, substr;
219 HSTRING_HEADER header;
221 /* Test substring of string buffers */
222 ok(WindowsCreateString(input_string, 6, &str) == S_OK, "Failed to create string\n");
223 ok(WindowsSubstring(str, 2, &substr) == S_OK, "Failed to create substring\n");
224 check_string(substr, output_substring, 4, FALSE);
225 ok(WindowsDeleteString(substr) == S_OK, "Failed to delete string\n");
226 ok(WindowsSubstringWithSpecifiedLength(str, 2, 3, &substr) == S_OK, "Failed to create substring\n");
227 check_string(substr, output_substring, 3, FALSE);
228 ok(WindowsDeleteString(substr) == S_OK, "Failed to delete string\n");
229 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
231 /* Test duplication of string using substring */
232 ok(WindowsCreateString(input_string, 6, &str) == S_OK, "Failed to create string\n");
233 ok(WindowsSubstring(str, 0, &substr) == S_OK, "Failed to create substring\n");
234 ok(str != substr, "Duplicated string didn't create new string\n");
235 check_string(substr, input_string, 6, FALSE);
236 ok(WindowsDeleteString(substr) == S_OK, "Failed to delete string\n");
237 ok(WindowsSubstringWithSpecifiedLength(str, 0, 6, &substr) == S_OK, "Failed to create substring\n");
238 ok(str != substr, "Duplicated string didn't create new string\n");
239 check_string(substr, input_string, 6, FALSE);
240 ok(WindowsDeleteString(substr) == S_OK, "Failed to delete string\n");
241 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
243 /* Test substring of string reference */
244 ok(WindowsCreateStringReference(input_string, 6, &header, &str) == S_OK, "Failed to create string ref\n");
245 ok(WindowsSubstring(str, 2, &substr) == S_OK, "Failed to create substring of string ref\n");
246 check_string(substr, output_substring, 4, FALSE);
247 ok(WindowsDeleteString(substr) == S_OK, "Failed to delete string\n");
248 ok(WindowsSubstringWithSpecifiedLength(str, 2, 3, &substr) == S_OK, "Failed to create substring of string ref\n");
249 check_string(substr, output_substring, 3, FALSE);
250 ok(WindowsDeleteString(substr) == S_OK, "Failed to delete string\n");
251 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string ref\n");
253 /* Test duplication of string reference using substring */
254 ok(WindowsCreateStringReference(input_string, 6, &header, &str) == S_OK, "Failed to create string ref\n");
255 ok(WindowsSubstring(str, 0, &substr) == S_OK, "Failed to create substring of string ref\n");
256 ok(str != substr, "Duplicated string ref didn't create new string\n");
257 check_string(substr, input_string, 6, FALSE);
258 ok(WindowsDeleteString(substr) == S_OK, "Failed to delete string\n");
259 ok(WindowsSubstringWithSpecifiedLength(str, 0, 6, &substr) == S_OK, "Failed to create substring of string ref\n");
260 ok(str != substr, "Duplicated string ref didn't create new string\n");
261 check_string(substr, input_string, 6, FALSE);
262 ok(WindowsDeleteString(substr) == S_OK, "Failed to delete string\n");
263 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string ref\n");
265 /* Test get substring of empty string */
266 ok(WindowsSubstring(NULL, 0, &substr) == S_OK, "Failed to duplicate NULL string\n");
267 ok(substr == NULL, "Substring created new string\n");
268 ok(WindowsSubstringWithSpecifiedLength(NULL, 0, 0, &substr) == S_OK, "Failed to duplicate NULL string\n");
269 ok(substr == NULL, "Substring created new string\n");
271 /* Test get empty substring of string */
272 ok(WindowsCreateString(input_string, 6, &str) == S_OK, "Failed to create string\n");
273 ok(WindowsSubstring(str, 6, &substr) == S_OK, "Failed to create substring\n");
274 ok(substr == NULL, "Substring created new string\n");
275 ok(WindowsSubstringWithSpecifiedLength(str, 6, 0, &substr) == S_OK, "Failed to create substring\n");
276 ok(substr == NULL, "Substring created new string\n");
277 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
279 /* Test handling of using too high start index or length */
280 ok(WindowsCreateString(input_string, 6, &str) == S_OK, "Failed to create string\n");
281 ok(WindowsSubstring(str, 7, &substr) == E_BOUNDS, "Incorrect error handling\n");
282 ok(WindowsSubstringWithSpecifiedLength(str, 7, 0, &substr) == E_BOUNDS, "Incorrect error handling\n");
283 ok(WindowsSubstringWithSpecifiedLength(str, 6, 1, &substr) == E_BOUNDS, "Incorrect error handling\n");
284 ok(WindowsSubstringWithSpecifiedLength(str, 7, ~0U, &substr) == E_BOUNDS, "Incorrect error handling\n");
285 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
287 /* Test handling of a NULL string */
288 ok(WindowsCreateString(input_string, 6, &str) == S_OK, "Failed to create string\n");
289 ok(WindowsSubstring(str, 7, NULL) == E_INVALIDARG, "Incorrect error handling\n");
290 ok(WindowsSubstringWithSpecifiedLength(str, 7, 0, NULL) == E_INVALIDARG, "Incorrect error handling\n");
291 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string\n");
294 static void test_concat(void)
296 HSTRING str1, str2, concat;
297 HSTRING_HEADER header1, header2;
299 /* Test concatenation of string buffers */
300 ok(WindowsCreateString(input_string1, 3, &str1) == S_OK, "Failed to create string\n");
301 ok(WindowsCreateString(input_string2, 3, &str2) == S_OK, "Failed to create string\n");
303 ok(WindowsConcatString(str1, NULL, NULL) == E_INVALIDARG, "Incorrect error handling\n");
304 ok(WindowsConcatString(str1, NULL, &concat) == S_OK, "Failed to concatenate string\n");
305 ok(str1 == concat, "Concatenate created new string\n");
306 check_string(concat, input_string1, 3, FALSE);
307 ok(WindowsDeleteString(concat) == S_OK, "Failed to delete string\n");
309 ok(WindowsConcatString(NULL, str2, NULL) == E_INVALIDARG, "Incorrect error handling\n");
310 ok(WindowsConcatString(NULL, str2, &concat) == S_OK, "Failed to concatenate string\n");
311 ok(str2 == concat, "Concatenate created new string\n");
312 check_string(concat, input_string2, 3, FALSE);
313 ok(WindowsDeleteString(concat) == S_OK, "Failed to delete string\n");
315 ok(WindowsConcatString(str1, str2, NULL) == E_INVALIDARG, "Incorrect error handling\n");
316 ok(WindowsConcatString(str1, str2, &concat) == S_OK, "Failed to concatenate string\n");
317 check_string(concat, input_string, 6, FALSE);
318 ok(WindowsDeleteString(concat) == S_OK, "Failed to delete string\n");
320 ok(WindowsDeleteString(str2) == S_OK, "Failed to delete string\n");
321 ok(WindowsDeleteString(str1) == S_OK, "Failed to delete string\n");
323 /* Test concatenation of string references */
324 ok(WindowsCreateStringReference(input_string1, 3, &header1, &str1) == S_OK, "Failed to create string ref\n");
325 ok(WindowsCreateStringReference(input_string2, 3, &header2, &str2) == S_OK, "Failed to create string ref\n");
327 ok(WindowsConcatString(str1, NULL, &concat) == S_OK, "Failed to concatenate string\n");
328 ok(str1 != concat, "Concatenate string ref didn't create new string\n");
329 check_string(concat, input_string1, 3, FALSE);
330 ok(WindowsDeleteString(concat) == S_OK, "Failed to delete string\n");
332 ok(WindowsConcatString(NULL, str2, &concat) == S_OK, "Failed to concatenate string\n");
333 ok(str2 != concat, "Concatenate string ref didn't create new string\n");
334 check_string(concat, input_string2, 3, FALSE);
335 ok(WindowsDeleteString(concat) == S_OK, "Failed to delete string\n");
337 ok(WindowsConcatString(str1, str2, &concat) == S_OK, "Failed to concatenate string\n");
338 check_string(concat, input_string, 6, FALSE);
339 ok(WindowsDeleteString(concat) == S_OK, "Failed to delete string\n");
341 ok(WindowsDeleteString(str2) == S_OK, "Failed to delete string ref\n");
342 ok(WindowsDeleteString(str1) == S_OK, "Failed to delete string ref\n");
344 /* Test concatenation of two empty strings */
345 ok(WindowsConcatString(NULL, NULL, NULL) == E_INVALIDARG, "Incorrect error handling\n");
346 ok(WindowsConcatString(NULL, NULL, &concat) == S_OK, "Failed to concatenate string\n");
347 ok(concat == NULL, "Concatenate created new string\n");
350 static void test_compare(void)
352 HSTRING str1, str2;
353 HSTRING_HEADER header1, header2;
354 INT32 res;
356 /* Test comparison of string buffers */
357 ok(WindowsCreateString(input_string1, 3, &str1) == S_OK, "Failed to create string\n");
358 ok(WindowsCreateString(input_string2, 3, &str2) == S_OK, "Failed to create string\n");
360 ok(WindowsCompareStringOrdinal(str1, str1, &res) == S_OK, "Failed to compare string\n");
361 ok(res == 0, "Expected 0, got %d\n", res);
362 ok(WindowsCompareStringOrdinal(str1, str2, &res) == S_OK, "Failed to compare string\n");
363 ok(res == -1, "Expected -1, got %d\n", res);
364 ok(WindowsCompareStringOrdinal(str2, str1, &res) == S_OK, "Failed to compare string\n");
365 ok(res == 1, "Expected 1, got %d\n", res);
366 ok(WindowsCompareStringOrdinal(str2, str2, &res) == S_OK, "Failed to compare string\n");
367 ok(res == 0, "Expected 0, got %d\n", res);
368 ok(WindowsCompareStringOrdinal(str1, NULL, &res) == S_OK, "Failed to compare string\n");
369 ok(res == 1, "Expected 1, got %d\n", res);
370 ok(WindowsCompareStringOrdinal(NULL, str1, &res) == S_OK, "Failed to compare string\n");
371 ok(res == -1, "Expected -1, got %d\n", res);
372 ok(WindowsCompareStringOrdinal(str2, NULL, &res) == S_OK, "Failed to compare string\n");
373 ok(res == 1, "Expected 1, got %d\n", res);
374 ok(WindowsCompareStringOrdinal(NULL, str2, &res) == S_OK, "Failed to compare string\n");
375 ok(res == -1, "Expected -1, got %d\n", res);
377 ok(WindowsDeleteString(str2) == S_OK, "Failed to delete string\n");
378 ok(WindowsDeleteString(str1) == S_OK, "Failed to delete string\n");
380 /* Test comparison of string references */
381 ok(WindowsCreateStringReference(input_string1, 3, &header1, &str1) == S_OK, "Failed to create string ref\n");
382 ok(WindowsCreateStringReference(input_string2, 3, &header2, &str2) == S_OK, "Failed to create string ref\n");
384 ok(WindowsCompareStringOrdinal(str1, str1, &res) == S_OK, "Failed to compare string\n");
385 ok(res == 0, "Expected 0, got %d\n", res);
386 ok(WindowsCompareStringOrdinal(str1, str2, &res) == S_OK, "Failed to compare string\n");
387 ok(res == -1, "Expected -1, got %d\n", res);
388 ok(WindowsCompareStringOrdinal(str2, str1, &res) == S_OK, "Failed to compare string\n");
389 ok(res == 1, "Expected 1, got %d\n", res);
390 ok(WindowsCompareStringOrdinal(str2, str2, &res) == S_OK, "Failed to compare string\n");
391 ok(res == 0, "Expected 0, got %d\n", res);
392 ok(WindowsCompareStringOrdinal(str1, NULL, &res) == S_OK, "Failed to compare string\n");
393 ok(res == 1, "Expected 1, got %d\n", res);
394 ok(WindowsCompareStringOrdinal(NULL, str1, &res) == S_OK, "Failed to compare string\n");
395 ok(res == -1, "Expected -1, got %d\n", res);
396 ok(WindowsCompareStringOrdinal(str2, NULL, &res) == S_OK, "Failed to compare string\n");
397 ok(res == 1, "Expected 1, got %d\n", res);
398 ok(WindowsCompareStringOrdinal(NULL, str2, &res) == S_OK, "Failed to compare string\n");
399 ok(res == -1, "Expected -1, got %d\n", res);
401 ok(WindowsDeleteString(str2) == S_OK, "Failed to delete string ref\n");
402 ok(WindowsDeleteString(str1) == S_OK, "Failed to delete string ref\n");
404 /* Test comparison of two empty strings */
405 ok(WindowsCompareStringOrdinal(NULL, NULL, NULL) == E_INVALIDARG, "Incorrect error handling\n");
406 ok(WindowsCompareStringOrdinal(NULL, NULL, &res) == S_OK, "Failed to compare NULL string\n");
407 ok(res == 0, "Expected 0, got %d\n", res);
410 static void test_trim(void)
412 HSTRING str1, str2, trimmed;
413 HSTRING_HEADER header1, header2;
415 /* Test trimming of string buffers */
416 ok(WindowsCreateString(input_string, 6, &str1) == S_OK, "Failed to create string\n");
417 ok(WindowsCreateString(input_string1, 3, &str2) == S_OK, "Failed to create string\n");
419 ok(WindowsTrimStringStart(str1, str2, &trimmed) == S_OK, "Failed to trim string\n");
420 check_string(trimmed, input_string2, 3, FALSE);
421 ok(WindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n");
422 ok(WindowsTrimStringEnd(str1, str2, &trimmed) == S_OK, "Failed to trim string\n");
423 ok(trimmed == str1, "Trimmed string created new string\n");
424 check_string(trimmed, input_string, 6, FALSE);
425 ok(WindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n");
427 ok(WindowsDeleteString(str2) == S_OK, "Failed to delete string\n");
428 ok(WindowsCreateString(input_string2, 3, &str2) == S_OK, "Failed to create string\n");
430 ok(WindowsTrimStringStart(str1, str2, &trimmed) == S_OK, "Failed to trim string\n");
431 ok(trimmed == str1, "Trimmed string created new string\n");
432 check_string(trimmed, input_string, 6, FALSE);
433 ok(WindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n");
434 ok(WindowsTrimStringEnd(str1, str2, &trimmed) == S_OK, "Failed to trim string\n");
435 check_string(trimmed, input_string1, 3, FALSE);
436 ok(WindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n");
438 ok(WindowsDeleteString(str2) == S_OK, "Failed to delete string\n");
439 ok(WindowsDeleteString(str1) == S_OK, "Failed to delete string\n");
441 /* Test trimming of string references */
442 ok(WindowsCreateStringReference(input_string, 6, &header1, &str1) == S_OK, "Failed to create string ref\n");
443 ok(WindowsCreateStringReference(input_string1, 3, &header2, &str2) == S_OK, "Failed to create string ref\n");
445 ok(WindowsTrimStringStart(str1, str2, &trimmed) == S_OK, "Failed to trim string\n");
446 check_string(trimmed, input_string2, 3, FALSE);
447 ok(WindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n");
448 ok(WindowsTrimStringEnd(str1, str2, &trimmed) == S_OK, "Failed to trim string\n");
449 ok(trimmed != str1, "Trimmed string ref didn't create new string\n");
450 check_string(trimmed, input_string, 6, FALSE);
451 ok(WindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n");
453 ok(WindowsDeleteString(str2) == S_OK, "Failed to delete string ref\n");
454 ok(WindowsCreateStringReference(input_string2, 3, &header2, &str2) == S_OK, "Failed to create string ref\n");
456 ok(WindowsTrimStringStart(str1, str2, &trimmed) == S_OK, "Failed to trim string\n");
457 ok(trimmed != str1, "Trimmed string ref didn't create new string\n");
458 check_string(trimmed, input_string, 6, FALSE);
459 ok(WindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n");
460 ok(WindowsTrimStringEnd(str1, str2, &trimmed) == S_OK, "Failed to trim string\n");
461 check_string(trimmed, input_string1, 3, FALSE);
462 ok(WindowsDeleteString(trimmed) == S_OK, "Failed to delete string\n");
464 ok(WindowsDeleteString(str2) == S_OK, "Failed to delete string ref\n");
465 ok(WindowsDeleteString(str1) == S_OK, "Failed to delete string ref\n");
467 /* Test handling of NULL strings */
468 ok(WindowsCreateString(input_string, 6, &str1) == S_OK, "Failed to create string\n");
469 ok(WindowsTrimStringStart(NULL, NULL, NULL) == E_INVALIDARG, "Incorrect error handling\n");
470 ok(WindowsTrimStringStart(NULL, str1, NULL) == E_INVALIDARG, "Incorrect error handling\n");
471 ok(WindowsTrimStringStart(NULL, NULL, &trimmed) == E_INVALIDARG, "Incorrect error handling\n");
472 ok(WindowsTrimStringStart(NULL, str1, &trimmed) == S_OK, "Failed to trim empty string\n");
473 ok(trimmed == NULL, "Trimming created new string\n");
474 ok(WindowsTrimStringEnd(NULL, NULL, NULL) == E_INVALIDARG, "Incorrect error handling\n");
475 ok(WindowsTrimStringEnd(NULL, str1, NULL) == E_INVALIDARG, "Incorrect error handling\n");
476 ok(WindowsTrimStringEnd(NULL, NULL, &trimmed) == E_INVALIDARG, "Incorrect error handling\n");
477 ok(WindowsTrimStringEnd(NULL, str1, &trimmed) == S_OK, "Failed to trim empty string\n");
478 ok(trimmed == NULL, "Trimming created new string\n");
479 ok(WindowsDeleteString(str1) == S_OK, "Failed to delete string\n");
482 static void test_hstring_struct(void)
484 struct hstring_header
486 UINT32 flags;
487 UINT32 length;
488 UINT32 padding1;
489 UINT32 padding2;
490 const WCHAR *str;
493 struct hstring_private
495 struct hstring_header header;
496 LONG refcount;
497 WCHAR buffer[1];
500 HSTRING str;
501 HSTRING str2;
502 HSTRING_HEADER hdr;
503 struct hstring_private* prv;
504 struct hstring_private* prv2;
506 BOOL arch64 = (sizeof(void*) == 8);
508 ok(arch64 ? (sizeof(prv->header) == 24) : (sizeof(prv->header) == 20), "hstring_header size incorrect.\n");
510 ok(WindowsCreateString(input_string, 6, &str) == S_OK, "Failed to create string.\n");
512 prv = CONTAINING_RECORD(str, struct hstring_private, header);
514 ok(prv->header.flags == 0, "Expected 0 in flags field, got %#x.\n", prv->header.flags);
515 ok(prv->header.length == 6, "Expected 6 in length field, got %u.\n", prv->header.length);
516 todo_wine
517 ok(prv->header.str == prv->buffer, "Expected str to point at buffer, instead pointing at %p.\n", prv->header.str);
518 todo_wine
519 ok(prv->refcount == 1, "Expected 1 in refcount, got %u.\n", prv->refcount);
520 todo_wine
521 ok(wcscmp(input_string, prv->buffer) == 0, "Expected strings to match.\n");
522 todo_wine
523 ok(prv->buffer[prv->header.length] == '\0', "Expected buffer to be null terminated.\n");
525 ok(WindowsDuplicateString(str, &str2) == S_OK, "Failed to duplicate string.\n");
527 prv2 = CONTAINING_RECORD(str2, struct hstring_private, header);
529 todo_wine
530 ok(prv->refcount == 2, "Expected 2 in refcount, got %u.\n", prv->refcount);
531 todo_wine
532 ok(prv2->refcount == 2, "Expected 2 in refcount, got %u.\n", prv2->refcount);
533 todo_wine
534 ok(wcscmp(input_string, prv2->buffer) == 0, "Expected strings to match.\n");
536 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string.\n");
538 todo_wine
539 ok(prv->refcount == 1, "Expected 1 in refcount, got %u.\n", prv->refcount);
541 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string.\n");
543 ok(WindowsCreateStringReference(input_string, 6, &hdr, &str) == S_OK, "Failed to create string ref.\n");
545 prv = CONTAINING_RECORD(&hdr, struct hstring_private, header);
546 prv2 = CONTAINING_RECORD(str, struct hstring_private, header);
548 ok(prv == prv2, "Pointers not identical.\n");
549 ok(prv2->header.flags == 1, "Expected HSTRING_REFERENCE_FLAG to be set, got %#x.\n", prv2->header.flags);
550 ok(prv2->header.length == 6, "Expected 6 in length field, got %u.\n", prv2->header.length);
551 todo_wine
552 ok(prv2->header.str == input_string, "Expected str to point at input_string, instead pointing at %p.\n", prv2->header.str);
554 ok(WindowsDeleteString(str) == S_OK, "Failed to delete string ref.\n");
557 START_TEST(string)
559 test_create_delete();
560 test_duplicate();
561 test_access();
562 test_string_buffer();
563 test_substring();
564 test_concat();
565 test_compare();
566 test_trim();
567 test_hstring_struct();