summaryrefslogblamecommitdiffstats
path: root/private/nw/rdr/util.c
blob: 54da848dcbf6fc79a884a6ca8580d4a108f4f93d (plain) (tree)
































































































































































































































































































































































































                                                                                                            
/*++

Copyright (c) 1993  Microsoft Corporation

Module Name:

    Util.c

Abstract:

    This module contains utilities function for the netware redirector.

Author:

    Manny Weiser     [MannyW]    07-Jan-1994

Revision History:

--*/

#include "Procs.h"

//
//  The local debug trace level
//

#define Dbg                              (DEBUG_TRACE_CONVERT)

#ifdef ALLOC_PRAGMA
#ifndef QFE_BUILD
#pragma alloc_text( PAGE1, CopyBufferToMdl )
#endif
#endif

#if 0  // Not pageable

// see ifndef QFE_BUILD above

#endif



VOID
CopyBufferToMdl(
    PMDL DestinationMdl,
    ULONG DataOffset,
    PUCHAR SourceData,
    ULONG SourceByteCount
    )
/*++

Routine Description:

    This routine copies data from a buffer described by a pointer to a
    given offset in a buffer described by an MDL.

Arguments:

    DestinationMdl - The MDL for the destination buffer.

    DataOffset - The offset into the destination buffer to copy the data.

    SourceData - A pointer to the source data buffer.

    SourceByteCount - The number of bytes to copy.

Return Value:

    None.

--*/
{
    ULONG BufferOffset;
    ULONG PreviousBufferOffset;
    PMDL Mdl;
    ULONG BytesToCopy;
    ULONG MdlByteCount;
    PVOID pSystemVa;

    DebugTrace( +1, Dbg, "MdlMoveMemory...\n", 0 );
    DebugTrace(  0, Dbg, "Desitination MDL = %X\n", DestinationMdl );
    DebugTrace(  0, Dbg, "DataOffset       = %d\n", DataOffset );
    DebugTrace(  0, Dbg, "SourceData       = %X\n", SourceData );
    DebugTrace(  0, Dbg, "SourceByteCount  = %d\n", SourceByteCount );

    BufferOffset = 0;

    Mdl = DestinationMdl;

    //
    //  Truncate the response if it is too big.
    //

    MdlByteCount = MdlLength( Mdl );
    if ( SourceByteCount + DataOffset > MdlByteCount ) {
        SourceByteCount = MdlByteCount - DataOffset;
    }

    while ( Mdl != NULL && SourceByteCount != 0 ) {

        PreviousBufferOffset = BufferOffset;
        BufferOffset += MmGetMdlByteCount( Mdl );

        if ( DataOffset < BufferOffset ) {

            //
            //  Copy the data to this buffer
            //

            while ( SourceByteCount > 0 ) {

                BytesToCopy = MIN( SourceByteCount,
                                   BufferOffset - DataOffset );

                pSystemVa = MmGetSystemAddressForMdl( Mdl );

                DebugTrace(  0, Dbg, "Copy to    %X\n", (PUCHAR) pSystemVa +
                                                                 DataOffset -
                                                                 PreviousBufferOffset );
                DebugTrace(  0, Dbg, "Copy from  %X\n", SourceData );
                DebugTrace(  0, Dbg, "Copy bytes %d\n", BytesToCopy );

                TdiCopyLookaheadData(
                    (PUCHAR)pSystemVa + DataOffset - PreviousBufferOffset,
                    SourceData,
                    BytesToCopy,
                    0 );

                SourceData += BytesToCopy;
                DataOffset += BytesToCopy;
                SourceByteCount -= BytesToCopy;

                Mdl = Mdl->Next;
                if ( Mdl != NULL ) {
                    PreviousBufferOffset = BufferOffset;
                    BufferOffset += MmGetMdlByteCount( Mdl );
                } else {
                    ASSERT( SourceByteCount == 0 );
                }
            }

        } else {

            Mdl = Mdl->Next;

        }
    }

    DebugTrace( -1, Dbg, "MdlMoveMemory -> VOID\n", 0 );
}

//
// These parsing routines are used to do multiple credential
// connects to a single server.
//

