WindowsXP-SP1/ds/nw/rdr/data.c

443 lines
10 KiB
C

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
NwData.c
Abstract:
This module declares the global data used by the Nw file system.
Author:
Colin Watson [ColinW] 19-Dec-1992
Anoop Anantha [AnoopA] 24-Jun-1998
Revision History:
--*/
#include "Procs.h"
#include <stdlib.h>
//
// The debug trace level
//
#define Dbg (DEBUG_TRACE_CATCH_EXCEPTIONS)
PEPROCESS FspProcess;
PDEVICE_OBJECT FileSystemDeviceObject = NULL;
//
// The volume control block for the redirector device.
//
RCB NwRcb;
//
// The ScbSpinLock protects the entire ScbQueue and the first part of the
// Scb entries on the queue. The first part of the Scb includes the name
// of the server and a reference count
//
KSPIN_LOCK ScbSpinLock;
LIST_ENTRY ScbQueue;
//
// The NwTimerSpinLock protects the Timer and TimerStop flag.
//
KSPIN_LOCK NwTimerSpinLock;
//
// A permanent SCB to synchronize access to the network.
//
NONPAGED_SCB NwPermanentNpScb;
LARGE_INTEGER NwMaxLarge = {MAXULONG,MAXLONG};
//
// tommye MS 90541 / MCS 277
//
// Set NwAbsoluteTotalWaitTime to 200, which is 100 half-seconds (duh). This gets
// referenced in NwProcessPositiveAck, which comes from the TimerDPC about every
// half second or so. This is the longest about of retries that we will send a
// packet that we've gotten a positive ACK on.
//
ULONG NwAbsoluteTotalWaitTime = 200;
TDI_ADDRESS_IPX OurAddress = {0,0,0,0,0,0,0,0};
UNICODE_STRING IpxTransportName;
HANDLE IpxHandle = NULL;
PDEVICE_OBJECT pIpxDeviceObject = NULL;
PFILE_OBJECT pIpxFileObject = NULL;
LIST_ENTRY LogonList;
LOGON Guest;
LARGE_INTEGER DefaultLuid = SYSTEM_LUID;
//
// A global list of VCBs, and a monotonic increasing VCB entry, used to
// control connection enumeration.
//
LIST_ENTRY GlobalVcbList;
ULONG CurrentVcbEntry;
#if 0
//
// HACKHACK - List of outstanding find notify request
// Protected by NwRcb resource.
//
LIST_ENTRY FnList;
#endif
//
// Drive mapping table of redirected drives. 26 disk drive mappings +
// 10 LPT mappings.
//
// Netware supports 32 disk redirections, but this funkiness is handled
// by the 16-bit code.
//
PVCB GlobalDriveMapTable[DRIVE_MAP_TABLE_SIZE]; //MultiUser
FAST_IO_DISPATCH NwFastIoDispatch;
//
// Scavenger related data
//
ULONG NwScavengerTickCount; // The current tick count
ULONG NwScavengerTickRunCount; // The count at which to run the scavenger routine
KSPIN_LOCK NwScavengerSpinLock; // Lock to protect access to the above.
//
// Worker thread
//
BOOLEAN WorkerThreadRunning = FALSE;
//
// Message queue data
//
LIST_ENTRY NwGetMessageList; // List of Get Message IRP contexts
KSPIN_LOCK NwMessageSpinLock; // Protects the list above.
//
// Pending lock list
//
LIST_ENTRY NwPendingLockList; // List of pending File lock IRP contexts
KSPIN_LOCK NwPendingLockSpinLock;// Protects the list above.
//
// Lock to synchronize all file opens.
//
ERESOURCE NwOpenResource;
//
// Configuration data
//
LONG PreferNDSBrowsing = 0; // when attempting to connect to UNC paths, attempt NDS connection first
BOOLEAN NwBurstModeEnabled = FALSE;
ULONG NwMaxSendSize = 0;
ULONG NwMaxReceiveSize = 0;
ULONG NwPrintOptions = 0x98;
UNICODE_STRING NwProviderName = { 0, 0, NULL };
LONG MaxSendDelay = 50000;
LONG MaxReceiveDelay = 50000;
LONG MinSendDelay = 0;
LONG MinReceiveDelay = 0;
LONG BurstSuccessCount = 1;
LONG BurstSuccessCount2 = 3;
LONG AllowGrowth = 0;
LONG DontShrink = 0;
LONG SendExtraNcp = 1;
LONG DefaultMaxPacketSize = 0;
LONG PacketThreshold = 1500; // Size to use Large vs Small PacketAdjustment
LONG LargePacketAdjustment = 38;
LONG LipPacketAdjustment = 0;
LONG LipAccuracy = BURST_PACKET_SIZE_TOLERANCE;
LONG Japan = 0; // Controls special DBCS translation
LONG Korean = 0; // Controls special Korean translation
LONG DisableReadCache = 0; // disable file i/o read cache
LONG DisableWriteCache = 0; // disable file i/o write cache
LONG FavourLongNames = 1 ; // use LFN where possible
DWORD LongNameFlags = 0; // flags for handling long names
ULONG DirCacheEntries = 1; // number of directory entries we cache
LARGE_INTEGER TimeOutEventInterval = {0, 0};
LONG MaxWriteTimeout = 50 ; // tick counts (see write.c)
LONG MaxReadTimeout = 50 ; // tick counts (see read.c)
LONG WriteTimeoutMultiplier = 100; // expressed as percentage (see write.c)
LONG ReadTimeoutMultiplier = 100; // expressed as percentage (see read.c)
ULONG EnableMultipleConnects = 0;
ULONG AllowSeedServerRedirection = 0;
ULONG ReadExecOnlyFiles = 0;
ULONG DisableAltFileName = 1;
ULONG NdsObjectCacheSize = 0;
ULONG NdsObjectCacheTimeout = 10;
//
// Static storage area for perfmon statistics
//
NW_REDIR_STATISTICS Stats;
ULONG ContextCount = 0;
//
// Data structure used to track discardable code.
//
SECTION_DESCRIPTOR NwSectionDescriptor;
ERESOURCE NwUnlockableCodeResource;
//
// The lock timeout value.
//
ULONG LockTimeoutThreshold = 1;
//
// The Kernel Queue from where the reconnect work items are picked up.
//
KQUEUE KernelQueue;
#ifndef _PNP_POWER_
//
// The TDI PNP Bind handle.
//
HANDLE TdiBindingHandle = NULL;
UNICODE_STRING TdiIpxDeviceName;
WCHAR IpxDevice[] = L"\\Device\\NwlnkIpx";
#endif
//
// We can't have the scavenger and a line change request running
// at the same time since they both run on worker threads and
// walk across all the SCBs. Therefore, when either is running,
// we set the WorkerRunning value used by the scavenger to TRUE.
// If a scavenger run tries to happen while a line change request
// is running, it gets skipped. If a line change request comes in
// while the scavenger is running, we set DelayedProcessLineChange
// to TRUE and run it when the scavenger finishes.
//
// These values are protected by the existing scavenger spin lock.
//
BOOLEAN DelayedProcessLineChange = FALSE;
PIRP DelayedLineChangeIrp = NULL;
#ifdef NWDBG
ULONG NwDebug = 0;
//ULONG NwDebug = 0xffffffbf;
ULONG NwMemDebug = 0xffffffff;
LONG NwDebugTraceIndent = 0;
ULONG NwFsdEntryCount = 0;
ULONG NwFspEntryCount = 0;
ULONG NwIoCallDriverCount = 0;
LONG NwPerformanceTimerLevel = 0x00000000;
ULONG NwTotalTicks[32] = { 0 };
//
// Debug data for tracking pool usage
//
KSPIN_LOCK NwDebugInterlock;
ERESOURCE NwDebugResource;
LIST_ENTRY NwPagedPoolList;
LIST_ENTRY NwNonpagedPoolList;
ULONG MdlCount;
ULONG IrpCount;
#endif // NWDBG
//
// Configurable parameters.
//
SHORT DefaultRetryCount = DEFAULT_RETRY_COUNT;
#ifdef _PNP_POWER_
BOOLEAN fPoweringDown = FALSE;
#endif
#ifdef ALLOC_PRAGMA
#pragma alloc_text( PAGE, NwInitializeData )
#endif
VOID
NwInitializeData(
VOID
)
{
LARGE_INTEGER Now;
PAGED_CODE();
NwRcb.State = RCB_STATE_STOPPED;
#ifdef NWDBG
// Initialize pool before allocating any memory
InitializeListHead( &NwPagedPoolList );
InitializeListHead( &NwNonpagedPoolList );
ExInitializeResourceLite( &NwDebugResource );
KeInitializeSpinLock( &NwDebugInterlock );
MdlCount = 0;
IrpCount = 0;
#endif
ExInitializeResourceLite( &NwOpenResource );
//
// Initialize the scavenger spin lock and run tick count.
//
KeInitializeSpinLock( &NwScavengerSpinLock );
NwScavengerTickRunCount = DEFAULT_SCAVENGER_TICK_RUN_COUNT;
//
// Initialize the timer spin lock.
//
KeInitializeSpinLock( &NwTimerSpinLock );
RtlInitUnicodeString( &IpxTransportName, NULL );
#ifndef _PNP_POWER_
RtlInitUnicodeString( &TdiIpxDeviceName, IpxDevice );
#endif
//
// Allocate a permanent Non-paged SCB. This SCB is used to
// synchronize access to finding the nearest server.
// This initialization must be done before the first possible call
// to UnloadDriver.
//
RtlZeroMemory( &NwPermanentNpScb, sizeof( NONPAGED_SCB ) );
NwPermanentNpScb.NodeTypeCode = NW_NTC_SCBNP;
NwPermanentNpScb.NodeByteSize = sizeof(NONPAGED_SCB);
NwPermanentNpScb.Reference = 1;
InitializeListHead( &NwPermanentNpScb.Requests );
//
// Initialize the logonlist to have a default entry with server NULL,
// username "GUEST" and null password. This will always be the last
// entry on the logonlist so that the workstation service can supply
// an override.
//
InitializeListHead( &LogonList );
Guest.NodeTypeCode = NW_NTC_LOGON;
Guest.NodeByteSize = sizeof(LOGON);
{
//Multi-user. Initialize the DriveMapTable
int i;
for ( i = 0; i < DRIVE_MAP_TABLE_SIZE; i ++ )
Guest.DriveMapTable[i] = NULL;
}
RtlInitUnicodeString( &Guest.ServerName, NULL );
RtlInitUnicodeString( &Guest.PassWord, NULL );
RtlInitUnicodeString( &Guest.UserName, L"GUEST" );
Guest.UserUid = DefaultLuid;
InitializeListHead( &Guest.NdsCredentialList );
InsertTailList( &LogonList, &Guest.Next );
//
// Initialize the global VCB list.
//
InitializeListHead( &GlobalVcbList );
CurrentVcbEntry = 1;
//
// Initialize the Get message queue.
//
InitializeListHead( &NwGetMessageList );
KeInitializeSpinLock( &NwMessageSpinLock );
//
// Initialize the Pending lock queue.
//
InitializeListHead( &NwPendingLockList );
KeInitializeSpinLock( &NwPendingLockSpinLock );
//
// Insert the Permanent SCB in the global list of SCBs.
//
InsertHeadList( &ScbQueue, &NwPermanentNpScb.ScbLinks );
//
// Initialize the Kernel Queue Object. Only one thread has to
// be concurrently active.
//
KeInitializeQueue( &KernelQueue, 1 );
//
// Spawn off our own worker thread which will service reroute and
// reconnect attempts.
//
SpawnWorkerThread();
#if 0
// HACKHACK
InitializeListHead( &FnList );
#endif
//
// Seed the random number generator.
//
KeQuerySystemTime( &Now );
srand( Now.LowPart );
RtlZeroMemory( &Stats, sizeof( NW_REDIR_STATISTICS ) );
ExInitializeResourceLite( &NwUnlockableCodeResource );
NwSectionDescriptor.Base = BurstReadTimeout;
NwSectionDescriptor.Handle = 0;
NwSectionDescriptor.ReferenceCount = 0;
return;
}