mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 06:15:26 +00:00
[0.4.10][SHELL32][USER32] Improve MSVC2010SP1 bootcd icon rendering CORE-14982 and CORE-15150
During 0.4.10-dev' Katayama worked heavily on the icon selection dialog and when we branched the releases/0.4.10 that was WIP, so we had a pretty inconsistent state unfortunately regarding extracting the desktop icons. The required fixing took a very long time into 0.4.11-dev'ing back then. So my only option for releases/0.4.10 back then was to appease the problems via 0.4.10-RC-13-g3a1fe9d044
which worked very well and gave a consistent state for the GCC build. Unfortunately it lead to the MSVC2010SP1 dbg build bootcd to not show some icons on the desktop and within the whole startmenu. As said: GCC was not affected by that. And LiveCD was neither. So today I do port back the remaining improvements in this context from 0.4.11-dev'ing to improve again also for the MSVC2010SP1 builds bootcd of releases/0.4.10: 0.4.11-dev-361-g2cbac3d049
[SHELL32] CORE-14982 0.4.11-dev-357-g40737bdddb
[USER32] Fix the ICO_ExtractIconExW() helper CORE-15150 <- this part is essential 0.4.11-dev-29-g19e9a44118
[SHELL32] Check the result from PathUnExpandEnvStringsW And while touching the file CShellLink.cpp anyway, I took also some other small unrelated improvements with me: 0.4.11-dev-360-g1e20a3e5b5
[SHELL32] 'Fix a potential buffer overrun' (which is a tiny part of CORE-8545) 0.4.11-dev-256-gae9ec94240
[SHELL32] Code formatting only (I picked only the CShellLink.cpp changes here) 0.4.11-dev-28-g608cb60e44
[SHELL32] Remove some mostly dead code from CShellLink
This commit is contained in:
parent
bada20db6d
commit
e95c6fe661
2 changed files with 117 additions and 98 deletions
|
@ -143,6 +143,14 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||
|
||||
/*
|
||||
* Allows to define whether or not Windows-compatible behaviour
|
||||
* should be adopted when setting and retrieving icon location paths.
|
||||
* See CShellLink::SetIconLocation(LPCWSTR pszIconPath, INT iIcon)
|
||||
* for more details.
|
||||
*/
|
||||
#define ICON_LINK_WINDOWS_COMPAT
|
||||
|
||||
#define SHLINK_LOCAL 0
|
||||
#define SHLINK_REMOTE 1
|
||||
|
||||
|
@ -349,14 +357,10 @@ HRESULT STDMETHODCALLTYPE CShellLink::Save(LPCOLESTR pszFileName, BOOL fRemember
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (pszFileName != m_sLinkPath)
|
||||
{
|
||||
if (m_sLinkPath)
|
||||
HeapFree(GetProcessHeap(), 0, m_sLinkPath);
|
||||
|
||||
m_sLinkPath = strdupW(pszFileName);
|
||||
}
|
||||
if (m_sLinkPath)
|
||||
HeapFree(GetProcessHeap(), 0, m_sLinkPath);
|
||||
|
||||
m_sLinkPath = strdupW(pszFileName);
|
||||
m_bDirty = FALSE;
|
||||
}
|
||||
else
|
||||
|
@ -523,7 +527,7 @@ static LPWSTR Stream_LoadPath(LPCSTR p, DWORD maxlen)
|
|||
{
|
||||
UINT len = 0;
|
||||
|
||||
while (p[len] && len < maxlen)
|
||||
while (len < maxlen && p[len])
|
||||
len++;
|
||||
|
||||
UINT wlen = MultiByteToWideChar(CP_ACP, 0, p, len, NULL, 0);
|
||||
|
@ -1204,7 +1208,6 @@ HRESULT STDMETHODCALLTYPE CShellLink::SetArguments(LPCSTR pszArgs)
|
|||
if (!m_sArgs)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
m_bDirty = TRUE;
|
||||
|
||||
return S_OK;
|
||||
|
@ -1403,7 +1406,6 @@ HRESULT STDMETHODCALLTYPE CShellLink::Resolve(HWND hwnd, DWORD fFlags)
|
|||
|
||||
/* Clear the cached path */
|
||||
HeapFree(GetProcessHeap(), 0, m_sPath);
|
||||
m_sPath = NULL;
|
||||
m_sPath = shelllink_get_msi_component_path(component);
|
||||
if (!m_sPath)
|
||||
return E_FAIL;
|
||||
|
@ -1416,12 +1418,9 @@ HRESULT STDMETHODCALLTYPE CShellLink::Resolve(HWND hwnd, DWORD fFlags)
|
|||
bSuccess = SHGetPathFromIDListW(m_pPidl, buffer);
|
||||
if (bSuccess && *buffer)
|
||||
{
|
||||
if (buffer != m_sPath)
|
||||
{
|
||||
m_sPath = strdupW(buffer);
|
||||
if (!m_sPath)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
m_sPath = strdupW(buffer);
|
||||
if (!m_sPath)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
m_bDirty = TRUE;
|
||||
}
|
||||
|
@ -1434,12 +1433,9 @@ HRESULT STDMETHODCALLTYPE CShellLink::Resolve(HWND hwnd, DWORD fFlags)
|
|||
// FIXME: Strange to do that here...
|
||||
if (!m_sIcoPath && m_sPath)
|
||||
{
|
||||
if (m_sIcoPath != m_sPath)
|
||||
{
|
||||
m_sIcoPath = strdupW(m_sPath);
|
||||
if (!m_sIcoPath)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
m_sIcoPath = strdupW(m_sPath);
|
||||
if (!m_sIcoPath)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
m_Header.nIconIndex = 0;
|
||||
|
||||
|
@ -1563,18 +1559,14 @@ HRESULT STDMETHODCALLTYPE CShellLink::SetDescription(LPCWSTR pszName)
|
|||
TRACE("(%p)->(desc=%s)\n", this, debugstr_w(pszName));
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, m_sDescription);
|
||||
m_sDescription = NULL;
|
||||
|
||||
if (pszName)
|
||||
{
|
||||
if (m_sDescription != pszName)
|
||||
{
|
||||
m_sDescription = strdupW(pszName);
|
||||
if (!m_sDescription)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
m_sDescription = strdupW(pszName);
|
||||
if (!m_sDescription)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
else
|
||||
m_sDescription = NULL;
|
||||
|
||||
m_bDirty = TRUE;
|
||||
|
||||
return S_OK;
|
||||
|
@ -1598,18 +1590,14 @@ HRESULT STDMETHODCALLTYPE CShellLink::SetWorkingDirectory(LPCWSTR pszDir)
|
|||
TRACE("(%p)->(dir=%s)\n", this, debugstr_w(pszDir));
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, m_sWorkDir);
|
||||
m_sWorkDir = NULL;
|
||||
|
||||
if (pszDir)
|
||||
{
|
||||
if (m_sWorkDir != pszDir)
|
||||
{
|
||||
m_sWorkDir = strdupW(pszDir);
|
||||
if (!m_sWorkDir)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
m_sWorkDir = strdupW(pszDir);
|
||||
if (!m_sWorkDir)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
else
|
||||
m_sWorkDir = NULL;
|
||||
|
||||
m_bDirty = TRUE;
|
||||
|
||||
return S_OK;
|
||||
|
@ -1633,18 +1621,14 @@ HRESULT STDMETHODCALLTYPE CShellLink::SetArguments(LPCWSTR pszArgs)
|
|||
TRACE("(%p)->(args=%s)\n", this, debugstr_w(pszArgs));
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, m_sArgs);
|
||||
m_sArgs = NULL;
|
||||
|
||||
if (pszArgs)
|
||||
{
|
||||
if (m_sArgs != pszArgs)
|
||||
{
|
||||
m_sArgs = strdupW(pszArgs);
|
||||
if (!m_sArgs)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
m_sArgs = strdupW(pszArgs);
|
||||
if (!m_sArgs)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
else
|
||||
m_sArgs = NULL;
|
||||
|
||||
m_bDirty = TRUE;
|
||||
|
||||
return S_OK;
|
||||
|
@ -1669,18 +1653,14 @@ HRESULT STDMETHODCALLTYPE CShellLink::GetIconLocation(LPWSTR pszIconPath, INT cc
|
|||
pInfo = (LPEXP_SZ_LINK)SHFindDataBlock(m_pDBList, EXP_SZ_ICON_SIG);
|
||||
if (pInfo && (pInfo->cbSize == sizeof(*pInfo)))
|
||||
{
|
||||
m_Header.dwFlags &= ~SLDF_HAS_ICONLOCATION;
|
||||
HeapFree(GetProcessHeap(), 0, m_sIcoPath);
|
||||
m_sIcoPath = NULL;
|
||||
|
||||
SHExpandEnvironmentStringsW(pInfo->szwTarget, szPath, _countof(szPath));
|
||||
|
||||
if (m_sIcoPath != szPath)
|
||||
{
|
||||
m_sIcoPath = strdupW(szPath);
|
||||
if (!m_sIcoPath)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
m_Header.dwFlags &= ~SLDF_HAS_ICONLOCATION;
|
||||
HeapFree(GetProcessHeap(), 0, m_sIcoPath);
|
||||
|
||||
m_sIcoPath = strdupW(szPath);
|
||||
if (!m_sIcoPath)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
m_Header.dwFlags |= SLDF_HAS_ICONLOCATION;
|
||||
|
||||
|
@ -1743,7 +1723,7 @@ HRESULT STDMETHODCALLTYPE CShellLink::GetIconLocation(UINT uFlags, PWSTR pszIcon
|
|||
uFlags |= GIL_FORSHORTCUT;
|
||||
|
||||
if (uFlags & GIL_DEFAULTICON)
|
||||
return E_FAIL;
|
||||
return S_FALSE;
|
||||
|
||||
hr = GetIconLocation(pszIconFile, cchMax, piIndex);
|
||||
if (FAILED(hr) || pszIconFile[0] == UNICODE_NULL)
|
||||
|
@ -1877,14 +1857,12 @@ BOOL PathFullyUnExpandEnvStringsW(
|
|||
HRESULT STDMETHODCALLTYPE CShellLink::SetIconLocation(LPCWSTR pszIconPath, INT iIcon)
|
||||
{
|
||||
HRESULT hr = E_FAIL;
|
||||
WCHAR szUnExpIconPath[MAX_PATH];
|
||||
WCHAR szIconPath[MAX_PATH];
|
||||
|
||||
TRACE("(%p)->(path=%s iicon=%u)\n", this, debugstr_w(pszIconPath), iIcon);
|
||||
|
||||
if (pszIconPath)
|
||||
{
|
||||
/* Try to fully unexpand the icon path */
|
||||
|
||||
/*
|
||||
* Check whether the user-given file path contains unexpanded
|
||||
* environment variables. If so, create a target environment block.
|
||||
|
@ -1895,16 +1873,35 @@ HRESULT STDMETHODCALLTYPE CShellLink::SetIconLocation(LPCWSTR pszIconPath, INT i
|
|||
* refer to the same place even if the would-be corresponding
|
||||
* environment variable could change).
|
||||
*/
|
||||
// FIXME: http://stackoverflow.com/questions/2976489/ishelllinkseticonlocation-translates-my-icon-path-into-program-files-which-i
|
||||
// if (PathFullyUnExpandEnvStringsW(pszIconPath, szUnExpIconPath, _countof(szUnExpIconPath)))
|
||||
PathUnExpandEnvStringsW(pszIconPath, szUnExpIconPath, _countof(szUnExpIconPath));
|
||||
if (wcscmp(pszIconPath, szUnExpIconPath) != 0)
|
||||
#ifdef ICON_LINK_WINDOWS_COMPAT
|
||||
/* Try to fully unexpand the icon path */
|
||||
// if (PathFullyUnExpandEnvStringsW(pszIconPath, szIconPath, _countof(szIconPath)))
|
||||
BOOL bSuccess = PathUnExpandEnvStringsW(pszIconPath, szIconPath, _countof(szIconPath));
|
||||
if (bSuccess && wcscmp(pszIconPath, szIconPath) != 0)
|
||||
#else
|
||||
/*
|
||||
* In some situations, described in http://stackoverflow.com/questions/2976489/ishelllinkseticonlocation-translates-my-icon-path-into-program-files-which-i
|
||||
* the result of PathUnExpandEnvStringsW() could be wrong, and instead
|
||||
* one would have to store the actual provided icon location path, while
|
||||
* creating an icon environment block ONLY if that path already contains
|
||||
* environment variables. This is what the present case is trying to implement.
|
||||
*/
|
||||
SHExpandEnvironmentStringsW(pszIconPath, szIconPath, _countof(szIconPath));
|
||||
if (wcscmp(pszIconPath, szIconPath) != 0)
|
||||
#endif
|
||||
{
|
||||
/* Unexpansion succeeded, so we need an icon environment block */
|
||||
/*
|
||||
* The user-given file path contains unexpanded environment
|
||||
* variables, so we need an icon environment block.
|
||||
*/
|
||||
EXP_SZ_LINK buffer;
|
||||
LPEXP_SZ_LINK pInfo;
|
||||
|
||||
pszIconPath = szUnExpIconPath;
|
||||
#ifdef ICON_LINK_WINDOWS_COMPAT
|
||||
/* Make pszIconPath point to the unexpanded path */
|
||||
LPCWSTR pszOrgIconPath = pszIconPath;
|
||||
pszIconPath = szIconPath;
|
||||
#endif
|
||||
pInfo = (LPEXP_SZ_LINK)SHFindDataBlock(m_pDBList, EXP_SZ_ICON_SIG);
|
||||
if (pInfo)
|
||||
{
|
||||
|
@ -1929,8 +1926,8 @@ HRESULT STDMETHODCALLTYPE CShellLink::SetIconLocation(LPCWSTR pszIconPath, INT i
|
|||
buffer.dwSignature = EXP_SZ_ICON_SIG;
|
||||
}
|
||||
|
||||
lstrcpynW(pInfo->szwTarget, szUnExpIconPath, _countof(pInfo->szwTarget));
|
||||
WideCharToMultiByte(CP_ACP, 0, szUnExpIconPath, -1,
|
||||
lstrcpynW(pInfo->szwTarget, pszIconPath, _countof(pInfo->szwTarget));
|
||||
WideCharToMultiByte(CP_ACP, 0, pszIconPath, -1,
|
||||
pInfo->szTarget, _countof(pInfo->szTarget), NULL, NULL);
|
||||
|
||||
hr = S_OK;
|
||||
|
@ -1938,28 +1935,39 @@ HRESULT STDMETHODCALLTYPE CShellLink::SetIconLocation(LPCWSTR pszIconPath, INT i
|
|||
hr = AddDataBlock(pInfo);
|
||||
if (hr == S_OK)
|
||||
m_Header.dwFlags |= SLDF_HAS_EXP_ICON_SZ;
|
||||
|
||||
#ifdef ICON_LINK_WINDOWS_COMPAT
|
||||
/* Set pszIconPath back to the original one */
|
||||
pszIconPath = pszOrgIconPath;
|
||||
#else
|
||||
/* Now, make pszIconPath point to the expanded path */
|
||||
pszIconPath = szIconPath;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unexpansion failed, so we need to remove any icon environment block */
|
||||
/*
|
||||
* The user-given file path does not contain unexpanded environment
|
||||
* variables, so we need to remove any icon environment block.
|
||||
*/
|
||||
m_Header.dwFlags &= ~SLDF_HAS_EXP_ICON_SZ;
|
||||
RemoveDataBlock(EXP_SZ_ICON_SIG);
|
||||
|
||||
/* pszIconPath points to the user path */
|
||||
}
|
||||
}
|
||||
|
||||
/* Store the original icon path location (this one may contain unexpanded environment strings) */
|
||||
#ifdef ICON_LINK_WINDOWS_COMPAT
|
||||
/* Store the original icon path location (may contain unexpanded environment strings) */
|
||||
#endif
|
||||
if (pszIconPath)
|
||||
{
|
||||
m_Header.dwFlags &= ~SLDF_HAS_ICONLOCATION;
|
||||
HeapFree(GetProcessHeap(), 0, m_sIcoPath);
|
||||
m_sIcoPath = NULL;
|
||||
|
||||
if (m_sIcoPath != pszIconPath)
|
||||
{
|
||||
m_sIcoPath = strdupW(pszIconPath);
|
||||
if (!m_sIcoPath)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
m_sIcoPath = strdupW(pszIconPath);
|
||||
if (!m_sIcoPath)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
m_Header.dwFlags |= SLDF_HAS_ICONLOCATION;
|
||||
}
|
||||
|
@ -1977,18 +1985,14 @@ HRESULT STDMETHODCALLTYPE CShellLink::SetRelativePath(LPCWSTR pszPathRel, DWORD
|
|||
TRACE("(%p)->(path=%s %x)\n", this, debugstr_w(pszPathRel), dwReserved);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, m_sPathRel);
|
||||
m_sPathRel = NULL;
|
||||
|
||||
if (pszPathRel)
|
||||
{
|
||||
if (m_sPathRel != pszPathRel)
|
||||
{
|
||||
m_sPathRel = strdupW(pszPathRel);
|
||||
if (!m_sPathRel)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
m_sPathRel = strdupW(pszPathRel);
|
||||
if (!m_sPathRel)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
else
|
||||
m_sPathRel = NULL;
|
||||
|
||||
m_bDirty = TRUE;
|
||||
|
||||
return ShellLink_UpdatePath(m_sPathRel, m_sPath, m_sWorkDir, &m_sPath);
|
||||
|
@ -2327,12 +2331,12 @@ HRESULT CShellLink::SetTargetFromPIDLOrPath(LPCITEMIDLIST pidl, LPCWSTR pszFile)
|
|||
/* Update the cached path (for link info) */
|
||||
ShellLink_GetVolumeInfo(pszFile, &volume);
|
||||
|
||||
if (m_sPath != pszFile)
|
||||
{
|
||||
m_sPath = strdupW(pszFile);
|
||||
if (!m_sPath)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
if (m_sPath)
|
||||
HeapFree(GetProcessHeap(), 0, m_sPath);
|
||||
|
||||
m_sPath = strdupW(pszFile);
|
||||
if (!m_sPath)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
m_bDirty = TRUE;
|
||||
return hr;
|
||||
|
@ -2439,7 +2443,7 @@ HRESULT STDMETHODCALLTYPE CShellLink::SetPath(LPCWSTR pszFile)
|
|||
if (hr == S_OK)
|
||||
m_Header.dwFlags |= SLDF_HAS_EXP_SZ;
|
||||
|
||||
/* Now, make pszFile point to the expanded buffer */
|
||||
/* Now, make pszFile point to the expanded path */
|
||||
pszFile = szPath;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
|
||||
#include <user32.h>
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
/* Start of Hack section */
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(icon);
|
||||
|
@ -275,13 +279,24 @@ static UINT ICO_ExtractIconExW(
|
|||
LPBYTE peimage;
|
||||
HANDLE fmapping;
|
||||
DWORD fsizeh,fsizel;
|
||||
#ifdef __REACTOS__
|
||||
WCHAR szExpandedExePath[MAX_PATH];
|
||||
#endif
|
||||
WCHAR szExePath[MAX_PATH];
|
||||
DWORD dwSearchReturn;
|
||||
|
||||
TRACE("%s, %d, %d %p 0x%08x\n", debugstr_w(lpszExeFileName), nIconIndex, nIcons, pIconId, flags);
|
||||
|
||||
dwSearchReturn = SearchPathW(NULL, lpszExeFileName, NULL, sizeof(szExePath) / sizeof(szExePath[0]), szExePath, NULL);
|
||||
if ((dwSearchReturn == 0) || (dwSearchReturn > sizeof(szExePath) / sizeof(szExePath[0])))
|
||||
#ifdef __REACTOS__
|
||||
if (RetPtr)
|
||||
*RetPtr = NULL;
|
||||
|
||||
if (ExpandEnvironmentStringsW(lpszExeFileName, szExpandedExePath, ARRAY_SIZE(szExpandedExePath)))
|
||||
lpszExeFileName = szExpandedExePath;
|
||||
#endif
|
||||
|
||||
dwSearchReturn = SearchPathW(NULL, lpszExeFileName, NULL, ARRAY_SIZE(szExePath), szExePath, NULL);
|
||||
if ((dwSearchReturn == 0) || (dwSearchReturn > ARRAY_SIZE(szExePath)))
|
||||
{
|
||||
WARN("File %s not found or path too long\n", debugstr_w(lpszExeFileName));
|
||||
return -1;
|
||||
|
|
Loading…
Reference in a new issue