9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* $Id$ */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** @file
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VBox WDDM Miniport driver
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Copyright (C) 2011 Oracle Corporation
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * available from http://www.virtualbox.org. This file is free software;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * General Public License (GPL) as published by the Free Software
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include "VBoxMPWddm.h"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsynctypedef struct VBOXVIDEOCM_CMD_DR
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync LIST_ENTRY QueueList;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_CTX pContext;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t cbMaxCmdSize;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync volatile uint32_t cRefs;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXVIDEOCM_CMD_HDR CmdHdr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync} VBOXVIDEOCM_CMD_DR, *PVBOXVIDEOCM_CMD_DR;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsynctypedef enum
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync{
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync VBOXVIDEOCM_CMD_CTL_KM_TYPE_POST_INVOKE = 1,
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync VBOXVIDEOCM_CMD_CTL_KM_TYPE_PRE_INVOKE,
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync VBOXVIDEOCM_CMD_CTL_KM_TYPE_DUMMY_32BIT = 0x7fffffff
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync} VBOXVIDEOCM_CMD_CTL_KM_TYPE;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsynctypedef DECLCALLBACK(VOID) FNVBOXVIDEOCM_CMD_CB(PVBOXVIDEOCM_CTX pContext, struct VBOXVIDEOCM_CMD_CTL_KM *pCmd, PVOID pvContext);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsynctypedef FNVBOXVIDEOCM_CMD_CB *PFNVBOXVIDEOCM_CMD_CB;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsynctypedef struct VBOXVIDEOCM_CMD_CTL_KM
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync{
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync VBOXVIDEOCM_CMD_CTL_KM_TYPE enmType;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync uint32_t u32Reserved;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PFNVBOXVIDEOCM_CMD_CB pfnCb;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PVOID pvCb;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync} VBOXVIDEOCM_CMD_CTL_KM, *PVBOXVIDEOCM_CMD_CTL_KM;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncAssertCompile(VBOXWDDM_ROUNDBOUND(RT_OFFSETOF(VBOXVIDEOCM_CMD_DR, CmdHdr), 8) == RT_OFFSETOF(VBOXVIDEOCM_CMD_DR, CmdHdr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define VBOXVIDEOCM_HEADER_SIZE() (VBOXWDDM_ROUNDBOUND(sizeof (VBOXVIDEOCM_CMD_DR), 8))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define VBOXVIDEOCM_SIZE_FROMBODYSIZE(_s) (VBOXVIDEOCM_HEADER_SIZE() + (_s))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//#define VBOXVIDEOCM_SIZE(_t) (VBOXVIDEOCM_SIZE_FROMBODYSIZE(sizeof (_t)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define VBOXVIDEOCM_BODY(_pCmd, _t) ( (_t*)(((uint8_t*)(_pCmd)) + VBOXVIDEOCM_HEADER_SIZE()) )
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define VBOXVIDEOCM_HEAD(_pCmd) ( (PVBOXVIDEOCM_CMD_DR)(((uint8_t*)(_pCmd)) - VBOXVIDEOCM_HEADER_SIZE()) )
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define VBOXVIDEOCM_SENDSIZE_FROMBODYSIZE(_s) ( VBOXVIDEOCM_SIZE_FROMBODYSIZE(_s) - RT_OFFSETOF(VBOXVIDEOCM_CMD_DR, CmdHdr))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync//#define VBOXVIDEOCM_BODY_FIELD_OFFSET(_ot, _t, _f) ( (_ot)( VBOXVIDEOCM_BODY(0, uint8_t) + RT_OFFSETOF(_t, _f) ) )
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsynctypedef struct VBOXVIDEOCM_SESSION
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* contexts in this session */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync LIST_ENTRY QueueEntry;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* contexts in this session */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync LIST_ENTRY ContextList;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* commands list */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync LIST_ENTRY CommandsList;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync /* post process commands list */
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync LIST_ENTRY PpCommandsList;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* event used to notify UMD about pending commands */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PKEVENT pUmEvent;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* sync lock */
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KSPIN_LOCK SynchLock;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* indicates whether event signaling is needed on cmd add */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool bEventNeeded;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync} VBOXVIDEOCM_SESSION, *PVBOXVIDEOCM_SESSION;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define VBOXCMENTRY_2_CMD(_pE) ((PVBOXVIDEOCM_CMD_DR)((uint8_t*)(_pE) - RT_OFFSETOF(VBOXVIDEOCM_CMD_DR, QueueList)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid* vboxVideoCmCmdReinitForContext(void *pvCmd, PVBOXVIDEOCM_CTX pContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_CMD_DR pHdr = VBOXVIDEOCM_HEAD(pvCmd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHdr->pContext = pContext;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHdr->CmdHdr.u64UmData = pContext->u64UmData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return pvCmd;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid* vboxVideoCmCmdCreate(PVBOXVIDEOCM_CTX pContext, uint32_t cbSize)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(cbSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!cbSize)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(VBOXWDDM_ROUNDBOUND(cbSize, 8) == cbSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbSize = VBOXWDDM_ROUNDBOUND(cbSize, 8);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pContext->pSession);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pContext->pSession)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t cbCmd = VBOXVIDEOCM_SIZE_FROMBODYSIZE(cbSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_CMD_DR pCmd = (PVBOXVIDEOCM_CMD_DR)vboxWddmMemAllocZero(cbCmd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCmd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCmd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InitializeListHead(&pCmd->QueueList);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCmd->pContext = pContext;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCmd->cbMaxCmdSize = VBOXVIDEOCM_SENDSIZE_FROMBODYSIZE(cbSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCmd->cRefs = 1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCmd->CmdHdr.u64UmData = pContext->u64UmData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCmd->CmdHdr.cbCmd = pCmd->cbMaxCmdSize;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return VBOXVIDEOCM_BODY(pCmd, void);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsyncstatic PVBOXVIDEOCM_CMD_CTL_KM vboxVideoCmCmdCreateKm(PVBOXVIDEOCM_CTX pContext, VBOXVIDEOCM_CMD_CTL_KM_TYPE enmType,
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PFNVBOXVIDEOCM_CMD_CB pfnCb, PVOID pvCb,
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync uint32_t cbSize)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync{
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PVBOXVIDEOCM_CMD_CTL_KM pCmd = (PVBOXVIDEOCM_CMD_CTL_KM)vboxVideoCmCmdCreate(pContext, cbSize + sizeof (*pCmd));
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pCmd->enmType = enmType;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pCmd->pfnCb = pfnCb;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pCmd->pvCb = pvCb;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PVBOXVIDEOCM_CMD_DR pHdr = VBOXVIDEOCM_HEAD(pCmd);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pHdr->CmdHdr.enmType = VBOXVIDEOCM_CMD_TYPE_CTL_KM;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync return pCmd;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync}
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsyncstatic DECLCALLBACK(VOID) vboxVideoCmCmdCbSetEventAndDereference(PVBOXVIDEOCM_CTX pContext, PVBOXVIDEOCM_CMD_CTL_KM pCmd, PVOID pvContext)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync{
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PKEVENT pEvent = (PKEVENT)pvContext;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync KeSetEvent(pEvent, 0, FALSE);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync ObDereferenceObject(pEvent);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxVideoCmCmdRelease(pCmd);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync}
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsyncNTSTATUS vboxVideoCmCmdSubmitCompleteEvent(PVBOXVIDEOCM_CTX pContext, PKEVENT pEvent)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync{
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Assert(pEvent);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PVBOXVIDEOCM_CMD_CTL_KM pCmd = vboxVideoCmCmdCreateKm(pContext, VBOXVIDEOCM_CMD_CTL_KM_TYPE_POST_INVOKE,
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxVideoCmCmdCbSetEventAndDereference, pEvent, 0);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (!pCmd)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync WARN(("vboxVideoCmCmdCreateKm failed"));
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync return STATUS_NO_MEMORY;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxVideoCmCmdSubmit(pCmd, VBOXVIDEOCM_SUBMITSIZE_DEFAULT);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync return STATUS_SUCCESS;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync}
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLINLINE(void) vboxVideoCmCmdRetainByHdr(PVBOXVIDEOCM_CMD_DR pHdr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ASMAtomicIncU32(&pHdr->cRefs);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLINLINE(void) vboxVideoCmCmdReleaseByHdr(PVBOXVIDEOCM_CMD_DR pHdr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t cRefs = ASMAtomicDecU32(&pHdr->cRefs);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(cRefs < UINT32_MAX/2);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!cRefs)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmMemFree(pHdr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void vboxVideoCmCmdCancel(PVBOXVIDEOCM_CMD_DR pHdr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InitializeListHead(&pHdr->QueueList);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVideoCmCmdReleaseByHdr(pHdr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void vboxVideoCmCmdPostByHdr(PVBOXVIDEOCM_SESSION pSession, PVBOXVIDEOCM_CMD_DR pHdr, uint32_t cbSize)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool bSignalEvent = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cbSize != VBOXVIDEOCM_SUBMITSIZE_DEFAULT)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync cbSize = VBOXVIDEOCM_SENDSIZE_FROMBODYSIZE(cbSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(cbSize <= pHdr->cbMaxCmdSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHdr->CmdHdr.cbCmd = cbSize;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KIRQL OldIrql;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InsertHeadList(&pSession->CommandsList, &pHdr->QueueList);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pSession->bEventNeeded)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSession->bEventNeeded = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bSignalEvent = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (bSignalEvent)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync KeSetEvent(pSession->pUmEvent, 0, FALSE);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid vboxVideoCmCmdRetain(void *pvCmd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_CMD_DR pHdr = VBOXVIDEOCM_HEAD(pvCmd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVideoCmCmdRetainByHdr(pHdr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid vboxVideoCmCmdRelease(void *pvCmd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_CMD_DR pHdr = VBOXVIDEOCM_HEAD(pvCmd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVideoCmCmdReleaseByHdr(pHdr);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param pvCmd memory buffer returned by vboxVideoCmCmdCreate
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @param cbSize should be <= cbSize posted to vboxVideoCmCmdCreate on command creation
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid vboxVideoCmCmdSubmit(void *pvCmd, uint32_t cbSize)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_CMD_DR pHdr = VBOXVIDEOCM_HEAD(pvCmd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVideoCmCmdPostByHdr(pHdr->pContext->pSession, pHdr, cbSize);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsyncNTSTATUS vboxVideoCmCmdVisit(PVBOXVIDEOCM_CTX pContext, BOOLEAN bEntireSession, PFNVBOXVIDEOCMCMDVISITOR pfnVisitor, PVOID pvVisitor)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_SESSION pSession = pContext->pSession;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PLIST_ENTRY pCurEntry = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_CMD_DR pHdr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KIRQL OldIrql;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCurEntry = pSession->CommandsList.Blink;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync do
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCurEntry != &pSession->CommandsList)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHdr = VBOXCMENTRY_2_CMD(pCurEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCurEntry = pHdr->QueueList.Blink;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (bEntireSession || pHdr->pContext == pContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (pHdr->CmdHdr.enmType == VBOXVIDEOCM_CMD_TYPE_UM)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync void * pvBody = VBOXVIDEOCM_BODY(pHdr, void);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync UINT fRet = pfnVisitor(pHdr->pContext, pvBody, pHdr->CmdHdr.cbCmd, pvVisitor);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (fRet & VBOXVIDEOCMCMDVISITOR_RETURN_RMCMD)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync RemoveEntryList(&pHdr->QueueList);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if ((fRet & VBOXVIDEOCMCMDVISITOR_RETURN_BREAK))
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync break;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync else
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync WARN(("non-um cmd on visit, skipping"));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } while (1);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid vboxVideoCmCtxInitEmpty(PVBOXVIDEOCM_CTX pContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InitializeListHead(&pContext->SessionEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pContext->pSession = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pContext->u64UmData = 0ULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic void vboxVideoCmSessionCtxAddLocked(PVBOXVIDEOCM_SESSION pSession, PVBOXVIDEOCM_CTX pContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InsertHeadList(&pSession->ContextList, &pContext->SessionEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pContext->pSession = pSession;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid vboxVideoCmSessionCtxAdd(PVBOXVIDEOCM_SESSION pSession, PVBOXVIDEOCM_CTX pContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KIRQL OldIrql;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVideoCmSessionCtxAddLocked(pSession, pContext);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync}
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsyncvoid vboxVideoCmSessionSignalEvent(PVBOXVIDEOCM_SESSION pSession)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync{
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (pSession->pUmEvent)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeSetEvent(pSession->pUmEvent, 0, FALSE);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsyncstatic void vboxVideoCmSessionDestroyLocked(PVBOXVIDEOCM_SESSION pSession)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync /* signal event so that user-space client can figure out the context is destroyed
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync * in case the context destroyal is caused by Graphics device reset or miniport driver update */
340ee06f35257fee1bd68223ab3504cf2b1d0c3evboxsync KeSetEvent(pSession->pUmEvent, 0, FALSE);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ObDereferenceObject(pSession->pUmEvent);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(IsListEmpty(&pSession->ContextList));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(IsListEmpty(&pSession->CommandsList));
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Assert(IsListEmpty(&pSession->PpCommandsList));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RemoveEntryList(&pSession->QueueEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxWddmMemFree(pSession);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsyncstatic void vboxVideoCmSessionCtxPpList(PVBOXVIDEOCM_CTX pContext, PLIST_ENTRY pHead)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync{
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync LIST_ENTRY *pCur;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync for (pCur = pHead->Flink; pCur != pHead; pCur = pHead->Flink)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync RemoveEntryList(pCur);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PVBOXVIDEOCM_CMD_DR pHdr = VBOXCMENTRY_2_CMD(pCur);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PVBOXVIDEOCM_CMD_CTL_KM pCmd = VBOXVIDEOCM_BODY(pHdr, VBOXVIDEOCM_CMD_CTL_KM);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pCmd->pfnCb(pContext, pCmd, pCmd->pvCb);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync}
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsyncstatic void vboxVideoCmSessionCtxDetachCmdsLocked(PLIST_ENTRY pEntriesHead, PVBOXVIDEOCM_CTX pContext, PLIST_ENTRY pDstHead)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync{
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync LIST_ENTRY *pCur;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync LIST_ENTRY *pPrev;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pCur = pEntriesHead->Flink;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pPrev = pEntriesHead;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync while (pCur != pEntriesHead)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PVBOXVIDEOCM_CMD_DR pCmd = VBOXCMENTRY_2_CMD(pCur);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (pCmd->pContext == pContext)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync RemoveEntryList(pCur);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync InsertTailList(pDstHead, pCur);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pCur = pPrev;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync /* pPrev - remains unchanged */
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync else
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pPrev = pCur;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pCur = pCur->Flink;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/**
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * @return true iff the given session is destroyed
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsyncbool vboxVideoCmSessionCtxRemoveLocked(PVBOXVIDEOCM_SESSION pSession, PVBOXVIDEOCM_CTX pContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool bDestroy;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync LIST_ENTRY RemainedList;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync LIST_ENTRY RemainedPpList;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync LIST_ENTRY *pCur;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InitializeListHead(&RemainedList);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync InitializeListHead(&RemainedPpList);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KIRQL OldIrql;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pContext->pSession = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RemoveEntryList(&pContext->SessionEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bDestroy = !!(IsListEmpty(&pSession->ContextList));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* ensure there are no commands left for the given context */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (bDestroy)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVideoLeDetach(&pSession->CommandsList, &RemainedList);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxVideoLeDetach(&pSession->PpCommandsList, &RemainedPpList);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxVideoCmSessionCtxDetachCmdsLocked(&pSession->CommandsList, pContext, &RemainedList);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxVideoCmSessionCtxDetachCmdsLocked(&pSession->PpCommandsList, pContext, &RemainedPpList);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (pCur = RemainedList.Flink; pCur != &RemainedList; pCur = RemainedList.Flink)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RemoveEntryList(pCur);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_CMD_DR pCmd = VBOXCMENTRY_2_CMD(pCur);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVideoCmCmdCancel(pCmd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxVideoCmSessionCtxPpList(pContext, &RemainedPpList);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (bDestroy)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync vboxVideoCmSessionDestroyLocked(pSession);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return bDestroy;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* the session gets destroyed once the last context is removed from it */
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsyncNTSTATUS vboxVideoCmSessionCreateLocked(PVBOXVIDEOCM_MGR pMgr, PVBOXVIDEOCM_SESSION *ppSession, PKEVENT pUmEvent, PVBOXVIDEOCM_CTX pContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = STATUS_UNSUCCESSFUL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_SESSION pSession = (PVBOXVIDEOCM_SESSION)vboxWddmMemAllocZero(sizeof (VBOXVIDEOCM_SESSION));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pSession);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pSession)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InitializeListHead(&pSession->ContextList);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InitializeListHead(&pSession->CommandsList);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync InitializeListHead(&pSession->PpCommandsList);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSession->pUmEvent = pUmEvent;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeInitializeSpinLock(&pSession->SynchLock);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSession->bEventNeeded = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVideoCmSessionCtxAddLocked(pSession, pContext);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InsertHeadList(&pMgr->SessionList, &pSession->QueueEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *ppSession = pSession;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// vboxWddmMemFree(pSession);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Status = STATUS_NO_MEMORY;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define VBOXCMENTRY_2_SESSION(_pE) ((PVBOXVIDEOCM_SESSION)((uint8_t*)(_pE) - RT_OFFSETOF(VBOXVIDEOCM_SESSION, QueueEntry)))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoCmCtxAdd(PVBOXVIDEOCM_MGR pMgr, PVBOXVIDEOCM_CTX pContext, HANDLE hUmEvent, uint64_t u64UmData)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PKEVENT pUmEvent = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NTSTATUS Status = ObReferenceObjectByHandle(hUmEvent, EVENT_MODIFY_STATE, *ExEventObjectType, UserMode,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync (PVOID*)&pUmEvent,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NULL);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Status == STATUS_SUCCESS);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Status == STATUS_SUCCESS)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KIRQL OldIrql;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeAcquireSpinLock(&pMgr->SynchLock, &OldIrql);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync bool bFound = false;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync PVBOXVIDEOCM_SESSION pSession = NULL;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync for (PLIST_ENTRY pEntry = pMgr->SessionList.Flink; pEntry != &pMgr->SessionList; pEntry = pEntry->Flink)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pSession = VBOXCMENTRY_2_SESSION(pEntry);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (pSession->pUmEvent == pUmEvent)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync bFound = true;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pContext->u64UmData = u64UmData;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (!bFound)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Status = vboxVideoCmSessionCreateLocked(pMgr, &pSession, pUmEvent, pContext);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Assert(Status == STATUS_SUCCESS);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync else
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync /* Status = */vboxVideoCmSessionCtxAdd(pSession, pContext);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync /*Assert(Status == STATUS_SUCCESS);*/
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeReleaseSpinLock(&pMgr->SynchLock, OldIrql);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync if (Status == STATUS_SUCCESS)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync ObDereferenceObject(pUmEvent);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Status;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoCmCtxRemove(PVBOXVIDEOCM_MGR pMgr, PVBOXVIDEOCM_CTX pContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_SESSION pSession = pContext->pSession;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!pSession)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KIRQL OldIrql;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeAcquireSpinLock(&pMgr->SynchLock, &OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync vboxVideoCmSessionCtxRemoveLocked(pSession, pContext);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeReleaseSpinLock(&pMgr->SynchLock, OldIrql);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoCmInit(PVBOXVIDEOCM_MGR pMgr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeInitializeSpinLock(&pMgr->SynchLock);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InitializeListHead(&pMgr->SessionList);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoCmTerm(PVBOXVIDEOCM_MGR pMgr)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(IsListEmpty(&pMgr->SessionList));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsyncNTSTATUS vboxVideoCmSignalEvents(PVBOXVIDEOCM_MGR pMgr)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync{
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync PVBOXVIDEOCM_SESSION pSession = NULL;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KIRQL OldIrql;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeAcquireSpinLock(&pMgr->SynchLock, &OldIrql);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync for (PLIST_ENTRY pEntry = pMgr->SessionList.Flink; pEntry != &pMgr->SessionList; pEntry = pEntry->Flink)
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync {
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync pSession = VBOXCMENTRY_2_SESSION(pEntry);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync vboxVideoCmSessionSignalEvent(pSession);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeReleaseSpinLock(&pMgr->SynchLock, OldIrql);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync return STATUS_SUCCESS;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync}
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsyncVOID vboxVideoCmProcessKm(PVBOXVIDEOCM_CTX pContext, PVBOXVIDEOCM_CMD_CTL_KM pCmd)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync{
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PVBOXVIDEOCM_SESSION pSession = pContext->pSession;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync switch (pCmd->enmType)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync case VBOXVIDEOCM_CMD_CTL_KM_TYPE_PRE_INVOKE:
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pCmd->pfnCb(pContext, pCmd, pCmd->pvCb);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync break;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync case VBOXVIDEOCM_CMD_CTL_KM_TYPE_POST_INVOKE:
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync PVBOXVIDEOCM_CMD_DR pHdr = VBOXVIDEOCM_HEAD(pCmd);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KIRQL OldIrql;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync InsertTailList(&pSession->PpCommandsList, &pHdr->QueueList);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync break;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync default:
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync WARN(("unsupported cmd type %d", pCmd->enmType));
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync break;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync}
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncNTSTATUS vboxVideoCmEscape(PVBOXVIDEOCM_CTX pContext, PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(cbCmd >= sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (cbCmd < sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_BUFFER_TOO_SMALL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_SESSION pSession = pContext->pSession;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXVIDEOCM_CMD_DR pHdr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync LIST_ENTRY DetachedList;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync LIST_ENTRY DetachedPpList;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PLIST_ENTRY pCurEntry = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t cbCmdsReturned = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t cbRemainingCmds = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t cbRemainingFirstCmd = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint32_t cbData = cbCmd - sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync uint8_t * pvData = ((uint8_t *)pCmd) + sizeof (VBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bool bDetachMode = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InitializeListHead(&DetachedList);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync InitializeListHead(&DetachedPpList);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync// PVBOXWDDM_GETVBOXVIDEOCMCMD_HDR *pvCmd
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync Assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KIRQL OldIrql;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxVideoCmSessionCtxDetachCmdsLocked(&pSession->PpCommandsList, pContext, &DetachedPpList);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync do
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (bDetachMode)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!IsListEmpty(&pSession->CommandsList))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(!pCurEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHdr = VBOXCMENTRY_2_CMD(pSession->CommandsList.Blink);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pHdr->CmdHdr.cbCmd);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync uint32_t cbUserCmd = pHdr->CmdHdr.enmType == VBOXVIDEOCM_CMD_TYPE_UM ? pHdr->CmdHdr.cbCmd : 0;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync if (cbData >= cbUserCmd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RemoveEntryList(&pHdr->QueueList);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync InsertHeadList(&DetachedList, &pHdr->QueueList);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync cbData -= cbUserCmd;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync Assert(cbUserCmd);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync cbRemainingFirstCmd = cbUserCmd;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync cbRemainingCmds = cbUserCmd;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCurEntry = pHdr->QueueList.Blink;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync bDetachMode = false;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pSession->bEventNeeded = true;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pCurEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCurEntry != &pSession->CommandsList)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHdr = VBOXCMENTRY_2_CMD(pCurEntry);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync uint32_t cbUserCmd = pHdr->CmdHdr.enmType == VBOXVIDEOCM_CMD_TYPE_UM ? pHdr->CmdHdr.cbCmd : 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(cbRemainingFirstCmd);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync cbRemainingCmds += cbUserCmd;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCurEntry = pHdr->QueueList.Blink;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync Assert(cbRemainingFirstCmd);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync Assert(cbRemainingCmds);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } while (1);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxVideoCmSessionCtxPpList(pContext, &DetachedPpList);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCmd->Hdr.cbCmdsReturned = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (pCurEntry = DetachedList.Blink; pCurEntry != &DetachedList; pCurEntry = DetachedList.Blink)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHdr = VBOXCMENTRY_2_CMD(pCurEntry);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RemoveEntryList(pCurEntry);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync switch (pHdr->CmdHdr.enmType)
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync case VBOXVIDEOCM_CMD_TYPE_UM:
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync memcpy(pvData, &pHdr->CmdHdr, pHdr->CmdHdr.cbCmd);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pvData += pHdr->CmdHdr.cbCmd;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync pCmd->Hdr.cbCmdsReturned += pHdr->CmdHdr.cbCmd;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxVideoCmCmdReleaseByHdr(pHdr);
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync break;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync case VBOXVIDEOCM_CMD_TYPE_CTL_KM:
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync vboxVideoCmProcessKm(pContext, VBOXVIDEOCM_BODY(pHdr, VBOXVIDEOCM_CMD_CTL_KM));
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync break;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync default:
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync {
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync WARN(("unsupported cmd type %d", pHdr->CmdHdr.enmType));
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync break;
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
3c5c04d7b0973be0757addef8ba44b9352b38386vboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCmd->Hdr.cbRemainingCmds = cbRemainingCmds;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCmd->Hdr.cbRemainingFirstCmd = cbRemainingFirstCmd;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCmd->Hdr.u32Reserved = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return STATUS_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsyncstatic BOOLEAN vboxVideoCmHasUncompletedCmdsLocked(PVBOXVIDEOCM_MGR pMgr)
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync{
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync PVBOXVIDEOCM_SESSION pSession = NULL;
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync for (PLIST_ENTRY pEntry = pMgr->SessionList.Flink; pEntry != &pMgr->SessionList; pEntry = pEntry->Flink)
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync {
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync pSession = VBOXCMENTRY_2_SESSION(pEntry);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KIRQL OldIrql;
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeAcquireSpinLock(&pSession->SynchLock, &OldIrql);
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync if (pSession->bEventNeeded)
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync {
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync /* commands still being processed */
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync return TRUE;
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync }
3fa7a7e633f46a212052b510cdb8cee41f279a67vboxsync KeReleaseSpinLock(&pSession->SynchLock, OldIrql);
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync }
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync return FALSE;
eb2d4958f7faf812c3bdb2d7587d815022f0bd55vboxsync}