From e554ee7fb427551b14ea94a1a8d46992f2249b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Pluci=C5=84ski?= Date: Wed, 29 Jun 2011 19:37:06 +0200 Subject: [PATCH] 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 6328ec52c94..e107f0e38e0 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 36230295270..e99b5547a55 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 */