Fix code assuming that the Reg* functions set the last error code
[reactos.git] / reactos / lib / userenv / setup.c
index bd72482..ff64788 100644 (file)
@@ -1,4 +1,22 @@
-/* $Id: setup.c,v 1.3 2004/01/16 15:31:53 ekohl Exp $ 
+/*
+ *  ReactOS kernel
+ *  Copyright (C) 2004 ReactOS Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id$
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
  * PROGRAMMER:      Eric Kohl
  */
 
-#include <windows.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
+#include <precomp.h>
 
-#include <userenv.h>
+#define NDEBUG
+#include <debug.h>
 
-#include "internal.h"
 
-typedef struct _DIRDATA
+typedef struct _FOLDERDATA
 {
-  BOOL Hidden;
-  LPWSTR DirName;
-} DIRDATA, *PDIRDATA;
+  LPWSTR lpValueName;
+  LPWSTR lpPath;
+  UINT uId;
+  BOOL bHidden;
+  BOOL bShellFolder;
+  BOOL bUserShellFolder;
+} FOLDERDATA, *PFOLDERDATA;
 
 
-static DIRDATA
-DefaultUserDirectories[] =
+static FOLDERDATA
+UserShellFolders[] =
 {
-  {TRUE,  L"Application Data"},
-  {FALSE, L"Desktop"},
-  {FALSE, L"Favorites"},
-  {FALSE, L"My Documents"},
-  {TRUE,  L"PrintHood"},
-  {TRUE,  L"Recent"},
-  {FALSE, L"Start Menu"},
-  {FALSE, L"Start Menu\\Programs"},
-  {FALSE, L"Start Menu\\Programs\\Startup"},
-
-  {FALSE, NULL}
+  {L"AppData", L"Application Data", IDS_APPDATA, TRUE, TRUE, TRUE},
+  {L"Desktop", L"Desktop", IDS_DESKTOP, FALSE, TRUE, TRUE},
+  {L"Favorites", L"Favorites", IDS_FAVORITES, FALSE, TRUE, TRUE},
+  {L"Personal", L"My Documents", IDS_MYDOCUMENTS, FALSE, TRUE, TRUE},
+  {L"My Pictures", L"My Documents\\My Pictures", IDS_MYPICTURES, FALSE, TRUE, TRUE},
+  {L"My Music", L"My Documents\\My Music", IDS_MYMUSIC, FALSE, TRUE, TRUE},
+  {L"My Video", L"My Documents\\My Videos", IDS_MYVIDEOS, FALSE, TRUE, TRUE},
+  {L"NetHood", L"NetHood", IDS_NETHOOD, TRUE, TRUE, TRUE},
+  {L"PrintHood", L"PrintHood", IDS_PRINTHOOD, TRUE, TRUE, TRUE},
+  {L"Recent", L"Recent", IDS_RECENT, TRUE, TRUE, TRUE},
+  {L"SendTo", L"SendTo", IDS_SENDTO, FALSE, TRUE, TRUE},
+  {L"Templates", L"Templates", IDS_TEMPLATES, FALSE, TRUE, TRUE},
+  {L"Start Menu", L"Start Menu", IDS_STARTMENU, FALSE, TRUE, TRUE},
+  {L"Programs", L"Start Menu\\Programs", IDS_PROGRAMS, FALSE, TRUE, TRUE},
+  {L"Startup", L"Start Menu\\Programs\\Startup", IDS_STARTUP, FALSE, TRUE, TRUE},
+  {L"Local Settings", L"Local Settings", IDS_LOCALSETTINGS, TRUE, TRUE, TRUE},
+  {L"Local AppData", L"Local Settings\\Application Data", IDS_LOCALAPPDATA, TRUE, TRUE, TRUE},
+  {L"Temp", L"Local Settings\\Temp", IDS_TEMP, FALSE, FALSE, FALSE},
+  {L"Cache", L"Local Settings\\Temporary Internet Files", IDS_CACHE, FALSE, TRUE, TRUE},
+  {L"History", L"Local Settings\\History", IDS_HISTORY, FALSE, TRUE, TRUE},
+  {L"Cookies", L"Cookies", IDS_COOKIES, FALSE, TRUE, TRUE},
+  {NULL, NULL, -1, FALSE, FALSE, FALSE}
 };
 
 
