From 859a1d0d44e33b9705dc8578d78b13b270d70708 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Tue, 14 Sep 2010 17:01:44 +0200 Subject: [PATCH] shell32: Implement SHGetFolderPathEx. --- dlls/shell32/shell32.spec | 1 + dlls/shell32/shellpath.c | 26 +++++++++++++++++++++ dlls/shell32/tests/shellpath.c | 51 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec index 961e1af5d8e..034f6401da5 100644 --- a/dlls/shell32/shell32.spec +++ b/dlls/shell32/shell32.spec @@ -356,6 +356,7 @@ @ stdcall SHGetFileInfoW(ptr long ptr long long) @ stdcall SHGetFolderLocation(long long long long ptr) @ stdcall SHGetFolderPathA(long long long long ptr) +@ stdcall SHGetFolderPathEx(ptr long ptr ptr long) @ stdcall SHGetFolderPathAndSubDirA(long long long long str ptr) @ stdcall SHGetFolderPathAndSubDirW(long long long long wstr ptr) @ stdcall SHGetFolderPathW(long long long long ptr) diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index 0eafdc1a1ea..ec66699da55 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -2937,3 +2937,29 @@ HRESULT WINAPI SHGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD flags, HANDLE t } return hr; } + +/************************************************************************* + * SHGetFolderPathEx [SHELL32.@] + */ +HRESULT WINAPI SHGetFolderPathEx(REFKNOWNFOLDERID rfid, DWORD flags, HANDLE token, LPWSTR path, DWORD len) +{ + HRESULT hr; + WCHAR *buffer; + + TRACE("%s, 0x%08x, %p, %p, %u\n", debugstr_guid(rfid), flags, token, path, len); + + if (!path || !len) return E_INVALIDARG; + + hr = SHGetKnownFolderPath( rfid, flags, token, &buffer ); + if (SUCCEEDED( hr )) + { + if (strlenW( buffer ) + 1 > len) + { + CoTaskMemFree( buffer ); + return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ); + } + strcpyW( path, buffer ); + CoTaskMemFree( buffer ); + } + return hr; +} diff --git a/dlls/shell32/tests/shellpath.c b/dlls/shell32/tests/shellpath.c index b874b5a1ee4..2a86eacf78e 100644 --- a/dlls/shell32/tests/shellpath.c +++ b/dlls/shell32/tests/shellpath.c @@ -31,6 +31,7 @@ #include "shlobj.h" #include "shlwapi.h" #include "initguid.h" +#include "knownfolders.h" #include "wine/test.h" /* CSIDL_MYDOCUMENTS is now the same as CSIDL_PERSONAL, but what we want @@ -93,6 +94,9 @@ static LPITEMIDLIST (WINAPI *pILFindLastID)(LPCITEMIDLIST); static int (WINAPI *pSHFileOperationA)(LPSHFILEOPSTRUCTA); static HRESULT (WINAPI *pSHGetMalloc)(LPMALLOC *); static UINT (WINAPI *pGetSystemWow64DirectoryA)(LPSTR,UINT); +static HRESULT (WINAPI *pSHGetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *); +static HRESULT (WINAPI *pSHGetFolderPathEx)(REFKNOWNFOLDERID, DWORD, HANDLE, LPWSTR, DWORD); + static DLLVERSIONINFO shellVersion = { 0 }; static LPMALLOC pMalloc; static const BYTE guidType[] = { PT_GUID }; @@ -187,7 +191,9 @@ static void loadShell32(void) GET_PROC(DllGetVersion) GET_PROC(SHGetFolderPathA) + GET_PROC(SHGetFolderPathEx) GET_PROC(SHGetFolderLocation) + GET_PROC(SHGetKnownFolderPath) GET_PROC(SHGetSpecialFolderPathA) GET_PROC(SHGetSpecialFolderLocation) GET_PROC(ILFindLastID) @@ -833,6 +839,50 @@ static void test_NonExistentPath(void) else skip("RegOpenKeyExA(HKEY_CURRENT_USER, %s, ...) failed\n", userShellFolders); } +static void test_SHGetFolderPathEx(void) +{ + HRESULT hr; + WCHAR buffer[MAX_PATH], *path; + DWORD len; + + if (!pSHGetKnownFolderPath || !pSHGetFolderPathEx) + { + win_skip("SHGetKnownFolderPath or SHGetFolderPathEx not available\n"); + return; + } + +if (0) { /* crashes */ + hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, NULL); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr); +} + path = NULL; + hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path); + ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); + ok(path != NULL, "expected path != NULL\n"); + + hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, MAX_PATH); + ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); + ok(!lstrcmpiW(path, buffer), "expected equal paths\n"); + len = lstrlenW(buffer); + CoTaskMemFree(path); + + hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, 0); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr); + +if (0) { /* crashes */ + hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, NULL, len + 1); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr); + + hr = pSHGetFolderPathEx(NULL, 0, NULL, buffer, MAX_PATH); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr); +} + hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len); + ok(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), "expected 0x8007007a, got 0x%08x\n", hr); + + hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len + 1); + ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr); +} + START_TEST(shellpath) { if (!init()) return; @@ -858,5 +908,6 @@ START_TEST(shellpath) testWinDir(); testSystemDir(); test_NonExistentPath(); + test_SHGetFolderPathEx(); } } -- 2.11.4.GIT