2011-05-15 15:55:49 +00:00
|
|
|
/*
|
2011-09-08 22:43:43 +00:00
|
|
|
* Copyright 1997 Marcus Meissner
|
|
|
|
* Copyright 1998 Juergen Schmied
|
2011-05-15 15:55:49 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
|
|
*/
|
|
|
|
|
2013-01-24 23:00:42 +00:00
|
|
|
#include "precomp.h"
|
2011-05-15 15:55:49 +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
2017-01-17 23:53:55 +00:00
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
|
|
|
|
2011-05-15 15:55:49 +00:00
|
|
|
WCHAR swShell32Name[MAX_PATH];
|
|
|
|
|
|
|
|
DWORD NumIconOverlayHandlers = 0;
|
|
|
|
IShellIconOverlayIdentifier ** Handlers = NULL;
|
|
|
|
|
2016-12-06 21:18:17 +00:00
|
|
|
static void InitIconOverlays(void)
|
2011-05-15 15:55:49 +00:00
|
|
|
{
|
|
|
|
HKEY hKey;
|
|
|
|
DWORD dwIndex, dwResult, dwSize;
|
|
|
|
WCHAR szName[MAX_PATH];
|
|
|
|
WCHAR szValue[100];
|
|
|
|
CLSID clsid;
|
|
|
|
|
2011-12-17 22:53:44 +00:00
|
|
|
if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
|
2011-05-15 15:55:49 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &dwResult, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Handlers = (IShellIconOverlayIdentifier **)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwResult * sizeof(IShellIconOverlayIdentifier*));
|
|
|
|
if (!Handlers)
|
|
|
|
{
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
dwIndex = 0;
|
|
|
|
|
|
|
|
CoInitialize(0);
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
dwSize = sizeof(szName) / sizeof(WCHAR);
|
|
|
|
dwResult = RegEnumKeyExW(hKey, dwIndex, szName, &dwSize, NULL, NULL, NULL, NULL);
|
|
|
|
|
|
|
|
if (dwResult == ERROR_NO_MORE_ITEMS)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (dwResult == ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
dwSize = sizeof(szValue) / sizeof(WCHAR);
|
|
|
|
if (RegGetValueW(hKey, szName, NULL, RRF_RT_REG_SZ, NULL, szValue, &dwSize) == ERROR_SUCCESS)
|
|
|
|
{
|
2014-08-20 00:39:40 +00:00
|
|
|
CComPtr<IShellIconOverlayIdentifier> Overlay;
|
2011-05-15 15:55:49 +00:00
|
|
|
|
|
|
|
CLSIDFromString(szValue, &clsid);
|
2014-04-28 21:59:02 +00:00
|
|
|
dwResult = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IShellIconOverlayIdentifier, &Overlay));
|
2011-05-15 15:55:49 +00:00
|
|
|
if (dwResult == S_OK)
|
|
|
|
{
|
2014-08-20 00:39:40 +00:00
|
|
|
Handlers[NumIconOverlayHandlers] = Overlay.Detach();
|
2011-05-15 15:55:49 +00:00
|
|
|
NumIconOverlayHandlers++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dwIndex++;
|
|
|
|
|
2011-12-17 22:53:44 +00:00
|
|
|
} while(1);
|
2011-05-15 15:55:49 +00:00
|
|
|
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
GetIconOverlay(LPCITEMIDLIST pidl, WCHAR * wTemp, int* pIndex)
|
|
|
|
{
|
|
|
|
DWORD Index;
|
|
|
|
HRESULT hResult;
|
|
|
|
int Priority;
|
|
|
|
int HighestPriority;
|
|
|
|
ULONG IconIndex;
|
|
|
|
ULONG Flags;
|
|
|
|
WCHAR szPath[MAX_PATH];
|
|
|
|
|
|
|
|
if(!SHGetPathFromIDListW(pidl, szPath))
|
|
|
|
return FALSE;
|
|
|
|
|
2016-12-06 21:18:17 +00:00
|
|
|
if (!Handlers)
|
|
|
|
InitIconOverlays();
|
2011-05-15 15:55:49 +00:00
|
|
|
|
|
|
|
HighestPriority = 101;
|
|
|
|
IconIndex = NumIconOverlayHandlers;
|
|
|
|
for(Index = 0; Index < NumIconOverlayHandlers; Index++)
|
|
|
|
{
|
|
|
|
hResult = Handlers[Index]->IsMemberOf(szPath, SFGAO_FILESYSTEM);
|
|
|
|
if (hResult == S_OK)
|
|
|
|
{
|
|
|
|
hResult = Handlers[Index]->GetPriority(&Priority);
|
|
|
|
if (hResult == S_OK)
|
|
|
|
{
|
|
|
|
if (Priority < HighestPriority)
|
|
|
|
{
|
|
|
|
HighestPriority = Priority;
|
|
|
|
IconIndex = Index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IconIndex == NumIconOverlayHandlers)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
hResult = Handlers[IconIndex]->GetOverlayInfo(wTemp, MAX_PATH, pIndex, &Flags);
|
|
|
|
|
|
|
|
if (hResult == S_OK)
|
|
|
|
return TRUE;
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|