Index: branches/egtra/ab5.0/abdev/OldWindowsHelperImpl.cpp
===================================================================
--- branches/egtra/ab5.0/abdev/OldWindowsHelperImpl.cpp	(revision 798)
+++ branches/egtra/ab5.0/abdev/OldWindowsHelperImpl.cpp	(revision 800)
@@ -1,9 +1,27 @@
 #include "stdafx.h"
+#include <cstdint>
+#include <process.h>
 #include "OSVersion.h"
 
-static HMODULE hmodKernel;
+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 void* TrapTableLast;
+} // extern "C"
 
-static HMODULE GetKernelModule()
+namespace {
+
+HMODULE GetKernelModule()
 {
+	static HMODULE hmodKernel;
 	if (hmodKernel == nullptr)
 	{
@@ -13,169 +31,110 @@
 }
 
-#define KERNEL32 (GetKernelModule())
+BOOL WINAPI Alternative_IsDebuggerPresent()
+{
+	::SetLastError(ERROR_NOT_SUPPORTED);
+	return FALSE;
+}
 
-#define GET_PROC_ADDRESS(hmod, functionName) reinterpret_cast<decltype(functionName)*>(GetProcAddress((hmod), #functionName))
+void* WINAPI Alternative_EncodePointer(void* p)
+{
+	return reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(p) ^ __security_cookie);
+}
 
-#define DECLARE_REAL_HOLDER(name) static decltype(name)* name ## _Real
+#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 __stdcall 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;
+}
+
+#define FUNCTION_INIT(name) \
+	if (auto f = ::GetProcAddress(GetKernelModule(), #name)) { \
+		alias__imp__ ## name = f; \
+	} else { \
+		alias__imp__ ## name = reinterpret_cast<FARPROC>(Alternative_ ## name); \
+	}
+
+void InitializeOldWindowsHelper()
+{
+	DWORD oldProtect;
+	::VirtualProtect(&TrapTableFirst,
+		reinterpret_cast<std::uintptr_t>(&TrapTableLast) - reinterpret_cast<std::uintptr_t>(&TrapTableFirst),
+		PAGE_READWRITE, &oldProtect);
+	FUNCTION_INIT(IsDebuggerPresent);
+	FUNCTION_INIT(EncodePointer);
+	FUNCTION_INIT(DecodePointer);
+	FUNCTION_INIT(HeapSetInformation);
+	alias__imp__InitializeCriticalSectionAndSpinCount = 
+		ActiveBasic::Common::Is9x()
+		? reinterpret_cast<FARPROC>(Alternative_InitializeCriticalSectionAndSpinCount)
+		: ::GetProcAddress(GetKernelModule(), "InitializeCriticalSectionAndSpinCount");
+	FUNCTION_INIT(InterlockedCompareExchange);
+	FUNCTION_INIT(IsProcessorFeaturePresent);
+	alias__imp__InterlockedPushEntrySList = ::GetProcAddress(GetKernelModule(), "InterlockedPushEntrySList");
+	alias__imp__InterlockedPopEntrySList = ::GetProcAddress(GetKernelModule(), "InterlockedPopEntrySList");
+
+	::VirtualProtect(&TrapTableFirst,
+		reinterpret_cast<std::uintptr_t>(&TrapTableLast) - reinterpret_cast<std::uintptr_t>(&TrapTableFirst),
+		PAGE_READONLY, &oldProtect);
+}
+
+} // unnamed namespace
 
 extern "C"
 {
-	BOOL WINAPI IsDebuggerPresent_Helper()
+#ifdef _UNICODE
+int wWinMainCRTStartup();
+#define tWinMainCRTStartup wWinMainCRTStartup
+#else
+int WinMainCRTStartup();
+#define tWinMainCRTStartup WinMainCRTStartup
+#endif
+
+void WinMainStartup_OldWindowsHelper()
+{
+	__security_init_cookie();
+
+	InitializeOldWindowsHelper();
+
+	__asm
 	{
-		DECLARE_REAL_HOLDER(IsDebuggerPresent);
-		static bool initialized;
-		if (!initialized)
-		{
-			auto IsDebuggerPresent_Real = GET_PROC_ADDRESS(KERNEL32, IsDebuggerPresent);
-			initialized = true;
-		}
-
-		if (IsDebuggerPresent_Real != nullptr)
-		{
-			return IsDebuggerPresent_Real();
-		}
-		else
-		{
-			return FALSE;
-		}
-	}
-
-	void* WINAPI EncodePointer_Helper(void* p)
-	{
-		DECLARE_REAL_HOLDER(EncodePointer);
-		static bool initialized;
-		if (!initialized)
-		{
-			auto EncodePointer_Real = GET_PROC_ADDRESS(KERNEL32, EncodePointer);
-			initialized = true;
-		}
-
-		if (EncodePointer_Real != nullptr)
-		{
-			return EncodePointer_Real(p);
-		}
-		else
-		{
-			return reinterpret_cast<void*>(reinterpret_cast<DWORD>(p) ^ GetCurrentProcessId());
-		}
-	}
-
-	void* WINAPI DecodePointer_Helper(void* p)
-	{
-		DECLARE_REAL_HOLDER(DecodePointer);
-		static bool initialized;
-		if (!initialized)
-		{
-			auto DecodePointer_Real = GET_PROC_ADDRESS(KERNEL32, DecodePointer);
-			initialized = true;
-		}
-
-		if (DecodePointer_Real != nullptr)
-		{
-			return DecodePointer_Real(p);
-		}
-		else
-		{
-			return reinterpret_cast<void*>(reinterpret_cast<DWORD>(p) ^ GetCurrentProcessId());
-		}
-	}
-
-	BOOL WINAPI IsProcessorFeaturePresent_Helper(DWORD feture)
-	{
-		DECLARE_REAL_HOLDER(IsProcessorFeaturePresent);
-		static bool initialized;
-		if (!initialized)
-		{
-			IsProcessorFeaturePresent_Real = GET_PROC_ADDRESS(KERNEL32, IsProcessorFeaturePresent);
-			initialized = true;
-		}
-
-		if (IsProcessorFeaturePresent_Real != nullptr)
-		{
-			return IsProcessorFeaturePresent_Real(feture);
-		}
-		else
-		{
-			assert(feture == PF_NX_ENABLED); // ATLから呼ばれる
-			return FALSE;
-		}
-	}
-
-	BOOL WINAPI HeapSetInformation_Helper(HANDLE hHeap, HEAP_INFORMATION_CLASS hic, void* information, SSIZE_T informationLength)
-	{
-		DECLARE_REAL_HOLDER(HeapSetInformation);
-		static bool initialized;
-		if (!initialized)
-		{
-			HeapSetInformation_Real = GET_PROC_ADDRESS(KERNEL32, HeapSetInformation);
-			initialized = true;
-		}
-
-		if (HeapSetInformation_Real != nullptr)
-		{
-			return HeapSetInformation_Real(hHeap, hic, information, informationLength);
-		}
-		else
-		{
-			return TRUE;
-		}
-	}
-
-	BOOL WINAPI InitializeCriticalSectionAndSpinCount_Helper(LPCRITICAL_SECTION lpcs, DWORD spinCount)
-	{
-		DECLARE_REAL_HOLDER(InitializeCriticalSectionAndSpinCount);
-		static bool initialized;
-		if (!initialized)
-		{
-			InitializeCriticalSectionAndSpinCount_Real = GET_PROC_ADDRESS(KERNEL32, InitializeCriticalSectionAndSpinCount);
-			initialized = true;
-		}
-
-		__try
-		{
-			if (InitializeCriticalSectionAndSpinCount_Real != nullptr)
-			{
-				BOOL ret = InitializeCriticalSectionAndSpinCount_Real(lpcs, spinCount);
-				return ActiveBasic::Common::Is9x()
-					? TRUE
-					: ret;
-			}
-			else
-			{
-				::InitializeCriticalSection(lpcs);
-				return TRUE;
-			}
-		}
-		__except(EXCEPTION_EXECUTE_HANDLER)
-		{
-		}
-		return FALSE;
-	}
-
-	// Interlocked(Push|Pop)EntrySListは、NXが有効な場合のみ呼ばれる。
-	// Windows XP以前はNX対応していないためInterlocked(Push|Pop)EntrySListが呼ばれることはない。
-	// そのため、GET_PROC_ADDRESSがnullptrを返すことはないと仮定している。
-	// なお、Interlocked(Push|Pop)EntrySListもWindows XPから搭載されている。
-
-	PSLIST_ENTRY WINAPI InterlockedPushEntrySList_Helper(PSLIST_HEADER head, PSLIST_ENTRY entry)
-	{
-		DECLARE_REAL_HOLDER(InterlockedPushEntrySList);
-		if (InterlockedPushEntrySList_Real == nullptr)
-		{
-			 InterlockedPushEntrySList_Real = GET_PROC_ADDRESS(KERNEL32, InterlockedPushEntrySList);
-		}
-		assert(InterlockedPushEntrySList_Real != nullptr);
-		return InterlockedPushEntrySList_Real(head, entry);
-	}
-
-	PSLIST_ENTRY WINAPI InterlockedPopEntrySList_Helper(PSLIST_HEADER head)
-	{
-		DECLARE_REAL_HOLDER(InterlockedPopEntrySList);
-		if (InterlockedPopEntrySList_Real == nullptr)
-		{
-			 InterlockedPopEntrySList_Real = GET_PROC_ADDRESS(KERNEL32, InterlockedPopEntrySList);
-		}
-		assert(InterlockedPopEntrySList_Real != nullptr);
-		return InterlockedPopEntrySList_Real(head);
+		jmp	tWinMainCRTStartup;
 	}
 }
+
+} // extern "C"
