file.c revision 7519a1c4323fa86fbb19a36a91cd25abfd7af714
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync/** @file
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync *
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * VirtualBox Windows Guest Shared Folders
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync *
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * File System Driver file routines
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync/*
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * Copyright (C) 2012 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>
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncstatic NTSTATUS vbsfReadInternal(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
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 {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync ByteCount = (ULONG)(FileSize - ByteOffset);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* @todo read 0 bytes == always success? */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if ( BufferMdl == NULL
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync || ByteCount == 0)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync AssertFailed();
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return STATUS_INVALID_PARAMETER;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* @todo Split large reads. */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync vboxRC = vboxCallRead(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync ByteOffset, &ByteCount, (uint8_t *)pbUserBuffer, true /* locked */);
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
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: MRxRead: RxDispatchToWorkerThread: Status 0x%08X\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Status));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if (Status == STATUS_SUCCESS)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Status = STATUS_PENDING;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return Status;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync}
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncstatic NTSTATUS vbsfWriteInternal(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
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. */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if ( BufferMdl == NULL
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync || ByteCount == 0)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync AssertFailed();
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync return STATUS_INVALID_PARAMETER;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* @todo Split large writes. */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync vboxRC = vboxCallWrite(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync ByteOffset, &ByteCount, (uint8_t *)pbUserBuffer, true /* locked */);
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 {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Status = STATUS_PENDING;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
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 {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync fu32Lock |= SHFL_LOCK_NOWAIT;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync else
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync fu32Lock |= SHFL_LOCK_WAIT;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
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
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: MRxLocks: Returned 0x%08X\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync 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
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: MRxFlush: Returned 0x%08X\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync 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);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if (pObjInfo == NULL)
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
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfSetEndOfFile: vboxCallFSInfo returned %Rrc\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync 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 {
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync vbsfFreeNonPagedMem(pObjInfo);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync }
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfSetEndOfFile: Returned 0x%08X\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync 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}