init.c revision 78a072e1b56619e3230735ae073668311232ec94
/*++
Copyright (c) 1989 - 1999 Microsoft Corporation
Module Name:
Abstract:
This module implements the DRIVER_INITIALIZATION routine for
the null mini rdr.
--*/
#include "precomp.h"
#include "rdbss_vbox.h"
#pragma hdrstop
#include "ntverp.h"
#include "nulmrx.h"
#ifdef VBOX
#include "VBoxGuestR0LibSharedFolders.h"
#if defined(DEBUG) || defined (LOG_ENABLED)
#endif
#endif
//
// Global data declarations.
//
//
// Mini Redirector global variables.
//
//
// LogRate
//
//
// This is the minirdr dispatch table. It is initialized by
// VBoxMRxInitializeTables. This table will be used by the wrapper to call
// into this minirdr
//
struct _MINIRDR_DISPATCH VBoxMRxDispatch;
//
// Pointer to the device Object for this minirdr. Since the device object is
// created by the wrapper when this minirdr registers, this pointer is
// initialized in the DriverEntry routine below (see RxRegisterMinirdr)
//
#define VBOX_SF_STATIC_LIB
//
// declare the shadow debugtrace controlpoints
//
//
// The following enumerated values signify the current state of the minirdr
// initialization. With the aid of this state information, it is possible
// to determine which resources to deallocate, whether deallocation comes
//
typedef enum _MRX_VBOX_INIT_STATES
{
MRX_VBOXINIT_UNINT, MRX_VBOXINIT_ALL_INITIALIZATION_COMPLETED, MRX_VBOXINIT_MINIRDR_REGISTERED, MRX_VBOXINIT_START
//
// function prototypes
//
NTSTATUS VBoxMRxInitializeTables (void);
#ifdef VBOX
static int
{
int rc;
if (RT_FAILURE (rc))
{
Log (("VBOXSF: vboxCtlGuestFilterMask: "
"VbglGRAlloc (CtlGuestFilterMask) failed rc=%Rrc\n", rc));
return -1;
}
if (RT_FAILURE (rc))
{
Log (("VBOXSF: vboxCtlGuestFilterMask: "
"VbglGRPerform (CtlGuestFilterMask) failed rc=%Rrc\n", rc));
return -1;
}
return 0;
}
#endif
BOOLEAN VBoxMrxFastIoRead (IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus,
{
#ifdef VBOX_FAIL_FASTIO
Log(("VBOXSF: VBoxMrxFastIoRead\n"));
IoStatus->Information = 0;
return FALSE;
#else
Log(("VBOXSF: VBoxMrxFastIoRead: FileObject = 0x%x, QuadPart = %RX64, Len = %d, Buffer = 0x%x\n", FileObject, FileOffset->QuadPart, Length, Buffer));
{
/* Necessary to satisfy the driver verifier. APCs must be turned off when ExAcquireResourceExclusiveLite is called */
ret = pfnRDBSSTable->FastIoRead(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject);
}
return ret;
#endif /* !VBOX_FAIL_FASTIO */
}
BOOLEAN VBoxMrxFastIoWrite (IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus,
{
#ifdef VBOX_FAIL_FASTIO
Log(("VBOXSF: VBoxMrxFastIoWrite\n"));
IoStatus->Information = 0;
return FALSE;
#else
Log(("VBOXSF: VBoxMrxFastIoWrite: FileObject = 0x%x, QuadPart = %RX64, Len = %d, Buffer = 0x%x\n", FileObject, FileOffset->QuadPart, Length, Buffer));
{
/* Necessary to satisfy the driver verifier. APCs must be turned off when ExAcquireResourceExclusiveLite is called */
ret = pfnRDBSSTable->FastIoWrite(FileObject, FileOffset, Length, Wait, LockKey, Buffer, IoStatus, DeviceObject);
}
return ret;
#endif /* !VBOX_FAIL_FASTIO */
}
BOOLEAN VBoxMrxFastIoCheckIfPossible (IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN BOOLEAN CheckForReadOperation,
{
{
ret = pfnRDBSSTable->FastIoCheckIfPossible(FileObject, FileOffset, Length, Wait, LockKey, CheckForReadOperation, IoStatus, DeviceObject);
}
return ret;
}
BOOLEAN VBoxMrxFastIoQueryBasicInfo (IN struct _FILE_OBJECT *FileObject, IN BOOLEAN Wait, OUT PFILE_BASIC_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject)
{
{
}
return ret;
}
BOOLEAN VBoxMrxFastIoQueryStandardInfo (IN struct _FILE_OBJECT *FileObject, IN BOOLEAN Wait, OUT PFILE_STANDARD_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus,
{
{
}
return ret;
}
BOOLEAN VBoxMrxFastIoLock (IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, BOOLEAN FailImmediately, BOOLEAN ExclusiveLock,
{
{
ret = pfnRDBSSTable->FastIoLock(FileObject, FileOffset, Length, ProcessId, Key, FailImmediately, ExclusiveLock, IoStatus, DeviceObject);
}
return ret;
}
BOOLEAN VBoxMrxFastIoUnlockSingle (IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus,
{
{
ret = pfnRDBSSTable->FastIoUnlockSingle(FileObject, FileOffset, Length, ProcessId, Key, IoStatus, DeviceObject);
}
return ret;
}
BOOLEAN VBoxMrxFastIoUnlockAll (IN struct _FILE_OBJECT *FileObject, PEPROCESS ProcessId, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject)
{
{
}
return ret;
}
BOOLEAN VBoxMrxFastIoUnlockAllByKey (IN struct _FILE_OBJECT *FileObject, PVOID ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN struct _DEVICE_OBJECT *DeviceObject)
{
{
}
return ret;
}
BOOLEAN VBoxMrxFastIoDeviceControl (IN struct _FILE_OBJECT *FileObject, IN BOOLEAN Wait, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength,
{
{
ret = pfnRDBSSTable->FastIoDeviceControl(FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, IoStatus, DeviceObject);
}
return ret;
}
{
{
Log(("VBOXSF: VBoxMrxAcquireFileForNtCreateSection: Called.\n"));
}
}
{
{
Log(("VBOXSF: VBoxMrxReleaseFileForNtCreateSection: Called.\n"));
}
}
VOID VBoxMrxFastIoDetachDevice (IN struct _DEVICE_OBJECT *SourceDevice, IN struct _DEVICE_OBJECT *TargetDevice)
{
{
Log(("VBOXSF: VBoxMrxFastIoDetachDevice: Called.\n"));
}
}
BOOLEAN VBoxMrxFastIoQueryNetworkOpenInfo (IN struct _FILE_OBJECT *FileObject, IN BOOLEAN Wait, OUT struct _FILE_NETWORK_OPEN_INFORMATION *Buffer, OUT struct _IO_STATUS_BLOCK *IoStatus,
{
{
Log(("VBOXSF: VBoxMrxFastIoQueryNetworkOpenInfo: Called.\n"));
}
return ret;
}
BOOLEAN VBoxMrxMdlRead (IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus,
{
{
ret = pfnRDBSSTable->MdlRead(FileObject, FileOffset, Length, LockKey, MdlChain, IoStatus, DeviceObject);
}
return ret;
}
BOOLEAN VBoxMrxMdlReadComplete (IN struct _FILE_OBJECT *FileObject, IN PMDL MdlChain, IN struct _DEVICE_OBJECT *DeviceObject)
{
{
}
return ret;
}
BOOLEAN VBoxMrxPrepareMdlWrite (IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus,
{
{
ret = pfnRDBSSTable->PrepareMdlWrite(FileObject, FileOffset, Length, LockKey, MdlChain, IoStatus, DeviceObject);
}
return ret;
}
BOOLEAN VBoxMrxMdlWriteComplete (IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain, IN struct _DEVICE_OBJECT *DeviceObject)
{
{
}
return ret;
}
NTSTATUS VBoxMrxAcquireForModWrite (IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER EndingOffset, OUT struct _ERESOURCE **ResourceToRelease, IN struct _DEVICE_OBJECT *DeviceObject)
{
{
}
return ret;
}
NTSTATUS VBoxMrxReleaseForModWrite (IN struct _FILE_OBJECT *FileObject, IN struct _ERESOURCE *ResourceToRelease, IN struct _DEVICE_OBJECT *DeviceObject)
{
{
}
return ret;
}
NTSTATUS VBoxMrxAcquireForCcFlush (IN struct _FILE_OBJECT *FileObject, IN struct _DEVICE_OBJECT *DeviceObject)
{
{
}
return ret;
}
NTSTATUS VBoxMrxReleaseForCcFlush (IN struct _FILE_OBJECT *FileObject, IN struct _DEVICE_OBJECT *DeviceObject)
{
{
}
return ret;
}
BOOLEAN VBoxMrxFastIoReadCompressed (IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PVOID Buffer, OUT PMDL *MdlChain,
OUT PIO_STATUS_BLOCK IoStatus, OUT struct _COMPRESSED_DATA_INFO *CompressedDataInfo, IN ULONG CompressedDataInfoLength, IN struct _DEVICE_OBJECT *DeviceObject)
{
{
ret = pfnRDBSSTable->FastIoReadCompressed(FileObject, FileOffset, Length, LockKey, Buffer, MdlChain, IoStatus, CompressedDataInfo, CompressedDataInfoLength, DeviceObject);
}
return ret;
}
BOOLEAN VBoxMrxFastIoWriteCompressed (IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, IN PVOID Buffer, OUT PMDL *MdlChain,
OUT PIO_STATUS_BLOCK IoStatus, IN struct _COMPRESSED_DATA_INFO *CompressedDataInfo, IN ULONG CompressedDataInfoLength, IN struct _DEVICE_OBJECT *DeviceObject)
{
{
ret = pfnRDBSSTable->FastIoWriteCompressed(FileObject, FileOffset, Length, LockKey, Buffer, MdlChain, IoStatus, CompressedDataInfo, CompressedDataInfoLength, DeviceObject);
}
return ret;
}
BOOLEAN VBoxMrxMdlReadCompleteCompressed (IN struct _FILE_OBJECT *FileObject, IN PMDL MdlChain, IN struct _DEVICE_OBJECT *DeviceObject)
{
{
}
return ret;
}
BOOLEAN VBoxMrxMdlWriteCompleteCompressed (IN struct _FILE_OBJECT *FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain, IN struct _DEVICE_OBJECT *DeviceObject)
{
{
}
return ret;
}
BOOLEAN VBoxMrxFastIoQueryOpen (IN struct _IRP *Irp, OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation, IN struct _DEVICE_OBJECT *DeviceObject)
{
{
}
return ret;
}
static FAST_IO_DISPATCH dispatchTable =
{
sizeof(FAST_IO_DISPATCH),
};
{
/* The FilePathName here looks like: \vboxsrv\... */
{
/* Both vboxsvr & vboxsrv are now accepted */
{
}
else
{
}
{
/* There is something after '\vboxsrv'. */
}
}
else
{
}
return PrefixOK;
}
#if 0
{
/* Detect '\vboxsrv' */
{
}
if (!PathToIntercept)
{
/* Detect '\vboxsrv\ipc$' */
{
{
/* There is something after '\vboxsrv\IPC$'. */
}
}
}
return PathToIntercept;
}
#endif
{
/* Make a local copy, it will be needed after the Irp completion. */
PMRX_VBOX_DEVICE_EXTENSION pDeviceExtension = (PMRX_VBOX_DEVICE_EXTENSION)((PBYTE)pDevObj + sizeof(RDBSS_DEVICE_OBJECT));
Log(("VBoxSF::VBoxMRXDeviceControl: pDevObj %p, pDeviceExtension %p, code %x\n",
switch (IoControlCode)
{
case IOCTL_REDIR_QUERY_PATH_EX: /* Vista */
case IOCTL_REDIR_QUERY_PATH: /* XP and earlier */
{
/* This IOCTL is intercepted for 2 reasons:
* 1) Claim the vboxsvr and vboxsrv prefixes. All name-based operations for them
* will be routed to the VBox provider automatically without any prefix resolution
* since the prefix is already in the prefix cache.
* 2) Reject other prefixes immediately to speed up the UNC path resolution a bit,
* because RDBSS will not be involved then.
*/
ULONG PathNameLength = 0;
{
/* MSDN: Network redirectors should only honor kernel-mode senders of this IOCTL, by verifying
* that RequestorMode member of the IRP structure is KernelMode.
*/
Log(("VBOXSF: VBoxMRxDevFcbXXXControlFile: IOCTL_REDIR_QUERY_PATH(_EX): not kernel mode!!!\n",
/* Continue to RDBSS. */
break;
}
if (IoControlCode == IOCTL_REDIR_QUERY_PATH)
{
Log(("VBOXSF: VBoxMRxDevFcbXXXControlFile: IOCTL_REDIR_QUERY_PATH: Called (pid %x).\n", IoGetCurrentProcess()));
{
Log(("VBOXSF: VBoxMRxDevFcbXXXControlFile: IOCTL_REDIR_QUERY_PATH: short input buffer %d.\n",
/* Continue to RDBSS. */
break;
}
Log(("VBOXSF: VBoxMRxDevFcbXXXControlFile: FilePathName = %.*ls.\n", pReq->PathNameLength / sizeof (WCHAR), pReq->FilePathName));
}
else
{
Log(("VBOXSF: VBoxMRxDevFcbXXXControlFile: IOCTL_REDIR_QUERY_PATH_EX: Called.\n"));
{
Log(("VBOXSF: VBoxMRxDevFcbXXXControlFile: IOCTL_REDIR_QUERY_PATH_EX: short input buffer %d.\n",
/* Continue to RDBSS. */
break;
}
Log(("VBOXSF: VBoxMRxDevFcbXXXControlFile: FilePathName = %.*ls.\n", pReqEx->PathName.Length / sizeof (WCHAR), pReqEx->PathName.Buffer));
}
if (!PrefixOK)
{
/* Immediately fail the IOCTL with STATUS_BAD_NETWORK_NAME as recommended by MSDN.
* No need to involve RDBSS.
*/
Log(("VBoxSF::VBoxMRXDeviceControl: returned STATUS_BAD_NETWORK_NAME\n"));
return Status;
}
if (pResp)
{
/* Always claim entire \vboxsrv prefix. The LengthAccepted initially is equal to entire path.
* Here it is assigned to the length of \vboxsrv prefix.
*/
Log(("VBoxSF::VBoxMRXDeviceControl: claiming the path.\n"));
return Status;
}
/* No pResp pointer, should not happen. Just a precaution. */
Log(("VBoxSF::VBoxMRXDeviceControl: returned STATUS_INVALID_PARAMETER\n"));
return Status;
}
default:
break;
}
/* Pass the IOCTL to RDBSS. */
{
}
else
{
/* No RDBSS, should not happen. Just a precaution. */
Log(("VBoxSF::VBoxMRXDeviceControl: returned STATUS_NOT_IMPLEMENTED\n"));
}
return Status;
}
/*++
Routine Description:
This is the initialization routine for the mini redirector
Arguments:
DriverObject - Pointer to driver object created by the system.
Return Value:
RXSTATUS - The function value is the final status from the initialization
operation.
--*/
{
ULONG i;
#ifdef VBOX
int vboxRC;
{ 0};
#endif
#ifdef VBOX
/* Initialize VBox subsystem. */
if (RT_FAILURE(vboxRC))
{
return Status;
}
/* Set filter mask */
if (vboxCtlGuestFilterMask (VMMDEV_EVENT_HGCM, 0)) /** @todo r=bird: Why are we doing this? And more importantely, why are we clearing it further down. We're not the only HGCM user, are we? */
{
Log (("VBOXSF: DriverEntry: ERROR while setting guest event filter mask!\n"));
return STATUS_UNSUCCESSFUL;
}
/* Connect the HGCM client */
if (RT_FAILURE (vboxRC))
{
vboxUninit();
return Status;
}
#endif
if (DriverObject == NULL)
{
Log(("VBOXSF: DriverEntry: Invalid driver object detected!\n"));
vboxUninit();
return Status;
}
//
// Setup Unload Routine
//
//
//setup the driver dispatch for people who come in here directly....like the browser
//
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
}
#ifdef VBOX_SF_STATIC_LIB
if (Status != STATUS_SUCCESS)
{
goto failure;
}
#endif
{
//
// Register this minirdr with the connection engine. Registration makes the connection
// engine aware of the device name, driver object, and other characteristics.
// If registration is successful, a new device object is returned
//
//
/* don't set RX_REGISTERMINI_FLAG_DONT_PROVIDE_UNCS or else UNC mappings don't work (including Windows explorer browsing) */
/** @todo set RX_REGISTERMINI_FLAG_DONT_INIT_PREFIX_N_SCAVENGER and the system will crash on boot */
&VBoxMRxDeviceObject, // where the new device object goes
DriverObject, // the Driver Object to register
&VBoxMRxDispatch, // the dispatch table for this driver
Controls, // dont register with unc and for mailslots
&VBoxMRxName, // the device name for this minirdr
sizeof(MRX_VBOX_DEVICE_EXTENSION), // IN ULONG DeviceExtensionSize,
FILE_DEVICE_NETWORK_FILE_SYSTEM, // IN ULONG DeviceType - disk ?
FILE_REMOTE_DEVICE // IN ULONG DeviceCharacteristics
);
if (Status!=STATUS_SUCCESS)
{
}
//
// Init the device extension data
// NOTE: the device extension actually points to fields
// in the RDBSS_DEVICE_OBJECT. Our space is past the end
// of this struct !!
//
// initialize local connection list
{
}
// Mutex for synchronizining our connection list
// The device object has been created. Need to setup a symbolic
// link so that the device may be accessed from a Win32 user mode
// application.
Log(("VBOXSF: DriverEntry: Calling IoCreateSymbolicLink ...\n"));
if (Status != STATUS_SUCCESS)
{
}
Log(("VBOXSF: DriverEntry: Symbolic link created.\n"));
//
// Build the dispatch tables for the minirdr
//
if (!NT_SUCCESS( Status ))
{
}
//
// Get information from the registry
//
Log(("VBOXSF: VBoxMRxDriverEntry: First phase done!\n"));
}
{
if (Status != STATUS_SUCCESS)
{
}
}
if (Status != STATUS_SUCCESS)
{
Log(("VBOXSF: VBoxMRxDriverEntry: VBoxSF.sys failed to start with Status = 0x%08lx, VBoxMRxInitState = 0x%08lx\n", Status, VBoxMRxInitState));
goto failure;
}
#ifdef VBOX
#endif
Log(("VBOXSF: VBoxMRxDriverEntry: FastIoDispatch address = 0x%x, DriverStartIo address = 0x%x\n", DriverObject->FastIoDispatch, DriverObject->DriverStartIo));
/* Wrap the fast io path */
if (DriverObject->FastIoDispatch)
{
Log(("VBOXSF: VBoxMRxDriverEntry: SizeOfFastIoDispatch = 0x%x (expected = 0x%x)\n", DriverObject->FastIoDispatch->SizeOfFastIoDispatch, sizeof(dispatchTable)));
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: FastIoCheckIfPossible == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: FastIoRead == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: FastIoWrite == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: FastIoQueryBasicInfo == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: FastIoQueryStandardInfo == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: FastIoLock == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: FastIoUnlockSingle == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: FastIoUnlockAll == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: FastIoUnlockAllByKey == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: FastIoDeviceControl == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: AcquireFileForNtCreateSection == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: ReleaseFileForNtCreateSection == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: FastIoDetachDevice == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: FastIoQueryNetworkOpenInfo == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: AcquireForModWrite == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: MdlRead == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: MdlReadComplete == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: PrepareMdlWrite == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: MdlWriteComplete == NULL\n"));
}
{
Log(("VVBOXSF: VBoxMRxDriverEntry: Function Table: FastIoReadCompressed == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: FastIoWriteCompressed == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: MdlReadCompleteCompressed == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: MdlWriteCompleteCompressed == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: FastIoQueryOpen == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: ReleaseForModWrite == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: AcquireForCcFlush == NULL\n"));
}
{
Log(("VBOXSF: VBoxMRxDriverEntry: Function Table: ReleaseForCcFlush == NULL\n"));
}
}
/* The redirector driver must intercept the IOCTL to avoid VBOXSVR name resolution
* by other redirectors. These additional name resolutions cause long delays.
*/
Log(("VBOXSF: VBoxMRxDriverEntry: VBoxMRxDeviceObject = %p, rdbss %p, devext %p\n",
Log(("VBOXSF: VBoxMRxDriverEntry: Init successful!\n"));
return STATUS_SUCCESS;
#ifdef VBOX
vboxUninit();
#endif
return Status;
}
/*++
Routine Description:
This routine does the common uninit work for unwinding from a bad driver entry or for unloading.
Arguments:
VBoxMRxInitState - tells how far we got into the intialization
Return Value:
None
--*/
{
PAGED_CODE();
switch (VBoxMRxInitState)
{
//Nothing extra to do...this is just so that the constant in RxUnload doesn't change.......
//lack of break intentional
//lack of break intentional
case MRX_VBOXINIT_START:
break;
}
}
/*++
Routine Description:
This is the unload routine for the Exchange mini redirector.
Arguments:
DriverObject - pointer to the driver object for the VBoxMRx
Return Value:
None
--*/
{
PAGED_CODE();
Log(("VBOXSF: VBoxMRxUnload: Called.\n"));
#ifdef VBOX
vboxUninit ();
#endif
{
if (Status == STATUS_SUCCESS)
{
State = (MRX_VBOX_STATE)InterlockedCompareExchange((LONG *)&VBoxMRxState, MRX_VBOX_STARTABLE, MRX_VBOX_STARTED);
if (State != MRX_VBOX_STARTABLE)
{
}
}
}
else
{
}
if (Status != STATUS_SUCCESS)
{
Log(("VBOXSF: VBoxMRxUnload: Could not delete symbolic link!\n"));
}
#ifdef VBOX_SF_STATIC_LIB
#endif
}
NTSTATUS VBoxMRxInitializeTables (void)
/*++
Routine Description:
This routine sets up the mini redirector dispatch vector and also calls
to initialize any other tables needed.
Return Value:
RXSTATUS - The return status for the operation
--*/
{
Log(("VBOXSF: VBoxMRxInitializeTables: Called.\n"));
//
// Ensure that the Exchange mini redirector context satisfies the size constraints
//
//ASSERT(sizeof(MRX_VBOX_RX_CONTEXT) <= MRX_CONTEXT_SIZE);
//
// Build the local minirdr dispatch table and initialize
//
//
// null mini redirector extension sizes and allocation policies.
//
// Mini redirector cancel routine ..
//
// while the others continue to operate.
//
//
// Mini redirector name resolution.
//
//
//
//
//
//
// Buffering state change
//
//
// File System Object I/O
//
//
// Miscellanous
//
VBoxMRxDispatch.MRxCompleteBufferingStateChangeRequest = VBoxMRxCompleteBufferingStateChangeRequest;
Log(("VBOXSF: VBoxMRxInitializeTables: Success.\n"));
return (STATUS_SUCCESS);
}
/*++
Routine Description:
This routine completes the initialization of the mini redirector fromn the
RDBSS perspective. Note that this is different from the initialization done
in DriverEntry. Any initialization that depends on RDBSS should be done as
part of this routine while the initialization that is independent of RDBSS
should be done in the DriverEntry routine.
Arguments:
RxContext - Supplies the Irp that was used to startup the rdbss
Return Value:
RXSTATUS - The return status for the operation
--*/
{
Log(("VBOXSF: VBoxMRxStart: Called.\n"));
CurrentState = (MRX_VBOX_STATE)InterlockedCompareExchange((PLONG) & VBoxMRxState, MRX_VBOX_STARTED, MRX_VBOX_START_IN_PROGRESS);
{
Log(("VBOXSF: VBoxMRxStart: Start in progress -> started\n"));
}
else if (VBoxMRxState == MRX_VBOX_STARTED)
{
Log(("VBOXSF: VBoxMRxStart: Already started!\n"));
}
else
{
}
return Status;
}
/*++
Routine Description:
This routine is used to activate the mini redirector from the RDBSS perspective
Arguments:
RxContext - the context that was used to start the mini redirector
pContext - the null mini rdr context passed in at registration time.
Return Value:
RXSTATUS - The return status for the operation
--*/
{
Log(("VBOXSF: VBoxMRxStop: Called.\n"));
return (STATUS_SUCCESS);
}
/*++
Routine Description:
This routine initializes the null miniredirector security .
Arguments:
None.
Return Value:
None.
Note:
This API can only be called from a FS process.
--*/
{
Log(("VBOXSF: VBoxMRxInitializeSecurity: Called.\n"));
return Status;
}
/*++
Routine Description:
Arguments:
None.
Return Value:
None.
Note:
This API can only be called from a FS process.
--*/
{
PAGED_CODE();
Log(("VBOXSF: VBoxMRxUninitializeSecurity: Called.\n"));
return Status;
}
/*++
Routine Description:
This routine implements the FSD dispatch for the mini DRIVER object.
Arguments:
DeviceObject - Supplies the device object for the packet being processed.
Irp - Supplies the Irp being processed
Return Value:
RXSTATUS - The Fsd status for the Irp
--*/
{
Log(("VBOXSF: VBoxMRxFsdDispatch: Called.\n"));
{
Log(("VBOXSF: VBoxMRxFsdDispatch: Invalid device request detected, this in no error!\n"));
return STATUS_INVALID_DEVICE_REQUEST;
}
return Status;
}
NTSTATUS VBoxMRxGetUlongRegistryParameter (HANDLE ParametersHandle, PWCHAR ParameterName, PULONG ParamUlong, BOOLEAN LogFailure)
/*++
Routine Description:
This routine is called to read a ULONG param from t he registry.
Arguments:
ParametersHandle - the handle of the containing registry "folder"
ParameterName - name of the parameter to be read
ParamUlong - where to store the value, if successful
LogFailure - if TRUE and the registry stuff fails, log an error
Return Value:
RXSTATUS - STATUS_SUCCESS
--*/
{
PAGED_CODE(); //INIT
Log(("VBOXSF: VBoxMRxGetUlongRegistryParameter: Called.\n"));
Status = ZwQueryValueKey(ParametersHandle, &UnicodeString, KeyValuePartialInformation, Value, ValueSize, &BytesRead);
if (NT_SUCCESS(Status))
{
{
Log(("BOXSF: VBoxMRxGetUlongRegistryParameter: Read registry value %.*ls = 0x%08lx\n", UnicodeString.Length / sizeof(WCHAR), UnicodeString.Buffer, *ParamUlong));
return (STATUS_SUCCESS);
}
else
{
}
}
if (LogFailure)
Log(("VBOXSF: VBoxMRxGetUlongRegistryParameter: Failure!\n"));
return Status;
}
{
Log(("VBOXSF: VBoxMRxReadRegistryParameters: Called.\n"));
InitializeObjectAttributes(&ObjectAttributes, &ParametersRegistryKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL
);
if (!NT_SUCCESS(Status))
{
);
}
}
#if defined(DEBUG) || defined (LOG_ENABLED)
{
switch (MinorFunction)
{
case IRP_MN_START_DEVICE:
return "IRP_MJ_PNP - IRP_MN_START_DEVICE";
return "IRP_MJ_PNP - IRP_MN_QUERY_REMOVE_DEVICE";
case IRP_MN_REMOVE_DEVICE:
return "IRP_MJ_PNP - IRP_MN_REMOVE_DEVICE";
return "IRP_MJ_PNP - IRP_MN_CANCEL_REMOVE_DEVICE";
case IRP_MN_STOP_DEVICE:
return "IRP_MJ_PNP - IRP_MN_STOP_DEVICE";
case IRP_MN_QUERY_STOP_DEVICE:
return "IRP_MJ_PNP - IRP_MN_QUERY_STOP_DEVICE";
return "IRP_MJ_PNP - IRP_MN_CANCEL_STOP_DEVICE";
return "IRP_MJ_PNP - IRP_MN_QUERY_DEVICE_RELATIONS";
case IRP_MN_QUERY_INTERFACE:
return "IRP_MJ_PNP - IRP_MN_QUERY_INTERFACE";
return "IRP_MJ_PNP - IRP_MN_QUERY_CAPABILITIES";
case IRP_MN_QUERY_RESOURCES:
return "IRP_MJ_PNP - IRP_MN_QUERY_RESOURCES";
return "IRP_MJ_PNP - IRP_MN_QUERY_RESOURCE_REQUIREMENTS";
case IRP_MN_QUERY_DEVICE_TEXT:
return "IRP_MJ_PNP - IRP_MN_QUERY_DEVICE_TEXT";
return "IRP_MJ_PNP - IRP_MN_FILTER_RESOURCE_REQUIREMENTS";
case IRP_MN_READ_CONFIG:
return "IRP_MJ_PNP - IRP_MN_READ_CONFIG";
case IRP_MN_WRITE_CONFIG:
return "IRP_MJ_PNP - IRP_MN_WRITE_CONFIG";
case IRP_MN_EJECT:
return "IRP_MJ_PNP - IRP_MN_EJECT";
case IRP_MN_SET_LOCK:
return "IRP_MJ_PNP - IRP_MN_SET_LOCK";
case IRP_MN_QUERY_ID:
return "IRP_MJ_PNP - IRP_MN_QUERY_ID";
return "IRP_MJ_PNP - IRP_MN_QUERY_PNP_DEVICE_STATE";
return "IRP_MJ_PNP - IRP_MN_QUERY_BUS_INFORMATION";
return "IRP_MJ_PNP - IRP_MN_DEVICE_USAGE_NOTIFICATION";
case IRP_MN_SURPRISE_REMOVAL:
return "IRP_MJ_PNP - IRP_MN_SURPRISE_REMOVAL";
default:
return "IRP_MJ_PNP - unknown_pnp_irp";
}
}
{
switch (MinorFunction)
{
case IRP_MJ_CREATE:
return "IRP_MJ_CREATE";
case IRP_MJ_CREATE_NAMED_PIPE:
return "IRP_MJ_CREATE_NAMED_PIPE";
case IRP_MJ_CLOSE:
return "IRP_MJ_CLOSE";
case IRP_MJ_READ:
return "IRP_MJ_READ";
case IRP_MJ_WRITE:
return "IRP_MJ_WRITE";
case IRP_MJ_QUERY_INFORMATION:
return "IRP_MJ_QUERY_INFORMATION";
case IRP_MJ_SET_INFORMATION:
return "IRP_MJ_SET_INFORMATION";
case IRP_MJ_QUERY_EA:
return "IRP_MJ_QUERY_EA";
case IRP_MJ_SET_EA:
return "IRP_MJ_SET_EA";
case IRP_MJ_FLUSH_BUFFERS:
return "IRP_MJ_FLUSH_BUFFERS";
return "IRP_MJ_QUERY_VOLUME_INFORMATION";
return "IRP_MJ_SET_VOLUME_INFORMATION";
case IRP_MJ_DIRECTORY_CONTROL:
return "IRP_MJ_DIRECTORY_CONTROL";
return "IRP_MJ_FILE_SYSTEM_CONTROL";
case IRP_MJ_DEVICE_CONTROL:
return "IRP_MJ_DEVICE_CONTROL";
return "IRP_MJ_INTERNAL_DEVICE_CONTROL";
case IRP_MJ_SHUTDOWN:
return "IRP_MJ_SHUTDOWN";
case IRP_MJ_LOCK_CONTROL:
return "IRP_MJ_LOCK_CONTROL";
case IRP_MJ_CLEANUP:
return "IRP_MJ_CLEANUP";
case IRP_MJ_CREATE_MAILSLOT:
return "IRP_MJ_CREATE_MAILSLOT";
case IRP_MJ_QUERY_SECURITY:
return "IRP_MJ_QUERY_SECURITY";
case IRP_MJ_SET_SECURITY:
return "IRP_MJ_SET_SECURITY";
case IRP_MJ_POWER:
return "IRP_MJ_POWER";
case IRP_MJ_SYSTEM_CONTROL:
return "IRP_MJ_SYSTEM_CONTROL";
case IRP_MJ_DEVICE_CHANGE:
return "IRP_MJ_DEVICE_CHANGE";
case IRP_MJ_QUERY_QUOTA:
return "IRP_MJ_QUERY_QUOTA";
case IRP_MJ_SET_QUOTA:
return "IRP_MJ_SET_QUOTA";
case IRP_MJ_PNP:
return PnPMinorFunctionString(MinorFunction);
default:
return "unknown_pnp_irp";
}
}
#endif