Ricardo Filipe | ecc8e52 | 2009-02-18 08:44:15 +0000 | [diff] [blame] | 1 | /* |
| 2 | * SetupAPI dialog functions |
| 3 | * |
| 4 | * Copyright 2009 Ricardo Filipe |
| 5 | * |
| 6 | * This library is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU Lesser General Public |
| 8 | * License as published by the Free Software Foundation; either |
| 9 | * version 2.1 of the License, or (at your option) any later version. |
| 10 | * |
| 11 | * This library is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | * Lesser General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU Lesser General Public |
| 17 | * License along with this library; if not, write to the Free Software |
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| 19 | */ |
| 20 | |
| 21 | #include <stdarg.h> |
| 22 | |
| 23 | #include "wine/debug.h" |
| 24 | #include "windef.h" |
| 25 | #include "winbase.h" |
| 26 | #include "wingdi.h" |
| 27 | #include "winuser.h" |
| 28 | #include "winreg.h" |
| 29 | #include "commdlg.h" |
| 30 | #include "setupapi.h" |
| 31 | #include "winnls.h" |
| 32 | #include "setupapi_private.h" |
| 33 | |
| 34 | #include "wine/unicode.h" |
| 35 | |
| 36 | WINE_DEFAULT_DEBUG_CHANNEL(setupapi); |
| 37 | |
| 38 | struct promptdisk_params { |
| 39 | PCWSTR DialogTitle; |
| 40 | PCWSTR DiskName; |
| 41 | PCWSTR PathToSource; |
| 42 | PCWSTR FileSought; |
| 43 | PCWSTR TagFile; |
| 44 | DWORD DiskPromptStyle; |
| 45 | PWSTR PathBuffer; |
| 46 | DWORD PathBufferSize; |
| 47 | PDWORD PathRequiredSize; |
| 48 | }; |
| 49 | |
Ricardo Filipe | c4c05cf | 2009-02-18 03:35:26 +0000 | [diff] [blame] | 50 | /* initiates the fields of the SetupPromptForDisk dialog according to the parameters |
| 51 | */ |
| 52 | static void promptdisk_init(HWND hwnd, struct promptdisk_params *params) |
| 53 | { |
| 54 | WCHAR format[256]; |
| 55 | WCHAR message[256]; |
| 56 | |
| 57 | SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)params); |
| 58 | |
| 59 | if(params->DialogTitle) |
| 60 | SetWindowTextW(hwnd, params->DialogTitle); |
| 61 | if(params->PathToSource) |
| 62 | SetDlgItemTextW(hwnd, IDC_PATH, params->PathToSource); |
| 63 | |
| 64 | if(!(params->DiskPromptStyle & IDF_OEMDISK)) |
| 65 | { |
| 66 | LoadStringW(SETUPAPI_hInstance, IDS_PROMPTDISK, format, |
| 67 | sizeof(format)/sizeof(format[0])); |
| 68 | |
| 69 | if(params->DiskName) |
| 70 | snprintfW(message, sizeof(message)/sizeof(message[0]), format, |
| 71 | params->FileSought, params->DiskName); |
| 72 | else |
| 73 | { |
| 74 | WCHAR unknown[256]; |
| 75 | LoadStringW(SETUPAPI_hInstance, IDS_UNKNOWN, unknown, |
| 76 | sizeof(unknown)/sizeof(unknown[0])); |
| 77 | snprintfW(message, sizeof(message)/sizeof(message[0]), format, |
| 78 | params->FileSought, unknown); |
| 79 | } |
| 80 | SetDlgItemTextW(hwnd, IDC_FILENEEDED, message); |
| 81 | |
| 82 | LoadStringW(SETUPAPI_hInstance, IDS_INFO, message, |
| 83 | sizeof(message)/sizeof(message[0])); |
| 84 | SetDlgItemTextW(hwnd, IDC_INFO, message); |
| 85 | LoadStringW(SETUPAPI_hInstance, IDS_COPYFROM, message, |
| 86 | sizeof(message)/sizeof(message[0])); |
| 87 | SetDlgItemTextW(hwnd, IDC_COPYFROM, message); |
| 88 | } |
| 89 | if(params->DiskPromptStyle & IDF_NOBROWSE) |
| 90 | ShowWindow(GetDlgItem(hwnd, IDC_RUNDLG_BROWSE), SW_HIDE); |
| 91 | } |
| 92 | |
Ricardo Filipe | 5a0079f | 2009-02-18 03:46:01 +0000 | [diff] [blame] | 93 | /* When the user clicks in the Ok button in SetupPromptForDisk dialog |
| 94 | * if the parameters are good it copies the path from the dialog to the output buffer |
| 95 | * saves the required size for the buffer if PathRequiredSize is given |
| 96 | * returns NO_ERROR if there is no PathBuffer to copy too |
| 97 | * returns DPROMPT_BUFFERTOOSMALL if the path is too big to fit in PathBuffer |
| 98 | */ |
| 99 | static void promptdisk_ok(HWND hwnd, struct promptdisk_params *params) |
| 100 | { |
| 101 | int requiredSize; |
| 102 | WCHAR aux[MAX_PATH]; |
| 103 | GetWindowTextW(GetDlgItem(hwnd, IDC_PATH), aux, MAX_PATH); |
| 104 | requiredSize = strlenW(aux)+1; |
| 105 | |
| 106 | if(params->PathRequiredSize) |
| 107 | { |
| 108 | *params->PathRequiredSize = requiredSize; |
| 109 | TRACE("returning PathRequiredSize=%d\n",*params->PathRequiredSize); |
| 110 | } |
Ricardo Filipe | 1999008 | 2009-03-23 17:05:59 +0000 | [diff] [blame] | 111 | if(!params->PathBuffer) |
Ricardo Filipe | 5a0079f | 2009-02-18 03:46:01 +0000 | [diff] [blame] | 112 | { |
| 113 | EndDialog(hwnd, NO_ERROR); |
| 114 | return; |
| 115 | } |
Ricardo Filipe | 1999008 | 2009-03-23 17:05:59 +0000 | [diff] [blame] | 116 | if(requiredSize > params->PathBufferSize) |
Ricardo Filipe | 5a0079f | 2009-02-18 03:46:01 +0000 | [diff] [blame] | 117 | { |
| 118 | EndDialog(hwnd, DPROMPT_BUFFERTOOSMALL); |
| 119 | return; |
| 120 | } |
| 121 | strcpyW(params->PathBuffer, aux); |
| 122 | TRACE("returning PathBuffer=%s\n", debugstr_w(params->PathBuffer)); |
| 123 | EndDialog(hwnd, DPROMPT_SUCCESS); |
| 124 | } |
| 125 | |
Ricardo Filipe | d80e24b | 2009-02-18 03:40:15 +0000 | [diff] [blame] | 126 | /* When the user clicks the browse button in SetupPromptForDisk dialog |
| 127 | * it copies the path of the selected file to the dialog path field |
| 128 | */ |
| 129 | static void promptdisk_browse(HWND hwnd, struct promptdisk_params *params) |
| 130 | { |
| 131 | OPENFILENAMEW ofn; |
| 132 | ZeroMemory(&ofn, sizeof(ofn)); |
| 133 | |
| 134 | ofn.lStructSize = sizeof(ofn); |
| 135 | ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; |
| 136 | ofn.hwndOwner = hwnd; |
| 137 | ofn.nMaxFile = MAX_PATH; |
| 138 | ofn.lpstrFile = HeapAlloc(GetProcessHeap(), 0, MAX_PATH*sizeof(WCHAR)); |
| 139 | strcpyW(ofn.lpstrFile, params->FileSought); |
| 140 | |
| 141 | if(GetOpenFileNameW(&ofn)) |
| 142 | { |
| 143 | WCHAR* last_slash = strrchrW(ofn.lpstrFile, '\\'); |
| 144 | if (last_slash) *last_slash = 0; |
| 145 | SetDlgItemTextW(hwnd, IDC_PATH, ofn.lpstrFile); |
| 146 | } |
| 147 | HeapFree(GetProcessHeap(), 0, ofn.lpstrFile); |
| 148 | } |
| 149 | |
Ricardo Filipe | ecc8e52 | 2009-02-18 08:44:15 +0000 | [diff] [blame] | 150 | /* Handles the messages sent to the SetupPromptForDisk dialog |
| 151 | */ |
| 152 | static INT_PTR CALLBACK promptdisk_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) |
| 153 | { |
| 154 | switch(msg) |
| 155 | { |
Ricardo Filipe | c4c05cf | 2009-02-18 03:35:26 +0000 | [diff] [blame] | 156 | case WM_INITDIALOG: |
| 157 | promptdisk_init(hwnd, (struct promptdisk_params *)lParam); |
| 158 | return TRUE; |
Ricardo Filipe | ecc8e52 | 2009-02-18 08:44:15 +0000 | [diff] [blame] | 159 | case WM_COMMAND: |
| 160 | switch(wParam) |
| 161 | { |
Ricardo Filipe | 5a0079f | 2009-02-18 03:46:01 +0000 | [diff] [blame] | 162 | case IDOK: |
| 163 | { |
| 164 | struct promptdisk_params *params = |
| 165 | (struct promptdisk_params *)GetWindowLongPtrW(hwnd, DWLP_USER); |
| 166 | promptdisk_ok(hwnd, params); |
| 167 | return TRUE; |
| 168 | } |
Ricardo Filipe | ecc8e52 | 2009-02-18 08:44:15 +0000 | [diff] [blame] | 169 | case IDCANCEL: |
| 170 | EndDialog(hwnd, DPROMPT_CANCEL); |
| 171 | return TRUE; |
Ricardo Filipe | d80e24b | 2009-02-18 03:40:15 +0000 | [diff] [blame] | 172 | case IDC_RUNDLG_BROWSE: |
| 173 | { |
| 174 | struct promptdisk_params *params = |
| 175 | (struct promptdisk_params *)GetWindowLongPtrW(hwnd, DWLP_USER); |
| 176 | promptdisk_browse(hwnd, params); |
| 177 | return TRUE; |
| 178 | } |
Ricardo Filipe | ecc8e52 | 2009-02-18 08:44:15 +0000 | [diff] [blame] | 179 | } |
| 180 | } |
| 181 | return FALSE; |
| 182 | } |
| 183 | |
| 184 | /*********************************************************************** |
Ricardo Filipe | 24a10fc | 2009-03-02 16:21:28 +0000 | [diff] [blame] | 185 | * SetupPromptForDiskA (SETUPAPI.@) |
| 186 | */ |
| 187 | UINT WINAPI SetupPromptForDiskA(HWND hwndParent, PCSTR DialogTitle, PCSTR DiskName, |
| 188 | PCSTR PathToSource, PCSTR FileSought, PCSTR TagFile, DWORD DiskPromptStyle, |
| 189 | PSTR PathBuffer, DWORD PathBufferSize, PDWORD PathRequiredSize) |
| 190 | { |
| 191 | WCHAR *DialogTitleW, *DiskNameW, *PathToSourceW; |
| 192 | WCHAR *FileSoughtW, *TagFileW, PathBufferW[MAX_PATH]; |
| 193 | UINT ret, length; |
| 194 | |
| 195 | TRACE("%p, %s, %s, %s, %s, %s, 0x%08x, %p, %d, %p\n", hwndParent, debugstr_a(DialogTitle), |
| 196 | debugstr_a(DiskName), debugstr_a(PathToSource), debugstr_a(FileSought), |
| 197 | debugstr_a(TagFile), DiskPromptStyle, PathBuffer, PathBufferSize, |
| 198 | PathRequiredSize); |
| 199 | |
| 200 | DialogTitleW = strdupAtoW(DialogTitle); |
| 201 | DiskNameW = strdupAtoW(DiskName); |
| 202 | PathToSourceW = strdupAtoW(PathToSource); |
| 203 | FileSoughtW = strdupAtoW(FileSought); |
| 204 | TagFileW = strdupAtoW(TagFile); |
| 205 | |
| 206 | ret = SetupPromptForDiskW(hwndParent, DialogTitleW, DiskNameW, PathToSourceW, |
| 207 | FileSoughtW, TagFileW, DiskPromptStyle, PathBufferW, MAX_PATH, PathRequiredSize); |
| 208 | |
| 209 | HeapFree(GetProcessHeap(), 0, DialogTitleW); |
| 210 | HeapFree(GetProcessHeap(), 0, DiskNameW); |
| 211 | HeapFree(GetProcessHeap(), 0, PathToSourceW); |
| 212 | HeapFree(GetProcessHeap(), 0, FileSoughtW); |
| 213 | HeapFree(GetProcessHeap(), 0, TagFileW); |
| 214 | |
| 215 | if(ret == DPROMPT_SUCCESS) |
| 216 | { |
| 217 | length = WideCharToMultiByte(CP_ACP, 0, PathBufferW, -1, NULL, 0, NULL, NULL); |
| 218 | if(PathRequiredSize) *PathRequiredSize = length; |
| 219 | if(PathBuffer) |
| 220 | { |
| 221 | if(length > PathBufferSize) |
| 222 | return DPROMPT_BUFFERTOOSMALL; |
| 223 | WideCharToMultiByte(CP_ACP, 0, PathBufferW, -1, PathBuffer, length, NULL, NULL); |
| 224 | } |
| 225 | } |
| 226 | return ret; |
| 227 | } |
| 228 | |
| 229 | /*********************************************************************** |
Ricardo Filipe | ecc8e52 | 2009-02-18 08:44:15 +0000 | [diff] [blame] | 230 | * SetupPromptForDiskW (SETUPAPI.@) |
| 231 | */ |
| 232 | UINT WINAPI SetupPromptForDiskW(HWND hwndParent, PCWSTR DialogTitle, PCWSTR DiskName, |
| 233 | PCWSTR PathToSource, PCWSTR FileSought, PCWSTR TagFile, DWORD DiskPromptStyle, |
| 234 | PWSTR PathBuffer, DWORD PathBufferSize, PDWORD PathRequiredSize) |
| 235 | { |
| 236 | struct promptdisk_params params; |
| 237 | UINT ret; |
| 238 | |
| 239 | TRACE("%p, %s, %s, %s, %s, %s, 0x%08x, %p, %d, %p\n", hwndParent, debugstr_w(DialogTitle), |
| 240 | debugstr_w(DiskName), debugstr_w(PathToSource), debugstr_w(FileSought), |
| 241 | debugstr_w(TagFile), DiskPromptStyle, PathBuffer, PathBufferSize, |
| 242 | PathRequiredSize); |
| 243 | |
| 244 | if(!FileSought) |
| 245 | { |
| 246 | SetLastError(ERROR_INVALID_PARAMETER); |
| 247 | return DPROMPT_CANCEL; |
| 248 | } |
| 249 | params.DialogTitle = DialogTitle; |
| 250 | params.DiskName = DiskName; |
| 251 | params.PathToSource = PathToSource; |
| 252 | params.FileSought = FileSought; |
| 253 | params.TagFile = TagFile; |
| 254 | params.DiskPromptStyle = DiskPromptStyle; |
| 255 | params.PathBuffer = PathBuffer; |
| 256 | params.PathBufferSize = PathBufferSize; |
| 257 | params.PathRequiredSize = PathRequiredSize; |
| 258 | |
| 259 | ret = DialogBoxParamW(SETUPAPI_hInstance, MAKEINTRESOURCEW(IDPROMPTFORDISK), |
| 260 | hwndParent, promptdisk_proc, (LPARAM)¶ms); |
| 261 | |
| 262 | if(ret == DPROMPT_CANCEL) |
| 263 | SetLastError(ERROR_CANCELLED); |
| 264 | return ret; |
| 265 | } |