Windows NT 4.0 source code leak
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

/*++
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