mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
233 lines
8.3 KiB
Diff
233 lines
8.3 KiB
Diff
From 68d7bcf933fabf684262f42a152ddf4fa5c38577 Mon Sep 17 00:00:00 2001
|
|
From: Louis Lenders <xerox.xerox2000x@gmail.com>
|
|
Date: Fri, 12 Oct 2018 11:57:18 +0200
|
|
Subject: [PATCH] shell32: Improve semi-stub SHGetStockIconInfo, try find
|
|
existing iconhandle
|
|
|
|
v3: try find handle to existing icon
|
|
|
|
this is the best I can come up with for now, on windows afaict all these icons mostly come from imegares.dll
|
|
so the attached patch is not really how windows does it
|
|
|
|
Fix for bug https://bugs.winehq.org/show_bug.cgi?id=45868
|
|
|
|
Signed-off-by: Louis Lenders <xerox.xerox2000x@gmail.com>
|
|
---
|
|
dlls/shell32/iconcache.c | 156 +++++++++++++++++++++++++++++++--
|
|
dlls/shell32/tests/shelllink.c | 15 ++++
|
|
2 files changed, 164 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/dlls/shell32/iconcache.c b/dlls/shell32/iconcache.c
|
|
index 1851d0d0fc6..705b818083c 100644
|
|
--- a/dlls/shell32/iconcache.c
|
|
+++ b/dlls/shell32/iconcache.c
|
|
@@ -1019,6 +1019,119 @@ INT WINAPI SHGetIconOverlayIndexW(LPCWSTR pszIconPath, INT iIconIndex)
|
|
return -1;
|
|
}
|
|
|
|
+/****************************************************************************
|
|
+ * For SHGetStockIconInfo
|
|
+ */
|
|
+typedef struct {
|
|
+ SHSTOCKICONID id;
|
|
+ DWORD iconid;
|
|
+} SI_ENTRY;
|
|
+
|
|
+static const SI_ENTRY si_table[] =
|
|
+{
|
|
+ [0] = { SIID_DOCNOASSOC, IDI_SHELL_FILE},
|
|
+ [1] = { SIID_DOCASSOC, IDI_SHELL_DOCUMENT},
|
|
+ [2] = { SIID_APPLICATION, IDI_SHELL_WINDOW},
|
|
+ [3] = { SIID_FOLDER, IDI_SHELL_FOLDER},
|
|
+ [4] = { SIID_FOLDEROPEN, IDI_SHELL_FOLDER_OPEN},
|
|
+ [5] = { SIID_DRIVE525, 0},
|
|
+ [6] = { SIID_DRIVE35, 0},
|
|
+ [7] = { SIID_DRIVERREMOVE, 0},
|
|
+ [8] = { SIID_DRIVERFIXED, IDI_SHELL_DRIVE},
|
|
+ [9] = { SIID_DRIVERNET, IDI_SHELL_NETDRIVE},
|
|
+ [10] = { SIID_DRIVERNETDISABLE, IDI_SHELL_NETDRIVE2},
|
|
+ [11] = { SIID_DRIVERCD, IDI_SHELL_OPTICAL_DRIVE},
|
|
+ [12] = { SIID_DRIVERRAM, IDI_SHELL_RAMDISK},
|
|
+ [13] = { SIID_WORLD, 0},
|
|
+ /* Missing: 14 */
|
|
+ [15] = { SIID_SERVER, 0},
|
|
+ [16] = { SIID_PRINTER, IDI_SHELL_PRINT},
|
|
+ [17] = { SIID_MYNETWORK, 0},
|
|
+ /* Missing: 18 - 21 */
|
|
+ [22] = { SIID_FIND, 0},
|
|
+ [23] = { SIID_HELP, IDI_SHELL_HELP},
|
|
+ /* Missing: 24 - 27 */
|
|
+ [28] = {SIID_SHARE, 0},
|
|
+ [29] = {SIID_LINK, 0},
|
|
+ [30] = {SIID_SLOWFILE, 0},
|
|
+ [31] = {SIID_RECYCLER, IDI_SHELL_TRASH_FOLDER},
|
|
+ [32] = {SIID_RECYCLERFULL, IDI_SHELL_FULL_RECYCLE_BIN},
|
|
+ /* Missing: 33 - 39 */
|
|
+ [40] = {SIID_MEDIACDAUDIO, 0},
|
|
+ /* Missing: 41 - 46 */
|
|
+ [47] = {SIID_LOCK, IDI_SHELL_PASSWORDS},
|
|
+ /* Missing: 48 */
|
|
+ [49] = {SIID_AUTOLIST, 0},
|
|
+ [50] = {SIID_PRINTERNET, 0},
|
|
+ [51] = {SIID_SERVERSHARE, 0},
|
|
+ [52] = {SIID_PRINTERFAX, 0},
|
|
+ [53] = {SIID_PRINTERFAXNET, 0},
|
|
+ [54] = {SIID_PRINTERFILE, 0},
|
|
+ [55] = {SIID_STACK, 0},
|
|
+ [56] = {SIID_MEDIASVCD, 0},
|
|
+ [57] = {SIID_STUFFEDFOLDER, 0},
|
|
+ [58] = {SIID_DRIVEUNKNOWN, 0},
|
|
+ [59] = {SIID_DRIVEDVD, 0},
|
|
+ [60] = {SIID_MEDIADVD, 0},
|
|
+ [61] = {SIID_MEDIADVDRAM, 0},
|
|
+ [62] = {SIID_MEDIADVDRW, 0},
|
|
+ [63] = {SIID_MEDIADVDR, 0},
|
|
+ [64] = {SIID_MEDIADVDROM, 0},
|
|
+ [65] = {SIID_MEDIACDAUDIOPLUS, 0},
|
|
+ [66] = {SIID_MEDIACDRW, 0},
|
|
+ [67] = {SIID_MEDIACDR, 0},
|
|
+ [68] = {SIID_MEDIACDBURN, 0},
|
|
+ [69] = {SIID_MEDIABLANKCD, 0},
|
|
+ [70] = {SIID_MEDIACDROM, 0},
|
|
+ [71] = {SIID_AUDIOFILES, IDI_SHELL_AUDIO_FILE},
|
|
+ [72] = {SIID_IMAGEFILES, IDI_SHELL_IMAGE_FILE},
|
|
+ [73] = {SIID_VIDEOFILES, IDI_SHELL_VIDEO_FILE},
|
|
+ [74] = {SIID_MIXEDFILES, 0},
|
|
+ [75] = {SIID_FOLDERBACK, 0},
|
|
+ [76] = {SIID_FOLDERFRONT, 0},
|
|
+ [77] = {SIID_SHIELD, 0},
|
|
+ [78] = {SIID_WARNING, 0},
|
|
+ [79] = {SIID_INFO, 0},
|
|
+ [80] = {SIID_ERROR, 0},
|
|
+ [81] = {SIID_KEY, 0},
|
|
+ [82] = {SIID_SOFTWARE, 0},
|
|
+ [83] = {SIID_RENAME, IDI_SHELL_RENAME},
|
|
+ [84] = {SIID_DELETE, IDI_SHELL_CONFIRM_DELETE},
|
|
+ [85] = {SIID_MEDIAAUDIODVD, 0},
|
|
+ [86] = {SIID_MEDIAMOVIEDVD, 0},
|
|
+ [87] = {SIID_MEDIAENHANCEDCD, 0},
|
|
+ [88] = {SIID_MEDIAENHANCEDDVD, 0},
|
|
+ [89] = {SIID_MEDIAHDDVD, 0},
|
|
+ [90] = {SIID_MEDIABLUERAY, 0},
|
|
+ [91] = {SIID_MEDIAVCD, 0},
|
|
+ [92] = {SIID_MEDIADVDPLUSR, 0},
|
|
+ [93] = {SIID_MEDIADVDPLUSRW, 0},
|
|
+ [94] = {SIID_DESKTOPPC, IDI_SHELL_MY_COMPUTER},
|
|
+ [95] = {SIID_MOBILEPC, 0},
|
|
+ [96] = {SIID_USERS, IDI_SHELL_USERS},
|
|
+ [97] = {SIID_MEDIASMARTMEDIA, 0},
|
|
+ [98] = {SIID_MEDIACOMPACTFLASH, 0},
|
|
+ [99] = {SIID_DEVICECELLPHONE, 0},
|
|
+ [100] = {SIID_DEVICECAMERA, 0},
|
|
+ [101] = {SIID_DEVICEVIDEOCAMERA, 0},
|
|
+ [102] = {SIID_DEVICEAUDIOPLAYER, 0},
|
|
+ [103] = {SIID_NETWORKCONNECT, 0},
|
|
+ [104] = {SIID_INTERNET, IDI_SHELL_WEB_BROWSER},
|
|
+ [105] = {SIID_ZIPFILE, 0},
|
|
+ [106] = {SIID_SETTINGS, IDI_SHELL_SETTINGS},
|
|
+ /* Missing: 107 - 131 */
|
|
+ [132] = {SIID_DRIVEHDDVD, 0},
|
|
+ [133] = {SIID_DRIVEBD, 0},
|
|
+ [134] = {SIID_MEDIAHDDVDROM, 0},
|
|
+ [135] = {SIID_MEDIAHDDVDR, 0},
|
|
+ [136] = {SIID_MEDIAHDDVDRAM, 0},
|
|
+ [137] = {SIID_MEDIABDROM, 0},
|
|
+ [138] = {SIID_MEDIABDR, 0},
|
|
+ [139] = {SIID_MEDIABDRE, 0},
|
|
+ [140] = {SIID_CLUSTEREDDRIVE, 0}
|
|
+ /* Missing: 141 - 180 and SIID_MAX_ICONS = 181*/
|
|
+ };
|
|
+
|
|
/****************************************************************************
|
|
* SHGetStockIconInfo [SHELL32.@]
|
|
*
|
|
@@ -1036,23 +1149,52 @@ INT WINAPI SHGetIconOverlayIndexW(LPCWSTR pszIconPath, INT iIconIndex)
|
|
*/
|
|
HRESULT WINAPI SHGetStockIconInfo(SHSTOCKICONID id, UINT flags, SHSTOCKICONINFO *sii)
|
|
{
|
|
- FIXME("(%d, 0x%x, %p) semi-stub\n", id, flags, sii);
|
|
+ HMODULE hmod;
|
|
+
|
|
+ TRACE("(%d, 0x%x, %p)\n", id, flags, sii);
|
|
+
|
|
if ((id < 0) || (id >= SIID_MAX_ICONS) || !sii || (sii->cbSize != sizeof(SHSTOCKICONINFO))) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
GetSystemDirectoryW(sii->szPath, MAX_PATH);
|
|
-
|
|
- /* no icons defined: use default */
|
|
- sii->iIcon = -IDI_SHELL_FILE;
|
|
lstrcatW(sii->szPath, L"\\shell32.dll");
|
|
|
|
- if (flags)
|
|
- FIXME("flags 0x%x not implemented\n", flags);
|
|
-
|
|
sii->hIcon = NULL;
|
|
sii->iSysImageIndex = -1;
|
|
|
|
+ /* this is not how windows does it, on windows picked mostly from imageres.dll !*/
|
|
+ if (si_table[id].iconid)
|
|
+ sii->iIcon = sii->iSysImageIndex - si_table[id].id;
|
|
+ else
|
|
+ {
|
|
+ FIXME("Couldn`t find SIID %d, returning default values (IDI_SHELL_FILE)\n", id);
|
|
+ sii->iIcon = sii->iSysImageIndex - IDI_SHELL_FILE;
|
|
+ }
|
|
+
|
|
+ if (flags & SHGSI_ICON)
|
|
+ {
|
|
+ flags &= ~SHGSI_ICON;
|
|
+
|
|
+ hmod = GetModuleHandleW(L"shell32.dll");
|
|
+ if (hmod)
|
|
+ {
|
|
+ if (si_table[id].iconid)
|
|
+ sii->hIcon = LoadIconW(hmod, MAKEINTRESOURCEW(si_table[id].iconid));
|
|
+ else
|
|
+ sii->hIcon = LoadIconW(hmod, MAKEINTRESOURCEW(IDI_SHELL_FILE));
|
|
+ }
|
|
+
|
|
+ if (!sii->hIcon)
|
|
+ {
|
|
+ ERR("failed to get an icon handle\n");
|
|
+ return E_INVALIDARG;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (flags)
|
|
+ FIXME("flags 0x%x not implemented\n", flags);
|
|
+
|
|
TRACE("%3d: returning %s (%d)\n", id, debugstr_w(sii->szPath), sii->iIcon);
|
|
|
|
return S_OK;
|
|
diff --git a/dlls/shell32/tests/shelllink.c b/dlls/shell32/tests/shelllink.c
|
|
index e4e1e664038..b2e95e5301a 100644
|
|
--- a/dlls/shell32/tests/shelllink.c
|
|
+++ b/dlls/shell32/tests/shelllink.c
|
|
@@ -1073,6 +1073,21 @@ static void test_SHGetStockIconInfo(void)
|
|
/* there is a NULL check for the struct */
|
|
hr = pSHGetStockIconInfo(SIID_FOLDER, SHGSI_ICONLOCATION, NULL);
|
|
ok(hr == E_INVALIDARG, "NULL: got 0x%lx\n", hr);
|
|
+
|
|
+ for(i = 0; i < 140; i++) /* highest on wvista, i > 140 gives E_INVALIDARG, win7 can go higher */
|
|
+ {
|
|
+ memset(buffer, 0, sizeof(buffer));
|
|
+ sii->cbSize = sizeof(SHSTOCKICONINFO);
|
|
+ hr = pSHGetStockIconInfo(i, SHGSI_ICON | SHGSI_SMALLICON, sii);
|
|
+ ok(hr == S_OK, "got 0x%lx (expected S_OK)\n", hr);
|
|
+ ok(sii->hIcon != NULL, "got NULL, expected an icon handle\n");
|
|
+ ok(sii->iIcon != 0, "got unexpected 0 for SIID %d\n", i); /* howto find out exact sii->iIcon value??? */
|
|
+ ok(sii->iSysImageIndex == -1, "got %ld (expected -1)\n", sii->iSysImageIndex);
|
|
+ ok(DestroyIcon(sii->hIcon), "DestroyIcon failed\n");
|
|
+ if (winetest_debug > 1)
|
|
+ trace("%3d: got iSysImageIndex %3d, iIcon %3d and %s\n", i, sii->iSysImageIndex,
|
|
+ sii->iIcon, wine_dbgstr_w(sii->szPath));
|
|
+ }
|
|
}
|
|
|
|
static void test_SHExtractIcons(void)
|
|
--
|
|
2.35.1
|
|
|