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