[PATCH 0/1] MR10675: Draft: scrrun: Implement IFolder and IFile ShortName and ShortPath.
Both get_ShortPath methods wrap GetShortPathNameW on the stored long path; get_ShortName extracts the last component of the resulting short path. Add matching tests comparing against GetShortPathNameW directly. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10675
From: Francis De Brabandere <francisdb@gmail.com> Both get_ShortPath methods wrap GetShortPathNameW on the stored long path; get_ShortName extracts the last component of the resulting short path. Add matching tests comparing against GetShortPathNameW directly. --- dlls/scrrun/filesystem.c | 84 ++++++++++++++++++++++++++--- dlls/scrrun/tests/filesystem.c | 97 ++++++++++++++++++++++++++++++++++ 2 files changed, 173 insertions(+), 8 deletions(-) diff --git a/dlls/scrrun/filesystem.c b/dlls/scrrun/filesystem.c index af76f0cf4d8..17fe1bf2557 100644 --- a/dlls/scrrun/filesystem.c +++ b/dlls/scrrun/filesystem.c @@ -2543,15 +2543,49 @@ static HRESULT WINAPI folder_put_Name(IFolder *iface, BSTR name) static HRESULT WINAPI folder_get_ShortPath(IFolder *iface, BSTR *path) { struct folder *This = impl_from_IFolder(iface); - FIXME("(%p)->(%p): stub\n", This, path); - return E_NOTIMPL; + WCHAR short_path[MAX_PATH]; + DWORD len; + + TRACE("(%p)->(%p)\n", This, path); + + if (!path) + return E_POINTER; + + *path = NULL; + + len = GetShortPathNameW(This->path, short_path, MAX_PATH); + if (!len) + return HRESULT_FROM_WIN32(GetLastError()); + if (len >= MAX_PATH) + return E_FAIL; + + *path = SysAllocString(short_path); + return *path ? S_OK : E_OUTOFMEMORY; } static HRESULT WINAPI folder_get_ShortName(IFolder *iface, BSTR *name) { struct folder *This = impl_from_IFolder(iface); - FIXME("(%p)->(%p): stub\n", This, name); - return E_NOTIMPL; + WCHAR short_path[MAX_PATH]; + const WCHAR *ptr; + DWORD len; + + TRACE("(%p)->(%p)\n", This, name); + + if (!name) + return E_POINTER; + + *name = NULL; + + len = GetShortPathNameW(This->path, short_path, MAX_PATH); + if (!len) + return HRESULT_FROM_WIN32(GetLastError()); + if (len >= MAX_PATH) + return E_FAIL; + + ptr = wcsrchr(short_path, '\\'); + *name = SysAllocString(ptr ? ptr + 1 : short_path); + return *name ? S_OK : E_OUTOFMEMORY; } static HRESULT WINAPI folder_get_Drive(IFolder *iface, IDrive **drive) @@ -2981,15 +3015,49 @@ static HRESULT WINAPI file_put_Name(IFile *iface, BSTR pbstrName) static HRESULT WINAPI file_get_ShortPath(IFile *iface, BSTR *pbstrPath) { struct file *This = impl_from_IFile(iface); - FIXME("(%p)->(%p)\n", This, pbstrPath); - return E_NOTIMPL; + WCHAR short_path[MAX_PATH]; + DWORD len; + + TRACE("(%p)->(%p)\n", This, pbstrPath); + + if (!pbstrPath) + return E_POINTER; + + *pbstrPath = NULL; + + len = GetShortPathNameW(This->path, short_path, MAX_PATH); + if (!len) + return HRESULT_FROM_WIN32(GetLastError()); + if (len >= MAX_PATH) + return E_FAIL; + + *pbstrPath = SysAllocString(short_path); + return *pbstrPath ? S_OK : E_OUTOFMEMORY; } static HRESULT WINAPI file_get_ShortName(IFile *iface, BSTR *pbstrName) { struct file *This = impl_from_IFile(iface); - FIXME("(%p)->(%p)\n", This, pbstrName); - return E_NOTIMPL; + WCHAR short_path[MAX_PATH]; + const WCHAR *ptr; + DWORD len; + + TRACE("(%p)->(%p)\n", This, pbstrName); + + if (!pbstrName) + return E_POINTER; + + *pbstrName = NULL; + + len = GetShortPathNameW(This->path, short_path, MAX_PATH); + if (!len) + return HRESULT_FROM_WIN32(GetLastError()); + if (len >= MAX_PATH) + return E_FAIL; + + ptr = wcsrchr(short_path, '\\'); + *pbstrName = SysAllocString(ptr ? ptr + 1 : short_path); + return *pbstrName ? S_OK : E_OUTOFMEMORY; } static HRESULT WINAPI file_get_Drive(IFile *iface, IDrive **ppdrive) diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c index 9b5abdf5c97..5bdb6898034 100644 --- a/dlls/scrrun/tests/filesystem.c +++ b/dlls/scrrun/tests/filesystem.c @@ -822,6 +822,101 @@ static void test_File_ParentFolder(void) DeleteFileW(pathW); } +static void test_File_ShortName(void) +{ + WCHAR long_path[MAX_PATH], expected_path[MAX_PATH], *ptr; + IFile *file; + BSTR path, str; + DWORD len; + HRESULT hr; + HANDLE hf; + + get_temp_path(NULL, long_path); + hf = CreateFileW(long_path, 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); + + len = GetShortPathNameW(long_path, expected_path, MAX_PATH); + ok(len && len < MAX_PATH, "GetShortPathNameW failed, len %lu\n", len); + + path = SysAllocString(long_path); + hr = IFileSystem3_GetFile(fs3, path, &file); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(path); + + hr = IFile_get_ShortPath(file, NULL); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + hr = IFile_get_ShortPath(file, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!lstrcmpiW(str, expected_path), "got %s, expected %s\n", + wine_dbgstr_w(str), wine_dbgstr_w(expected_path)); + SysFreeString(str); + + hr = IFile_get_ShortName(file, NULL); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + hr = IFile_get_ShortName(file, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ptr = wcsrchr(expected_path, '\\'); + ok(ptr != NULL, "short path has no backslash: %s\n", wine_dbgstr_w(expected_path)); + ok(!lstrcmpiW(str, ptr + 1), "got %s, expected %s\n", + wine_dbgstr_w(str), wine_dbgstr_w(ptr + 1)); + SysFreeString(str); + + IFile_Release(file); + DeleteFileW(long_path); +} + +static void test_Folder_ShortName(void) +{ + static const WCHAR dir_name[] = L"scrrun_shortname_test_longname"; + WCHAR temp_path[MAX_PATH], dir_path[MAX_PATH], expected_path[MAX_PATH], *ptr; + IFolder *folder; + BSTR path, str; + DWORD len; + HRESULT hr; + + GetTempPathW(MAX_PATH, temp_path); + lstrcpyW(dir_path, temp_path); + lstrcatW(dir_path, dir_name); + ok(CreateDirectoryW(dir_path, NULL), "CreateDirectory failed, error %ld\n", GetLastError()); + + len = GetShortPathNameW(dir_path, expected_path, MAX_PATH); + ok(len && len < MAX_PATH, "GetShortPathNameW failed, len %lu\n", len); + + path = SysAllocString(dir_path); + hr = IFileSystem3_GetFolder(fs3, path, &folder); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(path); + + hr = IFolder_get_ShortPath(folder, NULL); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + hr = IFolder_get_ShortPath(folder, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!lstrcmpiW(str, expected_path), "got %s, expected %s\n", + wine_dbgstr_w(str), wine_dbgstr_w(expected_path)); + SysFreeString(str); + + hr = IFolder_get_ShortName(folder, NULL); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + hr = IFolder_get_ShortName(folder, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ptr = wcsrchr(expected_path, '\\'); + ok(ptr != NULL, "short path has no backslash: %s\n", wine_dbgstr_w(expected_path)); + ok(!lstrcmpiW(str, ptr + 1), "got %s, expected %s\n", + wine_dbgstr_w(str), wine_dbgstr_w(ptr + 1)); + SysFreeString(str); + + IFolder_Release(folder); + RemoveDirectoryW(dir_path); +} + static inline BOOL create_file(const WCHAR *name) { HANDLE f = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL); @@ -3159,6 +3254,7 @@ START_TEST(filesystem) test_GetAbsolutePathName(); test_GetFile(); test_File_ParentFolder(); + test_File_ShortName(); test_GetTempName(); test_CopyFolder(); test_BuildPath(); @@ -3166,6 +3262,7 @@ START_TEST(filesystem) test_Folder_Attributes(); test_Folder_Dates(); test_Folder_ParentFolder(); + test_Folder_ShortName(); test_FolderCollection(); test_FileCollection(); test_DriveCollection(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10675
Nikolay Sivov (@nsivov) commented about dlls/scrrun/tests/filesystem.c:
+ len = GetShortPathNameW(long_path, expected_path, MAX_PATH); + ok(len && len < MAX_PATH, "GetShortPathNameW failed, len %lu\n", len); + + path = SysAllocString(long_path); + hr = IFileSystem3_GetFile(fs3, path, &file); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SysFreeString(path); + + hr = IFile_get_ShortPath(file, NULL); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + + hr = IFile_get_ShortPath(file, &str); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!lstrcmpiW(str, expected_path), "got %s, expected %s\n", + wine_dbgstr_w(str), wine_dbgstr_w(expected_path)); + SysFreeString(str); Do you need this case-insensitive?
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10675#note_136668
participants (3)
-
Francis De Brabandere -
Francis De Brabandere (@francisdb) -
Nikolay Sivov (@nsivov)