[VFDLIB] Fix preprocessor directive compilation error when being used inside a macro...
[reactos.git] / modules / rosapps / lib / vfdlib / vfdguiopen.c
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 }