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.

614 lines
21 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. cfg.c
  5. Abstract:
  6. ARP1394 Configuration-related routines.
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. josephj 12-01-98 Created (adapted from atmarp.sys)
  11. Notes:
  12. --*/
  13. #include <precomp.h>
  14. //
  15. // File-specific debugging defaults.
  16. //
  17. #define TM_CURRENT TM_CFG
  18. // TODO: change this to ARP1394
  19. #define ARP_NAME_STRING NDIS_STRING_CONST("ATMARPC")
  20. //=========================================================================
  21. // L O C A L P R O T O T Y P E S
  22. //=========================================================================
  23. #if TODO
  24. //
  25. // Size of local temp buffer
  26. //
  27. #define WORK_BUF_SIZE 200
  28. #define ASCII_TO_INT(val) \
  29. ( ( ((val) >= '0') && ('9' >= (val)) ) ? ((val) - '0') : \
  30. ( ((val) >= 'a') && ('z' >= (val)) ) ? ((val) - 'a' + 10) : \
  31. ( ((val) >= 'A') && ('Z' >= (val)) ) ? ((val) - 'A' + 10) : \
  32. 0 )
  33. //
  34. // Parameters for reading in a ULONG from configuration into an Interface
  35. // structure.
  36. //
  37. typedef struct _AA_READ_CONFIG_PARAMS
  38. {
  39. ULONG StructOffset; // Offset of param from beginning of struct
  40. PWCHAR ParameterName; // Name in config database
  41. ULONG DefaultValue;
  42. } AA_READ_CONFIG_PARAMS, *PAA_READ_CONFIG_PARAMS;
  43. #define AA_MAKE_RCP(Off, Name, Dflt) \
  44. { Off, Name, Dflt }
  45. #define LIS_CONFIG_ENTRY(Field, Name, Dflt) \
  46. AA_MAKE_RCP(FIELD_OFFSET(struct _ATMARP_INTERFACE, Field), Name, Dflt)
  47. #define AA_BANDWIDTH_UNSPECIFIED ((ULONG)-1)
  48. #define AA_PACKET_SIZE_UNSPECIFIED ((ULONG)-1)
  49. #define AA_MTU_UNSPECIFIED ((ULONG)-1)
  50. #define AA_SPEED_UNSPECIFIED ((ULONG)-1)
  51. //
  52. // List of ULONG parameters for an LIS
  53. //
  54. AA_READ_CONFIG_PARAMS AtmArpLISConfigTable[] =
  55. {
  56. LIS_CONFIG_ENTRY(SapSelector, L"SapSelector", AA_DEF_SELECTOR_VALUE),
  57. LIS_CONFIG_ENTRY(HeaderPool[AA_HEADER_TYPE_UNICAST].MaxHeaderBufs, L"MaxHeaderBufs", AA_DEF_MAX_HEADER_BUFFERS),
  58. LIS_CONFIG_ENTRY(HeaderPool[AA_HEADER_TYPE_UNICAST].HeaderBufSize, L"HeaderBufSize", AA_PKT_LLC_SNAP_HEADER_LENGTH),
  59. #ifdef IPMCAST
  60. LIS_CONFIG_ENTRY(HeaderPool[AA_HEADER_TYPE_NUNICAST].MaxHeaderBufs, L"McastMaxHeaderBufs", AA_DEF_MAX_HEADER_BUFFERS),
  61. LIS_CONFIG_ENTRY(HeaderPool[AA_HEADER_TYPE_NUNICAST].HeaderBufSize, L"McastHeaderBufSize", sizeof(AA_MC_PKT_TYPE1_SHORT_HEADER)),
  62. #endif // IPMCAST
  63. LIS_CONFIG_ENTRY(ProtocolBufSize, L"ProtocolBufSize", AA_DEF_PROTOCOL_BUFFER_SIZE),
  64. LIS_CONFIG_ENTRY(MaxProtocolBufs, L"MaxProtocolBufs", AA_DEF_MAX_PROTOCOL_BUFFERS),
  65. LIS_CONFIG_ENTRY(MTU, L"MTU", AA_MTU_UNSPECIFIED),
  66. LIS_CONFIG_ENTRY(Speed, L"Speed", AA_SPEED_UNSPECIFIED),
  67. LIS_CONFIG_ENTRY(PVCOnly, L"PVCOnly", AA_DEF_PVC_ONLY_VALUE),
  68. LIS_CONFIG_ENTRY(ServerConnectInterval, L"ServerConnectInterval", AA_DEF_SERVER_CONNECT_INTERVAL),
  69. LIS_CONFIG_ENTRY(ServerRegistrationTimeout, L"ServerRegistrationTimeout", AA_DEF_SERVER_REGISTRATION_TIMEOUT),
  70. LIS_CONFIG_ENTRY(AddressResolutionTimeout, L"AddressResolutionTimeout", AA_DEF_ADDRESS_RESOLUTION_TIMEOUT),
  71. LIS_CONFIG_ENTRY(ARPEntryAgingTimeout, L"ARPEntryAgingTimeout", AA_DEF_ARP_ENTRY_AGING_TIMEOUT),
  72. LIS_CONFIG_ENTRY(InARPWaitTimeout, L"InARPWaitTimeout", AA_DEF_INARP_WAIT_TIMEOUT),
  73. LIS_CONFIG_ENTRY(ServerRefreshTimeout, L"ServerRefreshTimeout", AA_DEF_SERVER_REFRESH_INTERVAL),
  74. LIS_CONFIG_ENTRY(MinWaitAfterNak, L"MinWaitAfterNak", AA_DEF_MIN_WAIT_AFTER_NAK),
  75. LIS_CONFIG_ENTRY(MaxRegistrationAttempts, L"MaxRegistrationAttempts", AA_DEF_MAX_REGISTRATION_ATTEMPTS),
  76. LIS_CONFIG_ENTRY(MaxResolutionAttempts, L"MaxResolutionAttempts", AA_DEF_MAX_RESOLUTION_ATTEMPTS),
  77. LIS_CONFIG_ENTRY(DefaultFlowSpec.SendPeakBandwidth, L"DefaultSendBandwidth", AA_BANDWIDTH_UNSPECIFIED),
  78. LIS_CONFIG_ENTRY(DefaultFlowSpec.ReceivePeakBandwidth, L"DefaultReceiveBandwidth", AA_BANDWIDTH_UNSPECIFIED),
  79. LIS_CONFIG_ENTRY(DefaultFlowSpec.SendMaxSize, L"DefaultSendMaxSize", AA_PACKET_SIZE_UNSPECIFIED),
  80. LIS_CONFIG_ENTRY(DefaultFlowSpec.ReceiveMaxSize, L"DefaultReceiveMaxSize", AA_PACKET_SIZE_UNSPECIFIED),
  81. LIS_CONFIG_ENTRY(DefaultFlowSpec.SendServiceType, L"DefaultServiceType", AA_DEF_FLOWSPEC_SERVICETYPE),
  82. LIS_CONFIG_ENTRY(DefaultFlowSpec.AgingTime, L"DefaultVCAgingTimeout", AA_DEF_VC_AGING_TIMEOUT)
  83. #ifdef IPMCAST
  84. ,
  85. LIS_CONFIG_ENTRY(MARSConnectInterval, L"MARSConnectInterval", AA_DEF_SERVER_CONNECT_INTERVAL),
  86. LIS_CONFIG_ENTRY(MARSRegistrationTimeout, L"MARSRegistrationTimeout", AA_DEF_SERVER_REGISTRATION_TIMEOUT),
  87. LIS_CONFIG_ENTRY(MARSKeepAliveTimeout, L"MARSKeepAliveTimeout", AA_DEF_MARS_KEEPALIVE_TIMEOUT),
  88. LIS_CONFIG_ENTRY(JoinTimeout, L"JoinTimeout", AA_DEF_MARS_JOIN_TIMEOUT),
  89. LIS_CONFIG_ENTRY(LeaveTimeout, L"LeaveTimeout", AA_DEF_MARS_LEAVE_TIMEOUT),
  90. LIS_CONFIG_ENTRY(MaxDelayBetweenMULTIs, L"MaxDelayBetweenMULTIs", AA_DEF_MULTI_TIMEOUT),
  91. LIS_CONFIG_ENTRY(MulticastEntryAgingTimeout, L"MulticastEntryAgingTimeout", AA_DEF_MCAST_IP_ENTRY_AGING_TIMEOUT),
  92. LIS_CONFIG_ENTRY(MinRevalidationDelay, L"MinMulticastRevalidationDelay", AA_DEF_MIN_MCAST_REVALIDATION_DELAY),
  93. LIS_CONFIG_ENTRY(MaxRevalidationDelay, L"MaxMulticastRevalidationDelay", AA_DEF_MAX_MCAST_REVALIDATION_DELAY),
  94. LIS_CONFIG_ENTRY(MinPartyRetryDelay, L"MinMulticastPartyRetryDelay", AA_DEF_MIN_MCAST_PARTY_RETRY_DELAY),
  95. LIS_CONFIG_ENTRY(MaxPartyRetryDelay, L"MaxMulticastPartyRetryDelay", AA_DEF_MAX_MCAST_PARTY_RETRY_DELAY),
  96. LIS_CONFIG_ENTRY(MaxJoinOrLeaveAttempts, L"MaxJoinLeaveAttempts", AA_DEF_MAX_JOIN_LEAVE_ATTEMPTS)
  97. #endif // IPMCAST
  98. };
  99. //
  100. // Size of above table.
  101. //
  102. #define LIS_CONFIG_ENTRIES \
  103. sizeof(AtmArpLISConfigTable)/sizeof(AA_READ_CONFIG_PARAMS)
  104. //
  105. // Names of LIS parameters and subkey names that don't appear
  106. // in the above table.
  107. //
  108. #define AA_LIS_IP_CONFIG_STRING L"IPConfig"
  109. #define AA_LIS_ATMARP_SERVER_LIST_KEY L"ARPServerList"
  110. #define AA_LIS_MARS_SERVER_LIST_KEY L"MARServerList"
  111. #define AA_LIS_ATMARP_SERVER_ADDRESS L"AtmAddress"
  112. #define AA_LIS_ATMARP_SERVER_SUBADDRESS L"AtmSubaddress"
  113. #endif // TODO
  114. NDIS_STATUS
  115. arpCfgReadAdapterConfiguration(
  116. IN ARP1394_ADAPTER * pAdapter,
  117. IN PRM_STACK_RECORD pSR
  118. )
  119. /*++
  120. Routine Description:
  121. Reads the following adapter configuration information from the
  122. registry:
  123. * pAdapter->ConfigString (Configuration string for the IP Interface
  124. associated with this adapter.)
  125. Arguments:
  126. pAdapter - Points to our adapter structure.
  127. Return Value:
  128. NDIS Status code
  129. --*/
  130. {
  131. NDIS_HANDLE ConfigHandle;
  132. NDIS_STATUS Status;
  133. PNDIS_STRING pConfigString = &pAdapter->bind.ConfigName;
  134. ENTER("ReadAdapterConfig", 0x025d9c6e)
  135. ASSERT(ARP_ATPASSIVE());
  136. //
  137. // We do not read adapter configuration if we're operating in ethernet emulation
  138. // (aka Bridge) mode...
  139. //
  140. if (ARP_BRIDGE_ENABLED(pAdapter))
  141. {
  142. return NDIS_STATUS_SUCCESS; // ****************** EARLY RETURN *********
  143. }
  144. // Set to this to test failure handling of bind-adapter after
  145. // open adapter succeeds.
  146. // return NDIS_STATUS_FAILURE;
  147. TR_INFO(("pAdapter 0x%p, pConfigString = 0x%p\n", pAdapter, pConfigString));
  148. NdisOpenProtocolConfiguration(
  149. &Status,
  150. &ConfigHandle,
  151. pConfigString
  152. );
  153. if (Status != NDIS_STATUS_SUCCESS)
  154. {
  155. ConfigHandle = NULL;
  156. }
  157. else
  158. {
  159. #if MILLEN
  160. //
  161. // On Win98/Millennium, we don't read the "IpConfigString" from the
  162. // Adapter (actually protocol->adapter binding) configuration (ConfigHandle).
  163. // This is because the "IpConfigString" value is the SAME as the
  164. // protocol binding key (i.e., pAdapter->bind.ConfigName).
  165. //
  166. // So we SIMPLY COPY pConfigString into pAdapter->bind.IpConfigString.
  167. //
  168. Status = arpCopyUnicodeString(
  169. &(pAdapter->bind.IpConfigString),
  170. pConfigString,
  171. FALSE // Don't UpCase
  172. );
  173. if (FAIL(Status))
  174. {
  175. ARP_ZEROSTRUCT(&(pAdapter->bind.IpConfigString));
  176. }
  177. #else //!MILLEN
  178. //
  179. // Read in the IPConfig string. If this is not present,
  180. // fail this call.
  181. //
  182. NDIS_STRING IpConfigName = NDIS_STRING_CONST("IPConfig");
  183. PNDIS_CONFIGURATION_PARAMETER pParam;
  184. NdisReadConfiguration(
  185. &Status,
  186. &pParam,
  187. ConfigHandle,
  188. &IpConfigName,
  189. NdisParameterMultiString
  190. );
  191. if ((Status == NDIS_STATUS_SUCCESS) &&
  192. (pParam->ParameterType == NdisParameterMultiString))
  193. {
  194. Status = arpCopyUnicodeString(
  195. &(pAdapter->bind.IpConfigString),
  196. &(pParam->ParameterData.StringData),
  197. FALSE // Don't UpCase
  198. );
  199. if (FAIL(Status))
  200. {
  201. ARP_ZEROSTRUCT(&(pAdapter->bind.IpConfigString));
  202. }
  203. }
  204. //
  205. // Note: NdisCloseConfiguration frees the contents of pParam.
  206. //
  207. #endif //!MILLEN
  208. }
  209. if (ConfigHandle != NULL)
  210. {
  211. NdisCloseConfiguration(ConfigHandle);
  212. ConfigHandle = NULL;
  213. }
  214. TR_INFO(("pAdapter 0x%p, Status 0x%p\n", pAdapter, Status));
  215. if (!FAIL(Status))
  216. {
  217. TR_INFO((
  218. "ConfigName=%Z; IPConfigName=%Z.\n",
  219. &pAdapter->bind.ConfigName,
  220. &pAdapter->bind.IpConfigString
  221. ));
  222. }
  223. EXIT()
  224. return Status;
  225. }
  226. NDIS_STATUS
  227. arpCfgReadInterfaceConfiguration(
  228. IN NDIS_HANDLE InterfaceConfigHandle,
  229. IN ARP1394_INTERFACE* pInterface,
  230. IN PRM_STACK_RECORD pSR
  231. )
  232. /*++
  233. Routine Description:
  234. Get all configuration parameters for the specified IP interface. We first
  235. fill in all configurable parameters with default values, and then
  236. overwrite them with values from the configuration database.
  237. Arguments:
  238. InterfaceLISComfigHandle - the handle returned by
  239. arpCfgOpenInterfaceConfiguration
  240. pInterface - the Interface control block structure for this
  241. interface.
  242. Return Value:
  243. NDIS_STATUS_SUCCESS if we were able to read in all config info.
  244. NDIS_STATUS_RESOURCES if we came across an allocation failure.
  245. NDIS_STATUS_FAILURE for any other kind of error.
  246. --*/
  247. {
  248. //
  249. // This is unimplemented.
  250. //
  251. // TODO -- remember to update interface with the interface lock held!
  252. //
  253. #if TODO
  254. NDIS_STATUS Status;
  255. PAA_READ_CONFIG_PARAMS pParamEntry;
  256. ULONG i;
  257. PATM_SAP pAtmSap;
  258. PATM_ADDRESS pAtmAddress; // SAP address
  259. NDIS_STRING ParameterName;
  260. PNDIS_CONFIGURATION_PARAMETER pNdisConfigurationParameter;
  261. do
  262. {
  263. //
  264. // Read in all the ULONGs first.
  265. //
  266. pParamEntry = AtmArpLISConfigTable;
  267. for (i = 0; i < LIS_CONFIG_ENTRIES; i++)
  268. {
  269. NdisInitUnicodeString(
  270. &ParameterName,
  271. pParamEntry->ParameterName
  272. );
  273. NdisReadConfiguration(
  274. &Status,
  275. &pNdisConfigurationParameter,
  276. LISConfigHandle,
  277. &ParameterName,
  278. NdisParameterInteger
  279. );
  280. if (Status != NDIS_STATUS_SUCCESS)
  281. {
  282. //
  283. // Error in accessing this parameter -- use the default.
  284. //
  285. *(ULONG *)((PUCHAR)pInterface + pParamEntry->StructOffset) =
  286. pParamEntry->DefaultValue;
  287. }
  288. else
  289. {
  290. *(ULONG *)((PUCHAR)pInterface + pParamEntry->StructOffset) =
  291. pNdisConfigurationParameter->ParameterData.IntegerData;
  292. }
  293. pParamEntry++;
  294. }
  295. //
  296. // Postprocessing. Sanity checks on some values.
  297. // Round up some sizes to make them multiples of 4.
  298. //
  299. pInterface->ProtocolBufSize = ROUND_UP(pInterface->ProtocolBufSize);
  300. pInterface->HeaderPool[AA_HEADER_TYPE_UNICAST].HeaderBufSize = ROUND_UP(pInterface->HeaderPool[AA_HEADER_TYPE_UNICAST].HeaderBufSize);
  301. #ifdef IPMCAST
  302. pInterface->HeaderPool[AA_HEADER_TYPE_NUNICAST].HeaderBufSize = ROUND_UP(pInterface->HeaderPool[AA_HEADER_TYPE_NUNICAST].HeaderBufSize);
  303. #endif // IPMCAST
  304. //
  305. // More postprocessing: use the SAP Selector value to set up our
  306. // "basic" listening SAP.
  307. //
  308. pInterface->SapList.pInterface = pInterface;
  309. pInterface->SapList.Flags = AA_SAP_REG_STATE_IDLE;
  310. pInterface->SapList.pInfo->SapType = SAP_TYPE_NSAP;
  311. pInterface->SapList.pInfo->SapLength = sizeof(ATM_SAP) + sizeof(ATM_ADDRESS);
  312. pAtmSap = (PATM_SAP)(pInterface->SapList.pInfo->Sap);
  313. AA_COPY_MEM((PUCHAR)&(pAtmSap->Blli), &AtmArpDefaultBlli, sizeof(ATM_BLLI_IE));
  314. AA_COPY_MEM((PUCHAR)&(pAtmSap->Bhli), &AtmArpDefaultBhli, sizeof(ATM_BHLI_IE));
  315. pAtmSap->NumberOfAddresses = 1;
  316. pAtmAddress = (PATM_ADDRESS)pAtmSap->Addresses;
  317. pAtmAddress->AddressType = SAP_FIELD_ANY_AESA_REST;
  318. pAtmAddress->NumberOfDigits = ATM_ADDRESS_LENGTH;
  319. pAtmAddress->Address[ATM_ADDRESS_LENGTH-1] = (UCHAR)(pInterface->SapSelector);
  320. pInterface->NumberOfSaps = 1;
  321. //
  322. // If the MTU wasn't specified, get it from the adapter.
  323. //
  324. if (pInterface->MTU == AA_MTU_UNSPECIFIED)
  325. {
  326. pInterface->MTU = pInterface->pAdapter->MaxPacketSize - AA_PKT_LLC_SNAP_HEADER_LENGTH;
  327. }
  328. else
  329. {
  330. //
  331. // If the MTU value isn't within bounds, default to 9180 bytes.
  332. //
  333. if ((pInterface->MTU < 9180) || (pInterface->MTU > 65535 - 8))
  334. {
  335. pInterface->MTU = 9180;
  336. }
  337. }
  338. //
  339. // If the I/F speed wasn't specified, get it from the adapter.
  340. //
  341. if (pInterface->Speed == AA_SPEED_UNSPECIFIED)
  342. {
  343. pInterface->Speed = pInterface->pAdapter->LineRate.Outbound;
  344. }
  345. //
  346. // Set up default flow parameters, if not specified, from the values
  347. // we got from the adapter.
  348. //
  349. if (pInterface->DefaultFlowSpec.SendPeakBandwidth == AA_BANDWIDTH_UNSPECIFIED)
  350. {
  351. pInterface->DefaultFlowSpec.SendPeakBandwidth = pInterface->pAdapter->LineRate.Outbound;
  352. pInterface->DefaultFlowSpec.SendAvgBandwidth = pInterface->pAdapter->LineRate.Outbound;
  353. }
  354. if (pInterface->DefaultFlowSpec.ReceivePeakBandwidth == AA_BANDWIDTH_UNSPECIFIED)
  355. {
  356. pInterface->DefaultFlowSpec.ReceivePeakBandwidth = pInterface->pAdapter->LineRate.Inbound;
  357. pInterface->DefaultFlowSpec.ReceiveAvgBandwidth = pInterface->pAdapter->LineRate.Inbound;
  358. }
  359. if (pInterface->DefaultFlowSpec.SendMaxSize == AA_PACKET_SIZE_UNSPECIFIED)
  360. {
  361. pInterface->DefaultFlowSpec.SendMaxSize = pInterface->MTU + AA_PKT_LLC_SNAP_HEADER_LENGTH;
  362. }
  363. if (pInterface->DefaultFlowSpec.ReceiveMaxSize == AA_PACKET_SIZE_UNSPECIFIED)
  364. {
  365. pInterface->DefaultFlowSpec.ReceiveMaxSize = pInterface->MTU + AA_PKT_LLC_SNAP_HEADER_LENGTH;
  366. }
  367. pInterface->DefaultFlowSpec.Encapsulation = AA_DEF_FLOWSPEC_ENCAPSULATION;
  368. pInterface->DefaultFlowSpec.SendServiceType =
  369. pInterface->DefaultFlowSpec.ReceiveServiceType = SERVICETYPE_BESTEFFORT;
  370. Status = NDIS_STATUS_SUCCESS;
  371. break;
  372. }
  373. while (FALSE);
  374. return (Status);
  375. #endif // TODO
  376. return 0;
  377. }
  378. NDIS_STATUS
  379. arpCfgGetInterfaceConfiguration(
  380. IN ARP1394_INTERFACE * pIF,
  381. IN PRM_STACK_RECORD pSR
  382. )
  383. /*++
  384. Routine Description:
  385. Read configuration information for interface pIF.
  386. Arguments:
  387. Return Value:
  388. NDIS_STATUS_SUCCESS on success.
  389. Ndis error code otherwise.
  390. --*/
  391. {
  392. ARP1394_ADAPTER * pAdapter = (ARP1394_ADAPTER*) RM_PARENT_OBJECT(pIF);
  393. ENTER("GetInterfaceConfiguration", 0xb570e01d)
  394. NDIS_STATUS Status;
  395. RM_ASSERT_NOLOCKS(pSR);
  396. do
  397. {
  398. NDIS_HANDLE ArpInterfaceConfigHandle = NULL;
  399. NDIS_STRING IpConfigString;
  400. #if OBSOLETE
  401. // Get the config string for FIRST specified LIS (we support only one)
  402. //
  403. {
  404. PWSTR p;
  405. do
  406. {
  407. p = pAdapter->bind.IpConfigString.Buffer;
  408. ASSERT(p!=NULL);
  409. DBGMARK(0x4b47fbd3);
  410. } while (p == NULL);
  411. if (*p == L'\0')
  412. {
  413. Status = NDIS_STATUS_FAILURE;
  414. break;
  415. }
  416. NdisInitUnicodeString(&IpConfigString, p);
  417. }
  418. #else // !OBSOLETE
  419. IpConfigString = pAdapter->bind.IpConfigString; // Struct copy
  420. #endif // !OBSOLETE
  421. // Open the configuration section for this interface.
  422. //
  423. {
  424. NDIS_STRING String;
  425. NDIS_HANDLE IpInterfaceConfigHandle;
  426. NDIS_STRING OurSectionName = ARP_NAME_STRING;
  427. ASSERT(ARP_ATPASSIVE());
  428. NdisOpenProtocolConfiguration(
  429. &Status,
  430. &IpInterfaceConfigHandle,
  431. &IpConfigString
  432. );
  433. if (Status != NDIS_STATUS_SUCCESS)
  434. {
  435. //
  436. // Even though we don't currently require anything
  437. // under the IP config handle, we treat this as a fatal error.
  438. //
  439. TR_WARN(("FATAL: cannot open IF IP configuration. pIF=0x%lx\n",pIF));
  440. break;
  441. }
  442. //
  443. // Get to our configuration section for this interface.
  444. //
  445. NdisOpenConfigurationKeyByName(
  446. &Status,
  447. IpInterfaceConfigHandle,
  448. &OurSectionName,
  449. &ArpInterfaceConfigHandle
  450. );
  451. if (FAIL(Status))
  452. {
  453. //
  454. // We don't *require* this to succeed.
  455. //
  456. TR_WARN(("Cannot open IF configuration. pIF=0x%lx\n", pIF));
  457. ArpInterfaceConfigHandle = NULL;
  458. Status = NDIS_STATUS_SUCCESS;
  459. }
  460. //
  461. // We don't need the main Interface section open anymore.
  462. //
  463. NdisCloseConfiguration(IpInterfaceConfigHandle);
  464. }
  465. if (ArpInterfaceConfigHandle != NULL)
  466. {
  467. // Get all configuration information for this interface.
  468. //
  469. Status = arpCfgReadInterfaceConfiguration(
  470. ArpInterfaceConfigHandle,
  471. pIF,
  472. pSR
  473. );
  474. // Close the configuration handle.
  475. //
  476. NdisCloseConfiguration(ArpInterfaceConfigHandle);
  477. ArpInterfaceConfigHandle = NULL;
  478. if (FAIL(Status))
  479. {
  480. TR_WARN((" FATAL: bad status (0x%p) reading IF cfg\n", Status));
  481. break;
  482. }
  483. }
  484. LOCKOBJ(pIF, pSR);
  485. // NOTE: we don't need to explicitly free pIF->ip.ConfigString.Buffer
  486. // when the interface goes away. The Buffer is maintained in pAdapter.
  487. //
  488. pIF->ip.ConfigString = IpConfigString; // struct copy.
  489. UNLOCKOBJ(pIF, pSR);
  490. } while(FALSE);
  491. EXIT()
  492. return Status;
  493. }