shell32: correct SHSimpleIDListFromPath

Rolf Kalbermatter rolf.kalbermatter at citeng.com
Tue Sep 16 13:51:22 CDT 2003


Changelog
  - dlls/shell32/Makefile.in
    Add dependency on ntdll.dll

  - dlls/shell32/pidl.c
    Implement SHSimpleIDListFromPath correctly

  - dlls/shell32/shell32_main.h
  - dlls/shell32/shlfsbind.c
  - dlls/shell32/shfldr_fs.c
    A few name corrections

License: X11
  
Rolf Kalbermatter

Index: dlls/shell32/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/shell32/Makefile.in,v
retrieving revision 1.69
diff -u -r1.69 Makefile.in
--- dlls/shell32/Makefile.in	15 Sep 2003 22:10:48 -0000	1.69
+++ dlls/shell32/Makefile.in	16 Sep 2003 18:49:45 -0000
@@ -5,7 +5,7 @@
 VPATH     = @srcdir@
 MODULE    = shell32.dll
 # fixme: avoid ole32.dll import
-IMPORTS   = ole32 shlwapi comctl32 user32 gdi32 advapi32 kernel32
+IMPORTS   = ole32 shlwapi comctl32 user32 gdi32 advapi32 kernel32 ntdll
 ALTNAMES  = shell.dll
 EXTRALIBS = $(LIBUUID) $(LIBUNICODE)
 
Index: dlls/shell32/pidl.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/pidl.c,v
retrieving revision 1.88
diff -u -r1.88 pidl.c
--- dlls/shell32/pidl.c	5 Sep 2003 23:08:31 -0000	1.88
+++ dlls/shell32/pidl.c	16 Sep 2003 18:11:28 -0000
@@ -36,6 +36,7 @@
 #include "shlguid.h"
 #include "winerror.h"
 #include "winnls.h"
+#include "winternl.h"
 #include "undocshell.h"
 #include "shell32_main.h"
 #include "shellapi.h"
@@ -807,46 +808,121 @@
 	return ILCreateFromPathA (path);
 }
 /*************************************************************************
- *  SHSimpleIDListFromPath [SHELL32.162]
+ * _ILParsePathW             [internal]
+ *
+ * Creates an ItemIDList from a path and returns it.
+ *
+ * PARAMS
+ *  path         [I]   path to parse and convert into an ItemIDList
+ *  lpFindFile   [I]   pointer to buffer to initialize the FileSystem
+ *                     Bind Data object with
+ *  bBindCtx     [I]   indicates to create a BindContext and assign a
+ *                     FileSystem Bind Data object
+ *  ppidl        [O]   the newly create ItemIDList
+ *  prgfInOut    [I/O] requested attributes on input and actual
+ *                     attributes on return
+ *
+ * RETURNS
+ *  NO_ERROR on success or an OLE error code
+ *
+ * NOTES
+ *  If either lpFindFile is non-NULL or bBindCtx is TRUE, this function
+ *  creates a BindContext object and assigns a FileSystem Bind Data object
+ *  to it, passing the BindContext to IShellFolder_ParseDisplayName. Each
+ *  IShellFolder uses that FileSystem Bind Data object of the BindContext
+ *  to pass data about the current path element to the next object. This
+ *  is used to avoid having to verify the current path element on disk, so
+ *  that creating an ItemIDList from a non existing path still can work.
  */
