From: Francis De Brabandere <francisdb@gmail.com> Return a new IFolder for the parent directory of This->path, mirroring the IFolder::get_ParentFolder implementation. The struct file path is a plain WCHAR* (not a BSTR), so the string length is taken via lstrlenW. --- dlls/scrrun/filesystem.c | 25 ++++++++++++++++-- dlls/scrrun/tests/filesystem.c | 46 ++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index 184a562ae16..4fcbd23c97d 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -2961,8 +2961,29 @@ static HRESULT WINAPI file_get_Drive(IFile *iface, IDrive **ppdrive) static HRESULT WINAPI file_get_ParentFolder(IFile *iface, IFolder **ppfolder) { struct file *This = impl_from_IFile(iface); - FIXME("(%p)->(%p)\n", This, ppfolder); - return E_NOTIMPL; + WCHAR *parent_path; + DWORD len; + HRESULT hr; + + TRACE("(%p)->(%p)\n", This, ppfolder); + + if(!ppfolder) + return E_POINTER; + + *ppfolder = NULL; + + len = get_parent_folder_name(This->path, lstrlenW(This->path)); + if(!len) + return S_OK; + + if(!(parent_path = malloc((len + 1) * sizeof(WCHAR)))) + return E_OUTOFMEMORY; + memcpy(parent_path, This->path, len * sizeof(WCHAR)); + parent_path[len] = 0; + + hr = create_folder(parent_path, ppfolder); + free(parent_path); + return hr; } static HRESULT WINAPI file_get_Attributes(IFile *iface, FileAttribute *pfa) diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 3911e910b4a..aa3c37fea4f 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -769,6 +769,51 @@ static void test_GetFile(void) RemoveDirectoryW(pathW); } +static void test_File_ParentFolder(void) +{ + WCHAR pathW[MAX_PATH]; + IFile *file; + IFolder *parent; + BSTR path, expected, str; + HRESULT hr; + HANDLE hf; + + get_temp_path(NULL, pathW); + hf = CreateFileW(pathW, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + if(hf == INVALID_HANDLE_VALUE) { + skip("Can't create temporary file\n"); + return; + } + CloseHandle(hf); + + path = SysAllocString(pathW); + hr = IFileSystem3_GetFile(fs3, path, &file); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IFile_get_ParentFolder(file, NULL); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + parent = (void*)0xdeadbeef; + hr = IFile_get_ParentFolder(file, &parent); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(parent != NULL && parent != (void*)0xdeadbeef, "got parent %p\n", parent); + + hr = IFileSystem3_GetParentFolderName(fs3, path, &expected); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IFolder_get_Path(parent, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!lstrcmpiW(str, expected), "got %s, expected %s\n", + wine_dbgstr_w(str), wine_dbgstr_w(expected)); + SysFreeString(str); + SysFreeString(expected); + + IFolder_Release(parent); + IFile_Release(file); + SysFreeString(path); + DeleteFileW(pathW); +} + static inline BOOL create_file(const WCHAR *name) { HANDLE f = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL); @@ -2995,6 +3040,7 @@ START_TEST(filesystem) test_GetBaseName(); test_GetAbsolutePathName(); test_GetFile(); + test_File_ParentFolder(); test_GetTempName(); test_CopyFolder(); test_BuildPath(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10661