mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
379 lines
8.2 KiB
379 lines
8.2 KiB
/*++
|
|
|
|
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
|
|
|