[NTDLL_WINETEST] Add a PCH.
[reactos.git] / modules / rostests / winetests / ntdll / large_int.c
1 /* Unit test suite for Rtl large integer functions
2 *
3 * Copyright 2003 Thomas Mertes
4 *
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.
9 *
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.
14 *
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
18 *
19 * NOTES
20 * We use function pointers here as there is no import library for NTDLL on
21 * windows.
22 */
23
24 #include "ntdll_test.h"
25
26 /* Function ptrs for ntdll calls */
27 static HMODULE hntdll = 0;
28 static LONGLONG (WINAPI *pRtlExtendedMagicDivide)(LONGLONG, LONGLONG, INT);
29 static VOID (WINAPI *pRtlFreeAnsiString)(PSTRING);
30 static NTSTATUS (WINAPI *pRtlInt64ToUnicodeString)(ULONGLONG, ULONG, UNICODE_STRING *);
31 static NTSTATUS (WINAPI *pRtlLargeIntegerToChar)(ULONGLONG *, ULONG, ULONG, PCHAR);
32 static NTSTATUS (WINAPI *pRtlUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN);
33 static void (WINAPI *p_alldvrm)(LONGLONG, LONGLONG);
34 static void (WINAPI *p_aulldvrm)(ULONGLONG, ULONGLONG);
35
36
37 static void InitFunctionPtrs(void)
38 {
39 hntdll = LoadLibraryA("ntdll.dll");
40 ok(hntdll != 0, "LoadLibrary failed\n");
41 if (hntdll) {
42 pRtlExtendedMagicDivide = (void *)GetProcAddress(hntdll, "RtlExtendedMagicDivide");
43 pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString");
44 pRtlInt64ToUnicodeString = (void *)GetProcAddress(hntdll, "RtlInt64ToUnicodeString");
45 pRtlLargeIntegerToChar = (void *)GetProcAddress(hntdll, "RtlLargeIntegerToChar");
46 pRtlUnicodeStringToAnsiString = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToAnsiString");
47 p_alldvrm = (void *)GetProcAddress(hntdll, "_alldvrm");
48 p_aulldvrm = (void *)GetProcAddress(hntdll, "_aulldvrm");
49 } /* if */
50 }
51
52 #define ULL(a,b) (((ULONGLONG)(a) << 32) | (b))
53
54 typedef struct {
55 LONGLONG a;
56 LONGLONG b;
57 INT shift;
58 LONGLONG result;
59 } magic_divide_t;
60
61 static const magic_divide_t magic_divide[] = {
62 { 3, ULL(0x55555555,0x55555555), 0, 0}, /* 1 */
63 { 333333333, ULL(0x55555555,0x55555555), 0, 111111110}, /* 111111111 */
64 { ULL(0x7fffffff,0xffffffff), ULL(0x55555555,0x55555555), 0, ULL(0x2aaaaaaa,0xaaaaaaaa)},
65 { 3, ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 0}, /* 1 */
66 { 333333333, ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 111111110}, /* 111111111 */
67 { ULL(0x7fffffff,0xffffffff), ULL(0xaaaaaaaa,0xaaaaaaaa), 1, ULL(0x2aaaaaaa,0xaaaaaaaa)},
68 { -3, ULL(0x55555555,0x55555555), 0, 0}, /* -1 */
69 { -333333333, ULL(0x55555555,0x55555555), 0, -111111110}, /* -111111111 */
70 {-ULL(0x7fffffff,0xffffffff), ULL(0x55555555,0x55555555), 0, -ULL(0x2aaaaaaa,0xaaaaaaaa)},
71 { -3, ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 0}, /* -1 */
72 { -333333333, ULL(0xaaaaaaaa,0xaaaaaaaa), 1, -111111110}, /* -111111111 */
73 {-ULL(0x7fffffff,0xffffffff), ULL(0xaaaaaaaa,0xaaaaaaaa), 1, -ULL(0x2aaaaaaa,0xaaaaaaaa)},
74 { -3, -ULL(0x55555555,0x55555555), 0, -2}, /* -1 */
75 { -333333333, -ULL(0x55555555,0x55555555), 0, -222222222}, /* -111111111 */
76 {-ULL(0x7fffffff,0xffffffff), -ULL(0x55555555,0x55555555), 0, -ULL(0x55555555,0x55555554)},
77 { -3, -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 0}, /* -1 */
78 { -333333333, -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, -55555555}, /* -111111111 */
79 {-ULL(0x7fffffff,0xffffffff), -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, -ULL(0x15555555,0x55555555)},
80 { 3, -ULL(0x55555555,0x55555555), 0, 2}, /* -1 */
81 { 333333333, -ULL(0x55555555,0x55555555), 0, 222222222}, /* -111111111 */
82 { ULL(0x7fffffff,0xffffffff), -ULL(0x55555555,0x55555555), 0, ULL(0x55555555,0x55555554)},
83 { 3, -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 0}, /* -1 */
84 { 333333333, -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 55555555}, /* -111111111 */
85 { ULL(0x7fffffff,0xffffffff), -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, ULL(0x15555555,0x55555555)},
86 { 3, ULL(0xaaaaaaaa,0xaaaaa800), 1, 0}, /* 1 */
87 { 333333333, ULL(0xaaaaaaaa,0xaaaaa800), 1, 111111110}, /* 111111111 */
88 { ULL(0x7fffffff,0xffffffff), ULL(0xaaaaaaaa,0xaaaaa800), 1, ULL(0x2aaaaaaa,0xaaaaa9ff)}, /* 0x2aaaaaaaaaaaaaaa */
89 { 5, ULL(0x33333333,0x333333ff), 0, 1},
90 { 555555555, ULL(0x33333333,0x333333ff), 0, 111111111},
91 { ULL(0x7fffffff,0xffffffff), ULL(0x33333333,0x333333ff), 0, ULL(0x19999999,0x999999ff)}, /* 0x199999999999999a */
92 { 5, ULL(0x66666666,0x666667fe), 1, 1},
93 { 555555555, ULL(0x66666666,0x666667fe), 1, 111111111},
94 { ULL(0x7fffffff,0xffffffff), ULL(0x66666666,0x666667fe), 1, ULL(0x19999999,0x999999ff)}, /* 0x199999999999999a */
95 { 5, ULL(0xcccccccc,0xcccccffd), 2, 1},
96 { 555555555, ULL(0xcccccccc,0xcccccffd), 2, 111111111},
97 { ULL(0x7fffffff,0xffffffff), ULL(0xcccccccc,0xcccccffd), 2, ULL(0x19999999,0x999999ff)}, /* 0x199999999999999a */
98 { ULL(0x00000add,0xcafeface), ULL(0x002f1e28,0xfd1b5cca), 33, 1},
99 { ULL(0x081ac1b9,0xc2310a80), ULL(0x002f1e28,0xfd1b5cca), 33, 0xbeef},
100 { ULL(0x74ae3b5f,0x1558c800), ULL(0x002f1e28,0xfd1b5cca), 33, 0xabcde},
101 { ULL(0x00000add,0xcafeface), ULL(0x2f1e28fd,0x1b5cca00), 41, 1},
102 { ULL(0x081ac1b9,0xc2310a80), ULL(0x2f1e28fd,0x1b5cca00), 41, 0xbeef},
103 { ULL(0x74ae3b5f,0x1558c800), ULL(0x2f1e28fd,0x1b5cca00), 41, 0xabcde},
104
105 };
106 #define NB_MAGIC_DIVIDE (sizeof(magic_divide)/sizeof(*magic_divide))
107
108
109 static void test_RtlExtendedMagicDivide(void)
110 {
111 int i;
112 LONGLONG result;
113
114 for (i = 0; i < NB_MAGIC_DIVIDE; i++) {
115 result = pRtlExtendedMagicDivide(magic_divide[i].a, magic_divide[i].b, magic_divide[i].shift);
116 ok(result == magic_divide[i].result,
117 "call failed: RtlExtendedMagicDivide(0x%s, 0x%s, %d) has result 0x%s, expected 0x%s\n",
118 wine_dbgstr_longlong(magic_divide[i].a), wine_dbgstr_longlong(magic_divide[i].b), magic_divide[i].shift,
119 wine_dbgstr_longlong(result), wine_dbgstr_longlong(magic_divide[i].result));
120 }
121 }
122
123
124 #define LARGE_STRI_BUFFER_LENGTH 67
125
126 typedef struct {
127 int base;
128 ULONGLONG value;
129 USHORT Length;
130 USHORT MaximumLength;
131 const char *Buffer;
132 NTSTATUS result;
133 } largeint2str_t;
134
135 /*
136 * The native DLL does produce garbage or STATUS_BUFFER_OVERFLOW for
137 * base 2, 8 and 16 when the value is larger than 0xFFFFFFFF.
138 * Therefore these testcases are commented out.
139 */
140
141 static const largeint2str_t largeint2str[] = {
142 {10, 123, 3, 11, "123\0---------------------------------------------------------------", STATUS_SUCCESS},
143
144 { 0, 0x80000000U, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS},
145 { 0, -2147483647, 20, 21, "18446744071562067969\0----------------------------------------------", STATUS_SUCCESS},
146 { 0, -2, 20, 21, "18446744073709551614\0----------------------------------------------", STATUS_SUCCESS},
147 { 0, -1, 20, 21, "18446744073709551615\0----------------------------------------------", STATUS_SUCCESS},
148 { 0, 0, 1, 11, "0\0-----------------------------------------------------------------", STATUS_SUCCESS},
149 { 0, 1, 1, 11, "1\0-----------------------------------------------------------------", STATUS_SUCCESS},
150 { 0, 12, 2, 11, "12\0----------------------------------------------------------------", STATUS_SUCCESS},
151 { 0, 123, 3, 11, "123\0---------------------------------------------------------------", STATUS_SUCCESS},
152 { 0, 1234, 4, 11, "1234\0--------------------------------------------------------------", STATUS_SUCCESS},
153 { 0, 12345, 5, 11, "12345\0-------------------------------------------------------------", STATUS_SUCCESS},
154 { 0, 123456, 6, 11, "123456\0------------------------------------------------------------", STATUS_SUCCESS},
155 { 0, 1234567, 7, 11, "1234567\0-----------------------------------------------------------", STATUS_SUCCESS},
156 { 0, 12345678, 8, 11, "12345678\0----------------------------------------------------------", STATUS_SUCCESS},
157 { 0, 123456789, 9, 11, "123456789\0---------------------------------------------------------", STATUS_SUCCESS},
158 { 0, 2147483646, 10, 11, "2147483646\0--------------------------------------------------------", STATUS_SUCCESS},
159 { 0, 2147483647, 10, 11, "2147483647\0--------------------------------------------------------", STATUS_SUCCESS},
160 { 0, 2147483648U, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS},
161 { 0, 2147483649U, 10, 11, "2147483649\0--------------------------------------------------------", STATUS_SUCCESS},
162 { 0, 4294967294U, 10, 11, "4294967294\0--------------------------------------------------------", STATUS_SUCCESS},
163 { 0, 4294967295U, 10, 11, "4294967295\0--------------------------------------------------------", STATUS_SUCCESS},
164 { 0, ULL(0x2,0xdfdc1c35), 11, 12, "12345678901\0-------------------------------------------------------", STATUS_SUCCESS},
165 { 0, ULL(0xe5,0xf4c8f374), 12, 13, "987654321012\0------------------------------------------------------", STATUS_SUCCESS},
166 { 0, ULL(0x1c0,0xfc161e3e), 13, 14, "1928374656574\0-----------------------------------------------------", STATUS_SUCCESS},
167 { 0, ULL(0xbad,0xcafeface), 14, 15, "12841062955726\0----------------------------------------------------", STATUS_SUCCESS},
168 { 0, ULL(0x5bad,0xcafeface), 15, 16, "100801993177806\0---------------------------------------------------", STATUS_SUCCESS},
169 { 0, ULL(0xaface,0xbeefcafe), 16, 20, "3090515640699646\0--------------------------------------------------", STATUS_SUCCESS},
170 { 0, ULL(0xa5beef,0xabcdcafe), 17, 20, "46653307746110206\0-------------------------------------------------", STATUS_SUCCESS},
171 { 0, ULL(0x1f8cf9b,0xf2df3af1), 18, 20, "142091656963767025\0------------------------------------------------", STATUS_SUCCESS},
172 { 0, ULL(0x0fffffff,0xffffffff), 19, 20, "1152921504606846975\0-----------------------------------------------", STATUS_SUCCESS},
173 { 0, ULL(0xffffffff,0xfffffffe), 20, 21, "18446744073709551614\0----------------------------------------------", STATUS_SUCCESS},
174 { 0, ULL(0xffffffff,0xffffffff), 20, 21, "18446744073709551615\0----------------------------------------------", STATUS_SUCCESS},
175
176 { 2, 0x80000000U, 32, 33, "10000000000000000000000000000000\0----------------------------------", STATUS_SUCCESS},
177 /*
178 * { 2, -2147483647, 64, 65, "1111111111111111111111111111111110000000000000000000000000000001\0--", STATUS_SUCCESS},
179 * { 2, -2, 64, 65, "1111111111111111111111111111111111111111111111111111111111111110\0--", STATUS_SUCCESS},
180 * { 2, -1, 64, 65, "1111111111111111111111111111111111111111111111111111111111111111\0--", STATUS_SUCCESS},
181 */
182 { 2, 0, 1, 33, "0\0-----------------------------------------------------------------", STATUS_SUCCESS},
183 { 2, 1, 1, 33, "1\0-----------------------------------------------------------------", STATUS_SUCCESS},
184 { 2, 10, 4, 33, "1010\0--------------------------------------------------------------", STATUS_SUCCESS},
185 { 2, 100, 7, 33, "1100100\0-----------------------------------------------------------", STATUS_SUCCESS},
186 { 2, 1000, 10, 33, "1111101000\0--------------------------------------------------------", STATUS_SUCCESS},
187 { 2, 10000, 14, 33, "10011100010000\0----------------------------------------------------", STATUS_SUCCESS},
188 { 2, 32767, 15, 33, "111111111111111\0---------------------------------------------------", STATUS_SUCCESS},
189 { 2, 32768, 16, 33, "1000000000000000\0--------------------------------------------------", STATUS_SUCCESS},
190 { 2, 65535, 16, 33, "1111111111111111\0--------------------------------------------------", STATUS_SUCCESS},
191 { 2, 100000, 17, 33, "11000011010100000\0-------------------------------------------------", STATUS_SUCCESS},
192 { 2, 1000000, 20, 33, "11110100001001000000\0----------------------------------------------", STATUS_SUCCESS},
193 { 2, 10000000, 24, 33, "100110001001011010000000\0------------------------------------------", STATUS_SUCCESS},
194 { 2, 100000000, 27, 33, "101111101011110000100000000\0---------------------------------------", STATUS_SUCCESS},
195 { 2, 1000000000, 30, 33, "111011100110101100101000000000\0------------------------------------", STATUS_SUCCESS},
196 { 2, 1073741823, 30, 33, "111111111111111111111111111111\0------------------------------------", STATUS_SUCCESS},
197 { 2, 2147483646, 31, 33, "1111111111111111111111111111110\0-----------------------------------", STATUS_SUCCESS},
198 { 2, 2147483647, 31, 33, "1111111111111111111111111111111\0-----------------------------------", STATUS_SUCCESS},
199 { 2, 2147483648U, 32, 33, "10000000000000000000000000000000\0----------------------------------", STATUS_SUCCESS},
200 { 2, 2147483649U, 32, 33, "10000000000000000000000000000001\0----------------------------------", STATUS_SUCCESS},
201 { 2, 4294967294U, 32, 33, "11111111111111111111111111111110\0----------------------------------", STATUS_SUCCESS},
202 { 2, 0xFFFFFFFF, 32, 33, "11111111111111111111111111111111\0----------------------------------", STATUS_SUCCESS},
203 /*
204 * { 2, 0x1FFFFFFFF, 33, 34, "111111111111111111111111111111111\0---------------------------------", STATUS_SUCCESS},
205 * { 2, 0x3FFFFFFFF, 34, 35, "1111111111111111111111111111111111\0--------------------------------", STATUS_SUCCESS},
206 * { 2, 0x7FFFFFFFF, 35, 36, "11111111111111111111111111111111111\0-------------------------------", STATUS_SUCCESS},
207 * { 2, 0xFFFFFFFFF, 36, 37, "111111111111111111111111111111111111\0------------------------------", STATUS_SUCCESS},
208 * { 2, 0x1FFFFFFFFF, 37, 38, "1111111111111111111111111111111111111\0-----------------------------", STATUS_SUCCESS},
209 * { 2, 0x3FFFFFFFFF, 38, 39, "11111111111111111111111111111111111111\0----------------------------", STATUS_SUCCESS},
210 * { 2, 0x7FFFFFFFFF, 39, 40, "111111111111111111111111111111111111111\0---------------------------", STATUS_SUCCESS},
211 * { 2, 0xFFFFFFFFFF, 40, 41, "1111111111111111111111111111111111111111\0--------------------------", STATUS_SUCCESS},
212 */
213
214 { 8, 0x80000000U, 11, 12, "20000000000\0-------------------------------------------------------", STATUS_SUCCESS},
215 /*
216 * { 8, -2147483647, 22, 23, "1777777777760000000001\0--------------------------------------------", STATUS_SUCCESS},
217 * { 8, -2, 22, 23, "1777777777777777777776\0--------------------------------------------", STATUS_SUCCESS},
218 * { 8, -1, 22, 23, "1777777777777777777777\0--------------------------------------------", STATUS_SUCCESS},
219 */
220 { 8, 0, 1, 12, "0\0-----------------------------------------------------------------", STATUS_SUCCESS},
221 { 8, 1, 1, 12, "1\0-----------------------------------------------------------------", STATUS_SUCCESS},
222 { 8, 2147483646, 11, 12, "17777777776\0-------------------------------------------------------", STATUS_SUCCESS},
223 { 8, 2147483647, 11, 12, "17777777777\0-------------------------------------------------------", STATUS_SUCCESS},
224 { 8, 2147483648U, 11, 12, "20000000000\0-------------------------------------------------------", STATUS_SUCCESS},
225 { 8, 2147483649U, 11, 12, "20000000001\0-------------------------------------------------------", STATUS_SUCCESS},
226 { 8, 4294967294U, 11, 12, "37777777776\0-------------------------------------------------------", STATUS_SUCCESS},
227 { 8, 4294967295U, 11, 12, "37777777777\0-------------------------------------------------------", STATUS_SUCCESS},
228
229 {10, 0x80000000U, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS},
230 {10, -2147483647, 20, 21, "18446744071562067969\0----------------------------------------------", STATUS_SUCCESS},
231 {10, -2, 20, 21, "18446744073709551614\0----------------------------------------------", STATUS_SUCCESS},
232 {10, -1, 20, 21, "18446744073709551615\0----------------------------------------------", STATUS_SUCCESS},
233 {10, 0, 1, 11, "0\0-----------------------------------------------------------------", STATUS_SUCCESS},
234 {10, 1, 1, 11, "1\0-----------------------------------------------------------------", STATUS_SUCCESS},
235 {10, 2147483646, 10, 11, "2147483646\0--------------------------------------------------------", STATUS_SUCCESS},
236 {10, 2147483647, 10, 11, "2147483647\0--------------------------------------------------------", STATUS_SUCCESS},
237 {10, 2147483648U, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS},
238 {10, 2147483649U, 10, 11, "2147483649\0--------------------------------------------------------", STATUS_SUCCESS},
239 {10, 4294967294U, 10, 11, "4294967294\0--------------------------------------------------------", STATUS_SUCCESS},
240 {10, 4294967295U, 10, 11, "4294967295\0--------------------------------------------------------", STATUS_SUCCESS},
241
242 {16, 0, 1, 9, "0\0-----------------------------------------------------------------", STATUS_SUCCESS},
243 {16, 1, 1, 9, "1\0-----------------------------------------------------------------", STATUS_SUCCESS},
244 {16, 2147483646, 8, 9, "7FFFFFFE\0----------------------------------------------------------", STATUS_SUCCESS},
245 {16, 2147483647, 8, 9, "7FFFFFFF\0----------------------------------------------------------", STATUS_SUCCESS},
246 {16, 0x80000000, 8, 9, "80000000\0----------------------------------------------------------", STATUS_SUCCESS},
247 {16, 0x80000001, 8, 9, "80000001\0----------------------------------------------------------", STATUS_SUCCESS},
248 {16, 0xFFFFFFFE, 8, 9, "FFFFFFFE\0----------------------------------------------------------", STATUS_SUCCESS},
249 {16, 0xFFFFFFFF, 8, 9, "FFFFFFFF\0----------------------------------------------------------", STATUS_SUCCESS},
250 /*
251 * {16, 0x100000000, 9, 10, "100000000\0---------------------------------------------------------", STATUS_SUCCESS},
252 * {16, 0xBADDEADBEEF, 11, 12, "BADDEADBEEF\0-------------------------------------------------------", STATUS_SUCCESS},
253 * {16, 0x8000000000000000, 16, 17, "8000000000000000\0--------------------------------------------------", STATUS_SUCCESS},
254 * {16, 0xFEDCBA9876543210, 16, 17, "FEDCBA9876543210\0--------------------------------------------------", STATUS_SUCCESS},
255 * {16, 0xFFFFFFFF80000001, 16, 17, "FFFFFFFF80000001\0--------------------------------------------------", STATUS_SUCCESS},
256 * {16, 0xFFFFFFFFFFFFFFFE, 16, 17, "FFFFFFFFFFFFFFFE\0--------------------------------------------------", STATUS_SUCCESS},
257 * {16, 0xFFFFFFFFFFFFFFFF, 16, 17, "FFFFFFFFFFFFFFFF\0--------------------------------------------------", STATUS_SUCCESS},
258 */
259
260 { 2, 32768, 16, 17, "1000000000000000\0--------------------------------------------------", STATUS_SUCCESS},
261 { 2, 32768, 16, 16, "1000000000000000---------------------------------------------------", STATUS_SUCCESS},
262 { 2, 65536, 17, 18, "10000000000000000\0-------------------------------------------------", STATUS_SUCCESS},
263 { 2, 65536, 17, 17, "10000000000000000--------------------------------------------------", STATUS_SUCCESS},
264 { 2, 131072, 18, 19, "100000000000000000\0------------------------------------------------", STATUS_SUCCESS},
265 { 2, 131072, 18, 18, "100000000000000000-------------------------------------------------", STATUS_SUCCESS},
266 {16, 0xffffffff, 8, 9, "FFFFFFFF\0----------------------------------------------------------", STATUS_SUCCESS},
267 {16, 0xffffffff, 8, 8, "FFFFFFFF-----------------------------------------------------------", STATUS_SUCCESS},
268 {16, 0xffffffff, 8, 7, "-------------------------------------------------------------------", STATUS_BUFFER_OVERFLOW},
269 {16, 0xa, 1, 2, "A\0-----------------------------------------------------------------", STATUS_SUCCESS},
270 {16, 0xa, 1, 1, "A------------------------------------------------------------------", STATUS_SUCCESS},
271 {16, 0, 1, 0, "-------------------------------------------------------------------", STATUS_BUFFER_OVERFLOW},
272 {20, 0xdeadbeef, 0, 9, "-------------------------------------------------------------------", STATUS_INVALID_PARAMETER},
273 {-8, 07654321, 0, 12, "-------------------------------------------------------------------", STATUS_INVALID_PARAMETER},
274 };
275 #define NB_LARGEINT2STR (sizeof(largeint2str)/sizeof(*largeint2str))
276
277
278 static void one_RtlInt64ToUnicodeString_test(int test_num, const largeint2str_t *largeint2str)
279 {
280 int pos;
281 WCHAR expected_str_Buffer[LARGE_STRI_BUFFER_LENGTH + 1];
282 UNICODE_STRING expected_unicode_string;
283 STRING expected_ansi_str;
284 WCHAR str_Buffer[LARGE_STRI_BUFFER_LENGTH + 1];
285 UNICODE_STRING unicode_string;
286 STRING ansi_str;
287 NTSTATUS result;
288
289 #ifdef _WIN64
290 if (largeint2str->value >> 32 == 0xffffffff) /* this crashes on 64-bit Vista */
291 {
292 skip( "Value ffffffff%08x broken on 64-bit windows\n", (DWORD)largeint2str->value );
293 return;
294 }
295 #endif
296
297 for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
298 expected_str_Buffer[pos] = largeint2str->Buffer[pos];
299 } /* for */
300 expected_unicode_string.Length = largeint2str->Length * sizeof(WCHAR);
301 expected_unicode_string.MaximumLength = largeint2str->MaximumLength * sizeof(WCHAR);
302 expected_unicode_string.Buffer = expected_str_Buffer;
303 pRtlUnicodeStringToAnsiString(&expected_ansi_str, &expected_unicode_string, 1);
304
305 for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
306 str_Buffer[pos] = '-';
307 } /* for */
308 unicode_string.Length = 0;
309 unicode_string.MaximumLength = largeint2str->MaximumLength * sizeof(WCHAR);
310 unicode_string.Buffer = str_Buffer;
311
312 if (largeint2str->base == 0) {
313 result = pRtlInt64ToUnicodeString(largeint2str->value, 10, &unicode_string);
314 } else {
315 result = pRtlInt64ToUnicodeString(largeint2str->value, largeint2str->base, &unicode_string);
316 } /* if */
317 pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
318 if (result == STATUS_BUFFER_OVERFLOW) {
319 /* On BUFFER_OVERFLOW the string Buffer should be unchanged */
320 for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
321 expected_str_Buffer[pos] = '-';
322 } /* for */
323 /* w2k: The native function has two reasons for BUFFER_OVERFLOW: */
324 /* If the value is too large to convert: The Length is unchanged */
325 /* If str is too small to hold the string: Set str->Length to the length */
326 /* the string would have (which can be larger than the MaximumLength). */
327 /* To allow all this in the tests we do the following: */
328 if (expected_unicode_string.Length >= 64) {
329 /* The value is too large to convert only triggered when testing native */
330 /* Length is not filled with the expected string length (garbage?) */
331 expected_unicode_string.Length = unicode_string.Length;
332 } /* if */
333 } else {
334 ok(result == largeint2str->result,
335 "(test %d): RtlInt64ToUnicodeString(0x%s, %d, [out]) has result %x, expected: %x\n",
336 test_num, wine_dbgstr_longlong(largeint2str->value), largeint2str->base, result, largeint2str->result);
337 if (result == STATUS_SUCCESS) {
338 ok(unicode_string.Buffer[unicode_string.Length/sizeof(WCHAR)] == '\0',
339 "(test %d): RtlInt64ToUnicodeString(0x%s, %d, [out]) string \"%s\" is not NULL terminated\n",
340 test_num, wine_dbgstr_longlong(largeint2str->value), largeint2str->base, ansi_str.Buffer);
341 } /* if */
342 } /* if */
343 ok(memcmp(unicode_string.Buffer, expected_unicode_string.Buffer, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
344 "(test %d): RtlInt64ToUnicodeString(0x%x%08x, %d, [out]) assigns string \"%s\", expected: \"%s\"\n",
345 test_num, (DWORD)(largeint2str->value >>32), (DWORD)largeint2str->value, largeint2str->base,
346 ansi_str.Buffer, expected_ansi_str.Buffer);
347 ok(unicode_string.Length == expected_unicode_string.Length,
348 "(test %d): RtlInt64ToUnicodeString(0x%s, %d, [out]) string has Length %d, expected: %d\n",
349 test_num, wine_dbgstr_longlong(largeint2str->value), largeint2str->base,
350 unicode_string.Length, expected_unicode_string.Length);
351 ok(unicode_string.MaximumLength == expected_unicode_string.MaximumLength,
352 "(test %d): RtlInt64ToUnicodeString(0x%s, %d, [out]) string has MaximumLength %d, expected: %d\n",
353 test_num, wine_dbgstr_longlong(largeint2str->value), largeint2str->base,
354 unicode_string.MaximumLength, expected_unicode_string.MaximumLength);
355 pRtlFreeAnsiString(&expected_ansi_str);
356 pRtlFreeAnsiString(&ansi_str);
357 }
358
359
360 static void test_RtlInt64ToUnicodeString(void)
361 {
362 int test_num;
363
364 for (test_num = 0; test_num < NB_LARGEINT2STR; test_num++) {
365 one_RtlInt64ToUnicodeString_test(test_num, &largeint2str[test_num]);
366 } /* for */
367 }
368
369
370 static void one_RtlLargeIntegerToChar_test(int test_num, const largeint2str_t *largeint2str)
371 {
372 NTSTATUS result;
373 char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
374 ULONGLONG value;
375
376 #ifdef _WIN64
377 if (largeint2str->value >> 32 == 0xffffffff) /* this crashes on 64-bit Vista */
378 {
379 skip( "Value ffffffff%08x broken on 64-bit windows\n", (DWORD)largeint2str->value );
380 return;
381 }
382 #endif
383
384 memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
385 dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
386 value = largeint2str->value;
387 if (largeint2str->base == 0) {
388 result = pRtlLargeIntegerToChar(&value, 10, largeint2str->MaximumLength, dest_str);
389 } else {
390 result = pRtlLargeIntegerToChar(&value, largeint2str->base, largeint2str->MaximumLength, dest_str);
391 } /* if */
392 ok(result == largeint2str->result,
393 "(test %d): RtlLargeIntegerToChar(0x%s, %d, %d, [out]) has result %x, expected: %x\n",
394 test_num, wine_dbgstr_longlong(largeint2str->value), largeint2str->base,
395 largeint2str->MaximumLength, result, largeint2str->result);
396 ok(memcmp(dest_str, largeint2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
397 "(test %d): RtlLargeIntegerToChar(0x%s, %d, %d, [out]) assigns string \"%s\", expected: \"%s\"\n",
398 test_num, wine_dbgstr_longlong(largeint2str->value), largeint2str->base,
399 largeint2str->MaximumLength, dest_str, largeint2str->Buffer);
400 }
401
402
403 static void test_RtlLargeIntegerToChar(void)
404 {
405 NTSTATUS result;
406 int test_num;
407 ULONGLONG value;
408
409 for (test_num = 0; test_num < NB_LARGEINT2STR; test_num++) {
410 one_RtlLargeIntegerToChar_test(test_num, &largeint2str[test_num]);
411 } /* for */
412
413 value = largeint2str[0].value;
414 result = pRtlLargeIntegerToChar(&value, 20, largeint2str[0].MaximumLength, NULL);
415 ok(result == STATUS_INVALID_PARAMETER,
416 "(test a): RtlLargeIntegerToChar(0x%s, %d, %d, NULL) has result %x, expected: %x\n",
417 wine_dbgstr_longlong(largeint2str[0].value), 20,
418 largeint2str[0].MaximumLength, result, STATUS_INVALID_PARAMETER);
419
420 result = pRtlLargeIntegerToChar(&value, 20, 0, NULL);
421 ok(result == STATUS_INVALID_PARAMETER,
422 "(test b): RtlLargeIntegerToChar(0x%s, %d, %d, NULL) has result %x, expected: %x\n",
423 wine_dbgstr_longlong(largeint2str[0].value), 20,
424 largeint2str[0].MaximumLength, result, STATUS_INVALID_PARAMETER);
425
426 result = pRtlLargeIntegerToChar(&value, largeint2str[0].base, 0, NULL);
427 ok(result == STATUS_BUFFER_OVERFLOW,
428 "(test c): RtlLargeIntegerToChar(0x%s, %d, %d, NULL) has result %x, expected: %x\n",
429 wine_dbgstr_longlong(largeint2str[0].value), largeint2str[0].base, 0, result, STATUS_BUFFER_OVERFLOW);
430
431 result = pRtlLargeIntegerToChar(&value, largeint2str[0].base, largeint2str[0].MaximumLength, NULL);
432 ok(result == STATUS_ACCESS_VIOLATION,
433 "(test d): RtlLargeIntegerToChar(0x%s, %d, %d, NULL) has result %x, expected: %x\n",
434 wine_dbgstr_longlong(largeint2str[0].value),
435 largeint2str[0].base, largeint2str[0].MaximumLength, result, STATUS_ACCESS_VIOLATION);
436 }
437
438
439 #ifdef __i386__
440
441 #include "pshpack1.h"
442 struct lldvrm_thunk
443 {
444 BYTE push_ebx; /* pushl %ebx */
445 DWORD push_esp1; /* pushl 24(%esp) */
446 DWORD push_esp2; /* pushl 24(%esp) */
447 DWORD push_esp3; /* pushl 24(%esp) */
448 DWORD push_esp4; /* pushl 24(%esp) */
449 DWORD call; /* call 24(%esp) */
450 WORD mov_ecx_eax; /* movl %ecx,%eax */
451 WORD mov_ebx_edx; /* movl %ebx,%edx */
452 BYTE pop_ebx; /* popl %ebx */
453 BYTE ret; /* ret */
454 };
455 #include "poppack.h"
456
457 static void test__alldvrm(void)
458 {
459 struct lldvrm_thunk *thunk = VirtualAlloc(NULL, sizeof(*thunk), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
460 ULONGLONG (CDECL *call_lldvrm_func)(void *func, ULONGLONG, ULONGLONG) = (void *)thunk;
461 ULONGLONG ret;
462
463 memset(thunk, 0x90, sizeof(*thunk));
464 thunk->push_ebx = 0x53; /* pushl %ebx */
465 thunk->push_esp1 = 0x182474ff; /* pushl 24(%esp) */
466 thunk->push_esp2 = 0x182474ff; /* pushl 24(%esp) */
467 thunk->push_esp3 = 0x182474ff; /* pushl 24(%esp) */
468 thunk->push_esp4 = 0x182474ff; /* pushl 24(%esp) */
469 thunk->call = 0x182454ff; /* call 24(%esp) */
470 thunk->pop_ebx = 0x5b; /* popl %ebx */
471 thunk->ret = 0xc3; /* ret */
472
473 ret = call_lldvrm_func(p_alldvrm, 0x0123456701234567ULL, 3);
474 ok(ret == 0x61172255b66c77ULL, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
475 ret = call_lldvrm_func(p_alldvrm, 0x0123456701234567ULL, -3);
476 ok(ret == 0xff9ee8ddaa499389ULL, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
477
478 ret = call_lldvrm_func(p_aulldvrm, 0x0123456701234567ULL, 3);
479 ok(ret == 0x61172255b66c77ULL, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
480 ret = call_lldvrm_func(p_aulldvrm, 0x0123456701234567ULL, -3);
481 ok(ret == 0, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
482
483 thunk->mov_ecx_eax = 0xc889;
484 thunk->mov_ebx_edx = 0xda89;
485
486 ret = call_lldvrm_func(p_alldvrm, 0x0123456701234567ULL, 3);
487 ok(ret == 2, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
488 ret = call_lldvrm_func(p_alldvrm, 0x0123456701234567ULL, -3);
489 ok(ret == 2, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
490
491 ret = call_lldvrm_func(p_aulldvrm, 0x0123456701234567ULL, 3);
492 ok(ret == 2, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
493 ret = call_lldvrm_func(p_aulldvrm, 0x0123456701234567ULL, -3);
494 ok(ret == 0x123456701234567ULL, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
495 }
496 #endif /* __i386__ */
497
498
499 START_TEST(large_int)
500 {
501 InitFunctionPtrs();
502
503 if (pRtlExtendedMagicDivide)
504 test_RtlExtendedMagicDivide();
505 if (pRtlInt64ToUnicodeString)
506 test_RtlInt64ToUnicodeString();
507 if (pRtlLargeIntegerToChar)
508 test_RtlLargeIntegerToChar();
509
510 #ifdef __i386__
511 test__alldvrm();
512 #endif /* __i386__ */
513 }