Changeset 800 in dev for branches/egtra/ab5.0/abdev/OldWindowsHelperImpl.cpp
- Timestamp:
- Feb 6, 2011, 4:35:27 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/egtra/ab5.0/abdev/OldWindowsHelperImpl.cpp
r798 r800 1 1 #include "stdafx.h" 2 #include <cstdint> 3 #include <process.h> 2 4 #include "OSVersion.h" 3 5 4 static HMODULE hmodKernel; 6 extern "C" 7 { 8 extern void* TrapTableFirst; 9 extern FARPROC alias__imp__IsDebuggerPresent; 10 extern FARPROC alias__imp__EncodePointer; 11 extern FARPROC alias__imp__DecodePointer; 12 extern FARPROC alias__imp__HeapSetInformation; 13 extern FARPROC alias__imp__InitializeCriticalSectionAndSpinCount; 14 extern FARPROC alias__imp__InterlockedCompareExchange; 15 extern FARPROC alias__imp__IsProcessorFeaturePresent; 16 extern FARPROC alias__imp__InterlockedPushEntrySList; 17 extern FARPROC alias__imp__InterlockedPopEntrySList; 18 extern void* TrapTableLast; 19 } // extern "C" 5 20 6 static HMODULE GetKernelModule() 21 namespace { 22 23 HMODULE GetKernelModule() 7 24 { 25 static HMODULE hmodKernel; 8 26 if (hmodKernel == nullptr) 9 27 { … … 13 31 } 14 32 15 #define KERNEL32 (GetKernelModule()) 33 BOOL WINAPI Alternative_IsDebuggerPresent() 34 { 35 ::SetLastError(ERROR_NOT_SUPPORTED); 36 return FALSE; 37 } 16 38 17 #define GET_PROC_ADDRESS(hmod, functionName) reinterpret_cast<decltype(functionName)*>(GetProcAddress((hmod), #functionName)) 39 void* WINAPI Alternative_EncodePointer(void* p) 40 { 41 return reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(p) ^ __security_cookie); 42 } 18 43 19 #define DECLARE_REAL_HOLDER(name) static decltype(name)* name ## _Real 44 #define Alternative_DecodePointer Alternative_EncodePointer 45 46 BOOL WINAPI Alternative_HeapSetInformation(HANDLE hHeap, HEAP_INFORMATION_CLASS hic, void* information, SSIZE_T informationLength) 47 { 48 return TRUE; 49 } 50 51 #pragma warning(push) 52 #pragma warning(disable: 6320 6322) 53 BOOL WINAPI Alternative_InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpcs, DWORD spinCount) 54 { 55 __try 56 { 57 ::InitializeCriticalSection(lpcs); 58 return TRUE; 59 } 60 __except(EXCEPTION_EXECUTE_HANDLER) 61 { 62 } 63 return FALSE; 64 } 65 #pragma warning(pop) 66 67 __declspec(naked) long __stdcall Alternative_InterlockedCompareExchange(long volatile*, long, long) 68 { 69 __asm 70 { 71 mov ecx,[esp+4] 72 mov edx,[esp+8] 73 mov eax,[esp+12] 74 lock cmpxchg [ecx],edx 75 ret 12 76 } 77 } 78 79 BOOL WINAPI Alternative_IsProcessorFeaturePresent(DWORD /*feture*/) 80 { 81 // ATLからfeture = PF_NX_ENABLEDで呼ばれる 82 return FALSE; 83 } 84 85 #define FUNCTION_INIT(name) \ 86 if (auto f = ::GetProcAddress(GetKernelModule(), #name)) { \ 87 alias__imp__ ## name = f; \ 88 } else { \ 89 alias__imp__ ## name = reinterpret_cast<FARPROC>(Alternative_ ## name); \ 90 } 91 92 void InitializeOldWindowsHelper() 93 { 94 DWORD oldProtect; 95 ::VirtualProtect(&TrapTableFirst, 96 reinterpret_cast<std::uintptr_t>(&TrapTableLast) - reinterpret_cast<std::uintptr_t>(&TrapTableFirst), 97 PAGE_READWRITE, &oldProtect); 98 FUNCTION_INIT(IsDebuggerPresent); 99 FUNCTION_INIT(EncodePointer); 100 FUNCTION_INIT(DecodePointer); 101 FUNCTION_INIT(HeapSetInformation); 102 alias__imp__InitializeCriticalSectionAndSpinCount = 103 ActiveBasic::Common::Is9x() 104 ? reinterpret_cast<FARPROC>(Alternative_InitializeCriticalSectionAndSpinCount) 105 : ::GetProcAddress(GetKernelModule(), "InitializeCriticalSectionAndSpinCount"); 106 FUNCTION_INIT(InterlockedCompareExchange); 107 FUNCTION_INIT(IsProcessorFeaturePresent); 108 alias__imp__InterlockedPushEntrySList = ::GetProcAddress(GetKernelModule(), "InterlockedPushEntrySList"); 109 alias__imp__InterlockedPopEntrySList = ::GetProcAddress(GetKernelModule(), "InterlockedPopEntrySList"); 110 111 ::VirtualProtect(&TrapTableFirst, 112 reinterpret_cast<std::uintptr_t>(&TrapTableLast) - reinterpret_cast<std::uintptr_t>(&TrapTableFirst), 113 PAGE_READONLY, &oldProtect); 114 } 115 116 } // unnamed namespace 20 117 21 118 extern "C" 22 119 { 23 BOOL WINAPI IsDebuggerPresent_Helper() 120 #ifdef _UNICODE 121 int wWinMainCRTStartup(); 122 #define tWinMainCRTStartup wWinMainCRTStartup 123 #else 124 int WinMainCRTStartup(); 125 #define tWinMainCRTStartup WinMainCRTStartup 126 #endif 127 128 void WinMainStartup_OldWindowsHelper() 129 { 130 __security_init_cookie(); 131 132 InitializeOldWindowsHelper(); 133 134 __asm 24 135 { 25 DECLARE_REAL_HOLDER(IsDebuggerPresent); 26 static bool initialized; 27 if (!initialized) 28 { 29 auto IsDebuggerPresent_Real = GET_PROC_ADDRESS(KERNEL32, IsDebuggerPresent); 30 initialized = true; 31 } 32 33 if (IsDebuggerPresent_Real != nullptr) 34 { 35 return IsDebuggerPresent_Real(); 36 } 37 else 38 { 39 return FALSE; 40 } 41 } 42 43 void* WINAPI EncodePointer_Helper(void* p) 44 { 45 DECLARE_REAL_HOLDER(EncodePointer); 46 static bool initialized; 47 if (!initialized) 48 { 49 auto EncodePointer_Real = GET_PROC_ADDRESS(KERNEL32, EncodePointer); 50 initialized = true; 51 } 52 53 if (EncodePointer_Real != nullptr) 54 { 55 return EncodePointer_Real(p); 56 } 57 else 58 { 59 return reinterpret_cast<void*>(reinterpret_cast<DWORD>(p) ^ GetCurrentProcessId()); 60 } 61 } 62 63 void* WINAPI DecodePointer_Helper(void* p) 64 { 65 DECLARE_REAL_HOLDER(DecodePointer); 66 static bool initialized; 67 if (!initialized) 68 { 69 auto DecodePointer_Real = GET_PROC_ADDRESS(KERNEL32, DecodePointer); 70 initialized = true; 71 } 72 73 if (DecodePointer_Real != nullptr) 74 { 75 return DecodePointer_Real(p); 76 } 77 else 78 { 79 return reinterpret_cast<void*>(reinterpret_cast<DWORD>(p) ^ GetCurrentProcessId()); 80 } 81 } 82 83 BOOL WINAPI IsProcessorFeaturePresent_Helper(DWORD feture) 84 { 85 DECLARE_REAL_HOLDER(IsProcessorFeaturePresent); 86 static bool initialized; 87 if (!initialized) 88 { 89 IsProcessorFeaturePresent_Real = GET_PROC_ADDRESS(KERNEL32, IsProcessorFeaturePresent); 90 initialized = true; 91 } 92 93 if (IsProcessorFeaturePresent_Real != nullptr) 94 { 95 return IsProcessorFeaturePresent_Real(feture); 96 } 97 else 98 { 99 assert(feture == PF_NX_ENABLED); // ATLから呼ばれる 100 return FALSE; 101 } 102 } 103 104 BOOL WINAPI HeapSetInformation_Helper(HANDLE hHeap, HEAP_INFORMATION_CLASS hic, void* information, SSIZE_T informationLength) 105 { 106 DECLARE_REAL_HOLDER(HeapSetInformation); 107 static bool initialized; 108 if (!initialized) 109 { 110 HeapSetInformation_Real = GET_PROC_ADDRESS(KERNEL32, HeapSetInformation); 111 initialized = true; 112 } 113 114 if (HeapSetInformation_Real != nullptr) 115 { 116 return HeapSetInformation_Real(hHeap, hic, information, informationLength); 117 } 118 else 119 { 120 return TRUE; 121 } 122 } 123 124 BOOL WINAPI InitializeCriticalSectionAndSpinCount_Helper(LPCRITICAL_SECTION lpcs, DWORD spinCount) 125 { 126 DECLARE_REAL_HOLDER(InitializeCriticalSectionAndSpinCount); 127 static bool initialized; 128 if (!initialized) 129 { 130 InitializeCriticalSectionAndSpinCount_Real = GET_PROC_ADDRESS(KERNEL32, InitializeCriticalSectionAndSpinCount); 131 initialized = true; 132 } 133 134 __try 135 { 136 if (InitializeCriticalSectionAndSpinCount_Real != nullptr) 137 { 138 BOOL ret = InitializeCriticalSectionAndSpinCount_Real(lpcs, spinCount); 139 return ActiveBasic::Common::Is9x() 140 ? TRUE 141 : ret; 142 } 143 else 144 { 145 ::InitializeCriticalSection(lpcs); 146 return TRUE; 147 } 148 } 149 __except(EXCEPTION_EXECUTE_HANDLER) 150 { 151 } 152 return FALSE; 153 } 154 155 // Interlocked(Push|Pop)EntrySListは、NXが有効な場合のみ呼ばれる。 156 // Windows XP以前はNX対応していないためInterlocked(Push|Pop)EntrySListが呼ばれることはない。 157 // そのため、GET_PROC_ADDRESSがnullptrを返すことはないと仮定している。 158 // なお、Interlocked(Push|Pop)EntrySListもWindows XPから搭載されている。 159 160 PSLIST_ENTRY WINAPI InterlockedPushEntrySList_Helper(PSLIST_HEADER head, PSLIST_ENTRY entry) 161 { 162 DECLARE_REAL_HOLDER(InterlockedPushEntrySList); 163 if (InterlockedPushEntrySList_Real == nullptr) 164 { 165 InterlockedPushEntrySList_Real = GET_PROC_ADDRESS(KERNEL32, InterlockedPushEntrySList); 166 } 167 assert(InterlockedPushEntrySList_Real != nullptr); 168 return InterlockedPushEntrySList_Real(head, entry); 169 } 170 171 PSLIST_ENTRY WINAPI InterlockedPopEntrySList_Helper(PSLIST_HEADER head) 172 { 173 DECLARE_REAL_HOLDER(InterlockedPopEntrySList); 174 if (InterlockedPopEntrySList_Real == nullptr) 175 { 176 InterlockedPopEntrySList_Real = GET_PROC_ADDRESS(KERNEL32, InterlockedPopEntrySList); 177 } 178 assert(InterlockedPopEntrySList_Real != nullptr); 179 return InterlockedPopEntrySList_Real(head); 136 jmp tWinMainCRTStartup; 180 137 } 181 138 } 139 140 } // extern "C"
Note:
See TracChangeset
for help on using the changeset viewer.