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.
386 lines
8.1 KiB
386 lines
8.1 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
string.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the string routines needed for the NT redirector
|
|
|
|
Author:
|
|
|
|
Colin Watson (ColinW) 02-Apr-1993
|
|
|
|
Revision History:
|
|
|
|
14-Jun-1990 LarryO
|
|
|
|
Created for Lanman Redirector
|
|
|
|
02-Apr-1993 ColinW
|
|
|
|
Modified for NwRdr
|
|
|
|
--*/
|
|
|
|
#include "Procs.h"
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text( PAGE, DuplicateStringWithString )
|
|
#pragma alloc_text( PAGE, DuplicateUnicodeStringWithString )
|
|
#pragma alloc_text( PAGE, SetUnicodeString )
|
|
#pragma alloc_text( PAGE, MergeStrings )
|
|
#endif
|
|
|
|
|
|
NTSTATUS
|
|
DuplicateStringWithString (
|
|
OUT PSTRING DestinationString,
|
|
IN PSTRING SourceString,
|
|
IN POOL_TYPE PoolType
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine duplicates a supplied input string, storing the result
|
|
of the duplication in the supplied string. The maximumlength of the
|
|
new string is determined by the length of the SourceString.
|
|
|
|
|
|
Arguments:
|
|
|
|
OUT PSTRING DestinationString - Returns the filled in string.
|
|
IN PSTRING SourceString - Supplies the string to duplicate
|
|
IN POOLTYPE PoolType - Supplies the type of pool (PagedPool or
|
|
NonPagedPool)
|
|
Return Value:
|
|
|
|
NTSTATUS - Status of resulting operation
|
|
If !NT_SUCCESS then DestinationString->Buffer == NULL
|
|
--*/
|
|
|
|
{
|
|
PAGED_CODE();
|
|
|
|
DestinationString->Buffer = NULL;
|
|
|
|
try {
|
|
|
|
if (SourceString->Length != 0) {
|
|
//
|
|
// Allocate pool to hold the buffer (contents of the string)
|
|
//
|
|
|
|
DestinationString->Buffer = (PSZ )ALLOCATE_POOL(PoolType,
|
|
SourceString->Length);
|
|
}
|
|
|
|
} except (EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
return GetExceptionCode();
|
|
|
|
}
|
|
|
|
if (DestinationString->Buffer == NULL && SourceString->Length != 0) {
|
|
|
|
//
|
|
// The allocation failed, return failure.
|
|
//
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
|
|
|
DestinationString->MaximumLength = SourceString->Length;
|
|
|
|
//
|
|
// Copy the source string into the newly allocated
|
|
// destination string
|
|
//
|
|
|
|
RtlCopyString(DestinationString, SourceString);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
DuplicateUnicodeStringWithString (
|
|
OUT PUNICODE_STRING DestinationString,
|
|
IN PUNICODE_STRING SourceString,
|
|
IN POOL_TYPE PoolType
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine duplicates a supplied input string, storing the result
|
|
of the duplication in the supplied string. The maximumlength of the
|
|
new string is determined by the length of the SourceString.
|
|
|
|
|
|
Arguments:
|
|
|
|
OUT PSTRING DestinationString - Returns the filled in string.
|
|
IN PSTRING SourceString - Supplies the string to duplicate
|
|
IN POOLTYPE PoolType - Supplies the type of pool (PagedPool or
|
|
NonPagedPool)
|
|
Return Value:
|
|
|
|
NTSTATUS - Status of resulting operation
|
|
If !NT_SUCCESS then DestinationString->Buffer == NULL
|
|
|
|
--*/
|
|
|
|
{
|
|
PAGED_CODE();
|
|
|
|
DestinationString->Buffer = NULL;
|
|
|
|
try {
|
|
|
|
if (SourceString->Length != 0) {
|
|
//
|
|
// Allocate pool to hold the buffer (contents of the string)
|
|
//
|
|
|
|
DestinationString->Buffer = (WCHAR *)ALLOCATE_POOL(PoolType,
|
|
SourceString->Length);
|
|
}
|
|
|
|
} except (EXCEPTION_EXECUTE_HANDLER) {
|
|
|
|
return GetExceptionCode();
|
|
|
|
}
|
|
|
|
if (DestinationString->Buffer == NULL && SourceString->Length != 0) {
|
|
|
|
//
|
|
// The allocation failed, return failure.
|
|
//
|
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
|
|
|
DestinationString->MaximumLength = SourceString->Length;
|
|
|
|
//
|
|
// Copy the source string into the newly allocated
|
|
// destination string
|
|
//
|
|
|
|
RtlCopyUnicodeString(DestinationString, SourceString);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
#if 0
|
|
|
|
VOID
|
|
CopyUnicodeStringToUnicode (
|
|
OUT PVOID *Destination,
|
|
IN PUNICODE_STRING Source,
|
|
IN BOOLEAN AdjustPointer
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
This routine copies the specified source string onto the destination
|
|
asciiz string.
|
|
|
|
Arguments:
|
|
|
|
OUT PUCHAR Destination, - Supplies a pointer to the destination
|
|
buffer for the string.
|
|
IN PSTRING String - Supplies the source string.
|
|
IN BOOLEAN AdjustPointer - If TRUE, increment destination pointer
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PAGED_CODE();
|
|
|
|
RtlCopyMemory((*Destination), (Source)->Buffer, (Source)->Length);
|
|
if (AdjustPointer) {
|
|
((PCHAR)(*Destination)) += ((Source)->Length);
|
|
}
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
CopyUnicodeStringToAscii (
|
|
OUT PUCHAR *Destination,
|
|
IN PUNICODE_STRING Source,
|
|
IN BOOLEAN AdjustPointer,
|
|
IN USHORT MaxLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine copies the specified source string onto the destination
|
|
asciiz string.
|
|
|
|
Arguments:
|
|
|
|
OUT PUCHAR Destination, - Supplies the destination asciiz string.
|
|
IN PUNICODE_STRING String - Supplies the source string.
|
|
IN BOOLEAN AdjustPointer - If TRUE, increment destination pointer
|
|
|
|
Return Value:
|
|
|
|
Status of conversion.
|
|
--*/
|
|
{
|
|
ANSI_STRING DestinationString;
|
|
|
|
NTSTATUS Status;
|
|
|
|
PAGED_CODE();
|
|
|
|
DestinationString.Buffer = (*Destination);
|
|
|
|
DestinationString.MaximumLength = (USHORT)(MaxLength);
|
|
|
|
Status = RtlUnicodeStringToOemString(&DestinationString, (Source), FALSE);
|
|
|
|
if (!NT_SUCCESS(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (AdjustPointer) {
|
|
(*Destination) += DestinationString.Length;
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
#endif
|
|
|
|
|
|
NTSTATUS
|
|
SetUnicodeString (
|
|
IN PUNICODE_STRING Destination,
|
|
IN ULONG Length,
|
|
IN PWCHAR Source
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine copies the specified source string onto the destination
|
|
UNICODE string allocating the buffer.
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
Status of conversion.
|
|
--*/
|
|
{
|
|
UNICODE_STRING Temp;
|
|
|
|
PAGED_CODE();
|
|
|
|
Destination->Buffer = NULL;
|
|
Destination->Length = 0;
|
|
Destination->MaximumLength = 0;
|
|
|
|
if (Length == 0) {
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
Temp.MaximumLength =
|
|
Temp.Length = (USHORT )Length;
|
|
Temp.Buffer = Source;
|
|
|
|
Destination->Buffer =
|
|
ALLOCATE_POOL(NonPagedPool,
|
|
Temp.MaximumLength+sizeof(WCHAR));
|
|
|
|
if (Destination->Buffer == NULL) {
|
|
Error(EVENT_NWRDR_RESOURCE_SHORTAGE, STATUS_INSUFFICIENT_RESOURCES, NULL, 0, 0);
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
|
|
|
Destination->MaximumLength = (USHORT)Length;
|
|
|
|
RtlCopyUnicodeString(Destination, &Temp);
|
|
|
|
Destination->Buffer[(Destination->Length/sizeof(WCHAR))] = UNICODE_NULL;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
MergeStrings(
|
|
IN PUNICODE_STRING Destination,
|
|
IN PUNICODE_STRING S1,
|
|
IN PUNICODE_STRING S2,
|
|
IN ULONG Type
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine Allocates space for Destination.Buffer and copies S1 followed
|
|
by S2 into the buffer.
|
|
|
|
Raises status if couldn't allocate buffer
|
|
|
|
Arguments:
|
|
|
|
IN PUNICODE_STRING Destination,
|
|
IN PUNICODE_STRING S1,
|
|
IN PUNICODE_STRING S2,
|
|
IN ULONG Type - PagedPool or NonPagedPool
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
PAGED_CODE();
|
|
|
|
//
|
|
// Ensuring we don't cause overflow, corrupting memory
|
|
//
|
|
|
|
if ( ((ULONG)S1->Length + (ULONG)S2->Length) > 0xFFFF ) {
|
|
ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
|
|
}
|
|
|
|
Destination->MaximumLength = S1->Length + S2->Length;
|
|
Destination->Length = S1->Length + S2->Length;
|
|
|
|
Destination->Buffer = ALLOCATE_POOL_EX( Type, Destination->MaximumLength );
|
|
|
|
RtlCopyMemory( Destination->Buffer,
|
|
S1->Buffer,
|
|
S1->Length);
|
|
|
|
RtlCopyMemory( (PUCHAR)Destination->Buffer + S1->Length,
|
|
S2->Buffer,
|
|
S2->Length);
|
|
return;
|
|
}
|