From f99da3f3a1a2ac7e312687d4e0d11e9f52c1acda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauri=20Kentt=C3=A4?= Date: Wed, 6 Jul 2016 13:27:43 +0300 Subject: [PATCH] comdlg32: Avoid generating filenames twice in filedlg. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lauri Kenttä Signed-off-by: Alexandre Julliard --- dlls/comdlg32/filedlg.c | 110 +++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 64 deletions(-) diff --git a/dlls/comdlg32/filedlg.c b/dlls/comdlg32/filedlg.c index b0402c06f53..a04e6462a00 100644 --- a/dlls/comdlg32/filedlg.c +++ b/dlls/comdlg32/filedlg.c @@ -3647,9 +3647,8 @@ void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd) { FileOpenDlgInfos *fodInfos; LPITEMIDLIST pidl; - UINT nFiles = 0, nFileToOpen, nFileSelected, nLength = 0; - WCHAR lpstrTemp[MAX_PATH]; - LPWSTR lpstrAllFile, lpstrCurrFile; + LPWSTR lpstrAllFiles, lpstrTmp; + UINT nFiles = 0, nFileToOpen, nFileSelected, nAllFilesLength = 0, nThisFileLength, nAllFilesMaxLength; TRACE("\n"); fodInfos = GetPropA(hwnd,FileOpenDlgInfosStr); @@ -3657,74 +3656,57 @@ void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd) /* Count how many files we have */ nFileSelected = GetNumSelected( fodInfos->Shell.FOIDataObject ); - /* calculate the string length, count files */ - if (nFileSelected >= 1) + /* Allocate a buffer */ + nAllFilesMaxLength = MAX_PATH + 3; + lpstrAllFiles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nAllFilesMaxLength * sizeof(WCHAR)); + if (!lpstrAllFiles) + goto ret; + + /* Loop through the selection, handle only files (not folders) */ + for (nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++) { - nLength += 3; /* first and last quotes, trailing \0 */ - for ( nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++ ) - { pidl = GetPidlFromDataObject( fodInfos->Shell.FOIDataObject, nFileToOpen+1 ); - if (pidl) - { - /* get the total length of the selected file names */ - lpstrTemp[0] = '\0'; - GetName( fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER|SHGDN_FORPARSING, lpstrTemp ); - - if ( ! IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl) ) /* Ignore folders */ - { - nLength += lstrlenW( lpstrTemp ) + 3; - nFiles++; - } - COMDLG32_SHFree( pidl ); - } - } + { + if (!IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl)) + { + if (nAllFilesLength + MAX_PATH + 3 > nAllFilesMaxLength) + { + nAllFilesMaxLength *= 2; + lpstrTmp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpstrAllFiles, nAllFilesMaxLength * sizeof(WCHAR)); + if (!lpstrTmp) + goto ret; + lpstrAllFiles = lpstrTmp; + } + nFiles += 1; + lpstrAllFiles[nAllFilesLength++] = '"'; + GetName(fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER | SHGDN_FORPARSING, lpstrAllFiles + nAllFilesLength); + nThisFileLength = lstrlenW(lpstrAllFiles + nAllFilesLength); + nAllFilesLength += nThisFileLength; + lpstrAllFiles[nAllFilesLength++] = '"'; + lpstrAllFiles[nAllFilesLength++] = ' '; + } + COMDLG32_SHFree(pidl); + } } - /* allocate the buffer */ - if (nFiles <= 1) nLength = MAX_PATH; - lpstrAllFile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nLength * sizeof(WCHAR)); - - /* Generate the string for the edit control */ - if(nFiles >= 1) + if (nFiles != 0) { - lpstrCurrFile = lpstrAllFile; - for ( nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++ ) - { - pidl = GetPidlFromDataObject( fodInfos->Shell.FOIDataObject, nFileToOpen+1 ); - - if (pidl) - { - /* get the file name */ - lpstrTemp[0] = '\0'; - GetName( fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER|SHGDN_FORPARSING, lpstrTemp ); - - if (! IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl)) /* Ignore folders */ - { - if ( nFiles > 1) - { - *lpstrCurrFile++ = '\"'; - lstrcpyW( lpstrCurrFile, lpstrTemp ); - lpstrCurrFile += lstrlenW( lpstrTemp ); - *lpstrCurrFile++ = '\"'; - *lpstrCurrFile++ = ' '; - *lpstrCurrFile = 0; - } - else - { - lstrcpyW( lpstrAllFile, lpstrTemp ); - } - } - COMDLG32_SHFree( pidl ); - } - } - SetWindowTextW( fodInfos->DlgInfos.hwndFileName, lpstrAllFile ); - - /* Select the file name like Windows does */ - if (filename_is_edit( fodInfos )) - SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1); + /* If there's only one file, use the name as-is without quotes */ + lpstrTmp = lpstrAllFiles; + if (nFiles == 1) + { + lpstrTmp += 1; + lpstrTmp[nThisFileLength] = 0; + } + SetWindowTextW(fodInfos->DlgInfos.hwndFileName, lpstrTmp); + /* Select the file name like Windows does */ + if (filename_is_edit(fodInfos)) + SendMessageW(fodInfos->DlgInfos.hwndFileName, EM_SETSEL, 0, -1); } - HeapFree(GetProcessHeap(),0, lpstrAllFile ); + +ret: + HeapFree(GetProcessHeap(), 0, lpstrAllFiles); }