file.c revision 7519a1c4323fa86fbb19a36a91cd25abfd7af714
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * VirtualBox Windows Guest Shared Folders
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * File System Driver file routines
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync * Copyright (C) 2012 Oracle Corporation
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.
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncstatic NTSTATUS vbsfReadInternal(IN PRX_CONTEXT RxContext)
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 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMDL BufferMdl = LowIoContext->ParamsFor.ReadWrite.Buffer;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync uint32_t ByteCount = LowIoContext->ParamsFor.ReadWrite.ByteCount;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RXVBO ByteOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PVOID pbUserBuffer = RxLowIoGetBufferAddress(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync BOOLEAN AsyncIo = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfReadInternal: AsyncIo = %d, Fcb->FileSize = 0x%RX64\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfReadInternal: UserBuffer %p, BufferMdl %p\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfReadInternal: ByteCount 0x%X, ByteOffset 0x%RX64, FileSize 0x%RX64\n",
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 if (!FlagOn(capFcb->FcbState, FCB_STATE_READCACHEING_ENABLED))
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* @todo read 0 bytes == always success? */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* @todo Split large reads. */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync vboxRC = vboxCallRead(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync ByteOffset, &ByteCount, (uint8_t *)pbUserBuffer, true /* locked */);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* Nothing read. */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfReadInternal: Status = 0x%08X, ByteCount = 0x%X\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfReadWorker: calling the worker\n"));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxContext->IoStatusBlock.Status = vbsfReadInternal(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync NTSTATUS Status = RxDispatchToWorkerThread(VBoxMRxDeviceObject, DelayedWorkQueue,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: MRxRead: RxDispatchToWorkerThread: Status 0x%08X\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncstatic NTSTATUS vbsfWriteInternal(IN PRX_CONTEXT RxContext)
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 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PMDL BufferMdl = LowIoContext->ParamsFor.ReadWrite.Buffer;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync uint32_t ByteCount = LowIoContext->ParamsFor.ReadWrite.ByteCount;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RXVBO ByteOffset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync PVOID pbUserBuffer = RxLowIoGetBufferAddress(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync BOOLEAN AsyncIo = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_ASYNC_OPERATION);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfWriteInternal: AsyncIo = %d, Fcb->FileSize = 0x%RX64\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfWriteInternal: UserBuffer %p, BufferMdl %p\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfWriteInternal: ByteCount is 0x%X, ByteOffset is 0x%RX64, FileSize 0x%RX64\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* @todo allow to write 0 bytes. */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* @todo Split large writes. */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync vboxRC = vboxCallWrite(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync ByteOffset, &ByteCount, (uint8_t *)pbUserBuffer, true /* locked */);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* Nothing written. */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfWriteInternal: Status = 0x%08X, ByteCount = 0x%X\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfWriteWorker: calling the worker\n"));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync RxContext->IoStatusBlock.Status = vbsfWriteInternal(RxContext);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync NTSTATUS Status = RxDispatchToWorkerThread(VBoxMRxDeviceObject, DelayedWorkQueue,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: MRxWrite: RxDispatchToWorkerThread: Status 0x%08X\n",
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 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync AssertMsgFailed(("VBOXSF: MRxLocks: Unsupported lock/unlock type %d detected!\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* @todo Remove multiple locks listed in LowIoContext.ParamsFor.Locks.LockList. */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: MRxLocks: Unsupported LOWIO_OP_UNLOCK_MULTIPLE!\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync fu32Lock = SHFL_LOCK_EXCLUSIVE | SHFL_LOCK_PARTIAL;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync if (LowIoContext->ParamsFor.Locks.Flags & LOWIO_LOCKSFLAG_FAIL_IMMEDIATELY)
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync vboxRC = vboxCallLock(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync LowIoContext->ParamsFor.Locks.ByteOffset, LowIoContext->ParamsFor.Locks.Length, fu32Lock);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncNTSTATUS VBoxMRxCompleteBufferingStateChangeRequest(IN OUT PRX_CONTEXT RxContext,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: MRxCompleteBufferingStateChangeRequest: not implemented\n"));
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 /* Do the actual flushing of file buffers */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync vboxRC = vboxCallFlush(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncNTSTATUS vbsfSetEndOfFile(IN OUT struct _RX_CONTEXT * RxContext,
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 Log(("VBOXSF: vbsfSetEndOfFile: New size = %RX64 (%p), pNewAllocationSize = %p\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync pNewFileSize->QuadPart, pNewFileSize, pNewAllocationSize));
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Assert(pVBoxFobx && pNetRootExtension && pDeviceExtension);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync pObjInfo = (SHFLFSOBJINFO *)vbsfAllocNonPagedMem(cbBuffer);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync vboxRC = vboxCallFSInfo(&pDeviceExtension->hgcmClient, &pNetRootExtension->map, pVBoxFobx->hFile,
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync SHFL_INFO_SET | SHFL_INFO_SIZE, &cbBuffer, (PSHFLDIRINFO)pObjInfo);
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfSetEndOfFile: vboxCallFSInfo returned %Rrc\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfSetEndOfFile: vboxCallFSInfo new allocation size = %RX64\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync /* Return new allocation size */
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync pNewAllocationSize->QuadPart = pObjInfo->cbAllocated;
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsync Log(("VBOXSF: vbsfSetEndOfFile: Returned 0x%08X\n",
09c9a430ad2caac61753f90b04a4989c6d54d13avboxsyncNTSTATUS VBoxMRxExtendStub(IN OUT struct _RX_CONTEXT * RxContext,
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.