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