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.
360 lines
6.8 KiB
360 lines
6.8 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
strmem.c
|
|
|
|
Abstract:
|
|
|
|
String routines that allocate memory
|
|
|
|
Author:
|
|
|
|
Jim Schmidt (jimschm) 10-Aug-2001
|
|
|
|
Revision History:
|
|
|
|
<alias> <date> <comments>
|
|
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
#include "commonp.h"
|
|
|
|
PSTR
|
|
RealSzJoinPathsA (
|
|
IN PCSTR BasePath,
|
|
IN PCSTR ChildPath OPTIONAL
|
|
)
|
|
{
|
|
PCSTR baseEnd;
|
|
PSTR p;
|
|
UINT_PTR baseByteCount;
|
|
UINT_PTR childSize;
|
|
PSTR result;
|
|
|
|
//
|
|
// Validate NULLs
|
|
//
|
|
|
|
if (!BasePath) {
|
|
MYASSERT (FALSE);
|
|
BasePath = "";
|
|
}
|
|
|
|
if (!ChildPath) {
|
|
ChildPath = "";
|
|
}
|
|
|
|
//
|
|
// Compute base length in bytes
|
|
//
|
|
|
|
baseEnd = SzGetEndA (BasePath);
|
|
p = SzPrevCharA (BasePath, baseEnd);
|
|
if ((p >= BasePath) && (*p == '\\')) {
|
|
baseEnd = p;
|
|
}
|
|
|
|
baseByteCount = (PBYTE) baseEnd - (PBYTE) BasePath;
|
|
|
|
//
|
|
// Compute child length in bytes
|
|
//
|
|
|
|
if (*ChildPath == '\\') {
|
|
ChildPath++;
|
|
}
|
|
|
|
childSize = SzSizeA (ChildPath);
|
|
|
|
//
|
|
// Allocate memory & copy strings
|
|
//
|
|
|
|
result = SzAllocBytesA (baseByteCount + sizeof (CHAR) + childSize);
|
|
|
|
if (result) {
|
|
CopyMemory (result, BasePath, baseByteCount);
|
|
p = (PSTR) ((PBYTE) result + baseByteCount);
|
|
*p++ = '\\';
|
|
CopyMemory (p, ChildPath, childSize);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
PWSTR
|
|
RealSzJoinPathsW (
|
|
IN PCWSTR BasePath,
|
|
IN PCWSTR ChildPath OPTIONAL
|
|
)
|
|
{
|
|
PCWSTR baseEnd;
|
|
PWSTR p;
|
|
UINT_PTR baseByteCount;
|
|
UINT_PTR childSize;
|
|
PWSTR result;
|
|
|
|
//
|
|
// Validate NULLs
|
|
//
|
|
|
|
if (!BasePath) {
|
|
MYASSERT (FALSE);
|
|
BasePath = L"";
|
|
}
|
|
|
|
if (!ChildPath) {
|
|
ChildPath = L"";
|
|
}
|
|
|
|
//
|
|
// Compute base length in bytes
|
|
//
|
|
|
|
baseEnd = SzGetEndW (BasePath);
|
|
p = (PWSTR) (baseEnd - 1);
|
|
if ((p >= BasePath) && (*p == L'\\')) {
|
|
baseEnd = p;
|
|
}
|
|
|
|
baseByteCount = (PBYTE) baseEnd - (PBYTE) BasePath;
|
|
|
|
//
|
|
// Compute child length in bytes
|
|
//
|
|
|
|
if (*ChildPath == L'\\') {
|
|
ChildPath++;
|
|
}
|
|
|
|
childSize = SzSizeW (ChildPath);
|
|
|
|
//
|
|
// Allocate memory & copy strings
|
|
//
|
|
|
|
result = SzAllocBytesW (baseByteCount + sizeof (WCHAR) + childSize);
|
|
|
|
if (result) {
|
|
CopyMemory (result, BasePath, baseByteCount);
|
|
p = (PWSTR) ((PBYTE) result + baseByteCount);
|
|
*p++ = L'\\';
|
|
CopyMemory (p, ChildPath, childSize);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
DWORD
|
|
pGetMaxJoinSizeA (
|
|
IN va_list args
|
|
)
|
|
{
|
|
DWORD size = 0;
|
|
PCSTR source;
|
|
|
|
for (source = va_arg(args, PCSTR); source != NULL; source = va_arg(args, PCSTR)) {
|
|
size += SzByteCountA (source) + sizeof (CHAR);
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
DWORD
|
|
pGetMaxJoinSizeW (
|
|
IN va_list args
|
|
)
|
|
{
|
|
DWORD size = 0;
|
|
PCWSTR source;
|
|
|
|
for (source = va_arg(args, PCWSTR); source != NULL; source = va_arg(args, PCWSTR)) {
|
|
size += SzByteCountW (source) + sizeof (WCHAR);
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
|
|
PSTR
|
|
pJoinPathsInBufferA (
|
|
OUT PSTR Buffer,
|
|
IN va_list args
|
|
)
|
|
{
|
|
PSTR end;
|
|
PSTR endMinusOne;
|
|
PCSTR source;
|
|
PCSTR p;
|
|
INT counter;
|
|
|
|
*Buffer = 0;
|
|
|
|
counter = 0;
|
|
p = end = Buffer;
|
|
for (source = va_arg(args, PCSTR); source != NULL; source = va_arg(args, PCSTR)) {
|
|
if (counter > 0) {
|
|
endMinusOne = SzPrevCharA (p, end);
|
|
if (endMinusOne) {
|
|
if (_mbsnextc (source) == '\\') {
|
|
if (_mbsnextc (endMinusOne) == '\\') {
|
|
source++;
|
|
}
|
|
} else {
|
|
if (_mbsnextc (endMinusOne) != '\\') {
|
|
*end = '\\';
|
|
end++;
|
|
*end = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (*source) {
|
|
p = end;
|
|
end = SzCatA (end, source);
|
|
}
|
|
counter++;
|
|
}
|
|
|
|
return end;
|
|
}
|
|
|
|
PWSTR
|
|
pJoinPathsInBufferW (
|
|
OUT PWSTR Buffer,
|
|
IN va_list args
|
|
)
|
|
{
|
|
PWSTR end;
|
|
PWSTR endMinusOne;
|
|
PCWSTR source;
|
|
PCWSTR p;
|
|
INT counter;
|
|
|
|
*Buffer = 0;
|
|
|
|
counter = 0;
|
|
p = end = Buffer;
|
|
for (source = va_arg(args, PCWSTR); source != NULL; source = va_arg(args, PCWSTR)) {
|
|
if (counter > 0) {
|
|
endMinusOne = end > p ? end - 1 : NULL;
|
|
if (endMinusOne) {
|
|
if (*source == L'\\') {
|
|
if (*endMinusOne == L'\\') {
|
|
source++;
|
|
}
|
|
} else {
|
|
if (*endMinusOne != L'\\') {
|
|
*end = L'\\';
|
|
end++;
|
|
*end = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (*source) {
|
|
p = end;
|
|
end = SzCatW (end, source);
|
|
}
|
|
counter++;
|
|
}
|
|
|
|
return end;
|
|
}
|
|
|
|
|
|
PCSTR
|
|
SzJoinPathsExA (
|
|
IN OUT PGROWBUFFER Buffer,
|
|
IN ...
|
|
)
|
|
{
|
|
PCSTR result = NULL;
|
|
PSTR end;
|
|
DWORD size;
|
|
va_list args;
|
|
|
|
if (!Buffer) {
|
|
MYASSERT (FALSE);
|
|
return NULL;
|
|
}
|
|
|
|
va_start (args, Buffer);
|
|
size = pGetMaxJoinSizeA (args);
|
|
va_end (args);
|
|
|
|
if (size == 0) {
|
|
return NULL;
|
|
}
|
|
|
|
end = (PSTR) GbGrow (Buffer, size);
|
|
if (!end) {
|
|
return NULL;
|
|
}
|
|
|
|
result = end;
|
|
|
|
va_start (args, Buffer);
|
|
end = pJoinPathsInBufferA (end, args);
|
|
va_end (args);
|
|
|
|
//
|
|
// adjust Buffer->End if resulting path is actually shorter than predicted
|
|
//
|
|
MYASSERT ((PBYTE)end >= Buffer->Buf && (PBYTE)(end + 1) <= Buffer->Buf + Buffer->End);
|
|
Buffer->End = (DWORD)((PBYTE)(end + 1) - Buffer->Buf);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
PCWSTR
|
|
SzJoinPathsExW (
|
|
IN OUT PGROWBUFFER Buffer,
|
|
IN ...
|
|
)
|
|
{
|
|
PWSTR end;
|
|
DWORD size;
|
|
va_list args;
|
|
PCWSTR result = NULL;
|
|
|
|
MYASSERT (Buffer);
|
|
if (!Buffer) {
|
|
return NULL;
|
|
}
|
|
|
|
va_start (args, Buffer);
|
|
size = pGetMaxJoinSizeW (args);
|
|
va_end (args);
|
|
|
|
if (size == 0) {
|
|
return NULL;
|
|
}
|
|
|
|
end = (PWSTR) GbGrow (Buffer, size);
|
|
if (!end) {
|
|
return NULL;
|
|
}
|
|
|
|
result = end;
|
|
|
|
va_start (args, Buffer);
|
|
end = pJoinPathsInBufferW (end, args);
|
|
va_end (args);
|
|
|
|
//
|
|
// adjust Buffer->End if resulting path is actually shorter than predicted
|
|
//
|
|
MYASSERT ((PBYTE)end >= Buffer->Buf && (PBYTE)(end + 1) <= Buffer->Buf + Buffer->End);
|
|
Buffer->End = (DWORD)((PBYTE)(end + 1) - Buffer->Buf);
|
|
|
|
return result;
|
|
}
|
|
|