219 lines
4.4 KiB
C
219 lines
4.4 KiB
C
/*
|
|
* String.c
|
|
*
|
|
* Author: BreenH
|
|
*
|
|
* String utilities in the NT flavor.
|
|
*/
|
|
|
|
/*
|
|
* Includes
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
#include "tsutilnt.h"
|
|
|
|
/*
|
|
* Function Implementations
|
|
*/
|
|
|
|
NTSTATUS NTAPI
|
|
NtAllocateAndCopyStringA(
|
|
PSTR *ppDestination,
|
|
PCSTR pString
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
PSTR pCopy;
|
|
ULONG cbString;
|
|
|
|
ASSERT(ppDestination != NULL);
|
|
|
|
cbString = (lstrlenA(pString) + 1) * sizeof(CHAR);
|
|
|
|
pCopy = LocalAlloc(LMEM_FIXED, cbString);
|
|
|
|
if (pCopy != NULL)
|
|
{
|
|
RtlCopyMemory(pCopy, pString, cbString);
|
|
*ppDestination = pCopy;
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
Status = STATUS_NO_MEMORY;
|
|
}
|
|
|
|
return(Status);
|
|
}
|
|
|
|
NTSTATUS NTAPI
|
|
NtAllocateAndCopyStringW(
|
|
PWSTR *ppDestination,
|
|
PCWSTR pString
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
PWSTR pCopy;
|
|
ULONG cbString;
|
|
|
|
ASSERT(ppDestination != NULL);
|
|
ASSERT(pString != NULL);
|
|
|
|
cbString = (lstrlenW(pString) + 1) * sizeof(WCHAR);
|
|
|
|
pCopy = LocalAlloc(LMEM_FIXED, cbString);
|
|
|
|
if (pCopy != NULL)
|
|
{
|
|
RtlCopyMemory(pCopy, pString, cbString);
|
|
*ppDestination = pCopy;
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
Status = STATUS_NO_MEMORY;
|
|
}
|
|
|
|
return(Status);
|
|
}
|
|
|
|
NTSTATUS NTAPI
|
|
NtConvertAnsiToUnicode(
|
|
PWSTR *ppUnicodeString,
|
|
PCSTR pAnsiString
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
PWSTR pUnicodeString;
|
|
ULONG cbAnsiString;
|
|
ULONG cbBytesWritten;
|
|
ULONG cbUnicodeString;
|
|
|
|
ASSERT(ppUnicodeString != NULL);
|
|
ASSERT(pAnsiString != NULL);
|
|
|
|
//
|
|
// Get the number of bytes in the ANSI string, then get the number of
|
|
// bytes needed for the Unicode version. None of the Rtl... APIs include
|
|
// the NULL terminator in their calculations.
|
|
//
|
|
|
|
cbAnsiString = lstrlenA(pAnsiString);
|
|
|
|
Status = RtlMultiByteToUnicodeSize(
|
|
&cbUnicodeString,
|
|
(PCHAR)pAnsiString,
|
|
cbAnsiString
|
|
);
|
|
|
|
if (Status == STATUS_SUCCESS)
|
|
{
|
|
|
|
//
|
|
// Allocate a buffer for the Unicode string and its NULL terminator,
|
|
// then convert the string.
|
|
//
|
|
|
|
cbUnicodeString += sizeof(WCHAR);
|
|
|
|
pUnicodeString = (PWSTR)LocalAlloc(LPTR, cbUnicodeString);
|
|
|
|
if (pUnicodeString != NULL)
|
|
{
|
|
Status = RtlMultiByteToUnicodeN(
|
|
pUnicodeString,
|
|
cbUnicodeString,
|
|
&cbBytesWritten,
|
|
(PCHAR)pAnsiString,
|
|
cbAnsiString
|
|
);
|
|
|
|
if (Status == STATUS_SUCCESS)
|
|
{
|
|
*ppUnicodeString = pUnicodeString;
|
|
}
|
|
else
|
|
{
|
|
LocalFree(pUnicodeString);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Status = STATUS_NO_MEMORY;
|
|
}
|
|
}
|
|
|
|
return(Status);
|
|
}
|
|
|
|
NTSTATUS NTAPI
|
|
NtConvertUnicodeToAnsi(
|
|
PSTR *ppAnsiString,
|
|
PCWSTR pUnicodeString
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
PSTR pAnsiString;
|
|
ULONG cbAnsiString;
|
|
ULONG cbBytesWritten;
|
|
ULONG cbUnicodeString;
|
|
|
|
ASSERT(ppAnsiString != NULL);
|
|
ASSERT(pUnicodeString != NULL);
|
|
|
|
//
|
|
// Get the number of bytes in the ANSI string, then get the number of
|
|
// bytes needed for the Unicode version. None of the Rtl... APIs include
|
|
// the NULL terminator in their calculations.
|
|
//
|
|
|
|
cbUnicodeString = lstrlenW(pUnicodeString) * sizeof(WCHAR);
|
|
|
|
Status = RtlUnicodeToMultiByteSize(
|
|
&cbAnsiString,
|
|
(PWSTR)pUnicodeString,
|
|
cbUnicodeString
|
|
);
|
|
|
|
if (Status == STATUS_SUCCESS)
|
|
{
|
|
|
|
//
|
|
// Allocate a buffer for the Unicode string and its NULL terminator,
|
|
// then convert the string.
|
|
//
|
|
|
|
cbAnsiString += sizeof(CHAR);
|
|
|
|
pAnsiString = (PSTR)LocalAlloc(LPTR, cbAnsiString);
|
|
|
|
if (pAnsiString != NULL)
|
|
{
|
|
Status = RtlUnicodeToMultiByteN(
|
|
pAnsiString,
|
|
cbAnsiString,
|
|
&cbBytesWritten,
|
|
(PWSTR)pUnicodeString,
|
|
cbUnicodeString
|
|
);
|
|
|
|
if (Status == STATUS_SUCCESS)
|
|
{
|
|
*ppAnsiString = pAnsiString;
|
|
}
|
|
else
|
|
{
|
|
LocalFree(pAnsiString);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Status = STATUS_NO_MEMORY;
|
|
}
|
|
}
|
|
|
|
return(Status);
|
|
}
|
|
|