1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
|
/*++
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
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;
//
// A permanent SCB to synchronize access to the network.
//
NONPAGED_SCB NwPermanentNpScb;
LARGE_INTEGER NwMaxLarge = {MAXULONG,MAXLONG};
ULONG NwAbsoluteTotalWaitTime = 0;
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 DriveMapTable[DRIVE_MAP_TABLE_SIZE];
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.
//
// 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
//
BOOLEAN NwBurstModeEnabled = FALSE;
ULONG NwMaxSendSize = 0;
ULONG NwMaxReceiveSize = 0;
ULONG NwPrintOptions = 0x98; // BUGBUG
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 DisableReadCache = 0; // disable file i/o read cache
LONG DisableWriteCache = 0; // disable file i/o write cache
LONG FavourLongNames = 0 ; // use LFN where possible
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 ReadExecOnlyFiles = 0;
//
// 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;
#ifdef _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 = 0xffffff;
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 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 );
ExInitializeResource( &NwDebugResource );
KeInitializeSpinLock( &NwDebugInterlock );
MdlCount = 0;
IrpCount = 0;
#endif
ExInitializeResource( &NwOpenResource );
//
// Initialize the scavenger spin lock and run tick count.
//
KeInitializeSpinLock( &NwScavengerSpinLock );
NwScavengerTickRunCount = DEFAULT_SCAVENGER_TICK_RUN_COUNT;
RtlInitUnicodeString( &IpxTransportName, NULL );
#ifdef _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);
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 );
#if 0
// HACKHACK
InitializeListHead( &FnList );
#endif
//
// Seed the random number generator.
//
KeQuerySystemTime( &Now );
srand( Now.LowPart );
RtlZeroMemory( &Stats, sizeof( NW_REDIR_STATISTICS ) );
ExInitializeResource( &NwUnlockableCodeResource );
NwSectionDescriptor.Base = BurstReadTimeout;
NwSectionDescriptor.Handle = 0;
NwSectionDescriptor.ReferenceCount = 0;
return;
}
|