ReactOS 0.4.17-dev-51-g1dc2e6d
rtl.c
Go to the documentation of this file.
1/* Unit test suite for Rtl* API 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#include <stdarg.h>
26
27#include "ntstatus.h"
28#define WIN32_NO_STATUS
29#include "windef.h"
30#include "winbase.h"
31#include "winreg.h"
32#include "winternl.h"
33#include "in6addr.h"
34#include "inaddr.h"
35#include "ip2string.h"
36#ifndef __REACTOS__
37#include "ddk/ntifs.h"
38#else
39#define FASTCALL __fastcall
46 _In_ ULONG Pattern
47);
48#endif
49#include "wine/test.h"
50#include "wine/asm.h"
51#include "wine/rbtree.h"
52
53#ifndef __WINE_WINTERNL_H
54
55typedef struct _RTL_HANDLE
56{
57 struct _RTL_HANDLE * Next;
59
60typedef struct _RTL_HANDLE_TABLE
61{
70
71#endif
72
73static BOOL is_win64 = (sizeof(void *) > sizeof(int));
74
75/* avoid #include <winsock2.h> */
76#undef htons
77#ifdef WORDS_BIGENDIAN
78#define htons(s) ((USHORT)(s))
79#else /* WORDS_BIGENDIAN */
81{
82 return (s >> 8) | (s << 8);
83}
84#define htons(s) __my_ushort_swap(s)
85#endif /* WORDS_BIGENDIAN */
86
87
88#ifdef __ASM_USE_FASTCALL_WRAPPER
89extern ULONG WINAPI wrap_fastcall_func1( void *func, ULONG a );
90__ASM_STDCALL_FUNC( wrap_fastcall_func1, 8,
91 "popl %ecx\n\t"
92 "popl %eax\n\t"
93 "xchgl (%esp),%ecx\n\t"
94 "jmp *%eax" )
95#define call_fastcall_func1(func,a) wrap_fastcall_func1(func,a)
96#else
97#define call_fastcall_func1(func,a) func(a)
98#endif
99
100
101/* Function ptrs for ntdll calls */
102static HMODULE hntdll = 0;
103static VOID (WINAPI *pRtlMoveMemory)(LPVOID,LPCVOID,SIZE_T);
104static VOID (WINAPI *pRtlFillMemory)(LPVOID,SIZE_T,BYTE);
105static VOID (WINAPI *pRtlFillMemoryUlong)(LPVOID,SIZE_T,ULONG);
106static VOID (WINAPI *pRtlZeroMemory)(LPVOID,SIZE_T);
107static USHORT (FASTCALL *pRtlUshortByteSwap)(USHORT source);
108static ULONG (FASTCALL *pRtlUlongByteSwap)(ULONG source);
109static ULONGLONG (FASTCALL *pRtlUlonglongByteSwap)(ULONGLONG source);
110static DWORD (WINAPI *pRtlGetThreadErrorMode)(void);
111static NTSTATUS (WINAPI *pRtlSetThreadErrorMode)(DWORD, LPDWORD);
112static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, LPSTR, PULONG);
113static NTSTATUS (WINAPI *pRtlIpv4StringToAddressExA)(PCSTR, BOOLEAN, IN_ADDR *, PUSHORT);
114static NTSTATUS (WINAPI *pRtlIpv6AddressToStringExA)(struct in6_addr *, ULONG, USHORT, PCHAR, PULONG);
115static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExA)(PCSTR, struct in6_addr *, PULONG, PUSHORT);
116static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExW)(PCWSTR, struct in6_addr *, PULONG, PUSHORT);
117static BOOL (WINAPI *pRtlIsCriticalSectionLocked)(CRITICAL_SECTION *);
118static BOOL (WINAPI *pRtlIsCriticalSectionLockedByThread)(CRITICAL_SECTION *);
119static NTSTATUS (WINAPI *pRtlInitializeCriticalSectionEx)(CRITICAL_SECTION *, ULONG, ULONG);
120static void * (WINAPI *pRtlFindExportedRoutineByName)(HMODULE,const char *);
121static NTSTATUS (WINAPI *pLdrEnumerateLoadedModules)(void *, void *, void *);
122static NTSTATUS (WINAPI *pLdrRegisterDllNotification)(ULONG, PLDR_DLL_NOTIFICATION_FUNCTION, void *, void **);
123static NTSTATUS (WINAPI *pLdrUnregisterDllNotification)(void *);
124static VOID (WINAPI *pRtlGetDeviceFamilyInfoEnum)(ULONGLONG *,DWORD *,DWORD *);
125static void (WINAPI *pRtlRbInsertNodeEx)(RTL_RB_TREE *, RTL_BALANCED_NODE *, BOOLEAN, RTL_BALANCED_NODE *);
126static void (WINAPI *pRtlRbRemoveNode)(RTL_RB_TREE *, RTL_BALANCED_NODE *);
127static DWORD (WINAPI *pRtlConvertDeviceFamilyInfoToString)(DWORD *, DWORD *, WCHAR *, WCHAR *);
128static NTSTATUS (WINAPI *pRtlInitializeNtUserPfn)( const UINT64 *client_procsA, ULONG procsA_size,
131static NTSTATUS (WINAPI *pRtlRetrieveNtUserPfn)( const UINT64 **client_procsA,
132 const UINT64 **client_procsW,
133 const UINT64 **client_workers );
134static NTSTATUS (WINAPI *pRtlResetNtUserPfn)(void);
135
137static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
138
139
140#define LEN 16
141static const char* src_src = "This is a test!"; /* 16 bytes long, incl NUL */
142static WCHAR ws2_32dllW[] = {'w','s','2','_','3','2','.','d','l','l',0};
143static WCHAR nsidllW[] = {'n','s','i','.','d','l','l',0};
144static WCHAR wintrustdllW[] = {'w','i','n','t','r','u','s','t','.','d','l','l',0};
145static WCHAR crypt32dllW[] = {'c','r','y','p','t','3','2','.','d','l','l',0};
148static const char *src = (const char*)src_aligned_block;
149static char* dest = (char*)dest_aligned_block;
151
152static void InitFunctionPtrs(void)
153{
154 hntdll = LoadLibraryA("ntdll.dll");
155 ok(hntdll != 0, "LoadLibrary failed\n");
156 if (hntdll) {
157 pRtlMoveMemory = (void *)GetProcAddress(hntdll, "RtlMoveMemory");
158 pRtlFillMemory = (void *)GetProcAddress(hntdll, "RtlFillMemory");
159 pRtlFillMemoryUlong = (void *)GetProcAddress(hntdll, "RtlFillMemoryUlong");
160 pRtlZeroMemory = (void *)GetProcAddress(hntdll, "RtlZeroMemory");
161 pRtlUshortByteSwap = (void *)GetProcAddress(hntdll, "RtlUshortByteSwap");
162 pRtlUlongByteSwap = (void *)GetProcAddress(hntdll, "RtlUlongByteSwap");
163 pRtlUlonglongByteSwap = (void *)GetProcAddress(hntdll, "RtlUlonglongByteSwap");
164 pRtlGetThreadErrorMode = (void *)GetProcAddress(hntdll, "RtlGetThreadErrorMode");
165 pRtlSetThreadErrorMode = (void *)GetProcAddress(hntdll, "RtlSetThreadErrorMode");
166 pRtlIpv4AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringExA");
167 pRtlIpv4StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressExA");
168 pRtlIpv6AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv6AddressToStringExA");
169 pRtlIpv6StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExA");
170 pRtlIpv6StringToAddressExW = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExW");
171 pRtlIsCriticalSectionLocked = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLocked");
172 pRtlIsCriticalSectionLockedByThread = (void *)GetProcAddress(hntdll, "RtlIsCriticalSectionLockedByThread");
173 pRtlInitializeCriticalSectionEx = (void *)GetProcAddress(hntdll, "RtlInitializeCriticalSectionEx");
174 pRtlFindExportedRoutineByName = (void *)GetProcAddress(hntdll, "RtlFindExportedRoutineByName");
175 pLdrEnumerateLoadedModules = (void *)GetProcAddress(hntdll, "LdrEnumerateLoadedModules");
176 pLdrRegisterDllNotification = (void *)GetProcAddress(hntdll, "LdrRegisterDllNotification");
177 pLdrUnregisterDllNotification = (void *)GetProcAddress(hntdll, "LdrUnregisterDllNotification");
178 pRtlGetDeviceFamilyInfoEnum = (void *)GetProcAddress(hntdll, "RtlGetDeviceFamilyInfoEnum");
179 pRtlRbInsertNodeEx = (void *)GetProcAddress(hntdll, "RtlRbInsertNodeEx");
180 pRtlRbRemoveNode = (void *)GetProcAddress(hntdll, "RtlRbRemoveNode");
181 pRtlConvertDeviceFamilyInfoToString = (void *)GetProcAddress(hntdll, "RtlConvertDeviceFamilyInfoToString");
182 pRtlInitializeNtUserPfn = (void *)GetProcAddress(hntdll, "RtlInitializeNtUserPfn");
183 pRtlRetrieveNtUserPfn = (void *)GetProcAddress(hntdll, "RtlRetrieveNtUserPfn");
184 pRtlResetNtUserPfn = (void *)GetProcAddress(hntdll, "RtlResetNtUserPfn");
185 }
186 hkernel32 = LoadLibraryA("kernel32.dll");
187 ok(hkernel32 != 0, "LoadLibrary failed\n");
188 if (hkernel32) {
189 pIsWow64Process = (void *)GetProcAddress(hkernel32, "IsWow64Process");
190 }
192 ok(strlen(src) == 15, "Source must be 16 bytes long!\n");
193}
194
196{
199
200 /* PDI_HEAPS | PDI_HEAP_BLOCKS */
202 ok( buffer != NULL, "RtlCreateQueryDebugBuffer returned NULL" );
203
205#ifdef __REACTOS__
206 ok( status == (GetNTVersion() >= _WIN32_WINNT_VISTA ? STATUS_INVALID_CID : STATUS_INVALID_PARAMETER), "RtlQueryProcessDebugInformation returned %lx\n", status );
207#else
208 ok( status == STATUS_INVALID_CID, "RtlQueryProcessDebugInformation returned %lx\n", status );
209#endif
210
212 ok( !status, "RtlQueryProcessDebugInformation returned %lx\n", status );
213 ok( buffer->InfoClassMask == (PDI_HEAPS | PDI_HEAP_BLOCKS), "unexpected InfoClassMask %ld\n", buffer->InfoClassMask);
214 ok( buffer->HeapInformation != NULL, "unexpected HeapInformation %p\n", buffer->HeapInformation);
215
217 ok( !status, "RtlDestroyQueryDebugBuffer returned %lx\n", status );
218
219 /* PDI_MODULES */
221 ok( buffer != NULL, "RtlCreateQueryDebugBuffer returned NULL" );
222
224 ok( !status, "RtlQueryProcessDebugInformation returned %lx\n", status );
225 ok( buffer->InfoClassMask == PDI_MODULES, "unexpected InfoClassMask %ld\n", buffer->InfoClassMask);
226 ok( buffer->ModuleInformation != NULL, "unexpected ModuleInformation %p\n", buffer->ModuleInformation);
227
229 ok( !status, "RtlDestroyQueryDebugBuffer returned %lx\n", status );
230}
231
232#define COMP(str1,str2,cmplen,len) size = RtlCompareMemory(str1, str2, cmplen); \
233 ok(size == len, "Expected %Id, got %Id\n", size, (SIZE_T)len)
234
235static void test_RtlCompareMemory(void)
236{
237 SIZE_T size;
238
239 strcpy(dest, src);
240
241 COMP(src,src,0,0);
242 COMP(src,src,LEN,LEN);
243 dest[0] = 'x';
244 COMP(src,dest,LEN,0);
245}
246
248{
249 ULONG a[10];
251
252 a[0]= 0x0123;
253 a[1]= 0x4567;
254 a[2]= 0x89ab;
255 a[3]= 0xcdef;
256 result = RtlCompareMemoryUlong(a, 0, 0x0123);
257 ok(result == 0, "RtlCompareMemoryUlong(%p, 0, 0x0123) returns %lu, expected 0\n", a, result);
258 result = RtlCompareMemoryUlong(a, 3, 0x0123);
259 ok(result == 0, "RtlCompareMemoryUlong(%p, 3, 0x0123) returns %lu, expected 0\n", a, result);
260 result = RtlCompareMemoryUlong(a, 4, 0x0123);
261 ok(result == 4, "RtlCompareMemoryUlong(%p, 4, 0x0123) returns %lu, expected 4\n", a, result);
262 result = RtlCompareMemoryUlong(a, 5, 0x0123);
263 ok(result == 4 || !result /* arm64 */, "RtlCompareMemoryUlong(%p, 5, 0x0123) returns %lu, expected 4\n", a, result);
264 result = RtlCompareMemoryUlong(a, 7, 0x0123);
265 ok(result == 4 || !result /* arm64 */, "RtlCompareMemoryUlong(%p, 7, 0x0123) returns %lu, expected 4\n", a, result);
266 result = RtlCompareMemoryUlong(a, 8, 0x0123);
267 ok(result == 4, "RtlCompareMemoryUlong(%p, 8, 0x0123) returns %lu, expected 4\n", a, result);
268 result = RtlCompareMemoryUlong(a, 9, 0x0123);
269 ok(result == 4 || !result /* arm64 */, "RtlCompareMemoryUlong(%p, 9, 0x0123) returns %lu, expected 4\n", a, result);
270 result = RtlCompareMemoryUlong(a, 4, 0x0127);
271 ok(result == 0, "RtlCompareMemoryUlong(%p, 4, 0x0127) returns %lu, expected 0\n", a, result);
272 result = RtlCompareMemoryUlong(a, 4, 0x7123);
273 ok(result == 0 || result == 1 /* arm64 */, "RtlCompareMemoryUlong(%p, 4, 0x7123) returns %lu, expected 0\n", a, result);
274 result = RtlCompareMemoryUlong(a, 16, 0x4567);
275 ok(result == 0, "RtlCompareMemoryUlong(%p, 16, 0x4567) returns %lu, expected 0\n", a, result);
276
277 a[1]= 0x0123;
278 result = RtlCompareMemoryUlong(a, 3, 0x0123);
279 ok(result == 0, "RtlCompareMemoryUlong(%p, 3, 0x0123) returns %lu, expected 0\n", a, result);
280 result = RtlCompareMemoryUlong(a, 4, 0x0123);
281 ok(result == 4, "RtlCompareMemoryUlong(%p, 4, 0x0123) returns %lu, expected 4\n", a, result);
282 result = RtlCompareMemoryUlong(a, 5, 0x0123);
283 ok(result == 4 || !result /* arm64 */, "RtlCompareMemoryUlong(%p, 5, 0x0123) returns %lu, expected 4\n", a, result);
284 result = RtlCompareMemoryUlong(a, 7, 0x0123);
285 ok(result == 4 || !result /* arm64 */, "RtlCompareMemoryUlong(%p, 7, 0x0123) returns %lu, expected 4\n", a, result);
286 result = RtlCompareMemoryUlong(a, 8, 0x0123);
287 ok(result == 8, "RtlCompareMemoryUlong(%p, 8, 0x0123) returns %lu, expected 8\n", a, result);
288 result = RtlCompareMemoryUlong(a, 9, 0x0123);
289 ok(result == 8 || !result /* arm64 */, "RtlCompareMemoryUlong(%p, 9, 0x0123) returns %lu, expected 8\n", a, result);
290}
291
292#define COPY(len) memset(dest,0,sizeof(dest_aligned_block)); pRtlMoveMemory(dest, src, len)
293#define CMP(str) ok(strcmp(dest,str) == 0, "Expected '%s', got '%s'\n", str, dest)
294
295static void test_RtlMoveMemory(void)
296{
297 if (!pRtlMoveMemory)
298 {
299 win_skip("RtlMoveMemory is not available\n");
300 return;
301 }
302
303 /* Length should be in bytes and not rounded. Use strcmp to ensure we
304 * didn't write past the end (it checks for the final NUL left by memset)
305 */
306 COPY(0); CMP("");
307 COPY(1); CMP("T");
308 COPY(2); CMP("Th");
309 COPY(3); CMP("Thi");
310 COPY(4); CMP("This");
311 COPY(5); CMP("This ");
312 COPY(6); CMP("This i");
313 COPY(7); CMP("This is");
314 COPY(8); CMP("This is ");
315 COPY(9); CMP("This is a");
316
317 /* Overlapping */
318 strcpy(dest, src); pRtlMoveMemory(dest, dest + 1, strlen(src) - 1);
319 CMP("his is a test!!");
320 strcpy(dest, src); pRtlMoveMemory(dest + 1, dest, strlen(src));
321 CMP("TThis is a test!");
322}
323
324#define FILL(len) memset(dest,0,sizeof(dest_aligned_block)); strcpy(dest, src); pRtlFillMemory(dest,len,'x')
325
326static void test_RtlFillMemory(void)
327{
328 if (!pRtlFillMemory)
329 {
330 win_skip("RtlFillMemory is not available\n");
331 return;
332 }
333
334 /* Length should be in bytes and not rounded. Use strcmp to ensure we
335 * didn't write past the end (the remainder of the string should match)
336 */
337 FILL(0); CMP("This is a test!");
338 FILL(1); CMP("xhis is a test!");
339 FILL(2); CMP("xxis is a test!");
340 FILL(3); CMP("xxxs is a test!");
341 FILL(4); CMP("xxxx is a test!");
342 FILL(5); CMP("xxxxxis a test!");
343 FILL(6); CMP("xxxxxxs a test!");
344 FILL(7); CMP("xxxxxxx a test!");
345 FILL(8); CMP("xxxxxxxxa test!");
346 FILL(9); CMP("xxxxxxxxx test!");
347}
348
349#define LFILL(len) memset(dest,0,sizeof(dest_aligned_block)); strcpy(dest, src); pRtlFillMemoryUlong(dest,len,val)
350
351static void test_RtlFillMemoryUlong(void)
352{
353 ULONG val = ('x' << 24) | ('x' << 16) | ('x' << 8) | 'x';
354 if (!pRtlFillMemoryUlong)
355 {
356 win_skip("RtlFillMemoryUlong is not available\n");
357 return;
358 }
359
360 /* Length should be in bytes and not rounded. Use strcmp to ensure we
361 * didn't write past the end (the remainder of the string should match)
362 */
363 LFILL(0); CMP("This is a test!");
364 LFILL(1); CMP("This is a test!");
365 LFILL(2); CMP("This is a test!");
366 LFILL(3); CMP("This is a test!");
367 LFILL(4); CMP("xxxx is a test!");
368 LFILL(5); CMP("xxxx is a test!");
369 LFILL(6); CMP("xxxx is a test!");
370 LFILL(7); CMP("xxxx is a test!");
371 LFILL(8); CMP("xxxxxxxxa test!");
372 LFILL(9); CMP("xxxxxxxxa test!");
373}
374
375#define ZERO(len) memset(dest,0,sizeof(dest_aligned_block)); strcpy(dest, src); pRtlZeroMemory(dest,len)
376#define MCMP(str) ok(memcmp(dest,str,LEN) == 0, "Memcmp failed\n")
377
378static void test_RtlZeroMemory(void)
379{
380 if (!pRtlZeroMemory)
381 {
382 win_skip("RtlZeroMemory is not available\n");
383 return;
384 }
385
386 /* Length should be in bytes and not rounded. */
387 ZERO(0); MCMP("This is a test!");
388 ZERO(1); MCMP("\0his is a test!");
389 ZERO(2); MCMP("\0\0is is a test!");
390 ZERO(3); MCMP("\0\0\0s is a test!");
391 ZERO(4); MCMP("\0\0\0\0 is a test!");
392 ZERO(5); MCMP("\0\0\0\0\0is a test!");
393 ZERO(6); MCMP("\0\0\0\0\0\0s a test!");
394 ZERO(7); MCMP("\0\0\0\0\0\0\0 a test!");
395 ZERO(8); MCMP("\0\0\0\0\0\0\0\0a test!");
396 ZERO(9); MCMP("\0\0\0\0\0\0\0\0\0 test!");
397}
398
399static void test_RtlByteSwap(void)
400{
401 ULONGLONG llresult;
402 ULONG lresult;
403 USHORT sresult;
404
405#ifdef _WIN64
406 /* the Rtl*ByteSwap() are always inlined and not exported from ntdll on 64bit */
407 sresult = RtlUshortByteSwap( 0x1234 );
408 ok( 0x3412 == sresult,
409 "inlined RtlUshortByteSwap() returns 0x%x\n", sresult );
410 lresult = RtlUlongByteSwap( 0x87654321 );
411 ok( 0x21436587 == lresult,
412 "inlined RtlUlongByteSwap() returns 0x%lx\n", lresult );
413 llresult = RtlUlonglongByteSwap( 0x7654321087654321ull );
414 ok( 0x2143658710325476 == llresult,
415 "inlined RtlUlonglongByteSwap() returns %#I64x\n", llresult );
416#else
417 ok( pRtlUshortByteSwap != NULL, "RtlUshortByteSwap is not available\n" );
418 if ( pRtlUshortByteSwap )
419 {
420 sresult = call_fastcall_func1( pRtlUshortByteSwap, 0x1234u );
421 ok( 0x3412u == sresult,
422 "ntdll.RtlUshortByteSwap() returns %#x\n", sresult );
423 }
424
425 ok( pRtlUlongByteSwap != NULL, "RtlUlongByteSwap is not available\n" );
426 if ( pRtlUlongByteSwap )
427 {
428 lresult = call_fastcall_func1( pRtlUlongByteSwap, 0x87654321ul );
429 ok( 0x21436587ul == lresult,
430 "ntdll.RtlUlongByteSwap() returns %#lx\n", lresult );
431 }
432
433#ifdef __REACTOS__
434 /* On older Windows versions, RtlUlonglongByteSwap has a broken calling convention! */
435 RTL_OSVERSIONINFOEXW verInfo = { sizeof(verInfo) };
436 RtlGetVersion(&verInfo);
437 if (verInfo.dwMajorVersion < 10)
438 {
439 skip("Skipping RtlUlonglongByteSwap test due to broken calling convention\n");
440 return;
441 }
442#endif
443
444 ok( pRtlUlonglongByteSwap != NULL, "RtlUlonglongByteSwap is not available\n");
445 if ( pRtlUlonglongByteSwap )
446 {
447 llresult = pRtlUlonglongByteSwap( 0x7654321087654321ull );
448 ok( 0x2143658710325476ull == llresult,
449 "ntdll.RtlUlonglongByteSwap() returns %#I64x\n", llresult );
450 }
451#endif
452}
453
454
455static void test_RtlUniform(void)
456{
457 const ULONG step = 0x7fff;
458 ULONG num;
459 ULONG seed;
460 ULONG seed_bak;
463
464#ifdef __REACTOS__
465 if (!is_reactos() && (_winver < _WIN32_WINNT_VISTA))
466 {
467 skip("Skipping tests for RtlUniform, because it's broken on Windows 2003\n");
468 return;
469 }
470#endif // __REACTOS__
471
472 /*
473 * According to the documentation RtlUniform is using D.H. Lehmer's 1948
474 * algorithm. We assume a more generic version of this algorithm,
475 * which is the linear congruential generator (LCG). Its formula is:
476 *
477 * X_(n+1) = (a * X_n + c) % m
478 *
479 * where a is the multiplier, c is the increment, and m is the modulus.
480 *
481 * According to the documentation, the random numbers are distributed over
482 * [0..MAXLONG]. Therefore, the modulus is MAXLONG + 1:
483 *
484 * X_(n+1) = (a * X_n + c) % (MAXLONG + 1)
485 *
486 * To find out the increment, we just call RtlUniform with seed set to 0.
487 * This reveals c = 0x7fffffc3.
488 */
489 seed = 0;
490 expected = 0x7fffffc3;
491 result = RtlUniform(&seed);
492 ok(result == expected,
493 "RtlUniform(&seed (seed == 0)) returns %lx, expected %lx\n",
495
496 /*
497 * The formula is now:
498 *
499 * X_(n+1) = (a * X_n + 0x7fffffc3) % (MAXLONG + 1)
500 *
501 * If the modulus is correct, RtlUniform(0) shall equal RtlUniform(MAXLONG + 1).
502 * However, testing reveals that this is not the case.
503 * That is, the modulus in the documentation is incorrect.
504 */
505 seed = 0x80000000U;
506 expected = 0x7fffffb1;
507 result = RtlUniform(&seed);
508
509 ok(result == expected,
510 "RtlUniform(&seed (seed == 0x80000000)) returns %lx, expected %lx\n",
512
513 /*
514 * We try another value for modulus, say MAXLONG.
515 * We discover that RtlUniform(0) equals RtlUniform(MAXLONG), which means
516 * the correct value for the modulus is actually MAXLONG.
517 */
518 seed = 0x7fffffff;
519 expected = 0x7fffffc3;
520 result = RtlUniform(&seed);
521 ok(result == expected,
522 "RtlUniform(&seed (seed == 0x7fffffff)) returns %lx, expected %lx\n",
524
525 /*
526 * The formula is now:
527 *
528 * X_(n+1) = (a * X_n + 0x7fffffc3) % MAXLONG
529 *
530 * To find out the multiplier we can use:
531 *
532 * a = RtlUniform(1) - 0x7fffffc3 (mod MAXLONG)
533 *
534 * This way, we find out that a = -18 (mod MAXLONG),
535 * which is congruent to 0x7fffffed (MAXLONG - 18).
536 */
537 seed = 1;
538 expected = ((ULONGLONG)seed * 0x7fffffed + 0x7fffffc3) % MAXLONG;
539 result = RtlUniform(&seed);
540 ok(result == expected,
541 "RtlUniform(&seed (seed == 1)) returns %lx, expected %lx\n",
543
544 num = 2;
545 do
546 {
547 seed = num;
548 expected = ((ULONGLONG)seed * 0x7fffffed + 0x7fffffc3) % 0x7fffffff;
549 result = RtlUniform(&seed);
550 ok(result == expected,
551 "test: RtlUniform(&seed (seed == %lx)) returns %lx, expected %lx\n",
553 ok(seed == expected,
554 "test: RtlUniform(&seed (seed == %lx)) sets seed to %lx, expected %lx\n",
556
557 num += step;
558 } while (num >= 2 + step);
559
560 seed = 0;
561 for (num = 0; num <= 100000; num++) {
562 expected = ((ULONGLONG)seed * 0x7fffffed + 0x7fffffc3) % 0x7fffffff;
563 seed_bak = seed;
564 result = RtlUniform(&seed);
565 ok(result == expected,
566 "test: %ld RtlUniform(&seed (seed == %lx)) returns %lx, expected %lx\n",
567 num, seed_bak, result, expected);
568 ok(seed == expected,
569 "test: %ld RtlUniform(&seed (seed == %lx)) sets seed to %lx, expected %lx\n",
570 num, seed_bak, result, expected);
571 } /* for */
572}
573
574
575static void test_RtlRandom(void)
576{
577 int i, j;
578 ULONG seed;
579 ULONG res[512];
580
581 seed = 0;
582 for (i = 0; i < ARRAY_SIZE(res); i++)
583 {
584 res[i] = RtlRandom(&seed);
585 ok(seed != res[i], "%i: seed is same as res %lx\n", i, seed);
586 for (j = 0; j < i; j++)
587 ok(res[i] != res[j], "res[%i] (%lx) is same as res[%i] (%lx)\n", j, res[j], i, res[i]);
588 }
589}
590
591
592typedef struct {
597
598static const all_accesses_t all_accesses[] = {
599 {0xFEDCBA76, 0xFEDCBA76, 1},
600 {0x00000000, 0xFEDCBA76, 0},
601 {0xFEDCBA76, 0x00000000, 1},
602 {0x00000000, 0x00000000, 1},
603 {0xFEDCBA76, 0xFEDCBA70, 1},
604 {0xFEDCBA70, 0xFEDCBA76, 0},
605 {0xFEDCBA76, 0xFEDC8A76, 1},
606 {0xFEDC8A76, 0xFEDCBA76, 0},
607 {0xFEDCBA76, 0xC8C4B242, 1},
608 {0xC8C4B242, 0xFEDCBA76, 0},
609};
610
611
613{
614 unsigned int test_num;
616
617 for (test_num = 0; test_num < ARRAY_SIZE(all_accesses); test_num++) {
619 all_accesses[test_num].DesiredAccess);
620 ok(all_accesses[test_num].result == result,
621 "(test %d): RtlAreAllAccessesGranted(%08lx, %08lx) returns %d, expected %d\n",
622 test_num, all_accesses[test_num].GrantedAccess,
623 all_accesses[test_num].DesiredAccess,
624 result, all_accesses[test_num].result);
625 } /* for */
626}
627
628
629typedef struct {
634
635static const any_accesses_t any_accesses[] = {
636 {0xFEDCBA76, 0xFEDCBA76, 1},
637 {0x00000000, 0xFEDCBA76, 0},
638 {0xFEDCBA76, 0x00000000, 0},
639 {0x00000000, 0x00000000, 0},
640 {0xFEDCBA76, 0x01234589, 0},
641 {0x00040000, 0xFEDCBA76, 1},
642 {0x00040000, 0xFED8BA76, 0},
643 {0xFEDCBA76, 0x00040000, 1},
644 {0xFED8BA76, 0x00040000, 0},
645};
646
647
649{
650 unsigned int test_num;
652
653 for (test_num = 0; test_num < ARRAY_SIZE(any_accesses); test_num++) {
655 any_accesses[test_num].DesiredAccess);
656 ok(any_accesses[test_num].result == result,
657 "(test %d): RtlAreAnyAccessesGranted(%08lx, %08lx) returns %d, expected %d\n",
658 test_num, any_accesses[test_num].GrantedAccess,
659 any_accesses[test_num].DesiredAccess,
660 result, any_accesses[test_num].result);
661 } /* for */
662}
663
664static void test_RtlComputeCrc32(void)
665{
666 DWORD crc = 0;
667
668 crc = RtlComputeCrc32(crc, (const BYTE *)src, LEN);
669 ok(crc == 0x40861dc2,"Expected 0x40861dc2, got %8lx\n", crc);
670}
671
672
673typedef struct MY_HANDLE
674{
676 void * MyValue;
678
680{
681 ULONG_PTR *AllocatedBit = (ULONG_PTR *)(&Handle->Next);
682 *AllocatedBit = *AllocatedBit | 1;
683}
684
685static void test_HandleTables(void)
686{
689 ULONG Index;
690 MY_HANDLE * MyHandle;
692
695 ok(MyHandle != NULL, "RtlAllocateHandle failed\n");
697 MyHandle = NULL;
699 ok(result, "Handle %p wasn't valid\n", MyHandle);
701 ok(result, "Couldn't free handle %p\n", MyHandle);
703 ok(status == STATUS_SUCCESS, "RtlDestroyHandleTable failed with error 0x%08lx\n", status);
704}
705
707{
709 SID_IDENTIFIER_AUTHORITY sia = {{ 1, 2, 3, 4, 5, 6 }};
710 PSID psid;
711
712 ret = RtlAllocateAndInitializeSid(&sia, 0, 1, 2, 3, 4, 5, 6, 7, 8, &psid);
713 ok(!ret, "RtlAllocateAndInitializeSid error %08lx\n", ret);
714 ret = RtlFreeSid(psid);
715 ok(!ret, "RtlFreeSid error %08lx\n", ret);
716
717 /* these tests crash on XP */
718 if (0)
719 {
720 RtlAllocateAndInitializeSid(NULL, 0, 1, 2, 3, 4, 5, 6, 7, 8, &psid);
721 RtlAllocateAndInitializeSid(&sia, 0, 1, 2, 3, 4, 5, 6, 7, 8, NULL);
722 }
723
724 ret = RtlAllocateAndInitializeSid(&sia, 9, 1, 2, 3, 4, 5, 6, 7, 8, &psid);
725 ok(ret == STATUS_INVALID_SID, "wrong error %08lx\n", ret);
726}
727
728static void test_RtlDeleteTimer(void)
729{
731
734 ret == STATUS_INVALID_PARAMETER, /* W2K */
735 "expected STATUS_INVALID_PARAMETER_1 or STATUS_INVALID_PARAMETER, got %lx\n", ret);
736}
737
738static void test_RtlThreadErrorMode(void)
739{
740 DWORD oldmode;
742 DWORD mode;
744
745 if (!pRtlGetThreadErrorMode || !pRtlSetThreadErrorMode)
746 {
747 win_skip("RtlGetThreadErrorMode and/or RtlSetThreadErrorMode not available\n");
748 return;
749 }
750
751 if (!pIsWow64Process || !pIsWow64Process(GetCurrentProcess(), &is_wow64))
752 is_wow64 = FALSE;
753
754 oldmode = pRtlGetThreadErrorMode();
755
756 status = pRtlSetThreadErrorMode(0x70, &mode);
758 status == STATUS_WAIT_1, /* Vista */
759 "RtlSetThreadErrorMode failed with error 0x%08lx\n", status);
760 ok(mode == oldmode,
761 "RtlSetThreadErrorMode returned mode 0x%lx, expected 0x%lx\n",
762 mode, oldmode);
763 ok(pRtlGetThreadErrorMode() == 0x70,
764 "RtlGetThreadErrorMode returned 0x%lx, expected 0x%x\n", mode, 0x70);
765 if (!is_wow64)
766 {
767 ok(NtCurrentTeb()->HardErrorMode == 0x70,
768 "The TEB contains 0x%lx, expected 0x%x\n",
769 NtCurrentTeb()->HardErrorMode, 0x70);
770 }
771
772 status = pRtlSetThreadErrorMode(0, &mode);
774 status == STATUS_WAIT_1, /* Vista */
775 "RtlSetThreadErrorMode failed with error 0x%08lx\n", status);
776 ok(mode == 0x70,
777 "RtlSetThreadErrorMode returned mode 0x%lx, expected 0x%x\n",
778 mode, 0x70);
779 ok(pRtlGetThreadErrorMode() == 0,
780 "RtlGetThreadErrorMode returned 0x%lx, expected 0x%x\n", mode, 0);
781 if (!is_wow64)
782 {
783 ok(NtCurrentTeb()->HardErrorMode == 0,
784 "The TEB contains 0x%lx, expected 0x%x\n",
785 NtCurrentTeb()->HardErrorMode, 0);
786 }
787
788 for (mode = 1; mode; mode <<= 1)
789 {
790 status = pRtlSetThreadErrorMode(mode, NULL);
791 if (mode & 0x70)
793 status == STATUS_WAIT_1, /* Vista */
794 "RtlSetThreadErrorMode(%lx,NULL) failed with error 0x%08lx\n",
795 mode, status);
796 else
798 "RtlSetThreadErrorMode(%lx,NULL) returns 0x%08lx, "
799 "expected STATUS_INVALID_PARAMETER_1\n",
800 mode, status);
801 }
802
803 pRtlSetThreadErrorMode(oldmode, NULL);
804}
805
807{
809 USHORT reloc;
810 DWORD addr32;
811 SHORT addr16;
812
813 addr32 = 0x50005;
814 reloc = IMAGE_REL_BASED_HIGHLOW<<12;
815 ret = LdrProcessRelocationBlock(&addr32, 1, &reloc, 0x500050);
816 ok((USHORT*)ret == &reloc+1, "ret = %p, expected %p\n", ret, &reloc+1);
817 ok(addr32 == 0x550055, "addr32 = %lx, expected 0x550055\n", addr32);
818
819 addr16 = 0x505;
820 reloc = IMAGE_REL_BASED_HIGH<<12;
821 ret = LdrProcessRelocationBlock(&addr16, 1, &reloc, 0x500060);
822 ok((USHORT*)ret == &reloc+1, "ret = %p, expected %p\n", ret, &reloc+1);
823 ok(addr16 == 0x555, "addr16 = %x, expected 0x555\n", addr16);
824
825 addr16 = 0x505;
826 reloc = IMAGE_REL_BASED_LOW<<12;
827 ret = LdrProcessRelocationBlock(&addr16, 1, &reloc, 0x500060);
828 ok((USHORT*)ret == &reloc+1, "ret = %p, expected %p\n", ret, &reloc+1);
829 ok(addr16 == 0x565, "addr16 = %x, expected 0x565\n", addr16);
830}
831
833{
834 CHAR buffer[20];
835 CHAR *res;
836 IN_ADDR ip;
838
839 ip.S_un.S_un_b.s_b1 = 1;
840 ip.S_un.S_un_b.s_b2 = 2;
841 ip.S_un.S_un_b.s_b3 = 3;
842 ip.S_un.S_un_b.s_b4 = 4;
843
844 memset(buffer, '#', sizeof(buffer) - 1);
845 buffer[sizeof(buffer) -1] = 0;
847 len = strlen(buffer);
848 ok(res == (buffer + len), "got %p with '%s' (expected %p)\n", res, buffer, buffer + len);
849
851 ok( (res == (char *)~0) ||
852 broken(res == (char *)len), /* XP and w2003 */
853 "got %p (expected ~0)\n", res);
854
855 if (0) {
856 /* this crashes in windows */
857 memset(buffer, '#', sizeof(buffer) - 1);
858 buffer[sizeof(buffer) -1] = 0;
860 trace("got %p with '%s'\n", res, buffer);
861 }
862
863 if (0) {
864 /* this crashes in windows */
866 trace("got %p\n", res);
867 }
868}
869
871{
872 CHAR ip_1234[] = "1.2.3.4";
873 CHAR ip_1234_80[] = "1.2.3.4:80";
875 CHAR buffer[30];
877 IN_ADDR ip;
878 ULONG size;
879 DWORD used;
880 USHORT port;
881
882 if (!pRtlIpv4AddressToStringExA)
883 {
884 win_skip("RtlIpv4AddressToStringExA not available\n");
885 return;
886 }
887
888 ip.S_un.S_un_b.s_b1 = 1;
889 ip.S_un.S_un_b.s_b2 = 2;
890 ip.S_un.S_un_b.s_b3 = 3;
891 ip.S_un.S_un_b.s_b4 = 4;
892
893 port = htons(80);
894 expect = ip_1234_80;
895
896 size = sizeof(buffer);
897 memset(buffer, '#', sizeof(buffer) - 1);
898 buffer[sizeof(buffer) -1] = 0;
899 res = pRtlIpv4AddressToStringExA(&ip, port, buffer, &size);
900 used = strlen(buffer);
901 ok( (res == STATUS_SUCCESS) &&
902 (size == strlen(expect) + 1) && !strcmp(buffer, expect),
903 "got 0x%lx and size %ld with '%s'\n", res, size, buffer);
904
905 size = used + 1;
906 memset(buffer, '#', sizeof(buffer) - 1);
907 buffer[sizeof(buffer) -1] = 0;
908 res = pRtlIpv4AddressToStringExA(&ip, port, buffer, &size);
909 ok( (res == STATUS_SUCCESS) &&
910 (size == strlen(expect) + 1) && !strcmp(buffer, expect),
911 "got 0x%lx and size %ld with '%s'\n", res, size, buffer);
912
913 size = used;
914 memset(buffer, '#', sizeof(buffer) - 1);
915 buffer[sizeof(buffer) -1] = 0;
916 res = pRtlIpv4AddressToStringExA(&ip, port, buffer, &size);
917 ok( (res == STATUS_INVALID_PARAMETER) && (size == used + 1),
918 "got 0x%lx and %ld with '%s' (expected STATUS_INVALID_PARAMETER and %ld)\n",
919 res, size, buffer, used + 1);
920
921 size = used - 1;
922 memset(buffer, '#', sizeof(buffer) - 1);
923 buffer[sizeof(buffer) -1] = 0;
924 res = pRtlIpv4AddressToStringExA(&ip, port, buffer, &size);
925 ok( (res == STATUS_INVALID_PARAMETER) && (size == used + 1),
926 "got 0x%lx and %ld with '%s' (expected STATUS_INVALID_PARAMETER and %ld)\n",
927 res, size, buffer, used + 1);
928
929
930 /* to get only the ip, use 0 as port */
931 port = 0;
932 expect = ip_1234;
933
934 size = sizeof(buffer);
935 memset(buffer, '#', sizeof(buffer) - 1);
936 buffer[sizeof(buffer) -1] = 0;
937 res = pRtlIpv4AddressToStringExA(&ip, port, buffer, &size);
938 used = strlen(buffer);
939 ok( (res == STATUS_SUCCESS) &&
940 (size == strlen(expect) + 1) && !strcmp(buffer, expect),
941 "got 0x%lx and size %ld with '%s'\n", res, size, buffer);
942
943 size = used + 1;
944 memset(buffer, '#', sizeof(buffer) - 1);
945 buffer[sizeof(buffer) -1] = 0;
946 res = pRtlIpv4AddressToStringExA(&ip, port, buffer, &size);
947 ok( (res == STATUS_SUCCESS) &&
948 (size == strlen(expect) + 1) && !strcmp(buffer, expect),
949 "got 0x%lx and size %ld with '%s'\n", res, size, buffer);
950
951 size = used;
952 memset(buffer, '#', sizeof(buffer) - 1);
953 buffer[sizeof(buffer) -1] = 0;
954 res = pRtlIpv4AddressToStringExA(&ip, port, buffer, &size);
955 ok( (res == STATUS_INVALID_PARAMETER) && (size == used + 1),
956 "got 0x%lx and %ld with '%s' (expected STATUS_INVALID_PARAMETER and %ld)\n",
957 res, size, buffer, used + 1);
958
959 size = used - 1;
960 memset(buffer, '#', sizeof(buffer) - 1);
961 buffer[sizeof(buffer) -1] = 0;
962 res = pRtlIpv4AddressToStringExA(&ip, port, buffer, &size);
963 ok( (res == STATUS_INVALID_PARAMETER) && (size == used + 1),
964 "got 0x%lx and %ld with '%s' (expected STATUS_INVALID_PARAMETER and %ld)\n",
965 res, size, buffer, used + 1);
966
967
968 /* parameters are checked */
969 memset(buffer, '#', sizeof(buffer) - 1);
970 buffer[sizeof(buffer) -1] = 0;
971 res = pRtlIpv4AddressToStringExA(&ip, 0, buffer, NULL);
973 "got 0x%lx with '%s' (expected STATUS_INVALID_PARAMETER)\n", res, buffer);
974
975 size = sizeof(buffer);
976 res = pRtlIpv4AddressToStringExA(&ip, 0, NULL, &size);
978 "got 0x%lx and size %ld (expected STATUS_INVALID_PARAMETER)\n", res, size);
979
980 size = sizeof(buffer);
981 memset(buffer, '#', sizeof(buffer) - 1);
982 buffer[sizeof(buffer) -1] = 0;
983 res = pRtlIpv4AddressToStringExA(NULL, 0, buffer, &size);
985 "got 0x%lx and size %ld with '%s' (expected STATUS_INVALID_PARAMETER)\n",
986 res, size, buffer);
987}
988
989static struct
990{
994 int ip[4];
995 enum { normal_4, strict_diff_4 = 1, ex_fail_4 = 2 } flags;
998 int ip_strict[4];
999} ipv4_tests[] =
1000{
1001 { "", STATUS_INVALID_PARAMETER, 0, { -1 } },
1002 { " ", STATUS_INVALID_PARAMETER, 0, { -1 } },
1003 { "1.1.1.1", STATUS_SUCCESS, 7, { 1, 1, 1, 1 } },
1004 { "0.0.0.0", STATUS_SUCCESS, 7, { 0, 0, 0, 0 } },
1005 { "255.255.255.255", STATUS_SUCCESS, 15, { 255, 255, 255, 255 } },
1006 { "255.255.255.255:123", STATUS_SUCCESS, 15, { 255, 255, 255, 255 } },
1007 { "255.255.255.256", STATUS_INVALID_PARAMETER, 15, { -1 } },
1008 { "255.255.255.4294967295", STATUS_INVALID_PARAMETER, 22, { -1 } },
1009 { "255.255.255.4294967296", STATUS_INVALID_PARAMETER, 21, { -1 } },
1010 { "255.255.255.4294967297", STATUS_INVALID_PARAMETER, 21, { -1 } },
1011 { "a", STATUS_INVALID_PARAMETER, 0, { -1 } },
1012 { "1.1.1.0xaA", STATUS_SUCCESS, 10, { 1, 1, 1, 170 }, strict_diff_4,
1013 STATUS_INVALID_PARAMETER, 8, { -1 } },
1014 { "1.1.1.0XaA", STATUS_SUCCESS, 10, { 1, 1, 1, 170 }, strict_diff_4,
1015 STATUS_INVALID_PARAMETER, 8, { -1 } },
1016 { "1.1.1.0x", STATUS_INVALID_PARAMETER, 8, { -1 } },
1017 { "1.1.1.0xff", STATUS_SUCCESS, 10, { 1, 1, 1, 255 }, strict_diff_4,
1018 STATUS_INVALID_PARAMETER, 8, { -1 } },
1019 { "1.1.1.0x100", STATUS_INVALID_PARAMETER, 11, { -1 }, strict_diff_4,
1020 STATUS_INVALID_PARAMETER, 8, { -1 } },
1021 { "1.1.1.0xffffffff", STATUS_INVALID_PARAMETER, 16, { -1 }, strict_diff_4,
1022 STATUS_INVALID_PARAMETER, 8, { -1 } },
1023 { "1.1.1.0x100000000", STATUS_INVALID_PARAMETER, 16, { -1, 0, 0, 0 }, strict_diff_4,
1024 STATUS_INVALID_PARAMETER, 8, { -1 } },
1025 { "1.1.1.010", STATUS_SUCCESS, 9, { 1, 1, 1, 8 }, strict_diff_4,
1026 STATUS_INVALID_PARAMETER, 7, { -1 } },
1027 { "1.1.1.00", STATUS_SUCCESS, 8, { 1, 1, 1, 0 }, strict_diff_4,
1028 STATUS_INVALID_PARAMETER, 7, { -1 } },
1029 { "1.1.1.007", STATUS_SUCCESS, 9, { 1, 1, 1, 7 }, strict_diff_4,
1030 STATUS_INVALID_PARAMETER, 7, { -1 } },
1031 { "1.1.1.08", STATUS_INVALID_PARAMETER, 7, { -1 } },
1032 { "1.1.1.008", STATUS_SUCCESS, 8, { 1, 1, 1, 0 }, strict_diff_4 | ex_fail_4,
1033 STATUS_INVALID_PARAMETER, 7, { -1 } },
1034 { "1.1.1.0a", STATUS_SUCCESS, 7, { 1, 1, 1, 0 }, ex_fail_4 },
1035 { "1.1.1.0o10", STATUS_SUCCESS, 7, { 1, 1, 1, 0 }, ex_fail_4 },
1036 { "1.1.1.0b10", STATUS_SUCCESS, 7, { 1, 1, 1, 0 }, ex_fail_4 },
1037 { "1.1.1.-2", STATUS_INVALID_PARAMETER, 6, { -1 } },
1038 { "1", STATUS_SUCCESS, 1, { 0, 0, 0, 1 }, strict_diff_4,
1039 STATUS_INVALID_PARAMETER, 1, { -1 } },
1040 { "-1", STATUS_INVALID_PARAMETER, 0, { -1 } },
1041 { "1.2", STATUS_SUCCESS, 3, { 1, 0, 0, 2 }, strict_diff_4,
1042 STATUS_INVALID_PARAMETER, 3, { -1 } },
1043 { "1000.2000", STATUS_INVALID_PARAMETER, 9, { -1 } },
1044 { "1.2.", STATUS_INVALID_PARAMETER, 4, { -1 } },
1045 { "1..2", STATUS_INVALID_PARAMETER, 3, { -1 } },
1046 { "1...2", STATUS_INVALID_PARAMETER, 3, { -1 } },
1047 { "1.2.3", STATUS_SUCCESS, 5, { 1, 2, 0, 3 }, strict_diff_4,
1048 STATUS_INVALID_PARAMETER, 5, { -1 } },
1049 { "1.2.3.", STATUS_INVALID_PARAMETER, 6, { -1 } },
1050 { "203569230", STATUS_SUCCESS, 9, { 12, 34, 56, 78 }, strict_diff_4,
1051 STATUS_INVALID_PARAMETER, 9, { -1 } },
1052 { "1.223756", STATUS_SUCCESS, 8, { 1, 3, 106, 12 }, strict_diff_4,
1053 STATUS_INVALID_PARAMETER, 8, { -1 } },
1054 { "3.4.756", STATUS_SUCCESS, 7, { 3, 4, 2, 244 }, strict_diff_4,
1055 STATUS_INVALID_PARAMETER, 7, { -1 } },
1056 { "756.3.4", STATUS_INVALID_PARAMETER, 7, { -1 } },
1057 { "3.756.4", STATUS_INVALID_PARAMETER, 7, { -1 } },
1058 { "3.4.756.1", STATUS_INVALID_PARAMETER, 9, { -1 } },
1059 { "3.4.65536", STATUS_INVALID_PARAMETER, 9, { -1 } },
1060 { "3.4.5.6.7", STATUS_INVALID_PARAMETER, 7, { -1 } },
1061 { "3.4.5.+6", STATUS_INVALID_PARAMETER, 6, { -1 } },
1062 { " 3.4.5.6", STATUS_INVALID_PARAMETER, 0, { -1 } },
1063 { "\t3.4.5.6", STATUS_INVALID_PARAMETER, 0, { -1 } },
1064 { "3.4.5.6 ", STATUS_SUCCESS, 7, { 3, 4, 5, 6 }, ex_fail_4 },
1065 { "3. 4.5.6", STATUS_INVALID_PARAMETER, 2, { -1 } },
1066 { ".", STATUS_INVALID_PARAMETER, 1, { -1 } },
1067 { "..", STATUS_INVALID_PARAMETER, 1, { -1 } },
1068 { "1.", STATUS_INVALID_PARAMETER, 2, { -1 } },
1069 { "1..", STATUS_INVALID_PARAMETER, 3, { -1 } },
1070 { ".1", STATUS_INVALID_PARAMETER, 1, { -1 } },
1071 { ".1.", STATUS_INVALID_PARAMETER, 1, { -1 } },
1072 { ".1.2.3", STATUS_INVALID_PARAMETER, 1, { -1 } },
1073 { ".1.2.3.4", STATUS_INVALID_PARAMETER, 1, { -1 } },
1074 { "0.1.2.3", STATUS_SUCCESS, 7, { 0, 1, 2, 3 } },
1075 { "0.1.2.3.", STATUS_INVALID_PARAMETER, 7, { -1 } },
1076 { "[0.1.2.3]", STATUS_INVALID_PARAMETER, 0, { -1 } },
1077 { "0x00010203", STATUS_SUCCESS, 10, { 0, 1, 2, 3 }, strict_diff_4,
1078 STATUS_INVALID_PARAMETER, 2, { -1 } },
1079 { "0X00010203", STATUS_SUCCESS, 10, { 0, 1, 2, 3 }, strict_diff_4,
1080 STATUS_INVALID_PARAMETER, 2, { -1 } },
1081 { "0x1234", STATUS_SUCCESS, 6, { 0, 0, 18, 52 }, strict_diff_4,
1082 STATUS_INVALID_PARAMETER, 2, { -1 } },
1083 { "0x123456789", STATUS_SUCCESS, 11, { 35, 69, 103, 137 }, strict_diff_4,
1084 STATUS_INVALID_PARAMETER, 2, { -1 } },
1085 { "0x00010Q03", STATUS_SUCCESS, 7, { 0, 0, 0, 16 }, strict_diff_4 | ex_fail_4,
1086 STATUS_INVALID_PARAMETER, 2, { -1 } },
1087 { "x00010203", STATUS_INVALID_PARAMETER, 0, { -1 } },
1088 { "1234BEEF", STATUS_SUCCESS, 4, { 0, 0, 4, 210 }, strict_diff_4 | ex_fail_4,
1089 STATUS_INVALID_PARAMETER, 4, { -1 } },
1090 { "017700000001", STATUS_SUCCESS, 12, { 127, 0, 0, 1 }, strict_diff_4,
1091 STATUS_INVALID_PARAMETER, 1, { -1 } },
1092 { "0777", STATUS_SUCCESS, 4, { 0, 0, 1, 255 }, strict_diff_4,
1093 STATUS_INVALID_PARAMETER, 1, { -1 } },
1094 { "::1", STATUS_INVALID_PARAMETER, 0, { -1 } },
1095 { ":1", STATUS_INVALID_PARAMETER, 0, { -1 } },
1097
1098static void init_ip4(IN_ADDR* addr, const int src[4])
1099{
1100 if (!src || src[0] == -1)
1101 {
1102 addr->S_un.S_addr = 0xabababab;
1103 }
1104 else
1105 {
1106 addr->S_un.S_un_b.s_b1 = src[0];
1107 addr->S_un.S_un_b.s_b2 = src[1];
1108 addr->S_un.S_un_b.s_b3 = src[2];
1109 addr->S_un.S_un_b.s_b4 = src[3];
1110 }
1111}
1112
1114{
1115 NTSTATUS res;
1116 IN_ADDR ip, expected_ip;
1117 PCSTR terminator;
1118 CHAR dummy;
1119 int i;
1120
1121 if (0)
1122 {
1123 /* leaving either parameter NULL crashes on Windows */
1124 res = RtlIpv4StringToAddressA(NULL, FALSE, &terminator, &ip);
1125 res = RtlIpv4StringToAddressA("1.1.1.1", FALSE, NULL, &ip);
1126 res = RtlIpv4StringToAddressA("1.1.1.1", FALSE, &terminator, NULL);
1127 /* same for the wide char version */
1128 /*
1129 res = RtlIpv4StringToAddressW(NULL, FALSE, &terminatorW, &ip);
1130 res = RtlIpv4StringToAddressW(L"1.1.1.1", FALSE, NULL, &ip);
1131 res = RtlIpv4StringToAddressW(L"1.1.1.1", FALSE, &terminatorW, NULL);
1132 */
1133 }
1134
1135 for (i = 0; i < ARRAY_SIZE(ipv4_tests); i++)
1136 {
1137 /* non-strict */
1138 terminator = &dummy;
1139 ip.S_un.S_addr = 0xabababab;
1141 ok(res == ipv4_tests[i].res,
1142 "[%s] res = 0x%08lx, expected 0x%08lx\n",
1145 "[%s] terminator = %p, expected %p\n",
1147
1148 init_ip4(&expected_ip, ipv4_tests[i].ip);
1149 ok(ip.S_un.S_addr == expected_ip.S_un.S_addr,
1150 "[%s] ip = %08lx, expected %08lx\n",
1151 ipv4_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr);
1152
1153 if (!(ipv4_tests[i].flags & strict_diff_4))
1154 {
1155 ipv4_tests[i].res_strict = ipv4_tests[i].res;
1156 ipv4_tests[i].terminator_offset_strict = ipv4_tests[i].terminator_offset;
1157 ipv4_tests[i].ip_strict[0] = ipv4_tests[i].ip[0];
1158 ipv4_tests[i].ip_strict[1] = ipv4_tests[i].ip[1];
1159 ipv4_tests[i].ip_strict[2] = ipv4_tests[i].ip[2];
1160 ipv4_tests[i].ip_strict[3] = ipv4_tests[i].ip[3];
1161 }
1162 /* strict */
1163 terminator = &dummy;
1164 ip.S_un.S_addr = 0xabababab;
1167 "[%s] res = 0x%08lx, expected 0x%08lx\n",
1170 "[%s] terminator = %p, expected %p\n",
1172
1173 init_ip4(&expected_ip, ipv4_tests[i].ip_strict);
1174 ok(ip.S_un.S_addr == expected_ip.S_un.S_addr,
1175 "[%s] ip = %08lx, expected %08lx\n",
1176 ipv4_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr);
1177 }
1178}
1179
1181{
1182 NTSTATUS res;
1183 IN_ADDR ip, expected_ip;
1184 USHORT port;
1185 static const struct
1186 {
1187 PCSTR address;
1188 NTSTATUS res;
1189 int ip[4];
1190 USHORT port;
1191 } ipv4_ex_tests[] =
1192 {
1193 { "", STATUS_INVALID_PARAMETER, { -1 }, 0xdead },
1194 { " ", STATUS_INVALID_PARAMETER, { -1 }, 0xdead },
1195 { "1.1.1.1:", STATUS_INVALID_PARAMETER, { 1, 1, 1, 1 }, 0xdead },
1196 { "1.1.1.1+", STATUS_INVALID_PARAMETER, { 1, 1, 1, 1 }, 0xdead },
1197 { "1.1.1.1:1", STATUS_SUCCESS, { 1, 1, 1, 1 }, 0x100 },
1198 { "256.1.1.1:1", STATUS_INVALID_PARAMETER, { -1 }, 0xdead },
1199 { "-1.1.1.1:1", STATUS_INVALID_PARAMETER, { -1 }, 0xdead },
1200 { "0.0.0.0:0", STATUS_INVALID_PARAMETER, { 0, 0, 0, 0 }, 0xdead },
1201 { "0.0.0.0:1", STATUS_SUCCESS, { 0, 0, 0, 0 }, 0x100 },
1202 { "1.2.3.4:65535", STATUS_SUCCESS, { 1, 2, 3, 4 }, 65535 },
1203 { "1.2.3.4:65536", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead },
1204 { "1.2.3.4:0xffff", STATUS_SUCCESS, { 1, 2, 3, 4 }, 65535 },
1205 { "1.2.3.4:0XfFfF", STATUS_SUCCESS, { 1, 2, 3, 4 }, 65535 },
1206 { "1.2.3.4:011064", STATUS_SUCCESS, { 1, 2, 3, 4 }, 0x3412 },
1207 { "1.2.3.4:1234a", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead },
1208 { "1.2.3.4:1234+", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead },
1209 { "1.2.3.4: 1234", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead },
1210 { "1.2.3.4:\t1234", STATUS_INVALID_PARAMETER, { 1, 2, 3, 4 }, 0xdead },
1211 };
1212 unsigned int i;
1214
1215 if (!pRtlIpv4StringToAddressExA)
1216 {
1217 win_skip("RtlIpv4StringToAddressEx not available\n");
1218 return;
1219 }
1220
1221 /* do not crash, and do not touch the ip / port. */
1222 ip.S_un.S_addr = 0xabababab;
1223 port = 0xdead;
1224 res = pRtlIpv4StringToAddressExA(NULL, FALSE, &ip, &port);
1225 ok(res == STATUS_INVALID_PARAMETER, "[null address] res = 0x%08lx, expected 0x%08lx\n",
1227 ok(ip.S_un.S_addr == 0xabababab, "RtlIpv4StringToAddressExA should not touch the ip!, ip == %lx\n", ip.S_un.S_addr);
1228 ok(port == 0xdead, "RtlIpv4StringToAddressExA should not touch the port!, port == %x\n", port);
1229
1230 port = 0xdead;
1231 res = pRtlIpv4StringToAddressExA("1.1.1.1", FALSE, NULL, &port);
1232 ok(res == STATUS_INVALID_PARAMETER, "[null ip] res = 0x%08lx, expected 0x%08lx\n",
1234 ok(port == 0xdead, "RtlIpv4StringToAddressExA should not touch the port!, port == %x\n", port);
1235
1236 ip.S_un.S_addr = 0xabababab;
1237 port = 0xdead;
1238 res = pRtlIpv4StringToAddressExA("1.1.1.1", FALSE, &ip, NULL);
1239 ok(res == STATUS_INVALID_PARAMETER, "[null port] res = 0x%08lx, expected 0x%08lx\n",
1241 ok(ip.S_un.S_addr == 0xabababab, "RtlIpv4StringToAddressExA should not touch the ip!, ip == %lx\n", ip.S_un.S_addr);
1242 ok(port == 0xdead, "RtlIpv4StringToAddressExA should not touch the port!, port == %x\n", port);
1243
1244 /* first we run the non-ex testcases on the ex function */
1245 for (i = 0; i < ARRAY_SIZE(ipv4_tests); i++)
1246 {
1247 NTSTATUS expect_res = (ipv4_tests[i].flags & ex_fail_4) ? STATUS_INVALID_PARAMETER : ipv4_tests[i].res;
1248
1249 /* non-strict */
1250 port = 0xdead;
1251 ip.S_un.S_addr = 0xabababab;
1252 res = pRtlIpv4StringToAddressExA(ipv4_tests[i].address, FALSE, &ip, &port);
1253 ok(res == expect_res, "[%s] res = 0x%08lx, expected 0x%08lx\n",
1254 ipv4_tests[i].address, res, expect_res);
1255
1256 init_ip4(&expected_ip, ipv4_tests[i].ip);
1257 ok(ip.S_un.S_addr == expected_ip.S_un.S_addr, "[%s] ip = %08lx, expected %08lx\n",
1258 ipv4_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr);
1259
1260 if (!(ipv4_tests[i].flags & strict_diff_4))
1261 {
1262 ipv4_tests[i].res_strict = ipv4_tests[i].res;
1263 ipv4_tests[i].terminator_offset_strict = ipv4_tests[i].terminator_offset;
1264 ipv4_tests[i].ip_strict[0] = ipv4_tests[i].ip[0];
1265 ipv4_tests[i].ip_strict[1] = ipv4_tests[i].ip[1];
1266 ipv4_tests[i].ip_strict[2] = ipv4_tests[i].ip[2];
1267 ipv4_tests[i].ip_strict[3] = ipv4_tests[i].ip[3];
1268 }
1269 /* strict */
1270 expect_res = (ipv4_tests[i].flags & ex_fail_4) ? STATUS_INVALID_PARAMETER : ipv4_tests[i].res_strict;
1271 port = 0xdead;
1272 ip.S_un.S_addr = 0xabababab;
1273 res = pRtlIpv4StringToAddressExA(ipv4_tests[i].address, TRUE, &ip, &port);
1274 ok(res == expect_res, "[%s] res = 0x%08lx, expected 0x%08lx\n",
1275 ipv4_tests[i].address, res, expect_res);
1276
1277 init_ip4(&expected_ip, ipv4_tests[i].ip_strict);
1278 ok(ip.S_un.S_addr == expected_ip.S_un.S_addr, "[%s] ip = %08lx, expected %08lx\n",
1279 ipv4_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr);
1280 }
1281
1282
1283 for (i = 0; i < ARRAY_SIZE(ipv4_ex_tests); i++)
1284 {
1285 /* Strict is only relevant for the ip address, so make sure that it does not influence the port */
1286 for (strict = 0; strict < 2; strict++)
1287 {
1288 ip.S_un.S_addr = 0xabababab;
1289 port = 0xdead;
1290 res = pRtlIpv4StringToAddressExA(ipv4_ex_tests[i].address, strict, &ip, &port);
1291 ok(res == ipv4_ex_tests[i].res, "[%s] res = 0x%08lx, expected 0x%08lx\n",
1292 ipv4_ex_tests[i].address, res, ipv4_ex_tests[i].res);
1293
1294 init_ip4(&expected_ip, ipv4_ex_tests[i].ip);
1295 ok(ip.S_un.S_addr == expected_ip.S_un.S_addr, "[%s] ip = %08lx, expected %08lx\n",
1296 ipv4_ex_tests[i].address, ip.S_un.S_addr, expected_ip.S_un.S_addr);
1297 ok(port == ipv4_ex_tests[i].port, "[%s] port = %u, expected %u\n",
1298 ipv4_ex_tests[i].address, port, ipv4_ex_tests[i].port);
1299 }
1300 }
1301}
1302
1303/* ipv6 addresses based on the set from https://github.com/beaugunderson/javascript-ipv6/tree/master/test/data */
1304static const struct
1305{
1306 PCSTR address;
1307 NTSTATUS res;
1309 int ip[8];
1310 /* win_broken: XP and Vista do not handle this correctly
1311 ex_fail: Ex function does need the string to be terminated, non-Ex does not.
1312 ex_skip: test doesn't make sense for Ex (f.e. it's invalid for non-Ex but valid for Ex) */
1313 enum { normal_6, win_broken_6 = 1, ex_fail_6 = 2, ex_skip_6 = 4, win_extra_zero = 8 } flags;
1314} ipv6_tests[] =
1315{
1316 { "0000:0000:0000:0000:0000:0000:0000:0000", STATUS_SUCCESS, 39,
1317 { 0, 0, 0, 0, 0, 0, 0, 0 } },
1318 { "0000:0000:0000:0000:0000:0000:0000:0001", STATUS_SUCCESS, 39,
1319 { 0, 0, 0, 0, 0, 0, 0, 0x100 } },
1320 { "0:0:0:0:0:0:0:0", STATUS_SUCCESS, 15,
1321 { 0, 0, 0, 0, 0, 0, 0, 0 } },
1322 { "0:0:0:0:0:0:0:1", STATUS_SUCCESS, 15,
1323 { 0, 0, 0, 0, 0, 0, 0, 0x100 } },
1324 { "0:0:0:0:0:0:0::", STATUS_SUCCESS, 15,
1325 { 0, 0, 0, 0, 0, 0, 0, 0 }, win_broken_6 },
1326 { "0:0:0:0:0:0:13.1.68.3", STATUS_SUCCESS, 21,
1327 { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } },
1328 { "0:0:0:0:0:0::", STATUS_SUCCESS, 13,
1329 { 0, 0, 0, 0, 0, 0, 0, 0 } },
1330 { "0:0:0:0:0::", STATUS_SUCCESS, 11,
1331 { 0, 0, 0, 0, 0, 0, 0, 0 } },
1332 { "0:0:0:0:0:FFFF:129.144.52.38", STATUS_SUCCESS, 28,
1333 { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } },
1334 { "0::", STATUS_SUCCESS, 3,
1335 { 0, 0, 0, 0, 0, 0, 0, 0 } },
1336 { "0:1:2:3:4:5:6:7", STATUS_SUCCESS, 15,
1337 { 0, 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700 } },
1338 { "1080:0:0:0:8:800:200c:417a", STATUS_SUCCESS, 26,
1339 { 0x8010, 0, 0, 0, 0x800, 0x8, 0x0c20, 0x7a41 } },
1340 { "0:a:b:c:d:e:f::", STATUS_SUCCESS, 15,
1341 { 0, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00, 0xf00, 0 }, win_broken_6 },
1342 { "1111:2222:3333:4444:5555:6666:123.123.123.123", STATUS_SUCCESS, 45,
1343 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
1344 { "1111:2222:3333:4444:5555:6666:7777:8888", STATUS_SUCCESS, 39,
1345 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } },
1346 { "1111:2222:3333:4444:0x5555:6666:7777:8888", STATUS_INVALID_PARAMETER, 21,
1347 { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } },
1348 { "1111:2222:3333:4444:x555:6666:7777:8888", STATUS_INVALID_PARAMETER, 20,
1349 { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } },
1350 { "1111:2222:3333:4444:0r5555:6666:7777:8888", STATUS_INVALID_PARAMETER, 21,
1351 { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } },
1352 { "1111:2222:3333:4444:r5555:6666:7777:8888", STATUS_INVALID_PARAMETER, 20,
1353 { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } },
1354 { "1111:2222:3333:4444:5555:6666:7777::", STATUS_SUCCESS, 36,
1355 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0 }, win_broken_6 },
1356 { "1111:2222:3333:4444:5555:6666::", STATUS_SUCCESS, 31,
1357 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0 } },
1358 { "1111:2222:3333:4444:5555:6666::8888", STATUS_SUCCESS, 35,
1359 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0x8888 } },
1360 { "1111:2222:3333:4444:5555:6666::7777:8888", STATUS_SUCCESS, 35,
1361 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0x7777 }, ex_fail_6 },
1362 { "1111:2222:3333:4444:5555:6666:7777::8888", STATUS_SUCCESS, 36,
1363 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0 }, ex_fail_6|win_broken_6 },
1364 { "1111:2222:3333:4444:5555::", STATUS_SUCCESS, 26,
1365 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0 } },
1366 { "1111:2222:3333:4444:5555::123.123.123.123", STATUS_SUCCESS, 41,
1367 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0x7b7b, 0x7b7b } },
1368 { "1111:2222:3333:4444:5555::0x1.123.123.123", STATUS_SUCCESS, 27,
1369 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x100 }, ex_fail_6 },
1370 { "1111:2222:3333:4444:5555::0x88", STATUS_SUCCESS, 27,
1371 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8800 }, ex_fail_6 },
1372 { "1111:2222:3333:4444:5555::0X88", STATUS_SUCCESS, 27,
1373 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8800 }, ex_fail_6 },
1374 { "1111:2222:3333:4444:5555::0X", STATUS_SUCCESS, 27,
1375 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0 }, ex_fail_6 },
1376 { "1111:2222:3333:4444:5555::0X88:7777", STATUS_SUCCESS, 27,
1377 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8800 }, ex_fail_6 },
1378 { "1111:2222:3333:4444:5555::0x8888", STATUS_SUCCESS, 27,
1379 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8888 }, ex_fail_6 },
1380 { "1111:2222:3333:4444:5555::0x80000000", STATUS_SUCCESS, 27,
1381 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0xffff }, ex_fail_6 },
1382 { "1111:2222:3333:4444::5555:0x012345678", STATUS_SUCCESS, 27,
1383 { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0, 0x5555, 0x7856 }, ex_fail_6 },
1384 { "1111:2222:3333:4444::5555:0x123456789", STATUS_SUCCESS, 27,
1385 { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0, 0x5555, 0xffff }, ex_fail_6 },
1386 { "1111:2222:3333:4444:5555:6666:0x12345678", STATUS_INVALID_PARAMETER, 31,
1387 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0xabab, 0xabab }, ex_fail_6 },
1388 { "1111:2222:3333:4444:5555:6666:7777:0x80000000", STATUS_SUCCESS, 36,
1389 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0xffff }, ex_fail_6 },
1390 { "1111:2222:3333:4444:5555:6666:7777:0x012345678", STATUS_SUCCESS, 36,
1391 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x7856 }, ex_fail_6 },
1392 { "1111:2222:3333:4444:5555:6666:7777:0x123456789", STATUS_SUCCESS, 36,
1393 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0xffff }, ex_fail_6 },
1394 { "111:222:333:444:555:666:777:0x123456789abcdef0", STATUS_SUCCESS, 29,
1395 { 0x1101, 0x2202, 0x3303, 0x4404, 0x5505, 0x6606, 0x7707, 0xffff }, ex_fail_6 },
1396 { "1111:2222:3333:4444:5555::08888", STATUS_INVALID_PARAMETER, 31,
1397 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0xabab, 0xabab, 0xabab } },
1398 { "1111:2222:3333:4444:5555::08888::", STATUS_INVALID_PARAMETER, 31,
1399 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0xabab, 0xabab, 0xabab } },
1400 { "1111:2222:3333:4444:5555:6666:7777:fffff:", STATUS_INVALID_PARAMETER, 40,
1401 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0xabab } },
1402 { "1111:2222:3333:4444:5555:6666::fffff:", STATUS_INVALID_PARAMETER, 36,
1403 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0xabab, 0xabab } },
1404 { "1111:2222:3333:4444:5555::fffff", STATUS_INVALID_PARAMETER, 31,
1405 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0xabab, 0xabab, 0xabab } },
1406 { "1111:2222:3333:4444::fffff", STATUS_INVALID_PARAMETER, 26,
1407 { 0x1111, 0x2222, 0x3333, 0x4444, 0xabab, 0xabab, 0xabab, 0xabab } },
1408 { "1111:2222:3333::fffff", STATUS_INVALID_PARAMETER, 21,
1409 { 0x1111, 0x2222, 0x3333, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1410 { "1111:2222:3333:4444:5555::7777:8888", STATUS_SUCCESS, 35,
1411 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0x7777, 0x8888 } },
1412 { "1111:2222:3333:4444:5555::8888", STATUS_SUCCESS, 30,
1413 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8888 } },
1414 { "1111::", STATUS_SUCCESS, 6,
1415 { 0x1111, 0, 0, 0, 0, 0, 0, 0 } },
1416 { "1111::123.123.123.123", STATUS_SUCCESS, 21,
1417 { 0x1111, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } },
1418 { "1111::3333:4444:5555:6666:123.123.123.123", STATUS_SUCCESS, 41,
1419 { 0x1111, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
1420 { "1111::3333:4444:5555:6666:7777:8888", STATUS_SUCCESS, 35,
1421 { 0x1111, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } },
1422 { "1111::4444:5555:6666:123.123.123.123", STATUS_SUCCESS, 36,
1423 { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
1424 { "1111::4444:5555:6666:7777:8888", STATUS_SUCCESS, 30,
1425 { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } },
1426 { "1111::5555:6666:123.123.123.123", STATUS_SUCCESS, 31,
1427 { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
1428 { "1111::5555:6666:7777:8888", STATUS_SUCCESS, 25,
1429 { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7777, 0x8888 } },
1430 { "1111::6666:123.123.123.123", STATUS_SUCCESS, 26,
1431 { 0x1111, 0, 0, 0, 0, 0x6666, 0x7b7b, 0x7b7b } },
1432 { "1111::6666:7777:8888", STATUS_SUCCESS, 20,
1433 { 0x1111, 0, 0, 0, 0, 0x6666, 0x7777, 0x8888 } },
1434 { "1111::7777:8888", STATUS_SUCCESS, 15,
1435 { 0x1111, 0, 0, 0, 0, 0, 0x7777, 0x8888 } },
1436 { "1111::8888", STATUS_SUCCESS, 10,
1437 { 0x1111, 0, 0, 0, 0, 0, 0, 0x8888 } },
1438 { "1:2:3:4:5:6:1.2.3.4", STATUS_SUCCESS, 19,
1439 { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x201, 0x403 } },
1440 { "1:2:3:4:5:6:7:8", STATUS_SUCCESS, 15,
1441 { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800 } },
1442 { "1:2:3:4:5:6::", STATUS_SUCCESS, 13,
1443 { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0 } },
1444 { "1:2:3:4:5:6::8", STATUS_SUCCESS, 14,
1445 { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0x800 } },
1446 { "2001:0000:1234:0000:0000:C1C0:ABCD:0876", STATUS_SUCCESS, 39,
1447 { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 } },
1448 { "2001:0000:4136:e378:8000:63bf:3fff:fdd2", STATUS_SUCCESS, 39,
1449 { 0x120, 0, 0x3641, 0x78e3, 0x80, 0xbf63, 0xff3f, 0xd2fd } },
1450 { "2001:0db8:0:0:0:0:1428:57ab", STATUS_SUCCESS, 27,
1451 { 0x120, 0xb80d, 0, 0, 0, 0, 0x2814, 0xab57 } },
1452 { "2001:0db8:1234:ffff:ffff:ffff:ffff:ffff", STATUS_SUCCESS, 39,
1453 { 0x120, 0xb80d, 0x3412, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff } },
1454 { "2001::CE49:7601:2CAD:DFFF:7C94:FFFE", STATUS_SUCCESS, 35,
1455 { 0x120, 0, 0x49ce, 0x176, 0xad2c, 0xffdf, 0x947c, 0xfeff } },
1456 { "2001:db8:85a3::8a2e:370:7334", STATUS_SUCCESS, 28,
1457 { 0x120, 0xb80d, 0xa385, 0, 0, 0x2e8a, 0x7003, 0x3473 } },
1458 { "3ffe:0b00:0000:0000:0001:0000:0000:000a", STATUS_SUCCESS, 39,
1459 { 0xfe3f, 0xb, 0, 0, 0x100, 0, 0, 0xa00 } },
1460 { "::", STATUS_SUCCESS, 2,
1461 { 0, 0, 0, 0, 0, 0, 0, 0 } },
1462 { "::%16", STATUS_SUCCESS, 2,
1463 { 0, 0, 0, 0, 0, 0, 0, 0 } },
1464 { "::/16", STATUS_SUCCESS, 2,
1465 { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 },
1466 { "::01234", STATUS_INVALID_PARAMETER, 7,
1467 { 0, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1468 { "::0", STATUS_SUCCESS, 3,
1469 { 0, 0, 0, 0, 0, 0, 0, 0 } },
1470 { "::0:0", STATUS_SUCCESS, 5,
1471 { 0, 0, 0, 0, 0, 0, 0, 0 } },
1472 { "::0:0:0", STATUS_SUCCESS, 7,
1473 { 0, 0, 0, 0, 0, 0, 0, 0 } },
1474 { "::0:0:0:0", STATUS_SUCCESS, 9,
1475 { 0, 0, 0, 0, 0, 0, 0, 0 } },
1476 { "::0:0:0:0:0", STATUS_SUCCESS, 11,
1477 { 0, 0, 0, 0, 0, 0, 0, 0 } },
1478 { "::0:0:0:0:0:0", STATUS_SUCCESS, 13,
1479 { 0, 0, 0, 0, 0, 0, 0, 0 } },
1480 /* this one and the next one are incorrectly parsed before Windows 11,
1481 it adds one zero too many in front, cutting off the last digit. */
1482 { "::0:0:0:0:0:0:0", STATUS_SUCCESS, 15,
1483 { 0, 0, 0, 0, 0, 0, 0, 0 }, win_broken_6|win_extra_zero },
1484 { "::0:a:b:c:d:e:f", STATUS_SUCCESS, 15,
1485 { 0, 0, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00, 0xf00 }, win_broken_6|win_extra_zero },
1486 { "::123.123.123.123", STATUS_SUCCESS, 17,
1487 { 0, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } },
1488 { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", STATUS_SUCCESS, 39,
1489 { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff } },
1490
1491 { "':10.0.0.1", STATUS_INVALID_PARAMETER, 0,
1492 { -1 } },
1493 { "-1", STATUS_INVALID_PARAMETER, 0,
1494 { -1 } },
1495 { "02001:0000:1234:0000:0000:C1C0:ABCD:0876", STATUS_INVALID_PARAMETER, -1,
1496 { -1 } },
1497 { "2001:00000:1234:0000:0000:C1C0:ABCD:0876", STATUS_INVALID_PARAMETER, -1,
1498 { 0x120, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1499 { "2001:0000:01234:0000:0000:C1C0:ABCD:0876", STATUS_INVALID_PARAMETER, -1,
1500 { 0x120, 0, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1501 { "2001:0000::01234.0", STATUS_INVALID_PARAMETER, -1,
1502 { 0x120, 0, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1503 { "2001:0::b.0", STATUS_SUCCESS, 9,
1504 { 0x120, 0, 0, 0, 0, 0, 0, 0xb00 }, ex_fail_6 },
1505 { "2001::0:b.0", STATUS_SUCCESS, 9,
1506 { 0x120, 0, 0, 0, 0, 0, 0, 0xb00 }, ex_fail_6 },
1507 { "1.2.3.4", STATUS_INVALID_PARAMETER, 7,
1508 { 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1509 { "1.2.3.4:1111::5555", STATUS_INVALID_PARAMETER, 7,
1510 { 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1511 { "1.2.3.4::5555", STATUS_INVALID_PARAMETER, 7,
1512 { 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1513 { "11112222:3333:4444:5555:6666:1.2.3.4", STATUS_INVALID_PARAMETER, -1,
1514 { -1 } },
1515 { "11112222:3333:4444:5555:6666:7777:8888", STATUS_INVALID_PARAMETER, -1,
1516 { -1 } },
1517 { "1111", STATUS_INVALID_PARAMETER, 4,
1518 { -1 } },
1519 { "0x1111", STATUS_INVALID_PARAMETER, 1,
1520 { -1 } },
1521 { "1111:22223333:4444:5555:6666:1.2.3.4", STATUS_INVALID_PARAMETER, -1,
1522 { 0x1111, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1523 { "1111:22223333:4444:5555:6666:7777:8888", STATUS_INVALID_PARAMETER, -1,
1524 { 0x1111, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1525 { "1111:123456789:4444:5555:6666:7777:8888", STATUS_INVALID_PARAMETER, -1,
1526 { 0x1111, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1527 { "1111:1234567890abcdef0:4444:5555:6666:7777:888", STATUS_INVALID_PARAMETER, -1,
1528 { 0x1111, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1529 { "1111:2222:", STATUS_INVALID_PARAMETER, 10,
1530 { 0x1111, 0x2222, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1531 { "1111:2222:1.2.3.4", STATUS_INVALID_PARAMETER, 17,
1532 { 0x1111, 0x2222, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab } },
1533 { "1111:2222:3333", STATUS_INVALID_PARAMETER, 14,
1534 { 0x1111, 0x2222, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1535 { "1111:2222:3333:4444:5555:6666::1.2.3.4", STATUS_SUCCESS, 32,
1536 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0x100 }, ex_fail_6 },
1537 { "1111:2222:3333:4444:5555:6666:7777:1.2.3.4", STATUS_SUCCESS, 36,
1538 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x100 }, ex_fail_6 },
1539 { "1111:2222:3333:4444:5555:6666:7777:8888:", STATUS_SUCCESS, 39,
1540 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, ex_fail_6 },
1541 { "1111:2222:3333:4444:5555:6666:7777:8888:1.2.3.4",STATUS_SUCCESS, 39,
1542 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, ex_fail_6 },
1543 { "1111:2222:3333:4444:5555:6666:7777:8888:9999", STATUS_SUCCESS, 39,
1544 { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, ex_fail_6 },
1545 { "1111:2222:::", STATUS_SUCCESS, 11,
1546 { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 }, ex_fail_6 },
1547 { "1111::5555:", STATUS_INVALID_PARAMETER, 11,
1548 { 0x1111, 0x5555, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1549 { "1111::3333:4444:5555:6666:7777::", STATUS_SUCCESS, 30,
1550 { 0x1111, 0, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777 }, ex_fail_6 },
1551 { "1111:2222:::4444:5555:6666:1.2.3.4", STATUS_SUCCESS, 11,
1552 { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 }, ex_fail_6 },
1553 { "1111::3333::5555:6666:1.2.3.4", STATUS_SUCCESS, 10,
1554 { 0x1111, 0, 0, 0, 0, 0, 0, 0x3333 }, ex_fail_6 },
1555 { "12345::6:7:8", STATUS_INVALID_PARAMETER, -1,
1556 { -1 } },
1557 { "1::001.2.3.4", STATUS_SUCCESS, 12,
1558 { 0x100, 0, 0, 0, 0, 0, 0x201, 0x403 } },
1559 { "1::1.002.3.4", STATUS_SUCCESS, 12,
1560 { 0x100, 0, 0, 0, 0, 0, 0x201, 0x403 } },
1561 { "1::0001.2.3.4", STATUS_INVALID_PARAMETER, -1,
1562 { 0x100, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1563 { "1::1.0002.3.4", STATUS_INVALID_PARAMETER, -1,
1564 { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1565 { "1::1.2.256.4", STATUS_INVALID_PARAMETER, -1,
1566 { 0x100, 0x201, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1567 { "1::1.2.4294967296.4", STATUS_INVALID_PARAMETER, -1,
1568 { 0x100, 0x201, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1569 { "1::1.2.18446744073709551616.4", STATUS_INVALID_PARAMETER, -1,
1570 { 0x100, 0x201, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1571 { "1::1.2.3.256", STATUS_INVALID_PARAMETER, 12,
1572 { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1573 { "1::1.2.3.4294967296", STATUS_INVALID_PARAMETER, 19,
1574 { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1575 { "1::1.2.3.18446744073709551616", STATUS_INVALID_PARAMETER, 29,
1576 { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1577 { "1::1.2.3.300", STATUS_INVALID_PARAMETER, 12,
1578 { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1579 { "1::1.2.3.300.", STATUS_INVALID_PARAMETER, 12,
1580 { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1581 { "1::1.2::1", STATUS_INVALID_PARAMETER, 6,
1582 { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1583 { "1::1.2.3.4::1", STATUS_SUCCESS, 10,
1584 { 0x100, 0, 0, 0, 0, 0, 0x201, 0x403 }, ex_fail_6 },
1585 { "1::1.", STATUS_INVALID_PARAMETER, 5,
1586 { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1587 { "1::1.2", STATUS_INVALID_PARAMETER, 6,
1588 { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1589 { "1::1.2.", STATUS_INVALID_PARAMETER, 7,
1590 { 0x100, 0x201, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1591 { "1::1.2.3", STATUS_INVALID_PARAMETER, 8,
1592 { 0x100, 0x201, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1593 { "1::1.2.3.", STATUS_INVALID_PARAMETER, 9,
1594 { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1595 { "1::1.2.3.4", STATUS_SUCCESS, 10,
1596 { 0x100, 0, 0, 0, 0, 0, 0x201, 0x403 } },
1597 { "1::1.2.3.900", STATUS_INVALID_PARAMETER, 12,
1598 { 0x100, 0x201, 0xab03, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1599 { "1::1.2.300.4", STATUS_INVALID_PARAMETER, -1,
1600 { 0x100, 0x201, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1601 { "1::1.256.3.4", STATUS_INVALID_PARAMETER, -1,
1602 { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1603 { "1::1.256:3.4", STATUS_INVALID_PARAMETER, 8,
1604 { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1605 { "1::1.2a.3.4", STATUS_INVALID_PARAMETER, 6,
1606 { 0x100, 0xab01, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1607 { "1::256.2.3.4", STATUS_INVALID_PARAMETER, -1,
1608 { 0x100, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1609 { "1::1a.2.3.4", STATUS_SUCCESS, 5,
1610 { 0x100, 0, 0, 0, 0, 0, 0, 0x1a00 }, ex_fail_6 },
1611 { "1::2::3", STATUS_SUCCESS, 4,
1612 { 0x100, 0, 0, 0, 0, 0, 0, 0x200 }, ex_fail_6 },
1613 { "2001:0000:1234: 0000:0000:C1C0:ABCD:0876", STATUS_INVALID_PARAMETER, 15,
1614 { 0x120, 0, 0x3412, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1615 { "2001:0000:1234:0000:0000:C1C0:ABCD:0876 0", STATUS_SUCCESS, 39,
1616 { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 }, ex_fail_6 },
1617 { "2001:1:1:1:1:1:255Z255X255Y255", STATUS_INVALID_PARAMETER, 18,
1618 { 0x120, 0x100, 0x100, 0x100, 0x100, 0x100, 0xabab, 0xabab } },
1619 { "2001::FFD3::57ab", STATUS_SUCCESS, 10,
1620 { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff }, ex_fail_6 },
1621 { ":", STATUS_INVALID_PARAMETER, 0,
1622 { -1 } },
1623 { ":1111:2222:3333:4444:5555:6666:1.2.3.4", STATUS_INVALID_PARAMETER, 0,
1624 { -1 } },
1625 { ":1111:2222:3333:4444:5555:6666:7777:8888", STATUS_INVALID_PARAMETER, 0,
1626 { -1 } },
1627 { ":1111::", STATUS_INVALID_PARAMETER, 0,
1628 { -1 } },
1629 { "::-1", STATUS_SUCCESS, 2,
1630 { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 },
1631 { "::12345678", STATUS_INVALID_PARAMETER, 10,
1632 { 0, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1633 { "::123456789", STATUS_INVALID_PARAMETER, 11,
1634 { 0, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1635 { "::1234567890abcdef0", STATUS_INVALID_PARAMETER, 19,
1636 { 0, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab, 0xabab } },
1637 { "::0x80000000", STATUS_SUCCESS, 3,
1638 { 0, 0, 0, 0, 0, 0, 0, 0xffff }, ex_fail_6 },
1639 { "::0x012345678", STATUS_SUCCESS, 3,
1640 { 0, 0, 0, 0, 0, 0, 0, 0x7856 }, ex_fail_6 },
1641 { "::0x123456789", STATUS_SUCCESS, 3,
1642 { 0, 0, 0, 0, 0, 0, 0, 0xffff }, ex_fail_6 },
1643 { "::0x1234567890abcdef0", STATUS_SUCCESS, 3,
1644 { 0, 0, 0, 0, 0, 0, 0, 0xffff }, ex_fail_6 },
1645 { "::.", STATUS_SUCCESS, 2,
1646 { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 },
1647 { "::..", STATUS_SUCCESS, 2,
1648 { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 },
1649 { "::...", STATUS_SUCCESS, 2,
1650 { 0, 0, 0, 0, 0, 0, 0, 0 }, ex_fail_6 },
1651 { "XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:1.2.3.4", STATUS_INVALID_PARAMETER, 0,
1652 { -1 } },
1653 { "[::]", STATUS_INVALID_PARAMETER, 0,
1654 { -1 }, ex_skip_6 },
1656
1657static void init_ip6(IN6_ADDR* addr, const int src[8])
1658{
1659 unsigned int j;
1660 if (!src || src[0] == -1)
1661 {
1662 for (j = 0; j < 8; ++j)
1663 addr->s6_words[j] = 0xabab;
1664 }
1665 else
1666 {
1667 for (j = 0; j < 8; ++j)
1668 addr->s6_words[j] = src[j];
1669 }
1670}
1671
1673{
1674 CHAR buffer[50];
1675 LPCSTR result;
1676 IN6_ADDR ip;
1677 DWORD_PTR len;
1678 static const struct
1679 {
1680 PCSTR address;
1681 int ip[8];
1682 } tests[] =
1683 {
1684 /* ipv4 addresses & ISATAP addresses */
1685 { "::13.1.68.3", { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } },
1686 { "::123.123.123.123", { 0, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } },
1687 { "::ffff", { 0, 0, 0, 0, 0, 0, 0, 0xffff } },
1688 { "::0.1.0.0", { 0, 0, 0, 0, 0, 0, 0x100, 0 } },
1689 { "::ffff:13.1.68.3", { 0, 0, 0, 0, 0, 0xffff, 0x10d, 0x344 } },
1690 { "::feff:d01:4403", { 0, 0, 0, 0, 0, 0xfffe, 0x10d, 0x344 } },
1691 { "::fffe:d01:4403", { 0, 0, 0, 0, 0, 0xfeff, 0x10d, 0x344 } },
1692 { "::100:d01:4403", { 0, 0, 0, 0, 0, 1, 0x10d, 0x344 } },
1693 { "::1:d01:4403", { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } },
1694 { "::1:0:d01:4403", { 0, 0, 0, 0, 0x100, 0, 0x10d, 0x344 } },
1695 { "::fffe:d01:4403", { 0, 0, 0, 0, 0, 0xfeff, 0x10d, 0x344 } },
1696 { "::fffe:0:d01:4403", { 0, 0, 0, 0, 0xfeff, 0, 0x10d, 0x344 } },
1697 { "::ffff:0:4403", { 0, 0, 0, 0, 0, 0xffff, 0, 0x344 } },
1698 { "::ffff:0.1.0.0", { 0, 0, 0, 0, 0, 0xffff, 0x100, 0 } },
1699 { "::ffff:13.1.0.0", { 0, 0, 0, 0, 0, 0xffff, 0x10d, 0 } },
1700 { "::ffff:0:0", { 0, 0, 0, 0, 0, 0xffff, 0, 0 } },
1701 { "::ffff:0:ffff", { 0, 0, 0, 0, 0, 0xffff, 0, 0xffff } },
1702 { "::ffff:0:0.1.0.0", { 0, 0, 0, 0, 0xffff, 0, 0x100, 0 } },
1703 { "::ffff:0:13.1.68.3", { 0, 0, 0, 0, 0xffff, 0, 0x10d, 0x344 } },
1704 { "::ffff:ffff:d01:4403", { 0, 0, 0, 0, 0xffff, 0xffff, 0x10d, 0x344 } },
1705 { "::ffff:0:0:d01:4403", { 0, 0, 0, 0xffff, 0, 0, 0x10d, 0x344 } },
1706 { "::ffff:255.255.255.255", { 0, 0, 0, 0, 0, 0xffff, 0xffff, 0xffff } },
1707 { "::ffff:129.144.52.38", { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } },
1708 { "::5efe:0.0.0.0", { 0, 0, 0, 0, 0, 0xfe5e, 0, 0 } },
1709 { "::5efe:129.144.52.38", { 0, 0, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 } },
1710 { "1111:2222:3333:4444:0:5efe:129.144.52.38", { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } },
1711 { "1111:2222:3333::5efe:129.144.52.38", { 0x1111, 0x2222, 0x3333, 0, 0, 0xfe5e, 0x9081, 0x2634 } },
1712 { "1111:2222::5efe:129.144.52.38", { 0x1111, 0x2222, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 } },
1713 { "1111::5efe:129.144.52.38", { 0x1111, 0, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 } },
1714 { "::300:5efe:8190:3426", { 0, 0, 0, 0, 3, 0xfe5e, 0x9081, 0x2634 } },
1715 { "::200:5efe:129.144.52.38", { 0, 0, 0, 0, 2, 0xfe5e, 0x9081, 0x2634 } },
1716 { "::100:5efe:8190:3426", { 0, 0, 0, 0, 1, 0xfe5e, 0x9081, 0x2634 } },
1717 /* 'normal' addresses */
1718 { "::1", { 0, 0, 0, 0, 0, 0, 0, 0x100 } },
1719 { "::2", { 0, 0, 0, 0, 0, 0, 0, 0x200 } },
1720 { "0:1:2:3:4:5:6:7", { 0, 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700 } },
1721 { "1080::8:800:200c:417a", { 0x8010, 0, 0, 0, 0x800, 0x8, 0x0c20, 0x7a41 } },
1722 { "1111:2222:3333:4444:5555:6666:7b7b:7b7b", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
1723 { "1111:2222:3333:4444:5555:6666:7777:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } },
1724 { "1111:2222:3333:4444:5555:6666::", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0 } },
1725 { "1111:2222:3333:4444:5555:6666:0:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0x8888 } },
1726 { "1111:2222:3333:4444:5555::", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0 } },
1727 { "1111:2222:3333:4444:5555:0:7b7b:7b7b", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0x7b7b, 0x7b7b } },
1728 { "1111:2222:3333:4444:5555:0:7777:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0x7777, 0x8888 } },
1729 { "1111:2222:3333:4444:5555::8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8888 } },
1730 { "1111::", { 0x1111, 0, 0, 0, 0, 0, 0, 0 } },
1731 { "1111::7b7b:7b7b", { 0x1111, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } },
1732 { "1111:0:3333:4444:5555:6666:7b7b:7b7b", { 0x1111, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
1733 { "1111:0:3333:4444:5555:6666:7777:8888", { 0x1111, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } },
1734 { "1111::4444:5555:6666:7b7b:7b7b", { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
1735 { "1111::4444:5555:6666:7777:8888", { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } },
1736 { "1111::5555:6666:7b7b:7b7b", { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
1737 { "1111::5555:6666:7777:8888", { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7777, 0x8888 } },
1738 { "1111::6666:7b7b:7b7b", { 0x1111, 0, 0, 0, 0, 0x6666, 0x7b7b, 0x7b7b } },
1739 { "1111::6666:7777:8888", { 0x1111, 0, 0, 0, 0, 0x6666, 0x7777, 0x8888 } },
1740 { "1111::7777:8888", { 0x1111, 0, 0, 0, 0, 0, 0x7777, 0x8888 } },
1741 { "1111::8888", { 0x1111, 0, 0, 0, 0, 0, 0, 0x8888 } },
1742 { "1:2:3:4:5:6:102:304", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x201, 0x403 } },
1743 { "1:2:3:4:5:6:7:8", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800 } },
1744 { "1:2:3:4:5:6::", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0 } },
1745 { "1:2:3:4:5:6:0:8", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0x800 } },
1746 { "2001:0:1234::c1c0:abcd:876", { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 } },
1747 { "2001:0:4136:e378:8000:63bf:3fff:fdd2", { 0x120, 0, 0x3641, 0x78e3, 0x80, 0xbf63, 0xff3f, 0xd2fd } },
1748 { "2001:db8::1428:57ab", { 0x120, 0xb80d, 0, 0, 0, 0, 0x2814, 0xab57 } },
1749 { "2001:db8:1234:ffff:ffff:ffff:ffff:ffff", { 0x120, 0xb80d, 0x3412, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff } },
1750 { "2001:0:ce49:7601:2cad:dfff:7c94:fffe", { 0x120, 0, 0x49ce, 0x176, 0xad2c, 0xffdf, 0x947c, 0xfeff } },
1751 { "2001:db8:85a3::8a2e:370:7334", { 0x120, 0xb80d, 0xa385, 0, 0, 0x2e8a, 0x7003, 0x3473 } },
1752 { "3ffe:b00::1:0:0:a", { 0xfe3f, 0xb, 0, 0, 0x100, 0, 0, 0xa00 } },
1753 { "::a:b:c:d:e", { 0, 0, 0, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00 } },
1754 { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff } },
1755 { "1111:2222:3333:4444:5555:6666:7777:1", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x100 } },
1756 { "1111:2222:3333:4444:5555:6666:7777:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } },
1757 { "1111:2222::", { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 } },
1758 { "1111::3333:4444:5555:6666:7777", { 0x1111, 0, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777 } },
1759 { "1111:2222::", { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 } },
1760 { "1111::3333", { 0x1111, 0, 0, 0, 0, 0, 0, 0x3333 } },
1761 { "2001:0:1234::c1c0:abcd:876", { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 } },
1762 { "2001::ffd3", { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } },
1763 };
1764 unsigned int i;
1765
1766 memset(buffer, '#', sizeof(buffer));
1767 buffer[sizeof(buffer)-1] = 0;
1768 memset(&ip, 0, sizeof(ip));
1770
1771 len = strlen(buffer);
1772 ok(result == (buffer + len) && !strcmp(buffer, "::"),
1773 "got %p with '%s' (expected %p with '::')\n", result, buffer, buffer + len);
1774
1776 ok(result == (LPCSTR)~0 || broken(result == (LPCSTR)len) /* WinXP / Win2k3 */,
1777 "got %p, expected %p\n", result, (LPCSTR)~0);
1778
1779 for (i = 0; i < ARRAY_SIZE(tests); i++)
1780 {
1781 init_ip6(&ip, tests[i].ip);
1782 memset(buffer, '#', sizeof(buffer));
1783 buffer[sizeof(buffer)-1] = 0;
1784
1786 len = strlen(buffer);
1787 ok(result == (buffer + len) && !strcmp(buffer, tests[i].address),
1788 "got %p with '%s' (expected %p with '%s')\n", result, buffer, buffer + len, tests[i].address);
1789
1790 ok(buffer[45] == 0 || broken(buffer[45] != 0) /* WinXP / Win2k3 */,
1791 "expected data at buffer[45] to always be NULL\n");
1792 ok(buffer[46] == '#', "expected data at buffer[46] not to change\n");
1793 }
1794}
1795
1797{
1798 CHAR buffer[70];
1799 NTSTATUS res;
1800 IN6_ADDR ip;
1801 ULONG len;
1802 static const struct
1803 {
1804 PCSTR address;
1805 ULONG scopeid;
1806 USHORT port;
1807 int ip[8];
1808 } tests[] =
1809 {
1810 /* ipv4 addresses & ISATAP addresses */
1811 { "::13.1.68.3", 0, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } },
1812 { "::13.1.68.3%1", 1, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } },
1813 { "::13.1.68.3%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } },
1814 { "[::13.1.68.3%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } },
1815 { "[::13.1.68.3%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } },
1816 { "[::13.1.68.3]:256", 0, 1, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } },
1817
1818 { "::1:d01:4403", 0, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } },
1819 { "::1:d01:4403%1", 1, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } },
1820 { "::1:d01:4403%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } },
1821 { "[::1:d01:4403%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } },
1822 { "[::1:d01:4403%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } },
1823 { "[::1:d01:4403]:256", 0, 1, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } },
1824
1825 { "1111:2222:3333:4444:0:5efe:129.144.52.38", 0, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } },
1826 { "1111:2222:3333:4444:0:5efe:129.144.52.38%1", 1, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } },
1827 { "1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819", 0xffffbbbb, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } },
1828 { "[1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819]:65518",0xffffbbbb, 0xeeff, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } },
1829 { "[1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819]:256", 0xffffbbbb, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } },
1830 { "[1111:2222:3333:4444:0:5efe:129.144.52.38]:256", 0, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } },
1831
1832 { "::1", 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 } },
1833 { "::1%1", 1, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 } },
1834 { "::1%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 } },
1835 { "[::1%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0, 0, 0x100 } },
1836 { "[::1%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0, 0, 0x100 } },
1837 { "[::1]:256", 0, 1, { 0, 0, 0, 0, 0, 0, 0, 0x100 } },
1838
1839 { "1111:2222:3333:4444:5555:6666:7b7b:7b7b", 0, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
1840 { "1111:2222:3333:4444:5555:6666:7b7b:7b7b%1", 1, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
1841 { "1111:2222:3333:4444:5555:6666:7b7b:7b7b%4294949819", 0xffffbbbb, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
1842 { "[1111:2222:3333:4444:5555:6666:7b7b:7b7b%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
1843 { "[1111:2222:3333:4444:5555:6666:7b7b:7b7b%4294949819]:256", 0xffffbbbb, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
1844 { "[1111:2222:3333:4444:5555:6666:7b7b:7b7b]:256", 0, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
1845
1846 { "1111::", 0, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } },
1847 { "1111::%1", 1, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } },
1848 { "1111::%4294949819", 0xffffbbbb, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } },
1849 { "[1111::%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } },
1850 { "[1111::%4294949819]:256", 0xffffbbbb, 1, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } },
1851 { "[1111::]:256", 0, 1, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } },
1852
1853 { "2001::ffd3", 0, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } },
1854 { "2001::ffd3%1", 1, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } },
1855 { "2001::ffd3%4294949819", 0xffffbbbb, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } },
1856 { "[2001::ffd3%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } },
1857 { "[2001::ffd3%4294949819]:256", 0xffffbbbb, 1, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } },
1858 { "[2001::ffd3]:256", 0, 1, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } },
1859 };
1860 unsigned int i;
1861
1862 if (!pRtlIpv6AddressToStringExA)
1863 {
1864 win_skip("RtlIpv6AddressToStringExA not available\n");
1865 return;
1866 }
1867
1868 memset(buffer, '#', sizeof(buffer));
1869 buffer[sizeof(buffer)-1] = 0;
1870 memset(&ip, 0, sizeof(ip));
1871 len = sizeof(buffer);
1872 res = pRtlIpv6AddressToStringExA(&ip, 0, 0, buffer, &len);
1873
1874 ok(res == STATUS_SUCCESS, "[validate] res = 0x%08lx, expected STATUS_SUCCESS\n", res);
1875 ok(len == 3 && !strcmp(buffer, "::"),
1876 "got len %ld with '%s' (expected 3 with '::')\n", len, buffer);
1877
1878 memset(buffer, '#', sizeof(buffer));
1879 buffer[sizeof(buffer)-1] = 0;
1880
1881 len = sizeof(buffer);
1882 res = pRtlIpv6AddressToStringExA(NULL, 0, 0, buffer, &len);
1883 ok(res == STATUS_INVALID_PARAMETER, "[null ip] res = 0x%08lx, expected STATUS_INVALID_PARAMETER\n", res);
1884
1885 len = sizeof(buffer);
1886 res = pRtlIpv6AddressToStringExA(&ip, 0, 0, NULL, &len);
1887 ok(res == STATUS_INVALID_PARAMETER, "[null buffer] res = 0x%08lx, expected STATUS_INVALID_PARAMETER\n", res);
1888
1889 res = pRtlIpv6AddressToStringExA(&ip, 0, 0, buffer, NULL);
1890 ok(res == STATUS_INVALID_PARAMETER, "[null length] res = 0x%08lx, expected STATUS_INVALID_PARAMETER\n", res);
1891
1892 len = 2;
1893 memset(buffer, '#', sizeof(buffer));
1894 buffer[sizeof(buffer)-1] = 0;
1895 res = pRtlIpv6AddressToStringExA(&ip, 0, 0, buffer, &len);
1896 ok(res == STATUS_INVALID_PARAMETER, "[null length] res = 0x%08lx, expected STATUS_INVALID_PARAMETER\n", res);
1897 ok(buffer[0] == '#', "got first char %c (expected '#')\n", buffer[0]);
1898 ok(len == 3, "got len %ld (expected len 3)\n", len);
1899
1900 for (i = 0; i < ARRAY_SIZE(tests); i++)
1901 {
1902 init_ip6(&ip, tests[i].ip);
1903 len = sizeof(buffer);
1904 memset(buffer, '#', sizeof(buffer));
1905 buffer[sizeof(buffer)-1] = 0;
1906
1907 res = pRtlIpv6AddressToStringExA(&ip, tests[i].scopeid, tests[i].port, buffer, &len);
1908
1909 ok(res == STATUS_SUCCESS, "[validate] res = 0x%08lx, expected STATUS_SUCCESS\n", res);
1910 ok(len == (strlen(tests[i].address) + 1) && !strcmp(buffer, tests[i].address),
1911 "got len %ld with '%s' (expected %d with '%s')\n", len, buffer, (int)strlen(tests[i].address), tests[i].address);
1912 }
1913}
1914
1915static void compare_RtlIpv6StringToAddressW(PCSTR name_a, int terminator_offset_a,
1916 const struct in6_addr *addr_a, NTSTATUS res_a)
1917{
1918 WCHAR name[512];
1919 NTSTATUS res;
1920 IN6_ADDR ip;
1921 PCWSTR terminator;
1922
1923 RtlMultiByteToUnicodeN(name, sizeof(name), NULL, name_a, strlen(name_a) + 1);
1924
1925 init_ip6(&ip, NULL);
1926 terminator = (void *)0xdeadbeef;
1927 res = RtlIpv6StringToAddressW(name, &terminator, &ip);
1928 ok(res == res_a, "[W:%s] res = 0x%08lx, expected 0x%08lx\n", name_a, res, res_a);
1929
1930 if (terminator_offset_a < 0)
1931 {
1932 ok(terminator == (void *)0xdeadbeef,
1933 "[W:%s] terminator = %p, expected it not to change\n",
1934 name_a, terminator);
1935 }
1936 else
1937 {
1938 ok(terminator == name + terminator_offset_a,
1939 "[W:%s] terminator = %p, expected %p\n",
1940 name_a, terminator, name + terminator_offset_a);
1941 }
1942
1943 ok(!memcmp(&ip, addr_a, sizeof(ip)),
1944 "[W:%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n",
1945 name_a,
1946 ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3],
1947 ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7],
1948 addr_a->s6_words[0], addr_a->s6_words[1], addr_a->s6_words[2], addr_a->s6_words[3],
1949 addr_a->s6_words[4], addr_a->s6_words[5], addr_a->s6_words[6], addr_a->s6_words[7]);
1950}
1951
1953{
1954 NTSTATUS res;
1955 IN6_ADDR ip, expected_ip;
1956 PCSTR terminator;
1957 unsigned int i;
1958
1959 res = RtlIpv6StringToAddressA("::", &terminator, &ip);
1960 ok(res == STATUS_SUCCESS, "[validate] res = 0x%08lx, expected STATUS_SUCCESS\n", res);
1961 if (0)
1962 {
1963 /* any of these crash */
1964 res = RtlIpv6StringToAddressA(NULL, &terminator, &ip);
1965 ok(res == STATUS_INVALID_PARAMETER, "[null string] res = 0x%08lx, expected STATUS_INVALID_PARAMETER\n", res);
1967 ok(res == STATUS_INVALID_PARAMETER, "[null terminator] res = 0x%08lx, expected STATUS_INVALID_PARAMETER\n", res);
1968 res = RtlIpv6StringToAddressA("::", &terminator, NULL);
1969 ok(res == STATUS_INVALID_PARAMETER, "[null result] res = 0x%08lx, expected STATUS_INVALID_PARAMETER\n", res);
1970 }
1971
1972 /* sanity check */
1973 ok(sizeof(ip) == sizeof(USHORT)* 8, "sizeof(ip)\n");
1974
1975 for (i = 0; i < ARRAY_SIZE(ipv6_tests); i++)
1976 {
1977 init_ip6(&ip, NULL);
1978 terminator = (void *)0xdeadbeef;
1979 res = RtlIpv6StringToAddressA(ipv6_tests[i].address, &terminator, &ip);
1980 compare_RtlIpv6StringToAddressW(ipv6_tests[i].address, (terminator != (void *)0xdeadbeef) ?
1981 (terminator - ipv6_tests[i].address) : -1, &ip, res);
1982
1983 if (ipv6_tests[i].flags & win_broken_6)
1984 {
1986 "[%s] res = 0x%08lx, expected 0x%08lx\n",
1988
1990 continue;
1991 }
1992 else
1993 {
1994 ok(res == ipv6_tests[i].res,
1995 "[%s] res = 0x%08lx, expected 0x%08lx\n",
1997 }
1998
2000 {
2001 ok(terminator == (void *)0xdeadbeef,
2002 "[%s] terminator = %p, expected it not to change\n",
2003 ipv6_tests[i].address, terminator);
2004 }
2005 else
2006 {
2007 if (ipv6_tests[i].flags & win_extra_zero)
2008 ok(terminator == ipv6_tests[i].address + ipv6_tests[i].terminator_offset ||
2010 "[%s] terminator = %p, expected %p\n",
2012 else
2014 "[%s] terminator = %p, expected %p\n",
2016 }
2017
2018 init_ip6(&expected_ip, ipv6_tests[i].ip);
2019 if (ipv6_tests[i].flags & win_extra_zero)
2020 ok(!memcmp(&ip, &expected_ip, sizeof(ip)) || broken(memcmp(&ip, &expected_ip, sizeof(ip))),
2021 "[%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n",
2022 ipv6_tests[i].address, ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3],
2023 ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7],
2024 expected_ip.s6_words[0], expected_ip.s6_words[1], expected_ip.s6_words[2], expected_ip.s6_words[3],
2025 expected_ip.s6_words[4], expected_ip.s6_words[5], expected_ip.s6_words[6], expected_ip.s6_words[7]);
2026 else
2027 ok(!memcmp(&ip, &expected_ip, sizeof(ip)),
2028 "[%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n",
2029 ipv6_tests[i].address, ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3],
2030 ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7],
2031 expected_ip.s6_words[0], expected_ip.s6_words[1], expected_ip.s6_words[2], expected_ip.s6_words[3],
2032 expected_ip.s6_words[4], expected_ip.s6_words[5], expected_ip.s6_words[6], expected_ip.s6_words[7]);
2033 }
2034}
2035
2036static void compare_RtlIpv6StringToAddressExW(PCSTR name_a, const struct in6_addr *addr_a, HRESULT res_a, ULONG scope_a, USHORT port_a)
2037{
2038 WCHAR name[512];
2039 NTSTATUS res;
2040 IN6_ADDR ip;
2041 ULONG scope = 0xbadf00d;
2042 USHORT port = 0xbeef;
2043
2044 if (!pRtlIpv6StringToAddressExW)
2045 return;
2046
2047 RtlMultiByteToUnicodeN(name, sizeof(name), NULL, name_a, strlen(name_a) + 1);
2048
2049 init_ip6(&ip, NULL);
2050 res = pRtlIpv6StringToAddressExW(name, &ip, &scope, &port);
2051
2052 ok(res == res_a, "[W:%s] res = 0x%08lx, expected 0x%08lx\n", name_a, res, res_a);
2053 ok(scope == scope_a, "[W:%s] scope = 0x%08lx, expected 0x%08lx\n", name_a, scope, scope_a);
2054 ok(port == port_a, "[W:%s] port = 0x%08x, expected 0x%08x\n", name_a, port, port_a);
2055
2056 ok(!memcmp(&ip, addr_a, sizeof(ip)),
2057 "[W:%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n",
2058 name_a,
2059 ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3],
2060 ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7],
2061 addr_a->s6_words[0], addr_a->s6_words[1], addr_a->s6_words[2], addr_a->s6_words[3],
2062 addr_a->s6_words[4], addr_a->s6_words[5], addr_a->s6_words[6], addr_a->s6_words[7]);
2063}
2064
2066{
2067 NTSTATUS res;
2068 IN6_ADDR ip, expected_ip;
2069 ULONG scope;
2070 USHORT port;
2071 static const struct
2072 {
2073 PCSTR address;
2074 NTSTATUS res;
2075 ULONG scope;
2076 USHORT port;
2077 int ip[8];
2078 } ipv6_ex_tests[] =
2079 {
2080 { "[::]", STATUS_SUCCESS, 0, 0,
2081 { 0, 0, 0, 0, 0, 0, 0, 0 } },
2082 { "[::1]:8080", STATUS_SUCCESS, 0, 0x901f,
2083 { 0, 0, 0, 0, 0, 0, 0, 0x100 } },
2084 { "[::1]:0x80", STATUS_SUCCESS, 0, 0x8000,
2085 { 0, 0, 0, 0, 0, 0, 0, 0x100 } },
2086 { "[::1]:0X80", STATUS_SUCCESS, 0, 0x8000,
2087 { 0, 0, 0, 0, 0, 0, 0, 0x100 } },
2088 { "[::1]:080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2089 { 0, 0, 0, 0, 0, 0, 0, 0x100 } },
2090 { "[::1]:800000000080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2091 { 0, 0, 0, 0, 0, 0, 0, 0x100 } },
2092 { "[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80", STATUS_SUCCESS, 0, 0x5000,
2093 { 0xdcfe, 0x98ba, 0x5476, 0x1032, 0xdcfe, 0x98ba, 0x5476, 0x1032 } },
2094 { "[1080:0:0:0:8:800:200C:417A]:1234", STATUS_SUCCESS, 0, 0xd204,
2095 { 0x8010, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2096 { "[3ffe:2a00:100:7031::1]:8080", STATUS_SUCCESS, 0, 0x901f,
2097 { 0xfe3f, 0x2a, 1, 0x3170, 0, 0, 0, 0x100 } },
2098 { "[ 3ffe:2a00:100:7031::1]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2099 { -1 } },
2100 { "[3ffe:2a00:100:7031::1 ]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2101 { 0xfe3f, 0x2a, 1, 0x3170, 0, 0, 0, 0x100 } },
2102 { "[3ffe:2a00:100:7031::1].8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2103 { 0xfe3f, 0x2a, 1, 0x3170, 0, 0, 0, 0x100 } },
2104 { "[1080::8:800:200C:417A]:8080", STATUS_SUCCESS, 0, 0x901f,
2105 { 0x8010, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2106 { "[1080::8:800:200C:417A]!8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2107 { 0x8010, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2108 { "[::FFFF:129.144.52.38]:80", STATUS_SUCCESS, 0, 0x5000,
2109 { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } },
2110 { "[::FFFF:129.144.52.38]:-80", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2111 { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } },
2112 { "[::FFFF:129.144.52.38]:999999999999", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2113 { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } },
2114 { "[::FFFF:129.144.52.38%-8]:80", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2115 { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } },
2116 { "[::FFFF:129.144.52.38]:80", STATUS_SUCCESS, 0, 0x5000,
2117 { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } },
2118 { "[12345::6:7:8]:80", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2119 { -1 } },
2120 { "[ff01::8:800:200C:417A%16]:8080", STATUS_SUCCESS, 16, 0x901f,
2121 { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2122 { "[ff01::8:800:200C:417A%100]:8080", STATUS_SUCCESS, 100, 0x901f,
2123 { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2124 { "[ff01::8:800:200C:417A%1000]:8080", STATUS_SUCCESS, 1000, 0x901f,
2125 { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2126 { "[ff01::8:800:200C:417A%10000]:8080", STATUS_SUCCESS, 10000, 0x901f,
2127 { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2128 { "[ff01::8:800:200C:417A%1000000]:8080", STATUS_SUCCESS, 1000000, 0x901f,
2129 { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2130 { "[ff01::8:800:200C:417A%4294967295]:8080", STATUS_SUCCESS, 0xffffffff, 0x901f,
2131 { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2132 { "[ff01::8:800:200C:417A%4294967296]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2133 { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2134 { "[ff01::8:800:200C:417A%-1]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2135 { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2136 { "[ff01::8:800:200C:417A%0]:8080", STATUS_SUCCESS, 0, 0x901f,
2137 { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2138 { "[ff01::8:800:200C:417A%1", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2139 { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2140 { "[ff01::8:800:200C:417A%0x1000]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2141 { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2142 { "[ff01::8:800:200C:417A/16]:8080", STATUS_INVALID_PARAMETER, 0xbadf00d, 0xbeef,
2143 { 0x1ff, 0, 0, 0, 0x800, 8, 0xc20, 0x7a41 } },
2144 };
2145 const char *simple_ip = "::";
2146 unsigned int i;
2147
2148 if (!pRtlIpv6StringToAddressExW)
2149 {
2150 win_skip("RtlIpv6StringToAddressExW not available\n");
2151 /* we can continue, just not test W */
2152 }
2153
2154 if (!pRtlIpv6StringToAddressExA)
2155 {
2156 win_skip("RtlIpv6StringToAddressExA not available\n");
2157 return;
2158 }
2159
2160 res = pRtlIpv6StringToAddressExA(simple_ip, &ip, &scope, &port);
2161 ok(res == STATUS_SUCCESS, "[validate] res = 0x%08lx, expected STATUS_SUCCESS\n", res);
2162
2163 init_ip6(&ip, NULL);
2164 init_ip6(&expected_ip, NULL);
2165 scope = 0xbadf00d;
2166 port = 0xbeef;
2167 res = pRtlIpv6StringToAddressExA(NULL, &ip, &scope, &port);
2169 "[null string] res = 0x%08lx, expected STATUS_INVALID_PARAMETER\n", res);
2170 ok(scope == 0xbadf00d, "[null string] scope = 0x%08lx, expected 0xbadf00d\n", scope);
2171 ok(port == 0xbeef, "[null string] port = 0x%08x, expected 0xbeef\n", port);
2172 ok(!memcmp(&ip, &expected_ip, sizeof(ip)),
2173 "[null string] ip is changed, expected it not to change\n");
2174
2175
2176 init_ip6(&ip, NULL);
2177 scope = 0xbadf00d;
2178 port = 0xbeef;
2179 res = pRtlIpv6StringToAddressExA(simple_ip, NULL, &scope, &port);
2181 "[null result] res = 0x%08lx, expected STATUS_INVALID_PARAMETER\n", res);
2182 ok(scope == 0xbadf00d, "[null result] scope = 0x%08lx, expected 0xbadf00d\n", scope);
2183 ok(port == 0xbeef, "[null result] port = 0x%08x, expected 0xbeef\n", port);
2184 ok(!memcmp(&ip, &expected_ip, sizeof(ip)),
2185 "[null result] ip is changed, expected it not to change\n");
2186
2187 init_ip6(&ip, NULL);
2188 scope = 0xbadf00d;
2189 port = 0xbeef;
2190 res = pRtlIpv6StringToAddressExA(simple_ip, &ip, NULL, &port);
2192 "[null scope] res = 0x%08lx, expected STATUS_INVALID_PARAMETER\n", res);
2193 ok(scope == 0xbadf00d, "[null scope] scope = 0x%08lx, expected 0xbadf00d\n", scope);
2194 ok(port == 0xbeef, "[null scope] port = 0x%08x, expected 0xbeef\n", port);
2195 ok(!memcmp(&ip, &expected_ip, sizeof(ip)),
2196 "[null scope] ip is changed, expected it not to change\n");
2197
2198 init_ip6(&ip, NULL);
2199 scope = 0xbadf00d;
2200 port = 0xbeef;
2201 res = pRtlIpv6StringToAddressExA(simple_ip, &ip, &scope, NULL);
2203 "[null port] res = 0x%08lx, expected STATUS_INVALID_PARAMETER\n", res);
2204 ok(scope == 0xbadf00d, "[null port] scope = 0x%08lx, expected 0xbadf00d\n", scope);
2205 ok(port == 0xbeef, "[null port] port = 0x%08x, expected 0xbeef\n", port);
2206 ok(!memcmp(&ip, &expected_ip, sizeof(ip)),
2207 "[null port] ip is changed, expected it not to change\n");
2208
2209 /* sanity check */
2210 ok(sizeof(ip) == sizeof(USHORT)* 8, "sizeof(ip)\n");
2211
2212 /* first we run all ip related tests, to make sure someone didn't accidentally reimplement instead of re-use. */
2213 for (i = 0; i < ARRAY_SIZE(ipv6_tests); i++)
2214 {
2215 ULONG scope = 0xbadf00d;
2216 USHORT port = 0xbeef;
2217 NTSTATUS expect_ret = (ipv6_tests[i].flags & ex_fail_6) ? STATUS_INVALID_PARAMETER : ipv6_tests[i].res;
2218
2219 if (ipv6_tests[i].flags & ex_skip_6)
2220 continue;
2221
2222 init_ip6(&ip, NULL);
2223 res = pRtlIpv6StringToAddressExA(ipv6_tests[i].address, &ip, &scope, &port);
2225
2226 /* make sure nothing was changed if this function fails. */
2228 {
2229 ok(scope == 0xbadf00d, "[%s] scope = 0x%08lx, expected 0xbadf00d\n",
2230 ipv6_tests[i].address, scope);
2231 ok(port == 0xbeef, "[%s] port = 0x%08x, expected 0xbeef\n",
2233 }
2234 else
2235 {
2236 ok(scope != 0xbadf00d, "[%s] scope = 0x%08lx, not expected 0xbadf00d\n",
2237 ipv6_tests[i].address, scope);
2238 ok(port != 0xbeef, "[%s] port = 0x%08x, not expected 0xbeef\n",
2240 }
2241
2242 if (ipv6_tests[i].flags & win_broken_6)
2243 {
2244 ok(res == expect_ret || broken(res == STATUS_INVALID_PARAMETER),
2245 "[%s] res = 0x%08lx, expected 0x%08lx\n", ipv6_tests[i].address, res, expect_ret);
2246
2248 continue;
2249 }
2250 else
2251 {
2252 ok(res == expect_ret, "[%s] res = 0x%08lx, expected 0x%08lx\n",
2253 ipv6_tests[i].address, res, expect_ret);
2254 }
2255
2256 /* If ex fails but non-ex does not we cannot check if the part that is converted
2257 before it failed was correct, since there is no data for it in the table. */
2258 if (res == expect_ret)
2259 {
2260 init_ip6(&expected_ip, ipv6_tests[i].ip);
2261 ok(!memcmp(&ip, &expected_ip, sizeof(ip)),
2262 "[%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n",
2264 ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3],
2265 ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7],
2266 expected_ip.s6_words[0], expected_ip.s6_words[1], expected_ip.s6_words[2], expected_ip.s6_words[3],
2267 expected_ip.s6_words[4], expected_ip.s6_words[5], expected_ip.s6_words[6], expected_ip.s6_words[7]);
2268 }
2269 }
2270
2271 /* now we run scope / port related tests */
2272 for (i = 0; i < ARRAY_SIZE(ipv6_ex_tests); i++)
2273 {
2274 scope = 0xbadf00d;
2275 port = 0xbeef;
2276 init_ip6(&ip, NULL);
2277 res = pRtlIpv6StringToAddressExA(ipv6_ex_tests[i].address, &ip, &scope, &port);
2278 compare_RtlIpv6StringToAddressExW(ipv6_ex_tests[i].address, &ip, res, scope, port);
2279
2280 ok(res == ipv6_ex_tests[i].res, "[%s] res = 0x%08lx, expected 0x%08lx\n",
2281 ipv6_ex_tests[i].address, res, ipv6_ex_tests[i].res);
2282 ok(scope == ipv6_ex_tests[i].scope, "[%s] scope = 0x%08lx, expected 0x%08lx\n",
2283 ipv6_ex_tests[i].address, scope, ipv6_ex_tests[i].scope);
2284 ok(port == ipv6_ex_tests[i].port, "[%s] port = 0x%08x, expected 0x%08x\n",
2285 ipv6_ex_tests[i].address, port, ipv6_ex_tests[i].port);
2286
2287 init_ip6(&expected_ip, ipv6_ex_tests[i].ip);
2288 ok(!memcmp(&ip, &expected_ip, sizeof(ip)),
2289 "[%s] ip = %x:%x:%x:%x:%x:%x:%x:%x, expected %x:%x:%x:%x:%x:%x:%x:%x\n",
2290 ipv6_ex_tests[i].address,
2291 ip.s6_words[0], ip.s6_words[1], ip.s6_words[2], ip.s6_words[3],
2292 ip.s6_words[4], ip.s6_words[5], ip.s6_words[6], ip.s6_words[7],
2293 expected_ip.s6_words[0], expected_ip.s6_words[1], expected_ip.s6_words[2], expected_ip.s6_words[3],
2294 expected_ip.s6_words[4], expected_ip.s6_words[5], expected_ip.s6_words[6], expected_ip.s6_words[7]);
2295 }
2296}
2297
2298static void test_LdrAddRefDll(void)
2299{
2300 HMODULE mod, mod2;
2302 BOOL ret;
2303
2304 mod = LoadLibraryA("comctl32.dll");
2305 ok(mod != NULL, "got %p\n", mod);
2306 ret = FreeLibrary(mod);
2307 ok(ret, "got %d\n", ret);
2308
2309 mod2 = GetModuleHandleA("comctl32.dll");
2310 ok(mod2 == NULL, "got %p\n", mod2);
2311
2312 /* load, addref and release 2 times */
2313 mod = LoadLibraryA("comctl32.dll");
2314 ok(mod != NULL, "got %p\n", mod);
2315 status = LdrAddRefDll(0, mod);
2316 ok(status == STATUS_SUCCESS, "got 0x%08lx\n", status);
2317 ret = FreeLibrary(mod);
2318 ok(ret, "got %d\n", ret);
2319
2320 mod2 = GetModuleHandleA("comctl32.dll");
2321 ok(mod2 != NULL, "got %p\n", mod2);
2322 ret = FreeLibrary(mod);
2323 ok(ret, "got %d\n", ret);
2324
2325 mod2 = GetModuleHandleA("comctl32.dll");
2326 ok(mod2 == NULL, "got %p\n", mod2);
2327
2328 /* pin refcount */
2329 mod = LoadLibraryA("comctl32.dll");
2330 ok(mod != NULL, "got %p\n", mod);
2332 ok(status == STATUS_SUCCESS, "got 0x%08lx\n", status);
2333
2334 ret = FreeLibrary(mod);
2335 ok(ret, "got %d\n", ret);
2336 ret = FreeLibrary(mod);
2337 ok(ret, "got %d\n", ret);
2338 ret = FreeLibrary(mod);
2339 ok(ret, "got %d\n", ret);
2340 ret = FreeLibrary(mod);
2341 ok(ret, "got %d\n", ret);
2342
2343 mod2 = GetModuleHandleA("comctl32.dll");
2344 ok(mod2 != NULL, "got %p\n", mod2);
2345}
2346
2347static void test_LdrLockLoaderLock(void)
2348{
2349 ULONG_PTR magic;
2350 ULONG result;
2352
2353 /* invalid flags */
2354 result = 10;
2355 magic = 0xdeadbeef;
2356 status = LdrLockLoaderLock(0x10, &result, &magic);
2357 ok(status == STATUS_INVALID_PARAMETER_1, "got 0x%08lx\n", status);
2358 ok(result == 0, "got %ld\n", result);
2359 ok(magic == 0, "got %Ix\n", magic);
2360
2361 magic = 0xdeadbeef;
2362 status = LdrLockLoaderLock(0x10, NULL, &magic);
2363 ok(status == STATUS_INVALID_PARAMETER_1, "got 0x%08lx\n", status);
2364 ok(magic == 0, "got %Ix\n", magic);
2365
2366 result = 10;
2368 ok(status == STATUS_INVALID_PARAMETER_1, "got 0x%08lx\n", status);
2369 ok(result == 0, "got %ld\n", result);
2370
2371 /* non-blocking mode, result is null */
2372 magic = 0xdeadbeef;
2373 status = LdrLockLoaderLock(0x2, NULL, &magic);
2374 ok(status == STATUS_INVALID_PARAMETER_2, "got 0x%08lx\n", status);
2375 ok(magic == 0, "got %Ix\n", magic);
2376
2377 /* magic pointer is null */
2378 result = 10;
2380 ok(status == STATUS_INVALID_PARAMETER_3, "got 0x%08lx\n", status);
2381 ok(result == 0, "got %ld\n", result);
2382
2383 /* lock in non-blocking mode */
2384 result = 0;
2385 magic = 0;
2386 status = LdrLockLoaderLock(0x2, &result, &magic);
2387 ok(status == STATUS_SUCCESS, "got 0x%08lx\n", status);
2388 ok(result == 1, "got %ld\n", result);
2389 ok(magic != 0, "got %Ix\n", magic);
2390 LdrUnlockLoaderLock(0, magic);
2391}
2392
2393static void test_RtlCompressBuffer(void)
2394{
2395 ULONG compress_workspace, decompress_workspace;
2396 static UCHAR test_buffer[] = "WineWineWine";
2397 static UCHAR buf1[0x1000], buf2[0x1000];
2398 ULONG final_size, buf_size;
2399 UCHAR *workspace = NULL;
2401
2402 compress_workspace = decompress_workspace = 0xdeadbeef;
2404 &decompress_workspace);
2405 ok(status == STATUS_SUCCESS, "got wrong status 0x%08lx\n", status);
2406 ok(compress_workspace != 0, "got wrong compress_workspace %lu\n", compress_workspace);
2407 workspace = HeapAlloc(GetProcessHeap(), 0, compress_workspace);
2408 ok(workspace != NULL, "HeapAlloc failed %ld\n", GetLastError());
2409
2410 /* test compression format / engine */
2411 final_size = 0xdeadbeef;
2413 buf1, sizeof(buf1) - 1, 4096, &final_size, workspace);
2414 ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08lx\n", status);
2415 ok(final_size == 0xdeadbeef, "got wrong final_size %lu\n", final_size);
2416
2417 final_size = 0xdeadbeef;
2419 buf1, sizeof(buf1) - 1, 4096, &final_size, workspace);
2420 ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08lx\n", status);
2421 ok(final_size == 0xdeadbeef, "got wrong final_size %lu\n", final_size);
2422
2423 final_size = 0xdeadbeef;
2425 buf1, sizeof(buf1) - 1, 4096, &final_size, workspace);
2426 ok(status == STATUS_UNSUPPORTED_COMPRESSION, "got wrong status 0x%08lx\n", status);
2427 ok(final_size == 0xdeadbeef, "got wrong final_size %lu\n", final_size);
2428
2429 /* test compression */
2430 final_size = 0xdeadbeef;
2431 memset(buf1, 0x11, sizeof(buf1));
2433 buf1, sizeof(buf1), 4096, &final_size, workspace);
2434 ok(status == STATUS_SUCCESS, "got wrong status 0x%08lx\n", status);
2435 ok((*(WORD *)buf1 & 0x7000) == 0x3000, "no chunk signature found %04x\n", *(WORD *)buf1);
2436 todo_wine
2437 ok(final_size < sizeof(test_buffer), "got wrong final_size %lu\n", final_size);
2438
2439 /* test decompression */
2440 buf_size = final_size;
2441 final_size = 0xdeadbeef;
2442 memset(buf2, 0x11, sizeof(buf2));
2444 buf1, buf_size, &final_size);
2445 ok(status == STATUS_SUCCESS, "got wrong status 0x%08lx\n", status);
2446 ok(final_size == sizeof(test_buffer), "got wrong final_size %lu\n", final_size);
2447 ok(!memcmp(buf2, test_buffer, sizeof(test_buffer)), "got wrong decoded data\n");
2448 ok(buf2[sizeof(test_buffer)] == 0x11, "too many bytes written\n");
2449
2450 /* buffer too small */
2451 final_size = 0xdeadbeef;
2452 memset(buf1, 0x11, sizeof(buf1));
2454 buf1, 4, 4096, &final_size, workspace);
2455 ok(status == STATUS_BUFFER_TOO_SMALL, "got wrong status 0x%08lx\n", status);
2456
2457 HeapFree(GetProcessHeap(), 0, workspace);
2458}
2459
2461{
2462 ULONG compress_workspace, decompress_workspace;
2464
2465 /* test invalid format / engine */
2467 &decompress_workspace);
2468 ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08lx\n", status);
2469
2471 &decompress_workspace);
2472 ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08lx\n", status);
2473
2474 status = RtlGetCompressionWorkSpaceSize(0xFF, &compress_workspace, &decompress_workspace);
2475 ok(status == STATUS_UNSUPPORTED_COMPRESSION, "got wrong status 0x%08lx\n", status);
2476
2477 /* test LZNT1 with normal and maximum compression */
2478 compress_workspace = decompress_workspace = 0xdeadbeef;
2480 &decompress_workspace);
2481 ok(status == STATUS_SUCCESS, "got wrong status 0x%08lx\n", status);
2482 ok(compress_workspace != 0, "got wrong compress_workspace %lu\n", compress_workspace);
2483 ok(decompress_workspace == 0x1000, "got wrong decompress_workspace %lu\n", decompress_workspace);
2484
2485 compress_workspace = decompress_workspace = 0xdeadbeef;
2487 &compress_workspace, &decompress_workspace);
2488 ok(status == STATUS_SUCCESS, "got wrong status 0x%08lx\n", status);
2489 ok(compress_workspace != 0, "got wrong compress_workspace %lu\n", compress_workspace);
2490 ok(decompress_workspace == 0x1000, "got wrong decompress_workspace %lu\n", decompress_workspace);
2491}
2492
2493/* helper for test_RtlDecompressBuffer, checks if a chunk is incomplete */
2494static BOOL is_incomplete_chunk(const UCHAR *compressed, ULONG compressed_size, BOOL check_all)
2495{
2496 ULONG chunk_size;
2497
2498 if (compressed_size <= sizeof(WORD))
2499 return TRUE;
2500
2501 while (compressed_size >= sizeof(WORD))
2502 {
2503 chunk_size = (*(WORD *)compressed & 0xFFF) + 1;
2504 if (compressed_size < sizeof(WORD) + chunk_size)
2505 return TRUE;
2506 if (!check_all)
2507 break;
2508 compressed += sizeof(WORD) + chunk_size;
2509 compressed_size -= sizeof(WORD) + chunk_size;
2510 }
2511
2512 return FALSE;
2513}
2514
2515#define DECOMPRESS_BROKEN_FRAGMENT 1 /* < Win 7 */
2516#define DECOMPRESS_BROKEN_TRUNCATED 2 /* broken on all machines */
2517
2519{
2520 static struct
2521 {
2522 UCHAR compressed[32];
2523 ULONG compressed_size;
2525 UCHAR uncompressed[32];
2526 ULONG uncompressed_size;
2527 DWORD broken_flags;
2528 }
2529 test_lznt[] =
2530 {
2531 /* 4 byte uncompressed chunk */
2532 {
2533 {0x03, 0x30, 'W', 'i', 'n', 'e'},
2534 6,
2536 "Wine",
2537 4,
2539 },
2540 /* 8 byte uncompressed chunk */
2541 {
2542 {0x07, 0x30, 'W', 'i', 'n', 'e', 'W', 'i', 'n', 'e'},
2543 10,
2545 "WineWine",
2546 8,
2548 },
2549 /* 4 byte compressed chunk */
2550 {
2551 {0x04, 0xB0, 0x00, 'W', 'i', 'n', 'e'},
2552 7,
2554 "Wine",
2555 4
2556 },
2557 /* 8 byte compressed chunk */
2558 {
2559 {0x08, 0xB0, 0x00, 'W', 'i', 'n', 'e', 'W', 'i', 'n', 'e'},
2560 11,
2562 "WineWine",
2563 8
2564 },
2565 /* compressed chunk using backwards reference */
2566 {
2567 {0x06, 0xB0, 0x10, 'W', 'i', 'n', 'e', 0x01, 0x30},
2568 9,
2570 "WineWine",
2571 8,
2573 },
2574 /* compressed chunk using backwards reference with length > bytes_read */
2575 {
2576 {0x06, 0xB0, 0x10, 'W', 'i', 'n', 'e', 0x05, 0x30},
2577 9,
2579 "WineWineWine",
2580 12,
2582 },
2583 /* same as above, but unused bits != 0 */
2584 {
2585 {0x06, 0xB0, 0x30, 'W', 'i', 'n', 'e', 0x01, 0x30},
2586 9,
2588 "WineWine",
2589 8,
2591 },
2592 /* compressed chunk without backwards reference and unused bits != 0 */
2593 {
2594 {0x01, 0xB0, 0x02, 'W'},
2595 4,
2597 "W",
2598 1
2599 },
2600 /* termination sequence after first chunk */
2601 {
2602 {0x03, 0x30, 'W', 'i', 'n', 'e', 0x00, 0x00, 0x03, 0x30, 'W', 'i', 'n', 'e'},
2603 14,
2605 "Wine",
2606 4,
2608 },
2609 /* compressed chunk using backwards reference with 4 bit offset, 12 bit length */
2610 {
2611 {0x14, 0xB0, 0x00, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
2612 0x00, 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
2613 0x01, 0x01, 0xF0},
2614 23,
2616 "ABCDEFGHIJKLMNOPABCD",
2617 20,
2619 },
2620 /* compressed chunk using backwards reference with 5 bit offset, 11 bit length */
2621 {
2622 {0x15, 0xB0, 0x00, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
2623 0x00, 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
2624 0x02, 'A', 0x00, 0x78},
2625 24,
2627 "ABCDEFGHIJKLMNOPABCD",
2628 20,
2630 },
2631 /* uncompressed chunk with invalid magic */
2632 {
2633 {0x03, 0x20, 'W', 'i', 'n', 'e'},
2634 6,
2636 "Wine",
2637 4,
2639 },
2640 /* compressed chunk with invalid magic */
2641 {
2642 {0x04, 0xA0, 0x00, 'W', 'i', 'n', 'e'},
2643 7,
2645 "Wine",
2646 4
2647 },
2648 /* garbage byte after end of buffer */
2649 {
2650 {0x00, 0xB0, 0x02, 0x01},
2651 4,
2653 "",
2654 0
2655 },
2656 /* empty compressed chunk */
2657 {
2658 {0x00, 0xB0, 0x00},
2659 3,
2661 "",
2662 0
2663 },
2664 /* empty compressed chunk with unused bits != 0 */
2665 {
2666 {0x00, 0xB0, 0x01},
2667 3,
2669 "",
2670 0
2671 },
2672 /* empty input buffer */
2673 {
2674 {0},
2675 0,
2677 },
2678 /* incomplete chunk header */
2679 {
2680 {0x01},
2681 1,
2683 },
2684 /* incomplete chunk header */
2685 {
2686 {0x00, 0x30},
2687 2,
2689 },
2690 /* compressed chunk with invalid backwards reference */
2691 {
2692 {0x06, 0xB0, 0x10, 'W', 'i', 'n', 'e', 0x05, 0x40},
2693 9,
2695 },
2696 /* compressed chunk with incomplete backwards reference */
2697 {
2698 {0x05, 0xB0, 0x10, 'W', 'i', 'n', 'e', 0x05},
2699 8,
2701 },
2702 /* incomplete uncompressed chunk */
2703 {
2704 {0x07, 0x30, 'W', 'i', 'n', 'e'},
2705 6,
2707 },
2708 /* incomplete compressed chunk */
2709 {
2710 {0x08, 0xB0, 0x00, 'W', 'i', 'n', 'e'},
2711 7,
2713 },
2714 /* two compressed chunks, the second one incomplete */
2715 {
2716 {0x00, 0xB0, 0x02, 0x00, 0xB0},
2717 5,
2719 }
2720 };
2721
2722 static UCHAR buf[0x2000], workspace[0x1000];
2723 NTSTATUS status, expected_status;
2724 ULONG final_size;
2725 int i;
2726
2727 /* test compression format / engine */
2728 final_size = 0xdeadbeef;
2729 status = RtlDecompressBuffer(COMPRESSION_FORMAT_NONE, buf, sizeof(buf), test_lznt[0].compressed,
2730 test_lznt[0].compressed_size, &final_size);
2731 ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08lx\n", status);
2732 ok(final_size == 0xdeadbeef, "got wrong final_size %lu\n", final_size);
2733
2734 final_size = 0xdeadbeef;
2735 status = RtlDecompressBuffer(COMPRESSION_FORMAT_DEFAULT, buf, sizeof(buf), test_lznt[0].compressed,
2736 test_lznt[0].compressed_size, &final_size);
2737 ok(status == STATUS_INVALID_PARAMETER, "got wrong status 0x%08lx\n", status);
2738 ok(final_size == 0xdeadbeef, "got wrong final_size %lu\n", final_size);
2739
2740 final_size = 0xdeadbeef;
2741 status = RtlDecompressBuffer(0xFF, buf, sizeof(buf), test_lznt[0].compressed,
2742 test_lznt[0].compressed_size, &final_size);
2743 ok(status == STATUS_UNSUPPORTED_COMPRESSION, "got wrong status 0x%08lx\n", status);
2744 ok(final_size == 0xdeadbeef, "got wrong final_size %lu\n", final_size);
2745
2746 /* regular tests for RtlDecompressBuffer */
2747 for (i = 0; i < ARRAY_SIZE(test_lznt); i++)
2748 {
2749 trace("Running test %d (compressed_size=%lu, uncompressed_size=%lu, status=0x%08lx)\n",
2750 i, test_lznt[i].compressed_size, test_lznt[i].uncompressed_size, test_lznt[i].status);
2751
2752 /* test with very big buffer */
2753 final_size = 0xdeadbeef;
2754 memset(buf, 0x11, sizeof(buf));
2755 status = RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed,
2756 test_lznt[i].compressed_size, &final_size);
2758 (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT)), "%d: got wrong status 0x%08lx\n", i, status);
2759 if (!status)
2760 {
2761 ok(final_size == test_lznt[i].uncompressed_size,
2762 "%d: got wrong final_size %lu\n", i, final_size);
2763 ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size),
2764 "%d: got wrong decoded data\n", i);
2765 ok(buf[test_lznt[i].uncompressed_size] == 0x11,
2766 "%d: buf[%lu] was modified\n", i, test_lznt[i].uncompressed_size);
2767 }
2768
2769 /* test that modifier for compression engine is ignored */
2770 final_size = 0xdeadbeef;
2771 memset(buf, 0x11, sizeof(buf));
2773 test_lznt[i].compressed, test_lznt[i].compressed_size, &final_size);
2775 (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT)), "%d: got wrong status 0x%08lx\n", i, status);
2776 if (!status)
2777 {
2778 ok(final_size == test_lznt[i].uncompressed_size,
2779 "%d: got wrong final_size %lu\n", i, final_size);
2780 ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size),
2781 "%d: got wrong decoded data\n", i);
2782 ok(buf[test_lznt[i].uncompressed_size] == 0x11,
2783 "%d: buf[%lu] was modified\n", i, test_lznt[i].uncompressed_size);
2784 }
2785
2786 /* test with expected output size */
2787 if (test_lznt[i].uncompressed_size > 0)
2788 {
2789 final_size = 0xdeadbeef;
2790 memset(buf, 0x11, sizeof(buf));
2791 status = RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, test_lznt[i].uncompressed_size,
2792 test_lznt[i].compressed, test_lznt[i].compressed_size, &final_size);
2793 ok(status == test_lznt[i].status, "%d: got wrong status 0x%08lx\n", i, status);
2794 if (!status)
2795 {
2796 ok(final_size == test_lznt[i].uncompressed_size,
2797 "%d: got wrong final_size %lu\n", i, final_size);
2798 ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size),
2799 "%d: got wrong decoded data\n", i);
2800 ok(buf[test_lznt[i].uncompressed_size] == 0x11,
2801 "%d: buf[%lu] was modified\n", i, test_lznt[i].uncompressed_size);
2802 }
2803 }
2804
2805 /* test with smaller output size */
2806 if (test_lznt[i].uncompressed_size > 1)
2807 {
2808 final_size = 0xdeadbeef;
2809 memset(buf, 0x11, sizeof(buf));
2810 status = RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, test_lznt[i].uncompressed_size - 1,
2811 test_lznt[i].compressed, test_lznt[i].compressed_size, &final_size);
2812 ok(status == test_lznt[i].status ||
2813 broken(status == STATUS_BAD_COMPRESSION_BUFFER && (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_TRUNCATED)),
2814 "%d: got wrong status 0x%08lx\n", i, status);
2815 if (!status)
2816 {
2817 ok(final_size == test_lznt[i].uncompressed_size - 1,
2818 "%d: got wrong final_size %lu\n", i, final_size);
2819 ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size - 1),
2820 "%d: got wrong decoded data\n", i);
2821 ok(buf[test_lznt[i].uncompressed_size - 1] == 0x11,
2822 "%d: buf[%lu] was modified\n", i, test_lznt[i].uncompressed_size - 1);
2823 }
2824 }
2825
2826 /* test with zero output size */
2827 final_size = 0xdeadbeef;
2828 memset(buf, 0x11, sizeof(buf));
2829 status = RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1, buf, 0, test_lznt[i].compressed,
2830 test_lznt[i].compressed_size, &final_size);
2831 if (is_incomplete_chunk(test_lznt[i].compressed, test_lznt[i].compressed_size, FALSE))
2832 ok(status == STATUS_BAD_COMPRESSION_BUFFER, "%d: got wrong status 0x%08lx\n", i, status);
2833 else
2834 {
2835 ok(status == STATUS_SUCCESS, "%d: got wrong status 0x%08lx\n", i, status);
2836 ok(final_size == 0, "%d: got wrong final_size %lu\n", i, final_size);
2837 ok(buf[0] == 0x11, "%d: buf[0] was modified\n", i);
2838 }
2839
2840 /* test RtlDecompressFragment with offset = 0 */
2841 final_size = 0xdeadbeef;
2842 memset(buf, 0x11, sizeof(buf));
2843 status = RtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed,
2844 test_lznt[i].compressed_size, 0, &final_size, workspace);
2845 if (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT)
2846 todo_wine
2847 ok(status == STATUS_BAD_COMPRESSION_BUFFER, "%d: got wrong status 0x%08lx\n", i, status);
2848 else
2849 ok(status == test_lznt[i].status, "%d: got wrong status 0x%08lx\n", i, status);
2850 if (!status)
2851 {
2852 ok(final_size == test_lznt[i].uncompressed_size,
2853 "%d: got wrong final_size %lu\n", i, final_size);
2854 ok(!memcmp(buf, test_lznt[i].uncompressed, test_lznt[i].uncompressed_size),
2855 "%d: got wrong decoded data\n", i);
2856 ok(buf[test_lznt[i].uncompressed_size] == 0x11,
2857 "%d: buf[%lu] was modified\n", i, test_lznt[i].uncompressed_size);
2858 }
2859
2860 /* test RtlDecompressFragment with offset = 1 */
2861 final_size = 0xdeadbeef;
2862 memset(buf, 0x11, sizeof(buf));
2863 status = RtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed,
2864 test_lznt[i].compressed_size, 1, &final_size, workspace);
2865 if (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT)
2866 todo_wine
2867 ok(status == STATUS_BAD_COMPRESSION_BUFFER, "%d: got wrong status 0x%08lx\n", i, status);
2868 else
2869 ok(status == test_lznt[i].status, "%d: got wrong status 0x%08lx\n", i, status);
2870 if (!status)
2871 {
2872 if (test_lznt[i].uncompressed_size == 0)
2873 {
2874 todo_wine
2875 ok(final_size == 4095, "%d: got wrong final_size %lu\n", i, final_size);
2876 /* Buffer doesn't contain any useful value on Windows */
2877 ok(buf[4095] == 0x11, "%d: buf[4095] was modified\n", i);
2878 }
2879 else
2880 {
2881 ok(final_size == test_lznt[i].uncompressed_size - 1,
2882 "%d: got wrong final_size %lu\n", i, final_size);
2883 ok(!memcmp(buf, test_lznt[i].uncompressed + 1, test_lznt[i].uncompressed_size - 1),
2884 "%d: got wrong decoded data\n", i);
2885 ok(buf[test_lznt[i].uncompressed_size - 1] == 0x11,
2886 "%d: buf[%lu] was modified\n", i, test_lznt[i].uncompressed_size - 1);
2887 }
2888 }
2889
2890 /* test RtlDecompressFragment with offset = 4095 */
2891 final_size = 0xdeadbeef;
2892 memset(buf, 0x11, sizeof(buf));
2893 status = RtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed,
2894 test_lznt[i].compressed_size, 4095, &final_size, workspace);
2895 if (test_lznt[i].broken_flags & DECOMPRESS_BROKEN_FRAGMENT)
2896 todo_wine
2897 ok(status == STATUS_BAD_COMPRESSION_BUFFER, "%d: got wrong status 0x%08lx\n", i, status);
2898 else
2899 ok(status == test_lznt[i].status, "%d: got wrong status 0x%08lx\n", i, status);
2900 if (!status)
2901 {
2902 todo_wine
2903 ok(final_size == 1, "%d: got wrong final_size %lu\n", i, final_size);
2904 todo_wine
2905 ok(buf[0] == 0, "%d: padding is not zero\n", i);
2906 ok(buf[1] == 0x11, "%d: buf[1] was modified\n", i);
2907 }
2908
2909 /* test RtlDecompressFragment with offset = 4096 */
2910 final_size = 0xdeadbeef;
2911 memset(buf, 0x11, sizeof(buf));
2912 status = RtlDecompressFragment(COMPRESSION_FORMAT_LZNT1, buf, sizeof(buf), test_lznt[i].compressed,
2913 test_lznt[i].compressed_size, 4096, &final_size, workspace);
2914 expected_status = is_incomplete_chunk(test_lznt[i].compressed, test_lznt[i].compressed_size, TRUE) ?
2915 test_lznt[i].status : STATUS_SUCCESS;
2916 ok(status == expected_status, "%d: got wrong status 0x%08lx, expected 0x%08lx\n", i, status, expected_status);
2917 if (!status)
2918 {
2919 ok(final_size == 0, "%d: got wrong final_size %lu\n", i, final_size);
2920 ok(buf[0] == 0x11, "%d: buf[4096] was modified\n", i);
2921 }
2922 }
2923}
2924
2925#undef DECOMPRESS_BROKEN_FRAGMENT
2926#undef DECOMPRESS_BROKEN_TRUNCATED
2927
2929{
2932};
2933
2935{
2937 DWORD ret;
2938
2939 ret = pRtlIsCriticalSectionLocked(&info->crit);
2940 ok(ret == TRUE, "expected TRUE, got %lu\n", ret);
2941 ret = pRtlIsCriticalSectionLockedByThread(&info->crit);
2942 ok(ret == FALSE, "expected FALSE, got %lu\n", ret);
2943
2944 ReleaseSemaphore(info->semaphores[0], 1, NULL);
2945 ret = WaitForSingleObject(info->semaphores[1], 1000);
2946 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %lu\n", ret);
2947
2948 ret = pRtlIsCriticalSectionLocked(&info->crit);
2949 ok(ret == FALSE, "expected FALSE, got %lu\n", ret);
2950 ret = pRtlIsCriticalSectionLockedByThread(&info->crit);
2951 ok(ret == FALSE, "expected FALSE, got %lu\n", ret);
2952
2953 EnterCriticalSection(&info->crit);
2954
2955 ret = pRtlIsCriticalSectionLocked(&info->crit);
2956 ok(ret == TRUE, "expected TRUE, got %lu\n", ret);
2957 ret = pRtlIsCriticalSectionLockedByThread(&info->crit);
2958 ok(ret == TRUE, "expected TRUE, got %lu\n", ret);
2959
2960 ReleaseSemaphore(info->semaphores[0], 1, NULL);
2961 ret = WaitForSingleObject(info->semaphores[1], 1000);
2962 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %lu\n", ret);
2963
2964 LeaveCriticalSection(&info->crit);
2965 return 0;
2966}
2967
2969{
2971 HANDLE thread;
2972 BOOL ret;
2973
2974 if (!pRtlIsCriticalSectionLocked || !pRtlIsCriticalSectionLockedByThread)
2975 {
2976 win_skip("skipping RtlIsCriticalSectionLocked tests, required functions not available\n");
2977 return;
2978 }
2979
2981 info.semaphores[0] = CreateSemaphoreW(NULL, 0, 1, NULL);
2982 ok(info.semaphores[0] != NULL, "CreateSemaphore failed with %lu\n", GetLastError());
2983 info.semaphores[1] = CreateSemaphoreW(NULL, 0, 1, NULL);
2984 ok(info.semaphores[1] != NULL, "CreateSemaphore failed with %lu\n", GetLastError());
2985
2986 ret = pRtlIsCriticalSectionLocked(&info.crit);
2987 ok(ret == FALSE, "expected FALSE, got %u\n", ret);
2988 ret = pRtlIsCriticalSectionLockedByThread(&info.crit);
2989 ok(ret == FALSE, "expected FALSE, got %u\n", ret);
2990
2992
2993 ret = pRtlIsCriticalSectionLocked(&info.crit);
2994 ok(ret == TRUE, "expected TRUE, got %u\n", ret);
2995 ret = pRtlIsCriticalSectionLockedByThread(&info.crit);
2996 ok(ret == TRUE, "expected TRUE, got %u\n", ret);
2997
2999 ok(thread != NULL, "CreateThread failed with %lu\n", GetLastError());
3000 ret = WaitForSingleObject(info.semaphores[0], 1000);
3001 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", ret);
3002
3004
3005 ReleaseSemaphore(info.semaphores[1], 1, NULL);
3006 ret = WaitForSingleObject(info.semaphores[0], 1000);
3007 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", ret);
3008
3009 ret = pRtlIsCriticalSectionLocked(&info.crit);
3010 ok(ret == TRUE, "expected TRUE, got %u\n", ret);
3011 ret = pRtlIsCriticalSectionLockedByThread(&info.crit);
3012 ok(ret == FALSE, "expected FALSE, got %u\n", ret);
3013
3014 ReleaseSemaphore(info.semaphores[1], 1, NULL);
3016 ok(ret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", ret);
3017
3019 CloseHandle(info.semaphores[0]);
3020 CloseHandle(info.semaphores[1]);
3022}
3023
3025{
3026 static const CRITICAL_SECTION_DEBUG *no_debug = (void *)~(ULONG_PTR)0;
3028
3029 if (!pRtlInitializeCriticalSectionEx)
3030 {
3031 win_skip("RtlInitializeCriticalSectionEx is not available\n");
3032 return;
3033 }
3034
3035 memset(&cs, 0x11, sizeof(cs));
3036 pRtlInitializeCriticalSectionEx(&cs, 0, 0);
3037 ok(cs.DebugInfo == no_debug || broken(cs.DebugInfo != NULL && cs.DebugInfo != no_debug) /* < Win8 */,
3038 "expected DebugInfo != NULL and DebugInfo != ~0, got %p\n", cs.DebugInfo);
3039 ok(cs.LockCount == -1, "expected LockCount == -1, got %ld\n", cs.LockCount);
3040 ok(cs.RecursionCount == 0, "expected RecursionCount == 0, got %ld\n", cs.RecursionCount);
3041 ok(cs.LockSemaphore == NULL, "expected LockSemaphore == NULL, got %p\n", cs.LockSemaphore);
3042 ok(cs.SpinCount == 0 || broken(cs.SpinCount != 0) /* >= Win 8 */,
3043 "expected SpinCount == 0, got %Id\n", cs.SpinCount);
3045
3046 memset(&cs, 0x11, sizeof(cs));
3047 pRtlInitializeCriticalSectionEx(&cs, 0, RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO);
3048 ok(cs.DebugInfo == no_debug, "expected DebugInfo == ~0, got %p\n", cs.DebugInfo);
3049 ok(cs.LockCount == -1, "expected LockCount == -1, got %ld\n", cs.LockCount);
3050 ok(cs.RecursionCount == 0, "expected RecursionCount == 0, got %ld\n", cs.RecursionCount);
3051 ok(cs.LockSemaphore == NULL, "expected LockSemaphore == NULL, got %p\n", cs.LockSemaphore);
3052 ok(cs.SpinCount == 0 || broken(cs.SpinCount != 0) /* >= Win 8 */,
3053 "expected SpinCount == 0, got %Id\n", cs.SpinCount);
3055}
3056
3058{
3061
3062 if (!pRtlInitializeCriticalSectionEx)
3063 return; /* Skip winxp */
3064
3066 ok(!status, "RtlInitializeCriticalSection failed: %lx\n", status);
3067
3069 ok(!status, "RtlEnterCriticalSection failed: %lx\n", status);
3070 todo_wine
3071 ok(cs.LockCount == -2, "expected LockCount == -2, got %ld\n", cs.LockCount);
3072 ok(cs.RecursionCount == 1, "expected RecursionCount == 1, got %ld\n", cs.RecursionCount);
3073 ok(cs.OwningThread == ULongToHandle(GetCurrentThreadId()), "unexpected OwningThread\n");
3074
3076 ok(!status, "RtlLeaveCriticalSection failed: %lx\n", status);
3077 ok(cs.LockCount == -1, "expected LockCount == -1, got %ld\n", cs.LockCount);
3078 ok(cs.RecursionCount == 0, "expected RecursionCount == 0, got %ld\n", cs.RecursionCount);
3079 ok(!cs.OwningThread, "unexpected OwningThread %p\n", cs.OwningThread);
3080
3081 /*
3082 * Trying to leave a section that wasn't acquired modifies RecursionCount to an invalid value,
3083 * but doesn't modify LockCount so that an attempt to enter the section later will work.
3084 */
3086 ok(!status, "RtlLeaveCriticalSection failed: %lx\n", status);
3087 ok(cs.LockCount == -1, "expected LockCount == -1, got %ld\n", cs.LockCount);
3088 ok(cs.RecursionCount == -1, "expected RecursionCount == -1, got %ld\n", cs.RecursionCount);
3089 ok(!cs.OwningThread, "unexpected OwningThread %p\n", cs.OwningThread);
3090
3091 /* and again */
3093 ok(!status, "RtlLeaveCriticalSection failed: %lx\n", status);
3094 ok(cs.LockCount == -1, "expected LockCount == -1, got %ld\n", cs.LockCount);
3095 ok(cs.RecursionCount == -2, "expected RecursionCount == -2, got %ld\n", cs.RecursionCount);
3096 ok(!cs.OwningThread, "unexpected OwningThread %p\n", cs.OwningThread);
3097
3098 /* entering section fixes RecursionCount */
3100 ok(!status, "RtlEnterCriticalSection failed: %lx\n", status);
3101 todo_wine
3102 ok(cs.LockCount == -2, "expected LockCount == -2, got %ld\n", cs.LockCount);
3103 ok(cs.RecursionCount == 1, "expected RecursionCount == 1, got %ld\n", cs.RecursionCount);
3104 ok(cs.OwningThread == ULongToHandle(GetCurrentThreadId()), "unexpected OwningThread\n");
3105
3107 ok(!status, "RtlLeaveCriticalSection failed: %lx\n", status);
3108 ok(cs.LockCount == -1, "expected LockCount == -1, got %ld\n", cs.LockCount);
3109 ok(cs.RecursionCount == 0, "expected RecursionCount == 0, got %ld\n", cs.RecursionCount);
3110 ok(!cs.OwningThread, "unexpected OwningThread %p\n", cs.OwningThread);
3111
3113 ok(!status, "RtlDeleteCriticalSection failed: %lx\n", status);
3114}
3115
3117{
3121};
3122
3124{
3125 static const WCHAR ntdllW[] = {'n','t','d','l','l','.','d','l','l',0};
3126 struct ldr_enum_context *ctx = context;
3127
3128 if (!lstrcmpiW(module->BaseDllName.Buffer, ntdllW))
3129 ctx->found = TRUE;
3130
3131 ctx->count++;
3132 *stop = ctx->abort;
3133}
3134
3136{
3137 struct ldr_enum_context ctx;
3139
3140 if (!pLdrEnumerateLoadedModules)
3141 {
3142 win_skip("LdrEnumerateLoadedModules not available\n");
3143 return;
3144 }
3145
3146 ctx.abort = FALSE;
3147 ctx.found = FALSE;
3148 ctx.count = 0;
3149 status = pLdrEnumerateLoadedModules(NULL, ldr_enum_callback, &ctx);
3150 ok(status == STATUS_SUCCESS, "LdrEnumerateLoadedModules failed with %08lx\n", status);
3151 ok(ctx.count > 1, "Expected more than one module, got %d\n", ctx.count);
3152 ok(ctx.found, "Could not find ntdll in list of modules\n");
3153
3154 ctx.abort = TRUE;
3155 ctx.count = 0;
3156 status = pLdrEnumerateLoadedModules(NULL, ldr_enum_callback, &ctx);
3157 ok(status == STATUS_SUCCESS, "LdrEnumerateLoadedModules failed with %08lx\n", status);
3158 ok(ctx.count == 1, "Expected exactly one module, got %d\n", ctx.count);
3159
3160 status = pLdrEnumerateLoadedModules((void *)0x1, ldr_enum_callback, (void *)0xdeadbeef);
3161 ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got 0x%08lx\n", status);
3162
3163 status = pLdrEnumerateLoadedModules((void *)0xdeadbeef, ldr_enum_callback, (void *)0xdeadbeef);
3164 ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got 0x%08lx\n", status);
3165
3166 status = pLdrEnumerateLoadedModules(NULL, NULL, (void *)0xdeadbeef);
3167 ok(status == STATUS_INVALID_PARAMETER, "expected STATUS_INVALID_PARAMETER, got 0x%08lx\n", status);
3168}
3169
3171{
3172 char buf[sizeof(SECURITY_DESCRIPTOR_RELATIVE) + 4];
3176 DWORD len;
3177
3178 memset( &sd, 0, sizeof(sd) );
3180
3181 len = 0;
3183 ok( status == STATUS_BUFFER_TOO_SMALL, "got %08lx\n", status );
3184 ok( len == sizeof(*sd_rel), "got %lu\n", len );
3185
3186 len += 4;
3187 status = RtlMakeSelfRelativeSD( &sd, sd_rel, &len );
3188 ok( status == STATUS_SUCCESS, "got %08lx\n", status );
3189 ok( len == sizeof(*sd_rel) + 4, "got %lu\n", len );
3190
3191 len = 0;
3193 ok( status == STATUS_BUFFER_TOO_SMALL, "got %08lx\n", status );
3194 ok( len == sizeof(*sd_rel), "got %lu\n", len );
3195
3196 len += 4;
3197 status = RtlAbsoluteToSelfRelativeSD( &sd, sd_rel, &len );
3198 ok( status == STATUS_SUCCESS, "got %08lx\n", status );
3199 ok( len == sizeof(*sd_rel) + 4, "got %lu\n", len );
3200
3201 sd.Control = SE_SELF_RELATIVE;
3202 status = RtlMakeSelfRelativeSD( &sd, sd_rel, &len );
3203 ok( status == STATUS_SUCCESS, "got %08lx\n", status );
3204 ok( len == sizeof(*sd_rel) + 4, "got %lu\n", len );
3205
3206 status = RtlAbsoluteToSelfRelativeSD( &sd, sd_rel, &len );
3207 ok( status == STATUS_BAD_DESCRIPTOR_FORMAT, "got %08lx\n", status );
3208}
3209
3210static DWORD (CALLBACK *orig_entry)(HMODULE,DWORD,LPVOID);
3212
3213static inline void *get_rva( HMODULE module, DWORD va )
3214{
3215 return (void *)((char *)module + va);
3216}
3217
3219{
3220 const IMAGE_IMPORT_DESCRIPTOR *imports;
3221 const IMAGE_THUNK_DATA *import_list;
3222 IMAGE_THUNK_DATA *thunk_list;
3224 DWORD *calls = context;
3225 LIST_ENTRY *mark;
3226 ULONG size;
3227 int i, j;
3228
3229 *calls <<= 4;
3230 *calls |= reason;
3231
3232 if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, expected_dll))
3233 return;
3234
3235 ok(data->Loaded.Flags == 0, "Expected flags 0, got %lx\n", data->Loaded.Flags);
3236 ok(!lstrcmpiW(data->Loaded.BaseDllName->Buffer, expected_dll), "Expected %s, got %s\n",
3237 wine_dbgstr_w(expected_dll), wine_dbgstr_w(data->Loaded.BaseDllName->Buffer));
3238 ok(!!data->Loaded.DllBase, "Expected non zero base address\n");
3239 ok(data->Loaded.SizeOfImage, "Expected non zero image size\n");
3240
3241 /* expect module to be last module listed in LdrData load order list */
3242 mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
3243 mod = CONTAINING_RECORD(mark->Blink, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
3244 ok(mod->DllBase == data->Loaded.DllBase, "Expected base address %p, got %p\n",
3245 data->Loaded.DllBase, mod->DllBase);
3246 ok(!lstrcmpiW(mod->BaseDllName.Buffer, expected_dll), "Expected %s, got %s\n",
3247 wine_dbgstr_w(expected_dll), wine_dbgstr_w(mod->BaseDllName.Buffer));
3248
3249 /* show that imports have already been resolved */
3251 ok(!!imports, "Expected dll to have imports\n");
3252
3253 for (i = 0; imports[i].Name; i++)
3254 {
3255 thunk_list = get_rva(data->Loaded.DllBase, (DWORD)imports[i].FirstThunk);
3256 if (imports[i].OriginalFirstThunk)
3257 import_list = get_rva(data->Loaded.DllBase, (DWORD)imports[i].OriginalFirstThunk);
3258 else
3259 import_list = thunk_list;
3260
3261 for (j = 0; import_list[j].u1.Ordinal; j++)
3262 {
3263 ok(thunk_list[j].u1.AddressOfData > data->Loaded.SizeOfImage,
3264 "Import has not been resolved: %p\n", (void*)thunk_list[j].u1.Function);
3265 }
3266 }
3267}
3268
3270{
3271 DWORD *calls = context;
3272 *calls <<= 4;
3273 *calls |= reason + 2;
3274}
3275
3277{
3279 {
3280 *dll_main_data <<= 4;
3281 *dll_main_data |= 3;
3282 }
3283 else if (reason == DLL_PROCESS_DETACH)
3284 {
3285 *dll_main_data <<= 4;
3286 *dll_main_data |= 4;
3287 }
3288 return orig_entry(instance, reason, reserved);
3289}
3290
3292{
3293 DWORD *calls = context;
3294 LIST_ENTRY *mark;
3296
3297 *calls <<= 4;
3298 *calls |= reason;
3299
3301 return;
3302
3303 mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
3304 mod = CONTAINING_RECORD(mark->Blink, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
3305 ok(mod->DllBase == data->Loaded.DllBase, "Expected base address %p, got %p\n",
3306 data->Loaded.DllBase, mod->DllBase);
3307 if (mod->DllBase != data->Loaded.DllBase)
3308 return;
3309
3310 orig_entry = mod->EntryPoint;
3311 mod->EntryPoint = fake_dll_main;
3312 dll_main_data = calls;
3313}
3314
3316{
3318 {
3319 *dll_main_data <<= 4;
3320 *dll_main_data |= 3;
3321 }
3322 else if (reason == DLL_PROCESS_DETACH)
3323 {
3324 *dll_main_data <<= 4;
3325 *dll_main_data |= 4;
3326 }
3327 return FALSE;
3328}
3329
3331{
3332 DWORD *calls = context;
3333 LIST_ENTRY *mark;
3335
3336 *calls <<= 4;
3337 *calls |= reason;
3338
3340 return;
3341
3342 mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
3343 mod = CONTAINING_RECORD(mark->Blink, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
3344 ok(mod->DllBase == data->Loaded.DllBase, "Expected base address %p, got %p\n",
3345 data->Loaded.DllBase, mod->DllBase);
3346 if (mod->DllBase != data->Loaded.DllBase)
3347 return;
3348
3349 orig_entry = mod->EntryPoint;
3350 mod->EntryPoint = fake_dll_main_fail;
3351 dll_main_data = calls;
3352}
3353
3355{
3356 DWORD *calls = context;
3357
3359 return;
3360
3361 if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, crypt32dllW))
3362 {
3363 *calls <<= 4;
3364 *calls |= 1;
3365 }
3366
3367 if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, wintrustdllW))
3368 {
3369 *calls <<= 4;
3370 *calls |= 2;
3371 }
3372}
3373
3375{
3376 void *cookie, *cookie2;
3378 HMODULE mod;
3379 DWORD calls;
3380
3381 if (!pLdrRegisterDllNotification || !pLdrUnregisterDllNotification)
3382 {
3383 win_skip("Ldr(Un)RegisterDllNotification not available\n");
3384 return;
3385 }
3386
3388 if(mod)
3390 else
3391 expected_dll = ws2_32dllW; /* XP Default */
3392
3393 /* generic test */
3394 status = pLdrRegisterDllNotification(0, ldr_notify_callback1, &calls, &cookie);
3395 ok(!status, "Expected STATUS_SUCCESS, got %08lx\n", status);
3396
3397 calls = 0;
3399 ok(!!mod, "Failed to load library: %ld\n", GetLastError());
3400 ok(calls == LDR_DLL_NOTIFICATION_REASON_LOADED, "Expected LDR_DLL_NOTIFICATION_REASON_LOADED, got %lx\n", calls);
3401
3402 calls = 0;
3404 ok(calls == LDR_DLL_NOTIFICATION_REASON_UNLOADED, "Expected LDR_DLL_NOTIFICATION_REASON_UNLOADED, got %lx\n", calls);
3405
3406 /* test order of callbacks */
3407 status = pLdrRegisterDllNotification(0, ldr_notify_callback2, &calls, &cookie2);
3408 ok(!status, "Expected STATUS_SUCCESS, got %08lx\n", status);
3409
3410 calls = 0;
3412 ok(!!mod, "Failed to load library: %ld\n", GetLastError());
3413 ok(calls == 0x13, "Expected order 0x13, got %lx\n", calls);
3414
3415 calls = 0;
3417 ok(calls == 0x24, "Expected order 0x24, got %lx\n", calls);
3418
3419 pLdrUnregisterDllNotification(cookie2);
3420 pLdrUnregisterDllNotification(cookie);
3421
3422 /* test dll main order */
3423 status = pLdrRegisterDllNotification(0, ldr_notify_callback_dll_main, &calls, &cookie);
3424 ok(!status, "Expected STATUS_SUCCESS, got %08lx\n", status);
3425
3426 calls = 0;
3428 ok(!!mod, "Failed to load library: %ld\n", GetLastError());
3429 ok(calls == 0x13, "Expected order 0x13, got %lx\n", calls);
3430
3431 calls = 0;
3433 ok(calls == 0x42, "Expected order 0x42, got %lx\n", calls);
3434
3435 pLdrUnregisterDllNotification(cookie);
3436
3437 /* test dll main order */
3438 status = pLdrRegisterDllNotification(0, ldr_notify_callback_fail, &calls, &cookie);
3439 ok(!status, "Expected STATUS_SUCCESS, got %08lx\n", status);
3440
3441 calls = 0;
3443 ok(!mod, "Expected library to fail loading\n");
3444 ok(calls == 0x1342, "Expected order 0x1342, got %lx\n", calls);
3445
3446 pLdrUnregisterDllNotification(cookie);
3447
3448 /* test dll with dependencies */
3449 status = pLdrRegisterDllNotification(0, ldr_notify_callback_imports, &calls, &cookie);
3450 ok(!status, "Expected STATUS_SUCCESS, got %08lx\n", status);
3451
3452 calls = 0;
3454 ok(!!mod, "Failed to load library: %ld\n", GetLastError());
3455 ok(calls == 0x12 || calls == 0x21, "got %lx\n", calls);
3456
3458 pLdrUnregisterDllNotification(cookie);
3459}
3460
3463
3465{
3467 {
3468 ok( eptrs->ExceptionRecord->NumberParameters == 2,
3469 "Unexpected NumberParameters: %ld\n", eptrs->ExceptionRecord->NumberParameters );
3470 ok( eptrs->ExceptionRecord->ExceptionInformation[0] == strlen("test_DbgPrint: Hello World") + 1,
3471 "Unexpected ExceptionInformation[0]: %d\n", (int)eptrs->ExceptionRecord->ExceptionInformation[0] );
3472 ok( !strcmp((char *)eptrs->ExceptionRecord->ExceptionInformation[1], "test_DbgPrint: Hello World"),
3473 "Unexpected ExceptionInformation[1]: %s\n", wine_dbgstr_a((char *)eptrs->ExceptionRecord->ExceptionInformation[1]) );
3476 }
3477
3479}
3480
3481static NTSTATUS WINAPIV test_vDbgPrintEx( ULONG id, ULONG level, const char *fmt, ... )
3482{
3484 va_list args;
3485 va_start( args, fmt );
3486 status = vDbgPrintEx( id, level, fmt, args );
3487 va_end( args );
3488 return status;
3489}
3490
3491static NTSTATUS WINAPIV test_vDbgPrintExWithPrefix( const char *prefix, ULONG id, ULONG level, const char *fmt, ... )
3492{
3494 va_list args;
3495 va_start( args, fmt );
3497 va_end( args );
3498 return status;
3499}
3500
3501static void test_DbgPrint(void)
3502{
3505 PEB *Peb = NtCurrentTeb()->Peb;
3506 BOOL debugged = Peb->BeingDebugged;
3507
3510 status = DbgPrint( "test_DbgPrint: %s", "Hello World" );
3511#ifdef __REACTOS__
3512 ok(status == (GetNTVersion() >= _WIN32_WINNT_VISTA ? 0 : 1), "DbgPrint returned %lx\n", status );
3513#else
3514 ok( !status, "DbgPrint returned %lx\n", status );
3515#endif
3516 ok( !test_dbg_print_except, "DBG_PRINTEXCEPTION_C received\n" );
3517
3518#ifdef __REACTOS__
3519 if (is_reactos())
3520 {
3521 skip("DbgPrint with a debugger attached is broken on ReactOS\n");
3522 return;
3523 }
3524#endif
3525
3529 status = DbgPrint( "test_DbgPrint: %s", "Hello World" );
3530 ok( !status, "DbgPrint returned %lx\n", status );
3531 ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
3532
3535 status = DbgPrint( "test_DbgPrint: %s", "Hello World" );
3536 ok( !status, "DbgPrint returned %lx\n", status );
3537 ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
3538
3541 status = DbgPrint( "test_DbgPrint: %s", "Hello World" );
3542 ok( !status, "DbgPrint returned %lx\n", status );
3543 ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
3544
3545
3546 /* FIXME: NtSetDebugFilterState / DbgSetDebugFilterState are probably what's controlling these */
3547
3550 status = DbgPrintEx( 0, DPFLTR_ERROR_LEVEL, "test_DbgPrint: %s", "Hello World" );
3551 ok( !status, "DbgPrintEx returned %lx\n", status );
3552 ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
3553
3556 status = DbgPrintEx( 0, DPFLTR_WARNING_LEVEL, "test_DbgPrint: %s", "Hello World" );
3557 ok( !status, "DbgPrintEx returned %lx\n", status );
3558 ok( !test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
3559
3562 status = DbgPrintEx( 0, DPFLTR_MASK|(1 << DPFLTR_ERROR_LEVEL), "test_DbgPrint: %s", "Hello World" );
3563 ok( !status, "DbgPrintEx returned %lx\n", status );
3564 ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
3565
3568 status = DbgPrintEx( 0, DPFLTR_MASK|(1 << DPFLTR_WARNING_LEVEL), "test_DbgPrint: %s", "Hello World" );
3569 ok( !status, "DbgPrintEx returned %lx\n", status );
3570 ok( !test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
3571
3572
3575 status = test_vDbgPrintEx( 0, 0xFFFFFFFF, "test_DbgPrint: %s", "Hello World" );
3576 ok( !status, "vDbgPrintEx returned %lx\n", status );
3577 ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
3578
3581 status = test_vDbgPrintExWithPrefix( "test_", 0, 0xFFFFFFFF, "DbgPrint: %s", "Hello World" );
3582 ok( !status, "vDbgPrintExWithPrefix returned %lx\n", status );
3583 ok( test_dbg_print_except, "DBG_PRINTEXCEPTION_C not received\n" );
3584
3585 Peb->BeingDebugged = debugged;
3587}
3588
3591
3593{
3595 {
3596#if defined( __i386__ )
3597 eptrs->ContextRecord->Eip += 1;
3600#elif defined( __x86_64__ )
3601 eptrs->ContextRecord->Rip += 1;
3604#elif defined( __aarch64__ )
3605 eptrs->ContextRecord->Pc += 4;
3608#endif
3609 }
3610
3612 {
3615 }
3616
3618}
3619
3620/* partially copied from ntdll/heap.c */
3621#define HEAP_VALIDATE_PARAMS 0x40000000
3622
3623struct heap
3624{
3635};
3636
3637static void test_RtlDestroyHeap(void)
3638{
3639 const struct heap invalid = {{0, 0}, {0, HEAP_VALIDATE_PARAMS}, {0, 0, 0, 0}, 0, {0, 0}, {0, 0, 0}, {0, 0}, HEAP_VALIDATE_PARAMS, 0, {0}};
3640 HANDLE heap = (HANDLE)&invalid, ret;
3641 PEB *Peb = NtCurrentTeb()->Peb;
3642 BOOL debugged;
3644
3647 debugged = Peb->BeingDebugged;
3649 ret = RtlDestroyHeap( heap );
3650 ok( ret == heap, "RtlDestroyHeap(%p) returned %p\n", heap, ret );
3651 ok( test_heap_destroy_dbgstr, "HeapDestroy didn't call OutputDebugStrA\n" );
3652 ok( test_heap_destroy_break, "HeapDestroy didn't call DbgBreakPoint\n" );
3653 Peb->BeingDebugged = debugged;
3654
3656}
3657
3659{
3660 void *base;
3662};
3663
3665
3667{
3668 commit_context.base = base;
3669 commit_context.size = *size;
3670
3672}
3673
3674static void test_RtlCreateHeap(void)
3675{
3676 void *ptr, *base, *reserve;
3678 HANDLE heap;
3679 BOOL ret;
3680
3681 heap = RtlCreateHeap(0, NULL, 0, 0, NULL, NULL);
3682 ok(!!heap, "Failed to create a heap.\n");
3684
3685 memset(&params, 0, sizeof(params));
3686 heap = RtlCreateHeap(0, NULL, 0, 0, NULL, &params);
3687 ok(!!heap, "Failed to create a heap.\n");
3689
3690 params.Length = 1;
3691 heap = RtlCreateHeap(0, NULL, 0, 0, NULL, &params);
3692 ok(!!heap, "Failed to create a heap.\n");
3694
3695 params.Length = sizeof(params);
3696 params.CommitRoutine = test_commit_routine;
3697 params.InitialCommit = 0x1000;
3698 params.InitialReserve = 0x10000;
3699
3700 heap = RtlCreateHeap(0, NULL, 0, 0, NULL, &params);
3701 todo_wine
3702 ok(!heap, "Unexpected heap.\n");
3703 if (heap)
3705
3708 ok(!!base, "Unexpected pointer.\n");
3709
3710 heap = RtlCreateHeap(0, base, 0, 0, NULL, &params);
3711 ok(!!heap, "Unexpected heap.\n");
3712
3713 /* Using block size above initially committed size to trigger
3714 new allocation via user callback. */
3715 ptr = RtlAllocateHeap(heap, 0, 0x4000);
3716 ok(!!ptr, "Failed to allocate a block.\n");
3717 todo_wine
3718 ok(commit_context.base == base, "Unexpected base %p.\n", commit_context.base);
3719 todo_wine
3720 ok(!!commit_context.size, "Unexpected allocation size.\n");
3721 RtlFreeHeap(heap, 0, ptr);
3723
3725 todo_wine
3726 ok(ret, "Unexpected return value.\n");
3727}
3728
3729static void test_RtlFirstFreeAce(void)
3730{
3731 PACL acl;
3733 BOOL ret;
3734 DWORD size;
3735 BOOLEAN found;
3736
3737 size = sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE));
3739 ret = InitializeAcl(acl, sizeof(ACL), ACL_REVISION);
3740 ok(ret, "InitializeAcl failed with error %ld\n", GetLastError());
3741
3742 /* AceCount = 0 */
3743 first = (ACE_HEADER *)0xdeadbeef;
3744 found = RtlFirstFreeAce(acl, &first);
3745 ok(found, "RtlFirstFreeAce failed\n");
3746 ok(first == (PACE_HEADER)(acl + 1), "Failed to find ACL\n");
3747
3748 acl->AclSize = sizeof(ACL) - 1;
3749 first = (ACE_HEADER *)0xdeadbeef;
3750 found = RtlFirstFreeAce(acl, &first);
3751 ok(found, "RtlFirstFreeAce failed\n");
3752 ok(first == NULL, "Found FirstAce = %p\n", first);
3753
3754 /* AceCount = 1 */
3755 acl->AceCount = 1;
3756 acl->AclSize = size;
3757 first = (ACE_HEADER *)0xdeadbeef;
3758 found = RtlFirstFreeAce(acl, &first);
3759 ok(found, "RtlFirstFreeAce failed\n");
3760 ok(first == (PACE_HEADER)(acl + 1), "Failed to find ACL %p, %p\n", first, (PACE_HEADER)(acl + 1));
3761
3762 acl->AclSize = sizeof(ACL) - 1;
3763 first = (ACE_HEADER *)0xdeadbeef;
3764 found = RtlFirstFreeAce(acl, &first);
3765 ok(!found, "RtlFirstFreeAce failed\n");
3766 ok(first == NULL, "Found FirstAce = %p\n", first);
3767
3768 acl->AclSize = sizeof(ACL);
3769 first = (ACE_HEADER *)0xdeadbeef;
3770 found = RtlFirstFreeAce(acl, &first);
3771 ok(!found, "RtlFirstFreeAce failed\n");
3772 ok(first == NULL, "Found FirstAce = %p\n", first);
3773
3774 HeapFree(GetProcessHeap(), 0, acl);
3775}
3776
3777static void test_RtlInitializeSid(void)
3778{
3781 PSID sid = (PSID)&buffer;
3783
3784 status = RtlInitializeSid(sid, &sid_ident, 1);
3785 ok(!status, "Unexpected status %#lx.\n", status);
3786
3788 ok(!status, "Unexpected status %#lx.\n", status);
3789
3791 ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %#lx.\n", status);
3792}
3793
3795{
3798 BOOLEAN ret;
3799
3801 ok(!ret, "Unexpected return value %d.\n", ret);
3802
3804
3806 ok(!ret, "Unexpected return value %d.\n", ret);
3807
3809 ok(!status, "Unexpected return value %#lx.\n", status);
3810
3812 ok(ret, "Unexpected return value %d.\n", ret);
3813
3814 free(sd);
3815}
3816
3818{
3819 void *proc;
3820
3822 {
3823 win_skip( "RtlFindExportedRoutineByName is not present\n" );
3824 return;
3825 }
3826 proc = pRtlFindExportedRoutineByName( GetModuleHandleW( L"kernelbase" ), "CtrlRoutine" );
3827 ok( proc != NULL, "Expected non NULL address\n" );
3828 proc = pRtlFindExportedRoutineByName( GetModuleHandleW( L"kernel32" ), "CtrlRoutine" );
3829 ok( proc == NULL, "Shouldn't find forwarded function\n" );
3830}
3831
3833{
3834#if !defined(__REACTOS__) || _WIN32_WINNT >= _WIN32_WINNT_WIN10
3836 DWORD family, form;
3837
3838 if (!pRtlGetDeviceFamilyInfoEnum)
3839 {
3840 win_skip( "RtlGetDeviceFamilyInfoEnum is not present\n" );
3841 return;
3842 }
3843
3844 version = 0x1234567;
3845 family = 1234567;
3846 form = 1234567;
3847 pRtlGetDeviceFamilyInfoEnum(&version, &family, &form);
3848 ok( version != 0x1234567, "got unexpected unchanged value 0x1234567\n" );
3849 ok( family <= DEVICEFAMILYINFOENUM_MAX, "got unexpected %lu\n", family );
3850 ok( form <= DEVICEFAMILYDEVICEFORM_MAX, "got unexpected %lu\n", form );
3851 trace( "UAP version is %#I64x, device family is %lu, form factor is %lu\n", version, family, form );
3852#endif
3853}
3854
3856{
3860};
3861
3862static int test_rb_tree_entry_compare( const void *key, const struct wine_rb_entry *entry )
3863{
3865 const int *value = key;
3866
3867 return *value - t->value;
3868}
3869
3871{
3873 const int *value = key;
3874
3875 return *value - t->value;
3876}
3877
3879 int (*compare_func)( const void *key, const RTL_BALANCED_NODE *entry ))
3880{
3882 BOOLEAN right = 0;
3883 int c;
3884
3885 while (parent)
3886 {
3887 if (!(c = compare_func( key, parent ))) return -1;
3888 right = c > 0;
3889 if (!parent->Children[right]) break;
3890 parent = parent->Children[right];
3891 }
3892 pRtlRbInsertNodeEx( tree, parent, right, entry );
3893 return 0;
3894}
3895
3897{
3898 if (!entry) return NULL;
3900}
3901
3903{
3904 if (!entry) return NULL;
3906}
3907
3909{
3910 return test_rb_tree_entry_from_rtl_rb( (void *)(node->rtl_entry.ParentValue
3912}
3913
3914static void test_rb_tree(void)
3915{
3916 static int test_values[] = { 44, 51, 6, 66, 69, 20, 87, 80, 72, 86, 90, 16, 54, 61, 62, 14, 27, 39, 42, 41 };
3917 static const unsigned int count = ARRAY_SIZE(test_values);
3918
3919 struct test_rb_tree_entry *nodes, *parent, *parent2;
3920 RTL_BALANCED_NODE *prev_min_entry = NULL;
3921 int ret, is_red, min_val;
3922 struct rb_tree wine_tree;
3923 RTL_RB_TREE rtl_tree;
3924 unsigned int i;
3925
3926 if (!pRtlRbInsertNodeEx)
3927 {
3928 win_skip( "RtlRbInsertNodeEx is not present.\n" );
3929 return;
3930 }
3931
3932 memset( &rtl_tree, 0, sizeof(rtl_tree) );
3933 nodes = malloc( count * sizeof(*nodes) );
3934 memset( nodes, 0xcc, count * sizeof(*nodes) );
3935
3936 min_val = test_values[0];
3937 rb_init( &wine_tree, test_rb_tree_entry_compare );
3938 for (i = 0; i < count; ++i)
3939 {
3940 winetest_push_context( "i %u", i );
3941 nodes[i].value = test_values[i];
3942 ret = rb_put( &wine_tree, &nodes[i].value, &nodes[i].wine_rb_entry );
3943 ok( !ret, "got %d.\n", ret );
3945 ret = rtl_rb_tree_put( &rtl_tree, &nodes[i].value, &nodes[i].rtl_entry, test_rtl_rb_tree_entry_compare );
3946 ok( !ret, "got %d.\n", ret );
3947 parent2 = test_rb_tree_entry_rtl_parent( &nodes[i] );
3948 ok( parent == parent2, "got %p, %p.\n", parent, parent2 );
3950 ok( is_red == rb_is_red( &nodes[i].wine_rb_entry ), "got %d, expected %d.\n", is_red,
3951 rb_is_red( &nodes[i].wine_rb_entry ));
3952
3954 parent2 = test_rb_tree_entry_from_rtl_rb( rtl_tree.root );
3955 ok( parent == parent2, "got %p, %p.\n", parent, parent2 );
3956 if (nodes[i].value <= min_val)
3957 {
3958 min_val = nodes[i].value;
3959 prev_min_entry = &nodes[i].rtl_entry;
3960 }
3961 ok( rtl_tree.min == prev_min_entry, "unexpected min tree entry.\n" );
3963 }
3964
3965 for (i = 0; i < count; ++i)
3966 {
3967 struct test_rb_tree_entry *node;
3968
3969 winetest_push_context( "i %u", i );
3970 rb_remove( &wine_tree, &nodes[i].wine_rb_entry );
3971 pRtlRbRemoveNode( &rtl_tree, &nodes[i].rtl_entry );
3972
3974 parent2 = test_rb_tree_entry_from_rtl_rb( rtl_tree.root );
3975 ok( parent == parent2, "got %p, %p.\n", parent, parent2 );
3976
3978 parent2 = test_rb_tree_entry_from_rtl_rb( rtl_tree.min );
3979 ok( parent == parent2, "got %p, %p.\n", parent, parent2 );
3980
3982 {
3983 is_red = node->rtl_entry.ParentValue & RTL_BALANCED_NODE_RESERVED_PARENT_MASK;
3984 ok( is_red == rb_is_red( &node->wine_rb_entry ), "got %d, expected %d.\n", is_red, rb_is_red( &node->wine_rb_entry ));
3985 parent = test_rb_tree_entry_from_wine_rb( node->wine_rb_entry.parent );
3987 ok( parent == parent2, "got %p, %p.\n", parent, parent2 );
3988 }
3990 }
3991 ok( !rtl_tree.root, "got %p.\n", rtl_tree.root );
3992 ok( !rtl_tree.min, "got %p.\n", rtl_tree.min );
3993 free(nodes);
3994}
3995
3997{
3998 DWORD device_family_size, device_form_size, ret;
3999 WCHAR device_family[16], device_form[16];
4000
4001 if (!pRtlConvertDeviceFamilyInfoToString)
4002 {
4003 win_skip("RtlConvertDeviceFamilyInfoToString is unavailable.\n" );
4004 return;
4005 }
4006
4007 if (0) /* Crash on Windows */
4008 {
4009 ret = pRtlConvertDeviceFamilyInfoToString(NULL, NULL, NULL, NULL);
4010 ok(ret == STATUS_INVALID_PARAMETER, "Got unexpected status %#lx.\n", ret);
4011
4012 device_family_size = 0;
4013 ret = pRtlConvertDeviceFamilyInfoToString(&device_family_size, NULL, NULL, NULL);
4014 ok(ret == STATUS_BUFFER_TOO_SMALL, "Got unexpected status %#lx.\n", ret);
4015 ok(device_family_size == (wcslen(L"Windows.Desktop") + 1) * sizeof(WCHAR),
4016 "Got unexpected %#lx.\n", device_family_size);
4017
4018 device_form_size = 0;
4019 ret = pRtlConvertDeviceFamilyInfoToString(NULL, &device_form_size, NULL, NULL);
4020 ok(ret == STATUS_BUFFER_TOO_SMALL, "Got unexpected status %#lx.\n", ret);
4021 ok(device_form_size == (wcslen(L"Unknown") + 1) * sizeof(WCHAR), "Got unexpected %#lx.\n",
4022 device_form_size);
4023
4024 ret = pRtlConvertDeviceFamilyInfoToString(&device_family_size, NULL, device_family, NULL);
4025 ok(ret == STATUS_SUCCESS, "Got unexpected status %#lx.\n", ret);
4026 ok(device_family_size == (wcslen(L"Windows.Desktop") + 1) * sizeof(WCHAR),
4027 "Got unexpected %#lx.\n", device_family_size);
4028 ok(!wcscmp(device_family, L"Windows.Desktop"), "Got unexpected %s.\n", wine_dbgstr_w(device_family));
4029
4030 ret = pRtlConvertDeviceFamilyInfoToString(NULL, &device_form_size, NULL, device_form);
4031 ok(ret == STATUS_SUCCESS, "Got unexpected status %#lx.\n", ret);
4032 ok(device_form_size == (wcslen(L"Unknown") + 1) * sizeof(WCHAR), "Got unexpected %#lx.\n",
4033 device_form_size);
4034 ok(!wcscmp(device_form, L"Unknown"), "Got unexpected %s.\n", wine_dbgstr_w(device_form));
4035
4036 ret = pRtlConvertDeviceFamilyInfoToString(&device_family_size, &device_form_size, NULL, NULL);
4037 ok(ret == STATUS_INVALID_PARAMETER, "Got unexpected status %#lx.\n", ret);
4038 }
4039
4040 device_family_size = wcslen(L"Windows.Desktop") * sizeof(WCHAR);
4041 device_form_size = wcslen(L"Unknown") * sizeof(WCHAR);
4042 ret = pRtlConvertDeviceFamilyInfoToString(&device_family_size, &device_form_size, NULL, NULL);
4043 ok(ret == STATUS_BUFFER_TOO_SMALL, "Got unexpected status %#lx.\n", ret);
4044 ok(device_family_size == (wcslen(L"Windows.Desktop") + 1) * sizeof(WCHAR),
4045 "Got unexpected %#lx.\n", device_family_size);
4046 ok(device_form_size == (wcslen(L"Unknown") + 1) * sizeof(WCHAR), "Got unexpected %#lx.\n",
4047 device_form_size);
4048
4049 ret = pRtlConvertDeviceFamilyInfoToString(&device_family_size, &device_form_size, device_family, device_form);
4050 ok(ret == STATUS_SUCCESS, "Got unexpected status %#lx.\n", ret);
4051 ok(!wcscmp(device_family, L"Windows.Desktop"), "Got unexpected %s.\n", wine_dbgstr_w(device_family));
4052 ok(!wcscmp(device_form, L"Unknown"), "Got unexpected %s.\n", wine_dbgstr_w(device_form));
4053}
4054
4055static void test_user_procs(void)
4056{
4057 UINT64 ptrs[32], dummy[32] = { 0 };
4059 const UINT64 *ptr_A, *ptr_W, *ptr_workers;
4060 ULONG size_A, size_W, size_workers;
4061
4062 if (!pRtlRetrieveNtUserPfn || !pRtlInitializeNtUserPfn)
4063 {
4064 win_skip( "user procs not supported\n" );
4065 return;
4066 }
4067
4068 status = pRtlRetrieveNtUserPfn( &ptr_A, &ptr_W, &ptr_workers );
4069 ok( !status || broken(!is_win64 && status == STATUS_INVALID_PARAMETER), /* <= win8 32-bit */
4070 "RtlRetrieveNtUserPfn failed %lx\n", status );
4071 if (status) return;
4072
4073 /* assume that the tables are consecutive */
4074 size_A = (ptr_W - ptr_A) * sizeof(UINT64);
4075 size_W = (ptr_workers - ptr_W) * sizeof(UINT64);
4076 ok( size_A > 0x80 && size_A < 0x100, "unexpected size for %p %p %p\n", ptr_A, ptr_W, ptr_workers );
4077 ok( size_W == size_A, "unexpected size for %p %p %p\n", ptr_A, ptr_W, ptr_workers );
4078 memcpy( ptrs, ptr_A, size_A );
4079
4080 status = pRtlInitializeNtUserPfn( dummy, size_A, dummy + 1, size_W, dummy + 2, 0 );
4081 ok( status == STATUS_INVALID_PARAMETER, "RtlInitializeNtUserPfn failed %lx\n", status );
4082
4083 if (!pRtlResetNtUserPfn)
4084 {
4085 win_skip( "RtlResetNtUserPfn not supported\n" );
4086 return;
4087 }
4088
4089 status = pRtlResetNtUserPfn();
4090 ok( !status, "RtlResetNtUserPfn failed %lx\n", status );
4091 ok( !memcmp( ptrs, ptr_A, size_A ), "pointers changed by reset\n" );
4092
4093 /* can't do anything after reset except set them again */
4094 status = pRtlResetNtUserPfn();
4095 ok( status == STATUS_INVALID_PARAMETER, "RtlResetNtUserPfn failed %lx\n", status );
4096 status = pRtlRetrieveNtUserPfn( &ptr_A, &ptr_W, &ptr_workers );
4097 ok( status == STATUS_INVALID_PARAMETER, "RtlRetrieveNtUserPfn failed %lx\n", status );
4098
4099 for (size_workers = 0x100; size_workers > 0; size_workers--)
4100 {
4101 status = pRtlInitializeNtUserPfn( dummy, size_A, dummy + 1, size_W, dummy + 2, size_workers );
4102 if (!status) break;
4103 ok( status == STATUS_INVALID_PARAMETER, "RtlInitializeNtUserPfn failed %lx\n", status );
4104 }
4105 trace( "got sizes %lx %lx %lx\n", size_A, size_W, size_workers );
4106 if (!size_workers) return; /* something went wrong */
4107 ok( !memcmp( ptrs, ptr_A, size_A ), "pointers changed by init\n" );
4108
4109 /* can't set twice without a reset */
4110 status = pRtlInitializeNtUserPfn( dummy, size_A, dummy + 1, size_W, dummy + 2, size_workers );
4111 ok( status == STATUS_INVALID_PARAMETER, "RtlInitializeNtUserPfn failed %lx\n", status );
4112 status = pRtlResetNtUserPfn();
4113 ok( !status, "RtlResetNtUserPfn failed %lx\n", status );
4114 status = pRtlInitializeNtUserPfn( dummy, size_A, dummy + 1, size_W, dummy + 2, size_workers );
4115 ok( !status, "RtlInitializeNtUserPfn failed %lx\n", status );
4116 ok( !memcmp( ptrs, ptr_A, size_A ), "pointers changed by init\n" );
4117}
4118
4120{
4122
4160 test_DbgPrint();
4169 test_rb_tree();
4171}
std::map< E_MODULE, HMODULE > mod
Definition: LocaleTests.cpp:64
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
static TCHAR test_buffer[TEST_BUFFER_SIZE]
Definition: _tfileio.c:53
#define VOID
Definition: acefi.h:82
unsigned char BOOLEAN
Definition: actypes.h:127
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
static int used
Definition: adh-main.c:39
#define GetNTVersion()
Definition: apitest.h:17
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
NTSYSAPI ULONG NTAPI vDbgPrintEx(_In_ ULONG ComponentId, _In_ ULONG Level, _In_z_ PCCH Format, _In_ va_list ap)
#define DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAY_SIZE(A)
Definition: main.h:20
static HANDLE thread
Definition: service.c:33
#define ULongToHandle(h)
Definition: basetsd.h:75
#define NTSYSAPI
Definition: ntoskrnl.h:12
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
FT_UInt sid
Definition: cffcmap.c:138
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define mod2(n)
Definition: vgavideo.h:71
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HINSTANCE instance
Definition: main.c:40
static BOOL reserve(struct dynamic_array *array, int count, int itemsize)
Definition: mesh.c:5392
NTSTATUS NTAPI RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
Definition: version.c:182
#define NTSTATUS
Definition: precomp.h:19
BOOL WINAPI InitializeAcl(PACL pAcl, DWORD nAclLength, DWORD dwAclRevision)
Definition: security.c:1006
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1904
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define RtlUlongByteSwap(_x)
Definition: compat.h:815
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define DLL_PROCESS_DETACH
Definition: compat.h:130
#define RtlComputeCrc32
Definition: compat.h:810
#define GetProcAddress(x, y)
Definition: compat.h:753
#define HeapAlloc
Definition: compat.h:733
#define FreeLibrary(x)
Definition: compat.h:748
#define GetCurrentProcess()
Definition: compat.h:759
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define LoadLibraryW(x)
Definition: compat.h:747
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const WCHAR version[]
Definition: asmname.c:66
PPEB Peb
Definition: dllmain.c:27
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4171
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7512
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1972
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
#define va_end(v)
Definition: stdarg.h:28
#define va_start(v, l)
Definition: stdarg.h:26
unsigned int _winver
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
char * va_list
Definition: vadefs.h:50
USHORT port
Definition: uri.c:228
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
r parent
Definition: btrfs.c:3010
r reserved
Definition: btrfs.c:3006
#define rb_is_red(r)
Definition: rbtree.h:115
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
int form
Definition: main.c:89
ULONG Handle
Definition: gdb_input.c:15
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble t
Definition: gl.h:2047
GLenum func
Definition: glext.h:6028
GLuint res
Definition: glext.h:9613
GLuint address
Definition: glext.h:9393
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
const GLubyte * c
Definition: glext.h:8905
GLdouble GLdouble right
Definition: glext.h:10859
GLenum mode
Definition: glext.h:6217
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
const GLint * first
Definition: glext.h:5794
GLenum const GLvoid * addr
Definition: glext.h:9621
GLuint GLfloat * val
Definition: glext.h:7180
GLuint64EXT * result
Definition: glext.h:11304
GLuint GLuint num
Definition: glext.h:9618
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLdouble u1
Definition: glext.h:8308
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define DbgPrint
Definition: hal.h:12
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define cs
Definition: i386-dis.c:442
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:91
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:92
#define NtCurrentTeb
uint32_t entry
Definition: isohybrid.c:63
#define DbgPrintEx(cmpid, lvl, fmt,...)
Definition: kdinit.c:24
#define c
Definition: ke_i.h:80
#define wine_dbgstr_w
Definition: kernel32.h:34
BOOL is_wow64
Definition: main.c:38
NTSTATUS NTAPI LdrUnlockLoaderLock(_In_ ULONG Flags, _In_opt_ ULONG_PTR Cookie)
Definition: ldrapi.c:101
PIMAGE_BASE_RELOCATION NTAPI LdrProcessRelocationBlock(_In_ ULONG_PTR Address, _In_ ULONG Count, _In_ PUSHORT TypeOffset, _In_ LONG_PTR Delta)
Definition: ldrapi.c:1570
NTSTATUS NTAPI LdrLockLoaderLock(_In_ ULONG Flags, _Out_opt_ PULONG Disposition, _Out_opt_ PULONG_PTR Cookie)
Definition: ldrapi.c:174
NTSTATUS NTAPI LdrAddRefDll(_In_ ULONG Flags, _In_ PVOID BaseAddress)
Definition: ldrapi.c:1205
#define LDR_DLL_NOTIFICATION_REASON_UNLOADED
Definition: ldrtypes.h:204
#define LDR_ADDREF_DLL_PIN
Definition: ldrtypes.h:75
#define LDR_DLL_NOTIFICATION_REASON_LOADED
Definition: ldrtypes.h:203
#define win_skip
Definition: minitest.h:67
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:537
#define todo_wine
Definition: minitest.h:80
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
static struct test_info tests[]
static BOOL rtl
Definition: propsheet.c:36
BOOL expected
Definition: store.c:2000
static const WCHAR sd[]
Definition: suminfo.c:286
static int strict
Definition: error.c:55
static void test_RtlFillMemoryUlong(void)
Definition: rtl.c:351
static HMODULE hntdll
Definition: rtl.c:102
#define LEN
Definition: rtl.c:140
static void *WINAPI * pRtlFindExportedRoutineByName(HMODULE, const char *)
#define DECOMPRESS_BROKEN_TRUNCATED
Definition: rtl.c:2516
static LONG CALLBACK test_heap_destroy_except_handler(EXCEPTION_POINTERS *eptrs)
Definition: rtl.c:3592
static DWORD DWORD *static RTL_BALANCED_NODE RTL_BALANCED_NODE *static RTL_BALANCED_NODE *static DWORD WCHAR WCHAR *static ULONG const UINT64 ULONG const void ULONG workers_size
Definition: rtl.c:130
static void test_RtlIpv4StringToAddress(void)
Definition: rtl.c:1113
static BOOL WINAPI fake_dll_main_fail(HINSTANCE instance, DWORD reason, void *reserved)
Definition: rtl.c:3315
static void CALLBACK ldr_notify_callback_imports(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
Definition: rtl.c:3354
static void test_RtlDeleteTimer(void)
Definition: rtl.c:728
static USHORT
Definition: rtl.c:112
NTSTATUS res
Definition: rtl.c:992
static NTSTATUS WINAPIV test_vDbgPrintEx(ULONG id, ULONG level, const char *fmt,...)
Definition: rtl.c:3481
#define DECOMPRESS_BROKEN_FRAGMENT
Definition: rtl.c:2515
static LONG CALLBACK test_dbg_print_except_handler(EXCEPTION_POINTERS *eptrs)
Definition: rtl.c:3464
static void test_RtlIsCriticalSectionLocked(void)
Definition: rtl.c:2968
static LPSTR
Definition: rtl.c:112
static NTSTATUS WINAPIV test_vDbgPrintExWithPrefix(const char *prefix, ULONG id, ULONG level, const char *fmt,...)
Definition: rtl.c:3491
static WCHAR wintrustdllW[]
Definition: rtl.c:144
static DWORD WINAPI critsect_locked_thread(void *param)
Definition: rtl.c:2934
static void test_RtlComputeCrc32(void)
Definition: rtl.c:664
static char * dest
Definition: rtl.c:149
PCSTR address
Definition: rtl.c:991
static void init_ip4(IN_ADDR *addr, const int src[4])
Definition: rtl.c:1098
static void test_RtlQueryProcessDebugInformation(void)
Definition: rtl.c:195
static BOOL test_dbg_print_except
Definition: rtl.c:3461
static void compare_RtlIpv6StringToAddressW(PCSTR name_a, int terminator_offset_a, const struct in6_addr *addr_a, NTSTATUS res_a)
Definition: rtl.c:1915
int ip[4]
Definition: rtl.c:994
static void CALLBACK ldr_notify_callback_dll_main(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
Definition: rtl.c:3291
static void * get_rva(HMODULE module, DWORD va)
Definition: rtl.c:3213
static void test_RtlByteSwap(void)
Definition: rtl.c:399
static const all_accesses_t all_accesses[]
Definition: rtl.c:598
static WCHAR crypt32dllW[]
Definition: rtl.c:145
static DWORD DWORD *static RTL_BALANCED_NODE RTL_BALANCED_NODE *static RTL_BALANCED_NODE *static DWORD WCHAR WCHAR *static ULONG const UINT64 * client_procsW
Definition: rtl.c:129
static void test_RtlUniform(void)
Definition: rtl.c:455
struct _RTL_HANDLE_TABLE RTL_HANDLE_TABLE
static void test_RtlIpv6AddressToString(void)
Definition: rtl.c:1672
static void test_RtlMakeSelfRelativeSD(void)
Definition: rtl.c:3170
#define LFILL(len)
Definition: rtl.c:349
#define CMP(str)
Definition: rtl.c:293
static void test_RtlFindExportedRoutineByName(void)
Definition: rtl.c:3817
static void test_RtlInitializeCriticalSectionEx(void)
Definition: rtl.c:3024
static void RtlpMakeHandleAllocated(RTL_HANDLE *Handle)
Definition: rtl.c:679
static void test_RtlAreAnyAccessesGranted(void)
Definition: rtl.c:648
static void test_RtlThreadErrorMode(void)
Definition: rtl.c:738
static void test_RtlRandom(void)
Definition: rtl.c:575
int terminator_offset
Definition: rtl.c:993
static ULONG dest_aligned_block[32]
Definition: rtl.c:147
static const char * src_src
Definition: rtl.c:141
static DWORD DWORD *static RTL_BALANCED_NODE RTL_BALANCED_NODE *static RTL_BALANCED_NODE *static DWORD WCHAR WCHAR *static ULONG const UINT64 ULONG procsW_size
Definition: rtl.c:129
static WCHAR ws2_32dllW[]
Definition: rtl.c:142
#define COPY(len)
Definition: rtl.c:292
static void test_RtlIpv4AddressToStringEx(void)
Definition: rtl.c:870
static void test_DbgPrint(void)
Definition: rtl.c:3501
static PULONG
Definition: rtl.c:112
struct _RTL_HANDLE RTL_HANDLE
static void test_RtlCreateHeap(void)
Definition: rtl.c:3674
static ULONG
Definition: rtl.c:105
static void CALLBACK ldr_notify_callback2(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
Definition: rtl.c:3269
static const any_accesses_t any_accesses[]
Definition: rtl.c:635
static void test_RtlZeroMemory(void)
Definition: rtl.c:378
static void test_RtlIpv4StringToAddressEx(void)
Definition: rtl.c:1180
static void test_LdrAddRefDll(void)
Definition: rtl.c:2298
static BOOLEAN
Definition: rtl.c:113
static void test_RtlIpv6StringToAddressEx(void)
Definition: rtl.c:2065
static void test_RtlLeaveCriticalSection(void)
Definition: rtl.c:3057
static void compare_RtlIpv6StringToAddressExW(PCSTR name_a, const struct in6_addr *addr_a, HRESULT res_a, ULONG scope_a, USHORT port_a)
Definition: rtl.c:2036
static LONG test_dbg_print_except_ret
Definition: rtl.c:3462
#define COMP(str1, str2, cmplen, len)
Definition: rtl.c:232
static struct test_rb_tree_entry * test_rb_tree_entry_from_wine_rb(struct rb_entry *entry)
Definition: rtl.c:3896
static DWORD
Definition: rtl.c:3210
static void test_RtlValidSecurityDescriptor(void)
Definition: rtl.c:3794
int terminator_offset_strict
Definition: rtl.c:997
#define HEAP_VALIDATE_PARAMS
Definition: rtl.c:3621
#define call_fastcall_func1(func, a)
Definition: rtl.c:97
static void test_RtlMoveMemory(void)
Definition: rtl.c:295
static void InitFunctionPtrs(void)
Definition: rtl.c:152
static BYTE
Definition: rtl.c:104
static PBOOL
Definition: rtl.c:137
static void test_RtlCompareMemory(void)
Definition: rtl.c:235
static IN_ADDR PUSHORT
Definition: rtl.c:113
static void WINAPI ldr_enum_callback(LDR_DATA_TABLE_ENTRY *module, void *context, BOOLEAN *stop)
Definition: rtl.c:3123
static ULONG src_aligned_block[4]
Definition: rtl.c:146
static BOOL test_heap_destroy_dbgstr
Definition: rtl.c:3589
static WCHAR nsidllW[]
Definition: rtl.c:143
static NTSTATUS NTAPI test_commit_routine(void *base, void **address, SIZE_T *size)
Definition: rtl.c:3666
static const struct @1831 ipv6_tests[]
static DWORD DWORD *static RTL_BALANCED_NODE RTL_BALANCED_NODE *static RTL_BALANCED_NODE *static DWORD WCHAR WCHAR *static ULONG const UINT64 ULONG const void * client_workers
Definition: rtl.c:130
static struct test_rb_tree_entry * test_rb_tree_entry_from_rtl_rb(RTL_BALANCED_NODE *entry)
Definition: rtl.c:3902
static void test_RtlDecompressBuffer(void)
Definition: rtl.c:2518
#define MCMP(str)
Definition: rtl.c:376
static void test_HandleTables(void)
Definition: rtl.c:685
static LPCVOID
Definition: rtl.c:103
enum @1830::@1832 flags
static struct test_rb_tree_entry * test_rb_tree_entry_rtl_parent(struct test_rb_tree_entry *node)
Definition: rtl.c:3908
static PCHAR
Definition: rtl.c:114
static void test_LdrRegisterDllNotification(void)
Definition: rtl.c:3374
static BOOL test_heap_destroy_break
Definition: rtl.c:3590
static int test_rtl_rb_tree_entry_compare(const void *key, const RTL_BALANCED_NODE *entry)
Definition: rtl.c:3870
static void test_RtlCompressBuffer(void)
Definition: rtl.c:2393
static BOOL is_incomplete_chunk(const UCHAR *compressed, ULONG compressed_size, BOOL check_all)
Definition: rtl.c:2494
static HMODULE hkernel32
Definition: rtl.c:136
#define htons(s)
Definition: rtl.c:84
static void init_ip6(IN6_ADDR *addr, const int src[8])
Definition: rtl.c:1657
static void test_RtlFillMemory(void)
Definition: rtl.c:326
static LPVOID
Definition: rtl.c:3210
static SIZE_T
Definition: rtl.c:103
static void test_LdrEnumerateLoadedModules(void)
Definition: rtl.c:3135
static LPDWORD
Definition: rtl.c:111
static void test_RtlConvertDeviceFamilyInfoToString(void)
Definition: rtl.c:3996
static void test_RtlGetCompressionWorkSpaceSize(void)
Definition: rtl.c:2460
static void CALLBACK ldr_notify_callback1(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
Definition: rtl.c:3218
static DWORD * dll_main_data
Definition: rtl.c:3211
static void test_RtlIpv6StringToAddress(void)
Definition: rtl.c:1952
static void test_RtlDestroyHeap(void)
Definition: rtl.c:3637
static void test_RtlAllocateAndInitializeSid(void)
Definition: rtl.c:706
static void test_RtlAreAllAccessesGranted(void)
Definition: rtl.c:612
#define FILL(len)
Definition: rtl.c:324
static BOOL WINAPI fake_dll_main(HINSTANCE instance, DWORD reason, void *reserved)
Definition: rtl.c:3276
static void test_user_procs(void)
Definition: rtl.c:4055
static void test_RtlGetDeviceFamilyInfoEnum(void)
Definition: rtl.c:3832
int ip_strict[4]
Definition: rtl.c:998
static void test_RtlInitializeSid(void)
Definition: rtl.c:3777
static DWORD DWORD *static RTL_BALANCED_NODE RTL_BALANCED_NODE *static RTL_BALANCED_NODE *static DWORD WCHAR WCHAR *static ULONG procsA_size
Definition: rtl.c:128
static struct @1830 ipv4_tests[]
static void test_LdrLockLoaderLock(void)
Definition: rtl.c:2347
const WCHAR * expected_dll
Definition: rtl.c:150
static BOOL is_win64
Definition: rtl.c:73
static void test_RtlCompareMemoryUlong(void)
Definition: rtl.c:247
static int test_rb_tree_entry_compare(const void *key, const struct wine_rb_entry *entry)
Definition: rtl.c:3862
#define ZERO(len)
Definition: rtl.c:375
static void test_RtlFirstFreeAce(void)
Definition: rtl.c:3729
static void test_RtlIpv6AddressToStringEx(void)
Definition: rtl.c:1796
static void test_rb_tree(void)
Definition: rtl.c:3914
static struct commit_routine_context commit_context
Definition: rtl.c:3664
static int rtl_rb_tree_put(RTL_RB_TREE *tree, const void *key, RTL_BALANCED_NODE *entry, int(*compare_func)(const void *key, const RTL_BALANCED_NODE *entry))
Definition: rtl.c:3878
static void void *static PLDR_DLL_NOTIFICATION_FUNCTION
Definition: rtl.c:122
NTSTATUS res_strict
Definition: rtl.c:996
static void test_LdrProcessRelocationBlock(void)
Definition: rtl.c:806
static void CALLBACK ldr_notify_callback_fail(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
Definition: rtl.c:3330
static USHORT __my_ushort_swap(USHORT s)
Definition: rtl.c:80
static void test_RtlIpv4AddressToString(void)
Definition: rtl.c:832
static const BYTE uncompressed[]
Definition: misc.c:392
struct _SID * PSID
Definition: eventlog.c:37
struct _ACL ACL
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
#define DPFLTR_WARNING_LEVEL
Definition: kdtypes.h:31
#define DPFLTR_MASK
Definition: kdtypes.h:34
NTSYSAPI ULONG NTAPI RtlUniform(_In_ PULONG Seed)
NTSYSAPI NTSTATUS NTAPI RtlIpv6StringToAddressW(_In_ PCWSTR String, _Out_ PCWSTR *Terminator, _Out_ struct in6_addr *Addr)
Definition: network.c:1005
NTSYSAPI NTSTATUS NTAPI RtlDeleteCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlDestroyQueryDebugBuffer(IN PRTL_DEBUG_INFORMATION DebugBuffer)
NTSYSAPI VOID NTAPI RtlInitializeHandleTable(_In_ ULONG TableSize, _In_ ULONG HandleSize, _In_ PRTL_HANDLE_TABLE HandleTable)
NTSYSAPI NTSTATUS NTAPI RtlCompressBuffer(_In_ USHORT CompressionFormatAndEngine, _In_reads_bytes_(UncompressedBufferSize) PUCHAR UncompressedBuffer, _In_ ULONG UncompressedBufferSize, _Out_writes_bytes_to_(CompressedBufferSize, *FinalCompressedSize) PUCHAR CompressedBuffer, _In_ ULONG CompressedBufferSize, _In_ ULONG UncompressedChunkSize, _Out_ PULONG FinalCompressedSize, _In_ PVOID WorkSpace)
NTSYSAPI BOOLEAN NTAPI RtlFreeHandle(_In_ PRTL_HANDLE_TABLE HandleTable, _In_ PRTL_HANDLE_TABLE_ENTRY Handle)
NTSYSAPI VOID NTAPI RtlDestroyHandleTable(_Inout_ PRTL_HANDLE_TABLE HandleTable)
NTSYSAPI NTSTATUS NTAPI RtlGetCompressionWorkSpaceSize(_In_ USHORT CompressionFormatAndEngine, _Out_ PULONG CompressBufferWorkSpaceSize, _Out_ PULONG CompressFragmentWorkSpaceSize)
NTSYSAPI NTSTATUS NTAPI RtlQueryProcessDebugInformation(_In_ ULONG ProcessId, _In_ ULONG DebugInfoClassMask, _Inout_ PRTL_DEBUG_INFORMATION DebugBuffer)
NTSYSAPI PRTL_HANDLE_TABLE_ENTRY NTAPI RtlAllocateHandle(_In_ PRTL_HANDLE_TABLE HandleTable, _Inout_ PULONG Index)
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
NTSYSAPI ULONG NTAPI RtlRandom(_Inout_ PULONG Seed)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI PSTR NTAPI RtlIpv6AddressToStringA(_In_ const struct in6_addr *Addr, _Out_writes_(46) PSTR S)
NTSYSAPI PRTL_DEBUG_INFORMATION NTAPI RtlCreateQueryDebugBuffer(_In_ ULONG Size, _In_ BOOLEAN EventPair)
Definition: dbgbuffer.c:66
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI PVOID NTAPI RtlFreeSid(_In_ _Post_invalid_ PSID Sid)
NTSYSAPI NTSTATUS NTAPI RtlIpv4StringToAddressA(_In_ PCSTR String, _In_ BOOLEAN Strict, _Out_ PCSTR *Terminator, _Out_ struct in_addr *Addr)
Definition: network.c:318
NTSYSAPI NTSTATUS NTAPI RtlDeleteTimer(_In_ HANDLE TimerQueue, _In_ HANDLE Timer, _In_ HANDLE CompletionEvent)
NTSYSAPI NTSTATUS NTAPI RtlMakeSelfRelativeSD(_In_ PSECURITY_DESCRIPTOR AbsoluteSD, _Out_ PSECURITY_DESCRIPTOR SelfRelativeSD, _Inout_ PULONG BufferLength)
NTSYSAPI BOOLEAN NTAPI RtlValidSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: sd.c:1054
NTSYSAPI NTSTATUS NTAPI RtlIpv6StringToAddressA(_In_ PCSTR String, _Out_ PCSTR *Terminator, _Out_ struct in6_addr *Addr)
Definition: network.c:725
NTSYSAPI BOOLEAN NTAPI RtlFirstFreeAce(PACL Acl, PACE *Ace)
NTSYSAPI BOOLEAN NTAPI RtlAreAllAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
NTSYSAPI BOOLEAN NTAPI RtlAreAnyAccessesGranted(ACCESS_MASK GrantedAccess, ACCESS_MASK DesiredAccess)
_Use_decl_annotations_ NTSTATUS NTAPI RtlMultiByteToUnicodeN(_Out_ PWCH UnicodeString, _In_ ULONG UnicodeSize, _Out_opt_ PULONG ResultSize, _In_ PCCH MbString, _In_ ULONG MbSize)
Definition: nlsboot.c:63
#define _In_
Definition: no_sal2.h:158
NTSYSAPI PVOID NTAPI RtlDestroyHeap(IN PVOID HeapHandle)
#define PAGE_READWRITE
Definition: nt_native.h:1307
ULONG ACCESS_MASK
Definition: nt_native.h:40
NTSYSAPI PVOID NTAPI RtlCreateHeap(IN ULONG Flags, IN PVOID HeapBase OPTIONAL, IN ULONG ReserveSize OPTIONAL, IN ULONG CommitSize OPTIONAL, IN PVOID Lock OPTIONAL, IN PRTL_HEAP_PARAMETERS Parameters OPTIONAL)
#define FASTCALL
Definition: nt_native.h:50
#define BOOL
Definition: nt_native.h:43
#define MEM_RESERVE
Definition: nt_native.h:1317
#define MEM_RELEASE
Definition: nt_native.h:1319
#define MEM_COMMIT
Definition: nt_native.h:1316
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define RTL_BALANCED_NODE_RESERVED_PARENT_MASK
#define COMPRESSION_FORMAT_DEFAULT
#define COMPRESSION_FORMAT_NONE
#define COMPRESSION_ENGINE_MAXIMUM
#define COMPRESSION_FORMAT_LZNT1
NTSYSAPI NTSTATUS NTAPI RtlAllocateAndInitializeSid(IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount, IN ULONG SubAuthority0, IN ULONG SubAuthority1, IN ULONG SubAuthority2, IN ULONG SubAuthority3, IN ULONG SubAuthority4, IN ULONG SubAuthority5, IN ULONG SubAuthority6, IN ULONG SubAuthority7, OUT PSID *Sid)
Definition: sid.c:290
NTSYSAPI NTSTATUS NTAPI RtlAbsoluteToSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor, IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, IN PULONG BufferLength)
Definition: sd.c:626
NTSYSAPI NTSTATUS NTAPI RtlInitializeSid(IN OUT PSID Sid, IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount)
#define STATUS_UNSUPPORTED_COMPRESSION
Definition: ntstatus.h:854
#define STATUS_WAIT_1
Definition: ntstatus.h:123
#define STATUS_BAD_DESCRIPTOR_FORMAT
Definition: ntstatus.h:561
#define STATUS_BAD_COMPRESSION_BUFFER
Definition: ntstatus.h:832
#define STATUS_INVALID_CID
Definition: ntstatus.h:341
#define STATUS_ASSERTION_FAILURE
Definition: ntstatus.h:1099
#define STATUS_INVALID_SID
Definition: ntstatus.h:450
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:570
#define STATUS_BREAKPOINT
Definition: ntstatus.h:264
#define DBG_PRINTEXCEPTION_C
Definition: ntstatus.h:104
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:569
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:571
static HANDLE proc()
Definition: pdb.c:32
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
short WCHAR
Definition: pedump.c:58
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
char CHAR
Definition: pedump.c:57
#define calloc
Definition: rosglue.h:14
#define WINAPIV
Definition: sdbpapi.h:64
strcpy
Definition: string.h:131
const char int int int static __inline const char * wine_dbgstr_a(const char *s)
Definition: debug.h:152
#define wine_rb_entry
Definition: rbtree.h:404
#define WINE_RB_ENTRY_VALUE
Definition: rbtree.h:414
static struct rb_entry * rb_head(struct rb_entry *iter)
Definition: rbtree.h:97
static int rb_put(struct rb_tree *tree, const void *key, struct rb_entry *entry)
Definition: rbtree.h:204
#define RB_FOR_EACH_ENTRY(elem, tree, type, field)
Definition: rbtree.h:148
static void rb_remove(struct rb_tree *tree, struct rb_entry *entry)
Definition: rbtree.h:272
static void rb_init(struct rb_tree *tree, rb_compare_func_t compare)
Definition: rbtree.h:173
#define memset(x, y, z)
Definition: compat.h:39
ULONG NTAPI vDbgPrintExWithPrefix(IN PCCH Prefix, IN ULONG ComponentId, IN ULONG Level, IN PCCH Format, IN va_list ap)
Definition: debug.c:167
#define args
Definition: format.c:66
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
Definition: rtl.c:674
void * MyValue
Definition: rtl.c:676
RTL_HANDLE RtlHandle
Definition: rtl.c:675
USHORT AceCount
Definition: ms-dtyp.idl:297
USHORT AclSize
Definition: ms-dtyp.idl:296
ULONG Eip
Definition: nt_native.h:1479
ULONG Pc
Definition: ke.h:271
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
PCONTEXT ContextRecord
Definition: rtltypes.h:201
DWORD ExceptionCode
Definition: compat.h:208
DWORD NumberParameters
Definition: compat.h:212
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
union _IMAGE_THUNK_DATA32::@2335 u1
Definition: btrfs_drv.h:1876
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
ULONG dwMajorVersion
Definition: rtltypes.h:270
BYTE BeingDebugged
Definition: btrfs_drv.h:1909
ULONG Unused[2]
Definition: rtl.c:64
PVOID ReservedMemory
Definition: rtl.c:67
PVOID FirstHandle
Definition: rtl.c:66
PVOID MaxHandle
Definition: rtl.c:68
PVOID NextFree
Definition: rtl.c:65
ULONG MaxHandleCount
Definition: rtl.c:62
ULONG HandleSize
Definition: rtl.c:63
struct _RTL_HANDLE * Next
Definition: rtl.c:57
FIXME: should move to rtltypes.h, but we can't include it here.
Definition: ketypes.h:1160
struct _root * root
Definition: btrfs_drv.h:433
ACCESS_MASK GrantedAccess
Definition: rtl.c:593
BOOLEAN result
Definition: rtl.c:595
ACCESS_MASK DesiredAccess
Definition: rtl.c:594
ACCESS_MASK GrantedAccess
Definition: rtl.c:630
BOOLEAN result
Definition: rtl.c:632
ACCESS_MASK DesiredAccess
Definition: rtl.c:631
Definition: match.c:390
Definition: http.c:7252
Definition: cookie.c:34
CRITICAL_SECTION crit
Definition: rtl.c:2930
HANDLE semaphores[2]
Definition: rtl.c:2931
Definition: dsound.c:943
Definition: heap.c:86
DWORD flags
Definition: rtl.c:3632
DWORD unknown4
Definition: rtl.c:3628
UINT_PTR unknown1[2]
Definition: heap.c:87
DWORD force_flags
Definition: rtl.c:3633
DWORD unknown6[3]
Definition: rtl.c:3630
DWORD_PTR unknown8[6]
Definition: rtl.c:3634
DWORD_PTR unknown7[2]
Definition: rtl.c:3631
UINT unknown3[2]
Definition: heap.c:91
UINT_PTR unknown2[7]
Definition: heap.c:90
DWORD_PTR unknown5[2]
Definition: rtl.c:3629
Definition: inet.h:67
Definition: tcpip.h:126
u_long S_addr
Definition: tcpip.h:131
union in_addr::@1116 S_un
Definition: dhcpd.h:62
Definition: copy.c:22
BOOL abort
Definition: rtl.c:3118
BOOL found
Definition: rtl.c:3119
Definition: name.c:39
Definition: rbtree.h:30
Definition: rbtree.h:40
struct rb_entry * root
Definition: rbtree.h:42
Definition: ps.c:97
Definition: rtl.c:3856
RTL_BALANCED_NODE rtl_entry
Definition: rtl.c:3859
int value
Definition: rtl.c:3857
struct rb_entry wine_rb_entry
Definition: rtl.c:3858
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:687
HANDLE WINAPI DECLSPEC_HOTPATCH CreateSemaphoreW(IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes OPTIONAL, IN LONG lInitialCount, IN LONG lMaximumCount, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:406
BOOL WINAPI DECLSPEC_HOTPATCH ReleaseSemaphore(IN HANDLE hSemaphore, IN LONG lReleaseCount, IN LPLONG lpPreviousCount)
Definition: synch.c:491
NTSYSAPI PSTR NTAPI RtlIpv4AddressToStringA(_In_ const struct in_addr *Addr, _Out_writes_(16) PSTR S)
Character const *const prefix
Definition: tempnam.cpp:195
const char * LPCSTR
Definition: typedefs.h:52
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char UCHAR
Definition: typedefs.h:53
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define NTAPI
Definition: typedefs.h:36
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
char * LPSTR
Definition: typedefs.h:51
uint64_t ULONGLONG
Definition: typedefs.h:67
const char * PCSTR
Definition: typedefs.h:52
uint32_t ULONG_PTR
Definition: typedefs.h:65
HANDLE HMODULE
Definition: typedefs.h:77
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define MAXLONG
Definition: umtypes.h:116
Definition: dlist.c:348
Definition: pdh_main.c:96
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664
LPVOID NTAPI VirtualAlloc(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:65
BOOL NTAPI VirtualFree(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:119
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1156
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define WAIT_OBJECT_0
Definition: winbase.h:383
#define WINAPI
Definition: msvc.h:6
#define __ASM_STDCALL_FUNC(name, args, code)
Definition: asm.h:123
NTSYSAPI BOOLEAN WINAPI RtlIsValidIndexHandle(const RTL_HANDLE_TABLE *, ULONG Index, RTL_HANDLE **)
NTSYSAPI ULONG WINAPI RtlRemoveVectoredExceptionHandler(PVOID)
#define PDI_HEAPS
Definition: winternl.h:3288
#define PDI_MODULES
Definition: winternl.h:3286
NTSYSAPI NTSTATUS WINAPI RtlDecompressFragment(USHORT, PUCHAR, ULONG, PUCHAR, ULONG, ULONG, PULONG, PVOID)
NTSYSAPI PVOID WINAPI RtlAddVectoredExceptionHandler(ULONG, PVECTORED_EXCEPTION_HANDLER)
NTSYSAPI NTSTATUS WINAPI RtlDecompressBuffer(USHORT, PUCHAR, ULONG, PUCHAR, ULONG, PULONG)
#define PDI_HEAP_BLOCKS
Definition: winternl.h:3290
#define IMAGE_REL_BASED_HIGHLOW
Definition: winnt_old.h:912
#define DEVICEFAMILYDEVICEFORM_MAX
Definition: winnt_old.h:4556
#define IMAGE_REL_BASED_HIGH
Definition: winnt_old.h:910
#define RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO
Definition: winnt_old.h:1152
#define IMAGE_REL_BASED_LOW
Definition: winnt_old.h:911
#define DEVICEFAMILYINFOENUM_MAX
Definition: winnt_old.h:4506
#define RtlUlonglongByteSwap(_x)
Definition: rtlfuncs.h:3216
#define RtlUshortByteSwap(_x)
Definition: rtlfuncs.h:3214
_Must_inspect_result_ NTSYSAPI SIZE_T NTAPI RtlCompareMemoryUlong(_In_reads_bytes_(Length) PVOID Source, _In_ SIZE_T Length, _In_ ULONG Pattern)
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK GrantedAccess
Definition: sefuncs.h:20
#define SE_SELF_RELATIVE
Definition: setypes.h:846
struct _SECURITY_DESCRIPTOR_RELATIVE SECURITY_DESCRIPTOR_RELATIVE
#define SECURITY_NT_AUTHORITY
Definition: setypes.h:554
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define SECURITY_DESCRIPTOR_MIN_LENGTH
Definition: setypes.h:827
#define ACL_REVISION
Definition: setypes.h:39
#define SID_MAX_SUB_AUTHORITIES
Definition: setypes.h:482
#define SECURITY_MAX_SID_SIZE
Definition: setypes.h:486
unsigned char BYTE
Definition: xxhash.c:193