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