mirror of
https://github.com/reactos/reactos.git
synced 2024-09-01 08:14:01 +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
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
|
@ -581,7 +581,7 @@ ExpandEnvironmentStringsA (
|
||||||
|
|
||||||
Destination.Length = 0;
|
Destination.Length = 0;
|
||||||
Destination.MaximumLength = nSize;
|
Destination.MaximumLength = nSize;
|
||||||
Destination.Buffer = lpDst,
|
Destination.Buffer = lpDst;
|
||||||
|
|
||||||
DestinationU.Length = 0;
|
DestinationU.Length = 0;
|
||||||
DestinationU.MaximumLength = nSize * sizeof(WCHAR);
|
DestinationU.MaximumLength = nSize * sizeof(WCHAR);
|
||||||
|
@ -598,11 +598,14 @@ ExpandEnvironmentStringsA (
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
RtlFreeHeap (RtlGetProcessHeap (),
|
|
||||||
0,
|
|
||||||
DestinationU.Buffer);
|
|
||||||
SetLastErrorByStatus (Status);
|
SetLastErrorByStatus (Status);
|
||||||
return 0;
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||||
|
{
|
||||||
|
RtlFreeHeap (RtlGetProcessHeap (),
|
||||||
|
0,
|
||||||
|
DestinationU.Buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlUnicodeStringToAnsiString (&Destination,
|
RtlUnicodeStringToAnsiString (&Destination,
|
||||||
|
@ -647,7 +650,8 @@ ExpandEnvironmentStringsW (
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
SetLastErrorByStatus (Status);
|
SetLastErrorByStatus (Status);
|
||||||
return 0;
|
if (Status != STATUS_BUFFER_TOO_SMALL)
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (Length / sizeof(WCHAR));
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS system libraries
|
* PROJECT: ReactOS system libraries
|
||||||
|
@ -120,83 +120,125 @@ RtlExpandEnvironmentStrings_U(PWSTR Environment,
|
||||||
PUNICODE_STRING Destination,
|
PUNICODE_STRING Destination,
|
||||||
PULONG Length)
|
PULONG Length)
|
||||||
{
|
{
|
||||||
UNICODE_STRING var;
|
UNICODE_STRING Variable;
|
||||||
UNICODE_STRING val;
|
UNICODE_STRING Value;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS ReturnStatus = STATUS_SUCCESS;
|
||||||
BOOLEAN flag = FALSE;
|
NTSTATUS Status;
|
||||||
PWSTR s;
|
PWSTR SourceBuffer;
|
||||||
PWSTR d;
|
PWSTR DestBuffer;
|
||||||
PWSTR w;
|
PWSTR CopyBuffer;
|
||||||
int src_len;
|
PWSTR VariableEnd;
|
||||||
int dst_max;
|
ULONG SourceLength;
|
||||||
int tail;
|
ULONG DestMax;
|
||||||
|
ULONG CopyLength;
|
||||||
|
ULONG Tail;
|
||||||
|
ULONG TotalLength = 1; /* for terminating NULL */
|
||||||
|
|
||||||
DPRINT("RtlExpandEnvironmentStrings_U %p %wZ %p %p\n",
|
DPRINT("RtlExpandEnvironmentStrings_U %p %wZ %p %p\n",
|
||||||
Environment, Source, Destination, Length);
|
Environment, Source, Destination, Length);
|
||||||
|
|
||||||
src_len = Source->Length / sizeof(WCHAR);
|
SourceLength = Source->Length / sizeof(WCHAR);
|
||||||
s = Source->Buffer;
|
SourceBuffer = Source->Buffer;
|
||||||
dst_max = Destination->MaximumLength / sizeof(WCHAR);
|
DestMax = Destination->MaximumLength / sizeof(WCHAR);
|
||||||
d = Destination->Buffer;
|
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;
|
SourceBuffer++;
|
||||||
goto copy;
|
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:
|
else
|
||||||
if (!dst_max)
|
|
||||||
{
|
{
|
||||||
Status = STATUS_BUFFER_TOO_SMALL;
|
/* Process environment variable. */
|
||||||
break;
|
|
||||||
|
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++;
|
TotalLength += CopyLength;
|
||||||
dst_max--;
|
if (DestMax)
|
||||||
src_len--;
|
{
|
||||||
|
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)
|
if (Length != NULL)
|
||||||
*Length = Destination->Length;
|
*Length = TotalLength * sizeof(WCHAR);
|
||||||
if (dst_max)
|
|
||||||
Destination->Buffer[Destination->Length / sizeof(WCHAR)] = 0;
|
|
||||||
|
|
||||||
DPRINT("Destination %wZ\n", Destination);
|
DPRINT("Destination %wZ\n", Destination);
|
||||||
return(Status);
|
|
||||||
|
return ReturnStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue