VirtualBox

Changeset 71131 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Feb 26, 2018 7:27:32 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
121017
Message:

VMM/NEM/win: Code for discovering VID I/O control functions (for logging and issue them in ring-0). bugref:9044 [build fix]

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r71129 r71131  
    7878    ( ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K) || ((RTGCPHYS)(a_GCPhys) < (RTGCPHYS)_64K) )
    7979
    80 
    81 
    82 /*********************************************************************************************************************************
    83 *   Structures and Typedefs                                                                                                      *
    84 *********************************************************************************************************************************/
     80/** VID I/O control detection: Fake partition handle input. */
     81#define NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE          ((HANDLE)(uintptr_t)38479125)
     82/** VID I/O control detection: Fake partition ID return. */
     83#define NEM_WIN_IOCTL_DETECTOR_FAKE_PARTITION_ID    UINT64_C(0xfa1e000042424242)
     84/** VID I/O control detection: Fake CPU index input. */
     85#define NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX        UINT32_C(42)
     86/** VID I/O control detection: Fake timeout input. */
     87#define NEM_WIN_IOCTL_DETECTOR_FAKE_TIMEOUT         UINT32_C(0x00080286)
    8588
    8689
     
    118121static decltype(VidMessageSlotHandleAndGetNext)    *g_pfnVidMessageSlotHandleAndGetNext;
    119122#ifdef LOG_ENABLED
     123static decltype(VidGetVirtualProcessorState)       *g_pfnVidGetVirtualProcessorState;
     124static decltype(VidSetVirtualProcessorState)       *g_pfnVidSetVirtualProcessorState;
    120125static decltype(VidGetVirtualProcessorRunningStatus) *g_pfnVidGetVirtualProcessorRunningStatus;
    121126#endif
     
    159164    NEM_WIN_IMPORT(1, false, VidStopVirtualProcessor),
    160165#ifdef LOG_ENABLED
     166    NEM_WIN_IMPORT(1, false, VidGetVirtualProcessorState),
     167    NEM_WIN_IMPORT(1, false, VidSetVirtualProcessorState),
    161168    NEM_WIN_IMPORT(1, false, VidGetVirtualProcessorRunningStatus),
    162169#endif
    163170#undef NEM_WIN_IMPORT
    164171};
     172
     173
     174/** The real NtDeviceIoControlFile API in NTDLL.   */
     175static decltype(NtDeviceIoControlFile) *g_pfnNtDeviceIoControlFile;
     176/** Pointer to the NtDeviceIoControlFile import table entry. */
     177static decltype(NtDeviceIoControlFile) **g_ppfnVidNtDeviceIoControlFile;
     178/** Info about the VidGetHvPartitionId I/O control interface. */
     179static NEMWINIOCTL g_IoCtlGetHvPartitionId;
     180/** Info about the VidStartVirtualProcessor I/O control interface. */
     181static NEMWINIOCTL g_IoCtlStartVirtualProcessor;
     182/** Info about the VidStopVirtualProcessor I/O control interface. */
     183static NEMWINIOCTL g_IoCtlStopVirtualProcessor;
     184/** Info about the VidMessageSlotHandleAndGetNext I/O control interface. */
     185static NEMWINIOCTL g_IoCtlMessageSlotHandleAndGetNext;
     186#ifdef LOG_ENABLED
     187/** Info about the VidMessageSlotMap I/O control interface - for logging. */
     188static NEMWINIOCTL g_IoCtlMessageSlotMap;
     189/* Info about the VidGetVirtualProcessorState I/O control interface - for logging. */
     190static NEMWINIOCTL g_IoCtlGetVirtualProcessorState;
     191/* Info about the VidSetVirtualProcessorState I/O control interface - for logging. */
     192static NEMWINIOCTL g_IoCtlSetVirtualProcessorState;
     193/** Pointer to what nemR3WinIoctlDetector_ForLogging should fill in. */
     194static NEMWINIOCTL *g_pIoCtlDetectForLogging;
     195#endif
     196
     197#ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS
     198/** Mapping slot for CPU #0.
     199 * @{  */
     200static VID_MESSAGE_MAPPING_HEADER            *g_pMsgSlotMapping = NULL;
     201static const HV_MESSAGE_HEADER               *g_pHvMsgHdr;
     202static const HV_X64_INTERCEPT_MESSAGE_HEADER *g_pX64MsgHdr;
     203/** @} */
     204#endif
    165205
    166206
     
    200240
    201241
     242
    202243#ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS
    203 
    204 /** The real NtDeviceIoControlFile API in NTDLL.   */
    205 static decltype(NtDeviceIoControlFile)       *g_pfnNtDeviceIoControlFile;
    206 /** Mapping slot for CPU #0.
    207  * @{  */
    208 static VID_MESSAGE_MAPPING_HEADER            *g_pMsgSlotMapping = NULL;
    209 static const HV_MESSAGE_HEADER               *g_pHvMsgHdr;
    210 static const HV_X64_INTERCEPT_MESSAGE_HEADER *g_pX64MsgHdr;
    211 /** @} */
    212 
    213 
    214244/**
    215245 * Wrapper that logs the call from VID.DLL.
     
    222252                                         PVOID pvOutput, ULONG cbOutput)
    223253{
     254
    224255    char szFunction[32];
    225256    const char *pszFunction;
    226     switch (uFunction)
    227     {
    228         case 0x2210cb: pszFunction = "VidMessageSlotHandleAndGetNext"; break;
    229         case 0x2210cc: pszFunction = "VidMessageSlotMap"; break;
    230         case 0x221164: pszFunction = "VidStopVirtualProcessor"; break;
    231         case 0x221158: pszFunction = "VidStartVirtualProcessor"; break;
    232         case 0x2210a7: pszFunction = "VidGetVirtualProcessorState"; break;
    233         case 0x221153: pszFunction = "VidSetVirtualProcessorState"; break;
    234         default:
    235             RTStrPrintf(szFunction, sizeof(szFunction), "%#x", uFunction);
    236             pszFunction = szFunction;
    237             break;
     257    if (uFunction == g_IoCtlMessageSlotHandleAndGetNext.uFunction)
     258        pszFunction = "VidMessageSlotHandleAndGetNext";
     259    else if (uFunction == g_IoCtlStartVirtualProcessor.uFunction)
     260        pszFunction = "VidStartVirtualProcessor";
     261    else if (uFunction == g_IoCtlStopVirtualProcessor.uFunction)
     262        pszFunction = "VidStopVirtualProcessor";
     263    else if (uFunction == g_IoCtlMessageSlotMap.uFunction)
     264        pszFunction = "VidMessageSlotMap";
     265    else if (uFunction == g_IoCtlGetVirtualProcessorState.uFunction)
     266        pszFunction = "VidGetVirtualProcessorState";
     267    else if (uFunction == g_IoCtlSetVirtualProcessorState.uFunction)
     268        pszFunction = "VidSetVirtualProcessorState";
     269    else
     270    {
     271        RTStrPrintf(szFunction, sizeof(szFunction), "%#x", uFunction);
     272        pszFunction = szFunction;
    238273    }
    239274
     
    260295        }
    261296    }
    262     if (g_pMsgSlotMapping && (uFunction == 0x2210cb || uFunction == 0x2210cc || uFunction == 0x221164))
     297    if (   g_pMsgSlotMapping
     298        && (   uFunction == g_IoCtlMessageSlotHandleAndGetNext.uFunction
     299            || uFunction == g_IoCtlStopVirtualProcessor.uFunction
     300            || uFunction == g_IoCtlMessageSlotMap.uFunction
     301               ))
    263302        Log12(("VID!NtDeviceIoControlFile: enmVidMsgType=%#x cb=%#x msg=%#x payload=%u cs:rip=%04x:%08RX64 (%s)\n",
    264303               g_pMsgSlotMapping->enmVidMsgType, g_pMsgSlotMapping->cbMessage,
     
    268307    return rcNt;
    269308}
     309#endif /* NEM_WIN_INTERCEPT_NT_IO_CTLS */
    270310
    271311
    272312/**
    273  * Patches the call table of VID.DLL so we can intercept and log
    274  * NtDeviceIoControlFile.
    275  *
    276  * This is for DEBUGGING only.
    277  *
     313 * Patches the call table of VID.DLL so we can intercept NtDeviceIoControlFile.
     314 *
     315 * This is for used to figure out the I/O control codes and in logging builds
     316 * for logging API calls that WinHvPlatform.dll does.
     317 *
     318 * @returns VBox status code.
    278319 * @param   hLdrModVid      The VID module handle.
    279  */
    280 static void nemR3WinInitVidIntercepts(RTLDRMOD hLdrModVid)
     320 * @param   pErrInfo        Where to return additional error information.
     321 */
     322static int nemR3WinInitVidIntercepts(RTLDRMOD hLdrModVid, PRTERRINFO pErrInfo)
    281323{
    282324    /*
     
    284326     */
    285327    g_pfnNtDeviceIoControlFile = (decltype(NtDeviceIoControlFile) *)RTLdrGetSystemSymbol("NTDLL.DLL", "NtDeviceIoControlFile");
    286     AssertReturnVoid(g_pfnNtDeviceIoControlFile > 0);
     328    AssertReturn(g_pfnNtDeviceIoControlFile != NULL,
     329                 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "Failed to resolve NtDeviceIoControlFile from NTDLL.DLL"));
    287330
    288331    /*
     
    291334    uint8_t const *pbImage = (uint8_t const *)RTLdrGetNativeHandle(hLdrModVid);
    292335    IMAGE_DOS_HEADER const *pMzHdr  = (IMAGE_DOS_HEADER const *)pbImage;
    293     AssertReturnVoid(pMzHdr->e_magic == IMAGE_DOS_SIGNATURE);
     336    AssertReturn(pMzHdr->e_magic == IMAGE_DOS_SIGNATURE,
     337                 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL mapping doesn't start with MZ signature: %#x", pMzHdr->e_magic));
    294338    IMAGE_NT_HEADERS const *pNtHdrs = (IMAGE_NT_HEADERS const *)&pbImage[pMzHdr->e_lfanew];
    295     AssertReturnVoid(pNtHdrs->Signature == IMAGE_NT_SIGNATURE);
     339    AssertReturn(pNtHdrs->Signature == IMAGE_NT_SIGNATURE,
     340                 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL has invalid PE signaturre: %#x @%#x",
     341                               pNtHdrs->Signature, pMzHdr->e_lfanew));
    296342
    297343    uint32_t const             cbImage   = pNtHdrs->OptionalHeader.SizeOfImage;
     
    301347     * Walk the import descriptor table looking for NTDLL.DLL.
    302348     */
    303     bool fSuccess = true;
    304     AssertReturnVoid(ImportDir.Size > 0);
    305     AssertReturnVoid(ImportDir.Size < cbImage);
    306     AssertReturnVoid(ImportDir.VirtualAddress > 0);
    307     AssertReturnVoid(ImportDir.VirtualAddress < cbImage);
     349    AssertReturn(   ImportDir.Size > 0
     350                 && ImportDir.Size < cbImage,
     351                 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL bad import directory size: %#x", ImportDir.Size));
     352    AssertReturn(   ImportDir.VirtualAddress > 0
     353                 && ImportDir.VirtualAddress <= cbImage - ImportDir.Size,
     354                 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL bad import directory RVA: %#x", ImportDir.VirtualAddress));
     355
    308356    for (PIMAGE_IMPORT_DESCRIPTOR pImps = (PIMAGE_IMPORT_DESCRIPTOR)&pbImage[ImportDir.VirtualAddress];
    309357         pImps->Name != 0 && pImps->FirstThunk != 0;
    310358         pImps++)
    311359    {
    312         AssertReturnVoid(pImps->Name < cbImage);
     360        AssertReturn(pImps->Name < cbImage,
     361                     RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL bad import directory entry name: %#x", pImps->Name));
    313362        const char *pszModName = (const char *)&pbImage[pImps->Name];
    314363        if (RTStrICmpAscii(pszModName, "ntdll.dll"))
    315364            continue;
    316         AssertReturnVoid(pImps->FirstThunk < cbImage);
    317         AssertReturnVoid(pImps->OriginalFirstThunk < cbImage);
     365        AssertReturn(pImps->FirstThunk < cbImage,
     366                     RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL bad FirstThunk: %#x", pImps->FirstThunk));
     367        AssertReturn(pImps->OriginalFirstThunk < cbImage,
     368                     RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL bad FirstThunk: %#x", pImps->FirstThunk));
    318369
    319370        /*
     
    328379            if (!(pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32))
    329380            {
    330                 AssertReturnVoid(pThunk->u1.Ordinal > 0 && pThunk->u1.Ordinal < cbImage);
     381                AssertReturn(pThunk->u1.Ordinal > 0 && pThunk->u1.Ordinal < cbImage,
     382                             RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL bad FirstThunk: %#x", pImps->FirstThunk));
    331383
    332384                const char *pszSymbol = (const char *)&pbImage[(uintptr_t)pThunk->u1.AddressOfData + 2];
    333385                if (strcmp(pszSymbol, "NtDeviceIoControlFile") == 0)
    334386                {
    335                     DWORD fOldProt = PAGE_EXECUTE;
     387                    DWORD fOldProt = PAGE_READONLY;
    336388                    VirtualProtect(&pFirstThunk->u1.Function, sizeof(uintptr_t), PAGE_EXECUTE_READWRITE, &fOldProt);
    337                     pFirstThunk->u1.Function = (uintptr_t)nemR3WinLogWrapper_NtDeviceIoControlFile;
    338                     VirtualProtect(&pFirstThunk->u1.Function, sizeof(uintptr_t), fOldProt, &fOldProt);
    339                     fSuccess = true;
     389                    g_ppfnVidNtDeviceIoControlFile = (decltype(NtDeviceIoControlFile) **)&pFirstThunk->u1.Function;
     390                    /* Don't restore the protection here, so we modify the NtDeviceIoControlFile pointer later. */
    340391                }
    341392            }
     
    345396        }
    346397    }
    347     Assert(fSuccess);
    348 }
    349 
    350 #endif /* NEM_WIN_INTERCEPT_NT_IO_CTLS */
     398
     399    if (*g_ppfnVidNtDeviceIoControlFile)
     400    {
     401#ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS
     402        *g_ppfnVidNtDeviceIoControlFile = nemR3WinLogWrapper_NtDeviceIoControlFile;
     403#endif
     404        return VINF_SUCCESS;
     405    }
     406    return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "Failed to patch NtDeviceIoControlFile import in VID.DLL!");
     407}
    351408
    352409
     
    426483    }
    427484    if (RT_SUCCESS(rc))
    428     {
    429 #ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS
    430         nemR3WinInitVidIntercepts(ahMods[1]);
    431 #endif
     485        rc = nemR3WinInitVidIntercepts(ahMods[1], pErrInfo);
     486    if (RT_SUCCESS(rc))
     487    {
    432488        for (unsigned i = 0; i < RT_ELEMENTS(g_aImports); i++)
    433489        {
     
    453509        }
    454510        if (RT_SUCCESS(rc))
     511        {
    455512            Assert(!RTErrInfoIsSet(pErrInfo));
     513        }
    456514    }
    457515
     
    675733
    676734/**
     735 * Used to fill in g_IoCtlGetHvPartitionId.
     736 */
     737static NTSTATUS WINAPI
     738nemR3WinIoctlDetector_GetHvPartitionId(HANDLE hFile, HANDLE hEvt, PIO_APC_ROUTINE pfnApcCallback, PVOID pvApcCtx,
     739                                       PIO_STATUS_BLOCK pIos, ULONG uFunction, PVOID pvInput, ULONG cbInput,
     740                                       PVOID pvOutput, ULONG cbOutput)
     741{
     742    AssertLogRelMsgReturn(hFile == NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, ("hFile=%p\n", hFile), STATUS_INVALID_PARAMETER_1);
     743    RT_NOREF(hEvt); RT_NOREF(pfnApcCallback); RT_NOREF(pvApcCtx);
     744    AssertLogRelMsgReturn(RT_VALID_PTR(pIos), ("pIos=%p\n", pIos), STATUS_INVALID_PARAMETER_5);
     745    AssertLogRelMsgReturn(cbInput == 0, ("cbInput=%#x\n", cbInput), STATUS_INVALID_PARAMETER_8);
     746    RT_NOREF(pvInput);
     747
     748    AssertLogRelMsgReturn(RT_VALID_PTR(pvOutput), ("pvOutput=%p\n", pvOutput), STATUS_INVALID_PARAMETER_9);
     749    AssertLogRelMsgReturn(cbOutput == sizeof(HV_PARTITION_ID), ("cbInput=%#x\n", cbInput), STATUS_INVALID_PARAMETER_10);
     750    *(HV_PARTITION_ID *)pvOutput = NEM_WIN_IOCTL_DETECTOR_FAKE_PARTITION_ID;
     751
     752    g_IoCtlGetHvPartitionId.cbInput   = cbInput;
     753    g_IoCtlGetHvPartitionId.cbOutput  = cbOutput;
     754    g_IoCtlGetHvPartitionId.uFunction = uFunction;
     755
     756    return STATUS_SUCCESS;
     757}
     758
     759
     760/**
     761 * Used to fill in g_IoCtlStartVirtualProcessor.
     762 */
     763static NTSTATUS WINAPI
     764nemR3WinIoctlDetector_StartVirtualProcessor(HANDLE hFile, HANDLE hEvt, PIO_APC_ROUTINE pfnApcCallback, PVOID pvApcCtx,
     765                                            PIO_STATUS_BLOCK pIos, ULONG uFunction, PVOID pvInput, ULONG cbInput,
     766                                            PVOID pvOutput, ULONG cbOutput)
     767{
     768    AssertLogRelMsgReturn(hFile == NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, ("hFile=%p\n", hFile), STATUS_INVALID_PARAMETER_1);
     769    RT_NOREF(hEvt); RT_NOREF(pfnApcCallback); RT_NOREF(pvApcCtx);
     770    AssertLogRelMsgReturn(RT_VALID_PTR(pIos), ("pIos=%p\n", pIos), STATUS_INVALID_PARAMETER_5);
     771    AssertLogRelMsgReturn(cbInput == sizeof(HV_VP_INDEX), ("cbInput=%#x\n", cbInput), STATUS_INVALID_PARAMETER_8);
     772    AssertLogRelMsgReturn(RT_VALID_PTR(pvInput), ("pvInput=%p\n", pvInput), STATUS_INVALID_PARAMETER_9);
     773    AssertLogRelMsgReturn(*(HV_VP_INDEX *)pvInput == NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX,
     774                          ("*piCpu=%u\n", *(HV_VP_INDEX *)pvInput), STATUS_INVALID_PARAMETER_9);
     775    AssertLogRelMsgReturn(cbOutput == 0, ("cbInput=%#x\n", cbInput), STATUS_INVALID_PARAMETER_10);
     776    RT_NOREF(pvOutput);
     777
     778    g_IoCtlStartVirtualProcessor.cbInput   = cbInput;
     779    g_IoCtlStartVirtualProcessor.cbOutput  = cbOutput;
     780    g_IoCtlStartVirtualProcessor.uFunction = uFunction;
     781
     782    return STATUS_SUCCESS;
     783}
     784
     785
     786/**
     787 * Used to fill in g_IoCtlStartVirtualProcessor.
     788 */
     789static NTSTATUS WINAPI
     790nemR3WinIoctlDetector_StopVirtualProcessor(HANDLE hFile, HANDLE hEvt, PIO_APC_ROUTINE pfnApcCallback, PVOID pvApcCtx,
     791                                           PIO_STATUS_BLOCK pIos, ULONG uFunction, PVOID pvInput, ULONG cbInput,
     792                                           PVOID pvOutput, ULONG cbOutput)
     793{
     794    AssertLogRelMsgReturn(hFile == NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, ("hFile=%p\n", hFile), STATUS_INVALID_PARAMETER_1);
     795    RT_NOREF(hEvt); RT_NOREF(pfnApcCallback); RT_NOREF(pvApcCtx);
     796    AssertLogRelMsgReturn(RT_VALID_PTR(pIos), ("pIos=%p\n", pIos), STATUS_INVALID_PARAMETER_5);
     797    AssertLogRelMsgReturn(cbInput == sizeof(HV_VP_INDEX), ("cbInput=%#x\n", cbInput), STATUS_INVALID_PARAMETER_8);
     798    AssertLogRelMsgReturn(RT_VALID_PTR(pvInput), ("pvInput=%p\n", pvInput), STATUS_INVALID_PARAMETER_9);
     799    AssertLogRelMsgReturn(*(HV_VP_INDEX *)pvInput == NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX,
     800                          ("*piCpu=%u\n", *(HV_VP_INDEX *)pvInput), STATUS_INVALID_PARAMETER_9);
     801    AssertLogRelMsgReturn(cbOutput == 0, ("cbInput=%#x\n", cbInput), STATUS_INVALID_PARAMETER_10);
     802    RT_NOREF(pvOutput);
     803
     804    g_IoCtlStopVirtualProcessor.cbInput   = cbInput;
     805    g_IoCtlStopVirtualProcessor.cbOutput  = cbOutput;
     806    g_IoCtlStopVirtualProcessor.uFunction = uFunction;
     807
     808    return STATUS_SUCCESS;
     809}
     810
     811
     812/**
     813 * Used to fill in g_IoCtlMessageSlotHandleAndGetNext
     814 */
     815static NTSTATUS WINAPI
     816nemR3WinIoctlDetector_MessageSlotHandleAndGetNext(HANDLE hFile, HANDLE hEvt, PIO_APC_ROUTINE pfnApcCallback, PVOID pvApcCtx,
     817                                                  PIO_STATUS_BLOCK pIos, ULONG uFunction, PVOID pvInput, ULONG cbInput,
     818                                                  PVOID pvOutput, ULONG cbOutput)
     819{
     820    AssertLogRelMsgReturn(hFile == NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, ("hFile=%p\n", hFile), STATUS_INVALID_PARAMETER_1);
     821    RT_NOREF(hEvt); RT_NOREF(pfnApcCallback); RT_NOREF(pvApcCtx);
     822    AssertLogRelMsgReturn(RT_VALID_PTR(pIos), ("pIos=%p\n", pIos), STATUS_INVALID_PARAMETER_5);
     823
     824    AssertLogRelMsgReturn(cbInput == sizeof(VID_IOCTL_INPUT_MESSAGE_SLOT_HANDLE_AND_GET_NEXT), ("cbInput=%#x\n", cbInput),
     825                          STATUS_INVALID_PARAMETER_8);
     826    AssertLogRelMsgReturn(RT_VALID_PTR(pvInput), ("pvInput=%p\n", pvInput), STATUS_INVALID_PARAMETER_9);
     827    PCVID_IOCTL_INPUT_MESSAGE_SLOT_HANDLE_AND_GET_NEXT pVidIn = (PCVID_IOCTL_INPUT_MESSAGE_SLOT_HANDLE_AND_GET_NEXT)pvInput;
     828    AssertLogRelMsgReturn(   pVidIn->iCpu == NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX
     829                          && pVidIn->fFlags == VID_MSHAGN_F_HANDLE_MESSAGE
     830                          && pVidIn->cMillies == NEM_WIN_IOCTL_DETECTOR_FAKE_TIMEOUT,
     831                          ("iCpu=%u fFlags=%#x cMillies=%#x\n", pVidIn->iCpu, pVidIn->fFlags, pVidIn->cMillies),
     832                          STATUS_INVALID_PARAMETER_9);
     833    AssertLogRelMsgReturn(cbOutput == 0, ("cbInput=%#x\n", cbInput), STATUS_INVALID_PARAMETER_10);
     834    RT_NOREF(pvOutput);
     835
     836    g_IoCtlMessageSlotHandleAndGetNext.cbInput   = cbInput;
     837    g_IoCtlMessageSlotHandleAndGetNext.cbOutput  = cbOutput;
     838    g_IoCtlMessageSlotHandleAndGetNext.uFunction = uFunction;
     839
     840    return STATUS_SUCCESS;
     841}
     842
     843
     844#ifdef LOG_ENABLED
     845/**
     846 * Used to fill in what g_pIoCtlDetectForLogging points to.
     847 */
     848static NTSTATUS WINAPI nemR3WinIoctlDetector_ForLogging(HANDLE hFile, HANDLE hEvt, PIO_APC_ROUTINE pfnApcCallback, PVOID pvApcCtx,
     849                                                        PIO_STATUS_BLOCK pIos, ULONG uFunction, PVOID pvInput, ULONG cbInput,
     850                                                        PVOID pvOutput, ULONG cbOutput)
     851{
     852    RT_NOREF(hFile, hEvt, pfnApcCallback, pvApcCtx, pIos, pvInput, pvOutput);
     853
     854    g_pIoCtlDetectForLogging->cbInput   = cbInput;
     855    g_pIoCtlDetectForLogging->cbOutput  = cbOutput;
     856    g_pIoCtlDetectForLogging->uFunction = uFunction;
     857
     858    return STATUS_SUCCESS;
     859}
     860#endif
     861
     862
     863/**
     864 * Worker for nemR3NativeInit that detect I/O control function numbers for VID.
     865 *
     866 * We use the function numbers directly in ring-0 and to name functions when
     867 * logging NtDeviceIoControlFile calls.
     868 *
     869 * @note    We could alternatively do this by disassembling the respective
     870 *          functions, but hooking NtDeviceIoControlFile and making fake calls
     871 *          more easily provides the desired information.
     872 *
     873 * @returns VBox status code.
     874 * @param   pVM                 The cross context VM structure.  Will set I/O
     875 *                              control info members.
     876 * @param   pErrInfo            Where to always return error info.
     877 */
     878static int nemR3WinInitDiscoverIoControlProperties(PVM pVM, PRTERRINFO pErrInfo)
     879{
     880    /*
     881     * Probe the I/O control information for select VID APIs so we can use
     882     * them directly from ring-0 and better log them.
     883     *
     884     */
     885    decltype(NtDeviceIoControlFile) * const pfnOrg = *g_ppfnVidNtDeviceIoControlFile;
     886
     887    /* VidGetHvPartitionId */
     888    *g_ppfnVidNtDeviceIoControlFile = nemR3WinIoctlDetector_GetHvPartitionId;
     889    HV_PARTITION_ID idHvPartition = HV_PARTITION_ID_INVALID;
     890    BOOL fRet = g_pfnVidGetHvPartitionId(NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, &idHvPartition);
     891    *g_ppfnVidNtDeviceIoControlFile = pfnOrg;
     892    AssertReturn(fRet && idHvPartition == NEM_WIN_IOCTL_DETECTOR_FAKE_PARTITION_ID && g_IoCtlGetHvPartitionId.uFunction != 0,
     893                 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED,
     894                               "Problem figuring out VidGetHvPartitionId: fRet=%u idHvPartition=%#x dwErr=%u",
     895                               fRet, idHvPartition, GetLastError()) );
     896    LogRel(("NEM: VidGetHvPartitionId            -> fun:%#x in:%#x out:%#x\n",
     897            g_IoCtlGetHvPartitionId.uFunction, g_IoCtlGetHvPartitionId.cbInput, g_IoCtlGetHvPartitionId.cbOutput));
     898
     899    /* VidStartVirtualProcessor */
     900    *g_ppfnVidNtDeviceIoControlFile = nemR3WinIoctlDetector_StartVirtualProcessor;
     901    fRet = g_pfnVidStartVirtualProcessor(NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX);
     902    *g_ppfnVidNtDeviceIoControlFile = pfnOrg;
     903    AssertReturn(fRet && g_IoCtlStartVirtualProcessor.uFunction != 0,
     904                 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED,
     905                               "Problem figuring out VidStartVirtualProcessor: fRet=%u dwErr=%u",
     906                               fRet, GetLastError()) );
     907    LogRel(("NEM: VidStartVirtualProcessor       -> fun:%#x in:%#x out:%#x\n", g_IoCtlStartVirtualProcessor.uFunction,
     908            g_IoCtlStartVirtualProcessor.cbInput, g_IoCtlStartVirtualProcessor.cbOutput));
     909
     910    /* VidStopVirtualProcessor */
     911    *g_ppfnVidNtDeviceIoControlFile = nemR3WinIoctlDetector_StopVirtualProcessor;
     912    fRet = g_pfnVidStopVirtualProcessor(NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX);
     913    *g_ppfnVidNtDeviceIoControlFile = pfnOrg;
     914    AssertReturn(fRet && g_IoCtlStopVirtualProcessor.uFunction != 0,
     915                 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED,
     916                               "Problem figuring out VidStopVirtualProcessor: fRet=%u dwErr=%u",
     917                               fRet, GetLastError()) );
     918    LogRel(("NEM: VidStopVirtualProcessor        -> fun:%#x in:%#x out:%#x\n", g_IoCtlStopVirtualProcessor.uFunction,
     919            g_IoCtlStopVirtualProcessor.cbInput, g_IoCtlStopVirtualProcessor.cbOutput));
     920
     921    /* VidMessageSlotHandleAndGetNext */
     922    *g_ppfnVidNtDeviceIoControlFile = nemR3WinIoctlDetector_MessageSlotHandleAndGetNext;
     923    fRet = g_pfnVidMessageSlotHandleAndGetNext(NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE,
     924                                               NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX, VID_MSHAGN_F_HANDLE_MESSAGE,
     925                                               NEM_WIN_IOCTL_DETECTOR_FAKE_TIMEOUT);
     926    *g_ppfnVidNtDeviceIoControlFile = pfnOrg;
     927    AssertReturn(fRet && g_IoCtlMessageSlotHandleAndGetNext.uFunction != 0,
     928                 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED,
     929                               "Problem figuring out VidMessageSlotHandleAndGetNext: fRet=%u dwErr=%u",
     930                               fRet, GetLastError()) );
     931    LogRel(("NEM: VidMessageSlotHandleAndGetNext -> fun:%#x in:%#x out:%#x\n",
     932            g_IoCtlMessageSlotHandleAndGetNext.uFunction, g_IoCtlMessageSlotHandleAndGetNext.cbInput,
     933            g_IoCtlMessageSlotHandleAndGetNext.cbOutput));
     934
     935#ifdef LOG_ENABLED
     936    /* The following are only for logging: */
     937    union
     938    {
     939        VID_MAPPED_MESSAGE_SLOT MapSlot;
     940        HV_REGISTER_NAME        Name;
     941        HV_REGISTER_VALUE       Value;
     942    } uBuf;
     943
     944    /* VidMessageSlotMap */
     945    g_pIoCtlDetectForLogging = &g_IoCtlMessageSlotMap;
     946    *g_ppfnVidNtDeviceIoControlFile = nemR3WinIoctlDetector_ForLogging;
     947    fRet = g_pfnVidMessageSlotMap(NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, &uBuf.MapSlot, NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX);
     948    *g_ppfnVidNtDeviceIoControlFile = pfnOrg;
     949    Assert(fRet);
     950    LogRel(("NEM: VidMessageSlotMap              -> fun:%#x in:%#x out:%#x\n", g_pIoCtlDetectForLogging->uFunction,
     951            g_pIoCtlDetectForLogging->cbInput, g_pIoCtlDetectForLogging->cbOutput));
     952
     953    /* VidGetVirtualProcessorState */
     954    uBuf.Name = HvRegisterExplicitSuspend;
     955    g_pIoCtlDetectForLogging = &g_IoCtlGetVirtualProcessorState;
     956    *g_ppfnVidNtDeviceIoControlFile = nemR3WinIoctlDetector_ForLogging;
     957    fRet = g_pfnVidGetVirtualProcessorState(NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX,
     958                                            &uBuf.Name, 1, &uBuf.Value);
     959    *g_ppfnVidNtDeviceIoControlFile = pfnOrg;
     960    Assert(fRet);
     961    LogRel(("NEM: VidGetVirtualProcessorState    -> fun:%#x in:%#x out:%#x\n", g_pIoCtlDetectForLogging->uFunction,
     962            g_pIoCtlDetectForLogging->cbInput, g_pIoCtlDetectForLogging->cbOutput));
     963
     964    /* VidSetVirtualProcessorState */
     965    uBuf.Name = HvRegisterExplicitSuspend;
     966    g_pIoCtlDetectForLogging = &g_IoCtlSetVirtualProcessorState;
     967    *g_ppfnVidNtDeviceIoControlFile = nemR3WinIoctlDetector_ForLogging;
     968    fRet = g_pfnVidSetVirtualProcessorState(NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX,
     969                                            &uBuf.Name, 1, &uBuf.Value);
     970    *g_ppfnVidNtDeviceIoControlFile = pfnOrg;
     971    Assert(fRet);
     972    LogRel(("NEM: VidSetVirtualProcessorState    -> fun:%#x in:%#x out:%#x\n", g_pIoCtlDetectForLogging->uFunction,
     973            g_pIoCtlDetectForLogging->cbInput, g_pIoCtlDetectForLogging->cbOutput));
     974
     975    g_pIoCtlDetectForLogging = NULL;
     976#endif
     977
     978    /* Done. */
     979    pVM->nem.s.IoCtlGetHvPartitionId            = g_IoCtlGetHvPartitionId;
     980    pVM->nem.s.IoCtlStartVirtualProcessor       = g_IoCtlStartVirtualProcessor;
     981    pVM->nem.s.IoCtlStopVirtualProcessor        = g_IoCtlStopVirtualProcessor;
     982    pVM->nem.s.IoCtlMessageSlotHandleAndGetNext = g_IoCtlMessageSlotHandleAndGetNext;
     983    return VINF_SUCCESS;
     984}
     985
     986
     987/**
    677988 * Creates and sets up a Hyper-V (exo) partition.
    678989 *
     
    7791090        {
    7801091            /*
    781              * Check out our ring-0 capabilities.
     1092             * Discover the VID I/O control function numbers we need.
    7821093             */
    783             rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_NEM_INIT_VM, 0, NULL);
     1094            rc = nemR3WinInitDiscoverIoControlProperties(pVM, pErrInfo);
    7841095            if (RT_SUCCESS(rc))
    7851096            {
    7861097                /*
    787                  * Create and initialize a partition.
     1098                 * Check out our ring-0 capabilities.
    7881099                 */
    789                 rc = nemR3WinInitCreatePartition(pVM, pErrInfo);
     1100                rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_NEM_INIT_VM, 0, NULL);
    7901101                if (RT_SUCCESS(rc))
    7911102                {
    792                     VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_NATIVE_API);
    793                     Log(("NEM: Marked active!\n"));
     1103                    /*
     1104                     * Create and initialize a partition.
     1105                     */
     1106                    rc = nemR3WinInitCreatePartition(pVM, pErrInfo);
     1107                    if (RT_SUCCESS(rc))
     1108                    {
     1109                        VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_NATIVE_API);
     1110                        Log(("NEM: Marked active!\n"));
     1111                    }
    7941112                }
    7951113            }
     
    17992117
    18002118            case VMCPUSTATE_STARTED_EXEC_NEM_WAIT:
    1801             {
    18022119                if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED, VMCPUSTATE_STARTED_EXEC_NEM_WAIT))
    18032120                {
     
    18102127                }
    18112128                break;
    1812             }
    18132129
    18142130            default:
     
    18222138
    18232139
    1824 /** 
     2140/**
    18252141 * Fills in WHV_VP_EXIT_CONTEXT from HV_X64_INTERCEPT_MESSAGE_HEADER.
    18262142 */
     
    30073323int nemR3NativeNotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb)
    30083324{
    3009     LogRel(("nemR3NativeNotifyPhysRamRegister: %RGp LB %RGp\n", GCPhys, cb));
     3325    Log5(("nemR3NativeNotifyPhysRamRegister: %RGp LB %RGp\n", GCPhys, cb));
    30103326    NOREF(pVM); NOREF(GCPhys); NOREF(cb);
    30113327    return VINF_SUCCESS;
     
    30153331int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvMmio2)
    30163332{
    3017     LogRel(("nemR3NativeNotifyPhysMmioExMap: %RGp LB %RGp fFlags=%#x pvMmio2=%p\n", GCPhys, cb, fFlags, pvMmio2));
     3333    Log5(("nemR3NativeNotifyPhysMmioExMap: %RGp LB %RGp fFlags=%#x pvMmio2=%p\n", GCPhys, cb, fFlags, pvMmio2));
    30183334    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); NOREF(pvMmio2);
    30193335    return VINF_SUCCESS;
     
    30233339int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)
    30243340{
    3025     LogRel(("nemR3NativeNotifyPhysMmioExUnmap: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags));
     3341    Log5(("nemR3NativeNotifyPhysMmioExUnmap: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags));
    30263342    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
    30273343    return VINF_SUCCESS;
     
    30443360int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)
    30453361{
    3046     LogRel(("nemR3NativeNotifyPhysRomRegisterEarly: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags));
     3362    Log5(("nemR3NativeNotifyPhysRomRegisterEarly: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags));
    30473363#if 0 /* Let's not do this after all.  We'll protection change notifications for each page and if not we'll map them lazily. */
    30483364    RTGCPHYS const cPages = cb >> X86_PAGE_SHIFT;
     
    30923408int nemR3NativeNotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags)
    30933409{
    3094     LogRel(("nemR3NativeNotifyPhysRomRegisterLate: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags));
     3410    Log5(("nemR3NativeNotifyPhysRomRegisterLate: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags));
    30953411    NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags);
    30963412    return VINF_SUCCESS;
     
    31783494void nemR3NativeNotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb)
    31793495{
    3180     LogRel(("nemR3NativeNotifyHandlerPhysicalRegister: %RGp LB %RGp enmKind=%d\n", GCPhys, cb, enmKind));
     3496    Log5(("nemR3NativeNotifyHandlerPhysicalRegister: %RGp LB %RGp enmKind=%d\n", GCPhys, cb, enmKind));
    31813497    NOREF(pVM); NOREF(enmKind); NOREF(GCPhys); NOREF(cb);
    31823498}
     
    31863502                                                int fRestoreAsRAM, bool fRestoreAsRAM2)
    31873503{
    3188     LogRel(("nemR3NativeNotifyHandlerPhysicalDeregister: %RGp LB %RGp enmKind=%d fRestoreAsRAM=%d fRestoreAsRAM2=%d\n",
    3189             GCPhys, cb, enmKind, fRestoreAsRAM, fRestoreAsRAM2));
     3504    Log5(("nemR3NativeNotifyHandlerPhysicalDeregister: %RGp LB %RGp enmKind=%d fRestoreAsRAM=%d fRestoreAsRAM2=%d\n",
     3505          GCPhys, cb, enmKind, fRestoreAsRAM, fRestoreAsRAM2));
    31903506    NOREF(pVM); NOREF(enmKind); NOREF(GCPhys); NOREF(cb); NOREF(fRestoreAsRAM); NOREF(fRestoreAsRAM2);
    31913507}
     
    31953511                                            RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM)
    31963512{
    3197     LogRel(("nemR3NativeNotifyHandlerPhysicalModify: %RGp LB %RGp -> %RGp enmKind=%d fRestoreAsRAM=%d\n",
    3198             GCPhysOld, cb, GCPhysNew, enmKind, fRestoreAsRAM));
     3513    Log5(("nemR3NativeNotifyHandlerPhysicalModify: %RGp LB %RGp -> %RGp enmKind=%d fRestoreAsRAM=%d\n",
     3514          GCPhysOld, cb, GCPhysNew, enmKind, fRestoreAsRAM));
    31993515    NOREF(pVM); NOREF(enmKind); NOREF(GCPhysOld); NOREF(GCPhysNew); NOREF(cb); NOREF(fRestoreAsRAM);
    32003516}
     
    34803796                                       PGMPAGETYPE enmType, uint8_t *pu2State)
    34813797{
    3482     LogRel(("nemR3NativeNotifyPhysPageAllocated: %RGp HCPhys=%RHp fPageProt=%#x enmType=%d *pu2State=%d\n",
    3483             GCPhys, HCPhys, fPageProt, enmType, *pu2State));
     3798    Log5(("nemR3NativeNotifyPhysPageAllocated: %RGp HCPhys=%RHp fPageProt=%#x enmType=%d *pu2State=%d\n",
     3799          GCPhys, HCPhys, fPageProt, enmType, *pu2State));
    34843800    RT_NOREF_PV(HCPhys); RT_NOREF_PV(enmType);
    34853801
     
    35153831                                          PGMPAGETYPE enmType, uint8_t *pu2State)
    35163832{
    3517     LogRel(("nemR3NativeNotifyPhysPageProtChanged: %RGp HCPhys=%RHp fPageProt=%#x enmType=%d *pu2State=%d\n",
    3518             GCPhys, HCPhys, fPageProt, enmType, *pu2State));
     3833    Log5(("nemR3NativeNotifyPhysPageProtChanged: %RGp HCPhys=%RHp fPageProt=%#x enmType=%d *pu2State=%d\n",
     3834          GCPhys, HCPhys, fPageProt, enmType, *pu2State));
    35193835    RT_NOREF_PV(HCPhys); RT_NOREF_PV(enmType);
    35203836
     
    35463862                                      uint32_t fPageProt, PGMPAGETYPE enmType, uint8_t *pu2State)
    35473863{
    3548     LogRel(("nemR3NativeNotifyPhysPageProtChanged: %RGp HCPhys=%RHp->%RHp fPageProt=%#x enmType=%d *pu2State=%d\n",
    3549             GCPhys, HCPhysPrev, HCPhysNew, fPageProt, enmType, *pu2State));
     3864    Log5(("nemR3NativeNotifyPhysPageProtChanged: %RGp HCPhys=%RHp->%RHp fPageProt=%#x enmType=%d *pu2State=%d\n",
     3865          GCPhys, HCPhysPrev, HCPhysNew, fPageProt, enmType, *pu2State));
    35503866    RT_NOREF_PV(HCPhysPrev); RT_NOREF_PV(HCPhysNew); RT_NOREF_PV(enmType);
    35513867
  • trunk/src/VBox/VMM/include/NEMInternal.h

    r71129 r71131  
    4949#  error "NEM_WIN_USE_OUR_OWN_RUN_API requires NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS"
    5050# endif
    51 #endif
     51
     52/**
     53 * Windows VID I/O control information.
     54 */
     55typedef struct NEMWINIOCTL
     56{
     57    /** The I/O control function number. */
     58    uint32_t    uFunction;
     59    uint32_t    cbInput;
     60    uint32_t    cbOutput;
     61} NEMWINIOCTL;
     62
     63#endif
     64
    5265
    5366/**
     
    104117    /** Number of currently mapped pages. */
    105118    uint32_t volatile           cMappedPages;
    106 #endif
    107 
     119
     120    /** Info about the VidGetHvPartitionId I/O control interface. */
     121    NEMWINIOCTL                 IoCtlGetHvPartitionId;
     122    /** Info about the VidStartVirtualProcessor I/O control interface. */
     123    NEMWINIOCTL                 IoCtlStartVirtualProcessor;
     124    /** Info about the VidStopVirtualProcessor I/O control interface. */
     125    NEMWINIOCTL                 IoCtlStopVirtualProcessor;
     126    /** Info about the VidStopVirtualProcessor I/O control interface. */
     127    NEMWINIOCTL                 IoCtlMessageSlotHandleAndGetNext;
     128
     129#endif /* RT_OS_WINDOWS */
    108130} NEM;
    109131/** Pointer to NEM VM instance data. */
     
    115137#define NEM_MAGIC_DEAD          UINT32_C(0xdead1111)
    116138
    117 #if defined(RT_OS_WINDOWS) && defined(NEM_WIN_USE_OUR_OWN_RUN_API)
    118 /** @name NEM_WIN_MSG_STATE_XXX - Windows message handling state.
    119  * @{ */
    120 /** The CPU has not been started. */
    121 # define NEM_WIN_MSG_STATE_STOPPED              UINT8_C(0x00)
    122 /** The CPU has been started, no messages are pending. */
    123 # define NEM_WIN_MSG_STATE_STARTED              UINT8_C(0x01)
    124 /** Message is pending and needs to be ACKed. */
    125 # define NEM_WIN_MSG_STATE_PENDING_MSG          UINT8_C(0x02)
    126 /** Both a message and execution stopping is pending.  We need to ACK the
    127  * current message and get the stop message, then ACK the stop message before
    128  *  the CPU can be started again.  */
    129 # define NEM_WIN_MSG_STATE_PENDING_STOP_AND_MSG UINT8_C(0x03)
    130 /** @} */
    131 #endif
    132139
    133140/**
     
    177184
    178185
     186#if defined(RT_OS_WINDOWS) && defined(NEM_WIN_USE_OUR_OWN_RUN_API)
     187/** @name NEM_WIN_MSG_STATE_XXX - Windows message handling state.
     188 * @{ */
     189/** The CPU has not been started. */
     190# define NEM_WIN_MSG_STATE_STOPPED              UINT8_C(0x00)
     191/** The CPU has been started, no messages are pending. */
     192# define NEM_WIN_MSG_STATE_STARTED              UINT8_C(0x01)
     193/** Message is pending and needs to be ACKed. */
     194# define NEM_WIN_MSG_STATE_PENDING_MSG          UINT8_C(0x02)
     195/** Both a message and execution stopping is pending.  We need to ACK the
     196 * current message and get the stop message, then ACK the stop message before
     197 *  the CPU can be started again.  */
     198# define NEM_WIN_MSG_STATE_PENDING_STOP_AND_MSG UINT8_C(0x03)
     199/** @} */
     200#endif
     201
     202
     203
    179204#ifdef IN_RING0
    180205
Note: See TracChangeset for help on using the changeset viewer.

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