summaryrefslogtreecommitdiffstats
path: root/private/ntos/tdi/loopback/loopsub.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/tdi/loopback/loopsub.c')
-rw-r--r--private/ntos/tdi/loopback/loopsub.c379
1 files changed, 379 insertions, 0 deletions
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
+