Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/iphlpapi/tests/iphlpapi.c | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+)
diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index 7a4821aae7..8ccbf5f9b6 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -56,6 +56,7 @@ static DWORD (WINAPI *pAllocateAndGetTcpExTableFromStack)(void**,BOOL,HANDLE,DWO static DWORD (WINAPI *pGetIfEntry2)(PMIB_IF_ROW2); static DWORD (WINAPI *pGetIfTable2)(PMIB_IF_TABLE2*); static DWORD (WINAPI *pGetIfTable2Ex)(MIB_IF_TABLE_LEVEL,PMIB_IF_TABLE2*); +static DWORD (WINAPI *pGetTcp6Table)(PMIB_TCP6TABLE,PDWORD,BOOL); static DWORD (WINAPI *pGetUdp6Table)(PMIB_UDP6TABLE,PDWORD,BOOL); static DWORD (WINAPI *pGetUnicastIpAddressEntry)(MIB_UNICASTIPADDRESS_ROW*); static DWORD (WINAPI *pGetUnicastIpAddressTable)(ADDRESS_FAMILY,MIB_UNICASTIPADDRESS_TABLE**); @@ -86,6 +87,7 @@ static void loadIPHlpApi(void) pGetIfEntry2 = (void *)GetProcAddress(hLibrary, "GetIfEntry2"); pGetIfTable2 = (void *)GetProcAddress(hLibrary, "GetIfTable2"); pGetIfTable2Ex = (void *)GetProcAddress(hLibrary, "GetIfTable2Ex"); + pGetTcp6Table = (void *)GetProcAddress(hLibrary, "GetTcp6Table"); pGetUdp6Table = (void *)GetProcAddress(hLibrary, "GetUdp6Table"); pGetUnicastIpAddressEntry = (void *)GetProcAddress(hLibrary, "GetUnicastIpAddressEntry"); pGetUnicastIpAddressTable = (void *)GetProcAddress(hLibrary, "GetUnicastIpAddressTable"); @@ -2095,6 +2097,51 @@ static void test_ConvertLengthToIpv4Mask(void) ok( mask == INADDR_NONE, "ConvertLengthToIpv4Mask mask value 0x%08x, expected 0x%08x\n", mask, INADDR_NONE ); }
+static void test_GetTcp6Table(void) +{ + DWORD ret; + ULONG size = 0; + PMIB_TCP6TABLE buf; + + if (!pGetTcp6Table) + { + win_skip("GetTcp6Table not available\n"); + return; + } + + ret = pGetTcp6Table(NULL, &size, FALSE); + if (ret == ERROR_NOT_SUPPORTED) + { + skip("GetTcp6Table is not supported\n"); + return; + } + ok(ret == ERROR_INSUFFICIENT_BUFFER, + "GetTcp6Table(NULL, &size, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n", ret); + if (ret != ERROR_INSUFFICIENT_BUFFER) return; + + buf = HeapAlloc(GetProcessHeap(), 0, size); + + ret = pGetTcp6Table(buf, &size, FALSE); + ok(ret == NO_ERROR, + "GetTcp6Table(buf, &size, FALSE) returned %d, expected NO_ERROR\n", ret); + + if (ret == NO_ERROR && winetest_debug > 1) + { + DWORD i; + trace("TCP6 table: %u entries\n", buf->dwNumEntries); + for (i = 0; i < buf->dwNumEntries; i++) + { + trace("%u: local %s%%%u:%u remote %s%%%u:%u state %u\n", i, + ntoa6(&buf->table[i].LocalAddr), ntohs(buf->table[i].dwLocalScopeId), + ntohs(buf->table[i].dwLocalPort), ntoa6(&buf->table[i].RemoteAddr), + ntohs(buf->table[i].dwRemoteScopeId), ntohs(buf->table[i].dwRemotePort), + buf->table[i].State); + } + } + + HeapFree(GetProcessHeap(), 0, buf); +} + static void test_GetUdp6Table(void) { DWORD apiReturn; @@ -2268,6 +2315,7 @@ START_TEST(iphlpapi) test_GetUnicastIpAddressEntry(); test_GetUnicastIpAddressTable(); test_ConvertLengthToIpv4Mask(); + test_GetTcp6Table(); test_GetUdp6Table(); test_ParseNetworkString(); freeIPHlpApi();
Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/iphlpapi/iphlpapi_main.c | 26 ++++-- dlls/iphlpapi/ipstats.c | 168 ++++++++++++++++++++++++++++++++++ dlls/iphlpapi/ipstats.h | 1 + 3 files changed, 187 insertions(+), 8 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index 8c7c9018c4..429958198d 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -2393,15 +2393,25 @@ DWORD WINAPI GetExtendedTcpTable(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder,
if (!pdwSize) return ERROR_INVALID_PARAMETER;
- if (ulAf != WS_AF_INET) - { - FIXME("ulAf = %u not supported\n", ulAf); - return ERROR_NOT_SUPPORTED; - } if (TableClass >= TCP_TABLE_OWNER_MODULE_LISTENER) FIXME("module classes not fully supported\n");
- if ((ret = build_tcp_table(TableClass, &table, bOrder, GetProcessHeap(), 0, &size))) + switch (ulAf) + { + case WS_AF_INET: + ret = build_tcp_table(TableClass, &table, bOrder, GetProcessHeap(), 0, &size); + break; + + case WS_AF_INET6: + ret = build_tcp6_table(TableClass, &table, bOrder, GetProcessHeap(), 0, &size); + break; + + default: + FIXME("ulAf = %u not supported\n", ulAf); + ret = ERROR_NOT_SUPPORTED; + } + + if (ret) return ret;
if (!pTcpTable || *pdwSize < size) @@ -3054,8 +3064,8 @@ ULONG WINAPI GetTcpTable2(PMIB_TCPTABLE2 table, PULONG size, BOOL order) */ ULONG WINAPI GetTcp6Table(PMIB_TCP6TABLE table, PULONG size, BOOL order) { - FIXME("pTcp6Table %p, size %p, order %d: stub\n", table, size, order); - return ERROR_NOT_SUPPORTED; + TRACE("(table %p, size %p, order %d)\n", table, size, order); + return GetExtendedTcpTable(table, size, order, WS_AF_INET6, TCP_TABLE_BASIC_ALL, 0); }
/****************************************************************** diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c index 6ce322a8d1..5fff824372 100644 --- a/dlls/iphlpapi/ipstats.c +++ b/dlls/iphlpapi/ipstats.c @@ -2545,6 +2545,71 @@ DWORD build_udp_table( UDP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE return ret; }
+static DWORD get_tcp6_table_sizes( TCP_TABLE_CLASS class, DWORD row_count, DWORD *row_size ) +{ + DWORD table_size; + + switch (class) + { + case TCP_TABLE_BASIC_LISTENER: + case TCP_TABLE_BASIC_CONNECTIONS: + case TCP_TABLE_BASIC_ALL: + { + table_size = FIELD_OFFSET(MIB_TCP6TABLE, table[row_count]); + if (row_size) *row_size = sizeof(MIB_TCP6ROW); + break; + } + case TCP_TABLE_OWNER_PID_LISTENER: + case TCP_TABLE_OWNER_PID_CONNECTIONS: + case TCP_TABLE_OWNER_PID_ALL: + { + table_size = FIELD_OFFSET(MIB_TCP6TABLE_OWNER_PID, table[row_count]); + if (row_size) *row_size = sizeof(MIB_TCP6ROW_OWNER_PID); + break; + } + case TCP_TABLE_OWNER_MODULE_LISTENER: + case TCP_TABLE_OWNER_MODULE_CONNECTIONS: + case TCP_TABLE_OWNER_MODULE_ALL: + { + table_size = FIELD_OFFSET(MIB_TCP6TABLE_OWNER_MODULE, table[row_count]); + if (row_size) *row_size = sizeof(MIB_TCP6ROW_OWNER_MODULE); + break; + } + default: + ERR("unhandled class %u\n", class); + return 0; + } + return table_size; +} + +static int compare_tcp6_basic_rows(const void *a, const void *b) +{ + const MIB_TCP6ROW *rowA = a; + const MIB_TCP6ROW *rowB = b; + int ret; + + if ((ret = memcmp(&rowA->LocalAddr, &rowB->LocalAddr, sizeof(rowA->LocalAddr)) != 0)) return ret; + if ((ret = rowA->dwLocalScopeId - rowB->dwLocalScopeId) != 0) return ret; + if ((ret = rowA->dwLocalPort - rowB->dwLocalPort) != 0) return ret; + if ((ret = memcmp(&rowA->RemoteAddr, &rowB->RemoteAddr, sizeof(rowA->RemoteAddr)) != 0)) return ret; + if ((ret = rowA->dwRemoteScopeId - rowB->dwRemoteScopeId) != 0) return ret; + return rowA->dwRemotePort - rowB->dwRemotePort; +} + +static int compare_tcp6_owner_rows(const void *a, const void *b) +{ + const MIB_TCP6ROW_OWNER_PID *rowA = a; + const MIB_TCP6ROW_OWNER_PID *rowB = b; + int ret; + + if ((ret = memcmp(&rowA->ucLocalAddr, &rowB->ucLocalAddr, sizeof(rowA->ucLocalAddr)) != 0)) return ret; + if ((ret = rowA->dwLocalScopeId - rowB->dwLocalScopeId) != 0) return ret; + if ((ret = rowA->dwLocalPort - rowB->dwLocalPort) != 0) return ret; + if ((ret = memcmp(&rowA->ucRemoteAddr, &rowB->ucRemoteAddr, sizeof(rowA->ucRemoteAddr)) != 0)) return ret; + if ((ret = rowA->dwRemoteScopeId - rowB->dwRemoteScopeId) != 0) return ret; + return rowA->dwRemotePort - rowB->dwRemotePort; +} + static DWORD get_udp6_table_sizes( UDP_TABLE_CLASS class, DWORD row_count, DWORD *row_size ) { DWORD table_size; @@ -2681,6 +2746,109 @@ static DWORD find_ipv6_addr_scope(const IN6_ADDR *addr, const struct ipv6_addr_s return -1; }
+DWORD build_tcp6_table( TCP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE heap, DWORD flags, + DWORD *size ) +{ + MIB_TCP6TABLE *table; + MIB_TCP6ROW_OWNER_MODULE row; + DWORD ret = NO_ERROR, count = 16, table_size, row_size; + + if (!(table_size = get_tcp6_table_sizes( class, count, &row_size ))) + return ERROR_INVALID_PARAMETER; + + if (!(table = HeapAlloc( heap, flags, table_size ))) + return ERROR_OUTOFMEMORY; + + table->dwNumEntries = 0; + +#ifdef __linux__ + { + FILE *fp; + + if ((fp = fopen( "/proc/net/tcp6", "r" ))) + { + char buf[512], *ptr; + struct pid_map *map = NULL; + unsigned int num_entries = 0; + struct ipv6_addr_scope *addr_scopes; + unsigned int addr_scopes_size = 0; + int inode; + + addr_scopes = get_ipv6_addr_scope_table(&addr_scopes_size); + + if (class >= TCP_TABLE_OWNER_PID_LISTENER) map = get_pid_map( &num_entries ); + + /* skip header line */ + ptr = fgets( buf, sizeof(buf), fp ); + while ((ptr = fgets( buf, sizeof(buf), fp ))) + { + DWORD *local_addr = (DWORD *)&row.ucLocalAddr; + DWORD *remote_addr = (DWORD *)&row.ucRemoteAddr; + + if (sscanf( ptr, "%*u: %8x%8x%8x%8x:%x %8x%8x%8x%8x:%x %x %*s %*s %*s %*s %*s %*s %*s %d", + &local_addr[0], &local_addr[1], &local_addr[2], &local_addr[3], &row.dwLocalPort, + &remote_addr[0], &remote_addr[1], &remote_addr[2], &remote_addr[3], &row.dwRemotePort, + &row.dwState, &inode ) != 12) + continue; + row.dwState = TCPStateToMIBState( row.dwState ); + if (!match_class( class, row.dwState )) continue; + row.dwLocalScopeId = find_ipv6_addr_scope((const IN6_ADDR *)&row.ucLocalAddr, addr_scopes, addr_scopes_size); + row.dwLocalPort = htons( row.dwLocalPort ); + row.dwRemoteScopeId = find_ipv6_addr_scope((const IN6_ADDR *)&row.ucRemoteAddr, addr_scopes, addr_scopes_size); + row.dwRemotePort = htons( row.dwRemotePort ); + + if (class <= TCP_TABLE_BASIC_ALL) + { + /* MIB_TCP6ROW has a different field order */ + MIB_TCP6ROW basic_row; + basic_row.State = row.dwState; + memcpy( &basic_row.LocalAddr, &row.ucLocalAddr, sizeof(row.ucLocalAddr) ); + basic_row.dwLocalScopeId = row.dwLocalScopeId; + basic_row.dwLocalPort = row.dwLocalPort; + memcpy( &basic_row.RemoteAddr, &row.ucRemoteAddr, sizeof(row.ucRemoteAddr) ); + basic_row.dwRemoteScopeId = row.dwRemoteScopeId; + basic_row.dwRemotePort = row.dwRemotePort; + if (!(table = append_table_row( heap, flags, table, &table_size, &count, &basic_row, row_size ))) + break; + continue; + } + + row.dwOwningPid = find_owning_pid( map, num_entries, inode ); + if (class >= TCP_TABLE_OWNER_MODULE_LISTENER) + { + row.liCreateTimestamp.QuadPart = 0; /* FIXME */ + memset( &row.OwningModuleInfo, 0, sizeof(row.OwningModuleInfo) ); + } + if (!(table = append_table_row( heap, flags, table, &table_size, &count, &row, row_size ))) + break; + } + HeapFree( GetProcessHeap(), 0, map ); + HeapFree( GetProcessHeap(), 0, addr_scopes ); + fclose( fp ); + } + else ret = ERROR_NOT_SUPPORTED; + } +#else + FIXME( "not implemented\n" ); + ret = ERROR_NOT_SUPPORTED; +#endif + + if (!table) return ERROR_OUTOFMEMORY; + if (!ret) + { + if (order && table->dwNumEntries) + { + qsort( table->table, table->dwNumEntries, row_size, + class <= TCP_TABLE_BASIC_ALL ? compare_tcp6_basic_rows : compare_tcp6_owner_rows ); + } + *tablep = table; + } + else HeapFree( heap, flags, table ); + if (size) *size = get_tcp6_table_sizes( class, count, NULL ); + TRACE( "returning ret %u table %p\n", ret, table ); + return ret; +} + DWORD build_udp6_table( UDP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE heap, DWORD flags, DWORD *size ) { diff --git a/dlls/iphlpapi/ipstats.h b/dlls/iphlpapi/ipstats.h index acf43ee27c..68bcb9c9ad 100644 --- a/dlls/iphlpapi/ipstats.h +++ b/dlls/iphlpapi/ipstats.h @@ -33,6 +33,7 @@ DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry) DECLSPEC_HIDDEN;
DWORD build_tcp_table(TCP_TABLE_CLASS, void **, BOOL, HANDLE, DWORD, DWORD *) DECLSPEC_HIDDEN; +DWORD build_tcp6_table(TCP_TABLE_CLASS, void **, BOOL, HANDLE, DWORD, DWORD *) DECLSPEC_HIDDEN; DWORD build_udp_table(UDP_TABLE_CLASS, void **, BOOL, HANDLE, DWORD, DWORD *) DECLSPEC_HIDDEN; DWORD build_udp6_table(UDP_TABLE_CLASS, void **, BOOL, HANDLE, DWORD, DWORD *) DECLSPEC_HIDDEN;
All of the strings produced by the semi-stub are valid IPv6 addresses, though not necessarily in the same format that Windows would give them in.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46788 Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/ntdll/ntdll.spec | 4 +- dlls/ntdll/rtl.c | 77 +++++++++++++++++ dlls/ntdll/tests/rtl.c | 189 +++++++++++++++++++++-------------------- 3 files changed, 177 insertions(+), 93 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 7aa953ca6c..db7949044c 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -774,8 +774,8 @@ @ stdcall RtlIpv4StringToAddressExA(str long ptr ptr) @ stdcall RtlIpv4StringToAddressExW(wstr long ptr ptr) @ stdcall RtlIpv4StringToAddressW(wstr long ptr ptr) -# @ stub RtlIpv6AddressToStringA -# @ stub RtlIpv6AddressToStringExA +@ stdcall RtlIpv6AddressToStringA(ptr ptr) +@ stdcall RtlIpv6AddressToStringExA(ptr long long ptr ptr) # @ stub RtlIpv6AddressToStringExW # @ stub RtlIpv6AddressToStringW # @ stub RtlIpv6StringToAddressA diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index 15ff037fef..26b1e8c7b9 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -1196,6 +1196,83 @@ CHAR * WINAPI RtlIpv4AddressToStringA(const IN_ADDR *pin, LPSTR buffer) return buffer + size - 1; }
+/*********************************************************************** + * RtlIpv6AddressToStringExA [NTDLL.@] + */ +NTSTATUS WINAPI RtlIpv6AddressToStringExA(const IN6_ADDR *address, ULONG scope, USHORT port, char *str, ULONG *size) +{ + char buffer[60]; + ULONG needed; + NTSTATUS ret; + + FIXME("(%p %u %u %p %p): semi-stub\n", address, scope, port, str, size); + + if (!address || !str || !size) + return STATUS_INVALID_PARAMETER; + + if (scope && port) + { + needed = sprintf(buffer, "[%x:%x:%x:%x:%x:%x:%x:%x%%%u]:%u", + ntohs(address->u.Word[0]), ntohs(address->u.Word[1]), + ntohs(address->u.Word[2]), ntohs(address->u.Word[3]), + ntohs(address->u.Word[4]), ntohs(address->u.Word[5]), + ntohs(address->u.Word[6]), ntohs(address->u.Word[7]), + scope, ntohs(port)); + } + else if (scope) + { + needed = sprintf(buffer, "%x:%x:%x:%x:%x:%x:%x:%x%%%u", + ntohs(address->u.Word[0]), ntohs(address->u.Word[1]), + ntohs(address->u.Word[2]), ntohs(address->u.Word[3]), + ntohs(address->u.Word[4]), ntohs(address->u.Word[5]), + ntohs(address->u.Word[6]), ntohs(address->u.Word[7]), + scope); + } + else if (port) + { + needed = sprintf(buffer, "[%x:%x:%x:%x:%x:%x:%x:%x]:%u", + ntohs(address->u.Word[0]), ntohs(address->u.Word[1]), + ntohs(address->u.Word[2]), ntohs(address->u.Word[3]), + ntohs(address->u.Word[4]), ntohs(address->u.Word[5]), + ntohs(address->u.Word[6]), ntohs(address->u.Word[7]), + ntohs(port)); + } + else + { + needed = sprintf(buffer, "%x:%x:%x:%x:%x:%x:%x:%x", + ntohs(address->u.Word[0]), ntohs(address->u.Word[1]), + ntohs(address->u.Word[2]), ntohs(address->u.Word[3]), + ntohs(address->u.Word[4]), ntohs(address->u.Word[5]), + ntohs(address->u.Word[6]), ntohs(address->u.Word[7])); + } + needed++; + + if (*size >= needed) + { + strcpy(str, buffer); + ret = STATUS_SUCCESS; + } + else + { + ret = STATUS_INVALID_PARAMETER; + } + + *size = needed; + return ret; +} + +/*********************************************************************** + * RtlIpv6AddressToStringA [NTDLL.@] + */ +char * WINAPI RtlIpv6AddressToStringA(const IN6_ADDR *address, char *str) +{ + ULONG size = 46; + if (!address || !str) return str - 1; + str[45] = 0; /* this byte is set even though the string is always shorter */ + if (RtlIpv6AddressToStringExA(address, 0, 0, str, &size) != STATUS_SUCCESS) return str - 1; + return str + size - 1; +} + /*********************************************************************** * get_pointer_obfuscator (internal) */ diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c index 559a7d625c..c7470258fb 100644 --- a/dlls/ntdll/tests/rtl.c +++ b/dlls/ntdll/tests/rtl.c @@ -1791,80 +1791,81 @@ static void test_RtlIpv6AddressToString(void) LPCSTR result; IN6_ADDR ip; DWORD_PTR len; - struct + static const struct { PCSTR address; int ip[8]; + BOOL todo; } tests[] = { /* ipv4 addresses & ISATAP addresses */ - { "::13.1.68.3", { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, - { "::ffff:13.1.68.3", { 0, 0, 0, 0, 0, 0xffff, 0x10d, 0x344 } }, - { "::feff:d01:4403", { 0, 0, 0, 0, 0, 0xfffe, 0x10d, 0x344 } }, - { "::fffe:d01:4403", { 0, 0, 0, 0, 0, 0xfeff, 0x10d, 0x344 } }, - { "::100:d01:4403", { 0, 0, 0, 0, 0, 1, 0x10d, 0x344 } }, - { "::1:d01:4403", { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, - { "::ffff:0:4403", { 0, 0, 0, 0, 0, 0xffff, 0, 0x344 } }, - { "::ffff:13.1.0.0", { 0, 0, 0, 0, 0, 0xffff, 0x10d, 0 } }, - { "::ffff:0:0", { 0, 0, 0, 0, 0, 0xffff, 0, 0 } }, - { "::ffff:0:13.1.68.3", { 0, 0, 0, 0, 0xffff, 0, 0x10d, 0x344 } }, - { "::ffff:ffff:d01:4403", { 0, 0, 0, 0, 0xffff, 0xffff, 0x10d, 0x344 } }, - { "::ffff:0:0:d01:4403", { 0, 0, 0, 0xffff, 0, 0, 0x10d, 0x344 } }, - { "::ffff:255.255.255.255", { 0, 0, 0, 0, 0, 0xffff, 0xffff, 0xffff } }, - { "::ffff:129.144.52.38", { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 } }, - { "::5efe:129.144.52.38", { 0, 0, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 } }, - { "1111:2222:3333:4444:0:5efe:129.144.52.38", { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, - { "1111:2222:3333::5efe:129.144.52.38", { 0x1111, 0x2222, 0x3333, 0, 0, 0xfe5e, 0x9081, 0x2634 } }, - { "1111:2222::5efe:129.144.52.38", { 0x1111, 0x2222, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 } }, - { "1111::5efe:129.144.52.38", { 0x1111, 0, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 } }, - { "::200:5efe:129.144.52.38", { 0, 0, 0, 0, 2, 0xfe5e, 0x9081, 0x2634 } }, - { "::100:5efe:8190:3426", { 0, 0, 0, 0, 1, 0xfe5e, 0x9081, 0x2634 } }, + { "::13.1.68.3", { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 }, TRUE }, + { "::ffff:13.1.68.3", { 0, 0, 0, 0, 0, 0xffff, 0x10d, 0x344 }, TRUE }, + { "::feff:d01:4403", { 0, 0, 0, 0, 0, 0xfffe, 0x10d, 0x344 }, TRUE }, + { "::fffe:d01:4403", { 0, 0, 0, 0, 0, 0xfeff, 0x10d, 0x344 }, TRUE }, + { "::100:d01:4403", { 0, 0, 0, 0, 0, 1, 0x10d, 0x344 }, TRUE }, + { "::1:d01:4403", { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 }, TRUE }, + { "::ffff:0:4403", { 0, 0, 0, 0, 0, 0xffff, 0, 0x344 }, TRUE }, + { "::ffff:13.1.0.0", { 0, 0, 0, 0, 0, 0xffff, 0x10d, 0 }, TRUE }, + { "::ffff:0:0", { 0, 0, 0, 0, 0, 0xffff, 0, 0 }, TRUE }, + { "::ffff:0:13.1.68.3", { 0, 0, 0, 0, 0xffff, 0, 0x10d, 0x344 }, TRUE }, + { "::ffff:ffff:d01:4403", { 0, 0, 0, 0, 0xffff, 0xffff, 0x10d, 0x344 }, TRUE }, + { "::ffff:0:0:d01:4403", { 0, 0, 0, 0xffff, 0, 0, 0x10d, 0x344 }, TRUE }, + { "::ffff:255.255.255.255", { 0, 0, 0, 0, 0, 0xffff, 0xffff, 0xffff }, TRUE }, + { "::ffff:129.144.52.38", { 0, 0, 0, 0, 0, 0xffff, 0x9081, 0x2634 }, TRUE }, + { "::5efe:129.144.52.38", { 0, 0, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 }, TRUE }, + { "1111:2222:3333:4444:0:5efe:129.144.52.38", { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 }, TRUE }, + { "1111:2222:3333::5efe:129.144.52.38", { 0x1111, 0x2222, 0x3333, 0, 0, 0xfe5e, 0x9081, 0x2634 }, TRUE }, + { "1111:2222::5efe:129.144.52.38", { 0x1111, 0x2222, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 }, TRUE }, + { "1111::5efe:129.144.52.38", { 0x1111, 0, 0, 0, 0, 0xfe5e, 0x9081, 0x2634 }, TRUE }, + { "::200:5efe:129.144.52.38", { 0, 0, 0, 0, 2, 0xfe5e, 0x9081, 0x2634 }, TRUE }, + { "::100:5efe:8190:3426", { 0, 0, 0, 0, 1, 0xfe5e, 0x9081, 0x2634 }, TRUE }, /* 'normal' addresses */ - { "::1", { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, + { "::1", { 0, 0, 0, 0, 0, 0, 0, 0x100 }, TRUE }, { "0:1:2:3:4:5:6:7", { 0, 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700 } }, - { "1080::8:800:200c:417a", { 0x8010, 0, 0, 0, 0x800, 0x8, 0x0c20, 0x7a41 } }, + { "1080::8:800:200c:417a", { 0x8010, 0, 0, 0, 0x800, 0x8, 0x0c20, 0x7a41 }, TRUE }, { "1111:2222:3333:4444:5555:6666:7b7b:7b7b", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, { "1111:2222:3333:4444:5555:6666:7777:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, - { "1111:2222:3333:4444:5555:6666::", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0 } }, + { "1111:2222:3333:4444:5555:6666::", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0 }, TRUE }, { "1111:2222:3333:4444:5555:6666:0:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0, 0x8888 } }, - { "1111:2222:3333:4444:5555::", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0 } }, + { "1111:2222:3333:4444:5555::", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0 }, TRUE }, { "1111:2222:3333:4444:5555:0:7b7b:7b7b", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0x7b7b, 0x7b7b } }, { "1111:2222:3333:4444:5555:0:7777:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0x7777, 0x8888 } }, - { "1111:2222:3333:4444:5555::8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8888 } }, - { "1111::", { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, - { "1111::7b7b:7b7b", { 0x1111, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } }, + { "1111:2222:3333:4444:5555::8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0, 0, 0x8888 }, TRUE }, + { "1111::", { 0x1111, 0, 0, 0, 0, 0, 0, 0 }, TRUE }, + { "1111::7b7b:7b7b", { 0x1111, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b }, TRUE }, { "1111:0:3333:4444:5555:6666:7b7b:7b7b", { 0x1111, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, { "1111:0:3333:4444:5555:6666:7777:8888", { 0x1111, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, - { "1111::4444:5555:6666:7b7b:7b7b", { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, - { "1111::4444:5555:6666:7777:8888", { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, - { "1111::5555:6666:7b7b:7b7b", { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, - { "1111::5555:6666:7777:8888", { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7777, 0x8888 } }, - { "1111::6666:7b7b:7b7b", { 0x1111, 0, 0, 0, 0, 0x6666, 0x7b7b, 0x7b7b } }, - { "1111::6666:7777:8888", { 0x1111, 0, 0, 0, 0, 0x6666, 0x7777, 0x8888 } }, - { "1111::7777:8888", { 0x1111, 0, 0, 0, 0, 0, 0x7777, 0x8888 } }, - { "1111::8888", { 0x1111, 0, 0, 0, 0, 0, 0, 0x8888 } }, + { "1111::4444:5555:6666:7b7b:7b7b", { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b }, TRUE }, + { "1111::4444:5555:6666:7777:8888", { 0x1111, 0, 0, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 }, TRUE }, + { "1111::5555:6666:7b7b:7b7b", { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7b7b, 0x7b7b }, TRUE }, + { "1111::5555:6666:7777:8888", { 0x1111, 0, 0, 0, 0x5555, 0x6666, 0x7777, 0x8888 }, TRUE }, + { "1111::6666:7b7b:7b7b", { 0x1111, 0, 0, 0, 0, 0x6666, 0x7b7b, 0x7b7b }, TRUE }, + { "1111::6666:7777:8888", { 0x1111, 0, 0, 0, 0, 0x6666, 0x7777, 0x8888 }, TRUE }, + { "1111::7777:8888", { 0x1111, 0, 0, 0, 0, 0, 0x7777, 0x8888 }, TRUE }, + { "1111::8888", { 0x1111, 0, 0, 0, 0, 0, 0, 0x8888 }, TRUE }, { "1:2:3:4:5:6:102:304", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x201, 0x403 } }, { "1:2:3:4:5:6:7:8", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800 } }, - { "1:2:3:4:5:6::", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0 } }, + { "1:2:3:4:5:6::", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0 }, TRUE }, { "1:2:3:4:5:6:0:8", { 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0, 0x800 } }, - { "2001:0:1234::c1c0:abcd:876", { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 } }, + { "2001:0:1234::c1c0:abcd:876", { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 }, TRUE }, { "2001:0:4136:e378:8000:63bf:3fff:fdd2", { 0x120, 0, 0x3641, 0x78e3, 0x80, 0xbf63, 0xff3f, 0xd2fd } }, - { "2001:db8::1428:57ab", { 0x120, 0xb80d, 0, 0, 0, 0, 0x2814, 0xab57 } }, + { "2001:db8::1428:57ab", { 0x120, 0xb80d, 0, 0, 0, 0, 0x2814, 0xab57 }, TRUE }, { "2001:db8:1234:ffff:ffff:ffff:ffff:ffff", { 0x120, 0xb80d, 0x3412, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff } }, { "2001:0:ce49:7601:2cad:dfff:7c94:fffe", { 0x120, 0, 0x49ce, 0x176, 0xad2c, 0xffdf, 0x947c, 0xfeff } }, - { "2001:db8:85a3::8a2e:370:7334", { 0x120, 0xb80d, 0xa385, 0, 0, 0x2e8a, 0x7003, 0x3473 } }, - { "3ffe:b00::1:0:0:a", { 0xfe3f, 0xb, 0, 0, 0x100, 0, 0, 0xa00 } }, - { "::a:b:c:d:e", { 0, 0, 0, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00 } }, - { "::123.123.123.123", { 0, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b } }, + { "2001:db8:85a3::8a2e:370:7334", { 0x120, 0xb80d, 0xa385, 0, 0, 0x2e8a, 0x7003, 0x3473 }, TRUE }, + { "3ffe:b00::1:0:0:a", { 0xfe3f, 0xb, 0, 0, 0x100, 0, 0, 0xa00 }, TRUE }, + { "::a:b:c:d:e", { 0, 0, 0, 0xa00, 0xb00, 0xc00, 0xd00, 0xe00 }, TRUE }, + { "::123.123.123.123", { 0, 0, 0, 0, 0, 0, 0x7b7b, 0x7b7b }, TRUE }, { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", { 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff } }, { "1111:2222:3333:4444:5555:6666:7777:1", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x100 } }, { "1111:2222:3333:4444:5555:6666:7777:8888", { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888 } }, - { "1111:2222::", { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 } }, - { "1111::3333:4444:5555:6666:7777", { 0x1111, 0, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777 } }, - { "1111:2222::", { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 } }, - { "1111::3333", { 0x1111, 0, 0, 0, 0, 0, 0, 0x3333 } }, - { "2001:0:1234::c1c0:abcd:876", { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 } }, - { "2001::ffd3", { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, + { "1111:2222::", { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 }, TRUE }, + { "1111::3333:4444:5555:6666:7777", { 0x1111, 0, 0, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777 }, TRUE }, + { "1111:2222::", { 0x1111, 0x2222, 0, 0, 0, 0, 0, 0 }, TRUE }, + { "1111::3333", { 0x1111, 0, 0, 0, 0, 0, 0, 0x3333 }, TRUE }, + { "2001:0:1234::c1c0:abcd:876", { 0x120, 0, 0x3412, 0, 0, 0xc0c1, 0xcdab, 0x7608 }, TRUE }, + { "2001::ffd3", { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff }, TRUE }, }; unsigned int i;
@@ -1880,6 +1881,7 @@ static void test_RtlIpv6AddressToString(void) result = pRtlIpv6AddressToStringA(&ip, buffer);
len = strlen(buffer); +todo_wine ok(result == (buffer + len) && !strcmp(buffer, "::"), "got %p with '%s' (expected %p with '::')\n", result, buffer, buffer + len);
@@ -1895,6 +1897,7 @@ static void test_RtlIpv6AddressToString(void)
result = pRtlIpv6AddressToStringA(&ip, buffer); len = strlen(buffer); +todo_wine_if(tests[i].todo) ok(result == (buffer + len) && !strcmp(buffer, tests[i].address), "got %p with '%s' (expected %p with '%s')\n", result, buffer, buffer + len, tests[i].address);
@@ -1910,42 +1913,43 @@ static void test_RtlIpv6AddressToStringEx(void) NTSTATUS res; IN6_ADDR ip; ULONG len; - struct + static const struct { PCSTR address; ULONG scopeid; USHORT port; int ip[8]; + BOOL todo; } tests[] = { /* ipv4 addresses & ISATAP addresses */ - { "::13.1.68.3", 0, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, - { "::13.1.68.3%1", 1, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, - { "::13.1.68.3%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, - { "[::13.1.68.3%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, - { "[::13.1.68.3%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, - { "[::13.1.68.3]:256", 0, 1, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 } }, - - { "::1:d01:4403", 0, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, - { "::1:d01:4403%1", 1, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, - { "::1:d01:4403%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, - { "[::1:d01:4403%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, - { "[::1:d01:4403%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, - { "[::1:d01:4403]:256", 0, 1, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 } }, - - { "1111:2222:3333:4444:0:5efe:129.144.52.38", 0, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, - { "1111:2222:3333:4444:0:5efe:129.144.52.38%1", 1, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, - { "1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819", 0xffffbbbb, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, - { "[1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819]:65518",0xffffbbbb, 0xeeff, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, - { "[1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819]:256", 0xffffbbbb, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, - { "[1111:2222:3333:4444:0:5efe:129.144.52.38]:256", 0, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 } }, - - { "::1", 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, - { "::1%1", 1, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, - { "::1%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, - { "[::1%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, - { "[::1%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, - { "[::1]:256", 0, 1, { 0, 0, 0, 0, 0, 0, 0, 0x100 } }, + { "::13.1.68.3", 0, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 }, TRUE }, + { "::13.1.68.3%1", 1, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 }, TRUE }, + { "::13.1.68.3%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 }, TRUE }, + { "[::13.1.68.3%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 }, TRUE }, + { "[::13.1.68.3%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 }, TRUE }, + { "[::13.1.68.3]:256", 0, 1, { 0, 0, 0, 0, 0, 0, 0x10d, 0x344 }, TRUE }, + + { "::1:d01:4403", 0, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 }, TRUE }, + { "::1:d01:4403%1", 1, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 }, TRUE }, + { "::1:d01:4403%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 }, TRUE }, + { "[::1:d01:4403%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 }, TRUE }, + { "[::1:d01:4403%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 }, TRUE }, + { "[::1:d01:4403]:256", 0, 1, { 0, 0, 0, 0, 0, 0x100, 0x10d, 0x344 }, TRUE }, + + { "1111:2222:3333:4444:0:5efe:129.144.52.38", 0, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 }, TRUE }, + { "1111:2222:3333:4444:0:5efe:129.144.52.38%1", 1, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 }, TRUE }, + { "1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819", 0xffffbbbb, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 }, TRUE }, + { "[1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819]:65518",0xffffbbbb, 0xeeff, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 }, TRUE }, + { "[1111:2222:3333:4444:0:5efe:129.144.52.38%4294949819]:256", 0xffffbbbb, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 }, TRUE }, + { "[1111:2222:3333:4444:0:5efe:129.144.52.38]:256", 0, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0, 0xfe5e, 0x9081, 0x2634 }, TRUE }, + + { "::1", 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 }, TRUE }, + { "::1%1", 1, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 }, TRUE }, + { "::1%4294949819", 0xffffbbbb, 0, { 0, 0, 0, 0, 0, 0, 0, 0x100 }, TRUE }, + { "[::1%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0, 0, 0, 0, 0, 0, 0, 0x100 }, TRUE }, + { "[::1%4294949819]:256", 0xffffbbbb, 1, { 0, 0, 0, 0, 0, 0, 0, 0x100 }, TRUE }, + { "[::1]:256", 0, 1, { 0, 0, 0, 0, 0, 0, 0, 0x100 }, TRUE },
{ "1111:2222:3333:4444:5555:6666:7b7b:7b7b", 0, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, { "1111:2222:3333:4444:5555:6666:7b7b:7b7b%1", 1, 0, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, @@ -1954,19 +1958,19 @@ static void test_RtlIpv6AddressToStringEx(void) { "[1111:2222:3333:4444:5555:6666:7b7b:7b7b%4294949819]:256", 0xffffbbbb, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } }, { "[1111:2222:3333:4444:5555:6666:7b7b:7b7b]:256", 0, 1, { 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7b7b, 0x7b7b } },
- { "1111::", 0, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, - { "1111::%1", 1, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, - { "1111::%4294949819", 0xffffbbbb, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, - { "[1111::%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, - { "[1111::%4294949819]:256", 0xffffbbbb, 1, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, - { "[1111::]:256", 0, 1, { 0x1111, 0, 0, 0, 0, 0, 0, 0 } }, - - { "2001::ffd3", 0, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, - { "2001::ffd3%1", 1, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, - { "2001::ffd3%4294949819", 0xffffbbbb, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, - { "[2001::ffd3%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, - { "[2001::ffd3%4294949819]:256", 0xffffbbbb, 1, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, - { "[2001::ffd3]:256", 0, 1, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff } }, + { "1111::", 0, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 }, TRUE }, + { "1111::%1", 1, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 }, TRUE }, + { "1111::%4294949819", 0xffffbbbb, 0, { 0x1111, 0, 0, 0, 0, 0, 0, 0 }, TRUE }, + { "[1111::%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0x1111, 0, 0, 0, 0, 0, 0, 0 }, TRUE }, + { "[1111::%4294949819]:256", 0xffffbbbb, 1, { 0x1111, 0, 0, 0, 0, 0, 0, 0 }, TRUE }, + { "[1111::]:256", 0, 1, { 0x1111, 0, 0, 0, 0, 0, 0, 0 }, TRUE }, + + { "2001::ffd3", 0, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff }, TRUE }, + { "2001::ffd3%1", 1, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff }, TRUE }, + { "2001::ffd3%4294949819", 0xffffbbbb, 0, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff }, TRUE }, + { "[2001::ffd3%4294949819]:65518", 0xffffbbbb, 0xeeff, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff }, TRUE }, + { "[2001::ffd3%4294949819]:256", 0xffffbbbb, 1, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff }, TRUE }, + { "[2001::ffd3]:256", 0, 1, { 0x120, 0, 0, 0, 0, 0, 0, 0xd3ff }, TRUE }, }; unsigned int i;
@@ -1983,6 +1987,7 @@ static void test_RtlIpv6AddressToStringEx(void) res = pRtlIpv6AddressToStringExA(&ip, 0, 0, buffer, &len);
ok(res == STATUS_SUCCESS, "[validate] res = 0x%08x, expected STATUS_SUCCESS\n", res); +todo_wine ok(len == 3 && !strcmp(buffer, "::"), "got len %d with '%s' (expected 3 with '::')\n", len, buffer);
@@ -2006,6 +2011,7 @@ static void test_RtlIpv6AddressToStringEx(void) res = pRtlIpv6AddressToStringExA(&ip, 0, 0, buffer, &len); ok(res == STATUS_INVALID_PARAMETER, "[null length] res = 0x%08x, expected STATUS_INVALID_PARAMETER\n", res); ok(buffer[0] == '#', "got first char %c (expected '#')\n", buffer[0]); +todo_wine ok(len == 3, "got len %d (expected len 3)\n", len);
for (i = 0; i < ARRAY_SIZE(tests); i++) @@ -2018,6 +2024,7 @@ static void test_RtlIpv6AddressToStringEx(void) res = pRtlIpv6AddressToStringExA(&ip, tests[i].scopeid, tests[i].port, buffer, &len);
ok(res == STATUS_SUCCESS, "[validate] res = 0x%08x, expected STATUS_SUCCESS\n", res); +todo_wine_if(tests[i].todo) ok(len == (strlen(tests[i].address) + 1) && !strcmp(buffer, tests[i].address), "got len %d with '%s' (expected %d with '%s')\n", len, buffer, (int)strlen(tests[i].address), tests[i].address); }