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