[PATCH] Support getting the shell folder path for users other =

Ge van Geldorp ge at thinstall.com
Sun Jan 27 11:08:18 CST 2008


than the current user and=0A=
the default user=0A=
---=0A=
 dlls/shell32/shellpath.c |   70 =
++++++++++++++++++++++++++++++++++++----------=0A=
 1 files changed, 55 insertions(+), 15 deletions(-)=0A=
=0A=
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c=0A=
index 5be77d7..f77fb43 100644=0A=
--- a/dlls/shell32/shellpath.c=0A=
+++ b/dlls/shell32/shellpath.c=0A=
@@ -46,6 +46,7 @@=0A=
 #include "pidl.h"=0A=
 #include "wine/unicode.h"=0A=
 #include "shlwapi.h"=0A=
+#include "sddl.h"=0A=
 =0A=
 WINE_DEFAULT_DEBUG_CHANNEL(shell);=0A=
 =0A=
@@ -1359,6 +1360,39 @@ static HRESULT _SHGetCurrentVersionPath(DWORD =
dwFlags, BYTE folder,=0A=
     return hr;=0A=
 }=0A=
 =0A=
+static LPWSTR _GetUserSidStringFromToken(HANDLE Token)=0A=
+{=0A=
+    char InfoBuffer[64];=0A=
+    PTOKEN_USER UserInfo;=0A=
+    DWORD InfoSize;=0A=
+    LPWSTR SidStr;=0A=
+=0A=
+    UserInfo =3D (PTOKEN_USER) InfoBuffer;=0A=
+    if (! GetTokenInformation(Token, TokenUser, InfoBuffer, =
sizeof(InfoBuffer),=0A=
+                              &InfoSize))=0A=
+    {=0A=
+        if (GetLastError() !=3D ERROR_INSUFFICIENT_BUFFER)=0A=
+            return NULL;=0A=
+        UserInfo =3D HeapAlloc(GetProcessHeap(), 0, InfoSize);=0A=
+        if (UserInfo =3D=3D NULL)=0A=
+            return NULL;=0A=
+        if (! GetTokenInformation(Token, TokenUser, UserInfo, InfoSize,=0A=
+                                  &InfoSize))=0A=
+        {=0A=
+            HeapFree(GetProcessHeap(), 0, UserInfo);=0A=
+            return NULL;=0A=
+        }=0A=
+    }=0A=
+=0A=
+    if (! ConvertSidToStringSidW(UserInfo->User.Sid, &SidStr))=0A=
+        SidStr =3D NULL;=0A=
+=0A=
+    if (UserInfo !=3D (PTOKEN_USER) InfoBuffer)=0A=
+        HeapFree(GetProcessHeap(), 0, UserInfo);=0A=
+=0A=
+    return SidStr;=0A=
+}=0A=
+=0A=
 /* Gets the user's path (unexpanded) for the CSIDL with index folder:=0A=
  * If SHGFP_TYPE_DEFAULT is set, calls _SHGetDefaultValue for it.  =
Otherwise=0A=
  * calls _SHGetUserShellFolderPath for it.  Where it looks depends on =
hToken:=0A=
@@ -1381,24 +1415,18 @@ static HRESULT _SHGetUserProfilePath(HANDLE =
hToken, DWORD dwFlags, BYTE folder,=0A=
     if (!pszPath)=0A=
         return E_INVALIDARG;=0A=
 =0A=
-    /* Only the current user and the default user are supported right =
now=0A=
-     * I'm afraid.=0A=
-     * FIXME: should be able to call GetTokenInformation on the token,=0A=
-     * then call ConvertSidToStringSidW on it to get the user prefix.=0A=
-     * But Wine's registry doesn't store user info by sid, it stores it=0A=
-     * by user name (and I don't know how to convert from a token to a=0A=
-     * user name).=0A=
-     */=0A=
-    if (hToken !=3D NULL && hToken !=3D (HANDLE)-1)=0A=
-    {=0A=
-        FIXME("unsupported for user other than current or default\n");=0A=
-        return E_FAIL;=0A=
-    }=0A=
-=0A=
     if (dwFlags & SHGFP_TYPE_DEFAULT)=0A=
+    {=0A=
+        if (hToken !=3D NULL && hToken !=3D (HANDLE)-1)=0A=
+        {=0A=
+            FIXME("unsupported for user other than current or =
default\n");=0A=
+            return E_FAIL;=0A=
+        }=0A=
         hr =3D _SHGetDefaultValue(folder, pszPath);=0A=
+    }=0A=
     else=0A=
     {=0A=
+        LPWSTR sidStr =3D NULL;=0A=
         LPCWSTR userPrefix =3D NULL;=0A=
         HKEY hRootKey;=0A=
 =0A=
@@ -1407,8 +1435,18 @@ static HRESULT _SHGetUserProfilePath(HANDLE =
hToken, DWORD dwFlags, BYTE folder,=0A=
             hRootKey =3D HKEY_USERS;=0A=
             userPrefix =3D DefaultW;=0A=
         }=0A=
-        else /* hToken =3D=3D NULL, other values disallowed above */=0A=
+        else if (hToken =3D=3D NULL)=0A=
             hRootKey =3D HKEY_CURRENT_USER;=0A=
+        else=0A=
+        {=0A=
+            hRootKey =3D HKEY_USERS;=0A=
+            userPrefix =3D _GetUserSidStringFromToken(hToken);=0A=
+            if (userPrefix =3D=3D NULL)=0A=
+            {=0A=
+                hr =3D HRESULT_FROM_WIN32(GetLastError());=0A=
+                goto error;=0A=
+            }=0A=
+        }=0A=
         hr =3D _SHGetUserShellFolderPath(hRootKey, userPrefix,=0A=
          CSIDL_Data[folder].szValueName, pszPath);=0A=
         if (FAILED(hr) && hRootKey !=3D HKEY_LOCAL_MACHINE)=0A=
@@ -1416,7 +1454,9 @@ static HRESULT _SHGetUserProfilePath(HANDLE =
hToken, DWORD dwFlags, BYTE folder,=0A=
              CSIDL_Data[folder].szValueName, pszPath);=0A=
         if (FAILED(hr))=0A=
             hr =3D _SHGetDefaultValue(folder, pszPath);=0A=
+        LocalFree(sidStr);=0A=
     }=0A=
+error:=0A=
     TRACE("returning 0x%08x (output path is %s)\n", hr, =
debugstr_w(pszPath));=0A=
     return hr;=0A=
 }=0A=
-- =0A=
1.5.2.4=0A=
=0A=

------=_NextPart_000_000A_01C8611C.9B939C60--




More information about the wine-patches mailing list