diff --git a/cppcryptfs/cppcryptfs.cpp b/cppcryptfs/cppcryptfs.cpp index b5cd4f24..70853673 100755 --- a/cppcryptfs/cppcryptfs.cpp +++ b/cppcryptfs/cppcryptfs.cpp @@ -53,6 +53,7 @@ THE SOFTWARE. #include "ui/uiutil.h" #include "../libipc/server.h" #include "../libipc/client.h" +#include "ui/locutils.h" #ifdef _DEBUG @@ -186,7 +187,7 @@ BOOL CcppcryptfsApp::InitInstance() ShowWindow(hWnd, SW_SHOWNORMAL); } } else { - ::MessageBox(NULL, L"cppcryptfs is already running, but window not found!", L"cppcryptfs", MB_OK | MB_ICONERROR); + ::MessageBox(NULL, LocUtils::GetStringFromResources(IDS_RUN_WINDOW_NOT_FOUND).c_str(), L"cppcryptfs", MB_OK | MB_ICONERROR); } return FALSE; @@ -194,7 +195,7 @@ BOOL CcppcryptfsApp::InitInstance() wstring mes; bool dokVerCheck = check_dokany_version(mes); if (!dokVerCheck && mes.length() < 1) { - mes = L"problem with Dokany version"; + mes = LocUtils::GetStringFromResources(IDS_PROBLEM_DOKANY_VERSION); } if (mes.length()) { ::MessageBox(NULL, mes.c_str(), L"cppcryptfs", MB_OK | (dokVerCheck ? MB_ICONEXCLAMATION : MB_ICONERROR)); diff --git a/cppcryptfs/cppcryptfs.rc b/cppcryptfs/cppcryptfs.rc index b2039b07..e5ecd89f 100644 Binary files a/cppcryptfs/cppcryptfs.rc and b/cppcryptfs/cppcryptfs.rc differ diff --git a/cppcryptfs/cppcryptfs.vcxproj b/cppcryptfs/cppcryptfs.vcxproj index e2e1d16f..96bcf5a3 100755 --- a/cppcryptfs/cppcryptfs.vcxproj +++ b/cppcryptfs/cppcryptfs.vcxproj @@ -227,6 +227,7 @@ + @@ -260,6 +261,10 @@ + + NotUsing + NotUsing + @@ -316,6 +321,16 @@ + + + + + + + + + + diff --git a/cppcryptfs/dokan/cryptdokan.cpp b/cppcryptfs/dokan/cryptdokan.cpp index 6f1a30e8..93bd4eda 100755 --- a/cppcryptfs/dokan/cryptdokan.cpp +++ b/cppcryptfs/dokan/cryptdokan.cpp @@ -98,6 +98,9 @@ THE SOFTWARE. #include "MountPointManager.h" #include "../libcommonutil/commonutil.h" +#include "resource.h" +#include "ui/locutils.h" +#include static DWORD g_SessionId; static BOOL g_GotSessionId = FALSE; @@ -2022,7 +2025,7 @@ int mount_crypt_fs(const WCHAR* mountpoint, const WCHAR *path, config_path = NULL; if (mountpoint == NULL) { - mes = L"invalid mountpoint"; + mes = LocUtils::GetStringFromResources(IDS_INVALID_MPOINT); return -1; } @@ -2030,9 +2033,9 @@ int mount_crypt_fs(const WCHAR* mountpoint, const WCHAR *path, if (mount_point_is_a_dir && !is_suitable_mountpoint(mountpoint)) { if (!PathFileExists(mountpoint)) { - mes = L"the mount point directory does not exist"; + mes = LocUtils::GetStringFromResources(IDS_MPOINT_DIR_NOT_EXIST); } else { - mes = L"mount point directory must be empty and reside on NTFS volume"; + mes = LocUtils::GetStringFromResources(IDS_MPOINT_DIR_EMPTY_NTFS); } return -1; } @@ -2041,7 +2044,7 @@ int mount_crypt_fs(const WCHAR* mountpoint, const WCHAR *path, bool already_mounted = MountPointManager::getInstance().find(mountpoint, dummy); if (already_mounted) { - mes = L"drive letter/mount point already in use\n"; + mes = LocUtils::GetStringFromResources(IDS_LETTER_MPOINT_ALREADY_USE); return -1; } @@ -2059,7 +2062,7 @@ int mount_crypt_fs(const WCHAR* mountpoint, const WCHAR *path, } if (!tdata) { - mes = L"Failed to allocate tdata\n"; + mes = LocUtils::GetStringFromResources(IDS_FAILED_ALLOCATE_TDATA); throw(-1); } @@ -2155,8 +2158,9 @@ int mount_crypt_fs(const WCHAR* mountpoint, const WCHAR *path, dokanOptions->MountPoint = tdata->mountpoint.c_str(); if (!config->read(mes, config_path, reverse)) { - if (mes.length() < 1) - mes = L"unable to load config\n"; + if (mes.length() < 1) { + mes = LocUtils::GetStringFromResources(IDS_UNABLE_LOAD_CONF); + } throw(-1); } @@ -2183,7 +2187,7 @@ int mount_crypt_fs(const WCHAR* mountpoint, const WCHAR *path, #endif if (!config->decrypt_key(password)) { - mes = L"password incorrect\n"; + mes = LocUtils::GetStringFromResources(IDS_PASS_INCORRECT); throw(-1); } @@ -2193,7 +2197,7 @@ int mount_crypt_fs(const WCHAR* mountpoint, const WCHAR *path, throw(-1); } } catch (...) { - mes = L"unable to initialize eme context"; + mes = LocUtils::GetStringFromResources(IDS_UNABLE_INIT_EME); throw(-1); } } @@ -2202,7 +2206,7 @@ int mount_crypt_fs(const WCHAR* mountpoint, const WCHAR *path, try { con->m_siv.SetKey(config->GetMasterKey(), 32, config->m_HKDF, config); } catch (...) { - mes = L"unable to intialize AESSIV context"; + mes = LocUtils::GetStringFromResources(IDS_UNABLE_INIT_AESSIV); throw(-1); } } @@ -2269,7 +2273,7 @@ int mount_crypt_fs(const WCHAR* mountpoint, const WCHAR *path, if (opts.mountmanagerwarn && !have_security_name_privilege()) { if (!mountmanager_continue_mounting()) { - mes = L"operation cancelled by user"; + mes = LocUtils::GetStringFromResources(IDS_CANCELED_BY_USER); throw(-1); } } @@ -2284,7 +2288,7 @@ int mount_crypt_fs(const WCHAR* mountpoint, const WCHAR *path, && !con->GetConfig()->m_reverse; if (!con->FinalInitBeforeMounting(opts.cachekeysinmemory)) { - mes = L"context final init failed"; + mes = LocUtils::GetStringFromResources(IDS_FINAL_INIT_FAILED); throw(-1); } @@ -2294,7 +2298,7 @@ int mount_crypt_fs(const WCHAR* mountpoint, const WCHAR *path, hThread = CreateThread(NULL, 0, CryptThreadProc, tdata, 0, NULL); if (!hThread) { - mes = L"unable to create thread for drive letter/mount point\n"; + mes = LocUtils::GetStringFromResources(IDS_UNABLE_CREATE_THREAD); throw(-1); } @@ -2303,7 +2307,7 @@ int mount_crypt_fs(const WCHAR* mountpoint, const WCHAR *path, // MountPointManager owns tdata from this point on, even if it fails to add (will delete it) if (!MountPointManager::getInstance().add(mountpoint, tdata)) { - mes = L"unable to add mount point to MountPointManager\n"; + mes = LocUtils::GetStringFromResources(IDS_UNABLE_ADD_MPOINT); throw(-1); } @@ -2345,12 +2349,12 @@ int mount_crypt_fs(const WCHAR* mountpoint, const WCHAR *path, if (wait_result != WAIT_OBJECT_0) { if (wait_result == (WAIT_OBJECT_0 + 1)) { // thread exited without mounting - mes = L"mount operation failed\n"; + mes = LocUtils::GetStringFromResources(IDS_MOUNT_FAILED); } else if (wait_result == WAIT_TIMEOUT) { - mes = L"mount operation timed out\n"; + mes = LocUtils::GetStringFromResources(IDS_MOUNT_TIMED_OUT); tdata = NULL; // deleting it would probably cause crash } else { - mes = L"error waiting for mount operation\n"; + mes = LocUtils::GetStringFromResources(IDS_MOUNT_ERROR_WAITING); tdata = NULL; // deleting it would probably cause crash } throw(-1); @@ -2372,8 +2376,8 @@ BOOL unmount_crypt_fs(const WCHAR* mountpoint, bool wait, wstring& mes) { wstring mpstr; if (!MountPointManager::getInstance().find(mountpoint, mpstr)) { - mes += L"unable to find mount point"; - return FALSE; + mes += LocUtils::GetStringFromResources(IDS_UNABLE_FIND_MPOINT); + return FALSE; } if (!DokanRemoveMountPoint(mpstr.c_str())) { mes += GetWindowsErrorString(GetLastError()); @@ -2383,7 +2387,9 @@ BOOL unmount_crypt_fs(const WCHAR* mountpoint, bool wait, wstring& mes) { if (wait) { bool res = MountPointManager::getInstance().wait_and_destroy(mpstr.c_str()); if (!res) { - mes += L"wait on umount returned an error " + GetWindowsErrorString(GetLastError()); + CString strMsg; + strMsg.Format(LocUtils::GetStringFromResources(IDS_WAIT_UNMOUNT_ERROR).c_str(), GetWindowsErrorString(GetLastError())); + mes += strMsg; } return res; } else { @@ -2421,7 +2427,7 @@ BOOL write_volume_name_if_changed(WCHAR dl, wstring& mes) { CryptThreadData *tdata = MountPointManager::getInstance().get(fs_root.c_str()); if (!tdata) { - mes += L"mount point not found"; + mes += LocUtils::GetStringFromResources(IDS_MPOINT_NOT_FOUND); return FALSE; } @@ -2430,7 +2436,7 @@ BOOL write_volume_name_if_changed(WCHAR dl, wstring& mes) { CryptContext *con = &tdata->con; if (!con) { - mes += L"mount point has null context"; + mes += LocUtils::GetStringFromResources(IDS_MPOINT_NULL); return FALSE; } @@ -2443,7 +2449,9 @@ BOOL write_volume_name_if_changed(WCHAR dl, wstring& mes) { NULL, NULL, 0)) { DWORD error = GetLastError(); DbgPrint(L"update volume name error = %u\n", error); - mes += L"Unable to get volume information, " + GetWindowsErrorString(error); + CString strMsg; + strMsg.Format(LocUtils::GetStringFromResources(IDS_UNABLE_GET_VOLUME_INFO).c_str(), GetWindowsErrorString(error)); + mes += strMsg; return FALSE; } @@ -2451,7 +2459,7 @@ BOOL write_volume_name_if_changed(WCHAR dl, wstring& mes) { con->GetConfig()->m_VolumeName = volbuf; bool res = con->GetConfig()->write_updated_config_file(nullptr, nullptr, 0); if (!res) { - mes += L"unable to write new volume name to config file"; + mes += LocUtils::GetStringFromResources(IDS_UNABLE_WRITE_NEW_VOL_NAME); return FALSE; } } @@ -2504,7 +2512,7 @@ wstring transform_path(const wchar_t* path, wstring& mes) _locale_t locale = _create_locale(LC_ALL, ""); if (locale == NULL) { - mes = L"cannot create locale"; + mes = LocUtils::GetStringFromResources(IDS_CANNOT_CREATE_LOCALE); return nullptr; } @@ -2527,7 +2535,7 @@ wstring transform_path(const wchar_t* path, wstring& mes) _free_locale(locale); if (!tdata) { - mes = L"could not found mount point or base dir"; + mes = LocUtils::GetStringFromResources(IDS_NOT_FOUND_MPOINT_BASE_DIR); return L""; } @@ -2537,12 +2545,12 @@ wstring transform_path(const wchar_t* path, wstring& mes) if (tdata->con.GetConfig()->m_reverse) { if (!encrypt_path(&tdata->con, p, storage)) { - mes = L"failed to convert path"; + mes = LocUtils::GetStringFromResources(IDS_FAILED_CONVERT_PATH); return L""; } } else { if (!unencrypt_path(&tdata->con, p, storage)) { - mes = L"failed to unencrypt path"; + mes = LocUtils::GetStringFromResources(IDS_FAILED_UNENCRYPT_PATH); return L""; } } @@ -2556,7 +2564,7 @@ wstring transform_path(const wchar_t* path, wstring& mes) FileNameEnc enc(&dfi, p, nullptr, false); auto pconv = static_cast(enc); if (!pconv) { - mes = L"failed to encrypt path"; + mes = LocUtils::GetStringFromResources(IDS_FAILED_ENCRYPT_PATH); return L""; } return pconv + std::size(L"\\\\?\\") - 1; @@ -2569,19 +2577,19 @@ BOOL list_files(const WCHAR *path, list &findDatas, err_mes = L""; if (!path) { - err_mes = L"path is null"; + err_mes = LocUtils::GetStringFromResources(IDS_PATH_NULL); return FALSE; } if (wcslen(path) > MAX_PATH - 1) { - err_mes = L"path is too long"; + err_mes = LocUtils::GetStringFromResources(IDS_PATH_TOO_LONG); return FALSE; } WCHAR newpath[MAX_PATH + 1]; if (!PathCanonicalize(newpath, path)) { - err_mes = L"failed to canonicalize path"; + err_mes = LocUtils::GetStringFromResources(IDS_FAILED_CANONICALIZE_PATH); return FALSE; } @@ -2590,17 +2598,17 @@ BOOL list_files(const WCHAR *path, list &findDatas, int dl = *path; if (dl < 'A' || dl > 'Z') { - err_mes = L"invalid drive letter"; + err_mes = LocUtils::GetStringFromResources(IDS_INVALID_DRIVE_LETTER); return FALSE; } if (wcslen(path) < 3) { - err_mes = L"path is too short"; + err_mes = LocUtils::GetStringFromResources(IDS_PATH_TOO_SHORT); return FALSE; } if (path[1] != ':' || path[2] != '\\') { - err_mes = L"invalid path"; + err_mes = LocUtils::GetStringFromResources(IDS_INVALID_PATH); return FALSE; } @@ -2614,7 +2622,7 @@ BOOL list_files(const WCHAR *path, list &findDatas, _locale_t locale = _create_locale(LC_ALL, ""); if (locale == NULL) { - err_mes = L"cannot create locale"; + err_mes = LocUtils::GetStringFromResources(IDS_CANNOT_CREATE_LOCALE); return FALSE; } @@ -2640,7 +2648,7 @@ BOOL list_files(const WCHAR *path, list &findDatas, _free_locale(locale); if (!tdata) { - err_mes = L"drive not mounted"; + err_mes = LocUtils::GetStringFromResources(IDS_DRIVE_NOT_MOUNTED); return FALSE; } @@ -2670,7 +2678,7 @@ BOOL list_files(const WCHAR *path, list &findDatas, if (find_files(con, filePath.CorrectCasePath(), filePath, crypt_fill_find_data_list, NULL, &findDatas) != 0) { - err_mes = L"error listing files"; + err_mes = LocUtils::GetStringFromResources(IDS_ERROR_LISTING_FILES); return FALSE; } } else if (PathFileExists(filePath)) { @@ -2697,7 +2705,7 @@ BOOL list_files(const WCHAR *path, list &findDatas, } else { - err_mes = L"path does not exist"; + err_mes = LocUtils::GetStringFromResources(IDS_PATH_NOT_EXIST); return FALSE; } @@ -2759,7 +2767,7 @@ bool check_dokany_version(wstring& mes) vector v; if (!get_dokany_version(ver, v)) { - mes = L"unable to get dokany version"; + mes = LocUtils::GetStringFromResources(IDS_UNABLE_GET_DOKANY_VERSION); return false; } @@ -2775,17 +2783,23 @@ bool check_dokany_version(wstring& mes) } if (major != required_major) { - mes = L"The installed Dokany version " + ver + L" is not compatible. Please install Dokany " + required_ver; + CString strMsg; + strMsg.Format(LocUtils::GetStringFromResources(IDS_DOKANY_VER_NOT_COMPATIBLE).c_str(), ver, required_ver); + mes = strMsg; return false; // error } if (major == required_major && middle < required_middle) { - mes = L"The installed Dokany version " + ver + L" is not compatible. Please install Dokany " + required_ver; + CString strMsg; + strMsg.Format(LocUtils::GetStringFromResources(IDS_DOKANY_VER_NOT_COMPATIBLE).c_str(), ver, required_ver); + mes = strMsg; return false; // error } if (major == required_major && middle > required_middle) { - mes = L"The installed Dokany version is " + ver + L", and it has not been tested with cppcryptfs. Please install Dokany " + required_ver; + CString strMsg; + strMsg.Format(LocUtils::GetStringFromResources(IDS_DOKANY_VER_NOT_TESTED).c_str(), ver, required_ver); + mes = strMsg; return true; // warning } @@ -2826,7 +2840,9 @@ static void InitLogging() const WCHAR* logdir = L"C:\\cppcryptfslogs"; if (!PathFileExists(logdir)) { - ::MessageBox(NULL, (wstring(L"Unable to init logging. Please create ") + logdir).c_str(), L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); + CString strMsg; + strMsg.Format(LocUtils::GetStringFromResources(IDS_UNABLE_INIT_LOGGING).c_str(), logdir); + ::MessageBox(NULL, strMsg, L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); return; } @@ -2862,9 +2878,13 @@ static void InitLogging() const int result = _wfopen_s(&g_DebugLogFile, logname.c_str(), L"at+"); if (result == 0) { - ::MessageBox(NULL, (wstring(L"Logging to ") + logname).c_str(), L"cppcryptfs", MB_OK | MB_ICONINFORMATION); + CString strMsg; + strMsg.Format(LocUtils::GetStringFromResources(IDS_LOGGING_TO_LOGNAME).c_str(), logname); + ::MessageBox(NULL, strMsg, L"cppcryptfs", MB_OK | MB_ICONINFORMATION); } else { - ::MessageBox(NULL, (wstring(L"Unable to open ") + logname.c_str()).c_str(), L"cppcryptfs", MB_OK | MB_ICONERROR); + CString strMsg; + strMsg.Format(LocUtils::GetStringFromResources(IDS_UNABLE_OPEN_LOGNAME).c_str(), logname); + ::MessageBox(NULL, strMsg, L"cppcryptfs", MB_OK | MB_ICONERROR); } } diff --git a/cppcryptfs/res/lic/en/aessiv.txt b/cppcryptfs/res/lic/en/aessiv.txt new file mode 100644 index 00000000..f97934ec Binary files /dev/null and b/cppcryptfs/res/lic/en/aessiv.txt differ diff --git a/cppcryptfs/res/lic/en/cppcryptfs.txt b/cppcryptfs/res/lic/en/cppcryptfs.txt new file mode 100644 index 00000000..eb73b919 Binary files /dev/null and b/cppcryptfs/res/lic/en/cppcryptfs.txt differ diff --git a/cppcryptfs/res/lic/en/dokany_lib.txt b/cppcryptfs/res/lic/en/dokany_lib.txt new file mode 100644 index 00000000..0a98ec4d Binary files /dev/null and b/cppcryptfs/res/lic/en/dokany_lib.txt differ diff --git a/cppcryptfs/res/lic/en/dokany_mir.txt b/cppcryptfs/res/lic/en/dokany_mir.txt new file mode 100644 index 00000000..926ceb2a Binary files /dev/null and b/cppcryptfs/res/lic/en/dokany_mir.txt differ diff --git a/cppcryptfs/res/lic/en/getopt.txt b/cppcryptfs/res/lic/en/getopt.txt new file mode 100644 index 00000000..2afb3d4b Binary files /dev/null and b/cppcryptfs/res/lic/en/getopt.txt differ diff --git a/cppcryptfs/res/lic/en/openssl.txt b/cppcryptfs/res/lic/en/openssl.txt new file mode 100644 index 00000000..60672bfd Binary files /dev/null and b/cppcryptfs/res/lic/en/openssl.txt differ diff --git a/cppcryptfs/res/lic/en/rapidjson.txt b/cppcryptfs/res/lic/en/rapidjson.txt new file mode 100644 index 00000000..0e3b8e5d Binary files /dev/null and b/cppcryptfs/res/lic/en/rapidjson.txt differ diff --git a/cppcryptfs/res/lic/en/secure_edit.txt b/cppcryptfs/res/lic/en/secure_edit.txt new file mode 100644 index 00000000..914b704e Binary files /dev/null and b/cppcryptfs/res/lic/en/secure_edit.txt differ diff --git a/cppcryptfs/resource.h b/cppcryptfs/resource.h index ad834252..c9445a93 100755 Binary files a/cppcryptfs/resource.h and b/cppcryptfs/resource.h differ diff --git a/cppcryptfs/ui/CreatePropertyPage.cpp b/cppcryptfs/ui/CreatePropertyPage.cpp index 422df475..46f6f979 100755 --- a/cppcryptfs/ui/CreatePropertyPage.cpp +++ b/cppcryptfs/ui/CreatePropertyPage.cpp @@ -41,10 +41,13 @@ THE SOFTWARE. #include "crypt/cryptdefs.h" #include "util/LockZeroBuffer.h" #include "util/util.h" +#include "locutils.h" + +static CString listBoxStringPlainText = LocUtils::GetStringFromResources(IDS_PLAIN_TEXT).c_str(); static const WCHAR *filename_encryption_types[] = { L"AES256-EME", - L"Plain text" + listBoxStringPlainText }; #define NUM_FN_ENC_TYPES (sizeof(filename_encryption_types)/sizeof(filename_encryption_types[0])) @@ -110,7 +113,7 @@ void CCreatePropertyPage::CreateCryptfs() LockZeroBuffer password2(MAX_PASSWORD_LEN + 1, false); if (!password.IsLocked() || !password2.IsLocked()) { - MessageBox(L"could not lock password buffers", L"cppcryptefs", MB_OK | MB_ICONERROR); + MessageBox(LocUtils::GetStringFromResources(IDS_COULD_NOT_LOCK_BUFFER).c_str(), L"cppcryptefs", MB_OK | MB_ICONERROR); return; } @@ -120,7 +123,7 @@ void CCreatePropertyPage::CreateCryptfs() return; if (wcslen(password.m_buf) < 1) { - MessageBox(L"please enter a password", L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); + MessageBox(LocUtils::GetStringFromResources(IDS_PASSWORD_EMPTY).c_str(), L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); return; } @@ -130,12 +133,12 @@ void CCreatePropertyPage::CreateCryptfs() return; if (wcslen(password2.m_buf) < 1) { - MessageBox(L"please repeat the password", L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); + MessageBox(LocUtils::GetStringFromResources(IDS_PASSWORD_REPEAT_EMPTY).c_str(), L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); return; } if (wcscmp(password.m_buf, password2.m_buf)) { - MessageBox(L"passwords do not match", L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); + MessageBox(LocUtils::GetStringFromResources(IDS_PASSWORD_DO_NOT_MATCH).c_str(), L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); return; } @@ -147,21 +150,20 @@ void CCreatePropertyPage::CreateCryptfs() pWnd->GetWindowTextW(cpath); if (cpath.GetLength() < 1) { - MessageBox(L"please enter a path", L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); + MessageBox(LocUtils::GetStringFromResources(IDS_PATH_EMPTY).c_str(), L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); return; } if (!PathFileExists(cpath)) { CString mes; - mes += cpath; - mes += L" does not exist. Do you want to create it?"; + mes.Format(LocUtils::GetStringFromResources(IDS_PATH_DOES_NOT_EXIST).c_str(), cpath); + if (MessageBox(mes, L"cppcryptfs", MB_YESNO | MB_ICONINFORMATION) == IDYES) { - if (!CreateDirectory(cpath, NULL)) { - mes = L"Could not create "; - mes += cpath; - MessageBox(mes, L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); - return; - } + if (!CreateDirectory(cpath, NULL)) { + mes.Format(LocUtils::GetStringFromResources(IDS_PATH_COULD_NOT_CREATE).c_str(), cpath); + MessageBox(mes, L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); + return; + } } else { return; } @@ -203,7 +205,7 @@ void CCreatePropertyPage::CreateCryptfs() if (cfenc == L"AES256-EME") eme = true; - else if (cfenc == "Plain text") + else if (cfenc == listBoxStringPlainText) plaintext = true; if (!plaintext) { @@ -257,9 +259,7 @@ void CCreatePropertyPage::CreateCryptfs() CString mes; - mes = reverse ? L"Created reverse encrypted filesystem in " : L"Created encrypted filesystem in "; - - mes.Append(cpath); + reverse ? mes.Format(LocUtils::GetStringFromResources(IDS_CREATED_REVERSE_FS).c_str(), cpath) : mes.Format(LocUtils::GetStringFromResources(IDS_CREATED_FORWARD_FS).c_str(), cpath); MessageBox(mes, L"cppcryptfs", MB_OK | MB_ICONINFORMATION); @@ -294,7 +294,15 @@ void CCreatePropertyPage::CreateCryptfs() if (nenc < 0 || nenc >= NUM_FN_ENC_TYPES) return; - theApp.WriteProfileStringW(L"CreateOptions", L"FilenameEncryption", filename_encryption_types[nenc]); + //To save localization-independent text in the registry + CString filename_encryption_type_for_registry; + if (filename_encryption_types[nenc] == listBoxStringPlainText) { + filename_encryption_type_for_registry = L"Plain text"; + } else { + filename_encryption_type_for_registry = filename_encryption_types[nenc]; + } + + theApp.WriteProfileStringW(L"CreateOptions", L"FilenameEncryption", filename_encryption_type_for_registry); pLbox = (CComboBox*)GetDlgItem(IDC_DATA_ENCRYPTION); if (!pLbox) @@ -345,7 +353,7 @@ void CCreatePropertyPage::OnClickedSelect() return; if (!IsDlgButtonChecked(IDC_REVERSE) && !can_delete_directory(cpath, TRUE)) { - MessageBox(L"directory must be empty", L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); + MessageBox(LocUtils::GetStringFromResources(IDS_DIRECTORY_NOT_EMPTY).c_str(), L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); return; } @@ -380,7 +388,14 @@ BOOL CCreatePropertyPage::OnInitDialog() CString creverse = theApp.GetProfileStringW(L"CreateOptions", L"Reverse", L"0"); - CString cfnenc = theApp.GetProfileStringW(L"CreateOptions", L"FilenameEncryption", L"AES256-EME"); + //To extract localization-independent text from the registry + CString cfnenc; + CString cfnenc_tmp = theApp.GetProfileStringW(L"CreateOptions", L"FilenameEncryption", L"AES256-EME"); + if (cfnenc_tmp == L"Plain text") { + cfnenc = listBoxStringPlainText; + } else { + cfnenc = cfnenc_tmp; + } CString cdataenc = theApp.GetProfileStringW(L"CreateOptions", L"DataEncryption", L"AES256-GCM"); @@ -452,7 +467,7 @@ BOOL CCreatePropertyPage::OnInitDialog() pLbox->EnableWindow(IsDlgButtonChecked(IDC_LONG_FILE_NAMES)); if (!m_password.ArePasswordBuffersLocked() || !m_password2.ArePasswordBuffersLocked()) { - MessageBox(L"unable to lock password buffers", L"cppcryptfs", MB_OK | MB_ICONERROR); + MessageBox(LocUtils::GetStringFromResources(IDS_UNABLE_LOCK_BUFFERS).c_str(), L"cppcryptfs", MB_OK | MB_ICONERROR); } const auto scryptN = theApp.GetProfileIntW(L"CreateOptions", L"ScryptN", DEFAULT_SCRYPTN); @@ -581,15 +596,16 @@ void CCreatePropertyPage::OnSelchangeScryptn() int mem = (1<= 1024) - { - suffix = L" GB required"; + CString suffix; + suffix.Format(LocUtils::GetStringFromResources(IDS_MB_REQUIRED).c_str(), mem); + + if (mem >= 1024) { mem /= 1024; + suffix.Format(LocUtils::GetStringFromResources(IDS_GB_REQUIRED).c_str(), mem); } auto pScryptMemReq = (CStatic*)GetDlgItem(IDC_SCRYPTMEMREQ); if (pScryptMemReq) { - pScryptMemReq->SetWindowText((std::to_wstring(mem) + suffix).c_str()); + pScryptMemReq->SetWindowText(suffix); } } diff --git a/cppcryptfs/ui/CryptAboutPropertyPage.cpp b/cppcryptfs/ui/CryptAboutPropertyPage.cpp index 40c6c64b..c6f61fe6 100755 --- a/cppcryptfs/ui/CryptAboutPropertyPage.cpp +++ b/cppcryptfs/ui/CryptAboutPropertyPage.cpp @@ -40,7 +40,43 @@ THE SOFTWARE. #include "crypt/aes.h" #include "openssl/crypto.h" #include "../libcommonutil/commonutil.h" +#include "locutils.h" +const int LICENSES_COUNT = 8; // Adjust when the number of licenses is changed +static const WCHAR* licenses[LICENSES_COUNT + 1] = { 0 }; +static CStringW storage[LICENSES_COUNT]; + +void LoadLicensesFromResource() { + static bool loaded = false; + if (loaded) return; + + UINT startId = IDR_LICENSE_CPPCRYPTFS; + + for (int i = 0; i < LICENSES_COUNT; i++) { + UINT currentId = startId + i; + licenses[i] = L""; + + HRSRC hRes = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(currentId), RT_RCDATA); + if (!hRes) continue; + + HGLOBAL hData = LoadResource(AfxGetResourceHandle(), hRes); + DWORD size = SizeofResource(AfxGetResourceHandle(), hRes); + const void* pData = LockResource(hData); + + if (pData && size > 0) { + int charCount = size / sizeof(WCHAR); + + LPWSTR pBuf = storage[i].GetBufferSetLength(charCount); + memcpy(pBuf, pData, size); + storage[i].ReleaseBuffer(charCount); + + licenses[i] = (const WCHAR*)storage[i]; + } + } + + licenses[LICENSES_COUNT] = NULL; + loaded = true; +} // CCryptAboutPropertyPage dialog @@ -49,7 +85,7 @@ IMPLEMENT_DYNAMIC(CCryptAboutPropertyPage, CCryptPropertyPage) CCryptAboutPropertyPage::CCryptAboutPropertyPage() : CCryptPropertyPage(IDD_ABOUTBOX) { - + LoadLicensesFromResource(); } CCryptAboutPropertyPage::~CCryptAboutPropertyPage() @@ -68,510 +104,24 @@ BEGIN_MESSAGE_MAP(CCryptAboutPropertyPage, CCryptPropertyPage) ON_NOTIFY(LVN_ITEMCHANGED, IDC_COMPONENTS_LIST, &CCryptAboutPropertyPage::OnItemchangedComponentsList) END_MESSAGE_MAP() - - -static const WCHAR * components[] = { - L"cppcryptfs - Copyright (C) 2016-2025 Bailey Brown. All Rights Reserved.", - L"OpenSSL - Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved.", - L"RapidJSON - Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.", - L"Dokany (mirror) - Copyright (C) 2020 - 2021 Google, Inc.; Copyright (C) 2015 - 2019 Adrien J., Maxime C.; Copyright (C) 2007 - 2011 Hiroki Asakawa", - L"Dokany (library) - Copyright (C) 2020 - 2021 Google, Inc.; Copyright (C) 2015 - 2019 Adrien J., Maxime C.; Copyright (C) 2007 - 2011 Hiroki Asakawa", - L"100% free Secure Edit control MFC class - Copyright (c) 2003 Dominik Reichl", - L"getopt_port - Copyright (c) 2012-2017, Kim Grasman . All rights reserved.", - L"aes-siv - Copyright (c) 2015 ARKconcepts / Sasha Kotlyar", - NULL -}; - -static const WCHAR *licenses[] = { - - // cppcryptfs - L"cppcryptfs - Copyright (C) 2016-2025 Bailey Brown. All rights reserved.\r\n\r\n" - L"project url: github.com/bailey27/cppcryptfs\r\n\r\n" - L"cppcryptfs is a user-mode cryptographic virtual overlay filesystem\r\n\r\n" - L"cppcryptfs is based on the design of gocryptfs (github.com/rfjakob/gocryptfs)\r\n\r\n" - L"cppcryptfs links with and incorporates source code from several open source projects.\r\n\r\n" - L"All incorporated sources use the MIT license or other permissive open source licenses.\r\n\r\n" - L"All statically linked libraries use a permissive open source license.\r\n" - L"\r\n" - L"Some libraries which are linked with dynamically use the GNU LGPL.\r\n" - L"\r\n" - L"cppcryptfs itself uses an MIT license which is as follows:\r\n" - L"\r\n" - L"The MIT License (MIT)\r\n" - L"\r\n" - L"Permission is hereby granted, free of charge, to any person obtaining a copy\r\n" - L"of this software and associated documentation files (the \"Software\"), to deal\r\n" - L"in the Software without restriction, including without limitation the rights\r\n" - L"to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n" - L"copies of the Software, and to permit persons to whom the Software is\r\n" - L"furnished to do so, subject to the following conditions:\r\n" - L"\r\n" - L"The above copyright notice and this permission notice shall be included in\r\n" - L"all copies or substantial portions of the Software.\r\n" - L"\r\n" - L"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n" - L"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n" - L"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n" - L"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n" - L"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n" - L"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n" - L"THE SOFTWARE.\r\n" - L"\r\n", - - // openssl - - L"poject url: github.com/openssl/openssl\r\n\r\n" - L"cppcryptfs usage: statically linked library\r\n\r\n" - L"OpenSSL copyright and license:\r\n\r\n" - LR"(LICENSE ISSUES - ============== - - The OpenSSL toolkit stays under a double license, i.e.both the conditions of - the OpenSSL License and the original SSLeay license apply to the toolkit. - See below for the actual license texts. - - OpenSSL License - -------------- - - - /* ==================================================================== - * Copyright (c) 1998-2019 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/) " - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/) " - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - - Original SSLeay License - ---------------------- - - - /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com) " - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com) " - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */)", - - // rapidjson - L"project url: github.com/miloyip/rapidjson\r\n\r\n" - L"cppcryptfs usage: included header files\r\n\r\n" - L"RapidJSON copyright and license:\r\n\r\n" - L"Tencent is pleased to support the open source community by making RapidJSON available. \r\n" - L" \r\n" - L"Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.\r\n" - L"\r\n" - L"If you have downloaded a copy of the RapidJSON binary from Tencent, please note that the RapidJSON binary is licensed under the MIT License.\r\n" - L"If you have downloaded a copy of the RapidJSON source code from Tencent, please note that RapidJSON source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of RapidJSON into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within RapidJSON. To avoid the problematic JSON license in your own projects, it's sufficient to exclude the bin/jsonchecker/ directory, as it's the only code under the JSON license.\r\n" - L"A copy of the MIT License is included in this file.\r\n" - L"\r\n" - L"Other dependencies and licenses:\r\n" - L"\r\n" - L"Open Source Software Licensed Under the BSD License:\r\n" - L"--------------------------------------------------------------------\r\n" - L"\r\n" - L"The msinttypes r29 \r\n" - L"Copyright (c) 2006-2013 Alexander Chemeris \r\n" - L"All rights reserved.\r\n" - L"\r\n" - L"Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\r\n" - L"\r\n" - L"* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. \r\n" - L"* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\r\n" - L"* Neither the name of copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\r\n" - L"\r\n" - L"THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n" - L"\r\n" - L"Open Source Software Licensed Under the JSON License:\r\n" - L"--------------------------------------------------------------------\r\n" - L"\r\n" - L"json.org \r\n" - L"Copyright (c) 2002 JSON.org\r\n" - L"All Rights Reserved.\r\n" - L"\r\n" - L"JSON_checker\r\n" - L"Copyright (c) 2002 JSON.org\r\n" - L"All Rights Reserved.\r\n" - L"\r\n" - L"\r\n" - L"Terms of the JSON License:\r\n" - L"---------------------------------------------------\r\n" - L"\r\n" - L"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n" - L"\r\n" - L"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n" - L"\r\n" - L"The Software shall be used for Good, not Evil.\r\n" - L"\r\n" - L"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n" - L"\r\n" - L"\r\n" - L"Terms of the MIT License:\r\n" - L"--------------------------------------------------------------------\r\n" - L"\r\n" - L"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r\n" - L"\r\n" - L"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n" - L"\r\n" - L"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n", - - // Dokany (mirror) - - L"project url: github.com/dokan-dev/dokany\r\n\r\n" - L"cppcryptfs usage: code from the mirror.c sample program from Dokany was used in modifed form in cppcryptfs (in cryptdokan.cpp).\r\n\r\n" - L"Dokany mirror.c copyright and license (MIT license):\r\n\r\n" - L"Copyright (C) 2020 - 2021 Google, Inc.\r\n" - L"Copyright (C) 2015 - 2019 Adrien J. and Maxime C. \r\n" - L"Copyright (C) 2007 - 2011 Hiroki Asakawa \r\n" - L"\r\n" - L"Permission is hereby granted, free of charge, to any person obtaining a copy\r\n" - L"of this software and associated documentation files (the \"Software\"), to deal\r\n" - L"in the Software without restriction, including without limitation the rights\r\n" - L"to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n" - L"copies of the Software, and to permit persons to whom the Software is\r\n" - L"furnished to do so, subject to the following conditions:\r\n" - L"\r\n" - L"The above copyright notice and this permission notice shall be included in\r\n" - L"all copies or substantial portions of the Software.\r\n" - L"\r\n" - L"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n" - L"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n" - L"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n" - L"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n" - L"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n" - L"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\n" - L"THE SOFTWARE.\r\n", - - // dokany (library) - - L"project url: github.com/dokan-dev/dokany\r\n\r\n" - L"cppcryptfs usage: dynamically linked library\r\n\r\n" - L"Dokany library copyright and license (GNU LGPL):\r\n\r\n" - L"Copyright (C) 2020 - 2021 Google, Inc.\r\n" - L"Copyright (C) 2015 - 2019 Adrien J. and Maxime C. \r\n" - L"Copyright (C) 2007 - 2011 Hiroki Asakawa \r\n\r\n" - L" GNU LESSER GENERAL PUBLIC LICENSE\r\n" - L" Version 3, 29 June 2007\r\n" - L"\r\n" - L" Copyright (C) 2007 Free Software Foundation, Inc. \r\n" - L" Everyone is permitted to copy and distribute verbatim copies\r\n" - L" of this license document, but changing it is not allowed.\r\n" - L"\r\n" - L"\r\n" - L" This version of the GNU Lesser General Public License incorporates\r\n" - L"the terms and conditions of version 3 of the GNU General Public\r\n" - L"License, supplemented by the additional permissions listed below.\r\n" - L"\r\n" - L" 0. Additional Definitions. \r\n" - L"\r\n" - L" As used herein, \"this License\" refers to version 3 of the GNU Lesser\r\n" - L"General Public License, and the \"GNU GPL\" refers to version 3 of the GNU\r\n" - L"General Public License.\r\n" - L"\r\n" - L" \"The Library\" refers to a covered work governed by this License,\r\n" - L"other than an Application or a Combined Work as defined below.\r\n" - L"\r\n" - L" An \"Application\" is any work that makes use of an interface provided\r\n" - L"by the Library, but which is not otherwise based on the Library.\r\n" - L"Defining a subclass of a class defined by the Library is deemed a mode\r\n" - L"of using an interface provided by the Library.\r\n" - L"\r\n" - L" A \"Combined Work\" is a work produced by combining or linking an\r\n" - L"Application with the Library. The particular version of the Library\r\n" - L"with which the Combined Work was made is also called the \"Linked\r\n" - L"Version\".\r\n" - L"\r\n" - L" The \"Minimal Corresponding Source\" for a Combined Work means the\r\n" - L"Corresponding Source for the Combined Work, excluding any source code\r\n" - L"for portions of the Combined Work that, considered in isolation, are\r\n" - L"based on the Application, and not on the Linked Version.\r\n" - L"\r\n" - L" The \"Corresponding Application Code\" for a Combined Work means the\r\n" - L"object code and/or source code for the Application, including any data\r\n" - L"and utility programs needed for reproducing the Combined Work from the\r\n" - L"Application, but excluding the System Libraries of the Combined Work.\r\n" - L"\r\n" - L" 1. Exception to Section 3 of the GNU GPL.\r\n" - L"\r\n" - L" You may convey a covered work under sections 3 and 4 of this License\r\n" - L"without being bound by section 3 of the GNU GPL.\r\n" - L"\r\n" - L" 2. Conveying Modified Versions.\r\n" - L"\r\n" - L" If you modify a copy of the Library, and, in your modifications, a\r\n" - L"facility refers to a function or data to be supplied by an Application\r\n" - L"that uses the facility (other than as an argument passed when the\r\n" - L"facility is invoked), then you may convey a copy of the modified\r\n" - L"version:\r\n" - L"\r\n" - L" a) under this License, provided that you make a good faith effort to\r\n" - L" ensure that, in the event an Application does not supply the\r\n" - L" function or data, the facility still operates, and performs\r\n" - L" whatever part of its purpose remains meaningful, or\r\n" - L"\r\n" - L" b) under the GNU GPL, with none of the additional permissions of\r\n" - L" this License applicable to that copy.\r\n" - L"\r\n" - L" 3. Object Code Incorporating Material from Library Header Files.\r\n" - L"\r\n" - L" The object code form of an Application may incorporate material from\r\n" - L"a header file that is part of the Library. You may convey such object\r\n" - L"code under terms of your choice, provided that, if the incorporated\r\n" - L"material is not limited to numerical parameters, data structure\r\n" - L"layouts and accessors, or small macros, inline functions and templates\r\n" - L"(ten or fewer lines in length), you do both of the following:\r\n" - L"\r\n" - L" a) Give prominent notice with each copy of the object code that the\r\n" - L" Library is used in it and that the Library and its use are\r\n" - L" covered by this License.\r\n" - L"\r\n" - L" b) Accompany the object code with a copy of the GNU GPL and this license\r\n" - L" document.\r\n" - L"\r\n" - L" 4. Combined Works.\r\n" - L"\r\n" - L" You may convey a Combined Work under terms of your choice that,\r\n" - L"taken together, effectively do not restrict modification of the\r\n" - L"portions of the Library contained in the Combined Work and reverse\r\n" - L"engineering for debugging such modifications, if you also do each of\r\n" - L"the following:\r\n" - L"\r\n" - L" a) Give prominent notice with each copy of the Combined Work that\r\n" - L" the Library is used in it and that the Library and its use are\r\n" - L" covered by this License.\r\n" - L"\r\n" - L" b) Accompany the Combined Work with a copy of the GNU GPL and this license\r\n" - L" document.\r\n" - L"\r\n" - L" c) For a Combined Work that displays copyright notices during\r\n" - L" execution, include the copyright notice for the Library among\r\n" - L" these notices, as well as a reference directing the user to the\r\n" - L" copies of the GNU GPL and this license document.\r\n" - L"\r\n" - L" d) Do one of the following:\r\n" - L"\r\n" - L" 0) Convey the Minimal Corresponding Source under the terms of this\r\n" - L" License, and the Corresponding Application Code in a form\r\n" - L" suitable for, and under terms that permit, the user to\r\n" - L" recombine or relink the Application with a modified version of\r\n" - L" the Linked Version to produce a modified Combined Work, in the\r\n" - L" manner specified by section 6 of the GNU GPL for conveying\r\n" - L" Corresponding Source.\r\n" - L"\r\n" - L" 1) Use a suitable shared library mechanism for linking with the\r\n" - L" Library. A suitable mechanism is one that (a) uses at run time\r\n" - L" a copy of the Library already present on the user's computer\r\n" - L" system, and (b) will operate properly with a modified version\r\n" - L" of the Library that is interface-compatible with the Linked\r\n" - L" Version. \r\n" - L"\r\n" - L" e) Provide Installation Information, but only if you would otherwise\r\n" - L" be required to provide such information under section 6 of the\r\n" - L" GNU GPL, and only to the extent that such information is\r\n" - L" necessary to install and execute a modified version of the\r\n" - L" Combined Work produced by recombining or relinking the\r\n" - L" Application with a modified version of the Linked Version. (If\r\n" - L" you use option 4d0, the Installation Information must accompany\r\n" - L" the Minimal Corresponding Source and Corresponding Application\r\n" - L" Code. If you use option 4d1, you must provide the Installation\r\n" - L" Information in the manner specified by section 6 of the GNU GPL\r\n" - L" for conveying Corresponding Source.)\r\n" - L"\r\n" - L" 5. Combined Libraries.\r\n" - L"\r\n" - L" You may place library facilities that are a work based on the\r\n" - L"Library side by side in a single library together with other library\r\n" - L"facilities that are not Applications and are not covered by this\r\n" - L"License, and convey such a combined library under terms of your\r\n" - L"choice, if you do both of the following:\r\n" - L"\r\n" - L" a) Accompany the combined library with a copy of the same work based\r\n" - L" on the Library, uncombined with any other library facilities,\r\n" - L" conveyed under the terms of this License.\r\n" - L"\r\n" - L" b) Give prominent notice with the combined library that part of it\r\n" - L" is a work based on the Library, and explaining where to find the\r\n" - L" accompanying uncombined form of the same work.\r\n" - L"\r\n" - L" 6. Revised Versions of the GNU Lesser General Public License.\r\n" - L"\r\n" - L" The Free Software Foundation may publish revised and/or new versions\r\n" - L"of the GNU Lesser General Public License from time to time. Such new\r\n" - L"versions will be similar in spirit to the present version, but may\r\n" - L"differ in detail to address new problems or concerns.\r\n" - L"\r\n" - L" Each version is given a distinguishing version number. If the\r\n" - L"Library as you received it specifies that a certain numbered version\r\n" - L"of the GNU Lesser General Public License \"or any later version\"\r\n" - L"applies to it, you have the option of following the terms and\r\n" - L"conditions either of that published version or of any later version\r\n" - L"published by the Free Software Foundation. If the Library as you\r\n" - L"received it does not specify a version number of the GNU Lesser\r\n" - L"General Public License, you may choose any version of the GNU Lesser\r\n" - L"General Public License ever published by the Free Software Foundation.\r\n" - L"\r\n" - L" If the Library as you received it specifies that a proxy can decide\r\n" - L"whether future versions of the GNU Lesser General Public License shall\r\n" - L"apply, that proxy's public statement of acceptance of any version is\r\n" - L"permanent authorization for you to choose that version for the\r\n" - L"Library.\r\n", - - // Secure Edit - L"cppcryptfs usage: modified and incorporated into cppcryptfs (as SecureEdit.cpp and SecureEdit.h).\r\n\r\n" - L"Secure Edit copyright and license:\r\n\r\n" - L"100% free Secure Edit control MFC class\r\n" - L"Copyright (c) 2003 Dominik Reichl\r\n" - L"If you use this class I would be more than happy if you mention\r\n" - L"my name somewhere in your application. Thanks!\r\n" - L"Do you have any questions or want to tell me that you are using\r\n" - L"my class, e-mail me: .\r\n", - - // getopt - - L"project url: github.com/kimgr/getopt_port\r\n\r\n" - L"cppcryptfs usage: getopt.c and getopt.h from this project were modified and incorporated into cppcryptfs.\r\n\r\n" - L"getopt_port copyright and license:\r\n\r\n" - L"Copyright (c) 2012-2017, Kim Grasman \r\n" - L"All rights reserved.\r\n" - L"\r\n" - L"Redistribution and use in source and binary forms, with or without\r\n" - L"modification, are permitted provided that the following conditions are met:\r\n" - L" * Redistributions of source code must retain the above copyright\r\n" - L" notice, this list of conditions and the following disclaimer.\r\n" - L" * Redistributions in binary form must reproduce the above copyright\r\n" - L" notice, this list of conditions and the following disclaimer in the\r\n" - L" documentation and/or other materials provided with the distribution.\r\n" - L" * Neither the name of Kim Grasman nor the\r\n" - L" names of contributors may be used to endorse or promote products\r\n" - L" derived from this software without specific prior written permission.\r\n" - L"\r\n" - L"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\r\n" - L"ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r\n" - L"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r\n" - L"DISCLAIMED. IN NO EVENT SHALL KIM GRASMAN BE LIABLE FOR ANY\r\n" - L"DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r\n" - L"(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r\n" - L"LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r\n" - L"ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r\n" - L"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r\n" - L"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r\n", - - // aes-siv - - L"project url: github.com/arktronic/aes-siv\r\n\r\n" - L"cppcryptfs usage: code from this project was modified and incorporated into cppcryptfs (in the cppcryptfs/aes-siv directory). " - L"The low-level, third-party AES implementation included with aes-siv was replaced with a new implementation that uses OpenSSL.\r\n\r\n" - L"aes-siv copyright and license:\r\n\r\n" - L"This project is licensed under the OSI-approved ISC License:\r\n" - L"\r\n" - L"Copyright (c) 2015 ARKconcepts / Sasha Kotlyar\r\n" - L"\r\n" - L"Permission to use, copy, modify, and/or distribute this software for any\r\n" - L"purpose with or without fee is hereby granted, provided that the above\r\n" - L"copyright notice and this permission notice appear in all copies.\r\n" - L"\r\n" - L"THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\n" - L"REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND\r\n" - L"FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\n" - L"INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\n" - L"LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\n" - L"OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\n" - L"PERFORMANCE OF THIS SOFTWARE.\r\n", - +static CString listViewStringCppcryptfs = LocUtils::GetStringFromResources(IDS_LVIEW_COPYRIGHT_CPPCRYPTFS).c_str(); +static CString listViewStringOpenSSL = LocUtils::GetStringFromResources(IDS_LVIEW_COPYRIGHT_OPENSSL).c_str(); +static CString listViewStringRapidJSON = LocUtils::GetStringFromResources(IDS_LVIEW_COPYRIGHT_RAPIDJSON).c_str(); +static CString listViewStringDokanyMir = LocUtils::GetStringFromResources(IDS_LVIEW_COPYRIGHT_DOKANY_MIR).c_str(); +static CString listViewStringDokanyLib = LocUtils::GetStringFromResources(IDS_LVIEW_COPYRIGHT_DOKANY_LIB).c_str(); +static CString listViewStringSecuryEdit = LocUtils::GetStringFromResources(IDS_LVIEW_COPYRIGHT_SECURE_EDIT).c_str(); +static CString listViewStringGetOpt = LocUtils::GetStringFromResources(IDS_LVIEW_COPYRIGHT_GETOPT_PORT).c_str(); +static CString listViewStringAESSIV = LocUtils::GetStringFromResources(IDS_LVIEW_COPYRIGHT_AES_SIV).c_str(); + +static const WCHAR* components[] = { + listViewStringCppcryptfs, + listViewStringOpenSSL, + listViewStringRapidJSON, + listViewStringDokanyMir, + listViewStringDokanyLib, + listViewStringSecuryEdit, + listViewStringGetOpt, + listViewStringAESSIV, NULL }; @@ -608,7 +158,7 @@ BOOL CCryptAboutPropertyPage::OnInitDialog() wstring prod = L"cppryptfs"; wstring ver = L"1.0"; - wstring copyright = L"Copyright (C) 2016-2025 Bailey Brown. All Rights Reserved."; + wstring copyright = LocUtils::GetStringFromResources(IDS_COPYRIGHT); GetProductVersionInfo(prod, ver, copyright); @@ -631,7 +181,7 @@ BOOL CCryptAboutPropertyPage::OnInitDialog() wstring openssl_ver_w; if (!utf8_to_unicode(openssl_ver_s.c_str(), openssl_ver_w)) - openssl_ver_w = L"error getting openssl version"; + openssl_ver_w = LocUtils::GetStringFromResources(IDS_ERR_GET_OPENSSL_VERSION); CString openssl_ver = openssl_ver_w.c_str(); @@ -639,27 +189,28 @@ BOOL CCryptAboutPropertyPage::OnInitDialog() std::wstring dok_ver; CString dokany_version; if (get_dokany_version(dok_ver, dv)) { - dokany_version = CString(L"; using Dokany ") + dok_ver.c_str(); + dokany_version = dok_ver.c_str(); } - wstring aes_ni; + CString aes_ni; if (AES::use_aes_ni()) { - aes_ni = L"; AES-NI detected"; + aes_ni = LocUtils::GetStringFromResources(IDS_AESNI_DETECTED).c_str(); } else { - aes_ni = L"; AES-NI not detected"; + aes_ni = LocUtils::GetStringFromResources(IDS_AESNI_NOT_DETECTED).c_str(); } - SetDlgItemText(IDC_LINKAGES, L"linked with " + openssl_ver + dokany_version); + CString strMsgLibraryVersions; + strMsgLibraryVersions.Format(LocUtils::GetStringFromResources(IDS_LIBRARY_VERSIONS).c_str(), openssl_ver, dokany_version); + SetDlgItemText(IDC_LINKAGES, strMsgLibraryVersions); bool is_admin = theApp.IsRunningAsAdministrator(); - CString prod_ver = prod.c_str(); - prod_ver += L" "; - prod_ver += ver.c_str(); - prod_ver += sizeof(void*) == 8 ? L" 64-bit" : L" 32-bit"; - prod_ver += (is_admin ? L" (admin)" : L""); + int prod_bit_depth = sizeof(void*) == 8 ? 64 : 32; + CString prod_admin = (is_admin ? CString(L" ") + LocUtils::GetStringFromResources(IDS_ADMIN).c_str() : CString(L"")); + CString strMsgCopyright; + strMsgCopyright.Format(LocUtils::GetStringFromResources(IDS_ABOUT_COPYRIGHT).c_str(), ver.c_str(), prod_bit_depth, prod_admin, aes_ni); - SetDlgItemText(IDC_PROD_VERSION, prod_ver + CString(aes_ni.c_str())); + SetDlgItemText(IDC_PROD_VERSION, strMsgCopyright); SetDlgItemText(IDC_COPYRIGHT, copyright.c_str()); CListCtrl *pList = (CListCtrl*)GetDlgItem(IDC_COMPONENTS_LIST); diff --git a/cppcryptfs/ui/CryptPropertySheet.cpp b/cppcryptfs/ui/CryptPropertySheet.cpp index f1ad8a36..43748f63 100755 --- a/cppcryptfs/ui/CryptPropertySheet.cpp +++ b/cppcryptfs/ui/CryptPropertySheet.cpp @@ -46,6 +46,7 @@ THE SOFTWARE. #include "../libcppcryptfs/util/KeyCache.h" #include "crypt/crypt.h" #include "cryptdefaults.h" +#include "locutils.h" // CryptPropertySheet @@ -80,8 +81,8 @@ CCryptPropertySheet::~CCryptPropertySheet() BOOL CCryptPropertySheet::CanClose() { if (!MountPointManager::getInstance().empty()) { - - if (MessageBox(L"All mounted cppcryptfs filesystems will be dismounted. Do you really wish to exit?", L"cppcryptfs", + + if (MessageBox(LocUtils::GetStringFromResources(IDS_DISMOUNT_ALL_ON_EXIT).c_str(), L"cppcryptfs", MB_YESNO | MB_ICONEXCLAMATION) == IDYES) { CString open_handles_mes = CheckOpenHandles(m_hWnd, nullptr, true, false).c_str(); diff --git a/cppcryptfs/ui/FolderDialog.cpp b/cppcryptfs/ui/FolderDialog.cpp index 8758ddf9..0e061a3e 100755 --- a/cppcryptfs/ui/FolderDialog.cpp +++ b/cppcryptfs/ui/FolderDialog.cpp @@ -6,6 +6,8 @@ #include "stdafx.h" #include "FolderDialog.h" +#include "locutils.h" +#include "resource.h" #ifdef _DEBUG #undef THIS_FILE @@ -44,10 +46,12 @@ CFolderDialog::CFolderDialog(LPCTSTR lpszFolderName, DWORD dwFlags, CWnd* pParen else m_bi.hwndOwner = pParentWnd->GetSafeHwnd(); + m_strTitleHolder = LocUtils::GetStringFromResources(IDS_SELECT_DIRECTORY).c_str(); + // Fill in the rest of the structure m_bi.pidlRoot = NULL; m_bi.pszDisplayName = m_szDisplayName; - m_bi.lpszTitle = _T("Select a directory"); + m_bi.lpszTitle = m_strTitleHolder; m_bi.ulFlags = dwFlags | BIF_NEWDIALOGSTYLE; m_bi.lpfn = BrowseDirectoryCallback; m_bi.lParam = (LPARAM)this; diff --git a/cppcryptfs/ui/FolderDialog.h b/cppcryptfs/ui/FolderDialog.h index c895dc0b..d270b640 100755 --- a/cppcryptfs/ui/FolderDialog.h +++ b/cppcryptfs/ui/FolderDialog.h @@ -9,6 +9,7 @@ #define _CFolderDialog_ #include +#include class CFolderDialog { @@ -50,6 +51,8 @@ friend static int CALLBACK BrowseDirectoryCallback( HWND m_hDialogBox; + CString m_strTitleHolder; + }; diff --git a/cppcryptfs/ui/FsInfoDialog.cpp b/cppcryptfs/ui/FsInfoDialog.cpp index 14ea934d..845d611b 100644 --- a/cppcryptfs/ui/FsInfoDialog.cpp +++ b/cppcryptfs/ui/FsInfoDialog.cpp @@ -34,6 +34,7 @@ THE SOFTWARE. #include "cppcryptfs.h" #include "FsInfoDialog.h" #include "afxdialogex.h" +#include "locutils.h" #ifdef _DEBUG @@ -87,9 +88,18 @@ BOOL CFsInfoDialog::OnInitDialog() { CDialog::OnInitDialog(); - LPCWSTR yes = L"Yes"; - LPCWSTR no = L"No"; - LPCWSTR na = L"n/a"; + CString strMsgYes, strMsgNo, strMsgNA, strMsgReverse, strMsgForward, strMsgKB, strMsgSec, strMsgInfinite, strMsgNone; + strMsgYes = LocUtils::GetStringFromResources(IDS_FSINFO_YES).c_str(); + strMsgNo = LocUtils::GetStringFromResources(IDS_FSINFO_NO).c_str(); + strMsgNA = LocUtils::GetStringFromResources(IDS_FSINFO_NA).c_str(); + strMsgReverse = LocUtils::GetStringFromResources(IDS_FSINFO_REVERSE).c_str(); + strMsgForward = LocUtils::GetStringFromResources(IDS_FSINFO_FORWARD).c_str(); + strMsgInfinite = LocUtils::GetStringFromResources(IDS_FSINFO_INFINITE).c_str(); + strMsgNone = LocUtils::GetStringFromResources(IDS_FSINFO_NAME_ENCRYPTION_NO).c_str(); + + LPCWSTR yes = strMsgYes; + LPCWSTR no = strMsgNo; + LPCWSTR na = strMsgNA; LPCWSTR path = m_info.path.c_str(); if (!wcsncmp(path, L"\\\\?\\", wcslen(L"\\\\?\\"))) { path += wcslen(L"\\\\?\\"); @@ -97,10 +107,19 @@ BOOL CFsInfoDialog::OnInitDialog() SetDlgItemText(IDC_PATH, m_info.path.c_str()); SetDlgItemText(IDC_MOUNT_POINT, m_mountPoint); SetDlgItemText(IDC_CONFIG_PATH, m_info.configPath.c_str()); - SetDlgItemText(IDC_FILE_NAME_ENCRYPTION, m_info.fileNameEncryption.c_str()); + + //To display localized text in the GUI + LPCWSTR none = strMsgNone; + if (m_info.fileNameEncryption == L"none") { + SetDlgItemText(IDC_FILE_NAME_ENCRYPTION, none); + } + else { + SetDlgItemText(IDC_FILE_NAME_ENCRYPTION, m_info.fileNameEncryption.c_str()); + } + SetDlgItemText(IDC_DATA_ENCRYPTION, m_info.dataEncryption.c_str()); SetDlgItemText(IDC_READ_ONLY, m_info.readOnly ? yes : no); - SetDlgItemText(IDC_MODE, m_info.reverse ? L"Reverse" : L"Forward"); + SetDlgItemText(IDC_MODE, m_info.reverse ? strMsgReverse : strMsgForward); SetDlgItemText(IDC_MOUNT_MANAGER, m_info.mountManager ? yes : no); SetDlgItemText(IDC_CASE_INSENSITIVE, m_info.caseInsensitive ? yes : no); SetDlgItemText(IDC_LONG_FILE_NAMES, m_info.longFileNames ? yes : no); @@ -113,17 +132,18 @@ BOOL CFsInfoDialog::OnInitDialog() wstring txt; txt = to_wstring(m_info.ioBufferSize); - txt += L" KB"; - SetDlgItemText(IDC_IO_BUF_SIZE, txt.c_str()); + strMsgKB.Format(LocUtils::GetStringFromResources(IDS_FSINFO_KB).c_str(), txt); + SetDlgItemText(IDC_IO_BUF_SIZE, strMsgKB); txt = m_info.multhreaded ? yes : no; SetDlgItemText(IDC_THREADS, txt.c_str()); if (m_info.cacheTTL > 0) { txt = to_wstring(m_info.cacheTTL); - txt += L" sec"; + strMsgSec.Format(LocUtils::GetStringFromResources(IDS_FSINFO_SEC).c_str(), txt); + SetDlgItemText(IDC_CACHE_TTL, strMsgSec); } else { - txt = L"infinite"; + SetDlgItemText(IDC_CACHE_TTL, strMsgInfinite); } - SetDlgItemText(IDC_CACHE_TTL, txt.c_str()); + WCHAR buf[32]; *buf = '\0'; float r; @@ -138,7 +158,7 @@ BOOL CFsInfoDialog::OnInitDialog() SetDlgItemText(IDC_CASE_CACHE_HR, txt.c_str()); r = m_info.lfnCacheHitRatio; if (r < 0.0f) { - txt = L"n/a"; + txt = strMsgNA; } else { _snwprintf_s(buf, _TRUNCATE, L"%.2f", r*100.0f); txt = buf; @@ -147,7 +167,7 @@ BOOL CFsInfoDialog::OnInitDialog() SetDlgItemText(IDC_LFN_CACHE_HR, txt.c_str()); r = m_info.dirIvCacheHitRatio; if (r < 0.0f) { - txt = L"n/a"; + txt = strMsgNA; } else { _snwprintf_s(buf, _TRUNCATE, L"%.2f", r*100.0f); txt = buf; diff --git a/cppcryptfs/ui/MountPropertyPage.cpp b/cppcryptfs/ui/MountPropertyPage.cpp index 8311bbd4..13c6aa5c 100644 --- a/cppcryptfs/ui/MountPropertyPage.cpp +++ b/cppcryptfs/ui/MountPropertyPage.cpp @@ -52,7 +52,7 @@ THE SOFTWARE. #include "dokan/MountPointManager.h" #include "../libipc/server.h" #include "../libcommonutil/commonutil.h" - +#include "locutils.h" #include // CMountPropertyPage dialog @@ -154,7 +154,7 @@ void CMountPropertyPage::DefaultAction() { CString mes = Mount(); - if (mes.GetLength() > 0 && mes != L"password cannot be empty") + if (mes.GetLength() > 0 && mes != LocUtils::GetStringFromResources(IDS_PASS_CANNOT_BE_EMPTY).c_str()) MessageBox(mes, L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); } @@ -169,24 +169,26 @@ CString CMountPropertyPage::Mount(LPCWSTR argPath, LPCWSTR argMountPoint, LPCWST LockZeroBuffer password(MAX_PASSWORD_LEN + 1, false); if (!password.IsLocked()) { - return CString(L"unable to lock password buffer"); + return LocUtils::GetStringFromResources(IDS_UNABLE_LOCK_BUFFER).c_str(); } - if (wcscpy_s(password.m_buf, MAX_PASSWORD_LEN + 1, argPassword ? argPassword : pPass->m_strRealText)) - return CString(L"unable to get password"); + if (wcscpy_s(password.m_buf, MAX_PASSWORD_LEN + 1, argPassword ? argPassword : pPass->m_strRealText)) { + return LocUtils::GetStringFromResources(IDS_UNABLE_GET_PASS).c_str(); + } - if (wcslen(password.m_buf) < 1) - return CString(L"password cannot be empty"); + if (wcslen(password.m_buf) < 1) { + return LocUtils::GetStringFromResources(IDS_PASS_CANNOT_BE_EMPTY).c_str(); + } CListCtrl *pList = (CListCtrl*)GetDlgItem(IDC_DRIVE_LETTERS); if (!pList) - return CString(L"unable to get list control"); + return LocUtils::GetStringFromResources(IDS_UNABLE_GET_LIST).c_str(); pos = pList->GetFirstSelectedItemPosition(); if (!pos) - return CString(L"unable to get selected entry"); + return LocUtils::GetStringFromResources(IDS_UNABLE_GET_SELECTED).c_str(); int nItem = -1; @@ -199,7 +201,9 @@ CString CMountPropertyPage::Mount(LPCWSTR argPath, LPCWSTR argMountPoint, LPCWST nItem = pList->FindItem(&fi); if (nItem < 0) { if (is_mountpoint_a_drive(str)) { - return CString(L"Mount point ") + str + CString(L" is already in use."); + CString strMsg; + strMsg.Format(LocUtils::GetStringFromResources(IDS_MPOINT_ALREADY_USED).c_str(), str); + return strMsg; } else { int i = pList->GetItemCount(); nItem = pList->InsertItem(LVIF_TEXT | (m_imageIndex >= 0 ? LVIF_IMAGE : 0) | LVIF_STATE, i, str, @@ -218,14 +222,14 @@ CString CMountPropertyPage::Mount(LPCWSTR argPath, LPCWSTR argMountPoint, LPCWST } if (nItem < 0) - return CString(L"unable to find item"); + return LocUtils::GetStringFromResources(IDS_UNABLE_FIND_ITEM).c_str(); CString cmp = argMountPoint && wcslen(argMountPoint) > 0 ? (wcslen(argMountPoint) == 1 ? CString(*argMountPoint) + L":" : argMountPoint) : pList->GetItemText(nItem, DL_INDEX); if (cmp.GetLength() < 1) - return CString(L"unable to get drive letter");; + return LocUtils::GetStringFromResources(IDS_UNABLE_GET_LETTER).c_str(); BOOL dlInUse = is_mountpoint_a_drive(cmp) && !IsDriveLetterAvailable(*(LPCWSTR)cmp); @@ -235,16 +239,15 @@ CString CMountPropertyPage::Mount(LPCWSTR argPath, LPCWSTR argMountPoint, LPCWST dlInUse = true; if (dlInUse) { - CString mes = L"Mount point "; - mes += cmp; - mes += L" is already being used."; + CString mes; + mes.Format(LocUtils::GetStringFromResources(IDS_MPOINT_ALREADY_USED).c_str(), cmp); return mes; } CWnd *pWnd = GetDlgItem(IDC_PATH); if (!pWnd) - return CString(L"unable to get window"); + return LocUtils::GetStringFromResources(IDS_UNABLE_GET_WINDOW).c_str(); CString cpath; @@ -253,8 +256,9 @@ CString CMountPropertyPage::Mount(LPCWSTR argPath, LPCWSTR argMountPoint, LPCWST else pWnd->GetWindowTextW(cpath); - if (cpath.GetLength() < 1) - return CString(L"path length is zero"); + if (cpath.GetLength() < 1) { + return LocUtils::GetStringFromResources(IDS_PATH_ZERO).c_str(); + } CString config_path; @@ -263,7 +267,7 @@ CString CMountPropertyPage::Mount(LPCWSTR argPath, LPCWSTR argMountPoint, LPCWST } else { pWnd = GetDlgItem(IDC_CONFIG_PATH); if (!pWnd) - return CString(L"unable to get window for config path"); + return LocUtils::GetStringFromResources(IDS_UNABLE_GET_CONF_WINDOW).c_str(); pWnd->GetWindowTextW(config_path); } @@ -292,10 +296,8 @@ CString CMountPropertyPage::Mount(LPCWSTR argPath, LPCWSTR argMountPoint, LPCWST } if (pathInUse) { - CString mes = L""; - mes += cpath; - mes += L" is already mounted on "; - mes += mdl; + CString mes; + mes.Format(LocUtils::GetStringFromResources(IDS_ALREADY_MOUNTED).c_str(), cpath, mdl); return mes; } @@ -323,14 +325,14 @@ CString CMountPropertyPage::Mount(LPCWSTR argPath, LPCWSTR argMountPoint, LPCWST CryptSettings::getInstance().GetSettings(opts); if (opts.denyothersessions || opts.denyservices) { - if (!CanGetSessionIdOk()) { - return CString(L"Unable to get session id. Deny other sessions/Deny services setting will not work and must be disabled."); + if (!CanGetSessionIdOk()) { + return LocUtils::GetStringFromResources(IDS_UNABLE_GET_SESSION_ID).c_str(); } if (!have_sessionid()) { - return CString(L"Unable to get current process session id. Deny other sessions/Deny services setting will not work and must be disabled."); + return LocUtils::GetStringFromResources(IDS_UNABLE_GET_PROCESS_SESSION_ID).c_str(); } if (get_sessionid() == 0) { - return CString(L"Current session id is 0. Deny other sessions/Deny services setting will not work and must be disabled."); + return LocUtils::GetStringFromResources(IDS_SESSION_ID_ZERO).c_str(); } } @@ -358,7 +360,7 @@ CString CMountPropertyPage::Mount(LPCWSTR argPath, LPCWSTR argMountPoint, LPCWST if (IsDlgButtonChecked(IDC_SAVE_PASSWORD)) { if (!SavedPasswords::SavePassword(cpath, password.m_buf)) { - MessageBox(L"unable to save password", L"cppcryptfs", MB_ICONEXCLAMATION | MB_OK); + MessageBox(LocUtils::GetStringFromResources(IDS_UNABLE_SAVE_PASS).c_str(), L"cppcryptfs", MB_ICONEXCLAMATION | MB_OK); } } @@ -492,7 +494,7 @@ BOOL CMountPropertyPage::OnInitDialog() // or using the string table resource CWnd *pWnd = GetDlgItem(IDC_SAVE_PASSWORD); if (pWnd) { - m_ToolTip.AddTool(pWnd, _T("To enable \"Save password\", turn on \"Enable saved passwords\" in the Settings tab.")); + m_ToolTip.AddTool(pWnd, LocUtils::GetStringFromResources(IDS_TOOLTIP_ENABLE_SAVE_PASS).c_str()); } } @@ -531,9 +533,9 @@ BOOL CMountPropertyPage::OnInitDialog() mountPointColumnWidth = 79; } - pList->InsertColumn(DL_INDEX, L"Mount Point", LVCFMT_LEFT, mountPointColumnWidth); + pList->InsertColumn(DL_INDEX, LocUtils::GetStringFromResources(IDS_COLUMN_HEADER_MOUNT_POINT).c_str(), LVCFMT_LEFT, mountPointColumnWidth); - pList->InsertColumn(PATH_INDEX, L"Path", LVCFMT_LEFT, 454-mountPointColumnWidth); + pList->InsertColumn(PATH_INDEX, LocUtils::GetStringFromResources(IDS_COLUMN_HEADER_PATH).c_str(), LVCFMT_LEFT, 454-mountPointColumnWidth); CString lastMountPoint = theApp.GetProfileString(L"MountPoints", L"LastMountPoint", L""); @@ -619,8 +621,9 @@ BOOL CMountPropertyPage::OnInitDialog() if (pCombo) pCombo->LimitText(MAX_PATH); - if (!m_password.ArePasswordBuffersLocked()) - MessageBox(L"unable to lock password buffer", L"cppcryptfs", MB_OK | MB_ICONERROR); + if (!m_password.ArePasswordBuffersLocked()) { + MessageBox(LocUtils::GetStringFromResources(IDS_UNABLE_LOCK_BUFFER).c_str(), L"cppcryptfs", MB_OK | MB_ICONERROR); + } ProcessCommandLine(GetCommandLine(), TRUE); @@ -747,7 +750,7 @@ void CMountPropertyPage::OnClickedMount() void CMountPropertyPage::OnClickedDismount() { CString mes = Dismount(nullptr, true, false); - if (mes.GetLength() > 0 && mes != L"operation cancelled by user") + if (mes.GetLength() > 0 && mes != LocUtils::GetStringFromResources(IDS_CANCELED_BY_USER).c_str()) MessageBox(mes, L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); } @@ -757,12 +760,12 @@ CString CMountPropertyPage::Dismount(LPCWSTR argMountPoint, bool interactive, bo CListCtrl *pList = (CListCtrl*)GetDlgItem(IDC_DRIVE_LETTERS); if (!pList) - return CString(L"unable to get list"); + return LocUtils::GetStringFromResources(IDS_UNABLE_GET_LIST).c_str(); POSITION pos = pList->GetFirstSelectedItemPosition(); if (!pos) - return CString(L"unable to get selection"); + return LocUtils::GetStringFromResources(IDS_UNABLE_GET_SELECTED).c_str(); int nItem; @@ -773,24 +776,30 @@ CString CMountPropertyPage::Dismount(LPCWSTR argMountPoint, bool interactive, bo CString str = wcslen(argMountPoint) == 1 ? CString(*argMountPoint) + L":" : argMountPoint; fi.psz = str; nItem = pList->FindItem(&fi); - if (nItem < 0) - return CString(L"Drive ") + str + CString(L" does not have a mounted cppcryptfs filesystem."); + if (nItem < 0) { + CString msg; + msg.Format(LocUtils::GetStringFromResources(IDS_DRIVE_WITHOUT_MOUNTED_FS).c_str(), str); + return msg; + } } else { nItem = pList->GetNextSelectedItem(pos); } if (nItem < 0) - return CString(L"unable to find item"); + return LocUtils::GetStringFromResources(IDS_UNABLE_FIND_ITEM).c_str(); CString cmp = pList->GetItemText(nItem, DL_INDEX); if (cmp.GetLength() < 1) - return CString(L"unable to get drive letter"); + return LocUtils::GetStringFromResources(IDS_UNABLE_GET_LETTER).c_str(); CString cpath = pList->GetItemText(nItem, PATH_INDEX); - if (cpath.GetLength() < 1) - return CString(L"Drive ") + cmp + CString(L" does not have a mounted cppcryptfs filesystem."); + if (cpath.GetLength() < 1) { + CString msg; + msg.Format(LocUtils::GetStringFromResources(IDS_DRIVE_WITHOUT_MOUNTED_FS).c_str(), cmp); + return msg; + } CString mes; @@ -811,10 +820,12 @@ CString CMountPropertyPage::Dismount(LPCWSTR argMountPoint, bool interactive, bo theApp.DoWaitCursor(-1); if (!bresult) { - if (mes.GetLength() > 0) + if (mes.GetLength() > 0) { mes += L". "; - mes += L"cannot unmount "; - mes.Append(cmp); + } + CString strMessage; + strMessage.Format(LocUtils::GetStringFromResources(IDS_CANNOT_UNMOUNT).c_str(), cmp); + mes += strMessage; if (wmes.length() > 0) { mes += L" "; mes += wmes.c_str(); @@ -845,7 +856,7 @@ CString CMountPropertyPage::DismountAll(bool interactive, bool forceDismount) CListCtrl *pList = (CListCtrl*)GetDlgItem(IDC_DRIVE_LETTERS); if (!pList) - return CString(L"unable to get list"); + return LocUtils::GetStringFromResources(IDS_UNABLE_GET_LIST).c_str(); int count = pList->GetItemCount(); @@ -902,16 +913,16 @@ CString CMountPropertyPage::DismountAll(bool interactive, bool forceDismount) if (hadFailure) { if (hadSuccess) { - mes = L"Some of the drives could not be dismounted"; + mes = LocUtils::GetStringFromResources(IDS_SOME_DRV_NOT_DISMOUNTED).c_str(); } else { - mes = L"Unable to dismount"; + mes = LocUtils::GetStringFromResources(IDS_UNABLE_DISMOUNT).c_str(); } } if (volnameFailure) { if (mes.GetLength() > 0) mes += L". "; - mes += L"unable to update one or more volume labels"; + mes += LocUtils::GetStringFromResources(IDS_UNABLE_UPDATE_LABELS).c_str(); } return mes; @@ -961,14 +972,18 @@ BOOL CMountPropertyPage::OnSetActive() if (flags & AUTO_MOUNT_FLAG) { CString mountPoint = theApp.GetProfileString(L"MountPoints", path_hash, NULL); if (mountPoint.GetLength() == 0) { - MessageBox(L"Fail to retrive MountPoint for " + m_lastDirs[i], L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); + CString strMessage; + strMessage.Format(LocUtils::GetStringFromResources(IDS_FAIL_RETRIVE_MPOINT).c_str(), m_lastDirs[i]); + MessageBox(strMessage, L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); continue; } LockZeroBuffer password(MAX_PASSWORD_LEN + 1, true); if (!SavedPasswords::RetrievePassword(m_lastDirs[i], password.m_buf, password.m_len)) { - MessageBox(L"Fail to retrive password for " + m_lastDirs[i], L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); + CString strMessage; + strMessage.Format(LocUtils::GetStringFromResources(IDS_FAIL_RETRIVE_PASS).c_str(), m_lastDirs[i]); + MessageBox(strMessage, L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); continue; } @@ -1723,7 +1738,7 @@ void CMountPropertyPage::OnContextMenu(CWnd* pWnd, CPoint point) if (!menu.CreatePopupMenu()) return; - menu.AppendMenu(MF_ENABLED, AddMountPointV, L"&Add Mount Point..."); + menu.AppendMenu(MF_ENABLED, AddMountPointV, LocUtils::GetStringFromResources(IDS_MENU_ADD_MOUNT_POINT).c_str()); int item = -1; @@ -1740,12 +1755,12 @@ void CMountPropertyPage::OnContextMenu(CWnd* pWnd, CPoint point) wstring mpstr; bool mounted = MountPointManager::getInstance().find(cmp, mpstr); if (mounted) { - menu.AppendMenu(MF_ENABLED, OpenV, L"Open...\tdouble-click"); - menu.AppendMenu(MF_ENABLED, PropertiesV, L"&Properties..."); - menu.AppendMenu(MF_ENABLED, DismountV, L"&Dismount"); + menu.AppendMenu(MF_ENABLED, OpenV, LocUtils::GetStringFromResources(IDS_MENU_OPEN).c_str()); + menu.AppendMenu(MF_ENABLED, PropertiesV, LocUtils::GetStringFromResources(IDS_MENU_PROPERTIES).c_str()); + menu.AppendMenu(MF_ENABLED, DismountV, LocUtils::GetStringFromResources(IDS_MENU_DISMOUNT).c_str()); } if (is_mountpoint_a_dir(cmp)) { - menu.AppendMenu(mounted ? MF_DISABLED : MF_ENABLED, DeleteMountPointV, L"Dele&te Mount Point"); + menu.AppendMenu(mounted ? MF_DISABLED : MF_ENABLED, DeleteMountPointV, LocUtils::GetStringFromResources(IDS_MENU_DELETE_MPOINT).c_str()); } } @@ -1806,8 +1821,7 @@ void CMountPropertyPage::AddMountPoint(const CString & path) return; if (!is_suitable_mountpoint(path)) { - MessageBox(L"The path is not suitable for use as a mount point. The folder must be empty, and it must reside on an NTFS filesystem", - L"cppcyrptfs", MB_OK | MB_ICONEXCLAMATION); + MessageBox(LocUtils::GetStringFromResources(IDS_PATH_NOT_SUITABLE_MPOINT).c_str(), L"cppcyrptfs", MB_OK | MB_ICONEXCLAMATION); return; } @@ -1816,7 +1830,7 @@ void CMountPropertyPage::AddMountPoint(const CString & path) int i = 0; for (CString mp = mountPointsStr.Tokenize(L"|", i); i >= 0; mp = mountPointsStr.Tokenize(L"|", i)) { if (!lstrcmpi(path, mp)) { - MessageBox(L"Mount point has already been added.", L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); + MessageBox(LocUtils::GetStringFromResources(IDS_MPOINT_ALREADY_ADDED).c_str(), L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); return; } } diff --git a/cppcryptfs/ui/SettingsPropertyPage.cpp b/cppcryptfs/ui/SettingsPropertyPage.cpp index e7a7bfe9..37c0e519 100644 --- a/cppcryptfs/ui/SettingsPropertyPage.cpp +++ b/cppcryptfs/ui/SettingsPropertyPage.cpp @@ -38,6 +38,7 @@ THE SOFTWARE. #include "ui/cryptdefaults.h" #include "ui/savedpasswords.h" #include "ui/uiutil.h" +#include "locutils.h" // CSettingsPropertyPage dialog @@ -95,10 +96,27 @@ static buffer_size_t buffer_sizes[] = { 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2 static int ttls[] = { 0, 1, 2, 5, 10, 15, 30, 45, 60, 90, 120, 300, 600, 900, 1800, 3600}; -static const WCHAR* ttl_strings[] = { L"infinite", L"1 second", L"2 seconds", L"5 seconds", - L"10 seconds", L"15 seconds", L"30 seconds", L"45 seconds", - L"60 seconds", L"90 seconds", L"2 minutes", L"5 minutes", - L"10 minutes", L"15 minutes", L"30 minutes", L"1 hour" }; +static CString listBoxStringInfinite = LocUtils::GetStringFromResources(IDS_TTL_INFINITE).c_str(); +static CString listBoxStringSec1 = LocUtils::GetStringFromResources(IDS_TTL_SEC_1).c_str(); +static CString listBoxStringSec2 = LocUtils::GetStringFromResources(IDS_TTL_SEC_2).c_str(); +static CString listBoxStringSec5 = LocUtils::GetStringFromResources(IDS_TTL_SEC_5).c_str(); +static CString listBoxStringSec10 = LocUtils::GetStringFromResources(IDS_TTL_SEC_10).c_str(); +static CString listBoxStringSec15 = LocUtils::GetStringFromResources(IDS_TTL_SEC_15).c_str(); +static CString listBoxStringSec30 = LocUtils::GetStringFromResources(IDS_TTL_SEC_30).c_str(); +static CString listBoxStringSec45 = LocUtils::GetStringFromResources(IDS_TTL_SEC_45).c_str(); +static CString listBoxStringSec60 = LocUtils::GetStringFromResources(IDS_TTL_SEC_60).c_str(); +static CString listBoxStringSec90 = LocUtils::GetStringFromResources(IDS_TTL_SEC_90).c_str(); +static CString listBoxStringMin2 = LocUtils::GetStringFromResources(IDS_TTL_MIN_2).c_str(); +static CString listBoxStringMin5 = LocUtils::GetStringFromResources(IDS_TTL_MIN_5).c_str(); +static CString listBoxStringMin10 = LocUtils::GetStringFromResources(IDS_TTL_MIN_10).c_str(); +static CString listBoxStringMin15 = LocUtils::GetStringFromResources(IDS_TTL_MIN_15).c_str(); +static CString listBoxStringMin30 = LocUtils::GetStringFromResources(IDS_TTL_MIN_30).c_str(); +static CString listBoxStringHour1 = LocUtils::GetStringFromResources(IDS_TTL_HOUR_1).c_str(); + +static const WCHAR* ttl_strings[] = { listBoxStringInfinite, listBoxStringSec1, listBoxStringSec2, listBoxStringSec5, + listBoxStringSec10, listBoxStringSec15, listBoxStringSec30, listBoxStringSec45, + listBoxStringSec60, listBoxStringSec90, listBoxStringMin2, listBoxStringMin5, + listBoxStringMin10, listBoxStringMin15, listBoxStringMin30, listBoxStringHour1 }; BOOL CSettingsPropertyPage::OnInitDialog() { @@ -295,18 +313,18 @@ void CSettingsPropertyPage::OnClickedEnableSavingPasswords() bool neversavehistory = false; CryptSettings::getInstance().GetSettingCurrent(NEVER_SAVE_HISTORY, neversavehistory); if (neversavehistory) { - MessageBox(L"Passwords will not be saved if \"Never save history\" is turned on.", + MessageBox(LocUtils::GetStringFromResources(IDS_PASS_WILL_NOT_BE_SAVED).c_str(), L"cppcryptfs", MB_OK | MB_ICONINFORMATION); } } else { int numSavedPasswords = SavedPasswords::ClearSavedPasswords(FALSE); if (numSavedPasswords < 0) { - MessageBox(L"unable to count saved passwords", L"cppcryptfs", MB_ICONEXCLAMATION | MB_OK); + MessageBox(LocUtils::GetStringFromResources(IDS_UNABLE_COUNT_SAVED_PASS).c_str(), L"cppcryptfs", MB_ICONEXCLAMATION | MB_OK); } else if (numSavedPasswords > 0) { - int result = MessageBox(L"Delete all saved passwords?", L"cppcryptfs", MB_ICONWARNING | MB_YESNO); + int result = MessageBox(LocUtils::GetStringFromResources(IDS_DELETE_ALL_SAVED_PASS).c_str(), L"cppcryptfs", MB_ICONWARNING | MB_YESNO); if (result == IDYES) { if (SavedPasswords::ClearSavedPasswords(TRUE) != numSavedPasswords) { - MessageBox(L"unable to delete saved passwords", L"cppcryptfs", MB_ICONEXCLAMATION | MB_OK); + MessageBox(LocUtils::GetStringFromResources(IDS_UNABLE_DELETE_SAVED_PASS).c_str(), L"cppcryptfs", MB_ICONEXCLAMATION | MB_OK); } } } @@ -329,8 +347,7 @@ void CSettingsPropertyPage::OnClickedNeverSaveHistory() CryptSettings::getInstance().GetSettingCurrent(ENABLE_SAVING_PASSWORDS, enablesavingpasswords); if (enablesavingpasswords) { - MessageBox(L"If you turn on \"Never save history\", saved passwords will not be deleted, but new passwords will not " - L"be saved. To delete any saved passwords, uncheck \"Enable saved passwords\".", + MessageBox(LocUtils::GetStringFromResources(IDS_NEVER_SAVE_HISTORY_HINT).c_str(), L"cppcryptfs", MB_OK | MB_ICONINFORMATION); } @@ -354,7 +371,7 @@ void CSettingsPropertyPage::OnClickedNeverSaveHistory() DeleteAllRegisteryValues(CPPCRYPTFS_REG_PATH L"CreateOptions", mes); error += mes; if (!error.empty()) { - MessageBox(L"unable to delete history from registry", L"cppcryptfs", + MessageBox(LocUtils::GetStringFromResources(IDS_UNABLE_DELETE_HISTORY).c_str(), L"cppcryptfs", MB_OK | MB_ICONEXCLAMATION); } } diff --git a/cppcryptfs/ui/locutils.cpp b/cppcryptfs/ui/locutils.cpp new file mode 100644 index 00000000..b272447d --- /dev/null +++ b/cppcryptfs/ui/locutils.cpp @@ -0,0 +1,11 @@ +#include "locutils.h" +#define VC_EXTRALEAN +#include + +std::wstring LocUtils::GetStringFromResources(unsigned int nID) { + ATL::CStringW str; + if (str.LoadString(nID)) { + return std::wstring((LPCWSTR)str); + } + return L""; +} diff --git a/cppcryptfs/ui/locutils.h b/cppcryptfs/ui/locutils.h new file mode 100644 index 00000000..9b6dda7d --- /dev/null +++ b/cppcryptfs/ui/locutils.h @@ -0,0 +1,7 @@ +#pragma once +#include + +class LocUtils { +public: + static std::wstring GetStringFromResources(unsigned int nID); +}; diff --git a/cppcryptfs/ui/uiutil.cpp b/cppcryptfs/ui/uiutil.cpp index df26be27..1ada2282 100644 --- a/cppcryptfs/ui/uiutil.cpp +++ b/cppcryptfs/ui/uiutil.cpp @@ -28,7 +28,7 @@ THE SOFTWARE. #include "stdafx.h" #include "uiutil.h" - +#include "cppcryptfs.h" #include #include "ui/MountMangerDialog.h" @@ -36,6 +36,8 @@ THE SOFTWARE. #include "ui/certutil.h" #include "ui/CryptSettings.h" #include "dokan/cryptdokan.h" +#include "resource.h" +#include "locutils.h" using namespace std; @@ -56,7 +58,7 @@ bool DeleteAllRegisteryValues(LPCWSTR regPath, wstring& mes) LSTATUS status = ::RegOpenKeyEx(HKEY_CURRENT_USER, regPath, 0, KEY_ALL_ACCESS, &hkey); if (status != ERROR_SUCCESS) { if (status != ERROR_FILE_NOT_FOUND) { - mes = L"unable to open history"; + mes = LocUtils::GetStringFromResources(IDS_UNABLE_OPEN_HISTORY); } return false; } @@ -73,7 +75,7 @@ bool DeleteAllRegisteryValues(LPCWSTR regPath, wstring& mes) if (status != ERROR_NO_MORE_ITEMS) { ::RegCloseKey(hkey); - mes = L"error while deleting history"; + mes = LocUtils::GetStringFromResources(IDS_ERR_DELETING_HISTORY); return false; } @@ -81,7 +83,7 @@ bool DeleteAllRegisteryValues(LPCWSTR regPath, wstring& mes) status = RegDeleteValue(hkey, it.c_str()); if (status != ERROR_SUCCESS) { ::RegCloseKey(hkey); - mes = L"error while deleting registry value"; + mes = LocUtils::GetStringFromResources(IDS_ERR_DELETING_REG_VALUE); return false; } } @@ -118,13 +120,15 @@ wstring CheckOpenHandles(HWND hWnd, const wchar_t* mp, bool interactive, bool fo } else if (open_handle_count > 0) { if (interactive) { - auto res = ::MessageBox(hWnd, mp ? (wstring(mp) + L" is still in use. Do you wish to continue dismounting?").c_str() : - L"Filesystem(s) are still in use. Do you wish to continue dismounting?", - L"cppcryptfs", MB_YESNO | MB_ICONHAND); + CString strMsg; + strMsg.Format(LocUtils::GetStringFromResources(IDS_IS_STILL_IN_USE).c_str(), mp); + auto res = ::MessageBox(hWnd, mp ? strMsg : LocUtils::GetStringFromResources(IDS_FS_IS_STILL_IN_USE).c_str(), L"cppcryptfs", MB_YESNO | MB_ICONHAND); if (res == IDYES) return L""; - else - return L"operation cancelled by user"; + else { + std::wstring strMsgCanceledByUser = LocUtils::GetStringFromResources(IDS_CANCELED_BY_USER); + return strMsgCanceledByUser; + } } else { return mp ? wstring(mp) + L" is still in use. Use --force to force dismounting." : diff --git a/libcppcryptfs/config/cryptconfig.cpp b/libcppcryptfs/config/cryptconfig.cpp index 05526df8..2cbb2741 100644 --- a/libcppcryptfs/config/cryptconfig.cpp +++ b/libcppcryptfs/config/cryptconfig.cpp @@ -64,6 +64,9 @@ THE SOFTWARE. #include "util/LockZeroBuffer.h" #include "filename/cryptfilename.h" #include "../libcommonutil/commonutil.h" +#include "../cppcryptfs/resource.h" +#include "../cppcryptfs/ui/locutils.h" +#include CryptConfig::CryptConfig() { @@ -114,7 +117,7 @@ CryptConfig::read(wstring& mes, const WCHAR *config_file_path, bool reverse) if (config_file_path) { if (_wfopen_s(&fl, config_file_path, L"rb")) { - mes = L"failed to open config file"; + mes = LocUtils::GetStringFromResources(IDS_FAILED_OPEN_CONF); return false; } m_configPath = config_file_path; @@ -124,7 +127,7 @@ CryptConfig::read(wstring& mes, const WCHAR *config_file_path, bool reverse) wstring config_path; if (m_basedir.size() < 1) { - mes = L"cannot read config because base dir is empty"; + mes = LocUtils::GetStringFromResources(IDS_NOT_CONF_DIR_EMPTY); return false; } @@ -138,7 +141,7 @@ CryptConfig::read(wstring& mes, const WCHAR *config_file_path, bool reverse) if (_wfopen_s(&fl, &config_file[0], L"rb")) { config_file = config_path + CONFIG_NAME; if (_wfopen_s(&fl, &config_file[0], L"rb")) { - mes = L"failed to open config file"; + mes = LocUtils::GetStringFromResources(IDS_FAILED_OPEN_CONF); return false; } m_reverse = false; @@ -152,24 +155,24 @@ CryptConfig::read(wstring& mes, const WCHAR *config_file_path, bool reverse) File.reset(fl); if (fseek(fl, 0, SEEK_END)) { - mes = L"unable to seek to end of config file"; + mes = LocUtils::GetStringFromResources(IDS_NOT_FOUND_END_CONF); return false; } long filesize = ftell(fl); if (filesize > MAX_CONFIG_FILE_SIZE) { - mes = L"config file is too big"; + mes = LocUtils::GetStringFromResources(IDS_CONF_TOO_BIG); return false; } if (filesize < 1) { - mes = L"config file is empty"; + mes = LocUtils::GetStringFromResources(IDS_CONF_EMPTY); return false; } if (fseek(fl, 0, SEEK_SET)) { - mes = L"unable to seek to beginning of config file"; + mes = LocUtils::GetStringFromResources(IDS_NOT_FOUND_BEGINNING_CONF); return false; } @@ -178,14 +181,14 @@ CryptConfig::read(wstring& mes, const WCHAR *config_file_path, bool reverse) char* buf = buf_rsc.get(); if (!buf) { - mes = L"cannot allocate buffer for reading config file"; + mes = LocUtils::GetStringFromResources(IDS_CANNOT_ALLOCATE_BUFFER_CONF); return false; } size_t len = fread(buf, 1, filesize, fl); if (len < 0) { - mes = L"read error when reading config file"; + mes = LocUtils::GetStringFromResources(IDS_RAED_ERR_CONF); return false; } @@ -196,7 +199,7 @@ CryptConfig::read(wstring& mes, const WCHAR *config_file_path, bool reverse) d.Parse(buf); if (!d.IsObject()) { - mes = L"config file is not valid JSON"; + mes = LocUtils::GetStringFromResources(IDS_CONF_NOT_VALID_JSON); return false; } @@ -205,19 +208,19 @@ CryptConfig::read(wstring& mes, const WCHAR *config_file_path, bool reverse) try { if (!d.HasMember("EncryptedKey") || !d["EncryptedKey"].IsString()) { - mes = L"key missing in config file"; + mes = LocUtils::GetStringFromResources(IDS_KEY_MISSING_IN_CONF); throw (-1); } rapidjson::Value& v = d["EncryptedKey"]; if (!base64_decode(v.GetString(), m_encrypted_key, false, true)) { - mes = L"failed to base64 decode key in config file"; + mes = LocUtils::GetStringFromResources(IDS_FAILED_BASE64_DECODE_KEY); throw (-1); } if (!d.HasMember("ScryptObject") || !d["ScryptObject"].IsObject()) { - mes = L"ScryptObject missing in config file"; + mes = LocUtils::GetStringFromResources(IDS_SCRYPTOBJECT_MISSING_IN_CONF); throw (-1); } @@ -225,7 +228,7 @@ CryptConfig::read(wstring& mes, const WCHAR *config_file_path, bool reverse) if (!base64_decode(scryptobject["Salt"].GetString(), m_encrypted_key_salt, false, true)) { - mes = L"failed to base64 decode Scrypt Salt in config file"; + mes = LocUtils::GetStringFromResources(IDS_FAILED_BASE64_DECODE_SALT); throw (-1); } @@ -235,7 +238,7 @@ CryptConfig::read(wstring& mes, const WCHAR *config_file_path, bool reverse) for (i = 0; i < sizeof(sstuff) / sizeof(sstuff[0]); i++) { if (scryptobject[sstuff[i]].IsNull() || !scryptobject[sstuff[i]].IsInt()) { - mes = L"invalid Scrypt object in config file"; + mes = LocUtils::GetStringFromResources(IDS_INVALID_SCRYPTOBJECT); throw (-1); } } @@ -246,21 +249,21 @@ CryptConfig::read(wstring& mes, const WCHAR *config_file_path, bool reverse) int keyLen = scryptobject["KeyLen"].GetInt(); if (keyLen != 32) { - mes = L"invalid KeyLen in config file"; + mes = LocUtils::GetStringFromResources(IDS_INVALID_KEYLEN); throw(-1); } m_pKeyBuf = new LockZeroBuffer(keyLen, false); if (!m_pKeyBuf->IsLocked()) { - mes = L"failed to lock key buffer while reading config file"; + mes = LocUtils::GetStringFromResources(IDS_FAILED_LOCK_BUFFER_READ_CONF); throw(-1); } m_keybuf_manager.RegisterBuf(m_pKeyBuf); if (d["Version"].IsNull() || !d["Version"].IsInt()) { - mes = L"invalid Version in config file"; + mes = LocUtils::GetStringFromResources(IDS_INVALID_VERSION_IN_CONF); throw (-1); } @@ -284,7 +287,7 @@ CryptConfig::read(wstring& mes, const WCHAR *config_file_path, bool reverse) try { m_fs_feature_disable_mask = stoul(fs_str, nullptr, 16); } catch (std::invalid_argument&) { - mes = L"invalid FsFeatureDisableMask in config file"; + mes = LocUtils::GetStringFromResources(IDS_INVALID_FSFEATUREDISABLEMASK); throw(-1); } } @@ -318,10 +321,11 @@ CryptConfig::read(wstring& mes, const WCHAR *config_file_path, bool reverse) } else { wstring wflag; if (utf8_to_unicode(itr->GetString(), wflag)) { - mes = L"unkown feature flag in config file: "; - mes += wflag; + CString strMsg; + strMsg.Format(LocUtils::GetStringFromResources(IDS_UNKNOWN_FEATURE_FLAG).c_str(), wflag); + mes = strMsg; } else { - mes = L"unable to convert unkown flag in config file to unicode"; + mes = LocUtils::GetStringFromResources(IDS_UNABLE_CONVERT_UNKNOWN_FLAG); } throw(-1); } @@ -338,11 +342,11 @@ CryptConfig::read(wstring& mes, const WCHAR *config_file_path, bool reverse) } m_LongNameMax = lnm; } catch (std::invalid_argument&) { - mes = L"invalid LongNameMax in config file"; + mes = LocUtils::GetStringFromResources(IDS_INVALID_LONGNAMEMAX); throw(-1); } } else { - mes = L"LongNameMax feature flag specified but no LongNameMax value provided"; + mes = LocUtils::GetStringFromResources(IDS_NO_VALUE_LONGNAMEMAX); throw(-1); } } @@ -601,16 +605,16 @@ bool CryptConfig::check_config(wstring& mes) mes = L""; if (m_Version != 2) - mes += L"Only version 2 is supported\n"; + mes += LocUtils::GetStringFromResources(IDS_ONLY_VERSION_2_SUPPORT); if (!m_EMENames && !m_PlaintextNames) - mes += L"EMENames is required unless PlaintextNames is specified\n"; + mes += LocUtils::GetStringFromResources(IDS_EMENAMES_REQUIRED); if (!m_GCMIV128) - mes += L"GCMIV128 must be specified\n"; + mes += LocUtils::GetStringFromResources(IDS_GCMIV128_NOT_SPECIFIED); if (m_reverse && !m_AESSIV) - mes += L"reverse mode is being used but AESSIV not specfied\n"; + mes += LocUtils::GetStringFromResources(IDS_REVERSE_MODE_WITHOUT_AESSIV); return mes.size() == 0; } @@ -726,7 +730,7 @@ bool CryptConfig::encrypt_key(const wchar_t* password, const BYTE* masterkey, st LockZeroBuffer pwkeyHKDF(MASTER_KEY_LEN, false); if (!pwkey.IsLocked() || !pwkeyHKDF.IsLocked()) { - error_mes = L"pw key not locked"; + error_mes = LocUtils::GetStringFromResources(IDS_PWKEY_NOT_LOCKED); return false; } @@ -734,14 +738,14 @@ bool CryptConfig::encrypt_key(const wchar_t* password, const BYTE* masterkey, st if (masterkey) { if (m_pKeyBuf) { - error_mes = L"master key is already set"; + error_mes = LocUtils::GetStringFromResources(IDS_MASTER_KEY_ALREADY_SET); return false; } m_pKeyBuf = new LockZeroBuffer(DEFAULT_KEY_LEN, false); if (!m_pKeyBuf->IsLocked()) { - error_mes = L"cannot lock key buffer\n"; + error_mes = LocUtils::GetStringFromResources(IDS_CANNOT_LOCK_KEY_BUFFER); throw(-1); } @@ -753,18 +757,18 @@ bool CryptConfig::encrypt_key(const wchar_t* password, const BYTE* masterkey, st m_encrypted_key_salt.resize(SALT_LEN); if (!get_sys_random_bytes(&m_encrypted_key_salt[0], SALT_LEN)) { - error_mes = L"get random bytes for salt failed\n"; + error_mes = LocUtils::GetStringFromResources(IDS_FAILED_GET_RANDOM); throw(-1); } LockZeroBuffer utf8pass(256, false); if (!utf8pass.IsLocked()) { - error_mes = L"utf8 pass is not locked"; + error_mes = LocUtils::GetStringFromResources(IDS_UTF8PASS_NOT_LOCKED); return false; } if (!unicode_to_utf8(password, utf8pass.m_buf, utf8pass.m_len - 1)) { - error_mes = L"cannot convert password to utf-8\n"; + error_mes = LocUtils::GetStringFromResources(IDS_CANNOT_CONVERT_PASS_UTF8); throw(-1); } @@ -774,13 +778,13 @@ bool CryptConfig::encrypt_key(const wchar_t* password, const BYTE* masterkey, st GetMasterKeyLength()); if (result != 1) { - error_mes = L"key derivation failed\n"; + error_mes = LocUtils::GetStringFromResources(IDS_KEY_DERIVATION_FAILED); throw(-1); } if (m_HKDF) { if (!hkdfDerive(pwkey.m_buf, pwkey.m_len, pwkeyHKDF.m_buf, pwkeyHKDF.m_len, hkdfInfoGCMContent)) { - error_mes = L"unable to perform hkdf on pw key"; + error_mes = LocUtils::GetStringFromResources(IDS_UNABLE_HKDF_ON_PWKEY); throw(-1); } } @@ -790,7 +794,7 @@ bool CryptConfig::encrypt_key(const wchar_t* password, const BYTE* masterkey, st int iv_len = m_HKDF ? HKDF_MASTER_IV_LEN : ORIG_MASTER_IV_LEN; if (!get_sys_random_bytes(iv, iv_len)) { - error_mes = L"unable to generate iv\n"; + error_mes = LocUtils::GetStringFromResources(IDS_UNABLE_GENERATE_IV); throw(-1); } @@ -801,14 +805,14 @@ bool CryptConfig::encrypt_key(const wchar_t* password, const BYTE* masterkey, st memset(adata, 0, adata_len); if (!InitGCMContentKey(GetMasterKey())) { - error_mes = L"unable to init gcm content key for volume name"; + error_mes = LocUtils::GetStringFromResources(IDS_UNABLE_INIT_GCM); throw(-1); } context = get_crypt_context(iv_len, AES_MODE_GCM); if (!context) { - error_mes = L"unable to get gcm context\n"; + error_mes = LocUtils::GetStringFromResources(IDS_UNABLE_GET_GCM); throw(-1); } @@ -820,19 +824,19 @@ bool CryptConfig::encrypt_key(const wchar_t* password, const BYTE* masterkey, st iv, (encrypted_key + iv_len), encrypted_key + iv_len + GetMasterKeyLength(), context.get()); if (ctlen < 1) { - error_mes = L"unable to encrypt master key\n"; + error_mes = LocUtils::GetStringFromResources(IDS_UNABLE_ENCRYPT_MASTER_KEY); throw(-1); } const char* base64_key = base64_encode(encrypted_key, GetMasterKeyLength() + iv_len + BLOCK_TAG_LEN, base64encryptedmasterkey, false, true); if (!base64_key) { - error_mes = L"unable to base64 encode key\n"; + error_mes = LocUtils::GetStringFromResources(IDS_UNABLE_BASE64_ENCODE_KEY); throw(-1); } if (!base64_encode(&m_encrypted_key_salt[0], (DWORD)m_encrypted_key_salt.size(), scryptSalt, false, true)) { - error_mes = L"unable to base64 encode salt\n"; + error_mes = LocUtils::GetStringFromResources(IDS_UNABLE_BASE64_ENCODE_SALT); throw(-1); } } @@ -899,22 +903,26 @@ bool CryptConfig::create(const WCHAR *path, const WCHAR *specified_config_file_p } if (m_reverse && !m_AESSIV) { - error_mes = L"AES256-SIV must be used with Reverse\n"; + error_mes = LocUtils::GetStringFromResources(IDS_ONLY_AES256SIV_WITH_REVERSE); throw(-1); } if (m_reverse) { if (PathFileExists(&config_path[0])) { if (specified_config_file_path) { - error_mes = config_path + L" already exists. Please remove it and try again."; + CString strMsg; + strMsg.Format(LocUtils::GetStringFromResources(IDS_CONF_PATH_ALREADY_EXIST).c_str(), config_path); + error_mes = strMsg; } else { - error_mes = config_path + L" (normally a hidden file) already exists. Please remove it and try again."; + CString strMsg; + strMsg.Format(LocUtils::GetStringFromResources(IDS_CONF_PATH_HIDDEN_EXIST).c_str(), config_path); + error_mes = strMsg; } throw(-1); } } else { if (!can_delete_directory(&m_basedir[0], TRUE)) { - error_mes = L"the directory is not empty\n"; + error_mes = LocUtils::GetStringFromResources(IDS_DIR_NOT_EMPTY); throw(-1); } } @@ -926,12 +934,12 @@ bool CryptConfig::create(const WCHAR *path, const WCHAR *specified_config_file_p m_pKeyBuf = new LockZeroBuffer(DEFAULT_KEY_LEN, false); if (!m_pKeyBuf->IsLocked()) { - error_mes = L"cannot lock key buffer\n"; + error_mes = LocUtils::GetStringFromResources(IDS_CANNOT_LOCK_KEY_BUFFER); throw(-1); } if (!get_sys_random_bytes(m_pKeyBuf->m_buf, GetMasterKeyLength())) { - error_mes = L"unable to generate master key\n"; + error_mes = LocUtils::GetStringFromResources(IDS_UNABLE_GENERATE_MASTER_KEY); throw(-1); } @@ -960,7 +968,7 @@ bool CryptConfig::create(const WCHAR *path, const WCHAR *specified_config_file_p if (vol.size() > MAX_VOLUME_NAME_LENGTH) vol.erase(MAX_VOLUME_NAME_LENGTH, wstring::npos); if (!encrypt_string_gcm(vol, GetGcmContentKey(), volume_name_utf8)) { - error_mes = L"cannot encrypt volume name\n"; + error_mes = LocUtils::GetStringFromResources(IDS_CANNOT_ENCRYPT_VOLUME_NAME); throw(-1); } } @@ -969,12 +977,12 @@ bool CryptConfig::create(const WCHAR *path, const WCHAR *specified_config_file_p auto fl = File.get(); if (!fl) { - error_mes = L"cannot create config file\n"; + error_mes = LocUtils::GetStringFromResources(IDS_CANNOT_CREATE_CONF); throw(-1); } if (!fl) { - error_mes = L"unable to open config file for writing\n"; + error_mes = LocUtils::GetStringFromResources(IDS_UNABLE_OPEN_WRITE_CONF); throw(-1); } @@ -1037,7 +1045,7 @@ bool CryptConfig::create(const WCHAR *path, const WCHAR *specified_config_file_p if (m_DirIV && !m_reverse) { if (!create_dir_iv(NULL, &m_basedir[0])) { - error_mes = L"cannot create diriv file\n"; + error_mes = LocUtils::GetStringFromResources(IDS_CANNOT_CREATE_DIRIV); throw(-1); } } @@ -1045,7 +1053,7 @@ bool CryptConfig::create(const WCHAR *path, const WCHAR *specified_config_file_p } catch (...) { if (error_mes.size() < 1) - error_mes = L"memory allocation failure\n"; + error_mes = LocUtils::GetStringFromResources(IDS_MEMORY_ALLOCATION_FAILURE); bret = false; } diff --git a/libcppcryptfs/libcppcryptfs.vcxproj b/libcppcryptfs/libcppcryptfs.vcxproj index 5e1647fd..d7ca69fd 100644 --- a/libcppcryptfs/libcppcryptfs.vcxproj +++ b/libcppcryptfs/libcppcryptfs.vcxproj @@ -169,6 +169,7 @@ + @@ -202,6 +203,10 @@ + + NotUsing + NotUsing + diff --git a/libcppcryptfs/libcppcryptfs.vcxproj.filters b/libcppcryptfs/libcppcryptfs.vcxproj.filters index a334313a..f7036600 100644 --- a/libcppcryptfs/libcppcryptfs.vcxproj.filters +++ b/libcppcryptfs/libcppcryptfs.vcxproj.filters @@ -28,6 +28,7 @@ + @@ -61,5 +62,6 @@ + - \ No newline at end of file +