Mariusz Pluciński : shell32: Add support of known folders redirection to Redirect.

Alexandre Julliard julliard at winehq.org
Wed Jun 29 15:47:44 CDT 2011


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

Author: Mariusz Pluciński <vshader at gmail.com>
Date:   Wed Jun 29 19:37:06 2011 +0200

shell32: Add support of known folders redirection to Redirect.

---

 dlls/shell32/shellpath.c       |   87 ++++++++++++++++++++++++++++++++++++++-
 dlls/shell32/tests/shellpath.c |    6 ---
 2 files changed, 84 insertions(+), 9 deletions(-)

diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c
index 6328ec5..e107f0e 100644
--- a/dlls/shell32/shellpath.c
+++ b/dlls/shell32/shellpath.c
@@ -817,6 +817,7 @@ static const WCHAR szSHFolders[] = {'S','o','f','t','w','a','r','e','\\','M','i'
 static const WCHAR szSHUserFolders[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','U','s','e','r',' ','S','h','e','l','l',' ','F','o','l','d','e','r','s','\0'};
 static const WCHAR szDefaultProfileDirW[] = {'u','s','e','r','s',0};
 static const WCHAR szKnownFolderDescriptions[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','F','o','l','d','e','r','D','e','s','c','r','i','p','t','i','o','n','s','\0'};
+static const WCHAR szKnownFolderRedirections[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','U','s','e','r',' ','S','h','e','l','l',' ','F','o','l','d','e','r','s',0};
 static const WCHAR AllUsersW[] = {'P','u','b','l','i','c',0};
 
 typedef enum _CSIDL_Type {
@@ -3124,6 +3125,88 @@ static HRESULT get_known_folder_registry_path(
     return hr;
 }
 
+/*
+ * Internal function to get place where folder redirection information are stored.
+ *
+ * Parameters:
+ *  rfid            [I] pointer to known folder identifier (may be NULL)
+ *  rootKey         [O] root key where the redirection information are stored
+ *                      It can be HKLM for COMMON folders, and HKCU for PERUSER folders.
+ *                      However, besides root key, path is always that same, and is stored
+ *                      as "szKnownFolderRedirections" constant
+ */
+static HRESULT WINAPI get_known_folder_redirection_place(
+    REFKNOWNFOLDERID rfid,
+    HKEY *rootKey)
+{
+    HRESULT hr;
+    LPWSTR lpRegistryPath = NULL;
+    KF_CATEGORY category;
+    DWORD dwSize;
+
+    /* first, get known folder's category */
+    hr = get_known_folder_registry_path(rfid, NULL, &lpRegistryPath);
+
+    if(SUCCEEDED(hr))
+    {
+        dwSize = sizeof(category);
+        hr = HRESULT_FROM_WIN32(RegGetValueW(HKEY_LOCAL_MACHINE, lpRegistryPath, szCategory, RRF_RT_DWORD, NULL, &category, &dwSize));
+    }
+
+    if(SUCCEEDED(hr))
+    {
+        if(category == KF_CATEGORY_COMMON)
+        {
+            *rootKey = HKEY_LOCAL_MACHINE;
+            hr = S_OK;
+        }
+        else if(category == KF_CATEGORY_PERUSER)
+        {
+            *rootKey = HKEY_CURRENT_USER;
+            hr = S_OK;
+        }
+        else
+            hr = E_FAIL;
+    }
+
+    HeapFree(GetProcessHeap(), 0, lpRegistryPath);
+    return hr;
+}
+
+static HRESULT WINAPI redirect_known_folder(
+    REFKNOWNFOLDERID rfid,
+    HWND hwnd,
+    KF_REDIRECT_FLAGS flags,
+    LPCWSTR pszTargetPath,
+    UINT cFolders,
+    KNOWNFOLDERID const *pExclusion,
+    LPWSTR *ppszError)
+{
+    HRESULT hr;
+    HKEY rootKey = HKEY_LOCAL_MACHINE, hKey;
+    WCHAR sGuid[39];
+    TRACE("(%s, %p, 0x%08x, %s, %d, %p, %p)\n", debugstr_guid(rfid), hwnd, flags, debugstr_w(pszTargetPath), cFolders, pExclusion, ppszError);
+
+    /* get path to redirection storage */
+    hr = get_known_folder_redirection_place(rfid, &rootKey);
+
+    /* write redirection information */
+    if(SUCCEEDED(hr))
+        hr = HRESULT_FROM_WIN32(RegCreateKeyExW(rootKey, szKnownFolderRedirections, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL));
+
+    if(SUCCEEDED(hr))
+    {
+        StringFromGUID2(rfid, sGuid, sizeof(sGuid)/sizeof(sGuid[0]));
+
+        hr = HRESULT_FROM_WIN32(RegSetValueExW(hKey, sGuid, 0, REG_SZ, (LPBYTE)pszTargetPath, (lstrlenW(pszTargetPath)+1)*sizeof(WCHAR)));
+
+        RegCloseKey(hKey);
+    }
+
+    return hr;
+}
+
+
 struct knownfolder
 {
     const struct IKnownFolderVtbl *vtbl;
@@ -3681,9 +3764,7 @@ static HRESULT WINAPI foldermanager_Redirect(
     KNOWNFOLDERID const *pExclusion,
     LPWSTR *ppszError)
 {
-    FIXME("%p, %p, 0x%08x, %s, %u, %p, %p\n", rfid, hwnd, flags,
-          debugstr_w(pszTargetPath), cFolders, pExclusion, ppszError);
-    return E_NOTIMPL;
+    return redirect_known_folder(rfid, hwnd, flags, pszTargetPath, cFolders, pExclusion, ppszError);
 }
 
 static const struct IKnownFolderManagerVtbl foldermanager_vtbl =
diff --git a/dlls/shell32/tests/shellpath.c b/dlls/shell32/tests/shellpath.c
index 3623029..e99b554 100644
--- a/dlls/shell32/tests/shellpath.c
+++ b/dlls/shell32/tests/shellpath.c
@@ -1232,7 +1232,6 @@ static void test_knownFolders(void)
 
                             /* try to redirect Example to Temp\Example2  */
                             hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, 0, sExample2Path, 0, NULL, &errorMsg);
-                            todo_wine
                             ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
 
                             /* verify */
@@ -1268,7 +1267,6 @@ static void test_knownFolders(void)
 
                             /* again perform that same redirection */
                             hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, 0, sExample2Path, 0, NULL, &errorMsg);
-                            todo_wine
                             ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
 
                             /* verify sub folder. It should succeed now, as the required sub folder exists */
@@ -1312,7 +1310,6 @@ static void test_knownFolders(void)
 
                             /* do that same redirection, but try to exclude sub-folder */
                             hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, 0, sExample2Path, 1, &subFolderId, &errorMsg);
-                            todo_wine
                             ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
 
                             /* verify */
@@ -1352,7 +1349,6 @@ static void test_knownFolders(void)
 
                             /* do that same redirection again, but set it to copy content. It should also copy the sub folder, so checking it would succeed now */
                             hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, KF_REDIRECT_COPY_CONTENTS, sExample2Path, 0, NULL, &errorMsg);
-                            todo_wine
                             ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
 
                             /* verify */
@@ -1392,7 +1388,6 @@ static void test_knownFolders(void)
 
                             /* redirect again, set it to copy content and remove originals */
                             hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, KF_REDIRECT_COPY_CONTENTS | KF_REDIRECT_DEL_SOURCE_CONTENTS, sExample2Path, 0, NULL, &errorMsg);
-                            todo_wine
                             ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
 
                             /* verify */
@@ -1417,7 +1412,6 @@ static void test_knownFolders(void)
 
                             /* redirect (with copy) to original path */
                             hr = IKnownFolderManager_Redirect(mgr, &newFolderId, NULL, KF_REDIRECT_COPY_CONTENTS,  sExamplePath, 0, NULL, &errorMsg);
-                            todo_wine
                             ok(hr == S_OK, "failed to redirect known folder: 0x%08x, errorMsg: %s\n", hr, wine_dbgstr_w(errorMsg));
 
                             /* verify */




More information about the wine-cvs mailing list