| /* | |
| * SetupAPI dialog functions | |
| * | |
| * Copyright 2009 Ricardo Filipe | |
| * | |
| * This library is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU Lesser General Public | |
| * License as published by the Free Software Foundation; either | |
| * version 2.1 of the License, or (at your option) any later version. | |
| * | |
| * This library is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| * Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; if not, write to the Free Software | |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |
| */ | |
| #include <stdarg.h> | |
| #include "wine/debug.h" | |
| #include "windef.h" | |
| #include "winbase.h" | |
| #include "wingdi.h" | |
| #include "winuser.h" | |
| #include "winreg.h" | |
| #include "commdlg.h" | |
| #include "setupapi.h" | |
| #include "winnls.h" | |
| #include "setupapi_private.h" | |
| #include "wine/unicode.h" | |
| WINE_DEFAULT_DEBUG_CHANNEL(setupapi); | |
| struct promptdisk_params { | |
| PCWSTR DialogTitle; | |
| PCWSTR DiskName; | |
| PCWSTR PathToSource; | |
| PCWSTR FileSought; | |
| PCWSTR TagFile; | |
| DWORD DiskPromptStyle; | |
| PWSTR PathBuffer; | |
| DWORD PathBufferSize; | |
| PDWORD PathRequiredSize; | |
| }; | |
| /* initiates the fields of the SetupPromptForDisk dialog according to the parameters | |
| */ | |
| static void promptdisk_init(HWND hwnd, struct promptdisk_params *params) | |
| { | |
| SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)params); | |
| if(params->DialogTitle) | |
| SetWindowTextW(hwnd, params->DialogTitle); | |
| if(params->PathToSource) | |
| SetDlgItemTextW(hwnd, IDC_PATH, params->PathToSource); | |
| if(!(params->DiskPromptStyle & IDF_OEMDISK)) | |
| { | |
| WCHAR message[256+2*MAX_PATH]; | |
| WCHAR format[256]; | |
| WCHAR unknown[256]; | |
| DWORD_PTR args[2]; | |
| LoadStringW(SETUPAPI_hInstance, IDS_PROMPTDISK, format, | |
| sizeof(format)/sizeof(format[0])); | |
| args[0] = (DWORD_PTR)params->FileSought; | |
| if(params->DiskName) | |
| args[1] = (DWORD_PTR)params->DiskName; | |
| else | |
| { | |
| LoadStringW(SETUPAPI_hInstance, IDS_UNKNOWN, unknown, | |
| sizeof(unknown)/sizeof(unknown[0])); | |
| args[1] = (DWORD_PTR)unknown; | |
| } | |
| FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY, | |
| format, 0, 0, message, sizeof(message)/sizeof(*message), | |
| (__ms_va_list*)args); | |
| SetDlgItemTextW(hwnd, IDC_FILENEEDED, message); | |
| LoadStringW(SETUPAPI_hInstance, IDS_INFO, message, | |
| sizeof(message)/sizeof(message[0])); | |
| SetDlgItemTextW(hwnd, IDC_INFO, message); | |
| LoadStringW(SETUPAPI_hInstance, IDS_COPYFROM, message, | |
| sizeof(message)/sizeof(message[0])); | |
| SetDlgItemTextW(hwnd, IDC_COPYFROM, message); | |
| } | |
| if(params->DiskPromptStyle & IDF_NOBROWSE) | |
| ShowWindow(GetDlgItem(hwnd, IDC_RUNDLG_BROWSE), SW_HIDE); | |
| } | |
| /* When the user clicks in the Ok button in SetupPromptForDisk dialog | |
| * if the parameters are good it copies the path from the dialog to the output buffer | |
| * saves the required size for the buffer if PathRequiredSize is given | |
| * returns NO_ERROR if there is no PathBuffer to copy too | |
| * returns DPROMPT_BUFFERTOOSMALL if the path is too big to fit in PathBuffer | |
| */ | |
| static void promptdisk_ok(HWND hwnd, struct promptdisk_params *params) | |
| { | |
| int requiredSize; | |
| WCHAR aux[MAX_PATH]; | |
| GetWindowTextW(GetDlgItem(hwnd, IDC_PATH), aux, MAX_PATH); | |
| requiredSize = strlenW(aux)+1; | |
| if(params->PathRequiredSize) | |
| { | |
| *params->PathRequiredSize = requiredSize; | |
| TRACE("returning PathRequiredSize=%d\n",*params->PathRequiredSize); | |
| } | |
| if(!params->PathBuffer) | |
| { | |
| EndDialog(hwnd, NO_ERROR); | |
| return; | |
| } | |
| if(requiredSize > params->PathBufferSize) | |
| { | |
| EndDialog(hwnd, DPROMPT_BUFFERTOOSMALL); | |
| return; | |
| } | |
| strcpyW(params->PathBuffer, aux); | |
| TRACE("returning PathBuffer=%s\n", debugstr_w(params->PathBuffer)); | |
| EndDialog(hwnd, DPROMPT_SUCCESS); | |
| } | |
| /* When the user clicks the browse button in SetupPromptForDisk dialog | |
| * it copies the path of the selected file to the dialog path field | |
| */ | |
| static void promptdisk_browse(HWND hwnd, struct promptdisk_params *params) | |
| { | |
| OPENFILENAMEW ofn; | |
| ZeroMemory(&ofn, sizeof(ofn)); | |
| ofn.lStructSize = sizeof(ofn); | |
| ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; | |
| ofn.hwndOwner = hwnd; | |
| ofn.nMaxFile = MAX_PATH; | |
| ofn.lpstrFile = HeapAlloc(GetProcessHeap(), 0, MAX_PATH*sizeof(WCHAR)); | |
| strcpyW(ofn.lpstrFile, params->FileSought); | |
| if(GetOpenFileNameW(&ofn)) | |
| { | |
| WCHAR* last_slash = strrchrW(ofn.lpstrFile, '\\'); | |
| if (last_slash) *last_slash = 0; | |
| SetDlgItemTextW(hwnd, IDC_PATH, ofn.lpstrFile); | |
| } | |
| HeapFree(GetProcessHeap(), 0, ofn.lpstrFile); | |
| } | |
| /* Handles the messages sent to the SetupPromptForDisk dialog | |
| */ | |
| static INT_PTR CALLBACK promptdisk_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | |
| { | |
| switch(msg) | |
| { | |
| case WM_INITDIALOG: | |
| promptdisk_init(hwnd, (struct promptdisk_params *)lParam); | |
| return TRUE; | |
| case WM_COMMAND: | |
| switch(wParam) | |
| { | |
| case IDOK: | |
| { | |
| struct promptdisk_params *params = | |
| (struct promptdisk_params *)GetWindowLongPtrW(hwnd, DWLP_USER); | |
| promptdisk_ok(hwnd, params); | |
| return TRUE; | |
| } | |
| case IDCANCEL: | |
| EndDialog(hwnd, DPROMPT_CANCEL); | |
| return TRUE; | |
| case IDC_RUNDLG_BROWSE: | |
| { | |
| struct promptdisk_params *params = | |
| (struct promptdisk_params *)GetWindowLongPtrW(hwnd, DWLP_USER); | |
| promptdisk_browse(hwnd, params); | |
| return TRUE; | |
| } | |
| } | |
| } | |
| return FALSE; | |
| } | |
| /*********************************************************************** | |
| * SetupPromptForDiskA (SETUPAPI.@) | |
| */ | |
| UINT WINAPI SetupPromptForDiskA(HWND hwndParent, PCSTR DialogTitle, PCSTR DiskName, | |
| PCSTR PathToSource, PCSTR FileSought, PCSTR TagFile, DWORD DiskPromptStyle, | |
| PSTR PathBuffer, DWORD PathBufferSize, PDWORD PathRequiredSize) | |
| { | |
| WCHAR *DialogTitleW, *DiskNameW, *PathToSourceW; | |
| WCHAR *FileSoughtW, *TagFileW, PathBufferW[MAX_PATH]; | |
| UINT ret, length; | |
| TRACE("%p, %s, %s, %s, %s, %s, 0x%08x, %p, %d, %p\n", hwndParent, debugstr_a(DialogTitle), | |
| debugstr_a(DiskName), debugstr_a(PathToSource), debugstr_a(FileSought), | |
| debugstr_a(TagFile), DiskPromptStyle, PathBuffer, PathBufferSize, | |
| PathRequiredSize); | |
| DialogTitleW = strdupAtoW(DialogTitle); | |
| DiskNameW = strdupAtoW(DiskName); | |
| PathToSourceW = strdupAtoW(PathToSource); | |
| FileSoughtW = strdupAtoW(FileSought); | |
| TagFileW = strdupAtoW(TagFile); | |
| ret = SetupPromptForDiskW(hwndParent, DialogTitleW, DiskNameW, PathToSourceW, | |
| FileSoughtW, TagFileW, DiskPromptStyle, PathBufferW, MAX_PATH, PathRequiredSize); | |
| HeapFree(GetProcessHeap(), 0, DialogTitleW); | |
| HeapFree(GetProcessHeap(), 0, DiskNameW); | |
| HeapFree(GetProcessHeap(), 0, PathToSourceW); | |
| HeapFree(GetProcessHeap(), 0, FileSoughtW); | |
| HeapFree(GetProcessHeap(), 0, TagFileW); | |
| if(ret == DPROMPT_SUCCESS) | |
| { | |
| length = WideCharToMultiByte(CP_ACP, 0, PathBufferW, -1, NULL, 0, NULL, NULL); | |
| if(PathRequiredSize) *PathRequiredSize = length; | |
| if(PathBuffer) | |
| { | |
| if(length > PathBufferSize) | |
| return DPROMPT_BUFFERTOOSMALL; | |
| WideCharToMultiByte(CP_ACP, 0, PathBufferW, -1, PathBuffer, length, NULL, NULL); | |
| } | |
| } | |
| return ret; | |
| } | |
| /*********************************************************************** | |
| * SetupPromptForDiskW (SETUPAPI.@) | |
| */ | |
| UINT WINAPI SetupPromptForDiskW(HWND hwndParent, PCWSTR DialogTitle, PCWSTR DiskName, | |
| PCWSTR PathToSource, PCWSTR FileSought, PCWSTR TagFile, DWORD DiskPromptStyle, | |
| PWSTR PathBuffer, DWORD PathBufferSize, PDWORD PathRequiredSize) | |
| { | |
| struct promptdisk_params params; | |
| UINT ret; | |
| TRACE("%p, %s, %s, %s, %s, %s, 0x%08x, %p, %d, %p\n", hwndParent, debugstr_w(DialogTitle), | |
| debugstr_w(DiskName), debugstr_w(PathToSource), debugstr_w(FileSought), | |
| debugstr_w(TagFile), DiskPromptStyle, PathBuffer, PathBufferSize, | |
| PathRequiredSize); | |
| if(!FileSought) | |
| { | |
| SetLastError(ERROR_INVALID_PARAMETER); | |
| return DPROMPT_CANCEL; | |
| } | |
| params.DialogTitle = DialogTitle; | |
| params.DiskName = DiskName; | |
| params.PathToSource = PathToSource; | |
| params.FileSought = FileSought; | |
| params.TagFile = TagFile; | |
| params.DiskPromptStyle = DiskPromptStyle; | |
| params.PathBuffer = PathBuffer; | |
| params.PathBufferSize = PathBufferSize; | |
| params.PathRequiredSize = PathRequiredSize; | |
| ret = DialogBoxParamW(SETUPAPI_hInstance, MAKEINTRESOURCEW(IDPROMPTFORDISK), | |
| hwndParent, promptdisk_proc, (LPARAM)¶ms); | |
| if(ret == DPROMPT_CANCEL) | |
| SetLastError(ERROR_CANCELLED); | |
| return ret; | |
| } |