shell32: create new internal function _ILCreateFromPathA to replace SHSimpleIDListFromPath

Rolf Kalbermatter rolf.kalbermatter at citeng.com
Wed Mar 26 06:19:30 CST 2003


This function is necessary since the function SHSimpleIDListFromPath()
used instead until now, is totally wrong and needs fixing. Despite
its name, this function does not create a simple (relative) ItemIDList
for a path but instead creates a simplified absolute ItemIDList.

Simpliefied here means that it does usually not test for the path to
really exist and consequently doesn't query the file system for the
file attributes and short 8.3 filename but instead seems to
artificially built up the ItemIDList just from the path name
itself. No attributes other than the FILE_ATTRIBUTE_DIRECTORY is set
as well as there is no file time and date, and only a 0 character
length short name.

The correct SHSimpleIDListFromPath() is used by SHChangeNotify and it's
the reason why native SHChangeNotify does not fail on already deleted
files and folders.

Changelog
  * dlls/shell32/pidl.h
  * dlls/shell32/pidl.c
    Add new helper function to create a relative file or folder
    ItemIDList for a path.
  * dlls/shell32/shfldr_fs.c
    Change usage of SHSimpleIDListFromPath to call new function instead.

License: X11/LGPL

Rolf Kalbermatter

Index: dlls/shell32/pidl.h
===================================================================
RCS file: /home/wine/wine/dlls/shell32/pidl.h,v
retrieving revision 1.25
diff -u -r1.25 pidl.h
--- dlls/shell32/pidl.h	12 Nov 2002 01:05:00 -0000	1.25
+++ dlls/shell32/pidl.h	26 Mar 2003 11:01:38 -0000
@@ -58,7 +58,8 @@
 *	drive		0x2F		drive		(lnk/persistant)
 *	folder/file	0x30		folder/file (1)	(lnk/persistant)
 *	folder		0x31		folder		(usual)
-*	value		0x32		file		(usual)
+*	valueA		0x32		file		(ANSI file name) 
+*	valueW		0x34		file		(Unicode file name)
 *	workgroup	0x41		network (3)
 *	computer	0x42		network (4)
 *	whole network	0x47		network (5)
@@ -174,6 +175,7 @@
 LPITEMIDLIST	_ILCreateFolder		(WIN32_FIND_DATAA * stffile);
 LPITEMIDLIST	_ILCreateValue		(WIN32_FIND_DATAA * stffile);
 LPITEMIDLIST	_ILCreateSpecial	(LPCSTR szGUID);
+LPITEMIDLIST	_ILCreateFromPathA	(LPCSTR szPath);
 
 /*
  * helper functions (getting struct-pointer)

Index: dlls/shell32/pidl.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/pidl.c,v
retrieving revision 1.81
diff -u -r1.81 pidl.c
--- dlls/shell32/pidl.c	18 Mar 2003 18:35:49 -0000	1.81
+++ dlls/shell32/pidl.c	26 Mar 2003 11:10:17 -0000
@@ -1116,7 +1116,7 @@
 	  pData = _ILGetDataPointer(pidl);
 	  FileTimeToDosDateTime(&(stffile->ftLastWriteTime),&pData->u.folder.uFileDate,&pData->u.folder.uFileTime);
 	  pData->u.folder.dwFileSize = stffile->nFileSizeLow;
-	  pData->u.folder.uFileAttribs=stffile->dwFileAttributes;
+	  pData->u.folder.uFileAttribs = stffile->dwFileAttributes;
 	}
 
 	return pidl;
@@ -1162,6 +1162,24 @@
 	return pidl;
 }
 
+LPITEMIDLIST _ILCreateFromPathA(LPCSTR szPath)
+{
+	HANDLE hFile;
+	WIN32_FIND_DATAA stffile;
+	LPITEMIDLIST pidl = NULL;
+	
+	hFile = FindFirstFileA(szPath, &stffile);
+	if (hFile != INVALID_HANDLE_VALUE) 
+	{
+	  if (stffile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+	    pidl = _ILCreateFolder(&stffile);
+	  else
+	    pidl = _ILCreateValue(&stffile);
+	  FindClose(hFile);
+	}
+	return pidl;
+}
+
 LPITEMIDLIST _ILCreateSpecial(LPCSTR szGUID)
 {
 	IID iid;

Index: dlls/shell32/shfldr_fs.c
===================================================================
RCS file: /home/wine/wine/dlls/shell32/shfldr_fs.c,v
retrieving revision 1.9
diff -u -r1.9 shfldr_fs.c
--- dlls/shell32/shfldr_fs.c	18 Mar 2003 18:35:49 -0000	1.9
+++ dlls/shell32/shfldr_fs.c	26 Mar 2003 12:09:41 -0000
@@ -324,9 +324,9 @@
     HRESULT hr = E_OUTOFMEMORY;
     LPCWSTR szNext = NULL;
     WCHAR szElement[MAX_PATH];
-    CHAR szTempA[MAX_PATH],
-      szPath[MAX_PATH];
+    CHAR szPath[MAX_PATH];
     LPITEMIDLIST pidlTemp = NULL;
+    DWORD len;
 
     TRACE ("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
 	   This, hwndOwner, pbcReserved, lpszDisplayName, debugstr_w (lpszDisplayName), pchEaten, ppidl, pdwAttributes);
@@ -342,14 +342,13 @@
 	szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
 
 	/* build the full pathname to the element */
