Ge van Geldorp : shell32: Support getting the shell folder path for users other than the current user and the default user .

Alexandre Julliard julliard at winehq.org
Thu Mar 27 07:22:46 CDT 2008


Module: wine
Branch: master
Commit: 35d7f7061247158b34ec46e7c8ec6ffb75e45a57
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=35d7f7061247158b34ec46e7c8ec6ffb75e45a57

Author: Ge van Geldorp <ge at thinstall.com>
Date:   Thu Mar 27 00:34:42 2008 +0100

shell32: Support getting the shell folder path for users other than the current user and the default user.

---

 dlls/shell32/shellpath.c |   70 ++++++++++++++++++++++++++++++++++++----------
 1 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c
index 738e9e3..c4ae688 100644
--- a/dlls/shell32/shellpath.c
+++ b/dlls/shell32/shellpath.c
@@ -47,6 +47,7 @@
 #include "wine/unicode.h"
 #include "shlwapi.h"
 #include "xdg.h"
+#include "sddl.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
@@ -1356,6 +1357,39 @@ static HRESULT _SHGetCurrentVersionPath(DWORD dwFlags, BYTE folder,
     return hr;
 }
 
+static LPWSTR _GetUserSidStringFromToken(HANDLE Token)
+{
+    char InfoBuffer[64];
+    PTOKEN_USER UserInfo;
+    DWORD InfoSize;
+    LPWSTR SidStr;
+
+    UserInfo = (PTOKEN_USER) InfoBuffer;
+    if (! GetTokenInformation(Token, TokenUser, InfoBuffer, sizeof(InfoBuffer),
+                              &InfoSize))
+    {
+        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+            return NULL;
+        UserInfo = HeapAlloc(GetProcessHeap(), 0, InfoSize);
+        if (UserInfo == NULL)
+            return NULL;
+        if (! GetTokenInformation(Token, TokenUser, UserInfo, InfoSize,
+                                  &InfoSize))
+        {
+            HeapFree(GetProcessHeap(), 0, UserInfo);
+            return NULL;
+        }
+    }
+
+    if (! ConvertSidToStringSidW(UserInfo->User.Sid, &SidStr))
+        SidStr = NULL;
+
+    if (UserInfo != (PTOKEN_USER) InfoBuffer)
+        HeapFree(GetProcessHeap(), 0, UserInfo);
+
+    return SidStr;
+}
+
 /* Gets the user's path (unexpanded) for the CSIDL with index folder:
  * If SHGFP_TYPE_DEFAULT is set, calls _SHGetDefaultValue for it.  Otherwise
  * calls _SHGetUserShellFolderPath for it.  Where it looks depends on hToken:
@@ -1378,22 +1412,15 @@ static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder,
     if (!pszPath)
         return E_INVALIDARG;
 
-    /* Only the current user and the default user are supported right now
-     * I'm afraid.
-     * FIXME: should be able to call GetTokenInformation on the token,
-     * then call ConvertSidToStringSidW on it to get the user prefix.
-     * But Wine's registry doesn't store user info by sid, it stores it
-     * by user name (and I don't know how to convert from a token to a
-     * user name).
-     */
-    if (hToken != NULL && hToken != (HANDLE)-1)
-    {
-        FIXME("unsupported for user other than current or default\n");
-        return E_FAIL;
-    }
-
     if (dwFlags & SHGFP_TYPE_DEFAULT)
+    {
+        if (hToken != NULL && hToken != (HANDLE)-1)
+        {
+            FIXME("unsupported for user other than current or default\n");
+            return E_FAIL;
+        }
         hr = _SHGetDefaultValue(folder, pszPath);
+    }
     else
     {
         LPCWSTR userPrefix = NULL;
@@ -1404,8 +1431,18 @@ static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder,
             hRootKey = HKEY_USERS;
             userPrefix = DefaultW;
         }
-        else /* hToken == NULL, other values disallowed above */
+        else if (hToken == NULL)
             hRootKey = HKEY_CURRENT_USER;
+        else
+        {
+            hRootKey = HKEY_USERS;
+            userPrefix = _GetUserSidStringFromToken(hToken);
+            if (userPrefix == NULL)
+            {
+                hr = E_FAIL;
+                goto error;
+            }
+        }
         hr = _SHGetUserShellFolderPath(hRootKey, userPrefix,
          CSIDL_Data[folder].szValueName, pszPath);
         if (FAILED(hr) && hRootKey != HKEY_LOCAL_MACHINE)
@@ -1413,7 +1450,10 @@ static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder,
              CSIDL_Data[folder].szValueName, pszPath);
         if (FAILED(hr))
             hr = _SHGetDefaultValue(folder, pszPath);
+        if (userPrefix != NULL && userPrefix != DefaultW)
+            LocalFree((HLOCAL) userPrefix);
     }
+error:
     TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath));
     return hr;
 }




More information about the wine-cvs mailing list