mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +00:00
- RtlExpandEnvironmentStrings_U and ExpandEnvironmentStrings[AW] should return the total length needed for the string with all the environment variables expanded.
svn path=/trunk/; revision=12363
This commit is contained in:
parent
ea579e1a95
commit
691f45eb54
2 changed files with 113 additions and 67 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $Id: env.c,v 1.26 2004/12/18 21:06:25 gvg Exp $
|
||||
/* $Id: env.c,v 1.27 2004/12/27 16:40:14 navaraf Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -581,7 +581,7 @@ ExpandEnvironmentStringsA (
|
|||
|
||||
Destination.Length = 0;
|
||||
Destination.MaximumLength = nSize;
|
||||
Destination.Buffer = lpDst,
|
||||
Destination.Buffer = lpDst;
|
||||
|
||||
DestinationU.Length = 0;
|
||||
DestinationU.MaximumLength = nSize * sizeof(WCHAR);
|
||||
|
@ -598,11 +598,14 @@ ExpandEnvironmentStringsA (
|
|||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
RtlFreeHeap (RtlGetProcessHeap (),
|
||||
0,
|
||||
DestinationU.Buffer);
|
||||
SetLastErrorByStatus (Status);
|
||||
return 0;
|
||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||
{
|
||||
RtlFreeHeap (RtlGetProcessHeap (),
|
||||
0,
|
||||
DestinationU.Buffer);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
RtlUnicodeStringToAnsiString (&Destination,
|
||||
|
@ -647,7 +650,8 @@ ExpandEnvironmentStringsW (
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastErrorByStatus (Status);
|
||||
return 0;
|
||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (Length / sizeof(WCHAR));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: env.c,v 1.3 2004/09/18 09:31:53 greatlrd Exp $
|
||||
/* $Id: env.c,v 1.4 2004/12/27 16:40:14 navaraf Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -120,83 +120,125 @@ RtlExpandEnvironmentStrings_U(PWSTR Environment,
|
|||
PUNICODE_STRING Destination,
|
||||
PULONG Length)
|
||||
{
|
||||
UNICODE_STRING var;
|
||||
UNICODE_STRING val;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
BOOLEAN flag = FALSE;
|
||||
PWSTR s;
|
||||
PWSTR d;
|
||||
PWSTR w;
|
||||
int src_len;
|
||||
int dst_max;
|
||||
int tail;
|
||||
UNICODE_STRING Variable;
|
||||
UNICODE_STRING Value;
|
||||
NTSTATUS ReturnStatus = STATUS_SUCCESS;
|
||||
NTSTATUS Status;
|
||||
PWSTR SourceBuffer;
|
||||
PWSTR DestBuffer;
|
||||
PWSTR CopyBuffer;
|
||||
PWSTR VariableEnd;
|
||||
ULONG SourceLength;
|
||||
ULONG DestMax;
|
||||
ULONG CopyLength;
|
||||
ULONG Tail;
|
||||
ULONG TotalLength = 1; /* for terminating NULL */
|
||||
|
||||
DPRINT("RtlExpandEnvironmentStrings_U %p %wZ %p %p\n",
|
||||
Environment, Source, Destination, Length);
|
||||
|
||||
src_len = Source->Length / sizeof(WCHAR);
|
||||
s = Source->Buffer;
|
||||
dst_max = Destination->MaximumLength / sizeof(WCHAR);
|
||||
d = Destination->Buffer;
|
||||
SourceLength = Source->Length / sizeof(WCHAR);
|
||||
SourceBuffer = Source->Buffer;
|
||||
DestMax = Destination->MaximumLength / sizeof(WCHAR);
|
||||
DestBuffer = Destination->Buffer;
|
||||
|
||||
while (src_len)
|
||||
while (SourceLength)
|
||||
{
|
||||
if (*s == L'%')
|
||||
if (*SourceBuffer != L'%')
|
||||
{
|
||||
if (flag)
|
||||
CopyBuffer = SourceBuffer;
|
||||
CopyLength = 0;
|
||||
while (SourceLength != 0 && *SourceBuffer != L'%')
|
||||
{
|
||||
flag = FALSE;
|
||||
goto copy;
|
||||
SourceBuffer++;
|
||||
CopyLength++;
|
||||
SourceLength--;
|
||||
}
|
||||
w = s + 1;
|
||||
tail = src_len - 1;
|
||||
while (*w != L'%' && tail)
|
||||
{
|
||||
w++;
|
||||
tail--;
|
||||
}
|
||||
if (!tail)
|
||||
goto copy;
|
||||
|
||||
var.Length = (w - ( s + 1)) * sizeof(WCHAR);
|
||||
var.MaximumLength = var.Length;
|
||||
var.Buffer = s + 1;
|
||||
|
||||
val.Length = 0;
|
||||
val.MaximumLength = dst_max * sizeof(WCHAR);
|
||||
val.Buffer = d;
|
||||
Status = RtlQueryEnvironmentVariable_U (Environment, &var, &val);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
d += val.Length / sizeof(WCHAR);
|
||||
dst_max -= val.Length / sizeof(WCHAR);
|
||||
s = w + 1;
|
||||
src_len = tail - 1;
|
||||
continue;
|
||||
}
|
||||
/* variable not found or buffer too small, just copy %var% */
|
||||
flag = TRUE;
|
||||
}
|
||||
copy:
|
||||
if (!dst_max)
|
||||
else
|
||||
{
|
||||
Status = STATUS_BUFFER_TOO_SMALL;
|
||||
break;
|
||||
/* Process environment variable. */
|
||||
|
||||
VariableEnd = SourceBuffer + 1;
|
||||
Tail = SourceLength - 1;
|
||||
while (*VariableEnd != L'%' && Tail != 0)
|
||||
{
|
||||
VariableEnd++;
|
||||
Tail--;
|
||||
}
|
||||
|
||||
if (Tail != 0)
|
||||
{
|
||||
Variable.MaximumLength =
|
||||
Variable.Length = (VariableEnd - (SourceBuffer + 1)) * sizeof(WCHAR);
|
||||
Variable.Buffer = SourceBuffer + 1;
|
||||
|
||||
Value.Length = 0;
|
||||
Value.MaximumLength = DestMax * sizeof(WCHAR);
|
||||
Value.Buffer = DestBuffer;
|
||||
|
||||
Status = RtlQueryEnvironmentVariable_U(Environment, &Variable,
|
||||
&Value);
|
||||
if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_TOO_SMALL)
|
||||
{
|
||||
SourceBuffer = VariableEnd + 1;
|
||||
SourceLength = Tail - 1;
|
||||
TotalLength += Value.Length / sizeof(WCHAR);
|
||||
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||
{
|
||||
DestBuffer += Value.Length / sizeof(WCHAR);
|
||||
DestMax -= Value.Length / sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
DestMax = 0;
|
||||
ReturnStatus = STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Variable not found. */
|
||||
CopyBuffer = SourceBuffer;
|
||||
CopyLength = SourceLength - Tail + 1;
|
||||
SourceLength -= CopyLength;
|
||||
SourceBuffer += CopyLength;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unfinished variable name. */
|
||||
CopyBuffer = SourceBuffer;
|
||||
CopyLength = SourceLength;
|
||||
SourceLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*d++ = *s++;
|
||||
dst_max--;
|
||||
src_len--;
|
||||
TotalLength += CopyLength;
|
||||
if (DestMax)
|
||||
{
|
||||
if (DestMax < CopyLength)
|
||||
{
|
||||
CopyLength = DestMax;
|
||||
ReturnStatus = STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
RtlCopyMemory(DestBuffer, CopyBuffer, CopyLength * sizeof(WCHAR));
|
||||
DestMax -= CopyLength;
|
||||
DestBuffer += CopyLength;
|
||||
}
|
||||
}
|
||||
|
||||
Destination->Length = (d - Destination->Buffer) * sizeof(WCHAR);
|
||||
/* NULL-terminate the buffer. */
|
||||
if (DestMax)
|
||||
*DestBuffer = 0;
|
||||
|
||||
Destination->Length = (DestBuffer - Destination->Buffer) * sizeof(WCHAR);
|
||||
if (Length != NULL)
|
||||
*Length = Destination->Length;
|
||||
if (dst_max)
|
||||
Destination->Buffer[Destination->Length / sizeof(WCHAR)] = 0;
|
||||
*Length = TotalLength * sizeof(WCHAR);
|
||||
|
||||
DPRINT("Destination %wZ\n", Destination);
|
||||
return(Status);
|
||||
|
||||
return ReturnStatus;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue