From 041ff27f2d8a2dc60c3d67fb8bb8a92ff2223a84 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Tue, 26 Jun 2012 06:08:38 +0000 Subject: [PATCH] [APITESTS] - Add wininet and winhttp tests for Winsock loading and initialization behavior [WS2_32_APITEST] - Make WSAStartup test more robust and stricter svn path=/trunk/; revision=56804 --- rostests/apitests/CMakeLists.txt | 2 + rostests/apitests/winhttp/CMakeLists.txt | 12 +++ rostests/apitests/winhttp/WinHttpOpen.c | 124 ++++++++++++++++++++++ rostests/apitests/winhttp/testlist.c | 15 +++ rostests/apitests/wininet/CMakeLists.txt | 12 +++ rostests/apitests/wininet/InternetOpen.c | 114 ++++++++++++++++++++ rostests/apitests/wininet/testlist.c | 15 +++ rostests/apitests/ws2_32/WSAStartup.c | 128 +++++++++++++++++++---- 8 files changed, 400 insertions(+), 22 deletions(-) create mode 100644 rostests/apitests/winhttp/CMakeLists.txt create mode 100644 rostests/apitests/winhttp/WinHttpOpen.c create mode 100644 rostests/apitests/winhttp/testlist.c create mode 100644 rostests/apitests/wininet/CMakeLists.txt create mode 100644 rostests/apitests/wininet/InternetOpen.c create mode 100644 rostests/apitests/wininet/testlist.c diff --git a/rostests/apitests/CMakeLists.txt b/rostests/apitests/CMakeLists.txt index a1da26967d0..3a2b6d634c6 100644 --- a/rostests/apitests/CMakeLists.txt +++ b/rostests/apitests/CMakeLists.txt @@ -14,4 +14,6 @@ if(NOT MSVC AND ARCH MATCHES i386) add_subdirectory(w32kdll) add_subdirectory(w32knapi) endif() +add_subdirectory(winhttp) +add_subdirectory(wininet) add_subdirectory(ws2_32) diff --git a/rostests/apitests/winhttp/CMakeLists.txt b/rostests/apitests/winhttp/CMakeLists.txt new file mode 100644 index 00000000000..2b9ba059760 --- /dev/null +++ b/rostests/apitests/winhttp/CMakeLists.txt @@ -0,0 +1,12 @@ + +list(APPEND SOURCE + WinHttpOpen.c + testlist.c) + +add_executable(winhttp_apitest ${SOURCE}) +target_link_libraries(winhttp_apitest wine) +set_module_type(winhttp_apitest win32cui) +add_importlibs(winhttp_apitest msvcrt kernel32 ntdll) +#add_delay_importlibs(winhttp_apitest winhttp) + +add_cd_file(TARGET winhttp_apitest DESTINATION reactos/bin FOR all) diff --git a/rostests/apitests/winhttp/WinHttpOpen.c b/rostests/apitests/winhttp/WinHttpOpen.c new file mode 100644 index 00000000000..54c65704d4d --- /dev/null +++ b/rostests/apitests/winhttp/WinHttpOpen.c @@ -0,0 +1,124 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Test for WinHttpOpen + * PROGRAMMER: Thomas Faber + */ + +#define UNICODE +#include +#include +#include + +struct hostent *(WINAPI *pgethostbyname)(const char *); +int (WINAPI *pWSACancelBlockingCall)(void); +int (WINAPI *pWSAGetLastError)(void); + +HINTERNET (WINAPI *pWinHttpOpen)(LPCWSTR, DWORD, LPCWSTR, LPCWSTR, DWORD); +BOOL (WINAPI *pWinHttpCloseHandle)(HINTERNET); + +static +PVOID +GetProc( + PCSTR FunctionName) +{ + HMODULE ModuleHandle; + + ModuleHandle = GetModuleHandle(L"ws2_32"); + if (!ModuleHandle) + return NULL; + return GetProcAddress(ModuleHandle, FunctionName); +} + +#define PROC(name) (p##name = GetProc(#name)) + +static +BOOLEAN +IsWinsockLoaded(VOID) +{ + return GetModuleHandle(L"ws2_32") != NULL; +} + +static +BOOLEAN +IsWininetLoaded(VOID) +{ + return GetModuleHandle(L"wininet") != NULL; +} + +static +BOOLEAN +IsWinsockInitialized(VOID) +{ + struct hostent *Hostent; + + if (!PROC(gethostbyname) || !PROC(WSAGetLastError)) + return FALSE; + + Hostent = pgethostbyname("localhost"); + if (!Hostent) + ok_dec(pWSAGetLastError(), WSANOTINITIALISED); + return Hostent != NULL; +} + +static +BOOLEAN +AreLegacyFunctionsSupported(VOID) +{ + int Error; + + if (!PROC(WSACancelBlockingCall) || !PROC(WSAGetLastError)) + return FALSE; + + Error = pWSACancelBlockingCall(); + ok(Error == SOCKET_ERROR, "Error = %d\n", Error); + ok(pWSAGetLastError() == WSAEOPNOTSUPP || + pWSAGetLastError() == WSAEINVAL, "WSAGetLastError = %d\n", pWSAGetLastError()); + + return pWSAGetLastError() != WSAEOPNOTSUPP; +} + +START_TEST(WinHttpOpen) +{ + HMODULE ModuleHandle; + HINTERNET InternetHandle; + BOOL Success; + + ok(!IsWinsockLoaded(), "Winsock loaded on startup\n"); + ok(!IsWinsockInitialized(), "Winsock initialized on startup\n"); + ok(!IsWininetLoaded(), "Wininet loaded on startup\n"); + + ModuleHandle = GetModuleHandle(L"winhttp"); + ok_ptr(ModuleHandle, NULL); + ModuleHandle = LoadLibrary(L"winhttp"); + ok(ModuleHandle != NULL, "LoadLibrary failed, error %lu\n", GetLastError()); + + pWinHttpOpen = (PVOID)GetProcAddress(ModuleHandle, "WinHttpOpen"); + pWinHttpCloseHandle = (PVOID)GetProcAddress(ModuleHandle, "WinHttpCloseHandle"); + + ok(!IsWinsockLoaded(), "Winsock loaded after winhttp load\n"); + ok(!IsWinsockInitialized(), "Winsock initialized after winhttp load\n"); + ok(!IsWininetLoaded(), "Wininet loaded after winhttp load\n"); + + InternetHandle = pWinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); + ok(InternetHandle != NULL, "InternetHandle = NULL\n"); + + if (InternetHandle != NULL) + { + ok(IsWinsockLoaded(), "Winsock not loaded after WinHttpOpen\n"); + ok(IsWinsockInitialized(), "Winsock not initialized after WinHttpOpen\n"); + ok(!IsWininetLoaded(), "Wininet loaded after WinHttpOpen\n"); + ok(AreLegacyFunctionsSupported(), "Winsock initialized with version 2\n"); + Success = pWinHttpCloseHandle(InternetHandle); + ok(Success, "WinHttpCloseHandle failed, error %lu\n", GetLastError()); + } + + ok(IsWinsockLoaded(), "Winsock unloaded after handle close\n"); + ok(IsWinsockInitialized(), "Winsock uninitialized after handle close\n"); + + FreeLibrary(ModuleHandle); + + ok(IsWinsockLoaded(), "Winsock unloaded after winhttp unload\n"); + trace("Winsock %sinitialized after winhttp unload (should be uninitialized in 2003, still initialized in 7)\n", + IsWinsockInitialized() ? "" : "un"); +} diff --git a/rostests/apitests/winhttp/testlist.c b/rostests/apitests/winhttp/testlist.c new file mode 100644 index 00000000000..fa5cd82646f --- /dev/null +++ b/rostests/apitests/winhttp/testlist.c @@ -0,0 +1,15 @@ +#define WIN32_LEAN_AND_MEAN +#define __ROS_LONG64__ +#include + +#define STANDALONE +#include "wine/test.h" + +extern void func_WinHttpOpen(void); + +const struct test winetest_testlist[] = +{ + { "WinHttpOpen", func_WinHttpOpen }, + + { 0, 0 } +}; diff --git a/rostests/apitests/wininet/CMakeLists.txt b/rostests/apitests/wininet/CMakeLists.txt new file mode 100644 index 00000000000..6b91d579a9c --- /dev/null +++ b/rostests/apitests/wininet/CMakeLists.txt @@ -0,0 +1,12 @@ + +list(APPEND SOURCE + InternetOpen.c + testlist.c) + +add_executable(wininet_apitest ${SOURCE}) +target_link_libraries(wininet_apitest wine) +set_module_type(wininet_apitest win32cui) +add_importlibs(wininet_apitest msvcrt kernel32 ntdll) +#add_delay_importlibs(wininet_apitest wininet) + +add_cd_file(TARGET wininet_apitest DESTINATION reactos/bin FOR all) diff --git a/rostests/apitests/wininet/InternetOpen.c b/rostests/apitests/wininet/InternetOpen.c new file mode 100644 index 00000000000..54806243b36 --- /dev/null +++ b/rostests/apitests/wininet/InternetOpen.c @@ -0,0 +1,114 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Test for InternetOpen + * PROGRAMMER: Thomas Faber + */ + +#define UNICODE +#include +#include +#include + +struct hostent *(WINAPI *pgethostbyname)(const char *); +int (WINAPI *pWSACancelBlockingCall)(void); +int (WINAPI *pWSAGetLastError)(void); + +HINTERNET (WINAPI *pInternetOpen)(LPCTSTR, DWORD, LPCTSTR, LPCTSTR, DWORD); +BOOL (WINAPI *pInternetCloseHandle)(HINTERNET); + +static +PVOID +GetProc( + PCSTR FunctionName) +{ + HMODULE ModuleHandle; + + ModuleHandle = GetModuleHandle(L"ws2_32"); + if (!ModuleHandle) + return NULL; + return GetProcAddress(ModuleHandle, FunctionName); +} + +#define PROC(name) (p##name = GetProc(#name)) + +static +BOOLEAN +IsWinsockLoaded(VOID) +{ + return GetModuleHandle(L"ws2_32") != NULL; +} + +static +BOOLEAN +IsWinsockInitialized(VOID) +{ + struct hostent *Hostent; + + if (!PROC(gethostbyname) || !PROC(WSAGetLastError)) + return FALSE; + + Hostent = pgethostbyname("localhost"); + if (!Hostent) + ok_dec(pWSAGetLastError(), WSANOTINITIALISED); + return Hostent != NULL; +} + +static +BOOLEAN +AreLegacyFunctionsSupported(VOID) +{ + int Error; + + if (!PROC(WSACancelBlockingCall) || !PROC(WSAGetLastError)) + return FALSE; + + Error = pWSACancelBlockingCall(); + ok(Error == SOCKET_ERROR, "Error = %d\n", Error); + ok(pWSAGetLastError() == WSAEOPNOTSUPP || + pWSAGetLastError() == WSAEINVAL, "WSAGetLastError = %d\n", pWSAGetLastError()); + + return pWSAGetLastError() != WSAEOPNOTSUPP; +} + +START_TEST(InternetOpen) +{ + HMODULE ModuleHandle; + HINTERNET InternetHandle; + BOOL Success; + + ok(!IsWinsockLoaded(), "Winsock loaded on startup\n"); + ok(!IsWinsockInitialized(), "Winsock initialized on startup\n"); + + ModuleHandle = GetModuleHandle(L"wininet"); + ok_ptr(ModuleHandle, NULL); + ModuleHandle = LoadLibrary(L"wininet"); + ok(ModuleHandle != NULL, "LoadLibrary failed, error %lu\n", GetLastError()); + + pInternetOpen = (PVOID)GetProcAddress(ModuleHandle, "InternetOpenW"); + pInternetCloseHandle = (PVOID)GetProcAddress(ModuleHandle, "InternetCloseHandle"); + + ok(!IsWinsockLoaded(), "Winsock loaded after wininet load\n"); + ok(!IsWinsockInitialized(), "Winsock initialized after wininet load\n"); + + InternetHandle = pInternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); + ok(InternetHandle != NULL, "InternetHandle = NULL\n"); + + if (InternetHandle != NULL) + { + ok(IsWinsockLoaded(), "Winsock not loaded after InternetOpen\n"); + ok(IsWinsockInitialized(), "Winsock not initialized after InternetOpen\n"); + ok(!AreLegacyFunctionsSupported(), "Winsock initialized with version 1\n"); + Success = pInternetCloseHandle(InternetHandle); + ok(Success, "InternetCloseHandle failed, error %lu\n", GetLastError()); + } + + ok(IsWinsockLoaded(), "Winsock unloaded after handle close\n"); + ok(IsWinsockInitialized(), "Winsock uninitialized after handle close\n"); + + FreeLibrary(ModuleHandle); + + ok(IsWinsockLoaded(), "Winsock unloaded after wininet unload\n"); + trace("Winsock %sinitialized after wininet unload (should be uninitialized in 2003, still initialized in 7)\n", + IsWinsockInitialized() ? "" : "un"); +} diff --git a/rostests/apitests/wininet/testlist.c b/rostests/apitests/wininet/testlist.c new file mode 100644 index 00000000000..8083e603077 --- /dev/null +++ b/rostests/apitests/wininet/testlist.c @@ -0,0 +1,15 @@ +#define WIN32_LEAN_AND_MEAN +#define __ROS_LONG64__ +#include + +#define STANDALONE +#include "wine/test.h" + +extern void func_InternetOpen(void); + +const struct test winetest_testlist[] = +{ + { "InternetOpen", func_InternetOpen }, + + { 0, 0 } +}; diff --git a/rostests/apitests/ws2_32/WSAStartup.c b/rostests/apitests/ws2_32/WSAStartup.c index fd2a864444b..86d5f421139 100644 --- a/rostests/apitests/ws2_32/WSAStartup.c +++ b/rostests/apitests/ws2_32/WSAStartup.c @@ -64,7 +64,50 @@ FreeGuarded( static BOOLEAN -IsInitialized(VOID) +CheckStringBuffer( + PCSTR Buffer, + SIZE_T MaximumLength, + PCSTR Expected, + UCHAR Fill) +{ + SIZE_T Length = strlen(Expected); + SIZE_T EqualLength; + BOOLEAN Result = TRUE; + SIZE_T i; + + EqualLength = RtlCompareMemory(Buffer, Expected, Length); + if (EqualLength != Length) + { + ok(0, "String is '%S', expected '%S'\n", Buffer, Expected); + Result = FALSE; + } + + if (Buffer[Length] != ANSI_NULL) + { + ok(0, "Not null terminated\n"); + Result = FALSE; + } + + /* The function nulls the rest of the buffer! */ + for (i = Length + 1; i < MaximumLength; i++) + { + UCHAR Char = ((PUCHAR)Buffer)[i]; + if (Char != Fill) + { + ok(0, "Found 0x%x at offset %lu, expected 0x%x\n", Char, (ULONG)i, Fill); + /* Don't count this as a failure unless the string was actually wrong */ + //Result = FALSE; + /* Don't flood the log */ + break; + } + } + + return Result; +} + +static +BOOLEAN +IsWinsockInitialized(VOID) { struct hostent *Hostent; @@ -91,6 +134,7 @@ AreLegacyFunctionsSupported(VOID) START_TEST(WSAStartup) { NTSTATUS ExceptionStatus; + BOOLEAN Okay; LPWSADATA WsaData; int Error; struct @@ -125,7 +169,7 @@ START_TEST(WSAStartup) const INT TestCount = sizeof(Tests) / sizeof(Tests[0]); INT i; - ok(!IsInitialized(), "Winsock unexpectedly initialized\n"); + ok(!IsWinsockInitialized(), "Winsock unexpectedly initialized\n"); /* parameter checks */ StartSeh() @@ -138,7 +182,7 @@ START_TEST(WSAStartup) ok_dec(Error, WSAEFAULT); ok_dec(WSAGetLastError(), WSANOTINITIALISED); EndSeh(STATUS_SUCCESS); - ok(!IsInitialized(), "Winsock unexpectedly initialized\n"); + ok(!IsWinsockInitialized(), "Winsock unexpectedly initialized\n"); WsaData = AllocateGuarded(sizeof(*WsaData)); if (!WsaData) @@ -162,27 +206,35 @@ START_TEST(WSAStartup) ok(!Tests[i].ExpectedSuccess, "WSAStartup failed unexpectedly\n"); ok_dec(Error, WSAVERNOTSUPPORTED); ok_dec(WSAGetLastError(), WSANOTINITIALISED); - ok(!IsInitialized(), "Winsock unexpectedly initialized\n"); + ok(!IsWinsockInitialized(), "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"); + ok(IsWinsockInitialized(), "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"); + ok(!IsWinsockInitialized(), "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"); + Okay = CheckStringBuffer(WsaData->szDescription, + sizeof(WsaData->szDescription), + "WinSock 2.0", + 0x55); + ok(Okay, "CheckStringBuffer failed\n"); + Okay = CheckStringBuffer(WsaData->szSystemStatus, + sizeof(WsaData->szSystemStatus), + "Running", + 0x55); + ok(Okay, "CheckStringBuffer failed\n"); if (LOBYTE(WsaData->wVersion) >= 2) { ok_dec(WsaData->iMaxSockets, 0); @@ -203,12 +255,20 @@ START_TEST(WSAStartup) 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"); + Okay = CheckStringBuffer(WsaData->szDescription, + sizeof(WsaData->szDescription), + "WinSock 2.0", + 0x55); + ok(Okay, "CheckStringBuffer failed\n"); + Okay = CheckStringBuffer(WsaData->szSystemStatus, + sizeof(WsaData->szSystemStatus), + "Running", + 0x55); + ok(Okay, "CheckStringBuffer failed\n"); ok_dec(WsaData->iMaxSockets, 32767); ok_dec(WsaData->iMaxUdpDg, 65467); ok_ptr(WsaData->lpVendorInfo, (PVOID)0x5555555555555555ULL); - ok(IsInitialized(), "Winsock not initialized\n"); + ok(IsWinsockInitialized(), "Winsock not initialized\n"); if (!Error) { ok(AreLegacyFunctionsSupported(), "Legacy function failed\n"); @@ -217,8 +277,16 @@ START_TEST(WSAStartup) 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"); + Okay = CheckStringBuffer(WsaData->szDescription, + sizeof(WsaData->szDescription), + "WinSock 2.0", + 0x55); + ok(Okay, "CheckStringBuffer failed\n"); + Okay = CheckStringBuffer(WsaData->szSystemStatus, + sizeof(WsaData->szSystemStatus), + "Running", + 0x55); + ok(Okay, "CheckStringBuffer failed\n"); ok_dec(WsaData->iMaxSockets, 0); ok_dec(WsaData->iMaxUdpDg, 0); ok_ptr(WsaData->lpVendorInfo, (PVOID)0x5555555555555555ULL); @@ -226,10 +294,10 @@ START_TEST(WSAStartup) { ok(AreLegacyFunctionsSupported(), "Legacy function failed\n"); WSACleanup(); - ok(IsInitialized(), "Winsock prematurely uninitialized\n"); + ok(IsWinsockInitialized(), "Winsock prematurely uninitialized\n"); } WSACleanup(); - ok(!IsInitialized(), "Winsock still initialized after cleanup\n"); + ok(!IsWinsockInitialized(), "Winsock still initialized after cleanup\n"); } /* downgrade the version */ @@ -239,12 +307,20 @@ START_TEST(WSAStartup) 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"); + Okay = CheckStringBuffer(WsaData->szDescription, + sizeof(WsaData->szDescription), + "WinSock 2.0", + 0x55); + ok(Okay, "CheckStringBuffer failed\n"); + Okay = CheckStringBuffer(WsaData->szSystemStatus, + sizeof(WsaData->szSystemStatus), + "Running", + 0x55); + ok(Okay, "CheckStringBuffer failed\n"); ok_dec(WsaData->iMaxSockets, 0); ok_dec(WsaData->iMaxUdpDg, 0); ok_ptr(WsaData->lpVendorInfo, (PVOID)0x5555555555555555ULL); - ok(IsInitialized(), "Winsock not initialized\n"); + ok(IsWinsockInitialized(), "Winsock not initialized\n"); if (!Error) { ok(!AreLegacyFunctionsSupported(), "Legacy function succeeded\n"); @@ -253,8 +329,16 @@ START_TEST(WSAStartup) 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"); + Okay = CheckStringBuffer(WsaData->szDescription, + sizeof(WsaData->szDescription), + "WinSock 2.0", + 0x55); + ok(Okay, "CheckStringBuffer failed\n"); + Okay = CheckStringBuffer(WsaData->szSystemStatus, + sizeof(WsaData->szSystemStatus), + "Running", + 0x55); + ok(Okay, "CheckStringBuffer failed\n"); ok_dec(WsaData->iMaxSockets, 32767); ok_dec(WsaData->iMaxUdpDg, 65467); ok_ptr(WsaData->lpVendorInfo, (PVOID)0x5555555555555555ULL); @@ -262,10 +346,10 @@ START_TEST(WSAStartup) { ok(AreLegacyFunctionsSupported(), "Legacy function failed\n"); WSACleanup(); - ok(IsInitialized(), "Winsock prematurely uninitialized\n"); + ok(IsWinsockInitialized(), "Winsock prematurely uninitialized\n"); } WSACleanup(); - ok(!IsInitialized(), "Winsock still initialized after cleanup\n"); + ok(!IsWinsockInitialized(), "Winsock still initialized after cleanup\n"); } FreeGuarded(WsaData);