diff --git a/dll/win32/shlwapi/shlwapi.spec b/dll/win32/shlwapi/shlwapi.spec index 821a2ed241c..cc625b5a84a 100644 --- a/dll/win32/shlwapi/shlwapi.spec +++ b/dll/win32/shlwapi/shlwapi.spec @@ -313,8 +313,8 @@ 313 stdcall -noname SHGetFileInfoWrapW(ptr long ptr long long) 314 stdcall -noname RegisterClassExWrapW(ptr) user32.RegisterClassExW 315 stdcall -noname GetClassInfoExWrapW(long wstr ptr) user32.GetClassInfoExW -316 stub -noname IShellFolder_GetDisplayNameOf -317 stub -noname IShellFolder_ParseDisplayName +316 stdcall -noname IShellFolder_GetDisplayNameOf(ptr ptr long ptr long) +317 stdcall -noname IShellFolder_ParseDisplayName(ptr ptr ptr wstr ptr ptr ptr) 318 stdcall -noname DragQueryFileWrapW(long long wstr long) 319 stdcall -noname FindWindowExWrapW(long long wstr wstr) user32.FindWindowExW 320 stdcall -noname RegisterMIMETypeForExtensionA(str str) @@ -548,7 +548,7 @@ 548 stdcall -noname SHAreIconsEqual(ptr ptr) 549 stdcall -noname SHCoCreateInstanceAC(ptr ptr long ptr ptr) 550 stub -noname GetTemplateInfoFromHandle -551 stub -noname IShellFolder_CompareIDs +551 stdcall -noname IShellFolder_CompareIDs(ptr ptr ptr ptr) 552 stdcall -stub -noname -version=0x501-0x502 SHEvaluateSystemCommandTemplate(wstr ptr ptr ptr) 553 stdcall IsInternetESCEnabled() 554 stdcall -noname -stub SHGetAllAccessSA() diff --git a/dll/win32/shlwapi/utils.cpp b/dll/win32/shlwapi/utils.cpp index 673d6d77f99..3a5db3516ac 100644 --- a/dll/win32/shlwapi/utils.cpp +++ b/dll/win32/shlwapi/utils.cpp @@ -2,17 +2,35 @@ * PROJECT: ReactOS Shell * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later) * PURPOSE: Implement shell light-weight utility functions - * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ + * COPYRIGHT: Copyright 2023-2024 Katayama Hirofumi MZ */ #define _ATL_NO_EXCEPTIONS + +/* + * HACK! These functions are conflicting with inline functions... + */ +#define IShellFolder_GetDisplayNameOf _disabled_IShellFolder_GetDisplayNameOf_ +#define IShellFolder_ParseDisplayName _disabled_IShellFolder_ParseDisplayName_ +#define IShellFolder_CompareIDs _disabled_IShellFolder_CompareIDs_ + #include "precomp.h" #include #include -#include #include #include #include + +/* + * HACK! + */ +#undef IShellFolder_GetDisplayNameOf +#undef IShellFolder_ParseDisplayName +#undef IShellFolder_CompareIDs + +#define SHLWAPI_ISHELLFOLDER_HELPERS /* HACK! */ +#include + #include WINE_DEFAULT_DEBUG_CHANNEL(shell); @@ -115,3 +133,101 @@ PathFileExistsDefExtAndAttributesW( return TRUE; } + +static inline BOOL +SHLWAPI_IsBogusHRESULT(HRESULT hr) +{ + return (hr == E_FAIL || hr == E_INVALIDARG || hr == E_NOTIMPL); +} + +/************************************************************************* + * IShellFolder_GetDisplayNameOf [SHLWAPI.316] + */ +EXTERN_C HRESULT WINAPI +IShellFolder_GetDisplayNameOf( + _In_ IShellFolder *psf, + _In_ LPCITEMIDLIST pidl, + _In_ DWORD uFlags, + _Out_ LPSTRRET lpName, + _In_ DWORD dwRetryFlags) +{ + HRESULT hr; + + TRACE("(%p)->(%p, 0x%lX, %p, 0x%lX)\n", psf, pidl, uFlags, lpName, dwRetryFlags); + + hr = psf->GetDisplayNameOf(pidl, uFlags, lpName); + if (!SHLWAPI_IsBogusHRESULT(hr)) + return hr; + + dwRetryFlags |= 0x80000000; + + if ((uFlags & SHGDN_FORPARSING) == 0) + dwRetryFlags |= SFGDNO_RETRYWITHFORPARSING; + + /* It seems the function is actually retrying here */ + FIXME("dwRetryFlags: 0x%X\n", dwRetryFlags); + + return hr; +} + +/************************************************************************* + * IShellFolder_ParseDisplayName [SHLWAPI.317] + */ +EXTERN_C HRESULT WINAPI +IShellFolder_ParseDisplayName( + _In_ IShellFolder *psf, + _In_opt_ HWND hwndOwner, + _In_opt_ LPBC pbcReserved, + _In_ LPOLESTR lpszDisplayName, + _Out_opt_ ULONG *pchEaten, + _Out_opt_ PIDLIST_RELATIVE *ppidl, + _Out_opt_ ULONG *pdwAttributes) +{ + ULONG dummy1, dummy2; + + TRACE("(%p)->(%p, %p, %s, %p, %p, %p)\n", psf, hwndOwner, pbcReserved, + debugstr_w(lpszDisplayName), pchEaten, ppidl, pdwAttributes); + + if (!pdwAttributes) + { + dummy1 = 0; + pdwAttributes = &dummy1; + } + + if (!pchEaten) + { + dummy2 = 0; + pchEaten = &dummy2; + } + + if (ppidl) + *ppidl = NULL; + + return psf->ParseDisplayName(hwndOwner, pbcReserved, lpszDisplayName, pchEaten, + ppidl, pdwAttributes); +} + +/************************************************************************* + * IShellFolder_CompareIDs [SHLWAPI.551] + */ +EXTERN_C HRESULT WINAPI +IShellFolder_CompareIDs( + _In_ IShellFolder *psf, + _In_ LPARAM lParam, + _In_ PCUIDLIST_RELATIVE pidl1, + _In_ PCUIDLIST_RELATIVE pidl2) +{ + TRACE("(%p, %p, %p, %p)\n", psf, lParam, pidl1, pidl2); + + if (lParam & ~(SIZE_T)SHCIDS_COLUMNMASK) + { + /* Try as IShellFolder2 if possible */ + HRESULT hr = psf->QueryInterface(IID_IShellFolder2, (void **)&psf); + if (FAILED(hr)) + lParam &= SHCIDS_COLUMNMASK; + else + psf->Release(); + } + + return psf->CompareIDs(lParam, pidl1, pidl2); +} diff --git a/sdk/include/psdk/shobjidl.idl b/sdk/include/psdk/shobjidl.idl index 6b4bdadffc9..b7958e2e8fe 100644 --- a/sdk/include/psdk/shobjidl.idl +++ b/sdk/include/psdk/shobjidl.idl @@ -218,6 +218,12 @@ interface IShellFolder : IUnknown cpp_quote("#define SFGAO_STORAGEANCESTOR 0x00800000L") cpp_quote("#define SFGAO_STORAGECAPMASK 0x70C50008L") cpp_quote("#define SFGAO_PKEYSFGAOMASK 0x81044000L") + typedef ULONG SFGAOF; + + cpp_quote("#define SHCIDS_COLUMNMASK 0x0000FFFFL") + cpp_quote("#define SHCIDS_BITMASK 0xFFFF0000L") + cpp_quote("#define SHCIDS_CANONICALONLY 0x10000000L") + cpp_quote("#define SHCIDS_ALLFIELDS 0x80000000L") cpp_quote("#define STR_PARSE_SHELL_PROTOCOL_TO_FILE_OBJECTS L\"Parse Shell Protocol To File Objects\"") cpp_quote("#define STR_FILE_SYS_BIND_DATA L\"File System Bind Data\"") @@ -225,8 +231,6 @@ interface IShellFolder : IUnknown cpp_quote("#define STR_PARSE_TRANSLATE_ALIASES L\"Parse Translate Aliases\"") cpp_quote("#define STR_DONT_PARSE_RELATIVE L\"Don't Parse Relative\"") - typedef ULONG SFGAOF; - HRESULT ParseDisplayName( [in] HWND hwndOwner, [in] LPBC pbcReserved, diff --git a/sdk/include/reactos/shlwapi_undoc.h b/sdk/include/reactos/shlwapi_undoc.h index cd2cc1882b8..eb002d4a170 100644 --- a/sdk/include/reactos/shlwapi_undoc.h +++ b/sdk/include/reactos/shlwapi_undoc.h @@ -332,6 +332,40 @@ IContextMenu_Invoke( DWORD WINAPI SHGetObjectCompatFlags(IUnknown *pUnk, const CLSID *clsid); +/* + * HACK! These functions are conflicting with inline functions... + * We provide a macro option SHLWAPI_ISHELLFOLDER_HELPERS for using these functions. + */ +#ifdef SHLWAPI_ISHELLFOLDER_HELPERS +HRESULT WINAPI +IShellFolder_GetDisplayNameOf( + _In_ IShellFolder *psf, + _In_ LPCITEMIDLIST pidl, + _In_ DWORD uFlags, + _Out_ LPSTRRET lpName, + _In_ DWORD dwRetryFlags); + +/* Flags for IShellFolder_GetDisplayNameOf */ +#define SFGDNO_RETRYWITHFORPARSING 1 + +HRESULT WINAPI +IShellFolder_ParseDisplayName( + _In_ IShellFolder *psf, + _In_ HWND hwndOwner, + _In_ LPBC pbcReserved, + _In_ LPOLESTR lpszDisplayName, + _Out_ ULONG *pchEaten, + _Out_ PIDLIST_RELATIVE *ppidl, + _Out_ ULONG *pdwAttributes); + +EXTERN_C HRESULT WINAPI +IShellFolder_CompareIDs( + _In_ IShellFolder *psf, + _In_ LPARAM lParam, + _In_ PCUIDLIST_RELATIVE pidl1, + _In_ PCUIDLIST_RELATIVE pidl2); +#endif /* SHLWAPI_ISHELLFOLDER_HELPERS */ + #ifdef __cplusplus } /* extern "C" */ #endif /* defined(__cplusplus) */