/*++

*****************************************************************************
*                                                                           *
*  This software contains proprietary and confiential information of        *
*                                                                           *
*                    Digi International Inc.                                *
*                                                                           *
*  By accepting transfer of this copy, Recipient agrees to retain this      *
*  software in confidence, to prevent disclosure to others, and to make     *
*  no use of this software other than that for which it was delivered.      *
*  This is an unpublished copyrighted work of Digi International Inc.       *
*  Except as permitted by federal law, 17 USC 117, copying is strictly      *
*  prohibited.                                                              *
*                                                                           *
*****************************************************************************

Module Name:

   x25misc.c

Abstract:


Revision History:

   $Log: /Components/Windows/NT/Sync/Wan/X25MISC.C $
 * 
 * 5     4/28/97 1:55p Mikez
 * Updated to use DsApi library.  Uses IoBuildDeviceIoControlRequest to
 * alloc Irps causing two problems.  Because ioctls are METHOD_BUFFERED, a
 * systemBuffer is alloc'd, but, because the completionroutines return
 * STATUS_MORE_PROCESSING_REQUIRED, never gets freed.  Also, SystemBuffer
 * is not copied to OutputBuffer until after completionRoutine returns
 * STATUS_SUCCESS.  Need to move from METHOD_BUFFER or from using
 * IoBuildDeviceIoControlRequest.
 * 
 * 4     1/09/97 10:51a Mikez
 * Added missing traversal of linked list in Is Adapter Created routine.
 * 
 * 3     12/06/96 2:28p Mikez
 * Modified to support new SXB paridigm of "one NT device per adapter"
 * rather than the older "one NT device per port".
 * 
 * 2     10/28/96 1:25p Mikez
 * Updated to support latest firmware release, v1.1.2b.
 * 
 * 1     3/11/96 5:07p Mikez
 * Revision 1.5  1995/10/06  07:00:19  Craig_Harrison
 * Version 1.0.1.2 
 * 
 * Revision 1.4  1995/09/15  00:00:00  Craig_Harrison
 * First beta release
 * 
 * Revision 1.2  1995/01/23  09:27:12  rik
 * Got direct X25 connections working reliably
 * 
 * Revision 1.1  1994/03/17  10:04:59  rik
 * Initial revision
 *

--*/
#include <ntddk.h>
#include <ntddndis.h>
#include <ndis.h>
#include <ndiswan.h>

#include "DsApi.h"
#include "digix25.h"
#include "digix25p.h"


DIGI_MEM_COMPARES DigiMemCompare( IN PHYSICAL_ADDRESS A,
                                  IN ULONG SpanOfA,
                                  IN PHYSICAL_ADDRESS B,
                                  IN ULONG SpanOfB )
/*++

Routine Description:

    Compare two phsical address.

Arguments:

    A - One half of the comparison.

    SpanOfA - In units of bytes, the span of A.

    B - One half of the comparison.

    SpanOfB - In units of bytes, the span of B.


Return Value:

    The result of the comparison.

--*/

{

    LARGE_INTEGER a;
    LARGE_INTEGER b;

    LARGE_INTEGER lower;
    ULONG lowerSpan;
    LARGE_INTEGER higher;

    a.LowPart = A.LowPart;
    a.HighPart = A.HighPart;
    b.LowPart = B.LowPart;
    b.HighPart = B.HighPart;

    if (RtlLargeIntegerEqualTo(
            a,
            b
            )) {

        return AddressesAreEqual;

    }

    if (RtlLargeIntegerGreaterThan(
            a,
            b
            )) {

        higher = a;
        lower = b;
        lowerSpan = SpanOfB;

    } else {

        higher = b;
        lower = a;
        lowerSpan = SpanOfA;

    }

    if (RtlLargeIntegerGreaterThanOrEqualTo(
            RtlLargeIntegerSubtract(
                higher,
                lower
                ),
            RtlConvertUlongToLargeInteger(lowerSpan)
            )) {

        return AddressesAreDisjoint;

    }

    return AddressesOverlap;

}  // end DigiMemCompare



USHORT DigiWstrLength( IN PWSTR Wstr )
/*++

Routine Description:

   Determines the number of bytes used by the passed in Wstr

Arguments:

   Wstr - Pointer to wide character string.

Return Value:

   Length, in bytes.

--*/
{
   USHORT Length=0;

   while( *Wstr++ )
   {
      Length += sizeof(WCHAR);
   }
   return( Length );
}  // end DigiWstrLength




BOOLEAN
GetNextMultistringString(
	IN OUT PUNICODE_STRING DestString,
	IN PUNICODE_STRING SrcMultiString
	)
/*++

Description:

	Initializes DestString to point to the next string inside the 
	SrcMultiString.

Parameters:

	DestString - Destination unicode string.

	SrcMultiString - Source string.

Return Value:

	TRUE if next string was found,
	FALSE if end of multistring.

--*/
{
	ASSERT( SrcMultiString->Buffer[SrcMultiString->MaximumLength/2-1] == 0 );
	ASSERT( SrcMultiString->Buffer[SrcMultiString->MaximumLength/2-2] == 0 );

	if ( !DestString->Buffer  )
		DestString->Buffer = SrcMultiString->Buffer;
	else
		DestString->Buffer = (PVOID)((char *)DestString->Buffer + 
		                     DestString->Length + sizeof(WCHAR) );

	if ( *DestString->Buffer == 0 )
		return( FALSE );

	DestString->Length = DestString->MaximumLength = 
	                     DigiWstrLength( DestString->Buffer );

	DigiDump( DIGIVERYLOUD, ("String: %wZ\n", DestString) );
	return( TRUE );
}



BOOLEAN
IsAdapterCreated(
	IN PUNICODE_STRING DeviceName,
	IN PLIST_ENTRY PhysAdaptersList,
	OUT PDIGIWAN_PHYS_ADAPTER *pPhysAdapter
	)
/*++

Description:

	Compares devicename with those already in the physAdapters list to see 
	if we've created a physAdapter for this adapter.  The DeviceNames are 
	of the form DigiSxb2A where A designates the port or Snid.  Strip off 
	the A and compare against previously created devices.

Parameters:

	DeviceName - Name of device to check.
	PhysAdaptersList - Head of physAdapters list.
	pPhysAdapter - Output pointer to physAdapter if already created, else NULL.

Return Value:

	TRUE if already created,
	FALSE if not.

--*/
{
	PLIST_ENTRY Entry;
	BOOLEAN Found = FALSE;

	Entry = PhysAdaptersList;
	*pPhysAdapter = NULL;
	while ( Entry->Flink != PhysAdaptersList )
	{
		PDIGIWAN_PHYS_ADAPTER PhysAdapter;

		PhysAdapter = CONTAINING_RECORD( Entry->Flink,
		                                 DIGIWAN_PHYS_ADAPTER,
		                                 List );
		if ( RtlEqualUnicodeString( &PhysAdapter->Name, DeviceName, TRUE ) )
		{
			*pPhysAdapter = PhysAdapter;
			return( TRUE );
		}
		Entry = Entry->Flink;
	}
	return( FALSE );
}
