ntdll: Implement RtlIpv6AddressToString(Ex)[AW].
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46788 Signed-off-by: Alex Henrie <alexhenrie24@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e5f69e81f3
commit
0af08318b7
|
@ -784,10 +784,10 @@
|
||||||
@ stdcall RtlIpv4StringToAddressExA(str long ptr ptr)
|
@ stdcall RtlIpv4StringToAddressExA(str long ptr ptr)
|
||||||
@ stdcall RtlIpv4StringToAddressExW(wstr long ptr ptr)
|
@ stdcall RtlIpv4StringToAddressExW(wstr long ptr ptr)
|
||||||
@ stdcall RtlIpv4StringToAddressW(wstr long ptr ptr)
|
@ stdcall RtlIpv4StringToAddressW(wstr long ptr ptr)
|
||||||
# @ stub RtlIpv6AddressToStringA
|
@ stdcall RtlIpv6AddressToStringA(ptr ptr)
|
||||||
# @ stub RtlIpv6AddressToStringExA
|
@ stdcall RtlIpv6AddressToStringExA(ptr long long ptr ptr)
|
||||||
# @ stub RtlIpv6AddressToStringExW
|
@ stdcall RtlIpv6AddressToStringExW(ptr long long ptr ptr)
|
||||||
# @ stub RtlIpv6AddressToStringW
|
@ stdcall RtlIpv6AddressToStringW(ptr ptr)
|
||||||
@ stdcall RtlIpv6StringToAddressA(str ptr ptr)
|
@ stdcall RtlIpv6StringToAddressA(str ptr ptr)
|
||||||
@ stdcall RtlIpv6StringToAddressExA(str ptr ptr ptr)
|
@ stdcall RtlIpv6StringToAddressExA(str ptr ptr ptr)
|
||||||
@ stdcall RtlIpv6StringToAddressExW(wstr ptr ptr ptr)
|
@ stdcall RtlIpv6StringToAddressExW(wstr ptr ptr ptr)
|
||||||
|
|
129
dlls/ntdll/rtl.c
129
dlls/ntdll/rtl.c
|
@ -1412,6 +1412,135 @@ CHAR * WINAPI RtlIpv4AddressToStringA(const IN_ADDR *pin, LPSTR buffer)
|
||||||
return buffer + size - 1;
|
return buffer + size - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL is_ipv4_in_ipv6(const IN6_ADDR *address)
|
||||||
|
{
|
||||||
|
if (address->s6_words[5] == htons(0x5efe) && (address->s6_words[4] & ~htons(0x200)) == 0)
|
||||||
|
return TRUE;
|
||||||
|
if (*(UINT64 *)address != 0)
|
||||||
|
return FALSE;
|
||||||
|
if (address->s6_words[4] != 0 && address->s6_words[4] != 0xffff)
|
||||||
|
return FALSE;
|
||||||
|
if (address->s6_words[4] == 0 && address->s6_words[5] != 0 && address->s6_words[5] != 0xffff)
|
||||||
|
return FALSE;
|
||||||
|
if (address->s6_words[4] == 0xffff && address->s6_words[5] != 0)
|
||||||
|
return FALSE;
|
||||||
|
if (address->s6_words[6] == 0)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* RtlIpv6AddressToStringExA [NTDLL.@]
|
||||||
|
*/
|
||||||
|
NTSTATUS WINAPI RtlIpv6AddressToStringExA(const IN6_ADDR *address, ULONG scope, USHORT port, char *str, ULONG *size)
|
||||||
|
{
|
||||||
|
char buffer[64], *p = buffer;
|
||||||
|
int i, len, gap = -1, gap_len = 1, ipv6_end = 8;
|
||||||
|
ULONG needed;
|
||||||
|
NTSTATUS ret;
|
||||||
|
|
||||||
|
TRACE("(%p %u %u %p %p)\n", address, scope, port, str, size);
|
||||||
|
|
||||||
|
if (!address || !str || !size)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (is_ipv4_in_ipv6(address))
|
||||||
|
ipv6_end = 6;
|
||||||
|
|
||||||
|
for (i = 0; i < ipv6_end; i++)
|
||||||
|
{
|
||||||
|
len = 0;
|
||||||
|
while (!address->s6_words[i] && i < ipv6_end)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
if (len > gap_len)
|
||||||
|
{
|
||||||
|
gap = i - len;
|
||||||
|
gap_len = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port) p += sprintf(p, "[");
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i < ipv6_end)
|
||||||
|
{
|
||||||
|
if (i == gap)
|
||||||
|
{
|
||||||
|
p += sprintf(p, ":");
|
||||||
|
i += gap_len;
|
||||||
|
if (i == ipv6_end) p += sprintf(p, ":");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (i > 0) p += sprintf(p, ":");
|
||||||
|
p += sprintf(p, "%x", ntohs(address->s6_words[i]));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipv6_end == 6)
|
||||||
|
{
|
||||||
|
if (p[-1] != ':') p += sprintf(p, ":");
|
||||||
|
p = RtlIpv4AddressToStringA((IN_ADDR *)(address->s6_words + 6), p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scope) p += sprintf(p, "%%%u", scope);
|
||||||
|
|
||||||
|
if (port) p += sprintf(p, "]:%u", ntohs(port));
|
||||||
|
|
||||||
|
needed = p - buffer + 1;
|
||||||
|
|
||||||
|
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 */
|
||||||
|
RtlIpv6AddressToStringExA(address, 0, 0, str, &size);
|
||||||
|
return str + size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* RtlIpv6AddressToStringExW [NTDLL.@]
|
||||||
|
*/
|
||||||
|
NTSTATUS WINAPI RtlIpv6AddressToStringExW(const IN6_ADDR *address, ULONG scope, USHORT port, WCHAR *str, ULONG *size)
|
||||||
|
{
|
||||||
|
char cstr[64];
|
||||||
|
NTSTATUS ret = RtlIpv6AddressToStringExA(address, scope, port, cstr, size);
|
||||||
|
if (ret == STATUS_SUCCESS) RtlMultiByteToUnicodeN(str, *size * sizeof(WCHAR), NULL, cstr, *size);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* RtlIpv6AddressToStringW [NTDLL.@]
|
||||||
|
*/
|
||||||
|
WCHAR * WINAPI RtlIpv6AddressToStringW(const IN6_ADDR *address, WCHAR *str)
|
||||||
|
{
|
||||||
|
ULONG size = 46;
|
||||||
|
if (!address || !str) return str;
|
||||||
|
str[45] = 0; /* this word is set even though the string is always shorter */
|
||||||
|
if (RtlIpv6AddressToStringExW(address, 0, 0, str, &size) != STATUS_SUCCESS)
|
||||||
|
return str;
|
||||||
|
return str + size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* get_pointer_obfuscator (internal)
|
* get_pointer_obfuscator (internal)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -73,7 +73,6 @@ static DWORD (WINAPI *pRtlGetThreadErrorMode)(void);
|
||||||
static NTSTATUS (WINAPI *pRtlSetThreadErrorMode)(DWORD, LPDWORD);
|
static NTSTATUS (WINAPI *pRtlSetThreadErrorMode)(DWORD, LPDWORD);
|
||||||
static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, LPSTR, PULONG);
|
static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, LPSTR, PULONG);
|
||||||
static NTSTATUS (WINAPI *pRtlIpv4StringToAddressExA)(PCSTR, BOOLEAN, IN_ADDR *, PUSHORT);
|
static NTSTATUS (WINAPI *pRtlIpv4StringToAddressExA)(PCSTR, BOOLEAN, IN_ADDR *, PUSHORT);
|
||||||
static CHAR * (WINAPI *pRtlIpv6AddressToStringA)(struct in6_addr *, PSTR);
|
|
||||||
static NTSTATUS (WINAPI *pRtlIpv6AddressToStringExA)(struct in6_addr *, ULONG, USHORT, PCHAR, PULONG);
|
static NTSTATUS (WINAPI *pRtlIpv6AddressToStringExA)(struct in6_addr *, ULONG, USHORT, PCHAR, PULONG);
|
||||||
static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExA)(PCSTR, struct in6_addr *, PULONG, PUSHORT);
|
static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExA)(PCSTR, struct in6_addr *, PULONG, PUSHORT);
|
||||||
static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExW)(PCWSTR, struct in6_addr *, PULONG, PUSHORT);
|
static NTSTATUS (WINAPI *pRtlIpv6StringToAddressExW)(PCWSTR, struct in6_addr *, PULONG, PUSHORT);
|
||||||
|
@ -114,7 +113,6 @@ static void InitFunctionPtrs(void)
|
||||||
pRtlSetThreadErrorMode = (void *)GetProcAddress(hntdll, "RtlSetThreadErrorMode");
|
pRtlSetThreadErrorMode = (void *)GetProcAddress(hntdll, "RtlSetThreadErrorMode");
|
||||||
pRtlIpv4AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringExA");
|
pRtlIpv4AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringExA");
|
||||||
pRtlIpv4StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressExA");
|
pRtlIpv4StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressExA");
|
||||||
pRtlIpv6AddressToStringA = (void *)GetProcAddress(hntdll, "RtlIpv6AddressToStringA");
|
|
||||||
pRtlIpv6AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv6AddressToStringExA");
|
pRtlIpv6AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv6AddressToStringExA");
|
||||||
pRtlIpv6StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExA");
|
pRtlIpv6StringToAddressExA = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExA");
|
||||||
pRtlIpv6StringToAddressExW = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExW");
|
pRtlIpv6StringToAddressExW = (void *)GetProcAddress(hntdll, "RtlIpv6StringToAddressExW");
|
||||||
|
@ -1801,22 +1799,16 @@ static void test_RtlIpv6AddressToString(void)
|
||||||
};
|
};
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (!pRtlIpv6AddressToStringA)
|
|
||||||
{
|
|
||||||
skip("RtlIpv6AddressToStringA not available\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(buffer, '#', sizeof(buffer));
|
memset(buffer, '#', sizeof(buffer));
|
||||||
buffer[sizeof(buffer)-1] = 0;
|
buffer[sizeof(buffer)-1] = 0;
|
||||||
memset(&ip, 0, sizeof(ip));
|
memset(&ip, 0, sizeof(ip));
|
||||||
result = pRtlIpv6AddressToStringA(&ip, buffer);
|
result = RtlIpv6AddressToStringA(&ip, buffer);
|
||||||
|
|
||||||
len = strlen(buffer);
|
len = strlen(buffer);
|
||||||
ok(result == (buffer + len) && !strcmp(buffer, "::"),
|
ok(result == (buffer + len) && !strcmp(buffer, "::"),
|
||||||
"got %p with '%s' (expected %p with '::')\n", result, buffer, buffer + len);
|
"got %p with '%s' (expected %p with '::')\n", result, buffer, buffer + len);
|
||||||
|
|
||||||
result = pRtlIpv6AddressToStringA(&ip, NULL);
|
result = RtlIpv6AddressToStringA(&ip, NULL);
|
||||||
ok(result == (LPCSTR)~0 || broken(result == (LPCSTR)len) /* WinXP / Win2k3 */,
|
ok(result == (LPCSTR)~0 || broken(result == (LPCSTR)len) /* WinXP / Win2k3 */,
|
||||||
"got %p, expected %p\n", result, (LPCSTR)~0);
|
"got %p, expected %p\n", result, (LPCSTR)~0);
|
||||||
|
|
||||||
|
@ -1826,7 +1818,7 @@ static void test_RtlIpv6AddressToString(void)
|
||||||
memset(buffer, '#', sizeof(buffer));
|
memset(buffer, '#', sizeof(buffer));
|
||||||
buffer[sizeof(buffer)-1] = 0;
|
buffer[sizeof(buffer)-1] = 0;
|
||||||
|
|
||||||
result = pRtlIpv6AddressToStringA(&ip, buffer);
|
result = RtlIpv6AddressToStringA(&ip, buffer);
|
||||||
len = strlen(buffer);
|
len = strlen(buffer);
|
||||||
ok(result == (buffer + len) && !strcmp(buffer, tests[i].address),
|
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);
|
"got %p with '%s' (expected %p with '%s')\n", result, buffer, buffer + len, tests[i].address);
|
||||||
|
|
|
@ -1134,10 +1134,10 @@
|
||||||
@ stdcall RtlIpv4StringToAddressExA(str long ptr ptr)
|
@ stdcall RtlIpv4StringToAddressExA(str long ptr ptr)
|
||||||
@ stdcall RtlIpv4StringToAddressExW(wstr long ptr ptr)
|
@ stdcall RtlIpv4StringToAddressExW(wstr long ptr ptr)
|
||||||
@ stdcall RtlIpv4StringToAddressW(wstr long ptr ptr)
|
@ stdcall RtlIpv4StringToAddressW(wstr long ptr ptr)
|
||||||
@ stub RtlIpv6AddressToStringA
|
@ stdcall RtlIpv6AddressToStringA(ptr ptr)
|
||||||
@ stub RtlIpv6AddressToStringExA
|
@ stdcall RtlIpv6AddressToStringExA(ptr long long ptr ptr)
|
||||||
@ stub RtlIpv6AddressToStringExW
|
@ stdcall RtlIpv6AddressToStringExW(ptr long long ptr ptr)
|
||||||
@ stub RtlIpv6AddressToStringW
|
@ stdcall RtlIpv6AddressToStringW(ptr ptr)
|
||||||
@ stdcall RtlIpv6StringToAddressA(str ptr ptr)
|
@ stdcall RtlIpv6StringToAddressA(str ptr ptr)
|
||||||
@ stdcall RtlIpv6StringToAddressExA(str ptr ptr ptr)
|
@ stdcall RtlIpv6StringToAddressExA(str ptr ptr ptr)
|
||||||
@ stdcall RtlIpv6StringToAddressExW(wstr ptr ptr ptr)
|
@ stdcall RtlIpv6StringToAddressExW(wstr ptr ptr ptr)
|
||||||
|
|
|
@ -30,6 +30,13 @@ NTSTATUS WINAPI RtlIpv4AddressToStringExA(const IN_ADDR *address, USHORT port, c
|
||||||
NTSTATUS WINAPI RtlIpv4AddressToStringExW(const IN_ADDR *address, USHORT port, WCHAR *str, ULONG *size);
|
NTSTATUS WINAPI RtlIpv4AddressToStringExW(const IN_ADDR *address, USHORT port, WCHAR *str, ULONG *size);
|
||||||
#define RtlIpv4AddressToStringEx WINELIB_NAME_AW(RtlIpv4AddressToStringEx)
|
#define RtlIpv4AddressToStringEx WINELIB_NAME_AW(RtlIpv4AddressToStringEx)
|
||||||
|
|
||||||
|
char * WINAPI RtlIpv6AddressToStringA(const IN6_ADDR *address, char *str);
|
||||||
|
WCHAR * WINAPI RtlIpv6AddressToStringW(const IN6_ADDR *address, WCHAR *str);
|
||||||
|
#define RtlIpv6AddressToString WINELIB_NAME_AW(RtlIpv6AddressToString)
|
||||||
|
NTSTATUS WINAPI RtlIpv6AddressToStringExA(const IN6_ADDR *address, LONG scope, USHORT port, char *str, ULONG *size);
|
||||||
|
NTSTATUS WINAPI RtlIpv6AddressToStringExW(const IN6_ADDR *address, LONG scope, USHORT port, WCHAR *str, ULONG *size);
|
||||||
|
#define RtlIpv6AddressToStringEx WINELIB_NAME_AW(RtlIpv6AddressToStringEx)
|
||||||
|
|
||||||
NTSTATUS WINAPI RtlIpv4StringToAddressA(const char *str, BOOLEAN strict, const char **terminator, IN_ADDR *address);
|
NTSTATUS WINAPI RtlIpv4StringToAddressA(const char *str, BOOLEAN strict, const char **terminator, IN_ADDR *address);
|
||||||
NTSTATUS WINAPI RtlIpv4StringToAddressW(const WCHAR *str, BOOLEAN strict, const WCHAR **terminator, IN_ADDR *address);
|
NTSTATUS WINAPI RtlIpv4StringToAddressW(const WCHAR *str, BOOLEAN strict, const WCHAR **terminator, IN_ADDR *address);
|
||||||
#define RtlIpv4StringToAddress WINELIB_NAME_AW(RtlIpv4StringToAddress)
|
#define RtlIpv4StringToAddress WINELIB_NAME_AW(RtlIpv4StringToAddress)
|
||||||
|
|
Loading…
Reference in New Issue