static HRESULT WINAPI ISF_Desktop_ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPCITEMIDLIST * apidl) { IGenericSFImpl *This = impl_from_ISFHelper(iface); UINT i; SHFILEOPSTRUCTW op; WCHAR wszPath[MAX_PATH]; WCHAR wszCaption[50]; WCHAR *wszPathsList; HRESULT ret; WCHAR *wszCurrentPath; UINT bRestoreWithDeskCpl = FALSE; int res; TRACE ("(%p)(%u %p)\n", This, cidl, apidl); if (cidl==0) return S_OK; for(i = 0; i < cidl; i++) { if (_ILIsMyComputer(apidl[i])) bRestoreWithDeskCpl++; else if (_ILIsNetHood(apidl[i])) bRestoreWithDeskCpl++; else if (_ILIsMyDocuments(apidl[i])) bRestoreWithDeskCpl++; } if (bRestoreWithDeskCpl) { /* FIXME use FormatMessage * use a similar message resource as in windows */ LoadStringW(shell32_hInstance, IDS_DELETEMULTIPLE_TEXT, wszPath, sizeof(wszPath)/sizeof(WCHAR)); wszPath[(sizeof(wszPath)/sizeof(WCHAR))-1] = 0; LoadStringW(shell32_hInstance, IDS_DELETEITEM_CAPTION, wszCaption, sizeof(wszCaption)/sizeof(WCHAR)); wszCaption[(sizeof(wszCaption)/sizeof(WCHAR))-1] = 0; res = SHELL_ConfirmMsgBox(GetActiveWindow(), wszPath, wszCaption, NULL, cidl > 1); if (res == IDD_YESTOALL || res == IDYES) { for(i = 0; i < cidl; i++) { if (_ILIsMyComputer(apidl[i])) SetNamespaceExtensionVisibleStatus(L"{20D04FE0-3AEA-1069-A2D8-08002B30309D}", 0x1); else if (_ILIsNetHood(apidl[i])) SetNamespaceExtensionVisibleStatus(L"{208D2C60-3AEA-1069-A2D7-08002B30309D}", 0x1); else if (_ILIsMyDocuments(apidl[i])) SetNamespaceExtensionVisibleStatus(L"{450D8FBA-AD25-11D0-98A8-0800361B1103}", 0x1); } } } 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; } else ret = S_OK; /* we currently need to manually send the notifies */ wszCurrentPath = wszPathsList; for (i = 0; i < cidl; i++) { LONG wEventId; if (_ILIsFolder(apidl[i])) wEventId = SHCNE_RMDIR; else if (_ILIsValue(apidl[i])) wEventId = SHCNE_DELETE; else continue; /* 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; } HeapFree(GetProcessHeap(), 0, wszPathsList); return ret; }
static HRESULT WINAPI ISF_Desktop_ISFHelper_fnCopyItems (ISFHelper * iface, IShellFolder * pSFFrom, UINT cidl, LPCITEMIDLIST * apidl) { IPersistFolder2 *ppf2 = NULL; WCHAR szSrcPath[MAX_PATH]; WCHAR szTargetPath[MAX_PATH]; SHFILEOPSTRUCTW op; LPITEMIDLIST pidl; LPWSTR pszSrc, pszTarget, pszSrcList, pszTargetList, pszFileName; int res, length; 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) { 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 (!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) { pszTarget--; pszTarget[0] = L'\0'; } else { pszTarget[1] = L'\0'; } op.pTo = szTargetPath; } 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 E_FAIL; }
static int test_add_service(int argc, char ** args, int validation) { GSList *really_removed=NULL, *commit_failed=NULL, *services_used=NULL; struct service_info_s *si; GSList *paths; GError *err; if (argc<1) { g_printerr("Failed to add anything : expecting argument\r\n"); abort(); } err = NULL; if (!meta2_remote_container_open(&(cnx.addr), cnx.timeout.req, &err, cid)) { g_printerr("Failed to open the distant container : %s\r\n", gerror_get_message(err)); g_clear_error(&err); return 0; } paths = build_paths_list(argc,args); si = meta2_remote_service_add_contents(&cnx, cid, service_name, paths, &err); _display_strlist("\tAdd wanted: ", paths); if (si == NULL) { g_printerr("Failed to insert a path : %s\r\n", gerror_get_message(err)); } else { gchar str_addr[128]; addr_info_to_string(&(si->addr), str_addr, sizeof(str_addr)); g_printerr("Service found: %s\r\n", str_addr); } if (validation) { status_t rc0, rc1, rc2; /* COMMIT */ rc0 = meta2_remote_service_commit_contents(&cnx,cid,service_name,paths,&commit_failed,&err); _display_strlist("\tCommit wanted: ", paths); _display_strlist("\tCommit succeeded: ", commit_failed); _gfree_list(&commit_failed); g_printerr("RESULT : %s\r\n", rc0 ? "ok" : gerror_get_message(err)); if (rc0) { GError *e; gboolean rc_local; /* Second-COMMIT */ e = NULL; rc_local = meta2_remote_service_commit_contents(&cnx,cid,service_name,paths,&commit_failed,&e); _display_strlist("\tSecond Commit wanted: ", paths); _display_strlist("\tSecond Commit failed: ", commit_failed); _gfree_list(&commit_failed); g_printerr("Second Commit RESULT : %s\r\n", rc_local ? "ok" : gerror_get_message(e)); } /* DELETE */ rc1 = meta2_remote_service_delete_contents(&cnx, cid, service_name, paths, &really_removed, &services_used, &err); _display_strlist("\tDelete wanted: ", paths); _display_strlist("\tservices used: ", services_used); _display_strlist("\tcontent removed : ", really_removed); _gfree_list(&services_used); _gfree_list(&really_removed); g_printerr("RESULT : %s\r\n", rc1 ? "ok" : gerror_get_message(err)); /* COMMIT */ rc2 = meta2_remote_service_commit_contents(&cnx,cid,service_name,paths,&commit_failed,&err); _display_strlist("\tCommit wanted: ", paths); _display_strlist("\tCommit succeeded: ", commit_failed); _gfree_list(&commit_failed); g_printerr("RESULT : %s\r\n", rc2 ? "ok" : gerror_get_message(err)); if (!rc0 || !rc1 || !rc2) goto error_label; } else { status_t rc0, rc1, rc2; rc0 = rc1 = rc2 = ~0; /* ROLLBACK */ rc0 = meta2_remote_service_rollback_contents(&cnx,cid,service_name,paths,&commit_failed,&err); _display_strlist("\tRollback wanted: ", paths); _display_strlist("\tRollback failed: ", commit_failed); _gfree_list(&commit_failed); g_printerr("RESULT : %s\r\n", rc0 ? "ok" : gerror_get_message(err)); if (rc0) { GError *e; gboolean rc_local; /* Second-COMMIT */ e = NULL; rc_local = meta2_remote_service_rollback_contents(&cnx,cid,service_name,paths,&commit_failed,&e); _display_strlist("\tSecond Rollback wanted: ", paths); _display_strlist("\tSecond Rollback failed: ", commit_failed); _gfree_list(&commit_failed); g_printerr("Second Rollback RESULT : %s\r\n", rc_local ? "ok" : gerror_get_message(e)); } /* DELETE */ rc1 = meta2_remote_service_delete_contents(&cnx, cid, service_name, paths, &really_removed, &services_used, &err); _display_strlist("\tDelete wanted: ", paths); _display_strlist("\tservices used: ", services_used); _display_strlist("\tcontent removed : ", really_removed); g_printerr("RESULT : %s\r\n", rc1 ? "ok" : gerror_get_message(err)); if (services_used || really_removed) { g_printerr("ADD+ROLLBACK content should not be found\n"); rc2 = 0; } if (!rc0 || !rc1 || !rc2) goto error_label; } meta2_remote_container_close_in_fd(cnx.fd, cnx.timeout.req, NULL, cid); return 1; error_label: g_slist_free(paths); meta2_remote_container_close_in_fd(cnx.fd, cnx.timeout.req, NULL, cid); g_clear_error(&err); return 0; }