VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/ExpandVolume/WinMain.cpp
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2015-01-20 09:02:17 +0100
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2015-01-20 12:42:04 +0100
commit1efb78266631d4c3aa0cd28e32485a9f2016f9de (patch)
treee6c5bda4e202e4858e2f27db8413356e9ccd875f /src/ExpandVolume/WinMain.cpp
parent38f3fc816ac1a9f894bc01a6cf9d9b97c2a2e21a (diff)
downloadVeraCrypt-1efb78266631d4c3aa0cd28e32485a9f2016f9de.tar.gz
VeraCrypt-1efb78266631d4c3aa0cd28e32485a9f2016f9de.zip
Windows: Add first version of VeraCryptExpander who is based on extcv. Minor modification to Mount.c to avoid link errors when building VeraCryptExpander.
Diffstat (limited to 'src/ExpandVolume/WinMain.cpp')
-rw-r--r--src/ExpandVolume/WinMain.cpp971
1 files changed, 971 insertions, 0 deletions
diff --git a/src/ExpandVolume/WinMain.cpp b/src/ExpandVolume/WinMain.cpp
new file mode 100644
index 00000000..7940b3d2
--- /dev/null
+++ b/src/ExpandVolume/WinMain.cpp
@@ -0,0 +1,971 @@
+/*
+
+Most of the source code contained in this file is taken from the source code of
+TrueCrypt 7.0a, which is governed by the TrueCrypt License 3.0 that can be found
+in the file 'License.txt' in the folder 'TrueCrypt-License'.
+
+Modifications and additions to the original source code (contained in this file)
+and all other portions of this file are Copyright (c) 2009-2010 by Kih-Oskh or
+Copyright (c) 2012-2013 Josef Schneider <josef@netpage.dk>
+
+
+Source code in this file is derived from 'Mount\Mount.c'
+
+-------------------------------------------------------------------------------
+
+Original legal notice of the TrueCrypt source:
+
+ Legal Notice: Some portions of the source code contained in this file were
+ derived from the source code of Encryption for the Masses 2.02a, which is
+ Copyright (c) 1998-2000 Paul Le Roux and which is governed by the 'License
+ Agreement for Encryption for the Masses'. Modifications and additions to
+ the original source code (contained in this file) and all other portions
+ of this file are Copyright (c) 2003-2009 TrueCrypt Developers Association
+ and are governed by the TrueCrypt License 3.0 the full text of which is
+ contained in the file License.txt included in TrueCrypt binary and source
+ code distribution packages.
+
+*/
+
+#include "Tcdefs.h"
+
+#include <time.h>
+#include <math.h>
+#include <dbt.h>
+#include <fcntl.h>
+#include <io.h>
+#include <sys/stat.h>
+#include <windowsx.h>
+
+#include "Apidrvr.h"
+#include "BootEncryption.h"
+#include "Cmdline.h"
+#include "Crypto.h"
+#include "Dlgcode.h"
+#include "Combo.h"
+#include "Keyfiles.h"
+#include "Language.h"
+#include "../Mount/MainCom.h"
+#include "../Mount/Mount.h"
+#include "Pkcs5.h"
+#include "Random.h"
+#include "Registry.h"
+#include "Resource.h"
+#include "Password.h"
+#include "Xml.h"
+#include "../Boot/Windows/BootCommon.h"
+#include "../Common/Dictionary.h"
+#include "../Common/Common.h"
+#include "../Common/Resource.h"
+#include "../Common/SecurityToken.h"
+#include "../Platform/Finally.h"
+#include "../Platform/ForEach.h"
+#include <Strsafe.h>
+
+#include "ExpandVolume.h"
+
+using namespace VeraCrypt;
+
+const char szExpandVolumeInfo[] =
+":: VeraCrypt Expander ::\n\nExpand a VeraCrypt volume on the fly without reformatting\n\n\n\
+All kind of volumes (container files, disks and partitions) formatted with \
+NTFS are supported. The only condition is that there must be enough free \
+space on the host drive or host device of the VeraCrypt volume.\n\n\
+Do not use this software to expand an outer volume containing a hidden \
+volume, because this destroys the hidden volume!\n\
+";
+
+enum timer_ids
+{
+ TIMER_ID_MAIN = 0xff,
+ TIMER_ID_KEYB_LAYOUT_GUARD
+};
+
+enum hidden_os_read_only_notif_mode
+{
+ TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE = 0,
+ TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_COMPACT,
+ TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_DISABLED
+};
+
+#define TIMER_INTERVAL_MAIN 500
+#define TIMER_INTERVAL_KEYB_LAYOUT_GUARD 10
+
+namespace VeraCryptExpander
+{
+
+BOOL bExplore = FALSE; /* Display explorer window after mount */
+BOOL bBeep = FALSE; /* Donot beep after mount */
+char szFileName[TC_MAX_PATH+1]; /* Volume to mount */
+char szDriveLetter[3]; /* Drive Letter to mount */
+char commandLineDrive = 0;
+BOOL bCacheInDriver = FALSE; /* Cache any passwords we see */
+BOOL bCacheInDriverDefault = FALSE;
+BOOL bHistoryCmdLine = FALSE; /* History control is always disabled */
+BOOL bCloseDismountedWindows=TRUE; /* Close all open explorer windows of dismounted volume */
+BOOL bWipeCacheOnExit = FALSE; /* Wipe password from chace on exit */
+BOOL bWipeCacheOnAutoDismount = TRUE;
+BOOL bEnableBkgTask = FALSE;
+BOOL bCloseBkgTaskWhenNoVolumes = FALSE;
+BOOL bDismountOnLogOff = TRUE;
+BOOL bDismountOnScreenSaver = TRUE;
+BOOL bDismountOnPowerSaving = FALSE;
+BOOL bForceAutoDismount = TRUE;
+BOOL bForceMount = FALSE; /* Mount volume even if host file/device already in use */
+BOOL bForceUnmount = FALSE; /* Unmount volume even if it cannot be locked */
+BOOL bWipe = FALSE; /* Wipe driver passwords */
+BOOL bAuto = FALSE; /* Do everything without user input */
+BOOL bAutoMountDevices = FALSE; /* Auto-mount devices */
+BOOL bAutoMountFavorites = FALSE;
+BOOL bPlaySoundOnHotkeyMountDismount = TRUE;
+BOOL bDisplayMsgBoxOnHotkeyDismount = FALSE;
+BOOL bHibernationPreventionNotified = FALSE; /* TRUE if the user has been notified that hibernation was prevented (system encryption) during the session. */
+BOOL bHiddenSysLeakProtNotifiedDuringSession = FALSE; /* TRUE if the user has been notified during the session that unencrypted filesystems and non-hidden VeraCrypt volumes are mounted as read-only under hidden OS. */
+BOOL CloseSecurityTokenSessionsAfterMount = FALSE;
+
+BOOL MultipleMountOperationInProgress = FALSE;
+
+BOOL Quit = FALSE; /* Exit after processing command line */
+BOOL ComServerMode = FALSE;
+BOOL UsePreferences = TRUE;
+
+int HiddenSysLeakProtectionNotificationStatus = TC_HIDDEN_OS_READ_ONLY_NOTIF_MODE_NONE;
+int MaxVolumeIdleTime = -120;
+int nCurrentShowType = 0; /* current display mode, mount, unmount etc */
+int nSelectedDriveIndex = -1; /* Item number of selected drive */
+
+int cmdUnmountDrive = 0; /* Volume drive letter to unmount (-1 = all) */
+Password VolumePassword; /* Password used for mounting volumes */
+Password CmdVolumePassword; /* Password passed from command line */
+BOOL CmdVolumePasswordValid = FALSE;
+MountOptions mountOptions;
+MountOptions defaultMountOptions;
+KeyFile *FirstCmdKeyFile;
+
+HBITMAP hbmLogoBitmapRescaled = NULL;
+char OrigKeyboardLayout [8+1] = "00000409";
+BOOL bKeyboardLayoutChanged = FALSE; /* TRUE if the keyboard layout was changed to the standard US keyboard layout (from any other layout). */
+BOOL bKeybLayoutAltKeyWarningShown = FALSE; /* TRUE if the user has been informed that it is not possible to type characters by pressing keys while the right Alt key is held down. */
+
+static KeyFilesDlgParam hidVolProtKeyFilesParam;
+VOLUME_NOTIFICATIONS_LIST VolumeNotificationsList;
+
+static int bPrebootPasswordDlgMode = FALSE;
+
+static void localcleanup (void)
+{
+ // Wipe command line
+ char *c = GetCommandLineA ();
+ wchar_t *wc = GetCommandLineW ();
+ burn(c, strlen (c));
+ burn(wc, wcslen (wc) * sizeof (wchar_t));
+
+ /* Delete buffered bitmaps (if any) */
+ if (hbmLogoBitmapRescaled != NULL)
+ {
+ DeleteObject ((HGDIOBJ) hbmLogoBitmapRescaled);
+ hbmLogoBitmapRescaled = NULL;
+ }
+
+ /* These items should have already been cleared by the functions that used them, but we're going to
+ clear them for extra security. */
+ burn (&VolumePassword, sizeof (VolumePassword));
+ burn (&CmdVolumePassword, sizeof (CmdVolumePassword));
+ burn (&mountOptions, sizeof (mountOptions));
+ burn (&defaultMountOptions, sizeof (defaultMountOptions));
+ burn (&szFileName, sizeof(szFileName));
+
+ /* Cleanup common code resources */
+ cleanup ();
+
+ RandStop (TRUE);
+}
+
+
+void EndMainDlg (HWND hwndDlg)
+{
+ if (!bHistory)
+ {
+ SetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), "");
+ }
+
+ EndDialog (hwndDlg, 0);
+}
+
+BOOL CALLBACK MountOptionsDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ // dummy (referenced by PasswordDlgProc() )
+ return FALSE;
+}
+BOOL TCBootLoaderOnInactiveSysEncDrive (void)
+{
+ // dummy (referenced by Dlgcode.c)
+ return FALSE;
+}
+
+BOOL CheckSysEncMountWithoutPBA (const char *devicePath, BOOL quiet)
+{
+ // dummy (referenced by Dlgcode.c)
+ return FALSE;
+}
+
+static void InitMainDialog (HWND hwndDlg)
+{
+ /* Call the common dialog init code */
+ InitDialog (hwndDlg);
+ LocalizeDialog (hwndDlg, NULL);
+
+ SendMessage (GetDlgItem (hwndDlg, IDC_VOLUME), CB_LIMITTEXT, TC_MAX_PATH, 0);
+ SetWindowTextW (hwndDlg, lpszTitle);
+
+ SendMessage (GetDlgItem (hwndDlg, IDC_INFOEXPAND), WM_SETFONT, (WPARAM) hBoldFont, (LPARAM) TRUE);
+ SetWindowText (GetDlgItem (hwndDlg, IDC_INFOEXPAND), szExpandVolumeInfo);
+
+ // Resize the logo bitmap if the user has a non-default DPI
+ if (ScreenDPI != USER_DEFAULT_SCREEN_DPI
+ && hbmLogoBitmapRescaled == NULL) // If not re-called (e.g. after language pack change)
+ {
+ hbmLogoBitmapRescaled = RenderBitmap (MAKEINTRESOURCE (IDB_LOGO_288DPI),
+ GetDlgItem (hwndDlg, IDC_LOGO),
+ 0, 0, 0, 0, FALSE, TRUE);
+ }
+
+ EnableDisableButtons (hwndDlg);
+}
+
+void EnableDisableButtons (HWND hwndDlg)
+{
+ HWND hOKButton = GetDlgItem (hwndDlg, IDOK);
+ WORD x;
+
+ x = LOWORD (GetSelectedLong (GetDlgItem (hwndDlg, IDC_DRIVELIST)));
+
+ EnableWindow (hOKButton, TRUE);
+
+}
+
+BOOL VolumeSelected (HWND hwndDlg)
+{
+ return (GetWindowTextLength (GetDlgItem (hwndDlg, IDC_VOLUME)) > 0);
+}
+
+
+void LoadSettings (HWND hwndDlg)
+{
+ WipeAlgorithmId savedWipeAlgorithm = TC_WIPE_NONE;
+
+ LoadSysEncSettings (hwndDlg);
+
+ if (LoadNonSysInPlaceEncSettings (&savedWipeAlgorithm) != 0)
+ bInPlaceEncNonSysPending = TRUE;
+
+ // If the config file has already been loaded during this session
+ if (ConfigBuffer != NULL)
+ {
+ free (ConfigBuffer);
+ ConfigBuffer = NULL;
+ }
+
+ // Options
+ bExplore = ConfigReadInt ("OpenExplorerWindowAfterMount", FALSE);
+ bCloseDismountedWindows = ConfigReadInt ("CloseExplorerWindowsOnDismount", TRUE);
+
+ bHistory = ConfigReadInt ("SaveVolumeHistory", FALSE);
+
+ bCacheInDriverDefault = bCacheInDriver = ConfigReadInt ("CachePasswords", FALSE);
+ bWipeCacheOnExit = ConfigReadInt ("WipePasswordCacheOnExit", FALSE);
+ bWipeCacheOnAutoDismount = ConfigReadInt ("WipeCacheOnAutoDismount", TRUE);
+
+ bStartOnLogon = ConfigReadInt ("StartOnLogon", FALSE);
+ bMountDevicesOnLogon = ConfigReadInt ("MountDevicesOnLogon", FALSE);
+ bMountFavoritesOnLogon = ConfigReadInt ("MountFavoritesOnLogon", FALSE);
+
+ bEnableBkgTask = ConfigReadInt ("EnableBackgroundTask", TRUE);
+ bCloseBkgTaskWhenNoVolumes = ConfigReadInt ("CloseBackgroundTaskOnNoVolumes", FALSE);
+
+ bDismountOnLogOff = ConfigReadInt ("DismountOnLogOff", TRUE);
+ bDismountOnPowerSaving = ConfigReadInt ("DismountOnPowerSaving", FALSE);
+ bDismountOnScreenSaver = ConfigReadInt ("DismountOnScreenSaver", FALSE);
+ bForceAutoDismount = ConfigReadInt ("ForceAutoDismount", TRUE);
+ MaxVolumeIdleTime = ConfigReadInt ("MaxVolumeIdleTime", -60);
+
+ HiddenSectorDetectionStatus = ConfigReadInt ("HiddenSectorDetectionStatus", 0);
+
+ defaultKeyFilesParam.EnableKeyFiles = ConfigReadInt ("UseKeyfiles", FALSE);
+
+ bPreserveTimestamp = defaultMountOptions.PreserveTimestamp = ConfigReadInt ("PreserveTimestamps", TRUE);
+ defaultMountOptions.Removable = ConfigReadInt ("MountVolumesRemovable", FALSE);
+ defaultMountOptions.ReadOnly = ConfigReadInt ("MountVolumesReadOnly", FALSE);
+ defaultMountOptions.ProtectHiddenVolume = FALSE;
+ defaultMountOptions.PartitionInInactiveSysEncScope = FALSE;
+ defaultMountOptions.RecoveryMode = FALSE;
+ defaultMountOptions.UseBackupHeader = FALSE;
+
+ mountOptions = defaultMountOptions;
+
+ CloseSecurityTokenSessionsAfterMount = ConfigReadInt ("CloseSecurityTokenSessionsAfterMount", 0);
+
+ ConfigReadString ("SecurityTokenLibrary", "", SecurityTokenLibraryPath, sizeof (SecurityTokenLibraryPath) - 1);
+ if (SecurityTokenLibraryPath[0])
+ InitSecurityTokenLibrary(hwndDlg);
+
+ /* we don't load the history */
+}
+
+
+BOOL SelectItem (HWND hTree, char nLetter)
+{
+ int i;
+ LVITEM item;
+
+ for (i = 0; i < ListView_GetItemCount(hTree); i++)
+ {
+ memset(&item, 0, sizeof(LVITEM));
+ item.mask = LVIF_PARAM;
+ item.iItem = i;
+
+ if (ListView_GetItem (hTree, &item) == FALSE)
+ return FALSE;
+ else
+ {
+ if (HIWORD (item.lParam) == nLetter)
+ {
+ memset(&item, 0, sizeof(LVITEM));
+ item.state = LVIS_FOCUSED|LVIS_SELECTED;
+ item.stateMask = LVIS_FOCUSED|LVIS_SELECTED;
+ item.mask = LVIF_STATE;
+ item.iItem = i;
+ SendMessage(hTree, LVM_SETITEMSTATE, i, (LPARAM) &item);
+ return TRUE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+
+LPARAM
+GetSelectedLong (HWND hTree)
+{
+ int hItem = ListView_GetSelectionMark (hTree);
+ LVITEM item;
+
+ if (nSelectedDriveIndex >= 0)
+ hItem = nSelectedDriveIndex;
+
+ memset(&item, 0, sizeof(LVITEM));
+ item.mask = LVIF_PARAM;
+ item.iItem = hItem;
+
+ if (ListView_GetItem (hTree, &item) == FALSE)
+ return MAKELONG (0xffff, 0xffff);
+ else
+ return item.lParam;
+}
+
+LPARAM
+GetItemLong (HWND hTree, int itemNo)
+{
+ LVITEM item;
+
+ memset(&item, 0, sizeof(LVITEM));
+ item.mask = LVIF_PARAM;
+ item.iItem = itemNo;
+
+ if (ListView_GetItem (hTree, &item) == FALSE)
+ return MAKELONG (0xffff, 0xffff);
+ else
+ return item.lParam;
+}
+
+static char PasswordDlgVolume[MAX_PATH + 1];
+static BOOL PasswordDialogDisableMountOptions;
+static char *PasswordDialogTitleStringId;
+
+/* Except in response to the WM_INITDIALOG message, the dialog box procedure
+ should return nonzero if it processes the message, and zero if it does
+ not. - see DialogProc */
+BOOL CALLBACK ExtcvPasswordDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ WORD lw = LOWORD (wParam);
+ static Password *szXPwd;
+ static int *pkcs5;
+ static BOOL* truecryptMode;
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ int i, nIndex;
+ szXPwd = ((PasswordDlgParam *) lParam) -> password;
+ pkcs5 = ((PasswordDlgParam *) lParam) -> pkcs5;
+ truecryptMode = ((PasswordDlgParam *) lParam) -> truecryptMode;
+ LocalizeDialog (hwndDlg, "IDD_PASSWORD_DLG");
+ DragAcceptFiles (hwndDlg, TRUE);
+
+ if (PasswordDialogTitleStringId)
+ {
+ SetWindowTextW (hwndDlg, GetString (PasswordDialogTitleStringId));
+ }
+ else if (strlen (PasswordDlgVolume) > 0)
+ {
+ wchar_t s[1024];
+ const int maxVisibleLen = 40;
+
+ if (strlen (PasswordDlgVolume) > maxVisibleLen)
+ {
+ string volStr = PasswordDlgVolume;
+ StringCbPrintfW (s, sizeof(s), GetString ("ENTER_PASSWORD_FOR"), ("..." + volStr.substr (volStr.size() - maxVisibleLen - 1)).c_str());
+ }
+ else
+ StringCbPrintfW (s, sizeof(s), GetString ("ENTER_PASSWORD_FOR"), PasswordDlgVolume);
+
+ SetWindowTextW (hwndDlg, s);
+ }
+
+ /* Populate the PRF algorithms list */
+ HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID);
+ SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
+
+ nIndex = SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION"));
+ SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0);
+
+ for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++)
+ {
+ nIndex = SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i));
+ SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i);
+ }
+
+ /* make autodetection the default */
+ SendMessage (hComboBox, CB_SETCURSEL, 0, 0);
+
+ SendMessage (GetDlgItem (hwndDlg, IDC_PASSWORD), EM_LIMITTEXT, MAX_PASSWORD, 0);
+ SendMessage (GetDlgItem (hwndDlg, IDC_CACHE), BM_SETCHECK, bCacheInDriver ? BST_CHECKED:BST_UNCHECKED, 0);
+
+ SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable);
+
+ mountOptions.PartitionInInactiveSysEncScope = bPrebootPasswordDlgMode;
+
+ if (bPrebootPasswordDlgMode)
+ {
+ SendMessage (hwndDlg, TC_APPMSG_PREBOOT_PASSWORD_MODE, 0, 0);
+ }
+
+ if (PasswordDialogDisableMountOptions)
+ {
+ EnableWindow (GetDlgItem (hwndDlg, IDC_CACHE), FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_MOUNT_OPTIONS), FALSE);
+ }
+
+ /* No support for mounting TrueCrypt volumes */
+ SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_TRUECRYPT_MODE), FALSE);
+
+ if (!SetForegroundWindow (hwndDlg) && (FavoriteMountOnArrivalInProgress))
+ {
+ SetWindowPos (hwndDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+
+ FLASHWINFO flash;
+ flash.cbSize = sizeof (flash);
+ flash.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG;
+ flash.dwTimeout = 0;
+ flash.hwnd = hwndDlg;
+ flash.uCount = 0;
+
+ FlashWindowEx (&flash);
+
+ SetWindowPos (hwndDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+ }
+ }
+ return 0;
+
+ case TC_APPMSG_PREBOOT_PASSWORD_MODE:
+ {
+ /* No support for mounting TrueCrypt system partition */
+ SetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE, FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_TRUECRYPT_MODE), FALSE);
+
+ /* Repopulate the PRF algorithms list with algorithms that support system encryption */
+ HWND hComboBox = GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID);
+ SendMessage (hComboBox, CB_RESETCONTENT, 0, 0);
+
+ int i, nIndex = SendMessageW (hComboBox, CB_ADDSTRING, 0, (LPARAM) GetString ("AUTODETECTION"));
+ SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) 0);
+
+ for (i = FIRST_PRF_ID; i <= LAST_PRF_ID; i++)
+ {
+ if (HashForSystemEncryption(i))
+ {
+ nIndex = SendMessage (hComboBox, CB_ADDSTRING, 0, (LPARAM) get_pkcs5_prf_name(i));
+ SendMessage (hComboBox, CB_SETITEMDATA, nIndex, (LPARAM) i);
+ }
+ }
+
+ /* make autodetection the default */
+ SendMessage (hComboBox, CB_SETCURSEL, 0, 0);
+
+ ToBootPwdField (hwndDlg, IDC_PASSWORD);
+
+ // Attempt to wipe the password stored in the input field buffer
+ char tmp[MAX_PASSWORD+1];
+ memset (tmp, 'X', MAX_PASSWORD);
+ tmp [MAX_PASSWORD] = 0;
+ SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp);
+ SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), "");
+
+ StringCbPrintfA (OrigKeyboardLayout, sizeof(OrigKeyboardLayout),"%08X", (DWORD) GetKeyboardLayout (NULL) & 0xFFFF);
+
+ DWORD keybLayout = (DWORD) LoadKeyboardLayout ("00000409", KLF_ACTIVATE);
+
+ if (keybLayout != 0x00000409 && keybLayout != 0x04090409)
+ {
+ Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", hwndDlg);
+ EndDialog (hwndDlg, IDCANCEL);
+ return 1;
+ }
+
+ if (SetTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD, TIMER_INTERVAL_KEYB_LAYOUT_GUARD, NULL) == 0)
+ {
+ Error ("CANNOT_SET_TIMER", hwndDlg);
+ EndDialog (hwndDlg, IDCANCEL);
+ return 1;
+ }
+
+ SetCheckBox (hwndDlg, IDC_SHOW_PASSWORD, FALSE);
+ EnableWindow (GetDlgItem (hwndDlg, IDC_SHOW_PASSWORD), FALSE);
+
+ SendMessage (GetDlgItem (hwndDlg, IDC_PASSWORD), EM_SETPASSWORDCHAR, '*', 0);
+ InvalidateRect (GetDlgItem (hwndDlg, IDC_PASSWORD), NULL, TRUE);
+
+ bPrebootPasswordDlgMode = TRUE;
+ }
+ return 1;
+
+ case WM_TIMER:
+ switch (wParam)
+ {
+ case TIMER_ID_KEYB_LAYOUT_GUARD:
+ if (bPrebootPasswordDlgMode)
+ {
+ DWORD keybLayout = (DWORD) GetKeyboardLayout (NULL);
+
+ if (keybLayout != 0x00000409 && keybLayout != 0x04090409)
+ {
+ // Keyboard layout is not standard US
+
+ // Attempt to wipe the password stored in the input field buffer
+ char tmp[MAX_PASSWORD+1];
+ memset (tmp, 'X', MAX_PASSWORD);
+ tmp [MAX_PASSWORD] = 0;
+ SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp);
+ SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), "");
+
+ keybLayout = (DWORD) LoadKeyboardLayout ("00000409", KLF_ACTIVATE);
+
+ if (keybLayout != 0x00000409 && keybLayout != 0x04090409)
+ {
+ KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD);
+ Error ("CANT_CHANGE_KEYB_LAYOUT_FOR_SYS_ENCRYPTION", hwndDlg);
+ EndDialog (hwndDlg, IDCANCEL);
+ return 1;
+ }
+
+ wchar_t szTmp [4096];
+ StringCbCopyW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_CHANGE_PREVENTED"));
+ StringCbCatW (szTmp, sizeof(szTmp), L"\n\n");
+ StringCbCatW (szTmp, sizeof(szTmp), GetString ("KEYB_LAYOUT_SYS_ENC_EXPLANATION"));
+ MessageBoxW (MainDlg, szTmp, lpszTitle, MB_ICONWARNING | MB_SETFOREGROUND | MB_TOPMOST);
+ }
+ }
+ return 1;
+ }
+ return 0;
+
+ case WM_COMMAND:
+
+ if (lw == IDC_MOUNT_OPTIONS)
+ {
+ DialogBoxParamW (hInst,
+ MAKEINTRESOURCEW (IDD_MOUNT_OPTIONS), hwndDlg,
+ (DLGPROC) MountOptionsDlgProc, (LPARAM) &mountOptions);
+
+ if (!bPrebootPasswordDlgMode && mountOptions.PartitionInInactiveSysEncScope)
+ SendMessage (hwndDlg, TC_APPMSG_PREBOOT_PASSWORD_MODE, 0, 0);
+
+ return 1;
+ }
+
+ if (lw == IDC_SHOW_PASSWORD)
+ {
+ SendMessage (GetDlgItem (hwndDlg, IDC_PASSWORD),
+ EM_SETPASSWORDCHAR,
+ GetCheckBox (hwndDlg, IDC_SHOW_PASSWORD) ? 0 : '*',
+ 0);
+ InvalidateRect (GetDlgItem (hwndDlg, IDC_PASSWORD), NULL, TRUE);
+ return 1;
+ }
+
+ if (lw == IDC_KEY_FILES)
+ {
+ KeyFilesDlgParam param;
+ param.EnableKeyFiles = KeyFilesEnable;
+ param.FirstKeyFile = FirstKeyFile;
+
+ if (IDOK == DialogBoxParamW (hInst,
+ MAKEINTRESOURCEW (IDD_KEYFILES), hwndDlg,
+ (DLGPROC) KeyFilesDlgProc, (LPARAM) &param))
+ {
+ KeyFilesEnable = param.EnableKeyFiles;
+ FirstKeyFile = param.FirstKeyFile;
+
+ SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable);
+ }
+
+ return 1;
+ }
+
+ if (lw == IDC_KEYFILES_ENABLE)
+ {
+ KeyFilesEnable = GetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE);
+
+ return 1;
+ }
+
+ if (lw == IDCANCEL || lw == IDOK)
+ {
+ char tmp[MAX_PASSWORD+1];
+
+ if (lw == IDOK)
+ {
+ if (mountOptions.ProtectHiddenVolume && hidVolProtKeyFilesParam.EnableKeyFiles)
+ KeyFilesApply (hwndDlg, &mountOptions.ProtectedHidVolPassword, hidVolProtKeyFilesParam.FirstKeyFile);
+
+ GetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), (LPSTR) szXPwd->Text, MAX_PASSWORD + 1);
+ szXPwd->Length = strlen ((char *) szXPwd->Text);
+
+ bCacheInDriver = IsButtonChecked (GetDlgItem (hwndDlg, IDC_CACHE));
+ *pkcs5 = (int) SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETITEMDATA, SendMessage (GetDlgItem (hwndDlg, IDC_PKCS5_PRF_ID), CB_GETCURSEL, 0, 0), 0);
+ *truecryptMode = GetCheckBox (hwndDlg, IDC_TRUECRYPT_MODE);
+ /* SHA-256 is not supported by TrueCrypt */
+ if ( (*truecryptMode)
+ && ((*pkcs5 == SHA256) || (mountOptions.ProtectHiddenVolume && mountOptions.ProtectedHidVolPkcs5Prf == SHA256))
+ )
+ {
+ Error ("ALGO_NOT_SUPPORTED_FOR_TRUECRYPT_MODE", hwndDlg);
+ return 1;
+ }
+ }
+
+ // Attempt to wipe password stored in the input field buffer
+ memset (tmp, 'X', MAX_PASSWORD);
+ tmp[MAX_PASSWORD] = 0;
+ SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD), tmp);
+ SetWindowText (GetDlgItem (hwndDlg, IDC_PASSWORD_PROT_HIDVOL), tmp);
+
+ if (hidVolProtKeyFilesParam.FirstKeyFile != NULL)
+ {
+ KeyFileRemoveAll (&hidVolProtKeyFilesParam.FirstKeyFile);
+ hidVolProtKeyFilesParam.EnableKeyFiles = FALSE;
+ }
+
+ if (bPrebootPasswordDlgMode)
+ {
+ KillTimer (hwndDlg, TIMER_ID_KEYB_LAYOUT_GUARD);
+
+ // Restore the original keyboard layout
+ if (LoadKeyboardLayout (OrigKeyboardLayout, KLF_ACTIVATE | KLF_SUBSTITUTE_OK) == NULL)
+ Warning ("CANNOT_RESTORE_KEYBOARD_LAYOUT", hwndDlg);
+ }
+
+ EndDialog (hwndDlg, lw);
+ return 1;
+ }
+ return 0;
+
+ case WM_CONTEXTMENU:
+ {
+ RECT buttonRect;
+ GetWindowRect (GetDlgItem (hwndDlg, IDC_KEY_FILES), &buttonRect);
+
+ if (LOWORD (lParam) >= buttonRect.left && LOWORD (lParam) <= buttonRect.right
+ && HIWORD (lParam) >= buttonRect.top && HIWORD (lParam) <= buttonRect.bottom)
+ {
+ // The "Keyfiles" button has been right-clicked
+
+ KeyFilesDlgParam param;
+ param.EnableKeyFiles = KeyFilesEnable;
+ param.FirstKeyFile = FirstKeyFile;
+
+ POINT popupPos;
+ popupPos.x = buttonRect.left + 2;
+ popupPos.y = buttonRect.top + 2;
+
+ if (KeyfilesPopupMenu (hwndDlg, popupPos, &param))
+ {
+ KeyFilesEnable = param.EnableKeyFiles;
+ FirstKeyFile = param.FirstKeyFile;
+ SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable);
+ }
+ }
+ }
+ break;
+
+ case WM_DROPFILES:
+ {
+ HDROP hdrop = (HDROP) wParam;
+ int i = 0, count = DragQueryFile (hdrop, 0xFFFFFFFF, NULL, 0);
+
+ while (count-- > 0)
+ {
+ KeyFile *kf = (KeyFile *) malloc (sizeof (KeyFile));
+ if (kf)
+ {
+ DragQueryFile (hdrop, i++, kf->FileName, sizeof (kf->FileName));
+ FirstKeyFile = KeyFileAdd (FirstKeyFile, kf);
+ KeyFilesEnable = TRUE;
+ }
+ }
+
+ SetCheckBox (hwndDlg, IDC_KEYFILES_ENABLE, KeyFilesEnable);
+ DragFinish (hdrop);
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
+void SaveSettings (HWND hwndDlg)
+{
+ // dummy
+}
+
+int BackupVolumeHeader (HWND hwndDlg, BOOL bRequireConfirmation, char *lpszVolume)
+{
+ // dummy
+ return 0;
+}
+
+int RestoreVolumeHeader (HWND hwndDlg, char *lpszVolume)
+{
+ // dummy
+ return 0;
+}
+
+int ExtcvAskVolumePassword (HWND hwndDlg, Password *password, int *pkcs5, BOOL* truecryptMode, char *titleStringId, BOOL enableMountOptions)
+{
+ int result;
+ PasswordDlgParam dlgParam;
+
+ PasswordDialogTitleStringId = titleStringId;
+ PasswordDialogDisableMountOptions = !enableMountOptions;
+
+ dlgParam.password = password;
+ dlgParam.pkcs5 = pkcs5;
+ dlgParam.truecryptMode = truecryptMode;
+
+ result = DialogBoxParamW (hInst,
+ MAKEINTRESOURCEW (IDD_PASSWORD_DLG), hwndDlg,
+ (DLGPROC) ExtcvPasswordDlgProc, (LPARAM) &dlgParam);
+
+ if (result != IDOK)
+ {
+ password->Length = 0;
+ *pkcs5 = 0;
+ *truecryptMode = FALSE;
+ burn (&mountOptions.ProtectedHidVolPassword, sizeof (mountOptions.ProtectedHidVolPassword));
+ burn (&mountOptions.ProtectedHidVolPkcs5Prf, sizeof (mountOptions.ProtectedHidVolPkcs5Prf));
+ }
+
+ return result == IDOK;
+}
+
+// GUI actions
+
+static BOOL SelectContainer (HWND hwndDlg)
+{
+ if (BrowseFiles (hwndDlg, "OPEN_VOL_TITLE", szFileName, bHistory, FALSE, NULL) == FALSE)
+ return FALSE;
+
+ AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory);
+ VeraCryptExpander::EnableDisableButtons (hwndDlg);
+ SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST));
+ return TRUE;
+}
+
+static BOOL SelectPartition (HWND hwndDlg)
+{
+ int nResult = DialogBoxParamW (hInst, MAKEINTRESOURCEW (IDD_RAWDEVICES_DLG), hwndDlg,
+ (DLGPROC) RawDevicesDlgProc, (LPARAM) & szFileName[0]);
+ if (nResult == IDOK)
+ {
+ AddComboItem (GetDlgItem (hwndDlg, IDC_VOLUME), szFileName, bHistory);
+ VeraCryptExpander::EnableDisableButtons (hwndDlg);
+ SetFocus (GetDlgItem (hwndDlg, IDC_DRIVELIST));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/* Except in response to the WM_INITDIALOG and WM_ENDSESSION messages, the dialog box procedure
+ should return nonzero if it processes a message, and zero if it does not. */
+BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static UINT taskBarCreatedMsg;
+ WORD lw = LOWORD (wParam);
+ WORD hw = HIWORD (wParam);
+
+ switch (uMsg)
+ {
+
+ case WM_INITDIALOG:
+ {
+ int exitCode = 0;
+
+ MainDlg = hwndDlg;
+
+ // Set critical default options in case UsePreferences is false
+ bPreserveTimestamp = defaultMountOptions.PreserveTimestamp = TRUE;
+
+ if (UsePreferences)
+ {
+ // General preferences
+ VeraCryptExpander::LoadSettings (hwndDlg);
+
+ // Keyfiles
+ LoadDefaultKeyFilesParam ();
+ RestoreDefaultKeyFilesParam ();
+ }
+
+ InitMainDialog (hwndDlg);
+
+ // Quit
+ if (Quit)
+ {
+ exit (exitCode);
+ }
+
+ Silent = FALSE;
+ }
+ return 0;
+
+ case WM_SYSCOMMAND:
+ if (lw == IDC_ABOUT)
+ {
+ DialogBoxW (hInst, MAKEINTRESOURCEW (IDD_ABOUT_DLG), hwndDlg, (DLGPROC) AboutDlgProc);
+ return 1;
+ }
+ return 0;
+
+ case WM_ENDSESSION:
+ VeraCryptExpander::EndMainDlg (hwndDlg);
+ localcleanup ();
+ return 0;
+
+ case WM_COMMAND:
+
+ if (lw == IDCANCEL || lw == IDC_EXIT)
+ {
+ VeraCryptExpander::EndMainDlg (hwndDlg);
+ return 1;
+ }
+
+ if ( lw == IDOK )
+ {
+ if (!VeraCryptExpander::VolumeSelected(hwndDlg))
+ {
+ Warning ("NO_VOLUME_SELECTED", hwndDlg);
+ }
+ else
+ {
+ char fileName[MAX_PATH];
+ GetWindowText (GetDlgItem (hwndDlg, IDC_VOLUME), fileName, sizeof (fileName));
+ ExpandVolumeWizard(hwndDlg, (char*)fileName);
+ }
+ return 1;
+ }
+
+ if (lw == IDM_ABOUT )
+ {
+ DialogBoxW (hInst, MAKEINTRESOURCEW (IDD_ABOUT_DLG), hwndDlg, (DLGPROC) AboutDlgProc);
+ return 1;
+ }
+
+ if (lw == IDM_HOMEPAGE )
+ {
+ ArrowWaitCursor ();
+ ShellExecute (NULL, "open", "https://veracrypt.codeplex.com", NULL, NULL, SW_SHOWNORMAL);
+ Sleep (200);
+ NormalCursor ();
+
+ return 1;
+ }
+
+ if (lw == IDC_SELECT_FILE)
+ {
+ SelectContainer (hwndDlg);
+ return 1;
+ }
+
+ if (lw == IDC_SELECT_DEVICE)
+ {
+ SelectPartition (hwndDlg);
+ return 1;
+ }
+
+ return 0;
+
+ case WM_CLOSE:
+ VeraCryptExpander::EndMainDlg (hwndDlg);
+ return 1;
+
+ default:
+ ;
+ }
+
+ return 0;
+}
+
+}
+
+
+int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, char *lpszCommandLine, int nCmdShow)
+{
+ int status;
+ atexit (VeraCryptExpander::localcleanup);
+ SetProcessShutdownParameters (0x100, 0);
+
+ VirtualLock (&VeraCryptExpander::VolumePassword, sizeof (VeraCryptExpander::VolumePassword));
+ VirtualLock (&VeraCryptExpander::CmdVolumePassword, sizeof (VeraCryptExpander::CmdVolumePassword));
+ VirtualLock (&VeraCryptExpander::mountOptions, sizeof (VeraCryptExpander::mountOptions));
+ VirtualLock (&VeraCryptExpander::defaultMountOptions, sizeof (VeraCryptExpander::defaultMountOptions));
+ VirtualLock (&VeraCryptExpander::szFileName, sizeof(VeraCryptExpander::szFileName));
+
+ InitCommonControls ();
+ InitApp (hInstance, lpszCommandLine);
+
+ /* application title */
+ lpszTitle = L"VeraCrypt Expander";
+
+ status = DriverAttach ();
+ if (status != 0)
+ {
+ if (status == ERR_OS_ERROR)
+ handleWin32Error (NULL);
+ else
+ handleError (NULL, status);
+
+ AbortProcess ("NODRIVER");
+ }
+
+ /* Create the main dialog box */
+ DialogBoxParamW (hInstance, MAKEINTRESOURCEW (IDD_MOUNT_DLG), NULL, (DLGPROC) VeraCryptExpander::MainDialogProc,
+ (LPARAM) lpszCommandLine);
+
+ /* Terminate */
+ return 0;
+}