1 /*
2 	vfdshprop.cpp
3 
4 	Virtual Floppy Drive for Windows
5 	Driver control library
6 	COM shell extension class property sheet functions
7 
8 	Copyright (c) 2003-2005 Ken Kato
9 */
10 
11 #define WIN32_LEAN_AND_MEAN
12 #include <windows.h>
13 #include <shellapi.h>
14 #include <shlobj.h>
15 #include <stdio.h>
16 
17 #include "vfdtypes.h"
18 #include "vfdapi.h"
19 #include "vfdlib.h"
20 #include "vfdver.h"
21 #ifndef __REACTOS__
22 #include "vfdmsg.h"
23 #else
24 #include "vfdmsg_lib.h"
25 #endif
26 #include "vfdguirc.h"
27 
28 //	class header
29 #include "vfdshext.h"
30 
31 //	property sheet property ID
32 
33 #define VFD_PROPERTY_ID	"VFD"
34 
35 //
36 //	local functions
37 //
38 #ifndef __REACTOS__
39 static BOOL CALLBACK VfdPageDlgProc(
40 #else
41 static INT_PTR CALLBACK VfdPageDlgProc(
42 #endif
43 	HWND			hDlg,
44 	UINT			uMessage,
45 	WPARAM			wParam,
46 	LPARAM			lParam);
47 
48 static UINT CALLBACK VfdPageCallback(
49 	HWND			hWnd,
50 	UINT			uMessage,
51 	LPPROPSHEETPAGE	ppsp);
52 
53 static void OnPropInit(HWND hDlg);
54 static void OnControl(HWND hDlg);
55 static void UpdateImageInfo(HWND hDlg, ULONG nDevice);
56 
57 //
58 //	property sheet callback function
59 //
60 UINT CALLBACK VfdPageCallback(
61 	HWND			hWnd,
62 	UINT			uMessage,
63 	LPPROPSHEETPAGE	ppsp)
64 {
65 	UNREFERENCED_PARAMETER(hWnd);
66 
67 	switch(uMessage) {
68 	case PSPCB_CREATE:
69 		return TRUE;
70 
71 	case PSPCB_RELEASE:
72 		if (ppsp->lParam) {
73 			((LPCVFDSHEXT)(ppsp->lParam))->Release();
74 		}
75 		return TRUE;
76 	}
77 	return TRUE;
78 }
79 
80 //
81 //	property page dialog procedure
82 //
83 #ifndef __REACTOS__
84 BOOL CALLBACK VfdPageDlgProc(
85 #else
86 INT_PTR CALLBACK VfdPageDlgProc(
87 #endif
88 	HWND			hDlg,
89 	UINT			uMessage,
90 	WPARAM			wParam,
91 	LPARAM			lParam)
92 {
93 	LPPROPSHEETPAGE psp;
94 	LPCVFDSHEXT		lpcs;
95 
96 	switch (uMessage) {
97 	case WM_INITDIALOG:
98 #ifndef __REACTOS__
99 		SetWindowLong(hDlg, DWL_USER, lParam);
100 #else
101 		SetWindowLongPtr(hDlg, DWLP_USER, lParam);
102 #endif
103 
104 		if (lParam) {
105 			lpcs = (LPCVFDSHEXT)((LPPROPSHEETPAGE)lParam)->lParam;
106 
107 			OnPropInit(hDlg);
108 			UpdateImageInfo(hDlg, lpcs->GetDevice());
109 		}
110 		return TRUE;
111 
112 	case WM_COMMAND:
113 #ifndef __REACTOS__
114 		psp = (LPPROPSHEETPAGE)GetWindowLong(hDlg, DWL_USER);
115 #else
116 		psp = (LPPROPSHEETPAGE)GetWindowLongPtr(hDlg, DWLP_USER);
117 #endif
118 
119 		if (!psp) {
120 			break;
121 		}
122 
123 		lpcs = (LPCVFDSHEXT)psp->lParam;
124 
125 		if (!lpcs) {
126 			break;
127 		}
128 
129 		switch (wParam) {
130 		case IDC_OPEN:
131 			if (lpcs->DoVfdOpen(hDlg) == ERROR_SUCCESS) {
132 				SendMessage((HWND)lParam,
133 					BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
134 			}
135 			UpdateImageInfo(hDlg, lpcs->GetDevice());
136 			break;
137 
138 		case IDC_SAVE:
139 			if (lpcs->DoVfdSave(hDlg) == ERROR_SUCCESS) {
140 				SendMessage((HWND)lParam,
141 					BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
142 			}
143 			UpdateImageInfo(hDlg, lpcs->GetDevice());
144 			break;
145 
146 		case IDC_CLOSE:
147 			if (lpcs->DoVfdClose(hDlg) == ERROR_SUCCESS) {
148 				SendMessage((HWND)lParam,
149 					BM_SETSTYLE, BS_PUSHBUTTON, TRUE);
150 			}
151 			UpdateImageInfo(hDlg, lpcs->GetDevice());
152 			break;
153 
154 		case IDC_WRITE_PROTECTED:
155 			lpcs->DoVfdProtect(hDlg);
156 			break;
157 
158 		case IDC_FORMAT:
159 			VfdGuiFormat(hDlg, lpcs->GetDevice());
160 			break;
161 
162 		case IDC_CONTROL:
163 			OnControl(hDlg);
164 			break;
165 		}
166 		break;
167 
168 	case WM_CONTEXTMENU:
169 		ShowContextMenu(hDlg, (HWND)wParam, lParam);
170 		break;
171 
172 	case WM_HELP:
173 		{
174 			LPHELPINFO info = (LPHELPINFO)lParam;
175 
176 			if (info->iContextType == HELPINFO_WINDOW) {
177 				ShowHelpWindow(hDlg, info->iCtrlId);
178 			}
179 		}
180 		return TRUE;
181 
182 	default:
183 		if (uMessage == g_nNotifyMsg) {
184 #ifndef __REACTOS__
185 			psp = (LPPROPSHEETPAGE)GetWindowLong(hDlg, DWL_USER);
186 #else
187 			psp = (LPPROPSHEETPAGE)GetWindowLongPtr(hDlg, DWLP_USER);
188 #endif
189 
190 			if (!psp) {
191 				break;
192 			}
193 
194 			lpcs = (LPCVFDSHEXT)psp->lParam;
195 
196 			if (!lpcs) {
197 				break;
198 			}
199 
200 			UpdateImageInfo(hDlg, lpcs->GetDevice());
201 		}
202 		break;
203 	}
204 
205 	return FALSE;
206 }
207 
208 //
209 //	initialize the property page
210 //
211 void OnPropInit(
212 	HWND			hDlg)
213 {
214 	//	set up control text
215 
216 	SetDlgItemText(hDlg, IDC_PROPERTY_TITLE,	VFD_PRODUCT_DESC);
217 	SetDlgItemText(hDlg, IDC_COPYRIGHT_STR,		VFD_COPYRIGHT_STR);
218 
219 	SetControlText(hDlg, IDC_IMAGEFILE_LABEL,	MSG_IMAGEFILE_LABEL);
220 	SetControlText(hDlg, IDC_IMAGEDESC_LABEL,	MSG_DESCRIPTION_LABEL);
221 	SetControlText(hDlg, IDC_DISKTYPE_LABEL,	MSG_DISKTYPE_LABEL);
222 	SetControlText(hDlg, IDC_MEDIATYPE_LABEL,	MSG_MEDIATYPE_LABEL);
223 	SetControlText(hDlg, IDC_WRITE_PROTECTED,	MSG_MENU_PROTECT);
224 	SetControlText(hDlg, IDC_OPEN,				MSG_OPEN_BUTTON);
225 	SetControlText(hDlg, IDC_SAVE,				MSG_SAVE_BUTTON);
226 	SetControlText(hDlg, IDC_CLOSE,				MSG_CLOSE_BUTTON);
227 	SetControlText(hDlg, IDC_FORMAT,			MSG_FORMAT_BUTTON);
228 	SetControlText(hDlg, IDC_CONTROL,			MSG_CONTROL_BUTTON);
229 }
230 
231 //
232 //	Control Panel button is clicked
233 //
234 void OnControl(
235 	HWND			hDlg)
236 {
237 	CHAR			module_path[MAX_PATH];
238 	CHAR			full_path[MAX_PATH];
239 	PSTR			file_name;
240 #ifndef __REACTOS__
241 	DWORD			ret;
242 #else
243 	DWORD_PTR		ret;
244 #endif
245 
246 	ret = GetModuleFileName(
247 		g_hDllModule, module_path, sizeof(module_path));
248 
249 	if (ret == 0 || ret >= sizeof(module_path)) {
250 		file_name = full_path;
251 	}
252 	else {
253 		ret = GetFullPathName(
254 			module_path, sizeof(full_path), full_path, &file_name);
255 
256 		if (ret == 0 || ret >= sizeof(full_path)) {
257 			file_name = full_path;
258 		}
259 	}
260 
261 	strcpy(file_name, "vfdwin.exe");
262 
263 	VFDTRACE(0, ("Starting %s\n", full_path));
264 
265 #ifndef __REACTOS__
266 	ret = (DWORD)ShellExecute(
267 		hDlg, NULL, full_path, NULL, NULL, SW_SHOW);
268 #else
269 	ret = (DWORD_PTR)ShellExecute(
270 		hDlg, NULL, full_path, NULL, NULL, SW_SHOW);
271 #endif
272 
273 	if (ret > 32) {
274 		PropSheet_PressButton(GetParent(hDlg), PSBTN_CANCEL);
275 	}
276 	else {
277 		MessageBox(hDlg, SystemMessage(ret),
278 			VFD_MSGBOX_TITLE, MB_ICONSTOP);
279 	}
280 }
281 
282 //
283 //	Update image information on the property page
284 //
285 void UpdateImageInfo(
286 	HWND			hDlg,
287 	ULONG			nDevice)
288 {
289 	HANDLE			hDevice;
290 	CHAR			buf[MAX_PATH];
291 	VFD_DISKTYPE	disk_type;
292 	VFD_MEDIA		media_type;
293 	VFD_FLAGS		media_flags;
294 	VFD_FILETYPE	file_type;
295 	ULONG			image_size;
296 	DWORD			attrib;
297 	ULONG			ret;
298 
299 	hDevice = VfdOpenDevice(nDevice);
300 
301 	if (hDevice == INVALID_HANDLE_VALUE) {
302 		MessageBox(hDlg,
303 			SystemMessage(GetLastError()),
304 			VFD_MSGBOX_TITLE, MB_ICONSTOP);
305 		return;
306 	}
307 
308 	//	get current image information
309 
310 	ret = VfdGetImageInfo(
311 		hDevice,
312 		buf,
313 		&disk_type,
314 		&media_type,
315 		&media_flags,
316 		&file_type,
317 		&image_size);
318 
319 	CloseHandle(hDevice);
320 
321 	if (ret != ERROR_SUCCESS) {
322 		MessageBox(hDlg,
323 			SystemMessage(ret),
324 			VFD_MSGBOX_TITLE, MB_ICONSTOP);
325 		return;
326 	}
327 
328 	if (media_type == VFD_MEDIA_NONE) {
329 
330 		//	drive is empty
331 
332 		SetDlgItemText(hDlg, IDC_IMAGEFILE,	NULL);
333 		SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, NULL);
334 		SetDlgItemText(hDlg, IDC_DISKTYPE, NULL);
335 		SetDlgItemText(hDlg, IDC_MEDIATYPE, NULL);
336 
337 		EnableWindow(GetDlgItem(hDlg, IDC_WRITE_PROTECTED), FALSE);
338 		EnableWindow(GetDlgItem(hDlg, IDC_OPEN),	TRUE);
339 		EnableWindow(GetDlgItem(hDlg, IDC_SAVE),	FALSE);
340 		EnableWindow(GetDlgItem(hDlg, IDC_CLOSE),	FALSE);
341 		EnableWindow(GetDlgItem(hDlg, IDC_FORMAT),	FALSE);
342 
343 		SendMessage(GetDlgItem(hDlg, IDC_OPEN),
344 			BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE);
345 
346 		SetFocus(GetDlgItem(hDlg, IDC_OPEN));
347 
348 		return;
349 	}
350 
351 	//	display image file name
352 
353 	if (buf[0]) {
354 		attrib = GetFileAttributes(buf);
355 
356 		if (attrib == INVALID_FILE_ATTRIBUTES) {
357 			attrib = 0;
358 		}
359 	}
360 	else {
361 		if (disk_type != VFD_DISKTYPE_FILE) {
362 			strcpy(buf, "<RAM>");
363 		}
364 		attrib = 0;
365 	}
366 
367 	SetDlgItemText(hDlg, IDC_IMAGEFILE, buf);
368 
369 	//	display image description
370 
371 	VfdMakeFileDesc(buf, sizeof(buf),
372 		file_type, image_size, attrib);
373 
374 	SetDlgItemText(hDlg, IDC_IMAGEFILE_DESC, buf);
375 
376 	//	display disk type
377 
378 	if (disk_type == VFD_DISKTYPE_FILE) {
379 		SetDlgItemText(hDlg, IDC_DISKTYPE, "FILE");
380 	}
381 	else {
382 		SetDlgItemText(hDlg, IDC_DISKTYPE, "RAM");
383 	}
384 
385 	//	display media type
386 
387 	SetDlgItemText(hDlg, IDC_MEDIATYPE,
388 		VfdMediaTypeName(media_type));
389 
390 	//	set write protect check box
391 
392 	if (media_flags & VFD_FLAG_WRITE_PROTECTED) {
393 		CheckDlgButton(hDlg, IDC_WRITE_PROTECTED, BST_CHECKED);
394 	}
395 	else {
396 		CheckDlgButton(hDlg, IDC_WRITE_PROTECTED, BST_UNCHECKED);
397 	}
398 
399 	EnableWindow(GetDlgItem(hDlg, IDC_WRITE_PROTECTED), TRUE);
400 	EnableWindow(GetDlgItem(hDlg, IDC_OPEN),	FALSE);
401 	EnableWindow(GetDlgItem(hDlg, IDC_SAVE),	TRUE);
402 	EnableWindow(GetDlgItem(hDlg, IDC_CLOSE),	TRUE);
403 	EnableWindow(GetDlgItem(hDlg, IDC_FORMAT),	TRUE);
404 
405 	SendMessage(GetDlgItem(hDlg, IDC_CLOSE),
406 		BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE);
407 
408 	SetFocus(GetDlgItem(hDlg, IDC_CLOSE));
409 }
410 
411 //
412 //	CVfdShExt class members inherited from IShellPropSheetExt
413 //
414 
415 //	Add property page
416 STDMETHODIMP CVfdShExt::AddPages(
417 	LPFNADDPROPSHEETPAGE	lpfnAddPage,
418 	LPARAM					lParam)
419 {
420 	PROPSHEETPAGE	psp;
421 	HPROPSHEETPAGE	hpage;
422 
423 	if (!m_pDataObj || m_nDevice == (ULONG)-1) {
424 		// not a VFD drive
425 		VFDTRACE(0, ("PropPage: Not a VFD drive\n"));
426 
427 		return NOERROR;
428 	}
429 
430 	psp.dwSize		= sizeof(psp);	// no extra data.
431 	psp.dwFlags		= PSP_USEREFPARENT | PSP_USETITLE | PSP_USECALLBACK;
432 	psp.hInstance	= g_hDllModule;
433 	psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPDIALOG);
434 	psp.hIcon		= 0;
435 	psp.pszTitle	= "VFD";
436 	psp.pfnDlgProc	= VfdPageDlgProc;
437 	psp.pcRefParent = &g_cDllRefCnt;
438 	psp.pfnCallback = VfdPageCallback;
439 	psp.lParam		= (LPARAM)this;
440 
441 	AddRef();
442 	hpage = CreatePropertySheetPage(&psp);
443 
444 	if (hpage) {
445 		if (!lpfnAddPage(hpage, lParam)) {
446 			DestroyPropertySheetPage(hpage);
447 			Release();
448 		}
449 	}
450 
451 	return NOERROR;
452 }
453 
454 STDMETHODIMP CVfdShExt::ReplacePage(
455 	UINT					uPageID,
456 	LPFNADDPROPSHEETPAGE	lpfnReplaceWith,
457 	LPARAM					lParam)
458 {
459 	UNREFERENCED_PARAMETER(uPageID);
460 	UNREFERENCED_PARAMETER(lpfnReplaceWith);
461 	UNREFERENCED_PARAMETER(lParam);
462 	return E_FAIL;
463 }
464