/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: drivers/net/afd/afd/tdiconn.c * PURPOSE: Ancillary functions driver * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net) * UPDATE HISTORY: * 20040708 Created */ #include UINT TdiAddressSizeFromType( UINT AddressType ) { DbgPrint("(PID %lx) TdiAddressSizeFromType() started - for type: %u\n", PsGetCurrentProcessId(), AddressType); switch( AddressType ) { case TDI_ADDRESS_TYPE_IP: return TDI_ADDRESS_LENGTH_IP; case TDI_ADDRESS_TYPE_APPLETALK: return TDI_ADDRESS_LENGTH_APPLETALK; case TDI_ADDRESS_TYPE_NETBIOS: return TDI_ADDRESS_LENGTH_NETBIOS; /* case TDI_ADDRESS_TYPE_NS: */ case TDI_ADDRESS_TYPE_IPX: return TDI_ADDRESS_LENGTH_IPX; case TDI_ADDRESS_TYPE_VNS: return TDI_ADDRESS_LENGTH_VNS; /* DLB added the following type to prevent some crashes in SAMBA where the IPV6 loopback is used */ case TDI_ADDRESS_TYPE_IP6: DbgPrint("(PID %lx) TdiAddressSizeFromType - Detected use of IPV6 address type! (unsupported): %x\n", PsGetCurrentProcessId(), AddressType); return TDI_ADDRESS_LENGTH_IP6; default: DbgPrint("(PID %lx) TdiAddressSizeFromType - invalid type: %x\n", PsGetCurrentProcessId(), AddressType); return 0; } } UINT TaLengthOfAddress( PTA_ADDRESS Addr ) { UINT AddrLen = Addr->AddressLength; if (!AddrLen) return 0; AddrLen += 2 * sizeof( USHORT ); AFD_DbgPrint(1,("(PID %lx) TaLengthOfAddress: AddrLen %x\n", PsGetCurrentProcessId(), AddrLen)); return AddrLen; } UINT TaLengthOfTransportAddress( PTRANSPORT_ADDRESS Addr ) { UINT AddrLen = TaLengthOfAddress(&Addr->Address[0]); if (!AddrLen) return 0; AddrLen += sizeof(ULONG); AFD_DbgPrint(1,("(PID %lx) TaLengthOfTransportAddress: AddrLen %x\n", PsGetCurrentProcessId(), AddrLen)); return AddrLen; } UINT TaLengthOfTransportAddressByType(UINT AddressType) { UINT AddrLen = TdiAddressSizeFromType(AddressType); DbgPrint("(PID %lx) TaLengthOfTransportAddressByType() started - for type: %u\n", PsGetCurrentProcessId(), AddressType); if (!AddrLen) { DbgPrint("(PID %lx) TaLengthOfTransportAddressByType() failed, called TdiAddressSizeFromType() and got no AddrLen - for type: %u\n", PsGetCurrentProcessId(), AddressType); return 0; } AddrLen += sizeof(ULONG) + 2 * sizeof(USHORT); AFD_DbgPrint(1,("(PID %lx) TaLengthOfTransportAddressByType: AddrLen %x\n", PsGetCurrentProcessId(), AddrLen)); DbgPrint("(PID %lx) TaLengthOfTransportAddressByType() completed - for type: %u AddrLen: %x\n", PsGetCurrentProcessId(), AddressType, AddrLen ); return AddrLen; } VOID TaCopyTransportAddressInPlace( PTRANSPORT_ADDRESS Target, PTRANSPORT_ADDRESS Source ) { UINT AddrLen = TaLengthOfTransportAddress( Source ); RtlCopyMemory( Target, Source, AddrLen ); } PTRANSPORT_ADDRESS TaCopyTransportAddress( PTRANSPORT_ADDRESS OtherAddress ) { UINT AddrLen; PTRANSPORT_ADDRESS A; AddrLen = TaLengthOfTransportAddress( OtherAddress ); if (!AddrLen) return NULL; A = ExAllocatePoolWithTag(NonPagedPool, AddrLen, TAG_AFD_TRANSPORT_ADDRESS); if( A ) TaCopyTransportAddressInPlace( A, OtherAddress ); return A; } NTSTATUS TdiBuildNullTransportAddressInPlace(PTRANSPORT_ADDRESS A, UINT AddressType) { DbgPrint("(PID %lx) TaBuildNullTransportAddressInPlace() called - for type: %u\n", PsGetCurrentProcessId(), AddressType); A->TAAddressCount = 1; A->Address[0].AddressLength = TdiAddressSizeFromType(AddressType); if (!A->Address[0].AddressLength) { DbgPrint("(PID %lx) TaBuildNullTransportAddressInPlace() detected AddressType length mismatch returning STATUS_INVALID_PARAMETER.\n", PsGetCurrentProcessId()); return STATUS_INVALID_PARAMETER; } A->Address[0].AddressType = AddressType; RtlZeroMemory(A->Address[0].Address, A->Address[0].AddressLength); DbgPrint("(PID %lx) TaBuildNullTransportAddressInPlace() completed, returning STATUS_SUCCESS.\n", PsGetCurrentProcessId()); return STATUS_SUCCESS; } PTRANSPORT_ADDRESS TaBuildNullTransportAddress(UINT AddressType) { UINT AddrLen; PTRANSPORT_ADDRESS A; DbgPrint("(PID %lx) TaBuildNullTransportAddress() called - for type: %u\n", PsGetCurrentProcessId(), AddressType); AddrLen = TaLengthOfTransportAddressByType(AddressType); if (!AddrLen) { DbgPrint("(PID %lx) TaBuildNullTransportAddress() call to TaLengthOfTransportAddressByType() failed, returning NULL.\n", PsGetCurrentProcessId()); return NULL; } A = ExAllocatePoolWithTag(NonPagedPool, AddrLen, TAG_AFD_TRANSPORT_ADDRESS); if (A) { if (TdiBuildNullTransportAddressInPlace(A, AddressType) != STATUS_SUCCESS) { ExFreePoolWithTag(A, TAG_AFD_TRANSPORT_ADDRESS); DbgPrint("(PID %lx) TaBuildNullTransportAddress() call to TdiBuildNullTransportAddressInPlace() failed, returning NULL.\n", PsGetCurrentProcessId()); return NULL; } } DbgPrint("(PID %lx) TaBuildNullTransportAddress() completed succesfully returning address.\n", PsGetCurrentProcessId()); return A; } NTSTATUS TdiBuildNullConnectionInfoInPlace ( PTDI_CONNECTION_INFORMATION ConnInfo, ULONG Type ) /* * FUNCTION: Builds a NULL TDI connection information structure * ARGUMENTS: * ConnectionInfo = Address of buffer to place connection information * Type = TDI style address type (TDI_ADDRESS_TYPE_XXX). * RETURNS: * Status of operation */ { ULONG TdiAddressSize; PTRANSPORT_ADDRESS TransportAddress; DbgPrint("(PID %lx) TdiBuildNullConnectionInfoInPlace() started - for type: %u\n", PsGetCurrentProcessId(), Type); TdiAddressSize = TaLengthOfTransportAddressByType(Type); if (!TdiAddressSize) { AFD_DbgPrint(1,("(PID %lx) TdiBuildNullConnectionInfoInPlace() call to TaLengthOfTransportAddressByType() did not return length, returning Invalid parameter\n", PsGetCurrentProcessId())); return STATUS_INVALID_PARAMETER; } RtlZeroMemory(ConnInfo, sizeof(TDI_CONNECTION_INFORMATION) + TdiAddressSize); ConnInfo->OptionsLength = sizeof(ULONG); ConnInfo->RemoteAddressLength = TdiAddressSize; TransportAddress = (PTRANSPORT_ADDRESS)&ConnInfo[1]; ConnInfo->RemoteAddress = TransportAddress; DbgPrint("(PID %lx) TdiBuildNullConnectionInfoInPlace() completed - for type: %u RemoteAddress\n", PsGetCurrentProcessId(), Type, TransportAddress->Address[0].Address ); return TdiBuildNullTransportAddressInPlace(TransportAddress, Type); } NTSTATUS TdiBuildNullConnectionInfo ( PTDI_CONNECTION_INFORMATION *ConnectionInfo, ULONG Type ) /* * FUNCTION: Builds a NULL TDI connection information structure * ARGUMENTS: * ConnectionInfo = Address of buffer pointer to allocate connection * information in * Type = TDI style address type (TDI_ADDRESS_TYPE_XXX). * RETURNS: * Status of operation */ { PTDI_CONNECTION_INFORMATION ConnInfo; ULONG TdiAddressSize; NTSTATUS Status; AFD_DbgPrint(1,("(PID %lx) TdiBuildNullConnectionInfo: Starting for type: %u\n", PsGetCurrentProcessId(), Type)); TdiAddressSize = TaLengthOfTransportAddressByType(Type); if (!TdiAddressSize) { AFD_DbgPrint(1,("(PID %lx) TdiBuildNullConnectionInfo: TaLengthOfTransportAddressByType() did not return TdiAddressSize ! - Invalid parameter\n", PsGetCurrentProcessId())); *ConnectionInfo = NULL; return STATUS_INVALID_PARAMETER; } ConnInfo = (PTDI_CONNECTION_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, sizeof(TDI_CONNECTION_INFORMATION) + TdiAddressSize, TAG_AFD_TDI_CONNECTION_INFORMATION); if (!ConnInfo) { *ConnectionInfo = NULL; AFD_DbgPrint(1,("(PID %lx) TdiBuildNullConnectionInfo: TaLengthOfTransportAddressByType() allocation failed ! - Insufficient Resources\n", PsGetCurrentProcessId())); return STATUS_INSUFFICIENT_RESOURCES; } Status = TdiBuildNullConnectionInfoInPlace( ConnInfo, Type ); if (!NT_SUCCESS(Status)) { AFD_DbgPrint(1,("(PID %lx) TdiBuildNullConnectionInfo: TaLengthOfTransportAddressByType() failed ! - setting ConnInfo to NULL\n", PsGetCurrentProcessId())); ExFreePoolWithTag(ConnInfo, TAG_AFD_TDI_CONNECTION_INFORMATION); ConnInfo = NULL; } *ConnectionInfo = ConnInfo; AFD_DbgPrint(1,("(PID %lx) TdiBuildNullConnectionInfo: completed, returning Status - %lx\n", PsGetCurrentProcessId(), Status)); return Status; } NTSTATUS TdiBuildConnectionInfoInPlace ( PTDI_CONNECTION_INFORMATION ConnectionInfo, PTRANSPORT_ADDRESS Address ) { NTSTATUS Status = STATUS_SUCCESS; _SEH2_TRY { RtlCopyMemory( ConnectionInfo->RemoteAddress, Address, ConnectionInfo->RemoteAddressLength ); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END; return Status; } NTSTATUS TdiBuildConnectionInfo ( PTDI_CONNECTION_INFORMATION *ConnectionInfo, PTRANSPORT_ADDRESS Address ) { NTSTATUS Status = TdiBuildNullConnectionInfo ( ConnectionInfo, Address->Address[0].AddressType ); if( NT_SUCCESS(Status) ) TdiBuildConnectionInfoInPlace( *ConnectionInfo, Address ); return Status; }