Mariusz Pluciński : shell32: Add support of parent folder to GetPath.

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


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

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

shell32: Add support of parent folder to GetPath.

---

 dlls/shell32/shellpath.c       |   87 +++++++++++++++++++++++++++++++---------
 dlls/shell32/tests/shellpath.c |    5 --
 2 files changed, 68 insertions(+), 24 deletions(-)

diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c
index 33c9908..6328ec5 100644
--- a/dlls/shell32/shellpath.c
+++ b/dlls/shell32/shellpath.c
@@ -3087,20 +3087,27 @@ static const WCHAR szParentFolder[] = {'P','a','r','e','n','t','F','o','l','d','
  * associated with known folder.
  *
  * Parameters:
- *  rfid            [I] pointer to known folder identifier
+ *  rfid            [I] pointer to known folder identifier (may be NULL)
+ *  lpStringGuid    [I] string with known folder identifier (used when rfid is NULL)
  *  lpPath          [O] place to store string address. String should be
  *                      later freed using HeapFree(GetProcessHeap(),0, ... )
  */
-static HRESULT get_known_folder_registry_path(REFKNOWNFOLDERID rfid, LPWSTR *lpPath)
+static HRESULT get_known_folder_registry_path(
+    REFKNOWNFOLDERID rfid,
+    LPWSTR lpStringGuid,
+    LPWSTR *lpPath)
 {
     static const WCHAR sBackslash[] = {'\\',0};
     HRESULT hr = S_OK;
     int length;
     WCHAR sGuid[50];
 
-    TRACE("(%s, %p)\n", debugstr_guid(rfid), lpPath);
+    TRACE("(%s, %s, %p)\n", debugstr_guid(rfid), debugstr_w(lpStringGuid), lpPath);
 
-    StringFromGUID2(rfid, sGuid, sizeof(sGuid)/sizeof(sGuid[0]));
+    if(rfid)
+        StringFromGUID2(rfid, sGuid, sizeof(sGuid)/sizeof(sGuid[0]));
+    else
+        lstrcpyW(sGuid, lpStringGuid);
 
     length = lstrlenW(szKnownFolderDescriptions)+51;
     *lpPath = HeapAlloc(GetProcessHeap(), 0, length*sizeof(WCHAR));
@@ -3187,7 +3194,7 @@ static HRESULT knownfolder_set_id(
     knownfolder->id = *kfid;
 
     /* check is it registry-registered folder */
-    hr = get_known_folder_registry_path(kfid, &knownfolder->registryPath);
+    hr = get_known_folder_registry_path(kfid, NULL, &knownfolder->registryPath);
     if(SUCCEEDED(hr))
         hr = HRESULT_FROM_WIN32(RegOpenKeyExW(HKEY_LOCAL_MACHINE, knownfolder->registryPath, 0, 0, &hKey));
 
@@ -3249,13 +3256,64 @@ static HRESULT WINAPI knownfolder_GetShellItem(
     return E_NOTIMPL;
 }
 
+static HRESULT get_known_folder_path(
+    LPWSTR registryPath,
+    LPWSTR *ppszPath)
+{
+    static const WCHAR sBackslash[] = {'\\',0};
+    HRESULT hr;
+    DWORD dwSize, dwType;
+    WCHAR path[MAX_PATH] = {0};
+    WCHAR parentGuid[39];
+    LPWSTR parentRegistryPath, parentPath;
+
+    TRACE("(%s, %p)\n", debugstr_w(registryPath), ppszPath);
+
+    /* check if folder has parent */
+    dwSize = sizeof(parentGuid);
+    hr = HRESULT_FROM_WIN32(RegGetValueW(HKEY_LOCAL_MACHINE, registryPath, szParentFolder, RRF_RT_REG_SZ, &dwType, parentGuid, &dwSize));
+    if(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) hr = S_FALSE;
+
+    if(hr == S_OK)
+    {
+        /* get parent's known folder path (recursive) */
+        get_known_folder_registry_path(NULL, parentGuid, &parentRegistryPath);
+
+        hr = get_known_folder_path(parentRegistryPath, &parentPath);
+
+        lstrcatW(path, parentPath);
+        lstrcatW(path, sBackslash);
+
+        HeapFree(GetProcessHeap(), 0, parentRegistryPath);
+        HeapFree(GetProcessHeap(), 0, parentPath);
+    }
+
+    /* read the relative path from registry */
+    if(SUCCEEDED(hr))
+        hr = HRESULT_FROM_WIN32(RegGetValueW(HKEY_LOCAL_MACHINE, registryPath, szRelativePath, RRF_RT_REG_SZ, &dwType, NULL, &dwSize));
+
+    if(SUCCEEDED(hr))
+    {
+        *ppszPath = CoTaskMemAlloc(dwSize+(lstrlenW(path)+1)*sizeof(WCHAR));
+        if(!*ppszPath) hr = E_OUTOFMEMORY;
+    }
+
+    if(SUCCEEDED(hr))
+    {
+        lstrcpyW(*ppszPath, path);
+        hr = HRESULT_FROM_WIN32(RegGetValueW(HKEY_LOCAL_MACHINE, registryPath, szRelativePath, RRF_RT_REG_SZ, &dwType, *ppszPath + lstrlenW(path), &dwSize));
+    }
+
+    TRACE("returning path: %s\n", debugstr_w(*ppszPath));
+    return hr;
+}
+
 static HRESULT WINAPI knownfolder_GetPath(
     IKnownFolder *iface,
     DWORD dwFlags,
     LPWSTR *ppszPath)
 {
     struct knownfolder *knownfolder = impl_from_IKnownFolder( iface );
-    DWORD dwSize, dwType;
     HRESULT hr;
 
     TRACE("(%p, 0x%08x, %p)\n", knownfolder, dwFlags, ppszPath);
@@ -3263,16 +3321,7 @@ static HRESULT WINAPI knownfolder_GetPath(
     /* 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));
-
-        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));
+        hr = get_known_folder_path(knownfolder->registryPath, ppszPath);
     }
     /* in other case, use older way */
     else
@@ -3495,7 +3544,7 @@ static BOOL is_knownfolder( struct foldermanager *fm, const KNOWNFOLDERID *id )
     for (i = 0; i < fm->num_ids; i++)
         if (IsEqualGUID( &fm->ids[i], id )) return TRUE;
 
-    hr = get_known_folder_registry_path(id, &registryPath);
+    hr = get_known_folder_registry_path(id, NULL, &registryPath);
     if(SUCCEEDED(hr))
         hr = HRESULT_FROM_WIN32(RegOpenKeyExW(HKEY_LOCAL_MACHINE, registryPath, 0, 0, &hKey));
 
@@ -3550,7 +3599,7 @@ static HRESULT WINAPI foldermanager_RegisterFolder(
     LPWSTR registryPath = NULL;
     TRACE("(%p, %s, %p)\n", iface, debugstr_guid(rfid), pKFD);
 
-    hr = get_known_folder_registry_path(rfid, &registryPath);
+    hr = get_known_folder_registry_path(rfid, NULL, &registryPath);
     TRACE("registry path: %s\n", debugstr_w(registryPath));
 
     if(SUCCEEDED(hr))
@@ -3594,7 +3643,7 @@ static HRESULT WINAPI foldermanager_UnregisterFolder(
     LPWSTR registryPath = NULL;
     TRACE("(%p, %s)\n", iface, debugstr_guid(rfid));
 
-    hr = get_known_folder_registry_path(rfid, &registryPath);
+    hr = get_known_folder_registry_path(rfid, NULL, &registryPath);
 
     if(SUCCEEDED(hr))
         hr = HRESULT_FROM_WIN32(RegDeleteKeyW(HKEY_LOCAL_MACHINE, registryPath));
diff --git a/dlls/shell32/tests/shellpath.c b/dlls/shell32/tests/shellpath.c
index ff47951..3623029 100644
--- a/dlls/shell32/tests/shellpath.c
+++ b/dlls/shell32/tests/shellpath.c
@@ -1226,7 +1226,6 @@ static void test_knownFolders(void)
                             /* check sub folder path */
                             hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
                             ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
-                            todo_wine
                             ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
                             CoTaskMemFree(folderPath);
 
@@ -1303,7 +1302,6 @@ static void test_knownFolders(void)
                             /* verify sub folder */
                             hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
                             ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
-                            todo_wine
                             ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
                             CoTaskMemFree(folderPath);
 
@@ -1348,7 +1346,6 @@ static void test_knownFolders(void)
                             /* verify sub folder */
                             hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
                             ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
-                            todo_wine
                             ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
                             CoTaskMemFree(folderPath);
 
@@ -1389,7 +1386,6 @@ static void test_knownFolders(void)
                             /* verify sub folder */
                             hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
                             ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
-                            todo_wine
                             ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
                             CoTaskMemFree(folderPath);
 
@@ -1433,7 +1429,6 @@ static void test_knownFolders(void)
                             /* verify sub folder */
                             hr = IKnownFolder_GetPath(subFolder, 0, &folderPath);
                             ok(hr == S_OK, "failed to get known folder path: 0x%08x\n", hr);
-                            todo_wine
                             ok(lstrcmpiW(folderPath, sSubFolderPath)==0, "invalid known folder path retrieved: \"%s\" when \"%s\" was expected\n", wine_dbgstr_w(folderPath), wine_dbgstr_w(sSubFolderPath));
                             CoTaskMemFree(folderPath);
 




More information about the wine-cvs mailing list