*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-#include "wine/port.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-#define COBJMACROS
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include "winerror.h"
-#include "windef.h"
-#include "winbase.h"
-#include "winreg.h"
-#include "wingdi.h"
-#include "winuser.h"
-
-#include "ole2.h"
-#include "shlguid.h"
-
-#include "enumidlist.h"
-#include "pidl.h"
-#include "undocshell.h"
-#include "shell32_main.h"
-#include "shresdef.h"
-#include "shlwapi.h"
-#include "shellfolder.h"
-#include "wine/debug.h"
-#include "debughlp.h"
-#include "shfldr.h"
+#include <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL (shell);
CLSID *pclsid;
/* both paths are parsible from the desktop */
- LPSTR sPathTarget; /* complete path to target used for enumeration and ChangeNotify */
+ LPWSTR sPathTarget; /* complete path to target used for enumeration and ChangeNotify */
LPITEMIDLIST pidlRoot; /* absolute pidl */
UINT cfShellIDList; /* clipboardformat for IDropTarget */
BOOL fAcceptFmt; /* flag for pending Drop */
-} IGenericSFImpl;
+} IGenericSFImpl, *LPIGenericSFImpl;
static const IUnknownVtbl unkvt;
static const IShellFolder2Vtbl sfvt;
static const IDropTargetVtbl dtvt;
static const ISFHelperVtbl shvt;
-static inline IGenericSFImpl *impl_from_IShellFolder2( IShellFolder2 *iface )
+static LPIGenericSFImpl __inline impl_from_IShellFolder2( IShellFolder2 *iface )
{
- return (IGenericSFImpl *)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblShellFolder));
+ return (LPIGenericSFImpl)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblShellFolder));
}
-static inline IGenericSFImpl *impl_from_IPersistFolder3( IPersistFolder3 *iface )
+static LPIGenericSFImpl __inline impl_from_IPersistFolder3( IPersistFolder3 *iface )
{
- return (IGenericSFImpl *)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblPersistFolder3));
+ return (LPIGenericSFImpl)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblPersistFolder3));
}
-static inline IGenericSFImpl *impl_from_IDropTarget( IDropTarget *iface )
+static LPIGenericSFImpl __inline impl_from_IDropTarget( IDropTarget *iface )
{
- return (IGenericSFImpl *)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblDropTarget));
+ return (LPIGenericSFImpl)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblDropTarget));
}
-static inline IGenericSFImpl *impl_from_ISFHelper( ISFHelper *iface )
+static LPIGenericSFImpl __inline impl_from_ISFHelper( ISFHelper *iface )
{
- return (IGenericSFImpl *)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblSFHelper));
+ return (LPIGenericSFImpl)((char*)iface - FIELD_OFFSET(IGenericSFImpl, lpvtblSFHelper));
}
IGenericSFImpl *This = (IGenericSFImpl *)iface;
ULONG refCount = InterlockedIncrement(&This->ref);
- TRACE ("(%p)->(count=%lu)\n", This, refCount - 1);
+ TRACE ("(%p)->(count=%u)\n", This, refCount - 1);
return refCount;
}
IGenericSFImpl *This = (IGenericSFImpl *)iface;
ULONG refCount = InterlockedDecrement(&This->ref);
- TRACE ("(%p)->(count=%lu)\n", This, refCount + 1);
+ TRACE ("(%p)->(count=%u)\n", This, refCount + 1);
if (!refCount) {
TRACE ("-- destroying IShellFolder(%p)\n", This);
- if (This->pidlRoot)
- SHFree (This->pidlRoot);
- if (This->sPathTarget)
- SHFree (This->sPathTarget);
+ SHFree (This->pidlRoot);
+ SHFree (This->sPathTarget);
LocalFree ((HLOCAL) This);
}
return refCount;
IUnknown_fnRelease,
};
-static shvheader GenericSFHeader[] = {
+static const shvheader GenericSFHeader[] = {
{IDS_SHV_COLUMN1, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
{IDS_SHV_COLUMN2, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
{IDS_SHV_COLUMN3, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
{
IGenericSFImpl *This = impl_from_IShellFolder2(iface);
- TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+ TRACE ("(%p)->(count=%u)\n", This, This->ref);
return IUnknown_AddRef (This->pUnkOuter);
}
{
IGenericSFImpl *This = impl_from_IShellFolder2(iface);
- TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+ TRACE ("(%p)->(count=%u)\n", This, This->ref);
return IUnknown_Release (This->pUnkOuter);
}
/**************************************************************************
* SHELL32_CreatePidlFromBindCtx [internal]
*
- * If the caller bound File System Bind Data, assume it is the
+ * If the caller bound File System Bind Data, assume it is the
* find data for the path.
* This allows binding of paths that don't exist.
*/
LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path)
{
- static const WCHAR szfsbc[] = {
+ static WCHAR szfsbc[] = {
'F','i','l','e',' ','S','y','s','t','e','m',' ',
'B','i','n','d',' ','D','a','t','a',0 };
IFileSystemBindData *fsbd = NULL;
}
IFileSystemBindData_Release( fsbd );
}
-
+
return pidl;
}
szNext = GetNextElementW (lpszDisplayName, szElement, MAX_PATH);
/* build the full pathname to the element */
- /* lstrcpyW(szPath, This->sPathTarget); */
- MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, szPath, MAX_PATH);
+ lstrcpynW(szPath, This->sPathTarget, MAX_PATH - 1);
PathAddBackslashW(szPath);
- len = lstrlenW(szPath);
+ len = wcslen(szPath);
lstrcpynW(szPath + len, szElement, MAX_PATH - len);
/* get the pidl */
else
*ppidl = NULL;
- TRACE ("(%p)->(-- pidl=%p ret=0x%08lx)\n", This, ppidl ? *ppidl : 0, hr);
+ TRACE ("(%p)->(-- pidl=%p ret=0x%08x)\n", This, ppidl ? *ppidl : 0, hr);
return hr;
}
{
IGenericSFImpl *This = impl_from_IShellFolder2(iface);
- TRACE ("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n", This, hwndOwner,
+ TRACE ("(%p)->(HWND=%p flags=0x%08x pplist=%p)\n", This, hwndOwner,
dwFlags, ppEnumIDList);
*ppEnumIDList = IEnumIDList_Constructor();
if (*ppEnumIDList)
- {
- WCHAR path[MAX_PATH];
- MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, path, MAX_PATH);
- CreateFolderEnumList(*ppEnumIDList, path, dwFlags);
- }
+ CreateFolderEnumList(*ppEnumIDList, This->sPathTarget, dwFlags);
TRACE ("-- (%p)->(new ID List: %p)\n", This, *ppEnumIDList);
LPBC pbc, REFIID riid, LPVOID * ppvOut)
{
IGenericSFImpl *This = impl_from_IShellFolder2(iface);
- WCHAR szPath[MAX_PATH];
TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This, pidl, pbc,
shdebugstr_guid (riid), ppvOut);
- MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, szPath, MAX_PATH);
- return SHELL32_BindToChild (This->pidlRoot, szPath, pidl, riid,
+ return SHELL32_BindToChild (This->pidlRoot, This->sPathTarget, pidl, riid,
ppvOut);
}
HRESULT hr = S_OK;
- TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08lx))\n", This, cidl, apidl,
+ TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08x))\n", This, cidl, apidl,
rgfInOut, rgfInOut ? *rgfInOut : 0);
if (!rgfInOut)
/* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
*rgfInOut &= ~SFGAO_VALIDATE;
- TRACE ("-- result=0x%08lx\n", *rgfInOut);
+ TRACE ("-- result=0x%08x\n", *rgfInOut);
return hr;
}
*ppvOut = NULL;
if (IsEqualIID (riid, &IID_IContextMenu) && (cidl >= 1)) {
- pObj = (LPUNKNOWN) ISvItemCm_Constructor ((IShellFolder *) iface,
- This->pidlRoot, apidl, cidl);
- hr = S_OK;
- } else if (IsEqualIID (riid, &IID_IDataObject) && (cidl >= 1)) {
+ hr = CDefFolderMenu_Create2(This->pidlRoot, hwndOwner, cidl, apidl, (IShellFolder*)iface, NULL, 0, NULL, (IContextMenu**)&pObj);
+ } else if (IsEqualIID (riid, &IID_IDataObject)){
+ if (cidl >= 1) {
pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner,
This->pidlRoot, apidl, cidl);
hr = S_OK;
+ }
+ else
+ {
+ pObj = (LPUNKNOWN) IDataObject_Constructor (hwndOwner, This->pidlRoot, (LPCITEMIDLIST*)&This->pidlRoot, 1);
+ hr = S_OK;
+ }
} else if (IsEqualIID (riid, &IID_IExtractIconA) && (cidl == 1)) {
pidl = ILCombine (This->pidlRoot, apidl[0]);
pObj = (LPUNKNOWN) IExtractIconA_Constructor (pidl);
*ppvOut = pObj;
}
- TRACE ("(%p)->hr=0x%08lx\n", This, hr);
+ TRACE ("(%p)->hr=0x%08x\n", This, hr);
return hr;
}
/******************************************************************************
* SHELL_FS_HideExtension [Internal]
*
- * Query the registry if the filename extension of a given path should be
+ * Query the registry if the filename extension of a given path should be
* hidden.
*
* PARAMS
* szPath [I] Relative or absolute path of a file
- *
+ *
* RETURNS
* TRUE, if the filename's extension should be hidden
* FALSE, otherwise.
DWORD dwData;
DWORD dwDataSize = sizeof (DWORD);
BOOL doHide = FALSE; /* The default value is FALSE (win98 at least) */
-
+
if (!RegCreateKeyExW(HKEY_CURRENT_USER, AdvancedW, 0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0)) {
if (!RegQueryValueExW(hKey, HideFileExtW, 0, 0, (LPBYTE) &dwData, &dwDataSize))
doHide = dwData;
}
return doHide;
}
-
-void SHELL_FS_ProcessDisplayFilename(LPSTR szPath, DWORD dwFlags)
-{
- WCHAR pathW[MAX_PATH];
+void SHELL_FS_ProcessDisplayFilename(LPWSTR szPath, DWORD dwFlags)
+{
/*FIXME: MSDN also mentions SHGDN_FOREDITING which is not yet handled. */
if (!(dwFlags & SHGDN_FORPARSING) &&
((dwFlags & SHGDN_INFOLDER) || (dwFlags == SHGDN_NORMAL))) {
- MultiByteToWideChar(CP_ACP, 0, szPath, -1, pathW, MAX_PATH);
- if (SHELL_FS_HideExtension(pathW) && szPath[0] != '.')
- PathRemoveExtensionA (szPath);
+ if (SHELL_FS_HideExtension(szPath) && szPath[0] != '.')
+ PathRemoveExtensionW(szPath);
}
}
DWORD dwFlags, LPSTRRET strRet)
{
IGenericSFImpl *This = impl_from_IShellFolder2(iface);
+ LPWSTR pszPath;
HRESULT hr = S_OK;
int len = 0;
- TRACE ("(%p)->(pidl=%p,0x%08lx,%p)\n", This, pidl, dwFlags, strRet);
+ TRACE ("(%p)->(pidl=%p,0x%08x,%p)\n", This, pidl, dwFlags, strRet);
pdump (pidl);
if (!pidl || !strRet)
return E_INVALIDARG;
-
- strRet->uType = STRRET_CSTR;
+
+ pszPath = CoTaskMemAlloc((MAX_PATH +1) * sizeof(WCHAR));
+ if (!pszPath)
+ return E_OUTOFMEMORY;
+
if (_ILIsDesktop(pidl)) { /* empty pidl */
if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
- (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER))
+ (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER))
{
if (This->sPathTarget)
- lstrcpynA(strRet->u.cStr, This->sPathTarget, MAX_PATH);
+ lstrcpynW(pszPath, This->sPathTarget, MAX_PATH);
} else {
/* pidl has to contain exactly one non null SHITEMID */
hr = E_INVALIDARG;
}
} else if (_ILIsPidlSimple(pidl)) {
if ((GET_SHGDN_FOR(dwFlags) & SHGDN_FORPARSING) &&
- (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER) &&
- This->sPathTarget)
+ (GET_SHGDN_RELATION(dwFlags) != SHGDN_INFOLDER) &&
+ This->sPathTarget)
{
- lstrcpynA(strRet->u.cStr, This->sPathTarget, MAX_PATH);
- PathAddBackslashA(strRet->u.cStr);
- len = lstrlenA(strRet->u.cStr);
+ lstrcpynW(pszPath, This->sPathTarget, MAX_PATH);
+ PathAddBackslashW(pszPath);
+ len = wcslen(pszPath);
}
- _ILSimpleGetText(pidl, strRet->u.cStr + len, MAX_PATH - len);
- if (!_ILIsFolder(pidl)) SHELL_FS_ProcessDisplayFilename(strRet->u.cStr, dwFlags);
+ _ILSimpleGetTextW(pidl, pszPath + len, MAX_PATH + 1 - len);
+ if (!_ILIsFolder(pidl)) SHELL_FS_ProcessDisplayFilename(pszPath, dwFlags);
} else {
- hr = SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, strRet->u.cStr, MAX_PATH);
+ hr = SHELL32_GetDisplayNameOfChild(iface, pidl, dwFlags, pszPath, MAX_PATH);
}
- TRACE ("-- (%p)->(%s)\n", This, strRet->u.cStr);
+ if (SUCCEEDED(hr)) {
+ /* Win9x always returns ANSI strings, NT always returns Unicode strings */
+ if (GetVersion() & 0x80000000) {
+ strRet->uType = STRRET_CSTR;
+ if (!WideCharToMultiByte(CP_ACP, 0, pszPath, -1, strRet->u.cStr, MAX_PATH,
+ NULL, NULL))
+ strRet->u.cStr[0] = '\0';
+ CoTaskMemFree(pszPath);
+ } else {
+ strRet->uType = STRRET_WSTR;
+ strRet->u.pOleStr = pszPath;
+ }
+ } else
+ CoTaskMemFree(pszPath);
+
+ TRACE ("-- (%p)->(%s)\n", This, strRet->uType == STRRET_CSTR ? strRet->u.cStr : debugstr_w(strRet->u.pOleStr));
return hr;
}
LPITEMIDLIST * pPidlOut)
{
IGenericSFImpl *This = impl_from_IShellFolder2(iface);
- WCHAR szSrc[MAX_PATH], szDest[MAX_PATH];
+ WCHAR szSrc[MAX_PATH + 1], szDest[MAX_PATH + 1];
LPWSTR ptr;
BOOL bIsFolder = _ILIsFolder (ILFindLastID (pidl));
- TRACE ("(%p)->(%p,pidl=%p,%s,%lu,%p)\n", This, hwndOwner, pidl,
+ TRACE ("(%p)->(%p,pidl=%p,%s,%u,%p)\n", This, hwndOwner, pidl,
debugstr_w (lpName), dwFlags, pPidlOut);
/* build source path */
- MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, szSrc, MAX_PATH);
+ lstrcpynW(szSrc, This->sPathTarget, MAX_PATH);
ptr = PathAddBackslashW (szSrc);
if (ptr)
- _ILSimpleGetTextW (pidl, ptr, MAX_PATH - (ptr - szSrc));
+ _ILSimpleGetTextW (pidl, ptr, MAX_PATH + 1 - (ptr - szSrc));
/* build destination path */
if (dwFlags == SHGDN_NORMAL || dwFlags & SHGDN_INFOLDER) {
- MultiByteToWideChar(CP_ACP, 0, This->sPathTarget, -1, szDest, MAX_PATH);
+ lstrcpynW(szDest, This->sPathTarget, MAX_PATH);
ptr = PathAddBackslashW (szDest);
if (ptr)
- lstrcpynW(ptr, lpName, MAX_PATH - (ptr - szDest));
+ lstrcpynW(ptr, lpName, MAX_PATH + 1 - (ptr - szDest));
} else
lstrcpynW(szDest, lpName, MAX_PATH);
if(!(dwFlags & SHGDN_FORPARSING) && SHELL_FS_HideExtension(szSrc)) {
WCHAR *ext = PathFindExtensionW(szSrc);
if(*ext != '\0') {
- INT len = strlenW(szDest);
+ INT len = wcslen(szDest);
lstrcpynW(szDest + len, ext, MAX_PATH - len);
}
}
-
+
TRACE ("src=%s dest=%s\n", debugstr_w(szSrc), debugstr_w(szDest));
+ if (!memcmp(szSrc, szDest, (wcslen(szDest)+1) * sizeof(WCHAR)))
+ {
+ /* src and destination is the same */
+ HRESULT hr = S_OK;
+ if (pPidlOut)
+ hr = _ILCreateFromPathW(szDest, pPidlOut);
+
+ return hr;
+ }
+
if (MoveFileW (szSrc, szDest)) {
HRESULT hr = S_OK;
psd->str.u.cStr, MAX_PATH);
return S_OK;
} else {
+ hr = S_OK;
+ psd->str.uType = STRRET_CSTR;
/* the data from the pidl */
switch (iColumn) {
case 0: /* name */
_ILGetFileAttributes (pidl, psd->str.u.cStr, MAX_PATH);
break;
}
- hr = S_OK;
- psd->str.uType = STRRET_CSTR;
}
return hr;
{
IGenericSFImpl *This = impl_from_ISFHelper(iface);
- TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+ TRACE ("(%p)->(count=%u)\n", This, This->ref);
return IUnknown_QueryInterface (This->pUnkOuter, riid, ppvObj);
}
{
IGenericSFImpl *This = impl_from_ISFHelper(iface);
- TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+ TRACE ("(%p)->(count=%u)\n", This, This->ref);
return IUnknown_AddRef (This->pUnkOuter);
}
*/
static HRESULT WINAPI
-ISFHelper_fnGetUniqueName (ISFHelper * iface, LPSTR lpName, UINT uLen)
+ISFHelper_fnGetUniqueName (ISFHelper * iface, LPWSTR pwszName, UINT uLen)
{
IGenericSFImpl *This = impl_from_ISFHelper(iface);
IEnumIDList *penum;
HRESULT hr;
- char szText[MAX_PATH];
- const char *szNewFolder = "New Folder";
+ WCHAR wszText[MAX_PATH];
+ WCHAR wszNewFolder[25];
+ const WCHAR wszFormat[] = {'%','s',' ','%','d',0 };
+
+ LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, sizeof(wszNewFolder)/sizeof(WCHAR));
- TRACE ("(%p)(%s %u)\n", This, lpName, uLen);
+ TRACE ("(%p)(%p %u)\n", This, pwszName, uLen);
- if (uLen < strlen (szNewFolder) + 4)
+ if (uLen < sizeof(wszNewFolder)/sizeof(WCHAR) + 3)
return E_POINTER;
- strcpy (lpName, szNewFolder);
+ lstrcpynW (pwszName, wszNewFolder, uLen);
hr = IShellFolder_fnEnumObjects (_IShellFolder2_ (This), 0,
SHCONTF_FOLDERS | SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &penum);
IEnumIDList_Reset (penum);
while (S_OK == IEnumIDList_Next (penum, 1, &pidl, &dwFetched) &&
dwFetched) {
- _ILSimpleGetText (pidl, szText, MAX_PATH);
- if (0 == strcasecmp (szText, lpName)) {
- sprintf (lpName, "%s %d", szNewFolder, i++);
+ _ILSimpleGetTextW (pidl, wszText, MAX_PATH);
+ if (0 == lstrcmpiW (wszText, pwszName)) {
+ _snwprintf (pwszName, uLen, wszFormat, wszNewFolder, i++);
if (i > 99) {
hr = E_FAIL;
break;
*/
static HRESULT WINAPI
-ISFHelper_fnAddFolder (ISFHelper * iface, HWND hwnd, LPCSTR lpName,
+ISFHelper_fnAddFolder (ISFHelper * iface, HWND hwnd, LPCWSTR pwszName,
LPITEMIDLIST * ppidlOut)
{
IGenericSFImpl *This = impl_from_ISFHelper(iface);
- char lpstrNewDir[MAX_PATH];
+ WCHAR wszNewDir[MAX_PATH];
DWORD bRes;
HRESULT hres = E_FAIL;
- TRACE ("(%p)(%s %p)\n", This, lpName, ppidlOut);
+ TRACE ("(%p)(%s %p)\n", This, debugstr_w(pwszName), ppidlOut);
- strcpy (lpstrNewDir, This->sPathTarget);
- PathAppendA(lpstrNewDir, lpName);
+ wszNewDir[0] = 0;
+ if (This->sPathTarget)
+ lstrcpynW(wszNewDir, This->sPathTarget, MAX_PATH);
+ PathAppendW(wszNewDir, pwszName);
- bRes = CreateDirectoryA (lpstrNewDir, NULL);
+ bRes = CreateDirectoryW (wszNewDir, NULL);
if (bRes) {
- SHChangeNotify (SHCNE_MKDIR, SHCNF_PATHA, lpstrNewDir, NULL);
+ SHChangeNotify (SHCNE_MKDIR, SHCNF_PATHW, wszNewDir, NULL);
hres = S_OK;
if (ppidlOut)
- hres = _ILCreateFromPathA(lpstrNewDir, ppidlOut);
+ hres = _ILCreateFromPathW(wszNewDir, ppidlOut);
} else {
- char lpstrText[128 + MAX_PATH];
- char lpstrTempText[128];
- char lpstrCaption[256];
+ WCHAR wszText[128 + MAX_PATH];
+ WCHAR wszTempText[128];
+ WCHAR wszCaption[256];
/* Cannot Create folder because of permissions */
- LoadStringA (shell32_hInstance, IDS_CREATEFOLDER_DENIED, lpstrTempText,
- sizeof (lpstrTempText));
- LoadStringA (shell32_hInstance, IDS_CREATEFOLDER_CAPTION, lpstrCaption,
- sizeof (lpstrCaption));
- sprintf (lpstrText, lpstrTempText, lpstrNewDir);
- MessageBoxA (hwnd, lpstrText, lpstrCaption, MB_OK | MB_ICONEXCLAMATION);
+ LoadStringW (shell32_hInstance, IDS_CREATEFOLDER_DENIED, wszTempText,
+ sizeof (wszTempText));
+ LoadStringW (shell32_hInstance, IDS_CREATEFOLDER_CAPTION, wszCaption,
+ sizeof (wszCaption));
+ swprintf (wszText, wszTempText, wszNewDir);
+ MessageBoxW (hwnd, wszText, wszCaption, MB_OK | MB_ICONEXCLAMATION);
}
return hres;
}
-extern BOOL fileMoving;
+/****************************************************************************
+ * build_paths_list
+ *
+ * Builds a list of paths like the one used in SHFileOperation from a table of
+ * PIDLs relative to the given base folder
+ */
+WCHAR *build_paths_list(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls)
+{
+ WCHAR *wszPathsList;
+ WCHAR *wszListPos;
+ int iPathLen;
+ int i;
+
+ iPathLen = wcslen(wszBasePath);
+ wszPathsList = HeapAlloc(GetProcessHeap(), 0, MAX_PATH*sizeof(WCHAR)*cidl+1);
+ wszListPos = wszPathsList;
+
+ for (i = 0; i < cidl; i++) {
+ if (!_ILIsFolder(pidls[i]) && !_ILIsValue(pidls[i]))
+ continue;
+
+ lstrcpynW(wszListPos, wszBasePath, MAX_PATH);
+ /* FIXME: abort if path too long */
+ _ILSimpleGetTextW(pidls[i], wszListPos+iPathLen, MAX_PATH-iPathLen);
+ wszListPos += wcslen(wszListPos)+1;
+ }
+ *wszListPos=0;
+ return wszPathsList;
+}
/****************************************************************************
* ISFHelper_fnDeleteItems
{
IGenericSFImpl *This = impl_from_ISFHelper(iface);
UINT i;
- char szPath[MAX_PATH];
- BOOL bConfirm = TRUE;
+ SHFILEOPSTRUCTW op;
+ WCHAR wszPath[MAX_PATH];
+ WCHAR *wszPathsList;
+ HRESULT ret;
+ WCHAR *wszCurrentPath;
TRACE ("(%p)(%u %p)\n", This, cidl, apidl);
-
- /* deleting multiple items so give a slightly different warning */
- if (cidl != 1) {
- char tmp[8];
+ if (cidl==0) return S_OK;
- snprintf (tmp, sizeof (tmp), "%d", cidl);
- if (!SHELL_ConfirmDialog(ASK_DELETE_MULTIPLE_ITEM, tmp))
- return E_FAIL;
- bConfirm = FALSE;
+ if (This->sPathTarget)
+ lstrcpynW(wszPath, This->sPathTarget, MAX_PATH);
+ else
+ wszPath[0] = '\0';
+ PathAddBackslashW(wszPath);
+ wszPathsList = build_paths_list(wszPath, cidl, apidl);
+
+ ZeroMemory(&op, sizeof(op));
+ op.hwnd = GetActiveWindow();
+ op.wFunc = FO_DELETE;
+ op.pFrom = wszPathsList;
+ op.fFlags = FOF_ALLOWUNDO;
+ if (SHFileOperationW(&op))
+ {
+ WARN("SHFileOperation failed\n");
+ ret = E_FAIL;
}
-
- for (i = 0; i < cidl; i++) {
- strcpy (szPath, This->sPathTarget);
- PathAddBackslashA (szPath);
- _ILSimpleGetText (apidl[i], szPath + strlen (szPath), MAX_PATH);
+ else
+ ret = S_OK;
- if (_ILIsFolder (apidl[i])) {
- LPITEMIDLIST pidl;
+ /* we currently need to manually send the notifies */
+ wszCurrentPath = wszPathsList;
+ for (i = 0; i < cidl; i++)
+ {
+ LONG wEventId;
- TRACE ("delete %s\n", szPath);
- if (!SHELL_DeleteDirectoryA (szPath, bConfirm)) {
- TRACE ("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
- return E_FAIL;
- }
- pidl = ILCombine (This->pidlRoot, apidl[i]);
- SHChangeNotify (SHCNE_RMDIR, SHCNF_IDLIST, pidl, NULL);
- SHFree (pidl);
- } else if (_ILIsValue (apidl[i])) {
- LPITEMIDLIST pidl;
+ if (_ILIsFolder(apidl[i]))
+ wEventId = SHCNE_RMDIR;
+ else if (_ILIsValue(apidl[i]))
+ wEventId = SHCNE_DELETE;
+ else
+ continue;
- TRACE ("delete %s\n", szPath);
- if (!SHELL_DeleteFileA (szPath, bConfirm)) {
- TRACE ("delete %s failed, bConfirm=%d\n", szPath, bConfirm);
- return E_FAIL;
- }
- pidl = ILCombine (This->pidlRoot, apidl[i]);
- SHChangeNotify (SHCNE_DELETE, SHCNF_IDLIST, pidl, NULL);
- SHFree (pidl);
+ /* check if file exists */
+ if (GetFileAttributesW(wszCurrentPath) == INVALID_FILE_ATTRIBUTES)
+ {
+ LPITEMIDLIST pidl = ILCombine(This->pidlRoot, apidl[i]);
+ SHChangeNotify(wEventId, SHCNF_IDLIST, pidl, NULL);
+ SHFree(pidl);
}
+ wszCurrentPath += wcslen(wszCurrentPath)+1;
}
- return S_OK;
+ HeapFree(GetProcessHeap(), 0, wszPathsList);
+ return ret;
}
/****************************************************************************
ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl,
LPCITEMIDLIST * apidl)
{
- UINT i;
IPersistFolder2 *ppf2 = NULL;
- char szSrcPath[MAX_PATH],
- szDstPath[MAX_PATH];
+ WCHAR szSrcPath[MAX_PATH];
+ WCHAR szTargetPath[MAX_PATH];
+ SHFILEOPSTRUCTW op;
+ LPITEMIDLIST pidl;
+ LPWSTR pszSrc, pszTarget, pszSrcList, pszTargetList, pszFileName;
+ int res, length;
+ HRESULT hr;
+ STRRET strRet;
IGenericSFImpl *This = impl_from_ISFHelper(iface);
TRACE ("(%p)->(%p,%u,%p)\n", This, pSFFrom, cidl, apidl);
- IShellFolder_QueryInterface (pSFFrom, &IID_IPersistFolder2,
- (LPVOID *) & ppf2);
- if (ppf2) {
- LPITEMIDLIST pidl;
+ hr = IShellFolder_QueryInterface (pSFFrom, &IID_IPersistFolder2, (LPVOID *) & ppf2);
+ if (SUCCEEDED(hr))
+ {
+ if (FAILED(IPersistFolder2_GetCurFolder (ppf2, &pidl)))
+ {
+ IPersistFolder2_Release(ppf2);
+ return E_FAIL;
+ }
+ IPersistFolder2_Release(ppf2);
+
+ if (FAILED(IShellFolder_GetDisplayNameOf(pSFFrom, pidl, SHGDN_FORPARSING, &strRet)))
+ {
+ SHFree (pidl);
+ return E_FAIL;
+ }
+
+ if (FAILED(StrRetToBufW(&strRet, pidl, szSrcPath, MAX_PATH)))
+ {
+ SHFree (pidl);
+ return E_FAIL;
+ }
+ SHFree (pidl);
+
+ pszSrc = PathAddBackslashW (szSrcPath);
+
+ wcscpy(szTargetPath, This->sPathTarget);
+ pszTarget = PathAddBackslashW (szTargetPath);
+
+ pszSrcList = build_paths_list(szSrcPath, cidl, apidl);
+ pszTargetList = build_paths_list(szTargetPath, cidl, apidl);
- if (SUCCEEDED (IPersistFolder2_GetCurFolder (ppf2, &pidl))) {
- for (i = 0; i < cidl; i++)
+ if (!pszSrcList || !pszTargetList)
+ {
+ if (pszSrcList)
+ HeapFree(GetProcessHeap(), 0, pszSrcList);
+
+ if (pszTargetList)
+ HeapFree(GetProcessHeap(), 0, pszTargetList);
+
+ SHFree (pidl);
+ IPersistFolder2_Release (ppf2);
+ return E_OUTOFMEMORY;
+ }
+ ZeroMemory(&op, sizeof(op));
+ if (!pszSrcList[0])
+ {
+ /* remove trailing backslash */
+ pszSrc--;
+ pszSrc[0] = L'\0';
+ op.pFrom = szSrcPath;
+ }
+ else
+ {
+ op.pFrom = pszSrcList;
+ }
+
+ if (!pszTargetList[0])
+ {
+ /* remove trailing backslash */
+ if (pszTarget - szTargetPath > 3)
{
- SHGetPathFromIDListA (pidl, szSrcPath);
- PathAddBackslashA (szSrcPath);
- _ILSimpleGetText (apidl[i], szSrcPath + strlen (szSrcPath),
- MAX_PATH);
-
- strcpy (szDstPath, This->sPathTarget);
- PathAddBackslashA (szDstPath);
- _ILSimpleGetText (apidl[i], szDstPath + strlen (szDstPath), MAX_PATH);
- DPRINT1 ("copy %s to %s\n", szSrcPath, szDstPath);
-
- if (fileMoving)
- {
- fileMoving = FALSE;
- SHNotifyMoveFileA(szSrcPath, szDstPath);
- }
- else
- {
- SHNotifyCopyFileA(szSrcPath, szDstPath, TRUE);
- }
-
- /*
- SHFILEOPSTRUCTA op;
-
- if (fileMoving)
- {
- op.wFunc = FO_MOVE;
- fileMoving = FALSE;
- }
- else
- {
- op.wFunc = FO_COPY;
- }
-
- op.pTo = szDstPath;
- op.pFrom = szSrcPath;
- op.fFlags = FOF_SIMPLEPROGRESS;
- op.hwnd = NULL;
- op.hNameMappings = NULL;
- op.lpszProgressTitle = NULL;
-
- UINT bRes = SHFileOperationA(&op);
- DbgPrint("CopyItems SHFileOperationA 0x%08x\n", bRes);
- */
-
+ pszTarget--;
+ pszTarget[0] = L'\0';
}
- SHFree (pidl);
+ else
+ {
+ pszTarget[1] = L'\0';
+ }
+
+ op.pTo = szTargetPath;
}
- IPersistFolder2_Release (ppf2);
+ else
+ {
+ op.pTo = pszTargetList;
+ }
+ op.hwnd = GetActiveWindow();
+ op.wFunc = FO_COPY;
+ op.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMMKDIR;
+
+ res = SHFileOperationW(&op);
+
+ if (res == DE_SAMEFILE)
+ {
+ length = wcslen(szTargetPath);
+
+ pszFileName = wcsrchr(pszSrcList, '\\');
+ pszFileName++;
+
+ if (LoadStringW(shell32_hInstance, IDS_COPY_OF, pszTarget, MAX_PATH - length))
+ {
+ wcscat(szTargetPath, L" ");
+ }
+
+ wcscat(szTargetPath, pszFileName);
+ op.pTo = szTargetPath;
+
+ res = SHFileOperationW(&op);
+ }
+
+ HeapFree(GetProcessHeap(), 0, pszSrcList);
+ HeapFree(GetProcessHeap(), 0, pszTargetList);
+
+ if (res)
+ return E_FAIL;
+ else
+ return S_OK;
}
- return S_OK;
+ return E_FAIL;
}
static const ISFHelperVtbl shvt =
{
IGenericSFImpl *This = impl_from_IPersistFolder3(iface);
- TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+ TRACE ("(%p)->(count=%u)\n", This, This->ref);
return IUnknown_AddRef (This->pUnkOuter);
}
{
IGenericSFImpl *This = impl_from_IPersistFolder3(iface);
- TRACE ("(%p)->(count=%lu)\n", This, This->ref);
+ TRACE ("(%p)->(count=%u)\n", This, This->ref);
return IUnknown_Release (This->pUnkOuter);
}
static HRESULT WINAPI
IFSFldr_PersistFolder3_Initialize (IPersistFolder3 * iface, LPCITEMIDLIST pidl)
{
- char sTemp[MAX_PATH];
+ WCHAR wszTemp[MAX_PATH];
IGenericSFImpl *This = impl_from_IPersistFolder3(iface);
TRACE ("(%p)->(%p)\n", This, pidl);
- if (This->pidlRoot)
- SHFree (This->pidlRoot); /* free the old pidl */
+ SHFree (This->pidlRoot); /* free the old pidl */
This->pidlRoot = ILClone (pidl); /* set my pidl */
- if (This->sPathTarget)
- SHFree (This->sPathTarget);
+ SHFree (This->sPathTarget);
+ This->sPathTarget = NULL;
/* set my path */
- if (SHGetPathFromIDListA (pidl, sTemp)) {
- This->sPathTarget = SHAlloc (strlen (sTemp) + 1);
- strcpy (This->sPathTarget, sTemp);
+ if (SHGetPathFromIDListW (pidl, wszTemp)) {
+ int len = wcslen(wszTemp);
+ This->sPathTarget = SHAlloc((len + 1) * sizeof(WCHAR));
+ if (!This->sPathTarget)
+ return E_OUTOFMEMORY;
+ memcpy(This->sPathTarget, wszTemp, (len + 1) * sizeof(WCHAR));
}
- TRACE ("--(%p)->(%s)\n", This, This->sPathTarget);
+ TRACE ("--(%p)->(%s)\n", This, debugstr_w(This->sPathTarget));
return S_OK;
}
IBindCtx * pbc, LPCITEMIDLIST pidlRoot,
const PERSIST_FOLDER_TARGET_INFO * ppfti)
{
- char sTemp[MAX_PATH];
+ WCHAR wszTemp[MAX_PATH];
IGenericSFImpl *This = impl_from_IPersistFolder3(iface);
TRACE ("(%p)->(%p,%p,%p)\n", This, pbc, pidlRoot, ppfti);
if (ppfti)
- TRACE ("--%p %s %s 0x%08lx 0x%08x\n",
+ TRACE ("--%p %s %s 0x%08x 0x%08x\n",
ppfti->pidlTargetFolder, debugstr_w (ppfti->szTargetParsingName),
debugstr_w (ppfti->szNetworkProvider), ppfti->dwAttributes,
ppfti->csidl);
*/
if (ppfti) {
if (ppfti->csidl != -1) {
- if (SHGetSpecialFolderPathA (0, sTemp, ppfti->csidl,
+ if (SHGetSpecialFolderPathW (0, wszTemp, ppfti->csidl,
ppfti->csidl & CSIDL_FLAG_CREATE)) {
- __SHCloneStrA (&This->sPathTarget, sTemp);
+ int len = wcslen(wszTemp);
+ This->sPathTarget = SHAlloc((len + 1) * sizeof(WCHAR));
+ if (!This->sPathTarget)
+ return E_OUTOFMEMORY;
+ memcpy(This->sPathTarget, wszTemp, (len + 1) * sizeof(WCHAR));
}
} else if (ppfti->szTargetParsingName[0]) {
- __SHCloneStrWtoA (&This->sPathTarget, ppfti->szTargetParsingName);
+ int len = wcslen(ppfti->szTargetParsingName);
+ This->sPathTarget = SHAlloc((len + 1) * sizeof(WCHAR));
+ if (!This->sPathTarget)
+ return E_OUTOFMEMORY;
+ memcpy(This->sPathTarget, ppfti->szTargetParsingName,
+ (len + 1) * sizeof(WCHAR));
} else if (ppfti->pidlTargetFolder) {
- if (SHGetPathFromIDListA (ppfti->pidlTargetFolder, sTemp)) {
- __SHCloneStrA (&This->sPathTarget, sTemp);
+ if (SHGetPathFromIDListW(ppfti->pidlTargetFolder, wszTemp)) {
+ int len = wcslen(wszTemp);
+ This->sPathTarget = SHAlloc((len + 1) * sizeof(WCHAR));
+ if (!This->sPathTarget)
+ return E_OUTOFMEMORY;
+ memcpy(This->sPathTarget, wszTemp, (len + 1) * sizeof(WCHAR));
}
}
}
- TRACE ("--(%p)->(target=%s)\n", This, debugstr_a (This->sPathTarget));
+ TRACE ("--(%p)->(target=%s)\n", This, debugstr_w(This->sPathTarget));
pdump (This->pidlRoot);
return (This->sPathTarget) ? S_OK : E_FAIL;
}
ISFDropTarget_Drop (IDropTarget * iface, IDataObject * pDataObject,
DWORD dwKeyState, POINTL pt, DWORD * pdwEffect)
{
- DWORD dwEffect = *pdwEffect;
-
IGenericSFImpl *This = impl_from_IDropTarget(iface);
- FIXME ("(%p) object dropped(%d)\n", This, dwKeyState);
+ FIXME ("(%p) object dropped\n", This);
return E_NOTIMPL;
}