Changeset 800 in dev


Ignore:
Timestamp:
Feb 6, 2011, 4:35:27 AM (13 years ago)
Author:
イグトランス (egtra)
Message:

OldWindowsHelperを整理

Location:
branches/egtra/ab5.0/abdev
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/egtra/ab5.0/abdev/OldWindowsHelper.asm

    r799 r800  
    22.model flat, stdcall
    33
    4 ImportTrapLocal MACRO name, arg
    5     @CATSTR(<_imp__>, name, <@>, arg) dd @CATSTR(name, <_Helper@>, arg)
     4ImportTrap MACRO name, arg
     5    @CATSTR(<alias__imp__>, name) LABEL DWORD
     6    @CATSTR(<_imp__>, name, <@>, arg) dd ?
    67    PUBLIC @CATSTR(<_imp__>, name, <@>, arg)
     8    PUBLIC @CATSTR(<alias__imp__>, name)
    79ENDM
    810
    9 ImportTrap MACRO name, arg
    10     ImportTrapLocal name, arg
    11     EXTERN @CATSTR(name, <_Helper@>, arg) : DWORD
    12 ENDM
    13 
    14 .data
     11.const
     12    TrapTableFirst LABEL DWORD
    1513    ImportTrap IsDebuggerPresent, 0
    1614    ImportTrap EncodePointer, 4
     
    2119    ImportTrap InterlockedPushEntrySList, 8
    2220    ImportTrap InterlockedPopEntrySList, 4
    23     ImportTrapLocal InterlockedCompareExchange, 12
     21    ImportTrap InterlockedCompareExchange, 12
     22    TrapTableLast LABEL DWORD
    2423
    25 .code
    26     InterlockedCompareExchange_Helper@12 PROC PRIVATE
    27         mov             ecx,[esp+4]
    28         mov             edx,[esp+8]
    29         mov             eax,[esp+12]
    30         lock cmpxchg    [ecx],edx
    31         ret             12
    32     InterlockedCompareExchange_Helper@12 ENDP
     24    REPEAT 4096 - (TrapTableLast - TrapTableFirst)
     25        db ?
     26    ENDM
     27
     28    PUBLIC TrapTableFirst
     29    PUBLIC TrapTableLast
    3330end
  • branches/egtra/ab5.0/abdev/OldWindowsHelperImpl.cpp

    r798 r800  
    11#include "stdafx.h"
     2#include <cstdint>
     3#include <process.h>
    24#include "OSVersion.h"
    35
    4 static HMODULE hmodKernel;
     6extern "C"
     7{
     8    extern void* TrapTableFirst;
     9    extern FARPROC alias__imp__IsDebuggerPresent;
     10    extern FARPROC alias__imp__EncodePointer;
     11    extern FARPROC alias__imp__DecodePointer;
     12    extern FARPROC alias__imp__HeapSetInformation;
     13    extern FARPROC alias__imp__InitializeCriticalSectionAndSpinCount;
     14    extern FARPROC alias__imp__InterlockedCompareExchange;
     15    extern FARPROC alias__imp__IsProcessorFeaturePresent;
     16    extern FARPROC alias__imp__InterlockedPushEntrySList;
     17    extern FARPROC alias__imp__InterlockedPopEntrySList;
     18    extern void* TrapTableLast;
     19} // extern "C"
    520
    6 static HMODULE GetKernelModule()
     21namespace {
     22
     23HMODULE GetKernelModule()
    724{
     25    static HMODULE hmodKernel;
    826    if (hmodKernel == nullptr)
    927    {
     
    1331}
    1432
    15 #define KERNEL32 (GetKernelModule())
     33BOOL WINAPI Alternative_IsDebuggerPresent()
     34{
     35    ::SetLastError(ERROR_NOT_SUPPORTED);
     36    return FALSE;
     37}
    1638
    17 #define GET_PROC_ADDRESS(hmod, functionName) reinterpret_cast<decltype(functionName)*>(GetProcAddress((hmod), #functionName))
     39void* WINAPI Alternative_EncodePointer(void* p)
     40{
     41    return reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(p) ^ __security_cookie);
     42}
    1843
    19 #define DECLARE_REAL_HOLDER(name) static decltype(name)* name ## _Real
     44#define Alternative_DecodePointer Alternative_EncodePointer
     45
     46BOOL WINAPI Alternative_HeapSetInformation(HANDLE hHeap, HEAP_INFORMATION_CLASS hic, void* information, SSIZE_T informationLength)
     47{
     48    return TRUE;
     49}
     50
     51#pragma warning(push)
     52#pragma warning(disable: 6320 6322)
     53BOOL WINAPI Alternative_InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpcs, DWORD spinCount)
     54{
     55    __try
     56    {
     57        ::InitializeCriticalSection(lpcs);
     58        return TRUE;
     59    }
     60    __except(EXCEPTION_EXECUTE_HANDLER)
     61    {
     62    }
     63    return FALSE;
     64}
     65#pragma warning(pop)
     66
     67__declspec(naked) long __stdcall Alternative_InterlockedCompareExchange(long volatile*, long, long)
     68{
     69    __asm
     70    {
     71        mov             ecx,[esp+4]
     72        mov             edx,[esp+8]
     73        mov             eax,[esp+12]
     74        lock cmpxchg    [ecx],edx
     75        ret             12
     76    }
     77}
     78
     79BOOL WINAPI Alternative_IsProcessorFeaturePresent(DWORD /*feture*/)
     80{
     81    // ATLからfeture = PF_NX_ENABLEDで呼ばれる
     82    return FALSE;
     83}
     84
     85#define FUNCTION_INIT(name) \
     86    if (auto f = ::GetProcAddress(GetKernelModule(), #name)) { \
     87        alias__imp__ ## name = f; \
     88    } else { \
     89        alias__imp__ ## name = reinterpret_cast<FARPROC>(Alternative_ ## name); \
     90    }
     91
     92void InitializeOldWindowsHelper()
     93{
     94    DWORD oldProtect;
     95    ::VirtualProtect(&TrapTableFirst,
     96        reinterpret_cast<std::uintptr_t>(&TrapTableLast) - reinterpret_cast<std::uintptr_t>(&TrapTableFirst),
     97        PAGE_READWRITE, &oldProtect);
     98    FUNCTION_INIT(IsDebuggerPresent);
     99    FUNCTION_INIT(EncodePointer);
     100    FUNCTION_INIT(DecodePointer);
     101    FUNCTION_INIT(HeapSetInformation);
     102    alias__imp__InitializeCriticalSectionAndSpinCount =
     103        ActiveBasic::Common::Is9x()
     104        ? reinterpret_cast<FARPROC>(Alternative_InitializeCriticalSectionAndSpinCount)
     105        : ::GetProcAddress(GetKernelModule(), "InitializeCriticalSectionAndSpinCount");
     106    FUNCTION_INIT(InterlockedCompareExchange);
     107    FUNCTION_INIT(IsProcessorFeaturePresent);
     108    alias__imp__InterlockedPushEntrySList = ::GetProcAddress(GetKernelModule(), "InterlockedPushEntrySList");
     109    alias__imp__InterlockedPopEntrySList = ::GetProcAddress(GetKernelModule(), "InterlockedPopEntrySList");
     110
     111    ::VirtualProtect(&TrapTableFirst,
     112        reinterpret_cast<std::uintptr_t>(&TrapTableLast) - reinterpret_cast<std::uintptr_t>(&TrapTableFirst),
     113        PAGE_READONLY, &oldProtect);
     114}
     115
     116} // unnamed namespace
    20117
    21118extern "C"
    22119{
    23     BOOL WINAPI IsDebuggerPresent_Helper()
     120#ifdef _UNICODE
     121int wWinMainCRTStartup();
     122#define tWinMainCRTStartup wWinMainCRTStartup
     123#else
     124int WinMainCRTStartup();
     125#define tWinMainCRTStartup WinMainCRTStartup
     126#endif
     127
     128void WinMainStartup_OldWindowsHelper()
     129{
     130    __security_init_cookie();
     131
     132    InitializeOldWindowsHelper();
     133
     134    __asm
    24135    {
    25         DECLARE_REAL_HOLDER(IsDebuggerPresent);
    26         static bool initialized;
    27         if (!initialized)
    28         {
    29             auto IsDebuggerPresent_Real = GET_PROC_ADDRESS(KERNEL32, IsDebuggerPresent);
    30             initialized = true;
    31         }
    32 
    33         if (IsDebuggerPresent_Real != nullptr)
    34         {
    35             return IsDebuggerPresent_Real();
    36         }
    37         else
    38         {
    39             return FALSE;
    40         }
    41     }
    42 
    43     void* WINAPI EncodePointer_Helper(void* p)
    44     {
    45         DECLARE_REAL_HOLDER(EncodePointer);
    46         static bool initialized;
    47         if (!initialized)
    48         {
    49             auto EncodePointer_Real = GET_PROC_ADDRESS(KERNEL32, EncodePointer);
    50             initialized = true;
    51         }
    52 
    53         if (EncodePointer_Real != nullptr)
    54         {
    55             return EncodePointer_Real(p);
    56         }
    57         else
    58         {
    59             return reinterpret_cast<void*>(reinterpret_cast<DWORD>(p) ^ GetCurrentProcessId());
    60         }
    61     }
    62 
    63     void* WINAPI DecodePointer_Helper(void* p)
    64     {
    65         DECLARE_REAL_HOLDER(DecodePointer);
    66         static bool initialized;
    67         if (!initialized)
    68         {
    69             auto DecodePointer_Real = GET_PROC_ADDRESS(KERNEL32, DecodePointer);
    70             initialized = true;
    71         }
    72 
    73         if (DecodePointer_Real != nullptr)
    74         {
    75             return DecodePointer_Real(p);
    76         }
    77         else
    78         {
    79             return reinterpret_cast<void*>(reinterpret_cast<DWORD>(p) ^ GetCurrentProcessId());
    80         }
    81     }
    82 
    83     BOOL WINAPI IsProcessorFeaturePresent_Helper(DWORD feture)
    84     {
    85         DECLARE_REAL_HOLDER(IsProcessorFeaturePresent);
    86         static bool initialized;
    87         if (!initialized)
    88         {
    89             IsProcessorFeaturePresent_Real = GET_PROC_ADDRESS(KERNEL32, IsProcessorFeaturePresent);
    90             initialized = true;
    91         }
    92 
    93         if (IsProcessorFeaturePresent_Real != nullptr)
    94         {
    95             return IsProcessorFeaturePresent_Real(feture);
    96         }
    97         else
    98         {
    99             assert(feture == PF_NX_ENABLED); // ATLから呼ばれる
    100             return FALSE;
    101         }
    102     }
    103 
    104     BOOL WINAPI HeapSetInformation_Helper(HANDLE hHeap, HEAP_INFORMATION_CLASS hic, void* information, SSIZE_T informationLength)
    105     {
    106         DECLARE_REAL_HOLDER(HeapSetInformation);
    107         static bool initialized;
    108         if (!initialized)
    109         {
    110             HeapSetInformation_Real = GET_PROC_ADDRESS(KERNEL32, HeapSetInformation);
    111             initialized = true;
    112         }
    113 
    114         if (HeapSetInformation_Real != nullptr)
    115         {
    116             return HeapSetInformation_Real(hHeap, hic, information, informationLength);
    117         }
    118         else
    119         {
    120             return TRUE;
    121         }
    122     }
    123 
    124     BOOL WINAPI InitializeCriticalSectionAndSpinCount_Helper(LPCRITICAL_SECTION lpcs, DWORD spinCount)
    125     {
    126         DECLARE_REAL_HOLDER(InitializeCriticalSectionAndSpinCount);
    127         static bool initialized;
    128         if (!initialized)
    129         {
    130             InitializeCriticalSectionAndSpinCount_Real = GET_PROC_ADDRESS(KERNEL32, InitializeCriticalSectionAndSpinCount);
    131             initialized = true;
    132         }
    133 
    134         __try
    135         {
    136             if (InitializeCriticalSectionAndSpinCount_Real != nullptr)
    137             {
    138                 BOOL ret = InitializeCriticalSectionAndSpinCount_Real(lpcs, spinCount);
    139                 return ActiveBasic::Common::Is9x()
    140                     ? TRUE
    141                     : ret;
    142             }
    143             else
    144             {
    145                 ::InitializeCriticalSection(lpcs);
    146                 return TRUE;
    147             }
    148         }
    149         __except(EXCEPTION_EXECUTE_HANDLER)
    150         {
    151         }
    152         return FALSE;
    153     }
    154 
    155     // Interlocked(Push|Pop)EntrySListは、NXが有効な場合のみ呼ばれる。
    156     // Windows XP以前はNX対応していないためInterlocked(Push|Pop)EntrySListが呼ばれることはない。
    157     // そのため、GET_PROC_ADDRESSがnullptrを返すことはないと仮定している。
    158     // なお、Interlocked(Push|Pop)EntrySListもWindows XPから搭載されている。
    159 
    160     PSLIST_ENTRY WINAPI InterlockedPushEntrySList_Helper(PSLIST_HEADER head, PSLIST_ENTRY entry)
    161     {
    162         DECLARE_REAL_HOLDER(InterlockedPushEntrySList);
    163         if (InterlockedPushEntrySList_Real == nullptr)
    164         {
    165              InterlockedPushEntrySList_Real = GET_PROC_ADDRESS(KERNEL32, InterlockedPushEntrySList);
    166         }
    167         assert(InterlockedPushEntrySList_Real != nullptr);
    168         return InterlockedPushEntrySList_Real(head, entry);
    169     }
    170 
    171     PSLIST_ENTRY WINAPI InterlockedPopEntrySList_Helper(PSLIST_HEADER head)
    172     {
    173         DECLARE_REAL_HOLDER(InterlockedPopEntrySList);
    174         if (InterlockedPopEntrySList_Real == nullptr)
    175         {
    176              InterlockedPopEntrySList_Real = GET_PROC_ADDRESS(KERNEL32, InterlockedPopEntrySList);
    177         }
    178         assert(InterlockedPopEntrySList_Real != nullptr);
    179         return InterlockedPopEntrySList_Real(head);
     136        jmp tWinMainCRTStartup;
    180137    }
    181138}
     139
     140} // extern "C"
  • branches/egtra/ab5.0/abdev/abdev/abdev.vcxproj

    r798 r800  
    115115      <SubSystem>Windows</SubSystem>
    116116      <TargetMachine>MachineX86</TargetMachine>
     117      <EntryPointSymbol>WinMainStartup_OldWindowsHelper</EntryPointSymbol>
    117118    </Link>
    118119    <Manifest>
     
    152153      <SubSystem>Windows</SubSystem>
    153154      <TargetMachine>MachineX64</TargetMachine>
     155      <EntryPointSymbol>WinMainStartup_OldWindowsHelper</EntryPointSymbol>
    154156    </Link>
    155157    <Manifest>
     
    192194      <EnableCOMDATFolding>true</EnableCOMDATFolding>
    193195      <TargetMachine>MachineX86</TargetMachine>
     196      <EntryPointSymbol>WinMainStartup_OldWindowsHelper</EntryPointSymbol>
    194197    </Link>
    195198    <Manifest>
     
    232235      <EnableCOMDATFolding>true</EnableCOMDATFolding>
    233236      <TargetMachine>MachineX64</TargetMachine>
     237      <EntryPointSymbol>WinMainStartup_OldWindowsHelper</EntryPointSymbol>
    234238    </Link>
    235239    <Manifest>
Note: See TracChangeset for help on using the changeset viewer.