mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
664 lines
16 KiB
664 lines
16 KiB
//+----------------------------------------------------------------------------//+----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 1996, Microsoft Corporation
|
|
//
|
|
// File: dfsinit.c
|
|
//
|
|
// Contents: Driver initialization routine for the Dfs server.
|
|
//
|
|
// Classes: None
|
|
//
|
|
// Functions: DriverEntry -- Entry point for driver
|
|
// DfsCreateMachineName -- Routine to query this computers name
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "dfsprocs.h"
|
|
#include "attach.h"
|
|
#include "fastio.h"
|
|
#include "registry.h"
|
|
#include "regkeys.h"
|
|
|
|
//
|
|
// The following are includes for init modules, which will get discarded when
|
|
// the driver has finished loading.
|
|
//
|
|
|
|
#include "provider.h"
|
|
#include "localvol.h"
|
|
#include "lvolinit.h"
|
|
#include "sitesup.h"
|
|
#include "ipsup.h"
|
|
#include "spcsup.h"
|
|
#include "dfswml.h"
|
|
|
|
//
|
|
// The debug trace level
|
|
//
|
|
|
|
#define Dbg (DEBUG_TRACE_INIT)
|
|
|
|
NTSTATUS
|
|
DriverEntry(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING RegistryPath
|
|
);
|
|
|
|
VOID
|
|
DfsUnload(
|
|
IN PDRIVER_OBJECT DriverObject);
|
|
|
|
NTSTATUS
|
|
DfsCreateMachineName(void);
|
|
|
|
VOID
|
|
DfsDeleteMachineName (
|
|
VOID);
|
|
|
|
#if DBG
|
|
VOID
|
|
DfsGetDebugFlags(void);
|
|
#endif
|
|
|
|
VOID
|
|
DfsGetEventLogValue(VOID);
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text( INIT, DfsCreateMachineName)
|
|
#pragma alloc_text( INIT, DriverEntry)
|
|
#pragma alloc_text( PAGE, DfsDeleteMachineName)
|
|
#pragma alloc_text( PAGE, DfsGetEventLogValue )
|
|
#pragma alloc_text( PAGE, DfsUnload)
|
|
#if DBG
|
|
#pragma alloc_text( PAGE, DfsGetDebugFlags )
|
|
#endif
|
|
#endif // ALLOC_PRAGMA
|
|
|
|
//
|
|
// This macro takes a pointer (or ulong) and returns its rounded up quadword
|
|
// value
|
|
//
|
|
|
|
#define QuadAlign(Ptr) ( \
|
|
((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
|
|
)
|
|
|
|
|
|
NTSTATUS DfsDrvWmiDispatch(PDEVICE_OBJECT p, PIRP i);
|
|
|
|
//+-------------------------------------------------------------------
|
|
//
|
|
// Function: DriverEntry, main entry point
|
|
//
|
|
// Synopsis: This is the initialization routine for the DFS file system
|
|
// device driver. This routine creates the device object for
|
|
// the FileSystem device and performs all other driver
|
|
// initialization.
|
|
//
|
|
// Arguments: [DriverObject] -- Pointer to driver object created by the
|
|
// system.
|
|
//
|
|
// Returns: [NTSTATUS] - The function value is the final status from
|
|
// the initialization operation.
|
|
//
|
|
//--------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
DriverEntry(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING RegistryPath
|
|
) {
|
|
NTSTATUS Status;
|
|
UNICODE_STRING UnicodeString;
|
|
PDEVICE_OBJECT DeviceObject;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
PWSTR p;
|
|
int i;
|
|
HANDLE hTemp;
|
|
HANDLE DirHandle;
|
|
PBYTE pData;
|
|
|
|
DebugTrace(0, Dbg, "***********Dfs DriverEntry()\n", 0);
|
|
|
|
DfsData.OperationalState = DFS_STATE_UNINITIALIZED;
|
|
DfsData.LvState = LV_UNINITIALIZED;
|
|
//
|
|
// Create the filesystem device object.
|
|
//
|
|
|
|
RtlInitUnicodeString( &UnicodeString, DFS_SERVER_NAME );
|
|
Status = IoCreateDevice( DriverObject,
|
|
0,
|
|
&UnicodeString,
|
|
FILE_DEVICE_DFS_FILE_SYSTEM,
|
|
FILE_REMOTE_DEVICE | FILE_DEVICE_SECURE_OPEN,
|
|
FALSE,
|
|
&DeviceObject );
|
|
if ( !NT_SUCCESS( Status ) ) {
|
|
return Status;
|
|
}
|
|
DriverObject->DriverUnload = DfsUnload;
|
|
//
|
|
// Initialize the driver object with this driver's entry points.
|
|
// Most are simply passed through to some other device driver.
|
|
//
|
|
|
|
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
|
|
DriverObject->MajorFunction[i] = DfsVolumePassThrough;
|
|
}
|
|
|
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)DfsFsdCreate;
|
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)DfsFsdClose;
|
|
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = (PDRIVER_DISPATCH)DfsFsdCleanup;
|
|
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = (PDRIVER_DISPATCH)DfsFsdSetInformation;
|
|
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = (PDRIVER_DISPATCH)DfsFsdFileSystemControl;
|
|
|
|
DriverObject->FastIoDispatch = &FastIoDispatch;
|
|
|
|
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
|
|
(PDRIVER_DISPATCH) DfsDrvWmiDispatch;
|
|
|
|
|
|
|
|
Status = IoWMIRegistrationControl (DeviceObject, WMIREG_ACTION_REGISTER);
|
|
|
|
//
|
|
// Initialize the global data structures
|
|
//
|
|
|
|
RtlZeroMemory(&DfsData, sizeof (DFS_DATA));
|
|
|
|
DfsData.NodeTypeCode = DFS_NTC_DATA_HEADER;
|
|
DfsData.NodeByteSize = sizeof( DFS_DATA );
|
|
|
|
InitializeListHead( &DfsData.AVdoQueue );
|
|
InitializeListHead( &DfsData.AFsoQueue );
|
|
|
|
//
|
|
// Init assorted hash tables
|
|
//
|
|
|
|
Status = DfsInitFcbs( 0 );
|
|
if (!NT_SUCCESS(Status)) {
|
|
IoDeleteDevice (DeviceObject);
|
|
return Status;
|
|
}
|
|
|
|
Status = DfsInitSites( 0 );
|
|
if (!NT_SUCCESS(Status)) {
|
|
DfsUninitFcbs ();
|
|
IoDeleteDevice (DeviceObject);
|
|
return Status;
|
|
}
|
|
|
|
Status = DfsInitSpcHashTable( &DfsData.SpcHashTable, 0 );
|
|
if (!NT_SUCCESS(Status)) {
|
|
DfsUninitSites ();
|
|
DfsUninitFcbs ();
|
|
IoDeleteDevice (DeviceObject);
|
|
return Status;
|
|
}
|
|
|
|
Status = DfsInitSpcHashTable( &DfsData.FtDfsHashTable, 0 );
|
|
if (!NT_SUCCESS(Status)) {
|
|
DfsUninitSpcHashTable (DfsData.SpcHashTable);
|
|
DfsUninitSites ();
|
|
DfsUninitFcbs ();
|
|
IoDeleteDevice (DeviceObject);
|
|
return Status;
|
|
}
|
|
|
|
Status = DfsInitIp( 0, 0 );
|
|
if (!NT_SUCCESS(Status)) {
|
|
DfsUninitSpcHashTable (DfsData.FtDfsHashTable);
|
|
DfsUninitSpcHashTable (DfsData.SpcHashTable);
|
|
DfsUninitSites ();
|
|
DfsUninitFcbs ();
|
|
IoDeleteDevice (DeviceObject);
|
|
return Status;
|
|
}
|
|
|
|
DfsData.DriverObject = DriverObject;
|
|
DfsData.FileSysDeviceObject = DeviceObject;
|
|
|
|
ExInitializeResourceLite( &DfsData.Resource );
|
|
|
|
DfsData.MachineState = DFS_UNKNOWN;
|
|
|
|
DfsData.IsDC = FALSE;
|
|
|
|
DfsCreateMachineName();
|
|
|
|
DfsData.Pkt.DefaultTimeToLive = DEFAULT_PKT_ENTRY_TIMEOUT;
|
|
|
|
//
|
|
// Override special name table timeout with registry entry
|
|
//
|
|
|
|
Status = KRegSetRoot(wszRegDfsDriver);
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
Status = KRegGetValue(
|
|
L"",
|
|
wszDefaultTimeToLive,
|
|
(PVOID ) &pData);
|
|
|
|
KRegCloseRoot();
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
DfsData.Pkt.DefaultTimeToLive = *((ULONG*)pData);
|
|
|
|
ExFreePool(pData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Initialize Lpc struct
|
|
//
|
|
|
|
RtlInitUnicodeString(&DfsData.DfsLpcInfo.LpcPortName, NULL);
|
|
DfsData.DfsLpcInfo.LpcPortState = LPC_STATE_UNINITIALIZED;
|
|
ExInitializeFastMutex(&DfsData.DfsLpcInfo.LpcPortMutex);
|
|
DfsData.DfsLpcInfo.LpcPortHandle = NULL;
|
|
ExInitializeResourceLite(&DfsData.DfsLpcInfo.LpcPortResource );
|
|
|
|
//
|
|
// Initialize the system wide PKT
|
|
//
|
|
|
|
Status = PktInitialize(&DfsData.Pkt);
|
|
if (!NT_SUCCESS(Status)) {
|
|
ExDeleteResourceLite(&DfsData.DfsLpcInfo.LpcPortResource );
|
|
DfsDeleteMachineName();
|
|
ExDeleteResourceLite( &DfsData.Resource );
|
|
DfsUninitIp ();
|
|
DfsUninitSpcHashTable (DfsData.FtDfsHashTable);
|
|
DfsUninitSpcHashTable (DfsData.SpcHashTable);
|
|
DfsUninitSites ();
|
|
DfsUninitFcbs ();
|
|
IoDeleteDevice (DfsData.FileSysDeviceObject);
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Set up global pointer to the system process.
|
|
//
|
|
|
|
DfsData.OurProcess = PsGetCurrentProcess();
|
|
|
|
//
|
|
// Register for callbacks when other file systems are loaded
|
|
//
|
|
|
|
Status = IoRegisterFsRegistrationChange( DriverObject, DfsFsNotification );
|
|
if (!NT_SUCCESS (Status)) {
|
|
PktUninitialize(&DfsData.Pkt);
|
|
ExDeleteResourceLite(&DfsData.DfsLpcInfo.LpcPortResource );
|
|
DfsDeleteMachineName();
|
|
ExDeleteResourceLite( &DfsData.Resource );
|
|
DfsUninitIp ();
|
|
DfsUninitSpcHashTable (DfsData.FtDfsHashTable);
|
|
DfsUninitSpcHashTable (DfsData.SpcHashTable);
|
|
DfsUninitSites ();
|
|
DfsUninitFcbs ();
|
|
IoDeleteDevice (DfsData.FileSysDeviceObject);
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Finally, mark our state to being INITIALIZED
|
|
//
|
|
|
|
DfsData.OperationalState = DFS_STATE_INITIALIZED;
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------
|
|
//
|
|
// Function: DfsUnload()
|
|
//
|
|
// Synopsis: Driver unload routine
|
|
//
|
|
// Arguments: [DriverObject] -- The driver object created by the system
|
|
//
|
|
// Returns: Nothing
|
|
//
|
|
//----------------------------------------------------------------------
|
|
VOID
|
|
DfsUnload(
|
|
IN PDRIVER_OBJECT DriverObject)
|
|
{
|
|
|
|
IoUnregisterFsRegistrationChange(DriverObject, DfsFsNotification);
|
|
|
|
DfsDetachAllFileSystems ();
|
|
|
|
PktUninitialize(&DfsData.Pkt);
|
|
ExDeleteResourceLite(&DfsData.DfsLpcInfo.LpcPortResource );
|
|
DfsDeleteMachineName();
|
|
ExDeleteResourceLite( &DfsData.Resource );
|
|
DfsUninitIp ();
|
|
DfsUninitSpcHashTable (DfsData.FtDfsHashTable);
|
|
DfsUninitSpcHashTable (DfsData.SpcHashTable);
|
|
DfsUninitSites ();
|
|
DfsUninitFcbs ();
|
|
IoDeleteDevice (DfsData.FileSysDeviceObject);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------
|
|
//
|
|
// Function: DfsCreateMachineName()
|
|
//
|
|
// Synopsis: Gets the principal name of this machine by looking at
|
|
// Registry.
|
|
//
|
|
// Arguments: [pustrName] -- The Service Name is to be filled in here.
|
|
//
|
|
// Returns: STATUS_SUCCESS -- If all went well.
|
|
//
|
|
//
|
|
// History: 30 Mar 1993 SudK Created.
|
|
//
|
|
//----------------------------------------------------------------------
|
|
|
|
NTSTATUS
|
|
DfsCreateMachineName(void)
|
|
{
|
|
|
|
NTSTATUS status;
|
|
UNICODE_STRING PName;
|
|
PWCHAR pwszNetBIOSName;
|
|
PWCHAR pwszComputerName;
|
|
PWCHAR pwszDomainRoot;
|
|
PWCHAR pwszOU;
|
|
ULONG lOUNameLength;
|
|
|
|
//
|
|
// Now we have to go and get the computer name from the registry.
|
|
//
|
|
|
|
status = KRegSetRoot(wszRegComputerNameRt);
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
status = KRegGetValue(
|
|
wszRegComputerNameSubKey,
|
|
wszRegComputerNameValue,
|
|
(PVOID ) &pwszComputerName);
|
|
|
|
KRegCloseRoot();
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
|
|
RtlInitUnicodeString(
|
|
&DfsData.NetBIOSName,
|
|
pwszComputerName);
|
|
|
|
RtlInitUnicodeString(
|
|
&DfsData.PrincipalName,
|
|
pwszComputerName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return(status);
|
|
|
|
}
|
|
|
|
VOID
|
|
DfsDeleteMachineName (
|
|
VOID)
|
|
{
|
|
ExFreePool (DfsData.NetBIOSName.Buffer);
|
|
}
|
|
|
|
VOID
|
|
DfsGetEventLogValue(VOID)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine checks registry keys to set the event logging level
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS status;
|
|
HANDLE DfsRegHandle;
|
|
OBJECT_ATTRIBUTES ObjAttr;
|
|
ULONG ValueSize;
|
|
|
|
UNICODE_STRING DfsRegKey;
|
|
UNICODE_STRING DfsValueName;
|
|
|
|
struct {
|
|
KEY_VALUE_PARTIAL_INFORMATION Info;
|
|
ULONG Buffer;
|
|
} DfsValue;
|
|
|
|
PAGED_CODE();
|
|
|
|
DebugTrace(0, Dbg, "DfsGetEventLogValue()\n", 0);
|
|
|
|
RtlInitUnicodeString(
|
|
&DfsRegKey,
|
|
L"\\Registry\\Machine\\SOFTWARE\\MicroSoft\\Windows NT\\CurrentVersion\\Diagnostics");
|
|
|
|
InitializeObjectAttributes(
|
|
&ObjAttr,
|
|
&DfsRegKey,
|
|
OBJ_CASE_INSENSITIVE,
|
|
0,
|
|
NULL);
|
|
|
|
status = ZwOpenKey(
|
|
&DfsRegHandle,
|
|
KEY_QUERY_VALUE,
|
|
&ObjAttr);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
return;
|
|
|
|
RtlInitUnicodeString(&DfsValueName, L"RunDiagnosticLoggingGlobal");
|
|
|
|
status = ZwQueryValueKey(
|
|
DfsRegHandle,
|
|
&DfsValueName,
|
|
KeyValuePartialInformation,
|
|
(PVOID) &DfsValue,
|
|
sizeof(DfsValue),
|
|
&ValueSize);
|
|
|
|
if (NT_SUCCESS(status) && DfsValue.Info.Type == REG_DWORD) {
|
|
|
|
DfsEventLog = *((PULONG) DfsValue.Info.Data);
|
|
goto Cleanup;
|
|
|
|
}
|
|
|
|
RtlInitUnicodeString(&DfsValueName, L"RunDiagnosticLoggingDfs");
|
|
|
|
status = ZwQueryValueKey(
|
|
DfsRegHandle,
|
|
&DfsValueName,
|
|
KeyValuePartialInformation,
|
|
(PVOID) &DfsValue,
|
|
sizeof(DfsValue),
|
|
&ValueSize);
|
|
|
|
if (NT_SUCCESS(status) && DfsValue.Info.Type == REG_DWORD)
|
|
DfsEventLog = *((PULONG) DfsValue.Info.Data);
|
|
|
|
Cleanup:
|
|
|
|
ZwClose( DfsRegHandle );
|
|
|
|
DebugTrace( 0, Dbg, "DfsGetEventLog exit DfsEventLog = 0x%x\n", ULongToPtr( DfsEventLog ));
|
|
|
|
}
|
|
|
|
//
|
|
// DfspGetMaxReferrals: read from registry the maximum number of referrals
|
|
// that we pass back to the client, and store this in the dfsdata.pkt
|
|
//
|
|
|
|
VOID
|
|
DfspGetMaxReferrals(
|
|
VOID)
|
|
{
|
|
NTSTATUS status;
|
|
HANDLE DfsRegHandle;
|
|
OBJECT_ATTRIBUTES ObjAttr;
|
|
ULONG ValueSize;
|
|
|
|
UNICODE_STRING DfsRegKey;
|
|
UNICODE_STRING DfsValueName;
|
|
|
|
struct {
|
|
KEY_VALUE_PARTIAL_INFORMATION Info;
|
|
ULONG Buffer;
|
|
} DfsValue;
|
|
|
|
RtlInitUnicodeString(
|
|
&DfsRegKey,
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\DfsDriver");
|
|
|
|
InitializeObjectAttributes(
|
|
&ObjAttr,
|
|
&DfsRegKey,
|
|
OBJ_CASE_INSENSITIVE,
|
|
0,
|
|
NULL);
|
|
|
|
status = ZwOpenKey(
|
|
&DfsRegHandle,
|
|
KEY_QUERY_VALUE,
|
|
&ObjAttr);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
return;
|
|
|
|
RtlInitUnicodeString(&DfsValueName, wszMaxReferrals);
|
|
|
|
status = ZwQueryValueKey(
|
|
DfsRegHandle,
|
|
&DfsValueName,
|
|
KeyValuePartialInformation,
|
|
(PVOID) &DfsValue,
|
|
sizeof(DfsValue),
|
|
&ValueSize);
|
|
|
|
if (NT_SUCCESS(status) && DfsValue.Info.Type == REG_DWORD) {
|
|
DfsData.Pkt.MaxReferrals = *((PULONG) DfsValue.Info.Data);
|
|
// DbgPrint("Set MaxReferrals to %d\n", DfsData.Pkt.MaxReferrals);
|
|
}
|
|
|
|
ZwClose( DfsRegHandle );
|
|
|
|
}
|
|
|
|
#if DBG
|
|
|
|
|
|
VOID
|
|
DfsGetDebugFlags(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine reads Dfs debug flag settings from the registry
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
HANDLE handle;
|
|
NTSTATUS status;
|
|
UNICODE_STRING valueName;
|
|
UNICODE_STRING keyName;
|
|
OBJECT_ATTRIBUTES objectAttributes;
|
|
PWCH providerName;
|
|
ULONG lengthRequired;
|
|
ULONG Flags = 0;
|
|
|
|
union {
|
|
KEY_VALUE_FULL_INFORMATION;
|
|
UCHAR buffer[ sizeof( KEY_VALUE_FULL_INFORMATION ) + 100 ];
|
|
} keyValueInformation;
|
|
|
|
PAGED_CODE();
|
|
|
|
RtlInitUnicodeString(
|
|
&keyName,
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Dfs");
|
|
|
|
InitializeObjectAttributes(
|
|
&objectAttributes,
|
|
&keyName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
0,
|
|
NULL);
|
|
|
|
status = ZwOpenKey(
|
|
&handle,
|
|
KEY_QUERY_VALUE,
|
|
&objectAttributes);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
return;
|
|
|
|
RtlInitUnicodeString( &valueName, L"DfsDebugTraceLevelServer" );
|
|
|
|
status = ZwQueryValueKey(
|
|
handle,
|
|
&valueName,
|
|
KeyValueFullInformation,
|
|
&keyValueInformation,
|
|
sizeof(keyValueInformation),
|
|
&lengthRequired
|
|
);
|
|
|
|
if (
|
|
NT_SUCCESS(status) &&
|
|
keyValueInformation.Type == REG_DWORD &&
|
|
keyValueInformation.DataLength != 0
|
|
) {
|
|
|
|
Flags = *(PULONG)(((PUCHAR)(&keyValueInformation)) + keyValueInformation.DataOffset);
|
|
DfsDebugTraceLevel = Flags;
|
|
|
|
}
|
|
|
|
ZwClose( handle );
|
|
|
|
return;
|
|
}
|
|
|
|
#endif // DBG
|