/[winpt]/trunk/Src/wptCryptdisk.cpp
ViewVC logotype

Contents of /trunk/Src/wptCryptdisk.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 193 - (show annotations)
Sat Apr 1 12:36:35 2006 UTC (18 years, 11 months ago) by twoaday
File size: 15905 byte(s)
2006-03-31  Timo Schulz  <ts@g10code.de>
 
        * wptCommonDlg.cpp (nls_load_langlist): New.
        (nsl_set_language): New.
        (nls_dlg_proc): New.
        (select_language): New. Allow user to select the language.
        * wptNLS.c (get_gettext_langid): Updated available languages.
        * WinPT.cpp (WinMain): Allow to select the languag on first
        start in non-installer environments.
        * wptVerifyList.cpp (verlist_build): Simplified.
        (verlist_add_sig_log): Likewise.
        * wptListview.cpp (listview_set_column_width,
        listview_get_selected_item): New.
        * wptKeyManager.cpp (gpg_clip_export): Merged into..
        (km_clip_export): ..this function.


1 /* wptCryptdisk.cpp
2 * Copyright (C) 2004, 2006 Timo Schulz
3 *
4 * This file is part of WinPT.
5 *
6 * WinPT is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * WinPT is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with WinPT; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #if 0 /* disabled until the code really works on all systems. */
25 #include <windows.h>
26 #include <winioctl.h>
27 #include <stdio.h>
28 #include <ctype.h>
29
30 #include "resource.h"
31 #include "wptCryptdisk.h"
32 #include "wptTypes.h"
33 #include "wptW32API.h"
34 #include "wptNLS.h"
35 #include "wptErrors.h"
36
37 /*DWORD SHFormatDrive(HWND hwnd, UINT drive, UINT fmtID, UINT options);*/
38 typedef DWORD (WINAPI *sh_format_drive_p) (HWND, UINT, UINT, UINT);
39
40 static mount_list_t mounted=NULL;
41 static HMODULE shell32=NULL;
42 static sh_format_drive_p shfmt=NULL;
43
44
45 static int
46 is_nt4 (void)
47 {
48 static int nt_flag = -1;
49 OSVERSIONINFO osinf;
50
51 if (nt_flag != -1)
52 return nt_flag;
53
54 memset (&osinf, 0, sizeof osinf);
55 osinf.dwOSVersionInfoSize = sizeof osinf;
56 GetVersionEx (&osinf);
57 if (osinf.dwPlatformId == VER_PLATFORM_WIN32_NT) {
58 nt_flag = 1;
59 shell32 = LoadLibrary ("SHELL32.DLL");
60 shfmt = (sh_format_drive_p)GetProcAddress (shell32, "SHFormatDrive");
61 if (!shfmt)
62 BUG (0);
63 }
64 else
65 nt_flag = 0;
66 return nt_flag;
67 }
68
69 static int
70 check_filedisk (void)
71 {
72 HKEY hk;
73 int rc = -1;
74
75 rc = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
76 "SYSTEM\\CurrentControlSet\\Services\\FileDisk",
77 0, KEY_READ, &hk);
78 if (rc == ERROR_SUCCESS) {
79 RegCloseKey (hk);
80 rc = 0;
81 }
82 return rc;
83 }
84
85
86 int
87 cryptdisk_available (void)
88 {
89 return (is_nt4 () == 1 && check_filedisk () == 0)? 1 : 0;
90 }
91
92
93 void
94 cryptdisk_cleanup (void)
95 {
96 if (shell32)
97 FreeLibrary (shell32);
98 shell32 = NULL;
99 }
100
101
102 static int
103 num_of_devices (void)
104 {
105 HKEY hk;
106 BYTE buf[32];
107 DWORD n=0, type=0;
108 int rc;
109
110 rc = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
111 "SYSTEM\\CurrentControlSet\\Services\\FileDisk\\Parameters",
112 0, KEY_READ, &hk);
113 if (rc != ERROR_SUCCESS)
114 return -1;
115
116 n = sizeof buf-1;
117 memset (buf, 0, sizeof buf);
118 rc = RegQueryValueEx (hk, "NumberOfDevices", 0, &type, buf, &n);
119 if (rc != ERROR_SUCCESS || type != REG_DWORD)
120 n=0;
121 else
122 n = *buf;
123 RegCloseKey (hk);
124 return n;
125 }
126
127
128 static HWND
129 start_cryptdisk_server (HANDLE * r_proc)
130 {
131 STARTUPINFO si;
132 PROCESS_INFORMATION pi;
133
134 memset (&si, 0, sizeof si);
135 memset (&pi, 0, sizeof pi);
136 si.cb = sizeof si;
137
138 if (CreateProcess (NULL, "CryptdiskSrv", NULL, NULL, FALSE, 0,
139 NULL, NULL, &si, &pi) == FALSE) {
140 msg_box (NULL, _("Could not execute Cryptdisk Server."),
141 _("Cryptdisk Error"), MB_ERR);
142 return NULL;
143 }
144 *r_proc = pi.hProcess;
145 Sleep (300);
146 return FindWindow ("CryptdiskSrv", NULL);
147 }
148
149
150 static int
151 cryptdisk_mount (int devnum,
152 const char * imgfile,
153 DWORD size,
154 const char * hdlet)
155 {
156 HWND h;
157 HANDLE proc, wait_ev;
158 COPYDATASTRUCT cds;
159 struct private_ofi_s ofi;
160
161 h = start_cryptdisk_server (&proc);
162 if (!h)
163 return WPTERR_GENERAL;
164 memset (&ofi, 0, sizeof ofi);
165 ofi.cmd = CMD_MOUNT;
166 ofi.devnum = devnum;
167 ofi.filesize.LowPart = size;
168 ofi.drvlet = *hdlet;
169 ofi.readonly = 0;
170 strcpy ((char *)ofi.fname, imgfile);
171 ofi.flen = strlen (imgfile);
172
173 wait_ev = OpenEvent (SYNCHRONIZE, FALSE, "cryptdisksrv.wait");
174 if (!wait_ev)
175 BUG (0);
176 memset (&cds, 0, sizeof cds);
177 cds.cbData = sizeof ofi;
178 cds.lpData = &ofi;
179 SendMessage (h, WM_COPYDATA, (WPARAM)GetDesktopWindow (), (LPARAM)&cds);
180 WaitForSingleObject (wait_ev, INFINITE);
181 CloseHandle (wait_ev);
182 CloseHandle (proc);
183 return 0;
184 }
185
186
187
188 int
189 cryptdisk_unmount (char drivelet, int forced)
190 {
191 HWND h;
192 HANDLE proc;
193 COPYDATASTRUCT cds;
194 struct private_ofi_s ofi;
195
196 h = start_cryptdisk_server (&proc);
197 if (!h)
198 return WPTERR_GENERAL;
199
200 memset (&ofi, 0, sizeof ofi);
201 ofi.cmd = CMD_UMOUNT;
202 ofi.drvlet = drivelet;
203 ofi.forced = forced;
204
205 memset (&cds, 0, sizeof cds);
206 cds.lpData = &ofi;
207 cds.cbData = sizeof ofi;
208 SendMessage (h, WM_COPYDATA, (WPARAM)GetDesktopWindow (), (LPARAM)&cds);
209 CloseHandle (proc);
210
211 return 0;
212 }
213
214 static void
215 print_lasterr (char * prefix)
216 {
217 LPVOID msg;
218
219 FormatMessage(
220 FORMAT_MESSAGE_ALLOCATE_BUFFER |
221 FORMAT_MESSAGE_FROM_SYSTEM |
222 FORMAT_MESSAGE_IGNORE_INSERTS,
223 NULL,
224 GetLastError(),
225 0,
226 (LPTSTR) &msg,
227 0,
228 NULL
229 );
230 MessageBox (NULL, (LPTSTR)msg, prefix, MB_ICONERROR|MB_OK);
231 LocalFree (msg);
232 }
233
234
235 static int
236 filedisk_status (char drivelet, LARGE_INTEGER * size, int * rdonly)
237 {
238 char VolumeName[] = "\\\\.\\ :";
239 HANDLE Device;
240 POPEN_FILE_INFORMATION ofi;
241 DWORD BytesReturned;
242 int n= sizeof (OPEN_FILE_INFORMATION)+ MAX_PATH;
243
244 VolumeName[4] = drivelet;
245
246 Device = CreateFile (VolumeName,
247 GENERIC_READ,
248 FILE_SHARE_READ | FILE_SHARE_WRITE,
249 NULL,
250 OPEN_EXISTING,
251 FILE_FLAG_NO_BUFFERING,
252 NULL);
253
254 if (Device == INVALID_HANDLE_VALUE) {
255 print_lasterr(&VolumeName[4]);
256 return WPTERR_CDISK_OPEN;
257 }
258
259 ofi = (POPEN_FILE_INFORMATION)malloc (n);
260
261 if (!DeviceIoControl (Device,
262 IOCTL_FILE_DISK_QUERY_FILE,
263 NULL,
264 0,
265 ofi,
266 sizeof(OPEN_FILE_INFORMATION) + MAX_PATH,
267 &BytesReturned, NULL)) {
268 print_lasterr (&VolumeName[4]);
269 return WPTERR_CDISK_QUERY;
270 }
271
272 if (BytesReturned < sizeof(OPEN_FILE_INFORMATION)) {
273 SetLastError (ERROR_INSUFFICIENT_BUFFER);
274 print_lasterr (&VolumeName[4]);
275 return WPTERR_CDISK_QUERY;
276 }
277
278 if (size)
279 *size = ofi->FileSize;
280 if (rdonly)
281 *rdonly = ofi->ReadOnly;
282
283 return 0;
284 }
285
286
287 static mount_list_t
288 new_mount_list (const char * drive, int devnum)
289 {
290 mount_list_t n;
291
292 n = (mount_list_t)calloc (1, sizeof *n);
293 if (n) {
294 strcpy (n->drive, drive);
295 n->devnum = devnum;
296 n->ttl = 1;
297 filedisk_status (*drive, &n->size, &n->rdonly);
298 }
299 return n;
300 }
301
302
303 static mount_list_t
304 find_mount_list (mount_list_t root, const char * drive)
305 {
306 mount_list_t n;
307
308 for (n=root; n; n=n->next) {
309 if (n->ttl == 0)
310 continue;
311 if (!strncmp (n->drive, drive, strlen (drive)))
312 return n;
313 }
314 return NULL;
315 }
316
317
318 static void
319 add_mount_list (mount_list_t root, mount_list_t node)
320 {
321 mount_list_t n;
322
323 if (find_mount_list (root, node->drive))
324 return;
325
326 for (n=root; n->next; n=n->next)
327 ;
328 n->next = node;
329 }
330
331
332 static void
333 remove_mount_list (mount_list_t root, mount_list_t node)
334 {
335 mount_list_t n;
336
337 n = find_mount_list (root, node->drive);
338 if (n)
339 n->ttl = 0;
340 }
341
342
343 static void
344 free_mount_list (mount_list_t root)
345 {
346 mount_list_t n;
347
348 while (root) {
349 n = root->next;
350 free (root);
351 root = n;
352 }
353 }
354
355
356 static int
357 last_devnum (mount_list_t root)
358 {
359 mount_list_t n;
360 int devnum=0;
361
362 if (!root)
363 return 0;
364
365 for (n=root; n; n=n->next) {
366 if (devnum < n->devnum)
367 devnum=n->devnum;
368 }
369 return devnum+1;
370 }
371
372
373 static char
374 init_drives (HWND dlg, int ctlid)
375 {
376 char buf[512], drv[5];
377 DWORD n=0, i=0;
378
379 n=GetLogicalDriveStrings (sizeof buf-1, buf);
380 for (i=0; i < n; i++) {
381 memcpy (drv, buf+i, 3); drv[3]=0;
382 i += 3;
383 }
384 if (!dlg && ctlid == -1)
385 return ++drv[0];
386
387 for (++drv[0]; drv[0] < 'Z'; drv[0]++)
388 SendDlgItemMessage (dlg, ctlid, CB_ADDSTRING, 0,
389 (LPARAM)(const char *)drv);
390 SendDlgItemMessage (dlg, ctlid, CB_SETCURSEL, 0, 0);
391 return 0;
392 }
393
394
395 static int
396 check_freespace (const char * imgfile, DWORD size)
397 {
398 ULARGE_INTEGER tocaller, total, totfree;
399 char buf[128] = {0};
400
401 if (!strchr (imgfile, ':'))
402 GetCurrentDirectory (sizeof buf-1, buf);
403 else
404 strncpy (buf, imgfile, sizeof buf-1);
405 buf[3] = '\0';
406 GetDiskFreeSpaceEx (buf, &tocaller, &total, &totfree);
407 if (size > tocaller.LowPart)
408 return -1;
409 return 0;
410 }
411
412
413 static void
414 do_check (HWND dlg)
415 {
416 if (!cryptdisk_serv_run ()) { /* xxx */
417 msg_box (dlg, _("The Cryptdisk service seems to be available but "
418 "it is not started yet.\nPlease start the service "
419 "and try again."), _("Cryptdisk Error"), MB_ERR);
420 EndDialog (dlg, TRUE);
421 }
422 }
423
424
425 BOOL CALLBACK
426 cryptdisk_new_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
427 {
428 const char * ciphers [] = {
429 "twofish",
430 NULL
431 };
432 const char * s;
433 char imgfile[128], key[128], drv[3];
434 int i;
435 DWORD size=0;
436
437 switch (msg) {
438 case WM_INITDIALOG:
439 do_check (dlg);
440 SetDlgItemInt (dlg, IDC_CDNEW_SIZE, DISK_DEFSIZE, FALSE);
441 for (i=0; (s=ciphers[i]); i++)
442 SendDlgItemMessage (dlg, IDC_CDNEW_CIPHERS, CB_ADDSTRING,
443 0, (LPARAM)(const char *) s);
444 SendDlgItemMessage (dlg, IDC_CDNEW_CIPHERS, CB_SETCURSEL, 0, 0);
445 center_window (dlg, NULL);
446 SetForegroundWindow (dlg);
447 break;
448
449 case WM_COMMAND:
450 switch (LOWORD (wparam)) {
451 case IDOK:
452 i = GetDlgItemText (dlg, IDC_CDNEW_IMGFILE, imgfile, sizeof imgfile-1);
453 if (!i) {
454 msg_box (dlg, _("Please enter a name for the image file."),
455 _("Cryptdisk"), MB_ERR);
456 return FALSE;
457 }
458 if (file_exist_check (imgfile) == 0) {
459 i = msg_box (dlg, _("This volume file already exists.\n"
460 "Do you want to overwrite it?"),
461 _("Cryptdisk Warning"), MB_YESNO|MB_WARN);
462 if (i == IDNO)
463 return FALSE;
464 }
465 for (i=0; i < (int)strlen (imgfile); i++)
466 imgfile[i] = toupper (imgfile[i]);
467 size = GetDlgItemInt (dlg, IDC_CDNEW_SIZE, NULL, FALSE);
468 if (!size) {
469 msg_box (dlg, _("Please enter the size for the volume"),
470 _("Cryptdisk"), MB_INFO);
471 return FALSE;
472 }
473 size *= 1024; /*KB*/
474 if (check_freespace (imgfile, (size*1024))) {
475 msg_box (dlg, _("There is not enough free disk space to "
476 "store the volume."), _("Cryptdisk"), MB_ERR);
477 return FALSE;
478 }
479 i = GetDlgItemText (dlg, IDC_CDNEW_PASS, key, sizeof key-1);
480 if (!i) {
481 msg_box (dlg, _("Please enter a passphrase for the volume."),
482 _("Cryptdisk"), MB_ERR);
483 return FALSE;
484 }
485 strcpy (drv, "?:\\");
486 drv[0] = init_drives (NULL, -1);
487 i = cryptdisk_mount (last_devnum (mounted), imgfile, size, drv);
488 if (!i)
489 shfmt (dlg, drv[0] - 65, 0, 0);
490 break;
491 case IDCANCEL:
492 EndDialog (dlg, FALSE);
493 break;
494 }
495 break;
496
497 }
498
499 return FALSE;
500 }
501
502
503 BOOL CALLBACK
504 cryptdisk_mount_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
505 {
506 const char * s_imgfile;
507 char buf[8], drive[8], passwd[64], imgfile[128];
508 int n, i, devnum=0;
509 int rc;
510
511 switch (msg) {
512 case WM_INITDIALOG:
513 do_check (dlg);
514 s_imgfile = (const char *)lparam;
515 if (s_imgfile)
516 SetDlgItemText (dlg, IDC_CDMOUNT_IMGFILE, s_imgfile);
517 init_drives (dlg, IDC_CDMOUNT_DRV);
518 n = num_of_devices ();
519 if (n == -1) {
520 msg_box (dlg, _("Cannot determine the number of drives."),
521 _("Cryptdisk Error"), MB_ERR);
522 EndDialog (dlg, FALSE);
523 }
524 for (i=last_devnum (mounted); i < n; i++) {
525 sprintf (buf, "%d", i);
526 SendDlgItemMessage (dlg, IDC_CDMOUNT_ID, CB_ADDSTRING, 0,
527 (LPARAM)(const char *)buf);
528 }
529 SendDlgItemMessage (dlg, IDC_CDMOUNT_ID, CB_SETCURSEL, 0, 0);
530 center_window (dlg, NULL);
531 SetForegroundWindow (dlg);
532 break;
533
534 case WM_COMMAND:
535 switch (LOWORD (wparam)) {
536 case IDC_CDMOUNT_SELFILE:
537 s_imgfile = get_fileopen_dlg (dlg, _("Select Crypdisk Volume"),
538 NULL, NULL);
539 if (s_imgfile != NULL)
540 SetDlgItemText (dlg, IDC_CDMOUNT_IMGFILE, s_imgfile);
541 break;
542
543 case IDOK:
544 n = item_get_text_length (dlg, IDC_CDMOUNT_IMGFILE);
545 if (!n) {
546 msg_box (dlg, _("Please enter the name of the image file."),
547 _("Cryptdisk Error"), MB_ERR);
548 return FALSE;
549 }
550 n = item_get_text_length (dlg, IDC_CDMOUNT_PASS);
551 if (!n) {
552 msg_box (dlg, _("Please enter a password."),
553 _("Cryptdisk Error"), MB_ERR);
554 return FALSE;
555 }
556 devnum = GetDlgItemInt (dlg, IDC_CDMOUNT_ID, NULL, FALSE);
557 GetDlgItemText (dlg, IDC_CDMOUNT_DRV, drive, sizeof drive-1);
558 GetDlgItemText (dlg, IDC_CDMOUNT_PASS, passwd, sizeof passwd-1);
559 GetDlgItemText (dlg, IDC_CDMOUNT_IMGFILE, imgfile, sizeof imgfile-1);
560 if (file_exist_check (imgfile)) {
561 msg_box (dlg, _("Image file does not exist or could not be accessed."),
562 _("Cryptdisk Error"), MB_ERR);
563 return FALSE;
564 }
565 rc = cryptdisk_mount (devnum, imgfile, 0, drive);
566 if (!rc) {
567 mount_list_t t = new_mount_list (drive, devnum);
568 if (!mounted)
569 mounted = t;
570 else
571 add_mount_list (mounted, t);
572 EndDialog (dlg, TRUE);
573 }
574 else
575 msg_box (dlg, winpt_strerror (rc), _("Cryptdisk Error"), MB_ERR);
576 break;
577
578 case IDCANCEL:
579 EndDialog (dlg, FALSE);
580 break;
581 }
582 break;
583 }
584 return FALSE;
585 }
586
587
588 static void
589 load_devs_from_mountlist (HWND dlg, int ctlid)
590 {
591 mount_list_t n;
592 char buf[128];
593
594 if (!mounted)
595 return;
596
597 for (n=mounted; n; n=n->next) {
598 if (n->ttl == 0)
599 continue;
600 _snprintf (buf, sizeof buf-1, _("Drive %s (ID %d); Size %d MB, Readonly=%s"),
601 n->drive, n->devnum, n->size.LowPart/1024/1024,
602 n->rdonly? "true" : "false");
603 SendDlgItemMessage (dlg, ctlid, LB_ADDSTRING, 0, (LPARAM)(const char *)buf);
604 }
605
606 }
607
608
609 static void
610 do_reaping (void)
611 {
612 mount_list_t n;
613 int ndevs=0, numount=0;
614
615 for (n=mounted; n; n=n->next) {
616 if (n->ttl == 0)
617 numount++;
618 ndevs++;
619 }
620 if (ndevs == numount) {
621 free_mount_list (mounted);
622 mounted = NULL;
623 }
624 }
625
626
627 BOOL CALLBACK
628 cryptdisk_umount_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
629 {
630 mount_list_t vol;
631 char buf[128];
632 int n, rc=0;
633
634 switch (msg) {
635 case WM_INITDIALOG:
636 do_check (dlg);
637 load_devs_from_mountlist (dlg, IDC_CDUMOUNT_LIST);
638 center_window (dlg, NULL);
639 SetForegroundWindow (dlg);
640 break;
641
642 case WM_DESTROY:
643 do_reaping ();
644 break;
645
646 case WM_COMMAND:
647 switch (LOWORD (wparam)) {
648 case IDOK:
649 n = SendDlgItemMessage (dlg, IDC_CDUMOUNT_LIST, LB_GETCURSEL, 0, 0);
650 if (n == LB_ERR) {
651 msg_box (dlg, _("Please select one drive to umount."), _("Cryptdisk"), MB_INFO);
652 return FALSE;
653 }
654 SendDlgItemMessage (dlg, IDC_CDUMOUNT_LIST, LB_GETTEXT, n,
655 (LPARAM)(char *)buf);
656 strcpy (buf, buf+6);
657 buf[2] = '\0';
658 vol = find_mount_list (mounted, buf);
659 if (!vol)
660 BUG (0);
661 rc = cryptdisk_unmount (buf[0], 0);
662 //if (rc == WPTERR_CDISK_LOCK)
663 // rc = cryptdisk_unmount (buf[0], 0);
664 if (!rc) {
665 SendDlgItemMessage (dlg, IDC_CDUMOUNT_LIST, LB_DELETESTRING, (WPARAM)n, 0);
666 remove_mount_list (mounted, vol);
667 }
668 else
669 msg_box (dlg, winpt_strerror (rc), _("Cryptdisk Error"), MB_ERR);
670 break;
671 case IDCANCEL:
672 EndDialog (dlg, FALSE);
673 break;
674 }
675 break;
676 }
677
678 return FALSE;
679 }
680
681
682 int
683 cryptdisk_serv_run (void)
684 {
685 SC_HANDLE hd;
686 ENUM_SERVICE_STATUS ess[4096];
687 DWORD nservs=0, dummy=0;
688 DWORD i;
689 int rc=0;
690
691 hd = OpenSCManager (NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
692 if (!hd)
693 return 0;
694
695 EnumServicesStatus (hd, SERVICE_DRIVER, SERVICE_ACTIVE,
696 (LPENUM_SERVICE_STATUS)&ess,
697 sizeof ess-1, &dummy, &nservs, &dummy);
698
699 for (i=0; i < nservs; i++) {
700 if (!strnicmp ("FileDisk", ess[i].lpDisplayName, 8)) {
701 rc = 1;
702 break;
703 }
704 }
705
706 CloseServiceHandle (hd);
707 return rc;
708 }
709 #endif

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26