diff --git a/dll/win32/shell32/folders/CDrivesFolder.cpp b/dll/win32/shell32/folders/CDrivesFolder.cpp index cf76b47392d..ba1a3d10160 100644 --- a/dll/win32/shell32/folders/CDrivesFolder.cpp +++ b/dll/win32/shell32/folders/CDrivesFolder.cpp @@ -511,15 +511,48 @@ HRESULT CDrivesExtractIcon_CreateInstance(IShellFolder * psf, LPCITEMIDLIST pidl DriveType = DRIVE_FIXED; WCHAR wTemp[MAX_PATH]; - int icon_idx; + int icon_idx, reg_idx; UINT flags = 0; - if ((DriveType == DRIVE_FIXED || DriveType == DRIVE_UNKNOWN) && - (HCR_GetIconW(L"Drive", wTemp, NULL, MAX_PATH, &icon_idx))) + + switch (DriveType) + { + case DRIVE_FIXED: + case DRIVE_UNKNOWN: + reg_idx = IDI_SHELL_DRIVE; + break; + case DRIVE_CDROM: + reg_idx = IDI_SHELL_CDROM; + break; + case DRIVE_REMOTE: + reg_idx = IDI_SHELL_NETDRIVE; + break; + case DRIVE_REMOVABLE: + if (!IsDriveFloppyA(pszDrive)) + reg_idx = IDI_SHELL_REMOVEABLE; + else + reg_idx = IDI_SHELL_3_14_FLOPPY; + break; + case DRIVE_RAMDISK: + reg_idx = IDI_SHELL_RAMDISK; + break; + case DRIVE_NO_ROOT_DIR: + default: + reg_idx = IDI_SHELL_DOCUMENT; + break; + } + + hr = getIconLocationForDrive(psf, pidl, 0, wTemp, _countof(wTemp), + &icon_idx, &flags); + if (SUCCEEDED(hr)) { initIcon->SetNormalIcon(wTemp, icon_idx); } - else if (SUCCEEDED(getIconLocationForDrive(psf, pidl, 0, wTemp, _countof(wTemp), - &icon_idx, &flags))) + else if (HLM_GetIconW(reg_idx - 1, wTemp, _countof(wTemp), &icon_idx)) + { + initIcon->SetNormalIcon(wTemp, icon_idx); + } + else if ((DriveType == DRIVE_FIXED || DriveType == DRIVE_UNKNOWN) && + (HCR_GetIconW(L"Drive", wTemp, NULL, _countof(wTemp), &icon_idx))) { initIcon->SetNormalIcon(wTemp, icon_idx); } diff --git a/dll/win32/shell32/folders/CFSFolder.cpp b/dll/win32/shell32/folders/CFSFolder.cpp index 93cacdd1e2f..4f26b4eb864 100644 --- a/dll/win32/shell32/folders/CFSFolder.cpp +++ b/dll/win32/shell32/folders/CFSFolder.cpp @@ -136,10 +136,13 @@ HRESULT GetCLSIDForFileType(PCUIDLIST_RELATIVE pidl, LPCWSTR KeyName, CLSID* pcl static HRESULT getDefaultIconLocation(LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT uFlags) { - if (!HCR_GetIconW(L"Folder", szIconFile, NULL, cchMax, piIndex)) + if (!HLM_GetIconW(IDI_SHELL_FOLDER - 1, szIconFile, cchMax, piIndex)) { - lstrcpynW(szIconFile, swShell32Name, cchMax); - *piIndex = -IDI_SHELL_FOLDER; + if (!HCR_GetIconW(L"Folder", szIconFile, NULL, cchMax, piIndex)) + { + StringCchCopyW(szIconFile, cchMax, swShell32Name); + *piIndex = -IDI_SHELL_FOLDER; + } } if (uFlags & GIL_OPENICON) diff --git a/dll/win32/shell32/folders/CRegFolder.cpp b/dll/win32/shell32/folders/CRegFolder.cpp index 6c5c3f7f3cb..489731638fd 100644 --- a/dll/win32/shell32/folders/CRegFolder.cpp +++ b/dll/win32/shell32/folders/CRegFolder.cpp @@ -123,6 +123,16 @@ HRESULT CGuidItemContextMenu_CreateInstance(PCIDLIST_ABSOLUTE pidlFolder, return CDefFolderMenu_Create2(pidlFolder, hwnd, cidl, apidl, psf, RegFolderContextMenuCallback, cKeys, hKeys, ppcm); } +HRESULT FormatGUIDKey(LPWSTR KeyName, SIZE_T KeySize, LPCWSTR RegPath, const GUID* riid) +{ + WCHAR xriid[40]; + + if (!StringFromGUID2(*riid, xriid, _countof(xriid) - 1)) + return E_FAIL; + + return StringCchPrintfW(KeyName, KeySize, RegPath, xriid); +} + HRESULT CGuidItemExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID iid, LPVOID * ppvOut) { CComPtr initIcon; @@ -145,14 +155,7 @@ HRESULT CGuidItemExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID iid, LPVO if (!riid) return E_FAIL; - /* my computer and other shell extensions */ - WCHAR xriid[50]; - - swprintf(xriid, L"CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", - riid->Data1, riid->Data2, riid->Data3, - riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3], - riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]); - + /* Choose a correct icon for Recycle Bin (full or empty) */ const WCHAR* iconname = NULL; if (_ILIsBitBucket(pidl)) { @@ -179,23 +182,37 @@ HRESULT CGuidItemExtractIcon_CreateInstance(LPCITEMIDLIST pidl, REFIID iid, LPVO } } - if (HCR_GetIconW(xriid, wTemp, iconname, MAX_PATH, &icon_idx)) + /* Prepare registry path for loading icons of My Computer and other shell extensions */ + WCHAR KeyName[MAX_PATH]; + + hr = FormatGUIDKey(KeyName, _countof(KeyName), + L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CLSID\\%s", + riid); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + /* Load icon for the current user */ + BOOL ret = HCU_GetIconW(KeyName, wTemp, iconname, _countof(wTemp), &icon_idx); + if (!ret) { + /* Failed, load default system-wide icon */ + hr = FormatGUIDKey(KeyName, _countof(KeyName), L"CLSID\\%s", riid); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + ret = HCR_GetIconW(KeyName, wTemp, iconname, _countof(wTemp), &icon_idx); + } + + if (ret) + { + /* Success, set loaded icon */ initIcon->SetNormalIcon(wTemp, icon_idx); } else { - // FIXME: Delete these hacks and make HCR_GetIconW and registry working - if (IsEqualGUID(*riid, CLSID_MyComputer)) - initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_COMPUTER); - else if (IsEqualGUID(*riid, CLSID_MyDocuments)) - initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_DOCUMENTS); - else if (IsEqualGUID(*riid, CLSID_NetworkPlaces)) - initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_MY_NETWORK_PLACES); - else if (IsEqualGUID(*riid, CLSID_Internet)) - initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_WEB_BROWSER); - else - initIcon->SetNormalIcon(swShell32Name, -IDI_SHELL_FOLDER); + /* Everything has failed, set blank paper icon */ + WARN("Failed to load an icon for the item, setting blank icon\n"); + initIcon->SetNormalIcon(swShell32Name, IDI_SHELL_DOCUMENT - 1); } return initIcon->QueryInterface(iid, ppvOut); diff --git a/dll/win32/shell32/iconcache.cpp b/dll/win32/shell32/iconcache.cpp index 9a55f0f9fc0..4af8d2a5c0d 100644 --- a/dll/win32/shell32/iconcache.cpp +++ b/dll/win32/shell32/iconcache.cpp @@ -654,34 +654,20 @@ void SIC_Destroy(void) */ static int SIC_LoadOverlayIcon(int icon_idx) { - WCHAR buffer[1024], wszIdx[8]; - HKEY hKeyShellIcons; - LPCWSTR iconPath; + WCHAR buffer[1024]; + LPWSTR iconPath; int iconIdx; iconPath = swShell32Name; /* default: load icon from shell32.dll */ iconIdx = icon_idx; - if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons", - 0, KEY_READ, &hKeyShellIcons) == ERROR_SUCCESS) + if (HLM_GetIconW(icon_idx, buffer, _countof(buffer), &iconIdx)) { - DWORD count = sizeof(buffer); - - swprintf(wszIdx, L"%d", icon_idx); - - /* read icon path and index */ - if (RegQueryValueExW(hKeyShellIcons, wszIdx, NULL, NULL, (LPBYTE)buffer, &count) == ERROR_SUCCESS) - { - LPWSTR p = wcschr(buffer, ','); - - if (p) - *p++ = 0; - - iconPath = buffer; - iconIdx = _wtoi(p); - } - - RegCloseKey(hKeyShellIcons); + iconPath = buffer; + } + else + { + WARN("Failed to load icon with index %d, using default one\n", icon_idx); } if (!sic_hdpa) diff --git a/dll/win32/shell32/wine/classes.c b/dll/win32/shell32/wine/classes.c index ede060044c4..0247add2710 100644 --- a/dll/win32/shell32/wine/classes.c +++ b/dll/win32/shell32/wine/classes.c @@ -34,6 +34,9 @@ #include #include #include +#ifdef __REACTOS__ +#include +#endif #include "pidl.h" #include "shell32_main.h" @@ -334,6 +337,60 @@ BOOL HCR_GetIconA(LPCSTR szClass, LPSTR szDest, LPCSTR szName, DWORD len, int* p return ret; } +#ifdef __REACTOS__ +BOOL HCU_GetIconW(LPCWSTR szClass, LPWSTR szDest, LPCWSTR szName, DWORD len, int* picon_idx) +{ + HKEY hkey; + WCHAR sTemp[MAX_PATH]; + BOOL ret = FALSE; + + TRACE("%s\n", debugstr_w(szClass)); + + StringCchPrintfW(sTemp, _countof(sTemp), L"%s\\DefaultIcon", szClass); + + if (!RegOpenKeyExW(HKEY_CURRENT_USER, sTemp, 0, KEY_READ, &hkey)) + { + ret = HCR_RegGetIconW(hkey, szDest, szName, len, picon_idx); + RegCloseKey(hkey); + } + + if (ret) + TRACE("-- %s %i\n", debugstr_w(szDest), *picon_idx); + else + TRACE("-- not found\n"); + + return ret; +} + +BOOL HLM_GetIconW(int reg_idx, LPWSTR szDest, DWORD len, int* picon_idx) +{ + HKEY hkey; + WCHAR sTemp[5]; + BOOL ret = FALSE; + + TRACE("%d\n", reg_idx); + + StringCchPrintfW(sTemp, _countof(sTemp), L"%d", reg_idx); + + if (!RegOpenKeyExW(HKEY_LOCAL_MACHINE, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons", + 0, + KEY_READ, + &hkey)) + { + ret = HCR_RegGetIconW(hkey, szDest, sTemp, len, picon_idx); + RegCloseKey(hkey); + } + + if (ret) + TRACE("-- %s %i\n", debugstr_w(szDest), *picon_idx); + else + TRACE("-- not found\n"); + + return ret; +} +#endif + /*************************************************************************************** * HCR_GetClassName [internal] * diff --git a/dll/win32/shell32/wine/shell32_main.h b/dll/win32/shell32/wine/shell32_main.h index a9da0b2e10f..b0965028090 100644 --- a/dll/win32/shell32/wine/shell32_main.h +++ b/dll/win32/shell32/wine/shell32_main.h @@ -50,6 +50,14 @@ BOOL HCR_GetExecuteCommandW( HKEY hkeyClass, LPCWSTR szClass, LPCWSTR szVerb, LP BOOL HCR_GetIconW(LPCWSTR szClass, LPWSTR szDest, LPCWSTR szName, DWORD len, int* picon_idx); BOOL HCR_GetClassNameW(REFIID riid, LPWSTR szDest, DWORD len) DECLSPEC_HIDDEN; +#ifdef __REACTOS__ +/* Current User */ +BOOL HCU_GetIconW(LPCWSTR szClass, LPWSTR szDest, LPCWSTR szName, DWORD len, int* picon_idx) DECLSPEC_HIDDEN; + +/* Local Machine */ +BOOL HLM_GetIconW(int reg_idx, LPWSTR szDest, DWORD len, int* picon_idx) DECLSPEC_HIDDEN; +#endif + /* ANSI versions of above functions, supposed to go away as soon as they are not used anymore */ BOOL HCR_MapTypeToValueA(LPCSTR szExtension, LPSTR szFileType, LONG len, BOOL bPrependDot) DECLSPEC_HIDDEN; BOOL HCR_GetIconA(LPCSTR szClass, LPSTR szDest, LPCSTR sName, DWORD len, int* picon_idx);