-static DIRDATA
-AllUsersDirectories[] =
+static FOLDERDATA
+CommonShellFolders[] =
 {
-  {TRUE,  L"Application Data"},
-  {FALSE, L"Desktop"},
-  {FALSE, L"Favorites"},
-  {FALSE, L"My Documents"},
-  {FALSE, L"Start Menu"},
-  {FALSE, L"Start Menu\\Programs"},
-  {FALSE, L"Start Menu\\Programs\\Startup"},
-  {FALSE, L"Start Menu\\Programs\\Administrative Tools"},
-  {TRUE,  L"Templates"},
-  {FALSE, NULL}
+  {L"Common AppData", L"Application Data", IDS_APPDATA, TRUE, TRUE, TRUE},
+  {L"Common Desktop", L"Desktop", IDS_DESKTOP, FALSE, TRUE, TRUE},
+  {L"Common Favorites", L"Favorites", IDS_FAVORITES, FALSE, TRUE, TRUE},
+  {L"Common Start Menu", L"Start Menu", IDS_STARTMENU, FALSE, TRUE, TRUE},
+  {L"Common Programs", L"Start Menu\\Programs", IDS_PROGRAMS, FALSE, TRUE, TRUE},
+  {L"Common Administrative Tools", L"Start Menu\\Programs\\Administrative Tools", IDS_ADMINTOOLS, FALSE, TRUE, FALSE},
+  {L"Common Startup", L"Start Menu\\Programs\\Startup", IDS_STARTUP, FALSE, TRUE, TRUE},
+  {L"Common Templates", L"Templates", IDS_TEMPLATES, TRUE, TRUE, TRUE},
+  {L"Common Documents", L"My Documents", IDS_MYDOCUMENTS, FALSE, TRUE, TRUE},
+  {L"CommonPictures", L"My Documents\\My Pictures", IDS_MYPICTURES, FALSE, TRUE, TRUE},
+  {L"CommonMusic", L"My Documents\\My Music", IDS_MYMUSIC, FALSE, TRUE, TRUE},
+  {L"CommonVideo", L"My Documents\\My Videos", IDS_MYVIDEOS, FALSE, TRUE, TRUE},
+  {NULL, NULL, -1, FALSE, FALSE, FALSE}
 };
 
 
@@ -76,33 +109,46 @@ InitializeProfiles (VOID)
   WCHAR szProfilesPath[MAX_PATH];
   WCHAR szProfilePath[MAX_PATH];
   WCHAR szBuffer[MAX_PATH];
-  LPWSTR lpszPtr;
   DWORD dwLength;
-  PDIRDATA lpDirData;
-
+  PFOLDERDATA lpFolderData;
   HKEY hKey;
+  LONG Error;
 
-  if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
-                    L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
-                    0,
-                    KEY_ALL_ACCESS,
-                    &hKey))
+  /* Load profiles directory path */
+  if (!LoadStringW(hInstance,
+                 IDS_PROFILEPATH,
+                 szBuffer,
+                 MAX_PATH))
     {
       DPRINT1("Error: %lu\n", GetLastError());
       return FALSE;
     }
 
-  /* Get profiles path */
-  dwLength = MAX_PATH * sizeof(WCHAR);
-  if (RegQueryValueExW (hKey,
-                       L"ProfilesDirectory",
-                       NULL,
-                       NULL,
-                       (LPBYTE)szBuffer,
-                       &dwLength))
+  Error = RegOpenKeyExW (HKEY_LOCAL_MACHINE,
+                        L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
+                        0,
+                        KEY_ALL_ACCESS,
+                        &hKey);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1("Error: %lu\n", GetLastError());
+      DPRINT1("Error: %lu\n", Error);
+      SetLastError((DWORD)Error);
+      return FALSE;
+    }
+
+  /* Store profiles directory path */
+  dwLength = (wcslen (szBuffer) + 1) * sizeof(WCHAR);
+  Error = RegSetValueExW (hKey,
+                         L"ProfilesDirectory",
+                         0,
+                         REG_EXPAND_SZ,
+                         (LPBYTE)szBuffer,
+                         dwLength);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
       RegCloseKey (hKey);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
@@ -137,18 +183,22 @@ InitializeProfiles (VOID)
     }
 
   dwLength = (wcslen (szBuffer) + 1) * sizeof(WCHAR);
