diff --git a/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp b/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp index d7481d88fb..fcedb2bee1 100644 --- a/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp +++ b/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp @@ -3,11 +3,92 @@ #include "cellHttpUtil.h" +#ifdef _WIN32 +#include +#include +#include +#pragma comment(lib, "Winhttp.lib") +#endif + logs::channel cellHttpUtil("cellHttpUtil"); s32 cellHttpUtilParseUri(vm::ptr uri, vm::cptr str, vm::ptr pool, u32 size, vm::ptr required) { + +#ifdef _WIN32 + + URL_COMPONENTS stUrlComp; + + ZeroMemory(&stUrlComp, sizeof(URL_COMPONENTS)); + stUrlComp.dwStructSize = sizeof(URL_COMPONENTS); + + wchar_t lpszScheme[MAX_PATH] = { 0 }; + wchar_t lpszHostName[MAX_PATH] = { 0 }; + wchar_t lpszPath[MAX_PATH] = { 0 }; + wchar_t lpszUserName[MAX_PATH] = { 0 }; + wchar_t lpszPassword[MAX_PATH] = { 0 }; + + stUrlComp.lpszScheme = lpszScheme; + stUrlComp.dwSchemeLength = MAX_PATH; + + stUrlComp.lpszHostName = lpszHostName; + stUrlComp.dwHostNameLength = MAX_PATH; + + stUrlComp.lpszUrlPath = lpszPath; + stUrlComp.dwUrlPathLength = MAX_PATH; + + stUrlComp.lpszUserName = lpszUserName; + stUrlComp.dwUserNameLength = MAX_PATH; + + stUrlComp.lpszPassword = lpszPassword; + stUrlComp.dwPasswordLength = MAX_PATH; + + std::wstring_convert> converter; + + LPCWSTR stupidTypeUrlString = converter.from_bytes(str.get_ptr()).c_str(); + if (!::WinHttpCrackUrl(stupidTypeUrlString, (DWORD)(LONG_PTR)wcslen(stupidTypeUrlString), ICU_ESCAPE, &stUrlComp)) + { + cellHttpUtil.error("Error %u in WinHttpCrackUrl.\n", GetLastError()); + } + else + { + + std::string scheme = converter.to_bytes(lpszScheme); + std::string host = converter.to_bytes(lpszHostName); + std::string path = converter.to_bytes(lpszPath); + std::string username = converter.to_bytes(lpszUserName); + std::string password = converter.to_bytes(lpszPassword); + + u32 schemeOffset = 0; + u32 hostOffset = scheme.length() + 1; + u32 pathOffset = hostOffset + host.length() + 1; + u32 usernameOffset = pathOffset + path.length() + 1; + u32 passwordOffset = usernameOffset + username.length() + 1; + u32 totalSize = passwordOffset + password.length() + 1; + + //called twice, first to setup pool, then to populate. + if (!uri) { + *required = totalSize; + return CELL_OK; + } else { + std::strncpy((char*)vm::base(pool.addr() + schemeOffset), (char*)scheme.c_str(), scheme.length() + 1); + std::strncpy((char*)vm::base(pool.addr() + hostOffset), (char*)host.c_str(), host.length() + 1); + std::strncpy((char*)vm::base(pool.addr() + pathOffset), (char*)path.c_str(), path.length() + 1); + std::strncpy((char*)vm::base(pool.addr() + usernameOffset), (char*)username.c_str(), username.length() + 1); + std::strncpy((char*)vm::base(pool.addr() + passwordOffset), (char*)password.c_str(), password.length() + 1); + + uri->scheme.set(pool.addr() + schemeOffset); + uri->hostname.set(pool.addr() + hostOffset); + uri->path.set(pool.addr() + pathOffset); + uri->username.set(pool.addr() + usernameOffset); + uri->password.set(pool.addr() + passwordOffset); + uri->port = stUrlComp.nPort; + } + } + +#else cellHttpUtil.todo("cellHttpUtilParseUri(uri=*0x%x, str=%s, pool=*0x%x, size=%d, required=*0x%x)", uri, str, pool, size, required); +#endif return CELL_OK; } diff --git a/rpcs3/main.cpp b/rpcs3/main.cpp index d21915ea39..f7d5fd7e99 100644 --- a/rpcs3/main.cpp +++ b/rpcs3/main.cpp @@ -15,6 +15,8 @@ int main(int argc, char** argv) { #ifdef _WIN32 SetProcessDPIAware(); + WSADATA wsa_data; + WSAStartup(MAKEWORD(2, 2), &wsa_data); #else qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1"); #endif