-	WideCharToMultiByte (CP_ACP, 0, szElement, -1, szTempA, MAX_PATH, NULL, NULL);
-	lstrcpyA (szPath, This->sPathTarget);
-	PathAddBackslashA (szPath);
-	lstrcatA (szPath, szTempA);
+	lstrcpyA(szPath, This->sPathTarget);
+	PathAddBackslashA(szPath);
+	len = lstrlenA(szPath);
+	WideCharToMultiByte(CP_ACP, 0, szElement, -1, szPath + len, MAX_PATH - len, NULL, NULL);
 
 	/* get the pidl */
-	pidlTemp = SHSimpleIDListFromPathA (szPath);
-
+	pidlTemp = _ILCreateFromPathA(szPath);
 	if (pidlTemp) {
 	    if (szNext && *szNext) {
 		/* try to analyse the next element */
@@ -696,6 +695,7 @@
 	len = strlen (szSrc);
 	_ILSimpleGetText (pidl, szSrc + len, MAX_PATH - len);
     } else {
+	/* FIXME: Can this work with a simple PIDL? */
 	SHGetPathFromIDListA (pidl, szSrc);
     }
 
@@ -708,7 +708,7 @@
     TRACE ("src=%s dest=%s\n", szSrc, szDest);
     if (MoveFileA (szSrc, szDest)) {
 	if (pPidlOut)
-	    *pPidlOut = SHSimpleIDListFromPathA (szDest);
+	    *pPidlOut = _ILCreateFromPathA(szDest);
 	SHChangeNotify (bIsFolder ? SHCNE_RENAMEFOLDER : SHCNE_RENAMEITEM, SHCNF_PATHA, szSrc, szDest);
 	return S_OK;
     }
@@ -931,23 +931,13 @@
     TRACE ("(%p)(%s %p)\n", This, lpName, ppidlOut);
 
     strcpy (lpstrNewDir, This->sPathTarget);
-    PathAddBackslashA (lpstrNewDir);
-    strcat (lpstrNewDir, lpName);
+    PathAppendA(lpstrNewDir, lpName);
 
     bRes = CreateDirectoryA (lpstrNewDir, NULL);
-
     if (bRes) {
-	LPITEMIDLIST pidl,
-	  pidlitem;
-
-	pidlitem = SHSimpleIDListFromPathA (lpstrNewDir);
-
-	pidl = ILCombine (This->pidlRoot, pidlitem);
-	SHChangeNotify (SHCNE_MKDIR, SHCNF_IDLIST, pidl, NULL);
-	SHFree (pidl);
-
+	SHChangeNotify (SHCNE_MKDIR, SHCNF_PATHA, lpstrNewDir, NULL);
 	if (ppidlOut)
-	    *ppidlOut = pidlitem;
+	    *ppidlOut = _ILCreateFromPathA(lpstrNewDir);
 	hres = S_OK;
     } else {
 	char lpstrText[128 + MAX_PATH];




More information about the wine-patches mailing list