[RTL]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Sat, 16 Feb 2013 17:53:05 +0000 (17:53 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Sat, 16 Feb 2013 17:53:05 +0000 (17:53 +0000)
Improve RtlCreateEnvironment, fixing some warnings from VS /analyze

svn path=/trunk/; revision=58321

reactos/lib/rtl/env.c

index c4dd08e..cce1278 100644 (file)
 /*
  * @implemented
  */
-NTSTATUS NTAPI
-RtlCreateEnvironment(BOOLEAN Inherit,
-                     PWSTR *Environment)
+NTSTATUS
+NTAPI
+RtlCreateEnvironment(
+    BOOLEAN Inherit,
+    PWSTR *OutEnvironment)
 {
-   MEMORY_BASIC_INFORMATION MemInfo;
-   PVOID EnvPtr = NULL;
-   NTSTATUS Status = STATUS_SUCCESS;
-   SIZE_T RegionSize = PAGE_SIZE;
-
-   if (Inherit == TRUE)
-   {
-      RtlAcquirePebLock();
-
-      if (NtCurrentPeb()->ProcessParameters->Environment != NULL)
-      {
-         Status = NtQueryVirtualMemory(NtCurrentProcess(),
-                                       NtCurrentPeb()->ProcessParameters->Environment,
-                                       MemoryBasicInformation,
-                                       &MemInfo,
-                                       sizeof(MEMORY_BASIC_INFORMATION),
-                                       NULL);
-         if (!NT_SUCCESS(Status))
-         {
-            RtlReleasePebLock();
-            *Environment = NULL;
-            return(Status);
-         }
-
-         RegionSize = MemInfo.RegionSize;
-         Status = NtAllocateVirtualMemory(NtCurrentProcess(),
-                                          &EnvPtr,
-                                          0,
-                                          &RegionSize,
-                                          MEM_RESERVE | MEM_COMMIT,
-                                          PAGE_READWRITE);
-         if (!NT_SUCCESS(Status))
-         {
-            RtlReleasePebLock();
-            *Environment = NULL;
-            return(Status);
-         }
-
-         memmove(EnvPtr,
-                 NtCurrentPeb ()->ProcessParameters->Environment,
-                 MemInfo.RegionSize);
-
-         *Environment = EnvPtr;
-      }
+    MEMORY_BASIC_INFORMATION MemInfo;
+    PVOID CurrentEnvironment, NewEnvironment = NULL;
+    NTSTATUS Status = STATUS_SUCCESS;
+    SIZE_T RegionSize = PAGE_SIZE;
+
+    /* Check if we should inherit the current environment */
+    if (Inherit)
+    {
+        /* In this case we need to lock the PEB */
+        RtlAcquirePebLock();
+
+        /* Get a pointer to the current Environment and check if it's not NULL */
+        CurrentEnvironment = NtCurrentPeb()->ProcessParameters->Environment;
+        if (CurrentEnvironment != NULL)
+        {
+            /* Query the size of the current environment allocation */
+            Status = NtQueryVirtualMemory(NtCurrentProcess(),
+                                          CurrentEnvironment,
+                                          MemoryBasicInformation,
+                                          &MemInfo,
+                                          sizeof(MEMORY_BASIC_INFORMATION),
+                                          NULL);
+            if (!NT_SUCCESS(Status))
+            {
+                RtlReleasePebLock();
+                *OutEnvironment = NULL;
+                return Status;
+            }
 
-      RtlReleasePebLock ();
-   }
-   else
-   {
-      Status = NtAllocateVirtualMemory(NtCurrentProcess(),
-                                       &EnvPtr,
-                                       0,
-                                       &RegionSize,
-                                       MEM_RESERVE | MEM_COMMIT,
-                                       PAGE_READWRITE);
-      if (NT_SUCCESS(Status))
-      {
-         memset(EnvPtr,
-                0,
-                RegionSize);
-         *Environment = EnvPtr;
-      }
-   }
+            /* Allocate a new region of the same size */
+            RegionSize = MemInfo.RegionSize;
+            Status = NtAllocateVirtualMemory(NtCurrentProcess(),
+                                             &NewEnvironment,
+                                             0,
+                                             &RegionSize,
+                                             MEM_RESERVE | MEM_COMMIT,
+                                             PAGE_READWRITE);
+            if (!NT_SUCCESS(Status))
+            {
+                RtlReleasePebLock();
+                *OutEnvironment = NULL;
+                return Status;
+            }
 
-   return(Status);
+            /* Copy the current environment */
+            RtlCopyMemory(NewEnvironment,
+                          CurrentEnvironment,
+                          MemInfo.RegionSize);
+        }
+
+        /* We are done with the PEB, release the lock */
+        RtlReleasePebLock ();
+    }
+
+    /* Check if we still need an environment */
+    if (NewEnvironment == NULL)
+    {
+        /* Allocate a new environment */
+        Status = NtAllocateVirtualMemory(NtCurrentProcess(),
+                                         &NewEnvironment,
+                                         0,
+                                         &RegionSize,
+                                         MEM_RESERVE | MEM_COMMIT,
+                                         PAGE_READWRITE);
+        if (NT_SUCCESS(Status))
+        {
+            RtlZeroMemory(NewEnvironment, RegionSize);
+        }
+    }
+
+    *OutEnvironment = NewEnvironment;
+
+    return Status;
 }
 
 
@@ -315,7 +325,7 @@ RtlSetEnvironmentVariable(PWSTR *Environment,
       while (*env_end);
       env_end++;
       env_len = env_end - env;
-      DPRINT("environment length %ld characters\n", env_len);
+      DPRINT("environment length %lu characters\n", env_len);
 
       /* find where to insert */
       while (*wcs)