Mariusz Pluciński : shell32: Add IKnownFolder:: GetPath support.

Alexandre Julliard julliard at winehq.org
Wed Jun 22 11:48:43 CDT 2011


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

Author: Mariusz Pluciński <vshader at gmail.com>
Date:   Wed Jun 22 15:10:36 2011 +0200

shell32: Add IKnownFolder::GetPath support.

---

 dlls/shell32/shellpath.c       |   55 +++++++++++++++++++++++++++++++++++++--
 dlls/shell32/tests/shellpath.c |    5 ---
 2 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c
index 06108ca..6779e61 100644
--- a/dlls/shell32/shellpath.c
+++ b/dlls/shell32/shellpath.c
@@ -3079,6 +3079,7 @@ HRESULT WINAPI SHGetFolderPathEx(REFKNOWNFOLDERID rfid, DWORD flags, HANDLE toke
 /* constant values used by known folder functions */
 static const WCHAR szCategory[] = {'C','a','t','e','g','o','r','y',0};
 static const WCHAR szName[] = {'N','a','m','e',0};
+static const WCHAR szRelativePath[] = {'R','e','l','a','t','i','v','e','P','a','t','h',0};
 
 /*
  * Internal function to convert known folder identifier to path of registry key
@@ -3120,6 +3121,7 @@ struct knownfolder
     const struct IKnownFolderVtbl *vtbl;
     LONG refs;
     KNOWNFOLDERID id;
+    LPWSTR registryPath;
 };
 
 static inline struct knownfolder *impl_from_IKnownFolder( IKnownFolder *iface )
@@ -3142,6 +3144,7 @@ static ULONG WINAPI knownfolder_Release(
     if (!refs)
     {
         TRACE("destroying %p\n", knownfolder);
+        HeapFree( GetProcessHeap(), 0, knownfolder->registryPath);
         HeapFree( GetProcessHeap(), 0, knownfolder );
     }
     return refs;
@@ -3175,11 +3178,32 @@ static HRESULT knownfolder_set_id(
     const KNOWNFOLDERID *kfid)
 {
     struct knownfolder *knownfolder = impl_from_IKnownFolder( iface );
+    HKEY hKey;
+    HRESULT hr;
 
     TRACE("%s\n", debugstr_guid(kfid));
 
     knownfolder->id = *kfid;
-    return S_OK;
+
+    /* check is it registry-registered folder */
+    hr = get_known_folder_registry_path(kfid, &knownfolder->registryPath);
+    if(SUCCEEDED(hr))
+        hr = HRESULT_FROM_WIN32(RegOpenKeyExW(HKEY_LOCAL_MACHINE, knownfolder->registryPath, 0, 0, &hKey));
+
+    if(SUCCEEDED(hr))
+    {
+        hr = S_OK;
+        RegCloseKey(hKey);
+    }
+    else
+    {
+        /* This known folder is not registered. To mark it, we set registryPath to NULL */
+        HeapFree(GetProcessHeap(), 0, knownfolder->registryPath);
+        knownfolder->registryPath = NULL;
+        hr = S_OK;
+    }
+
+    return hr;
 }
 
 static HRESULT WINAPI knownfolder_GetId(
@@ -3218,9 +3242,30 @@ static HRESULT WINAPI knownfolder_GetPath(
     LPWSTR *ppszPath)
 {
     struct knownfolder *knownfolder = impl_from_IKnownFolder( iface );
+    DWORD dwSize, dwType;
+    HRESULT hr;
+
+    TRACE("(%p, 0x%08x, %p)\n", knownfolder, dwFlags, ppszPath);
+
+    /* if this is registry-registered known folder, get path from registry */
+    if(knownfolder->registryPath)
+    {
+        hr = HRESULT_FROM_WIN32(RegGetValueW(HKEY_LOCAL_MACHINE, knownfolder->registryPath, szRelativePath, RRF_RT_REG_SZ, &dwType, NULL, &dwSize));
 
-    TRACE("0x%08x, %p\n", dwFlags, ppszPath);
-    return SHGetKnownFolderPath( &knownfolder->id, dwFlags, NULL, ppszPath );
+        if(SUCCEEDED(hr))
+        {
+            *ppszPath = CoTaskMemAlloc(dwSize);
+            if(!*ppszPath) hr = E_OUTOFMEMORY;
+        }
+
+        if(SUCCEEDED(hr))
+            hr = HRESULT_FROM_WIN32(RegGetValueW(HKEY_LOCAL_MACHINE, knownfolder->registryPath, szRelativePath, RRF_RT_REG_SZ, &dwType, *ppszPath, &dwSize));
+    }
+    /* in other case, use older way */
+    else
+        hr = SHGetKnownFolderPath( &knownfolder->id, dwFlags, NULL, ppszPath );
+
+    return hr;
 }
 
 static HRESULT WINAPI knownfolder_SetPath(
@@ -3291,6 +3336,7 @@ static HRESULT knownfolder_create( void **ppv )
     kf->vtbl = &knownfolder_vtbl;
     kf->refs = 1;
     memset( &kf->id, 0, sizeof(kf->id) );
+    kf->registryPath = NULL;
 
     *ppv = &kf->vtbl;
 
@@ -3480,6 +3526,9 @@ static HRESULT WINAPI foldermanager_RegisterFolder(
         if(SUCCEEDED(hr))
             hr = HRESULT_FROM_WIN32(RegSetValueExW(hKey, szName, 0, REG_SZ, (LPBYTE)pKFD->pszName, (lstrlenW(pKFD->pszName)+1)*sizeof(WCHAR) ));
 
+        if(SUCCEEDED(hr) && pKFD->category != KF_CATEGORY_VIRTUAL)
+            hr = HRESULT_FROM_WIN32(RegSetValueExW(hKey, szRelativePath, 0, REG_SZ, (LPBYTE)pKFD->pszRelativePath, (lstrlenW(pKFD->pszRelativePath)+1)*sizeof(WCHAR) ));
+
         RegCloseKey(hKey);
     }
 
diff --git a/dlls/shell32/tests/shellpath.c b/dlls/shell32/tests/shellpath.c
index 1b575fe..bba7858 100644
--- a/dlls/shell32/tests/shellpath.c
+++ b/dlls/shell32/tests/shellpath.c
@@ -1180,9 +1180,7 @@ static void test_knownFolders(void)
                     ok(IsEqualGUID(&folderId, &newFolderId)==TRUE, "invalid KNOWNFOLDERID returned\n");
 
                     hr = IKnownFolder_GetPath(folder, 0, &folderPath);
-                    todo_wine
                     ok(hr == S_OK, "failed to get path from known folder: 0x%08x\n", hr);
-                    todo_wine
                     ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retreived: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
                     CoTaskMemFree(folderPath);
 
@@ -1193,7 +1191,6 @@ static void test_knownFolders(void)
 
                     /* verify modified path */
                     hr = IKnownFolder_GetPath(folder, 0, &folderPath);
-                    todo_wine
                     ok(hr == S_OK, "failed to get path from known folder: 0x%08x\n", hr);
                     todo_wine
                     ok(lstrcmpiW(folderPath, sExample2Path)==0, "invalid known folder path retreived: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
@@ -1206,9 +1203,7 @@ static void test_knownFolders(void)
 
                     /* again verify modified path */
                     hr = IKnownFolder_GetPath(folder, 0, &folderPath);
-                    todo_wine
                     ok(hr == S_OK, "failed to get path from known folder: 0x%08x\n", hr);
-                    todo_wine
                     ok(lstrcmpiW(folderPath, sExamplePath)==0, "invalid known folder path retreived: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sExamplePath));
                     CoTaskMemFree(folderPath);
 




More information about the wine-cvs mailing list