[shellpath.c] Taking into account the profile value set in wine config file

Fabrice Ménard menard.fabrice at wanadoo.fr
Mon Nov 1 17:35:22 CST 2004


Hi all,

I'm currently setting wine for a multi-user environment.
I want to have the fake windows directory shared by all users and all user specific
stuffs put in their respective home directory.
So, in each user wine config file there is a profile value under the [wine] section.
For example:

 [wine]
 "GraphicsDriver" = "x11drv"  ; Affichage sous X
 "ShellLinker"  = "wineshelllink" ; Script de création des liens
 ; Chemins
 "Windows"   = "c:\\windows"
 "System"   = "c:\\windows\\system"
 "Temp"    = "z:"
 "Path"    = "c:\\windows;c:\\windows\\system;c:\\windows\\system32"
 "Profile"   = "d:\\.wine\\Profile"

with d: pointing to the user's home directory.

When launching regedit, the profile value is converted in HCU\Environment\USERPROFILE =  "d:\.wine\Profile".
So far so good.  But, when I setup the environment with
 
 rundll32 setupapi.dll,InstallHinfSection DefaultInstall 128 wine.inf

the system keeps setting up the user specific profiles in c:\windows\profile (the default).

Searching through the sources, I came to the _SHExpandEnvironmentStrings function in shellpath.c
that never checks the existence of the former registry key.  So I added some code.
With this patch, I've got the following results:
- the All User profile dir is still located in c:\windows\system\profiles
- the user's specific profile dir is in /home/user/.wine/Profile
Exactly what I wanted.
Send me a note if it breaks something or if I messed up anything.

Here is the patch

Index: shellpath.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shellpath.c,v
retrieving revision 1.94
diff -u -c -r1.94 shellpath.c
cvs server: conflicting specifications of output style
*** shellpath.c 28 Oct 2004 20:58:51 -0000 1.94
--- shellpath.c 1 Nov 2004 22:14:43 -0000
***************
*** 742,747 ****
--- 742,749 ----
   */
  static const WCHAR szDefaultProfileDirW[] = {'w','i','n','d','o','w','s','\\','p','r','o','f','i','l','e','s','\0'};
  static const WCHAR AllUsersW[] = {'A','l','l',' ','U','s','e','r','s','\0'};
+ static const WCHAR EnvironmentW[] = {'E','n','v','i','r','o','n','m','e','n','t','\0'};
+ static const WCHAR UserValueW[] = {'U','S','E','R','P','R','O','F','I','L','E','\0'};
  
  typedef enum _CSIDL_Type {
      CSIDL_Type_User,
***************
*** 1396,1401 ****
--- 1398,1428 ----
      return HRESULT_FROM_WIN32(lRet);
  }
  
+ /* Gets the value of USERPROFILE in KCU\Environment if it exists
+  * otherwise returns an error value
+  */
+ static HRESULT _SHGetUserProfilesPrefix(LPWSTR szValue)
+ {
+      LONG res;
+      HKEY hkey = 0;
+      DWORD len = MAX_PATH*sizeof(WCHAR);
+      
+      res = RegOpenKeyExW(HKEY_CURRENT_USER, EnvironmentW, 0, KEY_READ, &hkey);
+      if (res == ERROR_SUCCESS)
+      {
+  res = RegQueryValueExW(hkey, UserValueW, NULL, NULL, (LPBYTE)szValue, &len);  
+  if (res == ERROR_SUCCESS)
+  {
+       len /= sizeof(WCHAR);
+       szValue[len] = '\0';
+       RegCloseKey(hkey);
+       return ERROR_SUCCESS;
+  }
+  RegCloseKey(hkey);
+      }
+      return !ERROR_SUCCESS;
+ }
+ 
  /* Reads the value named szValueName from the key profilesKey (assumed to be
   * opened by _SHOpenProfilesKey) into szValue, which is assumed to be MAX_PATH
   * WCHARs in length.  If it doesn't exist, returns szDefault (and saves
***************
*** 1453,1458 ****
--- 1480,1486 ----
  {
      HRESULT hr;
      WCHAR szTemp[MAX_PATH], szProfilesPrefix[MAX_PATH] = { 0 };
+     WCHAR szUserProfilePrefix[MAX_PATH] = { 0 };
      HKEY key = NULL;
  
      TRACE("%s, %p\n", debugstr_w(szSrc), szDest);
***************
*** 1497,1506 ****
              WCHAR userName[MAX_PATH];
              DWORD userLen = MAX_PATH;
  
!             strcpyW(szDest, szProfilesPrefix);
!             GetUserNameW(userName, &userLen);
!             PathAppendW(szDest, userName);
!             PathAppendW(szDest, szTemp + strlenW(UserProfileW));
          }
          else if (!strncmpiW(szTemp, SystemDriveW, strlenW(SystemDriveW)))
          {
--- 1525,1543 ----
              WCHAR userName[MAX_PATH];
              DWORD userLen = MAX_PATH;
  
!      /* Giving a chance to the profile parameter (in wine conf file) */
!             if (!_SHGetUserProfilesPrefix(szUserProfilePrefix))
!      {
!    strcpyW(szDest, szUserProfilePrefix);
!    PathAppendW(szDest, szTemp + strlenW(UserProfileW));
!      }
!      else
!      {
!    strcpyW(szDest, szProfilesPrefix);
!    GetUserNameW(userName, &userLen);
!    PathAppendW(szDest, userName);
!    PathAppendW(szDest, szTemp + strlenW(UserProfileW));
!      }
          }
          else if (!strncmpiW(szTemp, SystemDriveW, strlenW(SystemDriveW)))
          {

Here is the changelog:

 * dlls/shell32/shellpath.c: Fabrice Ménard  <menard.fabrice at wanadoo.fr>
_SHExpandEnvironmentStrings must consider KCU\Environment\USERPROFILE.

-- 
Fabrice Ménard
menard.fabrice at wanadoo.fr




More information about the wine-patches mailing list