[CRT] Massively improve performance of rand_s
[reactos.git] / modules / rosapps / lib / vfdlib / vfdshprop.cpp
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 }