Module: wine Branch: master Commit: 9f61e1e593f69dee98921f172ca1e8880442d73c URL: https://gitlab.winehq.org/wine/wine/-/commit/9f61e1e593f69dee98921f172ca1e88...
Author: Akihiro Sagawa sagawa.aki@gmail.com Date: Sun Oct 30 15:41:08 2022 +0900
shell32: Reimplement DragQueryFileA to rely on its Unicode version.
Now, it returns a correct buffer size especially for a DBCS file name.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53738
---
dlls/shell32/shellole.c | 72 +++++++++++++++++-------------------------- dlls/shell32/tests/shellole.c | 3 -- 2 files changed, 28 insertions(+), 47 deletions(-)
diff --git a/dlls/shell32/shellole.c b/dlls/shell32/shellole.c index 0ee5c95402b..4f9d0db7ff6 100644 --- a/dlls/shell32/shellole.c +++ b/dlls/shell32/shellole.c @@ -560,56 +560,40 @@ BOOL WINAPI DragQueryPoint(HDROP hDrop, POINT *p) * DragQueryFileA [SHELL32.@] * DragQueryFile [SHELL32.@] */ -UINT WINAPI DragQueryFileA( - HDROP hDrop, - UINT lFile, - LPSTR lpszFile, - UINT lLength) +UINT WINAPI DragQueryFileA(HDROP hDrop, UINT lFile, LPSTR lpszFile, UINT lLength) { - LPSTR lpDrop; - UINT i = 0; - DROPFILES *lpDropFileStruct = GlobalLock(hDrop); - - TRACE("(%p, %x, %p, %u)\n", hDrop,lFile,lpszFile,lLength); + LPWSTR filenameW = NULL; + LPSTR filename = NULL; + UINT i;
- if(!lpDropFileStruct) goto end; + TRACE("(%p, %x, %p, %u)\n", hDrop, lFile, lpszFile, lLength);
- lpDrop = (LPSTR) lpDropFileStruct + lpDropFileStruct->pFiles; - - if(lpDropFileStruct->fWide) { - LPWSTR lpszFileW = NULL; - - if(lpszFile && lFile != 0xFFFFFFFF) { - lpszFileW = malloc(lLength * sizeof(WCHAR)); - if(lpszFileW == NULL) { - goto end; - } - } - i = DragQueryFileW(hDrop, lFile, lpszFileW, lLength); + i = DragQueryFileW(hDrop, lFile, NULL, 0); + if (!i || lFile == 0xFFFFFFFF) goto end; + filenameW = malloc((i + 1) * sizeof(WCHAR)); + if (!filenameW) goto error; + if (!DragQueryFileW(hDrop, lFile, filenameW, i + 1)) goto error;
- if(lpszFileW) { - WideCharToMultiByte(CP_ACP, 0, lpszFileW, -1, lpszFile, lLength, 0, NULL); - free(lpszFileW); - } - goto end; - } - - while (i++ < lFile) - { - while (*lpDrop++); /* skip filename */ - if (!*lpDrop) - { - i = (lFile == 0xFFFFFFFF) ? i : 0; - goto end; - } - } + i = WideCharToMultiByte(CP_ACP, 0, filenameW, -1, NULL, 0, NULL, NULL); + if (!lpszFile || !lLength) + { + /* minus a trailing null */ + i--; + goto end; + } + filename = malloc(i); + if (!filename) goto error; + WideCharToMultiByte(CP_ACP, 0, filenameW, -1, filename, i, NULL, NULL);
- i = strlen(lpDrop); - if (!lpszFile ) goto end; /* needed buffer size */ - lstrcpynA (lpszFile, lpDrop, lLength); + i = strlen(filename); + lstrcpynA(lpszFile, filename, lLength); end: - GlobalUnlock(hDrop); - return i; + free(filenameW); + free(filename); + return i; +error: + i = 0; + goto end; }
/************************************************************************* diff --git a/dlls/shell32/tests/shellole.c b/dlls/shell32/tests/shellole.c index 7d1204d1c1f..ca156ebda62 100644 --- a/dlls/shell32/tests/shellole.c +++ b/dlls/shell32/tests/shellole.c @@ -783,16 +783,13 @@ static LRESULT WINAPI drop_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARA
len = strlen(expected_filename); num = DragQueryFileA(hDrop, 0, NULL, 0); - todo_wine_if(expected_filename[0] == 'd' && (flags & DROP_WIDE_FILENAME)) ok(num == len, "expected %u, got %u\n", len, num);
num = DragQueryFileA(hDrop, 0, filename, 0); - todo_wine_if(expected_filename[0] == 'd' && (flags & DROP_WIDE_FILENAME)) ok(num == len, "expected %u, got %u\n", len, num); ok(!strcmp(filename, "dummy"), "got %s\n", filename);
num = DragQueryFileA(hDrop, 0, filename, sizeof(filename)); - todo_wine_if(expected_filename[0] == 'd' && (flags & DROP_WIDE_FILENAME)) ok(num == len, "expected %u, got %u\n", len, num); ok(!strcmp(filename, expected_filename), "expected %s, got %s\n", expected_filename, filename);