Fix code assuming that the Reg* functions set the last error code
[reactos.git] / reactos / lib / userenv / environment.c
index cca1da7..d5f5bb5 100644 (file)
  * PROGRAMMER:      Eric Kohl
  */
 
-#include "precomp.h"
+#include <precomp.h>
+
+#define NDEBUG
+#include <debug.h>
 
 
 static BOOL
@@ -166,6 +169,7 @@ GetCurrentUserKey (HANDLE hToken)
 {
   UNICODE_STRING SidString;
   HKEY hKey;
+  LONG Error;
 
   if (!GetUserSidFromToken (hToken,
                            &SidString))
@@ -174,14 +178,16 @@ GetCurrentUserKey (HANDLE hToken)
       return NULL;
     }
 
-  if (RegOpenKeyExW (HKEY_USERS,
-                    SidString.Buffer,
-                    0,
-                    KEY_ALL_ACCESS,
-                    &hKey))
+  Error = RegOpenKeyExW (HKEY_USERS,
+                        SidString.Buffer,
+                        0,
+                        KEY_ALL_ACCESS,
+                        &hKey);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", GetLastError());
+      DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", Error);
       RtlFreeUnicodeString (&SidString);
+      SetLastError((DWORD)Error);
       return NULL;
     }
 
@@ -206,32 +212,37 @@ SetUserEnvironment (LPVOID *lpEnvironment,
   DWORD i;
   LPWSTR lpValueName;
   LPWSTR lpValueData;
-
-  if (RegOpenKeyExW (hKey,
-                    lpSubKeyName,
-                    0,
-                    KEY_ALL_ACCESS,
-                    &hEnvKey))
+  LONG Error;
+
+  Error = RegOpenKeyExW (hKey,
+                        lpSubKeyName,
+                        0,
+                        KEY_ALL_ACCESS,
+                        &hEnvKey);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", GetLastError());
+      DPRINT1 ("RegOpenKeyExW() failed (Error %ld)\n", Error);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
-  if (RegQueryInfoKey (hEnvKey,
-                      NULL,
-                      NULL,
-                      NULL,
-                      NULL,
-                      NULL,
-                      NULL,
-                      &dwValues,
-                      &dwMaxValueNameLength,
-                      &dwMaxValueDataLength,
-                      NULL,
-                      NULL))
+  Error = RegQueryInfoKey (hEnvKey,
+                          NULL,
+                          NULL,
+                          NULL,
+                          NULL,
+                          NULL,
+                          NULL,
+                          &dwValues,
+                          &dwMaxValueNameLength,
+                          &dwMaxValueDataLength,
+                          NULL,
+                          NULL);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1 ("RegQueryInforKey() failed (Error %ld)\n", GetLastError());
+      DPRINT1 ("RegQueryInforKey() failed (Error %ld)\n", Error);
       RegCloseKey (hEnvKey);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
@@ -311,13 +322,17 @@ CreateEnvironmentBlock (LPVOID *lpEnvironment,
   DPRINT("CreateEnvironmentBlock() called\n");
 
   if (lpEnvironment == NULL)
-    return FALSE;
+    {
+      SetLastError(ERROR_INVALID_PARAMETER);
+      return FALSE;
+    }
 
   Status = RtlCreateEnvironment ((BOOLEAN)bInherit,
                                 (PWSTR*)lpEnvironment);
   if (!NT_SUCCESS (Status))
     {
       DPRINT1 ("RtlCreateEnvironment() failed (Status %lx)\n", Status);
+      SetLastError (RtlNtStatusToDosError (Status));
       return FALSE;
     }
 
@@ -387,11 +402,136 @@ DestroyEnvironmentBlock (LPVOID lpEnvironment)
   DPRINT ("DestroyEnvironmentBlock() called\n");
 
   if (lpEnvironment == NULL)
-    return FALSE;
+    {
+      SetLastError(ERROR_INVALID_PARAMETER);
+      return FALSE;
+    }
 
   RtlDestroyEnvironment (lpEnvironment);
 
   return TRUE;
 }
 
+
+BOOL WINAPI
+ExpandEnvironmentStringsForUserW(IN HANDLE hToken,
+                                 IN LPCWSTR lpSrc,
+                                 OUT LPWSTR lpDest,
+                                 IN DWORD dwSize)
+{
+    PVOID lpEnvironment;
+    BOOL Ret = FALSE;
+
+    if (lpSrc == NULL || lpDest == NULL || dwSize == 0)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    if (CreateEnvironmentBlock(&lpEnvironment,
+                               hToken,
+                               FALSE))
+    {
+        UNICODE_STRING SrcU, DestU;
+        NTSTATUS Status;
+
+        /* initialize the strings */
+        RtlInitUnicodeString(&SrcU,
+                             lpSrc);
+        DestU.Length = 0;
+        DestU.MaximumLength = dwSize * sizeof(WCHAR);
+        DestU.Buffer = lpDest;
+
+        /* expand the strings */
+        Status = RtlExpandEnvironmentStrings_U((PWSTR)lpEnvironment,
+                                               &SrcU,
+                                               &DestU,
+                                               NULL);
+
+        DestroyEnvironmentBlock(lpEnvironment);
+
+        if (NT_SUCCESS(Status))
+        {
+            Ret = TRUE;
+        }
+        else
+        {
+            SetLastError(RtlNtStatusToDosError(Status));
+        }
+    }
+
+    return Ret;
+}
+
+
+BOOL WINAPI
+ExpandEnvironmentStringsForUserA(IN HANDLE hToken,
+                                 IN LPCSTR lpSrc,
+                                 OUT LPSTR lpDest,
+                                 IN DWORD dwSize)
+{
+    DWORD dwSrcLen;
+    LPWSTR lpSrcW = NULL, lpDestW = NULL;
+    BOOL Ret = FALSE;
+
+    if (lpSrc == NULL || lpDest == NULL || dwSize == 0)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    dwSrcLen = strlen(lpSrc);
+    lpSrcW = (LPWSTR)GlobalAlloc(GMEM_FIXED,
+                                 (dwSrcLen + 1) * sizeof(WCHAR));
+    if (lpSrcW == NULL ||
+        MultiByteToWideChar(CP_ACP,
+                            0,
+                            lpSrc,
+                            -1,
+                            lpSrcW,
+                            dwSrcLen + 1) == 0)
+    {
+        goto Cleanup;
+    }
+
+    lpDestW = (LPWSTR)GlobalAlloc(GMEM_FIXED,
+                                  dwSize * sizeof(WCHAR));
+    if (lpDestW == NULL)
+    {
+        goto Cleanup;
+    }
+
+    Ret = ExpandEnvironmentStringsForUserW(hToken,
+                                           lpSrcW,
+                                           lpDestW,
+                                           dwSize);
+    if (Ret)
+    {
+        if (WideCharToMultiByte(CP_ACP,
+                                0,
+                                lpDestW,
+                                -1,
+                                lpDest,
+                                dwSize,
+                                NULL,
+                                NULL) == 0)
+        {
+            Ret = FALSE;
+        }
+    }
+
+Cleanup:
+    if (lpSrcW != NULL)
+    {
+        GlobalFree((HGLOBAL)lpSrcW);
+    }
+
+    if (lpDestW != NULL)
+    {
+        GlobalFree((HGLOBAL)lpDestW);
+    }
+
+    return Ret;
+}
+
 /* EOF */