VirtualBox

Changeset 96505 in vbox for trunk/src/VBox/Runtime/r3/win


Ignore:
Timestamp:
Aug 25, 2022 10:44:04 PM (2 years ago)
Author:
vboxsync
Message:

IPRT: Dynamically resolve GetProcessAffinityMask, SetThreadAffinityMask, CreateIoCompletionPort, GetQueuedCompletionStatus and PostQueuedCompletionStatus too so related (ValKit) code loads on ancient NT versions. bugref:10261

Location:
trunk/src/VBox/Runtime/r3/win
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/win/fileaio-win.cpp

    r96407 r96505  
    5151
    5252#include <iprt/win/windows.h>
     53
     54#include "internal-r3-win.h"
    5355
    5456
     
    283285RTDECL(int) RTFileAioCtxCreate(PRTFILEAIOCTX phAioCtx, uint32_t cAioReqsMax, uint32_t fFlags)
    284286{
    285     PRTFILEAIOCTXINTERNAL pCtxInt;
    286287    AssertPtrReturn(phAioCtx, VERR_INVALID_POINTER);
    287288    AssertReturn(!(fFlags & ~RTFILEAIOCTX_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
    288289    RT_NOREF_PV(cAioReqsMax);
    289290
    290     pCtxInt = (PRTFILEAIOCTXINTERNAL)RTMemAllocZ(sizeof(RTFILEAIOCTXINTERNAL));
    291     if (RT_UNLIKELY(!pCtxInt))
    292         return VERR_NO_MEMORY;
    293 
    294     pCtxInt->hIoCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
    295                                                         NULL,
    296                                                         0,
    297                                                         0);
    298     if (RT_UNLIKELY(!pCtxInt->hIoCompletionPort))
     291    if (   g_pfnCreateIoCompletionPort
     292        && g_pfnGetQueuedCompletionStatus
     293        && g_pfnPostQueuedCompletionStatus)
    299294    {
    300         RTMemFree(pCtxInt);
    301         return VERR_NO_MEMORY;
     295        PRTFILEAIOCTXINTERNAL pCtxInt = (PRTFILEAIOCTXINTERNAL)RTMemAllocZ(sizeof(RTFILEAIOCTXINTERNAL));
     296        if (RT_UNLIKELY(!pCtxInt))
     297            return VERR_NO_MEMORY;
     298
     299        pCtxInt->hIoCompletionPort = g_pfnCreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
     300        if (RT_UNLIKELY(!pCtxInt->hIoCompletionPort))
     301        {
     302            RTMemFree(pCtxInt);
     303            return VERR_NO_MEMORY;
     304        }
     305
     306        pCtxInt->fFlags   = fFlags;
     307        pCtxInt->u32Magic = RTFILEAIOCTX_MAGIC;
     308
     309        *phAioCtx = (RTFILEAIOCTX)pCtxInt;
     310
     311        return VINF_SUCCESS;
    302312    }
    303 
    304     pCtxInt->fFlags   = fFlags;
    305     pCtxInt->u32Magic = RTFILEAIOCTX_MAGIC;
    306 
    307     *phAioCtx = (RTFILEAIOCTX)pCtxInt;
    308 
    309     return VINF_SUCCESS;
     313    return VERR_NOT_SUPPORTED;
    310314}
    311315
     
    331335RTDECL(int) RTFileAioCtxAssociateWithFile(RTFILEAIOCTX hAioCtx, RTFILE hFile)
    332336{
    333     int rc = VINF_SUCCESS;
    334337    PRTFILEAIOCTXINTERNAL pCtxInt = hAioCtx;
    335338    RTFILEAIOCTX_VALID_RETURN(pCtxInt);
    336339
    337     HANDLE hTemp = CreateIoCompletionPort((HANDLE)RTFileToNative(hFile), pCtxInt->hIoCompletionPort, 0, 1);
    338     if (hTemp != pCtxInt->hIoCompletionPort)
    339         rc = RTErrConvertFromWin32(GetLastError());
    340 
    341     return rc;
     340    if (   g_pfnCreateIoCompletionPort
     341        && g_pfnGetQueuedCompletionStatus
     342        && g_pfnPostQueuedCompletionStatus)
     343    {
     344        int rc = VINF_SUCCESS;
     345        HANDLE hTemp = g_pfnCreateIoCompletionPort((HANDLE)RTFileToNative(hFile), pCtxInt->hIoCompletionPort, 0, 1);
     346        if (hTemp != pCtxInt->hIoCompletionPort)
     347            rc = RTErrConvertFromWin32(GetLastError());
     348
     349        return rc;
     350    }
     351    return VERR_NOT_SUPPORTED;
    342352}
    343353
     
    445455
    446456        ASMAtomicXchgBool(&pCtxInt->fWaiting, true);
    447         fSucceeded = GetQueuedCompletionStatus(pCtxInt->hIoCompletionPort,
    448                                                &cbTransfered,
    449                                                &lCompletionKey,
    450                                                &pOverlapped,
    451                                                dwTimeout);
     457        fSucceeded = g_pfnGetQueuedCompletionStatus(pCtxInt->hIoCompletionPort,
     458                                                    &cbTransfered,
     459                                                    &lCompletionKey,
     460                                                    &pOverlapped,
     461                                                    dwTimeout);
    452462        ASMAtomicXchgBool(&pCtxInt->fWaiting, false);
    453463        if (   !fSucceeded
     
    532542        && fWaiting)
    533543    {
    534         BOOL fSucceeded = PostQueuedCompletionStatus(pCtxInt->hIoCompletionPort,
    535                                                      0, AIO_CONTEXT_WAKEUP_EVENT,
    536                                                      NULL);
     544        BOOL fSucceeded = g_pfnPostQueuedCompletionStatus(pCtxInt->hIoCompletionPort,
     545                                                          0, AIO_CONTEXT_WAKEUP_EVENT,
     546                                                          NULL);
    537547
    538548        if (!fSucceeded)
  • trunk/src/VBox/Runtime/r3/win/init-win.cpp

    r96476 r96505  
    9494DECL_HIDDEN_DATA(decltype(IsDebuggerPresent) *)                 g_pfnIsDebuggerPresent = NULL;
    9595DECL_HIDDEN_DATA(decltype(GetSystemTimeAsFileTime) *)           g_pfnGetSystemTimeAsFileTime = NULL;
     96DECL_HIDDEN_DATA(decltype(GetProcessAffinityMask) *)            g_pfnGetProcessAffinityMask = NULL;
     97DECL_HIDDEN_DATA(decltype(SetThreadAffinityMask) *)             g_pfnSetThreadAffinityMask = NULL;
     98DECL_HIDDEN_DATA(decltype(CreateIoCompletionPort) *)            g_pfnCreateIoCompletionPort = NULL;
     99DECL_HIDDEN_DATA(decltype(GetQueuedCompletionStatus) *)         g_pfnGetQueuedCompletionStatus = NULL;
     100DECL_HIDDEN_DATA(decltype(PostQueuedCompletionStatus) *)        g_pfnPostQueuedCompletionStatus = NULL;
    96101
    97102/** The native ntdll.dll handle. */
     
    568573        g_pfnGetSystemWindowsDirectoryW  = (PFNGETWINSYSDIR)GetProcAddress(g_hModKernel32, "GetWindowsDirectoryW");
    569574    g_pfnSystemTimeToTzSpecificLocalTime = (decltype(SystemTimeToTzSpecificLocalTime) *)GetProcAddress(g_hModKernel32, "SystemTimeToTzSpecificLocalTime");
    570     g_pfnCreateWaitableTimerExW     = (PFNCREATEWAITABLETIMEREX)           GetProcAddress(g_hModKernel32, "CreateWaitableTimerExW");
    571     g_pfnGetHandleInformation       = (decltype(GetHandleInformation) *)   GetProcAddress(g_hModKernel32, "GetHandleInformation");
    572     g_pfnSetHandleInformation       = (decltype(SetHandleInformation) *)   GetProcAddress(g_hModKernel32, "SetHandleInformation");
    573     g_pfnIsDebuggerPresent          = (decltype(IsDebuggerPresent) *)      GetProcAddress(g_hModKernel32, "IsDebuggerPresent");
    574     g_pfnGetSystemTimeAsFileTime    = (decltype(GetSystemTimeAsFileTime) *)GetProcAddress(g_hModKernel32, "GetSystemTimeAsFileTime");
    575     Assert(g_pfnSetHandleInformation    || g_enmWinVer < kRTWinOSType_NT351);
    576     Assert(g_pfnGetHandleInformation    || g_enmWinVer < kRTWinOSType_NT351);
    577     Assert(g_pfnIsDebuggerPresent       || g_enmWinVer < kRTWinOSType_NT4);
    578     Assert(g_pfnGetSystemTimeAsFileTime || g_enmWinVer < kRTWinOSType_NT4);
     575    g_pfnCreateWaitableTimerExW     = (PFNCREATEWAITABLETIMEREX)              GetProcAddress(g_hModKernel32, "CreateWaitableTimerExW");
     576    g_pfnGetHandleInformation       = (decltype(GetHandleInformation) *)      GetProcAddress(g_hModKernel32, "GetHandleInformation");
     577    g_pfnSetHandleInformation       = (decltype(SetHandleInformation) *)      GetProcAddress(g_hModKernel32, "SetHandleInformation");
     578    g_pfnIsDebuggerPresent          = (decltype(IsDebuggerPresent) *)         GetProcAddress(g_hModKernel32, "IsDebuggerPresent");
     579    g_pfnGetSystemTimeAsFileTime    = (decltype(GetSystemTimeAsFileTime) *)   GetProcAddress(g_hModKernel32, "GetSystemTimeAsFileTime");
     580    g_pfnGetProcessAffinityMask     = (decltype(GetProcessAffinityMask) *)    GetProcAddress(g_hModKernel32, "GetProcessAffinityMask");
     581    g_pfnSetThreadAffinityMask      = (decltype(SetThreadAffinityMask) *)     GetProcAddress(g_hModKernel32, "SetThreadAffinityMask");
     582    g_pfnCreateIoCompletionPort     = (decltype(CreateIoCompletionPort) *)    GetProcAddress(g_hModKernel32, "CreateIoCompletionPort");
     583    g_pfnGetQueuedCompletionStatus  = (decltype(GetQueuedCompletionStatus) *) GetProcAddress(g_hModKernel32, "GetQueuedCompletionStatus");
     584    g_pfnPostQueuedCompletionStatus = (decltype(PostQueuedCompletionStatus) *)GetProcAddress(g_hModKernel32, "PostQueuedCompletionStatus");
     585
     586    Assert(g_pfnGetHandleInformation       || g_enmWinVer < kRTWinOSType_NT351);
     587    Assert(g_pfnSetHandleInformation       || g_enmWinVer < kRTWinOSType_NT351);
     588    Assert(g_pfnIsDebuggerPresent          || g_enmWinVer < kRTWinOSType_NT4);
     589    Assert(g_pfnGetSystemTimeAsFileTime    || g_enmWinVer < kRTWinOSType_NT4);
     590    Assert(g_pfnGetProcessAffinityMask     || g_enmWinVer < kRTWinOSType_NT350);
     591    Assert(g_pfnSetThreadAffinityMask      || g_enmWinVer < kRTWinOSType_NT350);
     592    Assert(g_pfnCreateIoCompletionPort     || g_enmWinVer < kRTWinOSType_NT350);
     593    Assert(g_pfnGetQueuedCompletionStatus  || g_enmWinVer < kRTWinOSType_NT350);
     594    Assert(g_pfnPostQueuedCompletionStatus || g_enmWinVer < kRTWinOSType_NT350);
    579595
    580596    /*
  • trunk/src/VBox/Runtime/r3/win/internal-r3-win.h

    r96476 r96505  
    117117typedef UINT (WINAPI *PFNGETWINSYSDIR)(LPWSTR,UINT);
    118118extern DECL_HIDDEN_DATA(PFNGETWINSYSDIR)                                g_pfnGetSystemWindowsDirectoryW;
    119 extern DECL_HIDDEN_DATA(decltype(SystemTimeToTzSpecificLocalTime) *)    g_pfnSystemTimeToTzSpecificLocalTime;
    120119typedef HANDLE (WINAPI *PFNCREATEWAITABLETIMEREX)(LPSECURITY_ATTRIBUTES, LPCWSTR, DWORD, DWORD);
    121120extern DECL_HIDDEN_DATA(PFNCREATEWAITABLETIMEREX)                       g_pfnCreateWaitableTimerExW;
     121extern DECL_HIDDEN_DATA(decltype(SystemTimeToTzSpecificLocalTime) *)    g_pfnSystemTimeToTzSpecificLocalTime;
    122122extern DECL_HIDDEN_DATA(decltype(GetHandleInformation) *)               g_pfnGetHandleInformation;
    123123extern DECL_HIDDEN_DATA(decltype(SetHandleInformation) *)               g_pfnSetHandleInformation;
    124124extern DECL_HIDDEN_DATA(decltype(IsDebuggerPresent) *)                  g_pfnIsDebuggerPresent;
    125125extern DECL_HIDDEN_DATA(decltype(GetSystemTimeAsFileTime) *)            g_pfnGetSystemTimeAsFileTime;
    126 typedef UINT (WINAPI *PFNGETWINSYSDIR)(LPWSTR,UINT);
    127 extern DECL_HIDDEN_DATA(PFNGETWINSYSDIR)                                g_pfnGetSystemWindowsDirectoryW;
     126extern DECL_HIDDEN_DATA(decltype(GetProcessAffinityMask) *)             g_pfnGetProcessAffinityMask;
     127extern DECL_HIDDEN_DATA(decltype(SetThreadAffinityMask) *)              g_pfnSetThreadAffinityMask;
     128extern DECL_HIDDEN_DATA(decltype(CreateIoCompletionPort) *)             g_pfnCreateIoCompletionPort;
     129extern DECL_HIDDEN_DATA(decltype(GetQueuedCompletionStatus) *)          g_pfnGetQueuedCompletionStatus;
     130extern DECL_HIDDEN_DATA(decltype(PostQueuedCompletionStatus) *)         g_pfnPostQueuedCompletionStatus;
    128131
    129132
  • trunk/src/VBox/Runtime/r3/win/localipc-win.cpp

    r96407 r96505  
    22/** @file
    33 * IPRT - Local IPC, Windows Implementation Using Named Pipes.
     4 *
     5 * @note This code only works on W2K because of the dependency on
     6 *       ConvertStringSecurityDescriptorToSecurityDescriptor.
    47 */
    58
     
    4043*********************************************************************************************************************************/
    4144#define LOG_GROUP RTLOGGROUP_LOCALIPC
    42 /*
    43  * We have to force NT 5.0 here because of
    44  * ConvertStringSecurityDescriptorToSecurityDescriptor. Note that because of
    45  * FILE_FLAG_FIRST_PIPE_INSTANCE this code actually requires W2K SP2+.
    46  */
    47 #ifndef _WIN32_WINNT
    48 # define _WIN32_WINNT 0x0500 /* for ConvertStringSecurityDescriptorToSecurityDescriptor */
    49 #elif _WIN32_WINNT < 0x0500
    50 # undef _WIN32_WINNT
    51 # define _WIN32_WINNT 0x0500
     45#ifdef _WIN32_WINNT
     46# if _WIN32_WINNT < 0x0500
     47#  undef _WIN32_WINNT
     48#  define _WIN32_WINNT 0x0500       /* For ConvertStringSecurityDescriptorToSecurityDescriptor. */
     49# endif
    5250#endif
    53 #define UNICODE    /* For the SDDL_ strings. */
    54 #include <iprt/win/windows.h>
     51#define UNICODE                     /* For the SDDL_ strings. */
     52#include <iprt/nt/nt-and-windows.h> /* Need NtCancelIoFile */
    5553#include <sddl.h>
    5654
     
    238236 * @param   fServer             Whether it's for a server or client instance.
    239237 */
    240 static int rtLocalIpcServerWinAllocSecurityDescriptior(PSECURITY_DESCRIPTOR *ppDesc, bool fServer)
     238static int rtLocalIpcServerWinAllocSecurityDescriptor(PSECURITY_DESCRIPTOR *ppDesc, bool fServer)
    241239{
    242240    /*
     
    298296
    299297    PSECURITY_DESCRIPTOR pSecDesc;
    300     int rc = rtLocalIpcServerWinAllocSecurityDescriptior(&pSecDesc, fFirst /* Server? */);
     298    int rc = rtLocalIpcServerWinAllocSecurityDescriptor(&pSecDesc, fFirst /* Server? */);
    301299    if (RT_SUCCESS(rc))
    302300    {
     
    671669                fRc = DisconnectNamedPipe(pThis->hNmPipe);
    672670            else if (dwErr == ERROR_IO_PENDING)
    673                 fRc = CancelIo(pThis->hNmPipe);
     671            {
     672                IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
     673                NTSTATUS rcNt = NtCancelIoFile(pThis->hNmPipe, &Ios);
     674                fRc = NT_SUCCESS(rcNt);
     675            }
    674676            else
    675677                fRc = TRUE;
     
    825827             */
    826828            PSECURITY_DESCRIPTOR pSecDesc;
    827             rc = rtLocalIpcServerWinAllocSecurityDescriptior(&pSecDesc, false /*fServer*/);
     829            rc = rtLocalIpcServerWinAllocSecurityDescriptor(&pSecDesc, false /*fServer*/);
    828830            if (RT_SUCCESS(rc))
    829831            {
     
    897899
    898900    /*
    899      * Call CancelIo since this call cancels both read and write oriented operations.
     901     * Call NtCancelIoFile since this call cancels both read and write
     902     * oriented operations.
    900903     */
    901904    if (   pThis->fZeroByteRead
    902905        || pThis->Read.hActiveThread != NIL_RTTHREAD
    903906        || pThis->Write.hActiveThread != NIL_RTTHREAD)
    904         CancelIo(pThis->hNmPipe);
     907    {
     908        IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
     909        NtCancelIoFile(pThis->hNmPipe, &Ios);
     910    }
    905911
    906912    /*
     
    10361042 * The zero byte read is started by the RTLocalIpcSessionWaitForData method and
    10371043 * left pending when the function times out.  This saves us the problem of
    1038  * CancelIo messing with all active I/O operations and the trouble of restarting
    1039  * the zero byte read the next time the method is called.  However should
    1040  * RTLocalIpcSessionRead be called after a failed RTLocalIpcSessionWaitForData
    1041  * call, the zero byte read will still be pending and it must wait for it to
    1042  * complete before the OVERLAPPEDIO structure can be reused.
     1044 * NtCancelIoFile messing with all active I/O operations and the trouble of
     1045 * restarting the zero byte read the next time the method is called.  However
     1046 * should RTLocalIpcSessionRead be called after a failed
     1047 * RTLocalIpcSessionWaitForData call, the zero byte read will still be pending
     1048 * and it must wait for it to complete before the OVERLAPPEDIO structure can be
     1049 * reused.
    10431050 *
    10441051 * Thus, both functions will do WaitForSingleObject and share this routine to
  • trunk/src/VBox/Runtime/r3/win/ntdll-mini-implib.def

    r96407 r96505  
    4444    NtAlertThread                         ;;= _NtAlertThread@4
    4545    NtAllocateVirtualMemory               ;;= _NtAllocateVirtualMemory@24
     46    NtCancelIoFile                        ;;= _NtCancelIoFile@8
    4647    NtClearEvent                          ;;= _NtClearEvent@4
    4748    NtClose                               ;;= _NtClose@4
  • trunk/src/VBox/Runtime/r3/win/pipe-win.cpp

    r96495 r96505  
    612612                RTCritSectLeave(&pThis->CritSect);
    613613
    614                 if (!CancelIo(pThis->hPipe))
     614                /* We use NtCancelIoFile here because the CancelIo API
     615                   providing access to it wasn't available till NT4.  This
     616                   code needs to work (or at least load) with NT 3.1 */
     617                IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
     618                NTSTATUS rcNt = NtCancelIoFile(pThis->hPipe, &Ios);
     619                if (!NT_SUCCESS(rcNt))
    615620                    WaitForSingleObject(pThis->Overlapped.hEvent, INFINITE);
     621
    616622                if (GetOverlappedResult(pThis->hPipe, &pThis->Overlapped, &cbRead, TRUE /*fWait*/))
    617623                {
     
    11621168                pThis->fIOPending = false;
    11631169                if (rc != VINF_SUCCESS)
    1164                     CancelIo(pThis->hPipe);
     1170                {
     1171                    IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
     1172                    NtCancelIoFile(pThis->hPipe, &Ios);
     1173                }
    11651174                DWORD cbRead = 0;
    11661175                GetOverlappedResult(pThis->hPipe, &pThis->Overlapped, &cbRead, TRUE /*fWait*/);
     
    15011510    if (pThis->fZeroByteRead)
    15021511    {
    1503         CancelIo(pThis->hPipe);
     1512        IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
     1513        NtCancelIoFile(pThis->hPipe, &Ios);
     1514
    15041515        DWORD cbRead = 0;
    15051516        if (   !GetOverlappedResult(pThis->hPipe, &pThis->Overlapped, &cbRead, TRUE /*fWait*/)
  • trunk/src/VBox/Runtime/r3/win/thread-win.cpp

    r96476 r96505  
    478478RTR3DECL(int) RTThreadSetAffinity(PCRTCPUSET pCpuSet)
    479479{
    480     DWORD_PTR fNewMask = pCpuSet ? RTCpuSetToU64(pCpuSet) : ~(DWORD_PTR)0;
    481     DWORD_PTR dwRet = SetThreadAffinityMask(GetCurrentThread(), fNewMask);
    482     if (dwRet)
    483         return VINF_SUCCESS;
    484 
    485     int iLastError = GetLastError();
    486     AssertMsgFailed(("SetThreadAffinityMask failed, LastError=%d\n", iLastError));
    487     return RTErrConvertFromWin32(iLastError);
     480    /* The affinity functionality was added in NT 3.50, so we resolve the APIs
     481       dynamically to be able to run on NT 3.1. */
     482    if (g_pfnSetThreadAffinityMask)
     483    {
     484        DWORD_PTR fNewMask = pCpuSet ? RTCpuSetToU64(pCpuSet) : ~(DWORD_PTR)0;
     485        DWORD_PTR dwRet = g_pfnSetThreadAffinityMask(GetCurrentThread(), fNewMask);
     486        if (dwRet)
     487            return VINF_SUCCESS;
     488
     489        int iLastError = GetLastError();
     490        AssertMsgFailed(("SetThreadAffinityMask failed, LastError=%d\n", iLastError));
     491        return RTErrConvertFromWin32(iLastError);
     492    }
     493    return VERR_NOT_SUPPORTED;
    488494}
    489495
     
    491497RTR3DECL(int) RTThreadGetAffinity(PRTCPUSET pCpuSet)
    492498{
    493     /*
    494      * Haven't found no query api, but the set api returns the old mask, so let's use that.
    495      */
    496     DWORD_PTR dwIgnored;
    497     DWORD_PTR dwProcAff = 0;
    498     if (GetProcessAffinityMask(GetCurrentProcess(), &dwProcAff, &dwIgnored))
    499     {
    500         HANDLE hThread = GetCurrentThread();
    501         DWORD_PTR dwRet = SetThreadAffinityMask(hThread, dwProcAff);
    502         if (dwRet)
     499    /* The affinity functionality was added in NT 3.50, so we resolve the APIs
     500       dynamically to be able to run on NT 3.1. */
     501    if (   g_pfnSetThreadAffinityMask
     502        && g_pfnGetProcessAffinityMask)
     503    {
     504        /*
     505         * Haven't found no query api, but the set api returns the old mask, so let's use that.
     506         */
     507        DWORD_PTR dwIgnored;
     508        DWORD_PTR dwProcAff = 0;
     509        if (g_pfnGetProcessAffinityMask(GetCurrentProcess(), &dwProcAff, &dwIgnored))
    503510        {
    504             DWORD_PTR dwSet = SetThreadAffinityMask(hThread, dwRet);
    505             Assert(dwSet == dwProcAff); NOREF(dwRet);
    506 
    507             RTCpuSetFromU64(pCpuSet, (uint64_t)dwSet);
    508             return VINF_SUCCESS;
     511            HANDLE hThread = GetCurrentThread();
     512            DWORD_PTR dwRet = g_pfnSetThreadAffinityMask(hThread, dwProcAff);
     513            if (dwRet)
     514            {
     515                DWORD_PTR dwSet = g_pfnSetThreadAffinityMask(hThread, dwRet);
     516                Assert(dwSet == dwProcAff); NOREF(dwRet);
     517
     518                RTCpuSetFromU64(pCpuSet, (uint64_t)dwSet);
     519                return VINF_SUCCESS;
     520            }
    509521        }
    510     }
    511 
    512     int iLastError = GetLastError();
    513     AssertMsgFailed(("SetThreadAffinityMask or GetProcessAffinityMask failed, LastError=%d\n", iLastError));
    514     return RTErrConvertFromWin32(iLastError);
     522
     523        int iLastError = GetLastError();
     524        AssertMsgFailed(("SetThreadAffinityMask or GetProcessAffinityMask failed, LastError=%d\n", iLastError));
     525        return RTErrConvertFromWin32(iLastError);
     526    }
     527    return VERR_NOT_SUPPORTED;
    515528}
    516529
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