Changeset 787 in dev for branches


Ignore:
Timestamp:
Jan 30, 2011, 2:16:08 AM (14 years ago)
Author:
イグトランス (egtra)
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/egtra/ab5.0/abdev/OldWindowsHelperImpl.cpp

    r785 r787  
    11#include "stdafx.h"
    22
    3 #define GET_PROC_ADDRESS(hmod, functionName) reinterpret_cast<decltype(functionName)*>(GetProcAddress((hmod), #functionName))
    4 
    5 namespace
    6 {
    7 
    8 OSVERSIONINFO GetVersionEx2()
     3static OSVERSIONINFO GetVersionEx2()
    94{
    105    OSVERSIONINFO vi = {sizeof vi};
     
    1510static OSVERSIONINFO const vi = GetVersionEx2();
    1611
    17 HMODULE GetKernelModule()
     12
     13
     14static HMODULE hmodKernel;
     15
     16static HMODULE GetKernelModule()
    1817{
    19     static HMODULE hmod = GetModuleHandle(TEXT("kernel32"));
    20     return hmod;
     18    if (hmodKernel == nullptr)
     19    {
     20        hmodKernel = GetModuleHandle(TEXT("kernel32"));
     21    }
     22    return hmodKernel;
    2123}
    2224
    23 }
     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
    2430
    2531extern "C"
     
    2733    BOOL WINAPI IsDebuggerPresent_Helper()
    2834    {
    29         static auto IsDebuggerPresent_Real = GET_PROC_ADDRESS(GetKernelModule(), IsDebuggerPresent);
    30         if (IsDebuggerPresent_Real)
     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)
    3144        {
    3245            return IsDebuggerPresent_Real();
     
    4053    void* WINAPI EncodePointer_Helper(void* p)
    4154    {
    42         static auto EncodePointer_Real = GET_PROC_ADDRESS(GetKernelModule(), EncodePointer);
    43         if (EncodePointer_Real)
     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)
    4464        {
    4565            return EncodePointer_Real(p);
     
    5373    void* WINAPI DecodePointer_Helper(void* p)
    5474    {
    55         static auto DecodePointer_Real = GET_PROC_ADDRESS(GetKernelModule(), DecodePointer);
    56         if (DecodePointer_Real)
     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)
    5784        {
    5885            return DecodePointer_Real(p);
     
    6693    BOOL WINAPI IsProcessorFeaturePresent_Helper(DWORD feture)
    6794    {
    68         static auto IsProcessorFeaturePresent_Real = GET_PROC_ADDRESS(GetKernelModule(), IsProcessorFeaturePresent);
    69         if (IsProcessorFeaturePresent_Real)
     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)
    70104        {
    71105            return IsProcessorFeaturePresent_Real(feture);
     
    80114    BOOL WINAPI HeapSetInformation_Helper(HANDLE hHeap, HEAP_INFORMATION_CLASS hic, void* information, SSIZE_T informationLength)
    81115    {
    82         static auto HeapSetInformation_Real = GET_PROC_ADDRESS(GetKernelModule(), HeapSetInformation);
    83         if (HeapSetInformation_Real)
     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)
    84125        {
    85126            return HeapSetInformation_Real(hHeap, hic, information, informationLength);
     
    91132    }
    92133
    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 
    123134    BOOL WINAPI InitializeCriticalSectionAndSpinCount_Helper(LPCRITICAL_SECTION lpcs, DWORD spinCount)
    124135    {
    125         static auto InitializeCriticalSectionAndSpinCount_Real = GET_PROC_ADDRESS(GetKernelModule(), InitializeCriticalSectionAndSpinCount);
    126         return InitializeCriticalSectionAndSpinCount_Helper2(InitializeCriticalSectionAndSpinCount_Real, lpcs, spinCount);
     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;
    127165    }
    128166
     
    134172    PSLIST_ENTRY WINAPI InterlockedPushEntrySList_Helper(PSLIST_HEADER head, PSLIST_ENTRY entry)
    135173    {
    136         static auto InterlockedPushEntrySList_Real = GET_PROC_ADDRESS(GetKernelModule(), InterlockedPushEntrySList);
     174        DECLARE_REAL_HOLDER(InterlockedPushEntrySList);
     175        if (InterlockedPushEntrySList_Real == nullptr)
     176        {
     177             InterlockedPushEntrySList_Real = GET_PROC_ADDRESS(KERNEL32, InterlockedPushEntrySList);
     178        }
    137179        assert(InterlockedPushEntrySList_Real != nullptr);
    138180        return InterlockedPushEntrySList_Real(head, entry);
     
    141183    PSLIST_ENTRY WINAPI InterlockedPopEntrySList_Helper(PSLIST_HEADER head)
    142184    {
    143         static auto InterlockedPopEntrySList_Real = GET_PROC_ADDRESS(GetKernelModule(), InterlockedPopEntrySList);
     185        DECLARE_REAL_HOLDER(InterlockedPopEntrySList);
     186        if (InterlockedPopEntrySList_Real == nullptr)
     187        {
     188             InterlockedPopEntrySList_Real = GET_PROC_ADDRESS(KERNEL32, InterlockedPopEntrySList);
     189        }
    144190        assert(InterlockedPopEntrySList_Real != nullptr);
    145191        return InterlockedPopEntrySList_Real(head);
Note: See TracChangeset for help on using the changeset viewer.