|
|
//+----------------------------------------------------------------------------//+----------------------------------------------------------------------------
//
// 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
|