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