NTSTATUS
GetCredentialFromServerName(
    IN PUNICODE_STRING puServerName,
    OUT PUNICODE_STRING puCredentialName
)
/*+++

   Description:  Given a munged server(credential) name,
   this routine returns the credential.
---*/
{

    DWORD NameLength = 0;
    BOOLEAN FoundFirstParen = FALSE;
    BOOLEAN FoundLastParen = FALSE;

    DebugTrace( 0, Dbg, "GetCredentialFromServerName: %wZ\n", puServerName );

    puCredentialName->Length = puServerName->Length;
    puCredentialName->Buffer = puServerName->Buffer;

    //
    // Find the first paren.
    //

    while ( ( puCredentialName->Length ) && !FoundFirstParen ) {

        if ( puCredentialName->Buffer[0] == L'(' ) {
            FoundFirstParen = TRUE;
        }

        puCredentialName->Buffer++;
        puCredentialName->Length -= sizeof( WCHAR );
    }

    if ( !FoundFirstParen ) {
        DebugTrace( 0, Dbg, "No opening paren for server(credential) name.\n", 0 );
        return STATUS_UNSUCCESSFUL;
    }

    //
    // Figure out the name length.
    //

    while ( ( puCredentialName->Length ) && !FoundLastParen ) {

        if ( puCredentialName->Buffer[NameLength] == L')' ) {
            FoundLastParen = TRUE;
        }

        NameLength++;
        puCredentialName->Length -= sizeof( WCHAR );
    }

    if ( !FoundLastParen ) {
        DebugTrace( 0, Dbg, "No closing paren for server(credential) name.\n", 0 );
        return STATUS_UNSUCCESSFUL;
    }

    //
    // Format the name and return.  Don't count the closing paren.
    //

    NameLength--;

    if ( !NameLength ) {
        DebugTrace( 0, Dbg, "Null credential name.\n", 0 );
        return STATUS_UNSUCCESSFUL;
    }

    puCredentialName->Length = (USHORT) (NameLength * sizeof( WCHAR ));
    puCredentialName->MaximumLength = puCredentialName->Length;

    DebugTrace( 0, Dbg, "GetCredentialFromServerName --> %wZ\n", puCredentialName );

    return STATUS_SUCCESS;

}

NTSTATUS
BuildExCredentialServerName(
    IN PUNICODE_STRING puServerName,
    IN PUNICODE_STRING puUserName,
    OUT PUNICODE_STRING puExCredServerName
)
/*+++

Description:

    Takes a server name and a user name and makes an
    ExCredServerName, which is simply: server(user)

    This routine allocates memory for the credential
    server name and the caller is responsible for
    freeing the memory when it is no longer needed.

---*/
{

    NTSTATUS Status;
    PBYTE pbCredNameBuffer;

    DebugTrace( 0, Dbg, "BuildExCredentialServerName\n", 0 );

    if ( ( !puExCredServerName ) ||
         ( !puServerName ) ||
         ( !puUserName ) ) {

        DebugTrace( 0, DEBUG_TRACE_ALWAYS, "BuildExCredentialServerName -> STATUS_INVALID_PARAMETER\n", 0 );
        return STATUS_INVALID_PARAMETER;
    }

    puExCredServerName->MaximumLength = puServerName->Length +
                                        puUserName->Length +
                                        ( 2 * sizeof( WCHAR ) );

    pbCredNameBuffer = ALLOCATE_POOL( PagedPool,
                                      puExCredServerName->MaximumLength );

    if ( pbCredNameBuffer == NULL ) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    puExCredServerName->Buffer = (PWCHAR) pbCredNameBuffer;
    puExCredServerName->Length = puExCredServerName->MaximumLength;

    //
    // Copy over the server name.
    //

    RtlCopyMemory( pbCredNameBuffer,
                   puServerName->Buffer,
                   puServerName->Length );

    pbCredNameBuffer += puServerName->Length;

    //
    // Add the credential name in parenthesis.
    //

    *( (PWCHAR) pbCredNameBuffer ) = L'(';

    pbCredNameBuffer += sizeof( WCHAR );

    RtlCopyMemory( pbCredNameBuffer,
                   puUserName->Buffer,
                   puUserName->Length );

    pbCredNameBuffer += puUserName->Length;

    *( (PWCHAR) pbCredNameBuffer ) = L')';

    DebugTrace( 0, Dbg, "BuildExCredentialServerName: %wZ\n", puExCredServerName );
    return STATUS_SUCCESS;

}

NTSTATUS
UnmungeCredentialName(
    IN PUNICODE_STRING puCredName,
    OUT PUNICODE_STRING puServerName
)
/*+++

Description:

    Given server(username), return the server
    name portion.

---*/
{

    USHORT Length = 0;

    DebugTrace( 0, Dbg, "UnmungeCredentialName: %wZ\n", puCredName );

    puServerName->Buffer = puCredName->Buffer;
    puServerName->MaximumLength = puCredName->MaximumLength;

    while ( Length < ( puCredName->Length / sizeof( WCHAR ) ) ) {

        //
        // Look for the opening paren.
        //

        if ( puCredName->Buffer[Length] == L'(' ) {
            break;
        }

        Length++;
    }

    puServerName->Length = Length * sizeof( WCHAR );

    DebugTrace( 0, Dbg, "    -> %wZ\n", puServerName );
    return STATUS_SUCCESS;

}

BOOLEAN
IsCredentialName(
    IN PUNICODE_STRING puObjectName
)
/*+++

Description:  This returns TRUE if the object is an extended
              credential munged name.

---*/
{

    DWORD dwCurrent = 0;

    if ( !puObjectName ) {
        return FALSE;
    }

    while ( dwCurrent < ( puObjectName->Length ) / sizeof( WCHAR ) ) {

        if ( puObjectName->Buffer[dwCurrent] == L'(' ) {
            return TRUE;
        }

        dwCurrent++;
    }

    return FALSE;
}