[SHELL32]

- Don't check exe files for Open With application
- If application is invalid display proper text
- Properly handle application parameters and quotes when parsing application command. Patch by EDIJS, improved by me.
See issue #6770 for more details.

svn path=/trunk/; revision=54906
This commit is contained in:
Rafal Harabien 2012-01-10 19:57:53 +00:00
parent d8433417af
commit 64760a47a1
34 changed files with 100 additions and 101 deletions

View file

@ -31,52 +31,39 @@ typedef struct _LANGANDCODEPAGE_
} LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);
BOOL PathIsExeW(LPCWSTR lpszPath);
static LONG
SH_GetAssociatedApplication(LPCWSTR pwszFileExt, WCHAR *pwszAssocApp)
static VOID
SH_FileGeneralOpensWith(HWND hwndDlg, LPCWSTR pwszExt)
{
WCHAR wszBuf[MAX_PATH] = {0};
LONG result;
WCHAR wszBuf[MAX_PATH] = L"";
WCHAR wszBuf2[MAX_PATH] = L"";
DWORD dwSize = sizeof(wszBuf);
result = RegGetValueW(HKEY_CLASSES_ROOT, pwszFileExt, L"", RRF_RT_REG_SZ, NULL, wszBuf, &dwSize);
if (result == ERROR_SUCCESS)
if (RegGetValueW(HKEY_CLASSES_ROOT, pwszExt, L"", RRF_RT_REG_SZ, NULL, wszBuf, &dwSize) == ERROR_SUCCESS)
{
StringCbCat(wszBuf, sizeof(wszBuf), L"\\shell\\open\\command");
dwSize = MAX_PATH * sizeof(WCHAR);
result = RegGetValueW(HKEY_CLASSES_ROOT, wszBuf, L"", RRF_RT_REG_SZ, NULL, pwszAssocApp, &dwSize);
/* FIXME: Make it return full path instead of
notepad.exe "%1"
%systemroot%\notepad.exe "%1"
etc
Maybe there is code to do that somewhere?
dll\win32\shell32\shlexec.c for example? */
}
StringCbCatW(wszBuf, sizeof(wszBuf), L"\\shell\\open\\command");
dwSize = sizeof(wszBuf2);
if (RegGetValueW(HKEY_CLASSES_ROOT, wszBuf, L"", RRF_RT_REG_SZ, NULL, wszBuf2, &dwSize) == ERROR_SUCCESS)
{
/* Get path from command line */
ExpandEnvironmentStringsW(wszBuf2, wszBuf, _countof(wszBuf));
PathRemoveArgs(wszBuf);
PathUnquoteSpacesW(wszBuf);
PathRemoveExtension(wszBuf);
LPWSTR pwszFilename = PathFindFileNameW(wszBuf);
pwszFilename[0] = towupper(pwszFilename[0]);
SetDlgItemTextW(hwndDlg, 14007, pwszFilename);
//PathSearchAndQualify(wAssocAppFullPath, wAssocAppFullPath, MAX_PATH);
return;
} else
WARN("RegGetValueW %ls failed\n", wszBuf);
} else
WARN("RegGetValueW %ls failed\n", pwszExt);
if (result != ERROR_SUCCESS)
pwszAssocApp[0] = '\0';
return result;
}
static LONG
SH_FileGeneralOpensWith(HWND hwndDlg, LPCWSTR fileext)
{
LONG result;
WCHAR wAppName[MAX_PATH] = {0};
WCHAR wAssocApp[MAX_PATH] = {0};
result = SH_GetAssociatedApplication(fileext, wAssocApp);
if (result == ERROR_SUCCESS)
{
_wsplitpath(wAssocApp, NULL, NULL, wAppName, NULL);
SetDlgItemTextW(hwndDlg, 14007, wAppName);
}
return result;
/* Unknown application */
LoadStringW(shell32_hInstance, IDS_UNKNOWN_APP, wszBuf, _countof(wszBuf));
SetDlgItemTextW(hwndDlg, 14007, wszBuf);
}
/*************************************************************************
@ -365,20 +352,21 @@ SH_FileGeneralSetText(HWND hwndDlg, LPCWSTR pwszPath)
*/
static BOOL
SH_FileGeneralSetFileSizeTime(HWND hwndDlg, LPCWSTR lpfilename, PULARGE_INTEGER lpfilesize)
SH_FileGeneralSetFileSizeTime(HWND hwndDlg, LPCWSTR pwszPath)
{
BOOL result;
HANDLE hFile;
FILETIME create_time;
FILETIME accessed_time;
FILETIME write_time;
WCHAR resultstr[MAX_PATH];
LARGE_INTEGER file_size;
FILETIME CreateTime;
FILETIME AccessedTime;
FILETIME WriteTime;
WCHAR wszBuf[MAX_PATH];
LARGE_INTEGER FileSize;
if (lpfilename == NULL)
if (pwszPath == NULL)
return FALSE;
hFile = CreateFileW(lpfilename,
TRACE("SH_FileGeneralSetFileSizeTime %ls\n", pwszPath);
hFile = CreateFileW(pwszPath,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
@ -388,34 +376,18 @@ SH_FileGeneralSetFileSizeTime(HWND hwndDlg, LPCWSTR lpfilename, PULARGE_INTEGER
if (hFile == INVALID_HANDLE_VALUE)
{
WARN("failed to open file %s\n", debugstr_w(lpfilename));
WARN("failed to open file %s\n", debugstr_w(pwszPath));
return FALSE;
}
result = GetFileTime(hFile, &create_time, &accessed_time, &write_time);
if (!result)
if (!GetFileTime(hFile, &CreateTime, &AccessedTime, &WriteTime))
{
WARN("GetFileTime failed\n");
CloseHandle(hFile);
return FALSE;
}
if (SHFileGeneralGetFileTimeString(&create_time, resultstr))
{
SetDlgItemTextW(hwndDlg, 14015, resultstr);
}
if (SHFileGeneralGetFileTimeString(&accessed_time, resultstr))
{
SetDlgItemTextW(hwndDlg, 14019, resultstr);
}
if (SHFileGeneralGetFileTimeString(&write_time, resultstr))
{
SetDlgItemTextW(hwndDlg, 14017, resultstr);
}
if (!GetFileSizeEx(hFile, &file_size))
if (!GetFileSizeEx(hFile, &FileSize))
{
WARN("GetFileSize failed\n");
CloseHandle(hFile);
@ -424,16 +396,21 @@ SH_FileGeneralSetFileSizeTime(HWND hwndDlg, LPCWSTR lpfilename, PULARGE_INTEGER
CloseHandle(hFile);
if (!SH_FormatFileSizeWithBytes((PULARGE_INTEGER)&file_size,
resultstr,
sizeof(resultstr) / sizeof(WCHAR)))
return FALSE;
if (SHFileGeneralGetFileTimeString(&CreateTime, wszBuf))
SetDlgItemTextW(hwndDlg, 14015, wszBuf);
TRACE("result size %u resultstr %s\n", file_size.QuadPart, debugstr_w(resultstr));
SetDlgItemTextW(hwndDlg, 14011, resultstr);
if (SHFileGeneralGetFileTimeString(&AccessedTime, wszBuf))
SetDlgItemTextW(hwndDlg, 14019, wszBuf);
if (lpfilesize)
lpfilesize->QuadPart = (ULONGLONG)file_size.QuadPart;
if (SHFileGeneralGetFileTimeString(&WriteTime, wszBuf))
SetDlgItemTextW(hwndDlg, 14017, wszBuf);
if (SH_FormatFileSizeWithBytes((PULARGE_INTEGER)&FileSize,
wszBuf,
sizeof(wszBuf) / sizeof(WCHAR)))
{
SetDlgItemTextW(hwndDlg, 14011, wszBuf);
}
return TRUE;
}
@ -679,11 +656,9 @@ SH_FileGeneralDlgProc(HWND hwndDlg,
LPCWSTR pwszPath = (WCHAR *)ppsp->lParam;
if (pwszPath == NULL)
{
ERR("no filename\n");
ERR("no path\n");
break;
}
LPCWSTR pwszExt = PathFindExtensionW(pwszPath);
/* set general text properties filename filelocation and icon */
SH_FileGeneralSetText(hwndDlg, pwszPath);
@ -692,10 +667,11 @@ SH_FileGeneralDlgProc(HWND hwndDlg,
SH_FileGeneralSetFileType(hwndDlg, pwszPath);
/* set opens with */
SH_FileGeneralOpensWith(hwndDlg, pwszExt);
if (!PathIsExeW(pwszPath))
SH_FileGeneralOpensWith(hwndDlg, PathFindExtensionW(pwszPath));
/* set file time create/modfied/accessed */
SH_FileGeneralSetFileSizeTime(hwndDlg, pwszPath, NULL);
SH_FileGeneralSetFileSizeTime(hwndDlg, pwszPath);
return TRUE;
}
@ -800,32 +776,24 @@ SH_ShowPropertiesDialog(LPCWSTR pwszPath, LPCITEMIDLIST pidlFolder, LPCITEMIDLIS
WCHAR wszPath[MAX_PATH];
StringCbCopyW(wszPath, sizeof(wszPath), pwszPath);
//
// get length
//
INT cchPath = wcslen(wszPath);
if (cchPath > 3 && wszPath[cchPath-1] == L'\\')
{
//
// remove trailing \\ at the end of path
//
wszPath[cchPath-1] = L'\0';
}
/* remove trailing \\ at the end of path */
PathRemoveBackslashW(wszPath);
/* Handle drives */
if (PathIsRootW(wszPath))
return SH_ShowDriveProperties(wszPath, pidlFolder, apidl);
/* Handle folders */
if (PathIsDirectoryW(wszPath))
return SH_ShowFolderProperties(wszPath, pidlFolder, apidl);
LPCWSTR pwszFilename = PathFindFileNameW(wszPath);
/* Handle files */
PROPSHEETHEADERW Info;
memset(&Info, 0x0, sizeof(PROPSHEETHEADERW));
Info.dwSize = sizeof(PROPSHEETHEADERW);
Info.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE;
Info.phpage = hppages;
Info.pszCaption = pwszFilename;
Info.pszCaption = PathFindFileNameW(wszPath);
hppages[Info.nPages] =
SH_CreatePropertySheetPage("SHELL_FILE_GENERAL_DLG",

View file

@ -771,6 +771,7 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -770,4 +770,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -758,4 +758,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -759,4 +759,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -775,4 +775,5 @@ BEGIN
IDS_FILE_TYPES "Dateitypen"
IDS_COLUMN_EXTENSION "Erweiterungen"
IDS_BYTES_FORMAT "Bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -771,4 +771,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -770,4 +770,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -780,4 +780,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -783,4 +783,5 @@ BEGIN
IDS_FILE_TYPES "Tipos de archivos"
IDS_COLUMN_EXTENSION "Extensiones"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -770,4 +770,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -774,4 +774,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -773,4 +773,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -781,4 +781,5 @@ BEGIN
IDS_FILE_TYPES "Tipi di file"
IDS_COLUMN_EXTENSION "Estensioni"
IDS_BYTES_FORMAT "byte"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -770,4 +770,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -770,4 +770,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -770,4 +770,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -773,4 +773,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -778,4 +778,5 @@ BEGIN
IDS_FILE_TYPES "Typy plików"
IDS_COLUMN_EXTENSION "Rozszerzenia"
IDS_BYTES_FORMAT "bajtów"
IDS_UNKNOWN_APP "Nieznana aplikacja"
END

View file

@ -772,4 +772,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -773,4 +773,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -789,5 +789,6 @@ BEGIN
IDS_FILE_TYPES "Tipuri"
IDS_COLUMN_EXTENSION "Extensii"
IDS_BYTES_FORMAT "octeți"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -768,4 +768,5 @@ BEGIN
IDS_FILE_TYPES "Типы файлов"
IDS_COLUMN_EXTENSION "Расширения"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -778,4 +778,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -770,4 +770,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -770,4 +770,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -770,4 +770,5 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -783,4 +783,5 @@ BEGIN
IDS_FILE_TYPES "Типи Файлів"
IDS_COLUMN_EXTENSION "Розширення"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -758,5 +758,6 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -770,5 +770,6 @@ BEGIN
IDS_FILE_TYPES "FileTypes"
IDS_COLUMN_EXTENSION "Extensions"
IDS_BYTES_FORMAT "bytes"
IDS_UNKNOWN_APP "Unknown application"
END

View file

@ -135,7 +135,7 @@ CNewMenu::SHELLNEW_ITEM *CNewMenu::LoadItem(LPCWSTR pwszExt)
{
/* Note: We are using ANSI function because strings can be treated as data */
cbData = 0;
DWORD dwFlags = Types[i].bStr ? RRF_RT_REG_SZ|RRF_RT_REG_EXPAND_SZ : RRF_RT_ANY;
DWORD dwFlags = Types[i].bStr ? RRF_RT_REG_SZ : RRF_RT_ANY;
if (RegGetValueA(hKey, NULL, Types[i].pszName, dwFlags, NULL, NULL, &cbData) == ERROR_SUCCESS)
{
if (Types[i].bNeedData && cbData > 0)

View file

@ -29,6 +29,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
// "NoInternetOpenWith"=dword:00000001
//
BOOL PathIsExeW(LPCWSTR lpszPath);
class COpenWithList
{
public:
@ -1350,9 +1352,7 @@ COpenWithMenu::Initialize(LPCITEMIDLIST pidlFolder,
TRACE("szPath %s\n", debugstr_w(m_wszPath));
pwszExt = PathFindExtensionW(m_wszPath);
if (!_wcsicmp(pwszExt, L".exe") || !_wcsicmp(pwszExt, L".com") ||
!_wcsicmp(pwszExt, L".scr") || !_wcsicmp(pwszExt, L".bat") ||
!_wcsicmp(pwszExt, L".cmd") || !_wcsicmp(pwszExt, L".lnk"))
if (PathIsExeW(pwszExt) || !_wcsicmp(pwszExt, L".lnk"))
{
TRACE("file is a executable or shortcut\n");
return E_FAIL;

View file

@ -177,7 +177,7 @@ static BOOL PathIsExeA (LPCSTR lpszPath)
/*************************************************************************
* PathIsExeW [internal]
*/
static BOOL PathIsExeW (LPCWSTR lpszPath)
BOOL PathIsExeW (LPCWSTR lpszPath)
{
LPCWSTR lpszExtension = PathGetExtensionW(lpszPath);
int i;

View file

@ -145,6 +145,8 @@
#define IDS_RUNDLG_BROWSE_CAPTION 182
#define IDS_RUNDLG_BROWSE_FILTER 183
#define IDS_UNKNOWN_APP 190
#define IDS_OPEN_VERB 300
#define IDS_EXPLORE_VERB 301
#define IDS_RUNAS_VERB 302