Annotation of ntddk/src/network/tdi/stndis.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.