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

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1989-1993  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     stdrvr.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This module contains code which defines the NT Sample
        !            12:     transport provider's device object.
        !            13: 
        !            14: Environment:
        !            15: 
        !            16:     Kernel mode
        !            17: 
        !            18: Revision History:
        !            19: 
        !            20: 
        !            21: --*/
        !            22: 
        !            23: #include "st.h"
        !            24: 
        !            25: 
        !            26: //
        !            27: // This is a list of all the device contexts that ST owns,
        !            28: // used while unloading.
        !            29: //
        !            30: 
        !            31: LIST_ENTRY StDeviceList = {0,0};   // initialized for real at runtime.
        !            32: 
        !            33: 
        !            34: 
        !            35: //
        !            36: // Forward declaration of various routines used in this module.
        !            37: //
        !            38: 
        !            39: NTSTATUS
        !            40: DriverEntry(
        !            41:     IN PDRIVER_OBJECT DriverObject,
        !            42:     IN PUNICODE_STRING RegistryPath
        !            43:     );
        !            44: 
        !            45: VOID
        !            46: StUnload(
        !            47:     IN PDRIVER_OBJECT DriverObject
        !            48:     );
        !            49: 
        !            50: NTSTATUS
        !            51: StConfigureTransport (
        !            52:     IN PUNICODE_STRING RegistryPath,
        !            53:     IN PCONFIG_DATA * ConfigData
        !            54:     );
        !            55: 
        !            56: VOID
        !            57: StFreeConfigurationInfo (
        !            58:     IN PCONFIG_DATA ConfigurationInfo
        !            59:     );
        !            60: 
        !            61: NTSTATUS
        !            62: StDeviceControl(
        !            63:     IN PDEVICE_OBJECT DeviceObject,
        !            64:     IN PIRP Irp,
        !            65:     IN PIO_STACK_LOCATION IrpSp
        !            66:     );
        !            67: 
        !            68: NTSTATUS
        !            69: StOpenAddress(
        !            70:     IN PDEVICE_OBJECT DeviceObject,
        !            71:     IN PIRP Irp,
        !            72:     IN PIO_STACK_LOCATION IrpSp
        !            73:     );
        !            74: 
        !            75: NTSTATUS
        !            76: StCloseAddress(
        !            77:     IN PDEVICE_OBJECT DeviceObject,
        !            78:     IN PIRP Irp,
        !            79:     IN PIO_STACK_LOCATION IrpSp
        !            80:     );
        !            81: 
        !            82: NTSTATUS
        !            83: StOpenConnection(
        !            84:     IN PDEVICE_OBJECT DeviceObject,
        !            85:     IN PIRP Irp,
        !            86:     IN PIO_STACK_LOCATION IrpSp
        !            87:     );
        !            88: 
        !            89: NTSTATUS
        !            90: StCloseConnection(
        !            91:     IN PDEVICE_OBJECT DeviceObject,
        !            92:     IN PIRP Irp,
        !            93:     IN PIO_STACK_LOCATION IrpSp
        !            94:     );
        !            95: 
        !            96: NTSTATUS
        !            97: StTdiAccept(
        !            98:     IN PIRP Irp
        !            99:     );
        !           100: 
        !           101: NTSTATUS
        !           102: StTdiConnect(
        !           103:     IN PIRP Irp
        !           104:     );
        !           105: 
        !           106: NTSTATUS
        !           107: StTdiDisconnect(
        !           108:     IN PIRP Irp
        !           109:     );
        !           110: 
        !           111: NTSTATUS
        !           112: StTdiDisassociateAddress (
        !           113:     IN PIRP Irp
        !           114:     );
        !           115: 
        !           116: NTSTATUS
        !           117: StTdiAssociateAddress(
        !           118:     IN PIRP Irp
        !           119:     );
        !           120: 
        !           121: NTSTATUS
        !           122: StTdiListen(
        !           123:     IN PIRP Irp
        !           124:     );
        !           125: 
        !           126: NTSTATUS
        !           127: StTdiQueryInformation(
        !           128:     IN PDEVICE_CONTEXT DeviceContext,
        !           129:     IN PIRP Irp
        !           130:     );
        !           131: 
        !           132: NTSTATUS
        !           133: StTdiReceive(
        !           134:     IN PIRP Irp
        !           135:     );
        !           136: 
        !           137: NTSTATUS
        !           138: StTdiReceiveDatagram(
        !           139:     IN PIRP Irp
        !           140:     );
        !           141: 
        !           142: NTSTATUS
        !           143: StTdiSend(
        !           144:     IN PIRP Irp
        !           145:     );
        !           146: 
        !           147: NTSTATUS
        !           148: StTdiSendDatagram(
        !           149:     IN PIRP Irp
        !           150:     );
        !           151: 
        !           152: NTSTATUS
        !           153: StTdiSetEventHandler(
        !           154:     IN PIRP Irp
        !           155:     );
        !           156: 
        !           157: NTSTATUS
        !           158: StTdiSetInformation(
        !           159:     IN PIRP Irp
        !           160:     );
        !           161: 
        !           162: VOID
        !           163: StDeallocateResources(
        !           164:     IN PDEVICE_CONTEXT DeviceContext
        !           165:     );
        !           166: 
        !           167: #ifdef ALLOC_PRAGMA
        !           168: #pragma alloc_text(init,DriverEntry)
        !           169: #endif
        !           170: 
        !           171: 
        !           172: 
        !           173: NTSTATUS
        !           174: DriverEntry(
        !           175:     IN PDRIVER_OBJECT DriverObject,
        !           176:     IN PUNICODE_STRING RegistryPath
        !           177:     )
        !           178: 
        !           179: /*++
        !           180: 
        !           181: Routine Description:
        !           182: 
        !           183:     This routine performs initialization of the sample
        !           184:     transport driver.  It creates the device objects for the transport
        !           185:     provider and performs other driver initialization.
        !           186: 
        !           187: Arguments:
        !           188: 
        !           189:     DriverObject - Pointer to driver object created by the system.
        !           190: 
        !           191:     RegistryPath - The name of ST's node in the registry.
        !           192: 
        !           193: Return Value:
        !           194: 
        !           195:     The function value is the final status from the initialization operation.
        !           196: 
        !           197: --*/
        !           198: 
        !           199: {
        !           200:     ULONG i, j;
        !           201:     STRING nameString;
        !           202:     PDEVICE_CONTEXT DeviceContext;
        !           203:     PTP_REQUEST Request;
        !           204:     PTP_CONNECTION Connection;
        !           205:     PTP_ADDRESS_FILE AddressFile;
        !           206:     PTP_ADDRESS Address;
        !           207:     PTP_PACKET Packet;
        !           208:     PNDIS_PACKET NdisPacket;
        !           209:     PRECEIVE_PACKET_TAG ReceiveTag;
        !           210:     PBUFFER_TAG BufferTag;
        !           211:     NTSTATUS status;
        !           212:     UINT SuccessfulOpens;
        !           213:     UINT MaxUserData;
        !           214: 
        !           215:     PCONFIG_DATA StConfig = NULL;
        !           216: 
        !           217: 
        !           218:     ASSERT (sizeof (SHORT) == 2);
        !           219: 
        !           220:     //
        !           221:     // This allocates the CONFIG_DATA structure and returns
        !           222:     // it in StConfig.
        !           223:     //
        !           224: 
        !           225:     status = StConfigureTransport(RegistryPath, &StConfig);
        !           226: 
        !           227:     if (!NT_SUCCESS (status)) {
        !           228:         PANIC (" Failed to initialize transport, St initialization failed.\n");
        !           229:         return STATUS_INSUFFICIENT_RESOURCES;
        !           230:     }
        !           231: 
        !           232:     //
        !           233:     // make ourselves known to the NDIS wrapper.
        !           234:     //
        !           235: 
        !           236:     RtlInitString( &nameString, ST_DEVICE_NAME );
        !           237: 
        !           238:     status = StRegisterProtocol (&nameString);
        !           239: 
        !           240:     if (!NT_SUCCESS (status)) {
        !           241: 
        !           242:         StFreeConfigurationInfo(StConfig);
        !           243:         PANIC ("StInitialize: RegisterProtocol failed!\n");
        !           244: 
        !           245:         StWriteGeneralErrorLog(
        !           246:             (PVOID)DriverObject,
        !           247:             EVENT_TRANSPORT_REGISTER_FAILED,
        !           248:             607,
        !           249:             status,
        !           250:             NULL,
        !           251:             0,
        !           252:             NULL);
        !           253: 
        !           254:         return STATUS_INSUFFICIENT_RESOURCES;
        !           255: 
        !           256:     }
        !           257: 
        !           258: 
        !           259:     //
        !           260:     // Initialize the driver object with this driver's entry points.
        !           261:     //
        !           262: 
        !           263:     DriverObject->MajorFunction [IRP_MJ_CREATE] = StDispatchOpenClose;
        !           264:     DriverObject->MajorFunction [IRP_MJ_CLOSE] = StDispatchOpenClose;
        !           265:     DriverObject->MajorFunction [IRP_MJ_CLEANUP] = StDispatchOpenClose;
        !           266:     DriverObject->MajorFunction [IRP_MJ_INTERNAL_DEVICE_CONTROL] = StDispatchInternal;
        !           267:     DriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL] = StDispatch;
        !           268: 
        !           269:     DriverObject->DriverUnload = StUnload;
        !           270: 
        !           271:     //
        !           272:     // Initialize the global list of devices.
        !           273:     //
        !           274: 
        !           275:     InitializeListHead (&StDeviceList);
        !           276: 
        !           277:     SuccessfulOpens = 0;
        !           278: 
        !           279:     for (j=0;j<StConfig->NumAdapters;j++ ) {
        !           280: 
        !           281: 
        !           282:         //
        !           283:         // Loop through all the adapters that are in the configuration
        !           284:         // information structure. Allocate a device object for each
        !           285:         // one that we find.
        !           286:         //
        !           287: 
        !           288:         status = StCreateDeviceContext (DriverObject, &StConfig->Names[StConfig->DevicesOffset+j], &DeviceContext);
        !           289: 
        !           290:         if (!NT_SUCCESS (status)) {
        !           291:             continue;
        !           292:         }
        !           293: 
        !           294:         //
        !           295:         // Initialize our counter that records memory usage.
        !           296:         //
        !           297: 
        !           298:         DeviceContext->MemoryUsage = 0;
        !           299:         DeviceContext->MemoryLimit = StConfig->MaxMemoryUsage;
        !           300: 
        !           301:         //
        !           302:         // Now fire up NDIS so this adapter talks
        !           303:         //
        !           304: 
        !           305:         status = StInitializeNdis (DeviceContext,
        !           306:                     StConfig,
        !           307:                     j);
        !           308: 
        !           309:         if (!NT_SUCCESS (status)) {
        !           310: 
        !           311:             //
        !           312:             // Log an error.
        !           313:             //
        !           314: 
        !           315:             StWriteGeneralErrorLog(
        !           316:                 DeviceContext,
        !           317:                 EVENT_TRANSPORT_BINDING_FAILED,
        !           318:                 601,
        !           319:                 status,
        !           320:                 StConfig->Names[j].Buffer,
        !           321:                 0,
        !           322:                 NULL);
        !           323: 
        !           324:             StDereferenceDeviceContext ("Initialize NDIS failed", DeviceContext);
        !           325:             continue;
        !           326: 
        !           327:         }
        !           328: 
        !           329: 
        !           330:         //
        !           331:         // Initialize our provider information structure; since it
        !           332:         // doesn't change, we just keep it around and copy it to
        !           333:         // whoever requests it.
        !           334:         //
        !           335: 
        !           336: 
        !           337:         MacReturnMaxDataSize(
        !           338:             &DeviceContext->MacInfo,
        !           339:             NULL,
        !           340:             0,
        !           341:             DeviceContext->MaxSendPacketSize,
        !           342:             &MaxUserData);
        !           343: 
        !           344:         DeviceContext->Information.Version = 0x0100;
        !           345:         DeviceContext->Information.MaxSendSize = 0x1fffe;   // 128k - 2
        !           346:         DeviceContext->Information.MaxConnectionUserData = 0;
        !           347:         DeviceContext->Information.MaxDatagramSize = MaxUserData - sizeof(ST_HEADER);
        !           348:         DeviceContext->Information.ServiceFlags = ST_SERVICE_FLAGS;
        !           349:         DeviceContext->Information.MinimumLookaheadData = 128;
        !           350:         DeviceContext->Information.MaximumLookaheadData =
        !           351:             DeviceContext->MaxReceivePacketSize - sizeof(ST_HEADER);
        !           352:         DeviceContext->Information.NumberOfResources = ST_TDI_RESOURCES;
        !           353:         KeQuerySystemTime (&DeviceContext->Information.StartTime);
        !           354: 
        !           355: 
        !           356:         //
        !           357:         // Allocate various structures we will need.
        !           358:         //
        !           359: 
        !           360: 
        !           361:         //
        !           362:         // The TP_PACKET structure has a CHAR[1] field at the end
        !           363:         // which we expand upon to include all the headers needed;
        !           364:         // the size of the MAC header depends on what the adapter
        !           365:         // told us about its max header size.
        !           366:         //
        !           367: 
        !           368:         DeviceContext->PacketHeaderLength =
        !           369:             DeviceContext->MacInfo.MaxHeaderLength +
        !           370:             sizeof (ST_HEADER);
        !           371: 
        !           372:         DeviceContext->PacketLength =
        !           373:             FIELD_OFFSET(TP_PACKET, Header[0]) +
        !           374:             DeviceContext->PacketHeaderLength;
        !           375: 
        !           376: 
        !           377:         //
        !           378:         // The BUFFER_TAG structure has a CHAR[1] field at the end
        !           379:         // which we expand upong to include all the frame data.
        !           380:         //
        !           381: 
        !           382:         DeviceContext->ReceiveBufferLength =
        !           383:             DeviceContext->MaxReceivePacketSize +
        !           384:             FIELD_OFFSET(BUFFER_TAG, Buffer[0]);
        !           385: 
        !           386: 
        !           387:         for (i=0; i<StConfig->InitRequests; i++) {
        !           388: 
        !           389:             StAllocateRequest (DeviceContext, &Request);
        !           390: 
        !           391:             if (Request == NULL) {
        !           392:                 PANIC ("StInitialize:  insufficient memory to allocate requests.\n");
        !           393:                 status = STATUS_INSUFFICIENT_RESOURCES;
        !           394:                 goto cleanup;
        !           395:             }
        !           396: 
        !           397:             InsertTailList (&DeviceContext->RequestPool, &Request->Linkage);
        !           398:         }
        !           399: 
        !           400:         DeviceContext->RequestInitAllocated = StConfig->InitRequests;
        !           401:         DeviceContext->RequestMaxAllocated = StConfig->MaxRequests;
        !           402: 
        !           403: 
        !           404:         for (i=0; i<StConfig->InitConnections; i++) {
        !           405: 
        !           406:             StAllocateConnection (DeviceContext, &Connection);
        !           407: 
        !           408:             if (Connection == NULL) {
        !           409:                 PANIC ("StInitialize:  insufficient memory to allocate connections.\n");
        !           410:                 status = STATUS_INSUFFICIENT_RESOURCES;
        !           411:                 goto cleanup;
        !           412:             }
        !           413: 
        !           414:             InsertTailList (&DeviceContext->ConnectionPool, &Connection->LinkList);
        !           415:         }
        !           416: 
        !           417:         DeviceContext->ConnectionInitAllocated = StConfig->InitConnections;
        !           418:         DeviceContext->ConnectionMaxAllocated = StConfig->MaxConnections;
        !           419: 
        !           420: 
        !           421:         for (i=0; i<StConfig->InitAddressFiles; i++) {
        !           422: 
        !           423:             StAllocateAddressFile (DeviceContext, &AddressFile);
        !           424: 
        !           425:             if (AddressFile == NULL) {
        !           426:                 PANIC ("StInitialize:  insufficient memory to allocate Address Files.\n");
        !           427:                 status = STATUS_INSUFFICIENT_RESOURCES;
        !           428:                 goto cleanup;
        !           429:             }
        !           430: 
        !           431:             InsertTailList (&DeviceContext->AddressFilePool, &AddressFile->Linkage);
        !           432:         }
        !           433: 
        !           434:         DeviceContext->AddressFileInitAllocated = StConfig->InitAddressFiles;
        !           435:         DeviceContext->AddressFileMaxAllocated = StConfig->MaxAddressFiles;
        !           436: 
        !           437: 
        !           438:         for (i=0; i<StConfig->InitAddresses; i++) {
        !           439: 
        !           440:             StAllocateAddress (DeviceContext, &Address);
        !           441:             if (Address == NULL) {
        !           442:                 PANIC ("StInitialize:  insufficient memory to allocate addresses.\n");
        !           443:                 status = STATUS_INSUFFICIENT_RESOURCES;
        !           444:                 goto cleanup;
        !           445:             }
        !           446: 
        !           447:             InsertTailList (&DeviceContext->AddressPool, &Address->Linkage);
        !           448:         }
        !           449: 
        !           450:         DeviceContext->AddressInitAllocated = StConfig->InitAddresses;
        !           451:         DeviceContext->AddressMaxAllocated = StConfig->MaxAddresses;
        !           452: 
        !           453: 
        !           454:         for (i=0; i<StConfig->InitPackets; i++) {
        !           455: 
        !           456:             StAllocateSendPacket (DeviceContext, &Packet);
        !           457:             if (Packet == NULL) {
        !           458:                 PANIC ("StInitialize:  insufficient memory to allocate packets.\n");
        !           459:                 status = STATUS_INSUFFICIENT_RESOURCES;
        !           460:                 goto cleanup;
        !           461:             }
        !           462: 
        !           463:             PushEntryList (&DeviceContext->PacketPool, (PSINGLE_LIST_ENTRY)&Packet->Linkage);
        !           464:         }
        !           465: 
        !           466:         DeviceContext->PacketInitAllocated = StConfig->InitPackets;
        !           467: 
        !           468: 
        !           469:         for (i=0; i<StConfig->InitReceivePackets; i++) {
        !           470: 
        !           471:             StAllocateReceivePacket (DeviceContext, &NdisPacket);
        !           472: 
        !           473:             if (NdisPacket == NULL) {
        !           474:                 PANIC ("StInitialize:  insufficient memory to allocate packet MDLs.\n");
        !           475:                 status = STATUS_INSUFFICIENT_RESOURCES;
        !           476:                 goto cleanup;
        !           477:             }
        !           478: 
        !           479:             ReceiveTag = (PRECEIVE_PACKET_TAG)NdisPacket->ProtocolReserved;
        !           480:             PushEntryList (&DeviceContext->ReceivePacketPool, (PSINGLE_LIST_ENTRY)&ReceiveTag->Linkage);
        !           481: 
        !           482:         }
        !           483: 
        !           484:         DeviceContext->ReceivePacketInitAllocated = StConfig->InitReceivePackets;
        !           485: 
        !           486: 
        !           487:         for (i=0; i<StConfig->InitReceiveBuffers; i++) {
        !           488: 
        !           489:             StAllocateReceiveBuffer (DeviceContext, &BufferTag);
        !           490: 
        !           491:             if (BufferTag == NULL) {
        !           492:                 PANIC ("StInitialize: Unable to allocate receive packet.\n");
        !           493:                 status = STATUS_INSUFFICIENT_RESOURCES;
        !           494:                 goto cleanup;
        !           495:             }
        !           496: 
        !           497:             PushEntryList (&DeviceContext->ReceiveBufferPool, &BufferTag->Linkage);
        !           498: 
        !           499:         }
        !           500: 
        !           501:         DeviceContext->ReceiveBufferInitAllocated = StConfig->InitReceiveBuffers;
        !           502: 
        !           503: 
        !           504:         //
        !           505:         // Now link the device into the global list.
        !           506:         //
        !           507: 
        !           508:         InsertTailList (&StDeviceList, &DeviceContext->Linkage);
        !           509: 
        !           510:         DeviceContext->State = DEVICECONTEXT_STATE_OPEN;
        !           511: 
        !           512:         ++SuccessfulOpens;
        !           513: 
        !           514:         continue;
        !           515: 
        !           516: cleanup:
        !           517: 
        !           518:         StWriteResourceErrorLog (DeviceContext, DeviceContext->MemoryUsage, 501);
        !           519: 
        !           520:         //
        !           521:         // Cleanup whatever device context we were initializing
        !           522:         // when we failed.
        !           523:         //
        !           524: 
        !           525:         StFreeResources (DeviceContext);
        !           526:         StCloseNdis (DeviceContext);
        !           527:         StDereferenceDeviceContext ("Load failed", DeviceContext);
        !           528: 
        !           529:     }
        !           530: 
        !           531:     StFreeConfigurationInfo(StConfig);
        !           532: 
        !           533:     return ((SuccessfulOpens > 0) ? STATUS_SUCCESS : STATUS_DEVICE_DOES_NOT_EXIST);
        !           534: 
        !           535: }
        !           536: 
        !           537: VOID
        !           538: StUnload(
        !           539:     IN PDRIVER_OBJECT DriverObject
        !           540:     )
        !           541: 
        !           542: /*++
        !           543: 
        !           544: Routine Description:
        !           545: 
        !           546:     This routine unloads the sample transport driver.
        !           547:     It unbinds from any NDIS drivers that are open and frees all resources
        !           548:     associated with the transport. The I/O system will not call us until
        !           549:     nobody above has ST open.
        !           550: 
        !           551: Arguments:
        !           552: 
        !           553:     DriverObject - Pointer to driver object created by the system.
        !           554: 
        !           555: Return Value:
        !           556: 
        !           557:     None. When the function returns, the driver is unloaded.
        !           558: 
        !           559: --*/
        !           560: 
        !           561: {
        !           562: 
        !           563:     PDEVICE_CONTEXT DeviceContext;
        !           564:     PLIST_ENTRY p;
        !           565: 
        !           566: 
        !           567:     UNREFERENCED_PARAMETER (DriverObject);
        !           568: 
        !           569:     //
        !           570:     // Walk the list of device contexts.
        !           571:     //
        !           572: 
        !           573:     while (!IsListEmpty (&StDeviceList)) {
        !           574: 
        !           575:         p = RemoveHeadList (&StDeviceList);
        !           576:         DeviceContext = CONTAINING_RECORD (p, DEVICE_CONTEXT, Linkage);
        !           577: 
        !           578:         //
        !           579:         // Remove all the storage associated with the device.
        !           580:         //
        !           581: 
        !           582:         StFreeResources (DeviceContext);
        !           583: 
        !           584:         //
        !           585:         // Free the packet pools, etc. and close the
        !           586:         // adapter.
        !           587:         //
        !           588: 
        !           589:         StCloseNdis (DeviceContext);
        !           590: 
        !           591:         //
        !           592:         // And remove the creation reference from the device
        !           593:         // context.
        !           594:         //
        !           595: 
        !           596:         StDereferenceDeviceContext ("Unload", DeviceContext);
        !           597: 
        !           598:     }
        !           599: 
        !           600: 
        !           601:     //
        !           602:     // Finally, remove ourselves as an NDIS protocol.
        !           603:     //
        !           604: 
        !           605:     StDeregisterProtocol();
        !           606: 
        !           607:     return;
        !           608: 
        !           609: }
        !           610: 
        !           611: 
        !           612: VOID
        !           613: StFreeResources (
        !           614:     IN PDEVICE_CONTEXT DeviceContext
        !           615:     )
        !           616: /*++
        !           617: 
        !           618: Routine Description:
        !           619: 
        !           620:     This routine is called by ST to clean up the data structures associated
        !           621:     with a given DeviceContext. When this routine exits, the DeviceContext
        !           622:     should be deleted as it no longer has any assocaited resources.
        !           623: 
        !           624: Arguments:
        !           625: 
        !           626:     DeviceContext - Pointer to the DeviceContext we wish to clean up.
        !           627: 
        !           628: Return Value:
        !           629: 
        !           630:     None.
        !           631: 
        !           632: --*/
        !           633: {
        !           634:     PLIST_ENTRY p;
        !           635:     PSINGLE_LIST_ENTRY s;
        !           636:     PTP_PACKET packet;
        !           637:     PTP_ADDRESS address;
        !           638:     PTP_CONNECTION connection;
        !           639:     PTP_REQUEST request;
        !           640:     PTP_ADDRESS_FILE addressFile;
        !           641:     PNDIS_PACKET ndisPacket;
        !           642:     PBUFFER_TAG BufferTag;
        !           643: 
        !           644: 
        !           645:     //
        !           646:     // Clean up packet pool.
        !           647:     //
        !           648: 
        !           649:     while ( DeviceContext->PacketPool.Next != NULL ) {
        !           650:         s = PopEntryList( &DeviceContext->PacketPool );
        !           651:         packet = CONTAINING_RECORD( s, TP_PACKET, Linkage );
        !           652: 
        !           653:         StDeallocateSendPacket (DeviceContext, packet);
        !           654:     }
        !           655: 
        !           656:     //
        !           657:     // Clean up address pool.
        !           658:     //
        !           659: 
        !           660:     while ( !IsListEmpty (&DeviceContext->AddressPool) ) {
        !           661:         p = RemoveHeadList (&DeviceContext->AddressPool);
        !           662:         address = CONTAINING_RECORD (p, TP_ADDRESS, Linkage);
        !           663: 
        !           664:         StDeallocateAddress (DeviceContext, address);
        !           665:     }
        !           666: 
        !           667:     //
        !           668:     // Clean up address file pool.
        !           669:     //
        !           670: 
        !           671:     while ( !IsListEmpty (&DeviceContext->AddressFilePool) ) {
        !           672:         p = RemoveHeadList (&DeviceContext->AddressFilePool);
        !           673:         addressFile = CONTAINING_RECORD (p, TP_ADDRESS_FILE, Linkage);
        !           674: 
        !           675:         StDeallocateAddressFile (DeviceContext, addressFile);
        !           676:     }
        !           677: 
        !           678:     //
        !           679:     // Clean up connection pool.
        !           680:     //
        !           681: 
        !           682:     while ( !IsListEmpty (&DeviceContext->ConnectionPool) ) {
        !           683:         p  = RemoveHeadList (&DeviceContext->ConnectionPool);
        !           684:         connection = CONTAINING_RECORD (p, TP_CONNECTION, LinkList);
        !           685: 
        !           686:         StDeallocateConnection (DeviceContext, connection);
        !           687:     }
        !           688: 
        !           689:     //
        !           690:     // Clean up request pool.
        !           691:     //
        !           692: 
        !           693:     while ( !IsListEmpty( &DeviceContext->RequestPool ) ) {
        !           694:         p = RemoveHeadList( &DeviceContext->RequestPool );
        !           695:         request = CONTAINING_RECORD (p, TP_REQUEST, Linkage );
        !           696: 
        !           697:         StDeallocateRequest (DeviceContext, request);
        !           698:     }
        !           699: 
        !           700:     //
        !           701:     // Clean up receive packet pool
        !           702:     //
        !           703: 
        !           704:     while ( DeviceContext->ReceivePacketPool.Next != NULL) {
        !           705:         s = PopEntryList (&DeviceContext->ReceivePacketPool);
        !           706: 
        !           707:         //
        !           708:         // HACK: This works because Linkage is the first field in
        !           709:         // ProtocolReserved for a receive packet.
        !           710:         //
        !           711: 
        !           712:         ndisPacket = CONTAINING_RECORD (s, NDIS_PACKET, ProtocolReserved[0]);
        !           713: 
        !           714:         StDeallocateReceivePacket (DeviceContext, ndisPacket);
        !           715:     }
        !           716: 
        !           717: 
        !           718:     //
        !           719:     // Clean up receive buffer pool.
        !           720:     //
        !           721: 
        !           722:     while ( DeviceContext->ReceiveBufferPool.Next != NULL ) {
        !           723:         s = PopEntryList( &DeviceContext->ReceiveBufferPool );
        !           724:         BufferTag = CONTAINING_RECORD (s, BUFFER_TAG, Linkage );
        !           725: 
        !           726:         StDeallocateReceiveBuffer (DeviceContext, BufferTag);
        !           727:     }
        !           728: 
        !           729: 
        !           730:     return;
        !           731: 
        !           732: }   /* StFreeResources */
        !           733: 
        !           734: 
        !           735: NTSTATUS
        !           736: StDispatch(
        !           737:     IN PDEVICE_OBJECT DeviceObject,
        !           738:     IN PIRP Irp
        !           739:     )
        !           740: 
        !           741: /*++
        !           742: 
        !           743: Routine Description:
        !           744: 
        !           745:     This routine is the main dispatch routine for the ST device driver.
        !           746:     It accepts an I/O Request Packet, performs the request, and then
        !           747:     returns with the appropriate status.
        !           748: 
        !           749: Arguments:
        !           750: 
        !           751:     DeviceObject - Pointer to the device object for this driver.
        !           752: 
        !           753:     Irp - Pointer to the request packet representing the I/O request.
        !           754: 
        !           755: Return Value:
        !           756: 
        !           757:     The function value is the status of the operation.
        !           758: 
        !           759: --*/
        !           760: 
        !           761: {
        !           762:     NTSTATUS Status;
        !           763:     PIO_STACK_LOCATION IrpSp;
        !           764:     PDEVICE_CONTEXT DeviceContext;
        !           765: 
        !           766:     //
        !           767:     // Check to see if ST has been initialized; if not, don't allow any use.
        !           768:     // Note that this only covers any user mode code use; kernel TDI clients
        !           769:     // will fail on their creation of an endpoint.
        !           770:     //
        !           771: 
        !           772:     DeviceContext = (PDEVICE_CONTEXT)DeviceObject;
        !           773:     if (DeviceContext->State != DEVICECONTEXT_STATE_OPEN) {
        !           774:         Irp->IoStatus.Status = STATUS_INVALID_DEVICE_STATE;
        !           775:         IoCompleteRequest (Irp, IO_NETWORK_INCREMENT);
        !           776:         return STATUS_INVALID_DEVICE_STATE;
        !           777:     }
        !           778: 
        !           779:     //
        !           780:     // Make sure status information is consistent every time.
        !           781:     //
        !           782: 
        !           783:     IoMarkIrpPending (Irp);
        !           784:     Irp->IoStatus.Status = STATUS_PENDING;
        !           785:     Irp->IoStatus.Information = 0;
        !           786: 
        !           787:     //
        !           788:     // Get a pointer to the current stack location in the IRP.  This is where
        !           789:     // the function codes and parameters are stored.
        !           790:     //
        !           791: 
        !           792:     IrpSp = IoGetCurrentIrpStackLocation (Irp);
        !           793: 
        !           794:     //
        !           795:     // Case on the function that is being performed by the requestor.  If the
        !           796:     // operation is a valid one for this device, then make it look like it was
        !           797:     // successfully completed, where possible.
        !           798:     //
        !           799: 
        !           800: 
        !           801:     switch (IrpSp->MajorFunction) {
        !           802: 
        !           803:         case IRP_MJ_DEVICE_CONTROL:
        !           804:             Status = StDeviceControl (DeviceObject, Irp, IrpSp);
        !           805:             break;
        !           806: 
        !           807:         default:
        !           808:             Status = STATUS_INVALID_DEVICE_REQUEST;
        !           809: 
        !           810:     } /* major function switch */
        !           811: 
        !           812:     if (Status != STATUS_PENDING) {
        !           813:         IrpSp->Control &= ~SL_PENDING_RETURNED;
        !           814:         Irp->IoStatus.Status = Status;
        !           815:         IoCompleteRequest (Irp, IO_NETWORK_INCREMENT);
        !           816:     }
        !           817: 
        !           818:     //
        !           819:     // Return the immediate status code to the caller.
        !           820:     //
        !           821: 
        !           822:     return Status;
        !           823: } /* StDispatch */
        !           824: 
        !           825: 
        !           826: NTSTATUS
        !           827: StDispatchOpenClose(
        !           828:     IN PDEVICE_OBJECT DeviceObject,
        !           829:     IN PIRP Irp
        !           830:     )
        !           831: 
        !           832: /*++
        !           833: 
        !           834: Routine Description:
        !           835: 
        !           836:     This routine is the main dispatch routine for the ST device driver.
        !           837:     It accepts an I/O Request Packet, performs the request, and then
        !           838:     returns with the appropriate status.
        !           839: 
        !           840: Arguments:
        !           841: 
        !           842:     DeviceObject - Pointer to the device object for this driver.
        !           843: 
        !           844:     Irp - Pointer to the request packet representing the I/O request.
        !           845: 
        !           846: Return Value:
        !           847: 
        !           848:     The function value is the status of the operation.
        !           849: 
        !           850: --*/
        !           851: 
        !           852: {
        !           853:     KIRQL oldirql;
        !           854:     PDEVICE_CONTEXT DeviceContext;
        !           855:     NTSTATUS Status;
        !           856:     PIO_STACK_LOCATION IrpSp;
        !           857:     PFILE_FULL_EA_INFORMATION openType;
        !           858:     USHORT i;
        !           859:     BOOLEAN found;
        !           860:     PTP_ADDRESS_FILE AddressFile;
        !           861:     PTP_CONNECTION Connection;
        !           862: 
        !           863:     //
        !           864:     // Check to see if ST has been initialized; if not, don't allow any use.
        !           865:     // Note that this only covers any user mode code use; kernel TDI clients
        !           866:     // will fail on their creation of an endpoint.
        !           867:     //
        !           868: 
        !           869:     DeviceContext = (PDEVICE_CONTEXT)DeviceObject;
        !           870:     if (DeviceContext->State != DEVICECONTEXT_STATE_OPEN) {
        !           871:         Irp->IoStatus.Status = STATUS_INVALID_DEVICE_STATE;
        !           872:         IoCompleteRequest (Irp, IO_NETWORK_INCREMENT);
        !           873:         return STATUS_INVALID_DEVICE_STATE;
        !           874:     }
        !           875: 
        !           876:     //
        !           877:     // Make sure status information is consistent every time.
        !           878:     //
        !           879: 
        !           880:     IoMarkIrpPending (Irp);
        !           881:     Irp->IoStatus.Status = STATUS_PENDING;
        !           882:     Irp->IoStatus.Information = 0;
        !           883: 
        !           884:     //
        !           885:     // Get a pointer to the current stack location in the IRP.  This is where
        !           886:     // the function codes and parameters are stored.
        !           887:     //
        !           888: 
        !           889:     IrpSp = IoGetCurrentIrpStackLocation (Irp);
        !           890: 
        !           891:     //
        !           892:     // Case on the function that is being performed by the requestor.  If the
        !           893:     // operation is a valid one for this device, then make it look like it was
        !           894:     // successfully completed, where possible.
        !           895:     //
        !           896: 
        !           897: 
        !           898:     switch (IrpSp->MajorFunction) {
        !           899: 
        !           900:     //
        !           901:     // The Create function opens a transport object (either address or
        !           902:     // connection).  Access checking is performed on the specified
        !           903:     // address to ensure security of transport-layer addresses.
        !           904:     //
        !           905: 
        !           906:     case IRP_MJ_CREATE:
        !           907: 
        !           908:         openType =
        !           909:             (PFILE_FULL_EA_INFORMATION)Irp->AssociatedIrp.SystemBuffer;
        !           910: 
        !           911:         if (openType != NULL) {
        !           912: 
        !           913:             found = TRUE;
        !           914: 
        !           915:             for (i=0;i<(USHORT)openType->EaNameLength;i++) {
        !           916:                 if (openType->EaName[i] == TdiTransportAddress[i]) {
        !           917:                     continue;
        !           918:                 } else {
        !           919:                     found = FALSE;
        !           920:                     break;
        !           921:                 }
        !           922:             }
        !           923: 
        !           924:             if (found) {
        !           925:                 Status = StOpenAddress (DeviceObject, Irp, IrpSp);
        !           926:                 break;
        !           927:             }
        !           928: 
        !           929:             //
        !           930:             // Connection?
        !           931:             //
        !           932: 
        !           933:             found = TRUE;
        !           934: 
        !           935:             for (i=0;i<(USHORT)openType->EaNameLength;i++) {
        !           936:                 if (openType->EaName[i] == TdiConnectionContext[i]) {
        !           937:                      continue;
        !           938:                 } else {
        !           939:                     found = FALSE;
        !           940:                     break;
        !           941:                 }
        !           942:             }
        !           943: 
        !           944:             if (found) {
        !           945:                 Status = StOpenConnection (DeviceObject, Irp, IrpSp);
        !           946:                 break;
        !           947:             }
        !           948: 
        !           949:         } else {
        !           950: 
        !           951:             ACQUIRE_SPIN_LOCK (&DeviceContext->SpinLock, &oldirql);
        !           952: 
        !           953:             IrpSp->FileObject->FsContext = (PVOID)(DeviceContext->ControlChannelIdentifier);
        !           954:             ++DeviceContext->ControlChannelIdentifier;
        !           955:             if (DeviceContext->ControlChannelIdentifier == 0) {
        !           956:                 DeviceContext->ControlChannelIdentifier = 1;
        !           957:             }
        !           958: 
        !           959:             RELEASE_SPIN_LOCK (&DeviceContext->SpinLock, oldirql);
        !           960: 
        !           961:             IrpSp->FileObject->FsContext2 = (PVOID)ST_FILE_TYPE_CONTROL;
        !           962:             Status = STATUS_SUCCESS;
        !           963:         }
        !           964: 
        !           965:         break;
        !           966: 
        !           967:     case IRP_MJ_CLOSE:
        !           968: 
        !           969:         //
        !           970:         // The Close function closes a transport endpoint, terminates
        !           971:         // all outstanding transport activity on the endpoint, and unbinds
        !           972:         // the endpoint from its transport address, if any.  If this
        !           973:         // is the last transport endpoint bound to the address, then
        !           974:         // the address is removed from the provider.
        !           975:         //
        !           976: 
        !           977:         switch ((ULONG)IrpSp->FileObject->FsContext2) {
        !           978:         case TDI_TRANSPORT_ADDRESS_FILE:
        !           979:             AddressFile = (PTP_ADDRESS_FILE)IrpSp->FileObject->FsContext;
        !           980: 
        !           981:             //
        !           982:             // This creates a reference to AddressFile->Address
        !           983:             // which is removed by StCloseAddress.
        !           984:             //
        !           985: 
        !           986:             Status = StVerifyAddressObject(AddressFile);
        !           987: 
        !           988:             if (!NT_SUCCESS (Status)) {
        !           989:                 Status = STATUS_INVALID_HANDLE;
        !           990:             } else {
        !           991:                 Status = StCloseAddress (DeviceObject, Irp, IrpSp);
        !           992:             }
        !           993: 
        !           994:             break;
        !           995: 
        !           996:         case TDI_CONNECTION_FILE:
        !           997: 
        !           998:             //
        !           999:             // This is a connection
        !          1000:             //
        !          1001: 
        !          1002:             Connection = (PTP_CONNECTION)IrpSp->FileObject->FsContext;
        !          1003:             Status = StVerifyConnectionObject (Connection);
        !          1004:             if (NT_SUCCESS (Status)) {
        !          1005: 
        !          1006:                 Status = StCloseConnection (DeviceObject, Irp, IrpSp);
        !          1007:                 StDereferenceConnection ("Temporary Use",Connection);
        !          1008: 
        !          1009:             }
        !          1010: 
        !          1011:             break;
        !          1012: 
        !          1013:         case ST_FILE_TYPE_CONTROL:
        !          1014: 
        !          1015:             //
        !          1016:             // this always succeeds
        !          1017:             //
        !          1018: 
        !          1019:             Status = STATUS_SUCCESS;
        !          1020:             break;
        !          1021: 
        !          1022:         default:
        !          1023:             Status = STATUS_INVALID_HANDLE;
        !          1024:         }
        !          1025: 
        !          1026:         break;
        !          1027: 
        !          1028:     case IRP_MJ_CLEANUP:
        !          1029: 
        !          1030:         //
        !          1031:         // Handle the two stage IRP for a file close operation. When the first
        !          1032:         // stage hits, run down all activity on the object of interest. This
        !          1033:         // do everything to it but remove the creation hold. Then, when the
        !          1034:         // CLOSE irp hits, actually close the object.
        !          1035:         //
        !          1036: 
        !          1037:         switch ((ULONG)IrpSp->FileObject->FsContext2) {
        !          1038:         case TDI_TRANSPORT_ADDRESS_FILE:
        !          1039:             AddressFile = (PTP_ADDRESS_FILE)IrpSp->FileObject->FsContext;
        !          1040:             Status = StVerifyAddressObject(AddressFile);
        !          1041:             if (!NT_SUCCESS (Status)) {
        !          1042: 
        !          1043:                 Status = STATUS_INVALID_HANDLE;
        !          1044: 
        !          1045:             } else {
        !          1046: 
        !          1047:                 StStopAddressFile (AddressFile, AddressFile->Address);
        !          1048:                 StDereferenceAddress ("IRP_MJ_CLEANUP", AddressFile->Address);
        !          1049:                 Status = STATUS_SUCCESS;
        !          1050:             }
        !          1051: 
        !          1052:             break;
        !          1053: 
        !          1054:         case TDI_CONNECTION_FILE:
        !          1055: 
        !          1056:             Connection = (PTP_CONNECTION)IrpSp->FileObject->FsContext;
        !          1057:             Status = StVerifyConnectionObject (Connection);
        !          1058:             if (NT_SUCCESS (Status)) {
        !          1059:                 StStopConnection (Connection, STATUS_LOCAL_DISCONNECT);
        !          1060:                 Status = STATUS_SUCCESS;
        !          1061:                 StDereferenceConnection ("Temporary Use",Connection);
        !          1062:             }
        !          1063: 
        !          1064:             break;
        !          1065: 
        !          1066:         case ST_FILE_TYPE_CONTROL:
        !          1067: 
        !          1068:             Status = STATUS_SUCCESS;
        !          1069:             break;
        !          1070: 
        !          1071:         default:
        !          1072:             Status = STATUS_INVALID_HANDLE;
        !          1073:         }
        !          1074: 
        !          1075:         break;
        !          1076: 
        !          1077:     default:
        !          1078:         Status = STATUS_INVALID_DEVICE_REQUEST;
        !          1079: 
        !          1080:     } /* major function switch */
        !          1081: 
        !          1082:     if (Status != STATUS_PENDING) {
        !          1083:         IrpSp->Control &= ~SL_PENDING_RETURNED;
        !          1084:         Irp->IoStatus.Status = Status;
        !          1085:         IoCompleteRequest (Irp, IO_NETWORK_INCREMENT);
        !          1086:     }
        !          1087: 
        !          1088: 
        !          1089:     //
        !          1090:     // Return the immediate status code to the caller.
        !          1091:     //
        !          1092: 
        !          1093:     return Status;
        !          1094: } /* StDispatchOpenClose */
        !          1095: 
        !          1096: 
        !          1097: NTSTATUS
        !          1098: StDeviceControl(
        !          1099:     IN PDEVICE_OBJECT DeviceObject,
        !          1100:     IN PIRP Irp,
        !          1101:     IN PIO_STACK_LOCATION IrpSp
        !          1102:     )
        !          1103: 
        !          1104: /*++
        !          1105: 
        !          1106: Routine Description:
        !          1107: 
        !          1108:     This routine dispatches TDI request types to different handlers based
        !          1109:     on the minor IOCTL function code in the IRP's current stack location.
        !          1110:     In addition to cracking the minor function code, this routine also
        !          1111:     reaches into the IRP and passes the packetized parameters stored there
        !          1112:     as parameters to the various TDI request handlers so that they are
        !          1113:     not IRP-dependent.
        !          1114: 
        !          1115: Arguments:
        !          1116: 
        !          1117:     DeviceObject - Pointer to the device object for this driver.
        !          1118: 
        !          1119:     Irp - Pointer to the request packet representing the I/O request.
        !          1120: 
        !          1121:     IrpSp - Pointer to current IRP stack frame.
        !          1122: 
        !          1123: Return Value:
        !          1124: 
        !          1125:     The function value is the status of the operation.
        !          1126: 
        !          1127: --*/
        !          1128: 
        !          1129: {
        !          1130:     NTSTATUS Status;
        !          1131:     PDEVICE_CONTEXT DeviceContext = (PDEVICE_CONTEXT)DeviceObject;
        !          1132: 
        !          1133: 
        !          1134:     //
        !          1135:     // Branch to the appropriate request handler.  Preliminary checking of
        !          1136:     // the size of the request block is performed here so that it is known
        !          1137:     // in the handlers that the minimum input parameters are readable.  It
        !          1138:     // is *not* determined here whether variable length input fields are
        !          1139:     // passed correctly; this is a check which must be made within each routine.
        !          1140:     //
        !          1141: 
        !          1142:     switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
        !          1143: 
        !          1144:         default:
        !          1145: 
        !          1146:             //
        !          1147:             // Convert the user call to the proper internal device call.
        !          1148:             //
        !          1149: 
        !          1150:             Status = TdiMapUserRequest (DeviceObject, Irp, IrpSp);
        !          1151: 
        !          1152:             if (Status == STATUS_SUCCESS) {
        !          1153: 
        !          1154:                 //
        !          1155:                 // If TdiMapUserRequest returns SUCCESS then the IRP
        !          1156:                 // has been converted into an IRP_MJ_INTERNAL_DEVICE_CONTROL
        !          1157:                 // IRP, so we dispatch it as usual. The IRP will
        !          1158:                 // be completed by this call.
        !          1159:                 //
        !          1160:                 // StDispatchInternal expects to complete the IRP,
        !          1161:                 // so we change Status to PENDING so we don't.
        !          1162:                 //
        !          1163: 
        !          1164:                 (VOID)StDispatchInternal (DeviceObject, Irp);
        !          1165:                 Status = STATUS_PENDING;
        !          1166: 
        !          1167:             }
        !          1168:     }
        !          1169: 
        !          1170:     return Status;
        !          1171: } /* StDeviceControl */
        !          1172: 
        !          1173: 
        !          1174: NTSTATUS
        !          1175: StDispatchInternal (
        !          1176:     IN PDEVICE_OBJECT DeviceObject,
        !          1177:     IN PIRP Irp
        !          1178:     )
        !          1179: 
        !          1180: /*++
        !          1181: 
        !          1182: Routine Description:
        !          1183: 
        !          1184:     This routine dispatches TDI request types to different handlers based
        !          1185:     on the minor IOCTL function code in the IRP's current stack location.
        !          1186:     In addition to cracking the minor function code, this routine also
        !          1187:     reaches into the IRP and passes the packetized parameters stored there
        !          1188:     as parameters to the various TDI request handlers so that they are
        !          1189:     not IRP-dependent.
        !          1190: 
        !          1191: Arguments:
        !          1192: 
        !          1193:     DeviceObject - Pointer to the device object for this driver.
        !          1194: 
        !          1195:     Irp - Pointer to the request packet representing the I/O request.
        !          1196: 
        !          1197: Return Value:
        !          1198: 
        !          1199:     The function value is the status of the operation.
        !          1200: 
        !          1201: --*/
        !          1202: 
        !          1203: {
        !          1204:     NTSTATUS Status;
        !          1205:     PDEVICE_CONTEXT DeviceContext;
        !          1206:     PIO_STACK_LOCATION IrpSp;
        !          1207: 
        !          1208: 
        !          1209:     //
        !          1210:     // Get a pointer to the current stack location in the IRP.  This is where
        !          1211:     // the function codes and parameters are stored.
        !          1212:     //
        !          1213: 
        !          1214:     IrpSp = IoGetCurrentIrpStackLocation (Irp);
        !          1215: 
        !          1216:     DeviceContext = (PDEVICE_CONTEXT)DeviceObject;
        !          1217: 
        !          1218: 
        !          1219:     if (DeviceContext->State != DEVICECONTEXT_STATE_OPEN) {
        !          1220:         Irp->IoStatus.Status = STATUS_INVALID_DEVICE_STATE;
        !          1221:         IoCompleteRequest (Irp, IO_NETWORK_INCREMENT);
        !          1222:         return STATUS_INVALID_DEVICE_STATE;
        !          1223:     }
        !          1224: 
        !          1225: 
        !          1226:     //
        !          1227:     // Make sure status information is consistent every time.
        !          1228:     //
        !          1229: 
        !          1230:     IoMarkIrpPending (Irp);
        !          1231:     Irp->IoStatus.Status = STATUS_PENDING;
        !          1232:     Irp->IoStatus.Information = 0;
        !          1233: 
        !          1234: 
        !          1235:     //
        !          1236:     // Branch to the appropriate request handler.  Preliminary checking of
        !          1237:     // the size of the request block is performed here so that it is known
        !          1238:     // in the handlers that the minimum input parameters are readable.  It
        !          1239:     // is *not* determined here whether variable length input fields are
        !          1240:     // passed correctly; this is a check which must be made within each routine.
        !          1241:     //
        !          1242: 
        !          1243:     switch (IrpSp->MinorFunction) {
        !          1244: 
        !          1245:         case TDI_ACCEPT:
        !          1246:             Status = StTdiAccept (Irp);
        !          1247:             break;
        !          1248: 
        !          1249:         case TDI_ACTION:
        !          1250:             Status = STATUS_SUCCESS;
        !          1251:             break;
        !          1252: 
        !          1253:         case TDI_ASSOCIATE_ADDRESS:
        !          1254:             Status = StTdiAssociateAddress (Irp);
        !          1255:             break;
        !          1256: 
        !          1257:         case TDI_DISASSOCIATE_ADDRESS:
        !          1258:             Status = StTdiDisassociateAddress (Irp);
        !          1259:             break;
        !          1260: 
        !          1261:         case TDI_CONNECT:
        !          1262:             Status = StTdiConnect (Irp);
        !          1263:             break;
        !          1264: 
        !          1265:         case TDI_DISCONNECT:
        !          1266:             Status = StTdiDisconnect (Irp);
        !          1267:             break;
        !          1268: 
        !          1269:         case TDI_LISTEN:
        !          1270:             Status = StTdiListen (Irp);
        !          1271:             break;
        !          1272: 
        !          1273:         case TDI_QUERY_INFORMATION:
        !          1274:             Status = StTdiQueryInformation (DeviceContext, Irp);
        !          1275:             break;
        !          1276: 
        !          1277:         case TDI_RECEIVE:
        !          1278:             Status =  StTdiReceive (Irp);
        !          1279:             break;
        !          1280: 
        !          1281:         case TDI_RECEIVE_DATAGRAM:
        !          1282:             Status =  StTdiReceiveDatagram (Irp);
        !          1283:             break;
        !          1284: 
        !          1285:         case TDI_SEND:
        !          1286:             Status =  StTdiSend (Irp);
        !          1287:             break;
        !          1288: 
        !          1289:         case TDI_SEND_DATAGRAM:
        !          1290:             Status = StTdiSendDatagram (Irp);
        !          1291:             break;
        !          1292: 
        !          1293:         case TDI_SET_EVENT_HANDLER:
        !          1294: 
        !          1295:             //
        !          1296:             // Because this request will enable direct callouts from the
        !          1297:             // transport provider at DISPATCH_LEVEL to a client-specified
        !          1298:             // routine, this request is only valid in kernel mode, denying
        !          1299:             // access to this request in user mode.
        !          1300:             //
        !          1301: 
        !          1302:             Status = StTdiSetEventHandler (Irp);
        !          1303:             break;
        !          1304: 
        !          1305:         case TDI_SET_INFORMATION:
        !          1306:             Status = StTdiSetInformation (Irp);
        !          1307:             break;
        !          1308: 
        !          1309: 
        !          1310:         //
        !          1311:         // Something we don't know about was submitted.
        !          1312:         //
        !          1313: 
        !          1314:         default:
        !          1315:             Status = STATUS_INVALID_DEVICE_REQUEST;
        !          1316:     }
        !          1317: 
        !          1318:     if (Status != STATUS_PENDING) {
        !          1319:         IrpSp->Control &= ~SL_PENDING_RETURNED;
        !          1320:         Irp->IoStatus.Status = Status;
        !          1321:         IoCompleteRequest (Irp, IO_NETWORK_INCREMENT);
        !          1322:     }
        !          1323: 
        !          1324: 
        !          1325:     //
        !          1326:     // Return the immediate status code to the caller.
        !          1327:     //
        !          1328: 
        !          1329:     return Status;
        !          1330: 
        !          1331: } /* StDispatchInternal */
        !          1332: 
        !          1333: 
        !          1334: VOID
        !          1335: StWriteResourceErrorLog(
        !          1336:     IN PDEVICE_CONTEXT DeviceContext,
        !          1337:     IN ULONG BytesNeeded,
        !          1338:     IN ULONG UniqueErrorValue
        !          1339:     )
        !          1340: 
        !          1341: /*++
        !          1342: 
        !          1343: Routine Description:
        !          1344: 
        !          1345:     This routine allocates and writes an error log entry indicating
        !          1346:     an out of resources condition.
        !          1347: 
        !          1348: Arguments:
        !          1349: 
        !          1350:     DeviceContext - Pointer to the device context.
        !          1351: 
        !          1352:     BytesNeeded - If applicable, the number of bytes that could not
        !          1353:         be allocated.
        !          1354: 
        !          1355:     UniqueErrorValue - Used as the UniqueErrorValue in the error log
        !          1356:         packet.
        !          1357: 
        !          1358: Return Value:
        !          1359: 
        !          1360:     None.
        !          1361: 
        !          1362: --*/
        !          1363: 
        !          1364: {
        !          1365:     PIO_ERROR_LOG_PACKET errorLogEntry;
        !          1366:     UCHAR EntrySize;
        !          1367:     PUCHAR StringLoc;
        !          1368:     ULONG TempUniqueError;
        !          1369:     static WCHAR UniqueErrorBuffer[4] = L"000";
        !          1370:     UINT i;
        !          1371: 
        !          1372: 
        !          1373:     EntrySize = sizeof(IO_ERROR_LOG_PACKET) +
        !          1374:                 DeviceContext->DeviceNameLength +
        !          1375:                 sizeof(UniqueErrorBuffer);
        !          1376: 
        !          1377:     errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(
        !          1378:         (PDEVICE_OBJECT)DeviceContext,
        !          1379:         EntrySize
        !          1380:     );
        !          1381: 
        !          1382:     //
        !          1383:     // Convert the error value into a buffer.
        !          1384:     //
        !          1385: 
        !          1386:     TempUniqueError = UniqueErrorValue;
        !          1387:     for (i=1; i>=0; i--) {
        !          1388:         UniqueErrorBuffer[i] = (WCHAR)((TempUniqueError % 10) + L'0');
        !          1389:         TempUniqueError /= 10;
        !          1390:     }
        !          1391: 
        !          1392:     if (errorLogEntry != NULL) {
        !          1393: 
        !          1394:         errorLogEntry->MajorFunctionCode = (UCHAR)-1;
        !          1395:         errorLogEntry->RetryCount = (UCHAR)-1;
        !          1396:         errorLogEntry->DumpDataSize = sizeof(ULONG);
        !          1397:         errorLogEntry->NumberOfStrings = 2;
        !          1398:         errorLogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET);
        !          1399:         errorLogEntry->EventCategory = 0;
        !          1400:         errorLogEntry->ErrorCode = EVENT_TRANSPORT_RESOURCE_POOL;
        !          1401:         errorLogEntry->UniqueErrorValue = UniqueErrorValue;
        !          1402:         errorLogEntry->FinalStatus = STATUS_INSUFFICIENT_RESOURCES;
        !          1403:         errorLogEntry->SequenceNumber = (ULONG)-1;
        !          1404:         errorLogEntry->IoControlCode = 0;
        !          1405:         errorLogEntry->DumpData[0] = BytesNeeded;
        !          1406: 
        !          1407:         StringLoc = ((PUCHAR)errorLogEntry) + errorLogEntry->StringOffset;
        !          1408:         RtlCopyMemory (StringLoc, DeviceContext->DeviceName, DeviceContext->DeviceNameLength);
        !          1409: 
        !          1410:         StringLoc += DeviceContext->DeviceNameLength;
        !          1411:         RtlCopyMemory (StringLoc, UniqueErrorBuffer, sizeof(UniqueErrorBuffer));
        !          1412: 
        !          1413:         IoWriteErrorLogEntry(errorLogEntry);
        !          1414: 
        !          1415:     }
        !          1416: 
        !          1417: }   /* StWriteResourceErrorLog */
        !          1418: 
        !          1419: 
        !          1420: VOID
        !          1421: StWriteGeneralErrorLog(
        !          1422:     IN PDEVICE_CONTEXT DeviceContext,
        !          1423:     IN NTSTATUS ErrorCode,
        !          1424:     IN ULONG UniqueErrorValue,
        !          1425:     IN NTSTATUS FinalStatus,
        !          1426:     IN PWSTR SecondString,
        !          1427:     IN ULONG DumpDataCount,
        !          1428:     IN ULONG DumpData[]
        !          1429:     )
        !          1430: 
        !          1431: /*++
        !          1432: 
        !          1433: Routine Description:
        !          1434: 
        !          1435:     This routine allocates and writes an error log entry indicating
        !          1436:     a general problem as indicated by the parameters. It handles
        !          1437:     event codes REGISTER_FAILED, BINDING_FAILED, ADAPTER_NOT_FOUND,
        !          1438:     TRANSFER_DATA, TOO_MANY_LINKS, and BAD_PROTOCOL. All these
        !          1439:     events have messages with one or two strings in them.
        !          1440: 
        !          1441: Arguments:
        !          1442: 
        !          1443:     DeviceContext - Pointer to the device context, or this may be
        !          1444:         a driver object instead.
        !          1445: 
        !          1446:     ErrorCode - The transport event code.
        !          1447: 
        !          1448:     UniqueErrorValue - Used as the UniqueErrorValue in the error log
        !          1449:         packet.
        !          1450: 
        !          1451:     FinalStatus - Used as the FinalStatus in the error log packet.
        !          1452: 
        !          1453:     SecondString - If not NULL, the string to use as the %3
        !          1454:         value in the error log packet.
        !          1455: 
        !          1456:     DumpDataCount - The number of ULONGs of dump data.
        !          1457: 
        !          1458:     DumpData - Dump data for the packet.
        !          1459: 
        !          1460: Return Value:
        !          1461: 
        !          1462:     None.
        !          1463: 
        !          1464: --*/
        !          1465: 
        !          1466: {
        !          1467:     PIO_ERROR_LOG_PACKET errorLogEntry;
        !          1468:     UCHAR EntrySize;
        !          1469:     ULONG SecondStringSize;
        !          1470:     PUCHAR StringLoc;
        !          1471:     static WCHAR DriverName[3] = L"St";
        !          1472: 
        !          1473:     EntrySize = sizeof(IO_ERROR_LOG_PACKET) +
        !          1474:                 (DumpDataCount * sizeof(ULONG));
        !          1475: 
        !          1476:     if (DeviceContext->Type == IO_TYPE_DEVICE) {
        !          1477:         EntrySize += (UCHAR)DeviceContext->DeviceNameLength;
        !          1478:     } else {
        !          1479:         EntrySize += sizeof(DriverName);
        !          1480:     }
        !          1481: 
        !          1482:     if (SecondString) {
        !          1483:         SecondStringSize = (wcslen(SecondString)*sizeof(WCHAR)) + sizeof(UNICODE_NULL);
        !          1484:         EntrySize += (UCHAR)SecondStringSize;
        !          1485:     }
        !          1486: 
        !          1487:     errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(
        !          1488:         (PDEVICE_OBJECT)DeviceContext,
        !          1489:         EntrySize
        !          1490:     );
        !          1491: 
        !          1492:     if (errorLogEntry != NULL) {
        !          1493: 
        !          1494:         errorLogEntry->MajorFunctionCode = (UCHAR)-1;
        !          1495:         errorLogEntry->RetryCount = (UCHAR)-1;
        !          1496:         errorLogEntry->DumpDataSize = (USHORT)(DumpDataCount * sizeof(ULONG));
        !          1497:         errorLogEntry->NumberOfStrings = (SecondString == NULL) ? 1 : 2;
        !          1498:         errorLogEntry->StringOffset =
        !          1499:             sizeof(IO_ERROR_LOG_PACKET) + ((DumpDataCount-1) * sizeof(ULONG));
        !          1500:         errorLogEntry->EventCategory = 0;
        !          1501:         errorLogEntry->ErrorCode = ErrorCode;
        !          1502:         errorLogEntry->UniqueErrorValue = UniqueErrorValue;
        !          1503:         errorLogEntry->FinalStatus = FinalStatus;
        !          1504:         errorLogEntry->SequenceNumber = (ULONG)-1;
        !          1505:         errorLogEntry->IoControlCode = 0;
        !          1506: 
        !          1507:         if (DumpDataCount) {
        !          1508:             RtlCopyMemory(errorLogEntry->DumpData, DumpData, DumpDataCount * sizeof(ULONG));
        !          1509:         }
        !          1510: 
        !          1511:         StringLoc = ((PUCHAR)errorLogEntry) + errorLogEntry->StringOffset;
        !          1512:         if (DeviceContext->Type == IO_TYPE_DEVICE) {
        !          1513:             RtlCopyMemory (StringLoc, DeviceContext->DeviceName, DeviceContext->DeviceNameLength);
        !          1514:             StringLoc += DeviceContext->DeviceNameLength;
        !          1515:         } else {
        !          1516:             RtlCopyMemory (StringLoc, DriverName, sizeof(DriverName));
        !          1517:             StringLoc += sizeof(DriverName);
        !          1518:         }
        !          1519:         if (SecondString) {
        !          1520:             RtlCopyMemory (StringLoc, SecondString, SecondStringSize);
        !          1521:         }
        !          1522: 
        !          1523:         IoWriteErrorLogEntry(errorLogEntry);
        !          1524: 
        !          1525:     }
        !          1526: 
        !          1527: }   /* StWriteGeneralErrorLog */
        !          1528: 
        !          1529: 
        !          1530: VOID
        !          1531: StWriteOidErrorLog(
        !          1532:     IN PDEVICE_CONTEXT DeviceContext,
        !          1533:     IN NTSTATUS ErrorCode,
        !          1534:     IN NTSTATUS FinalStatus,
        !          1535:     IN PWSTR AdapterString,
        !          1536:     IN ULONG OidValue
        !          1537:     )
        !          1538: 
        !          1539: /*++
        !          1540: 
        !          1541: Routine Description:
        !          1542: 
        !          1543:     This routine allocates and writes an error log entry indicating
        !          1544:     a problem querying or setting an OID on an adapter. It handles
        !          1545:     event codes SET_OID_FAILED and QUERY_OID_FAILED.
        !          1546: 
        !          1547: Arguments:
        !          1548: 
        !          1549:     DeviceContext - Pointer to the device context.
        !          1550: 
        !          1551:     ErrorCode - Used as the ErrorCode in the error log packet.
        !          1552: 
        !          1553:     FinalStatus - Used as the FinalStatus in the error log packet.
        !          1554: 
        !          1555:     AdapterString - The name of the adapter we were bound to.
        !          1556: 
        !          1557:     OidValue - The OID which could not be set or queried.
        !          1558: 
        !          1559: Return Value:
        !          1560: 
        !          1561:     None.
        !          1562: 
        !          1563: --*/
        !          1564: 
        !          1565: {
        !          1566:     PIO_ERROR_LOG_PACKET errorLogEntry;
        !          1567:     UCHAR EntrySize;
        !          1568:     ULONG AdapterStringSize;
        !          1569:     PUCHAR StringLoc;
        !          1570:     static WCHAR OidBuffer[9] = L"00000000";
        !          1571:     UINT i;
        !          1572:     UINT CurrentDigit;
        !          1573: 
        !          1574:     AdapterStringSize = (wcslen(AdapterString)*sizeof(WCHAR)) + sizeof(UNICODE_NULL);
        !          1575:     EntrySize = sizeof(IO_ERROR_LOG_PACKET) -
        !          1576:                 sizeof(ULONG) +
        !          1577:                 DeviceContext->DeviceNameLength +
        !          1578:                 AdapterStringSize +
        !          1579:                 sizeof(OidBuffer);
        !          1580: 
        !          1581:     errorLogEntry = (PIO_ERROR_LOG_PACKET)IoAllocateErrorLogEntry(
        !          1582:         (PDEVICE_OBJECT)DeviceContext,
        !          1583:         EntrySize
        !          1584:     );
        !          1585: 
        !          1586:     //
        !          1587:     // Convert the OID into a buffer.
        !          1588:     //
        !          1589: 
        !          1590:     for (i=7; i>=0; i--) {
        !          1591:         CurrentDigit = OidValue & 0xf;
        !          1592:         OidValue >>= 4;
        !          1593:         if (CurrentDigit >= 0xa) {
        !          1594:             OidBuffer[i] = (WCHAR)(CurrentDigit - 0xa + L'A');
        !          1595:         } else {
        !          1596:             OidBuffer[i] = (WCHAR)(CurrentDigit + L'0');
        !          1597:         }
        !          1598:     }
        !          1599: 
        !          1600:     if (errorLogEntry != NULL) {
        !          1601: 
        !          1602:         errorLogEntry->MajorFunctionCode = (UCHAR)-1;
        !          1603:         errorLogEntry->RetryCount = (UCHAR)-1;
        !          1604:         errorLogEntry->DumpDataSize = 0;
        !          1605:         errorLogEntry->NumberOfStrings = 3;
        !          1606:         errorLogEntry->StringOffset = sizeof(IO_ERROR_LOG_PACKET) - sizeof(ULONG);
        !          1607:         errorLogEntry->EventCategory = 0;
        !          1608:         errorLogEntry->ErrorCode = ErrorCode;
        !          1609:         errorLogEntry->UniqueErrorValue = 0;
        !          1610:         errorLogEntry->FinalStatus = FinalStatus;
        !          1611:         errorLogEntry->SequenceNumber = (ULONG)-1;
        !          1612:         errorLogEntry->IoControlCode = 0;
        !          1613: 
        !          1614:         StringLoc = ((PUCHAR)errorLogEntry) + errorLogEntry->StringOffset;
        !          1615:         RtlCopyMemory (StringLoc, DeviceContext->DeviceName, DeviceContext->DeviceNameLength);
        !          1616:         StringLoc += DeviceContext->DeviceNameLength;
        !          1617: 
        !          1618:         RtlCopyMemory (StringLoc, OidBuffer, sizeof(OidBuffer));
        !          1619:         StringLoc += sizeof(OidBuffer);
        !          1620: 
        !          1621:         RtlCopyMemory (StringLoc, AdapterString, AdapterStringSize);
        !          1622: 
        !          1623:         IoWriteErrorLogEntry(errorLogEntry);
        !          1624: 
        !          1625:     }
        !          1626: 
        !          1627: }   /* StWriteOidErrorLog */

unix.superglobalmegacorp.com

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