1 /* 2 vfdguiopen.c 3 4 Virtual Floppy Drive for Windows 5 Driver control library 6 Open 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 // String constants 37 // 38 39 #define FALLBACK_IMAGE_FILTER \ 40 "Common image files (bin,dat,fdd,flp,ima,img,vfd)\0" \ 41 "*.bin;*.dat;*.fdd;*.flp;*.ima;*.img;*.vfd\0" \ 42 "Zip compressed image (imz,zip)\0*.imz;*.zip\0" \ 43 "All files (*.*)\0*.*\0" 44 45 #define FALLBACK_IMAGE_TITLE "Open Virtual Floppy Image" 46 47 // 48 // local functions 49 // 50 static INT CALLBACK OpenDialogProc( 51 HWND hDlg, 52 UINT uMsg, 53 WPARAM wParam, 54 LPARAM lParam); 55 56 static void OnInit(HWND hDlg, ULONG nDevice); 57 static void OnImage(HWND hDlg, HWND hEdit); 58 static void OnBrowse(HWND hDlg); 59 static void OnDiskType(HWND hDlg, HWND hRadio); 60 static void OnMediaType(HWND hDlg, HWND hCombo); 61 static void OnProtect(HWND hDlg, HWND hCheck); 62 static DWORD OnOK(HWND hDlg); 63 64 // 65 // Show Open Image dialog box 66 // 67 DWORD WINAPI VfdGuiOpen( 68 HWND hParent, 69 ULONG nDevice) 70 { 71 switch (DialogBoxParam( 72 g_hDllModule, 73 MAKEINTRESOURCE(IDD_OPENDIALOG), 74 hParent, 75 OpenDialogProc, 76 nDevice)) 77 { 78 case IDOK: 79 return ERROR_SUCCESS; 80 81 case IDCANCEL: 82 return ERROR_CANCELLED; 83 84 default: 85 return GetLastError(); 86 } 87 } 88 89 // 90 // Open image dialog procedure 91 // 92 INT CALLBACK OpenDialogProc( 93 HWND hDlg, 94 UINT uMsg, 95 WPARAM wParam, 96 LPARAM lParam) 97 { 98 switch (uMsg) { 99 case WM_INITDIALOG: 100 OnInit(hDlg, lParam); 101 return TRUE; 102 103 case WM_COMMAND: 104 switch (wParam) { 105 case MAKELONG(IDC_IMAGEFILE, EN_CHANGE): 106 OnImage(hDlg, (HWND)lParam); 107 return TRUE; 108 109 case IDC_BROWSE: 110 OnBrowse(hDlg); 111 return TRUE; 112 113 case IDC_DISKTYPE_FILE: 114 case IDC_DISKTYPE_RAM: 115 OnDiskType(hDlg, (HWND)lParam); 116 return TRUE; 117 118 case MAKELONG(IDC_MEDIATYPE, CBN_SELCHANGE): 119 OnMediaType(hDlg, (HWND)lParam); 120 return TRUE; 121 122 case IDC_OPEN_PROTECTED: 123 OnProtect(hDlg, (HWND)lParam); 124 return TRUE; 125 126 case IDOK: 127 if (OnOK(hDlg) == ERROR_SUCCESS) { 128 EndDialog(hDlg, IDOK); 129 } 130 return TRUE; 131 132 case IDCANCEL: 133 EndDialog(hDlg, IDCANCEL); 134 return TRUE; 135 } 136 break; 137 138 case WM_CONTEXTMENU: 139 ShowContextMenu(hDlg, (HWND)wParam, lParam); 140 break; 141 142 case WM_HELP: 143 { 144 LPHELPINFO info = (LPHELPINFO)lParam; 145 146 if (info->iContextType == HELPINFO_WINDOW) { 147 ShowHelpWindow(hDlg, info->iCtrlId); 148 } 149 } 150 return TRUE; 151 } 152 153 return FALSE; 154 } 155 156 // 157 // Initialize the Open Image dialog 158 // 159 void OnInit( 160 HWND hDlg, 161 ULONG nDevice) 162 { 163 VFD_MEDIA i; 164 165 // Store the device number 166 167 SetWindowLong(hDlg, GWL_USERDATA, nDevice); 168 169 // Store default file size 170 171 SetWindowLong(hDlg, DWL_USER, INVALID_FILE_SIZE); 172 173 // Set dialog window title 174 175 SetControlText(hDlg, 0, MSG_OPEN_TITLE); 176 177 // Set control captions 178 179 SetControlText(hDlg, IDC_IMAGEFILE_LABEL, MSG_IMAGEFILE_ACCEL); 180 SetControlText(hDlg, IDC_IMAGEDESC_LABEL, MSG_DESCRIPTION_LABEL); 181 SetControlText(hDlg, IDC_BROWSE, MSG_BROWSE_BUTTON); 182 SetControlText(hDlg, IDC_DISKTYPE_LABEL, MSG_DISKTYPE_LABEL); 183 SetControlText(hDlg, IDC_MEDIATYPE_LABEL, MSG_MEDIATYPE_ACCEL); 184 SetControlText(hDlg, IDC_OPEN_PROTECTED, MSG_MENU_PROTECT); 185 SetControlText(hDlg, IDOK, MSG_CREATE_BUTTON); 186 SetControlText(hDlg, IDCANCEL, MSG_CANCEL_BUTTON); 187 188 // select RAM disk as default 189 190 CheckRadioButton(hDlg, IDC_DISKTYPE_FILE, 191 IDC_DISKTYPE_RAM, IDC_DISKTYPE_RAM); 192 193 // setup media type combo list 194 195 for (i = 1; i < VFD_MEDIA_MAX; i++) { 196 SendDlgItemMessage(hDlg, IDC_MEDIATYPE, 197 CB_ADDSTRING, 0, (LPARAM)VfdMediaTypeName(i)); 198 } 199 200 // select 1.44MB as the default 201 202 SendDlgItemMessage(hDlg, IDC_MEDIATYPE, CB_SELECTSTRING, 203 (WPARAM)-1, (LPARAM)VfdMediaTypeName(VFD_MEDIA_F3_1P4)); 204 205 // set up other controls 206 207 OnImage(hDlg, GetDlgItem(hDlg, IDC_IMAGEFILE)); 208 } 209 210 // 211 // Path is changed -- check if the file exists 212 // 213 void OnImage( 214 HWND hDlg, 215 HWND hEdit) 216 { 217 CHAR buf[MAX_PATH]; 218 DWORD file_attr; 219 ULONG image_size; 220 VFD_FILETYPE file_type; 221 VFD_MEDIA media_type; 222 223 DWORD ret = ERROR_SUCCESS; 224 225 // Store default file size 226 227 SetWindowLong(hDlg, DWL_USER, INVALID_FILE_SIZE); 228 229 // get currently selected media type 230 231 media_type = (VFD_MEDIA)(SendDlgItemMessage( 232 hDlg, IDC_MEDIATYPE, CB_GETCURSEL, 0, 0) + 1); 233 234 // clear hint and description text 235 236 SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, NULL); 237 SetDlgItemText(hDlg, IDC_IMAGEFILE_HINT, NULL); 238 239 // get file name and file information 240 241 if (GetWindowText(hEdit, buf, sizeof(buf))) { 242 243 ret = VfdCheckImageFile( 244 buf, &file_attr, &file_type, &image_size); 245 246 if (ret == ERROR_SUCCESS) { 247 248 // use media type from image size 249 250 media_type = VfdLookupMedia(image_size); 251 } 252 else if (ret == ERROR_FILE_NOT_FOUND) { 253 254 // new file 255 // use the parent directory attributes 256 257 PSTR p; 258 259 if ((p = strrchr(buf, '\\')) != NULL) { 260 *p = '\0'; 261 } 262 263 file_attr = GetFileAttributes(buf); 264 265 if (file_attr == INVALID_FILE_ATTRIBUTES) { 266 // directory access error 267 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); 268 SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, SystemMessage(ret)); 269 return; 270 } 271 272 file_attr &= ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_DIRECTORY); 273 image_size = INVALID_FILE_SIZE; 274 file_type = VFD_FILETYPE_RAW; 275 } 276 else { 277 // file access error 278 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); 279 SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, SystemMessage(ret)); 280 return; 281 } 282 283 // make file description text 284 285 VfdMakeFileDesc(buf, sizeof(buf), 286 file_type, image_size, file_attr); 287 288 // set file description 289 290 SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, buf); 291 } 292 else { 293 294 // filename is empty - RAM disk 295 296 file_attr = 0; 297 image_size = INVALID_FILE_SIZE; 298 file_type = VFD_FILETYPE_NONE; 299 300 SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, "RAM"); 301 } 302 303 // store the image size 304 305 SetWindowLong(hDlg, DWL_USER, image_size); 306 307 // setup disktype controls 308 309 if (file_type != VFD_FILETYPE_RAW || 310 (file_attr & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_COMPRESSED | FILE_ATTRIBUTE_ENCRYPTED))) { 311 312 // file cannot be opened directly -- RAM mode is forced 313 314 CheckRadioButton(hDlg, IDC_DISKTYPE_FILE, 315 IDC_DISKTYPE_RAM, IDC_DISKTYPE_RAM); 316 317 EnableWindow(GetDlgItem(hDlg, IDC_DISKTYPE_FILE), FALSE); 318 } 319 else { 320 EnableWindow(GetDlgItem(hDlg, IDC_DISKTYPE_FILE), TRUE); 321 } 322 323 // set OK button text 324 325 if (image_size == INVALID_FILE_SIZE) { 326 // file does not exist - OK button is "Create" 327 328 SetControlText(hDlg, IDOK, MSG_CREATE_BUTTON); 329 } 330 else { 331 // file exists - OK button is "Open" 332 333 SetControlText(hDlg, IDOK, MSG_OPEN_BUTTON); 334 } 335 336 // select media type 337 338 SendDlgItemMessage(hDlg, IDC_MEDIATYPE, 339 CB_SETCURSEL, media_type - 1, 0); 340 341 OnMediaType(hDlg, GetDlgItem(hDlg, IDC_MEDIATYPE)); 342 } 343 344 // 345 // Show open file dialog box 346 // 347 void OnBrowse( 348 HWND hDlg) 349 { 350 OPENFILENAME ofn; 351 PSTR title; 352 PSTR filter; 353 CHAR file[MAX_PATH]; 354 CHAR dir[MAX_PATH]; 355 DWORD len; 356 357 // prepare title and filter text 358 359 title = ModuleMessage(MSG_OPEN_TITLE); 360 361 filter = ModuleMessage(MSG_OPEN_FILTER); 362 363 if (filter) { 364 PSTR p = filter; 365 366 do { 367 if (*p == '|') { 368 *p = '\0'; 369 } 370 } 371 while (*(++p)); 372 } 373 374 // get current file name from the control 375 376 ZeroMemory(file, sizeof(file)); 377 ZeroMemory(dir, sizeof(dir)); 378 379 len = GetDlgItemText(hDlg, IDC_IMAGEFILE, file, sizeof(file)); 380 381 if (len && file[len - 1] == '\\') { 382 strcpy(dir, file); 383 ZeroMemory(file, sizeof(file)); 384 } 385 386 // prepare OPENFILENAME structure 387 388 ZeroMemory(&ofn, sizeof(ofn)); 389 390 ofn.lStructSize = IS_WINDOWS_NT() ? 391 OPENFILENAME_SIZE_VERSION_400 : sizeof(ofn); 392 393 ofn.hwndOwner = hDlg; 394 ofn.lpstrFilter = filter ? filter : FALLBACK_IMAGE_FILTER; 395 ofn.lpstrFile = file; 396 ofn.nMaxFile = sizeof(file); 397 ofn.lpstrInitialDir = dir; 398 ofn.lpstrTitle = title ? title : FALLBACK_IMAGE_TITLE; 399 ofn.Flags = OFN_ENABLESIZING | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST; 400 401 // show the open file dialog box 402 403 if (GetOpenFileName(&ofn)) { 404 SetDlgItemText(hDlg, IDC_IMAGEFILE, file); 405 SetFocus(GetDlgItem(hDlg, IDC_IMAGEFILE)); 406 } 407 408 // release text buffers 409 410 if (filter) { 411 LocalFree(filter); 412 } 413 414 if (title) { 415 LocalFree(title); 416 } 417 } 418 419 // 420 // Disk type is changed 421 // 422 void OnDiskType( 423 HWND hDlg, 424 HWND hRadio) 425 { 426 UNREFERENCED_PARAMETER(hDlg); 427 UNREFERENCED_PARAMETER(hRadio); 428 } 429 430 // 431 // Media type is changed 432 // 433 void OnMediaType( 434 HWND hDlg, 435 HWND hCombo) 436 { 437 VFD_MEDIA media_type; 438 ULONG media_size; 439 ULONG image_size; 440 441 image_size = GetWindowLong(hDlg, DWL_USER); 442 443 if (image_size == INVALID_FILE_SIZE) { 444 return; 445 } 446 447 media_type = (VFD_MEDIA)(SendMessage( 448 hCombo, CB_GETCURSEL, 0, 0) + 1); 449 450 if (media_type == 0) { 451 return; 452 } 453 454 media_size = VfdGetMediaSize(media_type); 455 456 if (media_size > image_size) { 457 // selected media is too large 458 SetControlText(hDlg, IDC_IMAGEFILE_HINT, MSG_FILE_TOO_SMALL); 459 EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); 460 return; 461 } 462 else if (media_size < image_size) { 463 SetControlText(hDlg, IDC_IMAGEFILE_HINT, MSG_SIZE_MISMATCH); 464 } 465 else { 466 SetDlgItemText(hDlg, IDC_IMAGEFILE_HINT, NULL); 467 } 468 469 EnableWindow(GetDlgItem(hDlg, IDOK), TRUE); 470 } 471 472 // 473 // Write Protect check box is clicked 474 // 475 void OnProtect( 476 HWND hDlg, 477 HWND hCheck) 478 { 479 UNREFERENCED_PARAMETER(hDlg); 480 UNREFERENCED_PARAMETER(hCheck); 481 } 482 483 // 484 // Create / open an image 485 // 486 DWORD OnOK( 487 HWND hDlg) 488 { 489 CHAR file_name[MAX_PATH]; 490 VFD_DISKTYPE disk_type; 491 VFD_MEDIA media_type; 492 VFD_FLAGS image_flags; 493 HANDLE hDevice; 494 DWORD ret; 495 496 // get the disk type 497 498 if (IsDlgButtonChecked(hDlg, IDC_DISKTYPE_FILE) == BST_CHECKED) { 499 disk_type = VFD_DISKTYPE_FILE; 500 } 501 else { 502 disk_type = VFD_DISKTYPE_RAM; 503 } 504 505 // get the media type 506 507 media_type = (VFD_MEDIA)(SendDlgItemMessage( 508 hDlg, IDC_MEDIATYPE, CB_GETCURSEL, 0, 0) + 1); 509 510 // get the protect flag 511 512 if (IsDlgButtonChecked(hDlg, IDC_OPEN_PROTECTED) == BST_CHECKED) { 513 image_flags = VFD_FLAG_WRITE_PROTECTED; 514 } 515 else { 516 image_flags = 0; 517 } 518 519 // get the image name to create 520 521 if (GetDlgItemText(hDlg, IDC_IMAGEFILE, file_name, sizeof(file_name))) { 522 523 // file is specified 524 525 if (GetWindowLong(hDlg, DWL_USER) == INVALID_FILE_SIZE) { 526 527 // create a new image 528 529 ret = VfdCreateImageFile( 530 file_name, media_type, VFD_FILETYPE_RAW, FALSE); 531 532 if (ret != ERROR_SUCCESS) { 533 goto exit_func; 534 } 535 } 536 } 537 538 // open the image 539 540 hDevice = VfdOpenDevice(GetWindowLong(hDlg, GWL_USERDATA)); 541 542 if (hDevice == INVALID_HANDLE_VALUE) { 543 ret = GetLastError(); 544 goto exit_func; 545 } 546 547 ret = VfdOpenImage( 548 hDevice, file_name, disk_type, media_type, image_flags); 549 550 CloseHandle(hDevice); 551 552 exit_func: 553 if (ret != ERROR_SUCCESS) { 554 555 // show error message 556 557 MessageBox(hDlg, SystemMessage(ret), 558 VFD_MSGBOX_TITLE, MB_ICONSTOP); 559 } 560 561 return ret; 562 } 563