Commit 4ec5aa68 authored by Michael Jung's avatar Michael Jung Committed by Alexandre Julliard

Append filename extension if necessary in IShellFolder::SetNameOf.

parent da6f8fac
...@@ -70,3 +70,4 @@ static inline int SHELL32_GUIDToStringW (REFGUID guid, LPWSTR str) ...@@ -70,3 +70,4 @@ static inline int SHELL32_GUIDToStringW (REFGUID guid, LPWSTR str)
} }
void SHELL_FS_ProcessDisplayFilename(LPSTR szPath, DWORD dwFlags); void SHELL_FS_ProcessDisplayFilename(LPSTR szPath, DWORD dwFlags);
BOOL SHELL_FS_HideExtension(LPWSTR pwszPath);
...@@ -700,7 +700,20 @@ static const WCHAR HideFileExtW[] = { 'H','i','d','e','F','i','l','e','E','x', ...@@ -700,7 +700,20 @@ static const WCHAR HideFileExtW[] = { 'H','i','d','e','F','i','l','e','E','x',
static const WCHAR NeverShowExtW[] = { 'N','e','v','e','r','S','h','o','w','E', static const WCHAR NeverShowExtW[] = { 'N','e','v','e','r','S','h','o','w','E',
'x','t',0 }; 'x','t',0 };
static BOOL hide_extension(LPWSTR szPath) /******************************************************************************
* SHELL_FS_HideExtension [Internal]
*
* Query the registry if the filename extension of a given path should be
* hidden.
*
* PARAMS
* szPath [I] Relative or absolute path of a file
*
* RETURNS
* TRUE, if the filename's extension should be hidden
* FALSE, otherwise.
*/
BOOL SHELL_FS_HideExtension(LPWSTR szPath)
{ {
HKEY hKey; HKEY hKey;
DWORD dwData; DWORD dwData;
...@@ -739,7 +752,7 @@ void SHELL_FS_ProcessDisplayFilename(LPSTR szPath, DWORD dwFlags) ...@@ -739,7 +752,7 @@ void SHELL_FS_ProcessDisplayFilename(LPSTR szPath, DWORD dwFlags)
if (!(dwFlags & SHGDN_FORPARSING) && if (!(dwFlags & SHGDN_FORPARSING) &&
((dwFlags & SHGDN_INFOLDER) || (dwFlags == SHGDN_NORMAL))) { ((dwFlags & SHGDN_INFOLDER) || (dwFlags == SHGDN_NORMAL))) {
MultiByteToWideChar(CP_ACP, 0, szPath, -1, pathW, MAX_PATH); MultiByteToWideChar(CP_ACP, 0, szPath, -1, pathW, MAX_PATH);
if (hide_extension(pathW) && szPath[0] != '.') if (SHELL_FS_HideExtension(pathW) && szPath[0] != '.')
PathRemoveExtensionA (szPath); PathRemoveExtensionA (szPath);
} }
} }
...@@ -844,7 +857,7 @@ static HRESULT WINAPI IShellFolder_fnSetNameOf (IShellFolder2 * iface, ...@@ -844,7 +857,7 @@ static HRESULT WINAPI IShellFolder_fnSetNameOf (IShellFolder2 * iface,
} else } else
lstrcpynW(szDest, lpName, MAX_PATH); lstrcpynW(szDest, lpName, MAX_PATH);
if(!(dwFlags & SHGDN_FORPARSING) && hide_extension(szSrc)) { if(!(dwFlags & SHGDN_FORPARSING) && SHELL_FS_HideExtension(szSrc)) {
WCHAR *ext = PathFindExtensionW(szSrc); WCHAR *ext = PathFindExtensionW(szSrc);
if(*ext != '\0') { if(*ext != '\0') {
INT len = strlenW(szDest); INT len = strlenW(szDest);
......
...@@ -833,10 +833,11 @@ static HRESULT WINAPI UnixFolder_IShellFolder2_SetNameOf(IShellFolder2* iface, H ...@@ -833,10 +833,11 @@ static HRESULT WINAPI UnixFolder_IShellFolder2_SetNameOf(IShellFolder2* iface, H
{ {
UnixFolder *This = ADJUST_THIS(UnixFolder, IShellFolder2, iface); UnixFolder *This = ADJUST_THIS(UnixFolder, IShellFolder2, iface);
char szSrc[FILENAME_MAX], szDest[FILENAME_MAX]; char szSrc[FILENAME_MAX], szDest[FILENAME_MAX], szDosDest[MAX_PATH];
WCHAR wszDosDest[MAX_PATH];
int cBasePathLen = lstrlenA(This->m_pszPath); int cBasePathLen = lstrlenA(This->m_pszPath);
struct stat statDest; struct stat statDest;
LPITEMIDLIST pidlNew; LPITEMIDLIST pidlSrc, pidlDest;
TRACE("(iface=%p, hwnd=%p, pidl=%p, lpszName=%s, uFlags=0x%08lx, ppidlOut=%p)\n", TRACE("(iface=%p, hwnd=%p, pidl=%p, lpszName=%s, uFlags=0x%08lx, ppidlOut=%p)\n",
iface, hwnd, pidl, debugstr_w(lpszName), uFlags, ppidlOut); iface, hwnd, pidl, debugstr_w(lpszName), uFlags, ppidlOut);
...@@ -856,9 +857,19 @@ static HRESULT WINAPI UnixFolder_IShellFolder2_SetNameOf(IShellFolder2* iface, H ...@@ -856,9 +857,19 @@ static HRESULT WINAPI UnixFolder_IShellFolder2_SetNameOf(IShellFolder2* iface, H
if (uFlags & SHGDN_FORPARSING) { /* absolute path in lpszName */ if (uFlags & SHGDN_FORPARSING) { /* absolute path in lpszName */
WideCharToMultiByte(CP_ACP, 0, lpszName, -1, szDest, FILENAME_MAX, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, lpszName, -1, szDest, FILENAME_MAX, NULL, NULL);
} else { } else {
WCHAR wszSrcRelative[MAX_PATH];
memcpy(szDest, This->m_pszPath, cBasePathLen); memcpy(szDest, This->m_pszPath, cBasePathLen);
WideCharToMultiByte(CP_ACP, 0, lpszName, -1, szDest+cBasePathLen, WideCharToMultiByte(CP_ACP, 0, lpszName, -1, szDest+cBasePathLen,
FILENAME_MAX-cBasePathLen, NULL, NULL); FILENAME_MAX-cBasePathLen, NULL, NULL);
/* uFlags is SHGDN_FOREDITING of SHGDN_FORADDRESSBAR. If the filename's
* extension is hidden to the user, we have to append it. */
if (_ILSimpleGetTextW(pidl, wszSrcRelative, MAX_PATH) &&
SHELL_FS_HideExtension(wszSrcRelative))
{
char *pszExt = PathFindExtensionA(_ILGetTextPointer(pidl));
lstrcatA(szDest, pszExt);
}
} }
TRACE("src=%s dest=%s\n", szSrc, szDest); TRACE("src=%s dest=%s\n", szSrc, szDest);
...@@ -867,23 +878,32 @@ static HRESULT WINAPI UnixFolder_IShellFolder2_SetNameOf(IShellFolder2* iface, H ...@@ -867,23 +878,32 @@ static HRESULT WINAPI UnixFolder_IShellFolder2_SetNameOf(IShellFolder2* iface, H
if (!stat(szDest, &statDest)) if (!stat(szDest, &statDest))
return E_FAIL; return E_FAIL;
/* Rename the file and inform the shell */ /* Rename the file */
if (!rename(szSrc, szDest) && UNIXFS_path_to_pidl(This, lpszName, &pidlNew)) { if (rename(szSrc, szDest))
LPITEMIDLIST pidlSrc = ILCombine(This->m_pidlLocation, pidl); return E_FAIL;
LPITEMIDLIST pidlDest = ILCombine(This->m_pidlLocation, pidlNew);
if (_ILIsFolder(pidlNew)) /* Build a pidl for the path of the renamed file */
if (!GetFullPathNameA(szDest, MAX_PATH, szDosDest, NULL) ||
!MultiByteToWideChar(CP_ACP, 0, szDosDest, -1, wszDosDest, MAX_PATH) ||
!UNIXFS_path_to_pidl(This, wszDosDest, &pidlDest))
{
rename(szDest, szSrc); /* Undo the renaming */
return E_FAIL;
}
/* Inform the shell */
pidlSrc = ILCombine(This->m_pidlLocation, pidl);
if (_ILIsFolder(ILFindLastID(pidlDest)))
SHChangeNotify(SHCNE_RENAMEFOLDER, SHCNF_IDLIST, pidlSrc, pidlDest); SHChangeNotify(SHCNE_RENAMEFOLDER, SHCNF_IDLIST, pidlSrc, pidlDest);
else else
SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_IDLIST, pidlSrc, pidlDest); SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_IDLIST, pidlSrc, pidlDest);
ILFree(pidlSrc); ILFree(pidlSrc);
ILFree(pidlDest); ILFree(pidlDest);
if (ppidlOut) if (ppidlOut)
*ppidlOut = pidlNew; _ILCreateFromPathW(wszDosDest, ppidlOut);
else
ILFree(pidlNew);
return S_OK; return S_OK;
}
return E_FAIL;
} }
static HRESULT WINAPI UnixFolder_IShellFolder2_EnumSearches(IShellFolder2* iface, static HRESULT WINAPI UnixFolder_IShellFolder2_EnumSearches(IShellFolder2* iface,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment