1 /* 2 vfdguisave.c 3 4 Virtual Floppy Drive for Windows 5 Driver control library 6 Save image GUI utility function 7 8 Copyright (c) 2003-2005 Ken Kato 9 */ 10 11 #ifdef __cplusplus 12 #pragma message(__FILE__": Compiled as C++ for testing purpose.") 13 #endif // __cplusplus 14 15 #define WIN32_LEAN_AND_MEAN 16 #include <windows.h> 17 #ifdef _MSC_VER 18 #pragma warning(push,3) 19 #endif 20 #include <commdlg.h> 21 #ifdef _MSC_VER 22 #pragma warning(pop) 23 #endif 24 25 #include "vfdtypes.h" 26 #include "vfdapi.h" 27 #include "vfdlib.h" 28 #ifndef __REACTOS__ 29 #include "vfdmsg.h" 30 #else 31 #include "vfdmsg_lib.h" 32 #endif 33 #include "vfdguirc.h" 34 35 // 36 // local functions 37 // 38 #ifndef __REACTOS__ 39 static INT CALLBACK SaveDialogProc( 40 #else 41 static INT_PTR CALLBACK SaveDialogProc( 42 #endif 43 HWND hDlg, 44 UINT uMsg, 45 WPARAM wParam, 46 LPARAM lParam); 47 48 static void OnInit(HWND hDlg, PCSAVE_PARAM pParam); 49 static void OnTarget(HWND hDlg, HWND hEdit); 50 static void OnBrowse(HWND hDlg); 51 static void OnOverwrite(HWND hDlg, HWND hCheck); 52 static void OnTruncate(HWND hDlg, HWND hCheck); 53 static DWORD OnOK(HWND hDlg); 54 55 // 56 // Show Save Image dialog box 57 // 58 DWORD WINAPI VfdGuiSave( 59 HWND hParent, 60 ULONG nDevice) 61 { 62 SAVE_PARAM param; 63 CHAR path[MAX_PATH]; 64 DWORD ret; 65 66 // open the source device 67 68 param.hDevice = VfdOpenDevice(nDevice); 69 70 if (param.hDevice == INVALID_HANDLE_VALUE) { 71 return GetLastError(); 72 } 73 74 // get current image information 75 76 param.ImageName = path; 77 78 ret = VfdGetImageInfo( 79 param.hDevice, 80 param.ImageName, 81 ¶m.DiskType, 82 ¶m.MediaType, 83 ¶m.MediaFlags, 84 ¶m.FileType, 85 ¶m.ImageSize); 86 87 if (ret == ERROR_SUCCESS) { 88 89 // show dialog box 90 91 ret = GuiSaveParam(hParent, ¶m); 92 } 93 94 // close the source device 95 96 CloseHandle(param.hDevice); 97 98 return ret; 99 } 100 101 DWORD GuiSaveParam( 102 HWND hParent, 103 PCSAVE_PARAM pParam) 104 { 105 switch (DialogBoxParam( 106 g_hDllModule, 107 MAKEINTRESOURCE(IDD_SAVEDIALOG), 108 hParent, 109 SaveDialogProc, 110 (LPARAM)pParam)) 111 { 112 case IDOK: 113 return ERROR_SUCCESS; 114 115 case IDCANCEL: 116 return ERROR_CANCELLED; 117 118 default: 119 return GetLastError(); 120 } 121 } 122 123 // 124 // The dialog procedure 125 // 126 #ifndef __REACTOS__ 127 INT CALLBACK SaveDialogProc( 128 #else 129 INT_PTR CALLBACK SaveDialogProc( 130 #endif 131 HWND hDlg, 132 UINT uMsg, 133 WPARAM wParam, 134 LPARAM lParam) 135 { 136 switch (uMsg) { 137 case WM_INITDIALOG: 138 OnInit(hDlg, (PCSAVE_PARAM)lParam); 139 return TRUE; 140 141 case WM_COMMAND: 142 switch (wParam) { 143 case MAKELONG(IDC_TARGETFILE, EN_CHANGE): 144 OnTarget(hDlg, (HWND)lParam); 145 return TRUE; 146 147 case IDC_BROWSE: 148 OnBrowse(hDlg); 149 return TRUE; 150 151 case IDC_OVERWRITE: 152 OnOverwrite(hDlg, (HWND)lParam); 153 return TRUE; 154 155 case IDC_TRUNCATE: 156 OnTruncate(hDlg, (HWND)lParam); 157 return TRUE; 158 159 case IDOK: 160 if (OnOK(hDlg) == ERROR_SUCCESS) { 161 EndDialog(hDlg, IDOK); 162 } 163 return TRUE; 164 165 case IDCANCEL: 166 EndDialog(hDlg, IDCANCEL); 167 return TRUE; 168 } 169 break; 170 171 case WM_CONTEXTMENU: 172 ShowContextMenu(hDlg, (HWND)wParam, lParam); 173 break; 174 175 case WM_HELP: 176 { 177 LPHELPINFO info = (LPHELPINFO)lParam; 178 179 if (info->iContextType == HELPINFO_WINDOW) { 180 ShowHelpWindow(hDlg, info->iCtrlId); 181 } 182 } 183 return TRUE; 184 } 185 186 return FALSE; 187 } 188 189 // 190 // Initialize the dialog 191 // 192 void OnInit( 193 HWND hDlg, 194 PCSAVE_PARAM pParam) 195 { 196 // Store parameters 197 198 SetWindowLongPtr(hDlg, GWLP_USERDATA, (ULONG_PTR)pParam); 199 200 // clear the target existence flag 201 202 SetWindowLong(hDlg, DWL_USER, 0); 203 204 // Set dialog window title 205 206 SetControlText(hDlg, 0, MSG_SAVE_TITLE); 207 208 // Set control captions 209 210 SetControlText(hDlg, IDC_IMAGEFILE_LABEL, MSG_IMAGEFILE_LABEL); 211 SetControlText(hDlg, IDC_DISKTYPE_LABEL, MSG_DISKTYPE_LABEL); 212 SetControlText(hDlg, IDC_MEDIATYPE_LABEL, MSG_MEDIATYPE_LABEL); 213 SetControlText(hDlg, IDC_TARGETFILE_LABEL, MSG_TARGETFILE_LABEL); 214 SetControlText(hDlg, IDC_IMAGEDESC_LABEL, MSG_DESCRIPTION_LABEL); 215 SetControlText(hDlg, IDC_BROWSE, MSG_BROWSE_BUTTON); 216 SetControlText(hDlg, IDC_OVERWRITE, MSG_OVERWRITE_CHECK); 217 SetControlText(hDlg, IDC_TRUNCATE, MSG_TRUNCATE_CHECK); 218 SetControlText(hDlg, IDOK, MSG_SAVE_BUTTON); 219 SetControlText(hDlg, IDCANCEL, MSG_CANCEL_BUTTON); 220 221 // set disk type 222 223 if (pParam->DiskType == VFD_DISKTYPE_FILE) { 224 SetDlgItemText(hDlg, IDC_DISKTYPE, "FILE"); 225 } 226 else { 227 SetDlgItemText(hDlg, IDC_DISKTYPE, "RAM"); 228 } 229 230 // display media type 231 232 SetDlgItemText(hDlg, IDC_MEDIATYPE, 233 VfdMediaTypeName(pParam->MediaType)); 234 235 // set current image and initial target 236 237 if (pParam->ImageName[0]) { 238 SetDlgItemText(hDlg, IDC_IMAGEFILE, pParam->ImageName); 239 SetDlgItemText(hDlg, IDC_TARGETFILE, pParam->ImageName); 240 } 241 else if (pParam->DiskType != VFD_DISKTYPE_FILE) { 242 SetDlgItemText(hDlg, IDC_IMAGEFILE, "<RAM>"); 243 OnTarget(hDlg, GetDlgItem(hDlg, IDC_TARGETFILE)); 244 } 245 } 246 247 // 248 // Path is changed -- check specified target file 249 // 250 void OnTarget( 251 HWND hDlg, 252 HWND hEdit) 253 { 254 PCSAVE_PARAM param; 255 CHAR buf[MAX_PATH]; 256 ULONG file_size; 257 VFD_FILETYPE file_type; 258 DWORD file_attr; 259 DWORD ret; 260 261 // clear the target existence flag 262 263 SetWindowLong(hDlg, DWL_USER, 0); 264 265 // clear the description and hint text 266 267 SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, NULL); 268 SetDlgItemText(hDlg, IDC_IMAGEFILE_HINT, NULL); 269 270 // get the target file name 271 272 if (GetWindowText(hEdit, buf, sizeof(buf)) == 0) { 273 274 // target file is blank 275 276 EnableWindow(GetDlgItem(hDlg, IDC_OVERWRITE), FALSE); 277 EnableWindow(GetDlgItem(hDlg, IDC_TRUNCATE), FALSE); 278 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); 279 280 return; 281 } 282 else { 283 CHAR full[MAX_PATH]; 284 PSTR file; 285 286 // convert into a full path 287 288 if (GetFullPathName(buf, sizeof(full), full, &file)) { 289 strcpy(buf, full); 290 } 291 } 292 293 // 294 // get the current image info 295 // 296 param = (PCSAVE_PARAM)GetWindowLongPtr(hDlg, GWLP_USERDATA); 297 298 if (_stricmp(param->ImageName, buf) == 0) { 299 300 // target is the current file 301 302 char desc[MAX_PATH]; 303 304 VfdMakeFileDesc(desc, sizeof(desc), 305 param->FileType, param->ImageSize, 306 GetFileAttributes(param->ImageName)); 307 308 SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, desc); 309 SetControlText(hDlg, IDC_IMAGEFILE_HINT, MSG_CURRENT_FILE); 310 311 if (param->DiskType == VFD_DISKTYPE_FILE) { 312 313 // cannot overwrite the current FILE disk image 314 315 EnableWindow(GetDlgItem(hDlg, IDC_OVERWRITE), FALSE); 316 EnableWindow(GetDlgItem(hDlg, IDC_TRUNCATE), FALSE); 317 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); 318 return; 319 } 320 } 321 322 // 323 // check target image file 324 // 325 ret = VfdCheckImageFile( 326 buf, &file_attr, &file_type, &file_size); 327 328 if (ret == ERROR_FILE_NOT_FOUND) { 329 // file does not exist 330 SetControlText(hDlg, IDC_IMAGEFILE_DESC, MSG_DESC_NEW_FILE); 331 EnableWindow(GetDlgItem(hDlg, IDC_OVERWRITE), FALSE); 332 EnableWindow(GetDlgItem(hDlg, IDC_TRUNCATE), FALSE); 333 EnableWindow(GetDlgItem(hDlg, IDOK), TRUE); 334 return; 335 } 336 else if (ret != ERROR_SUCCESS) { 337 SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, SystemMessage(ret)); 338 EnableWindow(GetDlgItem(hDlg, IDC_OVERWRITE), FALSE); 339 EnableWindow(GetDlgItem(hDlg, IDC_TRUNCATE), FALSE); 340 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); 341 return; 342 } 343 344 // set target file description 345 346 VfdMakeFileDesc(buf, sizeof(buf), 347 file_type, file_size, file_attr); 348 349 SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, buf); 350 351 // check target file type 352 353 if (file_type == VFD_FILETYPE_ZIP) { 354 SetControlText(hDlg, IDC_IMAGEFILE_HINT, MSG_TARGET_IS_ZIP); 355 EnableWindow(GetDlgItem(hDlg, IDC_OVERWRITE), FALSE); 356 EnableWindow(GetDlgItem(hDlg, IDC_TRUNCATE), FALSE); 357 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); 358 return; 359 } 360 361 // the target is an existing raw file 362 363 EnableWindow(GetDlgItem(hDlg, IDC_OVERWRITE), TRUE); 364 365 // set truncate box 366 367 if (file_size > VfdGetMediaSize(param->MediaType)) { 368 EnableWindow(GetDlgItem(hDlg, IDC_TRUNCATE), TRUE); 369 SetControlText(hDlg, IDC_IMAGEFILE_HINT, MSG_SIZE_MISMATCH); 370 } 371 else { 372 EnableWindow(GetDlgItem(hDlg, IDC_TRUNCATE), FALSE); 373 } 374 375 // check overwrite setting 376 377 if (IsDlgButtonChecked(hDlg, IDC_OVERWRITE) != BST_CHECKED) { 378 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); 379 } 380 else { 381 EnableWindow(GetDlgItem(hDlg, IDOK), TRUE); 382 } 383 384 // target file exists and overwritable 385 386 SetWindowLong(hDlg, DWL_USER, 1); 387 } 388 389 390 // 391 // Show save file dialog box 392 // 393 void OnBrowse( 394 HWND hDlg) 395 { 396 OPENFILENAME ofn; 397 PSTR title; 398 CHAR file[MAX_PATH]; 399 CHAR dir[MAX_PATH]; 400 DWORD len; 401 402 title = ModuleMessage(MSG_SAVE_TITLE); 403 404 ZeroMemory(&ofn, sizeof(ofn)); 405 ZeroMemory(file, sizeof(file)); 406 ZeroMemory(dir, sizeof(dir)); 407 408 len = GetDlgItemText(hDlg, IDC_TARGETFILE, file, sizeof(file)); 409 410 if (len && file[len - 1] == '\\') { 411 strcpy(dir, file); 412 ZeroMemory(file, sizeof(file)); 413 } 414 415 // Different structure sizes must be used for NT and 2K/XP 416 ofn.lStructSize = IS_WINDOWS_NT() ? 417 OPENFILENAME_SIZE_VERSION_400 : sizeof(ofn); 418 419 ofn.hwndOwner = hDlg; 420 ofn.lpstrFile = file; 421 ofn.nMaxFile = sizeof(file); 422 ofn.lpstrInitialDir = dir; 423 ofn.lpstrTitle = title ? title : "Save Image"; 424 ofn.lpstrFilter = "*.*\0*.*\0"; 425 ofn.Flags = OFN_ENABLESIZING | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST; 426 427 if (GetSaveFileName(&ofn)) { 428 SetDlgItemText(hDlg, IDC_TARGETFILE, file); 429 SetFocus(GetDlgItem(hDlg, IDC_TARGETFILE)); 430 } 431 432 if (title) { 433 LocalFree(title); 434 } 435 } 436 437 void OnOverwrite( 438 HWND hDlg, 439 HWND hCheck) 440 { 441 if (GetWindowLong(hDlg, DWL_USER)) { 442 // the target file exists and overwritable 443 if (SendMessage(hCheck, BM_GETCHECK, 0, 0) != BST_CHECKED) { 444 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); 445 } 446 else { 447 EnableWindow(GetDlgItem(hDlg, IDOK), TRUE); 448 } 449 } 450 } 451 452 void OnTruncate( 453 HWND hDlg, 454 HWND hCheck) 455 { 456 UNREFERENCED_PARAMETER(hDlg); 457 UNREFERENCED_PARAMETER(hCheck); 458 } 459 460 // 461 // Save image 462 // 463 DWORD OnOK( 464 HWND hDlg) 465 { 466 PCSAVE_PARAM param; 467 CHAR path[MAX_PATH]; 468 BOOL overwrite; 469 BOOL truncate; 470 DWORD ret; 471 472 param = (PCSAVE_PARAM)GetWindowLongPtr(hDlg, GWLP_USERDATA); 473 474 if (!param) { 475 return ERROR_INVALID_FUNCTION; 476 } 477 478 // get the target image name 479 480 if (GetDlgItemText(hDlg, IDC_TARGETFILE, path, sizeof(path)) == 0) { 481 return ERROR_INVALID_FUNCTION; 482 } 483 484 if (GetWindowLong(hDlg, DWL_USER)) { 485 // the target file exists and overwritable 486 overwrite = (IsDlgButtonChecked(hDlg, IDC_OVERWRITE) == BST_CHECKED); 487 truncate = (IsDlgButtonChecked(hDlg, IDC_TRUNCATE) == BST_CHECKED); 488 } 489 else { 490 overwrite = FALSE; 491 truncate = TRUE; 492 } 493 494 retry: 495 ret = VfdDismountVolume(param->hDevice, FALSE); 496 497 if (ret == ERROR_ACCESS_DENIED) { 498 PSTR msg = ModuleMessage(MSG_UNMOUNT_CONFIRM); 499 500 int reply = MessageBox( 501 hDlg, msg ? msg : "retry", VFD_MSGBOX_TITLE, 502 MB_ICONEXCLAMATION | MB_CANCELTRYCONTINUE); 503 504 if (msg) { 505 LocalFree(msg); 506 } 507 508 if (reply == IDRETRY) { 509 goto retry; 510 } 511 else if (reply == IDCANCEL) { 512 return ERROR_CANCELLED; 513 } 514 else { 515 VfdDismountVolume(param->hDevice, TRUE); 516 } 517 } 518 else if (ret != ERROR_SUCCESS) { 519 520 MessageBox(hDlg, SystemMessage(ret), 521 VFD_MSGBOX_TITLE, MB_ICONSTOP); 522 523 return ret; 524 } 525 526 ret = VfdSaveImage(param->hDevice, path, overwrite, truncate); 527 528 if (ret != ERROR_SUCCESS) { 529 530 // show error message 531 532 MessageBox(hDlg, SystemMessage(ret), 533 VFD_MSGBOX_TITLE, MB_ICONSTOP); 534 } 535 536 return ret; 537 } 538