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

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

旧Windows対応箇所で、動的な初期化を持つ静的変数の使用が9xでエラーを起こしていたため、それを回避する形に修正。

File size: 4.8 KB
Line 
1#include "stdafx.h"
2
3static OSVERSIONINFO GetVersionEx2()
4{
5 OSVERSIONINFO vi = {sizeof vi};
6 GetVersionEx(&vi);
7 return vi;
8}
9
10static OSVERSIONINFO const vi = GetVersionEx2();
11
12
13
14static HMODULE hmodKernel;
15
16static HMODULE GetKernelModule()
17{
18 if (hmodKernel == nullptr)
19 {
20 hmodKernel = GetModuleHandle(TEXT("kernel32"));
21 }
22 return hmodKernel;
23}
24
25#define KERNEL32 (GetKernelModule())
26
27#define GET_PROC_ADDRESS(hmod, functionName) reinterpret_cast<decltype(functionName)*>(GetProcAddress((hmod), #functionName))
28
29#define DECLARE_REAL_HOLDER(name) static decltype(name)* name ## _Real
30
31extern "C"
32{
33 BOOL WINAPI IsDebuggerPresent_Helper()
34 {
35 DECLARE_REAL_HOLDER(IsDebuggerPresent);
36 static bool initialized;
37 if (!initialized)
38 {
39 auto IsDebuggerPresent_Real = GET_PROC_ADDRESS(KERNEL32, IsDebuggerPresent);
40 initialized = true;
41 }
42
43 if (IsDebuggerPresent_Real != nullptr)
44 {
45 return IsDebuggerPresent_Real();
46 }
47 else
48 {
49 return FALSE;
50 }
51 }
52
53 void* WINAPI EncodePointer_Helper(void* p)
54 {
55 DECLARE_REAL_HOLDER(EncodePointer);
56 static bool initialized;
57 if (!initialized)
58 {
59 auto EncodePointer_Real = GET_PROC_ADDRESS(KERNEL32, EncodePointer);
60 initialized = true;
61 }
62
63 if (EncodePointer_Real != nullptr)
64 {
65 return EncodePointer_Real(p);
66 }
67 else
68 {
69 return reinterpret_cast<void*>(reinterpret_cast<DWORD>(p) ^ GetCurrentProcessId());
70 }
71 }
72
73 void* WINAPI DecodePointer_Helper(void* p)
74 {
75 DECLARE_REAL_HOLDER(DecodePointer);
76 static bool initialized;
77 if (!initialized)
78 {
79 auto DecodePointer_Real = GET_PROC_ADDRESS(KERNEL32, DecodePointer);
80 initialized = true;
81 }
82
83 if (DecodePointer_Real != nullptr)
84 {
85 return DecodePointer_Real(p);
86 }
87 else
88 {
89 return reinterpret_cast<void*>(reinterpret_cast<DWORD>(p) ^ GetCurrentProcessId());
90 }
91 }
92
93 BOOL WINAPI IsProcessorFeaturePresent_Helper(DWORD feture)
94 {
95 DECLARE_REAL_HOLDER(IsProcessorFeaturePresent);
96 static bool initialized;
97 if (!initialized)
98 {
99 IsProcessorFeaturePresent_Real = GET_PROC_ADDRESS(KERNEL32, IsProcessorFeaturePresent);
100 initialized = true;
101 }
102
103 if (IsProcessorFeaturePresent_Real != nullptr)
104 {
105 return IsProcessorFeaturePresent_Real(feture);
106 }
107 else
108 {
109 assert(feture == PF_NX_ENABLED); // ATLから呼ばれる
110 return FALSE;
111 }
112 }
113
114 BOOL WINAPI HeapSetInformation_Helper(HANDLE hHeap, HEAP_INFORMATION_CLASS hic, void* information, SSIZE_T informationLength)
115 {
116 DECLARE_REAL_HOLDER(HeapSetInformation);
117 static bool initialized;
118 if (!initialized)
119 {
120 HeapSetInformation_Real = GET_PROC_ADDRESS(KERNEL32, HeapSetInformation);
121 initialized = true;
122 }
123
124 if (HeapSetInformation_Real != nullptr)
125 {
126 return HeapSetInformation_Real(hHeap, hic, information, informationLength);
127 }
128 else
129 {
130 return TRUE;
131 }
132 }
133
134 BOOL WINAPI InitializeCriticalSectionAndSpinCount_Helper(LPCRITICAL_SECTION lpcs, DWORD spinCount)
135 {
136 DECLARE_REAL_HOLDER(InitializeCriticalSectionAndSpinCount);
137 static bool initialized;
138 if (!initialized)
139 {
140 InitializeCriticalSectionAndSpinCount_Real = GET_PROC_ADDRESS(KERNEL32, InitializeCriticalSectionAndSpinCount);
141 initialized = true;
142 }
143
144 __try
145 {
146 if (InitializeCriticalSectionAndSpinCount_Real != nullptr)
147 {
148 OSVERSIONINFO vi = {sizeof vi};
149 ::GetVersionEx(&vi);
150 BOOL ret = InitializeCriticalSectionAndSpinCount_Real(lpcs, spinCount);
151 return vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS
152 ? TRUE
153 : ret;
154 }
155 else
156 {
157 ::InitializeCriticalSection(lpcs);
158 return TRUE;
159 }
160 }
161 __except(EXCEPTION_EXECUTE_HANDLER)
162 {
163 }
164 return FALSE;
165 }
166
167 // Interlocked(Push|Pop)EntrySListは、NXが有効な場合のみ呼ばれる。
168 // Windows XP以前はNX対応していないためInterlocked(Push|Pop)EntrySListが呼ばれることはない。
169 // そのため、GET_PROC_ADDRESSがnullptrを返すことはないと仮定している。
170 // なお、Interlocked(Push|Pop)EntrySListもWindows XPから搭載されている。
171
172 PSLIST_ENTRY WINAPI InterlockedPushEntrySList_Helper(PSLIST_HEADER head, PSLIST_ENTRY entry)
173 {
174 DECLARE_REAL_HOLDER(InterlockedPushEntrySList);
175 if (InterlockedPushEntrySList_Real == nullptr)
176 {
177 InterlockedPushEntrySList_Real = GET_PROC_ADDRESS(KERNEL32, InterlockedPushEntrySList);
178 }
179 assert(InterlockedPushEntrySList_Real != nullptr);
180 return InterlockedPushEntrySList_Real(head, entry);
181 }
182
183 PSLIST_ENTRY WINAPI InterlockedPopEntrySList_Helper(PSLIST_HEADER head)
184 {
185 DECLARE_REAL_HOLDER(InterlockedPopEntrySList);
186 if (InterlockedPopEntrySList_Real == nullptr)
187 {
188 InterlockedPopEntrySList_Real = GET_PROC_ADDRESS(KERNEL32, InterlockedPopEntrySList);
189 }
190 assert(InterlockedPopEntrySList_Real != nullptr);
191 return InterlockedPopEntrySList_Real(head);
192 }
193}
Note: See TracBrowser for help on using the repository browser.