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

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

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

File size: 5.3 KB
RevLine 
[778]1#include "stdafx.h"
[800]2#include <cstdint>
[801]3#include <cstring>
[800]4#include <process.h>
[798]5#include "OSVersion.h"
[778]6
[800]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;
[801]19 extern FARPROC alias__imp__GetModuleHandleW;
20 extern FARPROC alias__imp__GetStartupInfoW;
21 extern FARPROC alias__imp__GetEnvironmentStringsW;
22 extern FARPROC alias__imp__FreeEnvironmentStringsW;
[800]23 extern void* TrapTableLast;
24} // extern "C"
[787]25
[800]26namespace {
27
28HMODULE GetKernelModule()
[785]29{
[800]30 static HMODULE hmodKernel;
[787]31 if (hmodKernel == nullptr)
32 {
[801]33 hmodKernel = GetModuleHandleA("kernel32");
[787]34 }
35 return hmodKernel;
[785]36}
[778]37
[800]38BOOL WINAPI Alternative_IsDebuggerPresent()
39{
40 ::SetLastError(ERROR_NOT_SUPPORTED);
41 return FALSE;
42}
[778]43
[800]44void* WINAPI Alternative_EncodePointer(void* p)
45{
46 return reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(p) ^ __security_cookie);
47}
[787]48
[800]49#define Alternative_DecodePointer Alternative_EncodePointer
[787]50
[800]51BOOL WINAPI Alternative_HeapSetInformation(HANDLE hHeap, HEAP_INFORMATION_CLASS hic, void* information, SSIZE_T informationLength)
[778]52{
[800]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
[778]61 {
[800]62 ::InitializeCriticalSection(lpcs);
63 return TRUE;
[778]64 }
[800]65 __except(EXCEPTION_EXECUTE_HANDLER)
[778]66 {
67 }
[800]68 return FALSE;
69}
70#pragma warning(pop)
[778]71
[801]72__declspec(naked) long WINAPI Alternative_InterlockedCompareExchange(long volatile*, long, long)
[800]73{
74 __asm
[778]75 {
[800]76 mov ecx,[esp+4]
77 mov edx,[esp+8]
78 mov eax,[esp+12]
79 lock cmpxchg [ecx],edx
80 ret 12
[778]81 }
[800]82}
[778]83
[800]84BOOL WINAPI Alternative_IsProcessorFeaturePresent(DWORD /*feture*/)
85{
86 // ATLからfeture = PF_NX_ENABLEDで呼ばれる
87 return FALSE;
88}
[787]89
[801]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
[800]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); \
[778]137 }
138
[801]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
[800]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);
[801]156 FUNCTION_INIT_9X(InitializeCriticalSectionAndSpinCount);
[800]157 FUNCTION_INIT(InterlockedCompareExchange);
158 FUNCTION_INIT(IsProcessorFeaturePresent);
159 alias__imp__InterlockedPushEntrySList = ::GetProcAddress(GetKernelModule(), "InterlockedPushEntrySList");
160 alias__imp__InterlockedPopEntrySList = ::GetProcAddress(GetKernelModule(), "InterlockedPopEntrySList");
[801]161 FUNCTION_INIT_9X(GetModuleHandleW);
162 FUNCTION_INIT_9X(GetStartupInfoW);
163 FUNCTION_INIT_9X(GetEnvironmentStringsW);
164 FUNCTION_INIT_9X(FreeEnvironmentStringsW);
[787]165
[800]166 ::VirtualProtect(&TrapTableFirst,
167 reinterpret_cast<std::uintptr_t>(&TrapTableLast) - reinterpret_cast<std::uintptr_t>(&TrapTableFirst),
168 PAGE_READONLY, &oldProtect);
169}
[778]170
[800]171} // unnamed namespace
[785]172
[800]173extern "C"
174{
[801]175#ifdef _CONSOLE
176# ifdef _UNICODE
177 int wmainCRTStartup();
178# define CRTStartup wmainCRTStartup
179# else
180 int mainCRTStartup();
181# define CRTStartup mainCRTStartup
182# endif
[800]183#else
[801]184# ifdef _UNICODE
185 int wWinMainCRTStartup();
186# define CRTStartup wWinMainCRTStartup
187# else
188 int WinMainCRTStartup();
189# define CRTStartup WinMainCRTStartup
190# endif
[800]191#endif
[778]192
[801]193void Startup_OldWindowsHelper()
[800]194{
195 __security_init_cookie();
[801]196// MessageBox(0, "Startup", "", 0);
[800]197 InitializeOldWindowsHelper();
[778]198
[800]199 __asm
[778]200 {
[801]201 jmp CRTStartup;
[778]202 }
203}
[800]204
205} // extern "C"
Note: See TracBrowser for help on using the repository browser.