-  if (RegSetValueExW (hKey,
-                     L"DefaultUserProfile",
-                     0,
-                     REG_SZ,
-                     (LPBYTE)szBuffer,
-                     dwLength))
+  Error = RegSetValueExW (hKey,
+                         L"DefaultUserProfile",
+                         0,
+                         REG_SZ,
+                         (LPBYTE)szBuffer,
+                         dwLength);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1("Error: %lu\n", GetLastError());
+      DPRINT1("Error: %lu\n", Error);
       RegCloseKey (hKey);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
+  RegCloseKey (hKey);
+
   /* Create 'Default User' profile directory */
   wcscpy (szProfilePath, szProfilesPath);
   wcscat (szProfilePath, L"\\");
@@ -158,110 +208,509 @@ InitializeProfiles (VOID)
       if (GetLastError () != ERROR_ALREADY_EXISTS)
        {
          DPRINT1("Error: %lu\n", GetLastError());
-         RegCloseKey (hKey);
          return FALSE;
        }
     }
 
   /* Set current user profile */
-  SetEnvironmentVariableW (L"USERPROFILE", szProfilePath);
+  SetEnvironmentVariableW(L"USERPROFILE", szProfilePath);
 
   /* Create 'Default User' subdirectories */
   /* FIXME: Get these paths from the registry */
-  lpszPtr = AppendBackslash (szProfilePath);
-  lpDirData = &DefaultUserDirectories[0];
-  while (lpDirData->DirName != NULL)
+  lpFolderData = &UserShellFolders[0];
+  while (lpFolderData->lpValueName != NULL)
     {
-      wcscpy (lpszPtr, lpDirData->DirName);
+      wcscpy(szBuffer, szProfilePath);
+      wcscat(szBuffer, L"\\");
+
+      /* Append the folder name */
+      dwLength = wcslen(szBuffer);
+      if (!LoadStringW(hInstance,
+                      lpFolderData->uId,
+                      &szBuffer[dwLength],
+                      MAX_PATH - dwLength))
+       {
+         /* Use the default name instead */
+         wcscat(szBuffer, lpFolderData->lpPath);
+       }
 
-      if (!CreateDirectoryW (szProfilePath, NULL))
+      if (!CreateDirectoryW(szBuffer, NULL))
        {
-         if (GetLastError () != ERROR_ALREADY_EXISTS)
+         if (GetLastError() != ERROR_ALREADY_EXISTS)
            {
              DPRINT1("Error: %lu\n", GetLastError());
-             RegCloseKey (hKey);
              return FALSE;
            }
        }
 
-      if (lpDirData->Hidden == TRUE)
+      if (lpFolderData->bHidden == TRUE)
+       {
+         SetFileAttributesW(szBuffer,
+                            FILE_ATTRIBUTE_HIDDEN);
+       }
+
+      lpFolderData++;
+    }
+
+  /* Set default 'Shell Folders' values */
+  Error = RegOpenKeyExW(HKEY_USERS,
+                       L".Default\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
+                       0,
+                       KEY_ALL_ACCESS,
+                       &hKey);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
+      SetLastError((DWORD)Error);
+      return FALSE;
+    }
+
+  lpFolderData = &UserShellFolders[0];
+  while (lpFolderData->lpValueName != NULL)
+    {
+      if (lpFolderData->bShellFolder)
+       {
+         wcscpy(szBuffer, szProfilePath);
+         wcscat(szBuffer, L"\\");
+
+         /* Append the folder name */
+         dwLength = wcslen(szBuffer);
+         if (!LoadStringW(hInstance,
+                          lpFolderData->uId,
+                          &szBuffer[dwLength],
+                          MAX_PATH - dwLength))
+           {
+             /* Use the default name instead */
+             wcscat(szBuffer, lpFolderData->lpPath);
+           }
+
+         dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
+         Error = RegSetValueExW(hKey,
+                                lpFolderData->lpValueName,
+                                0,
+                                REG_SZ,
+                                (LPBYTE)szBuffer,
+                                dwLength);
+          if (Error != ERROR_SUCCESS)
+           {
+             DPRINT1("Error: %lu\n", Error);
+             RegCloseKey(hKey);
+              SetLastError((DWORD)Error);
+             return FALSE;
+           }
+       }
+
+      lpFolderData++;
+    }
+
+  /* Set 'Fonts' folder path */
+  GetWindowsDirectoryW(szBuffer, MAX_PATH);
+  wcscat(szBuffer, L"\\media\\fonts");
+
+  dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
+  Error = RegSetValueExW(hKey,
+                        L"Fonts",
+                        0,
+                        REG_SZ,
+                        (LPBYTE)szBuffer,
+                        dwLength);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
+      RegCloseKey(hKey);
+      SetLastError((DWORD)Error);
+      return FALSE;
+    }
+
+  RegCloseKey(hKey);
+
+  /* Set default 'User Shell Folders' values */
+  Error = RegOpenKeyExW(HKEY_USERS,
+                       L".Default\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
+                       0,
+                       KEY_ALL_ACCESS,
+                       &hKey);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
+      SetLastError((DWORD)Error);
+      return FALSE;
+    }
+
+  lpFolderData = &UserShellFolders[0];
+  while (lpFolderData->lpValueName != NULL)
+    {
+      if (lpFolderData->bUserShellFolder)
        {
-         SetFileAttributesW (szProfilePath,
-                             FILE_ATTRIBUTE_HIDDEN);
+         wcscpy(szBuffer, L"%USERPROFILE%\\");
+
+         /* Append the folder name */
+         dwLength = wcslen(szBuffer);
+         if (!LoadStringW(hInstance,
+                          lpFolderData->uId,
+                          &szBuffer[dwLength],
+                          MAX_PATH - dwLength))
+           {
+             /* Use the default name instead */
+             wcscat(szBuffer, lpFolderData->lpPath);
+           }
+
+         dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
+         Error = RegSetValueExW(hKey,
+                                lpFolderData->lpValueName,
+                                0,
+                                REG_EXPAND_SZ,
+                                (LPBYTE)szBuffer,
+                                dwLength);
+          if (Error != ERROR_SUCCESS)
+           {
+             DPRINT1("Error: %lu\n", Error);
+             RegCloseKey(hKey);
+              SetLastError((DWORD)Error);
+             return FALSE;
+           }
        }
 
-      lpDirData++;
+      lpFolderData++;
     }
 
