#include "stdafx.h" #include #include #include #include "OSVersion.h" extern "C" { extern void* TrapTableFirst; extern FARPROC alias__imp__IsDebuggerPresent; extern FARPROC alias__imp__EncodePointer; extern FARPROC alias__imp__DecodePointer; extern FARPROC alias__imp__HeapSetInformation; extern FARPROC alias__imp__InitializeCriticalSectionAndSpinCount; extern FARPROC alias__imp__InterlockedCompareExchange; extern FARPROC alias__imp__IsProcessorFeaturePresent; extern FARPROC alias__imp__InterlockedPushEntrySList; extern FARPROC alias__imp__InterlockedPopEntrySList; extern FARPROC alias__imp__GetModuleHandleW; extern FARPROC alias__imp__GetStartupInfoW; extern FARPROC alias__imp__GetEnvironmentStringsW; extern FARPROC alias__imp__FreeEnvironmentStringsW; extern void* TrapTableLast; } // extern "C" namespace { HMODULE GetKernelModule() { static HMODULE hmodKernel; if (hmodKernel == nullptr) { hmodKernel = GetModuleHandleA("kernel32"); } return hmodKernel; } BOOL WINAPI Alternative_IsDebuggerPresent() { ::SetLastError(ERROR_NOT_SUPPORTED); return FALSE; } void* WINAPI Alternative_EncodePointer(void* p) { return reinterpret_cast(reinterpret_cast(p) ^ __security_cookie); } #define Alternative_DecodePointer Alternative_EncodePointer BOOL WINAPI Alternative_HeapSetInformation(HANDLE hHeap, HEAP_INFORMATION_CLASS hic, void* information, SSIZE_T informationLength) { return TRUE; } #pragma warning(push) #pragma warning(disable: 6320 6322) BOOL WINAPI Alternative_InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpcs, DWORD spinCount) { __try { ::InitializeCriticalSection(lpcs); return TRUE; } __except(EXCEPTION_EXECUTE_HANDLER) { } return FALSE; } #pragma warning(pop) __declspec(naked) long WINAPI Alternative_InterlockedCompareExchange(long volatile*, long, long) { __asm { mov ecx,[esp+4] mov edx,[esp+8] mov eax,[esp+12] lock cmpxchg [ecx],edx ret 12 } } BOOL WINAPI Alternative_IsProcessorFeaturePresent(DWORD /*feture*/) { // ATLからfeture = PF_NX_ENABLEDで呼ばれる return FALSE; } HMODULE WINAPI Alternative_GetModuleHandleW(LPCWSTR moduleName) { HMODULE ret = nullptr; auto size = std::wcslen(moduleName) + 1; auto mbsSize = size * 2; if (auto buffer = static_cast(::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, mbsSize))) { if (::WideCharToMultiByte(CP_ACP, 0, moduleName, static_cast(size), buffer, static_cast(mbsSize), nullptr, nullptr) > 0) { ret = ::GetModuleHandleA(buffer); } ::HeapFree(::GetProcessHeap(), 0, buffer); } return ret; } // CRT用に最小限の実装 void WINAPI Alternative_GetStartupInfoW(LPSTARTUPINFOW psi) { STARTUPINFOA sia; ::GetStartupInfoA(&sia); *psi = STARTUPINFOW(); psi->cb = sizeof *psi; if (sia.dwFlags & STARTF_USESHOWWINDOW) { psi->dwFlags = STARTF_USESHOWWINDOW; psi->wShowWindow = sia.wShowWindow; } } LPWCH WINAPI Alternative_GetEnvironmentStringsW() { static WCHAR c[2]; return c; } BOOL WINAPI Alternative_FreeEnvironmentStringsW(LPWCH) { return TRUE; } #define FUNCTION_INIT(name) \ if (auto f = ::GetProcAddress(GetKernelModule(), #name)) { \ alias__imp__ ## name = f; \ } else { \ alias__imp__ ## name = reinterpret_cast(Alternative_ ## name); \ } #define FUNCTION_INIT_9X(name) \ if (ActiveBasic::Common::Is9x()) { \ alias__imp__ ## name = reinterpret_cast(Alternative_ ## name); \ } else { \ alias__imp__ ## name = ::GetProcAddress(GetKernelModule(), #name); \ } void InitializeOldWindowsHelper() { DWORD oldProtect; ::VirtualProtect(&TrapTableFirst, reinterpret_cast(&TrapTableLast) - reinterpret_cast(&TrapTableFirst), PAGE_READWRITE, &oldProtect); FUNCTION_INIT(IsDebuggerPresent); FUNCTION_INIT(EncodePointer); FUNCTION_INIT(DecodePointer); FUNCTION_INIT(HeapSetInformation); FUNCTION_INIT_9X(InitializeCriticalSectionAndSpinCount); FUNCTION_INIT(InterlockedCompareExchange); FUNCTION_INIT(IsProcessorFeaturePresent); alias__imp__InterlockedPushEntrySList = ::GetProcAddress(GetKernelModule(), "InterlockedPushEntrySList"); alias__imp__InterlockedPopEntrySList = ::GetProcAddress(GetKernelModule(), "InterlockedPopEntrySList"); FUNCTION_INIT_9X(GetModuleHandleW); FUNCTION_INIT_9X(GetStartupInfoW); FUNCTION_INIT_9X(GetEnvironmentStringsW); FUNCTION_INIT_9X(FreeEnvironmentStringsW); ::VirtualProtect(&TrapTableFirst, reinterpret_cast(&TrapTableLast) - reinterpret_cast(&TrapTableFirst), PAGE_READONLY, &oldProtect); } } // unnamed namespace extern "C" { #ifdef _CONSOLE # ifdef _UNICODE int wmainCRTStartup(); # define CRTStartup wmainCRTStartup # else int mainCRTStartup(); # define CRTStartup mainCRTStartup # endif #else # ifdef _UNICODE int wWinMainCRTStartup(); # define CRTStartup wWinMainCRTStartup # else int WinMainCRTStartup(); # define CRTStartup WinMainCRTStartup # endif #endif void Startup_OldWindowsHelper() { __security_init_cookie(); // MessageBox(0, "Startup", "", 0); InitializeOldWindowsHelper(); __asm { jmp CRTStartup; } } } // extern "C"