|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1989-1993 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: stndis.c ! 8: ! 9: Abstract: ! 10: ! 11: This module contains code which implements the routines used to interface ! 12: ST and NDIS. All callback routines (except for Transfer Data, ! 13: Send Complete, and ReceiveIndication) are here, as well as those routines ! 14: called to initialize NDIS. ! 15: ! 16: Environment: ! 17: ! 18: Kernel mode ! 19: ! 20: --*/ ! 21: ! 22: #include "st.h" ! 23: ! 24: ! 25: // ! 26: // This is a one-per-driver variable used in binding ! 27: // to the NDIS interface. ! 28: // ! 29: ! 30: NDIS_HANDLE StNdisProtocolHandle = (NDIS_HANDLE)NULL; ! 31: ! 32: NDIS_STATUS ! 33: StSubmitNdisRequest( ! 34: IN PDEVICE_CONTEXT DeviceContext, ! 35: IN PNDIS_REQUEST NdisRequest, ! 36: IN PNDIS_STRING AdapterString ! 37: ); ! 38: ! 39: #ifdef ALLOC_PRAGMA ! 40: #pragma alloc_text(init,StRegisterProtocol) ! 41: #pragma alloc_text(init,StSubmitNdisRequest) ! 42: #pragma alloc_text(init,StInitializeNdis) ! 43: #endif ! 44: ! 45: ! 46: NTSTATUS ! 47: StRegisterProtocol ( ! 48: IN STRING *NameString ! 49: ) ! 50: ! 51: /*++ ! 52: ! 53: Routine Description: ! 54: ! 55: This routine introduces this transport to the NDIS interface. ! 56: ! 57: Arguments: ! 58: ! 59: Irp - Pointer to the request packet representing the I/O request. ! 60: ! 61: Return Value: ! 62: ! 63: The function value is the status of the operation. ! 64: STATUS_SUCCESS if all goes well, ! 65: Failure status if we tried to register and couldn't, ! 66: STATUS_INSUFFICIENT_RESOURCES if we couldn't even try to register. ! 67: ! 68: --*/ ! 69: ! 70: { ! 71: NDIS_STATUS ndisStatus; ! 72: ! 73: NDIS_PROTOCOL_CHARACTERISTICS ProtChars; // Used temporarily to register ! 74: ! 75: ! 76: // ! 77: // Set up the characteristics of this protocol ! 78: // ! 79: ! 80: ProtChars.MajorNdisVersion = 3; ! 81: ProtChars.MinorNdisVersion = 0; ! 82: ! 83: ProtChars.Name.Length = NameString->Length; ! 84: ProtChars.Name.Buffer = (PVOID)NameString->Buffer; ! 85: ! 86: ProtChars.OpenAdapterCompleteHandler = StOpenAdapterComplete; ! 87: ProtChars.CloseAdapterCompleteHandler = StCloseAdapterComplete; ! 88: ProtChars.ResetCompleteHandler = StResetComplete; ! 89: ProtChars.RequestCompleteHandler = StRequestComplete; ! 90: ! 91: ProtChars.SendCompleteHandler = StSendCompletionHandler; ! 92: ProtChars.TransferDataCompleteHandler = StTransferDataComplete; ! 93: ! 94: ProtChars.ReceiveHandler = StReceiveIndication; ! 95: ProtChars.ReceiveCompleteHandler = StReceiveComplete; ! 96: ProtChars.StatusHandler = StStatusIndication; ! 97: ProtChars.StatusCompleteHandler = StStatusComplete; ! 98: ! 99: NdisRegisterProtocol ( ! 100: &ndisStatus, ! 101: &StNdisProtocolHandle, ! 102: &ProtChars, ! 103: (UINT)sizeof(NDIS_PROTOCOL_CHARACTERISTICS) + NameString->Length); ! 104: ! 105: if (ndisStatus != NDIS_STATUS_SUCCESS) { ! 106: return (NTSTATUS)ndisStatus; ! 107: } ! 108: ! 109: return STATUS_SUCCESS; ! 110: } ! 111: ! 112: ! 113: VOID ! 114: StDeregisterProtocol ( ! 115: VOID ! 116: ) ! 117: ! 118: /*++ ! 119: ! 120: Routine Description: ! 121: ! 122: This routine removes this transport to the NDIS interface. ! 123: ! 124: Arguments: ! 125: ! 126: None. ! 127: ! 128: Return Value: ! 129: ! 130: None. ! 131: ! 132: --*/ ! 133: ! 134: { ! 135: NDIS_STATUS ndisStatus; ! 136: ! 137: if (StNdisProtocolHandle != (NDIS_HANDLE)NULL) { ! 138: NdisDeregisterProtocol ( ! 139: &ndisStatus, ! 140: StNdisProtocolHandle); ! 141: StNdisProtocolHandle = (NDIS_HANDLE)NULL; ! 142: } ! 143: } ! 144: ! 145: ! 146: NDIS_STATUS ! 147: StSubmitNdisRequest( ! 148: IN PDEVICE_CONTEXT DeviceContext, ! 149: IN PNDIS_REQUEST NdisRequest, ! 150: IN PNDIS_STRING AdapterString ! 151: ) ! 152: ! 153: /*++ ! 154: ! 155: Routine Description: ! 156: ! 157: This routine passed an NDIS_REQUEST to the MAC and waits ! 158: until it has completed before returning the final status. ! 159: ! 160: Arguments: ! 161: ! 162: DeviceContext - Pointer to the device context for this driver. ! 163: ! 164: NdisRequest - Pointer to the NDIS_REQUEST to submit. ! 165: ! 166: AdapterString - The name of the adapter, in case an error needs ! 167: to be logged. ! 168: ! 169: Return Value: ! 170: ! 171: The function value is the status of the operation. ! 172: ! 173: --*/ ! 174: { ! 175: NDIS_STATUS NdisStatus; ! 176: ! 177: NdisRequest( ! 178: &NdisStatus, ! 179: DeviceContext->NdisBindingHandle, ! 180: NdisRequest); ! 181: ! 182: if (NdisStatus == NDIS_STATUS_PENDING) { ! 183: ! 184: // ! 185: // The completion routine will set NdisRequestStatus. ! 186: // ! 187: ! 188: KeWaitForSingleObject( ! 189: &DeviceContext->NdisRequestEvent, ! 190: Executive, ! 191: KernelMode, ! 192: TRUE, ! 193: (PLARGE_INTEGER)NULL ! 194: ); ! 195: ! 196: NdisStatus = DeviceContext->NdisRequestStatus; ! 197: ! 198: KeResetEvent( ! 199: &DeviceContext->NdisRequestEvent ! 200: ); ! 201: ! 202: } ! 203: ! 204: if (NdisStatus != NDIS_STATUS_SUCCESS) { ! 205: ! 206: StWriteOidErrorLog( ! 207: DeviceContext, ! 208: NdisRequest->RequestType == NdisRequestSetInformation ? ! 209: EVENT_TRANSPORT_SET_OID_FAILED : EVENT_TRANSPORT_QUERY_OID_FAILED, ! 210: NdisStatus, ! 211: AdapterString->Buffer, ! 212: NdisRequest->DATA.QUERY_INFORMATION.Oid); ! 213: } ! 214: ! 215: return NdisStatus; ! 216: } ! 217: ! 218: ! 219: NTSTATUS ! 220: StInitializeNdis ( ! 221: IN PDEVICE_CONTEXT DeviceContext, ! 222: IN PCONFIG_DATA StConfig, ! 223: IN UINT ConfigInfoNameIndex ! 224: ) ! 225: ! 226: /*++ ! 227: ! 228: Routine Description: ! 229: ! 230: This routine introduces this transport to the NDIS interface and sets up ! 231: any necessary NDIS data structures (Buffer pools and such). It will be ! 232: called for each adapter opened by this transport. ! 233: ! 234: Arguments: ! 235: ! 236: DeviceObject - Pointer to the device object for this driver. ! 237: ! 238: Irp - Pointer to the request packet representing the I/O request. ! 239: ! 240: Return Value: ! 241: ! 242: The function value is the status of the operation. ! 243: ! 244: --*/ ! 245: { ! 246: ULONG SendPacketReservedLength; ! 247: ULONG ReceivePacketReservedLen; ! 248: ULONG SendPacketPoolSize; ! 249: ULONG ReceivePacketPoolSize; ! 250: NDIS_STATUS NdisStatus; ! 251: NDIS_STATUS OpenErrorStatus; ! 252: NDIS_MEDIUM StSupportedMedia[] = { NdisMedium802_3, NdisMedium802_5, NdisMediumFddi }; ! 253: UINT SelectedMedium; ! 254: NDIS_REQUEST StRequest; ! 255: UCHAR StDataBuffer[6]; ! 256: NDIS_OID StOid; ! 257: ULONG MinimumLookahead = 128 + sizeof(ST_HEADER); ! 258: ULONG ProtocolOptions, MacOptions; ! 259: PNDIS_STRING AdapterString; ! 260: ! 261: // ! 262: // Initialize this adapter for ST use through NDIS ! 263: // ! 264: ! 265: // ! 266: // This event is used in case any of the NDIS requests ! 267: // pend; we wait until it is set by the completion ! 268: // routine, which also sets NdisRequestStatus. ! 269: // ! 270: ! 271: KeInitializeEvent( ! 272: &DeviceContext->NdisRequestEvent, ! 273: NotificationEvent, ! 274: FALSE ! 275: ); ! 276: ! 277: DeviceContext->NdisBindingHandle = NULL; ! 278: AdapterString = (PNDIS_STRING)&StConfig->Names[ConfigInfoNameIndex]; ! 279: ! 280: NdisOpenAdapter ( ! 281: &NdisStatus, ! 282: &OpenErrorStatus, ! 283: &DeviceContext->NdisBindingHandle, ! 284: &SelectedMedium, ! 285: StSupportedMedia, ! 286: sizeof (StSupportedMedia) / sizeof(NDIS_MEDIUM), ! 287: StNdisProtocolHandle, ! 288: (NDIS_HANDLE)DeviceContext, ! 289: AdapterString, ! 290: 0, ! 291: NULL); ! 292: ! 293: if (NdisStatus == NDIS_STATUS_PENDING) { ! 294: ! 295: // ! 296: // The completion routine will set NdisRequestStatus. ! 297: // ! 298: ! 299: KeWaitForSingleObject( ! 300: &DeviceContext->NdisRequestEvent, ! 301: Executive, ! 302: KernelMode, ! 303: TRUE, ! 304: (PLARGE_INTEGER)NULL ! 305: ); ! 306: ! 307: NdisStatus = DeviceContext->NdisRequestStatus; ! 308: ! 309: KeResetEvent( ! 310: &DeviceContext->NdisRequestEvent ! 311: ); ! 312: ! 313: } ! 314: ! 315: if (NdisStatus != NDIS_STATUS_SUCCESS) { ! 316: ! 317: StWriteGeneralErrorLog( ! 318: DeviceContext, ! 319: EVENT_TRANSPORT_ADAPTER_NOT_FOUND, ! 320: 807, ! 321: NdisStatus, ! 322: AdapterString->Buffer, ! 323: 0, ! 324: NULL); ! 325: return STATUS_INSUFFICIENT_RESOURCES; ! 326: } ! 327: ! 328: ! 329: // ! 330: // Get the information we need about the adapter, based on ! 331: // the media type. ! 332: // ! 333: ! 334: MacInitializeMacInfo( ! 335: StSupportedMedia[SelectedMedium], ! 336: &DeviceContext->MacInfo); ! 337: ! 338: ! 339: // ! 340: // Set the multicast/functional addresses first so we avoid windows where we ! 341: // receive only part of the addresses. ! 342: // ! 343: ! 344: MacSetMulticastAddress ( ! 345: DeviceContext->MacInfo.MediumType, ! 346: DeviceContext->MulticastAddress.Address); ! 347: ! 348: ! 349: switch (DeviceContext->MacInfo.MediumType) { ! 350: ! 351: case NdisMedium802_3: ! 352: ! 353: // ! 354: // Fill in the data for our multicast list. ! 355: // ! 356: ! 357: RtlCopyMemory(StDataBuffer, DeviceContext->MulticastAddress.Address, 6); ! 358: ! 359: // ! 360: // Now fill in the NDIS_REQUEST. ! 361: // ! 362: ! 363: StRequest.RequestType = NdisRequestSetInformation; ! 364: StRequest.DATA.SET_INFORMATION.Oid = OID_802_3_MULTICAST_LIST; ! 365: StRequest.DATA.SET_INFORMATION.InformationBuffer = &StDataBuffer; ! 366: StRequest.DATA.SET_INFORMATION.InformationBufferLength = 6; ! 367: ! 368: break; ! 369: ! 370: case NdisMedium802_5: ! 371: ! 372: // ! 373: // For token-ring, we pass the last four bytes of the ! 374: // Netbios functional address. ! 375: // ! 376: ! 377: // ! 378: // Fill in the data for our functional address. ! 379: // ! 380: ! 381: RtlCopyMemory(StDataBuffer, ((PUCHAR)(DeviceContext->MulticastAddress.Address)) + 2, 4); ! 382: ! 383: // ! 384: // Now fill in the NDIS_REQUEST. ! 385: // ! 386: ! 387: StRequest.RequestType = NdisRequestSetInformation; ! 388: StRequest.DATA.SET_INFORMATION.Oid = OID_802_5_CURRENT_FUNCTIONAL; ! 389: StRequest.DATA.SET_INFORMATION.InformationBuffer = &StDataBuffer; ! 390: StRequest.DATA.SET_INFORMATION.InformationBufferLength = 4; ! 391: ! 392: break; ! 393: ! 394: case NdisMediumFddi: ! 395: ! 396: // ! 397: // Fill in the data for our multicast list. ! 398: // ! 399: ! 400: RtlCopyMemory(StDataBuffer, DeviceContext->MulticastAddress.Address, 6); ! 401: ! 402: // ! 403: // Now fill in the NDIS_REQUEST. ! 404: // ! 405: ! 406: StRequest.RequestType = NdisRequestSetInformation; ! 407: StRequest.DATA.SET_INFORMATION.Oid = OID_FDDI_LONG_MULTICAST_LIST; ! 408: StRequest.DATA.SET_INFORMATION.InformationBuffer = &StDataBuffer; ! 409: StRequest.DATA.SET_INFORMATION.InformationBufferLength = 6; ! 410: ! 411: break; ! 412: ! 413: } ! 414: ! 415: NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString); ! 416: ! 417: if (NdisStatus != NDIS_STATUS_SUCCESS) { ! 418: StCloseNdis (DeviceContext); ! 419: return STATUS_INSUFFICIENT_RESOURCES; ! 420: } ! 421: ! 422: ! 423: ! 424: switch (DeviceContext->MacInfo.MediumType) { ! 425: ! 426: case NdisMedium802_3: ! 427: ! 428: StOid = OID_802_3_CURRENT_ADDRESS; ! 429: break; ! 430: ! 431: case NdisMedium802_5: ! 432: ! 433: StOid = OID_802_5_CURRENT_ADDRESS; ! 434: break; ! 435: ! 436: case NdisMediumFddi: ! 437: ! 438: StOid = OID_FDDI_LONG_CURRENT_ADDR; ! 439: break; ! 440: ! 441: default: ! 442: ! 443: NdisStatus = NDIS_STATUS_FAILURE; ! 444: break; ! 445: ! 446: } ! 447: ! 448: StRequest.RequestType = NdisRequestQueryInformation; ! 449: StRequest.DATA.QUERY_INFORMATION.Oid = StOid; ! 450: StRequest.DATA.QUERY_INFORMATION.InformationBuffer = DeviceContext->LocalAddress.Address; ! 451: StRequest.DATA.QUERY_INFORMATION.InformationBufferLength = 6; ! 452: ! 453: NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString); ! 454: ! 455: if (NdisStatus != NDIS_STATUS_SUCCESS) { ! 456: StCloseNdis (DeviceContext); ! 457: return STATUS_INSUFFICIENT_RESOURCES; ! 458: } ! 459: ! 460: // ! 461: // Set up the reserved Netbios address. ! 462: // ! 463: ! 464: RtlZeroMemory(DeviceContext->ReservedNetBIOSAddress, 10); ! 465: RtlCopyMemory(&DeviceContext->ReservedNetBIOSAddress[10], DeviceContext->LocalAddress.Address, 6); ! 466: ! 467: ! 468: // ! 469: // Now query the maximum packet sizes. ! 470: // ! 471: ! 472: StRequest.RequestType = NdisRequestQueryInformation; ! 473: StRequest.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_FRAME_SIZE; ! 474: StRequest.DATA.QUERY_INFORMATION.InformationBuffer = &(DeviceContext->MaxReceivePacketSize); ! 475: StRequest.DATA.QUERY_INFORMATION.InformationBufferLength = 4; ! 476: ! 477: NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString); ! 478: ! 479: if (NdisStatus != NDIS_STATUS_SUCCESS) { ! 480: StCloseNdis (DeviceContext); ! 481: return STATUS_INSUFFICIENT_RESOURCES; ! 482: } ! 483: ! 484: ! 485: StRequest.RequestType = NdisRequestQueryInformation; ! 486: StRequest.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE; ! 487: StRequest.DATA.QUERY_INFORMATION.InformationBuffer = &(DeviceContext->MaxSendPacketSize); ! 488: StRequest.DATA.QUERY_INFORMATION.InformationBufferLength = 4; ! 489: ! 490: NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString); ! 491: ! 492: if (NdisStatus != NDIS_STATUS_SUCCESS) { ! 493: StCloseNdis (DeviceContext); ! 494: return STATUS_INSUFFICIENT_RESOURCES; ! 495: } ! 496: ! 497: ! 498: // ! 499: // Now set the minimum lookahead size. ! 500: // ! 501: ! 502: StRequest.RequestType = NdisRequestSetInformation; ! 503: StRequest.DATA.QUERY_INFORMATION.Oid = OID_GEN_CURRENT_LOOKAHEAD; ! 504: StRequest.DATA.QUERY_INFORMATION.InformationBuffer = &MinimumLookahead; ! 505: StRequest.DATA.QUERY_INFORMATION.InformationBufferLength = 4; ! 506: ! 507: NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString); ! 508: ! 509: if (NdisStatus != NDIS_STATUS_SUCCESS) { ! 510: StCloseNdis (DeviceContext); ! 511: return STATUS_INSUFFICIENT_RESOURCES; ! 512: } ! 513: ! 514: ! 515: // ! 516: // Now query the link speed ! 517: // ! 518: ! 519: StRequest.RequestType = NdisRequestQueryInformation; ! 520: StRequest.DATA.QUERY_INFORMATION.Oid = OID_GEN_LINK_SPEED; ! 521: StRequest.DATA.QUERY_INFORMATION.InformationBuffer = &(DeviceContext->MediumSpeed); ! 522: StRequest.DATA.QUERY_INFORMATION.InformationBufferLength = 4; ! 523: ! 524: NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString); ! 525: ! 526: if (NdisStatus != NDIS_STATUS_SUCCESS) { ! 527: StCloseNdis (DeviceContext); ! 528: return STATUS_INSUFFICIENT_RESOURCES; ! 529: } ! 530: ! 531: ! 532: // ! 533: // Now query the MAC's optional characteristics. ! 534: // ! 535: ! 536: StRequest.RequestType = NdisRequestQueryInformation; ! 537: StRequest.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAC_OPTIONS; ! 538: StRequest.DATA.QUERY_INFORMATION.InformationBuffer = &MacOptions; ! 539: StRequest.DATA.QUERY_INFORMATION.InformationBufferLength = 4; ! 540: ! 541: NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString); ! 542: ! 543: if (NdisStatus != NDIS_STATUS_SUCCESS) { ! 544: StCloseNdis (DeviceContext); ! 545: return STATUS_INSUFFICIENT_RESOURCES; ! 546: } ! 547: ! 548: // ! 549: // Since the sample transport does not try to optimize for the ! 550: // cases where transfer data is always synchronous or indications ! 551: // are not reentered, we ignore those bits in MacOptions. ! 552: // ! 553: ! 554: DeviceContext->MacInfo.CopyLookahead = ! 555: (BOOLEAN)((MacOptions & NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA) != 0); ! 556: ! 557: ! 558: // ! 559: // Now set our options if needed. We can only support ! 560: // partial indications if running over 802.3 where the ! 561: // real packet length can be obtained from the header. ! 562: // ! 563: ! 564: if (DeviceContext->MacInfo.MediumType == NdisMedium802_3) { ! 565: ! 566: ProtocolOptions = NDIS_PROT_OPTION_ESTIMATED_LENGTH; ! 567: ! 568: StRequest.RequestType = NdisRequestSetInformation; ! 569: StRequest.DATA.QUERY_INFORMATION.Oid = OID_GEN_PROTOCOL_OPTIONS; ! 570: StRequest.DATA.QUERY_INFORMATION.InformationBuffer = &ProtocolOptions; ! 571: StRequest.DATA.QUERY_INFORMATION.InformationBufferLength = 4; ! 572: ! 573: NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString); ! 574: ! 575: if (NdisStatus != NDIS_STATUS_SUCCESS) { ! 576: StCloseNdis (DeviceContext); ! 577: return STATUS_INSUFFICIENT_RESOURCES; ! 578: } ! 579: ! 580: } ! 581: ! 582: ! 583: // ! 584: // Calculate the NDIS-related stuff. ! 585: // ! 586: ! 587: SendPacketReservedLength = sizeof (SEND_PACKET_TAG); ! 588: ReceivePacketReservedLen = sizeof (RECEIVE_PACKET_TAG); ! 589: ! 590: // ! 591: // The send packet pool is used for UI frames and regular packets. ! 592: // ! 593: ! 594: SendPacketPoolSize = StConfig->SendPacketPoolSize; ! 595: ! 596: // ! 597: // The receive packet pool is used in transfer data. ! 598: // ! 599: ! 600: ReceivePacketPoolSize = StConfig->ReceivePacketPoolSize; ! 601: ! 602: ! 603: NdisAllocatePacketPool ( ! 604: &NdisStatus, ! 605: &DeviceContext->SendPacketPoolHandle, ! 606: SendPacketPoolSize, ! 607: SendPacketReservedLength); ! 608: ! 609: if (NdisStatus != NDIS_STATUS_SUCCESS) { ! 610: DeviceContext->SendPacketPoolHandle = NULL; ! 611: StCloseNdis (DeviceContext); ! 612: return STATUS_INSUFFICIENT_RESOURCES; ! 613: } ! 614: ! 615: DeviceContext->MemoryUsage += ! 616: (SendPacketPoolSize * ! 617: (sizeof(NDIS_PACKET) + SendPacketReservedLength)); ! 618: ! 619: ! 620: NdisAllocatePacketPool( ! 621: &NdisStatus, ! 622: &DeviceContext->ReceivePacketPoolHandle, ! 623: ReceivePacketPoolSize, ! 624: ReceivePacketReservedLen); ! 625: ! 626: if (NdisStatus != NDIS_STATUS_SUCCESS) { ! 627: DeviceContext->ReceivePacketPoolHandle = NULL; ! 628: StCloseNdis (DeviceContext); ! 629: return STATUS_INSUFFICIENT_RESOURCES; ! 630: } ! 631: ! 632: DeviceContext->MemoryUsage += ! 633: (ReceivePacketPoolSize * ! 634: (sizeof(NDIS_PACKET) + ReceivePacketReservedLen)); ! 635: ! 636: ! 637: // ! 638: // Allocate the buffer pool; as an estimate, allocate ! 639: // one per send or receive packet. ! 640: // ! 641: ! 642: NdisAllocateBufferPool ( ! 643: &NdisStatus, ! 644: &DeviceContext->NdisBufferPoolHandle, ! 645: SendPacketPoolSize + ReceivePacketPoolSize); ! 646: ! 647: if (NdisStatus != NDIS_STATUS_SUCCESS) { ! 648: DeviceContext->NdisBufferPoolHandle = NULL; ! 649: StCloseNdis (DeviceContext); ! 650: return STATUS_INSUFFICIENT_RESOURCES; ! 651: } ! 652: ! 653: ! 654: // ! 655: // Now that everything is set up, we enable the filter ! 656: // for packet reception. ! 657: // ! 658: ! 659: // ! 660: // Fill in the OVB for packet filter. ! 661: // ! 662: ! 663: switch (DeviceContext->MacInfo.MediumType) { ! 664: ! 665: case NdisMedium802_3: ! 666: case NdisMediumFddi: ! 667: ! 668: RtlStoreUlong((PULONG)StDataBuffer, ! 669: (NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_MULTICAST)); ! 670: break; ! 671: ! 672: case NdisMedium802_5: ! 673: ! 674: RtlStoreUlong((PULONG)StDataBuffer, ! 675: (NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_FUNCTIONAL)); ! 676: break; ! 677: ! 678: default: ! 679: ! 680: ASSERT (FALSE); ! 681: break; ! 682: ! 683: } ! 684: ! 685: // ! 686: // Now fill in the NDIS_REQUEST. ! 687: // ! 688: ! 689: StRequest.RequestType = NdisRequestSetInformation; ! 690: StRequest.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER; ! 691: StRequest.DATA.SET_INFORMATION.InformationBuffer = &StDataBuffer; ! 692: StRequest.DATA.SET_INFORMATION.InformationBufferLength = sizeof(ULONG); ! 693: ! 694: NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString); ! 695: ! 696: if (NdisStatus != NDIS_STATUS_SUCCESS) { ! 697: StCloseNdis (DeviceContext); ! 698: return STATUS_INSUFFICIENT_RESOURCES; ! 699: } ! 700: ! 701: ! 702: return STATUS_SUCCESS; ! 703: ! 704: } /* StInitializeNdis */ ! 705: ! 706: ! 707: VOID ! 708: StCloseNdis ( ! 709: IN PDEVICE_CONTEXT DeviceContext ! 710: ) ! 711: ! 712: /*++ ! 713: ! 714: Routine Description: ! 715: ! 716: This routine unbinds the transport from the NDIS interface and does ! 717: any other work required to undo what was done in StInitializeNdis. ! 718: It is written so that it can be called from within StInitializeNdis ! 719: if it fails partway through. ! 720: ! 721: Arguments: ! 722: ! 723: DeviceObject - Pointer to the device object for this driver. ! 724: ! 725: Return Value: ! 726: ! 727: The function value is the status of the operation. ! 728: ! 729: --*/ ! 730: { ! 731: NDIS_STATUS ndisStatus; ! 732: ! 733: // ! 734: // Close the NDIS binding. ! 735: // ! 736: ! 737: if (DeviceContext->NdisBindingHandle != (NDIS_HANDLE)NULL) { ! 738: ! 739: // ! 740: // This event is used in case any of the NDIS requests ! 741: // pend; we wait until it is set by the completion ! 742: // routine, which also sets NdisRequestStatus. ! 743: // ! 744: ! 745: KeInitializeEvent( ! 746: &DeviceContext->NdisRequestEvent, ! 747: NotificationEvent, ! 748: FALSE ! 749: ); ! 750: ! 751: NdisCloseAdapter( ! 752: &ndisStatus, ! 753: DeviceContext->NdisBindingHandle); ! 754: ! 755: if (ndisStatus == NDIS_STATUS_PENDING) { ! 756: ! 757: // ! 758: // The completion routine will set NdisRequestStatus. ! 759: // ! 760: ! 761: KeWaitForSingleObject( ! 762: &DeviceContext->NdisRequestEvent, ! 763: Executive, ! 764: KernelMode, ! 765: TRUE, ! 766: (PLARGE_INTEGER)NULL ! 767: ); ! 768: ! 769: ndisStatus = DeviceContext->NdisRequestStatus; ! 770: ! 771: KeResetEvent( ! 772: &DeviceContext->NdisRequestEvent ! 773: ); ! 774: ! 775: } ! 776: ! 777: // ! 778: // We ignore ndisStatus. ! 779: // ! 780: ! 781: } ! 782: ! 783: if (DeviceContext->SendPacketPoolHandle != NULL) { ! 784: NdisFreePacketPool (DeviceContext->SendPacketPoolHandle); ! 785: } ! 786: ! 787: if (DeviceContext->ReceivePacketPoolHandle != NULL) { ! 788: NdisFreePacketPool (DeviceContext->ReceivePacketPoolHandle); ! 789: } ! 790: ! 791: if (DeviceContext->NdisBufferPoolHandle != NULL) { ! 792: NdisFreeBufferPool (DeviceContext->NdisBufferPoolHandle); ! 793: } ! 794: ! 795: } /* StCloseNdis */ ! 796: ! 797: ! 798: VOID ! 799: StOpenAdapterComplete ( ! 800: IN NDIS_HANDLE BindingContext, ! 801: IN NDIS_STATUS NdisStatus, ! 802: IN NDIS_STATUS OpenErrorStatus ! 803: ) ! 804: ! 805: /*++ ! 806: ! 807: Routine Description: ! 808: ! 809: This routine is called by NDIS to indicate that an open adapter ! 810: is complete. Since we only ever have one outstanding, and then only ! 811: during initialization, all we do is record the status and set ! 812: the event to signalled to unblock the initialization thread. ! 813: ! 814: Arguments: ! 815: ! 816: BindingContext - Pointer to the device object for this driver. ! 817: ! 818: NdisStatus - The request completion code. ! 819: ! 820: OpenErrorStatus - More status information. ! 821: ! 822: Return Value: ! 823: ! 824: None. ! 825: ! 826: --*/ ! 827: ! 828: { ! 829: PDEVICE_CONTEXT DeviceContext = (PDEVICE_CONTEXT)BindingContext; ! 830: ! 831: DeviceContext->NdisRequestStatus = NdisStatus; ! 832: KeSetEvent( ! 833: &DeviceContext->NdisRequestEvent, ! 834: 0L, ! 835: FALSE); ! 836: ! 837: return; ! 838: } ! 839: ! 840: VOID ! 841: StCloseAdapterComplete ( ! 842: IN NDIS_HANDLE BindingContext, ! 843: IN NDIS_STATUS NdisStatus ! 844: ) ! 845: ! 846: /*++ ! 847: ! 848: Routine Description: ! 849: ! 850: This routine is called by NDIS to indicate that a close adapter ! 851: is complete. Currently we don't close adapters, so this is not ! 852: a problem. ! 853: ! 854: Arguments: ! 855: ! 856: BindingContext - Pointer to the device object for this driver. ! 857: ! 858: NdisStatus - The request completion code. ! 859: ! 860: Return Value: ! 861: ! 862: None. ! 863: ! 864: --*/ ! 865: ! 866: { ! 867: PDEVICE_CONTEXT DeviceContext = (PDEVICE_CONTEXT)BindingContext; ! 868: ! 869: DeviceContext->NdisRequestStatus = NdisStatus; ! 870: KeSetEvent( ! 871: &DeviceContext->NdisRequestEvent, ! 872: 0L, ! 873: FALSE); ! 874: ! 875: return; ! 876: } ! 877: ! 878: VOID ! 879: StResetComplete ( ! 880: IN NDIS_HANDLE BindingContext, ! 881: IN NDIS_STATUS NdisStatus ! 882: ) ! 883: ! 884: /*++ ! 885: ! 886: Routine Description: ! 887: ! 888: This routine is called by NDIS to indicate that a reset adapter ! 889: is complete. Currently we don't reset adapters, so this is not ! 890: a problem. ! 891: ! 892: Arguments: ! 893: ! 894: BindingContext - Pointer to the device object for this driver. ! 895: ! 896: NdisStatus - The request completion code. ! 897: ! 898: Return Value: ! 899: ! 900: None. ! 901: ! 902: --*/ ! 903: ! 904: { ! 905: UNREFERENCED_PARAMETER(BindingContext); ! 906: UNREFERENCED_PARAMETER(NdisStatus); ! 907: ! 908: return; ! 909: } ! 910: ! 911: VOID ! 912: StRequestComplete ( ! 913: IN NDIS_HANDLE BindingContext, ! 914: IN PNDIS_REQUEST NdisRequest, ! 915: IN NDIS_STATUS NdisStatus ! 916: ) ! 917: ! 918: /*++ ! 919: ! 920: Routine Description: ! 921: ! 922: This routine is called by NDIS to indicate that a request is complete. ! 923: Since we only ever have one request outstanding, and then only ! 924: during initialization, all we do is record the status and set ! 925: the event to signalled to unblock the initialization thread. ! 926: ! 927: Arguments: ! 928: ! 929: BindingContext - Pointer to the device object for this driver. ! 930: ! 931: NdisRequest - The object describing the request. ! 932: ! 933: NdisStatus - The request completion code. ! 934: ! 935: Return Value: ! 936: ! 937: None. ! 938: ! 939: --*/ ! 940: ! 941: { ! 942: PDEVICE_CONTEXT DeviceContext = (PDEVICE_CONTEXT)BindingContext; ! 943: ! 944: DeviceContext->NdisRequestStatus = NdisStatus; ! 945: KeSetEvent( ! 946: &DeviceContext->NdisRequestEvent, ! 947: 0L, ! 948: FALSE); ! 949: ! 950: return; ! 951: } ! 952: ! 953: VOID ! 954: StStatusIndication ( ! 955: IN NDIS_HANDLE NdisBindingContext, ! 956: IN NDIS_STATUS NdisStatus, ! 957: IN PVOID StatusBuffer, ! 958: IN UINT StatusBufferSize ! 959: ) ! 960: ! 961: { ! 962: PDEVICE_CONTEXT DeviceContext; ! 963: ! 964: DeviceContext = (PDEVICE_CONTEXT)NdisBindingContext; ! 965: ! 966: switch (NdisStatus) { ! 967: ! 968: // ! 969: // Handle various status codes here. ! 970: // ! 971: ! 972: default: ! 973: break; ! 974: ! 975: } ! 976: } ! 977: ! 978: ! 979: VOID ! 980: StStatusComplete ( ! 981: IN NDIS_HANDLE NdisBindingContext ! 982: ) ! 983: { ! 984: UNREFERENCED_PARAMETER (NdisBindingContext); ! 985: ! 986: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.