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