df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync/* $Id$ */
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync/** @file
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync *
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync * VBox extension to Wine D3D
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync *
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2011-2012 Oracle Corporation
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync *
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync * available from http://www.virtualbox.org. This file is free software;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync * you can redistribute it and/or modify it under the terms of the GNU
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync * General Public License (GPL) as published by the Free Software
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync */
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync#include "config.h"
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync#include "wine/port.h"
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync#include "wined3d_private.h"
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync#include "vboxext.h"
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync#ifdef VBOX_WITH_WDDM
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync#include <VBox/VBoxCrHgsmi.h>
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync#include <iprt/err.h>
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync#endif
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncWINE_DEFAULT_DEBUG_CHANNEL(d3d_vbox);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsynctypedef DECLCALLBACK(void) FNVBOXEXTWORKERCB(void *pvUser);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsynctypedef FNVBOXEXTWORKERCB *PFNVBOXEXTWORKERCB;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsyncHRESULT VBoxExtDwSubmitProcSync(PFNVBOXEXTWORKERCB pfnCb, void *pvCb);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsyncHRESULT VBoxExtDwSubmitProcAsync(PFNVBOXEXTWORKERCB pfnCb, void *pvCb);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync/*******************************/
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync#ifdef VBOX_WITH_WDDM
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync# if defined(VBOX_WDDM_WOW64)
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync# define VBOXEXT_WINE_MODULE_NAME "wined3dwddm-x86.dll"
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync# else
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync# define VBOXEXT_WINE_MODULE_NAME "wined3dwddm.dll"
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync# endif
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync#else
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync/* both 32bit and 64bit versions of xpdm wine libs are named identically */
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync# define VBOXEXT_WINE_MODULE_NAME "wined3d.dll"
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync#endif
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsynctypedef struct VBOXEXT_WORKER
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync CRITICAL_SECTION CritSect;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync HANDLE hEvent;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync HANDLE hThread;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync DWORD idThread;
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync /* wine does not seem to guarantie the dll is not unloaded in case FreeLibrary is used
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync * while d3d object is not terminated, keep an extra reference to ensure we're not unloaded
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync * while we are active */
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync HMODULE hSelf;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync} VBOXEXT_WORKER, *PVBOXEXT_WORKER;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncHRESULT VBoxExtWorkerCreate(PVBOXEXT_WORKER pWorker);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncHRESULT VBoxExtWorkerDestroy(PVBOXEXT_WORKER pWorker);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncHRESULT VBoxExtWorkerSubmitProc(PVBOXEXT_WORKER pWorker, PFNVBOXEXTWORKERCB pfnCb, void *pvCb);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync/*******************************/
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsynctypedef struct VBOXEXT_GLOBAL
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync VBOXEXT_WORKER Worker;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync} VBOXEXT_GLOBAL, *PVBOXEXT_GLOBAL;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncstatic VBOXEXT_GLOBAL g_VBoxExtGlobal;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync#define WM_VBOXEXT_CALLPROC (WM_APP+1)
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync#define WM_VBOXEXT_INIT_QUIT (WM_APP+2)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsynctypedef struct VBOXEXT_CALLPROC
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync PFNVBOXEXTWORKERCB pfnCb;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync void *pvCb;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync} VBOXEXT_CALLPROC, *PVBOXEXT_CALLPROC;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncstatic DWORD WINAPI vboxExtWorkerThread(void *pvUser)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync PVBOXEXT_WORKER pWorker = (PVBOXEXT_WORKER)pvUser;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync MSG Msg;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync PeekMessage(&Msg,
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync NULL /* HWND hWnd */,
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync WM_USER /* UINT wMsgFilterMin */,
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync WM_USER /* UINT wMsgFilterMax */,
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync PM_NOREMOVE);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync SetEvent(pWorker->hEvent);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync do
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync BOOL bResult = GetMessage(&Msg,
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync 0 /*HWND hWnd*/,
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync 0 /*UINT wMsgFilterMin*/,
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync 0 /*UINT wMsgFilterMax*/
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync );
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync if(!bResult) /* WM_QUIT was posted */
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync break;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync Assert(bResult != -1);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync if(bResult == -1) /* error occurred */
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync break;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync switch (Msg.message)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync case WM_VBOXEXT_CALLPROC:
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync VBOXEXT_CALLPROC* pData = (VBOXEXT_CALLPROC*)Msg.lParam;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync pData->pfnCb(pData->pvCb);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync SetEvent(pWorker->hEvent);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync break;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync case WM_VBOXEXT_INIT_QUIT:
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync case WM_CLOSE:
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync {
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync PostQuitMessage(0);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync break;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync default:
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync TranslateMessage(&Msg);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync DispatchMessage(&Msg);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync } while (1);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return 0;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync}
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncHRESULT VBoxExtWorkerCreate(PVBOXEXT_WORKER pWorker)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync if(!GetModuleHandleEx(0, VBOXEXT_WINE_MODULE_NAME, &pWorker->hSelf))
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync {
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync DWORD dwEr = GetLastError();
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync ERR("GetModuleHandleEx failed, %d", dwEr);
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync return E_FAIL;
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync }
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync InitializeCriticalSection(&pWorker->CritSect);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync pWorker->hEvent = CreateEvent(NULL, /* LPSECURITY_ATTRIBUTES lpEventAttributes */
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync FALSE, /* BOOL bManualReset */
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync FALSE, /* BOOL bInitialState */
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync NULL /* LPCTSTR lpName */
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync );
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync if (pWorker->hEvent)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync pWorker->hThread = CreateThread(
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync NULL /* LPSECURITY_ATTRIBUTES lpThreadAttributes */,
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync 0 /* SIZE_T dwStackSize */,
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync vboxExtWorkerThread,
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync pWorker,
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync 0 /* DWORD dwCreationFlags */,
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync &pWorker->idThread);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync if (pWorker->hThread)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync DWORD dwResult = WaitForSingleObject(pWorker->hEvent, INFINITE);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync if (WAIT_OBJECT_0 == dwResult)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return S_OK;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync ERR("WaitForSingleObject returned %d\n", dwResult);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync else
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync DWORD winErr = GetLastError();
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync ERR("CreateThread failed, winErr = (%d)", winErr);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync DeleteCriticalSection(&pWorker->CritSect);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync else
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync DWORD winErr = GetLastError();
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync ERR("CreateEvent failed, winErr = (%d)", winErr);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync FreeLibrary(pWorker->hSelf);
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return E_FAIL;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync}
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncHRESULT VBoxExtWorkerDestroy(PVBOXEXT_WORKER pWorker)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync BOOL bResult = PostThreadMessage(pWorker->idThread, WM_VBOXEXT_INIT_QUIT, 0, 0);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync DWORD dwErr;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync if (!bResult)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync DWORD winErr = GetLastError();
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync ERR("PostThreadMessage failed, winErr = (%d)", winErr);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return E_FAIL;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync dwErr = WaitForSingleObject(pWorker->hThread, INFINITE);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync if (dwErr != WAIT_OBJECT_0)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync ERR("WaitForSingleObject returned (%d)", dwErr);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return E_FAIL;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync CloseHandle(pWorker->hEvent);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync DeleteCriticalSection(&pWorker->CritSect);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync FreeLibrary(pWorker->hSelf);
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync
d23fcb489c7078aab1f58e9de4e9621b9d84bb4fvboxsync CloseHandle(pWorker->hThread);
d23fcb489c7078aab1f58e9de4e9621b9d84bb4fvboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return S_OK;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync}
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsyncstatic HRESULT vboxExtWorkerSubmit(VBOXEXT_WORKER *pWorker, UINT Msg, LPARAM lParam, BOOL fSync)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync HRESULT hr = E_FAIL;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync BOOL bResult;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync /* need to serialize since vboxExtWorkerThread is using one pWorker->hEvent
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync * to signal job completion */
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync EnterCriticalSection(&pWorker->CritSect);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync bResult = PostThreadMessage(pWorker->idThread, Msg, 0, lParam);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync if (bResult)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync if (fSync)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync DWORD dwErr = WaitForSingleObject(pWorker->hEvent, INFINITE);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync if (dwErr == WAIT_OBJECT_0)
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync {
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync hr = S_OK;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync }
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync else
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync {
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync ERR("WaitForSingleObject returned (%d)", dwErr);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync else
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync hr = S_OK;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync else
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync DWORD winErr = GetLastError();
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync ERR("PostThreadMessage failed, winErr = (%d)", winErr);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return E_FAIL;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync LeaveCriticalSection(&pWorker->CritSect);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return hr;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync}
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsyncHRESULT VBoxExtWorkerSubmitProcSync(PVBOXEXT_WORKER pWorker, PFNVBOXEXTWORKERCB pfnCb, void *pvCb)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync VBOXEXT_CALLPROC Ctx;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync Ctx.pfnCb = pfnCb;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync Ctx.pvCb = pvCb;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync return vboxExtWorkerSubmit(pWorker, WM_VBOXEXT_CALLPROC, (LPARAM)&Ctx, TRUE);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync}
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsyncstatic DECLCALLBACK(void) vboxExtWorkerSubmitProcAsyncWorker(void *pvUser)
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync{
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync PVBOXEXT_CALLPROC pCallInfo = (PVBOXEXT_CALLPROC)pvUser;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync pCallInfo[1].pfnCb(pCallInfo[1].pvCb);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync HeapFree(GetProcessHeap(), 0, pCallInfo);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync}
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsyncHRESULT VBoxExtWorkerSubmitProcAsync(PVBOXEXT_WORKER pWorker, PFNVBOXEXTWORKERCB pfnCb, void *pvCb)
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync{
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync HRESULT hr;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync PVBOXEXT_CALLPROC pCallInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (VBOXEXT_CALLPROC) * 2);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync if (!pCallInfo)
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync {
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync ERR("HeapAlloc failed\n");
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync return E_OUTOFMEMORY;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync }
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync pCallInfo[0].pfnCb = vboxExtWorkerSubmitProcAsyncWorker;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync pCallInfo[0].pvCb = pCallInfo;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync pCallInfo[1].pfnCb = pfnCb;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync pCallInfo[1].pvCb = pvCb;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync hr = vboxExtWorkerSubmit(pWorker, WM_VBOXEXT_CALLPROC, (LPARAM)pCallInfo, FALSE);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync if (FAILED(hr))
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync {
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync ERR("vboxExtWorkerSubmit failed, hr 0x%x\n", hr);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync HeapFree(GetProcessHeap(), 0, pCallInfo);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync return hr;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync }
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync return S_OK;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync}
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncstatic HRESULT vboxExtInit()
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync HRESULT hr = S_OK;
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync#ifdef VBOX_WITH_WDDM
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync int rc = VBoxCrHgsmiInit();
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync if (!RT_SUCCESS(rc))
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync {
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync ERR("VBoxCrHgsmiInit failed rc %d", rc);
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync return E_FAIL;
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync }
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync#endif
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync memset(&g_VBoxExtGlobal, 0, sizeof (g_VBoxExtGlobal));
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync hr = VBoxExtWorkerCreate(&g_VBoxExtGlobal.Worker);
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync if (SUCCEEDED(hr))
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync return S_OK;
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync /* failure branch */
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync#ifdef VBOX_WITH_WDDM
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync VBoxCrHgsmiTerm();
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync#endif
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return hr;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync}
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsyncstatic HRESULT vboxExtWndCleanup();
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncstatic HRESULT vboxExtTerm()
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync HRESULT hr = vboxExtWndCleanup();
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync if (!SUCCEEDED(hr))
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync {
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync ERR("vboxExtWndCleanup failed, hr %d", hr);
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync return hr;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync }
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync hr = VBoxExtWorkerDestroy(&g_VBoxExtGlobal.Worker);
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync if (!SUCCEEDED(hr))
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync {
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync ERR("VBoxExtWorkerDestroy failed, hr %d", hr);
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync return hr;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync }
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync#ifdef VBOX_WITH_WDDM
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync VBoxCrHgsmiTerm();
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync#endif
d10b60270f0c0eeb87f45002a010cff8ba2126b1vboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync return S_OK;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync}
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync/* wine serializes all calls to us, so no need for any synchronization here */
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncstatic DWORD g_cVBoxExtInits = 0;
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsyncstatic DWORD vboxExtAddRef()
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync{
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync return ++g_cVBoxExtInits;
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync}
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsyncstatic DWORD vboxExtRelease()
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync{
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync DWORD cVBoxExtInits = --g_cVBoxExtInits;
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync Assert(cVBoxExtInits < UINT32_MAX/2);
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync return cVBoxExtInits;
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync}
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsyncstatic DWORD vboxExtGetRef()
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync{
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync return g_cVBoxExtInits;
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync}
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncHRESULT VBoxExtCheckInit()
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync HRESULT hr = S_OK;
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync if (!vboxExtGetRef())
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync hr = vboxExtInit();
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync if (FAILED(hr))
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync ERR("vboxExtInit failed, hr (0x%x)", hr);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return hr;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync vboxExtAddRef();
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return S_OK;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync}
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncHRESULT VBoxExtCheckTerm()
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync HRESULT hr = S_OK;
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync if (vboxExtGetRef() == 1)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync hr = vboxExtTerm();
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync if (FAILED(hr))
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync ERR("vboxExtTerm failed, hr (0x%x)", hr);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return hr;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync vboxExtRelease();
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return S_OK;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync}
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsyncHRESULT VBoxExtDwSubmitProcSync(PFNVBOXEXTWORKERCB pfnCb, void *pvCb)
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync{
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync return VBoxExtWorkerSubmitProcSync(&g_VBoxExtGlobal.Worker, pfnCb, pvCb);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync}
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsyncHRESULT VBoxExtDwSubmitProcAsync(PFNVBOXEXTWORKERCB pfnCb, void *pvCb)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync return VBoxExtWorkerSubmitProcAsync(&g_VBoxExtGlobal.Worker, pfnCb, pvCb);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync}
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync# ifndef VBOX_WITH_WDDM
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsynctypedef struct VBOXEXT_GETDC_CB
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync HWND hWnd;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync HDC hDC;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync} VBOXEXT_GETDC_CB, *PVBOXEXT_GETDC_CB;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncstatic DECLCALLBACK(void) vboxExtGetDCWorker(void *pvUser)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync PVBOXEXT_GETDC_CB pData = (PVBOXEXT_GETDC_CB)pvUser;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync pData->hDC = GetDC(pData->hWnd);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync}
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsynctypedef struct VBOXEXT_RELEASEDC_CB
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync HWND hWnd;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync HDC hDC;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync int ret;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync} VBOXEXT_RELEASEDC_CB, *PVBOXEXT_RELEASEDC_CB;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncstatic DECLCALLBACK(void) vboxExtReleaseDCWorker(void *pvUser)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync PVBOXEXT_RELEASEDC_CB pData = (PVBOXEXT_RELEASEDC_CB)pvUser;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync pData->ret = ReleaseDC(pData->hWnd, pData->hDC);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync}
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncHDC VBoxExtGetDC(HWND hWnd)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync HRESULT hr;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync VBOXEXT_GETDC_CB Data = {0};
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync Data.hWnd = hWnd;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync Data.hDC = NULL;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync hr = VBoxExtDwSubmitProcSync(vboxExtGetDCWorker, &Data);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync if (FAILED(hr))
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync ERR("VBoxExtDwSubmitProcSync feiled, hr (0x%x)\n", hr);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return NULL;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return Data.hDC;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync}
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsyncint VBoxExtReleaseDC(HWND hWnd, HDC hDC)
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync{
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync HRESULT hr;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync VBOXEXT_RELEASEDC_CB Data = {0};
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync Data.hWnd = hWnd;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync Data.hDC = hDC;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync Data.ret = 0;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync hr = VBoxExtDwSubmitProcSync(vboxExtReleaseDCWorker, &Data);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync if (FAILED(hr))
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync {
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync ERR("VBoxExtDwSubmitProcSync feiled, hr (0x%x)\n", hr);
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return -1;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync }
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync return Data.ret;
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync}
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync# endif /* #ifndef VBOX_WITH_WDDM */
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsyncstatic DECLCALLBACK(void) vboxExtReleaseContextWorker(void *pvUser)
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync{
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync struct wined3d_context *context = (struct wined3d_context *)pvUser;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync wined3d_mutex_lock();
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync VBoxTlsRefRelease(context);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync wined3d_mutex_unlock();
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync}
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsyncvoid VBoxExtReleaseContextAsync(struct wined3d_context *context)
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync{
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync HRESULT hr;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync hr = VBoxExtDwSubmitProcAsync(vboxExtReleaseContextWorker, context);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync if (FAILED(hr))
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync {
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync ERR("VBoxExtDwSubmitProcAsync feiled, hr (0x%x)\n", hr);
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync return;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync }
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync}
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync#endif /* #if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT) */
df4e0d2af793d52c48d1f2a91a575d78eb728511vboxsync
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync/* window creation API */
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsyncstatic LRESULT CALLBACK vboxExtWndProc(HWND hwnd,
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync UINT uMsg,
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync WPARAM wParam,
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync LPARAM lParam
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync)
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync{
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync switch(uMsg)
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync {
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync case WM_CLOSE:
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync TRACE("got WM_CLOSE for hwnd(0x%x)", hwnd);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync return 0;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync case WM_DESTROY:
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync TRACE("got WM_DESTROY for hwnd(0x%x)", hwnd);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync return 0;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync case WM_NCHITTEST:
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync TRACE("got WM_NCHITTEST for hwnd(0x%x)\n", hwnd);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync return HTNOWHERE;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync }
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync return DefWindowProc(hwnd, uMsg, wParam, lParam);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync}
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync#define VBOXEXTWND_NAME "VboxDispD3DWineWnd"
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsyncstatic HRESULT vboxExtWndDoCleanup()
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync{
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync HRESULT hr = S_OK;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync WNDCLASS wc;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync if (GetClassInfo(hInstance, VBOXEXTWND_NAME, &wc))
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync {
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync if (!UnregisterClass(VBOXEXTWND_NAME, hInstance))
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync {
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync DWORD winEr = GetLastError();
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync ERR("UnregisterClass failed, winErr(%d)\n", winEr);
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync hr = E_FAIL;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync }
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync }
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync return hr;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync}
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsyncstatic HRESULT vboxExtWndDoCreate(DWORD w, DWORD h, HWND *phWnd, HDC *phDC)
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync{
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync HRESULT hr = S_OK;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync /* Register the Window Class. */
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync WNDCLASS wc;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync if (!GetClassInfo(hInstance, VBOXEXTWND_NAME, &wc))
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync {
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync wc.style = 0;//CS_OWNDC;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync wc.lpfnWndProc = vboxExtWndProc;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync wc.cbClsExtra = 0;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync wc.cbWndExtra = 0;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync wc.hInstance = hInstance;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync wc.hIcon = NULL;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync wc.hCursor = NULL;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync wc.hbrBackground = NULL;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync wc.lpszMenuName = NULL;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync wc.lpszClassName = VBOXEXTWND_NAME;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync if (!RegisterClass(&wc))
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync {
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync DWORD winErr = GetLastError();
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync ERR("RegisterClass failed, winErr(%d)\n", winErr);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync hr = E_FAIL;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync }
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync }
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync if (hr == S_OK)
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync {
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync HWND hWnd = CreateWindowEx (WS_EX_TOOLWINDOW,
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync VBOXEXTWND_NAME, VBOXEXTWND_NAME,
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED,
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync 0, 0,
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync w, h,
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync NULL, //GetDesktopWindow() /* hWndParent */,
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync NULL /* hMenu */,
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync hInstance,
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync NULL /* lpParam */);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync Assert(hWnd);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync if (hWnd)
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync {
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync *phWnd = hWnd;
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync *phDC = GetDC(hWnd);
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync /* make sure we keep inited until the window is active */
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync vboxExtAddRef();
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync }
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync else
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync {
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync DWORD winErr = GetLastError();
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync ERR("CreateWindowEx failed, winErr(%d)\n", winErr);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync hr = E_FAIL;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync }
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync }
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync return hr;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync}
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsyncstatic HRESULT vboxExtWndDoDestroy(HWND hWnd, HDC hDC)
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync{
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync BOOL bResult;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync DWORD winErr;
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync ReleaseDC(hWnd, hDC);
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync bResult = DestroyWindow(hWnd);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync Assert(bResult);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync if (bResult)
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync {
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync /* release the reference we previously acquired on window creation */
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync vboxExtRelease();
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync return S_OK;
4bf130c00563c28f21f65234bb7b898b25a1a179vboxsync }
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync winErr = GetLastError();
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync ERR("DestroyWindow failed, winErr(%d) for hWnd(0x%x)\n", winErr, hWnd);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync return E_FAIL;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync}
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsynctypedef struct VBOXEXTWND_CREATE_INFO
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync{
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync int hr;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync HWND hWnd;
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync HDC hDC;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync DWORD width;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync DWORD height;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync} VBOXEXTWND_CREATE_INFO;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsynctypedef struct VBOXEXTWND_DESTROY_INFO
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync{
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync int hr;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync HWND hWnd;
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync HDC hDC;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync} VBOXEXTWND_DESTROY_INFO;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsynctypedef struct VBOXEXTWND_CLEANUP_INFO
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync{
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync int hr;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync} VBOXEXTWND_CLEANUP_INFO;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsyncstatic DECLCALLBACK(void) vboxExtWndDestroyWorker(void *pvUser)
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync{
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync VBOXEXTWND_DESTROY_INFO *pInfo = (VBOXEXTWND_DESTROY_INFO*)pvUser;
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync pInfo->hr = vboxExtWndDoDestroy(pInfo->hWnd, pInfo->hDC);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync Assert(pInfo->hr == S_OK);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync}
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsyncstatic DECLCALLBACK(void) vboxExtWndCreateWorker(void *pvUser)
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync{
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync VBOXEXTWND_CREATE_INFO *pInfo = (VBOXEXTWND_CREATE_INFO*)pvUser;
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync pInfo->hr = vboxExtWndDoCreate(pInfo->width, pInfo->height, &pInfo->hWnd, &pInfo->hDC);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync Assert(pInfo->hr == S_OK);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync}
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsyncstatic DECLCALLBACK(void) vboxExtWndCleanupWorker(void *pvUser)
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync{
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync VBOXEXTWND_CLEANUP_INFO *pInfo = (VBOXEXTWND_CLEANUP_INFO*)pvUser;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync pInfo-> hr = vboxExtWndDoCleanup();
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync}
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsyncHRESULT VBoxExtWndDestroy(HWND hWnd, HDC hDC)
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync{
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync HRESULT hr;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync VBOXEXTWND_DESTROY_INFO Info;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync Info.hr = E_FAIL;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync Info.hWnd = hWnd;
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsync Info.hDC = hDC;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync hr = VBoxExtDwSubmitProcSync(vboxExtWndDestroyWorker, &Info);
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync if (!SUCCEEDED(hr))
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync {
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync ERR("VBoxExtDwSubmitProcSync-vboxExtWndDestroyWorker failed hr %d", hr);
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync return hr;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync }
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync if (!SUCCEEDED(Info.hr))
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync {
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync ERR("vboxExtWndDestroyWorker failed hr %d", Info.hr);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync return Info.hr;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync }
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync return S_OK;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync}
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync
3a974120cf0d8d23b2531cd62fe04532e6ac205evboxsyncHRESULT VBoxExtWndCreate(DWORD width, DWORD height, HWND *phWnd, HDC *phDC)
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync{
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync HRESULT hr;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync VBOXEXTWND_CREATE_INFO Info;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync Info.hr = E_FAIL;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync Info.width = width;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync Info.height = height;
6decafdf89f825b3af922ab6fa02345e08e5be7bvboxsync hr = VBoxExtDwSubmitProcSync(vboxExtWndCreateWorker, &Info);
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync if (!SUCCEEDED(hr))
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync {
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync ERR("VBoxExtDwSubmitProcSync-vboxExtWndCreateWorker failed hr %d", hr);
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync return hr;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync }
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync Assert(Info.hr == S_OK);
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync if (!SUCCEEDED(Info.hr))
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync {
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync ERR("vboxExtWndCreateWorker failed hr %d", Info.hr);
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync return Info.hr;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync }
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync *phWnd = Info.hWnd;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync *phDC = Info.hDC;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync return S_OK;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync}
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsyncstatic HRESULT vboxExtWndCleanup()
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync{
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync HRESULT hr;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync VBOXEXTWND_CLEANUP_INFO Info;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync Info.hr = E_FAIL;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync hr = VBoxExtDwSubmitProcSync(vboxExtWndCleanupWorker, &Info);
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync if (!SUCCEEDED(hr))
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync {
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync ERR("VBoxExtDwSubmitProcSync-vboxExtWndCleanupWorker failed hr %d", hr);
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync return hr;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync }
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync if (!SUCCEEDED(Info.hr))
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync {
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync ERR("vboxExtWndCleanupWorker failed hr %d", Info.hr);
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync return Info.hr;
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync }
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync
a11b298cea66713a07ea8105ebb4d12574477e9fvboxsync return S_OK;
3b5b00fc19a7b52f11075648a1b93d477137f4d3vboxsync}
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync/* hash map impl */
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsyncstatic void vboxExtHashInitEntries(PVBOXEXT_HASHMAP pMap)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync{
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync uint32_t i;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync pMap->cEntries = 0;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync for (i = 0; i < RT_ELEMENTS(pMap->aBuckets); ++i)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync {
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync RTListInit(&pMap->aBuckets[i].EntryList);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync }
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync}
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsyncvoid VBoxExtHashInit(PVBOXEXT_HASHMAP pMap, PFNVBOXEXT_HASHMAP_HASH pfnHash, PFNVBOXEXT_HASHMAP_EQUAL pfnEqual)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync{
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync pMap->pfnHash = pfnHash;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync pMap->pfnEqual = pfnEqual;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync vboxExtHashInitEntries(pMap);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync}
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsyncstatic DECLINLINE(uint32_t) vboxExtHashIdx(uint32_t u32Hash)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync{
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync return u32Hash % VBOXEXT_HASHMAP_NUM_BUCKETS;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync}
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync#define VBOXEXT_FOREACH_NODE(_pNode, _pList, _op) do { \
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync PRTLISTNODE _pNode; \
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync PRTLISTNODE __pNext; \
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync for (_pNode = (_pList)->pNext; \
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync _pNode != (_pList); \
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync _pNode = __pNext) \
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync { \
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync __pNext = _pNode->pNext; /* <- the _pNode should not be referenced after the _op */ \
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync _op \
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync } \
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync } while (0)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsyncDECLINLINE(PVBOXEXT_HASHMAP_ENTRY) vboxExtHashSearchEntry(PVBOXEXT_HASHMAP pMap, void *pvKey)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync{
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync uint32_t u32Hash = pMap->pfnHash(pvKey);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync uint32_t u32HashIdx = vboxExtHashIdx(u32Hash);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync PVBOXEXT_HASHMAP_BUCKET pBucket = &pMap->aBuckets[u32HashIdx];
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync PVBOXEXT_HASHMAP_ENTRY pEntry;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync VBOXEXT_FOREACH_NODE(pNode, &pBucket->EntryList,
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync pEntry = RT_FROM_MEMBER(pNode, VBOXEXT_HASHMAP_ENTRY, ListNode);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync if (pEntry->u32Hash != u32Hash)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync continue;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync if (!pMap->pfnEqual(pvKey, pEntry->pvKey))
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync continue;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync return pEntry;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync );
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync return NULL;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync}
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsyncvoid* VBoxExtHashRemoveEntry(PVBOXEXT_HASHMAP pMap, PVBOXEXT_HASHMAP_ENTRY pEntry)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync{
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync RTListNodeRemove(&pEntry->ListNode);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync --pMap->cEntries;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync Assert(pMap->cEntries <= UINT32_MAX/2);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync return pEntry->pvKey;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync}
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsyncstatic void vboxExtHashPutEntry(PVBOXEXT_HASHMAP pMap, PVBOXEXT_HASHMAP_BUCKET pBucket, PVBOXEXT_HASHMAP_ENTRY pEntry)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync{
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync RTListNodeInsertAfter(&pBucket->EntryList, &pEntry->ListNode);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync ++pMap->cEntries;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync}
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsyncPVBOXEXT_HASHMAP_ENTRY VBoxExtHashRemove(PVBOXEXT_HASHMAP pMap, void *pvKey)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync{
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync PVBOXEXT_HASHMAP_ENTRY pEntry = vboxExtHashSearchEntry(pMap, pvKey);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync if (!pEntry)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync return NULL;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync VBoxExtHashRemoveEntry(pMap, pEntry);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync return pEntry;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync}
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsyncPVBOXEXT_HASHMAP_ENTRY VBoxExtHashPut(PVBOXEXT_HASHMAP pMap, void *pvKey, PVBOXEXT_HASHMAP_ENTRY pEntry)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync{
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync PVBOXEXT_HASHMAP_ENTRY pOldEntry = VBoxExtHashRemove(pMap, pvKey);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync uint32_t u32Hash = pMap->pfnHash(pvKey);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync uint32_t u32HashIdx = vboxExtHashIdx(u32Hash);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync pEntry->pvKey = pvKey;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync pEntry->u32Hash = u32Hash;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync vboxExtHashPutEntry(pMap, &pMap->aBuckets[u32HashIdx], pEntry);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync return pOldEntry;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync}
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsyncPVBOXEXT_HASHMAP_ENTRY VBoxExtHashGet(PVBOXEXT_HASHMAP pMap, void *pvKey)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync{
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync return vboxExtHashSearchEntry(pMap, pvKey);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync}
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsyncvoid VBoxExtHashVisit(PVBOXEXT_HASHMAP pMap, PFNVBOXEXT_HASHMAP_VISITOR pfnVisitor, void *pvVisitor)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync{
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync uint32_t iBucket = 0, iEntry = 0;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync uint32_t cEntries = pMap->cEntries;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync if (!cEntries)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync return;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync for (; ; ++iBucket)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync {
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync PVBOXEXT_HASHMAP_ENTRY pEntry;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync PVBOXEXT_HASHMAP_BUCKET pBucket = &pMap->aBuckets[iBucket];
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync Assert(iBucket < RT_ELEMENTS(pMap->aBuckets));
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync VBOXEXT_FOREACH_NODE(pNode, &pBucket->EntryList,
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync pEntry = RT_FROM_MEMBER(pNode, VBOXEXT_HASHMAP_ENTRY, ListNode);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync if (!pfnVisitor(pMap, pEntry->pvKey, pEntry, pvVisitor))
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync return;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync if (++iEntry == cEntries)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync return;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync );
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync }
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync /* should not be here! */
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync AssertFailed();
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync}
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsyncvoid VBoxExtHashCleanup(PVBOXEXT_HASHMAP pMap, PFNVBOXEXT_HASHMAP_VISITOR pfnVisitor, void *pvVisitor)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync{
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync VBoxExtHashVisit(pMap, pfnVisitor, pvVisitor);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync vboxExtHashInitEntries(pMap);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync}
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsyncstatic DECLCALLBACK(bool) vboxExtCacheCleanupCb(struct VBOXEXT_HASHMAP *pMap, void *pvKey, struct VBOXEXT_HASHMAP_ENTRY *pValue, void *pvVisitor)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync{
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync PVBOXEXT_HASHCACHE pCache = VBOXEXT_HASHCACHE_FROM_MAP(pMap);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync PVBOXEXT_HASHCACHE_ENTRY pCacheEntry = VBOXEXT_HASHCACHE_ENTRY_FROM_MAP(pValue);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync pCache->pfnCleanupEntry(pvKey, pCacheEntry);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync return TRUE;
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync}
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsyncvoid VBoxExtCacheCleanup(PVBOXEXT_HASHCACHE pCache)
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync{
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync VBoxExtHashCleanup(&pCache->Map, vboxExtCacheCleanupCb, NULL);
b62daae35a821b998dc41ab2c90da52d18b6f229vboxsync}