mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 05:26:58 +00:00
[SHELL32]: CShellLink fixups Part 2:
- Add COM inheritance for interfaces IExtractIconA/W, and add in comment the missing other ones, the ordering of which is given by the apitests/com/shell32. - Add proper support for the extra data block list (which is added at the end of the .lnk files), by using the API from shlwapi.dll: SH[Read|Write|Free]DataBlockList, SH[Add|Find|Remove]DataBlock. - Using this support, getting/setting the MSI data block becomes as simple as child's play, and opens the possibility for implementing support for the other types of blocks. - This in particular enables support for paths with environment variables for the link's target and icon: CORE-9236 #resolve - Fix all the "shell32_winetest shelllink" tests: CORE-7158 #resolve Some of the fixes are inspired from a patch by Katayama Hirofumi MZ. - Fix all the "shell32_apitest CShellLink" tests *but* those calling IExtractIcon::GetIconLocation(). - Implement a hackish substitute to the shell32!PathResolve API until someone writes a correct one (see the code & the FIXMEs for some ideas), possibly using the SHELL_xxx helpers in Wine's shellpath.c. - In CFSExtractIcon_CreateInstance: Because IShellLink::GetIconLocation can return no icon location, in case none is specified in the .lnk (proved by apitests), we have to call the shell link's IExtractIcon::GetIconLocation in order to retrieve the icon of its target (yes, some shortcuts are made like that, e.g. Notepad++ 6.9 one...). - More fixes... - ... and a lot of documentation added in the code for you! CORE-12682 svn path=/trunk/; revision=73576
This commit is contained in:
parent
ef0d1d640c
commit
766a0d27df
File diff suppressed because it is too large
Load diff
|
@ -4,6 +4,7 @@
|
|||
* Copyright 1998 Juergen Schmied
|
||||
* Copyright 2005 Mike McCormack
|
||||
* Copyright 2009 Andrew Hill
|
||||
* Copyright 2017 Hermes Belusca-Maito
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -29,13 +30,21 @@ class CShellLink :
|
|||
public CComObjectRootEx<CComMultiThreadModelNoCS>,
|
||||
public IShellLinkA,
|
||||
public IShellLinkW,
|
||||
public IPersistFile,
|
||||
public IPersistStream,
|
||||
public IShellLinkDataList,
|
||||
public IPersistFile,
|
||||
public IShellExtInit,
|
||||
public IContextMenu,
|
||||
public IContextMenu, // Technically it should be IContextMenu3 (inherits from IContextMenu2 and IContextMenu)
|
||||
public IDropTarget,
|
||||
// public IQueryInfo,
|
||||
public IShellLinkDataList,
|
||||
public IExtractIconA,
|
||||
public IExtractIconW,
|
||||
// public IExtractImage2, // Inherits from IExtractImage
|
||||
// public IPersistPropertyBag,
|
||||
// public IServiceProvider,
|
||||
// public IFilter,
|
||||
public IObjectWithSite,
|
||||
// public ICustomizeInfoTip,
|
||||
public IShellPropSheetExt
|
||||
{
|
||||
public:
|
||||
|
@ -53,14 +62,8 @@ public:
|
|||
#include "poppack.h"
|
||||
|
||||
private:
|
||||
/* data structures according to the information in the link */
|
||||
WORD wHotKey;
|
||||
SYSTEMTIME time1;
|
||||
SYSTEMTIME time2;
|
||||
SYSTEMTIME time3;
|
||||
|
||||
DWORD iShowCmd;
|
||||
INT iIcoNdx;
|
||||
/* Cached link header */
|
||||
SHELL_LINK_HEADER m_Header;
|
||||
|
||||
/* Cached data set according to m_Header.dwFlags (SHELL_LINK_DATA_FLAGS) */
|
||||
|
||||
|
@ -77,7 +80,9 @@ private:
|
|||
LPWSTR m_sIcoPath;
|
||||
BOOL m_bRunAs;
|
||||
BOOL m_bDirty;
|
||||
LPDBLIST m_pDBList; /* Optional data block list (in the extra data section) */
|
||||
|
||||
/* Pointers to strings inside Logo3/Darwin info blocks, cached for debug info purposes only */
|
||||
LPWSTR sProduct;
|
||||
LPWSTR sComponent;
|
||||
|
||||
|
@ -87,10 +92,16 @@ private:
|
|||
CComPtr<IUnknown> m_site;
|
||||
CComPtr<IDropTarget> m_DropTarget;
|
||||
|
||||
VOID Reset();
|
||||
|
||||
HRESULT GetAdvertiseInfo(LPWSTR *str, DWORD dwSig);
|
||||
HRESULT SetAdvertiseInfo(LPCWSTR str);
|
||||
HRESULT WriteAdvertiseInfo(LPCWSTR string, DWORD dwSig);
|
||||
HRESULT SetTargetFromPIDLOrPath(LPCITEMIDLIST pidl, LPCWSTR pszFile);
|
||||
|
||||
public:
|
||||
CShellLink();
|
||||
~CShellLink();
|
||||
HRESULT SetAdvertiseInfo(LPCWSTR str);
|
||||
static INT_PTR CALLBACK SH_ShellLinkDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// IPersistFile
|
||||
|
@ -155,6 +166,14 @@ public:
|
|||
virtual HRESULT STDMETHODCALLTYPE GetFlags(DWORD *pdwFlags);
|
||||
virtual HRESULT STDMETHODCALLTYPE SetFlags(DWORD dwFlags);
|
||||
|
||||
// IExtractIconA
|
||||
virtual HRESULT STDMETHODCALLTYPE Extract(PCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
|
||||
virtual HRESULT STDMETHODCALLTYPE GetIconLocation(UINT uFlags, PSTR pszIconFile, UINT cchMax, int *piIndex, UINT *pwFlags);
|
||||
|
||||
// IExtractIconW
|
||||
virtual HRESULT STDMETHODCALLTYPE Extract(PCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
|
||||
virtual HRESULT STDMETHODCALLTYPE GetIconLocation(UINT uFlags, PWSTR pszIconFile, UINT cchMax, int *piIndex, UINT *pwFlags);
|
||||
|
||||
// IShellExtInit
|
||||
virtual HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID);
|
||||
|
||||
|
@ -183,17 +202,25 @@ DECLARE_NOT_AGGREGATABLE(CShellLink)
|
|||
DECLARE_PROTECT_FINAL_CONSTRUCT()
|
||||
|
||||
BEGIN_COM_MAP(CShellLink)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IShellLinkA, IShellLinkA)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IShellLinkW, IShellLinkW)
|
||||
COM_INTERFACE_ENTRY2_IID(IID_IPersist, IPersist, IPersistFile)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IPersistFile, IPersistFile)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IShellLinkA, IShellLinkA)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IShellLinkW, IShellLinkW)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IShellLinkDataList, IShellLinkDataList)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu) // Technically it should be IContextMenu3
|
||||
COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IShellPropSheetExt, IShellPropSheetExt)
|
||||
// COM_INTERFACE_ENTRY_IID(IID_IQueryInfo, IQueryInfo)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IShellLinkDataList, IShellLinkDataList)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IExtractIconA, IExtractIconA)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IExtractIconW, IExtractIconW)
|
||||
// COM_INTERFACE_ENTRY_IID(IID_IExtractImage2, IExtractImage2)
|
||||
// COM_INTERFACE_ENTRY_IID(IID_IPersistPropertyBag, IPersistPropertyBag)
|
||||
// COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
|
||||
// COM_INTERFACE_ENTRY_IID(IID_IFilter, IFilter)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
|
||||
// COM_INTERFACE_ENTRY_IID(IID_ICustomizeInfoTip, ICustomizeInfoTip)
|
||||
COM_INTERFACE_ENTRY_IID(IID_IShellPropSheetExt, IShellPropSheetExt)
|
||||
END_COM_MAP()
|
||||
};
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include "precomp.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||
|
||||
WCHAR swShell32Name[MAX_PATH];
|
||||
|
||||
DWORD NumIconOverlayHandlers = 0;
|
||||
|
@ -267,11 +269,21 @@ HRESULT CFSExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl, RE
|
|||
{
|
||||
/* extract icon from shell shortcut */
|
||||
CComPtr<IShellLinkW> psl;
|
||||
CComPtr<IExtractIconW> pei;
|
||||
|
||||
HRESULT hr = psf->GetUIObjectOf(NULL, 1, &pidl, IID_NULL_PPV_ARG(IShellLinkW, &psl));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = psl->GetIconLocation(wTemp, _countof(wTemp), &icon_idx);
|
||||
if (FAILED(hr) || !*wTemp)
|
||||
{
|
||||
/* The icon was not found directly, try to retrieve it from the shell link target */
|
||||
hr = psl->QueryInterface(IID_PPV_ARG(IExtractIconW, &pei));
|
||||
if (FAILED(hr) || !pei)
|
||||
TRACE("No IExtractIconW interface!\n");
|
||||
else
|
||||
hr = pei->GetIconLocation(GIL_FORSHELL, wTemp, _countof(wTemp), &icon_idx, &flags);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr) && *wTemp)
|
||||
found = TRUE;
|
||||
|
|
Loading…
Reference in a new issue