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.

2395 lines
62 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. atkinit.c
  5. Abstract:
  6. This module contains the initialization code for the Appletalk stack.
  7. Author:
  8. Jameel Hyder (jameelh@microsoft.com)
  9. Nikhil Kamkolkar (nikhilk@microsoft.com)
  10. Revision History:
  11. 19 Jun 1992 Initial Version
  12. Notes: Tab stop: 4
  13. --*/
  14. #include <atalk.h>
  15. #pragma hdrstop
  16. #define FILENUM ATKINIT
  17. #ifdef ALLOC_PRAGMA
  18. #pragma alloc_text(INIT, AtalkInitializeTransport)
  19. #pragma alloc_text(PAGEINIT, atalkInitGetHandleToKey)
  20. #pragma alloc_text(PAGEINIT, atalkInitGlobal)
  21. #pragma alloc_text(PAGEINIT, atalkInitPort)
  22. #pragma alloc_text(PAGEINIT, atalkInitNetRangeCheck)
  23. #pragma alloc_text(PAGEINIT, atalkInitNetRange)
  24. #pragma alloc_text(PAGEINIT, atalkInitZoneList)
  25. #pragma alloc_text(PAGEINIT, atalkInitDefZone)
  26. #pragma alloc_text(PAGEINIT, atalkInitSeeding)
  27. #pragma alloc_text(PAGEINIT, atalkInitPortParameters)
  28. #pragma alloc_text(PAGEINIT, atalkInitStartPort)
  29. #pragma alloc_text(PAGEINIT, AtalkInitAdapter)
  30. #pragma alloc_text(PAGEINIT, AtalkDeinitAdapter)
  31. #pragma alloc_text(PAGEINIT, atalkInitStartPort)
  32. #endif
  33. NTSTATUS
  34. AtalkInitializeTransport(
  35. IN PDRIVER_OBJECT pDrvObj,
  36. IN PUNICODE_STRING pRegPath
  37. )
  38. /*++
  39. Routine Description:
  40. This routine is called during initialization time to
  41. initialize the transport.
  42. Arguments:
  43. Return Value:
  44. Status - STATUS_SUCCESS if initialized,
  45. Appropriate NT error code otherwise
  46. --*/
  47. {
  48. PPORT_DESCRIPTOR pPortDesc;
  49. NTSTATUS status;
  50. do
  51. {
  52. // Initialize the default-port event
  53. KeInitializeEvent(&AtalkDefaultPortEvent, NotificationEvent, FALSE);
  54. // Save our registry path
  55. if ((AtalkRegPath.Buffer = AtalkAllocMemory(pRegPath->Length)) == NULL)
  56. {
  57. status = STATUS_INSUFFICIENT_RESOURCES;
  58. RES_LOG_ERROR();
  59. break;
  60. }
  61. AtalkRegPath.MaximumLength =
  62. AtalkRegPath.Length = pRegPath->Length;
  63. RtlCopyMemory(AtalkRegPath.Buffer,
  64. pRegPath->Buffer,
  65. pRegPath->Length);
  66. AtalkInitMemorySystem();
  67. // Get the frequency of the performance counters
  68. KeQueryPerformanceCounter(&AtalkStatistics.stat_PerfFreq);
  69. // Initialize the timer subsystem
  70. if (!NT_SUCCESS(status = AtalkTimerInit()) ||
  71. !NT_SUCCESS(status = AtalkZipInit(TRUE)))
  72. {
  73. RES_LOG_ERROR();
  74. break;
  75. }
  76. // Initialize the global port descriptors
  77. AtalkPortList = NULL;
  78. AtalkDefaultPort = NULL;
  79. AtalkNumberOfPorts = 0;
  80. AtalkRouter = FALSE;
  81. // Get the global parameters
  82. status = atalkInitGlobal();
  83. if (!NT_SUCCESS(status))
  84. {
  85. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  86. ("AtalkInitializeTransport: AtalkInitGlobal failed %ul\n", status));
  87. break;
  88. }
  89. if (!NT_SUCCESS(status = AtalkNdisInitRegisterProtocol()))
  90. {
  91. break;
  92. }
  93. } while (FALSE);
  94. if (NT_SUCCESS(status))
  95. {
  96. #if DBG
  97. AtalkTimerInitialize(&AtalkDumpTimerList,
  98. AtalkDumpComponents,
  99. DBG_DUMP_DEF_INTERVAL);
  100. AtalkTimerScheduleEvent(&AtalkDumpTimerList);
  101. #endif
  102. // Initialize the other subsystems now
  103. AtalkInitAspInitialize();
  104. AtalkInitPapInitialize();
  105. AtalkInitAdspInitialize();
  106. }
  107. else
  108. {
  109. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  110. ("Initialization failed!\n"));
  111. // We are not loading. Stop everything and return.
  112. // Stop all ports, release port resources
  113. // Stop the timer subsystem if it was started
  114. AtalkCleanup();
  115. }
  116. return status;
  117. }
  118. NTSTATUS
  119. atalkInitGetHandleToKey(
  120. IN PUNICODE_STRING KeyName,
  121. OUT PHANDLE KeyHandle
  122. )
  123. /*++
  124. Routine Description:
  125. Returns the handle for the key specified using SectionHandle as the
  126. root.
  127. Arguments:
  128. SectionHandle - Key to registry tree root
  129. KeyNameString - name of key to be opened
  130. KeyHandle - Returns the handle for KeyNameString
  131. Return Value:
  132. The status of the request.
  133. --*/
  134. {
  135. HANDLE ConfigHandle;
  136. NTSTATUS status;
  137. OBJECT_ATTRIBUTES ObjectAttributes;
  138. *KeyHandle = NULL;
  139. InitializeObjectAttributes(&ObjectAttributes,
  140. &AtalkRegPath, // name
  141. OBJ_CASE_INSENSITIVE, // attributes
  142. NULL, // root
  143. NULL); // security descriptor
  144. status = ZwOpenKey(&ConfigHandle,
  145. KEY_READ,
  146. &ObjectAttributes);
  147. if (NT_SUCCESS(status))
  148. {
  149. InitializeObjectAttributes(&ObjectAttributes,
  150. KeyName, // name
  151. OBJ_CASE_INSENSITIVE, // attributes
  152. ConfigHandle, // root
  153. NULL); // security descriptor
  154. status = ZwOpenKey(KeyHandle,
  155. KEY_READ,
  156. &ObjectAttributes);
  157. ZwClose(ConfigHandle);
  158. }
  159. return status;
  160. }
  161. NTSTATUS
  162. atalkInitGlobal(
  163. VOID
  164. )
  165. /*++
  166. Routine Description:
  167. Reads the Parameters key to get the global parameters. These are:
  168. - DefaultPort
  169. - DesiredZOne
  170. - EnableRouter
  171. - FilterOurNames
  172. Arguments:
  173. Return Value:
  174. Status - STATUS_SUCCESS
  175. Or other NT status codes
  176. --*/
  177. {
  178. UNICODE_STRING valueName, unicodePortName, unicodeZone;
  179. UNICODE_STRING rasName;
  180. HANDLE ParametersHandle;
  181. ANSI_STRING ansiZone;
  182. BYTE ansiBuf[MAX_ENTITY_LENGTH+1];
  183. NTSTATUS status;
  184. ULONG bytesWritten;
  185. PWCHAR portName;
  186. PWCHAR desiredZoneValue;
  187. PCHAR asciiDesiredZone = NULL;
  188. BYTE Storage[2*2*MAX_ENTITY_LENGTH+sizeof(KEY_VALUE_FULL_INFORMATION)];
  189. PKEY_VALUE_FULL_INFORMATION Info = (PKEY_VALUE_FULL_INFORMATION)Storage;
  190. PULONG Value;
  191. do
  192. {
  193. // Open the parameters key.
  194. RtlInitUnicodeString(&valueName, PARAMETERS_STRING);
  195. status = atalkInitGetHandleToKey(&valueName,
  196. &ParametersHandle);
  197. if (!NT_SUCCESS(status))
  198. {
  199. break;
  200. }
  201. // Read the "EnableRouter" value name
  202. RtlInitUnicodeString (&valueName, VALUENAME_ENABLEROUTER);
  203. status = ZwQueryValueKey(ParametersHandle,
  204. &valueName,
  205. KeyValueFullInformation,
  206. Info,
  207. sizeof(Storage),
  208. &bytesWritten);
  209. if (status == STATUS_SUCCESS)
  210. {
  211. Value = (PULONG)((PBYTE)Info + Info->DataOffset);
  212. if (*Value != 0)
  213. {
  214. // if router wasn't running before, change that! (PnP case)
  215. if (!AtalkRouter)
  216. {
  217. AtalkRouter = TRUE;
  218. AtalkRtmpInit(TRUE);
  219. AtalkLockRouterIfNecessary();
  220. }
  221. }
  222. else
  223. {
  224. AtalkRouter = FALSE;
  225. }
  226. }
  227. else
  228. {
  229. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  230. ("atalkInitGlobal: EnableRouter value not found, assuming false\n"));
  231. }
  232. // Read the "FilterOurNames" value name
  233. RtlInitUnicodeString (&valueName, VALUENAME_FILTEROURNAMES);
  234. status = ZwQueryValueKey(ParametersHandle,
  235. &valueName,
  236. KeyValueFullInformation,
  237. Info,
  238. sizeof(Storage),
  239. &bytesWritten);
  240. if (status == STATUS_SUCCESS)
  241. {
  242. Value = (PULONG)((PBYTE)Info + Info->DataOffset);
  243. if (*Value == 0)
  244. {
  245. AtalkFilterOurNames = FALSE;
  246. }
  247. }
  248. else
  249. {
  250. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_WARN,
  251. ("atalkInitGlobal: FilterOurNames value not found, assuming true\nq"));
  252. }
  253. // Get the default port value
  254. RtlInitUnicodeString (&valueName, VALUENAME_DEFAULTPORT);
  255. status = ZwQueryValueKey(ParametersHandle,
  256. &valueName,
  257. KeyValueFullInformation,
  258. Info,
  259. sizeof(Storage),
  260. &bytesWritten);
  261. if (status != STATUS_SUCCESS)
  262. {
  263. // No default port keyword specified! ABORT
  264. LOG_ERROR(EVENT_ATALK_NO_DEFAULTPORT, status, NULL, 0);
  265. ZwClose(ParametersHandle);
  266. // let appletalk run: it's just that it won't have default adapter
  267. status = STATUS_SUCCESS;
  268. break;
  269. }
  270. portName = (PWCHAR)((PBYTE)Info + Info->DataOffset);
  271. AtalkDefaultPortName.Buffer = NULL;
  272. if (*portName != 0)
  273. {
  274. RtlInitUnicodeString(&unicodePortName, portName);
  275. RtlInitUnicodeString(&rasName,RAS_ADAPTER_NAME);
  276. // make sure this isn't RAS adapter (setup bug)
  277. if (RtlEqualUnicodeString(&unicodePortName,&rasName,TRUE))
  278. {
  279. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  280. ("atalkInitGlobal: can't have RAS adapter as default adapter!\n"));
  281. // No default port keyword specified! ABORT
  282. LOG_ERROR(EVENT_ATALK_NO_DEFAULTPORT, status, NULL, 0);
  283. ZwClose(ParametersHandle);
  284. status = STATUS_INVALID_PARAMETER;
  285. break;
  286. }
  287. AtalkDefaultPortName.Buffer = AtalkAllocMemory(unicodePortName.Length);
  288. if (AtalkDefaultPortName.Buffer != NULL)
  289. {
  290. AtalkDefaultPortName.Length =
  291. AtalkDefaultPortName.MaximumLength = unicodePortName.Length;
  292. RtlCopyMemory(AtalkDefaultPortName.Buffer,
  293. unicodePortName.Buffer,
  294. unicodePortName.Length);
  295. }
  296. }
  297. if (AtalkDefaultPortName.Buffer == NULL)
  298. {
  299. LOG_ERROR(EVENT_ATALK_NO_DEFAULTPORT, status, NULL, 0);
  300. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  301. ("WARNING!!! Appletalk driver running, but no default port configured\n"));
  302. ZwClose(ParametersHandle);
  303. // let appletalk run: it's just that it won't have default adapter
  304. status = STATUS_SUCCESS;
  305. break;
  306. }
  307. // Get the desired zone value in the form of an asciiz string
  308. RtlInitUnicodeString (&valueName, VALUENAME_DESIREDZONE);
  309. status = ZwQueryValueKey(ParametersHandle,
  310. &valueName,
  311. KeyValueFullInformation,
  312. Info,
  313. sizeof(Storage),
  314. &bytesWritten);
  315. // Close this handle now - we do not need it anymore
  316. ZwClose(ParametersHandle);
  317. ParametersHandle = NULL;
  318. if (status != STATUS_SUCCESS)
  319. {
  320. LOG_ERROR(EVENT_ATALK_INVALID_DESIREDZONE, status, NULL, 0);
  321. status = STATUS_SUCCESS;
  322. break;
  323. }
  324. desiredZoneValue = (PWCHAR)((PBYTE)Info + Info->DataOffset);
  325. if (*desiredZoneValue != 0)
  326. {
  327. RtlInitUnicodeString(&unicodeZone, desiredZoneValue);
  328. ansiZone.Length = (USHORT)RtlUnicodeStringToAnsiSize(&unicodeZone)-1;
  329. if (ansiZone.Length > MAX_ENTITY_LENGTH)
  330. {
  331. status = STATUS_UNSUCCESSFUL;
  332. // Incorrect zone name!
  333. LOG_ERROR(EVENT_ATALK_INVALID_DESIREDZONE, status, NULL, 0);
  334. break;
  335. }
  336. ansiZone.Buffer = ansiBuf;
  337. ansiZone.MaximumLength = sizeof(ansiBuf);
  338. status = RtlUnicodeStringToAnsiString(&ansiZone,
  339. &unicodeZone,
  340. (BOOLEAN)FALSE);
  341. if (status == STATUS_SUCCESS)
  342. {
  343. AtalkDesiredZone = AtalkZoneReferenceByName(ansiBuf, (BYTE)(ansiZone.Length));
  344. }
  345. if ((status != STATUS_SUCCESS) ||
  346. (AtalkDesiredZone == NULL))
  347. {
  348. LOG_ERROR(EVENT_ATALK_RESOURCES, status, NULL, 0);
  349. }
  350. }
  351. } while (FALSE);
  352. return status;
  353. }
  354. NTSTATUS
  355. atalkInitPort(
  356. IN PPORT_DESCRIPTOR pPortDesc,
  357. IN HANDLE AdaptersHandle
  358. )
  359. /*++
  360. Routine Description:
  361. This routine is called during initialization time to get the per port
  362. parameters from the registry. It will store the per port parameters
  363. in the port information structures readying them to be passed to the main
  364. initialize() routine
  365. Arguments:
  366. AdaptersHandle- Handle to the ...\Parameters\Adapters key in registry
  367. Return Value:
  368. Status - STATUS_SUCCESS
  369. STATUS_INSUFFICIENT_RESOURCES
  370. --*/
  371. {
  372. OBJECT_ATTRIBUTES ObjectAttributes;
  373. NTSTATUS status;
  374. BOOLEAN seeding;
  375. // Get the key to the adapter for this port
  376. InitializeObjectAttributes(&ObjectAttributes,
  377. &pPortDesc->pd_AdapterKey, // name
  378. OBJ_CASE_INSENSITIVE, // attributes
  379. AdaptersHandle, // root
  380. NULL); // security descriptor
  381. status = ZwOpenKey(&pPortDesc->pd_AdapterInfoHandle,
  382. KEY_READ,
  383. &ObjectAttributes);
  384. if (!NT_SUCCESS(status))
  385. {
  386. if (!AtalkRouter)
  387. status = STATUS_SUCCESS;
  388. return status;
  389. }
  390. //
  391. // if this is the first time the adapter is being initialized (usually the case),
  392. // read the PramNodes from the registry. If we are initializing this adapter on
  393. // a PnP event, then there is a good chance our network config has changed, so
  394. // ignore the registry values and get fresh ones)
  395. //
  396. if (!(pPortDesc->pd_Flags & PD_CONFIGURED_ONCE))
  397. {
  398. pPortDesc->pd_Flags |= PD_CONFIGURED_ONCE;
  399. // Get PRAM Information
  400. AtalkInitNodeGetPramAddr(pPortDesc,
  401. ROUTER_NODE_VALUE,
  402. &pPortDesc->pd_RoutersPramNode);
  403. AtalkInitNodeGetPramAddr(pPortDesc,
  404. USER_NODE1_VALUE,
  405. &pPortDesc->pd_UsersPramNode1);
  406. AtalkInitNodeGetPramAddr(pPortDesc,
  407. USER_NODE2_VALUE,
  408. &pPortDesc->pd_UsersPramNode2);
  409. }
  410. else
  411. {
  412. ASSERT(pPortDesc->pd_RoutersPramNode.atn_Network == 0);
  413. ASSERT(pPortDesc->pd_RoutersPramNode.atn_Node == 0);
  414. ASSERT(pPortDesc->pd_UsersPramNode1.atn_Network == 0);
  415. ASSERT(pPortDesc->pd_UsersPramNode1.atn_Node == 0);
  416. ASSERT(pPortDesc->pd_UsersPramNode2.atn_Network == 0);
  417. ASSERT(pPortDesc->pd_UsersPramNode2.atn_Node == 0);
  418. }
  419. // If we are a router, get the following information
  420. if (AtalkRouter)
  421. {
  422. if (!DEF_PORT(pPortDesc))
  423. {
  424. AtalkZapPramValue(pPortDesc, USER_NODE1_VALUE);
  425. AtalkZapPramValue(pPortDesc, USER_NODE2_VALUE);
  426. }
  427. atalkInitSeeding(pPortDesc, &seeding);
  428. // Check following values only if the seeding flag is set.
  429. if (seeding) do
  430. {
  431. // Get the Network range information. Value names are
  432. // NetworkRangeLowerEnd & NetworkRangeUpperEnd
  433. status = atalkInitNetRange(pPortDesc);
  434. if (!NT_SUCCESS(status))
  435. {
  436. LOG_ERRORONPORT(pPortDesc,
  437. EVENT_ATALK_SEEDROUTER_NONETRANGE,
  438. 0,
  439. NULL,
  440. 0);
  441. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  442. ("atalkInitPort: Could not get network range\n"));
  443. break;
  444. }
  445. status = atalkInitNetRangeCheck(pPortDesc);
  446. if (!NT_SUCCESS(status))
  447. {
  448. break;
  449. }
  450. // Get the Zone list information. Value name is ZoneList
  451. status = atalkInitZoneList(pPortDesc);
  452. if (!NT_SUCCESS(status))
  453. {
  454. LOG_ERRORONPORT(pPortDesc,
  455. EVENT_ATALK_SEEDROUTER_NOZONELIST,
  456. 0,
  457. NULL,
  458. 0);
  459. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  460. ("atalkInitPort: Could not get zone list\n"));
  461. break;
  462. }
  463. // Get the default zone specification. Value name is DefaultZone
  464. status = atalkInitDefZone(pPortDesc);
  465. if (!NT_SUCCESS(status))
  466. {
  467. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  468. ("atalkInitPort: Could not get default zone\n"));
  469. break;
  470. }
  471. // Check for default zone being in the zone list for the port
  472. // Also make sure that a localtalk port is not specified
  473. // as the default port. And that a default zone was not
  474. // specified for a localtalk port. We can only do this after
  475. // bind as we do not know until then the media type.
  476. if (pPortDesc->pd_Flags & PD_SEED_ROUTER)
  477. {
  478. if (pPortDesc->pd_InitialDefaultZone == NULL)
  479. {
  480. LOG_ERRORONPORT(pPortDesc,
  481. EVENT_ATALK_NO_DEFZONE,
  482. 0,
  483. NULL,
  484. 0);
  485. status = STATUS_UNSUCCESSFUL;
  486. break;
  487. }
  488. if (pPortDesc->pd_InitialZoneList == NULL)
  489. {
  490. LOG_ERRORONPORT(pPortDesc,
  491. EVENT_ATALK_SEEDROUTER_NOZONELIST,
  492. 0,
  493. NULL,
  494. 0);
  495. status = STATUS_UNSUCCESSFUL;
  496. break;
  497. }
  498. if (!AtalkZoneOnList(pPortDesc->pd_InitialDefaultZone,
  499. pPortDesc->pd_InitialZoneList))
  500. {
  501. LOG_ERRORONPORT(pPortDesc,
  502. EVENT_ATALK_ZONE_NOTINLIST,
  503. 0,
  504. NULL,
  505. 0);
  506. status = STATUS_UNSUCCESSFUL;
  507. break;
  508. }
  509. }
  510. } while (FALSE);
  511. }
  512. else
  513. {
  514. AtalkZapPramValue(pPortDesc, ROUTER_NODE_VALUE);
  515. }
  516. if (NT_SUCCESS(status)) do
  517. {
  518. // Get the per-Port parameters
  519. status = atalkInitPortParameters(pPortDesc);
  520. if (!NT_SUCCESS(status))
  521. {
  522. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  523. ("atalkInitPort: Could not get port parameters\n"));
  524. }
  525. // None of the above affect us loading.
  526. status = STATUS_SUCCESS;
  527. break;
  528. } while (FALSE);
  529. return status;
  530. }
  531. NTSTATUS
  532. atalkInitNetRangeCheck(
  533. IN PPORT_DESCRIPTOR pPortDesc
  534. )
  535. /*++
  536. Routine Description:
  537. Arguments:
  538. Return Value:
  539. --*/
  540. {
  541. PPORT_DESCRIPTOR pTmp;
  542. NTSTATUS status = STATUS_SUCCESS;
  543. do
  544. {
  545. // Check for network range overlap among all the ports
  546. for (pTmp = AtalkPortList;
  547. pTmp != NULL;
  548. pTmp = pTmp->pd_Next)
  549. {
  550. if (pTmp != pPortDesc)
  551. {
  552. if ((pPortDesc->pd_InitialNetworkRange.anr_FirstNetwork != UNKNOWN_NETWORK) &&
  553. (pTmp->pd_InitialNetworkRange.anr_FirstNetwork != UNKNOWN_NETWORK))
  554. {
  555. if (AtalkRangesOverlap(&pPortDesc->pd_InitialNetworkRange,
  556. &pTmp->pd_InitialNetworkRange))
  557. {
  558. LOG_ERRORONPORT(pPortDesc,
  559. EVENT_ATALK_INITIAL_RANGEOVERLAP,
  560. status,
  561. NULL,
  562. 0);
  563. status = STATUS_UNSUCCESSFUL;
  564. break;
  565. }
  566. }
  567. }
  568. }
  569. if (!NT_SUCCESS(status))
  570. {
  571. break;
  572. }
  573. // Make sure any PRAM values we might have are in this range
  574. if ((pPortDesc->pd_RoutersPramNode.atn_Network != UNKNOWN_NETWORK) &&
  575. (pPortDesc->pd_InitialNetworkRange.anr_FirstNetwork != UNKNOWN_NETWORK) &&
  576. !(WITHIN_NETWORK_RANGE(pPortDesc->pd_RoutersPramNode.atn_Network,
  577. &pPortDesc->pd_InitialNetworkRange)))
  578. {
  579. LOG_ERRORONPORT(pPortDesc,
  580. EVENT_ATALK_PRAM_OUTOFSYNC,
  581. status,
  582. NULL,
  583. 0);
  584. pPortDesc->pd_RoutersPramNode.atn_Network = UNKNOWN_NETWORK;
  585. pPortDesc->pd_RoutersPramNode.atn_Node = UNKNOWN_NODE;
  586. }
  587. if ((pPortDesc->pd_UsersPramNode1.atn_Network != UNKNOWN_NETWORK) &&
  588. (pPortDesc->pd_InitialNetworkRange.anr_FirstNetwork != UNKNOWN_NETWORK) &&
  589. !(WITHIN_NETWORK_RANGE(pPortDesc->pd_UsersPramNode1.atn_Network,
  590. &pPortDesc->pd_InitialNetworkRange)))
  591. {
  592. LOG_ERRORONPORT(pPortDesc,
  593. EVENT_ATALK_PRAM_OUTOFSYNC,
  594. status,
  595. NULL,
  596. 0);
  597. pPortDesc->pd_UsersPramNode1.atn_Network = UNKNOWN_NETWORK;
  598. pPortDesc->pd_UsersPramNode1.atn_Node = UNKNOWN_NODE;
  599. }
  600. if ((pPortDesc->pd_UsersPramNode2.atn_Network != UNKNOWN_NETWORK) &&
  601. (pPortDesc->pd_InitialNetworkRange.anr_FirstNetwork != UNKNOWN_NETWORK) &&
  602. !(WITHIN_NETWORK_RANGE(pPortDesc->pd_UsersPramNode2.atn_Network,
  603. &pPortDesc->pd_InitialNetworkRange)))
  604. {
  605. LOG_ERRORONPORT(pPortDesc,
  606. EVENT_ATALK_PRAM_OUTOFSYNC,
  607. status,
  608. NULL,
  609. 0);
  610. pPortDesc->pd_UsersPramNode2.atn_Network = UNKNOWN_NETWORK;
  611. pPortDesc->pd_UsersPramNode2.atn_Node = UNKNOWN_NODE;
  612. }
  613. } while (FALSE);
  614. return status;
  615. }
  616. NTSTATUS
  617. atalkInitNetRange(
  618. OUT PPORT_DESCRIPTOR pPortDesc
  619. )
  620. /*++
  621. Routine Description:
  622. Gets the network range for the port defined by AdapterInfoHandle
  623. Arguments:
  624. AdapterInfoHandle- Handle to ...Atalk\Adapters\<adapterName>
  625. pPortDesc- Pointer to port information structure for the port
  626. Return Value:
  627. Status - STATUS_SUCCESS or system call returned status codes
  628. --*/
  629. {
  630. UNICODE_STRING valueName;
  631. NTSTATUS registryStatus;
  632. ULONG bytesWritten;
  633. PULONG netNumber;
  634. BYTE netNumberStorage[sizeof(KEY_VALUE_FULL_INFORMATION) + 80];
  635. PKEY_VALUE_FULL_INFORMATION netValue = (PKEY_VALUE_FULL_INFORMATION)netNumberStorage;
  636. do
  637. {
  638. // Read the "NetworkRangeLowerEnd" value name
  639. RtlInitUnicodeString (&valueName, VALUENAME_NETLOWEREND);
  640. registryStatus = ZwQueryValueKey(pPortDesc->pd_AdapterInfoHandle,
  641. &valueName,
  642. KeyValueFullInformation,
  643. netValue,
  644. sizeof(netNumberStorage),
  645. &bytesWritten);
  646. // This should change with the routing flags.
  647. if (registryStatus != STATUS_SUCCESS)
  648. {
  649. // Set defaults
  650. pPortDesc->pd_InitialNetworkRange.anr_FirstNetwork = UNKNOWN_NETWORK;
  651. pPortDesc->pd_InitialNetworkRange.anr_LastNetwork = UNKNOWN_NETWORK;
  652. registryStatus = STATUS_SUCCESS;
  653. break;
  654. }
  655. netNumber = (PULONG)((PBYTE)netValue + netValue->DataOffset);
  656. pPortDesc->pd_InitialNetworkRange.anr_FirstNetwork = (USHORT)(*netNumber);
  657. // Get the upper number only if lower was specified
  658. RtlInitUnicodeString (&valueName, VALUENAME_NETUPPEREND);
  659. registryStatus = ZwQueryValueKey(pPortDesc->pd_AdapterInfoHandle,
  660. &valueName,
  661. KeyValueFullInformation,
  662. netValue,
  663. sizeof(netNumberStorage),
  664. &bytesWritten);
  665. if (registryStatus != STATUS_SUCCESS)
  666. {
  667. // Do not load if lower end specified but upper end was not
  668. break;
  669. }
  670. // Set the upper end of the network range
  671. netNumber = (PULONG)((PBYTE)netValue + netValue->DataOffset);
  672. pPortDesc->pd_InitialNetworkRange.anr_LastNetwork =(USHORT)(*netNumber);
  673. if (!AtalkCheckNetworkRange(&pPortDesc->pd_InitialNetworkRange))
  674. {
  675. registryStatus = STATUS_UNSUCCESSFUL;
  676. break;
  677. }
  678. } while (FALSE);
  679. if (registryStatus != STATUS_SUCCESS)
  680. {
  681. LOG_ERRORONPORT(pPortDesc,
  682. EVENT_ATALK_INVALID_NETRANGE,
  683. registryStatus,
  684. NULL,
  685. 0);
  686. }
  687. return registryStatus;
  688. }
  689. NTSTATUS
  690. atalkInitZoneList(
  691. OUT PPORT_DESCRIPTOR pPortDesc
  692. )
  693. /*++
  694. Routine Description:
  695. Gets the zone list for the port defined by AdapterInfoHandle
  696. Arguments:
  697. AdapterInfoHandle- Handle to ...Atalk\Adapters\<adapterName>
  698. pPortDesc- Pointer to port information structure for the port
  699. Return Value:
  700. Status - STATUS_SUCCESS or system call returned status codes
  701. --*/
  702. {
  703. UNICODE_STRING valueName;
  704. NTSTATUS status;
  705. ULONG bytesWritten;
  706. PWCHAR curZoneValue;
  707. // Anticipate about 10 zones and get space for those, if more then do a
  708. // dynamic alloc. Note that the below *does not* guarantee 10 zones...
  709. BYTE zoneStorage[10*2*(MAX_ENTITY_LENGTH)+sizeof(KEY_VALUE_FULL_INFORMATION)];
  710. PKEY_VALUE_FULL_INFORMATION zoneValue = (PKEY_VALUE_FULL_INFORMATION)zoneStorage;
  711. RtlInitUnicodeString (&valueName, VALUENAME_ZONELIST);
  712. status = ZwQueryValueKey(pPortDesc->pd_AdapterInfoHandle,
  713. &valueName,
  714. KeyValueFullInformation,
  715. zoneValue,
  716. sizeof(zoneStorage),
  717. &bytesWritten);
  718. if (status == STATUS_BUFFER_OVERFLOW)
  719. {
  720. // If error was a buffer overrun, then allocate space and try again
  721. zoneValue = (PKEY_VALUE_FULL_INFORMATION)AtalkAllocMemory(bytesWritten);
  722. if (zoneValue == NULL)
  723. {
  724. return STATUS_INSUFFICIENT_RESOURCES;
  725. }
  726. status = ZwQueryValueKey(pPortDesc->pd_AdapterInfoHandle,
  727. &valueName,
  728. KeyValueFullInformation,
  729. zoneValue,
  730. bytesWritten,
  731. &bytesWritten);
  732. }
  733. do
  734. {
  735. if (status != STATUS_SUCCESS)
  736. {
  737. break;
  738. }
  739. // Proceed to get zone list
  740. pPortDesc->pd_InitialZoneList = NULL;
  741. curZoneValue = (PWCHAR)((PBYTE)zoneValue + zoneValue->DataOffset);
  742. while (*curZoneValue != 0)
  743. {
  744. UNICODE_STRING Us;
  745. ANSI_STRING As;
  746. BYTE ansiBuf[MAX_ENTITY_LENGTH + 1];
  747. RtlInitUnicodeString(&Us, curZoneValue);
  748. As.Buffer = ansiBuf;
  749. As.Length = (USHORT)RtlUnicodeStringToAnsiSize(&Us) - 1;
  750. As.MaximumLength = sizeof(ansiBuf);
  751. if (As.Length > MAX_ENTITY_LENGTH)
  752. {
  753. // Incorrect zone name!
  754. LOG_ERROR(EVENT_ATALK_INVALID_ZONEINLIST, status, NULL, 0);
  755. }
  756. status = RtlUnicodeStringToAnsiString(&As, &Us, FALSE);
  757. if (!NT_SUCCESS(status))
  758. {
  759. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  760. ("atalkInitZoneList: RtlUnicodeStringToAnsiSize %lx\n", status));
  761. break;
  762. }
  763. // Insert the zone in the list in Port
  764. pPortDesc->pd_InitialZoneList = AtalkZoneAddToList(pPortDesc->pd_InitialZoneList,
  765. ansiBuf,
  766. (BYTE)(As.Length));
  767. if (pPortDesc->pd_InitialZoneList == NULL)
  768. {
  769. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  770. ("atalkInitZoneList: AtalkZoneAddToList failed\n"));
  771. break;
  772. }
  773. // Now advance the curZoneValue value to next zone
  774. curZoneValue = (PWCHAR)((PBYTE)curZoneValue + Us.Length + sizeof(WCHAR));
  775. }
  776. } while (FALSE);
  777. if ((PVOID)zoneValue != (PVOID)zoneStorage)
  778. {
  779. AtalkFreeMemory(zoneValue);
  780. }
  781. return status;
  782. }
  783. NTSTATUS
  784. atalkInitDefZone(
  785. OUT PPORT_DESCRIPTOR pPortDesc
  786. )
  787. /*++
  788. Routine Description:
  789. Gets the default zone for the port defined by AdapterInfoHandle
  790. Arguments:
  791. AdapterInfoHandle- Handle to ...Atalk\Adapters\<adapterName>
  792. pPort- Pointer to port information structure for the port
  793. Return Value:
  794. Status - STATUS_SUCCESS or system call returned status codes
  795. --*/
  796. {
  797. UNICODE_STRING valueName;
  798. NTSTATUS status;
  799. ULONG bytesWritten;
  800. PWCHAR defZoneValue;
  801. BYTE zoneStorage[2*MAX_ENTITY_LENGTH+sizeof(KEY_VALUE_FULL_INFORMATION)];
  802. PKEY_VALUE_FULL_INFORMATION zoneValue = (PKEY_VALUE_FULL_INFORMATION)zoneStorage;
  803. RtlInitUnicodeString (&valueName, VALUENAME_DEFAULTZONE);
  804. status = ZwQueryValueKey(pPortDesc->pd_AdapterInfoHandle,
  805. &valueName,
  806. KeyValueFullInformation,
  807. zoneValue,
  808. sizeof(zoneStorage),
  809. &bytesWritten);
  810. if (status == STATUS_BUFFER_OVERFLOW)
  811. {
  812. // If error was a buffer overrun, then allocate space and try again
  813. zoneValue = (PKEY_VALUE_FULL_INFORMATION)AtalkAllocMemory(bytesWritten);
  814. if (zoneValue == NULL)
  815. {
  816. return STATUS_INSUFFICIENT_RESOURCES;
  817. }
  818. status = ZwQueryValueKey(pPortDesc->pd_AdapterInfoHandle,
  819. &valueName,
  820. KeyValueFullInformation,
  821. zoneValue,
  822. bytesWritten,
  823. &bytesWritten);
  824. }
  825. do
  826. {
  827. if (status != STATUS_SUCCESS)
  828. {
  829. LOG_ERRORONPORT(pPortDesc,
  830. EVENT_ATALK_NO_DEFZONE,
  831. status,
  832. NULL,
  833. 0);
  834. status = STATUS_SUCCESS;
  835. break;
  836. }
  837. else
  838. {
  839. ANSI_STRING ansiZone;
  840. UNICODE_STRING unicodeZone;
  841. BYTE ansiBuf[MAX_ENTITY_LENGTH+1];
  842. NTSTATUS status;
  843. defZoneValue = (PWCHAR)((PBYTE)zoneValue + zoneValue->DataOffset);
  844. if (*defZoneValue != 0)
  845. {
  846. RtlInitUnicodeString(&unicodeZone, defZoneValue);
  847. ansiZone.Length = (USHORT)RtlUnicodeStringToAnsiSize(&unicodeZone) - 1;
  848. if (ansiZone.Length > MAX_ENTITY_LENGTH+1)
  849. {
  850. status = STATUS_UNSUCCESSFUL;
  851. // Incorrect zone name!
  852. LOG_ERRORONPORT(pPortDesc,
  853. EVENT_ATALK_INVALID_DEFZONE,
  854. status,
  855. NULL,
  856. 0);
  857. break;
  858. }
  859. ansiZone.Buffer = ansiBuf;
  860. ansiZone.MaximumLength = sizeof(ansiBuf);
  861. status = RtlUnicodeStringToAnsiString(&ansiZone, &unicodeZone, (BOOLEAN)FALSE);
  862. if (status == STATUS_SUCCESS)
  863. {
  864. PZONE pZone;
  865. PZONE_LIST pZoneList;
  866. // Ensure that the zone exists in the zone list, We are seed-routing
  867. ASSERT(pPortDesc->pd_Flags & PD_SEED_ROUTER);
  868. for (pZoneList = pPortDesc->pd_InitialZoneList;
  869. pZoneList != NULL;
  870. pZoneList = pZoneList->zl_Next)
  871. {
  872. pZone = pZoneList->zl_pZone;
  873. if (AtalkFixedCompareCaseInsensitive(pZone->zn_Zone,
  874. pZone->zn_ZoneLen,
  875. ansiBuf,
  876. ansiZone.Length))
  877. {
  878. break;
  879. }
  880. }
  881. if (pZone == NULL)
  882. {
  883. // Incorrect zone name - not in the list
  884. LOG_ERRORONPORT(pPortDesc,
  885. EVENT_ATALK_INVALID_DEFZONE,
  886. status,
  887. NULL,
  888. 0);
  889. }
  890. pPortDesc->pd_InitialDefaultZone = AtalkZoneReferenceByName(ansiBuf,
  891. (BYTE)(ansiZone.Length));
  892. }
  893. if ((status != STATUS_SUCCESS) ||
  894. (pPortDesc->pd_InitialDefaultZone == NULL))
  895. {
  896. LOG_ERROR(EVENT_ATALK_RESOURCES, status, NULL, 0);
  897. }
  898. }
  899. }
  900. } while (FALSE);
  901. if ((PVOID)zoneValue != (PVOID)zoneStorage)
  902. {
  903. AtalkFreeMemory(zoneValue);
  904. }
  905. return status;
  906. }
  907. NTSTATUS
  908. atalkInitSeeding(
  909. IN OUT PPORT_DESCRIPTOR pPortDesc,
  910. OUT PBOOLEAN Seeding
  911. )
  912. /*++
  913. Routine Description:
  914. Gets the value of the enable router flag from the registry. Sets the
  915. startRouter value in PortInfo based on this flag.
  916. Arguments:
  917. AdapterHandle- Handle to the Adapter in registry
  918. Return Value:
  919. Value of the flag: TRUE/FALSE
  920. --*/
  921. {
  922. UNICODE_STRING valueName;
  923. NTSTATUS registryStatus;
  924. ULONG bytesWritten;
  925. PULONG seedingPortFlag;
  926. BYTE flagStorage[sizeof(KEY_VALUE_FULL_INFORMATION)+32];
  927. PKEY_VALUE_FULL_INFORMATION flagValue = (PKEY_VALUE_FULL_INFORMATION)flagStorage;
  928. *Seeding = FALSE;
  929. // Read the "seedingPort" value name
  930. RtlInitUnicodeString (&valueName, VALUENAME_SEEDROUTER);
  931. registryStatus = ZwQueryValueKey(pPortDesc->pd_AdapterInfoHandle,
  932. &valueName,
  933. KeyValueFullInformation,
  934. flagValue,
  935. sizeof(flagStorage),
  936. &bytesWritten);
  937. if (registryStatus == STATUS_SUCCESS)
  938. {
  939. seedingPortFlag = (PULONG)((PBYTE)flagValue + flagValue->DataOffset);
  940. if (*seedingPortFlag != 0)
  941. {
  942. *Seeding = TRUE;
  943. pPortDesc->pd_Flags |= PD_SEED_ROUTER;
  944. }
  945. }
  946. return registryStatus;
  947. }
  948. NTSTATUS
  949. atalkInitPortParameters(
  950. OUT PPORT_DESCRIPTOR pPortDesc
  951. )
  952. /*++
  953. Routine Description:
  954. Gets the per-port parameters for the port
  955. Arguments:
  956. pPortDesc- Pointer to port information structure for the port
  957. Return Value:
  958. Status - STATUS_SUCCESS or system call returned status codes
  959. --*/
  960. {
  961. UNICODE_STRING valueName;
  962. NTSTATUS status;
  963. ULONG bytesWritten;
  964. BYTE Storage[sizeof(KEY_VALUE_FULL_INFORMATION)+4*MAX_ENTITY_LENGTH];
  965. PKEY_VALUE_FULL_INFORMATION pInfo = (PKEY_VALUE_FULL_INFORMATION)Storage;
  966. // Read the "DdpChecksums" value name
  967. RtlInitUnicodeString (&valueName, VALUENAME_DDPCHECKSUMS);
  968. status = ZwQueryValueKey(pPortDesc->pd_AdapterInfoHandle,
  969. &valueName,
  970. KeyValueFullInformation,
  971. pInfo,
  972. sizeof(Storage),
  973. &bytesWritten);
  974. if (status == STATUS_SUCCESS)
  975. {
  976. PULONG ddpChecksumFlag;
  977. ddpChecksumFlag = (PULONG)((PBYTE)pInfo + pInfo->DataOffset);
  978. if ((*ddpChecksumFlag) != 0)
  979. {
  980. pPortDesc->pd_Flags |= PD_SEND_CHECKSUMS;
  981. }
  982. }
  983. // Read the "AarpRetries" value name
  984. RtlInitUnicodeString (&valueName, VALUENAME_AARPRETRIES);
  985. status = ZwQueryValueKey(pPortDesc->pd_AdapterInfoHandle,
  986. &valueName,
  987. KeyValueFullInformation,
  988. pInfo,
  989. sizeof(Storage),
  990. &bytesWritten);
  991. if (status == STATUS_SUCCESS)
  992. {
  993. PULONG aarpRetries;
  994. aarpRetries = (PULONG)((PBYTE)pInfo + pInfo->DataOffset);
  995. pPortDesc->pd_AarpProbes = (USHORT)*aarpRetries;
  996. }
  997. RtlInitUnicodeString (&valueName, VALUENAME_PORTNAME);
  998. status = ZwQueryValueKey(pPortDesc->pd_AdapterInfoHandle,
  999. &valueName,
  1000. KeyValueFullInformation,
  1001. pInfo,
  1002. sizeof(Storage),
  1003. &bytesWritten);
  1004. do
  1005. {
  1006. if (status == STATUS_SUCCESS)
  1007. {
  1008. PWCHAR portName;
  1009. ANSI_STRING ansiPort;
  1010. UNICODE_STRING unicodePort;
  1011. ULONG ansiSize;
  1012. NTSTATUS status;
  1013. portName = (PWCHAR)((PBYTE)pInfo + pInfo->DataOffset);
  1014. if (*portName != 0)
  1015. {
  1016. RtlInitUnicodeString(&unicodePort, portName);
  1017. ansiSize = RtlUnicodeStringToAnsiSize(&unicodePort);
  1018. if (ansiSize > MAX_ENTITY_LENGTH+1)
  1019. {
  1020. status = STATUS_UNSUCCESSFUL;
  1021. // Incorrect port name!
  1022. LOG_ERRORONPORT(pPortDesc,
  1023. EVENT_ATALK_INVALID_PORTNAME,
  1024. status,
  1025. NULL,
  1026. 0);
  1027. break;
  1028. }
  1029. ansiPort.Buffer = pPortDesc->pd_PortName;
  1030. ansiPort.MaximumLength = (USHORT)ansiSize+1;
  1031. ansiPort.Length = 0;
  1032. status = RtlUnicodeStringToAnsiString(&ansiPort,
  1033. &unicodePort,
  1034. (BOOLEAN)FALSE);
  1035. if (status != STATUS_SUCCESS)
  1036. {
  1037. LOG_ERROR(EVENT_ATALK_RESOURCES,status, NULL, 0);
  1038. }
  1039. }
  1040. else
  1041. {
  1042. // NULL Port Name! Set status to unsuccessful so we copy
  1043. // default name at the end.
  1044. status = STATUS_UNSUCCESSFUL;
  1045. }
  1046. }
  1047. } while (FALSE);
  1048. // Do we need to copy the default port name?
  1049. if (!NT_SUCCESS(status))
  1050. {
  1051. RtlCopyMemory(pPortDesc->pd_PortName, ATALK_PORT_NAME, ATALK_PORT_NAME_SIZE);
  1052. }
  1053. return status;
  1054. }
  1055. NTSTATUS
  1056. atalkInitStartPort(
  1057. IN OUT PPORT_DESCRIPTOR pPortDesc
  1058. )
  1059. /*++
  1060. Routine Description:
  1061. Arguments:
  1062. Return Value:
  1063. --*/
  1064. {
  1065. ATALK_NODEADDR Node;
  1066. ATALK_ADDR AtalkAddr;
  1067. PDDP_ADDROBJ pDdpAddr;
  1068. KIRQL OldIrql;
  1069. ATALK_ERROR error;
  1070. ULONG length;
  1071. NTSTATUS status = STATUS_UNSUCCESSFUL;
  1072. INT LookaheadSize;
  1073. BOOLEAN fPnpReconfigure;
  1074. fPnpReconfigure = (pPortDesc->pd_Flags & PD_PNP_RECONFIGURE)? TRUE : FALSE;
  1075. do
  1076. {
  1077. // Initialize NetworkRange. We can do this here, only *after*
  1078. // we bind, as we dont know our port type until then.
  1079. if (EXT_NET(pPortDesc))
  1080. {
  1081. pPortDesc->pd_NetworkRange.anr_FirstNetwork = FIRST_VALID_NETWORK;
  1082. pPortDesc->pd_NetworkRange.anr_LastNetwork = LAST_STARTUP_NETWORK;
  1083. }
  1084. else
  1085. {
  1086. pPortDesc->pd_NetworkRange.anr_FirstNetwork =
  1087. pPortDesc->pd_NetworkRange.anr_LastNetwork = UNKNOWN_NETWORK;
  1088. pPortDesc->pd_LtNetwork = UNKNOWN_NETWORK;
  1089. }
  1090. //
  1091. // only when the adapter is initialized for the first time, we need
  1092. // to all the initialization stuff (like set lookahead size etc.).
  1093. // If we are here because of a PnPReconfigure event, don't do it
  1094. //
  1095. if (!fPnpReconfigure)
  1096. {
  1097. error = AtalkInitNdisQueryAddrInfo(pPortDesc);
  1098. if (!ATALK_SUCCESS(error))
  1099. {
  1100. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1101. ("atalkInitStartPort: Error in AtalkInitNdisQueryAddrInfo %lx\n", error));
  1102. break;
  1103. }
  1104. LookaheadSize = AARPLINK_MAX_PKT_SIZE;
  1105. if (pPortDesc->pd_NdisPortType == NdisMedium802_5)
  1106. {
  1107. LookaheadSize = AARPLINK_MAX_PKT_SIZE + TLAP_MAX_LINKHDR_LEN;
  1108. }
  1109. else if (pPortDesc->pd_NdisPortType == NdisMediumWan)
  1110. {
  1111. LookaheadSize = AARPLINK_MAX_PKT_SIZE + TLAP_MAX_LINKHDR_LEN;
  1112. }
  1113. // Set lookahead to be the max of the complete aarp packet including link
  1114. error = AtalkInitNdisSetLookaheadSize(pPortDesc, LookaheadSize);
  1115. if (!ATALK_SUCCESS(error))
  1116. {
  1117. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1118. ("atalkInitStartPort: Error in AtalkInitNdisSetLookaheadSize %lx\n", error));
  1119. break;
  1120. }
  1121. //
  1122. // if this is an ARAP port, we need to do a little more work (e.g. set the
  1123. // protocol type, etc.
  1124. //
  1125. if (pPortDesc->pd_Flags & PD_RAS_PORT)
  1126. {
  1127. error = ArapAdapterInit( pPortDesc );
  1128. if (!ATALK_SUCCESS(error))
  1129. {
  1130. DBGPRINT(DBG_COMP_RAS, DBG_LEVEL_ERR,
  1131. ("ArapAdapterInit: failed (%d)\n",error));
  1132. break;
  1133. }
  1134. }
  1135. if (pPortDesc->pd_AddMulticastAddr)
  1136. {
  1137. error = (*pPortDesc->pd_AddMulticastAddr)(pPortDesc,
  1138. pPortDesc->pd_BroadcastAddr,
  1139. TRUE,
  1140. NULL,
  1141. NULL);
  1142. if (!ATALK_SUCCESS(error))
  1143. {
  1144. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1145. ("atalkInitStartPort: Error in pd_AddMulticastAddr %lx\n", error));
  1146. break;
  1147. }
  1148. }
  1149. error = AtalkInitNdisStartPacketReception(pPortDesc);
  1150. if (!ATALK_SUCCESS(error))
  1151. {
  1152. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1153. ("atalkInitStartPort: Error in AtalkInitNdisStartPacketReception %lx\n", error));
  1154. LOG_ERRORONPORT(pPortDesc,
  1155. EVENT_ATALK_RECEPTION,
  1156. 0,
  1157. NULL,
  1158. 0);
  1159. break;
  1160. }
  1161. } // if (!fPnpReconfigure)
  1162. // Set flag to active here. Until then all packets will be dropped
  1163. ACQUIRE_SPIN_LOCK(&pPortDesc->pd_Lock, &OldIrql);
  1164. pPortDesc->pd_Flags |= PD_ACTIVE;
  1165. RELEASE_SPIN_LOCK(&pPortDesc->pd_Lock, OldIrql);
  1166. // if this is arap port, we are done at this point
  1167. if (pPortDesc->pd_Flags & PD_RAS_PORT)
  1168. {
  1169. RtlZeroMemory(pPortDesc->pd_PortStats.prtst_PortName,
  1170. sizeof(pPortDesc->pd_PortStats.prtst_PortName));
  1171. // Set up the name in the statistics structure.
  1172. length = MIN(pPortDesc->pd_AdapterKey.Length,
  1173. ((MAX_INTERNAL_PORTNAME_LEN * sizeof(WCHAR)) - sizeof(WCHAR)));
  1174. RtlCopyMemory(pPortDesc->pd_PortStats.prtst_PortName,
  1175. pPortDesc->pd_AdapterKey.Buffer,
  1176. length);
  1177. AtalkStatistics.stat_NumActivePorts++;
  1178. AtalkNumberOfActivePorts ++;
  1179. status = STATUS_SUCCESS;
  1180. break;
  1181. }
  1182. // is localtalk our default port? if so, we make sure routing is not on.
  1183. if (AtalkRouter && !EXT_NET(pPortDesc) && DEF_PORT(pPortDesc))
  1184. {
  1185. // No can do.
  1186. break;
  1187. }
  1188. // We need to have a node created on every single port. If routing
  1189. // is on, then this will be the router node. The Default port will
  1190. // also have an additional user node. In the case, where we are non-
  1191. // routing, we should only create the user node on the default port.
  1192. // The other nodes will be created on the other ports as usual.
  1193. //
  1194. // !!! AtalkNodeCreateOnPort should set the pointer to the router
  1195. // node in the port descriptor. !!!
  1196. // Make sure we do not create this node if localtalk default port.
  1197. if (!DEF_PORT(pPortDesc) || AtalkRouter)
  1198. {
  1199. BOOLEAN allowstartuprange = !AtalkRouter;
  1200. // If router then startup range is not allowed!
  1201. error = AtalkInitNodeCreateOnPort(pPortDesc,
  1202. allowstartuprange,
  1203. AtalkRouter,
  1204. &Node);
  1205. if (!ATALK_SUCCESS(error))
  1206. {
  1207. LOG_ERRORONPORT(pPortDesc,
  1208. EVENT_ATALK_INIT_COULDNOTGETNODE,
  1209. 0,
  1210. NULL,
  1211. 0);
  1212. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1213. ("atalkInitStartPort: Failed to open node on port %lx (%Z)\n",
  1214. pPortDesc, &pPortDesc->pd_AdapterKey));
  1215. break;
  1216. }
  1217. if (AtalkRouter)
  1218. {
  1219. // Start RTMP/ZIP Processing on this port.
  1220. if (!AtalkInitRtmpStartProcessingOnPort(pPortDesc, &Node) ||
  1221. !AtalkInitZipStartProcessingOnPort(pPortDesc, &Node))
  1222. {
  1223. break;
  1224. }
  1225. }
  1226. // Register the port name on the NIS on this node.
  1227. AtalkAddr.ata_Network = Node.atn_Network;
  1228. AtalkAddr.ata_Node = Node.atn_Node;
  1229. AtalkAddr.ata_Socket = NAMESINFORMATION_SOCKET;
  1230. AtalkDdpReferenceByAddr(pPortDesc,
  1231. &AtalkAddr,
  1232. &pDdpAddr,
  1233. &error);
  1234. if (ATALK_SUCCESS(error))
  1235. {
  1236. PACTREQ pActReq;
  1237. NBPTUPLE NbpTuple;
  1238. NbpTuple.tpl_Zone[0] = '*';
  1239. NbpTuple.tpl_ZoneLen = 1;
  1240. NbpTuple.tpl_ObjectLen = (BYTE)strlen(pPortDesc->pd_PortName);
  1241. RtlCopyMemory(NbpTuple.tpl_Object,
  1242. pPortDesc->pd_PortName,
  1243. NbpTuple.tpl_ObjectLen);
  1244. if (AtalkRouter)
  1245. {
  1246. RtlCopyMemory(NbpTuple.tpl_Type,
  1247. ATALK_ROUTER_NBP_TYPE,
  1248. sizeof(ATALK_ROUTER_NBP_TYPE) - 1);
  1249. NbpTuple.tpl_TypeLen = sizeof(ATALK_ROUTER_NBP_TYPE) - 1;
  1250. }
  1251. else
  1252. {
  1253. RtlCopyMemory(NbpTuple.tpl_Type,
  1254. ATALK_NONROUTER_NBP_TYPE,
  1255. sizeof(ATALK_NONROUTER_NBP_TYPE) - 1);
  1256. NbpTuple.tpl_TypeLen = sizeof(ATALK_NONROUTER_NBP_TYPE) - 1;
  1257. }
  1258. // Initialize parameters and call AtalkNbpAction
  1259. if ((pActReq = AtalkAllocZeroedMemory(sizeof(ACTREQ))) == NULL)
  1260. error = ATALK_RESR_MEM;
  1261. else
  1262. {
  1263. #if DBG
  1264. pActReq->ar_Signature = ACTREQ_SIGNATURE;
  1265. #endif
  1266. pActReq->ar_Completion = atalkRegNbpComplete;
  1267. pActReq->ar_pParms = pPortDesc;
  1268. AtalkLockNbpIfNecessary();
  1269. error = AtalkNbpAction(pDdpAddr,
  1270. FOR_REGISTER,
  1271. &NbpTuple,
  1272. NULL,
  1273. 0,
  1274. pActReq);
  1275. if (!ATALK_SUCCESS(error))
  1276. {
  1277. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1278. ("atalkInitStartPort: AtalkNbpAction returned %lx\n",
  1279. error));
  1280. ASSERT(0);
  1281. AtalkFreeMemory(pActReq);
  1282. AtalkUnlockNbpIfNecessary();
  1283. }
  1284. else
  1285. {
  1286. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_WARN,
  1287. ("atalkInitStartPort: AtalkNbpAction(Register) %lx\n",
  1288. error));
  1289. }
  1290. }
  1291. // Remove the reference added here.
  1292. AtalkDdpDereference(pDdpAddr);
  1293. }
  1294. else
  1295. {
  1296. LOG_ERRORONPORT(pPortDesc,
  1297. EVENT_ATALK_INIT_NAMEREGISTERFAILED,
  1298. AtalkErrorToNtStatus(error),
  1299. NULL,
  1300. 0);
  1301. }
  1302. }
  1303. // If this is the default port, open the user node on it.
  1304. if (DEF_PORT(pPortDesc))
  1305. {
  1306. ASSERT(!AtalkRouter || EXT_NET(pPortDesc));
  1307. if (!ATALK_SUCCESS(AtalkInitNodeCreateOnPort(pPortDesc,
  1308. TRUE,
  1309. FALSE,
  1310. &Node)))
  1311. {
  1312. LOG_ERRORONPORT(pPortDesc,
  1313. EVENT_ATALK_INIT_COULDNOTGETNODE,
  1314. 0,
  1315. NULL,
  1316. 0);
  1317. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1318. ("atalkInitStartPort: Failed to open node on port %lx (%Z)\n",
  1319. pPortDesc, &pPortDesc->pd_AdapterKey));
  1320. break;
  1321. }
  1322. ACQUIRE_SPIN_LOCK(&pPortDesc->pd_Lock, &OldIrql);
  1323. pPortDesc->pd_Flags |= PD_USER_NODE_1;
  1324. AtalkUserNode1 = Node;
  1325. RELEASE_SPIN_LOCK(&pPortDesc->pd_Lock, OldIrql);
  1326. // Register the port name on the NIS on this node.
  1327. AtalkAddr.ata_Network = Node.atn_Network;
  1328. AtalkAddr.ata_Node = Node.atn_Node;
  1329. AtalkAddr.ata_Socket = NAMESINFORMATION_SOCKET;
  1330. AtalkDdpReferenceByAddr(pPortDesc,
  1331. &AtalkAddr,
  1332. &pDdpAddr,
  1333. &error);
  1334. if (ATALK_SUCCESS(error))
  1335. {
  1336. PACTREQ pActReq;
  1337. NBPTUPLE NbpTuple;
  1338. NbpTuple.tpl_Zone[0] = '*';
  1339. NbpTuple.tpl_ZoneLen = 1;
  1340. RtlCopyMemory(NbpTuple.tpl_Object,
  1341. pPortDesc->pd_PortName,
  1342. NbpTuple.tpl_ObjectLen = (BYTE)strlen(pPortDesc->pd_PortName));
  1343. RtlCopyMemory(NbpTuple.tpl_Type,
  1344. ATALK_NONROUTER_NBP_TYPE,
  1345. sizeof(ATALK_NONROUTER_NBP_TYPE) - 1);
  1346. NbpTuple.tpl_TypeLen = sizeof(ATALK_NONROUTER_NBP_TYPE) - 1;
  1347. // Initialize parameters and call AtalkNbpAction
  1348. if ((pActReq = AtalkAllocZeroedMemory(sizeof(ACTREQ))) == NULL)
  1349. error = ATALK_RESR_MEM;
  1350. else
  1351. {
  1352. #if DBG
  1353. pActReq->ar_Signature = ACTREQ_SIGNATURE;
  1354. #endif
  1355. pActReq->ar_Completion = atalkRegNbpComplete;
  1356. pActReq->ar_pParms = pPortDesc;
  1357. AtalkLockNbpIfNecessary();
  1358. error = AtalkNbpAction(pDdpAddr,
  1359. FOR_REGISTER,
  1360. &NbpTuple,
  1361. NULL,
  1362. 0,
  1363. pActReq);
  1364. if (!ATALK_SUCCESS(error))
  1365. {
  1366. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1367. ("atalkInitStartPort: AtalkNbpAction returned %lx\n",
  1368. error));
  1369. AtalkFreeMemory(pActReq);
  1370. AtalkUnlockNbpIfNecessary();
  1371. }
  1372. else
  1373. {
  1374. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_WARN,
  1375. ("atalkInitStartPort: AtalkNbpAction(Register) %lx\n",
  1376. error));
  1377. }
  1378. }
  1379. // Remove the reference added here.
  1380. AtalkDdpDereference(pDdpAddr);
  1381. }
  1382. else
  1383. {
  1384. LOG_ERRORONPORT(pPortDesc,
  1385. EVENT_ATALK_INIT_NAMEREGISTERFAILED,
  1386. STATUS_UNSUCCESSFUL,
  1387. NULL,
  1388. 0);
  1389. }
  1390. // If we are an extended port, we open a second node on the port.
  1391. if (EXT_NET(pPortDesc))
  1392. {
  1393. if (ATALK_SUCCESS(AtalkInitNodeCreateOnPort(pPortDesc,
  1394. TRUE,
  1395. FALSE,
  1396. &Node)))
  1397. {
  1398. ACQUIRE_SPIN_LOCK(&pPortDesc->pd_Lock, &OldIrql);
  1399. pPortDesc->pd_Flags |= PD_USER_NODE_2;
  1400. AtalkUserNode2 = Node;
  1401. RELEASE_SPIN_LOCK(&pPortDesc->pd_Lock, OldIrql);
  1402. }
  1403. else
  1404. {
  1405. LOG_ERRORONPORT(pPortDesc,
  1406. EVENT_ATALK_INIT_COULDNOTGETNODE,
  1407. 0,
  1408. NULL,
  1409. 0);
  1410. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1411. ("atalkInitStartPort: Fail 2nd node port %lx (%Z)\n",
  1412. pPortDesc, &pPortDesc->pd_AdapterKey));
  1413. }
  1414. }
  1415. }
  1416. // Start the Amt and Brc timers for the port, only for extended ports
  1417. if (EXT_NET(pPortDesc))
  1418. {
  1419. AtalkPortReferenceByPtr(pPortDesc, &error);
  1420. if (ATALK_SUCCESS(error))
  1421. {
  1422. AtalkTimerInitialize(&pPortDesc->pd_BrcTimer,
  1423. AtalkAarpBrcTimer,
  1424. BRC_AGE_TIME);
  1425. AtalkTimerScheduleEvent(&pPortDesc->pd_BrcTimer);
  1426. }
  1427. AtalkPortReferenceByPtr(pPortDesc, &error);
  1428. if (ATALK_SUCCESS(error))
  1429. {
  1430. AtalkTimerInitialize(&pPortDesc->pd_AmtTimer,
  1431. AtalkAarpAmtTimer,
  1432. AMT_AGE_TIME);
  1433. AtalkTimerScheduleEvent(&pPortDesc->pd_AmtTimer);
  1434. }
  1435. }
  1436. // Start the Rtmp aging timer for non-routing case
  1437. if (!AtalkRouter)
  1438. {
  1439. AtalkPortReferenceByPtr(pPortDesc, &error);
  1440. if (!ATALK_SUCCESS(error))
  1441. {
  1442. break;
  1443. }
  1444. AtalkTimerInitialize(&pPortDesc->pd_RtmpAgingTimer,
  1445. AtalkRtmpAgingTimer,
  1446. RTMP_AGING_TIMER);
  1447. AtalkTimerScheduleEvent(&pPortDesc->pd_RtmpAgingTimer);
  1448. }
  1449. RtlZeroMemory(pPortDesc->pd_PortStats.prtst_PortName,
  1450. sizeof(pPortDesc->pd_PortStats.prtst_PortName));
  1451. // Set up the name in the statistics structure.
  1452. length = MIN(pPortDesc->pd_AdapterKey.Length,
  1453. ((MAX_INTERNAL_PORTNAME_LEN * sizeof(WCHAR)) - sizeof(WCHAR)));
  1454. RtlCopyMemory(pPortDesc->pd_PortStats.prtst_PortName,
  1455. pPortDesc->pd_AdapterKey.Buffer,
  1456. length);
  1457. status = STATUS_SUCCESS;
  1458. } while (FALSE);
  1459. //
  1460. // in case of PnP, we want to get the stats right even in case of failure
  1461. //
  1462. if (fPnpReconfigure || NT_SUCCESS(status))
  1463. {
  1464. AtalkStatistics.stat_NumActivePorts++;
  1465. AtalkNumberOfActivePorts ++;
  1466. }
  1467. if (!NT_SUCCESS(status))
  1468. {
  1469. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1470. ("atalkInitStartPort: Start port failed %lx %s\n",
  1471. status, (fPnpReconfigure)?"(during PnP)" : " "));
  1472. }
  1473. return status;
  1474. }
  1475. VOID
  1476. atalkRegNbpComplete(
  1477. IN ATALK_ERROR Status,
  1478. IN PACTREQ pActReq
  1479. )
  1480. /*++
  1481. Routine Description:
  1482. Arguments:
  1483. Return Value:
  1484. --*/
  1485. {
  1486. ASSERT (VALID_ACTREQ(pActReq));
  1487. if (ATALK_SUCCESS(Status))
  1488. {
  1489. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
  1490. ("atalkInitNbpCompletion: NBP Name registered on port %Z\n",
  1491. &((PPORT_DESCRIPTOR)(pActReq->ar_pParms))->pd_AdapterKey));
  1492. LOG_ERRORONPORT((PPORT_DESCRIPTOR)(pActReq->ar_pParms),
  1493. EVENT_ATALK_INIT_NAMEREGISTERED,
  1494. STATUS_SUCCESS,
  1495. NULL,
  1496. 0);
  1497. }
  1498. else
  1499. {
  1500. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1501. ("atalkInitNbpCompletion: Failed to register name on port %Z (%ld)\n",
  1502. &((PPORT_DESCRIPTOR)(pActReq->ar_pParms))->pd_AdapterKey, Status));
  1503. LOG_ERRORONPORT((PPORT_DESCRIPTOR)(pActReq->ar_pParms),
  1504. EVENT_ATALK_INIT_NAMEREGISTERFAILED,
  1505. STATUS_UNSUCCESSFUL,
  1506. NULL,
  1507. 0);
  1508. }
  1509. AtalkFreeMemory(pActReq);
  1510. }
  1511. NTSTATUS
  1512. AtalkInitAdapter(
  1513. IN PUNICODE_STRING AdapterName,
  1514. IN PPORT_DESCRIPTOR pExistingPortDesc
  1515. )
  1516. /*++
  1517. Routine Description:
  1518. Arguments:
  1519. Return Value:
  1520. --*/
  1521. {
  1522. PPORT_DESCRIPTOR pPortDesc;
  1523. KIRQL OldIrql;
  1524. PWCHAR devicePrefix = L"\\Device\\";
  1525. #define prefixLength (sizeof(L"\\Device\\") - sizeof(WCHAR))
  1526. UCHAR Address[sizeof(TA_ADDRESS) + sizeof(TDI_ADDRESS_APPLETALK)];
  1527. PTA_ADDRESS AddressPtr;
  1528. NTSTATUS Status;
  1529. UNICODE_STRING Us;
  1530. UNICODE_STRING AspDeviceName;
  1531. HANDLE RegHandle;
  1532. BOOLEAN fMustBindToNdis;
  1533. BOOLEAN IsDefaultPort = FALSE;
  1534. if (AdapterName)
  1535. {
  1536. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
  1537. ("AtalkInitAdapter: Initiating bind for adapter %Z\n", AdapterName));
  1538. }
  1539. do
  1540. {
  1541. // Open the adapters section key.
  1542. RtlInitUnicodeString(&Us, ADAPTERS_STRING);
  1543. Status = atalkInitGetHandleToKey(&Us,
  1544. &RegHandle);
  1545. if (!NT_SUCCESS(Status))
  1546. {
  1547. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1548. ("AtalkInitAdapter: Failed to open %ws key\n", ADAPTERS_STRING));
  1549. break;
  1550. }
  1551. if (pExistingPortDesc == NULL)
  1552. {
  1553. // Get the size of the string, and make sure that is it atleast
  1554. // greater than the \Device prefix. Fail if not.
  1555. if (AdapterName->Length <= prefixLength)
  1556. {
  1557. break;
  1558. }
  1559. // Allocate space for the port descriptors. Allocate an extra DWORD
  1560. // and set port descriptor past the first DWORD_PTR. This is a kludge to
  1561. // force LONGLONG alignment.
  1562. pPortDesc =
  1563. (PPORT_DESCRIPTOR)AtalkAllocZeroedMemory(sizeof(PORT_DESCRIPTOR) +
  1564. AdapterName->Length +
  1565. sizeof(WCHAR) +
  1566. sizeof(DWORD_PTR));
  1567. if (pPortDesc == NULL)
  1568. {
  1569. Status = STATUS_INSUFFICIENT_RESOURCES;
  1570. break;
  1571. }
  1572. // Reference the port for creation
  1573. pPortDesc->pd_RefCount = 1;
  1574. #if DBG
  1575. pPortDesc->pd_Signature = PD_SIGNATURE;
  1576. #endif
  1577. // Copy the AdapterName and AdapterKey strings into the portdesc
  1578. pPortDesc->pd_AdapterName.Buffer =
  1579. (PWCHAR)((PBYTE)pPortDesc + sizeof(PORT_DESCRIPTOR));
  1580. pPortDesc->pd_AdapterName.Length = AdapterName->Length;
  1581. pPortDesc->pd_AdapterName.MaximumLength =
  1582. AdapterName->Length + sizeof(WCHAR);
  1583. RtlUpcaseUnicodeString(&pPortDesc->pd_AdapterName,
  1584. AdapterName,
  1585. FALSE);
  1586. pPortDesc->pd_AdapterKey.Buffer =
  1587. (PWCHAR)((PBYTE)pPortDesc->pd_AdapterName.Buffer + prefixLength);
  1588. pPortDesc->pd_AdapterKey.Length =
  1589. pPortDesc->pd_AdapterName.Length - prefixLength;
  1590. pPortDesc->pd_AdapterKey.MaximumLength =
  1591. pPortDesc->pd_AdapterName.MaximumLength - prefixLength;
  1592. // buffer for this will be allocated later
  1593. pPortDesc->pd_FriendlyAdapterName.Buffer = NULL;
  1594. pPortDesc->pd_FriendlyAdapterName.MaximumLength = 0;
  1595. pPortDesc->pd_FriendlyAdapterName.Length = 0;
  1596. // Now initialize any other fields that need to be.
  1597. INITIALIZE_SPIN_LOCK(&pPortDesc->pd_Lock);
  1598. InitializeListHead(&pPortDesc->pd_ReceiveQueue);
  1599. // only in case of a Ras port will these lists head be used
  1600. InitializeListHead(&pPortDesc->pd_ArapConnHead);
  1601. InitializeListHead(&pPortDesc->pd_PPPConnHead);
  1602. // Initialize the events in the port descriptor
  1603. KeInitializeEvent(&pPortDesc->pd_RequestEvent, NotificationEvent, FALSE);
  1604. KeInitializeEvent(&pPortDesc->pd_SeenRouterEvent, NotificationEvent, FALSE);
  1605. KeInitializeEvent(&pPortDesc->pd_NodeAcquireEvent, NotificationEvent, FALSE);
  1606. fMustBindToNdis = TRUE;
  1607. }
  1608. else
  1609. {
  1610. pPortDesc = pExistingPortDesc;
  1611. fMustBindToNdis = FALSE;
  1612. }
  1613. if ((AtalkDefaultPortName.Buffer != NULL) &&
  1614. (RtlEqualUnicodeString(&pPortDesc->pd_AdapterName,
  1615. &AtalkDefaultPortName,
  1616. TRUE)))
  1617. {
  1618. // Used for tracking Default Port for error message logging
  1619. IsDefaultPort = TRUE;
  1620. pPortDesc->pd_Flags |= PD_DEF_PORT;
  1621. pPortDesc->pd_InitialDesiredZone = AtalkDesiredZone;
  1622. if (AtalkDesiredZone != NULL)
  1623. AtalkZoneReferenceByPtr(pPortDesc->pd_InitialDesiredZone);
  1624. }
  1625. // Link it in the global list
  1626. ACQUIRE_SPIN_LOCK(&AtalkPortLock, &OldIrql);
  1627. pPortDesc->pd_Next = AtalkPortList;
  1628. AtalkPortList = pPortDesc;
  1629. AtalkNumberOfPorts ++;
  1630. RELEASE_SPIN_LOCK(&AtalkPortLock, OldIrql);
  1631. if (fMustBindToNdis)
  1632. {
  1633. // bind to the adapter
  1634. Status = AtalkNdisInitBind(pPortDesc);
  1635. if (NT_SUCCESS(Status))
  1636. {
  1637. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1638. ("Bind done for %Z\n", (pPortDesc->pd_FriendlyAdapterName.Buffer) ?
  1639. (&pPortDesc->pd_FriendlyAdapterName) :
  1640. (&pPortDesc->pd_AdapterName)));
  1641. }
  1642. else
  1643. {
  1644. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1645. ("AtalkInitAdapter: AtalkNdisInitBind failed (0x%lx) for adapter %Z\n",
  1646. Status,AdapterName));
  1647. }
  1648. }
  1649. else
  1650. {
  1651. Status = STATUS_SUCCESS;
  1652. }
  1653. if (Status == NDIS_STATUS_SUCCESS)
  1654. {
  1655. Status = STATUS_SUCCESS;
  1656. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
  1657. ("AtalkInitAdapter: Going into atalkInitPort (0x%lx) for adapter %Z\n",
  1658. Status,AdapterName));
  1659. // Get per port parameters (ARAP port doesn't have any parms to get)
  1660. if (!(pPortDesc->pd_Flags & PD_RAS_PORT))
  1661. {
  1662. Status = atalkInitPort(pPortDesc, RegHandle);
  1663. }
  1664. if (NT_SUCCESS(Status))
  1665. {
  1666. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
  1667. ("AtalkInitAdapter: atalkInitPort succeeded (0x%lx) for adapter %Z\n",
  1668. Status,AdapterName));
  1669. // And start the port
  1670. Status = atalkInitStartPort(pPortDesc);
  1671. if (NT_SUCCESS(Status) && (pPortDesc->pd_Flags & PD_DEF_PORT))
  1672. {
  1673. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
  1674. ("AtalkInitAdapter: atalkInitStartPort succeeded (0x%lx) for adapter %Z\n",
  1675. Status,AdapterName));
  1676. //
  1677. // if we were doing PnP, we are done with the PnP at this point:
  1678. // clear the flag, so macfile can do its things...
  1679. //
  1680. ACQUIRE_SPIN_LOCK(&pPortDesc->pd_Lock, &OldIrql);
  1681. pPortDesc->pd_Flags &= ~PD_PNP_RECONFIGURE;
  1682. RELEASE_SPIN_LOCK(&pPortDesc->pd_Lock, OldIrql);
  1683. // Set the global default port value
  1684. AtalkDefaultPort = pPortDesc;
  1685. KeSetEvent(&AtalkDefaultPortEvent, IO_NETWORK_INCREMENT, FALSE);
  1686. // Now tell TDI that we are up and ready for binding
  1687. RtlInitUnicodeString(&AspDeviceName, ATALKASPS_DEVICENAME);
  1688. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
  1689. ("AtalkInitAdapter: Calling TdiRegisterDeviceObject for adapter %Z\n",
  1690. AdapterName));
  1691. Status = TdiRegisterDeviceObject(
  1692. &AspDeviceName,
  1693. &TdiRegistrationHandle);
  1694. if (!NT_SUCCESS(Status))
  1695. {
  1696. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1697. ( "TdiRegisterDeviceObject failed with %lx\n", Status));
  1698. TdiRegistrationHandle = NULL;
  1699. }
  1700. else
  1701. {
  1702. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
  1703. ( "TdiRegisterDeviceObject succeeded\n"));
  1704. AddressPtr = (PTA_ADDRESS)Address;
  1705. RtlZeroMemory(Address, sizeof(Address));
  1706. AddressPtr->AddressLength = sizeof(TDI_ADDRESS_APPLETALK);
  1707. AddressPtr->AddressType = TDI_ADDRESS_TYPE_APPLETALK;
  1708. Status = TdiRegisterNetAddress(AddressPtr,
  1709. &pPortDesc->pd_AdapterName,
  1710. NULL,
  1711. &TdiAddressChangeRegHandle);
  1712. if (!NT_SUCCESS(Status))
  1713. {
  1714. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1715. ("AtalkInitAdapter: TdiRegisterNetAddress failed %lx\n",Status));
  1716. TdiAddressChangeRegHandle = NULL;
  1717. }
  1718. else
  1719. {
  1720. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
  1721. ("AtalkInitAdapter: TdiRegisterNetAddress on %Z done\n",
  1722. &pPortDesc->pd_AdapterName));
  1723. ASSERT(TdiAddressChangeRegHandle != NULL);
  1724. }
  1725. }
  1726. }
  1727. else if (!NT_SUCCESS(Status))
  1728. {
  1729. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1730. ( "AtalkInitBinding: atalkInitStartPort failed (%lx) on %Z\n",
  1731. Status, &pPortDesc->pd_AdapterName));
  1732. }
  1733. }
  1734. else
  1735. {
  1736. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1737. ("AtalkInitAdapter: atalkInitPort failed (0x%lx) for adapter %Z\n",
  1738. Status,AdapterName));
  1739. }
  1740. if (pPortDesc->pd_AdapterInfoHandle != NULL)
  1741. {
  1742. ZwClose(pPortDesc->pd_AdapterInfoHandle);
  1743. pPortDesc->pd_AdapterInfoHandle = NULL;
  1744. }
  1745. }
  1746. else
  1747. {
  1748. ASSERT(AdapterName != NULL);
  1749. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1750. ( "AtalkInitBinding failed (%lx) on %Z\n", Status, AdapterName));
  1751. if (pPortDesc->pd_FriendlyAdapterName.Buffer)
  1752. {
  1753. AtalkFreeMemory(pPortDesc->pd_FriendlyAdapterName.Buffer);
  1754. }
  1755. AtalkFreeMemory(pPortDesc);
  1756. }
  1757. } while (FALSE);
  1758. // Close the Adapters Key
  1759. if (RegHandle != NULL)
  1760. ZwClose (RegHandle);
  1761. //
  1762. // if we just successfully initialized default adapter or the RAS adapter,
  1763. // let RAS know about it
  1764. //
  1765. if ( (NT_SUCCESS(Status)) &&
  1766. (pPortDesc->pd_Flags & (PD_RAS_PORT | PD_DEF_PORT)) )
  1767. {
  1768. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1769. ("AtalkInitAdapter: %s adapter initialized (%lx), informing RAS\n",
  1770. (pPortDesc->pd_Flags & PD_RAS_PORT)? "RAS" : "Default",pPortDesc));
  1771. AtalkPnPInformRas(TRUE);
  1772. }
  1773. else
  1774. {
  1775. if (IsDefaultPort)
  1776. {
  1777. LOG_ERROR(EVENT_ATALK_NO_DEFAULTPORT, Status, NULL, 0);
  1778. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
  1779. ("WARNING!!! Appletalk driver running, but no default port configured\n"));
  1780. }
  1781. }
  1782. return Status;
  1783. }
  1784. NTSTATUS
  1785. AtalkDeinitAdapter(
  1786. IN PPORT_DESCRIPTOR pPortDesc
  1787. )
  1788. /*++
  1789. Routine Description:
  1790. Arguments:
  1791. Return Value:
  1792. --*/
  1793. {
  1794. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
  1795. ("AtalkDeinitAdapter: Initiating un-bind for adapter %Z\n",
  1796. &pPortDesc->pd_AdapterName));
  1797. AtalkPortShutdown(pPortDesc);
  1798. return STATUS_SUCCESS;
  1799. }
  1800. #ifdef ALLOC_DATA_PRAGMA
  1801. #pragma data_seg("PAGE")
  1802. #endif
  1803. ACTION_DISPATCH AtalkActionDispatch[MAX_ALLACTIONCODES+1] =
  1804. {
  1805. //
  1806. // NBP dispatch functions
  1807. //
  1808. {
  1809. sizeof(NBP_LOOKUP_ACTION),
  1810. COMMON_ACTION_NBPLOOKUP,
  1811. (DFLAG_CNTR | DFLAG_ADDR | DFLAG_MDL),
  1812. sizeof(NBP_LOOKUP_ACTION),
  1813. ATALK_DEV_ANY,
  1814. AtalkNbpTdiAction
  1815. },
  1816. {
  1817. sizeof(NBP_CONFIRM_ACTION),
  1818. COMMON_ACTION_NBPCONFIRM,
  1819. (DFLAG_CNTR | DFLAG_ADDR),
  1820. sizeof(NBP_CONFIRM_ACTION),
  1821. ATALK_DEV_ANY,
  1822. AtalkNbpTdiAction
  1823. },
  1824. {
  1825. sizeof(NBP_REGDEREG_ACTION),
  1826. COMMON_ACTION_NBPREGISTER,
  1827. DFLAG_ADDR,
  1828. sizeof(NBP_REGDEREG_ACTION),
  1829. ATALK_DEV_ANY,
  1830. AtalkNbpTdiAction
  1831. },
  1832. {
  1833. sizeof(NBP_REGDEREG_ACTION),
  1834. COMMON_ACTION_NBPREMOVE,
  1835. DFLAG_ADDR,
  1836. sizeof(NBP_REGDEREG_ACTION),
  1837. ATALK_DEV_ANY,
  1838. AtalkNbpTdiAction
  1839. },
  1840. //
  1841. // ZIP dispatch functions
  1842. //
  1843. {
  1844. sizeof(ZIP_GETMYZONE_ACTION),
  1845. COMMON_ACTION_ZIPGETMYZONE,
  1846. (DFLAG_CNTR | DFLAG_ADDR | DFLAG_MDL),
  1847. sizeof(ZIP_GETMYZONE_ACTION),
  1848. ATALK_DEV_ANY,
  1849. AtalkZipTdiAction
  1850. },
  1851. {
  1852. sizeof(ZIP_GETZONELIST_ACTION),
  1853. COMMON_ACTION_ZIPGETZONELIST,
  1854. (DFLAG_CNTR | DFLAG_ADDR | DFLAG_MDL),
  1855. sizeof(ZIP_GETZONELIST_ACTION),
  1856. ATALK_DEV_ANY,
  1857. AtalkZipTdiAction
  1858. },
  1859. {
  1860. sizeof(ZIP_GETZONELIST_ACTION),
  1861. COMMON_ACTION_ZIPGETLZONES,
  1862. (DFLAG_CNTR | DFLAG_ADDR | DFLAG_MDL),
  1863. sizeof(ZIP_GETZONELIST_ACTION),
  1864. ATALK_DEV_ANY,
  1865. AtalkZipTdiAction
  1866. },
  1867. {
  1868. sizeof(ZIP_GETZONELIST_ACTION),
  1869. COMMON_ACTION_ZIPGETLZONESONADAPTER,
  1870. (DFLAG_CNTR | DFLAG_ADDR | DFLAG_MDL),
  1871. sizeof(ZIP_GETZONELIST_ACTION),
  1872. ATALK_DEV_ANY,
  1873. AtalkZipTdiAction
  1874. },
  1875. {
  1876. sizeof(ZIP_GETPORTDEF_ACTION),
  1877. COMMON_ACTION_ZIPGETADAPTERDEFAULTS,
  1878. (DFLAG_CNTR | DFLAG_ADDR | DFLAG_MDL),
  1879. sizeof(ZIP_GETPORTDEF_ACTION),
  1880. ATALK_DEV_ANY,
  1881. AtalkZipTdiAction
  1882. },
  1883. {
  1884. sizeof(ATALK_STATS) +
  1885. sizeof(GET_STATISTICS_ACTION),
  1886. COMMON_ACTION_GETSTATISTICS,
  1887. (DFLAG_CNTR | DFLAG_ADDR | DFLAG_MDL),
  1888. sizeof(GET_STATISTICS_ACTION),
  1889. ATALK_DEV_ANY,
  1890. AtalkStatTdiAction
  1891. },
  1892. //
  1893. // ADSP dispatch functions
  1894. //
  1895. {
  1896. sizeof(ADSP_FORWARDRESET_ACTION),
  1897. ACTION_ADSPFORWARDRESET,
  1898. (DFLAG_CONN),
  1899. sizeof(ADSP_FORWARDRESET_ACTION),
  1900. ATALK_DEV_ADSP,
  1901. AtalkAdspTdiAction
  1902. },
  1903. //
  1904. // ASPC Dispatch functions
  1905. //
  1906. {
  1907. sizeof(ASPC_GETSTATUS_ACTION),
  1908. ACTION_ASPCGETSTATUS,
  1909. (DFLAG_ADDR | DFLAG_MDL),
  1910. sizeof(ASPC_GETSTATUS_ACTION),
  1911. ATALK_DEV_ASPC,
  1912. AtalkAspCTdiAction
  1913. },
  1914. {
  1915. sizeof(ASPC_COMMAND_OR_WRITE_ACTION),
  1916. ACTION_ASPCCOMMAND,
  1917. (DFLAG_CONN | DFLAG_MDL),
  1918. sizeof(ASPC_COMMAND_OR_WRITE_ACTION),
  1919. ATALK_DEV_ASPC,
  1920. AtalkAspCTdiAction
  1921. },
  1922. {
  1923. sizeof(ASPC_COMMAND_OR_WRITE_ACTION),
  1924. ACTION_ASPCWRITE,
  1925. (DFLAG_CONN | DFLAG_MDL),
  1926. sizeof(ASPC_COMMAND_OR_WRITE_ACTION),
  1927. ATALK_DEV_ASPC,
  1928. AtalkAspCTdiAction
  1929. },
  1930. //
  1931. // NBP dispatch functions used by atalk
  1932. // winsock helper dll's SetService Api
  1933. //
  1934. {
  1935. sizeof(NBP_REGDEREG_ACTION),
  1936. COMMON_ACTION_NBPREGISTER_BY_ADDR,
  1937. DFLAG_ADDR,
  1938. sizeof(NBP_REGDEREG_ACTION),
  1939. ATALK_DEV_ANY,
  1940. AtalkNbpTdiAction
  1941. },
  1942. {
  1943. sizeof(NBP_REGDEREG_ACTION),
  1944. COMMON_ACTION_NBPREMOVE_BY_ADDR,
  1945. DFLAG_ADDR,
  1946. sizeof(NBP_REGDEREG_ACTION),
  1947. ATALK_DEV_ANY,
  1948. AtalkNbpTdiAction
  1949. },
  1950. {
  1951. sizeof(ASPC_RESERVED_ACTION),
  1952. ACTION_ASPCRESERVED3,
  1953. (DFLAG_ADDR),
  1954. sizeof(ASPC_RESERVED_ACTION),
  1955. ATALK_DEV_ASPC,
  1956. AtalkAspCTdiAction
  1957. },
  1958. //
  1959. // ASP Dispatch functions
  1960. //
  1961. {
  1962. sizeof(ASP_BIND_ACTION),
  1963. ACTION_ASP_BIND,
  1964. (DFLAG_ADDR),
  1965. sizeof(ASP_BIND_ACTION),
  1966. ATALK_DEV_ASP,
  1967. AtalkAspTdiAction
  1968. },
  1969. //
  1970. // PAP dispatch routines
  1971. //
  1972. {
  1973. sizeof(PAP_GETSTATUSSRV_ACTION),
  1974. ACTION_PAPGETSTATUSSRV,
  1975. (DFLAG_ADDR | DFLAG_CNTR | DFLAG_MDL),
  1976. sizeof(PAP_GETSTATUSSRV_ACTION),
  1977. ATALK_DEV_PAP,
  1978. AtalkPapTdiAction
  1979. },
  1980. {
  1981. sizeof(PAP_SETSTATUS_ACTION),
  1982. ACTION_PAPSETSTATUS,
  1983. (DFLAG_ADDR | DFLAG_MDL),
  1984. sizeof(PAP_SETSTATUS_ACTION),
  1985. ATALK_DEV_PAP,
  1986. AtalkPapTdiAction
  1987. },
  1988. {
  1989. sizeof(PAP_PRIMEREAD_ACTION),
  1990. ACTION_PAPPRIMEREAD,
  1991. (DFLAG_CONN | DFLAG_MDL),
  1992. 0, // !!!NOTE!!!
  1993. ATALK_DEV_PAP, // We set the offset to be 0. We want the
  1994. AtalkPapTdiAction // complete buffer to be used for read data
  1995. // overwriting action header to preserve
  1996. } // winsock read model.
  1997. };