Commit in reactos/lib on MAIN
kernel32/misc/env.c+11-71.26 -> 1.27
rtl/env.c+100-581.3 -> 1.4
+111-65
2 modified files
- RtlExpandEnvironmentStrings_U and ExpandEnvironmentStrings[AW] should return the total length needed for the string with all the environment variables expanded.

reactos/lib/kernel32/misc
env.c 1.26 -> 1.27
diff -u -r1.26 -r1.27
--- env.c	18 Dec 2004 21:06:25 -0000	1.26
+++ env.c	27 Dec 2004 16:40:14 -0000	1.27
@@ -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 @@
 
 	Destination.Length = 0;
 	Destination.MaximumLength = nSize;
-	Destination.Buffer = lpDst,
+	Destination.Buffer = lpDst;
 
 	DestinationU.Length = 0;
 	DestinationU.MaximumLength = nSize * sizeof(WCHAR);
@@ -598,11 +598,14 @@
 
 	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 @@
 	if (!NT_SUCCESS(Status))
 	{
 		SetLastErrorByStatus (Status);
-		return 0;
+		if (Status != STATUS_BUFFER_TOO_SMALL)
+			return 0;
 	}
 
 	return (Length / sizeof(WCHAR));

reactos/lib/rtl
env.c 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- env.c	18 Sep 2004 09:31:53 -0000	1.3
+++ env.c	27 Dec 2004 16:40:14 -0000	1.4
@@ -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 @@
                               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;
-
-   while (src_len)
-   {
-      if (*s == L'%')
+   SourceLength = Source->Length / sizeof(WCHAR);
+   SourceBuffer = Source->Buffer;
+   DestMax = Destination->MaximumLength / sizeof(WCHAR);
+   DestBuffer = Destination->Buffer;
+
+   while (SourceLength)
+   {
+      if (*SourceBuffer != L'%')
+      {
+         CopyBuffer = SourceBuffer;
+         CopyLength = 0;
+         while (SourceLength != 0 && *SourceBuffer != L'%')
+         {
+            SourceBuffer++;
+            CopyLength++;
+            SourceLength--;
+         }
+      }
+      else
       {
-         if (flag)
+         /* Process environment variable. */ 
+         
+         VariableEnd = SourceBuffer + 1;
+         Tail = SourceLength - 1;
+         while (*VariableEnd != L'%' && Tail != 0)
          {
-            flag = FALSE;
-            goto copy;
+            VariableEnd++;
+            Tail--;
          }
-         w = s + 1;
-         tail = src_len - 1;
-         while (*w != L'%' && tail)
+
+         if (Tail != 0)
          {
-            w++;
-            tail--;
-         }
-         if (!tail)
-            goto copy;
+            Variable.MaximumLength = 
+            Variable.Length = (VariableEnd - (SourceBuffer + 1)) * sizeof(WCHAR);
+            Variable.Buffer = SourceBuffer + 1;
 
-         var.Length = (w - ( s + 1)) * sizeof(WCHAR);
-         var.MaximumLength = var.Length;
-         var.Buffer = s + 1;
+            Value.Length = 0;
+            Value.MaximumLength = DestMax * sizeof(WCHAR);
+            Value.Buffer = DestBuffer;
 
-         val.Length = 0;
-         val.MaximumLength = dst_max * sizeof(WCHAR);
-         val.Buffer = d;
-         Status = RtlQueryEnvironmentVariable_U (Environment, &var, &val);
-         if (NT_SUCCESS(Status))
+            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
          {
-            d += val.Length / sizeof(WCHAR);
-            dst_max -= val.Length / sizeof(WCHAR);
-            s = w + 1;
-            src_len = tail - 1;
-            continue;
+            /* Unfinished variable name. */
+            CopyBuffer = SourceBuffer;
+            CopyLength = SourceLength;
+            SourceLength = 0;
          }
-         /* variable not found or buffer too small, just copy %var% */
-         flag = TRUE;
       }
-copy:
-      if (!dst_max)
+
+      TotalLength += CopyLength;
+      if (DestMax)
       {
-         Status = STATUS_BUFFER_TOO_SMALL;
-         break;
+         if (DestMax < CopyLength)
+         {
+            CopyLength = DestMax;
+            ReturnStatus = STATUS_BUFFER_TOO_SMALL;
+         }
+         RtlCopyMemory(DestBuffer, CopyBuffer, CopyLength * sizeof(WCHAR));
+         DestMax -= CopyLength;
+         DestBuffer += CopyLength;
       }
-
-      *d++ = *s++;
-      dst_max--;
-      src_len--;
    }
 
-   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;
 }
 
 
CVSspam 0.2.8