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.

1182 lines
39 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corp., 1992 **/
  4. /**********************************************************************/
  5. /*
  6. Init.c
  7. OS Independent initialization routines
  8. FILE HISTORY:
  9. Johnl 26-Mar-1993 Created
  10. */
  11. #include "nbtnt.h"
  12. #include "precomp.h"
  13. #include "hosts.h"
  14. VOID
  15. ReadScope(
  16. IN tNBTCONFIG *pConfig,
  17. IN HANDLE ParmHandle
  18. );
  19. VOID
  20. ReadLmHostFile(
  21. IN tNBTCONFIG *pConfig,
  22. IN HANDLE ParmHandle
  23. );
  24. extern tTIMERQ TimerQ;
  25. //******************* Pageable Routine Declarations ****************
  26. #ifdef ALLOC_PRAGMA
  27. #pragma CTEMakePageable(INIT, InitNotOs)
  28. #pragma CTEMakePageable(PAGE, InitTimersNotOs)
  29. #pragma CTEMakePageable(PAGE, StopInitTimers)
  30. #pragma CTEMakePageable(PAGE, ReadParameters)
  31. #pragma CTEMakePageable(PAGE, ReadParameters2)
  32. #pragma CTEMakePageable(PAGE, ReadScope)
  33. #pragma CTEMakePageable(PAGE, ReadLmHostFile)
  34. #endif
  35. //******************* Pageable Routine Declarations ****************
  36. #ifdef VXD
  37. #pragma BEGIN_INIT
  38. #endif
  39. //----------------------------------------------------------------------------
  40. NTSTATUS
  41. InitNotOs(
  42. void
  43. )
  44. /*++
  45. Routine Description:
  46. This is the initialization routine for the Non-OS Specific side of the
  47. NBT device driver.
  48. pNbtGlobConfig must be initialized before this is called!
  49. Arguments:
  50. Return Value:
  51. NTSTATUS - The function value is the final status from the initialization
  52. operation.
  53. --*/
  54. {
  55. NTSTATUS status = STATUS_SUCCESS;
  56. ULONG i;
  57. CTEPagedCode();
  58. //
  59. // for multihomed hosts, this tracks the number of adapters as each one
  60. // is created.
  61. //
  62. NbtMemoryAllocated = 0;
  63. NbtConfig.AdapterCount = 0;
  64. NbtConfig.MultiHomed = FALSE;
  65. NbtConfig.SingleResponse = FALSE;
  66. NbtConfig.ServerMask = 0;
  67. NbtConfig.ClientMask = 0;
  68. NbtConfig.iCurrentNumBuff[eNBT_DGRAM_TRACKER] = 0;
  69. pNbtGlobConfig->iBufferSize[eNBT_DGRAM_TRACKER] = sizeof(tDGRAM_SEND_TRACKING);
  70. CTEZeroMemory (&NameStatsInfo,sizeof(tNAMESTATS_INFO)); // Initialize the name statistics
  71. CTEZeroMemory (&LmHostQueries,sizeof(tLMHSVC_REQUESTS)); // Synchronize reads from the LmHosts file
  72. InitializeListHead (&LmHostQueries.ToResolve);
  73. //
  74. // Initialize the linked lists associated with the global configuration
  75. // data structures
  76. //
  77. InitializeListHead (&NbtConfig.DeviceContexts);
  78. InitializeListHead (&NbtConfig.DevicesAwaitingDeletion);
  79. InitializeListHead (&NbtConfig.AddressHead);
  80. InitializeListHead (&NbtConfig.PendingNameQueries);
  81. InitializeListHead (&NbtConfig.WorkerQList);
  82. InitializeListHead (&NbtConfig.NodeStatusHead);
  83. InitializeListHead (&NbtConfig.DgramTrackerFreeQ);
  84. InitializeListHead (&UsedTrackers);
  85. InitializeListHead (&UsedIrps);
  86. InitializeListHead (&DomainNames.DomainList);
  87. // initialize the spin lock
  88. CTEInitLock (&NbtConfig.LockInfo.SpinLock);
  89. CTEInitLock (&NbtConfig.JointLock.LockInfo.SpinLock);
  90. CTEInitLock (&NbtConfig.WorkerQLock.LockInfo.SpinLock);
  91. #ifndef VXD
  92. pWinsInfo = NULL;
  93. NbtConfig.NumWorkerThreadsQueued = 0;
  94. NbtConfig.NumTimersRunning = 0;
  95. NbtConfig.CacheTimeStamp = 0;
  96. NbtConfig.InterfaceIndex = 0;
  97. NbtConfig.GlobalRefreshState = 0;
  98. NbtConfig.pWakeupRefreshTimer = NULL;
  99. NbtConfig.TransactionId = WINS_MAXIMUM_TRANSACTION_ID + 1;
  100. NbtConfig.RemoteCacheLen = REMOTE_CACHE_INCREMENT;
  101. NbtConfig.iBufferSize[eNBT_FREE_SESSION_MDLS] = sizeof(tSESSIONHDR);
  102. NbtConfig.iBufferSize[eNBT_DGRAM_MDLS] = DGRAM_HDR_SIZE + (NbtConfig.ScopeLength << 1);
  103. //
  104. // Set the Unitialized flag in the TimerQ, so that it can be initialized
  105. // when needed
  106. //
  107. TimerQ.TimersInitialized = FALSE;
  108. // Initialize the LastForcedReleaseTime!
  109. CTEQuerySystemTime (NbtConfig.LastForcedReleaseTime);
  110. CTEQuerySystemTime (NbtConfig.LastOutOfRsrcLogTime);
  111. CTEQuerySystemTime (NbtConfig.LastRefreshTime);
  112. ExSystemTimeToLocalTime (&NbtConfig.LastRefreshTime, &NbtConfig.LastRefreshTime);
  113. //
  114. // this resource is used to synchronize access to the Dns structure
  115. //
  116. CTEZeroMemory (&DnsQueries,sizeof(tLMHSVC_REQUESTS));
  117. InitializeListHead (&DnsQueries.ToResolve);
  118. //
  119. // this resource is used to synchronize access to the CheckAddr structure
  120. //
  121. CTEZeroMemory(&CheckAddr,sizeof(tLMHSVC_REQUESTS));
  122. InitializeListHead (&CheckAddr.ToResolve);
  123. //
  124. // Setup the default disconnect timeout - 10 seconds - convert
  125. // to negative 100 Ns.
  126. //
  127. DefaultDisconnectTimeout.QuadPart = Int32x32To64(DEFAULT_DISC_TIMEOUT, MILLISEC_TO_100NS);
  128. DefaultDisconnectTimeout.QuadPart = -(DefaultDisconnectTimeout.QuadPart);
  129. InitializeListHead (&NbtConfig.IrpFreeList);
  130. InitializeListHead (&FreeWinsList);
  131. // set up a list for connections when we run out of resources and need to
  132. // disconnect these connections. An Irp is also needed for this list, and
  133. // it is allocated in Driver.C after we have created the connections to the
  134. // transport and therefore know our Irp Stack Size.
  135. //
  136. InitializeListHead (&NbtConfig.OutOfRsrc.ConnectionHead);
  137. KeInitializeEvent (&NbtConfig.WorkerQLastEvent, NotificationEvent, TRUE);
  138. KeInitializeEvent (&NbtConfig.TimerQLastEvent, NotificationEvent, TRUE);
  139. KeInitializeEvent (&NbtConfig.WakeupTimerStartedEvent, NotificationEvent, TRUE);
  140. // use this resources to synchronize access to the security info between
  141. // assigning security and checking it - when adding names to the
  142. // name local name table through NbtregisterName. This also insures
  143. // that the name is in the local hash table (from a previous Registration)
  144. // before the next registration is allowed to proceed and check for
  145. // the name in the table.
  146. //
  147. ExInitializeResourceLite(&NbtConfig.Resource);
  148. #else
  149. DefaultDisconnectTimeout = DEFAULT_DISC_TIMEOUT * 1000; // convert to milliseconds
  150. InitializeListHead(&NbtConfig.SendTimeoutHead) ;
  151. InitializeListHead(&NbtConfig.SessionBufferFreeList) ;
  152. InitializeListHead(&NbtConfig.SendContextFreeList) ;
  153. InitializeListHead(&NbtConfig.RcvContextFreeList) ;
  154. //
  155. // For session headers, since they are only four bytes and we can't
  156. // change the size of the structure, we'll covertly add enough for
  157. // a full LIST_ENTRY and treat it like a standalone LIST_ENTRY structure
  158. // when adding and removing from the list.
  159. //
  160. NbtConfig.iBufferSize[eNBT_SESSION_HDR] = sizeof(tSESSIONHDR) + sizeof(LIST_ENTRY) - sizeof(tSESSIONHDR);
  161. NbtConfig.iBufferSize[eNBT_SEND_CONTEXT] = sizeof(TDI_SEND_CONTEXT);
  162. NbtConfig.iBufferSize[eNBT_RCV_CONTEXT] = sizeof(RCV_CONTEXT);
  163. NbtConfig.iCurrentNumBuff[eNBT_SESSION_HDR] = NBT_INITIAL_NUM;
  164. NbtConfig.iCurrentNumBuff[eNBT_SEND_CONTEXT] = NBT_INITIAL_NUM;
  165. NbtConfig.iCurrentNumBuff[eNBT_RCV_CONTEXT] = NBT_INITIAL_NUM;
  166. InitializeListHead (&NbtConfig.DNSDirectNameQueries);
  167. #endif
  168. #if DBG
  169. NbtConfig.LockInfo.LockNumber = NBTCONFIG_LOCK;
  170. NbtConfig.JointLock.LockInfo.LockNumber = JOINT_LOCK;
  171. NbtConfig.WorkerQLock.LockInfo.LockNumber = WORKERQ_LOCK;
  172. for (i=0; i<MAXIMUM_PROCESSORS; i++)
  173. {
  174. NbtConfig.CurrentLockNumber[i] = 0;
  175. }
  176. InitializeListHead(&NbtConfig.StaleRemoteNames);
  177. #endif
  178. //
  179. // create trackers List
  180. //
  181. // #if DBG
  182. for (i=0; i<NBT_TRACKER_NUM_TRACKER_TYPES; i++)
  183. {
  184. TrackTrackers[i] = 0;
  185. TrackerHighWaterMark[i] = 0;
  186. }
  187. // #endif // DBG
  188. //
  189. // Now allocate any initial memory/Resources
  190. //
  191. #ifdef VXD
  192. status = NbtInitQ (&NbtConfig.SessionBufferFreeList,
  193. NbtConfig.iBufferSize[eNBT_SESSION_HDR],
  194. NBT_INITIAL_NUM);
  195. if (!NT_SUCCESS (status))
  196. {
  197. return status ;
  198. }
  199. status = NbtInitQ( &NbtConfig.SendContextFreeList,
  200. sizeof( TDI_SEND_CONTEXT ),
  201. NBT_INITIAL_NUM);
  202. if (!NT_SUCCESS (status))
  203. {
  204. return status ;
  205. }
  206. status = NbtInitQ( &NbtConfig.RcvContextFreeList,
  207. sizeof (RCV_CONTEXT),
  208. NBT_INITIAL_NUM);
  209. if (!NT_SUCCESS (status))
  210. {
  211. return status ;
  212. }
  213. #endif
  214. // create the hash tables for storing names in.
  215. status = CreateHashTable(&NbtConfig.pLocalHashTbl, NbtConfig.uNumBucketsLocal, NBT_LOCAL);
  216. if (!NT_SUCCESS (status))
  217. {
  218. ASSERTMSG("NBT:Unable to create hash tables for Netbios Names\n", (status == STATUS_SUCCESS));
  219. return status ;
  220. }
  221. // we always have a remote hash table, but if we are a Proxy, it is
  222. // a larger table. In the Non-proxy case the remote table just caches
  223. // names resolved with the NS. In the Proxy case it also holds names
  224. // resolved for all other clients on the local broadcast area.
  225. // The node size registry parameter controls the number of remote buckets.
  226. status = CreateHashTable (&NbtConfig.pRemoteHashTbl, NbtConfig.uNumBucketsRemote, NBT_REMOTE);
  227. if (!NT_SUCCESS (status))
  228. {
  229. return status;
  230. }
  231. status = NbtInitTrackerQ (NBT_INITIAL_NUM);
  232. if (!NT_SUCCESS (status))
  233. {
  234. return status;
  235. }
  236. // create the timer control blocks, setting the number of concurrent timers
  237. // allowed at one time
  238. status = InitTimerQ (NBT_INITIAL_NUM);
  239. return status;
  240. }
  241. //----------------------------------------------------------------------------
  242. NTSTATUS
  243. InitTimersNotOs(
  244. void
  245. )
  246. /*++
  247. Routine Description:
  248. This is the initialization routine for the Non-OS Specific side of the
  249. NBT device driver that starts the timers needed.
  250. Arguments:
  251. Return Value:
  252. NTSTATUS - The function value is the final status from the initialization
  253. operation.
  254. --*/
  255. {
  256. NTSTATUS status = STATUS_SUCCESS;
  257. CTEPagedCode();
  258. //
  259. // If the timers have already been initialized, return success
  260. //
  261. if (TimerQ.TimersInitialized)
  262. {
  263. return STATUS_SUCCESS;
  264. }
  265. NbtConfig.iBufferSize[eNBT_TIMER_ENTRY] = sizeof(tTIMERQENTRY);
  266. NbtConfig.iCurrentNumBuff[eNBT_TIMER_ENTRY] = NBT_INITIAL_NUM;
  267. NbtConfig.pRefreshTimer = NULL;
  268. NbtConfig.pRemoteHashTimer = NULL;
  269. NbtConfig.pSessionKeepAliveTimer = NULL;
  270. NbtConfig.RefreshDivisor = REFRESH_DIVISOR;
  271. if (!NT_SUCCESS(status))
  272. {
  273. return status ;
  274. }
  275. // start a Timer to refresh names with the name service
  276. //
  277. if (!(NodeType & BNODE))
  278. {
  279. // the initial refresh rate until we can contact the name server
  280. NbtConfig.MinimumTtl = NbtConfig.InitialRefreshTimeout;
  281. NbtConfig.sTimeoutCount = 3;
  282. status = StartTimer(RefreshTimeout,
  283. NbtConfig.InitialRefreshTimeout/REFRESH_DIVISOR,
  284. NULL, // context value
  285. NULL, // context2 value
  286. NULL,
  287. NULL,
  288. NULL, // This timer is a global timer
  289. &NbtConfig.pRefreshTimer,
  290. 0,
  291. FALSE);
  292. if ( !NT_SUCCESS(status))
  293. {
  294. return status;
  295. }
  296. }
  297. //
  298. // Set the TimersInitialized flag
  299. //
  300. TimerQ.TimersInitialized = TRUE;
  301. // calculate the count necessary to timeout out names in RemoteHashTimeout
  302. // milliseconds
  303. //
  304. NbtConfig.RemoteTimeoutCount = (USHORT)((NbtConfig.RemoteHashTtl/REMOTE_HASH_TIMEOUT));
  305. if (NbtConfig.RemoteTimeoutCount == 0)
  306. {
  307. NbtConfig.RemoteTimeoutCount = 1;
  308. }
  309. // start a Timer to timeout remote cached names from the Remote hash table.
  310. // The timer is a one minute timer, and the hash entries count down to zero
  311. // then time out.
  312. //
  313. status = StartTimer(RemoteHashTimeout, // timer expiry routine
  314. REMOTE_HASH_TIMEOUT,
  315. NULL, // context value
  316. NULL, // context2 value
  317. NULL,
  318. NULL,
  319. NULL, // This timer is a global timer
  320. &NbtConfig.pRemoteHashTimer,
  321. 0,
  322. FALSE);
  323. if ( !NT_SUCCESS( status ) )
  324. {
  325. StopInitTimers();
  326. return status ;
  327. }
  328. // start a Timer for Session Keep Alives which sends a session keep alive
  329. // on a connection if the timer value is not set to -1
  330. //
  331. if (NbtConfig.KeepAliveTimeout != -1)
  332. {
  333. status = StartTimer(SessionKeepAliveTimeout, // timer expiry routine
  334. NbtConfig.KeepAliveTimeout,
  335. NULL, // context value
  336. NULL, // context2 value
  337. NULL,
  338. NULL,
  339. NULL, // This timer is a global timer
  340. &NbtConfig.pSessionKeepAliveTimer,
  341. 0,
  342. FALSE);
  343. if ( !NT_SUCCESS( status ) )
  344. {
  345. StopInitTimers();
  346. return status ;
  347. }
  348. }
  349. return(STATUS_SUCCESS);
  350. }
  351. //----------------------------------------------------------------------------
  352. NTSTATUS
  353. StopInitTimers(
  354. VOID
  355. )
  356. /*++
  357. Routine Description:
  358. This is stops the timers started in InitTimerNotOS
  359. Arguments:
  360. Return Value:
  361. NTSTATUS - The function value is the final status from the initialization
  362. operation.
  363. --*/
  364. {
  365. CTEPagedCode();
  366. //
  367. // If the timers have already been stopped, return success
  368. //
  369. if (!TimerQ.TimersInitialized)
  370. {
  371. return STATUS_SUCCESS;
  372. }
  373. //
  374. // Set the TimersInitialized flag to FALSE
  375. //
  376. TimerQ.TimersInitialized = FALSE;
  377. if (NbtConfig.pRefreshTimer)
  378. {
  379. StopTimer(NbtConfig.pRefreshTimer,NULL,NULL);
  380. }
  381. if (NbtConfig.pSessionKeepAliveTimer)
  382. {
  383. StopTimer(NbtConfig.pSessionKeepAliveTimer,NULL,NULL);
  384. }
  385. if (NbtConfig.pRemoteHashTimer)
  386. {
  387. StopTimer(NbtConfig.pRemoteHashTimer,NULL,NULL);
  388. }
  389. return(STATUS_SUCCESS);
  390. }
  391. //----------------------------------------------------------------------------
  392. VOID
  393. ReadParameters(
  394. IN tNBTCONFIG *pConfig,
  395. IN HANDLE ParmHandle
  396. )
  397. /*++
  398. Routine Description:
  399. This routine is called to read various parameters from the parameters
  400. section of the NBT section of the registry.
  401. Arguments:
  402. pConfig - A pointer to the configuration data structure.
  403. ParmHandle - a handle to the parameters Key under Nbt
  404. Return Value:
  405. Status
  406. --*/
  407. {
  408. ULONG NodeSize;
  409. ULONG Refresh;
  410. CTEPagedCode();
  411. ReadParameters2(pConfig, ParmHandle);
  412. pConfig->NameServerPort = (USHORT)CTEReadSingleIntParameter(ParmHandle,
  413. WS_NS_PORT_NUM,
  414. NBT_NAMESERVER_UDP_PORT,
  415. 0);
  416. pConfig->MaxPreloadEntries = CTEReadSingleIntParameter(ParmHandle,
  417. WS_MAX_PRELOADS,
  418. DEF_PRELOAD,
  419. DEF_PRELOAD ) ;
  420. if (pConfig->MaxPreloadEntries > MAX_PRELOAD)
  421. {
  422. pConfig->MaxPreloadEntries = MAX_PRELOAD;
  423. }
  424. #ifdef VXD
  425. pConfig->DnsServerPort = (USHORT)CTEReadSingleIntParameter(ParmHandle,
  426. WS_DNS_PORT_NUM,
  427. NBT_DNSSERVER_UDP_PORT,
  428. 0);
  429. pConfig->lRegistryMaxNames = (USHORT)CTEReadSingleIntParameter(ParmHandle,
  430. VXD_NAMETABLE_SIZE_NAME,
  431. VXD_DEF_NAMETABLE_SIZE,
  432. VXD_MIN_NAMETABLE_SIZE ) ;
  433. pConfig->lRegistryMaxSessions = (USHORT)CTEReadSingleIntParameter(ParmHandle,
  434. VXD_SESSIONTABLE_SIZE_NAME,
  435. VXD_DEF_SESSIONTABLE_SIZE,
  436. VXD_MIN_SESSIONTABLE_SIZE ) ;
  437. pConfig->DoDNSDevolutions = (BOOLEAN)CTEReadSingleIntParameter(ParmHandle,
  438. WS_DO_DNS_DEVOLUTIONS,
  439. 0, // disabled by default
  440. 0);
  441. #endif
  442. pConfig->RemoteHashTtl = CTEReadSingleIntParameter(ParmHandle,
  443. WS_CACHE_TIMEOUT,
  444. DEFAULT_CACHE_TIMEOUT,
  445. MIN_CACHE_TIMEOUT);
  446. pConfig->InitialRefreshTimeout = CTEReadSingleIntParameter(ParmHandle,
  447. WS_INITIAL_REFRESH,
  448. NBT_INITIAL_REFRESH_TTL,
  449. NBT_INITIAL_REFRESH_TTL);
  450. pConfig->MinimumRefreshSleepTimeout = CTEReadSingleIntParameter(ParmHandle,
  451. WS_MINIMUM_REFRESH_SLEEP_TIME,
  452. DEFAULT_MINIMUM_REFRESH_SLEEP_TIME,
  453. 0);
  454. // retry timeouts and number of retries for both Broadcast name resolution
  455. // and Name Service resolution
  456. //
  457. pConfig->uNumBcasts = (USHORT)CTEReadSingleIntParameter(ParmHandle,
  458. WS_NUM_BCASTS,
  459. DEFAULT_NUMBER_BROADCASTS,
  460. 1);
  461. pConfig->uBcastTimeout = CTEReadSingleIntParameter(ParmHandle,
  462. WS_BCAST_TIMEOUT,
  463. DEFAULT_BCAST_TIMEOUT,
  464. MIN_BCAST_TIMEOUT);
  465. pConfig->uNumRetries = (USHORT)CTEReadSingleIntParameter(ParmHandle,
  466. WS_NAMESRV_RETRIES,
  467. DEFAULT_NUMBER_RETRIES,
  468. 1);
  469. pConfig->uRetryTimeout = CTEReadSingleIntParameter(ParmHandle,
  470. WS_NAMESRV_TIMEOUT,
  471. DEFAULT_RETRY_TIMEOUT,
  472. MIN_RETRY_TIMEOUT);
  473. pConfig->KeepAliveTimeout = CTEReadSingleIntParameter(ParmHandle,
  474. WS_KEEP_ALIVE,
  475. DEFAULT_KEEP_ALIVE,
  476. MIN_KEEP_ALIVE);
  477. pConfig->SelectAdapter = (BOOLEAN)CTEReadSingleIntParameter(ParmHandle,
  478. WS_RANDOM_ADAPTER,
  479. 0,
  480. 0);
  481. pConfig->SingleResponse = (BOOLEAN)CTEReadSingleIntParameter(ParmHandle,
  482. WS_SINGLE_RESPONSE,
  483. 0,
  484. 0);
  485. pConfig->NoNameReleaseOnDemand = (BOOLEAN)CTEReadSingleIntParameter(ParmHandle,
  486. WS_NO_NAME_RELEASE,
  487. 0,
  488. 0); // disabled by default
  489. if (pConfig->CachePerAdapterEnabled = (BOOLEAN) CTEReadSingleIntParameter(ParmHandle,
  490. WS_CACHE_PER_ADAPTER_ENABLED,
  491. 1, // Enabled by default
  492. 0))
  493. {
  494. pConfig->ConnectOnRequestedInterfaceOnly = (BOOLEAN) CTEReadSingleIntParameter(ParmHandle,
  495. WS_CONNECT_ON_REQUESTED_IF_ONLY,
  496. 0, // Disabled by default
  497. 0);
  498. }
  499. else
  500. {
  501. pConfig->ConnectOnRequestedInterfaceOnly = FALSE;
  502. }
  503. pConfig->SendDgramOnRequestedInterfaceOnly = (BOOLEAN) CTEReadSingleIntParameter(ParmHandle,
  504. WS_SEND_DGRAM_ON_REQUESTED_IF_ONLY,
  505. 1, // Enabled by default
  506. 0);
  507. pConfig->SMBDeviceEnabled = (BOOLEAN) CTEReadSingleIntParameter(ParmHandle,
  508. WS_SMB_DEVICE_ENABLED,
  509. 1, // Enabled by default
  510. 0);
  511. pConfig->MultipleCacheFlags = (BOOLEAN) CTEReadSingleIntParameter(ParmHandle,
  512. WS_MULTIPLE_CACHE_FLAGS,
  513. 0, // Not enabled by default
  514. 0);
  515. pConfig->UseDnsOnly = (BOOLEAN)CTEReadSingleIntParameter(ParmHandle,
  516. WS_USE_DNS_ONLY,
  517. 0,
  518. 0); // disabled by default
  519. if (pConfig->UseDnsOnly)
  520. {
  521. pConfig->ResolveWithDns = TRUE;
  522. pConfig->TryAllNameServers = FALSE;
  523. }
  524. else
  525. {
  526. pConfig->ResolveWithDns = (BOOLEAN)CTEReadSingleIntParameter(ParmHandle,
  527. WS_ENABLE_DNS,
  528. 1, // Enabled by default
  529. 0);
  530. #ifdef MULTIPLE_WINS
  531. pConfig->TryAllNameServers = (BOOLEAN)CTEReadSingleIntParameter(ParmHandle,
  532. WS_TRY_ALL_NAME_SERVERS,
  533. 0, // disabled by default
  534. 0);
  535. #endif
  536. }
  537. pConfig->SmbDisableNetbiosNameCacheLookup = (BOOLEAN)CTEReadSingleIntParameter(ParmHandle,
  538. WS_SMB_DISABLE_NETBIOS_NAME_CACHE_LOOKUP,
  539. 1, // Enabled by default
  540. 0);
  541. pConfig->TryAllAddr = (BOOLEAN)CTEReadSingleIntParameter(ParmHandle,
  542. WS_TRY_ALL_ADDRS,
  543. 1,
  544. 1); // enabled by default
  545. pConfig->LmHostsTimeout = CTEReadSingleIntParameter(ParmHandle,
  546. WS_LMHOSTS_TIMEOUT,
  547. DEFAULT_LMHOST_TIMEOUT,
  548. MIN_LMHOST_TIMEOUT);
  549. pConfig->MaxDgramBuffering = CTEReadSingleIntParameter(ParmHandle,
  550. WS_MAX_DGRAM_BUFFER,
  551. DEFAULT_DGRAM_BUFFERING,
  552. DEFAULT_DGRAM_BUFFERING);
  553. pConfig->EnableProxyRegCheck = (BOOLEAN)CTEReadSingleIntParameter(ParmHandle,
  554. WS_ENABLE_PROXY_REG_CHECK,
  555. 0,
  556. 0);
  557. pConfig->WinsDownTimeout = (ULONG)CTEReadSingleIntParameter(ParmHandle,
  558. WS_WINS_DOWN_TIMEOUT,
  559. DEFAULT_WINS_DOWN_TIMEOUT,
  560. MIN_WINS_DOWN_TIMEOUT);
  561. pConfig->MaxBackLog = (ULONG)CTEReadSingleIntParameter(ParmHandle,
  562. WS_MAX_CONNECTION_BACKLOG,
  563. DEFAULT_CONN_BACKLOG,
  564. MIN_CONN_BACKLOG);
  565. pConfig->SpecialConnIncrement = (ULONG)CTEReadSingleIntParameter(ParmHandle,
  566. WS_CONNECTION_BACKLOG_INCREMENT,
  567. DEFAULT_CONN_BACKLOG_INCREMENT,
  568. MIN_CONN_BACKLOG_INCREMENT);
  569. pConfig->MinFreeLowerConnections = (ULONG)CTEReadSingleIntParameter(ParmHandle,
  570. WS_MIN_FREE_INCOMING_CONNECTIONS,
  571. DEFAULT_NBT_NUM_INITIAL_CONNECTIONS,
  572. MIN_NBT_NUM_INITIAL_CONNECTIONS);
  573. pConfig->BreakOnAssert = (BOOLEAN) CTEReadSingleIntParameter(ParmHandle,
  574. WS_BREAK_ON_ASSERT,
  575. 1, // Enabled by default
  576. 0);
  577. #ifndef REMOVE_IF_TCPIP_FIX___GATEWAY_AFTER_NOTIFY_BUG
  578. pConfig->DhcpProcessingDelay = (ULONG) CTEReadSingleIntParameter(ParmHandle,
  579. WS_DHCP_PROCESSING_DELAY,
  580. DEFAULT_DHCP_PROCESSING_DELAY,
  581. MIN_DHCP_PROCESSING_DELAY);
  582. #endif // REMOVE_IF_TCPIP_FIX___GATEWAY_AFTER_NOTIFY_BUG
  583. //
  584. // Cap the upper limit
  585. //
  586. if (pConfig->MaxBackLog > MAX_CONNECTION_BACKLOG) {
  587. pConfig->MaxBackLog = MAX_CONNECTION_BACKLOG;
  588. }
  589. if (pConfig->SpecialConnIncrement > MAX_CONNECTION_BACKLOG_INCREMENT) {
  590. pConfig->SpecialConnIncrement = MAX_CONNECTION_BACKLOG_INCREMENT;
  591. }
  592. //
  593. // Since UB chose the wrong opcode (9) we have to allow configuration
  594. // of that opcode incase our nodes refresh to their NBNS
  595. //
  596. Refresh = (ULONG)CTEReadSingleIntParameter(ParmHandle,
  597. WS_REFRESH_OPCODE,
  598. REFRESH_OPCODE,
  599. REFRESH_OPCODE);
  600. if (Refresh == UB_REFRESH_OPCODE)
  601. {
  602. pConfig->OpRefresh = OP_REFRESH_UB;
  603. }
  604. else
  605. {
  606. pConfig->OpRefresh = OP_REFRESH;
  607. }
  608. #ifndef VXD
  609. pConfig->EnableLmHosts = (BOOLEAN)CTEReadSingleIntParameter(ParmHandle,
  610. WS_ENABLE_LMHOSTS,
  611. 0,
  612. 0);
  613. #endif
  614. #ifdef PROXY_NODE
  615. {
  616. ULONG Proxy;
  617. Proxy = CTEReadSingleIntParameter(ParmHandle,
  618. WS_IS_IT_A_PROXY,
  619. IS_NOT_PROXY, //default value
  620. IS_NOT_PROXY);
  621. //
  622. // If the returned value is greater than IS_NOT_PROXY, it is a proxy
  623. // (also check that they have not entered an ascii string instead of a
  624. // dword in the registry
  625. //
  626. if ((Proxy > IS_NOT_PROXY) && (Proxy < ('0'+IS_NOT_PROXY)))
  627. {
  628. NodeType |= PROXY;
  629. RegistryNodeType |= PROXY;
  630. NbtConfig.ProxyType = Proxy;
  631. }
  632. }
  633. #endif
  634. NodeSize = CTEReadSingleIntParameter(ParmHandle,
  635. WS_NODE_SIZE,
  636. NodeType & PROXY ? LARGE : DEFAULT_NODE_SIZE,
  637. NodeType & PROXY ? LARGE : SMALL);
  638. switch (NodeSize)
  639. {
  640. default:
  641. case SMALL:
  642. pConfig->uNumLocalNames = NUMBER_LOCAL_NAMES;
  643. pConfig->uNumRemoteNames = NUMBER_REMOTE_NAMES;
  644. pConfig->uNumBucketsLocal = NUMBER_BUCKETS_LOCAL_HASH_TABLE;
  645. pConfig->uNumBucketsRemote = NUMBER_BUCKETS_REMOTE_HASH_TABLE;
  646. pConfig->iMaxNumBuff[eNBT_DGRAM_TRACKER] = NBT_NUM_DGRAM_TRACKERS;
  647. pConfig->iMaxNumBuff[eNBT_TIMER_ENTRY] = TIMER_Q_SIZE;
  648. #ifndef VXD
  649. pConfig->iMaxNumBuff[eNBT_FREE_IRPS] = NBT_NUM_IRPS;
  650. pConfig->iMaxNumBuff[eNBT_DGRAM_MDLS] = NBT_NUM_DGRAM_MDLS;
  651. pConfig->iMaxNumBuff[eNBT_FREE_SESSION_MDLS] = NBT_NUM_SESSION_MDLS;
  652. #else
  653. pConfig->iMaxNumBuff[eNBT_SESSION_HDR] = NBT_NUM_SESSION_HDR ;
  654. pConfig->iMaxNumBuff[eNBT_SEND_CONTEXT] = NBT_NUM_SEND_CONTEXT ;
  655. pConfig->iMaxNumBuff[eNBT_RCV_CONTEXT] = NBT_NUM_RCV_CONTEXT ;
  656. #endif
  657. break;
  658. case MEDIUM:
  659. pConfig->uNumLocalNames = MEDIUM_NUMBER_LOCAL_NAMES;
  660. pConfig->uNumRemoteNames = MEDIUM_NUMBER_REMOTE_NAMES;
  661. pConfig->uNumBucketsLocal = MEDIUM_NUMBER_BUCKETS_LOCAL_HASH_TABLE;
  662. pConfig->uNumBucketsRemote = MEDIUM_NUMBER_BUCKETS_REMOTE_HASH_TABLE;
  663. pConfig->iMaxNumBuff[eNBT_DGRAM_TRACKER] = MEDIUM_NBT_NUM_DGRAM_TRACKERS;
  664. pConfig->iMaxNumBuff[eNBT_TIMER_ENTRY] = MEDIUM_TIMER_Q_SIZE;
  665. #ifndef VXD
  666. pConfig->iMaxNumBuff[eNBT_FREE_IRPS] = MEDIUM_NBT_NUM_IRPS;
  667. pConfig->iMaxNumBuff[eNBT_DGRAM_MDLS] = MEDIUM_NBT_NUM_DGRAM_MDLS;
  668. pConfig->iMaxNumBuff[eNBT_FREE_SESSION_MDLS] = MEDIUM_NBT_NUM_SESSION_MDLS;
  669. #else
  670. pConfig->iMaxNumBuff[eNBT_SESSION_HDR] = MEDIUM_NBT_NUM_SESSION_HDR ;
  671. pConfig->iMaxNumBuff[eNBT_SEND_CONTEXT] = MEDIUM_NBT_NUM_SEND_CONTEXT ;
  672. pConfig->iMaxNumBuff[eNBT_RCV_CONTEXT] = MEDIUM_NBT_NUM_RCV_CONTEXT ;
  673. #endif
  674. break;
  675. case LARGE:
  676. pConfig->uNumLocalNames = LARGE_NUMBER_LOCAL_NAMES;
  677. pConfig->uNumRemoteNames = LARGE_NUMBER_REMOTE_NAMES;
  678. pConfig->uNumBucketsLocal = LARGE_NUMBER_BUCKETS_LOCAL_HASH_TABLE;
  679. pConfig->uNumBucketsRemote = LARGE_NUMBER_BUCKETS_REMOTE_HASH_TABLE;
  680. pConfig->iMaxNumBuff[eNBT_DGRAM_TRACKER] = LARGE_NBT_NUM_DGRAM_TRACKERS;
  681. pConfig->iMaxNumBuff[eNBT_TIMER_ENTRY] = LARGE_TIMER_Q_SIZE;
  682. #ifndef VXD
  683. pConfig->iMaxNumBuff[eNBT_FREE_IRPS] = LARGE_NBT_NUM_IRPS;
  684. pConfig->iMaxNumBuff[eNBT_DGRAM_MDLS] = LARGE_NBT_NUM_DGRAM_MDLS;
  685. pConfig->iMaxNumBuff[eNBT_FREE_SESSION_MDLS] = LARGE_NBT_NUM_SESSION_MDLS;
  686. #else
  687. pConfig->iMaxNumBuff[eNBT_SESSION_HDR] = LARGE_NBT_NUM_SESSION_HDR ;
  688. pConfig->iMaxNumBuff[eNBT_SEND_CONTEXT] = LARGE_NBT_NUM_SEND_CONTEXT ;
  689. pConfig->iMaxNumBuff[eNBT_RCV_CONTEXT] = LARGE_NBT_NUM_RCV_CONTEXT ;
  690. #endif
  691. break;
  692. }
  693. ReadLmHostFile(pConfig,ParmHandle);
  694. }
  695. #ifdef VXD
  696. #pragma END_INIT
  697. #endif
  698. //----------------------------------------------------------------------------
  699. VOID
  700. ReadParameters2(
  701. IN tNBTCONFIG *pConfig,
  702. IN HANDLE ParmHandle
  703. )
  704. /*++
  705. Routine Description:
  706. This routine is called to read DHCPable parameters from the parameters
  707. section of the NBT section of the registry.
  708. This routine is primarily for the Vxd.
  709. Arguments:
  710. pConfig - A pointer to the configuration data structure.
  711. ParmHandle - a handle to the parameters Key under Nbt
  712. Return Value:
  713. Status
  714. --*/
  715. {
  716. ULONG Node;
  717. ULONG ReadOne;
  718. ULONG ReadTwo;
  719. CTEPagedCode();
  720. Node = CTEReadSingleIntParameter(ParmHandle, // handle of key to look under
  721. WS_NODE_TYPE, // wide string name
  722. 0, // default value
  723. 0);
  724. switch (Node)
  725. {
  726. case 2:
  727. NodeType = PNODE;
  728. break;
  729. case 4:
  730. NodeType = MNODE;
  731. break;
  732. case 8:
  733. NodeType = MSNODE;
  734. break;
  735. case 1:
  736. NodeType = BNODE;
  737. break;
  738. default:
  739. NodeType = BNODE | DEFAULT_NODE_TYPE;
  740. break;
  741. }
  742. RegistryNodeType = NodeType;
  743. // do a trick here - read the registry twice for the same value, passing
  744. // in two different defaults, in order to determine if the registry
  745. // value has been defined or not - since it may be defined, but equal
  746. // to one default.
  747. ReadOne = CTEReadSingleHexParameter(ParmHandle,
  748. WS_ALLONES_BCAST,
  749. DEFAULT_BCAST_ADDR,
  750. 0);
  751. ReadTwo = CTEReadSingleHexParameter(ParmHandle,
  752. WS_ALLONES_BCAST,
  753. 0,
  754. 0);
  755. if (ReadOne != ReadTwo)
  756. {
  757. NbtConfig.UseRegistryBcastAddr = FALSE;
  758. }
  759. else
  760. {
  761. NbtConfig.UseRegistryBcastAddr = TRUE;
  762. NbtConfig.RegistryBcastAddr = ReadTwo;
  763. }
  764. ReadScope(pConfig,ParmHandle);
  765. }
  766. //----------------------------------------------------------------------------
  767. VOID
  768. ReadScope(
  769. IN tNBTCONFIG *pConfig,
  770. IN HANDLE ParmHandle
  771. )
  772. /*++
  773. Routine Description:
  774. This routine is called to read the scope from registry and convert it to
  775. a format where the intervening dots are length bytes.
  776. Arguments:
  777. pConfig - A pointer to the configuration data structure.
  778. ParmHandle - a handle to the parameters Key under Nbt
  779. Return Value:
  780. Status
  781. --*/
  782. {
  783. NTSTATUS status;
  784. PUCHAR pScope, pOldScope, pNewScope;
  785. PUCHAR pBuff;
  786. PUCHAR pBuffer;
  787. PUCHAR pPeriod;
  788. ULONG Len;
  789. UCHAR Chr;
  790. CTEPagedCode();
  791. //
  792. // this routine returns the scope in a dotted format.
  793. // "Scope.MoreScope.More" The dots are
  794. // converted to byte lengths by the code below. This routine allocates
  795. // the memory for the pScope string.
  796. //
  797. status = CTEReadIniString(ParmHandle,NBT_SCOPEID,&pBuffer);
  798. if (NT_SUCCESS(status))
  799. {
  800. //
  801. // the user can type in an * to indicate that they really want
  802. // a null scope and that should override the DHCP scope. So check
  803. // here for an * and if so, set the scope back to null.
  804. //
  805. if ((strlen(pBuffer) == 0) || (pBuffer[0] == '*'))
  806. {
  807. CTEMemFree(pBuffer);
  808. status = STATUS_UNSUCCESSFUL;
  809. }
  810. }
  811. if (NT_SUCCESS(status))
  812. {
  813. // length of scope is num chars plus the 0 on the end, plus
  814. // the length byte on the start(+2 total) - so allocate another buffer
  815. // that is one longer than the previous one so it can include
  816. // these extra two bytes.
  817. //
  818. Len = strlen(pBuffer);
  819. //
  820. // the scope cannot be longer than 255 characters as per RFC1002
  821. //
  822. if (Len <= MAX_SCOPE_LENGTH)
  823. {
  824. pScope = NbtAllocMem (Len+2, NBT_TAG2('02'));
  825. if (pScope)
  826. {
  827. CTEMemCopy((pScope+1),pBuffer,Len);
  828. //
  829. // Put a null on the end of the scope
  830. //
  831. pScope[Len+1] = 0;
  832. Len = 1;
  833. // now go through the string converting periods to length
  834. // bytes - we know the first byte is a length byte so skip it.
  835. //
  836. pBuff = pScope;
  837. pBuff++;
  838. Len++;
  839. pPeriod = pScope;
  840. while (Chr = *pBuff)
  841. {
  842. Len++;
  843. if (Chr == '.')
  844. {
  845. *pPeriod = (UCHAR) (pBuff-pPeriod-1);
  846. //
  847. // Each label can be at most 63 bytes long
  848. //
  849. if (*pPeriod > MAX_LABEL_LENGTH)
  850. {
  851. status = STATUS_UNSUCCESSFUL;
  852. NbtLogEvent (EVENT_SCOPE_LABEL_TOO_LONG, STATUS_SUCCESS, 0x104);
  853. break;
  854. }
  855. // check for two periods back to back and use no scope if this
  856. // happens
  857. if (*pPeriod == 0)
  858. {
  859. status = STATUS_UNSUCCESSFUL;
  860. break;
  861. }
  862. pPeriod = pBuff++;
  863. }
  864. else
  865. pBuff++;
  866. }
  867. if (NT_SUCCESS(status))
  868. {
  869. // the last ptr is always the end of the name.
  870. *pPeriod = (UCHAR)(pBuff - pPeriod -1);
  871. pOldScope = pConfig->pScope;
  872. pConfig->pScope = pScope;
  873. pConfig->ScopeLength = (USHORT)Len;
  874. if (pOldScope)
  875. {
  876. CTEMemFree(pOldScope);
  877. }
  878. CTEMemFree(pBuffer);
  879. return;
  880. }
  881. CTEMemFree(pScope);
  882. }
  883. CTEMemFree(pBuffer);
  884. }
  885. else
  886. {
  887. status = STATUS_UNSUCCESSFUL;
  888. NbtLogEvent (EVENT_SCOPE_LABEL_TOO_LONG, STATUS_SUCCESS, 0x105);
  889. }
  890. }
  891. //
  892. // the scope is one byte => '\0' - the length of the root name (zero)
  893. //
  894. // If the old scope and new scope are the same, then don't change the
  895. // scope tag!
  896. //
  897. pOldScope = pConfig->pScope;
  898. if (!(pOldScope) ||
  899. (*pOldScope != '\0'))
  900. {
  901. if (pNewScope = NbtAllocMem ((1), NBT_TAG2('03')))
  902. {
  903. *pNewScope = '\0';
  904. pConfig->ScopeLength = 1;
  905. pConfig->pScope = pNewScope;
  906. if (pOldScope)
  907. {
  908. CTEMemFree(pOldScope);
  909. }
  910. }
  911. }
  912. }
  913. #ifdef VXD
  914. #pragma BEGIN_INIT
  915. #endif
  916. //----------------------------------------------------------------------------
  917. VOID
  918. ReadLmHostFile(
  919. IN tNBTCONFIG *pConfig,
  920. IN HANDLE ParmHandle
  921. )
  922. /*++
  923. Routine Description:
  924. This routine is called to read the lmhost file path from the registry.
  925. Arguments:
  926. pConfig - A pointer to the configuration data structure.
  927. ParmHandle - a handle to the parameters Key under Nbt
  928. Return Value:
  929. Status
  930. --*/
  931. {
  932. NTSTATUS status;
  933. PUCHAR pBuffer, pOldLmHosts;
  934. PUCHAR pchr;
  935. CTEPagedCode();
  936. NbtConfig.PathLength = 0;
  937. pOldLmHosts = pConfig->pLmHosts;
  938. NbtConfig.pLmHosts = NULL;
  939. //
  940. // read in the LmHosts File location
  941. //
  942. #ifdef VXD
  943. status = CTEReadIniString(ParmHandle,WS_LMHOSTS_FILE,&pBuffer);
  944. #else
  945. status = NTGetLmHostPath(&pBuffer);
  946. #endif
  947. //
  948. // Find the last backslash so we can calculate the file path length
  949. //
  950. // Also, the lm host file must include a path of at least "c:\" i.e.
  951. // the registry contains c:\lmhost, otherwise NBT won't be
  952. // able to find the file since it doesn't know what directory
  953. // to look in.
  954. //
  955. if (NT_SUCCESS(status))
  956. {
  957. if (pchr = strrchr(pBuffer,'\\'))
  958. {
  959. NbtConfig.pLmHosts = pBuffer;
  960. NbtConfig.PathLength = (ULONG) (pchr-pBuffer+1); // include backslash in length
  961. IF_DBG(NBT_DEBUG_NAMESRV)
  962. KdPrint(("Nbt.ReadLmHostFile: LmHostsFile path is %s\n",NbtConfig.pLmHosts));
  963. }
  964. else
  965. {
  966. CTEMemFree(pBuffer);
  967. }
  968. }
  969. //
  970. // If we get a new Dhcp address this routine will get called again
  971. // after startup so we need to free any current lmhosts file path
  972. //
  973. if (pOldLmHosts)
  974. {
  975. CTEMemFree(pOldLmHosts);
  976. }
  977. }
  978. #ifdef VXD
  979. #pragma END_INIT
  980. #endif