📄 init.c
字号:
/*++
Copyright (c) 1989 - 1999 Microsoft Corporation
Module Name:
Init.c
Abstract:
This module implements the DRIVER_INITIALIZATION routine for the SMB mini rdr.
--*/
#include "precomp.h"
#pragma hdrstop
#include "smbmrx.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, DriverEntry)
#pragma alloc_text(PAGE, MRxSmbInitUnwind)
#pragma alloc_text(PAGE, MRxSmbUnload)
#pragma alloc_text(PAGE, MRxSmbInitializeTables)
#pragma alloc_text(PAGE, MRxSmbStart)
#pragma alloc_text(PAGE, MRxSmbStop)
#pragma alloc_text(PAGE, MRxSmbInitializeSecurity)
#pragma alloc_text(PAGE, MRxSmbUninitializeSecurity)
#pragma alloc_text(PAGE, SmbCeGetConfigurationInformation)
#pragma alloc_text(PAGE, MRxSmbFsdDispatch)
#pragma alloc_text(PAGE, MRxSmbDeallocateForFcb)
#pragma alloc_text(PAGE, MRxSmbDeallocateForFobx)
#pragma alloc_text(PAGE, MRxSmbGetUlongRegistryParameter)
#endif
extern ERESOURCE s_SmbCeDbResource;
//
// Global data declarations .
//
PVOID MRxSmbPoRegistrationState = NULL;
FAST_MUTEX MRxSmbSerializationMutex;
MRXSMB_CONFIGURATION MRxSmbConfiguration;
MRXSMB_STATE MRxSmbState = MRXSMB_STARTABLE;
SMBCE_CONTEXT SmbCeContext;
PMDL s_pEchoSmbMdl = NULL;
ULONG s_EchoSmbLength = 0;
#ifdef EXPLODE_POOLTAGS
ULONG MRxSmbExplodePoolTags = 1;
#else
ULONG MRxSmbExplodePoolTags = 0;
#endif
//
// Mini Redirector global variables.
//
struct _MINIRDR_DISPATCH MRxSmbDispatch;
PRDBSS_DEVICE_OBJECT MRxSmbDeviceObject;
MRXSMB_GLOBAL_PADDING MrxSmbCeGlobalPadding;
//
// If this flag is TRUE, we strictly obey the transport binding order. If it is FALSE,
// we can use whatever transport we want to connect to the remote server.
//
BOOLEAN MRxSmbObeyBindingOrder = FALSE;
//
// MRxSmbSecurityInitialized indicates whether MRxSmbInitializeSecurity
// has been called.
//
BOOLEAN MRxSmbSecurityInitialized = FALSE;
LIST_ENTRY MRxSmbPagingFilesSrvOpenList;
//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);
RXDT_DefineCategory(CONNECT);
typedef enum _MRXSMB_INIT_STATES {
MRXSMBINIT_ALL_INITIALIZATION_COMPLETED,
MRXSMBINIT_MINIRDR_REGISTERED,
MRXSMBINIT_START
} MRXSMB_INIT_STATES;
VOID
MRxSmbInitUnwind(
IN PDRIVER_OBJECT DriverObject,
IN MRXSMB_INIT_STATES MRxSmbInitState
);
NTSTATUS
MRxSmbFsdDispatch (
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 SMB 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;
MRXSMB_INIT_STATES MRxSmbInitState = 0;
UNICODE_STRING SmbMiniRedirectorName;
UNICODE_STRING UserModeDeviceName;
ULONG Controls = 0;
PAGED_CODE();
#ifdef MONOLITHIC_MINIRDR
Status = RxDriverEntry(DriverObject, RegistryPath);
if (Status != STATUS_SUCCESS) {
DbgPrint("Wrapper failed to initialize. Status = %08lx\n",Status);
return(Status);
}
#endif
RtlZeroMemory(&MRxSmbStatistics,sizeof(MRxSmbStatistics));
RtlZeroMemory(&MRxSmbConfiguration,sizeof(MRxSmbConfiguration));
KeQuerySystemTime(&MRxSmbStatistics.StatisticsStartTime);
RtlZeroMemory(&MrxSmbCeGlobalPadding,sizeof(MrxSmbCeGlobalPadding));
MmInitializeMdl(&MrxSmbCeGlobalPadding.Mdl,&MrxSmbCeGlobalPadding.Pad[0],SMBCE_PADDING_DATA_SIZE);
MmBuildMdlForNonPagedPool(&MrxSmbCeGlobalPadding.Mdl);
ExInitializeFastMutex(&MRxSmbSerializationMutex);
Status = MRxSmbInitializeTransport();
if (Status != STATUS_SUCCESS) {
RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("MRxSmbDriverEntry failed to init transport data structures: %08lx\n", Status ));
return(STATUS_UNSUCCESSFUL);
}
try {
ExInitializeResourceLite(&s_SmbCeDbResource);
MRxSmbInitState = MRXSMBINIT_START;
RtlInitUnicodeString(&SmbMiniRedirectorName, DD_SMBMRX_FS_DEVICE_NAME_U);
RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("MRxSmbDriverEntry: DriverObject =%p\n", DriverObject ));
SetFlag(Controls,RX_REGISTERMINI_FLAG_DONT_PROVIDE_MAILSLOTS);
Status = RxRegisterMinirdr(&MRxSmbDeviceObject,
DriverObject,
&MRxSmbDispatch,
Controls,
&SmbMiniRedirectorName,
0,
FILE_DEVICE_NETWORK_FILE_SYSTEM,
FILE_REMOTE_DEVICE
);
if (Status!=STATUS_SUCCESS) {
RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("MRxSmbDriverEntry failed: %08lx\n", Status ));
try_return(Status);
}
MRxSmbInitState = MRXSMBINIT_MINIRDR_REGISTERED;
RtlInitUnicodeString(&UserModeDeviceName, DD_SMBMRX_USERMODE_SHADOW_DEV_NAME_U);
Status = IoCreateSymbolicLink( &UserModeDeviceName, &SmbMiniRedirectorName);
//for all this stuff, there's no undo.....so no extra state
Status = MRxSmbInitializeTables();
if (!NT_SUCCESS( Status )) {
try_return(Status);
}
RtlInitUnicodeString(&SmbCeContext.ComputerName,NULL);
RtlInitUnicodeString(&SmbCeContext.OperatingSystem, NULL);
RtlInitUnicodeString(&SmbCeContext.LanmanType, NULL);
RtlInitUnicodeString(&SmbCeContext.Transports, NULL);
MRxSmbConfiguration.SessionTimeoutInterval = MRXSMB_DEFAULT_TIMED_EXCHANGE_EXPIRY_TIME;
MRxSmbConfiguration.LockIncrement = 0;
MRxSmbConfiguration.MaximumLock = 1000;
SmbCeGetConfigurationInformation();
SmbCeGetComputerName();
SmbCeGetOperatingSystemInformation();
try_exit: NOTHING;
} finally {
if (Status != STATUS_SUCCESS) {
MRxSmbInitUnwind(DriverObject,MRxSmbInitState);
}
}
if (Status != STATUS_SUCCESS) {
DbgPrint("MRxSmb failed to start with %08lx %08lx\n",Status,MRxSmbInitState);
return(Status);
}
// Setup Unload Routine
DriverObject->DriverUnload = MRxSmbUnload;
// set all IRR_MJ to the dispatch point
{
ULONG i;
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
DriverObject->MajorFunction[i] = (PDRIVER_DISPATCH)MRxSmbFsdDispatch;
}
}
//and get out
return STATUS_SUCCESS;
}
VOID
MRxSmbInitUnwind(
IN PDRIVER_OBJECT DriverObject,
IN MRXSMB_INIT_STATES MRxSmbInitState
)
/*++
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 (MRxSmbInitState) {
case MRXSMBINIT_ALL_INITIALIZATION_COMPLETED:
//Nothing extra to do...this is just so that the constant in RxUnload doesn't change.......
//lack of break intentional
case MRXSMBINIT_MINIRDR_REGISTERED:
RxUnregisterMinirdr(MRxSmbDeviceObject);
//lack of break intentional
case MRXSMBINIT_START:
// Deallocate the configuration strings ....
if (SmbCeContext.ComputerName.Buffer != NULL) {
RxFreePool(SmbCeContext.ComputerName.Buffer);
}
if (SmbCeContext.OperatingSystem.Buffer != NULL) {
RxFreePool(SmbCeContext.OperatingSystem.Buffer);
}
if (SmbCeContext.LanmanType.Buffer != NULL) {
RxFreePool(SmbCeContext.LanmanType.Buffer);
}
if (SmbCeContext.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 order to free.
PKEY_VALUE_PARTIAL_INFORMATION TransportsValueFromRegistry;
TransportsValueFromRegistry = CONTAINING_RECORD(
SmbCeContext.Transports.Buffer,
KEY_VALUE_PARTIAL_INFORMATION,
Data[0]
);
//DbgPrint("b1 %08lx b2 %08lx\n", TransportsValueFromRegistry,SmbCeContext.Transports.Buffer);
RxFreePool(TransportsValueFromRegistry);
SmbCeContext.Transports.Buffer = NULL;
SmbCeContext.Transports.Length = 0;
SmbCeContext.Transports.MaximumLength = 0;
}
MRxSmbUninitializeTransport();
ExDeleteResourceLite(&s_SmbCeDbResource);
break;
}
}
VOID
MRxSmbUnload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
This is the unload routine for the SMB mini redirector.
Arguments:
DriverObject - pointer to the driver object for the MRxSmb
Return Value:
None
--*/
{
UNICODE_STRING UserModeDeviceName;
PAGED_CODE();
RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("MRxSmbUnload: DriverObject =%p\n", DriverObject) );
MRxSmbInitUnwind(DriverObject,MRXSMBINIT_ALL_INITIALIZATION_COMPLETED);
RtlInitUnicodeString(&UserModeDeviceName, DD_SMBMRX_USERMODE_SHADOW_DEV_NAME_U);
IoDeleteSymbolicLink( &UserModeDeviceName);
#ifdef MONOLITHIC_MINIRDR
RxUnload(DriverObject);
#endif
RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("MRxSmbUnload exit: DriverObject =%p\n", DriverObject) );
}
NTSTATUS
MRxSmbInitializeTables(
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
--*/
{
PAGED_CODE();
// Ensure that the SMB mini redirector context satisfies the size constraints
ASSERT(sizeof(MRXSMB_RX_CONTEXT) <= MRX_CONTEXT_SIZE);
//local minirdr dispatch table init
ZeroAndInitializeNodeType( &MRxSmbDispatch, RDBSS_NTC_MINIRDR_DISPATCH, sizeof(MINIRDR_DISPATCH));
// SMB mini redirector extension sizes and allocation policies.
MRxSmbDispatch.MRxFlags = (RDBSS_MANAGE_FCB_EXTENSION |
RDBSS_MANAGE_SRV_OPEN_EXTENSION |
RDBSS_MANAGE_FOBX_EXTENSION);
MRxSmbDispatch.MRxSrvCallSize = 0;
MRxSmbDispatch.MRxNetRootSize = 0;
MRxSmbDispatch.MRxVNetRootSize = 0;
MRxSmbDispatch.MRxFcbSize = sizeof(MRX_SMB_FCB);
MRxSmbDispatch.MRxSrvOpenSize = sizeof(MRX_SMB_SRV_OPEN);
MRxSmbDispatch.MRxFobxSize = sizeof(MRX_SMB_FOBX);
// Mini redirector cancel routine ..
MRxSmbDispatch.MRxCancel = NULL;
// Mini redirector Start/Stop
MRxSmbDispatch.MRxStart = MRxSmbStart;
MRxSmbDispatch.MRxStop = MRxSmbStop;
MRxSmbDispatch.MRxDevFcbXXXControlFile = MRxSmbDevFcbXXXControlFile;
// Mini redirector name resolution
MRxSmbDispatch.MRxCreateSrvCall = MRxSmbCreateSrvCall;
MRxSmbDispatch.MRxSrvCallWinnerNotify = MRxSmbSrvCallWinnerNotify;
MRxSmbDispatch.MRxCreateVNetRoot = MRxSmbCreateVNetRoot;
MRxSmbDispatch.MRxUpdateNetRootState = MRxSmbUpdateNetRootState;
MRxSmbDispatch.MRxExtractNetRootName = MRxSmbExtractNetRootName;
MRxSmbDispatch.MRxFinalizeSrvCall = MRxSmbFinalizeSrvCall;
MRxSmbDispatch.MRxFinalizeNetRoot = MRxSmbFinalizeNetRoot;
MRxSmbDispatch.MRxFinalizeVNetRoot = MRxSmbFinalizeVNetRoot;
// File System Object Creation/Deletion.
MRxSmbDispatch.MRxCreate = MRxSmbCreate;
MRxSmbDispatch.MRxCollapseOpen = MRxSmbCollapseOpen;
MRxSmbDispatch.MRxShouldTryToCollapseThisOpen
= MRxSmbShouldTryToCollapseThisOpen;
MRxSmbDispatch.MRxExtendForCache = MRxSmbExtendForCache;
MRxSmbDispatch.MRxExtendForNonCache = MRxSmbExtendForNonCache;
MRxSmbDispatch.MRxTruncate = MRxSmbTruncate;
MRxSmbDispatch.MRxCleanupFobx = MRxSmbCleanupFobx;
MRxSmbDispatch.MRxCloseSrvOpen = MRxSmbCloseSrvOpen;
MRxSmbDispatch.MRxFlush = MRxSmbFlush;
MRxSmbDispatch.MRxForceClosed = MRxSmbForcedClose;
MRxSmbDispatch.MRxDeallocateForFcb = MRxSmbDeallocateForFcb;
MRxSmbDispatch.MRxDeallocateForFobx = MRxSmbDeallocateForFobx;
MRxSmbDispatch.MRxIsLockRealizable = MRxSmbIsLockRealizable;
// File System Objects query/Set
MRxSmbDispatch.MRxQueryDirectory = MRxSmbQueryDirectory;
MRxSmbDispatch.MRxQueryVolumeInfo = MRxSmbQueryVolumeInformation;
MRxSmbDispatch.MRxSetVolumeInfo = MRxSmbSetVolumeInformation;
MRxSmbDispatch.MRxQueryEaInfo = MRxSmbQueryEaInformation;
MRxSmbDispatch.MRxSetEaInfo = MRxSmbSetEaInformation;
MRxSmbDispatch.MRxQuerySdInfo = MRxSmbQuerySecurityInformation;
MRxSmbDispatch.MRxSetSdInfo = MRxSmbSetSecurityInformation;
MRxSmbDispatch.MRxQueryQuotaInfo = MRxSmbQueryQuotaInformation;
MRxSmbDispatch.MRxSetQuotaInfo = MRxSmbSetQuotaInformation;
MRxSmbDispatch.MRxQueryFileInfo = MRxSmbQueryFileInformation;
MRxSmbDispatch.MRxSetFileInfo = MRxSmbSetFileInformation;
MRxSmbDispatch.MRxSetFileInfoAtCleanup
= MRxSmbSetFileInformationAtCleanup;
MRxSmbDispatch.MRxIsValidDirectory= MRxSmbIsValidDirectory;
// Buffering state change
MRxSmbDispatch.MRxComputeNewBufferingState = MRxSmbComputeNewBufferingState;
// File System Object I/O
MRxSmbDispatch.MRxLowIOSubmit[LOWIO_OP_READ] = MRxSmbRead;
MRxSmbDispatch.MRxLowIOSubmit[LOWIO_OP_WRITE] = MRxSmbWrite;
MRxSmbDispatch.MRxLowIOSubmit[LOWIO_OP_SHAREDLOCK] = MRxSmbLocks;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -