mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-13 09:35:23 -04:00
Windows: Make it easier to run on NT 3.51
This commit is contained in:
parent
305649bda6
commit
e467ae89da
@ -351,7 +351,7 @@ static void Http_SetCurlOpts(struct HttpRequest* req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* url) {
|
static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* url) {
|
||||||
wchar_t urlStr[NATIVE_STR_LEN];
|
char urlStr[NATIVE_STR_LEN];
|
||||||
void* post_data = req->data;
|
void* post_data = req->data;
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
if (!curlSupported) return ERR_NOT_SUPPORTED;
|
if (!curlSupported) return ERR_NOT_SUPPORTED;
|
||||||
@ -402,6 +402,7 @@ static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* url) {
|
|||||||
#define _UNICODE
|
#define _UNICODE
|
||||||
#endif
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include "Errors.h"
|
||||||
|
|
||||||
/* === BEGIN wininet.h === */
|
/* === BEGIN wininet.h === */
|
||||||
#define INETAPI DECLSPEC_IMPORT
|
#define INETAPI DECLSPEC_IMPORT
|
||||||
@ -427,17 +428,17 @@ typedef WORD INTERNET_PORT;
|
|||||||
#define HTTP_QUERY_RAW_HEADERS 21
|
#define HTTP_QUERY_RAW_HEADERS 21
|
||||||
#define INTERNET_OPTION_SECURITY_FLAGS 31
|
#define INTERNET_OPTION_SECURITY_FLAGS 31
|
||||||
|
|
||||||
INETAPI BOOL WINAPI InternetCloseHandle(HINTERNET hInternet);
|
static BOOL (WINAPI *_InternetCloseHandle)(HINTERNET hInternet);
|
||||||
INETAPI HINTERNET WINAPI InternetConnectA(HINTERNET hInternet, PCSTR serverName, INTERNET_PORT serverPort, PCSTR userName, PCSTR password, DWORD service, DWORD flags, DWORD_PTR context);
|
static HINTERNET (WINAPI *_InternetConnectA)(HINTERNET hInternet, PCSTR serverName, INTERNET_PORT serverPort, PCSTR userName, PCSTR password, DWORD service, DWORD flags, DWORD_PTR context);
|
||||||
INETAPI HINTERNET WINAPI InternetOpenA(PCSTR agent, DWORD accessType, PCSTR lpszProxy, PCSTR proxyBypass, DWORD flags);
|
static HINTERNET (WINAPI *_InternetOpenA)(PCSTR agent, DWORD accessType, PCSTR lpszProxy, PCSTR proxyBypass, DWORD flags);
|
||||||
INETAPI BOOL WINAPI InternetQueryOptionA(HINTERNET hInternet, DWORD option, PVOID buffer, DWORD* bufferLength);
|
static BOOL (WINAPI *_InternetQueryOptionA)(HINTERNET hInternet, DWORD option, PVOID buffer, DWORD* bufferLength);
|
||||||
INETAPI BOOL WINAPI InternetSetOptionA(HINTERNET hInternet, DWORD option, PVOID buffer, DWORD bufferLength);
|
static BOOL (WINAPI *_InternetSetOptionA)(HINTERNET hInternet, DWORD option, PVOID buffer, DWORD bufferLength);
|
||||||
INETAPI BOOL WINAPI InternetQueryDataAvailable(HINTERNET hFile, DWORD* numBytesAvailable, DWORD flags, DWORD_PTR context);
|
static BOOL (WINAPI *_InternetQueryDataAvailable)(HINTERNET hFile, DWORD* numBytesAvailable, DWORD flags, DWORD_PTR context);
|
||||||
INETAPI BOOL WINAPI InternetReadFile(HINTERNET hFile, PVOID buffer, DWORD numBytesToRead, DWORD* numBytesRead);
|
static BOOL (WINAPI *_InternetReadFile)(HINTERNET hFile, PVOID buffer, DWORD numBytesToRead, DWORD* numBytesRead);
|
||||||
INETAPI BOOL WINAPI HttpQueryInfoA(HINTERNET hRequest, DWORD infoLevel, PVOID buffer, DWORD* bufferLength, DWORD* index);
|
static BOOL (WINAPI *_HttpQueryInfoA)(HINTERNET hRequest, DWORD infoLevel, PVOID buffer, DWORD* bufferLength, DWORD* index);
|
||||||
INETAPI BOOL WINAPI HttpAddRequestHeadersA(HINTERNET hRequest, PCSTR headers, DWORD headersLength, DWORD modifiers);
|
static BOOL (WINAPI *_HttpAddRequestHeadersA)(HINTERNET hRequest, PCSTR headers, DWORD headersLength, DWORD modifiers);
|
||||||
INETAPI HINTERNET WINAPI HttpOpenRequestA(HINTERNET hConnect, PCSTR verb, PCSTR objectName, PCSTR version, PCSTR referrer, PCSTR* acceptTypes, DWORD flags, DWORD_PTR context);
|
static HINTERNET (WINAPI *_HttpOpenRequestA)(HINTERNET hConnect, PCSTR verb, PCSTR objectName, PCSTR version, PCSTR referrer, PCSTR* acceptTypes, DWORD flags, DWORD_PTR context);
|
||||||
INETAPI BOOL WINAPI HttpSendRequestA(HINTERNET hRequest, PCSTR headers, DWORD headersLength, PVOID optional, DWORD optionalLength);
|
static BOOL (WINAPI *_HttpSendRequestA)(HINTERNET hRequest, PCSTR headers, DWORD headersLength, PVOID optional, DWORD optionalLength);
|
||||||
/* === END wininet.h === */
|
/* === END wininet.h === */
|
||||||
|
|
||||||
/* caches connections to web servers */
|
/* caches connections to web servers */
|
||||||
@ -498,7 +499,7 @@ static void HttpCache_MakeEntry(const cc_string* url, struct HttpCacheEntry* ent
|
|||||||
/* Inserts entry into the cache at the given index */
|
/* Inserts entry into the cache at the given index */
|
||||||
static cc_result HttpCache_Insert(int i, struct HttpCacheEntry* e) {
|
static cc_result HttpCache_Insert(int i, struct HttpCacheEntry* e) {
|
||||||
HINTERNET conn;
|
HINTERNET conn;
|
||||||
conn = InternetConnectA(hInternet, e->Address.buffer, e->Port, NULL, NULL,
|
conn = _InternetConnectA(hInternet, e->Address.buffer, e->Port, NULL, NULL,
|
||||||
INTERNET_SERVICE_HTTP, e->Https ? INTERNET_FLAG_SECURE : 0, 0);
|
INTERNET_SERVICE_HTTP, e->Https ? INTERNET_FLAG_SECURE : 0, 0);
|
||||||
if (!conn) return GetLastError();
|
if (!conn) return GetLastError();
|
||||||
|
|
||||||
@ -530,17 +531,31 @@ static cc_result HttpCache_Lookup(struct HttpCacheEntry* e) {
|
|||||||
|
|
||||||
/* TODO: Should we be consistent in which entry gets evicted? */
|
/* TODO: Should we be consistent in which entry gets evicted? */
|
||||||
i = (cc_uint8)Stopwatch_Measure() % HTTP_CACHE_ENTRIES;
|
i = (cc_uint8)Stopwatch_Measure() % HTTP_CACHE_ENTRIES;
|
||||||
InternetCloseHandle(http_cache[i].Handle);
|
_InternetCloseHandle(http_cache[i].Handle);
|
||||||
return HttpCache_Insert(i, e);
|
return HttpCache_Insert(i, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void* wininet_lib;
|
||||||
cc_bool Http_DescribeError(cc_result res, cc_string* dst) {
|
cc_bool Http_DescribeError(cc_result res, cc_string* dst) {
|
||||||
return Platform_DescribeErrorExt(res, dst, "wininet.dll");
|
return Platform_DescribeErrorExt(res, dst, wininet_lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HttpBackend_Init(void) {
|
static void HttpBackend_Init(void) {
|
||||||
|
static const struct DynamicLibSym funcs[] = {
|
||||||
|
DynamicLib_Sym(InternetCloseHandle),
|
||||||
|
DynamicLib_Sym(InternetConnectA), DynamicLib_Sym(InternetOpenA),
|
||||||
|
DynamicLib_Sym(InternetSetOptionA), DynamicLib_Sym(InternetQueryOptionA),
|
||||||
|
DynamicLib_Sym(InternetReadFile), DynamicLib_Sym(InternetQueryDataAvailable),
|
||||||
|
DynamicLib_Sym(HttpOpenRequestA), DynamicLib_Sym(HttpSendRequestA),
|
||||||
|
DynamicLib_Sym(HttpQueryInfoA), DynamicLib_Sym(HttpAddRequestHeadersA)
|
||||||
|
|
||||||
|
};
|
||||||
|
static const cc_string wininet = String_FromConst("wininet.dll");
|
||||||
|
DynamicLib_LoadAll(&wininet, funcs, Array_Elems(funcs), &wininet_lib);
|
||||||
|
if (!wininet_lib) return;
|
||||||
|
|
||||||
/* TODO: Should we use INTERNET_OPEN_TYPE_PRECONFIG instead? */
|
/* TODO: Should we use INTERNET_OPEN_TYPE_PRECONFIG instead? */
|
||||||
hInternet = InternetOpenA(GAME_APP_NAME, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
hInternet = _InternetOpenA(GAME_APP_NAME, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
||||||
if (!hInternet) Logger_Abort2(GetLastError(), "Failed to init WinINet");
|
if (!hInternet) Logger_Abort2(GetLastError(), "Failed to init WinINet");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,7 +564,7 @@ static void Http_AddHeader(struct HttpRequest* req, const char* key, const cc_st
|
|||||||
String_InitArray(tmp, tmpBuffer);
|
String_InitArray(tmp, tmpBuffer);
|
||||||
|
|
||||||
String_Format2(&tmp, "%c: %s\r\n", key, value);
|
String_Format2(&tmp, "%c: %s\r\n", key, value);
|
||||||
HttpAddRequestHeadersA((HINTERNET)req->meta, tmp.buffer, tmp.length,
|
_HttpAddRequestHeadersA((HINTERNET)req->meta, tmp.buffer, tmp.length,
|
||||||
HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
|
HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,31 +580,33 @@ static cc_result Http_StartRequest(struct HttpRequest* req, cc_string* url) {
|
|||||||
String_InitArray_NT(path, pathBuffer);
|
String_InitArray_NT(path, pathBuffer);
|
||||||
HttpCache_MakeEntry(url, &entry, &path);
|
HttpCache_MakeEntry(url, &entry, &path);
|
||||||
pathBuffer[path.length] = '\0';
|
pathBuffer[path.length] = '\0';
|
||||||
|
|
||||||
|
if (!wininet_lib) return ERR_NOT_SUPPORTED;
|
||||||
if ((res = HttpCache_Lookup(&entry))) return res;
|
if ((res = HttpCache_Lookup(&entry))) return res;
|
||||||
|
|
||||||
flags = INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_COOKIES;
|
flags = INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_COOKIES;
|
||||||
if (entry.Https) flags |= INTERNET_FLAG_SECURE;
|
if (entry.Https) flags |= INTERNET_FLAG_SECURE;
|
||||||
|
|
||||||
handle = HttpOpenRequestA(entry.Handle, verbs[req->requestType], pathBuffer, NULL, NULL, NULL, flags, 0);
|
handle = _HttpOpenRequestA(entry.Handle, verbs[req->requestType], pathBuffer, NULL, NULL, NULL, flags, 0);
|
||||||
/* Fallback for Windows 95 which returns ERROR_INVALID_PARAMETER */
|
/* Fallback for Windows 95 which returns ERROR_INVALID_PARAMETER */
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
flags &= ~INTERNET_FLAG_NO_UI; /* INTERNET_FLAG_NO_UI unsupported on Windows 95 */
|
flags &= ~INTERNET_FLAG_NO_UI; /* INTERNET_FLAG_NO_UI unsupported on Windows 95 */
|
||||||
handle = HttpOpenRequestA(entry.Handle, verbs[req->requestType], pathBuffer, NULL, NULL, NULL, flags, 0);
|
handle = _HttpOpenRequestA(entry.Handle, verbs[req->requestType], pathBuffer, NULL, NULL, NULL, flags, 0);
|
||||||
if (!handle) return GetLastError();
|
if (!handle) return GetLastError();
|
||||||
}
|
}
|
||||||
req->meta = handle;
|
req->meta = handle;
|
||||||
|
|
||||||
bufferLen = sizeof(flags);
|
bufferLen = sizeof(flags);
|
||||||
InternetQueryOptionA(handle, INTERNET_OPTION_SECURITY_FLAGS, (void*)&bufferLen, &flags);
|
_InternetQueryOptionA(handle, INTERNET_OPTION_SECURITY_FLAGS, (void*)&bufferLen, &flags);
|
||||||
/* Users have had issues in the past with revocation servers randomly being offline, */
|
/* Users have had issues in the past with revocation servers randomly being offline, */
|
||||||
/* which caused all https:// requests to fail. So just skip revocation check. */
|
/* which caused all https:// requests to fail. So just skip revocation check. */
|
||||||
flags |= SECURITY_FLAG_IGNORE_REVOCATION;
|
flags |= SECURITY_FLAG_IGNORE_REVOCATION;
|
||||||
|
|
||||||
if (!httpsVerify) flags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
|
if (!httpsVerify) flags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
|
||||||
InternetSetOptionA(handle, INTERNET_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
|
_InternetSetOptionA(handle, INTERNET_OPTION_SECURITY_FLAGS, &flags, sizeof(flags));
|
||||||
|
|
||||||
Http_SetRequestHeaders(req);
|
Http_SetRequestHeaders(req);
|
||||||
return HttpSendRequestA(handle, NULL, 0, req->data, req->size) ? 0 : GetLastError();
|
return _HttpSendRequestA(handle, NULL, 0, req->data, req->size) ? 0 : GetLastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Gets headers from a HTTP response */
|
/* Gets headers from a HTTP response */
|
||||||
@ -597,7 +614,7 @@ static cc_result Http_ProcessHeaders(struct HttpRequest* req, HINTERNET handle)
|
|||||||
cc_string left, line;
|
cc_string left, line;
|
||||||
char buffer[8192];
|
char buffer[8192];
|
||||||
DWORD len = 8192;
|
DWORD len = 8192;
|
||||||
if (!HttpQueryInfoA(handle, HTTP_QUERY_RAW_HEADERS, buffer, &len, NULL)) return GetLastError();
|
if (!_HttpQueryInfoA(handle, HTTP_QUERY_RAW_HEADERS, buffer, &len, NULL)) return GetLastError();
|
||||||
|
|
||||||
left = String_Init(buffer, len, len);
|
left = String_Init(buffer, len, len);
|
||||||
while (left.length) {
|
while (left.length) {
|
||||||
@ -613,11 +630,11 @@ static cc_result Http_DownloadData(struct HttpRequest* req, HINTERNET handle) {
|
|||||||
Http_BufferInit(req);
|
Http_BufferInit(req);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!InternetQueryDataAvailable(handle, &avail, 0, 0)) return GetLastError();
|
if (!_InternetQueryDataAvailable(handle, &avail, 0, 0)) return GetLastError();
|
||||||
if (!avail) break;
|
if (!avail) break;
|
||||||
Http_BufferEnsure(req, avail);
|
Http_BufferEnsure(req, avail);
|
||||||
|
|
||||||
if (!InternetReadFile(handle, &req->data[req->size], avail, &read)) return GetLastError();
|
if (!_InternetReadFile(handle, &req->data[req->size], avail, &read)) return GetLastError();
|
||||||
if (!read) break;
|
if (!read) break;
|
||||||
Http_BufferExpanded(req, read);
|
Http_BufferExpanded(req, read);
|
||||||
}
|
}
|
||||||
@ -635,14 +652,14 @@ static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* url) {
|
|||||||
handle = req->meta;
|
handle = req->meta;
|
||||||
http_curProgress = HTTP_PROGRESS_FETCHING_DATA;
|
http_curProgress = HTTP_PROGRESS_FETCHING_DATA;
|
||||||
res = Http_ProcessHeaders(req, handle);
|
res = Http_ProcessHeaders(req, handle);
|
||||||
if (res) { InternetCloseHandle(handle); return res; }
|
if (res) { _InternetCloseHandle(handle); return res; }
|
||||||
|
|
||||||
if (req->requestType != REQUEST_TYPE_HEAD) {
|
if (req->requestType != REQUEST_TYPE_HEAD) {
|
||||||
res = Http_DownloadData(req, handle);
|
res = Http_DownloadData(req, handle);
|
||||||
if (res) { InternetCloseHandle(handle); return res; }
|
if (res) { _InternetCloseHandle(handle); return res; }
|
||||||
}
|
}
|
||||||
|
|
||||||
return InternetCloseHandle(handle) ? 0 : GetLastError();
|
return _InternetCloseHandle(handle) ? 0 : GetLastError();
|
||||||
}
|
}
|
||||||
#elif defined CC_BUILD_ANDROID
|
#elif defined CC_BUILD_ANDROID
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
|
@ -37,7 +37,7 @@ extern const cc_result ReturnCode_DirectoryExists;
|
|||||||
int Platform_EncodeUtf16(void* data, const cc_string* src);
|
int Platform_EncodeUtf16(void* data, const cc_string* src);
|
||||||
/* Converts a null terminated WCHAR* to char* in-place */
|
/* Converts a null terminated WCHAR* to char* in-place */
|
||||||
void Platform_Utf16ToAnsi(void* data);
|
void Platform_Utf16ToAnsi(void* data);
|
||||||
cc_bool Platform_DescribeErrorExt(cc_result res, cc_string* dst, const char* file);
|
cc_bool Platform_DescribeErrorExt(cc_result res, cc_string* dst, void* lib);
|
||||||
#else
|
#else
|
||||||
/* Encodes a string in UTF8 format, also null terminating the string. */
|
/* Encodes a string in UTF8 format, also null terminating the string. */
|
||||||
/* Returns the number of bytes written, excluding trailing NULL terminator. */
|
/* Returns the number of bytes written, excluding trailing NULL terminator. */
|
||||||
|
@ -360,10 +360,12 @@ void Platform_LoadSysFonts(void) {
|
|||||||
char winFolder[FILENAME_SIZE];
|
char winFolder[FILENAME_SIZE];
|
||||||
WCHAR winTmp[FILENAME_SIZE];
|
WCHAR winTmp[FILENAME_SIZE];
|
||||||
UINT winLen;
|
UINT winLen;
|
||||||
/* System folder path may not be C:/Windows */
|
|
||||||
cc_string dirs[1];
|
|
||||||
String_InitArray(dirs[0], winFolder);
|
|
||||||
|
|
||||||
|
cc_string dirs[2];
|
||||||
|
String_InitArray(dirs[0], winFolder);
|
||||||
|
dirs[1] = String_FromReadonly("C:/WINNT35/system");
|
||||||
|
|
||||||
|
/* System folder path may not be C:/Windows */
|
||||||
winLen = GetWindowsDirectoryW(winTmp, FILENAME_SIZE);
|
winLen = GetWindowsDirectoryW(winTmp, FILENAME_SIZE);
|
||||||
if (winLen) {
|
if (winLen) {
|
||||||
String_AppendUtf16(&dirs[0], winTmp, winLen * 2);
|
String_AppendUtf16(&dirs[0], winTmp, winLen * 2);
|
||||||
@ -815,12 +817,9 @@ void Platform_Free(void) {
|
|||||||
HeapDestroy(heap);
|
HeapDestroy(heap);
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_bool Platform_DescribeErrorExt(cc_result res, cc_string* dst, const char* file) {
|
cc_bool Platform_DescribeErrorExt(cc_result res, cc_string* dst, void* lib) {
|
||||||
WCHAR chars[NATIVE_STR_LEN];
|
WCHAR chars[NATIVE_STR_LEN];
|
||||||
DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
|
DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
|
||||||
void* lib = NULL;
|
|
||||||
|
|
||||||
if (file) lib = GetModuleHandleA(file);
|
|
||||||
if (lib) flags |= FORMAT_MESSAGE_FROM_HMODULE;
|
if (lib) flags |= FORMAT_MESSAGE_FROM_HMODULE;
|
||||||
|
|
||||||
res = FormatMessageW(flags, lib, res, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
res = FormatMessageW(flags, lib, res, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user