868 lines
25 KiB
C
868 lines
25 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1989 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
Init.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module implements the DRIVER_INITIALIZATION routine for the PROXY mini rdr.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Balan Sethu Raman [SethuR] 7-Mar-1995
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "precomp.h"
|
|||
|
#pragma hdrstop
|
|||
|
#include "ntverp.h"
|
|||
|
#include "netevent.h"
|
|||
|
#include "nvisible.h"
|
|||
|
|
|||
|
#define RDBSS_DRIVER_LOAD_STRING L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Rdbss"
|
|||
|
NTSYSAPI
|
|||
|
NTSTATUS
|
|||
|
NTAPI
|
|||
|
ZwLoadDriver(
|
|||
|
IN PUNICODE_STRING DriverServiceName
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// Global data declarations . CODE.IMPROVEMENT why are these placed here!!
|
|||
|
//
|
|||
|
|
|||
|
PEPROCESS MRxProxySystemProcess;
|
|||
|
|
|||
|
FAST_MUTEX MRxProxySerializationMutex;
|
|||
|
KIRQL MRxProxyGlobalSpinLockSavedIrql;
|
|||
|
KSPIN_LOCK MRxProxyGlobalSpinLock;
|
|||
|
BOOLEAN MRxProxyGlobalSpinLockAcquired;
|
|||
|
|
|||
|
#ifdef EXPLODE_POOLTAGS
|
|||
|
ULONG MRxProxyExplodePoolTags = 1;
|
|||
|
#else
|
|||
|
ULONG MRxProxyExplodePoolTags = 0;
|
|||
|
#endif
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
MRxProxyInitializeTables(
|
|||
|
void
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
ProxyCeGetConfigurationInformation (
|
|||
|
void
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
MRxProxyUnload(
|
|||
|
IN PDRIVER_OBJECT DriverObject
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
MRxProxyGetUlongRegistryParameter(
|
|||
|
HANDLE ParametersHandle,
|
|||
|
PWCHAR ParameterName,
|
|||
|
PULONG ParamUlong,
|
|||
|
BOOLEAN LogFailure
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// Mini Redirector global variables.
|
|||
|
//
|
|||
|
|
|||
|
struct _MINIRDR_DISPATCH MRxProxyDispatch;
|
|||
|
|
|||
|
PMRXPROXY_DEVICE_OBJECT MRxProxyDeviceObject;
|
|||
|
|
|||
|
ULONG MRxProxyBuildNumber = VER_PRODUCTBUILD;
|
|||
|
#ifdef RX_PRIVATE_BUILD
|
|||
|
ULONG MRxProxyPrivateBuild = 1;
|
|||
|
#else
|
|||
|
ULONG MRxProxyPrivateBuild = 0;
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
//declare the shadow debugtrace controlpoints
|
|||
|
|
|||
|
RXDT_DefineCategory(CREATE);
|
|||
|
RXDT_DefineCategory(CLEANUP);
|
|||
|
RXDT_DefineCategory(CLOSE);
|
|||
|
RXDT_DefineCategory(READ);
|
|||
|
RXDT_DefineCategory(WRITE);
|
|||
|
RXDT_DefineCategory(LOCKCTRL);
|
|||
|
RXDT_DefineCategory(FLUSH);
|
|||
|
RXDT_DefineCategory(PREFIX);
|
|||
|
RXDT_DefineCategory(FCBSTRUCTS);
|
|||
|
RXDT_DefineCategory(DISPATCH);
|
|||
|
RXDT_DefineCategory(EA);
|
|||
|
RXDT_DefineCategory(DEVFCB);
|
|||
|
|
|||
|
|
|||
|
typedef enum _MRXPROXY_INIT_STATES {
|
|||
|
MRXPROXYINIT_ALL_INITIALIZATION_COMPLETED,
|
|||
|
MRXPROXYINIT_MINIRDR_REGISTERED,
|
|||
|
MRXPROXYINIT_START
|
|||
|
} MRXPROXY_INIT_STATES;
|
|||
|
|
|||
|
VOID
|
|||
|
MRxProxyInitUnwind(
|
|||
|
IN PDRIVER_OBJECT DriverObject,
|
|||
|
IN MRXPROXY_INIT_STATES MRxProxyInitState
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
MRxProxyFsdDispatch (
|
|||
|
IN PDEVICE_OBJECT DeviceObject,
|
|||
|
IN PIRP Irp
|
|||
|
);
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
DriverEntry(
|
|||
|
IN PDRIVER_OBJECT DriverObject,
|
|||
|
IN PUNICODE_STRING RegistryPath
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This is the initialization routine for the PROXY 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.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NTSTATUS Status;
|
|||
|
//UNICODE_STRING MRxProxyRdbssDriverLoadString;
|
|||
|
MRXPROXY_INIT_STATES MRxProxyInitState = 0;
|
|||
|
UNICODE_STRING ProxyMiniRedirectorName;
|
|||
|
|
|||
|
|
|||
|
#ifdef MONOLITHIC_MINIRDR
|
|||
|
DbgPrint("InitWrapper\n");
|
|||
|
Status = RxDriverEntry(DriverObject, RegistryPath);
|
|||
|
DbgPrint("BackFromInitWrapper %08lx\n",Status);
|
|||
|
if (Status != STATUS_SUCCESS) {
|
|||
|
DbgPrint("Wrapper failed to initialize. Status = %08lx\n",Status);
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
MRxProxySystemProcess = RxGetRDBSSProcess();
|
|||
|
|
|||
|
MRxProxyInitializeLoudStrings();
|
|||
|
|
|||
|
ExInitializeFastMutex(&MRxProxySerializationMutex);
|
|||
|
KeInitializeSpinLock(&MRxProxyGlobalSpinLock );
|
|||
|
MRxProxyGlobalSpinLockAcquired = FALSE;
|
|||
|
|
|||
|
try {
|
|||
|
|
|||
|
MRxProxyInitState = MRXPROXYINIT_START;
|
|||
|
|
|||
|
RtlInitUnicodeString(&ProxyMiniRedirectorName,MRXPROXY_DEVICE_NAME_U);
|
|||
|
RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("MRxProxyDriverEntry: DriverObject =%08lx\n", DriverObject ));
|
|||
|
|
|||
|
Status = RxRegisterMinirdr((PRDBSS_DEVICE_OBJECT *)(&MRxProxyDeviceObject),
|
|||
|
DriverObject,
|
|||
|
&MRxProxyDispatch,
|
|||
|
FALSE,FALSE, //don't register with unc and for mailslots
|
|||
|
&ProxyMiniRedirectorName,
|
|||
|
sizeof(MRXPROXY_DEVICE_OBJECT) - sizeof(RDBSS_DEVICE_OBJECT), //IN ULONG DeviceExtensionSize,
|
|||
|
0 //IN ULONG DeviceCharacteristics
|
|||
|
);
|
|||
|
if (Status!=STATUS_SUCCESS) {
|
|||
|
RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("MRxProxyDriverEntry failed: %08lx\n", Status ));
|
|||
|
try_return(Status);
|
|||
|
}
|
|||
|
MRxProxyInitState = MRXPROXYINIT_MINIRDR_REGISTERED;
|
|||
|
MRxProxyDeviceObject->SectorSize = 512; //BUGBUG go find out
|
|||
|
RtlInitUnicodeString(&MRxProxyDeviceObject->InnerPrefixForOpens,
|
|||
|
MRXPROXY_INNERPREFIX_FOR_OPENS
|
|||
|
);
|
|||
|
RtlInitUnicodeString(&MRxProxyDeviceObject->PrefixForRename,
|
|||
|
MRXPROXY_INNERPREFIX_FOR_OPENS
|
|||
|
//MRXPROXY_PREFIX_FOR_RENAME
|
|||
|
);
|
|||
|
|
|||
|
//for all this stuff, there's no undo.....so no extra state
|
|||
|
|
|||
|
Status = MRxProxyInitializeTables();
|
|||
|
if (!NT_SUCCESS( Status )) {
|
|||
|
try_return(Status);
|
|||
|
}
|
|||
|
|
|||
|
Status = ProxyCeGetConfigurationInformation();
|
|||
|
if (!NT_SUCCESS( Status )) {
|
|||
|
try_return(Status);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
try_exit: NOTHING;
|
|||
|
} finally {
|
|||
|
if (Status != STATUS_SUCCESS) {
|
|||
|
MRxProxyInitUnwind(DriverObject,MRxProxyInitState);
|
|||
|
}
|
|||
|
}
|
|||
|
if (Status != STATUS_SUCCESS) {
|
|||
|
DbgPrint("MRxProxy failed to start with %08lx %08lx\n",Status,MRxProxyInitState);
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Setup Unload Routine
|
|||
|
DriverObject->DriverUnload = MRxProxyUnload;
|
|||
|
|
|||
|
//setup the driverdispatch for people who come in here directly....like the browser
|
|||
|
//CODE.IMPROVEMENT we should change this code so that the things that aren't examined
|
|||
|
// in MRxProxyFsdDispatch are routed directly, i.e. reads and writes
|
|||
|
{ULONG i;
|
|||
|
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) {
|
|||
|
DriverObject->MajorFunction[i] = (PDRIVER_DISPATCH)MRxProxyFsdDispatch;
|
|||
|
}}
|
|||
|
|
|||
|
//and get out
|
|||
|
return STATUS_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
MRxProxyInitUnwind(
|
|||
|
IN PDRIVER_OBJECT DriverObject,
|
|||
|
IN MRXPROXY_INIT_STATES MRxProxyInitState
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine does the common uninit work for unwinding from a bad driver entry or for unloading.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
RxInitState - tells how far we got into the intialization
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PAGED_CODE();
|
|||
|
|
|||
|
switch (MRxProxyInitState) {
|
|||
|
case MRXPROXYINIT_ALL_INITIALIZATION_COMPLETED:
|
|||
|
//Nothing extra to do...this is just so that the constant in RxUnload doesn't change.......
|
|||
|
//lack of break intentional
|
|||
|
|
|||
|
|
|||
|
case MRXPROXYINIT_MINIRDR_REGISTERED:
|
|||
|
RxUnregisterMinirdr(&MRxProxyDeviceObject->RxDeviceObject);
|
|||
|
//lack of break intentional
|
|||
|
|
|||
|
case MRXPROXYINIT_START:
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
MRxProxyUnload(
|
|||
|
IN PDRIVER_OBJECT DriverObject
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This is the unload routine for the PROXY mini redirector.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DriverObject - pointer to the driver object for the MRxProxy
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PAGED_CODE();
|
|||
|
RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("MRxProxyUnload: DriverObject =%08lx\n", DriverObject) );
|
|||
|
//ASSERT(!"Starting to unload!");
|
|||
|
//RxUnregisterMinirdr(MRxProxyDeviceObject);
|
|||
|
MRxProxyInitUnwind(DriverObject,MRXPROXYINIT_ALL_INITIALIZATION_COMPLETED);
|
|||
|
|
|||
|
#ifdef MONOLITHIC_MINIRDR
|
|||
|
RxUnload(DriverObject);
|
|||
|
#endif
|
|||
|
|
|||
|
RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("MRxProxyUnload exit: DriverObject =%08lx\n", DriverObject) );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
MRxProxyInitializeTables(
|
|||
|
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
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
// Ensure that the PROXY mini redirector context satisfies the size constraints
|
|||
|
ASSERT(sizeof(MRXPROXY_RX_CONTEXT) <= MRX_CONTEXT_SIZE);
|
|||
|
|
|||
|
//local minirdr dispatch table init
|
|||
|
ZeroAndInitializeNodeType( &MRxProxyDispatch, RDBSS_NTC_MINIRDR_DISPATCH, sizeof(MINIRDR_DISPATCH));
|
|||
|
|
|||
|
// PROXY mini redirector extension sizes and allocation policies.
|
|||
|
// CODE.IMPROVEMENT -- currently we do not allocate the NET_ROOT and SRV_CALL extensions
|
|||
|
// in the wrapper. Except for V_NET_ROOT wherein it is shared across multiple instances in
|
|||
|
// the wrapper all the other data structure management should be left to the wrappers
|
|||
|
|
|||
|
MRxProxyDispatch.MRxFlags = (RDBSS_MANAGE_FCB_EXTENSION |
|
|||
|
RDBSS_MANAGE_SRV_OPEN_EXTENSION |
|
|||
|
RDBSS_MANAGE_FOBX_EXTENSION);
|
|||
|
|
|||
|
MRxProxyDispatch.MRxSrvCallSize = 0;
|
|||
|
MRxProxyDispatch.MRxNetRootSize = 0;
|
|||
|
MRxProxyDispatch.MRxVNetRootSize = 0;
|
|||
|
MRxProxyDispatch.MRxFcbSize = sizeof(MRX_PROXY_FCB);
|
|||
|
MRxProxyDispatch.MRxSrvOpenSize = sizeof(MRX_PROXY_SRV_OPEN);
|
|||
|
MRxProxyDispatch.MRxFobxSize = sizeof(MRX_PROXY_FOBX);
|
|||
|
|
|||
|
// // Transport update handler
|
|||
|
// MRxProxyDispatch.MRxTransportUpdateHandler = MRxProxyTransportUpdateHandler;
|
|||
|
|
|||
|
// Mini redirector cancel routine ..
|
|||
|
MRxProxyDispatch.MRxCancel = NULL;
|
|||
|
|
|||
|
// Mini redirector Start/Stop
|
|||
|
MRxProxyDispatch.MRxStart = MRxProxyStart;
|
|||
|
MRxProxyDispatch.MRxStop = MRxProxyStop;
|
|||
|
//MRxProxyDispatch.MRxMinirdrControl = MRxProxyMinirdrControl; //now we have no way to readch this BUGBUG
|
|||
|
MRxProxyDispatch.MRxDevFcbXXXControlFile = MRxProxyDevFcbXXXControlFile;
|
|||
|
|
|||
|
// Mini redirector name resolution
|
|||
|
MRxProxyDispatch.MRxCreateSrvCall = MRxProxyCreateSrvCall;
|
|||
|
MRxProxyDispatch.MRxSrvCallWinnerNotify = MRxProxySrvCallWinnerNotify;
|
|||
|
MRxProxyDispatch.MRxCreateVNetRoot = MRxProxyCreateVNetRoot;
|
|||
|
MRxProxyDispatch.MRxUpdateNetRootState = MRxProxyUpdateNetRootState;
|
|||
|
MRxProxyDispatch.MRxExtractNetRootName = MRxProxyExtractNetRootName;
|
|||
|
MRxProxyDispatch.MRxFinalizeSrvCall = MRxProxyFinalizeSrvCall;
|
|||
|
MRxProxyDispatch.MRxFinalizeNetRoot = MRxProxyFinalizeNetRoot;
|
|||
|
MRxProxyDispatch.MRxFinalizeVNetRoot = MRxProxyFinalizeVNetRoot;
|
|||
|
|
|||
|
// File System Object Creation/Deletion.
|
|||
|
MRxProxyDispatch.MRxCreate = MRxProxyCreate;
|
|||
|
MRxProxyDispatch.MRxCollapseOpen = MRxProxyCollapseOpen;
|
|||
|
MRxProxyDispatch.MRxShouldTryToCollapseThisOpen = MRxProxyShouldTryToCollapseThisOpen;
|
|||
|
MRxProxyDispatch.MRxExtendForCache = MRxProxyExtendForCache;
|
|||
|
MRxProxyDispatch.MRxExtendForNonCache = MRxProxyExtendForNonCache;
|
|||
|
MRxProxyDispatch.MRxTruncate = MRxProxyTruncate;
|
|||
|
MRxProxyDispatch.MRxCleanupFobx = MRxProxyCleanupFobx;
|
|||
|
MRxProxyDispatch.MRxCloseSrvOpen = MRxProxyCloseSrvOpen;
|
|||
|
MRxProxyDispatch.MRxFlush = MRxProxyFlush;
|
|||
|
MRxProxyDispatch.MRxForceClosed = MRxProxyForcedClose;
|
|||
|
MRxProxyDispatch.MRxDeallocateForFcb = MRxProxyDeallocateForFcb;
|
|||
|
MRxProxyDispatch.MRxDeallocateForFobx = MRxProxyDeallocateForFobx;
|
|||
|
MRxProxyDispatch.MRxIsLockRealizable = MRxProxyIsLockRealizable;
|
|||
|
|
|||
|
// File System Objects query/Set
|
|||
|
MRxProxyDispatch.MRxQueryDirectory = MRxProxyQueryDirectory;
|
|||
|
MRxProxyDispatch.MRxQueryVolumeInfo = MRxProxyQueryVolumeInformation;
|
|||
|
MRxProxyDispatch.MRxQueryEaInfo = MRxProxyQueryEaInformation;
|
|||
|
MRxProxyDispatch.MRxSetEaInfo = MRxProxySetEaInformation;
|
|||
|
MRxProxyDispatch.MRxQuerySdInfo = MRxProxyQuerySecurityInformation;
|
|||
|
MRxProxyDispatch.MRxSetSdInfo = MRxProxySetSecurityInformation;
|
|||
|
MRxProxyDispatch.MRxQueryFileInfo = MRxProxyQueryFileInformation;
|
|||
|
MRxProxyDispatch.MRxSetFileInfo = MRxProxySetFileInformation;
|
|||
|
MRxProxyDispatch.MRxSetFileInfoAtCleanup
|
|||
|
= MRxProxySetFileInformationAtCleanup;
|
|||
|
|
|||
|
|
|||
|
// Buffering state change
|
|||
|
MRxProxyDispatch.MRxComputeNewBufferingState = MRxProxyComputeNewBufferingState;
|
|||
|
|
|||
|
// File System Object I/O
|
|||
|
MRxProxyDispatch.MRxLowIOSubmit[LOWIO_OP_READ] = MRxProxyRead;
|
|||
|
MRxProxyDispatch.MRxLowIOSubmit[LOWIO_OP_WRITE] = MRxProxyWrite;
|
|||
|
MRxProxyDispatch.MRxLowIOSubmit[LOWIO_OP_SHAREDLOCK] = MRxProxyLocks;
|
|||
|
MRxProxyDispatch.MRxLowIOSubmit[LOWIO_OP_EXCLUSIVELOCK] = MRxProxyLocks;
|
|||
|
MRxProxyDispatch.MRxLowIOSubmit[LOWIO_OP_UNLOCK] = MRxProxyLocks;
|
|||
|
MRxProxyDispatch.MRxLowIOSubmit[LOWIO_OP_UNLOCK_MULTIPLE] = MRxProxyLocks;
|
|||
|
MRxProxyDispatch.MRxLowIOSubmit[LOWIO_OP_FSCTL] = MRxProxyFsCtl;
|
|||
|
MRxProxyDispatch.MRxLowIOSubmit[LOWIO_OP_IOCTL] = MRxProxyIoCtl;
|
|||
|
//CODE.IMPROVEMENT shouldn't flush come thru lowio???
|
|||
|
MRxProxyDispatch.MRxLowIOSubmit[LOWIO_OP_NOTIFY_CHANGE_DIRECTORY] = MRxProxyNotifyChangeDirectory;
|
|||
|
|
|||
|
//no longer a field MRxProxyDispatch.MRxUnlockRoutine = MRxProxyUnlockRoutine;
|
|||
|
|
|||
|
|
|||
|
// Miscellanous
|
|||
|
MRxProxyDispatch.MRxCompleteBufferingStateChangeRequest = MRxProxyCompleteBufferingStateChangeRequest;
|
|||
|
|
|||
|
return(STATUS_SUCCESS);
|
|||
|
}
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
MRxProxyStart(
|
|||
|
PRX_CONTEXT RxContext,
|
|||
|
IN OUT PRDBSS_DEVICE_OBJECT RxDeviceObject
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
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
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
NTSTATUS Status;
|
|||
|
|
|||
|
Status = STATUS_SUCCESS;
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
MRxProxyStop(
|
|||
|
PRX_CONTEXT RxContext,
|
|||
|
IN OUT PRDBSS_DEVICE_OBJECT RxDeviceObject
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
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 PROXY mini rdr context passed in at registration time.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RXSTATUS - The return status for the operation
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
//NTSTATUS Status;
|
|||
|
|
|||
|
// Deallocate the configuration strings ....
|
|||
|
#if 0
|
|||
|
if (ProxyCeContext.Transports.Buffer != NULL) {
|
|||
|
|
|||
|
// the transports buffer is at the end of a larger buffer (by 12 bytes)
|
|||
|
// allocated to read the value from the registry. recover the original buffer
|
|||
|
// pointer in orer to free.
|
|||
|
|
|||
|
PKEY_VALUE_PARTIAL_INFORMATION TransportsValueFromRegistry;
|
|||
|
TransportsValueFromRegistry = CONTAINING_RECORD(
|
|||
|
ProxyCeContext.Transports.Buffer,
|
|||
|
KEY_VALUE_PARTIAL_INFORMATION,
|
|||
|
Data[0]
|
|||
|
);
|
|||
|
//DbgPrint("b1 %08lx b2 %08lx\n", TransportsValueFromRegistry,ProxyCeContext.Transports.Buffer);
|
|||
|
RxFreePool(TransportsValueFromRegistry);
|
|||
|
}
|
|||
|
#endif //0
|
|||
|
|
|||
|
return(STATUS_SUCCESS);
|
|||
|
}
|
|||
|
|
|||
|
#if 0
|
|||
|
#define PROXYMRX_CONFIG_COMPUTER_NAME \
|
|||
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName"
|
|||
|
|
|||
|
#define COMPUTERNAME L"ComputerName"
|
|||
|
|
|||
|
#define PROXYMRX_CONFIG_TRANSPORTS \
|
|||
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\LanmanWorkStation\\Linkage"
|
|||
|
|
|||
|
#define TRANSPORT_BINDINGS L"Bind"
|
|||
|
|
|||
|
#define PROXYMRX_MINIRDR_PARAMETERS \
|
|||
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\MRxProxy\\Parameters"
|
|||
|
|
|||
|
VOID
|
|||
|
MRxProxyReadMiscellaneousRegistryParameters()
|
|||
|
{
|
|||
|
NTSTATUS Status;
|
|||
|
//ULONG BytesRead;
|
|||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|||
|
UNICODE_STRING ParametersRegistryKeyName;
|
|||
|
HANDLE ParametersHandle;
|
|||
|
ULONG Temp;
|
|||
|
|
|||
|
RtlInitUnicodeString(&ParametersRegistryKeyName, PROXYMRX_MINIRDR_PARAMETERS);
|
|||
|
|
|||
|
InitializeObjectAttributes(
|
|||
|
&ObjectAttributes,
|
|||
|
&ParametersRegistryKeyName,
|
|||
|
OBJ_CASE_INSENSITIVE,
|
|||
|
NULL,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
Status = ZwOpenKey (&ParametersHandle, KEY_READ, &ObjectAttributes);
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
RxLogFailure(
|
|||
|
MRxProxyDeviceObject,
|
|||
|
NULL,
|
|||
|
EVENT_RDR_CANT_READ_REGISTRY,
|
|||
|
Status);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
if (0) {
|
|||
|
MRxProxyGetUlongRegistryParameter(ParametersHandle,
|
|||
|
L"NoPreciousServerSetup",
|
|||
|
(PULONG)&Temp,
|
|||
|
FALSE
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
Status = MRxProxyGetUlongRegistryParameter(ParametersHandle,
|
|||
|
L"DeferredOpensEnabled",
|
|||
|
(PULONG)&Temp,
|
|||
|
FALSE
|
|||
|
);
|
|||
|
if (NT_SUCCESS(Status)) MRxProxyDeferredOpensEnabled = (BOOLEAN)Temp;
|
|||
|
|
|||
|
|
|||
|
Status = MRxProxyGetUlongRegistryParameter(ParametersHandle,
|
|||
|
L"OplocksDisabled",
|
|||
|
(PULONG)&Temp,
|
|||
|
FALSE
|
|||
|
);
|
|||
|
if (NT_SUCCESS(Status)) MRxProxyOplocksDisabled = (BOOLEAN)Temp;
|
|||
|
|
|||
|
ZwClose(ParametersHandle);
|
|||
|
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
ProxyCeGetConfigurationInformation()
|
|||
|
{
|
|||
|
ULONG Storage[256];
|
|||
|
//UNICODE_STRING UnicodeString;
|
|||
|
//HANDLE hRegistryKey;
|
|||
|
//HANDLE hProxyMrxConfiguration;
|
|||
|
//HANDLE ParametersHandle;
|
|||
|
NTSTATUS Status;
|
|||
|
//ULONG BytesRead;
|
|||
|
|
|||
|
//OBJECT_ATTRIBUTES ObjectAttributes;
|
|||
|
PKEY_VALUE_FULL_INFORMATION Value = (PKEY_VALUE_FULL_INFORMATION)Storage;
|
|||
|
//KEY_VALUE_PARTIAL_INFORMATION InitialPartialInformationValue;
|
|||
|
//ULONG AllocationLength;
|
|||
|
|
|||
|
PAGED_CODE();
|
|||
|
|
|||
|
//MRxProxyReadMiscellaneousRegistryParameters();
|
|||
|
|
|||
|
#if 0
|
|||
|
// Obtain the list of transports associated with PROXY redirector. This is stored
|
|||
|
// as a multivalued string and is used subsequently to weed out the
|
|||
|
// appropriate transports. This is a two step process; first we try to find out
|
|||
|
// how much space we need; then we allocate; then we read in. unfortunately, the kind of
|
|||
|
// structure that we have to use to get the value has a header on it, so we have to offset the
|
|||
|
// returned pointer both here and in the free routine.
|
|||
|
|
|||
|
//CODE.IMPROVEMENT we should perhaps get a subroutine going that does all this
|
|||
|
//also, there are no log entries.
|
|||
|
//also, we should be doing partial_infos instead of full
|
|||
|
|
|||
|
RtlInitUnicodeString(&ProxyCeContext.Transports, NULL);
|
|||
|
RtlInitUnicodeString(&UnicodeString, PROXYMRX_CONFIG_TRANSPORTS);
|
|||
|
|
|||
|
InitializeObjectAttributes(
|
|||
|
&ObjectAttributes,
|
|||
|
&UnicodeString, // name
|
|||
|
OBJ_CASE_INSENSITIVE, // attributes
|
|||
|
NULL, // root
|
|||
|
NULL); // security descriptor
|
|||
|
|
|||
|
Status = ZwOpenKey (&hRegistryKey, KEY_READ, &ObjectAttributes);
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
RtlInitUnicodeString(&UnicodeString, TRANSPORT_BINDINGS);
|
|||
|
Status = ZwQueryValueKey(
|
|||
|
hRegistryKey,
|
|||
|
&UnicodeString,
|
|||
|
KeyValuePartialInformation,
|
|||
|
&InitialPartialInformationValue,
|
|||
|
sizeof(InitialPartialInformationValue),
|
|||
|
&BytesRead);
|
|||
|
if (Status== STATUS_BUFFER_OVERFLOW) {
|
|||
|
Status = STATUS_SUCCESS;
|
|||
|
}
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
AllocationLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION)
|
|||
|
+ InitialPartialInformationValue.DataLength;
|
|||
|
if (0) {
|
|||
|
DbgPrint("SizeofBindingInfo=%08lx %08lx\n",
|
|||
|
AllocationLength,
|
|||
|
InitialPartialInformationValue.DataLength);
|
|||
|
}
|
|||
|
|
|||
|
//RtlInitUnicodeString(&UnicodeString, TRANSPORT_BINDINGS);
|
|||
|
{
|
|||
|
PKEY_VALUE_PARTIAL_INFORMATION TransportsValueFromRegistry;
|
|||
|
|
|||
|
(PBYTE)TransportsValueFromRegistry = RxAllocatePoolWithTag(
|
|||
|
PagedPool,
|
|||
|
AllocationLength,
|
|||
|
MRXPROXY_MISC_POOLTAG);
|
|||
|
if (TransportsValueFromRegistry == NULL) {
|
|||
|
return(STATUS_INSUFFICIENT_RESOURCES);
|
|||
|
}
|
|||
|
|
|||
|
Status = ZwQueryValueKey(
|
|||
|
hRegistryKey,
|
|||
|
&UnicodeString,
|
|||
|
KeyValuePartialInformation,
|
|||
|
TransportsValueFromRegistry,
|
|||
|
AllocationLength,
|
|||
|
&BytesRead);
|
|||
|
|
|||
|
if (NT_SUCCESS(Status) &&
|
|||
|
(TransportsValueFromRegistry->DataLength > 0) &&
|
|||
|
(TransportsValueFromRegistry->Type == REG_MULTI_SZ)) {
|
|||
|
ProxyCeContext.Transports.MaximumLength =
|
|||
|
ProxyCeContext.Transports.Length = (USHORT)TransportsValueFromRegistry->DataLength;
|
|||
|
ProxyCeContext.Transports.Buffer = (PWCHAR)(&TransportsValueFromRegistry->Data[0]);
|
|||
|
//DbgPrint("b1 %08lx b2 %08lx\n", TransportsValueFromRegistry,ProxyCeContext.Transports.Buffer);
|
|||
|
} else {
|
|||
|
RxLog(("Invalid Transport Binding string... using all transports"));
|
|||
|
RxFreePool(TransportsValueFromRegistry);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
ZwClose(hRegistryKey);
|
|||
|
#endif //0
|
|||
|
|
|||
|
Status = STATUS_SUCCESS;
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
MRxProxyFsdDispatch (
|
|||
|
IN PDEVICE_OBJECT DeviceObject,
|
|||
|
IN PIRP Irp
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine implements the FSD dispatch for the proxymini 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
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); //ok4ioget
|
|||
|
UCHAR MajorFunctionCode = IrpSp->MajorFunction;
|
|||
|
|
|||
|
ASSERT(DeviceObject==(PDEVICE_OBJECT)MRxProxyDeviceObject);
|
|||
|
if (DeviceObject!=(PDEVICE_OBJECT)MRxProxyDeviceObject) {
|
|||
|
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
|
|||
|
Irp->IoStatus.Information = 0;
|
|||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT );
|
|||
|
return (STATUS_INVALID_DEVICE_REQUEST);
|
|||
|
}
|
|||
|
return RxFsdDispatch((PRDBSS_DEVICE_OBJECT)MRxProxyDeviceObject,Irp);
|
|||
|
}
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
MRxProxyDeallocateForFcb (
|
|||
|
IN OUT PMRX_FCB pFcb
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is called when the wrapper is about to deallocate a FCB.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pFcb - the Fcb being deallocated.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RXSTATUS - STATUS_SUCCESS
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
//DbgPrint("Bob's opportunity to get rid of his fcb storage......\n");
|
|||
|
return(STATUS_SUCCESS);
|
|||
|
}
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
MRxProxyDeallocateForFobx (
|
|||
|
IN OUT PMRX_FOBX pFobx
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is called when the wrapper is about to deallocate a FOBX.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pFobx - the Fobx being deallocated.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
RXSTATUS - STATUS_SUCCESS
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PMRX_PROXY_FOBX proxyFobx = MRxProxyGetFileObjectExtension(pFobx);
|
|||
|
PMRX_SRV_OPEN SrvOpen = pFobx->pSrvOpen;
|
|||
|
PMRX_FCB Fcb = SrvOpen->pFcb;
|
|||
|
|
|||
|
IF_DEBUG {
|
|||
|
if (proxyFobx && FlagOn(proxyFobx->Enumeration.Flags,PROXYFOBX_ENUMFLAG_LOUD_FINALIZE)) {
|
|||
|
DbgPrint("Finalizobx side buffer %08lx %08lx %08lx %08lx %08lxon %wZ\n",
|
|||
|
0, 0, //sidebuffer,count
|
|||
|
proxyFobx,pFobx,&Fcb->AlreadyPrefixedName
|
|||
|
);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return(STATUS_SUCCESS);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
MRxProxyGetUlongRegistryParameter(
|
|||
|
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
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
ULONG Storage[16];
|
|||
|
PKEY_VALUE_PARTIAL_INFORMATION Value;
|
|||
|
ULONG ValueSize;
|
|||
|
UNICODE_STRING UnicodeString;
|
|||
|
NTSTATUS Status;
|
|||
|
ULONG BytesRead;
|
|||
|
|
|||
|
PAGED_CODE(); //INIT
|
|||
|
|
|||
|
Value = (PKEY_VALUE_PARTIAL_INFORMATION)Storage;
|
|||
|
ValueSize = sizeof(Storage);
|
|||
|
|
|||
|
RtlInitUnicodeString(&UnicodeString, ParameterName);
|
|||
|
|
|||
|
Status = ZwQueryValueKey(ParametersHandle,
|
|||
|
&UnicodeString,
|
|||
|
KeyValuePartialInformation,
|
|||
|
Value,
|
|||
|
ValueSize,
|
|||
|
&BytesRead);
|
|||
|
|
|||
|
|
|||
|
if (NT_SUCCESS(Status)) {
|
|||
|
if (Value->Type == REG_DWORD) {
|
|||
|
PULONG ConfigValue = (PULONG)&Value->Data[0];
|
|||
|
*ParamUlong = *((PULONG)ConfigValue);
|
|||
|
DbgPrint("readRegistryvalue %wZ = %08lx\n",&UnicodeString,*ParamUlong);
|
|||
|
return(STATUS_SUCCESS);
|
|||
|
} else {
|
|||
|
Status = STATUS_INVALID_PARAMETER;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!LogFailure) { return Status; }
|
|||
|
|
|||
|
RxLogFailureWithBuffer(
|
|||
|
MRxProxyDeviceObject,
|
|||
|
NULL,
|
|||
|
EVENT_RDR_CANT_READ_REGISTRY,
|
|||
|
Status,
|
|||
|
ParameterName,
|
|||
|
(USHORT)(wcslen(ParameterName)*sizeof(WCHAR))
|
|||
|
);
|
|||
|
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|