|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.