|
|
1.1 root 1:
2: #include "System.h"
3: #include "Core/RandomNumberGenerator.h"
4: #include "Main/Application.h"
5: #include "Main/GraphicUserInterface.h"
6: #include "Main/Resources.h"
7: #include "VolumeCreationWizard.h"
8: #include "EncryptionOptionsWizardPage.h"
9: #include "InfoWizardPage.h"
10: #include "ProgressWizardPage.h"
11: #include "SingleChoiceWizardPage.h"
12: #include "VolumeCreationIntroWizardPage.h"
13: #include "VolumeCreationProgressWizardPage.h"
14: #include "VolumeFormatOptionsWizardPage.h"
15: #include "VolumeLocationWizardPage.h"
16: #include "VolumePasswordWizardPage.h"
17: #include "VolumeSizeWizardPage.h"
18:
19: namespace TrueCrypt
20: {
21: VolumeCreationWizard::VolumeCreationWizard (wxWindow* parent)
22: : WizardFrame (parent),
23: DeviceWarningConfirmed (false),
24: DisplayKeyInfo (true),
25: QuickFormatEnabled (false),
26: SelectedFilesystemClusterSize (0),
27: SelectedFilesystemType (VolumeCreationOptions::FilesystemType::FAT),
28: SelectedVolumeType (VolumeType::Normal),
29: VolumeSize (0)
30: {
31: RandomNumberGenerator::Start();
32:
33: SetTitle (LangString["VOLUME_CREATION_WIZARD"]);
34: SetImage (Resources::GetVolumeCreationWizardBitmap (Gui->GetCharHeight (this) * 21));
35: SetMaxStaticTextWidth (55);
36:
37: SetStep (Step::VolumeType);
38:
39: class Timer : public wxTimer
40: {
41: public:
42: Timer (VolumeCreationWizard *wizard) : Wizard (wizard) { }
43:
44: void Notify()
45: {
46: Wizard->OnRandomPoolUpdateTimer();
47: }
48:
49: VolumeCreationWizard *Wizard;
50: };
51:
52: RandomPoolUpdateTimer.reset (dynamic_cast <wxTimer *> (new Timer (this)));
53: RandomPoolUpdateTimer->Start (200);
54: }
55:
56: VolumeCreationWizard::~VolumeCreationWizard ()
57: {
58: RandomNumberGenerator::Stop();
59: }
60:
61: WizardPage *VolumeCreationWizard::GetPage (WizardStep step)
62: {
63: switch (step)
64: {
65: case Step::VolumeType:
66: {
67: ClearHistory();
68:
69: VolumeCreationIntroWizardPage *page = new VolumeCreationIntroWizardPage (GetPageParent());
70: page->SetMinSize (wxSize (Gui->GetCharWidth (this) * 58, Gui->GetCharHeight (this) * 18 + 5));
71:
72: page->SetPageTitle (LangString["VOLUME_CREATION_WIZARD"]);
73: page->SetPageText (LangString["VOLUME_CREATION_INTRO"]);
74:
75: page->SetSelection (SelectedVolumeType);
76: return page;
77: }
78:
79: case Step::VolumeLocation:
80: {
81: VolumeLocationWizardPage *page = new VolumeLocationWizardPage (GetPageParent());
82: page->SetPageTitle (LangString["VOLUME_LOCATION"]);
83: page->SetPageText (LangString["VOLUME_LOCATION_WIZARD_PAGE_INFO"]);
84:
85: page->SetVolumePath (SelectedVolumePath);
86: return page;
87: }
88:
89: case Step::VolumeSize:
90: {
91: VolumeSizeWizardPage *page = new VolumeSizeWizardPage (GetPageParent(), SelectedVolumePath);
92: page->SetPageTitle (LangString["SIZE_TITLE"]);
93: page->SetPageText (LangString["VOLUME_SIZE_HELP"]);
94: page->SetVolumeSize (VolumeSize);
95: return page;
96: }
97:
98: case Step::EncryptionOptions:
99: {
100: EncryptionOptionsWizardPage *page = new EncryptionOptionsWizardPage (GetPageParent());
101: page->SetPageTitle (LangString["CIPHER_TITLE"]);
102: page->SetEncryptionAlgorithm (SelectedEncryptionAlgorithm);
103: page->SetHash (SelectedHash);
104: return page;
105: }
106:
107: case Step::VolumePassword:
108: {
109: VolumePasswordWizardPage *page = new VolumePasswordWizardPage (GetPageParent(), Password, Keyfiles);
110: page->SetPageTitle (LangString["PASSWORD_TITLE"]);
111: page->SetPageText (LangString["PASSWORD_HELP"]);
112: return page;
113: }
114:
115: case Step::FormatOptions:
116: {
117: VolumeFormatOptionsWizardPage *page = new VolumeFormatOptionsWizardPage (GetPageParent(), SelectedVolumePath);
118: page->SetPageTitle (_("Format Options"));
119: page->SetFilesystemType (SelectedFilesystemType);
120: page->SetQuickFormat (QuickFormatEnabled);
121: return page;
122: }
123:
124: case Step::CreationProgress:
125: {
126: VolumeCreationProgressWizardPage *page = new VolumeCreationProgressWizardPage (GetPageParent(), DisplayKeyInfo);
127: page->SetPageTitle (LangString["FORMAT_TITLE"]);
128: page->SetPageText (LangString["FORMAT_HELP"]);
129: page->AbortEvent.Connect (EventConnector <VolumeCreationWizard> (this, &VolumeCreationWizard::OnAbortButtonClick));
130: page->SetNextButtonText (LangString["FORMAT"]);
131: return page;
132: }
133:
134: case Step::VolumeCreatedInfo:
135: {
136: InfoWizardPage *page = new InfoWizardPage (GetPageParent());
137: page->SetPageTitle (LangString["FORMAT_FINISHED_TITLE"]);
138: page->SetPageText (LangString["FORMAT_FINISHED_HELP"]);
139:
140: SetCancelButtonText (_("Exit"));
141: return page;
142: }
143:
144: default:
145: throw ParameterIncorrect (SRC_POS);
146: }
147: }
148:
149: void VolumeCreationWizard::OnAbortButtonClick (EventArgs &args)
150: {
151: AbortRequested = true;
152: }
153:
154: void VolumeCreationWizard::OnMouseMotion (wxMouseEvent& event)
155: {
156: event.Skip();
157: if (!IsWorkInProgress() && RandomNumberGenerator::IsRunning())
158: {
159: RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast <byte *> (&event), sizeof (event)));
160:
161: long coord = event.GetX();
162: RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast <byte *> (&coord), sizeof (coord)));
163: coord = event.GetY();
164: RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast <byte *> (&coord), sizeof (coord)));
165: }
166: }
167:
168: void VolumeCreationWizard::OnProgressTimer ()
169: {
170: if (!IsWorkInProgress())
171: return;
172:
173: if (AbortRequested && !AbortConfirmationPending)
174: {
175: AbortConfirmationPending = true;
176: if (Gui->AskYesNo (LangString ["FORMAT_ABORT"], true))
177: {
178: if (IsWorkInProgress() && Creator.get() != nullptr)
179: {
180: CreationAborted = true;
181: Creator->Abort();
182: }
183: }
184: AbortRequested = false;
185: AbortConfirmationPending = false;
186: }
187:
188: VolumeCreator::ProgressInfo progress = Creator->GetProgressInfo();
189:
190: VolumeCreationProgressWizardPage *page = dynamic_cast <VolumeCreationProgressWizardPage *> (GetCurrentPage());
191: page->SetProgressValue (progress.SizeDone);
192:
193: if (!progress.CreationInProgress && !AbortConfirmationPending)
194: {
195: SetWorkInProgress (false);
196: OnVolumeCreatorFinished ();
197: }
198: }
199:
200: void VolumeCreationWizard::OnRandomPoolUpdateTimer ()
201: {
202: if (!IsWorkInProgress())
203: {
204: wxLongLong time = wxGetLocalTimeMillis();
205: RandomNumberGenerator::AddToPool (ConstBufferPtr (reinterpret_cast <byte *> (&time), sizeof (time)));
206: }
207: }
208:
209: void VolumeCreationWizard::OnVolumeCreatorFinished ()
210: {
211: VolumeCreationProgressWizardPage *page = dynamic_cast <VolumeCreationProgressWizardPage *> (GetCurrentPage());
212:
213: ProgressTimer.reset();
214: page->SetProgressState (false);
215:
216: Gui->EndInteractiveBusyState (this);
217: SetWorkInProgress (false);
218: UpdateControls();
219:
220: try
221: {
222: if (!CreationAborted)
223: {
224: Creator->CheckResult();
225: Gui->ShowInfo ("FORMAT_FINISHED_INFO");
226: SetStep (Step::VolumeCreatedInfo);
227: return;
228: }
229: }
230: catch (Exception &e)
231: {
232: Gui->ShowError (e);
233: }
234:
235: page->SetProgressValue (0);
236: if (SelectedVolumeType == VolumeType::Normal && !SelectedVolumePath.IsDevice())
237: {
238: try
239: {
240: FilePath (wstring (SelectedVolumePath)).Delete();
241: }
1.1.1.2 ! root 242: catch (...) { }
1.1 root 243: }
244: }
245:
246: WizardFrame::WizardStep VolumeCreationWizard::ProcessPageChangeRequest (bool forward)
247: {
248: switch (GetCurrentStep())
249: {
250: case Step::VolumeType:
251: {
252: VolumeCreationIntroWizardPage *page = dynamic_cast <VolumeCreationIntroWizardPage *> (GetCurrentPage());
253: SelectedVolumeType = page->GetSelection();
254:
255: if (forward && SelectedVolumeType != VolumeType::Normal)
256: {
257: Gui->ShowInfo ("FEATURE_CURRENTLY_UNSUPPORTED_ON_PLATFORM");
258: return Step::VolumeType;
259: }
260:
261: return Step::VolumeLocation;
262: }
263:
264: case Step::VolumeLocation:
265: {
266: VolumeLocationWizardPage *page = dynamic_cast <VolumeLocationWizardPage *> (GetCurrentPage());
267: SelectedVolumePath = page->GetVolumePath();
268: VolumeSize = 0;
269:
270: if (forward)
271: {
272: if (Core->IsVolumeMounted (SelectedVolumePath))
273: {
274: Gui->ShowInfo ("DISMOUNT_FIRST");
275: return GetCurrentStep();
276: }
277:
278: if (SelectedVolumePath.IsDevice())
279: {
280: if (!DeviceWarningConfirmed && !Gui->AskYesNo (LangString["FORMAT_DEVICE_FOR_ADVANCED_ONLY"]))
281: return GetCurrentStep();
282:
283: DeviceWarningConfirmed = true;
284:
285: try
286: {
287: VolumeSize = Core->GetDeviceSize (SelectedVolumePath);
288: }
289: catch (UserAbort&)
290: {
291: return Step::VolumeLocation;
292: }
293: catch (exception &e)
294: {
295: Gui->ShowError (e);
296: Gui->ShowError ("CANNOT_CALC_SPACE");
297: return GetCurrentStep();
298: }
299: }
300: }
301:
302: if (SelectedVolumePath.IsDevice())
303: return Step::EncryptionOptions;
304: else
305: return Step::VolumeSize;
306: }
307:
308: case Step::VolumeSize:
309: {
310: VolumeSizeWizardPage *page = dynamic_cast <VolumeSizeWizardPage *> (GetCurrentPage());
311:
312: try
313: {
314: VolumeSize = page->GetVolumeSize();
315: }
316: catch (Exception &e)
317: {
318: if (forward)
319: {
320: Gui->ShowError (e);
321: return GetCurrentStep();
322: }
323: }
324:
325: return Step::EncryptionOptions;
326: }
327:
328: case Step::EncryptionOptions:
329: {
330: EncryptionOptionsWizardPage *page = dynamic_cast <EncryptionOptionsWizardPage *> (GetCurrentPage());
331: SelectedEncryptionAlgorithm = page->GetEncryptionAlgorithm ();
332: SelectedHash = page->GetHash ();
333:
334: if (forward)
335: RandomNumberGenerator::SetHash (SelectedHash);
336:
337: return Step::VolumePassword;
338: }
339:
340: case Step::VolumePassword:
341: {
342: VolumePasswordWizardPage *page = dynamic_cast <VolumePasswordWizardPage *> (GetCurrentPage());
343: Password = page->GetPassword();
344: Keyfiles = page->GetKeyfiles();
345:
346: if (forward && Password && !Password->IsEmpty())
347: {
348: try
349: {
350: Password->CheckPortability();
351: }
352: catch (UnportablePassword &e)
353: {
354: Gui->ShowError (e);
355: return GetCurrentStep();
356: }
357:
358: if (Password->Size() < VolumePassword::WarningSizeThreshold
359: && !Gui->AskYesNo (LangString["PASSWORD_LENGTH_WARNING"], false, true))
360: {
361: return GetCurrentStep();
362: }
363: }
364:
365: return Step::FormatOptions;
366: }
367:
368: case Step::FormatOptions:
369: {
370: VolumeFormatOptionsWizardPage *page = dynamic_cast <VolumeFormatOptionsWizardPage *> (GetCurrentPage());
371: SelectedFilesystemType = page->GetFilesystemType();
372: QuickFormatEnabled = page->IsQuickFormatEnabled();
373:
374: return Step::CreationProgress;
375: }
376:
377:
378: case Step::CreationProgress:
379: {
380: VolumeCreationProgressWizardPage *page = dynamic_cast <VolumeCreationProgressWizardPage *> (GetCurrentPage());
381:
382: DisplayKeyInfo = page->IsKeyInfoDisplayed();
383:
384: if (forward)
385: {
386: if (SelectedVolumePath.IsDevice())
387: {
388: wxString confirmMsg = LangString["OVERWRITEPROMPT_DEVICE"];
389: confirmMsg.Replace (L"%hs", L"%s");
390:
391: if (!Gui->AskYesNo (wxString::Format (confirmMsg, wxString (_("DEVICE")).c_str(), wstring (SelectedVolumePath).c_str(), L""), false, true))
392: return GetCurrentStep();
393: }
394: else if (FilesystemPath (wstring (SelectedVolumePath)).IsFile())
395: {
396: wxString confirmMsg = LangString["OVERWRITEPROMPT"];
397: confirmMsg.Replace (L"%hs", L"%s");
398:
399: if (!Gui->AskYesNo (wxString::Format (confirmMsg, wstring (SelectedVolumePath).c_str(), false, true)))
400: return GetCurrentStep();
401: }
402:
403: AbortRequested = false;
404: AbortConfirmationPending = false;
405: CreationAborted = false;
406: SetWorkInProgress (true);
407: UpdateControls();
408:
409: Gui->BeginInteractiveBusyState (this);
410:
411: try
412: {
413: make_shared_auto (VolumeCreationOptions, options);
414:
415: options->Filesystem = SelectedFilesystemType;
416: options->FilesystemClusterSize = SelectedFilesystemClusterSize;
417:
418: options->EA = SelectedEncryptionAlgorithm;
1.1.1.2 ! root 419: options->Password = Keyfile::ApplyListToPassword (Keyfiles, Password);
1.1 root 420: options->Path = SelectedVolumePath;
421: options->Quick = QuickFormatEnabled;
422: options->Size = VolumeSize;
423: options->Type = SelectedVolumeType;
424: options->VolumeHeaderKdf = Pkcs5Kdf::GetAlgorithm (*SelectedHash);
425:
426: Creator.reset (new VolumeCreator);
427: Creator->CreateVolume (options);
428:
429: page->SetKeyInfo (Creator->GetKeyInfo());
430:
431: class Timer : public wxTimer
432: {
433: public:
434: Timer (VolumeCreationWizard *wizard) : Wizard (wizard) { }
435:
436: void Notify()
437: {
438: Wizard->OnProgressTimer();
439: }
440:
441: VolumeCreationWizard *Wizard;
442: };
443:
444: page->SetProgressRange (options->Size);
445: page->SetProgressState (true);
446: ProgressTimer.reset (dynamic_cast <wxTimer *> (new Timer (this)));
447: ProgressTimer->Start (50);
448: }
449: catch (Exception &e)
450: {
451: CreationAborted = true;
452: OnVolumeCreatorFinished();
453: Gui->ShowError (e);
454: }
455: }
456:
457: return GetCurrentStep();
458: }
459:
460: case Step::VolumeCreatedInfo:
461: Creator.reset();
462: SetCancelButtonText (L"");
463: return Step::VolumeType;
464:
465: default:
466: throw ParameterIncorrect (SRC_POS);
467: }
468: }
469:
470: void VolumeCreationWizard::UpdateControls ()
471: {
472: VolumeCreationProgressWizardPage *page = dynamic_cast <VolumeCreationProgressWizardPage *> (GetCurrentPage());
473: if (page)
474: {
475: page->EnableAbort (IsWorkInProgress());
476: }
477: }
478: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.