Annotation of ntddk/src/network/tdi/stdrvr.c, revision 1.1.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.