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];