From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/ntos/tdi/loopback/loopsub.c | 379 ++++++++++++++++++++++++++++++++++++ 1 file changed, 379 insertions(+) create mode 100644 private/ntos/tdi/loopback/loopsub.c (limited to 'private/ntos/tdi/loopback/loopsub.c') diff --git a/private/ntos/tdi/loopback/loopsub.c b/private/ntos/tdi/loopback/loopsub.c new file mode 100644 index 000000000..003161e5f --- /dev/null +++ b/private/ntos/tdi/loopback/loopsub.c @@ -0,0 +1,379 @@ +/*++ + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + loopsub.c + +Abstract: + + This module implements common functions for the loopback Transport + Provider driver for NT LAN Manager. + +Author: + + Chuck Lenzmeier (chuckl) 15-Aug-1991 + +Revision History: + +--*/ + +#include "loopback.h" + + +VOID +LoopCopyData ( + IN PMDL Destination, + IN PMDL Source, + IN ULONG Length + ) + +/*++ + +Routine Description: + + This routine copies data from the storage described by one MDL chain + into the storage described by another MDL chain. + +Arguments: + + Destination - Pointer to first MDL in Destination chain + + Source - Pointer to first MDL in Source chain + + Length - Amount of data to copy. Caller must ensure that the Source + and Destination chains are at least this long. + +Return Value: + + None. + +--*/ + +{ + PCHAR sourceAddress; + ULONG sourceLength; + + PCHAR destinationAddress; + ULONG destinationLength; + + ULONG copyLength; + + // + // Get the virtual address of the first source buffer, mapping it + // if necessary. Also get the length of the buffer. + // + + sourceAddress = MmGetSystemAddressForMdl( Source ); + sourceLength = MmGetMdlByteCount( Source ); + + // + // Get the virtual address of the first destination buffer, mapping + // it if necessary. Also get the length of the buffer. + // + + destinationAddress = MmGetSystemAddressForMdl( Destination ); + destinationLength = MmGetMdlByteCount( Destination ); + + // + // Loop copying data. + // + + do { + + // + // The amount to copy in this pass is the minimum of 1) the + // amount remaining in the current source buffer, 2) the amount + // remaining in the current destination buffer, and 3) the + // amount remaining in the overall copy operation. + // + + copyLength = sourceLength; + if ( copyLength > destinationLength ) copyLength = destinationLength; + if ( copyLength > Length ) copyLength = Length; + + // + // Copy from the source buffer into the destination buffer. + // + +#ifndef TIMING + IF_DEBUG(LOOP4) { + DbgPrint( " copying %lx bytes from %lx to %lx\n", + copyLength, sourceAddress, destinationAddress ); + DbgPrint( " source data: %lx, %lx\n", + *(PULONG)sourceAddress, *((PULONG)sourceAddress + 1) ); + } + RtlMoveMemory( destinationAddress, sourceAddress, copyLength ); +#else + if ( (NtGlobalFlag & 0x20000000) == 0 ) { + RtlMoveMemory( destinationAddress, sourceAddress, copyLength ); + } else { + RtlMoveMemory( + destinationAddress, + sourceAddress, + (copyLength > 200) ? 200 : copyLength + ); + } +#endif + + // + // If all of the requested data has been copied, leave. + // + + Length -= copyLength; + + if ( Length == 0 ) { + + return; + + } + + // + // If we have used up all of the current source buffer, move to + // the next buffer. Get the virtual address of the next buffer, + // mapping it if necessary. Also get the length of the buffer. + // If we haven't used up the current source buffer, simply + // update the source pointer and the remaining length. + // + + if ( copyLength == sourceLength ) { + + Source = Source->Next; + + sourceAddress = MmGetSystemAddressForMdl( Source ); + sourceLength = MmGetMdlByteCount( Source ); + + } else { + + sourceAddress += copyLength; + sourceLength -= copyLength; + + } + + // + // If we have used up all of the current destination buffer, + // move to the next buffer. Get the virtual address of the next + // buffer, mapping it if necessary. Also get the length of the + // buffer. If we haven't used up the current destination + // buffer, simply update the destination pointer and the + // remaining length. + // + + if ( copyLength == destinationLength ) { + + Destination = Destination->Next; + + destinationAddress = MmGetSystemAddressForMdl( Destination ); + destinationLength = MmGetMdlByteCount( Destination ); + + } else { + + destinationAddress += copyLength; + destinationLength -= copyLength; + + } + + } while ( TRUE ); + + // + // Can't get here. + // + + ASSERTMSG( FALSE, "Can't get here!" ); + +} // LoopCopyData + + +PVOID +LoopGetConnectionContextFromEa ( + PFILE_FULL_EA_INFORMATION Ea + ) + +/*++ + +Routine Description: + + This routine returns the connection context specified in an EA. + +Arguments: + + Ea - Pointer to EA buffer + +Return Value: + + PVOID - Connection context + +--*/ + +{ + PVOID ctx; + + RtlMoveMemory( &ctx, &Ea->EaName[Ea->EaNameLength + 1], sizeof(PVOID) ); + + return ctx; + +} // LoopGetConnectionContextFromEa + + +NTSTATUS +LoopGetEndpointTypeFromEa ( + PFILE_FULL_EA_INFORMATION Ea, + PBLOCK_TYPE Type + ) + +/*++ + +Routine Description: + + This routine determines whether an EA describes an address or a + connection. + +Arguments: + + Ea - Pointer to EA buffer + + Type - Returns block type + +Return Value: + + NTSTATUS - STATUS_INVALID_PARAMETER if EA is not valid + +--*/ + +{ + // + // First check for address type. + // + + if ( (Ea->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH) && + (strcmp( Ea->EaName, TdiTransportAddress ) == 0) ) { + *Type = BlockTypeLoopEndpoint; + return STATUS_SUCCESS; + } + + // + // Next check for connection type. + // + + if ( (Ea->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH) && + (strcmp( Ea->EaName, TdiConnectionContext ) == 0) ) { + *Type = BlockTypeLoopConnection; + return STATUS_SUCCESS; + } + + // + // Invalid type. + // + + return STATUS_INVALID_PARAMETER; + +} // LoopGetEndpointTypeFromEa + + +NTSTATUS +LoopParseAddress ( + IN PTA_NETBIOS_ADDRESS Address, + OUT PCHAR NetbiosName + ) + +/*++ + +Routine Description: + + This routine parses the input AddressString according to conventions + defined for transport address strings as defined in the TDI + specification. It converts the name from that form into a "standard" + NetBIOS name. + +Arguments: + + Address - Pointer to a transport address in the TDI format. + + NetbiosName - A 16-character space into which the NULL-terminated + NetBIOS name is written. + +Return Value: + + NTSTATUS - Indicates whether the address string was valid. + +--*/ + +{ + // + // If the input address is not a single unique address in NetBIOS + // format, reject it. + // + + if ( (Address->TAAddressCount != 1) || + (Address->Address[0].AddressType != TDI_ADDRESS_TYPE_NETBIOS) || + (Address->Address[0].AddressLength != sizeof(TDI_ADDRESS_NETBIOS)) || + (Address->Address[0].Address[0].NetbiosNameType != + TDI_ADDRESS_NETBIOS_TYPE_UNIQUE) ) { + return STATUS_INVALID_PARAMETER; + } + + // + // Copy the name into the output buffer. + // + + RtlMoveMemory( + NetbiosName, + Address->Address[0].Address[0].NetbiosName, + NETBIOS_NAME_LENGTH + ); + + return STATUS_SUCCESS; + +} // LoopParseAddress + + +NTSTATUS +LoopParseAddressFromEa ( + IN PFILE_FULL_EA_INFORMATION Ea, + OUT PCHAR NetbiosName + ) + +/*++ + +Routine Description: + + This routine parses the input EA according to conventions defined + for transport address strings as defined in the TDI specification. + It converts the name from that form into a "standard" NetBIOS name. + +Arguments: + + Ea - Pointer to an EA in the TDI format. + + NetbiosName - A 16-character space into which the NULL-terminated + NetBIOS name is written. + +Return Value: + + NTSTATUS - Indicates whether the address string was valid. + +--*/ + +{ + TA_NETBIOS_ADDRESS nbAddress; + + if ( Ea->EaValueLength != sizeof(TA_NETBIOS_ADDRESS) ) { + return STATUS_INVALID_PARAMETER; + } + + RtlMoveMemory( + &nbAddress, + &Ea->EaName[Ea->EaNameLength + 1], + sizeof(TA_NETBIOS_ADDRESS) + ); + + // + // Pass the value portion of the EA, which is a TRANSPORT_ADDRESS, + // to LoopParseAddress. + // + + return LoopParseAddress( &nbAddress, NetbiosName ); + +} // LoopParseAddressFromEa + -- cgit v1.2.3