-LPITEMIDLIST WINAPI SHSimpleIDListFromPathA (LPCSTR lpszPath)
+static HRESULT WINAPI _ILParsePathW(LPCWSTR path, LPWIN32_FIND_DATAW lpFindFile,
+                             BOOL bBindCtx, LPITEMIDLIST *ppidl, LPDWORD prgfInOut)
 {
-	LPITEMIDLIST	pidl=NULL;
-	HANDLE	hFile;
-	WIN32_FIND_DATAA	stffile;
+	LPSHELLFOLDER pSF = NULL;
+	LPBC pBC = NULL;
+	HRESULT ret;
 
-	TRACE("path=%s\n", lpszPath);
+	TRACE("%s %p %d (%p)->%p (%p)->0x%lx\n", debugstr_w(path), lpFindFile, bBindCtx,
+	                                         ppidl, ppidl ? *ppidl : NULL,
+	                                         prgfInOut, prgfInOut ? *prgfInOut : 0);
 
-	if (!lpszPath) return NULL;
+	ret = SHGetDesktopFolder(&pSF);
+	if (FAILED(ret))
+	{
+	  return ret;
+	}
 
-	hFile = FindFirstFileA(lpszPath, &stffile);
+	if (lpFindFile || bBindCtx)
+	  ret = IFileSystemBindData_Constructor(lpFindFile, &pBC);
 
-	if ( hFile != INVALID_HANDLE_VALUE )
+	if (SUCCEEDED(ret))
 	{
-	  if (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-	  {
-	    pidl = _ILCreateFolder (&stffile);
-	  }
-	  else
-	  {
-	    pidl = _ILCreateValue (&stffile);
-	  }
-	  FindClose (hFile);
+	  ret = IShellFolder_ParseDisplayName(pSF, 0, pBC, (LPOLESTR)path, NULL, ppidl, prgfInOut);
+	}
+
+	if (pBC)
+	{
+	  IBindCtx_Release(pBC);
+	  pBC = NULL;
 	}
+
+	IShellFolder_Release(pSF);
+
+	if (!SUCCEEDED(ret) && ppidl)
+	  *ppidl = NULL;
+
+	TRACE("%s %p 0x%lx\n", debugstr_w(path), ppidl ? *ppidl : NULL, prgfInOut ? *prgfInOut : 0);
+
+	return ret;
+}
+
+/*************************************************************************
+ * SHSimpleIDListFromPath    [SHELL32.162]
+ *
+ * Creates a simple ItemIDList from a path and returns it. This function
+ * does not fail on non-existing paths.
+ *
+ * PARAMS
+ *  path         [I]   path to parse and convert into an ItemIDList
+ *
+ * RETURNS
+ *  the newly created simple ItemIDList
+ *
+ * NOTES
+ *  Simple in the name does not mean a relative ItemIDList but rather a
+ *  fully qualified list, where only the file name is filled in and the
+ *  directory flag for those ItemID elements this is known about, eg.
+ *  it is not the last element in the ItemIDList or the actual directory
+ *  exists on disk.
+ *  exported by ordinal.
+ */
+LPITEMIDLIST WINAPI SHSimpleIDListFromPathA(LPCSTR lpszPath)
+{
+	LPITEMIDLIST pidl = NULL;
+	UNICODE_STRING wPath;
+
+	TRACE("%s\n", debugstr_a(lpszPath));
+
+	RtlCreateUnicodeStringFromAsciiz(&wPath, lpszPath);
+
+	_ILParsePathW(wPath.Buffer, NULL, TRUE, &pidl, NULL);
+	RtlFreeUnicodeString(&wPath);
+
+	TRACE("%s %p\n", debugstr_a(lpszPath), pidl);
 	return pidl;
 }
-LPITEMIDLIST WINAPI SHSimpleIDListFromPathW (LPCWSTR lpszPath)
+
+LPITEMIDLIST WINAPI SHSimpleIDListFromPathW(LPCWSTR lpszPath)
 {
-	char	lpszTemp[MAX_PATH];
-	TRACE("path=%s\n",debugstr_w(lpszPath));
+	LPITEMIDLIST pidl = NULL;
 
-        if (!WideCharToMultiByte( CP_ACP, 0, lpszPath, -1, lpszTemp, sizeof(lpszTemp), NULL, NULL ))
-            lpszTemp[sizeof(lpszTemp)-1] = 0;
+	TRACE("%s\n", debugstr_w(lpszPath));
 
-	return SHSimpleIDListFromPathA (lpszTemp);
+	_ILParsePathW(lpszPath, NULL, TRUE, &pidl, NULL);
+	TRACE("%s %p\n", debugstr_w(lpszPath), pidl);
+	return pidl;
 }
 
-LPITEMIDLIST WINAPI SHSimpleIDListFromPathAW (LPCVOID lpszPath)
+LPITEMIDLIST WINAPI SHSimpleIDListFromPathAW(LPCVOID lpszPath)
 {
 	if ( SHELL_OsIsUnicode())
 	  return SHSimpleIDListFromPathW (lpszPath);
@@ -958,7 +1034,7 @@
 	    {
 	       WIN32_FIND_DATAA * pfd = dest;
 
-	       if ( len < sizeof (WIN32_FIND_DATAA)) return E_INVALIDARG;
+	       if (len < (int)sizeof(WIN32_FIND_DATAA)) return E_INVALIDARG;
 
 	       ZeroMemory(pfd, sizeof (WIN32_FIND_DATAA));
 	       _ILGetFileDateTime( pidl, &(pfd->ftLastWriteTime));
@@ -998,7 +1074,7 @@
 	    {
 	       WIN32_FIND_DATAW * pfd = dest;
 
-	       if ( len < sizeof (WIN32_FIND_DATAW)) return E_INVALIDARG;
+	       if (len < (int)sizeof(WIN32_FIND_DATAW)) return E_INVALIDARG;
 
 	       ZeroMemory(pfd, sizeof (WIN32_FIND_DATAA));
 	       _ILGetFileDateTime( pidl, &(pfd->ftLastWriteTime));
@@ -1090,6 +1166,18 @@
 }
 
 /*************************************************************************
+ * SHGetPathFromIDList		[SHELL32.@][NT 4.0: SHELL32.219]
+ */
+BOOL WINAPI SHGetPathFromIDListAW(LPCITEMIDLIST pidl,LPVOID pszPath)
+{
+	TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath);
+
+	if (SHELL_OsIsUnicode())
+	  return SHGetPathFromIDListW(pidl,pszPath);
+	return SHGetPathFromIDListA(pidl,pszPath);
+}
+
+/*************************************************************************
  *	SHBindToParent		[shell version 5.0]
  */
 HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
@@ -1134,18 +1222,6 @@
 
 	TRACE_(shell)("-- psf=%p pidl=%p ret=0x%08lx\n", *ppv, (ppidlLast)?*ppidlLast:NULL, hr);
 	return hr;
-}
-
-/*************************************************************************
- * SHGetPathFromIDList		[SHELL32.@][NT 4.0: SHELL32.219]
- */
-BOOL WINAPI SHGetPathFromIDListAW(LPCITEMIDLIST pidl,LPVOID pszPath)
-{
-	TRACE_(shell)("(pidl=%p,%p)\n",pidl,pszPath);
-
-	if (SHELL_OsIsUnicode())
-	  return SHGetPathFromIDListW(pidl,pszPath);
-	return SHGetPathFromIDListA(pidl,pszPath);
 }
 
 /**************************************************************************
Index: dlls/shell32/shell32_main.h
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shell32_main.h,v
retrieving revision 1.71
diff -u -r1.71 shell32_main.h
--- dlls/shell32/shell32_main.h	15 Sep 2003 22:10:48 -0000	1.71
+++ dlls/shell32/shell32_main.h	16 Sep 2003 18:11:28 -0000
@@ -94,7 +94,7 @@
 HRESULT WINAPI ISF_Desktop_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
 HRESULT WINAPI ISF_MyComputer_Constructor(IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
 HRESULT WINAPI IDropTargetHelper_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv);
-HRESULT WINAPI FileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV);
+HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV);
 
 /* kind of enumidlist */
 #define EIDL_DESK	0
Index: dlls/shell32/shlfsbind.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shlfsbind.c,v
retrieving revision 1.1
diff -u -r1.1 shlfsbind.c
--- dlls/shell32/shlfsbind.c	15 Sep 2003 22:10:48 -0000	1.1
+++ dlls/shell32/shlfsbind.c	16 Sep 2003 18:34:01 -0000
@@ -64,7 +64,7 @@
 
 static WCHAR wFileSystemBindData[] = {'F','i','l','e',' ','S','y','s','t','e','m',' ','B','i','n','d','D','a','t','a',0};
 
-HRESULT WINAPI FileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV)
+HRESULT WINAPI IFileSystemBindData_Constructor(const WIN32_FIND_DATAW *pfd, LPBC *ppV)
 {
 	IFileSystemBindDataImpl *sb;
 	HRESULT ret = E_OUTOFMEMORY;
Index: dlls/shell32/shfldr_fs.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shfldr_fs.c,v
retrieving revision 1.15
diff -u -r1.15 shfldr_fs.c
--- dlls/shell32/shfldr_fs.c	15 Sep 2003 22:16:41 -0000	1.15
+++ dlls/shell32/shfldr_fs.c	16 Sep 2003 18:11:28 -0000
@@ -298,7 +298,7 @@
 *
 * PARAMS
 *  hwndOwner       [in]  Parent window for any message's
-*  pbc             [in]  Reserved
+*  pbc             [in]  optional FileSystemBindData context
 *  lpszDisplayName [in]  Unicode displayname.
 *  pchEaten        [out] (unicode) characters processed
 *  ppidl           [out] complex pidl to item
@@ -402,16 +402,16 @@
 *		IShellFolder_fnBindToObject
 * PARAMETERS
 *  LPCITEMIDLIST pidl,       //[in ] relative pidl to open
-*  LPBC          pbc,        //[in ] reserved
+*  LPBC          pbc,        //[in ] optional FileSystemBindData context
 *  REFIID        riid,       //[in ] Initial Interface
 *  LPVOID*       ppvObject   //[out] Interface*
 */
 static HRESULT WINAPI
-IShellFolder_fnBindToObject (IShellFolder2 * iface, LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
+IShellFolder_fnBindToObject (IShellFolder2 * iface, LPCITEMIDLIST pidl, LPBC pbc, REFIID riid, LPVOID * ppvOut)
 {
     _ICOM_THIS_From_IShellFolder2 (IGenericSFImpl, iface)
 
-    TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
+    TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbc, shdebugstr_guid (riid), ppvOut);
 
     return SHELL32_BindToChild (This->pidlRoot, This->sPathTarget, pidl, riid, ppvOut);
 }





More information about the wine-patches mailing list