1 /* Unit test suite for Rtl large integer functions
3 * Copyright 2003 Thomas Mertes
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 * We use function pointers here as there is no import library for NTDLL on
26 #include "ntdll_test.h"
29 /* Function ptrs for ntdll calls */
30 static HMODULE hntdll
= 0;
31 static LONGLONG (WINAPI
*pRtlExtendedMagicDivide
)(LONGLONG
, LONGLONG
, INT
);
32 static VOID (WINAPI
*pRtlFreeAnsiString
)(PSTRING
);
33 static NTSTATUS (WINAPI
*pRtlInt64ToUnicodeString
)(ULONGLONG
, ULONG
, UNICODE_STRING
*);
34 static NTSTATUS (WINAPI
*pRtlLargeIntegerToChar
)(ULONGLONG
*, ULONG
, ULONG
, PCHAR
);
35 static NTSTATUS (WINAPI
*pRtlUnicodeStringToAnsiString
)(STRING
*, const UNICODE_STRING
*, BOOLEAN
);
37 static LONGLONG (WINAPI
*p_alldiv
)( LONGLONG a
, LONGLONG b
);
38 static LONGLONG (WINAPI
*p_allrem
)( LONGLONG a
, LONGLONG b
);
39 static LONGLONG (WINAPI
*p_allmul
)( LONGLONG a
, LONGLONG b
);
40 static ULONGLONG (WINAPI
*p_aulldiv
)( ULONGLONG a
, ULONGLONG b
);
41 static ULONGLONG (WINAPI
*p_aullrem
)( ULONGLONG a
, ULONGLONG b
);
42 static void *p_allshl
, *p_allshr
, *p_aullshr
;
44 static void InitFunctionPtrs(void)
46 hntdll
= LoadLibraryA("ntdll.dll");
47 ok(hntdll
!= 0, "LoadLibrary failed\n");
49 pRtlExtendedMagicDivide
= (void *)GetProcAddress(hntdll
, "RtlExtendedMagicDivide");
50 pRtlFreeAnsiString
= (void *)GetProcAddress(hntdll
, "RtlFreeAnsiString");
51 pRtlInt64ToUnicodeString
= (void *)GetProcAddress(hntdll
, "RtlInt64ToUnicodeString");
52 pRtlLargeIntegerToChar
= (void *)GetProcAddress(hntdll
, "RtlLargeIntegerToChar");
53 pRtlUnicodeStringToAnsiString
= (void *)GetProcAddress(hntdll
, "RtlUnicodeStringToAnsiString");
55 p_alldiv
= (void *)GetProcAddress(hntdll
, "_alldiv");
56 p_allrem
= (void *)GetProcAddress(hntdll
, "_allrem");
57 p_allmul
= (void *)GetProcAddress(hntdll
, "_allmul");
58 p_allshl
= (void *)GetProcAddress(hntdll
, "_allshl");
59 p_allshr
= (void *)GetProcAddress(hntdll
, "_allshr");
60 p_aulldiv
= (void *)GetProcAddress(hntdll
, "_aulldiv");
61 p_aullrem
= (void *)GetProcAddress(hntdll
, "_aullrem");
62 p_aullshr
= (void *)GetProcAddress(hntdll
, "_aullshr");
66 #define ULL(a,b) (((ULONGLONG)(a) << 32) | (b))
75 static const magic_divide_t magic_divide
[] = {
76 { 3, ULL(0x55555555,0x55555555), 0, 0}, /* 1 */
77 { 333333333, ULL(0x55555555,0x55555555), 0, 111111110}, /* 111111111 */
78 { ULL(0x7fffffff,0xffffffff), ULL(0x55555555,0x55555555), 0, ULL(0x2aaaaaaa,0xaaaaaaaa)},
79 { 3, ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 0}, /* 1 */
80 { 333333333, ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 111111110}, /* 111111111 */
81 { ULL(0x7fffffff,0xffffffff), ULL(0xaaaaaaaa,0xaaaaaaaa), 1, ULL(0x2aaaaaaa,0xaaaaaaaa)},
82 { -3, ULL(0x55555555,0x55555555), 0, 0}, /* -1 */
83 { -333333333, ULL(0x55555555,0x55555555), 0, -111111110}, /* -111111111 */
84 {-ULL(0x7fffffff,0xffffffff), ULL(0x55555555,0x55555555), 0, -ULL(0x2aaaaaaa,0xaaaaaaaa)},
85 { -3, ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 0}, /* -1 */
86 { -333333333, ULL(0xaaaaaaaa,0xaaaaaaaa), 1, -111111110}, /* -111111111 */
87 {-ULL(0x7fffffff,0xffffffff), ULL(0xaaaaaaaa,0xaaaaaaaa), 1, -ULL(0x2aaaaaaa,0xaaaaaaaa)},
88 { -3, -ULL(0x55555555,0x55555555), 0, -2}, /* -1 */
89 { -333333333, -ULL(0x55555555,0x55555555), 0, -222222222}, /* -111111111 */
90 {-ULL(0x7fffffff,0xffffffff), -ULL(0x55555555,0x55555555), 0, -ULL(0x55555555,0x55555554)},
91 { -3, -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 0}, /* -1 */
92 { -333333333, -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, -55555555}, /* -111111111 */
93 {-ULL(0x7fffffff,0xffffffff), -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, -ULL(0x15555555,0x55555555)},
94 { 3, -ULL(0x55555555,0x55555555), 0, 2}, /* -1 */
95 { 333333333, -ULL(0x55555555,0x55555555), 0, 222222222}, /* -111111111 */
96 { ULL(0x7fffffff,0xffffffff), -ULL(0x55555555,0x55555555), 0, ULL(0x55555555,0x55555554)},
97 { 3, -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 0}, /* -1 */
98 { 333333333, -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 55555555}, /* -111111111 */
99 { ULL(0x7fffffff,0xffffffff), -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, ULL(0x15555555,0x55555555)},
100 { 3, ULL(0xaaaaaaaa,0xaaaaa800), 1, 0}, /* 1 */
101 { 333333333, ULL(0xaaaaaaaa,0xaaaaa800), 1, 111111110}, /* 111111111 */
102 { ULL(0x7fffffff,0xffffffff), ULL(0xaaaaaaaa,0xaaaaa800), 1, ULL(0x2aaaaaaa,0xaaaaa9ff)}, /* 0x2aaaaaaaaaaaaaaa */
103 { 5, ULL(0x33333333,0x333333ff), 0, 1},
104 { 555555555, ULL(0x33333333,0x333333ff), 0, 111111111},
105 { ULL(0x7fffffff,0xffffffff), ULL(0x33333333,0x333333ff), 0, ULL(0x19999999,0x999999ff)}, /* 0x199999999999999a */
106 { 5, ULL(0x66666666,0x666667fe), 1, 1},
107 { 555555555, ULL(0x66666666,0x666667fe), 1, 111111111},
108 { ULL(0x7fffffff,0xffffffff), ULL(0x66666666,0x666667fe), 1, ULL(0x19999999,0x999999ff)}, /* 0x199999999999999a */
109 { 5, ULL(0xcccccccc,0xcccccffd), 2, 1},
110 { 555555555, ULL(0xcccccccc,0xcccccffd), 2, 111111111},
111 { ULL(0x7fffffff,0xffffffff), ULL(0xcccccccc,0xcccccffd), 2, ULL(0x19999999,0x999999ff)}, /* 0x199999999999999a */
112 { ULL(0x00000add,0xcafeface), ULL(0x002f1e28,0xfd1b5cca), 33, 1},
113 { ULL(0x081ac1b9,0xc2310a80), ULL(0x002f1e28,0xfd1b5cca), 33, 0xbeef},
114 { ULL(0x74ae3b5f,0x1558c800), ULL(0x002f1e28,0xfd1b5cca), 33, 0xabcde},
115 { ULL(0x00000add,0xcafeface), ULL(0x2f1e28fd,0x1b5cca00), 41, 1},
116 { ULL(0x081ac1b9,0xc2310a80), ULL(0x2f1e28fd,0x1b5cca00), 41, 0xbeef},
117 { ULL(0x74ae3b5f,0x1558c800), ULL(0x2f1e28fd,0x1b5cca00), 41, 0xabcde},
122 static void test_RtlExtendedMagicDivide(void)
127 for (i
= 0; i
< ARRAY_SIZE(magic_divide
); i
++) {
128 result
= pRtlExtendedMagicDivide(magic_divide
[i
].a
, magic_divide
[i
].b
, magic_divide
[i
].shift
);
129 ok(result
== magic_divide
[i
].result
,
130 "call failed: RtlExtendedMagicDivide(0x%s, 0x%s, %d) has result 0x%s, expected 0x%s\n",
131 wine_dbgstr_longlong(magic_divide
[i
].a
), wine_dbgstr_longlong(magic_divide
[i
].b
), magic_divide
[i
].shift
,
132 wine_dbgstr_longlong(result
), wine_dbgstr_longlong(magic_divide
[i
].result
));
137 #define LARGE_STRI_BUFFER_LENGTH 67
143 USHORT MaximumLength
;
150 * The native DLL does produce garbage or STATUS_BUFFER_OVERFLOW for
151 * base 2, 8 and 16 when the value is larger than 0xFFFFFFFF.
152 * Therefore these testcases are commented out.
155 static const largeint2str_t largeint2str
[] = {
156 {10, 123, 3, 11, "123\0---------------------------------------------------------------", STATUS_SUCCESS
},
158 { 0, 0x80000000U
, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS
},
159 { 0, -2147483647, 20, 21, "18446744071562067969\0----------------------------------------------", STATUS_SUCCESS
},
160 { 0, -2, 20, 21, "18446744073709551614\0----------------------------------------------", STATUS_SUCCESS
},
161 { 0, -1, 20, 21, "18446744073709551615\0----------------------------------------------", STATUS_SUCCESS
},
162 { 0, 0, 1, 11, "0\0-----------------------------------------------------------------", STATUS_SUCCESS
},
163 { 0, 1, 1, 11, "1\0-----------------------------------------------------------------", STATUS_SUCCESS
},
164 { 0, 12, 2, 11, "12\0----------------------------------------------------------------", STATUS_SUCCESS
},
165 { 0, 123, 3, 11, "123\0---------------------------------------------------------------", STATUS_SUCCESS
},
166 { 0, 1234, 4, 11, "1234\0--------------------------------------------------------------", STATUS_SUCCESS
},
167 { 0, 12345, 5, 11, "12345\0-------------------------------------------------------------", STATUS_SUCCESS
},
168 { 0, 123456, 6, 11, "123456\0------------------------------------------------------------", STATUS_SUCCESS
},
169 { 0, 1234567, 7, 11, "1234567\0-----------------------------------------------------------", STATUS_SUCCESS
},
170 { 0, 12345678, 8, 11, "12345678\0----------------------------------------------------------", STATUS_SUCCESS
},
171 { 0, 123456789, 9, 11, "123456789\0---------------------------------------------------------", STATUS_SUCCESS
},
172 { 0, 2147483646, 10, 11, "2147483646\0--------------------------------------------------------", STATUS_SUCCESS
},
173 { 0, 2147483647, 10, 11, "2147483647\0--------------------------------------------------------", STATUS_SUCCESS
},
174 { 0, 2147483648U, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS
},
175 { 0, 2147483649U, 10, 11, "2147483649\0--------------------------------------------------------", STATUS_SUCCESS
},
176 { 0, 4294967294U, 10, 11, "4294967294\0--------------------------------------------------------", STATUS_SUCCESS
},
177 { 0, 4294967295U, 10, 11, "4294967295\0--------------------------------------------------------", STATUS_SUCCESS
},
178 { 0, ULL(0x2,0xdfdc1c35), 11, 12, "12345678901\0-------------------------------------------------------", STATUS_SUCCESS
},
179 { 0, ULL(0xe5,0xf4c8f374), 12, 13, "987654321012\0------------------------------------------------------", STATUS_SUCCESS
},
180 { 0, ULL(0x1c0,0xfc161e3e), 13, 14, "1928374656574\0-----------------------------------------------------", STATUS_SUCCESS
},
181 { 0, ULL(0xbad,0xcafeface), 14, 15, "12841062955726\0----------------------------------------------------", STATUS_SUCCESS
},
182 { 0, ULL(0x5bad,0xcafeface), 15, 16, "100801993177806\0---------------------------------------------------", STATUS_SUCCESS
},
183 { 0, ULL(0xaface,0xbeefcafe), 16, 20, "3090515640699646\0--------------------------------------------------", STATUS_SUCCESS
},
184 { 0, ULL(0xa5beef,0xabcdcafe), 17, 20, "46653307746110206\0-------------------------------------------------", STATUS_SUCCESS
},
185 { 0, ULL(0x1f8cf9b,0xf2df3af1), 18, 20, "142091656963767025\0------------------------------------------------", STATUS_SUCCESS
},
186 { 0, ULL(0x0fffffff,0xffffffff), 19, 20, "1152921504606846975\0-----------------------------------------------", STATUS_SUCCESS
},
187 { 0, ULL(0xffffffff,0xfffffffe), 20, 21, "18446744073709551614\0----------------------------------------------", STATUS_SUCCESS
},
188 { 0, ULL(0xffffffff,0xffffffff), 20, 21, "18446744073709551615\0----------------------------------------------", STATUS_SUCCESS
},
190 { 2, 0x80000000U
, 32, 33, "10000000000000000000000000000000\0----------------------------------", STATUS_SUCCESS
},
192 * { 2, -2147483647, 64, 65, "1111111111111111111111111111111110000000000000000000000000000001\0--", STATUS_SUCCESS},
193 * { 2, -2, 64, 65, "1111111111111111111111111111111111111111111111111111111111111110\0--", STATUS_SUCCESS},
194 * { 2, -1, 64, 65, "1111111111111111111111111111111111111111111111111111111111111111\0--", STATUS_SUCCESS},
196 { 2, 0, 1, 33, "0\0-----------------------------------------------------------------", STATUS_SUCCESS
},
197 { 2, 1, 1, 33, "1\0-----------------------------------------------------------------", STATUS_SUCCESS
},
198 { 2, 10, 4, 33, "1010\0--------------------------------------------------------------", STATUS_SUCCESS
},
199 { 2, 100, 7, 33, "1100100\0-----------------------------------------------------------", STATUS_SUCCESS
},
200 { 2, 1000, 10, 33, "1111101000\0--------------------------------------------------------", STATUS_SUCCESS
},
201 { 2, 10000, 14, 33, "10011100010000\0----------------------------------------------------", STATUS_SUCCESS
},
202 { 2, 32767, 15, 33, "111111111111111\0---------------------------------------------------", STATUS_SUCCESS
},
203 { 2, 32768, 16, 33, "1000000000000000\0--------------------------------------------------", STATUS_SUCCESS
},
204 { 2, 65535, 16, 33, "1111111111111111\0--------------------------------------------------", STATUS_SUCCESS
},
205 { 2, 100000, 17, 33, "11000011010100000\0-------------------------------------------------", STATUS_SUCCESS
},
206 { 2, 1000000, 20, 33, "11110100001001000000\0----------------------------------------------", STATUS_SUCCESS
},
207 { 2, 10000000, 24, 33, "100110001001011010000000\0------------------------------------------", STATUS_SUCCESS
},
208 { 2, 100000000, 27, 33, "101111101011110000100000000\0---------------------------------------", STATUS_SUCCESS
},
209 { 2, 1000000000, 30, 33, "111011100110101100101000000000\0------------------------------------", STATUS_SUCCESS
},
210 { 2, 1073741823, 30, 33, "111111111111111111111111111111\0------------------------------------", STATUS_SUCCESS
},
211 { 2, 2147483646, 31, 33, "1111111111111111111111111111110\0-----------------------------------", STATUS_SUCCESS
},
212 { 2, 2147483647, 31, 33, "1111111111111111111111111111111\0-----------------------------------", STATUS_SUCCESS
},
213 { 2, 2147483648U, 32, 33, "10000000000000000000000000000000\0----------------------------------", STATUS_SUCCESS
},
214 { 2, 2147483649U, 32, 33, "10000000000000000000000000000001\0----------------------------------", STATUS_SUCCESS
},
215 { 2, 4294967294U, 32, 33, "11111111111111111111111111111110\0----------------------------------", STATUS_SUCCESS
},
216 { 2, 0xFFFFFFFF, 32, 33, "11111111111111111111111111111111\0----------------------------------", STATUS_SUCCESS
},
218 * { 2, 0x1FFFFFFFF, 33, 34, "111111111111111111111111111111111\0---------------------------------", STATUS_SUCCESS},
219 * { 2, 0x3FFFFFFFF, 34, 35, "1111111111111111111111111111111111\0--------------------------------", STATUS_SUCCESS},
220 * { 2, 0x7FFFFFFFF, 35, 36, "11111111111111111111111111111111111\0-------------------------------", STATUS_SUCCESS},
221 * { 2, 0xFFFFFFFFF, 36, 37, "111111111111111111111111111111111111\0------------------------------", STATUS_SUCCESS},
222 * { 2, 0x1FFFFFFFFF, 37, 38, "1111111111111111111111111111111111111\0-----------------------------", STATUS_SUCCESS},
223 * { 2, 0x3FFFFFFFFF, 38, 39, "11111111111111111111111111111111111111\0----------------------------", STATUS_SUCCESS},
224 * { 2, 0x7FFFFFFFFF, 39, 40, "111111111111111111111111111111111111111\0---------------------------", STATUS_SUCCESS},
225 * { 2, 0xFFFFFFFFFF, 40, 41, "1111111111111111111111111111111111111111\0--------------------------", STATUS_SUCCESS},
228 { 8, 0x80000000U
, 11, 12, "20000000000\0-------------------------------------------------------", STATUS_SUCCESS
},
230 * { 8, -2147483647, 22, 23, "1777777777760000000001\0--------------------------------------------", STATUS_SUCCESS},
231 * { 8, -2, 22, 23, "1777777777777777777776\0--------------------------------------------", STATUS_SUCCESS},
232 * { 8, -1, 22, 23, "1777777777777777777777\0--------------------------------------------", STATUS_SUCCESS},
234 { 8, 0, 1, 12, "0\0-----------------------------------------------------------------", STATUS_SUCCESS
},
235 { 8, 1, 1, 12, "1\0-----------------------------------------------------------------", STATUS_SUCCESS
},
236 { 8, 2147483646, 11, 12, "17777777776\0-------------------------------------------------------", STATUS_SUCCESS
},
237 { 8, 2147483647, 11, 12, "17777777777\0-------------------------------------------------------", STATUS_SUCCESS
},
238 { 8, 2147483648U, 11, 12, "20000000000\0-------------------------------------------------------", STATUS_SUCCESS
},
239 { 8, 2147483649U, 11, 12, "20000000001\0-------------------------------------------------------", STATUS_SUCCESS
},
240 { 8, 4294967294U, 11, 12, "37777777776\0-------------------------------------------------------", STATUS_SUCCESS
},
241 { 8, 4294967295U, 11, 12, "37777777777\0-------------------------------------------------------", STATUS_SUCCESS
},
243 {10, 0x80000000U
, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS
},
244 {10, -2147483647, 20, 21, "18446744071562067969\0----------------------------------------------", STATUS_SUCCESS
},
245 {10, -2, 20, 21, "18446744073709551614\0----------------------------------------------", STATUS_SUCCESS
},
246 {10, -1, 20, 21, "18446744073709551615\0----------------------------------------------", STATUS_SUCCESS
},
247 {10, 0, 1, 11, "0\0-----------------------------------------------------------------", STATUS_SUCCESS
},
248 {10, 1, 1, 11, "1\0-----------------------------------------------------------------", STATUS_SUCCESS
},
249 {10, 2147483646, 10, 11, "2147483646\0--------------------------------------------------------", STATUS_SUCCESS
},
250 {10, 2147483647, 10, 11, "2147483647\0--------------------------------------------------------", STATUS_SUCCESS
},
251 {10, 2147483648U, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS
},
252 {10, 2147483649U, 10, 11, "2147483649\0--------------------------------------------------------", STATUS_SUCCESS
},
253 {10, 4294967294U, 10, 11, "4294967294\0--------------------------------------------------------", STATUS_SUCCESS
},
254 {10, 4294967295U, 10, 11, "4294967295\0--------------------------------------------------------", STATUS_SUCCESS
},
256 {16, 0, 1, 9, "0\0-----------------------------------------------------------------", STATUS_SUCCESS
},
257 {16, 1, 1, 9, "1\0-----------------------------------------------------------------", STATUS_SUCCESS
},
258 {16, 2147483646, 8, 9, "7FFFFFFE\0----------------------------------------------------------", STATUS_SUCCESS
},
259 {16, 2147483647, 8, 9, "7FFFFFFF\0----------------------------------------------------------", STATUS_SUCCESS
},
260 {16, 0x80000000, 8, 9, "80000000\0----------------------------------------------------------", STATUS_SUCCESS
},
261 {16, 0x80000001, 8, 9, "80000001\0----------------------------------------------------------", STATUS_SUCCESS
},
262 {16, 0xFFFFFFFE, 8, 9, "FFFFFFFE\0----------------------------------------------------------", STATUS_SUCCESS
},
263 {16, 0xFFFFFFFF, 8, 9, "FFFFFFFF\0----------------------------------------------------------", STATUS_SUCCESS
},
265 * {16, 0x100000000, 9, 10, "100000000\0---------------------------------------------------------", STATUS_SUCCESS},
266 * {16, 0xBADDEADBEEF, 11, 12, "BADDEADBEEF\0-------------------------------------------------------", STATUS_SUCCESS},
267 * {16, 0x8000000000000000, 16, 17, "8000000000000000\0--------------------------------------------------", STATUS_SUCCESS},
268 * {16, 0xFEDCBA9876543210, 16, 17, "FEDCBA9876543210\0--------------------------------------------------", STATUS_SUCCESS},
269 * {16, 0xFFFFFFFF80000001, 16, 17, "FFFFFFFF80000001\0--------------------------------------------------", STATUS_SUCCESS},
270 * {16, 0xFFFFFFFFFFFFFFFE, 16, 17, "FFFFFFFFFFFFFFFE\0--------------------------------------------------", STATUS_SUCCESS},
271 * {16, 0xFFFFFFFFFFFFFFFF, 16, 17, "FFFFFFFFFFFFFFFF\0--------------------------------------------------", STATUS_SUCCESS},
274 { 2, 32768, 16, 17, "1000000000000000\0--------------------------------------------------", STATUS_SUCCESS
},
275 { 2, 32768, 16, 16, "1000000000000000---------------------------------------------------", STATUS_SUCCESS
, 1},
276 { 2, 65536, 17, 18, "10000000000000000\0-------------------------------------------------", STATUS_SUCCESS
},
277 { 2, 65536, 17, 17, "10000000000000000--------------------------------------------------", STATUS_SUCCESS
, 1},
278 { 2, 131072, 18, 19, "100000000000000000\0------------------------------------------------", STATUS_SUCCESS
},
279 { 2, 131072, 18, 18, "100000000000000000-------------------------------------------------", STATUS_SUCCESS
, 1},
280 {16, 0xffffffff, 8, 9, "FFFFFFFF\0----------------------------------------------------------", STATUS_SUCCESS
},
281 {16, 0xffffffff, 8, 8, "FFFFFFFF-----------------------------------------------------------", STATUS_SUCCESS
, 1},
282 {16, 0xffffffff, 8, 7, "-------------------------------------------------------------------", STATUS_BUFFER_OVERFLOW
, 1},
283 {16, 0xa, 1, 2, "A\0-----------------------------------------------------------------", STATUS_SUCCESS
},
284 {16, 0xa, 1, 1, "A------------------------------------------------------------------", STATUS_SUCCESS
, 1},
285 {16, 0, 1, 0, "-------------------------------------------------------------------", STATUS_BUFFER_OVERFLOW
, 1},
286 {20, 0xdeadbeef, 0, 9, "-------------------------------------------------------------------", STATUS_INVALID_PARAMETER
},
287 {-8, 07654321, 0, 12, "-------------------------------------------------------------------", STATUS_INVALID_PARAMETER
},
291 static void one_RtlInt64ToUnicodeString_test(int test_num
, const largeint2str_t
*largeint2str
)
294 WCHAR expected_str_Buffer
[LARGE_STRI_BUFFER_LENGTH
+ 1];
295 UNICODE_STRING expected_unicode_string
;
296 STRING expected_ansi_str
;
297 WCHAR str_Buffer
[LARGE_STRI_BUFFER_LENGTH
+ 1];
298 UNICODE_STRING unicode_string
;
303 if (largeint2str
->value
>> 32 == 0xffffffff) /* this crashes on 64-bit Vista */
305 skip( "Value ffffffff%08lx broken on 64-bit windows\n", (DWORD
)largeint2str
->value
);
310 for (pos
= 0; pos
< LARGE_STRI_BUFFER_LENGTH
; pos
++) {
311 expected_str_Buffer
[pos
] = largeint2str
->Buffer
[pos
];
313 expected_unicode_string
.Length
= largeint2str
->Length
* sizeof(WCHAR
);
314 expected_unicode_string
.MaximumLength
= largeint2str
->MaximumLength
* sizeof(WCHAR
);
315 expected_unicode_string
.Buffer
= expected_str_Buffer
;
316 pRtlUnicodeStringToAnsiString(&expected_ansi_str
, &expected_unicode_string
, 1);
318 for (pos
= 0; pos
< LARGE_STRI_BUFFER_LENGTH
; pos
++) {
319 str_Buffer
[pos
] = '-';
321 unicode_string
.Length
= 0;
322 unicode_string
.MaximumLength
= largeint2str
->MaximumLength
* sizeof(WCHAR
);
323 unicode_string
.Buffer
= str_Buffer
;
325 if (largeint2str
->base
== 0) {
326 result
= pRtlInt64ToUnicodeString(largeint2str
->value
, 10, &unicode_string
);
328 result
= pRtlInt64ToUnicodeString(largeint2str
->value
, largeint2str
->base
, &unicode_string
);
330 pRtlUnicodeStringToAnsiString(&ansi_str
, &unicode_string
, 1);
331 if (result
== STATUS_BUFFER_OVERFLOW
) {
332 /* On BUFFER_OVERFLOW the string Buffer should be unchanged */
333 for (pos
= 0; pos
< LARGE_STRI_BUFFER_LENGTH
; pos
++) {
334 expected_str_Buffer
[pos
] = '-';
336 /* w2k: The native function has two reasons for BUFFER_OVERFLOW: */
337 /* If the value is too large to convert: The Length is unchanged */
338 /* If str is too small to hold the string: Set str->Length to the length */
339 /* the string would have (which can be larger than the MaximumLength). */
340 /* To allow all this in the tests we do the following: */
341 if (expected_unicode_string
.Length
>= 64) {
342 /* The value is too large to convert only triggered when testing native */
343 /* Length is not filled with the expected string length (garbage?) */
344 expected_unicode_string
.Length
= unicode_string
.Length
;
347 ok(result
== largeint2str
->result
,
348 "(test %d): RtlInt64ToUnicodeString(0x%s, %d, [out]) has result %lx, expected: %lx\n",
349 test_num
, wine_dbgstr_longlong(largeint2str
->value
), largeint2str
->base
, result
, largeint2str
->result
);
350 if (result
== STATUS_SUCCESS
) {
351 ok(unicode_string
.Buffer
[unicode_string
.Length
/sizeof(WCHAR
)] == '\0',
352 "(test %d): RtlInt64ToUnicodeString(0x%s, %d, [out]) string \"%s\" is not NULL terminated\n",
353 test_num
, wine_dbgstr_longlong(largeint2str
->value
), largeint2str
->base
, ansi_str
.Buffer
);
356 ok(memcmp(unicode_string
.Buffer
, expected_unicode_string
.Buffer
, LARGE_STRI_BUFFER_LENGTH
* sizeof(WCHAR
)) == 0,
357 "(test %d): RtlInt64ToUnicodeString(0x%I64x, %d, [out]) assigns string \"%s\", expected: \"%s\"\n",
358 test_num
, largeint2str
->value
, largeint2str
->base
, ansi_str
.Buffer
, expected_ansi_str
.Buffer
);
359 ok(unicode_string
.Length
== expected_unicode_string
.Length
||
360 broken(largeint2str
->broken_len
&& !unicode_string
.Length
) /* win11 */,
361 "(test %d): RtlInt64ToUnicodeString(0x%s, %d, [out]) string has Length %d, expected: %d\n",
362 test_num
, wine_dbgstr_longlong(largeint2str
->value
), largeint2str
->base
,
363 unicode_string
.Length
, expected_unicode_string
.Length
);
364 ok(unicode_string
.MaximumLength
== expected_unicode_string
.MaximumLength
,
365 "(test %d): RtlInt64ToUnicodeString(0x%s, %d, [out]) string has MaximumLength %d, expected: %d\n",
366 test_num
, wine_dbgstr_longlong(largeint2str
->value
), largeint2str
->base
,
367 unicode_string
.MaximumLength
, expected_unicode_string
.MaximumLength
);
368 pRtlFreeAnsiString(&expected_ansi_str
);
369 pRtlFreeAnsiString(&ansi_str
);
373 static void test_RtlInt64ToUnicodeString(void)
377 for (test_num
= 0; test_num
< ARRAY_SIZE(largeint2str
); test_num
++) {
378 one_RtlInt64ToUnicodeString_test(test_num
, &largeint2str
[test_num
]);
383 static void one_RtlLargeIntegerToChar_test(int test_num
, const largeint2str_t
*largeint2str
)
386 char dest_str
[LARGE_STRI_BUFFER_LENGTH
+ 1];
390 if (largeint2str
->value
>> 32 == 0xffffffff) /* this crashes on 64-bit Vista */
392 skip( "Value ffffffff%08lx broken on 64-bit windows\n", (DWORD
)largeint2str
->value
);
397 memset(dest_str
, '-', LARGE_STRI_BUFFER_LENGTH
);
398 dest_str
[LARGE_STRI_BUFFER_LENGTH
] = '\0';
399 value
= largeint2str
->value
;
400 if (largeint2str
->base
== 0) {
401 result
= pRtlLargeIntegerToChar(&value
, 10, largeint2str
->MaximumLength
, dest_str
);
403 result
= pRtlLargeIntegerToChar(&value
, largeint2str
->base
, largeint2str
->MaximumLength
, dest_str
);
405 ok(result
== largeint2str
->result
,
406 "(test %d): RtlLargeIntegerToChar(0x%s, %d, %d, [out]) has result %lx, expected: %lx\n",
407 test_num
, wine_dbgstr_longlong(largeint2str
->value
), largeint2str
->base
,
408 largeint2str
->MaximumLength
, result
, largeint2str
->result
);
409 ok(memcmp(dest_str
, largeint2str
->Buffer
, LARGE_STRI_BUFFER_LENGTH
) == 0,
410 "(test %d): RtlLargeIntegerToChar(0x%s, %d, %d, [out]) assigns string \"%s\", expected: \"%s\"\n",
411 test_num
, wine_dbgstr_longlong(largeint2str
->value
), largeint2str
->base
,
412 largeint2str
->MaximumLength
, dest_str
, largeint2str
->Buffer
);
416 static void test_RtlLargeIntegerToChar(void)
422 for (test_num
= 0; test_num
< ARRAY_SIZE(largeint2str
); test_num
++) {
423 one_RtlLargeIntegerToChar_test(test_num
, &largeint2str
[test_num
]);
426 value
= largeint2str
[0].value
;
427 result
= pRtlLargeIntegerToChar(&value
, 20, largeint2str
[0].MaximumLength
, NULL
);
428 ok(result
== STATUS_INVALID_PARAMETER
,
429 "(test a): RtlLargeIntegerToChar(0x%s, %d, %d, NULL) has result %lx, expected: %lx\n",
430 wine_dbgstr_longlong(largeint2str
[0].value
), 20,
431 largeint2str
[0].MaximumLength
, result
, STATUS_INVALID_PARAMETER
);
433 result
= pRtlLargeIntegerToChar(&value
, 20, 0, NULL
);
434 ok(result
== STATUS_INVALID_PARAMETER
,
435 "(test b): RtlLargeIntegerToChar(0x%s, %d, %d, NULL) has result %lx, expected: %lx\n",
436 wine_dbgstr_longlong(largeint2str
[0].value
), 20,
437 largeint2str
[0].MaximumLength
, result
, STATUS_INVALID_PARAMETER
);
439 result
= pRtlLargeIntegerToChar(&value
, largeint2str
[0].base
, 0, NULL
);
440 ok(result
== STATUS_BUFFER_OVERFLOW
,
441 "(test c): RtlLargeIntegerToChar(0x%s, %d, %d, NULL) has result %lx, expected: %lx\n",
442 wine_dbgstr_longlong(largeint2str
[0].value
), largeint2str
[0].base
, 0, result
, STATUS_BUFFER_OVERFLOW
);
444 result
= pRtlLargeIntegerToChar(&value
, largeint2str
[0].base
, largeint2str
[0].MaximumLength
, NULL
);
445 ok(result
== STATUS_ACCESS_VIOLATION
,
446 "(test d): RtlLargeIntegerToChar(0x%s, %d, %d, NULL) has result %lx, expected: %lx\n",
447 wine_dbgstr_longlong(largeint2str
[0].value
),
448 largeint2str
[0].base
, largeint2str
[0].MaximumLength
, result
, STATUS_ACCESS_VIOLATION
);
451 static void test_builtins(void)
458 static const BYTE call_shift_code
[] =
460 0x55, /* pushl %ebp */
461 0x89, 0xe5, /* movl %esp,%ebp */
462 0x31, 0xc0, /* xorl %eax,%eax */
463 0x31, 0xd2, /* xorl %edx,%edx */
464 0x31, 0xc9, /* xorl %ecx,%ecx */
465 0x87, 0x45, 0x0c, /* xchgl 12(%ebp),%eax */
466 0x87, 0x55, 0x10, /* xchgl 16(%ebp),%edx */
467 0x87, 0x4d, 0x14, /* xchgl 20(%ebp),%ecx */
468 0xff, 0x55, 0x08, /* call *8(%ebp) */
469 0x39, 0xe5, /* cmpl %esp,%ebp */
470 0x74, 0x05, /* je 1f */
471 0xb8, 0xef, 0xbe, 0xad, 0xde, /* movl $0xdeadbeef,%eax */
475 LONGLONG (__cdecl
*call_shift_func
)(void *func
, LONGLONG a
, LONG b
);
477 code_mem
= VirtualAlloc(NULL
, 0x1000, MEM_RESERVE
| MEM_COMMIT
, PAGE_EXECUTE_READWRITE
);
479 l
= p_alldiv(100, 7);
480 ok(l
== 14, "_alldiv returned %s\n", wine_dbgstr_longlong(l
));
482 l
= p_alldiv(-100, 7);
483 ok(l
== -14, "_alldiv returned %s\n", wine_dbgstr_longlong(l
));
485 l
= p_alldiv(0x2000000040ll
, 0x100000007ll
);
486 ok(l
== 0x1f, "_alldiv returned %s\n", wine_dbgstr_longlong(l
));
488 u
= p_aulldiv(100, 7);
489 ok(u
== 14, "_aulldiv returned %s\n", wine_dbgstr_longlong(u
));
491 u
= p_aulldiv(-100, 7);
492 ok(u
== 0x2492492492492484ull
, "_alldiv returned %s\n", wine_dbgstr_longlong(u
));
494 u
= p_aulldiv(0x2000000040ull
, 0x100000007ull
);
495 ok(u
== 0x1f, "_aulldiv returned %s\n", wine_dbgstr_longlong(u
));
497 l
= p_allrem(100, 7);
498 ok(l
== 2, "_allrem returned %s\n", wine_dbgstr_longlong(l
));
500 l
= p_allrem(-100, 7);
501 ok(l
== -2, "_allrem returned %s\n", wine_dbgstr_longlong(l
));
503 l
= p_allrem(0x2000000040ll
, 0x100000007ll
);
504 ok(l
== 0xffffff67, "_allrem returned %s\n", wine_dbgstr_longlong(l
));
506 u
= p_aullrem(100, 7);
507 ok(u
== 2, "_aullrem returned %s\n", wine_dbgstr_longlong(u
));
509 u
= p_aullrem(-100, 7);
510 ok(u
== 0, "_allrem returned %s\n", wine_dbgstr_longlong(u
));
512 u
= p_aullrem(0x2000000040ull
, 0x100000007ull
);
513 ok(u
== 0xffffff67, "_aullrem returned %s\n", wine_dbgstr_longlong(u
));
516 ok(l
== 12, "_allmul = %s\n", wine_dbgstr_longlong(l
));
518 l
= p_allmul(0x300000001ll
, 4);
519 ok(l
== 0xc00000004, "_allmul = %s\n", wine_dbgstr_longlong(l
));
521 memcpy(code_mem
, call_shift_code
, sizeof(call_shift_code
));
522 call_shift_func
= code_mem
;
524 l
= call_shift_func(p_allshl
, 0x0123456789abcdefll
, 12);
525 ok(l
== 0x3456789abcdef000ll
, "got %#I64x\n", l
);
527 l
= call_shift_func(p_allshl
, 0x0123456789abcdefll
, 44);
528 ok(l
== 0xbcdef00000000000ll
, "got %#I64x\n", l
);
530 l
= call_shift_func(p_allshl
, 0x0123456789abcdefll
, 88);
531 ok(!l
, "got %#I64x\n", l
);
533 l
= call_shift_func(p_allshl
, 0x0123456789abcdefll
, 0x88);
534 ok(!l
, "got %#I64x\n", l
);
536 l
= call_shift_func(p_allshl
, 0x0123456789abcdefll
, 0x108);
537 ok(l
== 0x23456789abcdef00ll
, "got %#I64x\n", l
);
539 l
= call_shift_func(p_allshr
, 0x0123456789abcdefll
, 12);
540 ok(l
== 0x0123456789abcll
, "got %#I64x\n", l
);
542 l
= call_shift_func(p_allshr
, 0x0123456789abcdefll
, 44);
543 ok(l
== 0x01234ll
, "got %#I64x\n", l
);
545 l
= call_shift_func(p_allshr
, 0x0123456789abcdefll
, 88);
546 ok(!l
, "got %#I64x\n", l
);
548 l
= call_shift_func(p_allshr
, 0x8123456789abcdefll
, 12);
549 ok(l
== 0xfff8123456789abcll
, "got %#I64x\n", l
);
551 l
= call_shift_func(p_allshr
, 0x8123456789abcdefll
, 44);
552 ok(l
== 0xfffffffffff81234ll
, "got %#I64x\n", l
);
554 l
= call_shift_func(p_allshr
, 0x8123456789abcdefll
, 88);
555 ok(l
== -1ll, "got %#I64x\n", l
);
557 l
= call_shift_func(p_allshr
, 0x8123456789abcdefll
, 0x108);
558 ok(l
== 0xff8123456789abcdll
, "got %#I64x\n", l
);
560 l
= call_shift_func(p_aullshr
, 0x8123456789abcdefll
, 12);
561 ok(l
== 0x8123456789abcll
, "got %#I64x\n", l
);
563 l
= call_shift_func(p_aullshr
, 0x8123456789abcdefll
, 44);
564 ok(l
== 0x81234ll
, "got %#I64x\n", l
);
566 l
= call_shift_func(p_aullshr
, 0x8123456789abcdefll
, 88);
567 ok(!l
, "got %#I64x\n", l
);
569 l
= call_shift_func(p_aullshr
, 0x8123456789abcdefll
, 0x108);
570 ok(l
== 0x8123456789abcdll
, "got %#I64x\n", l
);
572 VirtualFree(code_mem
, 0, MEM_RELEASE
);
573 #endif /* __i386__ */
576 START_TEST(large_int
)
580 if (pRtlExtendedMagicDivide
)
581 test_RtlExtendedMagicDivide();
582 if (pRtlInt64ToUnicodeString
)
583 test_RtlInt64ToUnicodeString();
584 if (pRtlLargeIntegerToChar
)
585 test_RtlLargeIntegerToChar();