VirtualBox

Changeset 70336 in vbox for trunk/src


Ignore:
Timestamp:
Dec 24, 2017 2:38:14 PM (7 years ago)
Author:
vboxsync
Message:

iprt/r0drv-nt: Working on NT 3.1 compatibility.

Location:
trunk/src/VBox/Runtime
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r70309 r70336  
    24142414
    24152415RuntimeR0Drv_SOURCES.win.amd64 := $(RuntimeWin64ASM_SOURCES)
    2416 RuntimeR0Drv_SOURCES.win.x86   := $(RuntimeWin32ASM_SOURCES)
     2416RuntimeR0Drv_SOURCES.win.x86   := $(RuntimeWin32ASM_SOURCES) \
     2417        r0drv/nt/nt3fakes-stub-r0drv-nt.cpp
     2418
    24172419
    24182420RuntimeR0Drv_SOURCES.darwin = \
  • trunk/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp

    r70212 r70336  
    110110/** RtlGetVersion, introduced in ??. */
    111111PFNRTRTLGETVERSION                      g_pfnrtRtlGetVersion;
    112 #ifndef RT_ARCH_AMD64
     112#ifdef RT_ARCH_X86
    113113/** KeQueryInterruptTime - exported/new in Windows 2000. */
    114114PFNRTKEQUERYINTERRUPTTIME               g_pfnrtKeQueryInterruptTime;
    115 /** KeQuerySystemTime - exported/new in Windows 2000. */
    116 PFNRTKEQUERYSYSTEMTIME                  g_pfnrtKeQuerySystemTime;
    117115#endif
    118116/** KeQueryInterruptTimePrecise - new in Windows 8. */
     
    129127
    130128/** The combined NT version, see RTNT_MAKE_VERSION. */
    131 uint32_t                                g_uRtNtVersion;
     129uint32_t                                g_uRtNtVersion = RTNT_MAKE_VERSION(4, 0);
    132130/** The major version number. */
    133131uint8_t                                 g_uRtNtMajorVer;
     
    314312
    315313    GET_SYSTEM_ROUTINE_TYPE(RtlGetVersion, PFNRTRTLGETVERSION);
    316 #ifndef RT_ARCH_AMD64
     314#ifdef RT_ARCH_X86
    317315    GET_SYSTEM_ROUTINE(KeQueryInterruptTime);
    318     GET_SYSTEM_ROUTINE(KeQuerySystemTime);
    319316#endif
    320317    GET_SYSTEM_ROUTINE_TYPE(KeQueryInterruptTimePrecise, PFNRTKEQUERYINTERRUPTTIMEPRECISE);
     
    327324    g_puRtMmSystemRangeStart   = (uintptr_t const *)RTR0DbgKrnlInfoGetSymbol(hKrnlInfo, NULL, "MmSystemRangeStart");
    328325
     326#ifdef RT_ARCH_X86
     327    rc = rtR0Nt3InitSymbols(hKrnlInfo);
    329328    RTR0DbgKrnlInfoRelease(hKrnlInfo);
     329    if (RT_FAILURE(rc))
     330        return rc;
     331#else
     332    RTR0DbgKrnlInfoRelease(hKrnlInfo);
     333#endif
    330334
    331335    /*
  • trunk/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h

    r70212 r70336  
    9393
    9494extern PFNRTRTLGETVERSION                      g_pfnrtRtlGetVersion;
    95 #ifndef RT_ARCH_AMD64
     95#ifdef RT_ARCH_X86
    9696extern PFNRTKEQUERYINTERRUPTTIME               g_pfnrtKeQueryInterruptTime;
    97 extern PFNRTKEQUERYSYSTEMTIME                  g_pfnrtKeQuerySystemTime;
    9897#endif
    9998extern PFNRTKEQUERYINTERRUPTTIMEPRECISE        g_pfnrtKeQueryInterruptTimePrecise;
     
    125124DECLHIDDEN(int)  rtR0MpNtInit(struct RTNTSDBOSVER const *pOsVerInfo);
    126125DECLHIDDEN(void) rtR0MpNtTerm(void);
    127 DECLHIDDEN(int) rtMpNtSetTargetProcessorDpc(KDPC *pDpc, RTCPUID idCpu);
     126DECLHIDDEN(int)  rtMpNtSetTargetProcessorDpc(KDPC *pDpc, RTCPUID idCpu);
     127#if defined(RT_ARCH_X86) && defined(NIL_RTDBGKRNLINFO)
     128DECLHIDDEN(int)  rtR0Nt3InitSymbols(RTDBGKRNLINFO hKrnlInfo);
     129#endif
    128130
    129131RT_C_DECLS_END
  • trunk/src/VBox/Runtime/r0drv/nt/nt3fakes-r0drv-nt.cpp

    r70210 r70336  
    2929*   Header Files                                                                                                                 *
    3030*********************************************************************************************************************************/
    31 #define PsGetVersion                PsGetVersion_Nt4Plus
    32 #define ZwQuerySystemInformation    ZwQuerySystemInformation_Nt4Plus
    33 #define KeInitializeTimerEx         KeInitializeTimerEx_Nt4Plus
    34 #define KeSetTimerEx                KeSetTimerEx_Nt4Plus
    35 #define IoAttachDeviceToDeviceStack IoAttachDeviceToDeviceStack_Nt4Plus
    36 #define PsGetCurrentProcessId       PsGetCurrentProcessId_Nt4Plus
    37 #define ZwYieldExecution            ZwYieldExecution_Nt4Plus
    38 
    3931#define _IMAGE_NT_HEADERS           RT_CONCAT(_IMAGE_NT_HEADERS,ARCH_BITS)
    4032#include "the-nt-kernel.h"
     
    4234
    4335#include <iprt/assert.h>
     36#include <iprt/asm.h>
    4437#include <iprt/ctype.h>
     38#include <iprt/dbg.h>
    4539#include <iprt/err.h>
    4640#include <iprt/log.h>
    4741#include <iprt/string.h>
     42#include <iprt/x86.h>
    4843#include <iprt/formats/mz.h>
    4944#include <iprt/formats/pecoff.h>
    5045#include "internal-r0drv-nt.h"
    5146
    52 #undef PsGetVersion
    53 #undef ZwQuerySystemInformation
    54 #undef KeInitializeTimerEx
    55 #undef KeSetTimerEx
    56 #undef IoAttachDeviceToDeviceStack
    57 #undef PsGetCurrentProcessId
    58 #undef ZwYieldExecution
     47
     48/*********************************************************************************************************************************
     49*   Internal Functions                                                                                                           *
     50*********************************************************************************************************************************/
     51DECLASM(void) rtNt3InitSymbolsAssembly(void); /* in nt3fakesA-r0drv-nt.asm */
    5952
    6053
     
    7467static uint32_t         g_cbNt3Hal      = _512K;
    7568static bool volatile    g_fNt3ModuleInfoInitialized = false;
     69
     70
     71RT_C_DECLS_BEGIN
     72/** @name KPIs we provide fallback implementations for.
     73 *
     74 * The assembly init routine will point the __imp_xxx variable to the NT
     75 * implementation if available, using the fallback if not.
     76 * @{  */
     77decltype(PsGetVersion)                     *g_pfnrtPsGetVersion;
     78decltype(ZwQuerySystemInformation)         *g_pfnrtZwQuerySystemInformation;
     79decltype(KeSetTimerEx)                     *g_pfnrtKeSetTimerEx;
     80decltype(IoAttachDeviceToDeviceStack)      *g_pfnrtIoAttachDeviceToDeviceStack;
     81decltype(PsGetCurrentProcessId)            *g_pfnrtPsGetCurrentProcessId;
     82decltype(ZwYieldExecution)                 *g_pfnrtZwYieldExecution;
     83decltype(ExAcquireFastMutex)               *g_pfnrtExAcquireFastMutex;
     84decltype(ExReleaseFastMutex)               *g_pfnrtExReleaseFastMutex;
     85/** @} */
     86
     87/** @name Fastcall optimizations not present in NT 3.1.
     88 *
     89 * We try resolve both the stdcall and fastcall variants and patch it up in
     90 * assembly. The last four routines are in the hal.
     91 *
     92 * @{  */
     93decltype(IofCompleteRequest)               *g_pfnrtIofCompleteRequest;
     94decltype(ObfDereferenceObject)             *g_pfnrtObfDereferenceObject;
     95decltype(IofCallDriver)                    *g_pfnrtIofCallDriver;
     96decltype(KfAcquireSpinLock)                *g_pfnrtKfAcquireSpinLock;
     97decltype(KfReleaseSpinLock)                *g_pfnrtKfReleaseSpinLock;
     98decltype(KfLowerIrql)                      *g_pfnrtKfLowerIrql;
     99decltype(KfRaiseIrql)                      *g_pfnrtKfRaiseIrql;
     100
     101VOID                            (__stdcall *g_pfnrtIoCompleteRequest)(PIRP, CCHAR);
     102LONG_PTR                        (__stdcall *g_pfnrtObDereferenceObject)(PVOID);
     103NTSTATUS                        (__stdcall *g_pfnrtIoCallDriver)(PDEVICE_OBJECT, PIRP);
     104KIRQL                           (__stdcall *g_pfnrtKeAcquireSpinLock)(PKSPIN_LOCK);
     105VOID                            (__stdcall *g_pfnrtKeReleaseSpinLock)(PKSPIN_LOCK, KIRQL);
     106VOID                            (__stdcall *g_pfnrtKeLowerIrql)(KIRQL);
     107KIRQL                           (__stdcall *g_pfnrtKeRaiseIrql)(KIRQL);
     108/** @} */
     109
     110/** @name DATA exports and associated stuff
     111 * @{ */
     112/** Import address table entry for KeTickCount (defined in asm). */
     113extern KSYSTEM_TIME                        *_imp__KeTickCount;
     114/** @} */
     115
     116RT_C_DECLS_END
    76117
    77118
     
    237278/**
    238279 * Figure out the NT 3 version from the registry.
     280 *
     281 * @note this will be called before the rtR0Nt3InitSymbols is called.
    239282 */
    240283static void rtR0Nt3InitVersion(void)
     
    275318
    276319extern "C" DECLEXPORT(BOOLEAN) __stdcall
    277 PsGetVersion(ULONG *puMajor, ULONG *puMinor, ULONG *puBuildNo, UNICODE_STRING *pCsdStr)
     320Nt3Fb_PsGetVersion(ULONG *puMajor, ULONG *puMinor, ULONG *puBuildNo, UNICODE_STRING *pCsdStr)
    278321{
    279322    if (!g_fNt3VersionInitialized)
     
    365408
    366409extern "C" DECLEXPORT(NTSTATUS) __stdcall
    367 ZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS enmClass, PVOID pvBuf, ULONG cbBuf, PULONG pcbActual)
     410Nt3Fb_ZwQuerySystemInformation(SYSTEM_INFORMATION_CLASS enmClass, PVOID pvBuf, ULONG cbBuf, PULONG pcbActual)
    368411{
    369412    switch (enmClass)
     
    415458}
    416459
     460/**
     461 * Calculates the length indicated by an ModR/M sequence.
     462 *
     463 * @returns Length, including RM byte.
     464 * @param   bRm         The RM byte.
     465 */
     466static uint32_t rtR0Nt3CalcModRmLength(uint8_t bRm)
     467{
     468    uint32_t cbRm = 1;
     469
     470    if (   (bRm & X86_MODRM_MOD_MASK) == 3
     471        || (bRm & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5)
     472        cbRm += 4; /* disp32 */
     473    else if ((bRm & X86_MODRM_MOD_MASK) == 1)
     474        cbRm += 1; /* disp8 */
     475    else if ((bRm & X86_MODRM_MOD_MASK) == 2)
     476        cbRm += 2; /* disp16 */
     477
     478    if ((bRm & X86_MODRM_RM_MASK) == 4 && (bRm & X86_MODRM_MOD_MASK) != 3)
     479        cbRm += 1; /* SIB */
     480
     481    return cbRm;
     482}
     483
     484
     485/**
     486 * Init symbols.
     487 *
     488 * This is called after both ZwQuerySystemInformation and PsGetVersion are used
     489 * for the first time.
     490 *
     491 * @returns IPRT status code
     492 * @param   hKrnlInfo           Kernel symbol digger handle.
     493 */
     494DECLHIDDEN(int) rtR0Nt3InitSymbols(RTDBGKRNLINFO hKrnlInfo)
     495{
     496    /*
     497     * Resolve symbols.  (We set C variables (g_pfnrtXxx) here, not the __imp__Xxx ones.)
     498     */
     499#define GET_SYSTEM_ROUTINE(a_fnName) do { \
     500            RT_CONCAT(g_pfnrt, a_fnName) = (decltype(RT_CONCAT(g_pfnrt, a_fnName)))RTR0DbgKrnlInfoGetSymbol(hKrnlInfo, NULL, #a_fnName); \
     501        } while (0)
     502
     503    GET_SYSTEM_ROUTINE(PsGetVersion);
     504    GET_SYSTEM_ROUTINE(ZwQuerySystemInformation);
     505    GET_SYSTEM_ROUTINE(KeSetTimerEx);
     506    GET_SYSTEM_ROUTINE(IoAttachDeviceToDeviceStack);
     507    GET_SYSTEM_ROUTINE(PsGetCurrentProcessId);
     508    GET_SYSTEM_ROUTINE(ZwYieldExecution);
     509    GET_SYSTEM_ROUTINE(ExAcquireFastMutex);
     510    GET_SYSTEM_ROUTINE(ExReleaseFastMutex);
     511
     512#define GET_FAST_CALL_SYSTEM_ROUTINE(a_fnFastcall, a_fnStdcall) do { \
     513            GET_SYSTEM_ROUTINE(a_fnFastcall); \
     514            GET_SYSTEM_ROUTINE(a_fnStdcall); \
     515            AssertLogRelReturn(RT_CONCAT(g_pfnrt,a_fnFastcall) || RT_CONCAT(g_pfnrt,a_fnStdcall), VERR_INTERNAL_ERROR_3); \
     516        } while (0)
     517    GET_FAST_CALL_SYSTEM_ROUTINE(IofCompleteRequest,   IoCompleteRequest);
     518    GET_FAST_CALL_SYSTEM_ROUTINE(ObfDereferenceObject, ObDereferenceObject);
     519    GET_FAST_CALL_SYSTEM_ROUTINE(IofCallDriver,        IofCallDriver);
     520    GET_FAST_CALL_SYSTEM_ROUTINE(KfAcquireSpinLock,    KeAcquireSpinLock);
     521    GET_FAST_CALL_SYSTEM_ROUTINE(KfReleaseSpinLock,    KeReleaseSpinLock);
     522    GET_FAST_CALL_SYSTEM_ROUTINE(KfLowerIrql,          KeLowerIrql);
     523    GET_FAST_CALL_SYSTEM_ROUTINE(KfRaiseIrql,          KeRaiseIrql);
     524
     525    /*
     526     * We need to call assembly to update the __imp__Xxx entries, since C
     527     * doesn't allow '@' in symbols.
     528     */
     529    rtNt3InitSymbolsAssembly();
     530
     531    /*
     532     * Tick count data.  We disassemble KeQueryTickCount until we find the
     533     * first absolute address referenced in it.
     534     *      %80105b70 8b 44 24 04             mov eax, dword [esp+004h]
     535     *      %80105b74 c7 40 04 00 00 00 00    mov dword [eax+004h], 000000000h
     536     *      %80105b7b 8b 0d 88 70 19 80       mov ecx, dword [080197088h]
     537     *      %80105b81 89 08                   mov dword [eax], ecx
     538     *      %80105b83 c2 04 00                retn 00004h
     539     */
     540    _imp__KeTickCount = (decltype(_imp__KeTickCount))RTR0DbgKrnlInfoGetSymbol(hKrnlInfo, NULL, "KeTickCount");
     541    if (!_imp__KeTickCount)
     542    {
     543        Assert(g_uNt3MajorVer == 3 && g_uNt3MinorVer < 50);
     544        uint8_t const *pbCode = (uint8_t const *)RTR0DbgKrnlInfoGetSymbol(hKrnlInfo, NULL, "KeQueryTickCount");
     545        AssertLogRelReturn(pbCode, VERR_INTERNAL_ERROR_2);
     546
     547        for (uint32_t off = 0; off < 128 && _imp__KeTickCount == NULL;)
     548        {
     549            uint8_t const b1 = pbCode[off++];
     550            switch (b1)
     551            {
     552                case 0x89:
     553                    /* mov reg, r/m     ; We're looking for absolute address in r/m. */
     554                    if ((pbCode[off] & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5 /*disp32*/)
     555                        _imp__KeTickCount = *(KSYSTEM_TIME **)&pbCode[off + 1];
     556                    RT_FALL_THRU();
     557                case 0x8b:
     558                    off += rtR0Nt3CalcModRmLength(pbCode[off]);
     559                    break;
     560
     561                case 0xc7:
     562                    if ((pbCode[off] & X86_MODRM_REG_MASK) == 0) /* mov r/m, imm32 */
     563                        off += rtR0Nt3CalcModRmLength(pbCode[off]) + 4;
     564                    else
     565                    {
     566                        RTLogBackdoorPrintf("rtR0Nt3InitSymbols: Failed to find KeTickCount! Encountered unknown opcode at %#x! %.*Rhxs\n",
     567                                            off - 1, RT_MAX(off + 16, RT_MIN(PAGE_SIZE - ((uintptr_t)pbCode & PAGE_OFFSET_MASK), 128)), pbCode);
     568                        return VERR_INTERNAL_ERROR_3;
     569                    }
     570                    break;
     571
     572                case 0xc2: /* ret iw */
     573                    RTLogBackdoorPrintf("rtR0Nt3InitSymbols: Failed to find KeTickCount! Encountered RET! %.*Rhxs\n",
     574                                        off + 2, pbCode);
     575                    return VERR_INTERNAL_ERROR_3;
     576
     577                default:
     578                    RTLogBackdoorPrintf("rtR0Nt3InitSymbols: Failed to find KeTickCount! Encountered unknown opcode at %#x! %.*Rhxs\n",
     579                                        off - 1, RT_MAX(off + 16, RT_MIN(PAGE_SIZE - ((uintptr_t)pbCode & PAGE_OFFSET_MASK), 128)), pbCode);
     580                    return VERR_INTERNAL_ERROR_3;
     581
     582                /* Just in case: */
     583
     584                case 0xa1: /* mov eax, [m32] */
     585                    _imp__KeTickCount = *(KSYSTEM_TIME **)&pbCode[off];
     586                    off += 4;
     587                    break;
     588
     589                case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: /* push reg */
     590                    break;
     591            }
     592        }
     593        if (!_imp__KeTickCount)
     594        {
     595            RTLogBackdoorPrintf("rtR0Nt3InitSymbols: Failed to find KeTickCount after 128 bytes! %.*Rhxs\n", 128, pbCode);
     596            return VERR_INTERNAL_ERROR_3;
     597        }
     598    }
     599
     600    return VINF_SUCCESS;
     601}
     602
    417603
    418604extern "C" DECLEXPORT(VOID)
    419 KeInitializeTimerEx(PKTIMER pTimer, TIMER_TYPE enmType)
     605Nt3Fb_KeInitializeTimerEx(PKTIMER pTimer, TIMER_TYPE enmType)
    420606{
    421607    KeInitializeTimer(pTimer);
     
    427613
    428614extern "C" DECLEXPORT(BOOLEAN) __stdcall
    429 KeSetTimerEx(PKTIMER pTimer, LARGE_INTEGER DueTime, LONG cMsPeriod, PKDPC pDpc)
     615Nt3Fb_KeSetTimerEx(PKTIMER pTimer, LARGE_INTEGER DueTime, LONG cMsPeriod, PKDPC pDpc)
    430616{
    431617    AssertReturn(cMsPeriod == 0, FALSE);
     
    435621
    436622extern "C" DECLEXPORT(PDEVICE_OBJECT)
    437 IoAttachDeviceToDeviceStack(PDEVICE_OBJECT pSourceDevice, PDEVICE_OBJECT pTargetDevice)
     623Nt3Fb_IoAttachDeviceToDeviceStack(PDEVICE_OBJECT pSourceDevice, PDEVICE_OBJECT pTargetDevice)
    438624{
    439625    NOREF(pSourceDevice); NOREF(pTargetDevice);
     
    443629
    444630extern "C" DECLEXPORT(HANDLE)
    445 PsGetCurrentProcessId(void)
     631Nt3Fb_PsGetCurrentProcessId(void)
    446632{
    447633    if (!g_fNt3VersionInitialized)
     
    457643
    458644extern "C" DECLEXPORT(NTSTATUS)
    459 ZwYieldExecution(VOID)
     645Nt3Fb_ZwYieldExecution(VOID)
    460646{
    461647    LARGE_INTEGER Interval;
     
    465651}
    466652
     653
     654/**
     655 * This is a simple implementation of the fast mutex api introduced in 3.50.
     656 */
     657extern "C" DECLEXPORT(VOID) FASTCALL
     658Nt3Fb_ExAcquireFastMutex(PFAST_MUTEX pFastMtx)
     659{
     660    PETHREAD pSelf = PsGetCurrentThread();
     661    KIRQL    OldIrql;
     662    KeRaiseIrql(APC_LEVEL, &OldIrql);
     663
     664    /* The Count member is initialized to 1.  So if we decrement it to zero, we're
     665       the first locker and owns the mutex.  Otherwise we must wait for our turn. */
     666    int32_t  cLockers = ASMAtomicDecS32((int32_t volatile *)&pFastMtx->Count);
     667    if (cLockers != 0)
     668    {
     669        ASMAtomicIncU32((uint32_t volatile *)&pFastMtx->Contention);
     670        KeWaitForSingleObject(&pFastMtx->Event, Executive, KernelMode, FALSE /*fAlertable*/, NULL /*pTimeout*/);
     671    }
     672
     673    pFastMtx->Owner   = (PKTHREAD)pSelf;
     674    pFastMtx->OldIrql = OldIrql;
     675}
     676
     677
     678/**
     679 * This is a simple implementation of the fast mutex api introduced in 3.50.
     680 */
     681extern "C" DECLEXPORT(VOID) FASTCALL
     682Nt3Fb_ExReleaseFastMutex(PFAST_MUTEX pFastMtx)
     683{
     684    AssertMsg(pFastMtx->Owner == (PKTHREAD)PsGetCurrentThread(), ("Owner=%p, expected %p\n", pFastMtx->Owner, PsGetCurrentThread()));
     685
     686    KIRQL    OldIrql  = pFastMtx->OldIrql;
     687    pFastMtx->Owner   = NULL;
     688    int32_t  cLockers = ASMAtomicIncS32((int32_t volatile *)&pFastMtx->Count);
     689    if (cLockers < 0)
     690        KeSetEvent(&pFastMtx->Event, EVENT_INCREMENT, FALSE /*fWait*/);
     691    if (OldIrql != APC_LEVEL)
     692        KeLowerIrql(OldIrql);
     693}
     694
  • trunk/src/VBox/Runtime/r0drv/nt/nt3fakesA-r0drv-nt.asm

    r70192 r70336  
    3030%include "iprt/asmdefs.mac"
    3131
     32%undef NAME
     33%define NAME(name) NAME_OVERLOAD(name)
     34
    3235BEGINCODE
    3336
    34 extern      _PsGetVersion@16
    35 GLOBALNAME _imp__PsGetVersion@16
    36     dd      _PsGetVersion@16
     37;;
     38; Called from rtR0Nt3InitSymbols after symbols have been resolved.
     39BEGINPROC _rtNt3InitSymbolsAssembly
     40        push    ebp
     41        mov     ebp, esp
    3742
    38 extern      _ZwQuerySystemInformation@16
    39 GLOBALNAME _imp__ZwQuerySystemInformation@16
    40     dd      _ZwQuerySystemInformation@16
     43;;
     44; @param 1  The fastcall name.
     45; @param 2  Byte size of arguments.
     46%macro DefineImportDataAndInitCode 3
     47extern          $%1 %+ Nt3Fb_ %+ %2 %+ @ %+ %3
     48BEGINDATA
     49extern          _g_pfnrt %+ %2
     50GLOBALNAME __imp_ %+ %1 %+ %2 %+ @ %+ %3
     51        dd      $%1 %+ Nt3Fb_ %+ %2 %+ @ %+ %3
     52BEGINCODE
     53        mov     eax, [_g_pfnrt %+ %2]
     54        test    eax, eax
     55        jz      %%next
     56        mov     [__imp_ %+ %1 %+ %2 %+ @ %+ %3], eax
     57%%next:
     58%endmacro
    4159
    42 extern      _KeInitializeTimerEx@8
    43 GLOBALNAME _imp__KeInitializeTimerEx@8
    44     dd      _KeInitializeTimerEx@8
     60        DefineImportDataAndInitCode _,PsGetVersion, 16
     61        DefineImportDataAndInitCode _,ZwQuerySystemInformation, 16
     62        DefineImportDataAndInitCode _,KeSetTimerEx, 20
     63        DefineImportDataAndInitCode _,IoAttachDeviceToDeviceStack, 8
     64        DefineImportDataAndInitCode _,PsGetCurrentProcessId, 0
     65        DefineImportDataAndInitCode _,ZwYieldExecution, 0
     66        DefineImportDataAndInitCode @,ExAcquireFastMutex, 4
     67        DefineImportDataAndInitCode @,ExReleaseFastMutex, 4
    4568
    46 extern      _KeSetTimerEx@20
    47 GLOBALNAME _imp__KeSetTimerEx@20
    48     dd      _KeSetTimerEx@20
     69        xor     eax, eax
     70        leave
     71        ret
     72ENDPROC _rtNt3InitSymbolsAssembly
    4973
    50 extern      _IoAttachDeviceToDeviceStack@8
    51 GLOBALNAME _imp__IoAttachDeviceToDeviceStack@8
    52     dd      _IoAttachDeviceToDeviceStack@8
    5374
    54 extern      _PsGetCurrentProcessId@0
    55 GLOBALNAME _imp__PsGetCurrentProcessId@0
    56     dd      _PsGetCurrentProcessId@0
     75;;
     76; @param 1  The fastcall name.
     77; @param 2  The stdcall name.
     78; @param 3  Byte size of arguments.
     79%macro FastOrStdCallWrapper 3
     80BEGINCODE
     81extern _g_pfnrt %+ %1
     82extern _g_pfnrt %+ %2
     83BEGINPROC_EXPORTED $@ %+ %1 %+ @ %+ %3
     84        mov     eax, [_g_pfnrt %+ %1]
     85        cmp     eax, 0
     86        jnz     .got_fast_call
     87        mov     eax, .stdcall_wrapper
     88        mov     [__imp_@ %+ %1 %+ @ %+ %3], eax
    5789
    58 extern      _ZwYieldExecution@0
    59 GLOBALNAME _imp__ZwYieldExecution@0
    60     dd      _ZwYieldExecution@0
     90.stdcall_wrapper:
     91        push    ebp
     92        mov     ebp, esp
     93        push    edx
     94        push    ecx
     95        call    [_g_pfnrt %+ %2]
     96        leave
     97        ret
    6198
     99.got_fast_call:
     100        mov     [__imp_@ %+ %1 %+ @ %+ %3], eax
     101        jmp     eax
     102ENDPROC $@ %+ %1 %+ @ %+ %3
     103
     104BEGINDATA
     105GLOBALNAME __imp_@ %+ %1 %+ @ %+ %3
     106        dd       $@ %+ %1 %+ @ %+ %3
     107%endmacro
     108
     109FastOrStdCallWrapper IofCompleteRequest, IoCompleteRequest, 8
     110FastOrStdCallWrapper IofCallDriver, IoCallDriver, 8
     111FastOrStdCallWrapper ObfDereferenceObject, ObDereferenceObject, 4
     112FastOrStdCallWrapper KfAcquireSpinLock, KeAcquireSpinLock, 4
     113FastOrStdCallWrapper KfReleaseSpinLock, KeReleaseSpinLock, 8
     114FastOrStdCallWrapper KfLowerIrql, KeLowerIrql, 4
     115FastOrStdCallWrapper KfRaiseIrql, KeRaiseIrql, 4
     116
     117
     118BEGINCODE
     119; LONG FASTCALL InterlockedExchange(LONG volatile *,LONG );
     120BEGINPROC_EXPORTED $@InterlockedExchange@8
     121        mov     eax, edx
     122        xchg    [ecx], eax
     123        ret
     124
     125BEGINDATA
     126GLOBALNAME __imp_@InterlockedExchange@8
     127        dd      $@InterlockedExchange@8
     128
     129
     130BEGINDATA
     131GLOBALNAME __imp__KeTickCount
     132GLOBALNAME _KeTickCount
     133        dd      0
     134
     135
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette