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.
591 lines
16 KiB
591 lines
16 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
NwInit.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the DRIVER_INITIALIZATION routine for NetWare
|
|
|
|
Author:
|
|
|
|
Colin Watson [ColinW] 15-Dec-1992
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "Procs.h"
|
|
#include "wdmsec.h"
|
|
#define Dbg (DEBUG_TRACE_LOAD)
|
|
|
|
//
|
|
// Private declaration because ZwQueryDefaultLocale isn't in any header.
|
|
//
|
|
|
|
NTSYSAPI
|
|
NTSTATUS
|
|
NTAPI
|
|
ZwQueryDefaultLocale(
|
|
IN BOOLEAN UserProfile,
|
|
OUT PLCID DefaultLocaleId
|
|
);
|
|
|
|
NTSTATUS
|
|
DriverEntry(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING RegistryPath
|
|
);
|
|
|
|
VOID
|
|
UnloadDriver(
|
|
IN PDRIVER_OBJECT DriverObject
|
|
);
|
|
|
|
VOID
|
|
GetConfigurationInformation(
|
|
PUNICODE_STRING RegistryPath
|
|
);
|
|
|
|
VOID
|
|
ReadValue(
|
|
HANDLE ParametersHandle,
|
|
PLONG pVar,
|
|
PWCHAR Name
|
|
);
|
|
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text( PAGE, DriverEntry )
|
|
#pragma alloc_text( PAGE, GetConfigurationInformation )
|
|
#pragma alloc_text( PAGE, ReadValue )
|
|
#endif
|
|
|
|
#if 0 // Not pageable
|
|
UnloadDriver
|
|
#endif
|
|
|
|
#ifdef _PNP_POWER_
|
|
extern HANDLE TdiBindingHandle;
|
|
#endif
|
|
|
|
static ULONG IrpStackSize;
|
|
|
|
|
|
NTSTATUS
|
|
DriverEntry(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING RegistryPath
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is the initialization routine for the Nw 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.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - The function value is the final status from the initialization
|
|
operation.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
UNICODE_STRING UnicodeString;
|
|
UNICODE_STRING SddlString;
|
|
PAGED_CODE();
|
|
|
|
//DbgBreakPoint();
|
|
|
|
InitializeAttach( );
|
|
NwInitializeData();
|
|
//NwInitializePidTable(); // Terminal Server code merge -
|
|
// NwInitalizePidTable in the NwAllocateAndInitScb
|
|
// Pid table is per SCB base.
|
|
|
|
//
|
|
// Create the device object.
|
|
//
|
|
|
|
RtlInitUnicodeString( &UnicodeString, DD_NWFS_DEVICE_NAME_U );
|
|
RtlInitUnicodeString( &SddlString, L"D:P(A;;GX;;;WD)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;LS)(A;;GA;;;NS)(A;;GX;;;RC)" );
|
|
|
|
Status = IoCreateDeviceSecure( DriverObject,
|
|
0,
|
|
&UnicodeString,
|
|
FILE_DEVICE_NETWORK_FILE_SYSTEM,
|
|
FILE_REMOTE_DEVICE,
|
|
FALSE,
|
|
&SddlString,
|
|
NULL,
|
|
&FileSystemDeviceObject );
|
|
|
|
if (!NT_SUCCESS( Status )) {
|
|
Error(EVENT_NWRDR_CANT_CREATE_DEVICE, Status, NULL, 0, 0);
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Initialize parameters to the defaults.
|
|
//
|
|
|
|
IrpStackSize = NWRDR_IO_STACKSIZE;
|
|
|
|
//
|
|
// Attempt to read config information from the registry
|
|
//
|
|
|
|
GetConfigurationInformation( RegistryPath );
|
|
|
|
//
|
|
// Set the stack size.
|
|
//
|
|
|
|
FileSystemDeviceObject->StackSize = (CCHAR)IrpStackSize;
|
|
|
|
//
|
|
// Initialize the driver object with this driver's entry points.
|
|
//
|
|
|
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)NwFsdCreate;
|
|
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = (PDRIVER_DISPATCH)NwFsdCleanup;
|
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)NwFsdClose;
|
|
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = (PDRIVER_DISPATCH)NwFsdFileSystemControl;
|
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)NwFsdDeviceIoControl;
|
|
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = (PDRIVER_DISPATCH)NwFsdQueryInformation;
|
|
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)NwFsdQueryVolumeInformation;
|
|
DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)NwFsdSetVolumeInformation;
|
|
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = (PDRIVER_DISPATCH)NwFsdDirectoryControl;
|
|
DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH)NwFsdRead;
|
|
DriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH)NwFsdWrite;
|
|
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = (PDRIVER_DISPATCH)NwFsdSetInformation;
|
|
DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = (PDRIVER_DISPATCH)NwFsdLockControl;
|
|
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = (PDRIVER_DISPATCH)NwFsdFlushBuffers;
|
|
|
|
#ifdef _PNP_POWER_
|
|
DriverObject->MajorFunction[IRP_MJ_PNP] = (PDRIVER_DISPATCH)NwFsdProcessPnpIrp;
|
|
#endif
|
|
|
|
/*
|
|
DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = (PDRIVER_DISPATCH)NwFsdQueryEa;
|
|
DriverObject->MajorFunction[IRP_MJ_SET_EA] = (PDRIVER_DISPATCH)NwFsdSetEa;
|
|
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = (PDRIVER_DISPATCH)NwFsdShutdown;
|
|
*/
|
|
DriverObject->DriverUnload = UnloadDriver;
|
|
|
|
#if NWFASTIO
|
|
DriverObject->FastIoDispatch = &NwFastIoDispatch;
|
|
|
|
NwFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
|
|
NwFastIoDispatch.FastIoCheckIfPossible = NULL;
|
|
NwFastIoDispatch.FastIoRead = NwFastRead;
|
|
NwFastIoDispatch.FastIoWrite = NwFastWrite;
|
|
NwFastIoDispatch.FastIoQueryBasicInfo = NwFastQueryBasicInfo;
|
|
NwFastIoDispatch.FastIoQueryStandardInfo = NwFastQueryStandardInfo;
|
|
NwFastIoDispatch.FastIoLock = NULL;
|
|
NwFastIoDispatch.FastIoUnlockSingle = NULL;
|
|
NwFastIoDispatch.FastIoUnlockAll = NULL;
|
|
NwFastIoDispatch.FastIoUnlockAllByKey = NULL;
|
|
NwFastIoDispatch.FastIoDeviceControl = NULL;
|
|
#endif
|
|
|
|
NwInitializeRcb( &NwRcb );
|
|
|
|
InitializeIrpContext( );
|
|
|
|
NwPermanentNpScb.State = SCB_STATE_DISCONNECTING;
|
|
|
|
//
|
|
// Do a kludge here so that we get to the "real" global variables.
|
|
//
|
|
|
|
//NlsLeadByteInfo = *(PUSHORT *)NlsLeadByteInfo;
|
|
//NlsMbCodePageTag = *(*(PBOOLEAN *)&NlsMbCodePageTag);
|
|
|
|
#ifndef IFS
|
|
FsRtlLegalAnsiCharacterArray = *(PUCHAR *)FsRtlLegalAnsiCharacterArray;
|
|
#endif
|
|
|
|
//
|
|
// Register as a file system, notifies filters
|
|
//
|
|
|
|
IoRegisterFileSystem(FileSystemDeviceObject);
|
|
|
|
DebugTrace(0, Dbg, "NetWare redirector loaded\n", 0);
|
|
|
|
//
|
|
// And return to our caller
|
|
//
|
|
|
|
return( STATUS_SUCCESS );
|
|
}
|
|
|
|
VOID
|
|
UnloadDriver(
|
|
IN PDRIVER_OBJECT DriverObject
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is the unload routine for the NetWare redirector filesystem.
|
|
|
|
Arguments:
|
|
|
|
DriverObject - pointer to the driver object for the redirector
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
KIRQL OldIrql;
|
|
NTSTATUS status;
|
|
|
|
//
|
|
// Lock down code
|
|
//
|
|
DebugTrace(0, Dbg, "UnloadDriver called\n", 0);
|
|
|
|
//
|
|
// Unregister as a file system, notifies filters
|
|
//
|
|
|
|
IoUnregisterFileSystem(FileSystemDeviceObject);
|
|
|
|
//
|
|
// tommye - MS bug 33463
|
|
//
|
|
// Clean up our cached credentials - this fixes a
|
|
// memory leak when we shut down.
|
|
//
|
|
|
|
{
|
|
LARGE_INTEGER Unused;
|
|
|
|
KeQuerySystemTime( &Unused );
|
|
|
|
CleanupSupplementalCredentials(Unused, TRUE);
|
|
}
|
|
|
|
NwReferenceUnlockableCodeSection ();
|
|
|
|
TerminateWorkerThread();
|
|
|
|
#ifdef _PNP_POWER_
|
|
|
|
//
|
|
// Unregister the bind handler with tdi.
|
|
//
|
|
|
|
if ( TdiBindingHandle != NULL ) {
|
|
status = TdiDeregisterPnPHandlers( TdiBindingHandle );
|
|
TdiBindingHandle = NULL;
|
|
DebugTrace(0, Dbg,"TDI binding handle deregistered\n",0);
|
|
}
|
|
|
|
#endif
|
|
|
|
IpxClose();
|
|
|
|
IPX_Close_Socket( &NwPermanentNpScb.Server );
|
|
|
|
KeAcquireSpinLock( &ScbSpinLock, &OldIrql );
|
|
RemoveEntryList( &NwPermanentNpScb.ScbLinks );
|
|
KeReleaseSpinLock( &ScbSpinLock, OldIrql );
|
|
|
|
DestroyAllScb();
|
|
|
|
UninitializeIrpContext();
|
|
|
|
NwDereferenceUnlockableCodeSection ();
|
|
NwUnlockCodeSections(FALSE);
|
|
StopTimer();
|
|
|
|
if (IpxTransportName.Buffer != NULL) {
|
|
|
|
FREE_POOL(IpxTransportName.Buffer);
|
|
|
|
}
|
|
|
|
if ( NwProviderName.Buffer != NULL ) {
|
|
FREE_POOL( NwProviderName.Buffer );
|
|
}
|
|
|
|
//NwUninitializePidTable(); //Terminal Server code merge -
|
|
//NwUninitializePidTable is called in
|
|
//NwDeleteScb. Pid table is per SCB base.
|
|
|
|
ASSERT( IsListEmpty( &NwPagedPoolList ) );
|
|
ASSERT( IsListEmpty( &NwNonpagedPoolList ) );
|
|
|
|
ASSERT( MdlCount == 0 );
|
|
ASSERT( IrpCount == 0 );
|
|
|
|
NwDeleteRcb( &NwRcb );
|
|
|
|
#ifdef NWDBG
|
|
ExDeleteResourceLite( &NwDebugResource );
|
|
#endif
|
|
|
|
ExDeleteResourceLite( &NwOpenResource );
|
|
ExDeleteResourceLite( &NwUnlockableCodeResource );
|
|
|
|
IoDeleteDevice(FileSystemDeviceObject);
|
|
|
|
DebugTrace(0, Dbg, "NetWare redirector unloaded\n\n", 0);
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
GetConfigurationInformation(
|
|
PUNICODE_STRING RegistryPath
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine read redirector configuration information from the registry.
|
|
|
|
Arguments:
|
|
|
|
RegistryPath - A pointer the a path to the
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
UNICODE_STRING UnicodeString;
|
|
HANDLE ConfigHandle;
|
|
HANDLE ParametersHandle;
|
|
NTSTATUS Status;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
ULONG TimeOutEventinMins = 0L;
|
|
LCID lcid;
|
|
|
|
PAGED_CODE();
|
|
|
|
Japan = FALSE;
|
|
Korean = FALSE;
|
|
|
|
|
|
ZwQueryDefaultLocale( FALSE, &lcid );
|
|
|
|
if (PRIMARYLANGID(lcid) == LANG_JAPANESE ||
|
|
PRIMARYLANGID(lcid) == LANG_KOREAN ||
|
|
PRIMARYLANGID(lcid) == LANG_CHINESE) {
|
|
|
|
Japan = TRUE;
|
|
if (PRIMARYLANGID(lcid) == LANG_KOREAN){
|
|
Korean = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
InitializeObjectAttributes(
|
|
&ObjectAttributes,
|
|
RegistryPath, // name
|
|
OBJ_CASE_INSENSITIVE, // attributes
|
|
NULL, // root
|
|
NULL // security descriptor
|
|
);
|
|
|
|
Status = ZwOpenKey ( &ConfigHandle, KEY_READ, &ObjectAttributes );
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
return;
|
|
}
|
|
|
|
RtlInitUnicodeString( &UnicodeString, L"Parameters" );
|
|
|
|
InitializeObjectAttributes(
|
|
&ObjectAttributes,
|
|
&UnicodeString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
ConfigHandle,
|
|
NULL
|
|
);
|
|
|
|
Status = ZwOpenKey( &ParametersHandle, KEY_READ, &ObjectAttributes );
|
|
|
|
if ( !NT_SUCCESS( Status ) ) {
|
|
ZwClose( ConfigHandle );
|
|
return;
|
|
}
|
|
|
|
ReadValue( ParametersHandle, &IrpStackSize, L"IrpStackSize" );
|
|
|
|
ReadValue( ParametersHandle, &MaxSendDelay, L"MaxSendDelay" );
|
|
ReadValue( ParametersHandle, &MaxReceiveDelay, L"MaxReceiveDelay" );
|
|
|
|
ReadValue( ParametersHandle, &MinSendDelay, L"MinSendDelay" );
|
|
ReadValue( ParametersHandle, &MinReceiveDelay, L"MinReceiveDelay" );
|
|
|
|
ReadValue( ParametersHandle, &BurstSuccessCount, L"BurstSuccessCount" );
|
|
ReadValue( ParametersHandle, &BurstSuccessCount2, L"BurstSuccessCount2" );
|
|
ReadValue( ParametersHandle, &MaxReadTimeout, L"MaxReadTimeout" );
|
|
ReadValue( ParametersHandle, &MaxWriteTimeout, L"MaxWriteTimeout" );
|
|
ReadValue( ParametersHandle, &ReadTimeoutMultiplier, L"ReadTimeoutMultiplier" );
|
|
ReadValue( ParametersHandle, &WriteTimeoutMultiplier, L"WriteTimeoutMultiplier" );
|
|
ReadValue( ParametersHandle, &AllowGrowth, L"AllowGrowth" );
|
|
ReadValue( ParametersHandle, &DontShrink, L"DontShrink" );
|
|
ReadValue( ParametersHandle, &SendExtraNcp, L"SendExtraNcp" );
|
|
ReadValue( ParametersHandle, &DefaultMaxPacketSize, L"DefaultMaxPacketSize" );
|
|
ReadValue( ParametersHandle, &PacketThreshold, L"PacketThreshold" );
|
|
ReadValue( ParametersHandle, &LargePacketAdjustment, L"LargePacketAdjustment" );
|
|
ReadValue( ParametersHandle, &LipPacketAdjustment, L"LipPacketAdjustment" );
|
|
ReadValue( ParametersHandle, &LipAccuracy, L"LipAccuracy" );
|
|
|
|
ReadValue( ParametersHandle, &DisableReadCache, L"DisableReadCache" );
|
|
ReadValue( ParametersHandle, &DisableWriteCache, L"DisableWriteCache" );
|
|
ReadValue( ParametersHandle, &FavourLongNames, L"FavourLongNames" );
|
|
|
|
ReadValue( ParametersHandle, &LongNameFlags, L"LongNameFlags" );
|
|
|
|
ReadValue( ParametersHandle, &DirCacheEntries, L"DirectoryCacheSize" );
|
|
if( DirCacheEntries == 0 ) {
|
|
DirCacheEntries = 1;
|
|
}
|
|
if( DirCacheEntries > MAX_DIR_CACHE_ENTRIES ) {
|
|
DirCacheEntries = MAX_DIR_CACHE_ENTRIES;
|
|
}
|
|
|
|
ReadValue( ParametersHandle, &LockTimeoutThreshold, L"LockTimeout" );
|
|
|
|
ReadValue( ParametersHandle, &TimeOutEventinMins, L"TimeOutEventinMins");
|
|
|
|
ReadValue( ParametersHandle, &EnableMultipleConnects, L"EnableMultipleConnects");
|
|
|
|
ReadValue( ParametersHandle, &AllowSeedServerRedirection, L"AllowSeedServerRedirection");
|
|
|
|
ReadValue( ParametersHandle, &ReadExecOnlyFiles, L"ReadExecOnlyFiles");
|
|
|
|
ReadValue( ParametersHandle, &DisableAltFileName, L"DisableAltFileName");
|
|
|
|
ReadValue( ParametersHandle, &NwAbsoluteTotalWaitTime, L"AbsoluteTotalWaitTime");
|
|
|
|
ReadValue( ParametersHandle, &NdsObjectCacheSize, L"NdsObjectCacheSize" );
|
|
|
|
ReadValue( ParametersHandle, &NdsObjectCacheTimeout, L"NdsObjectCacheTimeout" );
|
|
|
|
ReadValue ( ParametersHandle, &PreferNDSBrowsing, L"PreferNDSBrowsing" );
|
|
|
|
//
|
|
// Make sure the object cache values are within bounds.
|
|
//
|
|
// NOTE: If the timeout is set to zero, then the cache is
|
|
// effectively disabled. NdsObjectCacheSize is set
|
|
// to zero to accomplish this.
|
|
//
|
|
|
|
if( NdsObjectCacheSize > MAX_NDS_OBJECT_CACHE_SIZE ) {
|
|
NdsObjectCacheSize = MAX_NDS_OBJECT_CACHE_SIZE;
|
|
}
|
|
|
|
if( NdsObjectCacheTimeout > MAX_NDS_OBJECT_CACHE_TIMEOUT ) {
|
|
NdsObjectCacheTimeout = MAX_NDS_OBJECT_CACHE_TIMEOUT;
|
|
|
|
} else if( NdsObjectCacheTimeout == 0 ) {
|
|
NdsObjectCacheSize = 0;
|
|
}
|
|
|
|
if (!TimeOutEventinMins) {
|
|
//
|
|
// If for some reason, the registry has set the TimeOutEventInterval
|
|
// to zero, reset to the default value to avoid divide-by-zero
|
|
//
|
|
|
|
TimeOutEventinMins = DEFAULT_TIMEOUT_EVENT_INTERVAL;
|
|
}
|
|
|
|
TimeOutEventInterval.QuadPart = TimeOutEventinMins * 60 * SECONDS;
|
|
|
|
//
|
|
// tommye - MS bug 2743 we now get the RetryCount from the registry, providing
|
|
// a default of DEFAULT_RETRY_COUNT.
|
|
//
|
|
|
|
{
|
|
LONG TempRetryCount;
|
|
|
|
TempRetryCount = DEFAULT_RETRY_COUNT;
|
|
ReadValue( ParametersHandle, &TempRetryCount, L"DefaultRetryCount");
|
|
DefaultRetryCount = (SHORT) TempRetryCount & 0xFFFF;
|
|
}
|
|
|
|
ZwClose( ParametersHandle );
|
|
ZwClose( ConfigHandle );
|
|
|
|
|
|
}
|
|
|
|
VOID
|
|
ReadValue(
|
|
HANDLE ParametersHandle,
|
|
PLONG pVar,
|
|
PWCHAR Name
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine reads a single redirector configuration value from the registry.
|
|
|
|
Arguments:
|
|
|
|
Parameters - Supplies where to look for values.
|
|
|
|
pVar - Address of the variable to receive the new value if the name exists.
|
|
|
|
Name - Name whose value is to be loaded.
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
WCHAR Storage[256];
|
|
UNICODE_STRING UnicodeString;
|
|
NTSTATUS Status;
|
|
ULONG BytesRead;
|
|
PKEY_VALUE_FULL_INFORMATION Value = (PKEY_VALUE_FULL_INFORMATION)Storage;
|
|
|
|
PAGED_CODE();
|
|
|
|
UnicodeString.Buffer = Storage;
|
|
|
|
RtlInitUnicodeString(&UnicodeString, Name );
|
|
|
|
Status = ZwQueryValueKey(
|
|
ParametersHandle,
|
|
&UnicodeString,
|
|
KeyValueFullInformation,
|
|
Value,
|
|
sizeof(Storage),
|
|
&BytesRead );
|
|
|
|
if ( NT_SUCCESS( Status ) ) {
|
|
|
|
if ( Value->DataLength >= sizeof(ULONG) ) {
|
|
|
|
*pVar = *(LONG UNALIGNED *)( (PCHAR)Value + Value->DataOffset );
|
|
|
|
}
|
|
}
|
|
}
|