Generate stub entries on the fly for missing entry points instead of
[wine] / dlls / ntdll / tests / 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 <stdlib.h>
25
26 #include "ntdll_test.h"
27
28 #include "winnls.h"
29
30 /* Function ptrs for ntdll calls */
31 static HMODULE hntdll = 0;
32 static LONGLONG (WINAPI *pRtlExtendedMagicDivide)(LONGLONG, LONGLONG, INT);
33 static VOID     (WINAPI *pRtlFreeAnsiString)(PSTRING);
34 static NTSTATUS (WINAPI *pRtlInt64ToUnicodeString)(ULONGLONG, ULONG, UNICODE_STRING *);
35 static NTSTATUS (WINAPI *pRtlLargeIntegerToChar)(ULONGLONG *, ULONG, ULONG, PCHAR);
36 static NTSTATUS (WINAPI *pRtlUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN);
37
38
39 static void InitFunctionPtrs()
40 {
41     hntdll = LoadLibraryA("ntdll.dll");
42     ok(hntdll != 0, "LoadLibrary failed\n");
43     if (hntdll) {
44         pRtlExtendedMagicDivide = (void *)GetProcAddress(hntdll, "RtlExtendedMagicDivide");
45         pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString");
46         pRtlInt64ToUnicodeString = (void *)GetProcAddress(hntdll, "RtlInt64ToUnicodeString");
47         pRtlLargeIntegerToChar = (void *)GetProcAddress(hntdll, "RtlLargeIntegerToChar");
48         pRtlUnicodeStringToAnsiString = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToAnsiString");
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(%lld, %llu, %d) has result %llx, expected %llx\n",
118            magic_divide[i].a, magic_divide[i].b, magic_divide[i].shift, result, magic_divide[i].result);
119     }
120 }
121
122
123 #define LARGE_STRI_BUFFER_LENGTH 67
124
125 typedef struct {
126     int base;
127     ULONGLONG value;
128     USHORT Length;
129     USHORT MaximumLength;
130     const char *Buffer;
131     NTSTATUS result;
132 } largeint2str_t;
133
134 /*
135  * The native DLL does produce garbage or STATUS_BUFFER_OVERFLOW for
136  * base 2, 8 and 16 when the value is larger than 0xFFFFFFFF.
137  * Therefore these testcases are commented out.
138  */
139
140 static const largeint2str_t largeint2str[] = {
141     {10,          123,  3, 11, "123\0---------------------------------------------------------------", STATUS_SUCCESS},
142
143     { 0,  0x80000000U, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS},
144     { 0,  -2147483647, 20, 21, "18446744071562067969\0----------------------------------------------", STATUS_SUCCESS},
145     { 0,           -2, 20, 21, "18446744073709551614\0----------------------------------------------", STATUS_SUCCESS},
146     { 0,           -1, 20, 21, "18446744073709551615\0----------------------------------------------", STATUS_SUCCESS},
147     { 0,            0,  1, 11, "0\0-----------------------------------------------------------------", STATUS_SUCCESS},
148     { 0,            1,  1, 11, "1\0-----------------------------------------------------------------", STATUS_SUCCESS},
149     { 0,           12,  2, 11, "12\0----------------------------------------------------------------", STATUS_SUCCESS},
150     { 0,          123,  3, 11, "123\0---------------------------------------------------------------", STATUS_SUCCESS},
151     { 0,         1234,  4, 11, "1234\0--------------------------------------------------------------", STATUS_SUCCESS},
152     { 0,        12345,  5, 11, "12345\0-------------------------------------------------------------", STATUS_SUCCESS},
153     { 0,       123456,  6, 11, "123456\0------------------------------------------------------------", STATUS_SUCCESS},
154     { 0,      1234567,  7, 11, "1234567\0-----------------------------------------------------------", STATUS_SUCCESS},
155     { 0,     12345678,  8, 11, "12345678\0----------------------------------------------------------", STATUS_SUCCESS},
156     { 0,    123456789,  9, 11, "123456789\0---------------------------------------------------------", STATUS_SUCCESS},
157     { 0,   2147483646, 10, 11, "2147483646\0--------------------------------------------------------", STATUS_SUCCESS},
158     { 0,   2147483647, 10, 11, "2147483647\0--------------------------------------------------------", STATUS_SUCCESS},
159     { 0,  2147483648U, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS},
160     { 0,  2147483649U, 10, 11, "2147483649\0--------------------------------------------------------", STATUS_SUCCESS},
161     { 0,  4294967294U, 10, 11, "4294967294\0--------------------------------------------------------", STATUS_SUCCESS},
162     { 0,  4294967295U, 10, 11, "4294967295\0--------------------------------------------------------", STATUS_SUCCESS},
163     { 0,  ULL(0x2,0xdfdc1c35), 11, 12, "12345678901\0-------------------------------------------------------", STATUS_SUCCESS},
164     { 0,  ULL(0xe5,0xf4c8f374), 12, 13, "987654321012\0------------------------------------------------------", STATUS_SUCCESS},
165     { 0,  ULL(0x1c0,0xfc161e3e), 13, 14, "1928374656574\0-----------------------------------------------------", STATUS_SUCCESS},
166     { 0, ULL(0xbad,0xcafeface), 14, 15, "12841062955726\0----------------------------------------------------", STATUS_SUCCESS},
167     { 0, ULL(0x5bad,0xcafeface), 15, 16, "100801993177806\0---------------------------------------------------", STATUS_SUCCESS},
168     { 0, ULL(0xaface,0xbeefcafe), 16, 20, "3090515640699646\0--------------------------------------------------", STATUS_SUCCESS},
169     { 0, ULL(0xa5beef,0xabcdcafe), 17, 20, "46653307746110206\0-------------------------------------------------", STATUS_SUCCESS},
170     { 0, ULL(0x1f8cf9b,0xf2df3af1), 18, 20, "142091656963767025\0------------------------------------------------", STATUS_SUCCESS},
171     { 0, ULL(0x0fffffff,0xffffffff), 19, 20, "1152921504606846975\0-----------------------------------------------", STATUS_SUCCESS},
172     { 0, ULL(0xffffffff,0xfffffffe), 20, 21, "18446744073709551614\0----------------------------------------------", STATUS_SUCCESS},
173     { 0, ULL(0xffffffff,0xffffffff), 20, 21, "18446744073709551615\0----------------------------------------------", STATUS_SUCCESS},
174
175     { 2,  0x80000000U, 32, 33, "10000000000000000000000000000000\0----------------------------------", STATUS_SUCCESS},
176 /*
177  *  { 2,  -2147483647, 64, 65, "1111111111111111111111111111111110000000000000000000000000000001\0--", STATUS_SUCCESS},
178  *  { 2,           -2, 64, 65, "1111111111111111111111111111111111111111111111111111111111111110\0--", STATUS_SUCCESS},
179  *  { 2,           -1, 64, 65, "1111111111111111111111111111111111111111111111111111111111111111\0--", STATUS_SUCCESS},
180  */
181     { 2,            0,  1, 33, "0\0-----------------------------------------------------------------", STATUS_SUCCESS},
182     { 2,            1,  1, 33, "1\0-----------------------------------------------------------------", STATUS_SUCCESS},
183     { 2,           10,  4, 33, "1010\0--------------------------------------------------------------", STATUS_SUCCESS},
184     { 2,          100,  7, 33, "1100100\0-----------------------------------------------------------", STATUS_SUCCESS},
185     { 2,         1000, 10, 33, "1111101000\0--------------------------------------------------------", STATUS_SUCCESS},
186     { 2,        10000, 14, 33, "10011100010000\0----------------------------------------------------", STATUS_SUCCESS},
187     { 2,        32767, 15, 33, "111111111111111\0---------------------------------------------------", STATUS_SUCCESS},
188     { 2,        32768, 16, 33, "1000000000000000\0--------------------------------------------------", STATUS_SUCCESS},
189     { 2,        65535, 16, 33, "1111111111111111\0--------------------------------------------------", STATUS_SUCCESS},
190     { 2,       100000, 17, 33, "11000011010100000\0-------------------------------------------------", STATUS_SUCCESS},
191     { 2,      1000000, 20, 33, "11110100001001000000\0----------------------------------------------", STATUS_SUCCESS},
192     { 2,     10000000, 24, 33, "100110001001011010000000\0------------------------------------------", STATUS_SUCCESS},
193     { 2,    100000000, 27, 33, "101111101011110000100000000\0---------------------------------------", STATUS_SUCCESS},
194     { 2,   1000000000, 30, 33, "111011100110101100101000000000\0------------------------------------", STATUS_SUCCESS},
195     { 2,   1073741823, 30, 33, "111111111111111111111111111111\0------------------------------------", STATUS_SUCCESS},
196     { 2,   2147483646, 31, 33, "1111111111111111111111111111110\0-----------------------------------", STATUS_SUCCESS},
197     { 2,   2147483647, 31, 33, "1111111111111111111111111111111\0-----------------------------------", STATUS_SUCCESS},
198     { 2,  2147483648U, 32, 33, "10000000000000000000000000000000\0----------------------------------", STATUS_SUCCESS},
199     { 2,  2147483649U, 32, 33, "10000000000000000000000000000001\0----------------------------------", STATUS_SUCCESS},
200     { 2,  4294967294U, 32, 33, "11111111111111111111111111111110\0----------------------------------", STATUS_SUCCESS},
201     { 2,   0xFFFFFFFF, 32, 33, "11111111111111111111111111111111\0----------------------------------", STATUS_SUCCESS},
202 /*
203  *  { 2,  0x1FFFFFFFF, 33, 34, "111111111111111111111111111111111\0---------------------------------", STATUS_SUCCESS},
204  *  { 2,  0x3FFFFFFFF, 34, 35, "1111111111111111111111111111111111\0--------------------------------", STATUS_SUCCESS},
205  *  { 2,  0x7FFFFFFFF, 35, 36, "11111111111111111111111111111111111\0-------------------------------", STATUS_SUCCESS},
206  *  { 2,  0xFFFFFFFFF, 36, 37, "111111111111111111111111111111111111\0------------------------------", STATUS_SUCCESS},
207  *  { 2, 0x1FFFFFFFFF, 37, 38, "1111111111111111111111111111111111111\0-----------------------------", STATUS_SUCCESS},
208  *  { 2, 0x3FFFFFFFFF, 38, 39, "11111111111111111111111111111111111111\0----------------------------", STATUS_SUCCESS},
209  *  { 2, 0x7FFFFFFFFF, 39, 40, "111111111111111111111111111111111111111\0---------------------------", STATUS_SUCCESS},
210  *  { 2, 0xFFFFFFFFFF, 40, 41, "1111111111111111111111111111111111111111\0--------------------------", STATUS_SUCCESS},
211  */
212
213     { 8,  0x80000000U, 11, 12, "20000000000\0-------------------------------------------------------", STATUS_SUCCESS},
214 /*
215  *  { 8,  -2147483647, 22, 23, "1777777777760000000001\0--------------------------------------------", STATUS_SUCCESS},
216  *  { 8,           -2, 22, 23, "1777777777777777777776\0--------------------------------------------", STATUS_SUCCESS},
217  *  { 8,           -1, 22, 23, "1777777777777777777777\0--------------------------------------------", STATUS_SUCCESS},
218  */
219     { 8,            0,  1, 12, "0\0-----------------------------------------------------------------", STATUS_SUCCESS},
220     { 8,            1,  1, 12, "1\0-----------------------------------------------------------------", STATUS_SUCCESS},
221     { 8,   2147483646, 11, 12, "17777777776\0-------------------------------------------------------", STATUS_SUCCESS},
222     { 8,   2147483647, 11, 12, "17777777777\0-------------------------------------------------------", STATUS_SUCCESS},
223     { 8,  2147483648U, 11, 12, "20000000000\0-------------------------------------------------------", STATUS_SUCCESS},
224     { 8,  2147483649U, 11, 12, "20000000001\0-------------------------------------------------------", STATUS_SUCCESS},
225     { 8,  4294967294U, 11, 12, "37777777776\0-------------------------------------------------------", STATUS_SUCCESS},
226     { 8,  4294967295U, 11, 12, "37777777777\0-------------------------------------------------------", STATUS_SUCCESS},
227
228     {10,  0x80000000U, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS},
229     {10,  -2147483647, 20, 21, "18446744071562067969\0----------------------------------------------", STATUS_SUCCESS},
230     {10,           -2, 20, 21, "18446744073709551614\0----------------------------------------------", STATUS_SUCCESS},
231     {10,           -1, 20, 21, "18446744073709551615\0----------------------------------------------", STATUS_SUCCESS},
232     {10,            0,  1, 11, "0\0-----------------------------------------------------------------", STATUS_SUCCESS},
233     {10,            1,  1, 11, "1\0-----------------------------------------------------------------", STATUS_SUCCESS},
234     {10,   2147483646, 10, 11, "2147483646\0--------------------------------------------------------", STATUS_SUCCESS},
235     {10,   2147483647, 10, 11, "2147483647\0--------------------------------------------------------", STATUS_SUCCESS},
236     {10,  2147483648U, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS},
237     {10,  2147483649U, 10, 11, "2147483649\0--------------------------------------------------------", STATUS_SUCCESS},
238     {10,  4294967294U, 10, 11, "4294967294\0--------------------------------------------------------", STATUS_SUCCESS},
239     {10,  4294967295U, 10, 11, "4294967295\0--------------------------------------------------------", STATUS_SUCCESS},
240
241     {16,                  0,  1,  9, "0\0-----------------------------------------------------------------", STATUS_SUCCESS},
242     {16,                  1,  1,  9, "1\0-----------------------------------------------------------------", STATUS_SUCCESS},
243     {16,         2147483646,  8,  9, "7FFFFFFE\0----------------------------------------------------------", STATUS_SUCCESS},
244     {16,         2147483647,  8,  9, "7FFFFFFF\0----------------------------------------------------------", STATUS_SUCCESS},
245     {16,         0x80000000,  8,  9, "80000000\0----------------------------------------------------------", STATUS_SUCCESS},
246     {16,         0x80000001,  8,  9, "80000001\0----------------------------------------------------------", STATUS_SUCCESS},
247     {16,         0xFFFFFFFE,  8,  9, "FFFFFFFE\0----------------------------------------------------------", STATUS_SUCCESS},
248     {16,         0xFFFFFFFF,  8,  9, "FFFFFFFF\0----------------------------------------------------------", STATUS_SUCCESS},
249 /*
250  *  {16,        0x100000000,  9, 10, "100000000\0---------------------------------------------------------", STATUS_SUCCESS},
251  *  {16,      0xBADDEADBEEF, 11, 12, "BADDEADBEEF\0-------------------------------------------------------", STATUS_SUCCESS},
252  *  {16, 0x8000000000000000, 16, 17, "8000000000000000\0--------------------------------------------------", STATUS_SUCCESS},
253  *  {16, 0xFEDCBA9876543210, 16, 17, "FEDCBA9876543210\0--------------------------------------------------", STATUS_SUCCESS},
254  *  {16, 0xFFFFFFFF80000001, 16, 17, "FFFFFFFF80000001\0--------------------------------------------------", STATUS_SUCCESS},
255  *  {16, 0xFFFFFFFFFFFFFFFE, 16, 17, "FFFFFFFFFFFFFFFE\0--------------------------------------------------", STATUS_SUCCESS},
256  *  {16, 0xFFFFFFFFFFFFFFFF, 16, 17, "FFFFFFFFFFFFFFFF\0--------------------------------------------------", STATUS_SUCCESS},
257  */
258
259     { 2,        32768, 16, 17, "1000000000000000\0--------------------------------------------------", STATUS_SUCCESS},
260     { 2,        32768, 16, 16, "1000000000000000---------------------------------------------------",  STATUS_SUCCESS},
261     { 2,        65536, 17, 18, "10000000000000000\0-------------------------------------------------", STATUS_SUCCESS},
262     { 2,        65536, 17, 17, "10000000000000000--------------------------------------------------",  STATUS_SUCCESS},
263     { 2,       131072, 18, 19, "100000000000000000\0------------------------------------------------", STATUS_SUCCESS},
264     { 2,       131072, 18, 18, "100000000000000000-------------------------------------------------",  STATUS_SUCCESS},
265     {16,   0xffffffff,  8,  9, "FFFFFFFF\0----------------------------------------------------------", STATUS_SUCCESS},
266     {16,   0xffffffff,  8,  8, "FFFFFFFF-----------------------------------------------------------",  STATUS_SUCCESS},
267     {16,   0xffffffff,  8,  7, "-------------------------------------------------------------------",  STATUS_BUFFER_OVERFLOW},
268     {16,          0xa,  1,  2, "A\0-----------------------------------------------------------------", STATUS_SUCCESS},
269     {16,          0xa,  1,  1, "A------------------------------------------------------------------",  STATUS_SUCCESS},
270     {16,            0,  1,  0, "-------------------------------------------------------------------",  STATUS_BUFFER_OVERFLOW},
271     {20,   0xdeadbeef,  0,  9, "-------------------------------------------------------------------",  STATUS_INVALID_PARAMETER},
272     {-8,     07654321,  0, 12, "-------------------------------------------------------------------",  STATUS_INVALID_PARAMETER},
273 };
274 #define NB_LARGEINT2STR (sizeof(largeint2str)/sizeof(*largeint2str))
275
276
277 static void one_RtlInt64ToUnicodeString_test(int test_num, const largeint2str_t *largeint2str)
278 {
279     int pos;
280     WCHAR expected_str_Buffer[LARGE_STRI_BUFFER_LENGTH + 1];
281     UNICODE_STRING expected_unicode_string;
282     STRING expected_ansi_str;
283     WCHAR str_Buffer[LARGE_STRI_BUFFER_LENGTH + 1];
284     UNICODE_STRING unicode_string;
285     STRING ansi_str;
286     NTSTATUS result;
287
288     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
289         expected_str_Buffer[pos] = largeint2str->Buffer[pos];
290     } /* for */
291     expected_unicode_string.Length = largeint2str->Length * sizeof(WCHAR);
292     expected_unicode_string.MaximumLength = largeint2str->MaximumLength * sizeof(WCHAR);
293     expected_unicode_string.Buffer = expected_str_Buffer;
294     pRtlUnicodeStringToAnsiString(&expected_ansi_str, &expected_unicode_string, 1);
295
296     for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
297         str_Buffer[pos] = '-';
298     } /* for */
299     unicode_string.Length = 0;
300     unicode_string.MaximumLength = largeint2str->MaximumLength * sizeof(WCHAR);
301     unicode_string.Buffer = str_Buffer;
302
303     if (largeint2str->base == 0) {
304         result = pRtlInt64ToUnicodeString(largeint2str->value, 10, &unicode_string);
305     } else {
306         result = pRtlInt64ToUnicodeString(largeint2str->value, largeint2str->base, &unicode_string);
307     } /* if */
308     pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1);
309     if (result == STATUS_BUFFER_OVERFLOW) {
310         /* On BUFFER_OVERFLOW the string Buffer should be unchanged */
311         for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) {
312             expected_str_Buffer[pos] = '-';
313         } /* for */
314         /* w2k: The native function has two reasons for BUFFER_OVERFLOW: */
315         /* If the value is too large to convert: The Length is unchanged */
316         /* If str is too small to hold the string: Set str->Length to the length */
317         /* the string would have (which can be larger than the MaximumLength). */
318         /* To allow all this in the tests we do the following: */
319         if (expected_unicode_string.Length >= 64) {
320             /* The value is too large to convert only triggerd when testing native */
321             /* Length is not filled with the expected string length (garbage?) */
322             expected_unicode_string.Length = unicode_string.Length;
323         } /* if */
324     } else {
325         ok(result == largeint2str->result,
326            "(test %d): RtlInt64ToUnicodeString(%llu, %d, [out]) has result %lx, expected: %lx\n",
327            test_num, largeint2str->value, largeint2str->base, result, largeint2str->result);
328         if (result == STATUS_SUCCESS) {
329             ok(unicode_string.Buffer[unicode_string.Length/sizeof(WCHAR)] == '\0',
330                "(test %d): RtlInt64ToUnicodeString(%llu, %d, [out]) string \"%s\" is not NULL terminated\n",
331                test_num, largeint2str->value, largeint2str->base, ansi_str.Buffer);
332         } /* if */
333     } /* if */
334     ok(memcmp(unicode_string.Buffer, expected_unicode_string.Buffer, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
335        "(test %d): RtlInt64ToUnicodeString(%llu, %d, [out]) assigns string \"%s\", expected: \"%s\"\n",
336        test_num, largeint2str->value, largeint2str->base, ansi_str.Buffer, expected_ansi_str.Buffer);
337     ok(unicode_string.Length == expected_unicode_string.Length,
338        "(test %d): RtlInt64ToUnicodeString(%llu, %d, [out]) string has Length %d, expected: %d\n",
339        test_num, largeint2str->value, largeint2str->base, unicode_string.Length, expected_unicode_string.Length);
340     ok(unicode_string.MaximumLength == expected_unicode_string.MaximumLength,
341        "(test %d): RtlInt64ToUnicodeString(%llu, %d, [out]) string has MaximumLength %d, expected: %d\n",
342        test_num, largeint2str->value, largeint2str->base, unicode_string.MaximumLength, expected_unicode_string.MaximumLength);
343     pRtlFreeAnsiString(&expected_ansi_str);
344     pRtlFreeAnsiString(&ansi_str);
345 }
346
347
348 static void test_RtlInt64ToUnicodeString(void)
349 {
350     int test_num;
351
352     for (test_num = 0; test_num < NB_LARGEINT2STR; test_num++) {
353         one_RtlInt64ToUnicodeString_test(test_num, &largeint2str[test_num]);
354     } /* for */
355 }
356
357
358 static void one_RtlLargeIntegerToChar_test(int test_num, const largeint2str_t *largeint2str)
359 {
360     NTSTATUS result;
361     char dest_str[LARGE_STRI_BUFFER_LENGTH + 1];
362     ULONGLONG value;
363
364     memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH);
365     dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0';
366     value = largeint2str->value;
367     if (largeint2str->base == 0) {
368         result = pRtlLargeIntegerToChar(&value, 10, largeint2str->MaximumLength, dest_str);
369     } else {
370         result = pRtlLargeIntegerToChar(&value, largeint2str->base, largeint2str->MaximumLength, dest_str);
371     } /* if */
372     ok(result == largeint2str->result,
373        "(test %d): RtlLargeIntegerToChar(%llu, %d, %d, [out]) has result %lx, expected: %lx\n",
374        test_num, largeint2str->value, largeint2str->base, largeint2str->MaximumLength, result, largeint2str->result);
375     ok(memcmp(dest_str, largeint2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
376        "(test %d): RtlLargeIntegerToChar(%llu, %d, %d, [out]) assigns string \"%s\", expected: \"%s\"\n",
377        test_num, largeint2str->value, largeint2str->base, largeint2str->MaximumLength, dest_str, largeint2str->Buffer);
378 }
379
380
381 static void test_RtlLargeIntegerToChar(void)
382 {
383     NTSTATUS result;
384     int test_num;
385     ULONGLONG value;
386
387     for (test_num = 0; test_num < NB_LARGEINT2STR; test_num++) {
388         one_RtlLargeIntegerToChar_test(test_num, &largeint2str[test_num]);
389     } /* for */
390
391     value = largeint2str[0].value;
392     result = pRtlLargeIntegerToChar(&value, 20, largeint2str[0].MaximumLength, NULL);
393     ok(result == STATUS_INVALID_PARAMETER,
394        "(test a): RtlLargeIntegerToChar(%llu, %d, %d, NULL) has result %lx, expected: %x\n",
395        largeint2str[0].value, 20, largeint2str[0].MaximumLength, result, STATUS_INVALID_PARAMETER);
396
397     result = pRtlLargeIntegerToChar(&value, 20, 0, NULL);
398     ok(result == STATUS_INVALID_PARAMETER,
399        "(test b): RtlLargeIntegerToChar(%llu, %d, %d, NULL) has result %lx, expected: %x\n",
400        largeint2str[0].value, 20, largeint2str[0].MaximumLength, result, STATUS_INVALID_PARAMETER);
401
402     result = pRtlLargeIntegerToChar(&value, largeint2str[0].base, 0, NULL);
403     ok(result == STATUS_BUFFER_OVERFLOW,
404        "(test c): RtlLargeIntegerToChar(%llu, %d, %d, NULL) has result %lx, expected: %x\n",
405        largeint2str[0].value, largeint2str[0].base, 0, result, STATUS_BUFFER_OVERFLOW);
406
407     result = pRtlLargeIntegerToChar(&value, largeint2str[0].base, largeint2str[0].MaximumLength, NULL);
408     ok(result == STATUS_ACCESS_VIOLATION,
409        "(test d): RtlLargeIntegerToChar(%llu, %d, %d, NULL) has result %lx, expected: %x\n",
410        largeint2str[0].value, largeint2str[0].base, largeint2str[0].MaximumLength, result, STATUS_ACCESS_VIOLATION);
411 }
412
413
414 START_TEST(large_int)
415 {
416     InitFunctionPtrs();
417
418     if (pRtlExtendedMagicDivide)
419         test_RtlExtendedMagicDivide();
420     if (pRtlInt64ToUnicodeString)
421             test_RtlInt64ToUnicodeString();
422     if (pRtlLargeIntegerToChar)
423         test_RtlLargeIntegerToChar();
424 }