+  RegCloseKey(hKey);
+
+
   /* Set 'AllUsersProfile' value */
-  wcscpy (szBuffer, L"All Users");
-  if (!AppendSystemPostfix (szBuffer, MAX_PATH))
+  wcscpy(szBuffer, L"All Users");
+  if (!AppendSystemPostfix(szBuffer, MAX_PATH))
     {
       DPRINT1("AppendSystemPostfix() failed\n", GetLastError());
-      RegCloseKey (hKey);
       return FALSE;
     }
 
-  dwLength = (wcslen (szBuffer) + 1) * sizeof(WCHAR);
-  if (RegSetValueExW (hKey,
-                     L"AllUsersProfile",
-                     0,
-                     REG_SZ,
-                     (LPBYTE)szBuffer,
-                     dwLength))
+  Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                       L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList",
+                       0,
+                       KEY_ALL_ACCESS,
+                       &hKey);
+  if (Error != ERROR_SUCCESS)
     {
-      DPRINT1("Error: %lu\n", GetLastError());
+      DPRINT1("Error: %lu\n", Error);
+      SetLastError((DWORD)Error);
+      return FALSE;
+    }
+
+  dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
+  Error = RegSetValueExW(hKey,
+                        L"AllUsersProfile",
+                        0,
+                        REG_SZ,
+                        (LPBYTE)szBuffer,
+                        dwLength);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
       RegCloseKey (hKey);
+      SetLastError((DWORD)Error);
       return FALSE;
     }
 
+  RegCloseKey(hKey);
+
+
   /* Create 'All Users' profile directory */
-  wcscpy (szProfilePath, szProfilesPath);
-  wcscat (szProfilePath, L"\\");
-  wcscat (szProfilePath, szBuffer);
-  if (!CreateDirectoryW (szProfilePath, NULL))
+  wcscpy(szProfilePath, szProfilesPath);
+  wcscat(szProfilePath, L"\\");
+  wcscat(szProfilePath, szBuffer);
+  if (!CreateDirectoryW(szProfilePath, NULL))
     {
-      if (GetLastError () != ERROR_ALREADY_EXISTS)
+      if (GetLastError() != ERROR_ALREADY_EXISTS)
        {
          DPRINT1("Error: %lu\n", GetLastError());
-         RegCloseKey (hKey);
          return FALSE;
        }
     }
 
   /* Set 'All Users' profile */
-  SetEnvironmentVariableW (L"ALLUSERSPROFILE", szProfilePath);
+  SetEnvironmentVariableW(L"ALLUSERSPROFILE", szProfilePath);
 
   /* Create 'All Users' subdirectories */
   /* FIXME: Take these paths from the registry */
