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.

1054 lines
22 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. lpmini.c
  5. Abstract:
  6. Loopback miniport
  7. Author:
  8. Jameel Hyder jameelh@microsoft.com
  9. Environment:
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. NDIS_OID LBSupportedOidArray[] =
  15. {
  16. OID_GEN_SUPPORTED_LIST,
  17. OID_GEN_HARDWARE_STATUS,
  18. OID_GEN_MEDIA_SUPPORTED,
  19. OID_GEN_MEDIA_IN_USE,
  20. OID_GEN_MAXIMUM_LOOKAHEAD,
  21. OID_GEN_MAXIMUM_FRAME_SIZE,
  22. OID_GEN_MAC_OPTIONS,
  23. OID_GEN_PROTOCOL_OPTIONS,
  24. OID_GEN_LINK_SPEED,
  25. OID_GEN_TRANSMIT_BUFFER_SPACE,
  26. OID_GEN_RECEIVE_BUFFER_SPACE,
  27. OID_GEN_TRANSMIT_BLOCK_SIZE,
  28. OID_GEN_RECEIVE_BLOCK_SIZE,
  29. OID_GEN_VENDOR_ID,
  30. OID_GEN_VENDOR_DESCRIPTION,
  31. OID_GEN_CURRENT_PACKET_FILTER,
  32. OID_GEN_CURRENT_LOOKAHEAD,
  33. OID_GEN_DRIVER_VERSION,
  34. OID_GEN_MAXIMUM_TOTAL_SIZE,
  35. OID_GEN_XMIT_OK,
  36. OID_GEN_RCV_OK,
  37. OID_GEN_XMIT_ERROR,
  38. OID_GEN_RCV_ERROR,
  39. OID_GEN_RCV_NO_BUFFER,
  40. OID_802_3_PERMANENT_ADDRESS,
  41. OID_802_3_CURRENT_ADDRESS,
  42. OID_802_3_MULTICAST_LIST,
  43. OID_802_3_MAXIMUM_LIST_SIZE,
  44. OID_802_3_RCV_ERROR_ALIGNMENT,
  45. OID_802_3_XMIT_ONE_COLLISION,
  46. OID_802_3_XMIT_MORE_COLLISIONS,
  47. OID_802_5_PERMANENT_ADDRESS,
  48. OID_802_5_CURRENT_ADDRESS,
  49. OID_802_5_CURRENT_FUNCTIONAL,
  50. OID_802_5_CURRENT_GROUP,
  51. OID_802_5_LAST_OPEN_STATUS,
  52. OID_802_5_CURRENT_RING_STATUS,
  53. OID_802_5_CURRENT_RING_STATE,
  54. OID_802_5_LINE_ERRORS,
  55. OID_802_5_LOST_FRAMES,
  56. OID_FDDI_LONG_PERMANENT_ADDR,
  57. OID_FDDI_LONG_CURRENT_ADDR,
  58. OID_FDDI_LONG_MULTICAST_LIST,
  59. OID_FDDI_LONG_MAX_LIST_SIZE,
  60. OID_FDDI_SHORT_PERMANENT_ADDR,
  61. OID_FDDI_SHORT_CURRENT_ADDR,
  62. OID_FDDI_SHORT_MULTICAST_LIST,
  63. OID_FDDI_SHORT_MAX_LIST_SIZE,
  64. OID_LTALK_CURRENT_NODE_ID,
  65. OID_ARCNET_PERMANENT_ADDRESS,
  66. OID_ARCNET_CURRENT_ADDRESS
  67. };
  68. UINT LBSupportedOids = sizeof(LBSupportedOidArray)/sizeof(NDIS_OID);
  69. UCHAR LBVendorDescription[] = "MS LoopBack Driver";
  70. UCHAR LBVendorId[3] = {0xFF, 0xFF, 0xFF};
  71. const NDIS_PHYSICAL_ADDRESS physicalConst = NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);
  72. LONG LoopDebugLevel = DBG_LEVEL_ERR;
  73. LONG LoopDebugComponent = DBG_COMP_ALL;
  74. const MEDIA_INFO MediaParams[] =
  75. {
  76. /* NdisMedium802_3 */ { 1500, 14, PACKET_FILTER_802_3, 100000},
  77. /* NdisMedium802_5 */ { 4082, 14, PACKET_FILTER_802_5, 40000},
  78. /* NdisMediumFddi */ { 4486, 13, PACKET_FILTER_FDDI, 1000000},
  79. /* NdisMediumWan */ { 0, 0, 0, 0},
  80. /* NdisMediumLocalTalk */ { 600, 3, PACKET_FILTER_LTALK, 2300},
  81. /* NdisMediumDix */ { 1500, 14, PACKET_FILTER_DIX, 100000},
  82. /* NdisMediumArcnetRaw */ { 1512, 3, PACKET_FILTER_ARCNET, 25000},
  83. /* NdisMediumArcnet878_2 */ {1512, 3, PACKET_FILTER_ARCNET, 25000}
  84. };
  85. NTSTATUS
  86. DriverEntry(
  87. IN PDRIVER_OBJECT DriverObject,
  88. IN PUNICODE_STRING RegistryPath
  89. )
  90. /*++
  91. Routine Description:
  92. Arguments:
  93. Return Value:
  94. --*/
  95. {
  96. NDIS_STATUS Status;
  97. NDIS_MINIPORT_CHARACTERISTICS MChars;
  98. NDIS_STRING Name;
  99. NDIS_HANDLE WrapperHandle;
  100. //
  101. // Register the miniport with NDIS.
  102. //
  103. NdisMInitializeWrapper(&WrapperHandle, DriverObject, RegistryPath, NULL);
  104. NdisZeroMemory(&MChars, sizeof(NDIS_MINIPORT_CHARACTERISTICS));
  105. MChars.MajorNdisVersion = NDIS_MAJOR_VERSION;
  106. MChars.MinorNdisVersion = NDIS_MINOR_VERSION;
  107. MChars.InitializeHandler = LBInitialize;
  108. MChars.QueryInformationHandler = LBQueryInformation;
  109. MChars.SetInformationHandler = LBSetInformation;
  110. MChars.ResetHandler = LBReset;
  111. MChars.TransferDataHandler = LBTransferData;
  112. MChars.SendHandler = LBSend;
  113. MChars.HaltHandler = LBHalt;
  114. MChars.CheckForHangHandler = LBCheckForHang;
  115. Status = NdisMRegisterMiniport(WrapperHandle,
  116. &MChars,
  117. sizeof(MChars));
  118. if (Status != NDIS_STATUS_SUCCESS)
  119. {
  120. NdisTerminateWrapper(WrapperHandle, NULL);
  121. }
  122. return(Status);
  123. }
  124. NDIS_STATUS
  125. LBInitialize(
  126. OUT PNDIS_STATUS OpenErrorStatus,
  127. OUT PUINT SelectedMediumIndex,
  128. IN PNDIS_MEDIUM MediumArray,
  129. IN UINT MediumArraySize,
  130. IN NDIS_HANDLE MiniportAdapterHandle,
  131. IN NDIS_HANDLE ConfigurationContext
  132. )
  133. /*++
  134. Routine Description:
  135. This is the initialize handler.
  136. Arguments:
  137. OpenErrorStatus Not used by us.
  138. SelectedMediumIndex Place-holder for what media we are using
  139. MediumArray Array of ndis media passed down to us to pick from
  140. MediumArraySize Size of the array
  141. MiniportAdapterHandle The handle NDIS uses to refer to us
  142. WrapperConfigurationContext For use by NdisOpenConfiguration
  143. Return Value:
  144. NDIS_STATUS_SUCCESS unless something goes wrong
  145. --*/
  146. {
  147. UINT i, Length;
  148. PADAPTER pAdapt;
  149. NDIS_MEDIUM AdapterMedium;
  150. NDIS_HANDLE ConfigHandle = NULL;
  151. PNDIS_CONFIGURATION_PARAMETER Parameter;
  152. PUCHAR NetworkAddress;
  153. NDIS_STRING MediumKey = NDIS_STRING_CONST("Medium");
  154. NDIS_STATUS Status;
  155. do
  156. {
  157. //
  158. // Start off by allocating the adapter block
  159. //
  160. NdisAllocateMemory(&pAdapt,
  161. sizeof(ADAPTER),
  162. 0,
  163. physicalConst);
  164. if (pAdapt == NULL)
  165. {
  166. Status = NDIS_STATUS_RESOURCES;
  167. break;
  168. }
  169. NdisZeroMemory(pAdapt, sizeof(ADAPTER));
  170. pAdapt->MiniportHandle = MiniportAdapterHandle;
  171. NdisOpenConfiguration(&Status,
  172. &ConfigHandle,
  173. ConfigurationContext);
  174. if (Status != NDIS_STATUS_SUCCESS)
  175. {
  176. DBGPRINT(DBG_COMP_REGISTRY, DBG_LEVEL_FATAL,
  177. ("Unable to open configuration database!\n"));
  178. break;
  179. }
  180. NdisReadConfiguration(&Status,
  181. &Parameter,
  182. ConfigHandle,
  183. &MediumKey,
  184. NdisParameterInteger);
  185. AdapterMedium = NdisMedium802_3; // Default
  186. if (Status == NDIS_STATUS_SUCCESS)
  187. {
  188. AdapterMedium = (NDIS_MEDIUM)Parameter->ParameterData.IntegerData;
  189. if ((AdapterMedium != NdisMedium802_3) &&
  190. (AdapterMedium != NdisMedium802_5) &&
  191. (AdapterMedium != NdisMediumFddi) &&
  192. (AdapterMedium != NdisMediumLocalTalk) &&
  193. (AdapterMedium != NdisMediumArcnet878_2))
  194. {
  195. DBGPRINT(DBG_COMP_REGISTRY, DBG_LEVEL_FATAL,
  196. ("Unable to find 'Medium' keyword or invalid value!\n"));
  197. Status = NDIS_STATUS_NOT_SUPPORTED;
  198. break;
  199. }
  200. }
  201. switch (AdapterMedium)
  202. {
  203. case NdisMedium802_3:
  204. NdisMoveMemory(pAdapt->PermanentAddress,
  205. ETH_CARD_ADDRESS,
  206. ETH_LENGTH_OF_ADDRESS);
  207. NdisMoveMemory(pAdapt->CurrentAddress,
  208. ETH_CARD_ADDRESS,
  209. ETH_LENGTH_OF_ADDRESS);
  210. break;
  211. case NdisMedium802_5:
  212. NdisMoveMemory(pAdapt->PermanentAddress,
  213. TR_CARD_ADDRESS,
  214. TR_LENGTH_OF_ADDRESS);
  215. NdisMoveMemory(pAdapt->CurrentAddress,
  216. TR_CARD_ADDRESS,
  217. TR_LENGTH_OF_ADDRESS);
  218. break;
  219. case NdisMediumFddi:
  220. NdisMoveMemory(pAdapt->PermanentAddress,
  221. FDDI_CARD_ADDRESS,
  222. FDDI_LENGTH_OF_LONG_ADDRESS);
  223. NdisMoveMemory(pAdapt->CurrentAddress,
  224. FDDI_CARD_ADDRESS,
  225. FDDI_LENGTH_OF_LONG_ADDRESS);
  226. break;
  227. case NdisMediumLocalTalk:
  228. pAdapt->PermanentAddress[0] = LTALK_CARD_ADDRESS;
  229. pAdapt->CurrentAddress[0] = LTALK_CARD_ADDRESS;
  230. break;
  231. case NdisMediumArcnet878_2:
  232. pAdapt->PermanentAddress[0] = ARC_CARD_ADDRESS;
  233. pAdapt->CurrentAddress[0] = ARC_CARD_ADDRESS;
  234. break;
  235. }
  236. pAdapt->Medium = AdapterMedium;
  237. pAdapt->MediumLinkSpeed = MediaParams[(UINT)AdapterMedium].LinkSpeed;
  238. pAdapt->MediumMinPacketLen = MediaParams[(UINT)AdapterMedium].MacHeaderLen;
  239. pAdapt->MediumMaxPacketLen = MediaParams[(UINT)AdapterMedium].MacHeaderLen+
  240. MediaParams[(UINT)AdapterMedium].MaxFrameLen;
  241. pAdapt->MediumMacHeaderLen = MediaParams[(UINT)AdapterMedium].MacHeaderLen;
  242. pAdapt->MediumMaxFrameLen = MediaParams[(UINT)AdapterMedium].MaxFrameLen;
  243. pAdapt->MediumPacketFilters = MediaParams[(UINT)AdapterMedium].PacketFilters;
  244. NdisReadNetworkAddress(&Status,
  245. &NetworkAddress,
  246. &Length,
  247. ConfigHandle);
  248. if (Status == NDIS_STATUS_SUCCESS)
  249. {
  250. //
  251. // verify the address is appropriate for the specific media and
  252. // ensure that the locally administered address bit is set
  253. //
  254. switch (AdapterMedium)
  255. {
  256. case NdisMedium802_3:
  257. case NdisMediumFddi:
  258. if ((Length != ETH_LENGTH_OF_ADDRESS) ||
  259. ETH_IS_MULTICAST(NetworkAddress) ||
  260. ((NetworkAddress[0] & 0x02) == 0))
  261. {
  262. Length = 0;
  263. }
  264. break;
  265. case NdisMedium802_5:
  266. if ((Length != TR_LENGTH_OF_ADDRESS) ||
  267. (NetworkAddress[0] & 0x80) ||
  268. ((NetworkAddress[0] & 0x40) == 0))
  269. {
  270. Length = 0;
  271. }
  272. break;
  273. case NdisMediumLocalTalk:
  274. if ((Length != 1) || LT_IS_BROADCAST(NetworkAddress[0]))
  275. {
  276. Length = 0;
  277. }
  278. break;
  279. case NdisMediumArcnet878_2:
  280. if ((Length != 1) || ARC_IS_BROADCAST(NetworkAddress[0]))
  281. {
  282. Length = 0;
  283. }
  284. break;
  285. }
  286. if (Length == 0)
  287. {
  288. DBGPRINT(DBG_COMP_REGISTRY, DBG_LEVEL_FATAL,
  289. ("Invalid NetAddress in registry!\n"));
  290. }
  291. else
  292. {
  293. NdisMoveMemory(pAdapt->CurrentAddress,
  294. NetworkAddress,
  295. Length);
  296. }
  297. }
  298. //
  299. // Make sure the medium saved is one of the ones being offered
  300. //
  301. for (i = 0; i < MediumArraySize; i++)
  302. {
  303. if (MediumArray[i] == AdapterMedium)
  304. {
  305. *SelectedMediumIndex = i;
  306. break;
  307. }
  308. }
  309. if (i == MediumArraySize)
  310. {
  311. Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
  312. break;
  313. }
  314. //
  315. // Set the attributes now.
  316. //
  317. NdisMSetAttributesEx(MiniportAdapterHandle,
  318. pAdapt,
  319. 0, // CheckForHangTimeInSeconds
  320. NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT|NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT,
  321. 0);
  322. Status = NDIS_STATUS_SUCCESS;
  323. } while (FALSE);
  324. if (ConfigHandle != NULL)
  325. {
  326. NdisCloseConfiguration(ConfigHandle);
  327. }
  328. if (Status != NDIS_STATUS_SUCCESS)
  329. {
  330. if (pAdapt != NULL)
  331. {
  332. NdisFreeMemory(pAdapt, sizeof(ADAPTER), 0);
  333. }
  334. }
  335. return Status;
  336. }
  337. VOID
  338. LBHalt(
  339. IN NDIS_HANDLE MiniportAdapterContext
  340. )
  341. /*++
  342. Routine Description:
  343. Halt handler.
  344. Arguments:
  345. MiniportAdapterContext Pointer to the Adapter
  346. Return Value:
  347. None.
  348. --*/
  349. {
  350. PADAPTER pAdapt = (PADAPTER)MiniportAdapterContext;
  351. //
  352. // Free the resources now
  353. //
  354. NdisFreeMemory(pAdapt, sizeof(ADAPTER), 0);
  355. }
  356. NDIS_STATUS
  357. LBReset(
  358. OUT PBOOLEAN AddressingReset,
  359. IN NDIS_HANDLE MiniportAdapterContext
  360. )
  361. /*++
  362. Routine Description:
  363. Reset Handler. We just don't do anything.
  364. Arguments:
  365. AddressingReset To let NDIS know whether we need help from it with our reset
  366. MiniportAdapterContext Pointer to our adapter
  367. Return Value:
  368. --*/
  369. {
  370. PADAPTER pAdapt = (PADAPTER)MiniportAdapterContext;
  371. *AddressingReset = FALSE;
  372. return(NDIS_STATUS_SUCCESS);
  373. }
  374. NDIS_STATUS
  375. LBSend(
  376. IN NDIS_HANDLE MiniportAdapterContext,
  377. IN PNDIS_PACKET Packet,
  378. IN UINT Flags
  379. )
  380. /*++
  381. Routine Description:
  382. Send handler. Just re-wrap the packet and send it below. Re-wrapping is necessary since
  383. NDIS uses the WrapperReserved for its own use.
  384. Arguments:
  385. MiniportAdapterContext Pointer to the adapter
  386. Packet Packet to send
  387. Flags Unused, passed down below
  388. Return Value:
  389. Return code from NdisSend
  390. --*/
  391. {
  392. PADAPTER pAdapt = (PADAPTER)MiniportAdapterContext;
  393. pAdapt->SendPackets++;
  394. return NDIS_STATUS_SUCCESS;
  395. }
  396. NDIS_STATUS
  397. LBQueryInformation(
  398. IN NDIS_HANDLE MiniportAdapterContext,
  399. IN NDIS_OID Oid,
  400. IN PVOID InformationBuffer,
  401. IN ULONG InformationBufferLength,
  402. OUT PULONG BytesWritten,
  403. OUT PULONG BytesNeeded
  404. )
  405. /*++
  406. Routine Description:
  407. Miniport QueryInfo handler.
  408. Arguments:
  409. MiniportAdapterContext Pointer to the adapter structure
  410. Oid Oid for this query
  411. InformationBuffer Buffer for information
  412. InformationBufferLength Size of this buffer
  413. BytesWritten Specifies how much info is written
  414. BytesNeeded In case the buffer is smaller than what we need, tell them how much is needed
  415. Return Value:
  416. Return code from the NdisRequest below.
  417. --*/
  418. {
  419. PADAPTER pAdapt = (PADAPTER)MiniportAdapterContext;
  420. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  421. UINT i;
  422. NDIS_OID MaskOid;
  423. PVOID SourceBuffer;
  424. UINT SourceBufferLength;
  425. ULONG GenericUlong = 0;
  426. USHORT GenericUshort;
  427. *BytesWritten = 0;
  428. *BytesNeeded = 0;
  429. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  430. ("OID = %lx\n", Oid));
  431. for (i = 0;i < LBSupportedOids; i++)
  432. {
  433. if (Oid == LBSupportedOidArray[i])
  434. break;
  435. }
  436. if ((i == LBSupportedOids) ||
  437. (((Oid & OID_TYPE) != OID_TYPE_GENERAL) &&
  438. (((pAdapt->Medium == NdisMedium802_3) && ((Oid & OID_TYPE) != OID_TYPE_802_3)) ||
  439. ((pAdapt->Medium == NdisMedium802_5) && ((Oid & OID_TYPE) != OID_TYPE_802_5)) ||
  440. ((pAdapt->Medium == NdisMediumFddi) && ((Oid & OID_TYPE) != OID_TYPE_FDDI)) ||
  441. ((pAdapt->Medium == NdisMediumLocalTalk) && ((Oid & OID_TYPE) != OID_TYPE_LTALK)) ||
  442. ((pAdapt->Medium == NdisMediumArcnet878_2) && ((Oid & OID_TYPE) != OID_TYPE_ARCNET)))))
  443. {
  444. return NDIS_STATUS_INVALID_OID;
  445. }
  446. //
  447. // Initialize these once, since this is the majority of cases.
  448. //
  449. SourceBuffer = (PVOID)&GenericUlong;
  450. SourceBufferLength = sizeof(ULONG);
  451. switch (Oid & OID_TYPE_MASK)
  452. {
  453. case OID_TYPE_GENERAL_OPERATIONAL:
  454. switch (Oid)
  455. {
  456. case OID_GEN_MAC_OPTIONS:
  457. GenericUlong = (ULONG)(NDIS_MAC_OPTION_NO_LOOPBACK);
  458. break;
  459. case OID_GEN_SUPPORTED_LIST:
  460. SourceBuffer = LBSupportedOidArray;
  461. SourceBufferLength = LBSupportedOids * sizeof(ULONG);
  462. break;
  463. case OID_GEN_HARDWARE_STATUS:
  464. GenericUlong = NdisHardwareStatusReady;
  465. break;
  466. case OID_GEN_MEDIA_SUPPORTED:
  467. case OID_GEN_MEDIA_IN_USE:
  468. GenericUlong = pAdapt->Medium;
  469. break;
  470. case OID_GEN_MAXIMUM_LOOKAHEAD:
  471. GenericUlong = MAX_LOOKAHEAD;
  472. break;
  473. case OID_GEN_MAXIMUM_FRAME_SIZE:
  474. GenericUlong = pAdapt->MediumMaxFrameLen;
  475. break;
  476. case OID_GEN_LINK_SPEED:
  477. GenericUlong = pAdapt->MediumLinkSpeed;
  478. break;
  479. case OID_GEN_TRANSMIT_BUFFER_SPACE:
  480. GenericUlong = pAdapt->MediumMaxPacketLen;
  481. break;
  482. case OID_GEN_RECEIVE_BUFFER_SPACE:
  483. GenericUlong = pAdapt->MediumMaxPacketLen;
  484. break;
  485. case OID_GEN_TRANSMIT_BLOCK_SIZE:
  486. GenericUlong = 1;
  487. break;
  488. case OID_GEN_RECEIVE_BLOCK_SIZE:
  489. GenericUlong = 1;
  490. break;
  491. case OID_GEN_VENDOR_ID:
  492. SourceBuffer = LBVendorId;
  493. SourceBufferLength = sizeof(LBVendorId);
  494. break;
  495. case OID_GEN_VENDOR_DESCRIPTION:
  496. SourceBuffer = LBVendorDescription;
  497. SourceBufferLength = sizeof(LBVendorDescription);
  498. break;
  499. case OID_GEN_CURRENT_PACKET_FILTER:
  500. GenericUlong = pAdapt->PacketFilter;
  501. break;
  502. case OID_GEN_CURRENT_LOOKAHEAD:
  503. GenericUlong = pAdapt->MaxLookAhead;
  504. break;
  505. case OID_GEN_DRIVER_VERSION:
  506. GenericUshort = (LOOP_MAJOR_VERSION << 8) + LOOP_MINOR_VERSION;
  507. SourceBuffer = &GenericUshort;
  508. SourceBufferLength = sizeof(USHORT);
  509. break;
  510. case OID_GEN_MAXIMUM_TOTAL_SIZE:
  511. GenericUlong = pAdapt->MediumMaxPacketLen;
  512. break;
  513. default:
  514. ASSERT(FALSE);
  515. break;
  516. }
  517. break;
  518. case OID_TYPE_GENERAL_STATISTICS:
  519. MaskOid = (Oid & OID_INDEX_MASK) - 1;
  520. switch (Oid & OID_REQUIRED_MASK)
  521. {
  522. case OID_REQUIRED_MANDATORY:
  523. switch(Oid)
  524. {
  525. case OID_GEN_XMIT_OK:
  526. SourceBuffer = &(pAdapt->SendPackets);
  527. SourceBufferLength = sizeof(ULONG);
  528. break;
  529. default:
  530. ASSERT (MaskOid < GM_ARRAY_SIZE);
  531. GenericUlong = pAdapt->GeneralMandatory[MaskOid];
  532. break;
  533. }
  534. break;
  535. default:
  536. ASSERT(FALSE);
  537. break;
  538. }
  539. break;
  540. case OID_TYPE_802_3_OPERATIONAL:
  541. switch (Oid)
  542. {
  543. case OID_802_3_PERMANENT_ADDRESS:
  544. SourceBuffer = pAdapt->PermanentAddress;
  545. SourceBufferLength = ETH_LENGTH_OF_ADDRESS;
  546. break;
  547. case OID_802_3_CURRENT_ADDRESS:
  548. SourceBuffer = pAdapt->CurrentAddress;
  549. SourceBufferLength = ETH_LENGTH_OF_ADDRESS;
  550. break;
  551. case OID_802_3_MAXIMUM_LIST_SIZE:
  552. GenericUlong = ETH_MAX_MULTICAST_ADDRESS;
  553. break;
  554. default:
  555. ASSERT(FALSE);
  556. break;
  557. }
  558. break;
  559. case OID_TYPE_802_3_STATISTICS:
  560. switch (Oid)
  561. {
  562. case OID_802_3_RCV_ERROR_ALIGNMENT:
  563. case OID_802_3_XMIT_ONE_COLLISION:
  564. case OID_802_3_XMIT_MORE_COLLISIONS:
  565. GenericUlong = 0;
  566. break;
  567. default:
  568. ASSERT(FALSE);
  569. break;
  570. }
  571. break;
  572. case OID_TYPE_802_5_OPERATIONAL:
  573. switch (Oid)
  574. {
  575. case OID_802_5_PERMANENT_ADDRESS:
  576. SourceBuffer = pAdapt->PermanentAddress;
  577. SourceBufferLength = TR_LENGTH_OF_ADDRESS;
  578. break;
  579. case OID_802_5_CURRENT_ADDRESS:
  580. SourceBuffer = pAdapt->CurrentAddress;
  581. SourceBufferLength = TR_LENGTH_OF_ADDRESS;
  582. break;
  583. case OID_802_5_LAST_OPEN_STATUS:
  584. GenericUlong = 0;
  585. break;
  586. case OID_802_5_CURRENT_RING_STATUS:
  587. GenericUlong = NDIS_RING_SINGLE_STATION;
  588. break;
  589. case OID_802_5_CURRENT_RING_STATE:
  590. GenericUlong = NdisRingStateOpened;
  591. break;
  592. default:
  593. ASSERT(FALSE);
  594. break;
  595. }
  596. break;
  597. case OID_TYPE_802_5_STATISTICS:
  598. switch (Oid)
  599. {
  600. case OID_802_5_LINE_ERRORS:
  601. case OID_802_5_LOST_FRAMES:
  602. GenericUlong = 0;
  603. break;
  604. default:
  605. ASSERT(FALSE);
  606. break;
  607. }
  608. break;
  609. case OID_TYPE_FDDI_OPERATIONAL:
  610. switch (Oid)
  611. {
  612. case OID_FDDI_LONG_PERMANENT_ADDR:
  613. SourceBuffer = pAdapt->PermanentAddress;
  614. SourceBufferLength = FDDI_LENGTH_OF_LONG_ADDRESS;
  615. break;
  616. case OID_FDDI_LONG_CURRENT_ADDR:
  617. SourceBuffer = pAdapt->CurrentAddress;
  618. SourceBufferLength = FDDI_LENGTH_OF_LONG_ADDRESS;
  619. break;
  620. case OID_FDDI_LONG_MAX_LIST_SIZE:
  621. GenericUlong = FDDI_MAX_MULTICAST_LONG;
  622. break;
  623. case OID_FDDI_SHORT_PERMANENT_ADDR:
  624. SourceBuffer = pAdapt->PermanentAddress;
  625. SourceBufferLength = FDDI_LENGTH_OF_SHORT_ADDRESS;
  626. break;
  627. case OID_FDDI_SHORT_CURRENT_ADDR:
  628. SourceBuffer = pAdapt->CurrentAddress;
  629. SourceBufferLength = FDDI_LENGTH_OF_SHORT_ADDRESS;
  630. break;
  631. case OID_FDDI_SHORT_MAX_LIST_SIZE:
  632. GenericUlong = FDDI_MAX_MULTICAST_SHORT;
  633. break;
  634. default:
  635. ASSERT(FALSE);
  636. break;
  637. }
  638. break;
  639. case OID_TYPE_LTALK_OPERATIONAL:
  640. switch(Oid)
  641. {
  642. case OID_LTALK_CURRENT_NODE_ID:
  643. SourceBuffer = pAdapt->CurrentAddress;
  644. SourceBufferLength = 1;
  645. break;
  646. default:
  647. ASSERT(FALSE);
  648. break;
  649. }
  650. break;
  651. case OID_TYPE_ARCNET_OPERATIONAL:
  652. switch(Oid)
  653. {
  654. case OID_ARCNET_PERMANENT_ADDRESS:
  655. SourceBuffer = pAdapt->PermanentAddress;
  656. SourceBufferLength = 1;
  657. break;
  658. case OID_ARCNET_CURRENT_ADDRESS:
  659. SourceBuffer = pAdapt->CurrentAddress;
  660. SourceBufferLength = 1;
  661. break;
  662. default:
  663. ASSERT(FALSE);
  664. break;
  665. }
  666. break;
  667. default:
  668. ASSERT(FALSE);
  669. break;
  670. }
  671. if (SourceBufferLength > InformationBufferLength)
  672. {
  673. *BytesNeeded = SourceBufferLength;
  674. return NDIS_STATUS_BUFFER_TOO_SHORT;
  675. }
  676. NdisMoveMemory(InformationBuffer, SourceBuffer, SourceBufferLength);
  677. *BytesWritten = SourceBufferLength;
  678. return(Status);
  679. }
  680. NDIS_STATUS
  681. LBSetInformation(
  682. IN NDIS_HANDLE MiniportAdapterContext,
  683. IN NDIS_OID Oid,
  684. IN PVOID InformationBuffer,
  685. IN ULONG InformationBufferLength,
  686. OUT PULONG BytesRead,
  687. OUT PULONG BytesNeeded
  688. )
  689. /*++
  690. Routine Description:
  691. Miniport SetInfo handler.
  692. Arguments:
  693. MiniportAdapterContext Pointer to the adapter structure
  694. Oid Oid for this query
  695. InformationBuffer Buffer for information
  696. InformationBufferLength Size of this buffer
  697. BytesRead Specifies how much info is read
  698. BytesNeeded In case the buffer is smaller than what we need, tell them how much is needed
  699. Return Value:
  700. Return code from the NdisRequest below.
  701. --*/
  702. {
  703. PADAPTER pAdapt = (PADAPTER)MiniportAdapterContext;
  704. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  705. *BytesRead = 0;
  706. *BytesNeeded = 0;
  707. DBGPRINT(DBG_COMP_REQUEST, DBG_LEVEL_INFO,
  708. ("SetInformation: OID = %lx\n", Oid));
  709. switch (Oid)
  710. {
  711. case OID_GEN_CURRENT_PACKET_FILTER:
  712. if (InformationBufferLength != sizeof(ULONG))
  713. {
  714. Status = NDIS_STATUS_INVALID_DATA;
  715. }
  716. else
  717. {
  718. ULONG PacketFilter;
  719. PacketFilter = *(UNALIGNED ULONG *)InformationBuffer;
  720. if (PacketFilter != (PacketFilter & pAdapt->MediumPacketFilters))
  721. {
  722. Status = NDIS_STATUS_NOT_SUPPORTED;
  723. }
  724. else
  725. {
  726. pAdapt->PacketFilter = PacketFilter;
  727. *BytesRead = InformationBufferLength;
  728. }
  729. }
  730. break;
  731. case OID_GEN_CURRENT_LOOKAHEAD:
  732. if (InformationBufferLength != sizeof(ULONG))
  733. {
  734. Status = NDIS_STATUS_INVALID_DATA;
  735. }
  736. else
  737. {
  738. ULONG CurrentLookahead;
  739. CurrentLookahead = *(UNALIGNED ULONG *)InformationBuffer;
  740. if (CurrentLookahead > MAX_LOOKAHEAD)
  741. {
  742. Status = NDIS_STATUS_INVALID_LENGTH;
  743. }
  744. else if (CurrentLookahead >= pAdapt->MaxLookAhead)
  745. {
  746. pAdapt->MaxLookAhead = CurrentLookahead;
  747. *BytesRead = sizeof(ULONG);
  748. Status = NDIS_STATUS_SUCCESS;
  749. }
  750. }
  751. break;
  752. case OID_802_3_MULTICAST_LIST:
  753. if (pAdapt->Medium != NdisMedium802_3)
  754. {
  755. Status = NDIS_STATUS_INVALID_OID;
  756. break;
  757. }
  758. if ((InformationBufferLength % ETH_LENGTH_OF_ADDRESS) != 0)
  759. {
  760. Status = NDIS_STATUS_INVALID_LENGTH;
  761. break;
  762. }
  763. break;
  764. case OID_802_5_CURRENT_FUNCTIONAL:
  765. if (pAdapt->Medium != NdisMedium802_5)
  766. {
  767. Status = NDIS_STATUS_INVALID_OID;
  768. break;
  769. }
  770. if (InformationBufferLength != TR_LENGTH_OF_FUNCTIONAL)
  771. {
  772. Status = NDIS_STATUS_INVALID_LENGTH;
  773. break;
  774. }
  775. break;
  776. case OID_802_5_CURRENT_GROUP:
  777. if (pAdapt->Medium != NdisMedium802_5)
  778. {
  779. Status = NDIS_STATUS_INVALID_OID;
  780. break;
  781. }
  782. if (InformationBufferLength != TR_LENGTH_OF_FUNCTIONAL)
  783. {
  784. Status = NDIS_STATUS_INVALID_LENGTH;
  785. break;
  786. }
  787. break;
  788. case OID_FDDI_LONG_MULTICAST_LIST:
  789. if (pAdapt->Medium != NdisMediumFddi)
  790. {
  791. Status = NDIS_STATUS_INVALID_OID;
  792. break;
  793. }
  794. if ((InformationBufferLength % FDDI_LENGTH_OF_LONG_ADDRESS) != 0)
  795. {
  796. Status = NDIS_STATUS_INVALID_LENGTH;
  797. break;
  798. }
  799. break;
  800. case OID_FDDI_SHORT_MULTICAST_LIST:
  801. if (pAdapt->Medium != NdisMediumFddi)
  802. {
  803. Status = NDIS_STATUS_INVALID_OID;
  804. break;
  805. }
  806. if ((InformationBufferLength % FDDI_LENGTH_OF_SHORT_ADDRESS) != 0)
  807. {
  808. Status = NDIS_STATUS_INVALID_LENGTH;
  809. break;
  810. }
  811. break;
  812. case OID_GEN_PROTOCOL_OPTIONS:
  813. Status = NDIS_STATUS_SUCCESS;
  814. break;
  815. default:
  816. Status = NDIS_STATUS_INVALID_OID;
  817. break;
  818. }
  819. return(Status);
  820. }
  821. BOOLEAN
  822. LBCheckForHang(
  823. IN NDIS_HANDLE MiniportAdapterContext
  824. )
  825. {
  826. return FALSE;
  827. }
  828. NDIS_STATUS
  829. LBTransferData(
  830. OUT PNDIS_PACKET Packet,
  831. OUT PUINT BytesTransferred,
  832. IN NDIS_HANDLE MiniportAdapterContext,
  833. IN NDIS_HANDLE MiniportReceiveContext,
  834. IN UINT ByteOffset,
  835. IN UINT BytesToTransfer
  836. )
  837. {
  838. ASSERT (0);
  839. return NDIS_STATUS_NOT_SUPPORTED;
  840. }