Commit 7f5ccd32 authored by David Hedberg's avatar David Hedberg Committed by Alexandre Julliard

comdlg32: Factor out some path validating code from FILEDLG95_OnOpen.

parent fcb169fe
......@@ -175,6 +175,8 @@ HRESULT FileSaveDialog_Constructor(IUnknown *pUnkOuter, REFIID riid, void **ppv)
/* Shared helper functions */
void COMDLG32_GetCanonicalPath(PCIDLIST_ABSOLUTE pidlAbsCurrent, LPWSTR lpstrFile, LPWSTR lpstrPathAndFile);
int FILEDLG95_ValidatePathAction(LPWSTR lpstrPathAndFile, IShellFolder **ppsf,
HWND hwnd, DWORD flags, BOOL isSaveDlg, int defAction);
/* ITEMIDLIST */
......@@ -190,4 +192,8 @@ extern LPVOID (WINAPI *COMDLG32_SHAlloc)(DWORD);
extern DWORD (WINAPI *COMDLG32_SHFree)(LPVOID);
extern BOOL (WINAPI *COMDLG32_SHGetFolderPathW)(HWND,int,HANDLE,DWORD,LPWSTR);
#define ONOPEN_BROWSE 1
#define ONOPEN_OPEN 2
#define ONOPEN_SEARCH 3
#endif /* _WINE_DLL_CDLG_H */
......@@ -2211,16 +2211,6 @@ static void FILEDLG95_MRU_load_filename(LPWSTR stored_path)
TRACE("got MRU path: %s\n", wine_dbgstr_w(stored_path));
}
/***********************************************************************
* FILEDLG95_OnOpen
*
* Ok button WM_COMMAND message handler
*
* If the function succeeds, the return value is nonzero.
*/
#define ONOPEN_BROWSE 1
#define ONOPEN_OPEN 2
#define ONOPEN_SEARCH 3
static void FILEDLG95_OnOpenMessage(HWND hwnd, int idCaption, int idText)
{
WCHAR strMsgTitle[MAX_PATH];
......@@ -2233,82 +2223,22 @@ static void FILEDLG95_OnOpenMessage(HWND hwnd, int idCaption, int idText)
MessageBoxW(hwnd,strMsgText, strMsgTitle, MB_OK | MB_ICONHAND);
}
BOOL FILEDLG95_OnOpen(HWND hwnd)
int FILEDLG95_ValidatePathAction(LPWSTR lpstrPathAndFile, IShellFolder **ppsf,
HWND hwnd, DWORD flags, BOOL isSaveDlg, int defAction)
{
LPWSTR lpstrFileList;
UINT nFileCount = 0;
UINT sizeUsed = 0;
BOOL ret = TRUE;
WCHAR lpstrPathAndFile[MAX_PATH];
LPSHELLFOLDER lpsf = NULL;
int nOpenAction;
FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
TRACE("hwnd=%p\n", hwnd);
/* try to browse the selected item */
if(BrowseSelectedFolder(hwnd))
return FALSE;
/* get the files from the edit control */
nFileCount = FILEDLG95_FILENAME_GetFileNames(hwnd, &lpstrFileList, &sizeUsed);
if(nFileCount == 0)
return FALSE;
if(nFileCount > 1)
{
ret = FILEDLG95_OnOpenMultipleFiles(hwnd, lpstrFileList, nFileCount, sizeUsed);
goto ret;
}
TRACE("count=%u len=%u file=%s\n", nFileCount, sizeUsed, debugstr_w(lpstrFileList));
/*
Step 1: Build a complete path name from the current folder and
the filename or path in the edit box.
Special cases:
- the path in the edit box is a root path
(with or without drive letter)
- the edit box contains ".." (or a path with ".." in it)
*/
COMDLG32_GetCanonicalPath(fodInfos->ShellInfos.pidlAbsCurrent, lpstrFileList, lpstrPathAndFile);
MemFree(lpstrFileList);
/*
Step 2: here we have a cleaned up path
We have to parse the path step by step to see if we have to browse
to a folder if the path points to a directory or the last
valid element is a directory.
valid variables:
lpstrPathAndFile: cleaned up path
*/
if (nFileCount &&
(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE) &&
!(fodInfos->ofnInfos->Flags & OFN_FILEMUSTEXIST))
nOpenAction = ONOPEN_OPEN;
else
nOpenAction = ONOPEN_BROWSE;
/* don't apply any checks with OFN_NOVALIDATE */
{
int nOpenAction = defAction;
LPWSTR lpszTemp, lpszTemp1;
LPITEMIDLIST pidl = NULL;
static const WCHAR szwInvalid[] = { '/',':','<','>','|', 0};
/* check for invalid chars */
if((strpbrkW(lpstrPathAndFile+3, szwInvalid) != NULL) && !(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE))
if((strpbrkW(lpstrPathAndFile+3, szwInvalid) != NULL) && !(flags & OFN_NOVALIDATE))
{
FILEDLG95_OnOpenMessage(hwnd, IDS_INVALID_FILENAME_TITLE, IDS_INVALID_FILENAME);
ret = FALSE;
goto ret;
return FALSE;
}
if (FAILED (SHGetDesktopFolder(&lpsf))) return FALSE;
if (FAILED (SHGetDesktopFolder(ppsf))) return FALSE;
lpszTemp1 = lpszTemp = lpstrPathAndFile;
while (lpszTemp1)
......@@ -2327,7 +2257,7 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
lpszTemp = lpszTemp + lstrlenW(lpwstrTemp);
/* There are no wildcards when OFN_NOVALIDATE is set */
if(*lpszTemp==0 && !(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE))
if(*lpszTemp==0 && !(flags & OFN_NOVALIDATE))
{
static const WCHAR wszWild[] = { '*', '?', 0 };
/* if the last element is a wildcard do a search */
......@@ -2339,7 +2269,7 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
}
lpszTemp1 = lpszTemp;
TRACE("parse now=%s next=%s sf=%p\n",debugstr_w(lpwstrTemp), debugstr_w(lpszTemp), lpsf);
TRACE("parse now=%s next=%s sf=%p\n",debugstr_w(lpwstrTemp), debugstr_w(lpszTemp), *ppsf);
/* append a backslash to drive letters */
if(lstrlenW(lpwstrTemp)==2 && lpwstrTemp[1] == ':' &&
......@@ -2350,19 +2280,19 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
}
dwAttributes = SFGAO_FOLDER;
if(SUCCEEDED(IShellFolder_ParseDisplayName(lpsf, hwnd, NULL, lpwstrTemp, &dwEaten, &pidl, &dwAttributes)))
if(SUCCEEDED(IShellFolder_ParseDisplayName(*ppsf, hwnd, NULL, lpwstrTemp, &dwEaten, &pidl, &dwAttributes)))
{
/* the path component is valid, we have a pidl of the next path component */
TRACE("parse OK attr=0x%08x pidl=%p\n", dwAttributes, pidl);
if(dwAttributes & SFGAO_FOLDER)
{
if(FAILED(IShellFolder_BindToObject(lpsf, pidl, 0, &IID_IShellFolder, (LPVOID*)&lpsfChild)))
if(FAILED(IShellFolder_BindToObject(*ppsf, pidl, 0, &IID_IShellFolder, (LPVOID*)&lpsfChild)))
{
ERR("bind to failed\n"); /* should not fail */
break;
}
IShellFolder_Release(lpsf);
lpsf = lpsfChild;
IShellFolder_Release(*ppsf);
*ppsf = lpsfChild;
lpsfChild = NULL;
}
else
......@@ -2376,12 +2306,12 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
COMDLG32_SHFree(pidl);
pidl = NULL;
}
else if (!(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE))
else if (!(flags & OFN_NOVALIDATE))
{
if(*lpszTemp || /* points to trailing null for last path element */
(lpwstrTemp[strlenW(lpwstrTemp)-1] == '\\')) /* or if last element ends in '\' */
{
if(fodInfos->ofnInfos->Flags & OFN_PATHMUSTEXIST)
if(flags & OFN_PATHMUSTEXIST)
{
FILEDLG95_OnOpenMessage(hwnd, 0, IDS_PATHNOTEXISTING);
break;
......@@ -2389,8 +2319,7 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
}
else
{
if( (fodInfos->ofnInfos->Flags & OFN_FILEMUSTEXIST) &&
!( fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG ) )
if( (flags & OFN_FILEMUSTEXIST) && !isSaveDlg )
{
FILEDLG95_OnOpenMessage(hwnd, 0, IDS_FILENOTEXISTING);
break;
......@@ -2407,8 +2336,85 @@ BOOL FILEDLG95_OnOpen(HWND hwnd)
}
}
if(pidl) COMDLG32_SHFree(pidl);
return nOpenAction;
}
/***********************************************************************
* FILEDLG95_OnOpen
*
* Ok button WM_COMMAND message handler
*
* If the function succeeds, the return value is nonzero.
*/
BOOL FILEDLG95_OnOpen(HWND hwnd)
{
LPWSTR lpstrFileList;
UINT nFileCount = 0;
UINT sizeUsed = 0;
BOOL ret = TRUE;
WCHAR lpstrPathAndFile[MAX_PATH];
LPSHELLFOLDER lpsf = NULL;
int nOpenAction;
FileOpenDlgInfos *fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr);
TRACE("hwnd=%p\n", hwnd);
/* try to browse the selected item */
if(BrowseSelectedFolder(hwnd))
return FALSE;
/* get the files from the edit control */
nFileCount = FILEDLG95_FILENAME_GetFileNames(hwnd, &lpstrFileList, &sizeUsed);
if(nFileCount == 0)
return FALSE;
if(nFileCount > 1)
{
ret = FILEDLG95_OnOpenMultipleFiles(hwnd, lpstrFileList, nFileCount, sizeUsed);
goto ret;
}
TRACE("count=%u len=%u file=%s\n", nFileCount, sizeUsed, debugstr_w(lpstrFileList));
/*
Step 1: Build a complete path name from the current folder and
the filename or path in the edit box.
Special cases:
- the path in the edit box is a root path
(with or without drive letter)
- the edit box contains ".." (or a path with ".." in it)
*/
COMDLG32_GetCanonicalPath(fodInfos->ShellInfos.pidlAbsCurrent, lpstrFileList, lpstrPathAndFile);
MemFree(lpstrFileList);
/*
Step 2: here we have a cleaned up path
We have to parse the path step by step to see if we have to browse
to a folder if the path points to a directory or the last
valid element is a directory.
valid variables:
lpstrPathAndFile: cleaned up path
*/
if (nFileCount &&
(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE) &&
!(fodInfos->ofnInfos->Flags & OFN_FILEMUSTEXIST))
nOpenAction = ONOPEN_OPEN;
else
nOpenAction = ONOPEN_BROWSE;
nOpenAction = FILEDLG95_ValidatePathAction(lpstrPathAndFile, &lpsf, hwnd,
fodInfos->ofnInfos->Flags,
fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG,
nOpenAction);
if(!nOpenAction)
goto ret;
/*
Step 3: here we have a cleaned up and validated path
......
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