Esempio n. 1
0
static void
OpenOrCreate(HWND hwnd)
{
	static bool openAlreadyOpened = false;

	if (openAlreadyOpened)
		return;

	class Unique {
	public:
		Unique() { openAlreadyOpened = true; }
		~Unique() { openAlreadyOpened = false; }
	} unique;

	std::tstring dir = GetExistingDirectory(hwnd,
		_T("Select a folder which contains or will contain encrypted data."), _T("Select Crypt Folder"));
	if (dir.empty())
		return;

	// if directory is already configured add and try to mount
	boost::shared_ptr<EncFSConfig> config(new EncFSConfig);
	if (readConfig(slashTerminate(wchar_to_utf8_cstr(dir.c_str())), config) != Config_None) {
		char drive = SelectFreeDrive(hwnd);
		if (drive) {
			Drives::drive_t dr(Drives::Add(dir, drive));
			if (dr)
				dr->Mount(hwnd);
		}
		return;
	}

	// TODO check directory is empty, warning if continue
	// "You are initializing a crypted directory with a no-empty directory. Is this expected?"
	OptionsData data;
	data.rootDir = dir;
	if (DialogBoxParam(hInst, (LPCTSTR) IDD_OPTIONS, hwnd, (DLGPROC) OptionsDlgProc, (LPARAM) &data) != IDOK)
		return;

	// add configuration and add new drive
	createConfig(slashTerminate(wchar_to_utf8_cstr(dir.c_str())), data.paranoia, false, wchar_to_utf8_cstr(data.password).c_str(), true);

	Drives::drive_t dr(Drives::Add(dir, data.drive));
	if (dr)
		dr->Mount(hwnd);
}
Esempio n. 2
0
void Drive::Mount(HWND hwnd)
{
	// check drive empty or require a new drive
	while (GetDriveType(mnt) != DRIVE_NO_ROOT_DIR) {
		char drive = SelectFreeDrive(hwnd);
		if (!drive)
			return;
		_stprintf(mnt, _T("%c:\\"), drive);
		Save();
	}

	// check directory existence
	if (!isDirectory(wchar_to_utf8_cstr(dir.c_str()).c_str())) {
		if (YesNo(hwnd, _T("Directory does not exists. Remove from list?")))
			Drives::Delete(shared_from_this());
		return;
	}

	// TODO check configuration still exists ?? ... no can cause recursion problem

	// search if executable is present
	TCHAR executable[MAX_PATH];
	if (!SearchPath(NULL, _T("encfs.exe"), NULL, LENGTH(executable), executable, NULL))
		throw truntime_error(_T("Unable to find encfs.exe file"));

	// ask a password to mount
	TCHAR pass[128+2];
	if (!GetPassword(hwnd, pass, LENGTH(pass)-2))
		return;
	_tcscat(pass, _T("\r\n"));

	// mount using a sort of popen
	TCHAR cmd[2048];
	_sntprintf(cmd, LENGTH(cmd), _T("\"%s\" -S \"%s\" %c:"), executable, dir.c_str(), mnt[0]);
	boost::shared_ptr<SubProcessInformations> proc(new SubProcessInformations);
	proc->creationFlags = CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW;
	if (!CreateSubProcess(cmd, proc.get())) {
		DWORD err = GetLastError();
		memset(pass, 0, sizeof(pass));
		_sntprintf(cmd, LENGTH(cmd), _T("Error: %s (%u)"), proc->errorPart, (unsigned) err);
		throw truntime_error(cmd);
	}
	subProcess = proc;

	// send the password
	std::string pwd = wchar_to_utf8_cstr(pass);
	DWORD written;
	WriteFile(proc->hIn, pwd.c_str(), pwd.length(), &written, NULL);
	CloseHandle(proc->hIn);	// close input so sub process does not any more
	proc->hIn = NULL;
	memset(pass, 0, sizeof(pass));
	memset((char*) pwd.c_str(), 0, pwd.length());

	mounted = false;

	// wait for mount, read error and give feedback
	for (unsigned n = 0; n < 5*10; ++n) {
		// drive appeared
		if (GetDriveType(mnt) != DRIVE_NO_ROOT_DIR) {
			if (Drives::autoShow)
				Show(hwnd);
			break;
		}

		// process terminated
		DWORD readed;
		char output[2048];
		switch (WaitForSingleObject(subProcess->hProcess, 200)) {
		case WAIT_OBJECT_0:
		case WAIT_ABANDONED:
			if (ReadFile(proc->hOut, output, sizeof(output)-1, &readed, NULL)) {
				output[readed] = 0;
				utf8_to_wchar_buf(output, cmd, LENGTH(cmd));
			} else {
				_stprintf(cmd, _T("Unknown error mounting drive %c:"), mnt[0]);
			}
			subProcess.reset();
			throw truntime_error(cmd);
		}
	}
	if (subProcess)
		mounted = true;
	Save(); // save for resume
}