diff --git a/dlls/shell32/pidl.c b/dlls/shell32/pidl.c index dd35668ae094c1836b23b05dc14f819fc01f9018..31315f6df42e6b2044a9c6c526b9f46cb7678696 100644 --- a/dlls/shell32/pidl.c +++ b/dlls/shell32/pidl.c @@ -49,14 +49,127 @@ WINE_DECLARE_DEBUG_CHANNEL(shell); extern LPVOID WINAPI Alloc(INT); extern BOOL WINAPI Free(LPVOID); +/************************************************************************* + * ILGetDisplayNameEx [SHELL32.186] + * + * Retrieves the display name of an ItemIDList + * + * PARAMS + * psf [I] Shell Folder to start with, if NULL the desktop is used + * pidl [I] ItemIDList relativ to the psf to get the display name for + * path [O] Filled in with the display name, assumed to be at least MAX_PATH long + * type [I] Type of display name to retrieve + * 0 = SHGDN_FORPARSING | SHGDN_FORADDRESSBAR uses always the desktop as root + * 1 = SHGDN_NORMAL relative to the root folder + * 2 = SHGDN_INFOLDER relative to the root folder, only the last name + * + * RETURNS + * True if the display name could be retrieved successfully, False otherwise + */ +BOOL WINAPI ILGetDisplayNameExA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPSTR path, DWORD type) +{ + BOOL ret = FALSE; + WCHAR wPath[MAX_PATH]; + + TRACE("%p %p %p %ld\n", psf, pidl, path, type); + + if (!pidl || !path) + return FALSE; + + ret = ILGetDisplayNameExW(psf, pidl, wPath, type); + WideCharToMultiByte(CP_ACP, 0, wPath, -1, path, MAX_PATH, NULL, NULL); + TRACE("%p %p %s\n", psf, pidl, debugstr_a(path)); + + return ret; +} + +BOOL WINAPI ILGetDisplayNameExW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPWSTR path, DWORD type) +{ + LPSHELLFOLDER psfParent, lsf = psf; + HRESULT ret = NO_ERROR; + LPITEMIDLIST pidllast; + STRRET strret; + DWORD flag; + + TRACE("%p %p %p %ld\n", psf, pidl, path, type); + + if (!pidl || !path) + return FALSE; + + if (!lsf) + { + ret = SHGetDesktopFolder(&lsf); + if (FAILED(ret)) + return FALSE; + } + + if (type >= 0 && type <= 2) + { + switch (type) + { + case ILGDN_FORPARSING: + flag = SHGDN_FORPARSING | SHGDN_FORADDRESSBAR; + break; + case ILGDN_NORMAL: + flag = SHGDN_NORMAL; + break; + case ILGDN_INFOLDER: + flag = SHGDN_INFOLDER; + break; + default: + FIXME("Unknown type parameter = %lx", type); + flag = SHGDN_FORPARSING | SHGDN_FORADDRESSBAR; + break; + } + if (!*(LPWORD)pidl || type == ILGDN_FORPARSING) + { + ret = IShellFolder_GetDisplayNameOf(lsf, pidl, flag, &strret); + if (SUCCEEDED(ret)) + { + ret = StrRetToStrNW(path, MAX_PATH, &strret, pidl); + } + } + else + { + ret = SHBindToParent(pidl, &IID_IShellFolder, (LPVOID*)&psfParent, &pidllast); + if (SUCCEEDED(ret)) + { + ret = IShellFolder_GetDisplayNameOf(psfParent, pidllast, flag, &strret); + if (SUCCEEDED(ret)) + { + ret = StrRetToStrNW(path, MAX_PATH, &strret, pidllast); + } + IShellFolder_Release(psfParent); + } + } + } + + TRACE("%p %p %s\n", psf, pidl, debugstr_w(path)); + + if (!psf) + IShellFolder_Release(lsf); + return SUCCEEDED(ret); +} + +BOOL WINAPI ILGetDisplayNameEx(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPVOID path, DWORD type) +{ + TRACE_(shell)("%p %p %p %ld\n", psf, pidl, path, type); + if (SHELL_OsIsUnicode()) + return ILGetDisplayNameExW(psf, pidl, path, type); + return ILGetDisplayNameExA(psf, pidl, path, type); +} + /************************************************************************* * ILGetDisplayName [SHELL32.15] */ -BOOL WINAPI ILGetDisplayName(LPCITEMIDLIST pidl,LPSTR path) +BOOL WINAPI ILGetDisplayName(LPCITEMIDLIST pidl, LPVOID path) { - TRACE_(shell)("pidl=%p %p semi-stub\n",pidl,path); - return SHGetPathFromIDListA(pidl, path); + TRACE_(shell)("%p %p\n", pidl, path); + if (SHELL_OsIsUnicode()) + return ILGetDisplayNameExW(NULL, pidl, path, ILGDN_FORPARSING); + return ILGetDisplayNameExA(NULL, pidl, path, ILGDN_FORPARSING); } + /************************************************************************* * ILFindLastID [SHELL32.16] * @@ -217,8 +330,6 @@ HRESULT WINAPI ILSaveToStream (IStream * pStream, LPCITEMIDLIST pPidl) { ret = S_OK; } } - - IStream_Release (pStream); return ret; diff --git a/dlls/shell32/pidl.h b/dlls/shell32/pidl.h index f2961ac697f6f0b6491493099c11336915420f53..d87fcd371ae2947abeb6721b31334b57d96cb0cc 100644 --- a/dlls/shell32/pidl.h +++ b/dlls/shell32/pidl.h @@ -198,4 +198,7 @@ void _ILFreeaPidl(LPITEMIDLIST * apidl, UINT cidl); LPITEMIDLIST * _ILCopyaPidl(LPITEMIDLIST * apidlsrc, UINT cidl); LPITEMIDLIST * _ILCopyCidaToaPidl(LPITEMIDLIST* pidl, LPIDA cida); +BOOL WINAPI ILGetDisplayNameExA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPSTR path, DWORD type); +BOOL WINAPI ILGetDisplayNameExW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPWSTR path, DWORD type); + #endif diff --git a/dlls/shell32/shell32.spec b/dlls/shell32/shell32.spec index d928107a67c799ea4afe17c802171b7e3c1975be..93768cf3969de8e98ecbf832542aa140fe8c2f68 100644 --- a/dlls/shell32/shell32.spec +++ b/dlls/shell32/shell32.spec @@ -3,7 +3,7 @@ # win95 and winNT dlls import shell32.dll by ordinal) # This list was updated to dll version 4.72 - 2 stdcall SHChangeNotifyRegister(long long long long long long) + 2 stdcall SHChangeNotifyRegister(long long long long long ptr) 4 stdcall SHChangeNotifyDeregister (long) 5 stdcall SHChangeNotifyUpdateEntryList (long long long long) 9 stub PifMgr_OpenProperties@16 @@ -173,6 +173,7 @@ 183 varargs ShellMessageBoxA(long long long str long) 184 stdcall ArrangeWindows(long long long long long) 185 stub SHHandleDiskFull + 186 stdcall ILGetDisplayNameEx(ptr ptr ptr long) 195 stdcall SHFree(ptr) 196 stdcall SHAlloc(long) 197 stub SHGlobalDefect diff --git a/dlls/shell32/shlmenu.c b/dlls/shell32/shlmenu.c index 45f95b524b5ce311e8621707cf000211f8c03379..eb3f79c03b39768017f8545c366cc37bdac3fd93 100644 --- a/dlls/shell32/shlmenu.c +++ b/dlls/shell32/shlmenu.c @@ -178,7 +178,7 @@ static int FM_InitMenuPopup(HMENU hmenu, LPITEMIDLIST pAlternatePidl) { if (SUCCEEDED (IShellFolder_GetAttributesOf(lpsf, 1, &pidlTemp, &ulItemAttr))) { - ILGetDisplayName( pidlTemp, sTemp); + ILGetDisplayNameExA(NULL, pidlTemp, sTemp, ILGDN_FORPARSING); if (! (PidlToSicIndex(lpsf, pidlTemp, FALSE, 0, &iIcon))) iIcon = FM_BLANK_ICON; if ( SFGAO_FOLDER & ulItemAttr) diff --git a/dlls/shell32/undocshell.h b/dlls/shell32/undocshell.h index 248fd81d69e1032383a9eab46fff025733809183..202c66651da5a0b6d3e616aef069f005f3ee5b60 100644 --- a/dlls/shell32/undocshell.h +++ b/dlls/shell32/undocshell.h @@ -63,7 +63,18 @@ BOOL WINAPI ILIsParent( BOOL WINAPI ILGetDisplayName( LPCITEMIDLIST pidl, - LPSTR path); + LPVOID path); + +/* type parameter for ILGetDisplayNameEx() */ +#define ILGDN_FORPARSING 0 +#define ILGDN_NORMAL 1 +#define ILGDN_INFOLDER 2 + +BOOL WINAPI ILGetDisplayNameEx( + LPSHELLFOLDER psf, + LPCITEMIDLIST pidl, + LPVOID path, + DWORD type); DWORD WINAPI ILFree(LPITEMIDLIST pidl); diff --git a/include/wine/obj_shellfolder.h b/include/wine/obj_shellfolder.h index 3a72483fb94818d4e74d3276d3ed3e38c815e211..3db244337d96bf2e3542aa814255ceebdec76913 100644 --- a/include/wine/obj_shellfolder.h +++ b/include/wine/obj_shellfolder.h @@ -104,9 +104,12 @@ ICOM_DEFINE(IEnumExtraSearch,IUnknown) * IShellFolder::GetDisplayNameOf/SetNameOf uFlags */ typedef enum -{ SHGDN_NORMAL = 0, /* default (display purpose) */ - SHGDN_INFOLDER = 1, /* displayed under a folder (relative)*/ - SHGDN_FORPARSING = 0x8000 /* for ParseDisplayName or path */ +{ SHGDN_NORMAL = 0, /* default (display purpose) */ + SHGDN_INFOLDER = 1, /* displayed under a folder (relative)*/ + SHGDN_INCLUDE_NONFILESYS = 0x2000, /* if not set, display names for shel name space + items, that are not in the file system wil fail */ + SHGDN_FORADDRESSBAR = 0x4000, /* for displaying in the address (drives drop down) bar */ + SHGDN_FORPARSING = 0x8000 /* for ParseDisplayName or path */ } SHGNO; /*****************************************************************************