-  lpszPtr = AppendBackslash (szProfilePath);
-  lpDirData = &AllUsersDirectories[0];
-  while (lpDirData->DirName != NULL)
+  lpFolderData = &CommonShellFolders[0];
+  while (lpFolderData->lpValueName != NULL)
     {
-      wcscpy (lpszPtr, lpDirData->DirName);
+      wcscpy(szBuffer, szProfilePath);
+      wcscat(szBuffer, L"\\");
+
+      /* Append the folder name */
+      dwLength = wcslen(szBuffer);
+      if (!LoadStringW(hInstance,
+                      lpFolderData->uId,
+                      &szBuffer[dwLength],
+                      MAX_PATH - dwLength))
+       {
+         /* Use the default name instead */
+         wcscat(szBuffer, lpFolderData->lpPath);
+       }
 
-      if (!CreateDirectoryW (szProfilePath, NULL))
+      if (!CreateDirectoryW(szBuffer, NULL))
        {
-         if (GetLastError () != ERROR_ALREADY_EXISTS)
+         if (GetLastError() != ERROR_ALREADY_EXISTS)
            {
              DPRINT1("Error: %lu\n", GetLastError());
-             RegCloseKey (hKey);
              return FALSE;
            }
        }
 
-      if (lpDirData->Hidden == TRUE)
+      if (lpFolderData->bHidden)
+       {
+         SetFileAttributesW(szBuffer,
+                            FILE_ATTRIBUTE_HIDDEN);
+       }
+
+      lpFolderData++;
+    }
+
+  /* Set common 'Shell Folders' values */
+  Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                       L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
+                       0,
+                       KEY_ALL_ACCESS,
+                       &hKey);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
+      SetLastError((DWORD)Error);
+      return FALSE;
+    }
+
+  lpFolderData = &CommonShellFolders[0];
+  while (lpFolderData->lpValueName != NULL)
+    {
+      if (lpFolderData->bShellFolder)
+       {
+         wcscpy(szBuffer, szProfilePath);
+         wcscat(szBuffer, L"\\");
+
+         /* Append the folder name */
+         dwLength = wcslen(szBuffer);
+         if (!LoadStringW(hInstance,
+                          lpFolderData->uId,
+                          &szBuffer[dwLength],
+                          MAX_PATH - dwLength))
+           {
+             /* Use the default name instead */
+             wcscat(szBuffer, lpFolderData->lpPath);
+           }
+
+         dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
+         Error = RegSetValueExW(hKey,
+                                lpFolderData->lpValueName,
+                                0,
+                                REG_SZ,
+                                (LPBYTE)szBuffer,
+                                dwLength);
+          if (Error != ERROR_SUCCESS)
+           {
+             DPRINT1("Error: %lu\n", Error);
+             RegCloseKey(hKey);
+              SetLastError((DWORD)Error);
+             return FALSE;
+           }
+       }
+
+      lpFolderData++;
+    }
+
+  RegCloseKey(hKey);
+
+  /* Set common 'User Shell Folders' values */
+  Error = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                       L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
+                       0,
+                       KEY_ALL_ACCESS,
+                       &hKey);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
+      SetLastError((DWORD)Error);
+      return FALSE;
+    }
+
+  lpFolderData = &CommonShellFolders[0];
+  while (lpFolderData->lpValueName != NULL)
+    {
+      if (lpFolderData->bUserShellFolder)
        {
-         SetFileAttributesW (szProfilePath,
-                             FILE_ATTRIBUTE_HIDDEN);
+         wcscpy(szBuffer, L"%ALLUSERSPROFILE%\\");
+
+         /* Append the folder name */
+         dwLength = wcslen(szBuffer);
+         if (!LoadStringW(hInstance,
+                          lpFolderData->uId,
+                          &szBuffer[dwLength],
+                          MAX_PATH - dwLength))
+           {
+             /* Use the default name instead */
+             wcscat(szBuffer, lpFolderData->lpPath);
+           }
+
+         dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
+         Error = RegSetValueExW(hKey,
+                                lpFolderData->lpValueName,
+                                0,
+                                REG_EXPAND_SZ,
+                                (LPBYTE)szBuffer,
+                                dwLength);
+          if (Error != ERROR_SUCCESS)
+           {
+             DPRINT1("Error: %lu\n", Error);
+             RegCloseKey(hKey);
+              SetLastError((DWORD)Error);
+             return FALSE;
+           }
        }
 
-      lpDirData++;
+      lpFolderData++;
+    }
+
+  RegCloseKey(hKey);
+
+  /* Load 'Program Files' location */
+  if (!LoadStringW(hInstance,
+                 IDS_PROGRAMFILES,
+                 szBuffer,
+                 MAX_PATH))
+    {
+      DPRINT1("Error: %lu\n", GetLastError());
+      return FALSE;
+    }
+
+  /* Expand it */
+  if (!ExpandEnvironmentStringsW (szBuffer,
+                                 szProfilesPath,
+                                 MAX_PATH))
+    {
+      DPRINT1("Error: %lu\n", GetLastError());
+      RegCloseKey (hKey);
+      return FALSE;
+    }
+
+  /* Store it */
+  Error = RegOpenKeyExW (HKEY_LOCAL_MACHINE,
+                        L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion",
+                        0,
+                        KEY_ALL_ACCESS,
+                        &hKey);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
+      SetLastError((DWORD)Error);
+      return FALSE;
+    }
+
+  dwLength = (wcslen (szProfilesPath) + 1) * sizeof(WCHAR);
+  Error = RegSetValueExW (hKey,
+                         L"ProgramFilesDir",
+                         0,
+                         REG_SZ,
+                         (LPBYTE)szProfilesPath,
+                         dwLength);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
+      RegCloseKey (hKey);
+      SetLastError((DWORD)Error);
+      return FALSE;
     }
 
   RegCloseKey (hKey);
 
