shell32: IShellFolder::ParseDisplayName should work for missing files if given valid IBindCtx.
Additionally, SHSimpleIDListFromPath now returns PIDLs for non-existent paths, as it should.
This commit is contained in:
parent
e8c5e2b890
commit
f99c81621c
|
@ -128,6 +128,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
#ifdef HAVE_DIRENT_H
|
#ifdef HAVE_DIRENT_H
|
||||||
# include <dirent.h>
|
# include <dirent.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -184,6 +185,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
||||||
#define PATHMODE_UNIX 0
|
#define PATHMODE_UNIX 0
|
||||||
#define PATHMODE_DOS 1
|
#define PATHMODE_DOS 1
|
||||||
|
|
||||||
|
static const WCHAR wFileSystemBindData[] = {
|
||||||
|
'F','i','l','e',' ','S','y','s','t','e','m',' ','B','i','n','d',' ','D','a','t','a',0};
|
||||||
|
|
||||||
/* UnixFolder object layout and typedef.
|
/* UnixFolder object layout and typedef.
|
||||||
*/
|
*/
|
||||||
typedef struct _UnixFolder {
|
typedef struct _UnixFolder {
|
||||||
|
@ -464,6 +468,7 @@ static inline void UNIXFS_seconds_since_1970_to_dos_date_time(
|
||||||
*
|
*
|
||||||
* PARAMS
|
* PARAMS
|
||||||
* pszUnixPath [I] An absolute path. The SHITEMID will be built for the last component.
|
* pszUnixPath [I] An absolute path. The SHITEMID will be built for the last component.
|
||||||
|
* pbc [I] Bind context for this action, used to determine if the file must exist
|
||||||
* pIDL [O] SHITEMID will be constructed here.
|
* pIDL [O] SHITEMID will be constructed here.
|
||||||
*
|
*
|
||||||
* RETURNS
|
* RETURNS
|
||||||
|
@ -475,7 +480,7 @@ static inline void UNIXFS_seconds_since_1970_to_dos_date_time(
|
||||||
* If what you need is a PIDLLIST with a single SHITEMID, don't forget to append
|
* If what you need is a PIDLLIST with a single SHITEMID, don't forget to append
|
||||||
* a 0 USHORT value.
|
* a 0 USHORT value.
|
||||||
*/
|
*/
|
||||||
static char* UNIXFS_build_shitemid(char *pszUnixPath, void *pIDL) {
|
static char* UNIXFS_build_shitemid(char *pszUnixPath, LPBC pbc, void *pIDL) {
|
||||||
LPPIDLDATA pIDLData;
|
LPPIDLDATA pIDLData;
|
||||||
struct stat fileStat;
|
struct stat fileStat;
|
||||||
char *pszComponentU, *pszComponentA;
|
char *pszComponentU, *pszComponentA;
|
||||||
|
@ -484,12 +489,35 @@ static char* UNIXFS_build_shitemid(char *pszUnixPath, void *pIDL) {
|
||||||
USHORT cbLen;
|
USHORT cbLen;
|
||||||
FileStructW *pFileStructW;
|
FileStructW *pFileStructW;
|
||||||
WORD uOffsetW, *pOffsetW;
|
WORD uOffsetW, *pOffsetW;
|
||||||
|
BOOL must_exist = TRUE;
|
||||||
|
|
||||||
TRACE("(pszUnixPath=%s, pIDL=%p)\n", debugstr_a(pszUnixPath), pIDL);
|
TRACE("(pszUnixPath=%s, pbc=%p, pIDL=%p)\n", debugstr_a(pszUnixPath), pbc, pIDL);
|
||||||
|
|
||||||
|
if (pbc){
|
||||||
|
IUnknown *unk;
|
||||||
|
IFileSystemBindData *fsb;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = IBindCtx_GetObjectParam(pbc, (LPOLESTR)wFileSystemBindData, &unk);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
hr = IUnknown_QueryInterface(unk, &IID_IFileSystemBindData, (LPVOID*)&fsb);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
/* Windows tries to get WIN32_FIND_DATAW structure from
|
||||||
|
* fsb here for no known reason */
|
||||||
|
must_exist = FALSE;
|
||||||
|
IFileSystemBindData_Release(fsb);
|
||||||
|
}
|
||||||
|
IUnknown_Release(unk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* We are only interested in regular files and directories. */
|
/* We are only interested in regular files and directories. */
|
||||||
if (stat(pszUnixPath, &fileStat)) return NULL;
|
if (stat(pszUnixPath, &fileStat)){
|
||||||
if (!S_ISDIR(fileStat.st_mode) && !S_ISREG(fileStat.st_mode)) return NULL;
|
if (must_exist || errno != ENOENT)
|
||||||
|
return NULL;
|
||||||
|
}else
|
||||||
|
if (!S_ISDIR(fileStat.st_mode) && !S_ISREG(fileStat.st_mode))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* Compute the SHITEMID's length and wipe it. */
|
/* Compute the SHITEMID's length and wipe it. */
|
||||||
pszComponentU = strrchr(pszUnixPath, '/') + 1;
|
pszComponentU = strrchr(pszUnixPath, '/') + 1;
|
||||||
|
@ -544,13 +572,14 @@ static char* UNIXFS_build_shitemid(char *pszUnixPath, void *pIDL) {
|
||||||
* NOTES
|
* NOTES
|
||||||
* pUnixFolder also carries the information if the path is expected to be unix or dos.
|
* pUnixFolder also carries the information if the path is expected to be unix or dos.
|
||||||
*/
|
*/
|
||||||
static HRESULT UNIXFS_path_to_pidl(UnixFolder *pUnixFolder, const WCHAR *path, LPITEMIDLIST *ppidl) {
|
static HRESULT UNIXFS_path_to_pidl(UnixFolder *pUnixFolder, LPBC pbc, const WCHAR *path,
|
||||||
|
LPITEMIDLIST *ppidl) {
|
||||||
LPITEMIDLIST pidl;
|
LPITEMIDLIST pidl;
|
||||||
int cPidlLen, cPathLen;
|
int cPidlLen, cPathLen;
|
||||||
char *pSlash, *pNextSlash, szCompletePath[FILENAME_MAX], *pNextPathElement, *pszAPath;
|
char *pSlash, *pNextSlash, szCompletePath[FILENAME_MAX], *pNextPathElement, *pszAPath;
|
||||||
WCHAR *pwszPath;
|
WCHAR *pwszPath;
|
||||||
|
|
||||||
TRACE("pUnixFolder=%p, path=%s, ppidl=%p\n", pUnixFolder, debugstr_w(path), ppidl);
|
TRACE("pUnixFolder=%p, pbc=%p, path=%s, ppidl=%p\n", pUnixFolder, pbc, debugstr_w(path), ppidl);
|
||||||
|
|
||||||
if (!ppidl || !path)
|
if (!ppidl || !path)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
@ -643,7 +672,7 @@ static HRESULT UNIXFS_path_to_pidl(UnixFolder *pUnixFolder, const WCHAR *path, L
|
||||||
while (*pNextPathElement) {
|
while (*pNextPathElement) {
|
||||||
pSlash = strchr(pNextPathElement+1, '/');
|
pSlash = strchr(pNextPathElement+1, '/');
|
||||||
if (pSlash) *pSlash = '\0';
|
if (pSlash) *pSlash = '\0';
|
||||||
pNextPathElement = UNIXFS_build_shitemid(szCompletePath, pidl);
|
pNextPathElement = UNIXFS_build_shitemid(szCompletePath, pbc, pidl);
|
||||||
if (pSlash) *pSlash = '/';
|
if (pSlash) *pSlash = '/';
|
||||||
|
|
||||||
if (!pNextPathElement) {
|
if (!pNextPathElement) {
|
||||||
|
@ -849,17 +878,17 @@ static ULONG WINAPI UnixFolder_IShellFolder2_Release(IShellFolder2 *iface) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI UnixFolder_IShellFolder2_ParseDisplayName(IShellFolder2* iface, HWND hwndOwner,
|
static HRESULT WINAPI UnixFolder_IShellFolder2_ParseDisplayName(IShellFolder2* iface, HWND hwndOwner,
|
||||||
LPBC pbcReserved, LPOLESTR lpszDisplayName, ULONG* pchEaten, LPITEMIDLIST* ppidl,
|
LPBC pbc, LPOLESTR lpszDisplayName, ULONG* pchEaten, LPITEMIDLIST* ppidl,
|
||||||
ULONG* pdwAttributes)
|
ULONG* pdwAttributes)
|
||||||
{
|
{
|
||||||
UnixFolder *This = ADJUST_THIS(UnixFolder, IShellFolder2, iface);
|
UnixFolder *This = ADJUST_THIS(UnixFolder, IShellFolder2, iface);
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
|
|
||||||
TRACE("(iface=%p, hwndOwner=%p, pbcReserved=%p, lpszDisplayName=%s, pchEaten=%p, ppidl=%p, "
|
TRACE("(iface=%p, hwndOwner=%p, pbc=%p, lpszDisplayName=%s, pchEaten=%p, ppidl=%p, "
|
||||||
"pdwAttributes=%p) stub\n", iface, hwndOwner, pbcReserved, debugstr_w(lpszDisplayName),
|
"pdwAttributes=%p) stub\n", iface, hwndOwner, pbc, debugstr_w(lpszDisplayName),
|
||||||
pchEaten, ppidl, pdwAttributes);
|
pchEaten, ppidl, pdwAttributes);
|
||||||
|
|
||||||
result = UNIXFS_path_to_pidl(This, lpszDisplayName, ppidl);
|
result = UNIXFS_path_to_pidl(This, pbc, lpszDisplayName, ppidl);
|
||||||
if (SUCCEEDED(result) && pdwAttributes && *pdwAttributes)
|
if (SUCCEEDED(result) && pdwAttributes && *pdwAttributes)
|
||||||
{
|
{
|
||||||
IShellFolder *pParentSF;
|
IShellFolder *pParentSF;
|
||||||
|
@ -1768,7 +1797,7 @@ static HRESULT WINAPI UnixFolder_ISFHelper_AddFolder(ISFHelper* iface, HWND hwnd
|
||||||
LPITEMIDLIST pidlRelative;
|
LPITEMIDLIST pidlRelative;
|
||||||
|
|
||||||
/* Inform the shell */
|
/* Inform the shell */
|
||||||
if (SUCCEEDED(UNIXFS_path_to_pidl(This, pwszName, &pidlRelative))) {
|
if (SUCCEEDED(UNIXFS_path_to_pidl(This, NULL, pwszName, &pidlRelative))) {
|
||||||
LPITEMIDLIST pidlAbsolute = ILCombine(This->m_pidlLocation, pidlRelative);
|
LPITEMIDLIST pidlAbsolute = ILCombine(This->m_pidlLocation, pidlRelative);
|
||||||
if (ppidlOut)
|
if (ppidlOut)
|
||||||
*ppidlOut = pidlRelative;
|
*ppidlOut = pidlRelative;
|
||||||
|
@ -2303,7 +2332,7 @@ static HRESULT WINAPI UnixSubFolderIterator_IEnumIDList_Next(IEnumIDList* iface,
|
||||||
lstrcpyA(pszRelativePath, pDirEntry->d_name);
|
lstrcpyA(pszRelativePath, pDirEntry->d_name);
|
||||||
rgelt[i] = SHAlloc(
|
rgelt[i] = SHAlloc(
|
||||||
UNIXFS_shitemid_len_from_filename(pszRelativePath, NULL, NULL)+sizeof(USHORT));
|
UNIXFS_shitemid_len_from_filename(pszRelativePath, NULL, NULL)+sizeof(USHORT));
|
||||||
if (!UNIXFS_build_shitemid(This->m_szFolder, rgelt[i]) ||
|
if (!UNIXFS_build_shitemid(This->m_szFolder, NULL, rgelt[i]) ||
|
||||||
!UNIXFS_is_pidl_of_type(rgelt[i], This->m_fFilter))
|
!UNIXFS_is_pidl_of_type(rgelt[i], This->m_fFilter))
|
||||||
{
|
{
|
||||||
SHFree(rgelt[i]);
|
SHFree(rgelt[i]);
|
||||||
|
|
|
@ -62,7 +62,7 @@ static const IFileSystemBindDataVtbl sbvt =
|
||||||
};
|
};
|
||||||
|
|
||||||
static const WCHAR wFileSystemBindData[] = {
|
static const WCHAR wFileSystemBindData[] = {
|
||||||
'F','i','l','e',' ','S','y','s','t','e','m',' ','B','i','n','d','D','a','t','a',0};
|
'F','i','l','e',' ','S','y','s','t','e','m',' ','B','i','n','d',' ','D','a','t','a',0};
|
||||||
|
|
||||||
HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV)
|
HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV)
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,6 +55,7 @@ static BOOL (WINAPI *pILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST);
|
||||||
static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMIDLIST,IShellItem**);
|
static HRESULT (WINAPI *pSHCreateShellItem)(LPCITEMIDLIST,IShellFolder*,LPCITEMIDLIST,IShellItem**);
|
||||||
static LPITEMIDLIST (WINAPI *pILCombine)(LPCITEMIDLIST,LPCITEMIDLIST);
|
static LPITEMIDLIST (WINAPI *pILCombine)(LPCITEMIDLIST,LPCITEMIDLIST);
|
||||||
static HRESULT (WINAPI *pSHParseDisplayName)(LPCWSTR,IBindCtx*,LPITEMIDLIST*,SFGAOF,SFGAOF*);
|
static HRESULT (WINAPI *pSHParseDisplayName)(LPCWSTR,IBindCtx*,LPITEMIDLIST*,SFGAOF,SFGAOF*);
|
||||||
|
static LPITEMIDLIST (WINAPI *pSHSimpleIDListFromPathAW)(LPCVOID);
|
||||||
|
|
||||||
static void init_function_pointers(void)
|
static void init_function_pointers(void)
|
||||||
{
|
{
|
||||||
|
@ -80,6 +81,7 @@ static void init_function_pointers(void)
|
||||||
MAKEFUNC_ORD(ILIsEqual, 21);
|
MAKEFUNC_ORD(ILIsEqual, 21);
|
||||||
MAKEFUNC_ORD(ILCombine, 25);
|
MAKEFUNC_ORD(ILCombine, 25);
|
||||||
MAKEFUNC_ORD(ILFree, 155);
|
MAKEFUNC_ORD(ILFree, 155);
|
||||||
|
MAKEFUNC_ORD(SHSimpleIDListFromPathAW, 162);
|
||||||
#undef MAKEFUNC_ORD
|
#undef MAKEFUNC_ORD
|
||||||
|
|
||||||
/* test named exports */
|
/* test named exports */
|
||||||
|
@ -2264,6 +2266,265 @@ static void test_GetUIObject(void)
|
||||||
Cleanup();
|
Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define verify_pidl(i,p) r_verify_pidl(__LINE__, i, p)
|
||||||
|
static void r_verify_pidl(unsigned l, LPCITEMIDLIST pidl, const WCHAR *path)
|
||||||
|
{
|
||||||
|
LPCITEMIDLIST child;
|
||||||
|
IShellFolder *parent;
|
||||||
|
STRRET filename;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if(!pSHBindToParent){
|
||||||
|
win_skip("SHBindToParent is not available, not performing full PIDL verification\n");
|
||||||
|
if(path)
|
||||||
|
ok_(__FILE__,l)(pidl != NULL, "Expected PIDL to be non-NULL\n");
|
||||||
|
else
|
||||||
|
ok_(__FILE__,l)(pidl == NULL, "Expected PIDL to be NULL\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(path){
|
||||||
|
if(!pidl){
|
||||||
|
ok_(__FILE__,l)(0, "didn't get expected path (%s), instead: NULL\n", wine_dbgstr_w(path));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pSHBindToParent(pidl, &IID_IShellFolder, (LPVOID*)&parent, &child);
|
||||||
|
ok_(__FILE__,l)(hr == S_OK, "SHBindToParent failed: 0x%08x\n", hr);
|
||||||
|
if(FAILED(hr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
hr = IShellFolder_GetDisplayNameOf(parent, child, SHGDN_FORPARSING, &filename);
|
||||||
|
ok_(__FILE__,l)(hr == S_OK, "GetDisplayNameOf failed: 0x%08x\n", hr);
|
||||||
|
if(FAILED(hr)){
|
||||||
|
IShellFolder_Release(parent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok_(__FILE__,l)(filename.uType == STRRET_WSTR, "Got unexpected string type: %d\n", filename.uType);
|
||||||
|
ok_(__FILE__,l)(lstrcmpW(path, filename.pOleStr) == 0,
|
||||||
|
"didn't get expected path (%s), instead: %s\n",
|
||||||
|
wine_dbgstr_w(path), wine_dbgstr_w(filename.pOleStr));
|
||||||
|
|
||||||
|
IShellFolder_Release(parent);
|
||||||
|
}else
|
||||||
|
ok_(__FILE__,l)(pidl == NULL, "Expected PIDL to be NULL\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_SHSimpleIDListFromPath(void)
|
||||||
|
{
|
||||||
|
const WCHAR adirW[] = {'C',':','\\','s','i','d','l','f','p','d','i','r',0};
|
||||||
|
const CHAR adirA[] = "C:\\sidlfpdir";
|
||||||
|
BOOL br, is_unicode = !(GetVersion() & 0x80000000);
|
||||||
|
|
||||||
|
LPITEMIDLIST pidl = NULL;
|
||||||
|
|
||||||
|
if(!pSHSimpleIDListFromPathAW){
|
||||||
|
win_skip("SHSimpleIDListFromPathAW not available\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
br = CreateDirectoryA(adirA, NULL);
|
||||||
|
ok(br == TRUE, "CreateDirectory failed: %d\n", GetLastError());
|
||||||
|
|
||||||
|
if(is_unicode)
|
||||||
|
pidl = pSHSimpleIDListFromPathAW(adirW);
|
||||||
|
else
|
||||||
|
pidl = pSHSimpleIDListFromPathAW(adirA);
|
||||||
|
verify_pidl(pidl, adirW);
|
||||||
|
pILFree(pidl);
|
||||||
|
|
||||||
|
br = RemoveDirectoryA(adirA);
|
||||||
|
ok(br == TRUE, "RemoveDirectory failed: %d\n", GetLastError());
|
||||||
|
|
||||||
|
if(is_unicode)
|
||||||
|
pidl = pSHSimpleIDListFromPathAW(adirW);
|
||||||
|
else
|
||||||
|
pidl = pSHSimpleIDListFromPathAW(adirA);
|
||||||
|
verify_pidl(pidl, adirW);
|
||||||
|
pILFree(pidl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* IFileSystemBindData impl */
|
||||||
|
static HRESULT WINAPI fsbd_QueryInterface(IFileSystemBindData *fsbd,
|
||||||
|
REFIID riid, void **ppv)
|
||||||
|
{
|
||||||
|
if(IsEqualIID(riid, &IID_IFileSystemBindData) ||
|
||||||
|
IsEqualIID(riid, &IID_IUnknown)){
|
||||||
|
*ppv = fsbd;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI fsbd_AddRef(IFileSystemBindData *fsbd)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI fsbd_Release(IFileSystemBindData *fsbd)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI fsbd_SetFindData(IFileSystemBindData *fsbd,
|
||||||
|
const WIN32_FIND_DATAW *pfd)
|
||||||
|
{
|
||||||
|
ok(0, "SetFindData called\n");
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI fsbd_GetFindData_nul(IFileSystemBindData *fsbd,
|
||||||
|
WIN32_FIND_DATAW *pfd)
|
||||||
|
{
|
||||||
|
memset(pfd, 0, sizeof(WIN32_FIND_DATAW));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI fsbd_GetFindData_junk(IFileSystemBindData *fsbd,
|
||||||
|
WIN32_FIND_DATAW *pfd)
|
||||||
|
{
|
||||||
|
memset(pfd, 0xdeadbeef, sizeof(WIN32_FIND_DATAW));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI fsbd_GetFindData_invalid(IFileSystemBindData *fsbd,
|
||||||
|
WIN32_FIND_DATAW *pfd)
|
||||||
|
{
|
||||||
|
memset(pfd, 0, sizeof(WIN32_FIND_DATAW));
|
||||||
|
*pfd->cFileName = 'a';
|
||||||
|
*pfd->cAlternateFileName = 'a';
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI fsbd_GetFindData_valid(IFileSystemBindData *fsbd,
|
||||||
|
WIN32_FIND_DATAW *pfd)
|
||||||
|
{
|
||||||
|
static const WCHAR adirW[] = {'C',':','\\','f','s','b','d','d','i','r',0};
|
||||||
|
HANDLE handle = FindFirstFileW(adirW, pfd);
|
||||||
|
FindClose(handle);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI fsbd_GetFindData_fail(IFileSystemBindData *fsbd,
|
||||||
|
WIN32_FIND_DATAW *pfd)
|
||||||
|
{
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IFileSystemBindDataVtbl fsbdVtbl = {
|
||||||
|
fsbd_QueryInterface,
|
||||||
|
fsbd_AddRef,
|
||||||
|
fsbd_Release,
|
||||||
|
fsbd_SetFindData,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static IFileSystemBindData fsbd = { &fsbdVtbl };
|
||||||
|
|
||||||
|
static void test_ParseDisplayNamePBC(void)
|
||||||
|
{
|
||||||
|
WCHAR wFileSystemBindData[] =
|
||||||
|
{'F','i','l','e',' ','S','y','s','t','e','m',' ','B','i','n','d',' ','D','a','t','a',0};
|
||||||
|
WCHAR adirW[] = {'C',':','\\','f','s','b','d','d','i','r',0};
|
||||||
|
const HRESULT exp_err = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||||
|
|
||||||
|
IShellFolder *psf;
|
||||||
|
IBindCtx *pbc;
|
||||||
|
HRESULT hres;
|
||||||
|
ITEMIDLIST *pidl;
|
||||||
|
|
||||||
|
/* Check if we support WCHAR functions */
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
lstrcmpiW(adirW, adirW);
|
||||||
|
if(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED){
|
||||||
|
win_skip("Most W-calls are not implemented\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hres = SHGetDesktopFolder(&psf);
|
||||||
|
ok(hres == S_OK, "SHGetDesktopFolder failed: 0x%08x\n", hres);
|
||||||
|
if(FAILED(hres)){
|
||||||
|
win_skip("Failed to get IShellFolder, can't run tests\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fails on unknown dir with no IBindCtx */
|
||||||
|
hres = IShellFolder_ParseDisplayName(psf, NULL, NULL, adirW, NULL, &pidl, NULL);
|
||||||
|
ok(hres == exp_err || broken(hres == E_FAIL) /* NT4 */,
|
||||||
|
"ParseDisplayName failed with wrong error: 0x%08x\n", hres);
|
||||||
|
|
||||||
|
/* fails on unknown dir with IBindCtx with no IFileSystemBindData */
|
||||||
|
hres = CreateBindCtx(0, &pbc);
|
||||||
|
ok(hres == S_OK, "CreateBindCtx failed: 0x%08x\n", hres);
|
||||||
|
|
||||||
|
hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, adirW, NULL, &pidl, NULL);
|
||||||
|
ok(hres == exp_err || broken(hres == E_FAIL) /* NT4 */,
|
||||||
|
"ParseDisplayName failed with wrong error: 0x%08x\n", hres);
|
||||||
|
|
||||||
|
/* unknown dir with IBindCtx with IFileSystemBindData */
|
||||||
|
hres = IBindCtx_RegisterObjectParam(pbc, wFileSystemBindData, (IUnknown*)&fsbd);
|
||||||
|
ok(hres == S_OK, "RegisterObjectParam failed: 0x%08x\n", hres);
|
||||||
|
|
||||||
|
/* return E_FAIL from GetFindData */
|
||||||
|
pidl = (ITEMIDLIST*)0xdeadbeef;
|
||||||
|
fsbdVtbl.GetFindData = fsbd_GetFindData_fail;
|
||||||
|
hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, adirW, NULL, &pidl, NULL);
|
||||||
|
ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */,
|
||||||
|
"ParseDisplayName failed: 0x%08x\n", hres);
|
||||||
|
if(SUCCEEDED(hres)){
|
||||||
|
verify_pidl(pidl, adirW);
|
||||||
|
ILFree(pidl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set FIND_DATA struct to NULLs */
|
||||||
|
pidl = (ITEMIDLIST*)0xdeadbeef;
|
||||||
|
fsbdVtbl.GetFindData = fsbd_GetFindData_nul;
|
||||||
|
hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, adirW, NULL, &pidl, NULL);
|
||||||
|
ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */,
|
||||||
|
"ParseDisplayName failed: 0x%08x\n", hres);
|
||||||
|
if(SUCCEEDED(hres)){
|
||||||
|
verify_pidl(pidl, adirW);
|
||||||
|
ILFree(pidl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set FIND_DATA struct to junk */
|
||||||
|
pidl = (ITEMIDLIST*)0xdeadbeef;
|
||||||
|
fsbdVtbl.GetFindData = fsbd_GetFindData_junk;
|
||||||
|
hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, adirW, NULL, &pidl, NULL);
|
||||||
|
ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */,
|
||||||
|
"ParseDisplayName failed: 0x%08x\n", hres);
|
||||||
|
if(SUCCEEDED(hres)){
|
||||||
|
verify_pidl(pidl, adirW);
|
||||||
|
ILFree(pidl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set FIND_DATA struct to invalid data */
|
||||||
|
pidl = (ITEMIDLIST*)0xdeadbeef;
|
||||||
|
fsbdVtbl.GetFindData = fsbd_GetFindData_invalid;
|
||||||
|
hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, adirW, NULL, &pidl, NULL);
|
||||||
|
ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */,
|
||||||
|
"ParseDisplayName failed: 0x%08x\n", hres);
|
||||||
|
if(SUCCEEDED(hres)){
|
||||||
|
verify_pidl(pidl, adirW);
|
||||||
|
ILFree(pidl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set FIND_DATA struct to valid data */
|
||||||
|
pidl = (ITEMIDLIST*)0xdeadbeef;
|
||||||
|
fsbdVtbl.GetFindData = fsbd_GetFindData_valid;
|
||||||
|
hres = IShellFolder_ParseDisplayName(psf, NULL, pbc, adirW, NULL, &pidl, NULL);
|
||||||
|
ok(hres == S_OK || broken(hres == E_FAIL) /* NT4 */,
|
||||||
|
"ParseDisplayName failed: 0x%08x\n", hres);
|
||||||
|
if(SUCCEEDED(hres)){
|
||||||
|
verify_pidl(pidl, adirW);
|
||||||
|
ILFree(pidl);
|
||||||
|
}
|
||||||
|
|
||||||
|
IBindCtx_Release(pbc);
|
||||||
|
IShellFolder_Release(psf);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(shlfolder)
|
START_TEST(shlfolder)
|
||||||
{
|
{
|
||||||
init_function_pointers();
|
init_function_pointers();
|
||||||
|
@ -2286,6 +2547,8 @@ START_TEST(shlfolder)
|
||||||
test_SHCreateShellItem();
|
test_SHCreateShellItem();
|
||||||
test_desktop_IPersist();
|
test_desktop_IPersist();
|
||||||
test_GetUIObject();
|
test_GetUIObject();
|
||||||
|
test_SHSimpleIDListFromPath();
|
||||||
|
test_ParseDisplayNamePBC();
|
||||||
|
|
||||||
OleUninitialize();
|
OleUninitialize();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue