Source code of Windows XP (NT5)
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.

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