From bfa3a605c961b98faadefa8581f5c6995ec87dbc Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Mon, 25 Jun 2012 08:21:11 +0000 Subject: [PATCH] [WS2_32_APITEST] - Add a few more getaddrinfo tests - Add a test for WSAStartup svn path=/trunk/; revision=56802 --- rostests/apitests/ws2_32/CMakeLists.txt | 1 + rostests/apitests/ws2_32/WSAStartup.c | 272 ++++++++++++++++++++++++ rostests/apitests/ws2_32/getaddrinfo.c | 22 +- rostests/apitests/ws2_32/testlist.c | 2 + 4 files changed, 293 insertions(+), 4 deletions(-) create mode 100644 rostests/apitests/ws2_32/WSAStartup.c diff --git a/rostests/apitests/ws2_32/CMakeLists.txt b/rostests/apitests/ws2_32/CMakeLists.txt index bbf35a0141f..0235f56e319 100644 --- a/rostests/apitests/ws2_32/CMakeLists.txt +++ b/rostests/apitests/ws2_32/CMakeLists.txt @@ -4,6 +4,7 @@ list(APPEND SOURCE helpers.c ioctlsocket.c recv.c + WSAStartup.c testlist.c) add_executable(ws2_32_apitest ${SOURCE}) diff --git a/rostests/apitests/ws2_32/WSAStartup.c b/rostests/apitests/ws2_32/WSAStartup.c new file mode 100644 index 00000000000..fd2a864444b --- /dev/null +++ b/rostests/apitests/ws2_32/WSAStartup.c @@ -0,0 +1,272 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Test for WSAStartup + * PROGRAMMER: Thomas Faber + */ + +#define WIN32_NO_STATUS +#include +#include +#include +#include +#include + +#define StartSeh() ExceptionStatus = STATUS_SUCCESS; _SEH2_TRY { +#define EndSeh(ExpectedStatus) } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExceptionStatus = _SEH2_GetExceptionCode(); } _SEH2_END; ok(ExceptionStatus == ExpectedStatus, "Exception %lx, expected %lx\n", ExceptionStatus, ExpectedStatus) + +static +PVOID +AllocateGuarded( + SIZE_T SizeRequested) +{ + NTSTATUS Status; + SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE); + PVOID VirtualMemory = NULL; + PCHAR StartOfBuffer; + + Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS); + + if (!NT_SUCCESS(Status)) + return NULL; + + Size -= PAGE_SIZE; + if (Size) + { + Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + Size = 0; + Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); + ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); + return NULL; + } + } + + StartOfBuffer = VirtualMemory; + StartOfBuffer += Size - SizeRequested; + + return StartOfBuffer; +} + +static +VOID +FreeGuarded( + PVOID Pointer) +{ + NTSTATUS Status; + PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer); + SIZE_T Size = 0; + + Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); + ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); +} + +static +BOOLEAN +IsInitialized(VOID) +{ + struct hostent *Hostent; + + Hostent = gethostbyname("localhost"); + if (!Hostent) + ok_dec(WSAGetLastError(), WSANOTINITIALISED); + return Hostent != NULL; +} + +static +BOOLEAN +AreLegacyFunctionsSupported(VOID) +{ + int Error; + + Error = WSACancelBlockingCall(); + ok(Error == SOCKET_ERROR, "Error = %d\n", Error); + ok(WSAGetLastError() == WSAEOPNOTSUPP || + WSAGetLastError() == WSAEINVAL, "WSAGetLastError = %d\n", WSAGetLastError()); + + return WSAGetLastError() != WSAEOPNOTSUPP; +} + +START_TEST(WSAStartup) +{ + NTSTATUS ExceptionStatus; + LPWSADATA WsaData; + int Error; + struct + { + WORD Version; + BOOLEAN ExpectedSuccess; + WORD ExpectedVersion; + } Tests[] = + { + { MAKEWORD(0, 0), FALSE, MAKEWORD(2, 2) }, + { MAKEWORD(0, 9), FALSE, MAKEWORD(2, 2) }, + { MAKEWORD(1, 0), TRUE }, + { MAKEWORD(1, 1), TRUE }, + { MAKEWORD(1, 2), TRUE, MAKEWORD(1, 1) }, + { MAKEWORD(1, 15), TRUE, MAKEWORD(1, 1) }, + { MAKEWORD(1, 255), TRUE, MAKEWORD(1, 1) }, + { MAKEWORD(2, 0), TRUE }, + { MAKEWORD(2, 1), TRUE }, + { MAKEWORD(2, 2), TRUE }, + { MAKEWORD(2, 3), TRUE, MAKEWORD(2, 2) }, + { MAKEWORD(2, 15), TRUE, MAKEWORD(2, 2) }, + { MAKEWORD(2, 255), TRUE, MAKEWORD(2, 2) }, + { MAKEWORD(3, 0), TRUE, MAKEWORD(2, 2) }, + { MAKEWORD(3, 1), TRUE, MAKEWORD(2, 2) }, + { MAKEWORD(3, 2), TRUE, MAKEWORD(2, 2) }, + { MAKEWORD(3, 3), TRUE, MAKEWORD(2, 2) }, + { MAKEWORD(3, 15), TRUE, MAKEWORD(2, 2) }, + { MAKEWORD(3, 255), TRUE, MAKEWORD(2, 2) }, + { MAKEWORD(15, 255), TRUE, MAKEWORD(2, 2) }, + { MAKEWORD(255, 255), TRUE, MAKEWORD(2, 2) }, + }; + const INT TestCount = sizeof(Tests) / sizeof(Tests[0]); + INT i; + + ok(!IsInitialized(), "Winsock unexpectedly initialized\n"); + + /* parameter checks */ + StartSeh() + Error = WSAStartup(0, NULL); + ok_dec(Error, WSAVERNOTSUPPORTED); + ok_dec(WSAGetLastError(), WSANOTINITIALISED); + EndSeh(STATUS_SUCCESS); + StartSeh() + Error = WSAStartup(MAKEWORD(2, 2), NULL); + ok_dec(Error, WSAEFAULT); + ok_dec(WSAGetLastError(), WSANOTINITIALISED); + EndSeh(STATUS_SUCCESS); + ok(!IsInitialized(), "Winsock unexpectedly initialized\n"); + + WsaData = AllocateGuarded(sizeof(*WsaData)); + if (!WsaData) + { + skip("Out of memory\n"); + return; + } + + /* test different version */ + for (i = 0; i < TestCount; i++) + { + trace("%d: version %d.%d\n", + i, LOBYTE(Tests[i].Version), HIBYTE(Tests[i].Version)); + FillMemory(WsaData, sizeof(*WsaData), 0x55); + Error = WSANO_RECOVERY; + StartSeh() + Error = WSAStartup(Tests[i].Version, WsaData); + EndSeh(STATUS_SUCCESS); + if (Error) + { + ok(!Tests[i].ExpectedSuccess, "WSAStartup failed unexpectedly\n"); + ok_dec(Error, WSAVERNOTSUPPORTED); + ok_dec(WSAGetLastError(), WSANOTINITIALISED); + ok(!IsInitialized(), "Winsock unexpectedly initialized\n"); + } + else + { + ok(Tests[i].ExpectedSuccess, "WSAStartup succeeded unexpectedly\n"); + ok_dec(WSAGetLastError(), 0); + ok(IsInitialized(), "Winsock not initialized despite success\n"); + if (LOBYTE(Tests[i].Version) < 2) + ok(AreLegacyFunctionsSupported(), "Legacy function failed\n"); + else + ok(!AreLegacyFunctionsSupported(), "Legacy function succeeded\n"); + WSACleanup(); + ok(!IsInitialized(), "Winsock still initialized after cleanup\n"); + } + if (Tests[i].ExpectedVersion) + ok_hex(WsaData->wVersion, Tests[i].ExpectedVersion); + else + ok_hex(WsaData->wVersion, Tests[i].Version); + ok_hex(WsaData->wHighVersion, MAKEWORD(2, 2)); + ok_str(WsaData->szDescription, "WinSock 2.0"); + ok_str(WsaData->szSystemStatus, "Running"); + if (LOBYTE(WsaData->wVersion) >= 2) + { + ok_dec(WsaData->iMaxSockets, 0); + ok_dec(WsaData->iMaxUdpDg, 0); + } + else + { + ok_dec(WsaData->iMaxSockets, 32767); + ok_dec(WsaData->iMaxUdpDg, 65467); + } + ok_ptr(WsaData->lpVendorInfo, (PVOID)0x5555555555555555ULL); + } + + /* upgrade the version */ + FillMemory(WsaData, sizeof(*WsaData), 0x55); + Error = WSAStartup(MAKEWORD(1, 1), WsaData); + ok_dec(Error, 0); + ok_dec(WSAGetLastError(), 0); + ok_hex(WsaData->wVersion, MAKEWORD(1, 1)); + ok_hex(WsaData->wHighVersion, MAKEWORD(2, 2)); + ok_str(WsaData->szDescription, "WinSock 2.0"); + ok_str(WsaData->szSystemStatus, "Running"); + ok_dec(WsaData->iMaxSockets, 32767); + ok_dec(WsaData->iMaxUdpDg, 65467); + ok_ptr(WsaData->lpVendorInfo, (PVOID)0x5555555555555555ULL); + ok(IsInitialized(), "Winsock not initialized\n"); + if (!Error) + { + ok(AreLegacyFunctionsSupported(), "Legacy function failed\n"); + FillMemory(WsaData, sizeof(*WsaData), 0x55); + Error = WSAStartup(MAKEWORD(2, 2), WsaData); + ok_dec(Error, 0); + ok_hex(WsaData->wVersion, MAKEWORD(2, 2)); + ok_hex(WsaData->wHighVersion, MAKEWORD(2, 2)); + ok_str(WsaData->szDescription, "WinSock 2.0"); + ok_str(WsaData->szSystemStatus, "Running"); + ok_dec(WsaData->iMaxSockets, 0); + ok_dec(WsaData->iMaxUdpDg, 0); + ok_ptr(WsaData->lpVendorInfo, (PVOID)0x5555555555555555ULL); + if (!Error) + { + ok(AreLegacyFunctionsSupported(), "Legacy function failed\n"); + WSACleanup(); + ok(IsInitialized(), "Winsock prematurely uninitialized\n"); + } + WSACleanup(); + ok(!IsInitialized(), "Winsock still initialized after cleanup\n"); + } + + /* downgrade the version */ + FillMemory(WsaData, sizeof(*WsaData), 0x55); + Error = WSAStartup(MAKEWORD(2, 2), WsaData); + ok_dec(Error, 0); + ok_dec(WSAGetLastError(), 0); + ok_hex(WsaData->wVersion, MAKEWORD(2, 2)); + ok_hex(WsaData->wHighVersion, MAKEWORD(2, 2)); + ok_str(WsaData->szDescription, "WinSock 2.0"); + ok_str(WsaData->szSystemStatus, "Running"); + ok_dec(WsaData->iMaxSockets, 0); + ok_dec(WsaData->iMaxUdpDg, 0); + ok_ptr(WsaData->lpVendorInfo, (PVOID)0x5555555555555555ULL); + ok(IsInitialized(), "Winsock not initialized\n"); + if (!Error) + { + ok(!AreLegacyFunctionsSupported(), "Legacy function succeeded\n"); + FillMemory(WsaData, sizeof(*WsaData), 0x55); + Error = WSAStartup(MAKEWORD(1, 1), WsaData); + ok_dec(Error, 0); + ok_hex(WsaData->wVersion, MAKEWORD(1, 1)); + ok_hex(WsaData->wHighVersion, MAKEWORD(2, 2)); + ok_str(WsaData->szDescription, "WinSock 2.0"); + ok_str(WsaData->szSystemStatus, "Running"); + ok_dec(WsaData->iMaxSockets, 32767); + ok_dec(WsaData->iMaxUdpDg, 65467); + ok_ptr(WsaData->lpVendorInfo, (PVOID)0x5555555555555555ULL); + if (!Error) + { + ok(AreLegacyFunctionsSupported(), "Legacy function failed\n"); + WSACleanup(); + ok(IsInitialized(), "Winsock prematurely uninitialized\n"); + } + WSACleanup(); + ok(!IsInitialized(), "Winsock still initialized after cleanup\n"); + } + + FreeGuarded(WsaData); +} diff --git a/rostests/apitests/ws2_32/getaddrinfo.c b/rostests/apitests/ws2_32/getaddrinfo.c index 26f41be59f9..50ff0a27b7c 100644 --- a/rostests/apitests/ws2_32/getaddrinfo.c +++ b/rostests/apitests/ws2_32/getaddrinfo.c @@ -66,6 +66,9 @@ TestNodeName(VOID) { "0.0.0.0:80", NULL }, { "0.0.0.0.0", NULL }, { "1.1.1.256", NULL }, + { "1.2.3", NULL }, + { "1.2.3.0x4", "1.2.3.4", AI_NUMERICHOST }, + { "1.2.3.010", "1.2.3.8", AI_NUMERICHOST }, /* let's just assume this one doesn't change any time soon ;) */ { "google-public-dns-a.google.com", "8.8.8.8" }, }; @@ -80,7 +83,7 @@ TestNodeName(VOID) for (i = 0; i < TestCount; i++) { trace("%d: '%s'\n", i, Tests[i].NodeName); - StartSeh(); + StartSeh() AddrInfo = InvalidPointer; Error = getaddrinfo(Tests[i].NodeName, NULL, &Hints, &AddrInfo); if (Tests[i].ExpectedAddress) @@ -214,6 +217,17 @@ START_TEST(getaddrinfo) struct hostent *Hostent; /* not yet initialized */ + StartSeh() + Error = getaddrinfo(NULL, NULL, NULL, NULL); + ok_dec(Error, WSANOTINITIALISED); + EndSeh(STATUS_SUCCESS); + StartSeh() + AddrInfo = InvalidPointer; + Error = getaddrinfo(NULL, NULL, NULL, &AddrInfo); + ok_dec(Error, WSANOTINITIALISED); + ok_ptr(AddrInfo, InvalidPointer); + EndSeh(STATUS_SUCCESS); + Error = getaddrinfo("127.0.0.1", "80", NULL, &AddrInfo); ok_dec(Error, WSANOTINITIALISED); @@ -239,9 +253,9 @@ START_TEST(getaddrinfo) ZeroMemory(&Hints, sizeof(Hints)); /* parameter tests */ - StartSeh(); getaddrinfo(NULL, NULL, NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION); - StartSeh(); getaddrinfo("", "", &Hints, NULL); EndSeh(STATUS_ACCESS_VIOLATION); - StartSeh(); + StartSeh() getaddrinfo(NULL, NULL, NULL, NULL); EndSeh(STATUS_ACCESS_VIOLATION); + StartSeh() getaddrinfo("", "", &Hints, NULL); EndSeh(STATUS_ACCESS_VIOLATION); + StartSeh() AddrInfo = InvalidPointer; Error = getaddrinfo(NULL, NULL, NULL, &AddrInfo); ok_dec(Error, WSAHOST_NOT_FOUND); diff --git a/rostests/apitests/ws2_32/testlist.c b/rostests/apitests/ws2_32/testlist.c index 9c08f5e54f5..4f2378cd4e6 100644 --- a/rostests/apitests/ws2_32/testlist.c +++ b/rostests/apitests/ws2_32/testlist.c @@ -8,12 +8,14 @@ extern void func_getaddrinfo(void); extern void func_ioctlsocket(void); extern void func_recv(void); +extern void func_WSAStartup(void); const struct test winetest_testlist[] = { { "getaddrinfo", func_getaddrinfo }, { "ioctlsocket", func_ioctlsocket }, { "recv", func_recv }, + { "WSAStartup", func_WSAStartup }, { 0, 0 } };