diff --git a/misc/windows/min-imagehlp.h b/misc/windows/min-imagehlp.h index 07a812074..5d9ca76a6 100644 --- a/misc/windows/min-imagehlp.h +++ b/misc/windows/min-imagehlp.h @@ -1,17 +1,21 @@ +#ifndef CC_IMAGEHLP_FUNC +#define CC_IMAGEHLP_FUNC +#endif + /*Not available on older SDKs */ typedef cc_uintptr _DWORD_PTR; -static _DWORD_PTR (WINAPI *_SymGetModuleBase)(HANDLE process, _DWORD_PTR addr); -static PVOID (WINAPI *_SymFunctionTableAccess)(HANDLE process, _DWORD_PTR addr); -static BOOL (WINAPI *_SymInitialize)(HANDLE process, PCSTR userSearchPath, BOOL fInvadeProcess); +CC_IMAGEHLP_FUNC _DWORD_PTR (WINAPI *_SymGetModuleBase)(HANDLE process, _DWORD_PTR addr); +CC_IMAGEHLP_FUNC PVOID (WINAPI *_SymFunctionTableAccess)(HANDLE process, _DWORD_PTR addr); +CC_IMAGEHLP_FUNC BOOL (WINAPI *_SymInitialize)(HANDLE process, PCSTR userSearchPath, BOOL fInvadeProcess); -static BOOL (WINAPI *_SymGetSymFromAddr)(HANDLE process, _DWORD_PTR addr, _DWORD_PTR* displacement, IMAGEHLP_SYMBOL* sym); -static BOOL (WINAPI *_SymGetModuleInfo) (HANDLE process, _DWORD_PTR addr, IMAGEHLP_MODULE* module); -static BOOL (WINAPI *_SymGetLineFromAddr)(HANDLE hProcess, _DWORD_PTR addr, DWORD* displacement, IMAGEHLP_LINE* line); /* displacement is intentionally DWORD */ +CC_IMAGEHLP_FUNC BOOL (WINAPI *_SymGetSymFromAddr)(HANDLE process, _DWORD_PTR addr, _DWORD_PTR* displacement, IMAGEHLP_SYMBOL* sym); +CC_IMAGEHLP_FUNC BOOL (WINAPI *_SymGetModuleInfo) (HANDLE process, _DWORD_PTR addr, IMAGEHLP_MODULE* module); +CC_IMAGEHLP_FUNC BOOL (WINAPI *_SymGetLineFromAddr)(HANDLE hProcess, _DWORD_PTR addr, DWORD* displacement, IMAGEHLP_LINE* line); /* displacement is intentionally DWORD */ -static BOOL (WINAPI *_EnumerateLoadedModules)(HANDLE process, PENUMLOADED_MODULES_CALLBACK callback, PVOID userContext); +CC_IMAGEHLP_FUNC BOOL (WINAPI *_EnumerateLoadedModules)(HANDLE process, PENUMLOADED_MODULES_CALLBACK callback, PVOID userContext); -static BOOL (WINAPI *_StackWalk)(DWORD machineType, HANDLE process, HANDLE thread, STACKFRAME* stackFrame, PVOID contextRecord, +CC_IMAGEHLP_FUNC BOOL (WINAPI *_StackWalk)(DWORD machineType, HANDLE process, HANDLE thread, STACKFRAME* stackFrame, PVOID contextRecord, PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE TranslateAddress); diff --git a/misc/windows/min-kernel32.h b/misc/windows/min-kernel32.h new file mode 100644 index 000000000..a5559cb45 --- /dev/null +++ b/misc/windows/min-kernel32.h @@ -0,0 +1,31 @@ +#ifndef CC_KERN32_FUNC +#define CC_KERN32_FUNC +#endif + +CC_KERN32_FUNC void (WINAPI *_GetSystemTimeAsFileTime)(LPFILETIME sysTime); +/* Fallback support for NT 3.5 */ +static void WINAPI Fallback_GetSystemTimeAsFileTime(LPFILETIME sysTime) { + SYSTEMTIME curTime; + GetSystemTime(&curTime); + SystemTimeToFileTime(&curTime, sysTime); +} + +CC_KERN32_FUNC BOOL (WINAPI *_AttachConsole)(DWORD processId); +CC_KERN32_FUNC BOOL (WINAPI *_IsDebuggerPresent)(void); +CC_KERN32_FUNC void (NTAPI *_RtlCaptureContext)(CONTEXT* ContextRecord); + + +static void Kernel32_LoadDynamicFuncs(void) { + static const struct DynamicLibSym funcs[] = { + DynamicLib_Sym(AttachConsole), + DynamicLib_Sym(IsDebuggerPresent), + DynamicLib_Sym(GetSystemTimeAsFileTime), + DynamicLib_Sym(RtlCaptureContext) + }; + + static const cc_string kernel32 = String_FromConst("KERNEL32.DLL"); + void* lib; + DynamicLib_LoadAll(&kernel32, funcs, Array_Elems(funcs), &lib); + /* Not present on Windows NT 3.5 */ + if (!_GetSystemTimeAsFileTime) _GetSystemTimeAsFileTime = Fallback_GetSystemTimeAsFileTime; +} \ No newline at end of file diff --git a/misc/windows/min-schannel.h b/misc/windows/min-schannel.h new file mode 100644 index 000000000..8201e0c1d --- /dev/null +++ b/misc/windows/min-schannel.h @@ -0,0 +1,58 @@ +typedef void* HCERTSTORE; + +typedef struct _CERT_CONTEXT { + DWORD dwCertEncodingType; + BYTE* pbCertEncoded; + DWORD cbCertEncoded; + CERT_INFO* pCertInfo; + HCERTSTORE hCertStore; +} CERT_CONTEXT, *PCERT_CONTEXT; + + +#define UNISP_NAME_A "Microsoft Unified Security Protocol Provider" +#define UNISP_NAME_W L"Microsoft Unified Security Protocol Provider" + +#define SCH_CRED_NO_SYSTEM_MAPPER 0x00000002 +#define SCH_CRED_NO_SERVERNAME_CHECK 0x00000004 +#define SCH_CRED_MANUAL_CRED_VALIDATION 0x00000008 +#define SCH_CRED_NO_DEFAULT_CREDS 0x00000010 +#define SCH_CRED_AUTO_CRED_VALIDATION 0x00000020 +#define SCH_CRED_USE_DEFAULT_CREDS 0x00000040 +#define SCH_CRED_DISABLE_RECONNECTS 0x00000080 + +#define SCH_CRED_REVOCATION_CHECK_END_CERT 0x00000100 +#define SCH_CRED_REVOCATION_CHECK_CHAIN 0x00000200 +#define SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT 0x00000400 +#define SCH_CRED_IGNORE_NO_REVOCATION_CHECK 0x00000800 +#define SCH_CRED_IGNORE_REVOCATION_OFFLINE 0x00001000 +#define SCH_CRED_REVOCATION_CHECK_CACHE_ONLY 0x00004000 + +#define SP_PROT_SSL3_CLIENT 0x00000020 +#define SP_PROT_TLS1_CLIENT 0x00000080 +#define SP_PROT_TLS1_1_CLIENT 0x00000200 +#define SP_PROT_TLS1_2_CLIENT 0x00000800 + + +#define SCH_CRED_V1 0x00000001 +#define SCH_CRED_V2 0x00000002 +#define SCH_CRED_VERSION 0x00000002 +#define SCH_CRED_V3 0x00000003 +#define SCHANNEL_CRED_VERSION 0x00000004 + +struct _HMAPPER; +typedef struct _SCHANNEL_CRED { + DWORD dwVersion; + DWORD cCreds; + PCCERT_CONTEXT* paCred; + HCERTSTORE hRootStore; + DWORD cMappers; + struct _HMAPPER **aphMappers; + DWORD cSupportedAlgs; + ALG_ID* palgSupportedAlgs; + DWORD grbitEnabledProtocols; + DWORD dwMinimumCipherStrength; + DWORD dwMaximumCipherStrength; + DWORD dwSessionLifespan; + DWORD dwFlags; + DWORD dwCredFormat; +} SCHANNEL_CRED; \ No newline at end of file diff --git a/misc/windows/min-wincrypt.h b/misc/windows/min-wincrypt.h index f7f54d8c7..50ae350b0 100644 --- a/misc/windows/min-wincrypt.h +++ b/misc/windows/min-wincrypt.h @@ -1,10 +1,14 @@ +#ifndef CC_CRYPT32_FUNC +#define CC_CRYPT32_FUNC +#endif + typedef struct _CRYPTOAPI_BLOB { DWORD cbData; BYTE* pbData; } DATA_BLOB; -static BOOL (WINAPI *_CryptProtectData )(DATA_BLOB* dataIn, PCWSTR dataDescr, PVOID entropy, PVOID reserved, PVOID promptStruct, DWORD flags, DATA_BLOB* dataOut); -static BOOL (WINAPI *_CryptUnprotectData)(DATA_BLOB* dataIn, PWSTR* dataDescr, PVOID entropy, PVOID reserved, PVOID promptStruct, DWORD flags, DATA_BLOB* dataOut); +CC_CRYPT32_FUNC BOOL (WINAPI *_CryptProtectData )(DATA_BLOB* dataIn, PCWSTR dataDescr, PVOID entropy, PVOID reserved, PVOID promptStruct, DWORD flags, DATA_BLOB* dataOut); +CC_CRYPT32_FUNC BOOL (WINAPI *_CryptUnprotectData)(DATA_BLOB* dataIn, PWSTR* dataDescr, PVOID entropy, PVOID reserved, PVOID promptStruct, DWORD flags, DATA_BLOB* dataOut); static void Crypt32_LoadDynamicFuncs(void) { static const struct DynamicLibSym funcs[] = { diff --git a/misc/windows/min-winsock2.h b/misc/windows/min-winsock2.h index 528fc8e55..cb3d2427e 100644 --- a/misc/windows/min-winsock2.h +++ b/misc/windows/min-winsock2.h @@ -1,3 +1,7 @@ +#ifndef CC_WINSOCK_FUNC +#define CC_WINSOCK_FUNC +#endif + /* Not available on older SDKs */ typedef cc_uintptr _UINT_PTR; @@ -120,26 +124,26 @@ typedef struct WSAData { } WSADATA; /* Function declarations */ -static int (WINAPI *_WSAStartup)(WORD versionRequested, WSADATA* wsaData); -static int (WINAPI *_WSACleanup)(void); -static int (WINAPI *_WSAGetLastError)(void); -static int (WINAPI *_WSAStringToAddressW)(LPWSTR addressString, INT addressFamily, LPVOID protocolInfo, LPVOID address, LPINT addressLength); +CC_WINSOCK_FUNC int (WINAPI *_WSAStartup)(WORD versionRequested, WSADATA* wsaData); +CC_WINSOCK_FUNC int (WINAPI *_WSACleanup)(void); +CC_WINSOCK_FUNC int (WINAPI *_WSAGetLastError)(void); +CC_WINSOCK_FUNC int (WINAPI *_WSAStringToAddressW)(LPWSTR addressString, INT addressFamily, LPVOID protocolInfo, LPVOID address, LPINT addressLength); -static int (WINAPI *_socket)(int af, int type, int protocol); -static int (WINAPI *_closesocket)(SOCKET s); -static int (WINAPI *_connect)(SOCKET s, const struct sockaddr* name, int namelen); -static int (WINAPI *_shutdown)(SOCKET s, int how); +CC_WINSOCK_FUNC int (WINAPI *_socket)(int af, int type, int protocol); +CC_WINSOCK_FUNC int (WINAPI *_closesocket)(SOCKET s); +CC_WINSOCK_FUNC int (WINAPI *_connect)(SOCKET s, const struct sockaddr* name, int namelen); +CC_WINSOCK_FUNC int (WINAPI *_shutdown)(SOCKET s, int how); -static int (WINAPI *_ioctlsocket)(SOCKET s, long cmd, u_long* argp); -static int (WINAPI *_getsockopt)(SOCKET s, int level, int optname, char* optval, int* optlen); -static int (WINAPI *_recv)(SOCKET s, char* buf, int len, int flags); -static int (WINAPI *_send)(SOCKET s, const char FAR * buf, int len, int flags); -static int (WINAPI *_select)(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const struct timeval* timeout); +CC_WINSOCK_FUNC int (WINAPI *_ioctlsocket)(SOCKET s, long cmd, u_long* argp); +CC_WINSOCK_FUNC int (WINAPI *_getsockopt)(SOCKET s, int level, int optname, char* optval, int* optlen); +CC_WINSOCK_FUNC int (WINAPI *_recv)(SOCKET s, char* buf, int len, int flags); +CC_WINSOCK_FUNC int (WINAPI *_send)(SOCKET s, const char FAR * buf, int len, int flags); +CC_WINSOCK_FUNC int (WINAPI *_select)(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const struct timeval* timeout); -static struct hostent* (WINAPI *_gethostbyname)(const char* name); -static unsigned short (WINAPI *_htons)(u_short hostshort); -static int (WINAPI *_getaddrinfo )(PCSTR nodeName, PCSTR serviceName, const ADDRINFOA* hints, ADDRINFOA** result); -static void (WINAPI* _freeaddrinfo)(ADDRINFOA* addrInfo); +CC_WINSOCK_FUNC struct hostent* (WINAPI *_gethostbyname)(const char* name); +CC_WINSOCK_FUNC unsigned short (WINAPI *_htons)(u_short hostshort); +CC_WINSOCK_FUNC int (WINAPI *_getaddrinfo )(PCSTR nodeName, PCSTR serviceName, const ADDRINFOA* hints, ADDRINFOA** result); +CC_WINSOCK_FUNC void (WINAPI* _freeaddrinfo)(ADDRINFOA* addrInfo); static void Winsock_LoadDynamicFuncs(void) { static const struct DynamicLibSym funcs[] = { diff --git a/misc/windows/min-winuser.h b/misc/windows/min-winuser.h index 89beec416..016600c66 100644 --- a/misc/windows/min-winuser.h +++ b/misc/windows/min-winuser.h @@ -1,3 +1,7 @@ +#ifndef CC_USER32_FUNC +#define CC_USER32_FUNC +#endif + /* Not available on older SDKs */ typedef cc_uintptr _SIZE_T; @@ -37,9 +41,9 @@ typedef cc_uintptr _SIZE_T; #endif -static BOOL (WINAPI *_RegisterRawInputDevices)(PCRAWINPUTDEVICE devices, UINT numDevices, UINT size); -static UINT (WINAPI *_GetRawInputData)(HRAWINPUT hRawInput, UINT cmd, void* data, UINT* size, UINT headerSize); -static BOOL (WINAPI* _SetProcessDPIAware)(void); +CC_USER32_FUNC BOOL (WINAPI *_RegisterRawInputDevices)(PCRAWINPUTDEVICE devices, UINT numDevices, UINT size); +CC_USER32_FUNC UINT (WINAPI *_GetRawInputData)(HRAWINPUT hRawInput, UINT cmd, void* data, UINT* size, UINT headerSize); +CC_USER32_FUNC BOOL (WINAPI *_SetProcessDPIAware)(void); static void User32_LoadDynamicFuncs(void) { static const struct DynamicLibSym funcs[] = { diff --git a/readme.md b/readme.md index 8b4b7645b..3e6537bde 100644 --- a/readme.md +++ b/readme.md @@ -124,9 +124,8 @@ I am assuming you used the installer from https://osdn.net/projects/mingw/ ##### Using TCC (Tiny C Compiler) Setting up TCC: 1. Download and extract `tcc-0.9.27-win64-bin.zip` from https://bellard.org/tcc/ -2. In TCC's `lib/kernel32.def`, add missing `RtlCaptureContext` at line 554 (In between `RtlAddFunctionTable` and `RtlDeleteFunctionTable`) -3. Download `winapi-full-for-0.9.27.zip` from https://bellard.org/tcc/ -4. Copy `winapi` folder and `_mingw_dxhelper.h` from `winapi-full-for-0.9.27.zip` into TCC's `include` folder +2. Download `winapi-full-for-0.9.27.zip` from https://bellard.org/tcc/ +3. Copy `winapi` folder and `_mingw_dxhelper.h` from `winapi-full-for-0.9.27.zip` into TCC's `include` folder Compiling with TCC: 1. Navigate to the directory with ClassiCube's source code diff --git a/src/Logger.c b/src/Logger.c index b0ab8db9d..9d1e84c4b 100644 --- a/src/Logger.c +++ b/src/Logger.c @@ -20,6 +20,8 @@ #include /* Compatibility version so compiling works on older Windows SDKs */ #include "../misc/windows/min-imagehlp.h" + #define CC_KERN32_FUNC extern /* main use is Platform_Windows.c */ + #include "../misc/windows/min-kernel32.h" static HANDLE curProcess = CUR_PROCESS_HANDLE; #elif defined CC_BUILD_OPENBSD || defined CC_BUILD_HAIKU || defined CC_BUILD_SERENITY #include @@ -287,12 +289,12 @@ static void DumpFrame(cc_string* trace, void* addr) { *#########################################################################################################################*/ #if defined CC_BUILD_WIN -static PVOID WINAPI FunctionTableAccessCallback(HANDLE process, DWORD_PTR addr) { +static PVOID WINAPI FunctionTableAccessCallback(HANDLE process, _DWORD_PTR addr) { if (!_SymFunctionTableAccess) return NULL; return _SymFunctionTableAccess(process, addr); } -static DWORD_PTR WINAPI GetModuleBaseCallback(HANDLE process, DWORD_PTR addr) { +static _DWORD_PTR WINAPI GetModuleBaseCallback(HANDLE process, _DWORD_PTR addr) { if (!_SymGetModuleBase) return 0; return _SymGetModuleBase(process, addr); } @@ -1202,6 +1204,7 @@ void __attribute__((optimize("O0"))) Logger_Abort2(cc_result result, const char* void Logger_Abort2(cc_result result, const char* raw_msg) { #endif CONTEXT ctx; + CONTEXT* ctx_ptr; #if _M_IX86 && __GNUC__ /* Stack frame layout on x86: */ /* [ebp] is previous frame's EBP */ @@ -1219,14 +1222,16 @@ void Logger_Abort2(cc_result result, const char* raw_msg) { : "eax", "memory" ); ctx.ContextFlags = CONTEXT_CONTROL; + ctx_ptr = &ctx; #else - /* This method is guaranteed to exist on 64 bit windows. */ - /* NOTE: This is missing in 32 bit Windows 2000 however, */ - /* so an alternative is provided for MinGW above so that */ - /* the game can be cross-compiled for Windows 98 / 2000 */ - RtlCaptureContext(&ctx); + /* This method is guaranteed to exist on 64 bit windows. */ + /* NOTE: This is missing in 32 bit Windows 2000 however */ + if (_RtlCaptureContext) { + _RtlCaptureContext(&ctx); + ctx_ptr = &ctx; + } else { ctx_ptr = NULL; } #endif - AbortCommon(result, raw_msg, &ctx); + AbortCommon(result, raw_msg, ctx_ptr); } #else void Logger_Abort2(cc_result result, const char* raw_msg) { @@ -1317,7 +1322,7 @@ static void AbortCommon(cc_result result, const char* raw_msg, void* ctx) { /* However that was not always inlined by the compiler, which resulted in a */ /* useless strackframe being logged - so manually inline Logger_Backtrace call */ Logger_Log(&backtrace); - Logger_Backtrace(&msg, ctx); + if (ctx) Logger_Backtrace(&msg, ctx); DumpMisc(); CloseLogFile(); diff --git a/src/Platform_Windows.c b/src/Platform_Windows.c index 50c14f1e0..a3bbee8c9 100644 --- a/src/Platform_Windows.c +++ b/src/Platform_Windows.c @@ -27,6 +27,7 @@ #include "../misc/windows/min-winsock2.h" #include "../misc/windows/min-shellapi.h" #include "../misc/windows/min-wincrypt.h" +#include "../misc/windows/min-kernel32.h" static HANDLE heap; const cc_result ReturnCode_FileShareViolation = ERROR_SHARING_VIOLATION; @@ -131,14 +132,6 @@ void Platform_Log(const char* msg, int len) { OutputDebugStringA("\n"); } -static void (WINAPI *_GetSystemTimeAsFileTime)(LPFILETIME sysTime); -/* Fallback support for NT 3.5 */ -static void WINAPI Fallback_GetSystemTimeAsFileTime(LPFILETIME sysTime) { - SYSTEMTIME curTime; - GetSystemTime(&curTime); - SystemTimeToFileTime(&curTime, sysTime); -} - #define FILETIME_EPOCH 50491123200ULL #define FILETIME_UNIX_EPOCH 11644473600ULL #define FileTime_TotalSecs(time) ((time / 10000000) + FILETIME_EPOCH) @@ -920,38 +913,14 @@ static void Platform_InitStopwatch(void) { } else { sw_freqDiv = 10; } } -static BOOL (WINAPI *_AttachConsole)(DWORD processId); -static BOOL (WINAPI *_IsDebuggerPresent)(void); - -static void LoadKernelFuncs(void) { - static const struct DynamicLibSym funcs[] = { - DynamicLib_Sym(AttachConsole), - DynamicLib_Sym(IsDebuggerPresent), - DynamicLib_Sym(GetSystemTimeAsFileTime), - }; - - static const cc_string kernel32 = String_FromConst("KERNEL32.DLL"); - void* lib; - DynamicLib_LoadAll(&kernel32, funcs, Array_Elems(funcs), &lib); - /* Not present on Windows NT 3.5 */ - if (!_GetSystemTimeAsFileTime) _GetSystemTimeAsFileTime = Fallback_GetSystemTimeAsFileTime; -} - void Platform_Init(void) { WSADATA wsaData; cc_result res; Platform_InitStopwatch(); heap = GetProcessHeap(); + Kernel32_LoadDynamicFuncs(); - Winsock_LoadDynamicFuncs(); - /* Fallback for older OS versions which lack WSAStringToAddressW */ - if (!_WSAStringToAddressW) _WSAStringToAddressW = FallbackParseAddress; - - res = _WSAStartup(MAKEWORD(2, 2), &wsaData); - if (res) Logger_SysWarn(res, "starting WSA"); - - LoadKernelFuncs(); if (_IsDebuggerPresent) hasDebugger = _IsDebuggerPresent(); /* For when user runs from command prompt */ #if CC_WIN_BACKEND != CC_WIN_BACKEND_TERMINAL @@ -960,6 +929,13 @@ void Platform_Init(void) { conHandle = GetStdHandle(STD_OUTPUT_HANDLE); if (conHandle == INVALID_HANDLE_VALUE) conHandle = NULL; + + Winsock_LoadDynamicFuncs(); + /* Fallback for older OS versions which lack WSAStringToAddressW */ + if (!_WSAStringToAddressW) _WSAStringToAddressW = FallbackParseAddress; + + res = _WSAStartup(MAKEWORD(2, 2), &wsaData); + if (res) Logger_SysWarn(res, "starting WSA"); } void Platform_Free(void) {