Annotation of ntddk/src/network/tdi/info.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1989-1993 Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     info.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This module contains code which performs the following TDI services:
                     12: 
                     13:         o   TdiQueryInformation
                     14:         o   TdiSetInformation
                     15: 
                     16: Environment:
                     17: 
                     18:     Kernel mode
                     19: 
                     20: Revision History:
                     21: 
                     22: --*/
                     23: 
                     24: #include "st.h"
                     25: 
                     26: 
                     27: //
                     28: // Useful macro to obtain the total length of an MDL chain.
                     29: //
                     30: 
                     31: #define StGetMdlChainLength(Mdl, Length) { \
                     32:     PMDL _Mdl = (Mdl); \
                     33:     *(Length) = 0; \
                     34:     while (_Mdl) { \
                     35:         *(Length) += MmGetMdlByteCount(_Mdl); \
                     36:         _Mdl = _Mdl->Next; \
                     37:     } \
                     38: }
                     39: 
                     40: //
                     41: // Local functions used to satisfy various requests.
                     42: //
                     43: 
                     44: VOID
                     45: StStoreProviderStatistics(
                     46:     IN PDEVICE_CONTEXT DeviceContext,
                     47:     IN PTDI_PROVIDER_STATISTICS ProviderStatistics
                     48:     );
                     49: 
                     50: VOID
                     51: StStoreAdapterStatus(
                     52:     IN PDEVICE_CONTEXT DeviceContext,
                     53:     IN PUCHAR SourceRouting,
                     54:     IN UINT SourceRoutingLength,
                     55:     IN PVOID StatusBuffer
                     56:     );
                     57: 
                     58: VOID
                     59: StStoreNameBuffers(
                     60:     IN PDEVICE_CONTEXT DeviceContext,
                     61:     IN PVOID Buffer,
                     62:     IN ULONG BufferLength,
                     63:     IN ULONG NamesToSkip,
                     64:     OUT PULONG NamesWritten,
                     65:     OUT PULONG TotalNameCount OPTIONAL,
                     66:     OUT PBOOLEAN Truncated
                     67:     );
                     68: 
                     69: 
                     70: NTSTATUS
                     71: StTdiQueryInformation(
                     72:     IN PDEVICE_CONTEXT DeviceContext,
                     73:     IN PIRP Irp
                     74:     )
                     75: 
                     76: /*++
                     77: 
                     78: Routine Description:
                     79: 
                     80:     This routine performs the TdiQueryInformation request for the transport
                     81:     provider.
                     82: 
                     83: Arguments:
                     84: 
                     85:     Irp - the Irp for the requested operation.
                     86: 
                     87: Return Value:
                     88: 
                     89:     NTSTATUS - status of operation.
                     90: 
                     91: --*/
                     92: 
                     93: {
                     94:     NTSTATUS status;
                     95:     PIO_STACK_LOCATION irpSp;
                     96:     PVOID adapterStatus;
                     97:     PTDI_REQUEST_KERNEL_QUERY_INFORMATION query;
                     98:     PTA_NETBIOS_ADDRESS broadcastAddress;
                     99:     PTDI_PROVIDER_STATISTICS ProviderStatistics;
                    100:     PTDI_CONNECTION_INFO ConnectionInfo;
                    101:     ULONG TargetBufferLength;
                    102:     LARGE_INTEGER timeout = {0,0};
                    103:     PTP_CONNECTION Connection;
                    104:     ULONG NamesWritten, TotalNameCount, BytesWritten;
                    105:     BOOLEAN Truncated;
                    106: 
                    107:     //
                    108:     // what type of status do we want?
                    109:     //
                    110: 
                    111:     irpSp = IoGetCurrentIrpStackLocation (Irp);
                    112: 
                    113:     query = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&irpSp->Parameters;
                    114: 
                    115:     switch (query->QueryType) {
                    116: 
                    117:     case TDI_QUERY_CONNECTION_INFO:
                    118: 
                    119:         //
                    120:         // Connection info is queried on a connection,
                    121:         // verify this.
                    122:         //
                    123: 
                    124:         Connection = irpSp->FileObject->FsContext;
                    125: 
                    126:         status = StVerifyConnectionObject (Connection);
                    127: 
                    128:         if (!NT_SUCCESS (status)) {
                    129:             return status;
                    130:         }
                    131: 
                    132:         ConnectionInfo = ExAllocatePool (
                    133:                              NonPagedPool,
                    134:                              sizeof (TDI_CONNECTION_INFO));
                    135: 
                    136:         if (ConnectionInfo == NULL) {
                    137: 
                    138:             PANIC ("StQueryInfo: Cannot allocate connection info!\n");
                    139:             StWriteResourceErrorLog (DeviceContext, sizeof(TDI_CONNECTION_INFO), 6);
                    140:             status = STATUS_INSUFFICIENT_RESOURCES;
                    141: 
                    142:         } else if ((Connection->Flags & CONNECTION_FLAGS_STOPPING) != 0) {
                    143: 
                    144:             status = Connection->Status;
                    145:             ExFreePool (ConnectionInfo);
                    146: 
                    147:         } else if ((Connection->Flags & CONNECTION_FLAGS_READY) == 0) {
                    148: 
                    149:             status = STATUS_INVALID_CONNECTION;
                    150:             ExFreePool (ConnectionInfo);
                    151: 
                    152:         } else {
                    153: 
                    154:             RtlZeroMemory ((PVOID)ConnectionInfo, sizeof(TDI_CONNECTION_INFO));
                    155: 
                    156:             //
                    157:             // Fill in connection information here.
                    158:             //
                    159: 
                    160:             status = TdiCopyBufferToMdl (
                    161:                             (PVOID)ConnectionInfo,
                    162:                             0L,
                    163:                             sizeof(TDI_CONNECTION_INFO),
                    164:                             Irp->MdlAddress,
                    165:                             0,
                    166:                             &(Irp->IoStatus.Information));
                    167: 
                    168:             ExFreePool (ConnectionInfo);
                    169:         }
                    170: 
                    171:         StDereferenceConnection ("query connection info", Connection);
                    172: 
                    173:         break;
                    174: 
                    175:     case TDI_QUERY_BROADCAST_ADDRESS:
                    176: 
                    177:         //
                    178:         // for this provider, the broadcast address is a zero byte name,
                    179:         // contained in a Transport address structure.
                    180:         //
                    181: 
                    182:         broadcastAddress = ExAllocatePool (
                    183:                                 NonPagedPool,
                    184:                                 sizeof (TA_NETBIOS_ADDRESS));
                    185:         if (broadcastAddress == NULL) {
                    186:             PANIC ("StQueryInfo: Cannot allocate broadcast address!\n");
                    187:             StWriteResourceErrorLog (DeviceContext, sizeof(TA_NETBIOS_ADDRESS), 2);
                    188:             status = STATUS_INSUFFICIENT_RESOURCES;
                    189:         } else {
                    190: 
                    191:             broadcastAddress->TAAddressCount = 1;
                    192:             broadcastAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
                    193:             broadcastAddress->Address[0].AddressLength = 0;
                    194: 
                    195:             Irp->IoStatus.Information =
                    196:                     sizeof (broadcastAddress->TAAddressCount) +
                    197:                     sizeof (broadcastAddress->Address[0].AddressType) +
                    198:                     sizeof (broadcastAddress->Address[0].AddressLength);
                    199: 
                    200:             status = TdiCopyBufferToMdl (
                    201:                             (PVOID)broadcastAddress,
                    202:                             0L,
                    203:                             Irp->IoStatus.Information,
                    204:                             Irp->MdlAddress,
                    205:                             0,
                    206:                             &(Irp->IoStatus.Information));
                    207: 
                    208:             ExFreePool (broadcastAddress);
                    209:         }
                    210: 
                    211:         break;
                    212: 
                    213:     case TDI_QUERY_PROVIDER_INFO:
                    214: 
                    215:         status = TdiCopyBufferToMdl (
                    216:                     &(DeviceContext->Information),
                    217:                     0,
                    218:                     sizeof (TDI_PROVIDER_INFO),
                    219:                     Irp->MdlAddress,
                    220:                     0,
                    221:                     &Irp->IoStatus.Information);
                    222:         break;
                    223: 
                    224:     case TDI_QUERY_PROVIDER_STATISTICS:
                    225: 
                    226:         StGetMdlChainLength (Irp->MdlAddress, &TargetBufferLength);
                    227: 
                    228:         if (TargetBufferLength < sizeof(TDI_PROVIDER_STATISTICS) + ((ST_TDI_RESOURCES-1) * sizeof(TDI_PROVIDER_RESOURCE_STATS))) {
                    229: 
                    230:             Irp->IoStatus.Information = 0;
                    231:             status = STATUS_BUFFER_OVERFLOW;
                    232: 
                    233:         } else {
                    234: 
                    235:             ProviderStatistics = ExAllocatePool(
                    236:                                    NonPagedPool,
                    237:                                    sizeof(TDI_PROVIDER_STATISTICS) +
                    238:                                      ((ST_TDI_RESOURCES-1) * sizeof(TDI_PROVIDER_RESOURCE_STATS)));
                    239: 
                    240:             if (ProviderStatistics == NULL) {
                    241: 
                    242:                 PANIC ("StQueryInfo: Cannot allocate provider statistics!\n");
                    243:                 StWriteResourceErrorLog (DeviceContext, sizeof(TDI_PROVIDER_STATISTICS), 7);
                    244:                 status = STATUS_INSUFFICIENT_RESOURCES;
                    245: 
                    246:             } else {
                    247: 
                    248:                 StStoreProviderStatistics (DeviceContext, ProviderStatistics);
                    249: 
                    250:                 status = TdiCopyBufferToMdl (
                    251:                                 (PVOID)ProviderStatistics,
                    252:                                 0L,
                    253:                                 sizeof(TDI_PROVIDER_STATISTICS) +
                    254:                                   ((ST_TDI_RESOURCES-1) * sizeof(TDI_PROVIDER_RESOURCE_STATS)),
                    255:                                 Irp->MdlAddress,
                    256:                                 0,
                    257:                                 &(Irp->IoStatus.Information));
                    258: 
                    259:                 ExFreePool (ProviderStatistics);
                    260:             }
                    261: 
                    262:         }
                    263: 
                    264:         break;
                    265: 
                    266:     case TDI_QUERY_SESSION_STATUS:
                    267: 
                    268:         status = STATUS_NOT_IMPLEMENTED;
                    269:         break;
                    270: 
                    271:     case TDI_QUERY_ADAPTER_STATUS:
                    272: 
                    273:         StGetMdlChainLength (Irp->MdlAddress, &TargetBufferLength);
                    274: 
                    275:         //
                    276:         // Determine if this is a local or remote query. It is
                    277:         // local if there is no remote address specific at all,
                    278:         // or if it is equal to our reserved address.
                    279:         //
                    280: 
                    281:         if ((query->RequestConnectionInformation != NULL) &&
                    282:              (RtlCompareMemory(
                    283:                  ((PTA_NETBIOS_ADDRESS)(query->RequestConnectionInformation->RemoteAddress))->
                    284:                      Address[0].Address[0].NetbiosName,
                    285:                  DeviceContext->ReservedNetBIOSAddress,
                    286:                  NETBIOS_NAME_LENGTH) != NETBIOS_NAME_LENGTH)) {
                    287: 
                    288:             //
                    289:             // Remote, not supported here.
                    290:             //
                    291: 
                    292:             status = STATUS_NOT_IMPLEMENTED;
                    293: 
                    294:         } else {
                    295: 
                    296:             //
                    297:             // Local.
                    298:             //
                    299: 
                    300:             adapterStatus = ExAllocatePool (
                    301:                                 NonPagedPool,
                    302:                                 TargetBufferLength);
                    303: 
                    304:             if (adapterStatus == NULL) {
                    305:                 PANIC("StQueryInfo: PANIC! Could not allocate adapter status buffer\n");
                    306:                 StWriteResourceErrorLog (DeviceContext, TargetBufferLength, 3);
                    307:                 return STATUS_INSUFFICIENT_RESOURCES;
                    308:             }
                    309: 
                    310:             StStoreAdapterStatus (
                    311:                 DeviceContext,
                    312:                 NULL,
                    313:                 0,
                    314:                 adapterStatus);
                    315: 
                    316:             StStoreNameBuffers (
                    317:                 DeviceContext,
                    318:                 (PUCHAR)adapterStatus + sizeof(ADAPTER_STATUS),
                    319:                 TargetBufferLength - sizeof(ADAPTER_STATUS),
                    320:                 0,
                    321:                 &NamesWritten,
                    322:                 &TotalNameCount,
                    323:                 &Truncated);
                    324: 
                    325:             ((PADAPTER_STATUS)adapterStatus)->name_count = (WORD)TotalNameCount;
                    326: 
                    327:             BytesWritten = sizeof(ADAPTER_STATUS) + (NamesWritten * sizeof(NAME_BUFFER));
                    328: 
                    329:             status = TdiCopyBufferToMdl (
                    330:                         adapterStatus,
                    331:                         0,
                    332:                         BytesWritten,
                    333:                         Irp->MdlAddress,
                    334:                         0,
                    335:                         &Irp->IoStatus.Information);
                    336: 
                    337:             if (Truncated) {
                    338:                  status = STATUS_BUFFER_OVERFLOW;
                    339:             }
                    340: 
                    341:             ExFreePool (adapterStatus);
                    342: 
                    343:         }
                    344: 
                    345:         break;
                    346: 
                    347:     case TDI_QUERY_FIND_NAME:
                    348: 
                    349:         //
                    350:         // Find name, not supported here.
                    351:         //
                    352: 
                    353:         status = STATUS_NOT_IMPLEMENTED;
                    354:         break;
                    355: 
                    356:     default:
                    357:         status = STATUS_INVALID_DEVICE_REQUEST;
                    358:         break;
                    359:     }
                    360: 
                    361:     return status;
                    362: 
                    363: } /* StTdiQueryInformation */
                    364: 
                    365: //
                    366: // Quick macros, assumes DeviceContext and ProviderStatistics exist.
                    367: //
                    368: 
                    369: #define STORE_RESOURCE_STATS_1(_ResourceNum,_ResourceId,_ResourceName) \
                    370: { \
                    371:     PTDI_PROVIDER_RESOURCE_STATS RStats = &ProviderStatistics->ResourceStats[_ResourceNum]; \
                    372:     RStats->ResourceId = (_ResourceId); \
                    373:     RStats->MaximumResourceUsed = DeviceContext->_ResourceName ## MaxInUse; \
                    374:     if (DeviceContext->_ResourceName ## Samples > 0) { \
                    375:         RStats->AverageResourceUsed = DeviceContext->_ResourceName ## Total / DeviceContext->_ResourceName ## Samples; \
                    376:     } else { \
                    377:         RStats->AverageResourceUsed = 0; \
                    378:     } \
                    379:     RStats->ResourceExhausted = DeviceContext->_ResourceName ## Exhausted; \
                    380: }
                    381: 
                    382: #define STORE_RESOURCE_STATS_2(_ResourceNum,_ResourceId,_ResourceName) \
                    383: { \
                    384:     PTDI_PROVIDER_RESOURCE_STATS RStats = &ProviderStatistics->ResourceStats[_ResourceNum]; \
                    385:     RStats->ResourceId = (_ResourceId); \
                    386:     RStats->MaximumResourceUsed = DeviceContext->_ResourceName ## Allocated; \
                    387:     RStats->AverageResourceUsed = DeviceContext->_ResourceName ## Allocated; \
                    388:     RStats->ResourceExhausted = DeviceContext->_ResourceName ## Exhausted; \
                    389: }
                    390: 
                    391: 
                    392: VOID
                    393: StStoreProviderStatistics(
                    394:     IN PDEVICE_CONTEXT DeviceContext,
                    395:     IN PTDI_PROVIDER_STATISTICS ProviderStatistics
                    396:     )
                    397: 
                    398: /*++
                    399: 
                    400: Routine Description:
                    401: 
                    402:     This routine writes the TDI_PROVIDER_STATISTICS structure
                    403:     from the device context into ProviderStatistics.
                    404: 
                    405: Arguments:
                    406: 
                    407:     DeviceContext - a pointer to the device context.
                    408: 
                    409:     ProviderStatistics - The buffer that holds the result. It is assumed
                    410:         that it is long enough.
                    411: 
                    412: Return Value:
                    413: 
                    414:     None.
                    415: 
                    416: --*/
                    417: 
                    418: {
                    419: 
                    420:     ProviderStatistics->Version = 0x0100;
                    421: 
                    422:     //
                    423:     // Copy all the statistics from OpenConnections to WastedSpace
                    424:     // Packets in one move.
                    425:     //
                    426: 
                    427:     RtlCopyMemory(
                    428:         (PVOID)&(ProviderStatistics->OpenConnections),
                    429:         (PVOID)&(DeviceContext->OpenConnections),
                    430:         sizeof(TDI_PROVIDER_STATISTICS));
                    431: 
                    432:     //
                    433:     // Copy the resource statistics.
                    434:     //
                    435: 
                    436:     ProviderStatistics->NumberOfResources = ST_TDI_RESOURCES;
                    437: 
                    438:     STORE_RESOURCE_STATS_1 (0, 12, Address);
                    439:     STORE_RESOURCE_STATS_1 (1, 13, AddressFile);
                    440:     STORE_RESOURCE_STATS_1 (2, 14, Connection);
                    441:     STORE_RESOURCE_STATS_1 (3, 15, Request);
                    442: 
                    443:     STORE_RESOURCE_STATS_2 (4, 22, Packet);
                    444:     STORE_RESOURCE_STATS_2 (5, 23, ReceivePacket);
                    445:     STORE_RESOURCE_STATS_2 (6, 24, ReceiveBuffer);
                    446: 
                    447: }   /* StStoreProviderStatistics */
                    448: 
                    449: 
                    450: VOID
                    451: StStoreAdapterStatus(
                    452:     IN PDEVICE_CONTEXT DeviceContext,
                    453:     IN PUCHAR SourceRouting,
                    454:     IN UINT SourceRoutingLength,
                    455:     IN PVOID StatusBuffer
                    456:     )
                    457: 
                    458: /*++
                    459: 
                    460: Routine Description:
                    461: 
                    462:     This routine writes the ADAPTER_STATUS structure for the
                    463:     device context into StatusBuffer. The name_count field is
                    464:     initialized to zero; StStoreNameBuffers is used to write
                    465:     name buffers.
                    466: 
                    467: Arguments:
                    468: 
                    469:     DeviceContext - a pointer to the device context.
                    470: 
                    471:     SourceRouting - If this is a remote request, the source
                    472:         routing information from the frame.
                    473: 
                    474:     SourceRoutingLength - The length of SourceRouting.
                    475: 
                    476:     StatusBuffer - The buffer that holds the result. It is assumed
                    477:         that it is at least sizeof(ADAPTER_STATUS) bytes long.
                    478: 
                    479: Return Value:
                    480: 
                    481:     None.
                    482: 
                    483: --*/
                    484: 
                    485: {
                    486: 
                    487:     PADAPTER_STATUS AdapterStatus = (PADAPTER_STATUS)StatusBuffer;
                    488:     UINT MaxUserData;
                    489: 
                    490:     RtlZeroMemory ((PVOID)AdapterStatus, sizeof(ADAPTER_STATUS));
                    491: 
                    492:     RtlCopyMemory (AdapterStatus->adapter_address, DeviceContext->LocalAddress.Address, 6);
                    493:     AdapterStatus->rev_major = 0x03;
                    494: 
                    495:     switch (DeviceContext->MacInfo.MediumType) {
                    496:         case NdisMedium802_5: AdapterStatus->adapter_type = 0xff; break;
                    497:         default: AdapterStatus->adapter_type = 0xfe; break;
                    498:     }
                    499: 
                    500:     AdapterStatus->frmr_recv = 0;
                    501:     AdapterStatus->frmr_xmit = 0;
                    502: 
                    503:     AdapterStatus->recv_buff_unavail = (WORD)(DeviceContext->ReceivePacketExhausted + DeviceContext->ReceiveBufferExhausted);
                    504:     AdapterStatus->xmit_buf_unavail = (WORD)DeviceContext->PacketExhausted;
                    505: 
                    506:     AdapterStatus->xmit_success = (WORD)(DeviceContext->IFramesSent - DeviceContext->IFramesResent);
                    507:     AdapterStatus->recv_success = (WORD)DeviceContext->IFramesReceived;
                    508:     AdapterStatus->iframe_recv_err = (WORD)DeviceContext->IFramesRejected;
                    509:     AdapterStatus->iframe_xmit_err = (WORD)DeviceContext->IFramesResent;
                    510: 
                    511:     AdapterStatus->t1_timeouts = 0;
                    512:     AdapterStatus->ti_timeouts = 0;
                    513:     AdapterStatus->xmit_aborts = 0;
                    514: 
                    515: 
                    516:     AdapterStatus->free_ncbs = 0xffff;
                    517:     AdapterStatus->max_cfg_ncbs = 0xffff;
                    518:     AdapterStatus->max_ncbs = 0xffff;
                    519:     AdapterStatus->pending_sess = (WORD)DeviceContext->OpenConnections;
                    520:     AdapterStatus->max_cfg_sess = 0xffff;
                    521:     AdapterStatus->max_sess = 0xffff;
                    522: 
                    523: 
                    524:     MacReturnMaxDataSize(
                    525:         &DeviceContext->MacInfo,
                    526:         SourceRouting,
                    527:         SourceRoutingLength,
                    528:         DeviceContext->MaxSendPacketSize,
                    529:         &MaxUserData);
                    530: 
                    531:     AdapterStatus->max_dgram_size = (WORD)(MaxUserData - sizeof(ST_HEADER));
                    532:     AdapterStatus->max_sess_pkt_size = (WORD)(MaxUserData - sizeof(ST_HEADER));
                    533: 
                    534:     return;
                    535: 
                    536: }   /* StStoreAdapterStatus */
                    537: 
                    538: 
                    539: VOID
                    540: StStoreNameBuffers(
                    541:     IN PDEVICE_CONTEXT DeviceContext,
                    542:     IN PVOID Buffer,
                    543:     IN ULONG BufferLength,
                    544:     IN ULONG NamesToSkip,
                    545:     OUT PULONG NamesWritten,
                    546:     OUT PULONG TotalNameCount OPTIONAL,
                    547:     OUT PBOOLEAN Truncated
                    548:     )
                    549: 
                    550: /*++
                    551: 
                    552: Routine Description:
                    553: 
                    554:     This routine writes NAME_BUFFER structures for the
                    555:     device context into NameBuffer. It can skip a specified
                    556:     number of names at the beginning, and returns the number
                    557:     of names written into NameBuffer. If a name will only
                    558:     partially fit, it is not written.
                    559: 
                    560: Arguments:
                    561: 
                    562:     DeviceContext - a pointer to the device context.
                    563: 
                    564:     NameBuffer - The buffer to write the names into.
                    565: 
                    566:     NameBufferLength - The length of NameBuffer.
                    567: 
                    568:     NamesToSkip - The number of names to skip.
                    569: 
                    570:     NamesWritten - Returns the number of names written.
                    571: 
                    572:     TotalNameCount - Returns the total number of names available,
                    573:         if specified.
                    574: 
                    575:     Truncated - More names are available than were written.
                    576: 
                    577: Return Value:
                    578: 
                    579:     None.
                    580: 
                    581: --*/
                    582: 
                    583: {
                    584: 
                    585:     ULONG NameCount = 0;
                    586:     ULONG BytesWritten = 0;
                    587:     KIRQL oldirql;
                    588:     PLIST_ENTRY p;
                    589:     PNAME_BUFFER NameBuffer = (PNAME_BUFFER)Buffer;
                    590:     PTP_ADDRESS address;
                    591: 
                    592: 
                    593:     //
                    594:     // Spin through the address list for this device context.
                    595:     //
                    596: 
                    597:     ACQUIRE_SPIN_LOCK (&DeviceContext->SpinLock, &oldirql);
                    598: 
                    599:     p = DeviceContext->AddressDatabase.Flink;
                    600: 
                    601:     for (p = DeviceContext->AddressDatabase.Flink;
                    602:          p != &DeviceContext->AddressDatabase;
                    603:          p = p->Flink) {
                    604: 
                    605:         address = CONTAINING_RECORD (p, TP_ADDRESS, Linkage);
                    606: 
                    607:         //
                    608:         // Ignore addresses that are shutting down.
                    609:         //
                    610: 
                    611:         if ((address->Flags & ADDRESS_FLAGS_STOPPING) != 0) {
                    612:             continue;
                    613:         }
                    614: 
                    615:         //
                    616:         // Ignore the broadcast address.
                    617:         //
                    618: 
                    619:         if (address->NetworkName == NULL) {
                    620:             continue;
                    621:         }
                    622: 
                    623:         //
                    624:         // Ignore the reserved address.
                    625:         //
                    626: 
                    627:         if ((address->NetworkName->NetbiosName[0] == 0) &&
                    628:             (RtlCompareMemory(
                    629:                  address->NetworkName->NetbiosName,
                    630:                  DeviceContext->ReservedNetBIOSAddress,
                    631:                  NETBIOS_NAME_LENGTH) == NETBIOS_NAME_LENGTH)) {
                    632: 
                    633:             continue;
                    634:         }
                    635: 
                    636:         //
                    637:         // Check if we are still skipping.
                    638:         //
                    639: 
                    640:         if (NameCount < NamesToSkip) {
                    641:              ++NameCount;
                    642:              continue;
                    643:         }
                    644: 
                    645:         //
                    646:         // Make sure we still have room.
                    647:         //
                    648: 
                    649:         if (BytesWritten + sizeof(NAME_BUFFER) > BufferLength) {
                    650:             break;
                    651:         }
                    652: 
                    653:         RtlCopyMemory(
                    654:             NameBuffer->name,
                    655:             address->NetworkName->NetbiosName,
                    656:             NETBIOS_NAME_LENGTH);
                    657: 
                    658:         ++NameCount;
                    659:         NameBuffer->name_num = (UCHAR)NameCount;
                    660: 
                    661:         NameBuffer->name_flags = REGISTERED;
                    662:         if (address->Flags & ADDRESS_FLAGS_GROUP) {
                    663:             NameBuffer->name_flags |= GROUP_NAME;
                    664:         }
                    665: 
                    666:         // BUGBUG: name_flags should be done more accurately.
                    667: 
                    668:         BytesWritten += sizeof(NAME_BUFFER);
                    669:         ++NameBuffer;
                    670: 
                    671:     }
                    672: 
                    673:     *NamesWritten = NameBuffer - (PNAME_BUFFER)Buffer;
                    674: 
                    675:     if (p == &DeviceContext->AddressDatabase) {
                    676: 
                    677:         *Truncated = FALSE;
                    678:         if (ARGUMENT_PRESENT(TotalNameCount)) {
                    679:             *TotalNameCount = NameCount;
                    680:         }
                    681: 
                    682:     } else {
                    683: 
                    684:         *Truncated = TRUE;
                    685: 
                    686:         //
                    687:         // If requested, continue through the list and count
                    688:         // all the addresses.
                    689:         //
                    690: 
                    691:         if (ARGUMENT_PRESENT(TotalNameCount)) {
                    692: 
                    693:             for ( ;
                    694:                  p != &DeviceContext->AddressDatabase;
                    695:                  p = p->Flink) {
                    696: 
                    697:                 address = CONTAINING_RECORD (p, TP_ADDRESS, Linkage);
                    698: 
                    699:                 //
                    700:                 // Ignore addresses that are shutting down.
                    701:                 //
                    702: 
                    703:                 if ((address->Flags & ADDRESS_FLAGS_STOPPING) != 0) {
                    704:                     continue;
                    705:                 }
                    706: 
                    707:                 //
                    708:                 // Ignore the broadcast address.
                    709:                 //
                    710: 
                    711:                 if (address->NetworkName == NULL) {
                    712:                     continue;
                    713:                 }
                    714: 
                    715:                 //
                    716:                 // Ignore the reserved address, since we count it no matter what.
                    717:                 //
                    718: 
                    719:                 if ((address->NetworkName->NetbiosName[0] == 0) &&
                    720:                     (RtlCompareMemory(
                    721:                          address->NetworkName->NetbiosName,
                    722:                          DeviceContext->ReservedNetBIOSAddress,
                    723:                          NETBIOS_NAME_LENGTH) == NETBIOS_NAME_LENGTH)) {
                    724: 
                    725:                     continue;
                    726:                 }
                    727: 
                    728:                 ++NameCount;
                    729: 
                    730:             }
                    731: 
                    732:             *TotalNameCount = NameCount;
                    733: 
                    734:         }
                    735: 
                    736:     }
                    737: 
                    738: 
                    739:     RELEASE_SPIN_LOCK (&DeviceContext->SpinLock, oldirql);
                    740: 
                    741:     return;
                    742: 
                    743: }   /* StStoreNameBuffers */
                    744: 
                    745: 
                    746: NTSTATUS
                    747: StTdiSetInformation(
                    748:     IN PIRP Irp
                    749:     )
                    750: 
                    751: /*++
                    752: 
                    753: Routine Description:
                    754: 
                    755:     This routine performs the TdiSetInformation request for the transport
                    756:     provider.
                    757: 
                    758: Arguments:
                    759: 
                    760:     Irp - the Irp for the requested operation.
                    761: 
                    762: Return Value:
                    763: 
                    764:     NTSTATUS - status of operation.
                    765: 
                    766: --*/
                    767: 
                    768: {
                    769:     UNREFERENCED_PARAMETER (Irp);
                    770: 
                    771:     return STATUS_NOT_IMPLEMENTED;
                    772: 
                    773: } /* StTdiQueryInformation */
                    774: 

unix.superglobalmegacorp.com

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