09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync/** @file
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync *
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * VirtualBox Windows Guest Shared Folders
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync *
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * File System Driver file routines
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync/*
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync * Copyright (C) 2012-2013 Oracle Corporation
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync *
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * available from http://www.virtualbox.org. This file is free software;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * you can redistribute it and/or modify it under the terms of the GNU
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * General Public License (GPL) as published by the Free Software
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync#include "vbsf.h"
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync#include <iprt/fs.h>
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync#include <iprt/mem.h>
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync/* How much data to transfer in one HGCM request. */
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync#define VBSF_MAX_READ_WRITE_PAGES 256
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsynctypedef int FNVBSFTRANSFERBUFFER(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint64_t offset, uint32_t *pcbBuffer,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint8_t *pBuffer, bool fLocked);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsynctypedef FNVBSFTRANSFERBUFFER *PFNVBSFTRANSFERBUFFER;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsynctypedef int FNVBSFTRANSFERPAGES(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint64_t offset, uint32_t *pcbBuffer,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsynctypedef FNVBSFTRANSFERPAGES *PFNVBSFTRANSFERPAGES;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsyncstatic int vbsfTransferBufferRead(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint64_t offset, uint32_t *pcbBuffer,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint8_t *pBuffer, bool fLocked)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync{
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync return vboxCallRead(pClient, pMap, hFile, offset, pcbBuffer, pBuffer, fLocked);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync}
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsyncstatic int vbsfTransferBufferWrite(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint64_t offset, uint32_t *pcbBuffer,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint8_t *pBuffer, bool fLocked)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync{
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync return vboxCallWrite(pClient, pMap, hFile, offset, pcbBuffer, pBuffer, fLocked);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync}
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsyncstatic int vbsfTransferPagesRead(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint64_t offset, uint32_t *pcbBuffer,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync{
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync return VbglR0SharedFolderReadPageList(pClient, pMap, hFile, offset, pcbBuffer, offFirstPage, cPages, paPages);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync}
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsyncstatic int vbsfTransferPagesWrite(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE hFile,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint64_t offset, uint32_t *pcbBuffer,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint16_t offFirstPage, uint16_t cPages, RTGCPHYS64 *paPages)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync{
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync return VbglR0SharedFolderWritePageList(pClient, pMap, hFile, offset, pcbBuffer, offFirstPage, cPages, paPages);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync}
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsynctypedef struct VBSFTRANSFERCTX
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync{
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync PVBSFCLIENT pClient;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync PVBSFMAP pMap;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync SHFLHANDLE hFile;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint64_t offset;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint32_t cbData;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync PMDL pMdl;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint8_t *pBuffer;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync bool fLocked;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync PFNVBSFTRANSFERBUFFER pfnTransferBuffer;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync PFNVBSFTRANSFERPAGES pfnTransferPages;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync} VBSFTRANSFERCTX;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsyncstatic int vbsfTransferCommon(VBSFTRANSFERCTX *pCtx)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync{
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync int rc = VINF_SUCCESS;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync BOOLEAN fProcessed = FALSE;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint32_t cbTransferred = 0;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint32_t cbToTransfer;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync uint32_t cbIO;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync if (VbglR0CanUsePhysPageList())
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync {
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ULONG offFirstPage = MmGetMdlByteOffset(pCtx->pMdl);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ULONG cPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(pCtx->pMdl), pCtx->cbData);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ULONG cPagesToTransfer = RT_MIN(cPages, VBSF_MAX_READ_WRITE_PAGES);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync RTGCPHYS64 *paPages = (RTGCPHYS64 *)RTMemTmpAlloc(cPagesToTransfer * sizeof(RTGCPHYS64));
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync Log(("VBOXSF: vbsfTransferCommon: using page list: %d pages, offset 0x%03X\n", cPages, offFirstPage));
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync if (paPages)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync {
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync PPFN_NUMBER paPfns = MmGetMdlPfnArray(pCtx->pMdl);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ULONG cPagesTransferred = 0;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cbTransferred = 0;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync while (cPagesToTransfer != 0)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync {
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ULONG iPage;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cbToTransfer = cPagesToTransfer * PAGE_SIZE - offFirstPage;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync if (cbToTransfer > pCtx->cbData - cbTransferred)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cbToTransfer = pCtx->cbData - cbTransferred;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync if (cbToTransfer == 0)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync {
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync /* Nothing to transfer. */
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync break;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync }
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cbIO = cbToTransfer;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync Log(("VBOXSF: vbsfTransferCommon: transferring %d pages at %d; %d bytes at %d\n",
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cPagesToTransfer, cPagesTransferred, cbToTransfer, cbTransferred));
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync for (iPage = 0; iPage < cPagesToTransfer; iPage++)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync paPages[iPage] = (RTGCPHYS64)paPfns[iPage + cPagesTransferred] << PAGE_SHIFT;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync rc = pCtx->pfnTransferPages(pCtx->pClient, pCtx->pMap, pCtx->hFile,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync pCtx->offset + cbTransferred, &cbIO,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync (uint16_t)offFirstPage, (uint16_t)cPagesToTransfer, paPages);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync if (RT_FAILURE(rc))
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync {
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync Log(("VBOXSF: vbsfTransferCommon: pfnTransferPages %Rrc, cbTransferred %d\n", rc, cbTransferred));
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync /* If some data was transferred, then it is no error. */
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync if (cbTransferred > 0)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync rc = VINF_SUCCESS;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync break;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync }
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cbTransferred += cbIO;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync if (cbToTransfer < cbIO)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync {
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync /* Transferred less than requested, do not continue with the possibly remaining data. */
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync break;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync }
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cPagesTransferred += cPagesToTransfer;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync offFirstPage = 0;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cPagesToTransfer = cPages - cPagesTransferred;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync if (cPagesToTransfer > VBSF_MAX_READ_WRITE_PAGES)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cPagesToTransfer = VBSF_MAX_READ_WRITE_PAGES;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync }
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync RTMemTmpFree(paPages);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync fProcessed = TRUE;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync }
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync }
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync if (fProcessed != TRUE)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync {
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync /* Split large transfers. */
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cbTransferred = 0;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cbToTransfer = RT_MIN(pCtx->cbData, VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync /* Page list not supported or a fallback. */
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync Log(("VBOXSF: vbsfTransferCommon: using linear address\n"));
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync while (cbToTransfer != 0)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync {
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cbIO = cbToTransfer;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync Log(("VBOXSF: vbsfTransferCommon: transferring %d bytes at %d\n",
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cbToTransfer, cbTransferred));
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync rc = pCtx->pfnTransferBuffer(pCtx->pClient, pCtx->pMap, pCtx->hFile,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync pCtx->offset + cbTransferred, &cbIO,
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync pCtx->pBuffer + cbTransferred, true /* locked */);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync if (RT_FAILURE(rc))
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync {
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync Log(("VBOXSF: vbsfTransferCommon: pfnTransferBuffer %Rrc, cbTransferred %d\n", rc, cbTransferred));
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync /* If some data was transferred, then it is no error. */
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync if (cbTransferred > 0)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync rc = VINF_SUCCESS;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync break;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync }
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cbTransferred += cbIO;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync if (cbToTransfer < cbIO)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync {
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync /* Transferred less than requested, do not continue with the possibly remaining data. */
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync break;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync }
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cbToTransfer = pCtx->cbData - cbTransferred;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync if (cbToTransfer > VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE)
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync cbToTransfer = VBSF_MAX_READ_WRITE_PAGES * PAGE_SIZE;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync }
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync }
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync pCtx->cbData = cbTransferred;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync return rc;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync}
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncstatic NTSTATUS vbsfReadInternal(IN PRX_CONTEXT RxContext)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync{
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync NTSTATUS Status = STATUS_SUCCESS;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync VBSFTRANSFERCTX ctx;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxCaptureFcb;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxCaptureFobx;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMDL BufferMdl = LowIoContext->ParamsFor.ReadWrite.Buffer;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync uint32_t ByteCount = LowIoContext->ParamsFor.ReadWrite.ByteCount;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RXVBO ByteOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PVOID pbUserBuffer = RxLowIoGetBufferAddress(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync int vboxRC;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync BOOLEAN AsyncIo = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync LONGLONG FileSize;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxGetFileSizeWithLock((PFCB)capFcb, &FileSize);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfReadInternal: AsyncIo = %d, Fcb->FileSize = 0x%RX64\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync AsyncIo, capFcb->Header.FileSize.QuadPart));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfReadInternal: UserBuffer %p, BufferMdl %p\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync pbUserBuffer, BufferMdl));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfReadInternal: ByteCount 0x%X, ByteOffset 0x%RX64, FileSize 0x%RX64\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync ByteCount, ByteOffset, FileSize));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* @todo check if this is necessary. */
7519a1c4323fa86fbb19a36a91cd25abfd7af714vboxsync#ifdef FCB_STATE_READCACHING_ENABLED /* Correct spelling for Vista 6001 SDK. */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if (!FlagOn(capFcb->FcbState, FCB_STATE_READCACHING_ENABLED))
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync#else
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if (!FlagOn(capFcb->FcbState, FCB_STATE_READCACHEING_ENABLED))
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync#endif
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if (ByteOffset >= FileSize)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfReadInternal: EOF\n"));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return STATUS_END_OF_FILE;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if (ByteCount > FileSize - ByteOffset)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync ByteCount = (ULONG)(FileSize - ByteOffset);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* @todo read 0 bytes == always success? */
d736beed1ca63b0f4b16c4973ebf9188c3d8dda6vboxsync if ( !BufferMdl
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync || ByteCount == 0)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync AssertFailed();
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return STATUS_INVALID_PARAMETER;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.pClient = &pDeviceExtension->hgcmClient;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.pMap = &pNetRootExtension->map;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.hFile = pVBoxFobx->hFile;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.offset = (uint64_t)ByteOffset;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.cbData = ByteCount;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.pMdl = BufferMdl;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.pBuffer = (uint8_t *)pbUserBuffer;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.fLocked = true;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.pfnTransferBuffer = vbsfTransferBufferRead;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.pfnTransferPages = vbsfTransferPagesRead;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync vboxRC = vbsfTransferCommon(&ctx);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ByteCount = ctx.cbData;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Status = VBoxErrorToNTStatus(vboxRC);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if (Status != STATUS_SUCCESS)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* Nothing read. */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync ByteCount = 0;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxContext->InformationToReturn = ByteCount;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfReadInternal: Status = 0x%08X, ByteCount = 0x%X\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Status, ByteCount));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return Status;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync}
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncstatic VOID vbsfReadWorker(VOID *pv)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync{
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PRX_CONTEXT RxContext = (PRX_CONTEXT)pv;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfReadWorker: calling the worker\n"));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxContext->IoStatusBlock.Status = vbsfReadInternal(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfReadWorker: Status 0x%08X\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxContext->IoStatusBlock.Status));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxLowIoCompletion(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync}
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncNTSTATUS VBoxMRxRead(IN PRX_CONTEXT RxContext)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync{
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync NTSTATUS Status = RxDispatchToWorkerThread(VBoxMRxDeviceObject, DelayedWorkQueue,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync vbsfReadWorker,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
d736beed1ca63b0f4b16c4973ebf9188c3d8dda6vboxsync Log(("VBOXSF: MRxRead: RxDispatchToWorkerThread: Status 0x%08X\n", Status));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if (Status == STATUS_SUCCESS)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Status = STATUS_PENDING;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return Status;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync}
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncstatic NTSTATUS vbsfWriteInternal(IN PRX_CONTEXT RxContext)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync{
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync NTSTATUS Status = STATUS_SUCCESS;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync VBSFTRANSFERCTX ctx;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxCaptureFcb;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxCaptureFobx;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMDL BufferMdl = LowIoContext->ParamsFor.ReadWrite.Buffer;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync uint32_t ByteCount = LowIoContext->ParamsFor.ReadWrite.ByteCount;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RXVBO ByteOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PVOID pbUserBuffer = RxLowIoGetBufferAddress(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync int vboxRC;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync BOOLEAN AsyncIo = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync LONGLONG FileSize;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxGetFileSizeWithLock((PFCB)capFcb, &FileSize);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfWriteInternal: AsyncIo = %d, Fcb->FileSize = 0x%RX64\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync AsyncIo, capFcb->Header.FileSize.QuadPart));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfWriteInternal: UserBuffer %p, BufferMdl %p\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync pbUserBuffer, BufferMdl));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfWriteInternal: ByteCount is 0x%X, ByteOffset is 0x%RX64, FileSize 0x%RX64\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync ByteCount, ByteOffset, FileSize));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* @todo allow to write 0 bytes. */
d736beed1ca63b0f4b16c4973ebf9188c3d8dda6vboxsync if ( !BufferMdl
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync || ByteCount == 0)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync AssertFailed();
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return STATUS_INVALID_PARAMETER;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.pClient = &pDeviceExtension->hgcmClient;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.pMap = &pNetRootExtension->map;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.hFile = pVBoxFobx->hFile;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.offset = (uint64_t)ByteOffset;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.cbData = ByteCount;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.pMdl = BufferMdl;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.pBuffer = (uint8_t *)pbUserBuffer;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.fLocked = true;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.pfnTransferBuffer = vbsfTransferBufferWrite;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ctx.pfnTransferPages = vbsfTransferPagesWrite;
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync vboxRC = vbsfTransferCommon(&ctx);
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync
f6c43e9fc1e5cc41195ac222ad185905e33fe08dvboxsync ByteCount = ctx.cbData;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Status = VBoxErrorToNTStatus(vboxRC);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if (Status != STATUS_SUCCESS)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* Nothing written. */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync ByteCount = 0;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxContext->InformationToReturn = ByteCount;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfWriteInternal: Status = 0x%08X, ByteCount = 0x%X\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Status, ByteCount));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return Status;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync}
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncstatic VOID vbsfWriteWorker(VOID *pv)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync{
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PRX_CONTEXT RxContext = (PRX_CONTEXT)pv;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfWriteWorker: calling the worker\n"));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxContext->IoStatusBlock.Status = vbsfWriteInternal(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfWriteWorker: Status 0x%08X\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxContext->IoStatusBlock.Status));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxLowIoCompletion(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync}
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncNTSTATUS VBoxMRxWrite(IN PRX_CONTEXT RxContext)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync{
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync NTSTATUS Status = RxDispatchToWorkerThread(VBoxMRxDeviceObject, DelayedWorkQueue,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync vbsfWriteWorker,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: MRxWrite: RxDispatchToWorkerThread: Status 0x%08X\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Status));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if (Status == STATUS_SUCCESS)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Status = STATUS_PENDING;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return Status;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync}
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncNTSTATUS VBoxMRxLocks(IN PRX_CONTEXT RxContext)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync{
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync NTSTATUS Status = STATUS_SUCCESS;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxCaptureFcb;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxCaptureFobx;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync uint32_t fu32Lock = 0;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync int vboxRC;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: MRxLocks: Operation %d\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync LowIoContext->Operation));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync switch (LowIoContext->Operation)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync default:
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync AssertMsgFailed(("VBOXSF: MRxLocks: Unsupported lock/unlock type %d detected!\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync LowIoContext->Operation));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return STATUS_NOT_IMPLEMENTED;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync case LOWIO_OP_UNLOCK_MULTIPLE:
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* @todo Remove multiple locks listed in LowIoContext.ParamsFor.Locks.LockList. */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: MRxLocks: Unsupported LOWIO_OP_UNLOCK_MULTIPLE!\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync LowIoContext->Operation));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return STATUS_NOT_IMPLEMENTED;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync case LOWIO_OP_SHAREDLOCK:
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync fu32Lock = SHFL_LOCK_SHARED | SHFL_LOCK_PARTIAL;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync break;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync case LOWIO_OP_EXCLUSIVELOCK:
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync fu32Lock = SHFL_LOCK_EXCLUSIVE | SHFL_LOCK_PARTIAL;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync break;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync case LOWIO_OP_UNLOCK:
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync fu32Lock = SHFL_LOCK_CANCEL | SHFL_LOCK_PARTIAL;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync break;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if (LowIoContext->ParamsFor.Locks.Flags & LOWIO_LOCKSFLAG_FAIL_IMMEDIATELY)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync fu32Lock |= SHFL_LOCK_NOWAIT;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync else
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync fu32Lock |= SHFL_LOCK_WAIT;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync vboxRC = vboxCallLock(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync LowIoContext->ParamsFor.Locks.ByteOffset, LowIoContext->ParamsFor.Locks.Length, fu32Lock);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Status = VBoxErrorToNTStatus(vboxRC);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
d736beed1ca63b0f4b16c4973ebf9188c3d8dda6vboxsync Log(("VBOXSF: MRxLocks: Returned 0x%08X\n", Status));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return Status;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync}
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncNTSTATUS VBoxMRxCompleteBufferingStateChangeRequest(IN OUT PRX_CONTEXT RxContext,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync IN OUT PMRX_SRV_OPEN SrvOpen,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync IN PVOID pContext)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync{
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: MRxCompleteBufferingStateChangeRequest: not implemented\n"));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return STATUS_NOT_IMPLEMENTED;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync}
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncNTSTATUS VBoxMRxFlush (IN PRX_CONTEXT RxContext)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync{
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync NTSTATUS Status = STATUS_SUCCESS;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxCaptureFcb;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxCaptureFobx;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync int vboxRC;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: MRxFlush\n"));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* Do the actual flushing of file buffers */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync vboxRC = vboxCallFlush(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Status = VBoxErrorToNTStatus(vboxRC);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
d736beed1ca63b0f4b16c4973ebf9188c3d8dda6vboxsync Log(("VBOXSF: MRxFlush: Returned 0x%08X\n", Status));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return Status;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync}
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncNTSTATUS vbsfSetEndOfFile(IN OUT struct _RX_CONTEXT * RxContext,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync IN OUT PLARGE_INTEGER pNewFileSize,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync OUT PLARGE_INTEGER pNewAllocationSize)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync{
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync NTSTATUS Status = STATUS_SUCCESS;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxCaptureFcb;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxCaptureFobx;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_NETROOT_EXTENSION pNetRootExtension = VBoxMRxGetNetRootExtension(capFcb->pNetRoot);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMRX_VBOX_FOBX pVBoxFobx = VBoxMRxGetFileObjectExtension(capFobx);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PSHFLFSOBJINFO pObjInfo;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync uint32_t cbBuffer;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync int vboxRC;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfSetEndOfFile: New size = %RX64 (%p), pNewAllocationSize = %p\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync pNewFileSize->QuadPart, pNewFileSize, pNewAllocationSize));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Assert(pVBoxFobx && pNetRootExtension && pDeviceExtension);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync cbBuffer = sizeof(SHFLFSOBJINFO);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync pObjInfo = (SHFLFSOBJINFO *)vbsfAllocNonPagedMem(cbBuffer);
d736beed1ca63b0f4b16c4973ebf9188c3d8dda6vboxsync if (!pObjInfo)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync AssertFailed();
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return STATUS_INSUFFICIENT_RESOURCES;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RtlZeroMemory(pObjInfo, cbBuffer);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync pObjInfo->cbObject = pNewFileSize->QuadPart;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync vboxRC = vboxCallFSInfo(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync SHFL_INFO_SET | SHFL_INFO_SIZE, &cbBuffer, (PSHFLDIRINFO)pObjInfo);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
d736beed1ca63b0f4b16c4973ebf9188c3d8dda6vboxsync Log(("VBOXSF: vbsfSetEndOfFile: vboxCallFSInfo returned %Rrc\n", vboxRC));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Status = VBoxErrorToNTStatus(vboxRC);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if (Status == STATUS_SUCCESS)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfSetEndOfFile: vboxCallFSInfo new allocation size = %RX64\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync pObjInfo->cbAllocated));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* Return new allocation size */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync pNewAllocationSize->QuadPart = pObjInfo->cbAllocated;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if (pObjInfo)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync vbsfFreeNonPagedMem(pObjInfo);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
d736beed1ca63b0f4b16c4973ebf9188c3d8dda6vboxsync Log(("VBOXSF: vbsfSetEndOfFile: Returned 0x%08X\n", Status));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return Status;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync}
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncNTSTATUS VBoxMRxExtendStub(IN OUT struct _RX_CONTEXT * RxContext,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync IN OUT PLARGE_INTEGER pNewFileSize,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync OUT PLARGE_INTEGER pNewAllocationSize)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync{
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* Note: On Windows hosts vbsfSetEndOfFile returns ACCESS_DENIED if the file has been
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * opened in APPEND mode. Writes to a file will extend it anyway, therefore it is
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * better to not call the host at all and tell the caller that the file was extended.
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: MRxExtendStub: new size = %RX64\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync pNewFileSize->QuadPart));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync pNewAllocationSize->QuadPart = pNewFileSize->QuadPart;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return STATUS_SUCCESS;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync}