/*++ Copyright (c) 1989-1993 Microsoft Corporation Module Name: query.c Abstract: This module contains code which performs the following TDI services: o TdiQueryInformation Environment: Kernel mode Revision History: --*/ #include "precomp.h" #pragma hdrstop // // Useful macro to obtain the total length of an MDL chain. // #define IpxGetMdlChainLength(Mdl, Length) { \ PMDL _Mdl = (Mdl); \ *(Length) = 0; \ while (_Mdl) { \ *(Length) += MmGetMdlByteCount(_Mdl); \ _Mdl = _Mdl->Next; \ } \ } NTSTATUS IpxTdiQueryInformation( IN PDEVICE Device, IN PREQUEST Request ) /*++ Routine Description: This routine performs the TdiQueryInformation request for the transport provider. Arguments: Request - the request for the operation. Return Value: NTSTATUS - status of operation. --*/ { NTSTATUS status; PTDI_REQUEST_KERNEL_QUERY_INFORMATION query; PADDRESS_FILE AddressFile; ULONG ElementSize, TransportAddressSize; PTRANSPORT_ADDRESS TransportAddress; TA_ADDRESS * CurAddress; PBINDING Binding; union { struct { ULONG ActivityCount; TA_IPX_ADDRESS IpxAddress; } AddressInfo; TDI_DATAGRAM_INFO DatagramInfo; TDI_ADDRESS_IPX IpxAddress; } TempBuffer; UINT i; IPX_DEFINE_LOCK_HANDLE(LockHandle1) // // what type of status do we want? // query = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)REQUEST_PARAMETERS(Request); switch (query->QueryType) { case TDI_QUERY_ADDRESS_INFO: // // The caller wants the exact address value. // AddressFile = (PADDRESS_FILE)REQUEST_OPEN_CONTEXT(Request); status = IpxVerifyAddressFile (AddressFile); if (status == STATUS_SUCCESS) { TempBuffer.AddressInfo.ActivityCount = 0; IpxBuildTdiAddress( &TempBuffer.AddressInfo.IpxAddress, Device->SourceAddress.NetworkAddress, Device->SourceAddress.NodeAddress, AddressFile->Address->Socket); #ifdef SUNDOWN status = TdiCopyBufferToMdl( &TempBuffer.AddressInfo, 0, sizeof(TempBuffer.AddressInfo), REQUEST_NDIS_BUFFER(Request), 0, (PULONG)&REQUEST_INFORMATION(Request)); #else status = TdiCopyBufferToMdl( &TempBuffer.AddressInfo, 0, sizeof(TempBuffer.AddressInfo), REQUEST_NDIS_BUFFER(Request), 0, &REQUEST_INFORMATION(Request)); #endif IpxDereferenceAddressFile (AddressFile, AFREF_VERIFY); } break; case TDI_QUERY_PROVIDER_INFO: #ifdef SUNDOWN status = TdiCopyBufferToMdl ( &(Device->Information), 0, sizeof (TDI_PROVIDER_INFO), REQUEST_NDIS_BUFFER(Request), 0, (PULONG)&REQUEST_INFORMATION(Request)); #else status = TdiCopyBufferToMdl ( &(Device->Information), 0, sizeof (TDI_PROVIDER_INFO), REQUEST_NDIS_BUFFER(Request), 0, &REQUEST_INFORMATION(Request)); #endif break; case TDI_QUERY_PROVIDER_STATISTICS: #ifdef SUNDOWN status = TdiCopyBufferToMdl ( &Device->Statistics, 0, FIELD_OFFSET (TDI_PROVIDER_STATISTICS, ResourceStats[0]), REQUEST_NDIS_BUFFER(Request), 0, (PULONG)&REQUEST_INFORMATION(Request)); #else status = TdiCopyBufferToMdl ( &Device->Statistics, 0, FIELD_OFFSET (TDI_PROVIDER_STATISTICS, ResourceStats[0]), REQUEST_NDIS_BUFFER(Request), 0, &REQUEST_INFORMATION(Request)); #endif break; case TDI_QUERY_DATAGRAM_INFO: TempBuffer.DatagramInfo.MaximumDatagramBytes = 0; TempBuffer.DatagramInfo.MaximumDatagramCount = 0; #ifdef SUNDOWN status = TdiCopyBufferToMdl ( &TempBuffer.DatagramInfo, 0, sizeof(TempBuffer.DatagramInfo), REQUEST_NDIS_BUFFER(Request), 0, (PULONG)&REQUEST_INFORMATION(Request)); #else status = TdiCopyBufferToMdl ( &TempBuffer.DatagramInfo, 0, sizeof(TempBuffer.DatagramInfo), REQUEST_NDIS_BUFFER(Request), 0, &REQUEST_INFORMATION(Request)); #endif break; case TDI_QUERY_DATA_LINK_ADDRESS: case TDI_QUERY_NETWORK_ADDRESS: if (query->QueryType == TDI_QUERY_DATA_LINK_ADDRESS) { ElementSize = (2 * sizeof(USHORT)) + 6; } else { ElementSize = (2 * sizeof(USHORT)) + sizeof(TDI_ADDRESS_IPX); } TransportAddress = IpxAllocateMemory(sizeof(int) + (ElementSize * MIN (Device->MaxBindings, Device->ValidBindings)), MEMORY_QUERY, "NetworkAddress"); if (TransportAddress == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; } else { TransportAddress->TAAddressCount = 0; TransportAddressSize = sizeof(int); CurAddress = (TA_ADDRESS *)TransportAddress->Address; IPX_GET_LOCK1(&Device->BindAccessLock, &LockHandle1); { ULONG Index = MIN (Device->MaxBindings, Device->ValidBindings); for (i = FIRST_REAL_BINDING; i <= Index; i++) { Binding = NIC_ID_TO_BINDING(Device, i); if ((Binding == NULL) || (!Binding->LineUp)) { continue; } if (query->QueryType == TDI_QUERY_DATA_LINK_ADDRESS) { CurAddress->AddressLength = 6; #ifdef SUNDOWN CurAddress->AddressType = (USHORT)Binding->Adapter->MacInfo.RealMediumType; #else CurAddress->AddressType = Binding->Adapter->MacInfo.RealMediumType; #endif RtlCopyMemory (CurAddress->Address, Binding->LocalAddress.NodeAddress, 6); } else { CurAddress->AddressLength = sizeof(TDI_ADDRESS_IPX); CurAddress->AddressType = TDI_ADDRESS_TYPE_IPX; RtlCopyMemory (CurAddress->Address, &Binding->LocalAddress, sizeof(TDI_ADDRESS_IPX)); } ++TransportAddress->TAAddressCount; TransportAddressSize += ElementSize; CurAddress = (TA_ADDRESS *)(((PUCHAR)CurAddress) + ElementSize); } } IPX_FREE_LOCK1(&Device->BindAccessLock, LockHandle1); #ifdef SUNDOWN status = TdiCopyBufferToMdl ( TransportAddress, 0, TransportAddressSize, REQUEST_NDIS_BUFFER(Request), 0, (PULONG)&REQUEST_INFORMATION(Request)); #else status = TdiCopyBufferToMdl ( TransportAddress, 0, TransportAddressSize, REQUEST_NDIS_BUFFER(Request), 0, &REQUEST_INFORMATION(Request)); #endif CTEFreeMem (TransportAddress); } break; default: status = STATUS_INVALID_DEVICE_REQUEST; break; } return status; } /* IpxTdiQueryInformation */ NTSTATUS IpxTdiSetInformation( IN PDEVICE Device, IN PREQUEST Request ) /*++ Routine Description: This routine performs the TdiSetInformation request for the transport provider. Arguments: Device - the device. Request - the request for the operation. Return Value: NTSTATUS - status of operation. --*/ { UNREFERENCED_PARAMETER (Device); UNREFERENCED_PARAMETER (Request); return STATUS_NOT_IMPLEMENTED; } /* IpxTdiSetInformation */