[4/4] shell32: Implement SHGetFolderPathEx.

Hans Leidekker hans at codeweavers.com
Tue Sep 14 10:01:44 CDT 2010


See http://bugs.winehq.org/show_bug.cgi?id=22896
---
 dlls/shell32/shell32.spec      |    1 +
 dlls/shell32/shellpath.c       |   26 ++++++++++++++++++++
 dlls/shell32/tests/shellpath.c |   51 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec
index 961e1af..034f640 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 0eafdc1..ec66699 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 b874b5a..2a86eac 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();
     }
 }
-- 
1.7.0.4






More information about the wine-patches mailing list