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, ®istryPath);
+ hr = get_known_folder_registry_path(id, NULL, ®istryPath);
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, ®istryPath);
+ hr = get_known_folder_registry_path(rfid, NULL, ®istryPath);
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, ®istryPath);
+ hr = get_known_folder_registry_path(rfid, NULL, ®istryPath);
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