| 1 | // Eraser.cpp |
|---|
| 2 | // $Id$ |
|---|
| 3 | // |
|---|
| 4 | // Eraser. Secure data removal. For Windows. |
|---|
| 5 | // Copyright © 1997-2001 Sami Tolvanen (sami@tolvanen.com). |
|---|
| 6 | // Copyright © 2001-2006 Garrett Trant (support@heidi.ie). |
|---|
| 7 | // Copyright © 2007 The Eraser Project |
|---|
| 8 | // |
|---|
| 9 | // This program is free software; you can redistribute it and/or |
|---|
| 10 | // modify it under the terms of the GNU General Public License |
|---|
| 11 | // as published by the Free Software Foundation; either version 2 |
|---|
| 12 | // of the License, or (at your option) any later version. |
|---|
| 13 | // |
|---|
| 14 | // This program is distributed in the hope that it will be useful, |
|---|
| 15 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 16 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 17 | // GNU General Public License for more details. |
|---|
| 18 | // |
|---|
| 19 | // You should have received a copy of the GNU General Public License |
|---|
| 20 | // along with this program; if not, write to the Free Software |
|---|
| 21 | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
|---|
| 22 | // 02111-1307, USA. |
|---|
| 23 | |
|---|
| 24 | #include "stdafx.h" |
|---|
| 25 | #include "Eraser.h" |
|---|
| 26 | |
|---|
| 27 | #include "MainFrm.h" |
|---|
| 28 | #include "EraserDoc.h" |
|---|
| 29 | #include "EraserView.h" |
|---|
| 30 | #include "Windows.h" |
|---|
| 31 | #include "version.h" |
|---|
| 32 | |
|---|
| 33 | #include "EraserDll\EraserDll.h" |
|---|
| 34 | #include "EraserDll\SecurityManager.h" |
|---|
| 35 | #include "EraserUI\HyperLink.h" |
|---|
| 36 | #include "EraserUI\VisualStyles.h" |
|---|
| 37 | |
|---|
| 38 | #ifdef _DEBUG |
|---|
| 39 | #define new DEBUG_NEW |
|---|
| 40 | #undef THIS_FILE |
|---|
| 41 | static char THIS_FILE[] = __FILE__; |
|---|
| 42 | #endif |
|---|
| 43 | |
|---|
| 44 | ///////////////////////////////////////////////////////////////////////////// |
|---|
| 45 | // CEraserApp |
|---|
| 46 | |
|---|
| 47 | BEGIN_MESSAGE_MAP(CEraserApp, CWinApp) |
|---|
| 48 | //{{AFX_MSG_MAP(CEraserApp) |
|---|
| 49 | ON_COMMAND(ID_APP_ABOUT, OnAppAbout) |
|---|
| 50 | // NOTE - the ClassWizard will add and remove mapping macros here. |
|---|
| 51 | // DO NOT EDIT what you see in these blocks of generated code! |
|---|
| 52 | //}}AFX_MSG_MAP |
|---|
| 53 | // Standard file based document commands |
|---|
| 54 | ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) |
|---|
| 55 | ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) |
|---|
| 56 | END_MESSAGE_MAP() |
|---|
| 57 | |
|---|
| 58 | ///////////////////////////////////////////////////////////////////////////// |
|---|
| 59 | // CEraserApp construction |
|---|
| 60 | |
|---|
| 61 | CEraserApp::CEraserApp() : |
|---|
| 62 | m_pDoc(0) |
|---|
| 63 | { |
|---|
| 64 | _set_se_translator(SeTranslator); |
|---|
| 65 | } |
|---|
| 66 | |
|---|
| 67 | ///////////////////////////////////////////////////////////////////////////// |
|---|
| 68 | // The one and only CEraserApp object |
|---|
| 69 | |
|---|
| 70 | CEraserApp theApp; |
|---|
| 71 | |
|---|
| 72 | ///////////////////////////////////////////////////////////////////////////// |
|---|
| 73 | // CEraserApp initialization |
|---|
| 74 | |
|---|
| 75 | // Add a static BOOL that indicates whether the class was |
|---|
| 76 | // registered so that we can unregister it in ExitInstance |
|---|
| 77 | static BOOL bClassRegistered = FALSE; |
|---|
| 78 | |
|---|
| 79 | BOOL CEraserApp::FirstInstance() |
|---|
| 80 | { |
|---|
| 81 | CWnd *pWndPrev = CWnd::FindWindow(szEraserClassName, NULL); |
|---|
| 82 | CWnd *pWndChild; |
|---|
| 83 | |
|---|
| 84 | // Determine if another window with our class name exists... |
|---|
| 85 | if (pWndPrev) |
|---|
| 86 | { |
|---|
| 87 | // if so, does it have any popups? |
|---|
| 88 | pWndChild = pWndPrev->GetLastActivePopup(); |
|---|
| 89 | |
|---|
| 90 | // If iconic, restore the main window |
|---|
| 91 | if (!pWndPrev->IsWindowVisible() || pWndPrev->IsIconic()) |
|---|
| 92 | pWndPrev->ShowWindow(SW_RESTORE); |
|---|
| 93 | |
|---|
| 94 | // Bring the main window or its popup to |
|---|
| 95 | // the foreground |
|---|
| 96 | pWndChild->SetForegroundWindow(); |
|---|
| 97 | |
|---|
| 98 | // and we are done activating the previous one. |
|---|
| 99 | return FALSE; |
|---|
| 100 | } |
|---|
| 101 | // First instance. Proceed as normal. |
|---|
| 102 | else |
|---|
| 103 | return TRUE; |
|---|
| 104 | } |
|---|
| 105 | |
|---|
| 106 | __declspec(dllimport) bool no_registry; |
|---|
| 107 | |
|---|
| 108 | BOOL CEraserApp::InitInstance() |
|---|
| 109 | { |
|---|
| 110 | // If a previous instance of the application is already running, |
|---|
| 111 | // then activate it and return FALSE from InitInstance to |
|---|
| 112 | // end the execution of this instance. |
|---|
| 113 | |
|---|
| 114 | { |
|---|
| 115 | char temp[512]; |
|---|
| 116 | ::GetModuleFileName(NULL, temp, sizeof(temp)); |
|---|
| 117 | ::PathStripToRoot(temp); |
|---|
| 118 | switch(::GetDriveType(temp)) { |
|---|
| 119 | case DRIVE_UNKNOWN: |
|---|
| 120 | case DRIVE_NO_ROOT_DIR: |
|---|
| 121 | case DRIVE_FIXED: |
|---|
| 122 | default: |
|---|
| 123 | no_registry = false; |
|---|
| 124 | break; |
|---|
| 125 | case DRIVE_REMOVABLE: |
|---|
| 126 | case DRIVE_REMOTE: |
|---|
| 127 | case DRIVE_CDROM: |
|---|
| 128 | case DRIVE_RAMDISK: |
|---|
| 129 | no_registry = true; |
|---|
| 130 | break; |
|---|
| 131 | } |
|---|
| 132 | } |
|---|
| 133 | // no_registry = true; |
|---|
| 134 | if (no_registry) { |
|---|
| 135 | char temp[512]; |
|---|
| 136 | ::GetModuleFileName(NULL, temp, sizeof(temp)); |
|---|
| 137 | ::PathRemoveFileSpec(temp); |
|---|
| 138 | ::PathAppend(temp, "eraser.ini"); |
|---|
| 139 | m_pszProfileName = strdup(temp); |
|---|
| 140 | } |
|---|
| 141 | |
|---|
| 142 | if (!CheckAccess()) |
|---|
| 143 | return false; |
|---|
| 144 | |
|---|
| 145 | if (!FirstInstance()) |
|---|
| 146 | return FALSE; |
|---|
| 147 | |
|---|
| 148 | eraserInit(); |
|---|
| 149 | |
|---|
| 150 | // Register our unique class name that we wish to use |
|---|
| 151 | WNDCLASS wndcls; |
|---|
| 152 | ZeroMemory(&wndcls, sizeof(WNDCLASS)); // start with NULL |
|---|
| 153 | |
|---|
| 154 | // defaults |
|---|
| 155 | wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; |
|---|
| 156 | wndcls.lpfnWndProc = ::DefWindowProc; |
|---|
| 157 | wndcls.hInstance = AfxGetInstanceHandle(); |
|---|
| 158 | wndcls.hIcon = LoadIcon(IDR_MAINFRAME); // or load a different icon |
|---|
| 159 | wndcls.hCursor = LoadCursor(IDC_ARROW); |
|---|
| 160 | wndcls.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); |
|---|
| 161 | wndcls.lpszMenuName = NULL; |
|---|
| 162 | |
|---|
| 163 | // Specify our own class name for using FindWindow later |
|---|
| 164 | wndcls.lpszClassName = szEraserClassName; |
|---|
| 165 | |
|---|
| 166 | // Register new class and exit if it fails |
|---|
| 167 | if (!AfxRegisterClass(&wndcls)) |
|---|
| 168 | { |
|---|
| 169 | AfxMessageBox("Class Registration Failed"); |
|---|
| 170 | return FALSE; |
|---|
| 171 | } |
|---|
| 172 | |
|---|
| 173 | bClassRegistered = TRUE; |
|---|
| 174 | |
|---|
| 175 | // Initialize OLE libraries |
|---|
| 176 | if (!AfxOleInit()) |
|---|
| 177 | { |
|---|
| 178 | AfxMessageBox("OLE initialization failed."); |
|---|
| 179 | return FALSE; |
|---|
| 180 | } |
|---|
| 181 | |
|---|
| 182 | // Standard initialization |
|---|
| 183 | // If you are not using these features and wish to reduce the size |
|---|
| 184 | // of your final executable, you should remove from the following |
|---|
| 185 | // the specific initialization routines you do not need. |
|---|
| 186 | // Change the registry key under which our settings are stored. |
|---|
| 187 | if (!no_registry) |
|---|
| 188 | SetRegistryKey(_T("Heidi Computers Ltd\\Eraser\\5.5")); |
|---|
| 189 | |
|---|
| 190 | LoadStdProfileSettings(0); // Load standard INI file options (including MRU) |
|---|
| 191 | |
|---|
| 192 | // Register the application's document templates. Document templates |
|---|
| 193 | // serve as the connection between documents, frame windows and views. |
|---|
| 194 | |
|---|
| 195 | CSingleDocTemplate* pDocTemplate; |
|---|
| 196 | pDocTemplate = new CSingleDocTemplate( |
|---|
| 197 | IDR_MAINFRAME, |
|---|
| 198 | RUNTIME_CLASS(CEraserDoc), |
|---|
| 199 | RUNTIME_CLASS(CMainFrame), // main SDI frame window |
|---|
| 200 | NULL); // we create views by ourselves; no default view here |
|---|
| 201 | AddDocTemplate(pDocTemplate); |
|---|
| 202 | |
|---|
| 203 | // Enable DDE Execute open |
|---|
| 204 | EnableShellOpen(); |
|---|
| 205 | RegisterShellFileTypes(TRUE); |
|---|
| 206 | |
|---|
| 207 | CString str(m_lpCmdLine); |
|---|
| 208 | BOOL bHide = (str.Find(NOWINDOW_PARAMETER) != -1); |
|---|
| 209 | |
|---|
| 210 | if (bHide) |
|---|
| 211 | m_nCmdShow = SW_HIDE; |
|---|
| 212 | |
|---|
| 213 | // Parse command line for standard shell commands, DDE, file open |
|---|
| 214 | CCommandLineInfo cmdInfo; |
|---|
| 215 | ParseCommandLine(cmdInfo); |
|---|
| 216 | |
|---|
| 217 | // Dispatch commands specified on the command line |
|---|
| 218 | if (!ProcessShellCommand(cmdInfo)) |
|---|
| 219 | return FALSE; |
|---|
| 220 | |
|---|
| 221 | EnableHtmlHelp(); |
|---|
| 222 | int helpfilelen = strlen(m_pszHelpFilePath); |
|---|
| 223 | if((helpfilelen >= 4) && !stricmp(&m_pszHelpFilePath[helpfilelen - 4], ".hlp")) |
|---|
| 224 | strcpy((char *)&m_pszHelpFilePath[helpfilelen - 4], ".chm"); |
|---|
| 225 | |
|---|
| 226 | // The one and only window has been initialized, so show and update it. |
|---|
| 227 | |
|---|
| 228 | m_pMainWnd->ShowWindow((bHide) ? SW_HIDE : SW_SHOW); |
|---|
| 229 | m_pMainWnd->UpdateWindow(); |
|---|
| 230 | |
|---|
| 231 | return TRUE; |
|---|
| 232 | } |
|---|
| 233 | |
|---|
| 234 | |
|---|
| 235 | ///////////////////////////////////////////////////////////////////////////// |
|---|
| 236 | // CAboutDlg dialog used for App About |
|---|
| 237 | |
|---|
| 238 | class CAboutDlg : public CDialog |
|---|
| 239 | { |
|---|
| 240 | public: |
|---|
| 241 | CAboutDlg(); |
|---|
| 242 | |
|---|
| 243 | // Dialog Data |
|---|
| 244 | //{{AFX_DATA(CAboutDlg) |
|---|
| 245 | enum { IDD = IDD_ABOUTBOX }; |
|---|
| 246 | CHyperLink m_hlMail; |
|---|
| 247 | CHyperLink m_hlLink; |
|---|
| 248 | CString m_strVersion; |
|---|
| 249 | //}}AFX_DATA |
|---|
| 250 | |
|---|
| 251 | // ClassWizard generated virtual function overrides |
|---|
| 252 | //{{AFX_VIRTUAL(CAboutDlg) |
|---|
| 253 | protected: |
|---|
| 254 | virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support |
|---|
| 255 | //}}AFX_VIRTUAL |
|---|
| 256 | |
|---|
| 257 | // Implementation |
|---|
| 258 | protected: |
|---|
| 259 | //{{AFX_MSG(CAboutDlg) |
|---|
| 260 | virtual BOOL OnInitDialog(); |
|---|
| 261 | //}}AFX_MSG |
|---|
| 262 | DECLARE_MESSAGE_MAP() |
|---|
| 263 | }; |
|---|
| 264 | |
|---|
| 265 | CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) |
|---|
| 266 | { |
|---|
| 267 | //{{AFX_DATA_INIT(CAboutDlg) |
|---|
| 268 | m_strVersion = _T("Eraser Version 5.8.1"); |
|---|
| 269 | //}}AFX_DATA_INIT |
|---|
| 270 | } |
|---|
| 271 | |
|---|
| 272 | void CAboutDlg::DoDataExchange(CDataExchange* pDX) |
|---|
| 273 | { |
|---|
| 274 | CDialog::DoDataExchange(pDX); |
|---|
| 275 | //{{AFX_DATA_MAP(CAboutDlg) |
|---|
| 276 | DDX_Control(pDX, IDC_HYPERLINK_MAIL, m_hlMail); |
|---|
| 277 | DDX_Control(pDX, IDC_HYPERLINK, m_hlLink); |
|---|
| 278 | DDX_Text(pDX, IDC_STATIC_VERSION, m_strVersion); |
|---|
| 279 | //}}AFX_DATA_MAP |
|---|
| 280 | } |
|---|
| 281 | |
|---|
| 282 | BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) |
|---|
| 283 | //{{AFX_MSG_MAP(CAboutDlg) |
|---|
| 284 | //}}AFX_MSG_MAP |
|---|
| 285 | END_MESSAGE_MAP() |
|---|
| 286 | |
|---|
| 287 | // App command to run the dialog |
|---|
| 288 | void CEraserApp::OnAppAbout() |
|---|
| 289 | { |
|---|
| 290 | CAboutDlg aboutDlg; |
|---|
| 291 | //aboutDlg.m_strVersion.Format("Eraser Version %s",GetVersionInfoFromModule( TRUE )); // Show four-digit version info |
|---|
| 292 | aboutDlg.m_strVersion.Format("Eraser Version %s",VERSION_NUMBER_STRING); |
|---|
| 293 | aboutDlg.DoModal(); |
|---|
| 294 | } |
|---|
| 295 | LPCTSTR CEraserApp::GetVersionInfoFromModule( BOOL boolFourDigitString ) |
|---|
| 296 | { |
|---|
| 297 | // From: Chris Copenhaver <ccopenhaver@documentsolutions.com> |
|---|
| 298 | |
|---|
| 299 | // This method reads information from the Version resource. |
|---|
| 300 | |
|---|
| 301 | char szFullPath[MAX_PATH]; |
|---|
| 302 | DWORD dwVerHnd; |
|---|
| 303 | DWORD dwVerInfoSize; |
|---|
| 304 | |
|---|
| 305 | // Get version information from the application |
|---|
| 306 | ::GetModuleFileName(NULL, szFullPath, sizeof(szFullPath)); |
|---|
| 307 | |
|---|
| 308 | dwVerInfoSize = ::GetFileVersionInfoSize(szFullPath, &dwVerHnd); |
|---|
| 309 | if (dwVerInfoSize) |
|---|
| 310 | { |
|---|
| 311 | char* pVersionInfo = new char[dwVerInfoSize]; |
|---|
| 312 | if(pVersionInfo) |
|---|
| 313 | { |
|---|
| 314 | BOOL bRet = ::GetFileVersionInfo((LPTSTR)szFullPath, |
|---|
| 315 | (DWORD)dwVerHnd, |
|---|
| 316 | (DWORD)dwVerInfoSize, |
|---|
| 317 | (LPVOID)pVersionInfo); |
|---|
| 318 | char* szVer = NULL; |
|---|
| 319 | UINT uVerLength; |
|---|
| 320 | if(bRet) |
|---|
| 321 | { |
|---|
| 322 | bRet = ::VerQueryValue(pVersionInfo, |
|---|
| 323 | |
|---|
| 324 | TEXT("\\StringFileInfo\\040904b0\\FileVersion"), |
|---|
| 325 | (LPVOID*)&szVer, |
|---|
| 326 | &uVerLength); |
|---|
| 327 | if (bRet) |
|---|
| 328 | { |
|---|
| 329 | // Now return the file version... |
|---|
| 330 | CString strVersion = szVer; |
|---|
| 331 | if ( !boolFourDigitString ) |
|---|
| 332 | { |
|---|
| 333 | int posComma = strVersion.ReverseFind( ',' ); |
|---|
| 334 | strVersion = strVersion.Left( posComma ); |
|---|
| 335 | } |
|---|
| 336 | |
|---|
| 337 | return strVersion; |
|---|
| 338 | } |
|---|
| 339 | } |
|---|
| 340 | delete pVersionInfo; |
|---|
| 341 | } |
|---|
| 342 | } |
|---|
| 343 | |
|---|
| 344 | return ""; |
|---|
| 345 | } |
|---|
| 346 | |
|---|
| 347 | ///////////////////////////////////////////////////////////////////////////// |
|---|
| 348 | // CEraserApp message handlers |
|---|
| 349 | |
|---|
| 350 | |
|---|
| 351 | int CEraserApp::ExitInstance() |
|---|
| 352 | { |
|---|
| 353 | try |
|---|
| 354 | { |
|---|
| 355 | if (AfxIsValidAddress(m_pDoc, sizeof(CEraserDoc))) |
|---|
| 356 | delete m_pDoc; |
|---|
| 357 | |
|---|
| 358 | m_pDoc = 0; |
|---|
| 359 | } |
|---|
| 360 | catch (CException *e) |
|---|
| 361 | { |
|---|
| 362 | ASSERT(FALSE); |
|---|
| 363 | REPORT_ERROR(e); |
|---|
| 364 | e->Delete(); |
|---|
| 365 | } |
|---|
| 366 | |
|---|
| 367 | if (bClassRegistered) |
|---|
| 368 | ::UnregisterClass(szEraserClassName, AfxGetInstanceHandle()); |
|---|
| 369 | |
|---|
| 370 | eraserEnd(); |
|---|
| 371 | |
|---|
| 372 | return CWinApp::ExitInstance(); |
|---|
| 373 | } |
|---|
| 374 | |
|---|
| 375 | BOOL CAboutDlg::OnInitDialog() |
|---|
| 376 | { |
|---|
| 377 | //m_strVersion.Format("Eraser %u.%u (Build %u)", MAJOR_NUMBER, MINOR_NUMBER, BUILD_NUMBER); |
|---|
| 378 | |
|---|
| 379 | m_hlLink.SetURL(ERASER_URL_HOMEPAGE); |
|---|
| 380 | m_hlMail.SetURL(ERASER_URL_EMAIL); |
|---|
| 381 | |
|---|
| 382 | CDialog::OnInitDialog(); |
|---|
| 383 | |
|---|
| 384 | return TRUE; // return TRUE unless you set the focus to a control |
|---|
| 385 | // EXCEPTION: OCX Property Pages should return FALSE |
|---|
| 386 | } |
|---|
| 387 | |
|---|