Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52128
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net
-- v3: scrrun: Support wildcards in MoveFolder(). scrrun: Move source dir into destination dir if destination ends with separator in MoveFolder().
From: Robert Wilhelm robert.wilhelm@gmx.net
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52128
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 7 +++---- dlls/scrrun/tests/filesystem.c | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 35b43e2f124..dac3b9fdcf7 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3764,12 +3764,11 @@ static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR source, BSTR de return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); }
-static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface,BSTR Source, - BSTR Destination) +static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR destination) { - FIXME("%p %s %s\n", iface, debugstr_w(Source), debugstr_w(Destination)); + TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination));
- return E_NOTIMPL; + return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); }
static inline HRESULT copy_file(const WCHAR *source, DWORD source_len, diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 1ba0e81a2d1..4d7692a5d1e 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2600,6 +2600,25 @@ static void test_MoveFile(void) SysFreeString(str); }
+static void test_MoveFolder(void) +{ + BSTR src, dst; + WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH]; + HRESULT hr; + + get_temp_path(L"foo", buffW1); + get_temp_path(L"bar", buffW2); + + ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); + src = SysAllocString(buffW1); + dst = SysAllocString(buffW2); + hr = IFileSystem3_MoveFolder(fs3, src, dst); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW1)); +} + static void test_DoOpenPipeStream(void) { static const char testdata[] = "test"; @@ -2733,6 +2752,7 @@ START_TEST(filesystem) test_GetExtensionName(); test_GetSpecialFolder(); test_MoveFile(); + test_MoveFolder(); test_DoOpenPipeStream();
IFileSystem3_Release(fs3);
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 3 +++ dlls/scrrun/tests/filesystem.c | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index dac3b9fdcf7..815ec934ac1 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3768,6 +3768,9 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR { TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination));
+ if(!source || !destination) + return E_INVALIDARG; + return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); }
diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 4d7692a5d1e..31c0ddd1b95 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2602,7 +2602,7 @@ static void test_MoveFile(void)
static void test_MoveFolder(void) { - BSTR src, dst; + BSTR src, dst, str; WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH]; HRESULT hr;
@@ -2617,6 +2617,13 @@ static void test_MoveFolder(void) SysFreeString(src); SysFreeString(dst); ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW1)); + + str = SysAllocString(L"null.txt"); + hr = IFileSystem3_MoveFolder(fs3, str, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + hr = IFileSystem3_MoveFolder(fs3, NULL, str); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + SysFreeString(str); }
static void test_DoOpenPipeStream(void)
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/tests/filesystem.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 31c0ddd1b95..5c911172d1a 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2624,6 +2624,17 @@ static void test_MoveFolder(void) hr = IFileSystem3_MoveFolder(fs3, NULL, str); ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); SysFreeString(str); + + ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); + ok(CreateDirectoryW(buffW2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); + src = SysAllocString(buffW1); + dst = SysAllocString(buffW2); + hr = IFileSystem3_MoveFolder(fs3, src, dst); /* dst already exists */ + ok(hr == CTL_E_FILEALREADYEXISTS, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + ok(RemoveDirectoryW(buffW1), "can't remove %s directory\n", wine_dbgstr_w(buffW1)); + ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); }
static void test_DoOpenPipeStream(void)
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 6 ++++++ dlls/scrrun/tests/filesystem.c | 7 +++++++ 2 files changed, 13 insertions(+)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 815ec934ac1..816d8993530 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3766,11 +3766,17 @@ static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR source, BSTR de
static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR destination) { + DWORD attrs; + TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination));
if(!source || !destination) return E_INVALIDARG;
+ attrs = GetFileAttributesW(source); + if(attrs == INVALID_FILE_ATTRIBUTES) + return CTL_E_PATHNOTFOUND; + return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); }
diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 5c911172d1a..f2bfe52c2ad 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2635,6 +2635,13 @@ static void test_MoveFolder(void) SysFreeString(dst); ok(RemoveDirectoryW(buffW1), "can't remove %s directory\n", wine_dbgstr_w(buffW1)); ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); + + src = SysAllocString(buffW1); + dst = SysAllocString(buffW2); + hr = IFileSystem3_MoveFolder(fs3, src, dst); /* src nonexistant */ + ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); }
static void test_DoOpenPipeStream(void)
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 2 +- dlls/scrrun/tests/filesystem.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 816d8993530..6ffebc0af12 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3774,7 +3774,7 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR return E_INVALIDARG;
attrs = GetFileAttributesW(source); - if(attrs == INVALID_FILE_ATTRIBUTES) + if((attrs == INVALID_FILE_ATTRIBUTES) || !(attrs & FILE_ATTRIBUTE_DIRECTORY)) return CTL_E_PATHNOTFOUND;
return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index f2bfe52c2ad..4d144937840 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2605,6 +2605,7 @@ static void test_MoveFolder(void) BSTR src, dst, str; WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH]; HRESULT hr; + File *file;
get_temp_path(L"foo", buffW1); get_temp_path(L"bar", buffW2); @@ -2642,6 +2643,19 @@ static void test_MoveFolder(void) ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr); SysFreeString(src); SysFreeString(dst); + + file = CreateFileW(buffW1, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFile failed\n"); + CloseHandle(file); + + src = SysAllocString(buffW1); + dst = SysAllocString(buffW2); + hr = IFileSystem3_MoveFolder(fs3, src, dst); /* src is regular file */ + ok(hr == CTL_E_PATHNOTFOUND, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + DeleteFileW(buffW1); }
static void test_DoOpenPipeStream(void)
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 42 ++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 6ffebc0af12..197fe9f3625 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3301,10 +3301,37 @@ static HRESULT WINAPI filesys_GetParentFolderName(IFileSystem3 *iface, BSTR Path return S_OK; }
+static HRESULT get_file_name(const WCHAR *path, int *start, int *end) +{ + int s,e; + + if(!path) + return 0; + + for(e=lstrlenW(path)-1; e>=0; e--) + if(path[e]!='/' && path[e]!='\') + break; + + for(s=e; s>=0; s--) + if(path[s]=='/' || path[s]=='\') + break; + + s++; + + if(s>e || (s==0 && e==1 && path[1]==':')) { + return E_FAIL; + } + + *start = s; + *end = e; + + return S_OK; +} + static HRESULT WINAPI filesys_GetFileName(IFileSystem3 *iface, BSTR Path, BSTR *pbstrResult) { - int i, end; + int start=0, end=0;
TRACE("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
@@ -3316,21 +3343,12 @@ static HRESULT WINAPI filesys_GetFileName(IFileSystem3 *iface, BSTR Path, return S_OK; }
- for(end=lstrlenW(Path)-1; end>=0; end--) - if(Path[end]!='/' && Path[end]!='\') - break; - - for(i=end; i>=0; i--) - if(Path[i]=='/' || Path[i]=='\') - break; - i++; - - if(i>end || (i==0 && end==1 && Path[1]==':')) { + if (FAILED(get_file_name( Path, &start, &end))) { *pbstrResult = NULL; return S_OK; }
- *pbstrResult = SysAllocStringLen(Path+i, end-i+1); + *pbstrResult = SysAllocStringLen(Path+start, end-start+1); if(!*pbstrResult) return E_OUTOFMEMORY; return S_OK;
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 14 ++++++++++++++ dlls/scrrun/tests/filesystem.c | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 197fe9f3625..908ac53683b 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3785,16 +3785,30 @@ static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR source, BSTR de static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR destination) { DWORD attrs; + int len,start,end; + WCHAR dst_path[MAX_PATH];
TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination));
if(!source || !destination) return E_INVALIDARG;
+ if (FAILED(get_file_name( source, &start, &end))) + return E_INVALIDARG; + attrs = GetFileAttributesW(source); if((attrs == INVALID_FILE_ATTRIBUTES) || !(attrs & FILE_ATTRIBUTE_DIRECTORY)) return CTL_E_PATHNOTFOUND;
+ len = lstrlenW(destination); + + if (destination[len-1] == '\') + { + memcpy(dst_path, destination, (len+1)*sizeof(WCHAR)); + memcpy(dst_path+len, source + start, (end-start+1)*sizeof(WCHAR)); + dst_path[len+end-start+1] = 0; + return MoveFileW(source, dst_path) ? S_OK : create_error(GetLastError()); + } return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); }
diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 4d144937840..da092f27d3b 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2536,6 +2536,7 @@ static void test_MoveFile(void) { ITextStream *stream; BSTR str, src, dst; + WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH],pathW[MAX_PATH]; HRESULT hr;
str = SysAllocString(L"test.txt"); @@ -2598,6 +2599,24 @@ static void test_MoveFile(void) hr = IFileSystem3_MoveFile(fs3, NULL, str); ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); SysFreeString(str); + + GetTempPathW(MAX_PATH, buffW1); + lstrcatW(buffW1,L"foo"); + GetTempPathW(MAX_PATH, buffW2); + lstrcatW(buffW2,L"bar"); + ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); + ok(CreateDirectoryW(buffW2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW2)); + lstrcpyW(pathW,buffW2); + lstrcatW(pathW,L"\"); + src = SysAllocString(buffW1); + dst = SysAllocString(pathW); + hr = IFileSystem3_MoveFolder(fs3, src, dst); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + lstrcatW(pathW,L"foo"); + ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); + ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); }
static void test_MoveFolder(void)
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 62 ++++++++++++++++++++++++++++------ dlls/scrrun/tests/filesystem.c | 32 +++++++++++++++++- 2 files changed, 82 insertions(+), 12 deletions(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 908ac53683b..fc5ffe752c6 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3785,8 +3785,11 @@ static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR source, BSTR de static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR destination) { DWORD attrs; - int len,start,end; - WCHAR dst_path[MAX_PATH]; + int i,len,len2,slen,start,end; + WCHAR src_path[MAX_PATH],dst_path[MAX_PATH]; + WIN32_FIND_DATAW ffd; + HANDLE f; + BOOL wildcard = FALSE;
TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination));
@@ -3796,20 +3799,57 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR if (FAILED(get_file_name( source, &start, &end))) return E_INVALIDARG;
- attrs = GetFileAttributesW(source); - if((attrs == INVALID_FILE_ATTRIBUTES) || !(attrs & FILE_ATTRIBUTE_DIRECTORY)) - return CTL_E_PATHNOTFOUND; + for(i = start; i <= end; i++) + { + if( source[i]=='*' || source[i]=='?') + { + wildcard = TRUE; + break; + } + } + + if (!wildcard) { + attrs = GetFileAttributesW(source); + if((attrs == INVALID_FILE_ATTRIBUTES) || !(attrs & FILE_ATTRIBUTE_DIRECTORY)) + return CTL_E_PATHNOTFOUND; + }
+ slen = lstrlenW(source); len = lstrlenW(destination);
- if (destination[len-1] == '\') + if (wildcard || destination[len-1] == '\') + { + f = FindFirstFileW(source, &ffd); + if(f == INVALID_HANDLE_VALUE) + return create_error(GetLastError()); + + do { + memcpy(dst_path, destination, (len+1)*sizeof(WCHAR)); + memcpy(src_path, source, (slen+1)*sizeof(WCHAR)); + if (wildcard) { + len2 = len; + if (destination[len-1] != '\') + { + dst_path[len] = '\'; + len2++; + } + memcpy(dst_path+len2, ffd.cFileName, (lstrlenW(ffd.cFileName)+1)*sizeof(WCHAR)); + memcpy(src_path+start,ffd.cFileName,(lstrlenW(ffd.cFileName)+1)*sizeof(WCHAR)); + } + else { + memcpy(dst_path+len, source + start, (end-start+1)*sizeof(WCHAR)); + dst_path[len+end-start+1]=0; + } + if (!MoveFileW(src_path, dst_path)) + return create_error(GetLastError()); + } while(FindNextFileW(f, &ffd)); + FindClose(f); + } + else { - memcpy(dst_path, destination, (len+1)*sizeof(WCHAR)); - memcpy(dst_path+len, source + start, (end-start+1)*sizeof(WCHAR)); - dst_path[len+end-start+1] = 0; - return MoveFileW(source, dst_path) ? S_OK : create_error(GetLastError()); + return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); } - return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); + return S_OK; }
static inline HRESULT copy_file(const WCHAR *source, DWORD source_len, diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index da092f27d3b..df02cd1186b 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2536,7 +2536,7 @@ static void test_MoveFile(void) { ITextStream *stream; BSTR str, src, dst; - WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH],pathW[MAX_PATH]; + WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH],pathW[MAX_PATH],srcW[MAX_PATH]; HRESULT hr;
str = SysAllocString(L"test.txt"); @@ -2617,6 +2617,36 @@ static void test_MoveFile(void) lstrcatW(pathW,L"foo"); ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); + + GetTempPathW(MAX_PATH, buffW1); + lstrcatW(buffW1,L"foo1"); + GetTempPathW(MAX_PATH, buffW2); + lstrcatW(buffW2,L"foo2"); + GetTempPathW(MAX_PATH, srcW); + lstrcatW(srcW,L"foo?"); + GetTempPathW(MAX_PATH, pathW); + lstrcatW(pathW,L"bar"); + RemoveDirectoryW(buffW1); + RemoveDirectoryW(buffW2); + RemoveDirectoryW(pathW); + ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); + ok(CreateDirectoryW(buffW2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW2)); + ok(CreateDirectoryW(pathW, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(pathW)); + src = SysAllocString(srcW); + dst = SysAllocString(pathW); + hr = IFileSystem3_MoveFolder(fs3, src, dst); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + lstrcpyW(buffW1,pathW); + lstrcatW(buffW1,L"\"); + lstrcatW(buffW1,L"foo1"); + lstrcpyW(buffW2,pathW); + lstrcatW(buffW2,L"\"); + lstrcatW(buffW2,L"foo2"); + ok(RemoveDirectoryW(buffW1), "can't remove %s directory\n", wine_dbgstr_w(buffW1)); + ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); + ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); }
static void test_MoveFolder(void)
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/filesystem.c | 113 +++++++++------------------------ dlls/scrrun/tests/filesystem.c | 69 ++++++-------------- 2 files changed, 48 insertions(+), 134 deletions(-)
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index fc5ffe752c6..70c54a5ecb3 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -3301,37 +3301,10 @@ static HRESULT WINAPI filesys_GetParentFolderName(IFileSystem3 *iface, BSTR Path return S_OK; }
-static HRESULT get_file_name(const WCHAR *path, int *start, int *end) -{ - int s,e; - - if(!path) - return 0; - - for(e=lstrlenW(path)-1; e>=0; e--) - if(path[e]!='/' && path[e]!='\') - break; - - for(s=e; s>=0; s--) - if(path[s]=='/' || path[s]=='\') - break; - - s++; - - if(s>e || (s==0 && e==1 && path[1]==':')) { - return E_FAIL; - } - - *start = s; - *end = e; - - return S_OK; -} - static HRESULT WINAPI filesys_GetFileName(IFileSystem3 *iface, BSTR Path, BSTR *pbstrResult) { - int start=0, end=0; + int i, end;
TRACE("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
@@ -3343,12 +3316,21 @@ static HRESULT WINAPI filesys_GetFileName(IFileSystem3 *iface, BSTR Path, return S_OK; }
- if (FAILED(get_file_name( Path, &start, &end))) { + for(end=lstrlenW(Path)-1; end>=0; end--) + if(Path[end]!='/' && Path[end]!='\') + break; + + for(i=end; i>=0; i--) + if(Path[i]=='/' || Path[i]=='\') + break; + i++; + + if(i>end || (i==0 && end==1 && Path[1]==':')) { *pbstrResult = NULL; return S_OK; }
- *pbstrResult = SysAllocStringLen(Path+start, end-start+1); + *pbstrResult = SysAllocStringLen(Path+i, end-i+1); if(!*pbstrResult) return E_OUTOFMEMORY; return S_OK; @@ -3785,71 +3767,34 @@ static HRESULT WINAPI filesys_MoveFile(IFileSystem3 *iface, BSTR source, BSTR de static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR destination) { DWORD attrs; - int i,len,len2,slen,start,end; - WCHAR src_path[MAX_PATH],dst_path[MAX_PATH]; - WIN32_FIND_DATAW ffd; - HANDLE f; - BOOL wildcard = FALSE; + int len; + WCHAR src_drive[MAX_PATH],src_dir[MAX_PATH],dst_path[MAX_PATH], + file_name[MAX_PATH],file_ext[MAX_PATH];
TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination));
if(!source || !destination) return E_INVALIDARG;
- if (FAILED(get_file_name( source, &start, &end))) - return E_INVALIDARG; - - for(i = start; i <= end; i++) - { - if( source[i]=='*' || source[i]=='?') - { - wildcard = TRUE; - break; - } - } + _wsplitpath(source, src_drive, src_dir, file_name, file_ext);
- if (!wildcard) { - attrs = GetFileAttributesW(source); - if((attrs == INVALID_FILE_ATTRIBUTES) || !(attrs & FILE_ATTRIBUTE_DIRECTORY)) - return CTL_E_PATHNOTFOUND; - } + attrs = GetFileAttributesW(source); + if((attrs == INVALID_FILE_ATTRIBUTES) || !(attrs & FILE_ATTRIBUTE_DIRECTORY)) + return CTL_E_PATHNOTFOUND;
- slen = lstrlenW(source); len = lstrlenW(destination);
- if (wildcard || destination[len-1] == '\') - { - f = FindFirstFileW(source, &ffd); - if(f == INVALID_HANDLE_VALUE) - return create_error(GetLastError()); - - do { - memcpy(dst_path, destination, (len+1)*sizeof(WCHAR)); - memcpy(src_path, source, (slen+1)*sizeof(WCHAR)); - if (wildcard) { - len2 = len; - if (destination[len-1] != '\') - { - dst_path[len] = '\'; - len2++; - } - memcpy(dst_path+len2, ffd.cFileName, (lstrlenW(ffd.cFileName)+1)*sizeof(WCHAR)); - memcpy(src_path+start,ffd.cFileName,(lstrlenW(ffd.cFileName)+1)*sizeof(WCHAR)); - } - else { - memcpy(dst_path+len, source + start, (end-start+1)*sizeof(WCHAR)); - dst_path[len+end-start+1]=0; - } - if (!MoveFileW(src_path, dst_path)) - return create_error(GetLastError()); - } while(FindNextFileW(f, &ffd)); - FindClose(f); - } - else - { - return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); + if (destination[len-1] == '\') { + lstrcpyW(dst_path, destination); + lstrcatW(dst_path, file_name); + if (*file_ext) { + lstrcatW(dst_path, L"."); + lstrcatW(dst_path, file_ext); + } + TRACE(" %s %s\n", debugstr_w(source), debugstr_w(dst_path)); + return MoveFileW(source, dst_path) ? S_OK : create_error(GetLastError()); } - return S_OK; + return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); }
static inline HRESULT copy_file(const WCHAR *source, DWORD source_len, diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index df02cd1186b..be7f090daec 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2536,7 +2536,6 @@ static void test_MoveFile(void) { ITextStream *stream; BSTR str, src, dst; - WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH],pathW[MAX_PATH],srcW[MAX_PATH]; HRESULT hr;
str = SysAllocString(L"test.txt"); @@ -2599,60 +2598,12 @@ static void test_MoveFile(void) hr = IFileSystem3_MoveFile(fs3, NULL, str); ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); SysFreeString(str); - - GetTempPathW(MAX_PATH, buffW1); - lstrcatW(buffW1,L"foo"); - GetTempPathW(MAX_PATH, buffW2); - lstrcatW(buffW2,L"bar"); - ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); - ok(CreateDirectoryW(buffW2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW2)); - lstrcpyW(pathW,buffW2); - lstrcatW(pathW,L"\"); - src = SysAllocString(buffW1); - dst = SysAllocString(pathW); - hr = IFileSystem3_MoveFolder(fs3, src, dst); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - SysFreeString(src); - SysFreeString(dst); - lstrcatW(pathW,L"foo"); - ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); - ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); - - GetTempPathW(MAX_PATH, buffW1); - lstrcatW(buffW1,L"foo1"); - GetTempPathW(MAX_PATH, buffW2); - lstrcatW(buffW2,L"foo2"); - GetTempPathW(MAX_PATH, srcW); - lstrcatW(srcW,L"foo?"); - GetTempPathW(MAX_PATH, pathW); - lstrcatW(pathW,L"bar"); - RemoveDirectoryW(buffW1); - RemoveDirectoryW(buffW2); - RemoveDirectoryW(pathW); - ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); - ok(CreateDirectoryW(buffW2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW2)); - ok(CreateDirectoryW(pathW, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(pathW)); - src = SysAllocString(srcW); - dst = SysAllocString(pathW); - hr = IFileSystem3_MoveFolder(fs3, src, dst); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - SysFreeString(src); - SysFreeString(dst); - lstrcpyW(buffW1,pathW); - lstrcatW(buffW1,L"\"); - lstrcatW(buffW1,L"foo1"); - lstrcpyW(buffW2,pathW); - lstrcatW(buffW2,L"\"); - lstrcatW(buffW2,L"foo2"); - ok(RemoveDirectoryW(buffW1), "can't remove %s directory\n", wine_dbgstr_w(buffW1)); - ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); - ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); }
static void test_MoveFolder(void) { BSTR src, dst, str; - WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH]; + WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH],pathW[MAX_PATH]; HRESULT hr; File *file;
@@ -2705,6 +2656,24 @@ static void test_MoveFolder(void) SysFreeString(src); SysFreeString(dst); DeleteFileW(buffW1); + + GetTempPathW(MAX_PATH, buffW1); + lstrcatW(buffW1,L"foo"); + GetTempPathW(MAX_PATH, buffW2); + lstrcatW(buffW2,L"bar"); + ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); + ok(CreateDirectoryW(buffW2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW2)); + lstrcpyW(pathW,buffW2); + lstrcatW(pathW,L"\"); + src = SysAllocString(buffW1); + dst = SysAllocString(pathW); + hr = IFileSystem3_MoveFolder(fs3, src, dst); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + lstrcatW(pathW,L"foo"); + ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); + ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); }
static void test_DoOpenPipeStream(void)
From: Robert Wilhelm robert.wilhelm@gmx.net
Signed-off-by: Robert Wilhelm robert.wilhelm@gmx.net --- dlls/scrrun/Makefile.in | 2 +- dlls/scrrun/filesystem.c | 47 ++++++++++++++++++++++++---------- dlls/scrrun/tests/filesystem.c | 33 +++++++++++++++++++++++- 3 files changed, 66 insertions(+), 16 deletions(-)
diff --git a/dlls/scrrun/Makefile.in b/dlls/scrrun/Makefile.in index 12be899162b..21798694587 100644 --- a/dlls/scrrun/Makefile.in +++ b/dlls/scrrun/Makefile.in @@ -1,6 +1,6 @@ MODULE = scrrun.dll IMPORTLIB = scrrun -IMPORTS = uuid oleaut32 version advapi32 +IMPORTS = uuid oleaut32 version advapi32 shlwapi
EXTRADLLFLAGS = -Wb,--prefer-native
diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 70c54a5ecb3..b2a7d10e883 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -29,6 +29,7 @@ #include "olectl.h" #include "dispex.h" #include "ntsecapi.h" +#include "shlwapi.h" #include "scrrun.h" #include "scrrun_private.h"
@@ -3768,8 +3769,11 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR { DWORD attrs; int len; - WCHAR src_drive[MAX_PATH],src_dir[MAX_PATH],dst_path[MAX_PATH], + WCHAR src_path[MAX_PATH],src_drive[MAX_PATH],src_dir[MAX_PATH],dst_path[MAX_PATH], file_name[MAX_PATH],file_ext[MAX_PATH]; + WIN32_FIND_DATAW ffd; + HANDLE f; + BOOL wildcard = FALSE;
TRACE("%p %s %s\n", iface, debugstr_w(source), debugstr_w(destination));
@@ -3777,24 +3781,39 @@ static HRESULT WINAPI filesys_MoveFolder(IFileSystem3 *iface, BSTR source, BSTR return E_INVALIDARG;
_wsplitpath(source, src_drive, src_dir, file_name, file_ext); + if (wcschr(file_name,'*') || wcschr(file_name,'?') ||wcschr(file_ext,'*') || wcschr(file_ext,'?')) + wildcard = TRUE;
- attrs = GetFileAttributesW(source); - if((attrs == INVALID_FILE_ATTRIBUTES) || !(attrs & FILE_ATTRIBUTE_DIRECTORY)) - return CTL_E_PATHNOTFOUND; + if (!wildcard) { + attrs = GetFileAttributesW(source); + if((attrs == INVALID_FILE_ATTRIBUTES) || !(attrs & FILE_ATTRIBUTE_DIRECTORY)) + return CTL_E_PATHNOTFOUND; + }
len = lstrlenW(destination);
- if (destination[len-1] == '\') { - lstrcpyW(dst_path, destination); - lstrcatW(dst_path, file_name); - if (*file_ext) { - lstrcatW(dst_path, L"."); - lstrcatW(dst_path, file_ext); - } - TRACE(" %s %s\n", debugstr_w(source), debugstr_w(dst_path)); - return MoveFileW(source, dst_path) ? S_OK : create_error(GetLastError()); + if (wildcard || destination[len-1] == '\') + { + f = FindFirstFileW(source, &ffd); + if(f == INVALID_HANDLE_VALUE) + return create_error(GetLastError()); + + do { + lstrcpyW(dst_path, destination); + lstrcpyW(src_path, src_drive); + lstrcatW(src_path, src_dir); + if (!PathAppendW(src_path, ffd.cFileName)) return create_error(GetLastError()); + if (!PathAppendW(dst_path, ffd.cFileName)) return create_error(GetLastError()); + if (!MoveFileW(src_path, dst_path)) + return create_error(GetLastError()); + } while(FindNextFileW(f, &ffd)); + FindClose(f); } - return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); + else + { + return MoveFileW(source, destination) ? S_OK : create_error(GetLastError()); + } + return S_OK; }
static inline HRESULT copy_file(const WCHAR *source, DWORD source_len, diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index be7f090daec..5a2ad229b49 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -2603,7 +2603,7 @@ static void test_MoveFile(void) static void test_MoveFolder(void) { BSTR src, dst, str; - WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH],pathW[MAX_PATH]; + WCHAR buffW1[MAX_PATH],buffW2[MAX_PATH],pathW[MAX_PATH],srcW[MAX_PATH]; HRESULT hr; File *file;
@@ -2674,6 +2674,37 @@ static void test_MoveFolder(void) lstrcatW(pathW,L"foo"); ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); + + GetTempPathW(MAX_PATH, buffW1); + lstrcatW(buffW1,L"foo1"); + GetTempPathW(MAX_PATH, buffW2); + lstrcatW(buffW2,L"foo2"); + GetTempPathW(MAX_PATH, srcW); + lstrcatW(srcW,L"foo?"); + GetTempPathW(MAX_PATH, pathW); + lstrcatW(pathW,L"bar"); + RemoveDirectoryW(buffW1); + RemoveDirectoryW(buffW2); + RemoveDirectoryW(pathW); + ok(CreateDirectoryW(buffW1, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW1)); + ok(CreateDirectoryW(buffW2, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(buffW2)); + ok(CreateDirectoryW(pathW, NULL), "CreateDirectory(%s) failed\n", wine_dbgstr_w(pathW)); + src = SysAllocString(srcW); + dst = SysAllocString(pathW); + hr = IFileSystem3_MoveFolder(fs3, src, dst); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(src); + SysFreeString(dst); + lstrcpyW(buffW1,pathW); + lstrcatW(buffW1,L"\"); + lstrcatW(buffW1,L"foo1"); + lstrcpyW(buffW2,pathW); + lstrcatW(buffW2,L"\"); + lstrcatW(buffW2,L"foo2"); + ok(RemoveDirectoryW(buffW1), "can't remove %s directory\n", wine_dbgstr_w(buffW1)); + ok(RemoveDirectoryW(buffW2), "can't remove %s directory\n", wine_dbgstr_w(buffW2)); + ok(RemoveDirectoryW(pathW), "can't remove %s directory\n", wine_dbgstr_w(pathW)); + }
static void test_DoOpenPipeStream(void)
Again, have you checked existing API to move/rename files, either from shell or from kernel32?
On Tue Jul 5 17:28:21 2022 +0000, Nikolay Sivov wrote:
Again, have you checked existing API to move/rename files, either from shell or from kernel32?
I checked existing API, but did no find function which fits my needs. Do you have anything in mind? Preexisting code in scrrun (e.g. MoveFile, CopyFile) does not use such API either. objFSO.MoveFolder has basically three different modes: 1) rename: MoveFolder("foo","bar") "bar" must not exist. 2) move: MoveFolder("foo","bar") "bar" must exist. 3) wildcard: MoveFolder("f*.*,"bar") or MoveFolder("f*.*,"bar")
On Tue Jul 5 17:28:21 2022 +0000, Robert Wilhelm wrote:
I checked existing API, but did no find function which fits my needs. Do you have anything in mind? Preexisting code in scrrun (e.g. MoveFile, CopyFile) does not use such API either. objFSO.MoveFolder has basically three different modes:
- rename: MoveFolder("foo","bar") "bar" must not exist.
- move: MoveFolder("foo","bar") "bar" must exist.
- wildcard: MoveFolder("f*.*,"bar") or MoveFolder("f*.*,"bar")
I goofed up V3 merge request. Old patches are still included and crufty code is then deleted in last two patches. I will try to get this fixed.
This merge request was closed by Robert Wilhelm.