From: Haoyang Chen chenhaoyang@kylinos.cn
--- dlls/shell32/shlfileop.c | 82 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-)
diff --git a/dlls/shell32/shlfileop.c b/dlls/shell32/shlfileop.c index 6ecb0da6e8c..d4a4570a0d4 100644 --- a/dlls/shell32/shlfileop.c +++ b/dlls/shell32/shlfileop.c @@ -1895,6 +1895,45 @@ end: return ret; }
+static HRESULT new_item(const WCHAR *folder, const WCHAR *name, DWORD attributes, struct file_operations *ops) +{ + HRESULT ret; + WCHAR path[MAX_PATH]; + HANDLE file; + + if (!(ops->flags & FOF_NOCONFIRMATION) && !PathFileExistsW(folder)) + { + if (!SHELL_ConfirmDialogW(ops->hwnd, ASK_CREATE_FOLDER, PathFindFileNameW(folder), NULL)) + { + ops->fAnyOperationsAborted = TRUE; + return ERROR_CANCELLED; + } + ret = SHNotifyCreateDirectoryW(folder, NULL); + if (S_OK != ret) return ret; + } + + PathCombineW(path, folder, name); + + if (attributes & FILE_ATTRIBUTE_DIRECTORY) + { + ret = SHNotifyCreateDirectoryW(path, NULL); + if (S_OK == ret) + { + if (!SetFileAttributesW(path, attributes)) ret = HRESULT_FROM_WIN32(GetLastError()); + }; + } + else + { + file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attributes, NULL); + + if (file != INVALID_HANDLE_VALUE) + CloseHandle(file); + else + ret = HRESULT_FROM_WIN32(GetLastError()); + } + + return ret; +} static inline struct file_operations *impl_from_IFileOperation(IFileOperation *iface) { return CONTAINING_RECORD(iface, struct file_operations, IFileOperation_iface); @@ -2187,9 +2226,48 @@ end:
static HRESULT WINAPI file_operation_PerformOperations(IFileOperation *iface) { - FIXME("(%p): stub.\n", iface); + struct file_operations *operations = impl_from_IFileOperation(iface); + struct file_operation *ptr, *next; + SHFILEOPSTRUCTW shfoW; + HRESULT ret = E_UNEXPECTED;
- return E_NOTIMPL; + TRACE("\n"); + + shfoW.hwnd = operations->hwnd; + shfoW.fFlags = operations->flags; + + LIST_FOR_EACH_ENTRY_SAFE( ptr, next, &operations->ops, struct file_operation, entry ) + { + TRACE("func: %d\n", ptr->wFunc); + if (ptr->wFunc == FO_NEW) + { + if (ptr->pTemplateName) + FIXME("stub template\n"); + + ret = new_item(ptr->pTo, ptr->pNewName, ptr->attributes, operations); + + if (ptr->pNewName) free((void*)ptr->pNewName); + if (ptr->pTo) free((void*)ptr->pTo); + if (ptr->pTemplateName) free((void*)ptr->pTemplateName); + list_remove(&ptr->entry); + continue; + } + + shfoW.wFunc = ptr->wFunc; + shfoW.pFrom = ptr->pFrom; + shfoW.pTo = ptr->pTo; + + ret = SHFileOperationW(&shfoW); + if (!operations->fAnyOperationsAborted) + operations->fAnyOperationsAborted = shfoW.fAnyOperationsAborted; + + list_remove(&ptr->entry); + if (ptr->pFrom) free((void*)ptr->pFrom); + if (ptr->pTo) free((void*)ptr->pTo); + free(ptr); + } + + return ret; }
static HRESULT WINAPI file_operation_GetAnyOperationsAborted(IFileOperation *iface, BOOL *aborted)