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
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
)
34 BOOL empty
= length
== 0;
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)
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
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)
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)
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
172 HSTRING_BUFFER buf
= NULL
;
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)
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)
353 HSTRING_HEADER header1
, header2
;
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
493 struct hstring_private
495 struct hstring_header header
;
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
);
517 ok(prv
->header
.str
== prv
->buffer
, "Expected str to point at buffer, instead pointing at %p.\n", prv
->header
.str
);
519 ok(prv
->refcount
== 1, "Expected 1 in refcount, got %u.\n", prv
->refcount
);
521 ok(wcscmp(input_string
, prv
->buffer
) == 0, "Expected strings to match.\n");
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
);
530 ok(prv
->refcount
== 2, "Expected 2 in refcount, got %u.\n", prv
->refcount
);
532 ok(prv2
->refcount
== 2, "Expected 2 in refcount, got %u.\n", prv2
->refcount
);
534 ok(wcscmp(input_string
, prv2
->buffer
) == 0, "Expected strings to match.\n");
536 ok(WindowsDeleteString(str
) == S_OK
, "Failed to delete string.\n");
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
);
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");
559 test_create_delete();
562 test_string_buffer();
567 test_hstring_struct();