-  DPRINT1("Success\n");
+  /* Create directory */
+  if (!CreateDirectoryW (szProfilesPath, NULL))
+    {
+      if (GetLastError () != ERROR_ALREADY_EXISTS)
+       {
+         DPRINT1("Error: %lu\n", GetLastError());
+         return FALSE;
+       }
+    }
+
+
+  DPRINT("Success\n");
 
   return TRUE;
 }
+
+
+BOOL
+UpdateUsersShellFolderSettings(LPCWSTR lpUserProfilePath,
+                              HKEY hUserKey)
+{
+  WCHAR szBuffer[MAX_PATH];
+  DWORD dwLength;
+  PFOLDERDATA lpFolderData;
+  HKEY hFoldersKey;
+  LONG Error;
+
+  DPRINT("UpdateUsersShellFolderSettings() called\n");
+
+  DPRINT("User profile path: %S\n", lpUserProfilePath);
+
+  Error = RegOpenKeyExW(hUserKey,
+                       L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
+                       0,
+                       KEY_ALL_ACCESS,
+                       &hFoldersKey);
+  if (Error != ERROR_SUCCESS)
+    {
+      DPRINT1("Error: %lu\n", Error);
+      SetLastError((DWORD)Error);
+      return FALSE;
+    }
+
+  lpFolderData = &UserShellFolders[0];
+  while (lpFolderData->lpValueName != NULL)
+    {
+      if (lpFolderData->bShellFolder)
+       {
+         wcscpy(szBuffer, lpUserProfilePath);
+         wcscat(szBuffer, L"\\");
+
+         /* Append the folder name */
+         dwLength = wcslen(szBuffer);
+         if (!LoadStringW(hInstance,
+                          lpFolderData->uId,
+                          &szBuffer[dwLength],
+                          MAX_PATH - dwLength))
+           {
+             /* Use the default name instead */
+             wcscat(szBuffer, lpFolderData->lpPath);
+           }
+
+         DPRINT("%S: %S\n", lpFolderData->lpValueName, szBuffer);
+
+         dwLength = (wcslen(szBuffer) + 1) * sizeof(WCHAR);
+         Error = RegSetValueExW(hFoldersKey,
+                                lpFolderData->lpValueName,
+                                0,
+                                REG_SZ,
+                                (LPBYTE)szBuffer,
+                                dwLength);
+          if (Error != ERROR_SUCCESS)
+           {
+             DPRINT1("Error: %lu\n", Error);
+             RegCloseKey(hFoldersKey);
+              SetLastError((DWORD)Error);
+             return FALSE;
+           }
+       }
+
+      lpFolderData++;
+    }
+
+  RegCloseKey(hFoldersKey);
+
+  DPRINT("UpdateUsersShellFolderSettings() done\n");
+
+  return TRUE;
+}
+
+/* EOF */