vbsf.c revision 2888816fbcb216a2dbc97a95fa5a50b6caa09e32
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* $Id$ */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @file
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * VirtualBox Windows Guest Shared Folders.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * File System Driver initialization and generic routines
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Copyright (C) 2012 Oracle Corporation
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * available from http://www.virtualbox.org. This file is free software;
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync */
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#include "vbsf.h"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The current state of the driver.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef enum _MRX_VBOX_STATE_
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync MRX_VBOX_STARTABLE,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync MRX_VBOX_START_IN_PROGRESS,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync MRX_VBOX_STARTED
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync} MRX_VBOX_STATE, *PMRX_VBOX_STATE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsyncstatic MRX_VBOX_STATE VBoxMRxState = MRX_VBOX_STARTABLE;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
48d60b042893290a747d3abeda71a3085d9133fdvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The VBoxSF dispatch table.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic struct _MINIRDR_DISPATCH VBoxMRxDispatch;
8809400ad2407593d3471b82d5caf0c24cbcdf8avboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * The VBoxSF device object.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncPRDBSS_DEVICE_OBJECT VBoxMRxDeviceObject;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic NTSTATUS VBoxMRxFsdDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NTSTATUS Status = STATUS_SUCCESS;
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync UCHAR MajorFunctionCode = IrpSp->MajorFunction;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG MinorFunctionCode = IrpSp->MinorFunction;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxFsdDispatch: major %d, minor %d: %s\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync MajorFunctionCode, MinorFunctionCode, MajorFunctionString(MajorFunctionCode, MinorFunctionCode)));
ffa39e5fea478b00909918ab8d45fb3ffb02bc14vboxsync
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync if (DeviceObject != (PDEVICE_OBJECT)VBoxMRxDeviceObject)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Irp->IoStatus.Information = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync IoCompleteRequest(Irp, IO_NO_INCREMENT);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxFsdDispatch: Invalid device request detected %p %p\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync DeviceObject, (PDEVICE_OBJECT)VBoxMRxDeviceObject));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return STATUS_INVALID_DEVICE_REQUEST;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Status = RxFsdDispatch((PRDBSS_DEVICE_OBJECT)VBoxMRxDeviceObject, Irp);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
ffa39e5fea478b00909918ab8d45fb3ffb02bc14vboxsync Log(("VBOXSF: MRxFsdDispatch: Returned 0x%X\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void VBoxMRxUnload(IN PDRIVER_OBJECT DriverObject)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NTSTATUS Status;
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync UNICODE_STRING UserModeDeviceName;
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync Log(("VBOXSF: MRxUnload\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (VBoxMRxDeviceObject)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pDeviceExtension = (PMRX_VBOX_DEVICE_EXTENSION)((PBYTE)VBoxMRxDeviceObject + sizeof(RDBSS_DEVICE_OBJECT));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxDisconnect (&pDeviceExtension->hgcmClient);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxUninit();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (VBoxMRxDeviceObject)
38b70b2dcb1783801f7580cba797a0c8af4b5326vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PRX_CONTEXT RxContext;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RxContext = RxCreateRxContext(NULL, VBoxMRxDeviceObject, RX_CONTEXT_FLAG_IN_FSP);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
38b70b2dcb1783801f7580cba797a0c8af4b5326vboxsync if (RxContext != NULL)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = RxStopMinirdr(RxContext, &RxContext->PostRequest);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
38b70b2dcb1783801f7580cba797a0c8af4b5326vboxsync if (Status == STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync MRX_VBOX_STATE State;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync State = (MRX_VBOX_STATE)InterlockedCompareExchange((LONG *)&VBoxMRxState, MRX_VBOX_STARTABLE, MRX_VBOX_STARTED);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (State != MRX_VBOX_STARTABLE)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = STATUS_REDIRECTOR_STARTED;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RxDereferenceAndDeleteRxContext(RxContext);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync Status = STATUS_INSUFFICIENT_RESOURCES;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RxUnregisterMinirdr(VBoxMRxDeviceObject);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RtlInitUnicodeString(&UserModeDeviceName, DD_MRX_VBOX_USERMODE_SHADOW_DEV_NAME_U);
17c6e5e8177d068d1bc6af875d1610718efcfdb4vboxsync Status = IoDeleteSymbolicLink(&UserModeDeviceName);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (Status != STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
b1c3cdef473df2fbc621d5da81acc82dbfb8a11avboxsync Log(("VBOXSF: MRxUnload: IoDeleteSymbolicLink Status 0x%08X\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
fa92c704624def98d3c4aca86d65182effb98e04vboxsync
fa92c704624def98d3c4aca86d65182effb98e04vboxsync RxUnload(DriverObject);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
17c6e5e8177d068d1bc6af875d1610718efcfdb4vboxsync Log(("VBOXSF: MRxUnload: VBoxSF.sys driver object %p unloaded\n",
17c6e5e8177d068d1bc6af875d1610718efcfdb4vboxsync DriverObject));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic void vbsfInitMRxDispatch(void)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
17c6e5e8177d068d1bc6af875d1610718efcfdb4vboxsync Log(("VBOXSF: vbsfInitMRxDispatch: Called.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ZeroAndInitializeNodeType(&VBoxMRxDispatch, RDBSS_NTC_MINIRDR_DISPATCH, sizeof(MINIRDR_DISPATCH));
b1c3cdef473df2fbc621d5da81acc82dbfb8a11avboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxFlags = (RDBSS_MANAGE_NET_ROOT_EXTENSION | RDBSS_MANAGE_FOBX_EXTENSION);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
fa92c704624def98d3c4aca86d65182effb98e04vboxsync VBoxMRxDispatch.MRxSrvCallSize = 0;
fa92c704624def98d3c4aca86d65182effb98e04vboxsync VBoxMRxDispatch.MRxNetRootSize = sizeof(MRX_VBOX_NETROOT_EXTENSION);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxVNetRootSize = 0;
17c6e5e8177d068d1bc6af875d1610718efcfdb4vboxsync VBoxMRxDispatch.MRxFcbSize = 0;
17c6e5e8177d068d1bc6af875d1610718efcfdb4vboxsync VBoxMRxDispatch.MRxSrvOpenSize = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxFobxSize = sizeof(MRX_VBOX_FOBX);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxStart = VBoxMRxStart;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxStop = VBoxMRxStop;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxCreate = VBoxMRxCreate;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxCollapseOpen = VBoxMRxCollapseOpen;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxShouldTryToCollapseThisOpen = VBoxMRxShouldTryToCollapseThisOpen;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxFlush = VBoxMRxFlush;
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync VBoxMRxDispatch.MRxTruncate = VBoxMRxTruncate;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxCleanupFobx = VBoxMRxCleanupFobx;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxCloseSrvOpen = VBoxMRxCloseSrvOpen;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxDeallocateForFcb = VBoxMRxDeallocateForFcb;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxDeallocateForFobx = VBoxMRxDeallocateForFobx;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxForceClosed = VBoxMRxForceClosed;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxQueryDirectory = VBoxMRxQueryDirectory;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxQueryFileInfo = VBoxMRxQueryFileInfo;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxSetFileInfo = VBoxMRxSetFileInfo;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxSetFileInfoAtCleanup = VBoxMRxSetFileInfoAtCleanup;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxQueryEaInfo = VBoxMRxQueryEaInfo;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxSetEaInfo = VBoxMRxSetEaInfo;
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync VBoxMRxDispatch.MRxQuerySdInfo = VBoxMRxQuerySdInfo;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxSetSdInfo = VBoxMRxSetSdInfo;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxQueryVolumeInfo = VBoxMRxQueryVolumeInfo;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxComputeNewBufferingState = VBoxMRxComputeNewBufferingState;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_READ] = VBoxMRxRead;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_WRITE] = VBoxMRxWrite;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_SHAREDLOCK] = VBoxMRxLocks;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_EXCLUSIVELOCK] = VBoxMRxLocks;
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_UNLOCK] = VBoxMRxLocks;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_UNLOCK_MULTIPLE] = VBoxMRxLocks;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_FSCTL] = VBoxMRxFsCtl;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_IOCTL] = VBoxMRxIoCtl;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDispatch.MRxLowIOSubmit[LOWIO_OP_NOTIFY_CHANGE_DIRECTORY] = VBoxMRxNotifyChangeDirectory;
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync
940dbfa4936f2e3966e9e874c4886709f0c75b44vboxsync VBoxMRxDispatch.MRxExtendForCache = VBoxMRxExtendStub;
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync VBoxMRxDispatch.MRxExtendForNonCache = VBoxMRxExtendStub;
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync VBoxMRxDispatch.MRxCompleteBufferingStateChangeRequest = VBoxMRxCompleteBufferingStateChangeRequest;
940dbfa4936f2e3966e9e874c4886709f0c75b44vboxsync
940dbfa4936f2e3966e9e874c4886709f0c75b44vboxsync VBoxMRxDispatch.MRxCreateVNetRoot = VBoxMRxCreateVNetRoot;
940dbfa4936f2e3966e9e874c4886709f0c75b44vboxsync VBoxMRxDispatch.MRxFinalizeVNetRoot = VBoxMRxFinalizeVNetRoot;
940dbfa4936f2e3966e9e874c4886709f0c75b44vboxsync VBoxMRxDispatch.MRxFinalizeNetRoot = VBoxMRxFinalizeNetRoot;
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync VBoxMRxDispatch.MRxUpdateNetRootState = VBoxMRxUpdateNetRootState;
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync VBoxMRxDispatch.MRxExtractNetRootName = VBoxMRxExtractNetRootName;
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync VBoxMRxDispatch.MRxCreateSrvCall = VBoxMRxCreateSrvCall;
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync VBoxMRxDispatch.MRxSrvCallWinnerNotify = VBoxMRxSrvCallWinnerNotify;
940dbfa4936f2e3966e9e874c4886709f0c75b44vboxsync VBoxMRxDispatch.MRxFinalizeSrvCall = VBoxMRxFinalizeSrvCall;
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync VBoxMRxDispatch.MRxDevFcbXXXControlFile = VBoxMRxDevFcbXXXControlFile;
940dbfa4936f2e3966e9e874c4886709f0c75b44vboxsync
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync Log(("VBOXSF: vbsfInitMRxDispatch: Success.\n"));
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync return;
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync}
5eca6b757429b1f1d768e16fba65c485af34319dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic BOOL vboxIsPrefixOK (const WCHAR *FilePathName, ULONG PathNameLength)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync BOOL PrefixOK;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* The FilePathName here looks like: \vboxsrv\... */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (PathNameLength >= 8 * sizeof (WCHAR)) /* Number of bytes in '\vboxsrv' unicode string. */
ada08ea58e7613c10d4c40669fd4fb955324bfdfvboxsync {
ada08ea58e7613c10d4c40669fd4fb955324bfdfvboxsync PrefixOK = (FilePathName[0] == L'\\');
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync PrefixOK &= (FilePathName[1] == L'V') || (FilePathName[1] == L'v');
ada08ea58e7613c10d4c40669fd4fb955324bfdfvboxsync PrefixOK &= (FilePathName[2] == L'B') || (FilePathName[2] == L'b');
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PrefixOK &= (FilePathName[3] == L'O') || (FilePathName[3] == L'o');
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PrefixOK &= (FilePathName[4] == L'X') || (FilePathName[4] == L'x');
5cd35366dd244ca8c8c583904fc6ff2a0c60fa0fvboxsync PrefixOK &= (FilePathName[5] == L'S') || (FilePathName[5] == L's');
2a08e12d5dcc1bb5057a9620e87ad361d41a1c1fvboxsync /* Both vboxsvr & vboxsrv are now accepted */
2a08e12d5dcc1bb5057a9620e87ad361d41a1c1fvboxsync if ((FilePathName[6] == L'V') || (FilePathName[6] == L'v'))
2a08e12d5dcc1bb5057a9620e87ad361d41a1c1fvboxsync {
2a08e12d5dcc1bb5057a9620e87ad361d41a1c1fvboxsync PrefixOK &= (FilePathName[6] == L'V') || (FilePathName[6] == L'v');
2a08e12d5dcc1bb5057a9620e87ad361d41a1c1fvboxsync PrefixOK &= (FilePathName[7] == L'R') || (FilePathName[7] == L'r');
2a08e12d5dcc1bb5057a9620e87ad361d41a1c1fvboxsync }
2a08e12d5dcc1bb5057a9620e87ad361d41a1c1fvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
43d3e60a2bcef646da0887a845e67c3a47759158vboxsync PrefixOK &= (FilePathName[6] == L'R') || (FilePathName[6] == L'r');
48d60b042893290a747d3abeda71a3085d9133fdvboxsync PrefixOK &= (FilePathName[7] == L'V') || (FilePathName[7] == L'v');
48d60b042893290a747d3abeda71a3085d9133fdvboxsync }
48d60b042893290a747d3abeda71a3085d9133fdvboxsync if (PathNameLength > 8 * sizeof (WCHAR))
48d60b042893290a747d3abeda71a3085d9133fdvboxsync {
48d60b042893290a747d3abeda71a3085d9133fdvboxsync /* There is something after '\vboxsrv'. */
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync PrefixOK &= (FilePathName[8] == L'\\') || (FilePathName[8] == 0);
48d60b042893290a747d3abeda71a3085d9133fdvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync {
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync PrefixOK = FALSE;
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync }
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync return PrefixOK;
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync}
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsyncstatic NTSTATUS VBoxMRXDeviceControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync NTSTATUS Status = STATUS_SUCCESS;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync QUERY_PATH_REQUEST *pReq = NULL;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync QUERY_PATH_REQUEST_EX *pReqEx = NULL;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync QUERY_PATH_RESPONSE *pResp = NULL;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync BOOL PrefixOK = FALSE;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync /* Make a local copy, it will be needed after the Irp completion. */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync ULONG IoControlCode = pStack->Parameters.DeviceIoControl.IoControlCode;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = (PMRX_VBOX_DEVICE_EXTENSION)((PBYTE)pDevObj + sizeof(RDBSS_DEVICE_OBJECT));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Log(("VBOXSF: MRXDeviceControl: pDevObj %p, pDeviceExtension %p, code %x\n",
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync pDevObj, pDevObj->DeviceExtension, IoControlCode));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync switch (IoControlCode)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync {
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync case IOCTL_REDIR_QUERY_PATH_EX: /* Vista */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync case IOCTL_REDIR_QUERY_PATH: /* XP and earlier */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync {
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync /* This IOCTL is intercepted for 2 reasons:
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * 1) Claim the vboxsvr and vboxsrv prefixes. All name-based operations for them
5cd35366dd244ca8c8c583904fc6ff2a0c60fa0fvboxsync * will be routed to the VBox provider automatically without any prefix resolution
43d3e60a2bcef646da0887a845e67c3a47759158vboxsync * since the prefix is already in the prefix cache.
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * 2) Reject other prefixes immediately to speed up the UNC path resolution a bit,
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * because RDBSS will not be involved then.
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
f20f327b65009074292a4b9ad44a02b6bfb2de8avboxsync const WCHAR *FilePathName = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG PathNameLength = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (pIrp->RequestorMode != KernelMode)
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync {
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync /* MSDN: Network redirectors should only honor kernel-mode senders of this IOCTL, by verifying
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync * that RequestorMode member of the IRP structure is KernelMode.
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync */
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync Log(("VBOXSF: MRxDeviceControl: IOCTL_REDIR_QUERY_PATH(_EX): not kernel mode!!!\n",
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync pStack->Parameters.DeviceIoControl.InputBufferLength));
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync /* Continue to RDBSS. */
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync break;
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync }
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync if (IoControlCode == IOCTL_REDIR_QUERY_PATH)
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync {
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync Log(("VBOXSF: MRxDeviceControl: IOCTL_REDIR_QUERY_PATH: Called (pid %x).\n", IoGetCurrentProcess()));
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync if (pStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(QUERY_PATH_REQUEST))
da2ac963e5567d049d02bad0ad7783a0b9181637vboxsync {
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync Log(("VBOXSF: MRxDeviceControl: IOCTL_REDIR_QUERY_PATH: short input buffer %d.\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pStack->Parameters.DeviceIoControl.InputBufferLength));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Continue to RDBSS. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
f20f327b65009074292a4b9ad44a02b6bfb2de8avboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pReq = (QUERY_PATH_REQUEST *)pStack->Parameters.DeviceIoControl.Type3InputBuffer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync Log(("VBOXSF: MRxDeviceControl: PathNameLength = %d.\n", pReq->PathNameLength));
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync Log(("VBOXSF: MRxDeviceControl: SecurityContext = %p.\n", pReq->SecurityContext));
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync Log(("VBOXSF: MRxDeviceControl: FilePathName = %.*ls.\n", pReq->PathNameLength / sizeof (WCHAR), pReq->FilePathName));
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync FilePathName = pReq->FilePathName;
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync PathNameLength = pReq->PathNameLength;
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync }
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync else
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync {
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync Log(("VBOXSF: MRxDeviceControl: IOCTL_REDIR_QUERY_PATH_EX: Called.\n"));
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync
447f830b91e4e0a6702f578f2c0babfd812a5d74vboxsync if (pStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(QUERY_PATH_REQUEST_EX))
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync {
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync Log(("VBOXSF: MRxDeviceControl: IOCTL_REDIR_QUERY_PATH_EX: short input buffer %d.\n",
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync pStack->Parameters.DeviceIoControl.InputBufferLength));
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync /* Continue to RDBSS. */
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync break;
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pReqEx = (QUERY_PATH_REQUEST_EX *)pStack->Parameters.DeviceIoControl.Type3InputBuffer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxDeviceControl: pSecurityContext = %p.\n", pReqEx->pSecurityContext));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxDeviceControl: EaLength = %d.\n", pReqEx->EaLength));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxDeviceControl: pEaBuffer = %p.\n", pReqEx->pEaBuffer));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxDeviceControl: PathNameLength = %d.\n", pReqEx->PathName.Length));
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync Log(("VBOXSF: MRxDeviceControl: FilePathName = %.*ls.\n", pReqEx->PathName.Length / sizeof (WCHAR), pReqEx->PathName.Buffer));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync FilePathName = pReqEx->PathName.Buffer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PathNameLength = pReqEx->PathName.Length;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pResp = (QUERY_PATH_RESPONSE *)pIrp->UserBuffer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync PrefixOK = vboxIsPrefixOK (FilePathName, PathNameLength);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxDeviceControl PrefixOK %d\n", PrefixOK));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (!PrefixOK)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync {
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync /* Immediately fail the IOCTL with STATUS_BAD_NETWORK_NAME as recommended by MSDN.
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * No need to involve RDBSS.
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Status = STATUS_BAD_NETWORK_NAME;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync pIrp->IoStatus.Status = Status;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync pIrp->IoStatus.Information = 0;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync IoCompleteRequest(pIrp, IO_NO_INCREMENT);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Log(("VBOXSF: MRxDeviceControl: returned STATUS_BAD_NETWORK_NAME\n"));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync return Status;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync }
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Log(("VBOXSF: MRxDeviceControl pResp %p verifying the path.\n", pResp));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync if (pResp)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync {
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync /* Always claim entire \vboxsrv prefix. The LengthAccepted initially is equal to entire path.
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * Here it is assigned to the length of \vboxsrv prefix.
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pResp->LengthAccepted = 8 * sizeof (WCHAR);
f20f327b65009074292a4b9ad44a02b6bfb2de8avboxsync
1f67f03c498fb10dfaa104a3698a1e149b7e9eb5vboxsync Status = STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pIrp->IoStatus.Status = Status;
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync pIrp->IoStatus.Information = 0;
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync IoCompleteRequest(pIrp, IO_NO_INCREMENT);
e17f587595bd5d3a7be56a892e3fd3a0ef83d268vboxsync
10eaaac806009b8336cc5d746fe5072f6c9f58c0vboxsync Log(("VBOXSF: MRxDeviceControl: claiming the path.\n"));
ef5b48babdb77b6bcc17a490cbbd0eef5e46e9fcvboxsync return Status;
ef5b48babdb77b6bcc17a490cbbd0eef5e46e9fcvboxsync }
1f67f03c498fb10dfaa104a3698a1e149b7e9eb5vboxsync
1f67f03c498fb10dfaa104a3698a1e149b7e9eb5vboxsync /* No pResp pointer, should not happen. Just a precaution. */
1f67f03c498fb10dfaa104a3698a1e149b7e9eb5vboxsync Status = STATUS_INVALID_PARAMETER;
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync pIrp->IoStatus.Status = Status;
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync pIrp->IoStatus.Information = 0;
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync IoCompleteRequest(pIrp, IO_NO_INCREMENT);
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync Log(("VBOXSF: MRxDeviceControl: returned STATUS_INVALID_PARAMETER\n"));
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync return Status;
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync }
3c292c68aeb0a95090706381edf33b886c81afd1vboxsync
3c292c68aeb0a95090706381edf33b886c81afd1vboxsync default:
3c292c68aeb0a95090706381edf33b886c81afd1vboxsync break;
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync }
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync /* Pass the IOCTL to RDBSS. */
1f67f03c498fb10dfaa104a3698a1e149b7e9eb5vboxsync if (pDeviceExtension && pDeviceExtension->pfnRDBSSDeviceControl)
8809400ad2407593d3471b82d5caf0c24cbcdf8avboxsync {
8809400ad2407593d3471b82d5caf0c24cbcdf8avboxsync Log(("VBOXSF: MRxDeviceControl calling RDBSS %p\n", pDeviceExtension->pfnRDBSSDeviceControl));
8809400ad2407593d3471b82d5caf0c24cbcdf8avboxsync Status = pDeviceExtension->pfnRDBSSDeviceControl (pDevObj, pIrp);
8809400ad2407593d3471b82d5caf0c24cbcdf8avboxsync Log(("VBOXSF: MRxDeviceControl RDBSS status 0x%08X\n", Status));
6a2b7cefae549318ba64aee5d6f40d0aae28f1a3vboxsync }
8809400ad2407593d3471b82d5caf0c24cbcdf8avboxsync else
960d1f2d42faa8d833309114e5adc46a6a658c27vboxsync {
960d1f2d42faa8d833309114e5adc46a6a658c27vboxsync /* No RDBSS, should not happen. Just a precaution. */
960d1f2d42faa8d833309114e5adc46a6a658c27vboxsync Status = STATUS_NOT_IMPLEMENTED;
960d1f2d42faa8d833309114e5adc46a6a658c27vboxsync
960d1f2d42faa8d833309114e5adc46a6a658c27vboxsync pIrp->IoStatus.Status = Status;
960d1f2d42faa8d833309114e5adc46a6a658c27vboxsync pIrp->IoStatus.Information = 0;
960d1f2d42faa8d833309114e5adc46a6a658c27vboxsync
395ac8a20a012656020c61a3975493a65fee0e77vboxsync IoCompleteRequest(pIrp, IO_NO_INCREMENT);
960d1f2d42faa8d833309114e5adc46a6a658c27vboxsync
395ac8a20a012656020c61a3975493a65fee0e77vboxsync Log(("VBOXSF: MRxDeviceControl: returned STATUS_NOT_IMPLEMENTED\n"));
8809400ad2407593d3471b82d5caf0c24cbcdf8avboxsync }
8809400ad2407593d3471b82d5caf0c24cbcdf8avboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
f20f327b65009074292a4b9ad44a02b6bfb2de8avboxsyncNTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync IN PUNICODE_STRING RegistryPath)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NTSTATUS Status;
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync UNICODE_STRING VBoxMRxName;
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync UNICODE_STRING UserModeDeviceName;
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension;
e17f587595bd5d3a7be56a892e3fd3a0ef83d268vboxsync ULONG i;
10eaaac806009b8336cc5d746fe5072f6c9f58c0vboxsync int vboxRC;
1bc5a31ae6d57c2b4731a23205f3958678b60193vboxsync VBSFCLIENT hgcmClient;
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync Log(("VBOXSF: DriverEntry: Driver object %p\n", DriverObject));
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync if (DriverObject == NULL)
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync {
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync Log(("VBOXSF: DriverEntry: driver object is NULL.\n"));
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync return STATUS_UNSUCCESSFUL;
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync }
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync /* Initialize VBox subsystem. */
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync vboxRC = vboxInit();
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync if (RT_FAILURE(vboxRC))
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync {
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync Log(("VBOXSF: DriverEntry: ERROR while initializing VBox subsystem (%Rrc)!\n",
09b36b509b761f9ce006fa9c25cb86d12757b937vboxsync vboxRC));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return STATUS_UNSUCCESSFUL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
f20f327b65009074292a4b9ad44a02b6bfb2de8avboxsync /* Connect the HGCM client */
c50100d1513854735d4e3593b3b385c007f6d8b6vboxsync RT_ZERO(hgcmClient);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxRC = vboxConnect(&hgcmClient);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (RT_FAILURE(vboxRC))
c50100d1513854735d4e3593b3b385c007f6d8b6vboxsync {
c50100d1513854735d4e3593b3b385c007f6d8b6vboxsync Log(("VBOXSF: DriverEntry: ERROR while connecting to host (%Rrc)!\n",
b0d29fd0a868929a608ff72658aac997cc95319avboxsync vboxRC));
c50100d1513854735d4e3593b3b385c007f6d8b6vboxsync vboxUninit();
b0d29fd0a868929a608ff72658aac997cc95319avboxsync return STATUS_UNSUCCESSFUL;
b0d29fd0a868929a608ff72658aac997cc95319avboxsync }
b0d29fd0a868929a608ff72658aac997cc95319avboxsync
c50100d1513854735d4e3593b3b385c007f6d8b6vboxsync /* Init the driver object. */
b0d29fd0a868929a608ff72658aac997cc95319avboxsync DriverObject->DriverUnload = VBoxMRxUnload;
b0d29fd0a868929a608ff72658aac997cc95319avboxsync for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
b0d29fd0a868929a608ff72658aac997cc95319avboxsync {
c50100d1513854735d4e3593b3b385c007f6d8b6vboxsync DriverObject->MajorFunction[i] = (PDRIVER_DISPATCH)VBoxMRxFsdDispatch;
b0d29fd0a868929a608ff72658aac997cc95319avboxsync }
b0d29fd0a868929a608ff72658aac997cc95319avboxsync
b0d29fd0a868929a608ff72658aac997cc95319avboxsync /* Forward to RDBSS. */
b0d29fd0a868929a608ff72658aac997cc95319avboxsync Status = RxDriverEntry(DriverObject, RegistryPath);
c50100d1513854735d4e3593b3b385c007f6d8b6vboxsync if (Status != STATUS_SUCCESS)
b0d29fd0a868929a608ff72658aac997cc95319avboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: DriverEntry: RxDriverEntry failed: 0x%08X\n", Status));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync goto failure;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync __try
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: DriverEntry: RxRegisterMinirdr: calling VBoxMRxDeviceObject %p\n",
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync VBoxMRxDeviceObject));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RtlInitUnicodeString(&VBoxMRxName, DD_MRX_VBOX_FS_DEVICE_NAME_U);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /* Don use RX_REGISTERMINI_FLAG_DONT_PROVIDE_UNCS or else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * UNC mappings don't work (including Windows explorer browsing).
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = RxRegisterMinirdr(&VBoxMRxDeviceObject,
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync DriverObject,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync &VBoxMRxDispatch,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RX_REGISTERMINI_FLAG_DONT_PROVIDE_MAILSLOTS,
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync &VBoxMRxName,
6565c2fb4f10f47bcb5436630d2dc35e5a4f28e2vboxsync sizeof(MRX_VBOX_DEVICE_EXTENSION),
6c83eb6b98d1dd1b1d9795c16801ee2f53d2cc31vboxsync FILE_DEVICE_NETWORK_FILE_SYSTEM,
6565c2fb4f10f47bcb5436630d2dc35e5a4f28e2vboxsync FILE_REMOTE_DEVICE);
6565c2fb4f10f47bcb5436630d2dc35e5a4f28e2vboxsync
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync Log(("VBOXSF: DriverEntry: RxRegisterMinirdr: returned 0x%08X VBoxMRxDeviceObject %p\n",
6565c2fb4f10f47bcb5436630d2dc35e5a4f28e2vboxsync Status, VBoxMRxDeviceObject));
6565c2fb4f10f47bcb5436630d2dc35e5a4f28e2vboxsync
2da513a7caa29822c9991d7e8615658a194c0cf8vboxsync if (Status!=STATUS_SUCCESS)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync {
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Log(("VBOXSF: DriverEntry: RxRegisterMinirdr failed: 0x%08X\n", Status ));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync try_return(Status);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync }
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync /* Init the device extension.
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * NOTE: the device extension actually points to fields
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * in the RDBSS_DEVICE_OBJECT. Our space is past the end
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * of this struct!!
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync pDeviceExtension = (PMRX_VBOX_DEVICE_EXTENSION)((PBYTE)VBoxMRxDeviceObject + sizeof(RDBSS_DEVICE_OBJECT));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync pDeviceExtension->pDeviceObject = VBoxMRxDeviceObject;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync for (i = 0; i < RT_ELEMENTS(pDeviceExtension->cLocalConnections); i++)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync {
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync pDeviceExtension->cLocalConnections[i] = FALSE;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync }
2da513a7caa29822c9991d7e8615658a194c0cf8vboxsync
2da513a7caa29822c9991d7e8615658a194c0cf8vboxsync /* Mutex for synchronizining our connection list */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync ExInitializeFastMutex(&pDeviceExtension->mtxLocalCon);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync /* The device object has been created. Need to setup a symbolic
2da513a7caa29822c9991d7e8615658a194c0cf8vboxsync * link so that the device may be accessed from a Win32 user mode
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * application.
86b620001857a05e9e7b83b11525094c34637e23vboxsync */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RtlInitUnicodeString(&UserModeDeviceName, DD_MRX_VBOX_USERMODE_SHADOW_DEV_NAME_U);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: DriverEntry: Calling IoCreateSymbolicLink\n"));
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync Status = IoCreateSymbolicLink(&UserModeDeviceName, &VBoxMRxName);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (Status != STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: DriverEntry: IoCreateSymbolicLink: 0x%08X\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status));
86b620001857a05e9e7b83b11525094c34637e23vboxsync try_return(Status);
86b620001857a05e9e7b83b11525094c34637e23vboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: DriverEntry: Symbolic link created.\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Build the dispatch tables for the minirdr
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vbsfInitMRxDispatch();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync try_exit:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync __finally
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync if (Status != STATUS_SUCCESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: DriverEntry: VBoxSF.sys failed to start with Status = 0x%08X\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync goto failure;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync }
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync pDeviceExtension->hgcmClient = hgcmClient;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync /* The redirector driver must intercept the IOCTL to avoid VBOXSVR name resolution
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * by other redirectors. These additional name resolutions cause long delays.
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Log(("VBOXSF: DriverEntry: VBoxMRxDeviceObject = %p, rdbss %p, devext %p\n",
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync VBoxMRxDeviceObject, DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL], pDeviceExtension));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync pDeviceExtension->pfnRDBSSDeviceControl = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VBoxMRXDeviceControl;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync /* @todo start the redirector here RxStartMiniRdr. */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: DriverEntry: Init successful!\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return STATUS_SUCCESS;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsyncfailure:
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: DriverEntry: Failure! Status = 0x%08X\n", Status));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxDisconnect(&hgcmClient);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync vboxUninit();
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (VBoxMRxDeviceObject)
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RxUnregisterMinirdr(VBoxMRxDeviceObject);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync VBoxMRxDeviceObject = NULL;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync return Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsyncNTSTATUS VBoxMRxStart(PRX_CONTEXT RxContext, IN OUT PRDBSS_DEVICE_OBJECT RxDeviceObject)
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync{
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync NTSTATUS Status;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync MRX_VBOX_STATE CurrentState;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxStart\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync CurrentState = (MRX_VBOX_STATE)InterlockedCompareExchange((PLONG)&VBoxMRxState, MRX_VBOX_STARTED, MRX_VBOX_START_IN_PROGRESS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync if (CurrentState == MRX_VBOX_START_IN_PROGRESS)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxStart: Start in progress -> started\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else if (VBoxMRxState == MRX_VBOX_STARTED)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxStart: Already started\n"));
dee2201f96a012bfb966c8de4ab006c2c90a0eefvboxsync Status = STATUS_REDIRECTOR_STARTED;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Log(("VBOXSF: MRxStart: Bad state! VBoxMRxState = %d\n", VBoxMRxState));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Status = STATUS_UNSUCCESSFUL;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync }
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync return Status;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync}
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsyncNTSTATUS VBoxMRxStop(PRX_CONTEXT RxContext, IN OUT PRDBSS_DEVICE_OBJECT RxDeviceObject)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync{
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Log(("VBOXSF: MRxStop\n"));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync return STATUS_SUCCESS;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync}
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsyncNTSTATUS VBoxMRxIoCtl(IN OUT PRX_CONTEXT RxContext)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync{
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Log(("VBOXSF: MRxIoCtl: IoControlCode = 0x%08X\n",
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync RxContext->LowIoContext.ParamsFor.FsCtl.FsControlCode));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync return STATUS_INVALID_DEVICE_REQUEST;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync}
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsyncNTSYSAPI NTSTATUS NTAPI ZwSetSecurityObject(IN HANDLE Handle,
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync IN SECURITY_INFORMATION SecurityInformation,
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync IN PSECURITY_DESCRIPTOR SecurityDescriptor);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsyncNTSTATUS VBoxMRxDevFcbXXXControlFile(IN OUT PRX_CONTEXT RxContext)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync{
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync NTSTATUS Status = STATUS_SUCCESS;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync RxCaptureFobx;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Log(("VBOXSF: MRxDevFcbXXXControlFile: MajorFunction = 0x%02X\n",
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync RxContext->MajorFunction));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync switch (RxContext->MajorFunction)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync {
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync case IRP_MJ_FILE_SYSTEM_CONTROL:
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync {
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Log(("VBOXSF: MRxDevFcbXXXControlFile: IRP_MN_USER_FS_REQUEST: 0x%08X\n",
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync LowIoContext->ParamsFor.FsCtl.MinorFunction));
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync Status = STATUS_INVALID_DEVICE_REQUEST;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync break;
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync }
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync case IRP_MJ_DEVICE_CONTROL:
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync {
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync switch (LowIoContext->ParamsFor.IoCtl.IoControlCode)
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync {
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync case IOCTL_MRX_VBOX_ADDCONN:
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_ADDCONN\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vbsfCreateConnection(RxContext, &RxContext->PostRequest);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case IOCTL_MRX_VBOX_DELCONN:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_DELCONN\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = vbsfDeleteConnection(RxContext, &RxContext->PostRequest);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync } break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case IOCTL_MRX_VBOX_GETLIST:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG cbOut = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint8_t *pu8Out = (uint8_t *)LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETLIST\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (NULL == pDeviceExtension)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RxContext->InformationToReturn = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if ((cbOut >= _MRX_MAX_DRIVE_LETTERS) && (NULL != pu8Out))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync BOOLEAN fLocked = FALSE;
38b70b2dcb1783801f7580cba797a0c8af4b5326vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETLIST: Copying local connections\n"));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync fLocked = ExTryToAcquireFastMutex(&pDeviceExtension->mtxLocalCon);
38b70b2dcb1783801f7580cba797a0c8af4b5326vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RtlCopyMemory(pu8Out, pDeviceExtension->cLocalConnections, _MRX_MAX_DRIVE_LETTERS);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (fLocked)
38b70b2dcb1783801f7580cba797a0c8af4b5326vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ExReleaseFastMutex(&pDeviceExtension->mtxLocalCon);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RxContext->InformationToReturn = _MRX_MAX_DRIVE_LETTERS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync else
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETLIST: cbOut is too small %d bytes\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync cbOut));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RxContext->InformationToReturn = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Status = STATUS_SUCCESS;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /*
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Returns the root IDs of shared folder mappings.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync case IOCTL_MRX_VBOX_GETGLOBALLIST:
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync ULONG cbOut = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint8_t *pu8Out = (uint8_t *)LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETGLOBALLIST\n"));
38b70b2dcb1783801f7580cba797a0c8af4b5326vboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync RxContext->InformationToReturn = 0;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync if (NULL == pDeviceExtension)
38b70b2dcb1783801f7580cba797a0c8af4b5326vboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync break;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync }
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
38b70b2dcb1783801f7580cba797a0c8af4b5326vboxsync if ((cbOut >= _MRX_MAX_DRIVE_LETTERS) && (NULL != pu8Out))
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync {
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync SHFLMAPPING mappings[_MRX_MAX_DRIVE_LETTERS];
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync uint32_t cMappings = RT_ELEMENTS(mappings);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int vboxRC = vboxCallQueryMappings(&pDeviceExtension->hgcmClient, mappings, &cMappings);
ffa39e5fea478b00909918ab8d45fb3ffb02bc14vboxsync
if (vboxRC == VINF_SUCCESS)
{
uint32_t i;
RtlZeroMemory(pu8Out, _MRX_MAX_DRIVE_LETTERS);
for (i = 0; i < RT_MIN(cMappings, cbOut); i++)
{
pu8Out[i] = mappings[i].root;
pu8Out[i] |= 0x80; /* mark active */ /** @todo fix properly */
}
RxContext->InformationToReturn = _MRX_MAX_DRIVE_LETTERS;
}
else
{
Status = VBoxErrorToNTStatus(vboxRC);
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETGLOBALLIST failed: 0x%08X\n",
Status));
}
}
Status = STATUS_SUCCESS;
break;
}
/*
* Translates a local connection name (e.g. drive "S:") to the
* corresponding remote name (e.g. \\vboxsrv\share).
*/
case IOCTL_MRX_VBOX_GETCONN:
{
ULONG cbConnectName = LowIoContext->ParamsFor.IoCtl.InputBufferLength;
PWCHAR pwcConnectName = (PWCHAR)LowIoContext->ParamsFor.IoCtl.pInputBuffer;
ULONG cbRemoteName = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
PWCHAR pwcRemoteName = (PWCHAR)LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN: ConnectName = %.*ls, Len = %d, RemoteName = 0x%p, Len = %d\n",
cbConnectName / sizeof(WCHAR), pwcConnectName, cbConnectName, pwcRemoteName, cbRemoteName));
if (NULL == pDeviceExtension)
{
Status = STATUS_INVALID_PARAMETER;
break;
}
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN: Looking up connection name and connections\n"));
if ((cbConnectName > sizeof(WCHAR)) && (NULL != pwcConnectName))
{
ULONG cbLocalConnectionName;
uint32_t idx = *pwcConnectName - L'A';
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN: Index = %d\n", idx));
if (idx >= RTL_NUMBER_OF(pDeviceExtension->wszLocalConnectionName))
{
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN: Index is invalid!\n"));
Status = STATUS_INVALID_PARAMETER;
break;
}
ExAcquireFastMutex(&pDeviceExtension->mtxLocalCon);
if (NULL == pDeviceExtension->wszLocalConnectionName[idx])
{
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN: LocalConnectionName is NULL!\n"));
ExReleaseFastMutex(&pDeviceExtension->mtxLocalCon);
Status = STATUS_BAD_NETWORK_NAME;
break;
}
cbLocalConnectionName = pDeviceExtension->wszLocalConnectionName[idx]->Length;
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN: LocalConnectionName = %.*ls\n",
cbLocalConnectionName / sizeof(WCHAR), pDeviceExtension->wszLocalConnectionName[idx]->Buffer));
if ((pDeviceExtension->cLocalConnections[idx]) && (cbLocalConnectionName <= cbRemoteName))
{
RtlZeroMemory(pwcRemoteName, cbRemoteName);
RtlCopyMemory(pwcRemoteName, pDeviceExtension->wszLocalConnectionName[idx]->Buffer, cbLocalConnectionName);
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN: Remote name = %.*ls, Len = %d\n",
cbLocalConnectionName / sizeof(WCHAR), pwcRemoteName, cbLocalConnectionName));
RxContext->InformationToReturn = cbLocalConnectionName;
}
else
{
Status = STATUS_BUFFER_TOO_SMALL;
RxContext->InformationToReturn = cbLocalConnectionName;
}
ExReleaseFastMutex(&pDeviceExtension->mtxLocalCon);
}
else
{
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETCONN: bad connect name!n"));
Status = STATUS_BAD_NETWORK_NAME;
}
break;
}
case IOCTL_MRX_VBOX_GETGLOBALCONN:
{
ULONG ReturnedSize = 0;
uint8_t *pConnectId = (uint8_t *)LowIoContext->ParamsFor.IoCtl.pInputBuffer;
ULONG cbRemoteName = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
PWCHAR pwcRemoteName = (PWCHAR)LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
int vboxRC;
PSHFLSTRING pString;
uint32_t cbString;
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETGLOBALCONN: Connection ID = %d, RemoteName = 0x%x, Len = %d\n",
*pConnectId, pwcRemoteName, cbRemoteName));
cbString = sizeof(SHFLSTRING) + cbRemoteName;
pString = (PSHFLSTRING)vbsfAllocNonPagedMem(cbString);
if (!pString)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
memset(pString, 0, cbString);
ShflStringInitBuffer(pString, cbRemoteName);
vboxRC = vboxCallQueryMapName(&pDeviceExtension->hgcmClient,
(*pConnectId) & ~0x80 /** @todo fix properly */,
pString,
cbString);
if ( vboxRC == VINF_SUCCESS
&& pString->u16Length < cbRemoteName)
{
ReturnedSize = pString->u16Length;
RtlCopyMemory(pwcRemoteName, pString->String.ucs2, pString->u16Length);
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_GETGLOBALCONN: Returned name = %.*ls, Len = %d\n",
ReturnedSize / sizeof(WCHAR), pwcRemoteName, ReturnedSize));
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_BAD_NETWORK_NAME;
}
vbsfFreeNonPagedMem(pString);
RxContext->InformationToReturn = ReturnedSize;
} break;
case IOCTL_MRX_VBOX_START:
{
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: capFobx %p\n",
capFobx));
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: process: current 0x%X, RDBSS 0x%X\n",
IoGetCurrentProcess(), RxGetRDBSSProcess()));
switch (VBoxMRxState)
{
case MRX_VBOX_STARTABLE:
Log(("VBOXSF: MRxDevFcbXXXControlFile: MRX_VBOX_STARTABLE\n"));
if (capFobx)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
break;;
}
InterlockedCompareExchange((PLONG)&VBoxMRxState, MRX_VBOX_START_IN_PROGRESS, MRX_VBOX_STARTABLE);
case MRX_VBOX_START_IN_PROGRESS:
Status = RxStartMinirdr(RxContext, &RxContext->PostRequest);
Log(("VBOXSF: MRxDevFcbXXXControlFile: MRX_VBOX_START_IN_PROGRESS RxStartMiniRdr Status 0x%08X, post %d\n",
Status, RxContext->PostRequest));
if (Status == STATUS_REDIRECTOR_STARTED)
{
Status = STATUS_SUCCESS;
break;
}
if ( Status == STATUS_PENDING
&& RxContext->PostRequest == TRUE)
{
/* Will be restarted in RDBSS process. */
Status = STATUS_MORE_PROCESSING_REQUIRED;
break;
}
/* Allow restricted users to use shared folders; works only in XP and Vista. (@@todo hack) */
if (Status == STATUS_SUCCESS)
{
SECURITY_DESCRIPTOR SecurityDescriptor;
OBJECT_ATTRIBUTES InitializedAttributes;
HANDLE hDevice;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING UserModeDeviceName;
RtlInitUnicodeString(&UserModeDeviceName, DD_MRX_VBOX_USERMODE_SHADOW_DEV_NAME_U);
/* Create empty security descriptor */
RtlZeroMemory (&SecurityDescriptor, sizeof (SecurityDescriptor));
Status = RtlCreateSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
if (Status != STATUS_SUCCESS)
{
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: MRX_VBOX_START_IN_PROGRESS: RtlCreateSecurityDescriptor failed with 0x%08X!\n",
Status));
return Status;
}
RtlZeroMemory (&InitializedAttributes, sizeof (InitializedAttributes));
InitializeObjectAttributes(&InitializedAttributes, &UserModeDeviceName, OBJ_KERNEL_HANDLE, 0, 0);
/* Open our symbolic link device name */
Status = ZwOpenFile(&hDevice, WRITE_DAC, &InitializedAttributes, &IoStatusBlock, 0, 0);
if (Status != STATUS_SUCCESS)
{
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: MRX_VBOX_START_IN_PROGRESS: ZwOpenFile %ls failed with 0x%08X!\n",
DD_MRX_VBOX_USERMODE_SHADOW_DEV_NAME_U, Status));
return Status;
}
/* Override the discretionary access control list (DACL) settings */
Status = ZwSetSecurityObject(hDevice, DACL_SECURITY_INFORMATION, &SecurityDescriptor);
if (Status != STATUS_SUCCESS)
{
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: MRX_VBOX_START_IN_PROGRESS: ZwSetSecurityObject failed with 0x%08X!\n",
Status));
return Status;
}
Status = ZwClose(hDevice);
if (Status != STATUS_SUCCESS)
{
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: MRX_VBOX_START_IN_PROGRESS: ZwClose failed with 0x%08X\n",
Status));
return Status;
}
}
break;
case MRX_VBOX_STARTED:
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: MRX_VBOX_STARTED: Already started\n"));
Status = STATUS_SUCCESS;
break;
default:
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: Invalid state (%d)!\n",
VBoxMRxState));
Status = STATUS_INVALID_PARAMETER;
break;
}
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_START: Returned 0x%08X\n",
Status));
break;
}
case IOCTL_MRX_VBOX_STOP:
{
MRX_VBOX_STATE CurrentState;
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_STOP: capFobx %p\n",
capFobx));
if (capFobx)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
if (RxContext->RxDeviceObject->NumberOfActiveFcbs > 0)
{
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_STOP: Open handles = %d\n",
RxContext->RxDeviceObject->NumberOfActiveFcbs));
Status = STATUS_REDIRECTOR_HAS_OPEN_HANDLES;
break;
}
CurrentState = (MRX_VBOX_STATE)InterlockedCompareExchange((PLONG) & VBoxMRxState, MRX_VBOX_STARTABLE, MRX_VBOX_STARTED);
Status = RxStopMinirdr(RxContext, &RxContext->PostRequest);
Log(("VBOXSF: MRxDevFcbXXXControlFile: IOCTL_MRX_VBOX_STOP: Returned 0x%08X\n",
Status));
if (Status == STATUS_PENDING && RxContext->PostRequest == TRUE)
{
Status = STATUS_MORE_PROCESSING_REQUIRED;
}
} break;
default:
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
} break;
}
case IRP_MJ_INTERNAL_DEVICE_CONTROL:
{
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
default:
Log(("VBOXSF: MRxDevFcbXXXControlFile: unimplemented major function 0x%02X\n",
RxContext->MajorFunction));
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
Log(("VBOXSF: MRxDevFcbXXXControlFile: Status = 0x%08X, Info = 0x%08X\n",
Status, RxContext->InformationToReturn));
return Status;
}
static HANDLE vbsfOpenConnectionHandle(PUNICODE_STRING ConnectionName)
{
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE Handle = INVALID_HANDLE_VALUE;
Log(("VBOXSF: vbsfOpenConnectionHandle: ConnectionName = %.*ls\n",
ConnectionName->Length / sizeof(WCHAR), ConnectionName->Buffer));
/* Have to create a OBJ_KERNEL_HANDLE. Otherwise the driver verifier on Windows 7 bugchecks. */
InitializeObjectAttributes(&ObjectAttributes,
ConnectionName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
Status = ZwCreateFile(&Handle,
SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN_IF,
FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if ( Status != STATUS_SUCCESS
|| Handle == INVALID_HANDLE_VALUE)
{
Log(("VBOXSF: vbsfOpenConnectionHandle: ZwCreateFile failed status 0x%08X or invalid handle!\n",
Status));
Handle = INVALID_HANDLE_VALUE;
}
return Handle;
}
NTSTATUS vbsfCreateConnection(IN PRX_CONTEXT RxContext, OUT PBOOLEAN PostToFsp)
{
NTSTATUS Status = STATUS_SUCCESS;
PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension;
PLOWIO_CONTEXT LowIoContext;
ULONG cbConnectName;
PWCHAR pwcConnectName;
HANDLE Handle;
UNICODE_STRING FileName;
Log(("VBOXSF: vbsfCreateConnection\n"));
if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT))
{
Log(("VBOXSF: vbsfCreateConnection: post to file system process\n"));
*PostToFsp = TRUE;
return STATUS_PENDING;
}
pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
LowIoContext = &RxContext->LowIoContext;
cbConnectName = LowIoContext->ParamsFor.IoCtl.InputBufferLength;
pwcConnectName = (PWCHAR)LowIoContext->ParamsFor.IoCtl.pInputBuffer;
if (pDeviceExtension == NULL)
{
return STATUS_INVALID_PARAMETER;
}
if (cbConnectName == 0 || pwcConnectName == NULL)
{
Log(("VBOXSF: vbsfCreateConnection: Connection name / length is invalid!\n"));
return STATUS_INVALID_PARAMETER;
}
Log(("VBOXSF: vbsfCreateConnection: Name = %.*ls, Len = %d\n",
cbConnectName / sizeof(WCHAR), pwcConnectName, cbConnectName));
FileName.Buffer = pwcConnectName;
FileName.Length = (USHORT)cbConnectName;
FileName.MaximumLength = (USHORT)cbConnectName;
Handle = vbsfOpenConnectionHandle(&FileName);
if (Handle != INVALID_HANDLE_VALUE)
{
PWCHAR pwc;
ULONG i;
ZwClose(Handle);
/* Skip the "\Device\VBoxMiniRdr\;X:" of the string "\Device\VBoxMiniRdr\;X:\vboxsrv\sf" */
pwc = pwcConnectName;
for (i = 0; i < cbConnectName; i += sizeof(WCHAR))
{
if (*pwc == L':')
{
break;
}
pwc++;
}
if (i >= sizeof(WCHAR) && i < cbConnectName)
{
pwc--; /* Go back to the drive letter, "X" for example. */
if (*pwc >= L'A' && *pwc <= L'Z') /* Are we in range? */
{
uint32_t idx = *pwc - L'A'; /* Get the index based on the driver letter numbers (26). */
if (idx >= RTL_NUMBER_OF(pDeviceExtension->cLocalConnections))
{
Log(("VBOXSF: vbsfCreateConnection: Index 0x%x is invalid!\n",
idx));
Status = STATUS_BAD_NETWORK_NAME;
}
else
{
ExAcquireFastMutex(&pDeviceExtension->mtxLocalCon);
if (pDeviceExtension->wszLocalConnectionName[idx] != NULL)
{
Log(("VBOXSF: vbsfCreateConnection: LocalConnectionName at index %d is NOT empty!\n",
idx));
}
pDeviceExtension->wszLocalConnectionName[idx] = (PUNICODE_STRING)vbsfAllocNonPagedMem(sizeof(UNICODE_STRING) + cbConnectName);
if (pDeviceExtension->wszLocalConnectionName[idx] == NULL)
{
Log(("VBOXSF: vbsfCreateConnection: LocalConnectionName at index %d NOT allocated!\n",
idx));
Status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
PUNICODE_STRING pRemoteName = pDeviceExtension->wszLocalConnectionName[idx];
pRemoteName->Buffer = (PWSTR)(pRemoteName + 1);
pRemoteName->Length = (USHORT)(cbConnectName - i - sizeof(WCHAR));
pRemoteName->MaximumLength = pRemoteName->Length;
RtlCopyMemory(&pRemoteName->Buffer[0], pwc+2, pRemoteName->Length);
Log(("VBOXSF: vbsfCreateConnection: RemoteName %.*ls, Len = %d\n",
pRemoteName->Length / sizeof(WCHAR), pRemoteName->Buffer, pRemoteName->Length));
pDeviceExtension->cLocalConnections[idx] = TRUE;
}
ExReleaseFastMutex(&pDeviceExtension->mtxLocalCon);
}
}
}
else
{
Log(("VBOXSF: vbsfCreateConnection: bad format\n"));
Status = STATUS_BAD_NETWORK_NAME;
}
}
else
{
Log(("VBOXSF: vbsfCreateConnection: connection was not found\n"));
Status = STATUS_BAD_NETWORK_NAME;
}
return Status;
}
NTSTATUS vbsfDeleteConnection(IN PRX_CONTEXT RxContext, OUT PBOOLEAN PostToFsp)
{
NTSTATUS Status;
UNICODE_STRING FileName;
HANDLE Handle;
PLOWIO_CONTEXT LowIoContext;
PWCHAR pwcConnectName;
ULONG cbConnectName;
PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension;
if (!BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT))
{
Log(("VBOXSF: vbsfDeleteConnection: post to file system process\n"));
*PostToFsp = TRUE;
return STATUS_PENDING;
}
LowIoContext = &RxContext->LowIoContext;
pwcConnectName = (PWCHAR)LowIoContext->ParamsFor.IoCtl.pInputBuffer;
cbConnectName = LowIoContext->ParamsFor.IoCtl.InputBufferLength;
pDeviceExtension = VBoxMRxGetDeviceExtension(RxContext);
Log(("VBOXSF: vbsfDeleteConnection: pwcConnectName = %.*ls\n",
cbConnectName / sizeof(WCHAR), pwcConnectName));
FileName.Buffer = pwcConnectName;
FileName.Length = (USHORT)cbConnectName;
FileName.MaximumLength = (USHORT)cbConnectName;
Handle = vbsfOpenConnectionHandle(&FileName);
if (Handle != INVALID_HANDLE_VALUE)
{
PFILE_OBJECT pFileObject;
Status = ObReferenceObjectByHandle(Handle, 0L, NULL, KernelMode, (PVOID *)&pFileObject, NULL);
Log(("VBOXSF: vbsfDeleteConnection: ObReferenceObjectByHandle Status 0x%08X\n",
Status));
if (NT_SUCCESS(Status))
{
PFOBX Fobx = (PFOBX)pFileObject->FsContext2;
if (NodeType(Fobx) == RDBSS_NTC_V_NETROOT)
{
PV_NET_ROOT VNetRoot = (PV_NET_ROOT)Fobx;
Status = RxFinalizeConnection(VNetRoot->NetRoot, VNetRoot, TRUE);
}
else
{
Log(("VBOXSF: vbsfDeleteConnection: wrong FsContext2\n"));
Status = STATUS_INVALID_DEVICE_REQUEST;
}
ObDereferenceObject(pFileObject);
}
ZwClose(Handle);
}
if (NT_SUCCESS(Status))
{
PWCHAR pwc;
ULONG i;
/* Skip the "\Device\VBoxMiniRdr\;X:" of the string "\Device\VBoxMiniRdr\;X:\vboxsrv\sf" */
pwc = pwcConnectName;
for (i = 0; i < cbConnectName; i += sizeof(WCHAR))
{
if (*pwc == L':')
{
break;
}
pwc++;
}
if (i >= sizeof(WCHAR) && i < cbConnectName)
{
pwc--;
if (*pwc >= L'A' && *pwc <= L'Z')
{
uint32_t idx = *pwc - L'A';
if (idx >= RTL_NUMBER_OF(pDeviceExtension->cLocalConnections))
{
Log(("VBOXSF: vbsfDeleteConnection: Index 0x%x is invalid!\n",
idx));
Status = STATUS_BAD_NETWORK_NAME;
}
else
{
ExAcquireFastMutex(&pDeviceExtension->mtxLocalCon);
pDeviceExtension->cLocalConnections[idx] = FALSE;
/* Free saved name */
if (pDeviceExtension->wszLocalConnectionName[idx])
{
vbsfFreeNonPagedMem(pDeviceExtension->wszLocalConnectionName[idx]);
pDeviceExtension->wszLocalConnectionName[idx] = NULL;
}
ExReleaseFastMutex(&pDeviceExtension->mtxLocalCon);
}
}
}
else
{
Log(("VBOXSF: vbsfCreateConnection: bad format\n"));
Status = STATUS_BAD_NETWORK_NAME;
}
}
return Status;
}
NTSTATUS VBoxMRxQueryEaInfo(IN OUT PRX_CONTEXT RxContext)
{
Log(("VBOXSF: MRxQueryEaInfo: Ea buffer len remaining is %d\n",
RxContext->Info.LengthRemaining));
return STATUS_SUCCESS;
}
NTSTATUS VBoxMRxSetEaInfo(IN OUT PRX_CONTEXT RxContext)
{
Log(("VBOXSF: MRxSetEaInfo\n"));
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS VBoxMRxFsCtl (IN OUT PRX_CONTEXT RxContext)
{
Log(("VBOXSF: MRxFsCtl\n"));
return STATUS_INVALID_DEVICE_REQUEST;
}
NTSTATUS VBoxMRxNotifyChangeDirectory(IN OUT PRX_CONTEXT RxContext)
{
Log(("VBOXSF: MRxNotifyChangeDirectory\n"));
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS VBoxMRxQuerySdInfo(IN OUT PRX_CONTEXT RxContext)
{
Log(("VBOXSF: MRxQuerySdInfo\n"));
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS VBoxMRxSetSdInfo(IN OUT struct _RX_CONTEXT * RxContext)
{
Log(("VBOXSF: MRxSetSdInfo\n"));
return STATUS_NOT_IMPLEMENTED;
}
/*
* WML stubs which are referenced by rdbsslib.
*/
NTSTATUS WmlTinySystemControl(IN OUT PVOID pWmiLibInfo, IN PVOID pDevObj, IN PVOID pIrp)
{
return STATUS_WMI_GUID_NOT_FOUND;
}
ULONG WmlTrace(IN ULONG ulType, IN PVOID pTraceUuid, IN ULONG64 ullLogger, ...)
{
return STATUS_SUCCESS;
}