From: Nikolay Sivov Subject: [PATCH 2/3] comdlg32: Consolidate file dialog initialization to avoid duplication Message-Id: <20170221123517.6785-2-nsivov@codeweavers.com> Date: Tue, 21 Feb 2017 15:35:16 +0300 In-Reply-To: <20170221123517.6785-1-nsivov@codeweavers.com> References: <20170221123517.6785-1-nsivov@codeweavers.com> Signed-off-by: Nikolay Sivov --- dlls/comdlg32/filedlg.c | 365 ++++++++++++++++++++---------------------------- 1 file changed, 154 insertions(+), 211 deletions(-) diff --git a/dlls/comdlg32/filedlg.c b/dlls/comdlg32/filedlg.c index d76fad925a..4093cf019f 100644 --- a/dlls/comdlg32/filedlg.c +++ b/dlls/comdlg32/filedlg.c @@ -318,236 +318,162 @@ static BOOL GetFileName95(FileOpenDlgInfos *fodInfos) return lRes; } -/*********************************************************************** - * GetFileDialog95A - * - * Call GetFileName95 with this structure and clean the memory. - * - * IN : The OPENFILENAMEA initialisation structure passed to - * GetOpenFileNameA win api function (see filedlg.c) - */ -static BOOL GetFileDialog95A(LPOPENFILENAMEA ofn,UINT iDlgType) +static WCHAR *heap_strdupAtoW(const char *str) { - BOOL ret; - FileOpenDlgInfos fodInfos; - LPSTR lpstrSavDir = NULL; - LPWSTR title = NULL; - LPWSTR defext = NULL; - LPWSTR filter = NULL; - LPWSTR customfilter = NULL; - INITCOMMONCONTROLSEX icc; - - /* Initialize ComboBoxEx32 */ - icc.dwSize = sizeof(icc); - icc.dwICC = ICC_USEREX_CLASSES; - InitCommonControlsEx(&icc); - - /* Initialize CommDlgExtendedError() */ - COMDLG32_SetCommDlgExtendedError(0); - - /* Initialize FileOpenDlgInfos structure */ - ZeroMemory(&fodInfos, sizeof(FileOpenDlgInfos)); - - /* Pass in the original ofn */ - fodInfos.ofnInfos = (LPOPENFILENAMEW)ofn; - - /* save current directory */ - if (ofn->Flags & OFN_NOCHANGEDIR) - { - lpstrSavDir = MemAlloc(MAX_PATH); - GetCurrentDirectoryA(MAX_PATH, lpstrSavDir); - } + WCHAR *ret; + INT len; - fodInfos.unicode = FALSE; + if (!str) + return NULL; - /* convert all the input strings to unicode */ - if(ofn->lpstrInitialDir) - { - DWORD len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrInitialDir, -1, NULL, 0 ); - fodInfos.initdir = MemAlloc((len+1)*sizeof(WCHAR)); - MultiByteToWideChar( CP_ACP, 0, ofn->lpstrInitialDir, -1, fodInfos.initdir, len); - } - else - fodInfos.initdir = NULL; + len = MultiByteToWideChar(CP_ACP, 0, str, -1, 0, 0); + ret = MemAlloc(len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); - if(ofn->lpstrFile) - { - fodInfos.filename = MemAlloc(ofn->nMaxFile*sizeof(WCHAR)); - MultiByteToWideChar( CP_ACP, 0, ofn->lpstrFile, -1, fodInfos.filename, ofn->nMaxFile); - } - else - fodInfos.filename = NULL; + return ret; +} - if(ofn->lpstrDefExt) - { - DWORD len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrDefExt, -1, NULL, 0 ); - defext = MemAlloc((len+1)*sizeof(WCHAR)); - MultiByteToWideChar( CP_ACP, 0, ofn->lpstrDefExt, -1, defext, len); - } - fodInfos.defext = defext; +static void init_filedlg_infoW(OPENFILENAMEW *ofn, FileOpenDlgInfos *info) +{ + INITCOMMONCONTROLSEX icc; - if(ofn->lpstrTitle) - { - DWORD len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrTitle, -1, NULL, 0 ); - title = MemAlloc((len+1)*sizeof(WCHAR)); - MultiByteToWideChar( CP_ACP, 0, ofn->lpstrTitle, -1, title, len); - } - fodInfos.title = title; + /* Initialize ComboBoxEx32 */ + icc.dwSize = sizeof(icc); + icc.dwICC = ICC_USEREX_CLASSES; + InitCommonControlsEx(&icc); - if (ofn->lpstrFilter) - { - LPCSTR s; - int n, len; - - /* filter is a list... title\0ext\0......\0\0 */ - s = ofn->lpstrFilter; - while (*s) s = s+strlen(s)+1; - s++; - n = s - ofn->lpstrFilter; - len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrFilter, n, NULL, 0 ); - filter = MemAlloc(len*sizeof(WCHAR)); - MultiByteToWideChar( CP_ACP, 0, ofn->lpstrFilter, n, filter, len ); - } - fodInfos.filter = filter; + /* Initialize CommDlgExtendedError() */ + COMDLG32_SetCommDlgExtendedError(0); - /* convert lpstrCustomFilter */ - if (ofn->lpstrCustomFilter) - { - LPCSTR s; - int n, len; - - /* customfilter contains a pair of strings... title\0ext\0 */ - s = ofn->lpstrCustomFilter; - if (*s) s = s+strlen(s)+1; - if (*s) s = s+strlen(s)+1; - n = s - ofn->lpstrCustomFilter; - len = MultiByteToWideChar( CP_ACP, 0, ofn->lpstrCustomFilter, n, NULL, 0 ); - customfilter = MemAlloc(len*sizeof(WCHAR)); - MultiByteToWideChar( CP_ACP, 0, ofn->lpstrCustomFilter, n, customfilter, len ); - } - fodInfos.customfilter = customfilter; + memset(info, 0, sizeof(*info)); - /* Initialize the dialog property */ - fodInfos.DlgInfos.dwDlgProp = 0; - fodInfos.DlgInfos.hwndCustomDlg = NULL; + /* Pass in the original ofn */ + info->ofnInfos = ofn; - switch(iDlgType) - { - case OPEN_DIALOG : - ret = GetFileName95(&fodInfos); - break; - case SAVE_DIALOG : - fodInfos.DlgInfos.dwDlgProp |= FODPROP_SAVEDLG; - ret = GetFileName95(&fodInfos); - break; - default : - ret = FALSE; - } + info->title = ofn->lpstrTitle; + info->defext = ofn->lpstrDefExt; + info->filter = ofn->lpstrFilter; + info->customfilter = ofn->lpstrCustomFilter; - if (lpstrSavDir) - { - SetCurrentDirectoryA(lpstrSavDir); - MemFree(lpstrSavDir); - } - - MemFree(title); - MemFree(defext); - MemFree(filter); - MemFree(customfilter); - MemFree(fodInfos.initdir); - MemFree(fodInfos.filename); + if (ofn->lpstrFile) + { + info->filename = MemAlloc(ofn->nMaxFile * sizeof(WCHAR)); + lstrcpynW(info->filename, ofn->lpstrFile, ofn->nMaxFile); + } - TRACE("selected file: %s\n",ofn->lpstrFile); + if (ofn->lpstrInitialDir) + { + DWORD len = ExpandEnvironmentStringsW(ofn->lpstrInitialDir, NULL, 0); + if (len) + { + info->initdir = MemAlloc(len * sizeof(WCHAR)); + ExpandEnvironmentStringsW(ofn->lpstrInitialDir, info->initdir, len); + } + } - return ret; + info->unicode = TRUE; } -/*********************************************************************** - * GetFileDialog95W - * - * Copy the OPENFILENAMEW structure in a FileOpenDlgInfos structure. - * Call GetFileName95 with this structure and clean the memory. - * - */ -static BOOL GetFileDialog95W(LPOPENFILENAMEW ofn,UINT iDlgType) +static void init_filedlg_infoA(OPENFILENAMEA *ofn, FileOpenDlgInfos *info) { - BOOL ret; - FileOpenDlgInfos fodInfos; - LPWSTR lpstrSavDir = NULL; - INITCOMMONCONTROLSEX icc; + OPENFILENAMEW ofnW; - /* Initialize ComboBoxEx32 */ - icc.dwSize = sizeof(icc); - icc.dwICC = ICC_USEREX_CLASSES; - InitCommonControlsEx(&icc); + ofnW = *(OPENFILENAMEW *)ofn; - /* Initialize CommDlgExtendedError() */ - COMDLG32_SetCommDlgExtendedError(0); + ofnW.lpstrInitialDir = heap_strdupAtoW(ofn->lpstrInitialDir); + ofnW.lpstrFile = heap_strdupAtoW(ofn->lpstrFile); + ofnW.lpstrDefExt = heap_strdupAtoW(ofn->lpstrDefExt); + ofnW.lpstrTitle = heap_strdupAtoW(ofn->lpstrTitle); - /* Initialize FileOpenDlgInfos structure */ - ZeroMemory(&fodInfos, sizeof(FileOpenDlgInfos)); + if (ofn->lpstrFilter) + { + int n, len; + LPCSTR s; + + /* filter is a list... title\0ext\0......\0\0 */ + s = ofn->lpstrFilter; + while (*s) s = s+strlen(s)+1; + s++; + n = s - ofn->lpstrFilter; + len = MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFilter, n, NULL, 0); + ofnW.lpstrFilter = MemAlloc(len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, ofn->lpstrFilter, n, (WCHAR *)ofnW.lpstrFilter, len); + } - /* Pass in the original ofn */ - fodInfos.ofnInfos = ofn; + /* convert lpstrCustomFilter */ + if (ofn->lpstrCustomFilter) + { + int n, len; + LPCSTR s; + + /* customfilter contains a pair of strings... title\0ext\0 */ + s = ofn->lpstrCustomFilter; + if (*s) s = s+strlen(s)+1; + if (*s) s = s+strlen(s)+1; + n = s - ofn->lpstrCustomFilter; + len = MultiByteToWideChar(CP_ACP, 0, ofn->lpstrCustomFilter, n, NULL, 0); + ofnW.lpstrCustomFilter = MemAlloc(len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, ofn->lpstrCustomFilter, n, ofnW.lpstrCustomFilter, len); + } - fodInfos.title = ofn->lpstrTitle; - fodInfos.defext = ofn->lpstrDefExt; - fodInfos.filter = ofn->lpstrFilter; - fodInfos.customfilter = ofn->lpstrCustomFilter; + init_filedlg_infoW(&ofnW, info); - /* convert string arguments, save others */ - if(ofn->lpstrFile) - { - fodInfos.filename = MemAlloc(ofn->nMaxFile*sizeof(WCHAR)); - lstrcpynW(fodInfos.filename,ofn->lpstrFile,ofn->nMaxFile); - } - else - fodInfos.filename = NULL; + /* fixup A-specific fields */ + info->ofnInfos = (OPENFILENAMEW *)ofn; + info->unicode = FALSE; - fodInfos.initdir = NULL; - if(ofn->lpstrInitialDir) - { - /* fodInfos.initdir = strdupW(ofn->lpstrInitialDir); */ - DWORD len = ExpandEnvironmentStringsW(ofn->lpstrInitialDir, NULL, 0); - if (len) + /* free what was duplicated */ + MemFree((WCHAR *)ofnW.lpstrInitialDir); + MemFree((WCHAR *)ofnW.lpstrFile); +} + +/*********************************************************************** + * GetFileDialog95 + * + * Call GetFileName95 with this structure and clean the memory. + */ +static BOOL GetFileDialog95(FileOpenDlgInfos *info, UINT dlg_type) +{ + WCHAR *current_dir = NULL; + BOOL ret; + + /* save current directory */ + if (info->ofnInfos->Flags & OFN_NOCHANGEDIR) { - fodInfos.initdir = MemAlloc(len * sizeof(WCHAR)); - ExpandEnvironmentStringsW(ofn->lpstrInitialDir, fodInfos.initdir, len); + current_dir = MemAlloc(MAX_PATH * sizeof(WCHAR)); + GetCurrentDirectoryW(MAX_PATH, current_dir); } - } - - /* save current directory */ - if (ofn->Flags & OFN_NOCHANGEDIR) - { - lpstrSavDir = MemAlloc(MAX_PATH*sizeof(WCHAR)); - GetCurrentDirectoryW(MAX_PATH, lpstrSavDir); - } - fodInfos.unicode = TRUE; + switch (dlg_type) + { + case OPEN_DIALOG: + ret = GetFileName95(info); + break; + case SAVE_DIALOG: + info->DlgInfos.dwDlgProp |= FODPROP_SAVEDLG; + ret = GetFileName95(info); + break; + default: + ret = FALSE; + } - switch(iDlgType) - { - case OPEN_DIALOG : - ret = GetFileName95(&fodInfos); - break; - case SAVE_DIALOG : - fodInfos.DlgInfos.dwDlgProp |= FODPROP_SAVEDLG; - ret = GetFileName95(&fodInfos); - break; - default : - ret = FALSE; - } + if (current_dir) + { + SetCurrentDirectoryW(current_dir); + MemFree(current_dir); + } - if (lpstrSavDir) - { - SetCurrentDirectoryW(lpstrSavDir); - MemFree(lpstrSavDir); - } + if (!info->unicode) + { + MemFree((WCHAR *)info->defext); + MemFree((WCHAR *)info->title); + MemFree((WCHAR *)info->filter); + MemFree((WCHAR *)info->customfilter); + } - /* restore saved IN arguments and convert OUT arguments back */ - MemFree(fodInfos.filename); - MemFree(fodInfos.initdir); - return ret; + MemFree(info->filename); + MemFree(info->initdir); + return ret; } /****************************************************************************** @@ -4080,8 +4006,7 @@ static inline BOOL is_win16_looks(DWORD flags) * FALSE on cancel, error, close or filename-does-not-fit-in-buffer. * */ -BOOL WINAPI GetOpenFileNameA( - LPOPENFILENAMEA ofn) /* [in/out] address of init structure */ +BOOL WINAPI GetOpenFileNameA(OPENFILENAMEA *ofn) { TRACE("flags %08x\n", ofn->Flags); @@ -4098,7 +4023,12 @@ BOOL WINAPI GetOpenFileNameA( if (is_win16_looks(ofn->Flags)) return GetFileName31A(ofn, OPEN_DIALOG); else - return GetFileDialog95A(ofn, OPEN_DIALOG); + { + FileOpenDlgInfos info; + + init_filedlg_infoA(ofn, &info); + return GetFileDialog95(&info, OPEN_DIALOG); + } } /*********************************************************************** @@ -4111,8 +4041,7 @@ BOOL WINAPI GetOpenFileNameA( * FALSE on cancel, error, close or filename-does-not-fit-in-buffer. * */ -BOOL WINAPI GetOpenFileNameW( - LPOPENFILENAMEW ofn) /* [in/out] address of init structure */ +BOOL WINAPI GetOpenFileNameW(OPENFILENAMEW *ofn) { TRACE("flags %08x\n", ofn->Flags); @@ -4129,7 +4058,12 @@ BOOL WINAPI GetOpenFileNameW( if (is_win16_looks(ofn->Flags)) return GetFileName31W(ofn, OPEN_DIALOG); else - return GetFileDialog95W(ofn, OPEN_DIALOG); + { + FileOpenDlgInfos info; + + init_filedlg_infoW(ofn, &info); + return GetFileDialog95(&info, OPEN_DIALOG); + } } @@ -4143,8 +4077,7 @@ BOOL WINAPI GetOpenFileNameW( * FALSE on cancel, error, close or filename-does-not-fit-in-buffer. * */ -BOOL WINAPI GetSaveFileNameA( - LPOPENFILENAMEA ofn) /* [in/out] address of init structure */ +BOOL WINAPI GetSaveFileNameA(OPENFILENAMEA *ofn) { if (!valid_struct_size( ofn->lStructSize )) { @@ -4155,7 +4088,12 @@ BOOL WINAPI GetSaveFileNameA( if (is_win16_looks(ofn->Flags)) return GetFileName31A(ofn, SAVE_DIALOG); else - return GetFileDialog95A(ofn, SAVE_DIALOG); + { + FileOpenDlgInfos info; + + init_filedlg_infoA(ofn, &info); + return GetFileDialog95(&info, SAVE_DIALOG); + } } /*********************************************************************** @@ -4180,7 +4118,12 @@ BOOL WINAPI GetSaveFileNameW( if (is_win16_looks(ofn->Flags)) return GetFileName31W(ofn, SAVE_DIALOG); else - return GetFileDialog95W(ofn, SAVE_DIALOG); + { + FileOpenDlgInfos info; + + init_filedlg_infoW(ofn, &info); + return GetFileDialog95(&info, SAVE_DIALOG); + } } /*********************************************************************** -- 2.11.0