Leaked source code of windows server 2003
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

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. NwInit.c
  5. Abstract:
  6. This module implements the DRIVER_INITIALIZATION routine for NetWare
  7. Author:
  8. Colin Watson [ColinW] 15-Dec-1992
  9. Revision History:
  10. --*/
  11. #include "Procs.h"
  12. #include "wdmsec.h"
  13. #define Dbg (DEBUG_TRACE_LOAD)
  14. //
  15. // Private declaration because ZwQueryDefaultLocale isn't in any header.
  16. //
  17. NTSYSAPI
  18. NTSTATUS
  19. NTAPI
  20. ZwQueryDefaultLocale(
  21. IN BOOLEAN UserProfile,
  22. OUT PLCID DefaultLocaleId
  23. );
  24. NTSTATUS
  25. DriverEntry(
  26. IN PDRIVER_OBJECT DriverObject,
  27. IN PUNICODE_STRING RegistryPath
  28. );
  29. VOID
  30. UnloadDriver(
  31. IN PDRIVER_OBJECT DriverObject
  32. );
  33. VOID
  34. GetConfigurationInformation(
  35. PUNICODE_STRING RegistryPath
  36. );
  37. VOID
  38. ReadValue(
  39. HANDLE ParametersHandle,
  40. PLONG pVar,
  41. PWCHAR Name
  42. );
  43. #ifdef ALLOC_PRAGMA
  44. #pragma alloc_text( PAGE, DriverEntry )
  45. #pragma alloc_text( PAGE, GetConfigurationInformation )
  46. #pragma alloc_text( PAGE, ReadValue )
  47. #endif
  48. #if 0 // Not pageable
  49. UnloadDriver
  50. #endif
  51. #ifdef _PNP_POWER_
  52. extern HANDLE TdiBindingHandle;
  53. #endif
  54. static ULONG IrpStackSize;
  55. NTSTATUS
  56. DriverEntry(
  57. IN PDRIVER_OBJECT DriverObject,
  58. IN PUNICODE_STRING RegistryPath
  59. )
  60. /*++
  61. Routine Description:
  62. This is the initialization routine for the Nw file system
  63. device driver. This routine creates the device object for the FileSystem
  64. device and performs all other driver initialization.
  65. Arguments:
  66. DriverObject - Pointer to driver object created by the system.
  67. Return Value:
  68. NTSTATUS - The function value is the final status from the initialization
  69. operation.
  70. --*/
  71. {
  72. NTSTATUS Status;
  73. UNICODE_STRING UnicodeString;
  74. UNICODE_STRING SddlString;
  75. PAGED_CODE();
  76. //DbgBreakPoint();
  77. InitializeAttach( );
  78. NwInitializeData();
  79. //NwInitializePidTable(); // Terminal Server code merge -
  80. // NwInitalizePidTable in the NwAllocateAndInitScb
  81. // Pid table is per SCB base.
  82. //
  83. // Create the device object.
  84. //
  85. RtlInitUnicodeString( &UnicodeString, DD_NWFS_DEVICE_NAME_U );
  86. RtlInitUnicodeString( &SddlString, L"D:P(A;;GX;;;WD)(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;LS)(A;;GA;;;NS)(A;;GX;;;RC)" );
  87. Status = IoCreateDeviceSecure( DriverObject,
  88. 0,
  89. &UnicodeString,
  90. FILE_DEVICE_NETWORK_FILE_SYSTEM,
  91. FILE_REMOTE_DEVICE,
  92. FALSE,
  93. &SddlString,
  94. NULL,
  95. &FileSystemDeviceObject );
  96. if (!NT_SUCCESS( Status )) {
  97. Error(EVENT_NWRDR_CANT_CREATE_DEVICE, Status, NULL, 0, 0);
  98. return Status;
  99. }
  100. //
  101. // Initialize parameters to the defaults.
  102. //
  103. IrpStackSize = NWRDR_IO_STACKSIZE;
  104. //
  105. // Attempt to read config information from the registry
  106. //
  107. GetConfigurationInformation( RegistryPath );
  108. //
  109. // Set the stack size.
  110. //
  111. FileSystemDeviceObject->StackSize = (CCHAR)IrpStackSize;
  112. //
  113. // Initialize the driver object with this driver's entry points.
  114. //
  115. DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)NwFsdCreate;
  116. DriverObject->MajorFunction[IRP_MJ_CLEANUP] = (PDRIVER_DISPATCH)NwFsdCleanup;
  117. DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)NwFsdClose;
  118. DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = (PDRIVER_DISPATCH)NwFsdFileSystemControl;
  119. DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)NwFsdDeviceIoControl;
  120. DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = (PDRIVER_DISPATCH)NwFsdQueryInformation;
  121. DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)NwFsdQueryVolumeInformation;
  122. DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)NwFsdSetVolumeInformation;
  123. DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = (PDRIVER_DISPATCH)NwFsdDirectoryControl;
  124. DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH)NwFsdRead;
  125. DriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH)NwFsdWrite;
  126. DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = (PDRIVER_DISPATCH)NwFsdSetInformation;
  127. DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = (PDRIVER_DISPATCH)NwFsdLockControl;
  128. DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = (PDRIVER_DISPATCH)NwFsdFlushBuffers;
  129. #ifdef _PNP_POWER_
  130. DriverObject->MajorFunction[IRP_MJ_PNP] = (PDRIVER_DISPATCH)NwFsdProcessPnpIrp;
  131. #endif
  132. /*
  133. DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = (PDRIVER_DISPATCH)NwFsdQueryEa;
  134. DriverObject->MajorFunction[IRP_MJ_SET_EA] = (PDRIVER_DISPATCH)NwFsdSetEa;
  135. DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = (PDRIVER_DISPATCH)NwFsdShutdown;
  136. */
  137. DriverObject->DriverUnload = UnloadDriver;
  138. #if NWFASTIO
  139. DriverObject->FastIoDispatch = &NwFastIoDispatch;
  140. NwFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
  141. NwFastIoDispatch.FastIoCheckIfPossible = NULL;
  142. NwFastIoDispatch.FastIoRead = NwFastRead;
  143. NwFastIoDispatch.FastIoWrite = NwFastWrite;
  144. NwFastIoDispatch.FastIoQueryBasicInfo = NwFastQueryBasicInfo;
  145. NwFastIoDispatch.FastIoQueryStandardInfo = NwFastQueryStandardInfo;
  146. NwFastIoDispatch.FastIoLock = NULL;
  147. NwFastIoDispatch.FastIoUnlockSingle = NULL;
  148. NwFastIoDispatch.FastIoUnlockAll = NULL;
  149. NwFastIoDispatch.FastIoUnlockAllByKey = NULL;
  150. NwFastIoDispatch.FastIoDeviceControl = NULL;
  151. #endif
  152. NwInitializeRcb( &NwRcb );
  153. InitializeIrpContext( );
  154. NwPermanentNpScb.State = SCB_STATE_DISCONNECTING;
  155. //
  156. // Do a kludge here so that we get to the "real" global variables.
  157. //
  158. //NlsLeadByteInfo = *(PUSHORT *)NlsLeadByteInfo;
  159. //NlsMbCodePageTag = *(*(PBOOLEAN *)&NlsMbCodePageTag);
  160. #ifndef IFS
  161. FsRtlLegalAnsiCharacterArray = *(PUCHAR *)FsRtlLegalAnsiCharacterArray;
  162. #endif
  163. //
  164. // Register as a file system, notifies filters
  165. //
  166. IoRegisterFileSystem(FileSystemDeviceObject);
  167. DebugTrace(0, Dbg, "NetWare redirector loaded\n", 0);
  168. //
  169. // And return to our caller
  170. //
  171. return( STATUS_SUCCESS );
  172. }
  173. VOID
  174. UnloadDriver(
  175. IN PDRIVER_OBJECT DriverObject
  176. )
  177. /*++
  178. Routine Description:
  179. This is the unload routine for the NetWare redirector filesystem.
  180. Arguments:
  181. DriverObject - pointer to the driver object for the redirector
  182. Return Value:
  183. None
  184. --*/
  185. {
  186. KIRQL OldIrql;
  187. NTSTATUS status;
  188. //
  189. // Lock down code
  190. //
  191. DebugTrace(0, Dbg, "UnloadDriver called\n", 0);
  192. //
  193. // Unregister as a file system, notifies filters
  194. //
  195. IoUnregisterFileSystem(FileSystemDeviceObject);
  196. //
  197. // tommye - MS bug 33463
  198. //
  199. // Clean up our cached credentials - this fixes a
  200. // memory leak when we shut down.
  201. //
  202. {
  203. LARGE_INTEGER Unused;
  204. KeQuerySystemTime( &Unused );
  205. CleanupSupplementalCredentials(Unused, TRUE);
  206. }
  207. NwReferenceUnlockableCodeSection ();
  208. TerminateWorkerThread();
  209. #ifdef _PNP_POWER_
  210. //
  211. // Unregister the bind handler with tdi.
  212. //
  213. if ( TdiBindingHandle != NULL ) {
  214. status = TdiDeregisterPnPHandlers( TdiBindingHandle );
  215. TdiBindingHandle = NULL;
  216. DebugTrace(0, Dbg,"TDI binding handle deregistered\n",0);
  217. }
  218. #endif
  219. IpxClose();
  220. IPX_Close_Socket( &NwPermanentNpScb.Server );
  221. KeAcquireSpinLock( &ScbSpinLock, &OldIrql );
  222. RemoveEntryList( &NwPermanentNpScb.ScbLinks );
  223. KeReleaseSpinLock( &ScbSpinLock, OldIrql );
  224. DestroyAllScb();
  225. UninitializeIrpContext();
  226. NwDereferenceUnlockableCodeSection ();
  227. NwUnlockCodeSections(FALSE);
  228. StopTimer();
  229. if (IpxTransportName.Buffer != NULL) {
  230. FREE_POOL(IpxTransportName.Buffer);
  231. }
  232. if ( NwProviderName.Buffer != NULL ) {
  233. FREE_POOL( NwProviderName.Buffer );
  234. }
  235. //NwUninitializePidTable(); //Terminal Server code merge -
  236. //NwUninitializePidTable is called in
  237. //NwDeleteScb. Pid table is per SCB base.
  238. ASSERT( IsListEmpty( &NwPagedPoolList ) );
  239. ASSERT( IsListEmpty( &NwNonpagedPoolList ) );
  240. ASSERT( MdlCount == 0 );
  241. ASSERT( IrpCount == 0 );
  242. NwDeleteRcb( &NwRcb );
  243. #ifdef NWDBG
  244. ExDeleteResourceLite( &NwDebugResource );
  245. #endif
  246. ExDeleteResourceLite( &NwOpenResource );
  247. ExDeleteResourceLite( &NwUnlockableCodeResource );
  248. IoDeleteDevice(FileSystemDeviceObject);
  249. DebugTrace(0, Dbg, "NetWare redirector unloaded\n\n", 0);
  250. }
  251. VOID
  252. GetConfigurationInformation(
  253. PUNICODE_STRING RegistryPath
  254. )
  255. /*++
  256. Routine Description:
  257. This routine read redirector configuration information from the registry.
  258. Arguments:
  259. RegistryPath - A pointer the a path to the
  260. Return Value:
  261. None
  262. --*/
  263. {
  264. UNICODE_STRING UnicodeString;
  265. HANDLE ConfigHandle;
  266. HANDLE ParametersHandle;
  267. NTSTATUS Status;
  268. OBJECT_ATTRIBUTES ObjectAttributes;
  269. ULONG TimeOutEventinMins = 0L;
  270. LCID lcid;
  271. PAGED_CODE();
  272. Japan = FALSE;
  273. Korean = FALSE;
  274. ZwQueryDefaultLocale( FALSE, &lcid );
  275. if (PRIMARYLANGID(lcid) == LANG_JAPANESE ||
  276. PRIMARYLANGID(lcid) == LANG_KOREAN ||
  277. PRIMARYLANGID(lcid) == LANG_CHINESE) {
  278. Japan = TRUE;
  279. if (PRIMARYLANGID(lcid) == LANG_KOREAN){
  280. Korean = TRUE;
  281. }
  282. }
  283. InitializeObjectAttributes(
  284. &ObjectAttributes,
  285. RegistryPath, // name
  286. OBJ_CASE_INSENSITIVE, // attributes
  287. NULL, // root
  288. NULL // security descriptor
  289. );
  290. Status = ZwOpenKey ( &ConfigHandle, KEY_READ, &ObjectAttributes );
  291. if (!NT_SUCCESS(Status)) {
  292. return;
  293. }
  294. RtlInitUnicodeString( &UnicodeString, L"Parameters" );
  295. InitializeObjectAttributes(
  296. &ObjectAttributes,
  297. &UnicodeString,
  298. OBJ_CASE_INSENSITIVE,
  299. ConfigHandle,
  300. NULL
  301. );
  302. Status = ZwOpenKey( &ParametersHandle, KEY_READ, &ObjectAttributes );
  303. if ( !NT_SUCCESS( Status ) ) {
  304. ZwClose( ConfigHandle );
  305. return;
  306. }
  307. ReadValue( ParametersHandle, &IrpStackSize, L"IrpStackSize" );
  308. ReadValue( ParametersHandle, &MaxSendDelay, L"MaxSendDelay" );
  309. ReadValue( ParametersHandle, &MaxReceiveDelay, L"MaxReceiveDelay" );
  310. ReadValue( ParametersHandle, &MinSendDelay, L"MinSendDelay" );
  311. ReadValue( ParametersHandle, &MinReceiveDelay, L"MinReceiveDelay" );
  312. ReadValue( ParametersHandle, &BurstSuccessCount, L"BurstSuccessCount" );
  313. ReadValue( ParametersHandle, &BurstSuccessCount2, L"BurstSuccessCount2" );
  314. ReadValue( ParametersHandle, &MaxReadTimeout, L"MaxReadTimeout" );
  315. ReadValue( ParametersHandle, &MaxWriteTimeout, L"MaxWriteTimeout" );
  316. ReadValue( ParametersHandle, &ReadTimeoutMultiplier, L"ReadTimeoutMultiplier" );
  317. ReadValue( ParametersHandle, &WriteTimeoutMultiplier, L"WriteTimeoutMultiplier" );
  318. ReadValue( ParametersHandle, &AllowGrowth, L"AllowGrowth" );
  319. ReadValue( ParametersHandle, &DontShrink, L"DontShrink" );
  320. ReadValue( ParametersHandle, &SendExtraNcp, L"SendExtraNcp" );
  321. ReadValue( ParametersHandle, &DefaultMaxPacketSize, L"DefaultMaxPacketSize" );
  322. ReadValue( ParametersHandle, &PacketThreshold, L"PacketThreshold" );
  323. ReadValue( ParametersHandle, &LargePacketAdjustment, L"LargePacketAdjustment" );
  324. ReadValue( ParametersHandle, &LipPacketAdjustment, L"LipPacketAdjustment" );
  325. ReadValue( ParametersHandle, &LipAccuracy, L"LipAccuracy" );
  326. ReadValue( ParametersHandle, &DisableReadCache, L"DisableReadCache" );
  327. ReadValue( ParametersHandle, &DisableWriteCache, L"DisableWriteCache" );
  328. ReadValue( ParametersHandle, &FavourLongNames, L"FavourLongNames" );
  329. ReadValue( ParametersHandle, &LongNameFlags, L"LongNameFlags" );
  330. ReadValue( ParametersHandle, &DirCacheEntries, L"DirectoryCacheSize" );
  331. if( DirCacheEntries == 0 ) {
  332. DirCacheEntries = 1;
  333. }
  334. if( DirCacheEntries > MAX_DIR_CACHE_ENTRIES ) {
  335. DirCacheEntries = MAX_DIR_CACHE_ENTRIES;
  336. }
  337. ReadValue( ParametersHandle, &LockTimeoutThreshold, L"LockTimeout" );
  338. ReadValue( ParametersHandle, &TimeOutEventinMins, L"TimeOutEventinMins");
  339. ReadValue( ParametersHandle, &EnableMultipleConnects, L"EnableMultipleConnects");
  340. ReadValue( ParametersHandle, &AllowSeedServerRedirection, L"AllowSeedServerRedirection");
  341. ReadValue( ParametersHandle, &ReadExecOnlyFiles, L"ReadExecOnlyFiles");
  342. ReadValue( ParametersHandle, &DisableAltFileName, L"DisableAltFileName");
  343. ReadValue( ParametersHandle, &NwAbsoluteTotalWaitTime, L"AbsoluteTotalWaitTime");
  344. ReadValue( ParametersHandle, &NdsObjectCacheSize, L"NdsObjectCacheSize" );
  345. ReadValue( ParametersHandle, &NdsObjectCacheTimeout, L"NdsObjectCacheTimeout" );
  346. ReadValue ( ParametersHandle, &PreferNDSBrowsing, L"PreferNDSBrowsing" );
  347. //
  348. // Make sure the object cache values are within bounds.
  349. //
  350. // NOTE: If the timeout is set to zero, then the cache is
  351. // effectively disabled. NdsObjectCacheSize is set
  352. // to zero to accomplish this.
  353. //
  354. if( NdsObjectCacheSize > MAX_NDS_OBJECT_CACHE_SIZE ) {
  355. NdsObjectCacheSize = MAX_NDS_OBJECT_CACHE_SIZE;
  356. }
  357. if( NdsObjectCacheTimeout > MAX_NDS_OBJECT_CACHE_TIMEOUT ) {
  358. NdsObjectCacheTimeout = MAX_NDS_OBJECT_CACHE_TIMEOUT;
  359. } else if( NdsObjectCacheTimeout == 0 ) {
  360. NdsObjectCacheSize = 0;
  361. }
  362. if (!TimeOutEventinMins) {
  363. //
  364. // If for some reason, the registry has set the TimeOutEventInterval
  365. // to zero, reset to the default value to avoid divide-by-zero
  366. //
  367. TimeOutEventinMins = DEFAULT_TIMEOUT_EVENT_INTERVAL;
  368. }
  369. TimeOutEventInterval.QuadPart = TimeOutEventinMins * 60 * SECONDS;
  370. //
  371. // tommye - MS bug 2743 we now get the RetryCount from the registry, providing
  372. // a default of DEFAULT_RETRY_COUNT.
  373. //
  374. {
  375. LONG TempRetryCount;
  376. TempRetryCount = DEFAULT_RETRY_COUNT;
  377. ReadValue( ParametersHandle, &TempRetryCount, L"DefaultRetryCount");
  378. DefaultRetryCount = (SHORT) TempRetryCount & 0xFFFF;
  379. }
  380. ZwClose( ParametersHandle );
  381. ZwClose( ConfigHandle );
  382. }
  383. VOID
  384. ReadValue(
  385. HANDLE ParametersHandle,
  386. PLONG pVar,
  387. PWCHAR Name
  388. )
  389. /*++
  390. Routine Description:
  391. This routine reads a single redirector configuration value from the registry.
  392. Arguments:
  393. Parameters - Supplies where to look for values.
  394. pVar - Address of the variable to receive the new value if the name exists.
  395. Name - Name whose value is to be loaded.
  396. Return Value:
  397. None
  398. --*/
  399. {
  400. WCHAR Storage[256];
  401. UNICODE_STRING UnicodeString;
  402. NTSTATUS Status;
  403. ULONG BytesRead;
  404. PKEY_VALUE_FULL_INFORMATION Value = (PKEY_VALUE_FULL_INFORMATION)Storage;
  405. PAGED_CODE();
  406. UnicodeString.Buffer = Storage;
  407. RtlInitUnicodeString(&UnicodeString, Name );
  408. Status = ZwQueryValueKey(
  409. ParametersHandle,
  410. &UnicodeString,
  411. KeyValueFullInformation,
  412. Value,
  413. sizeof(Storage),
  414. &BytesRead );
  415. if ( NT_SUCCESS( Status ) ) {
  416. if ( Value->DataLength >= sizeof(ULONG) ) {
  417. *pVar = *(LONG UNALIGNED *)( (PCHAR)Value + Value->DataOffset );
  418. }
  419. }
  420. }