source: dev/branches/egtra/ab5.0/abdev/OldWindowsHelperImpl.cpp@ 801

Last change on this file since 801 was 801, checked in by イグトランス (egtra), 14 years ago

コンパイラにXP以前対応用のコードを適用

File size: 5.3 KB
Line 
1#include "stdafx.h"
2#include <cstdint>
3#include <cstring>
4#include <process.h>
5#include "OSVersion.h"
6
7extern "C"
8{
9 extern void* TrapTableFirst;
10 extern FARPROC alias__imp__IsDebuggerPresent;
11 extern FARPROC alias__imp__EncodePointer;
12 extern FARPROC alias__imp__DecodePointer;
13 extern FARPROC alias__imp__HeapSetInformation;
14 extern FARPROC alias__imp__InitializeCriticalSectionAndSpinCount;
15 extern FARPROC alias__imp__InterlockedCompareExchange;
16 extern FARPROC alias__imp__IsProcessorFeaturePresent;
17 extern FARPROC alias__imp__InterlockedPushEntrySList;
18 extern FARPROC alias__imp__InterlockedPopEntrySList;
19 extern FARPROC alias__imp__GetModuleHandleW;
20 extern FARPROC alias__imp__GetStartupInfoW;
21 extern FARPROC alias__imp__GetEnvironmentStringsW;
22 extern FARPROC alias__imp__FreeEnvironmentStringsW;
23 extern void* TrapTableLast;
24} // extern "C"
25
26namespace {
27
28HMODULE GetKernelModule()
29{
30 static HMODULE hmodKernel;
31 if (hmodKernel == nullptr)
32 {
33 hmodKernel = GetModuleHandleA("kernel32");
34 }
35 return hmodKernel;
36}
37
38BOOL WINAPI Alternative_IsDebuggerPresent()
39{
40 ::SetLastError(ERROR_NOT_SUPPORTED);
41 return FALSE;
42}
43
44void* WINAPI Alternative_EncodePointer(void* p)
45{
46 return reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(p) ^ __security_cookie);
47}
48
49#define Alternative_DecodePointer Alternative_EncodePointer
50
51BOOL WINAPI Alternative_HeapSetInformation(HANDLE hHeap, HEAP_INFORMATION_CLASS hic, void* information, SSIZE_T informationLength)
52{
53 return TRUE;
54}
55
56#pragma warning(push)
57#pragma warning(disable: 6320 6322)
58BOOL WINAPI Alternative_InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpcs, DWORD spinCount)
59{
60 __try
61 {
62 ::InitializeCriticalSection(lpcs);
63 return TRUE;
64 }
65 __except(EXCEPTION_EXECUTE_HANDLER)
66 {
67 }
68 return FALSE;
69}
70#pragma warning(pop)
71
72__declspec(naked) long WINAPI Alternative_InterlockedCompareExchange(long volatile*, long, long)
73{
74 __asm
75 {
76 mov ecx,[esp+4]
77 mov edx,[esp+8]
78 mov eax,[esp+12]
79 lock cmpxchg [ecx],edx
80 ret 12
81 }
82}
83
84BOOL WINAPI Alternative_IsProcessorFeaturePresent(DWORD /*feture*/)
85{
86 // ATLからfeture = PF_NX_ENABLEDで呼ばれる
87 return FALSE;
88}
89
90HMODULE WINAPI Alternative_GetModuleHandleW(LPCWSTR moduleName)
91{
92 HMODULE ret = nullptr;
93 auto size = std::wcslen(moduleName) + 1;
94 auto mbsSize = size * 2;
95 if (auto buffer = static_cast<LPSTR>(::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, mbsSize)))
96 {
97 if (::WideCharToMultiByte(CP_ACP, 0, moduleName, static_cast<int>(size), buffer, static_cast<int>(mbsSize), nullptr, nullptr) > 0)
98 {
99 ret = ::GetModuleHandleA(buffer);
100 }
101 ::HeapFree(::GetProcessHeap(), 0, buffer);
102 }
103 return ret;
104}
105
106// CRT用に最小限の実装
107void WINAPI Alternative_GetStartupInfoW(LPSTARTUPINFOW psi)
108{
109 STARTUPINFOA sia;
110 ::GetStartupInfoA(&sia);
111
112 *psi = STARTUPINFOW();
113 psi->cb = sizeof *psi;
114 if (sia.dwFlags & STARTF_USESHOWWINDOW)
115 {
116 psi->dwFlags = STARTF_USESHOWWINDOW;
117 psi->wShowWindow = sia.wShowWindow;
118 }
119}
120
121LPWCH WINAPI Alternative_GetEnvironmentStringsW()
122{
123 static WCHAR c[2];
124 return c;
125}
126
127BOOL WINAPI Alternative_FreeEnvironmentStringsW(LPWCH)
128{
129 return TRUE;
130}
131
132#define FUNCTION_INIT(name) \
133 if (auto f = ::GetProcAddress(GetKernelModule(), #name)) { \
134 alias__imp__ ## name = f; \
135 } else { \
136 alias__imp__ ## name = reinterpret_cast<FARPROC>(Alternative_ ## name); \
137 }
138
139#define FUNCTION_INIT_9X(name) \
140 if (ActiveBasic::Common::Is9x()) { \
141 alias__imp__ ## name = reinterpret_cast<FARPROC>(Alternative_ ## name); \
142 } else { \
143 alias__imp__ ## name = ::GetProcAddress(GetKernelModule(), #name); \
144 }
145
146void InitializeOldWindowsHelper()
147{
148 DWORD oldProtect;
149 ::VirtualProtect(&TrapTableFirst,
150 reinterpret_cast<std::uintptr_t>(&TrapTableLast) - reinterpret_cast<std::uintptr_t>(&TrapTableFirst),
151 PAGE_READWRITE, &oldProtect);
152 FUNCTION_INIT(IsDebuggerPresent);
153 FUNCTION_INIT(EncodePointer);
154 FUNCTION_INIT(DecodePointer);
155 FUNCTION_INIT(HeapSetInformation);
156 FUNCTION_INIT_9X(InitializeCriticalSectionAndSpinCount);
157 FUNCTION_INIT(InterlockedCompareExchange);
158 FUNCTION_INIT(IsProcessorFeaturePresent);
159 alias__imp__InterlockedPushEntrySList = ::GetProcAddress(GetKernelModule(), "InterlockedPushEntrySList");
160 alias__imp__InterlockedPopEntrySList = ::GetProcAddress(GetKernelModule(), "InterlockedPopEntrySList");
161 FUNCTION_INIT_9X(GetModuleHandleW);
162 FUNCTION_INIT_9X(GetStartupInfoW);
163 FUNCTION_INIT_9X(GetEnvironmentStringsW);
164 FUNCTION_INIT_9X(FreeEnvironmentStringsW);
165
166 ::VirtualProtect(&TrapTableFirst,
167 reinterpret_cast<std::uintptr_t>(&TrapTableLast) - reinterpret_cast<std::uintptr_t>(&TrapTableFirst),
168 PAGE_READONLY, &oldProtect);
169}
170
171} // unnamed namespace
172
173extern "C"
174{
175#ifdef _CONSOLE
176# ifdef _UNICODE
177 int wmainCRTStartup();
178# define CRTStartup wmainCRTStartup
179# else
180 int mainCRTStartup();
181# define CRTStartup mainCRTStartup
182# endif
183#else
184# ifdef _UNICODE
185 int wWinMainCRTStartup();
186# define CRTStartup wWinMainCRTStartup
187# else
188 int WinMainCRTStartup();
189# define CRTStartup WinMainCRTStartup
190# endif
191#endif
192
193void Startup_OldWindowsHelper()
194{
195 __security_init_cookie();
196// MessageBox(0, "Startup", "", 0);
197 InitializeOldWindowsHelper();
198
199 __asm
200 {
201 jmp CRTStartup;
202 }
203}
204
205} // extern "C"
Note: See TracBrowser for help on using the repository browser.