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

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

旧Windows対応箇所で、毎回の関数呼出を行なわないようにした。タイミングによって、GetModuleHandle内のHeap関数呼出が落ちる現象に遭遇したため。

File size: 4.1 KB
Line 
1#include "stdafx.h"
2
3#define GET_PROC_ADDRESS(hmod, functionName) reinterpret_cast<decltype(functionName)*>(GetProcAddress((hmod), #functionName))
4
5namespace
6{
7
8OSVERSIONINFO GetVersionEx2()
9{
10 OSVERSIONINFO vi = {sizeof vi};
11 GetVersionEx(&vi);
12 return vi;
13}
14
15static OSVERSIONINFO const vi = GetVersionEx2();
16
17HMODULE GetKernelModule()
18{
19 static HMODULE hmod = GetModuleHandle(TEXT("kernel32"));
20 return hmod;
21}
22
23}
24
25extern "C"
26{
27 BOOL WINAPI IsDebuggerPresent_Helper()
28 {
29 static auto IsDebuggerPresent_Real = GET_PROC_ADDRESS(GetKernelModule(), IsDebuggerPresent);
30 if (IsDebuggerPresent_Real)
31 {
32 return IsDebuggerPresent_Real();
33 }
34 else
35 {
36 return FALSE;
37 }
38 }
39
40 void* WINAPI EncodePointer_Helper(void* p)
41 {
42 static auto EncodePointer_Real = GET_PROC_ADDRESS(GetKernelModule(), EncodePointer);
43 if (EncodePointer_Real)
44 {
45 return EncodePointer_Real(p);
46 }
47 else
48 {
49 return reinterpret_cast<void*>(reinterpret_cast<DWORD>(p) ^ GetCurrentProcessId());
50 }
51 }
52
53 void* WINAPI DecodePointer_Helper(void* p)
54 {
55 static auto DecodePointer_Real = GET_PROC_ADDRESS(GetKernelModule(), DecodePointer);
56 if (DecodePointer_Real)
57 {
58 return DecodePointer_Real(p);
59 }
60 else
61 {
62 return reinterpret_cast<void*>(reinterpret_cast<DWORD>(p) ^ GetCurrentProcessId());
63 }
64 }
65
66 BOOL WINAPI IsProcessorFeaturePresent_Helper(DWORD feture)
67 {
68 static auto IsProcessorFeaturePresent_Real = GET_PROC_ADDRESS(GetKernelModule(), IsProcessorFeaturePresent);
69 if (IsProcessorFeaturePresent_Real)
70 {
71 return IsProcessorFeaturePresent_Real(feture);
72 }
73 else
74 {
75 assert(feture == PF_NX_ENABLED); // ATLから呼ばれる
76 return FALSE;
77 }
78 }
79
80 BOOL WINAPI HeapSetInformation_Helper(HANDLE hHeap, HEAP_INFORMATION_CLASS hic, void* information, SSIZE_T informationLength)
81 {
82 static auto HeapSetInformation_Real = GET_PROC_ADDRESS(GetKernelModule(), HeapSetInformation);
83 if (HeapSetInformation_Real)
84 {
85 return HeapSetInformation_Real(hHeap, hic, information, informationLength);
86 }
87 else
88 {
89 return TRUE;
90 }
91 }
92
93 namespace
94 {
95 typedef decltype(InitializeCriticalSectionAndSpinCount)* PInitializeCriticalSectionAndSpinCount;
96
97 // 関数内静的変数とSEHは両立できないようなので別の関数へ分離
98 BOOL WINAPI InitializeCriticalSectionAndSpinCount_Helper2(PInitializeCriticalSectionAndSpinCount pfn, LPCRITICAL_SECTION lpcs, DWORD spinCount)
99 {
100 __try
101 {
102 if (pfn != nullptr)
103 {
104 BOOL ret = pfn(lpcs, spinCount);
105 return vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS
106 ? TRUE
107 : ret;
108 }
109 else
110 {
111 ::InitializeCriticalSection(lpcs);
112 return TRUE;
113 }
114 }
115 __except(EXCEPTION_EXECUTE_HANDLER)
116 {
117 }
118 ::SetLastError(ERROR_OUTOFMEMORY);
119 return FALSE;
120 }
121 }
122
123 BOOL WINAPI InitializeCriticalSectionAndSpinCount_Helper(LPCRITICAL_SECTION lpcs, DWORD spinCount)
124 {
125 static auto InitializeCriticalSectionAndSpinCount_Real = GET_PROC_ADDRESS(GetKernelModule(), InitializeCriticalSectionAndSpinCount);
126 return InitializeCriticalSectionAndSpinCount_Helper2(InitializeCriticalSectionAndSpinCount_Real, lpcs, spinCount);
127 }
128
129 // Interlocked(Push|Pop)EntrySListは、NXが有効な場合のみ呼ばれる。
130 // Windows XP以前はNX対応していないためInterlocked(Push|Pop)EntrySListが呼ばれることはない。
131 // そのため、GET_PROC_ADDRESSがnullptrを返すことはないと仮定している。
132 // なお、Interlocked(Push|Pop)EntrySListもWindows XPから搭載されている。
133
134 PSLIST_ENTRY WINAPI InterlockedPushEntrySList_Helper(PSLIST_HEADER head, PSLIST_ENTRY entry)
135 {
136 static auto InterlockedPushEntrySList_Real = GET_PROC_ADDRESS(GetKernelModule(), InterlockedPushEntrySList);
137 assert(InterlockedPushEntrySList_Real != nullptr);
138 return InterlockedPushEntrySList_Real(head, entry);
139 }
140
141 PSLIST_ENTRY WINAPI InterlockedPopEntrySList_Helper(PSLIST_HEADER head)
142 {
143 static auto InterlockedPopEntrySList_Real = GET_PROC_ADDRESS(GetKernelModule(), InterlockedPopEntrySList);
144 assert(InterlockedPopEntrySList_Real != nullptr);
145 return InterlockedPopEntrySList_Real(head);
146 }
147}
Note: See TracBrowser for help on using the repository browser.