VBoxMPMisc.cpp revision 3a343ca21a267ec3c54e2317e2ed18fe99b8ebbb
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * VBox WDDM Miniport driver
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * Copyright (C) 2011 Oracle Corporation
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * available from http://www.virtualbox.org. This file is free software;
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * you can redistribute it and/or modify it under the terms of the GNU
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * General Public License (GPL) as published by the Free Software
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync/* simple handle -> value table API */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxWddmHTableCreate(PVBOXWDDM_HTABLE pTbl, uint32_t cSize)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync pTbl->paData = (PVOID*)vboxWddmMemAllocZero(sizeof (pTbl->paData[0]) * cSize);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncDECLINLINE(VBOXWDDM_HANDLE) vboxWddmHTableIndex2Handle(uint32_t iIndex)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncDECLINLINE(uint32_t) vboxWddmHTableHandle2Index(VBOXWDDM_HANDLE hHandle)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxWddmHTableRealloc(PVBOXWDDM_HTABLE pTbl, uint32_t cNewSize)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync PVOID *pvNewData = (PVOID*)vboxWddmMemAllocZero(sizeof (pTbl->paData[0]) * cNewSize);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync WARN(("vboxWddmMemAllocZero failed for size (%d)", sizeof (pTbl->paData[0]) * cNewSize));
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync memcpy(pvNewData, pTbl->paData, sizeof (pTbl->paData[0]) * pTbl->cSize);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncVBOXWDDM_HANDLE vboxWddmHTablePut(PVBOXWDDM_HTABLE pTbl, PVOID pvData)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync NTSTATUS Status = vboxWddmHTableRealloc(pTbl, pTbl->cSize + RT_MAX(10, pTbl->cSize/4));
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync for (UINT i = pTbl->iNext2Search; ; ++i, i %= pTbl->cSize)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncPVOID vboxWddmHTableRemove(PVBOXWDDM_HTABLE pTbl, VBOXWDDM_HANDLE hHandle)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync uint32_t iIndex = vboxWddmHTableHandle2Index(hHandle);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncPVOID vboxWddmHTableGet(PVBOXWDDM_HTABLE pTbl, VBOXWDDM_HANDLE hHandle)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync uint32_t iIndex = vboxWddmHTableHandle2Index(hHandle);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncVOID vboxWddmHTableIterInit(PVBOXWDDM_HTABLE pTbl, PVBOXWDDM_HTABLE_ITERATOR pIter)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncBOOL vboxWddmHTableIterHasNext(PVBOXWDDM_HTABLE_ITERATOR pIter)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncPVOID vboxWddmHTableIterNext(PVBOXWDDM_HTABLE_ITERATOR pIter, VBOXWDDM_HANDLE *phHandle)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync for (uint32_t i = pIter->iCur+1; i < pIter->pTbl->cSize ; ++i)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync VBOXWDDM_HANDLE hHandle = vboxWddmHTableIndex2Handle(i);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncPVOID vboxWddmHTableIterRemoveCur(PVBOXWDDM_HTABLE_ITERATOR pIter)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync VBOXWDDM_HANDLE hHandle = vboxWddmHTableIndex2Handle(pIter->iCur);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync PVOID pRet = vboxWddmHTableRemove(pIter->pTbl, hHandle);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync PVBOXWDDM_SWAPCHAIN pSwapchain = (PVBOXWDDM_SWAPCHAIN)vboxWddmMemAllocZero(sizeof (VBOXWDDM_SWAPCHAIN));
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync pSwapchain->enmState = VBOXWDDM_OBJSTATE_TYPE_INITIALIZED;
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncDECLINLINE(BOOLEAN) vboxWddmSwapchainRetainLocked(PVBOXWDDM_SWAPCHAIN pSwapchain)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync if (pSwapchain->enmState == VBOXWDDM_OBJSTATE_TYPE_INITIALIZED)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncDECLINLINE(BOOLEAN) vboxWddmSwapchainRetain(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncDECLINLINE(VOID) vboxWddmSwapchainRelease(PVBOXWDDM_SWAPCHAIN pSwapchain)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync const uint32_t cRefs = ASMAtomicDecU32(&pSwapchain->cRefs);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncPVBOXWDDM_SWAPCHAIN vboxWddmSwapchainRetainByAlloc(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAlloc)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync if (pSwapchain && !vboxWddmSwapchainRetainLocked(pSwapchain))
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncVOID vboxWddmSwapchainAllocRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain, PVBOXWDDM_ALLOCATION pAlloc)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncBOOLEAN vboxWddmSwapchainAllocAdd(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain, PVBOXWDDM_ALLOCATION pAlloc)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync InsertTailList(&pSwapchain->AllocList, &pAlloc->SwapchainEntry);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync#define VBOXSCENTRY_2_ALLOC(_pE) ((PVBOXWDDM_ALLOCATION)((uint8_t*)(_pE) - RT_OFFSETOF(VBOXWDDM_ALLOCATION, SwapchainEntry)))
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncstatic VOID vboxWddmSwapchainAllocRemoveAllInternal(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain, BOOLEAN bOnDestroy)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync PVBOXWDDM_ALLOCATION pAlloc = VBOXSCENTRY_2_ALLOC(pEntry);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync } while (1);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync pSwapchain->enmState = VBOXWDDM_OBJSTATE_TYPE_TERMINATED;
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncVOID vboxWddmSwapchainAllocRemoveAll(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync vboxWddmSwapchainAllocRemoveAllInternal(pDevExt, pSwapchain, FALSE);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncVOID vboxWddmSwapchainDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SWAPCHAIN pSwapchain)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync vboxWddmSwapchainAllocRemoveAllInternal(pDevExt, pSwapchain, TRUE);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync NTSTATUS tmpStatus = vboxVdmaGgCmdCancel(pDevExt, pSwapchain->pContext, pSwapchain);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync WARN(("vboxVdmaGgCmdCancel returned Status (0x%x)", tmpStatus));
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncstatic BOOLEAN vboxWddmSwapchainCtxAddLocked(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync pSwapchain->hSwapchainKm = vboxWddmHTablePut(&pContext->Swapchains, pSwapchain);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync InsertHeadList(&pDevExt->SwapchainList3D, &pSwapchain->DevExtListEntry);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncstatic VOID vboxWddmSwapchainCtxRemoveLocked(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync void * pTst = vboxWddmHTableRemove(&pContext->Swapchains, pSwapchain->hSwapchainKm);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync vboxVideoCmCmdRelease(pSwapchain->pLastReportedRects);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync/* adds the given swapchain to the context's swapchain list
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @return true on success */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncBOOLEAN vboxWddmSwapchainCtxAdd(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync bRc = vboxWddmSwapchainCtxAddLocked(pDevExt, pContext, pSwapchain);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync/* removes the given swapchain from the context's swapchain list
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncVOID vboxWddmSwapchainCtxRemove(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync vboxWddmSwapchainCtxRemoveLocked(pDevExt, pContext, pSwapchain);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync/* destroys all swapchains for the given context
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncVOID vboxWddmSwapchainCtxDestroyAll(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync vboxWddmHTableIterInit(&pContext->Swapchains, &Iter);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync PVBOXWDDM_SWAPCHAIN pSwapchain = (PVBOXWDDM_SWAPCHAIN)vboxWddmHTableIterNext(&Iter, NULL);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* yes, we can call remove locked even when using iterator */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync vboxWddmSwapchainCtxRemoveLocked(pDevExt, pContext, pSwapchain);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* we must not do vboxWddmSwapchainDestroy inside a context mutex */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* start from the very beginning, we will quit the loop when no swapchains left */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync } while (1);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* no swapchains left, we exiteed the while loop via the "break", and we still owning the mutex */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync/* process the swapchain info passed from user-mode display driver & synchronizes the driver state with it */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxWddmSwapchainCtxEscape(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXDISPIFESCAPE_SWAPCHAININFO pSwapchainInfo, UINT cbSize)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync Assert((cbSize >= RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[0])));
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync if (cbSize < RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[0]))
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync Assert(cbSize >= RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[pSwapchainInfo->SwapchainInfo.cAllocs]));
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync if (cbSize < RT_OFFSETOF(VBOXDISPIFESCAPE_SWAPCHAININFO, SwapchainInfo.ahAllocs[pSwapchainInfo->SwapchainInfo.cAllocs]))
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync apAlloc = (PVBOXWDDM_ALLOCATION *)vboxWddmMemAlloc(sizeof (PVBOXWDDM_ALLOCATION) * pSwapchainInfo->SwapchainInfo.cAllocs);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync for (UINT i = 0; i < pSwapchainInfo->SwapchainInfo.cAllocs; ++i)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync GhData.hObject = pSwapchainInfo->SwapchainInfo.ahAllocs[i];
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pDevExt->u.primary.DxgkInterface.DxgkCbGetHandleData(&GhData);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync pSwapchain = (PVBOXWDDM_SWAPCHAIN)vboxWddmHTableGet(&pContext->Swapchains, (VBOXWDDM_HANDLE)pSwapchainInfo->SwapchainInfo.hSwapchainKm);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync Assert(pSwapchain->hSwapchainKm == pSwapchainInfo->SwapchainInfo.hSwapchainKm);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync BOOLEAN bRc = vboxWddmSwapchainCtxAddLocked(pDevExt, pContext, pSwapchain);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* do not zero up the view rect since it may still be valid */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync// memset(&pSwapchain->ViewRect, 0, sizeof (pSwapchain->ViewRect));
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync vboxVideoCmCmdRelease(pSwapchain->pLastReportedRects);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync vboxWddmSwapchainAllocRemoveAll(pDevExt, pSwapchain);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync for (UINT i = 0; i < pSwapchainInfo->SwapchainInfo.cAllocs; ++i)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync vboxWddmSwapchainAllocAdd(pDevExt, pSwapchain, apAlloc[i]);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync pSwapchain->hSwapchainUm = pSwapchainInfo->SwapchainInfo.hSwapchainUm;
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync vboxWddmSwapchainCtxRemoveLocked(pDevExt, pContext, pSwapchain);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync pSwapchainInfo->SwapchainInfo.hSwapchainKm = pSwapchain->hSwapchainKm;
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync } while (0);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* cleanup */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxWddmSwapchainCtxInit(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync NTSTATUS Status = vboxWddmHTableCreate(&pContext->Swapchains, 4);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync WARN(("vboxWddmHTableCreate failes, Status (x%x)", Status));
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncVOID vboxWddmSwapchainCtxTerm(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync#define VBOXWDDM_REG_DRVKEY_PREFIX L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxWddmRegQueryDrvKeyName(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync bool bFallback = false;
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync memcpy(pBuf, VBOXWDDM_REG_DRVKEY_PREFIX, sizeof (VBOXWDDM_REG_DRVKEY_PREFIX));
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync pSuffix = pBuf + (sizeof (VBOXWDDM_REG_DRVKEY_PREFIX)-2)/2;
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync NTSTATUS Status = IoGetDeviceProperty (pDevExt->pPDO,
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync *pcbResult = cbBuf + sizeof (VBOXWDDM_REG_DRVKEY_PREFIX)-2;
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync#define VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_VISTA L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Control\\VIDEO\\"
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync#define VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7 L"\\Registry\\Machine\\System\\CurrentControlSet\\Hardware Profiles\\UnitedVideo\\CONTROL\\VIDEO\\"
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync#define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELX L"Attach.RelativeX"
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync#define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELY L"Attach.RelativeY"
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync#define VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_DESKTOP L"Attach.ToDesktop"
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxWddmRegQueryDisplaySettingsKeyName(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId,
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync bool bFallback = false;
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync UNICODE_STRING* pVGuid = vboxWddmVGuidGet(pDevExt);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync pKeyPrefix = VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_VISTA;
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync cbKeyPrefix = sizeof (VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_VISTA);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync pKeyPrefix = VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7;
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync cbKeyPrefix = sizeof (VBOXWDDM_REG_DISPLAYSETTINGSKEY_PREFIX_WIN7);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync ULONG cbResult = cbKeyPrefix + pVGuid->Length + 2 + 8; // L"\\" + "XXXX"
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync#define VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\"
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync#define VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY L"\\Video"
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxWddmRegQueryVideoGuidString(ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync NTSTATUS Status = vboxWddmRegOpenKey(&hKey, VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY, GENERIC_READ);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync WCHAR KeyBuf[sizeof (VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY)/2 + 256 + 64];
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync wcscpy(KeyBuf, VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync Status = ZwEnumerateKey(hKey, i, KeyBasicInformation, &Buf, sizeof (Buf), &ResultLength);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* we should not encounter STATUS_NO_MORE_ENTRIES here since this would mean we did not find our entry */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync PWCHAR pSubBuf = KeyBuf + (sizeof (VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY) - 2)/2;
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync memcpy(pSubBuf, Buf.Name.Name, Buf.Name.NameLength);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync memcpy(pSubBuf, VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY, sizeof (VBOXWDDM_REG_DISPLAYSETTINGSVIDEOKEY_SUBKEY));
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync Status = vboxWddmRegOpenKey(&hSubKey, KeyBuf, GENERIC_READ);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync UCHAR Buf[sizeof (L"VBoxVideoWddm")]; /* should be enough */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync Assert(Status == STATUS_SUCCESS || STATUS_BUFFER_TOO_SMALL || STATUS_BUFFER_OVERFLOW);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync if (KeyData.Info.DataLength == sizeof (L"VBoxVideoWddm"))
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync if (!wcscmp(L"VBoxVideoWddm", (PWCHAR)KeyData.Info.Data))
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync memcpy(pBuf, Buf.Name.Name, Buf.Name.NameLength + 2);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxWddmRegOpenKey(OUT PHANDLE phKey, IN PWCHAR pName, IN ACCESS_MASK fAccess)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync InitializeObjectAttributes(&ObjAttr, &RtlStr, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxWddmRegOpenDisplaySettingsKey(IN PVBOXMP_DEVEXT pDeviceExtension, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, OUT PHANDLE phKey)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync NTSTATUS Status = vboxWddmRegQueryDisplaySettingsKeyName(pDeviceExtension, VidPnSourceId, cbBuf, Buf, &cbBuf);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync Status = vboxWddmRegOpenKey(phKey, Buf, GENERIC_READ);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* fall-back to make the subsequent VBoxVideoCmnRegXxx calls treat the fail accordingly
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * basically needed to make as less modifications to the current XPDM code as possible */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxWddmRegDisplaySettingsQueryRelX(HANDLE hKey, int * pResult)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync NTSTATUS Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELX, &dwVal);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxWddmRegDisplaySettingsQueryRelY(HANDLE hKey, int * pResult)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync NTSTATUS Status = vboxWddmRegQueryValueDword(hKey, VBOXWDDM_REG_DISPLAYSETTINGS_ATTACH_RELY, &dwVal);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxWddmDisplaySettingsQueryPos(IN PVBOXMP_DEVEXT pDeviceExtension, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, POINT * pPos)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync NTSTATUS Status = vboxWddmRegOpenDisplaySettingsKey(pDeviceExtension, VidPnSourceId, &hKey);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync Status = vboxWddmRegDisplaySettingsQueryRelX(hKey, &x);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync Status = vboxWddmRegDisplaySettingsQueryRelY(hKey, &y);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxWddmRegQueryValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT PDWORD pDword)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxWddmRegSetValueDword(IN HANDLE hKey, IN PWCHAR pName, OUT DWORD val)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncUNICODE_STRING* vboxWddmVGuidGet(PVBOXMP_DEVEXT pDevExt)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync NTSTATUS Status = vboxWddmRegQueryVideoGuidString(cbVideoGuidBuf, VideoGuidBuf, &cbVideoGuidBuf);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync PWCHAR pBuf = (PWCHAR)vboxWddmMemAllocZero(cbVideoGuidBuf);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync UINT cbBuffer = VBOXWDDM_ROUNDBOUND(cPages, 8) >> 3;
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync PULONG pBuf = (PULONG)vboxWddmMemAllocZero(cbBuffer);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync ULONG iPage = RtlFindClearBitsAndSet(&pMm->BitMap, cPages, 0);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncVOID vboxMmFree(PVBOXWDDM_MM pMm, UINT iPage, UINT cPages)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync Assert(RtlAreBitsSet(&pMm->BitMap, iPage, cPages));
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxVideoCmAllocAlloc(PVBOXVIDEOCM_ALLOC_MGR pMgr, PVBOXVIDEOCM_ALLOC pAlloc)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync uint32_t offData = pMgr->offData + (iPage << PAGE_SHIFT);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync Assert(offData + cbSize <= pMgr->offData + pMgr->cbData);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync pAlloc->hGlobalHandle = vboxWddmHTablePut(&pMgr->AllocTable, pAlloc);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync if (VBOXWDDM_HANDLE_INVALID != pAlloc->hGlobalHandle)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncVOID vboxVideoCmAllocDealloc(PVBOXVIDEOCM_ALLOC_MGR pMgr, PVBOXVIDEOCM_ALLOC pAlloc)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync UINT iPage = BYTES_TO_PAGES(pAlloc->offData - pMgr->offData);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync vboxWddmHTableRemove(&pMgr->AllocTable, pAlloc->hGlobalHandle);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncNTSTATUS vboxVideoAMgrAllocCreate(PVBOXVIDEOCM_ALLOC_MGR pMgr, UINT cbSize, PVBOXVIDEOCM_ALLOC *ppAlloc)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync PVBOXVIDEOCM_ALLOC pAlloc = (PVBOXVIDEOCM_ALLOC)vboxWddmMemAllocZero(sizeof (*pAlloc));
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncVOID vboxVideoAMgrAllocDestroy(PVBOXVIDEOCM_ALLOC_MGR pMgr, PVBOXVIDEOCM_ALLOC pAlloc)
NTSTATUS vboxVideoAMgrCtxAllocMap(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, PVBOXVIDEOCM_ALLOC pAlloc, PVBOXVIDEOCM_UM_ALLOC pUmAlloc)
Status = ObReferenceObjectByHandle((HANDLE)pUmAlloc->hSynch, EVENT_MODIFY_STATE, *ExEventObjectType, UserMode,
NULL);
Status = ObReferenceObjectByHandle((HANDLE)pUmAlloc->hSynch, EVENT_MODIFY_STATE, *ExSemaphoreObjectType, UserMode,
NULL);
PVBOXVIDEOCM_ALLOC_REF pAllocRef = (PVBOXVIDEOCM_ALLOC_REF)vboxWddmMemAllocZero(sizeof (*pAllocRef) + sizeof (PFN_NUMBER) * ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseVa, cbLength));
if (pAllocRef)
Assert(0);
if (pvUm)
return STATUS_SUCCESS;
Assert(0);
Assert(0);
if (pSynchEvent)
Assert(0);
return Status;
NTSTATUS vboxVideoAMgrCtxAllocUnmap(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, VBOXDISP_KMHANDLE hSesionHandle, PVBOXVIDEOCM_ALLOC *ppAlloc)
PVBOXVIDEOCM_ALLOC_REF pAllocRef = (PVBOXVIDEOCM_ALLOC_REF)vboxWddmHTableRemove(&pContext->AllocTable, hSesionHandle);
if (pAllocRef)
Assert(0);
return Status;
static PVBOXVIDEOCM_ALLOC_REF vboxVideoAMgrCtxAllocRefAcquire(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, VBOXDISP_KMHANDLE hSesionHandle)
PVBOXVIDEOCM_ALLOC_REF pAllocRef = (PVBOXVIDEOCM_ALLOC_REF)vboxWddmHTableGet(&pContext->AllocTable, hSesionHandle);
return pAllocRef;
Assert(cRefs >= 1); /* we do not do cleanup-on-zero here, instead we wait for the cRefs to reach 1 in vboxVideoAMgrCtxAllocUnmap before unmapping */
NTSTATUS vboxVideoAMgrCtxAllocCreate(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, PVBOXVIDEOCM_UM_ALLOC pUmAlloc)
return STATUS_SUCCESS;
Assert(0);
Assert(0);
return Status;
NTSTATUS vboxVideoAMgrCtxAllocDestroy(PVBOXVIDEOCM_ALLOC_CONTEXT pContext, VBOXDISP_KMHANDLE hSesionHandle)
Assert(0);
return Status;
#ifdef VBOX_WITH_CRHGSMI
static DECLCALLBACK(VOID) vboxVideoAMgrAllocSubmitCompletion(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
FALSE);
Assert(0);
NTSTATUS vboxVideoAMgrCtxAllocSubmit(PVBOXMP_DEVEXT pDevExt, PVBOXVIDEOCM_ALLOC_CONTEXT pContext, UINT cBuffers, VBOXWDDM_UHGSMI_BUFFER_UI_INFO_ESCAPE *paBuffers)
UINT cbCmd = VBOXVDMACMD_SIZE_FROMBODYSIZE(RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CMD, aBuffers[cBuffers]));
if (pDr)
if (pRef)
#ifdef DEBUG_misha
for (UINT j = 0; j < i; ++j)
return STATUS_SUCCESS;
Assert(0);
return Status;
NTSTATUS vboxVideoAMgrCreate(PVBOXMP_DEVEXT pDevExt, PVBOXVIDEOCM_ALLOC_MGR pMgr, uint32_t offData, uint32_t cbData)
if (!cbData)
return STATUS_INVALID_PARAMETER;
return STATUS_SUCCESS;
return Status;
return STATUS_SUCCESS;
return STATUS_SUCCESS;
return Status;
return STATUS_SUCCESS;
if (!pRef)
return Status;
if (!hSharedRc)
return FALSE;
#define PVBOXWDDM_ALLOCATION_FROM_SHRCTREENODE(_p) ((PVBOXWDDM_ALLOCATION)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXWDDM_ALLOCATION, ShRcTreeEntry)))
if (!pNode)
return NULL;
return pAlloc;
if (!hSharedRc)
return FALSE;
if (!pNode)
return NULL;
return !!pRetAlloc;