⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thismfcapp.cpp

📁 Password Safe Password Safe is a password database utility. Users can keep their passwords securely
💻 CPP
字号:
/// \file ThisMfcApp.cpp/// \brief App object of MFC version of Password Safe//-----------------------------------------------------------------------------#include "PasswordSafe.h"#include "corelib/PwsPlatform.h"#include "corelib/PWSprefs.h"#if defined(POCKET_PC)  #include "pocketpc/PocketPC.h"  #include "pocketpc/resource.h"#else  #include <errno.h>  #include <io.h>  #include "resource.h"#endif#include "ThisMfcApp.h"#include "corelib/Util.h"#include "DboxMain.h"#include "CryptKeyEntry.h"BEGIN_MESSAGE_MAP(ThisMfcApp, CWinApp)//   ON_COMMAND(ID_HELP, CWinApp::OnHelp)   ON_COMMAND(ID_HELP, OnHelp)END_MESSAGE_MAP()ThisMfcApp::ThisMfcApp() :#if defined(POCKET_PC)	m_bUseAccelerator( false ),#else	m_bUseAccelerator( true ),#endif	m_pMRU( NULL ){// {kjp} Temporary until I'm sure that PwsPlatform.h configures the endianness properly#if defined(POCKET_PC)	// Double check that *_ENDIAN has been correctly set!#if defined(LITTLE_ENDIAN)	unsigned char	buf[4]	= { 1, 0, 0, 0 };	unsigned int	ii		= 1;#define ENDIANNESS	_T("little endian")#define ENDIANNESS2	_T("big endian")#elif defined(BIG_ENDIAN)	unsigned char	buf[4]	= { 0, 0, 0, 1 };	unsigned int	ii		= 1;#define ENDIANNESS	_T("big endian")#define ENDIANNESS2	_T("little endian")#endif	if (*(unsigned int*)buf != ii)	{		AfxMessageBox(_T("Password Safe has been compiled as ") ENDIANNESS			_T(" but CPU is really ") ENDIANNESS2 _T("\n")			_T("You may not be able to open files or saved files may be incompatible with other platforms."));	}#endif}ThisMfcApp::~ThisMfcApp(){	if ( m_pMRU )	{		m_pMRU->WriteList();		delete m_pMRU;	}   /*     apparently, with vc7, there's a CWinApp::HtmlHelp - I'd like     to see the docs, someday.  In the meantime, force with :: syntax   */#if !defined(POCKET_PC)   ::HtmlHelp(NULL, NULL, HH_CLOSE_ALL, 0);#endif}#if !defined(POCKET_PC)static void Usage(){  AfxMessageBox(_T("Usage: PasswordSafe [password database]\n")		_T("or PasswordSafe [-e|-d] filename"));}// tests if file exists, returns empty string if so, displays error message if notstatic BOOL CheckFile(const CString &fn){  DWORD status = ::GetFileAttributes(fn);  CString ErrMess;  if (status == -1) {    ErrMess = _T("Could not access file: ");    ErrMess += fn;  } else if (status & FILE_ATTRIBUTE_DIRECTORY) {    ErrMess = fn;    ErrMess += _T(" is a directory");  }  if (ErrMess.IsEmpty()) {    return TRUE;  } else {    AfxMessageBox(ErrMess);    return FALSE;  }}//Complain if the file has not opened correctlystatic voidErrorMessages(const CString &fn, FILE *fp){#if !defined(POCKET_PC)  if (fp == NULL)    {      CString text;      text = "A fatal error occured: ";      if (errno==EACCES)	text += "Given path is a directory or file is read-only";      else if (errno==EEXIST)	text += "The filename already exists.";      else if (errno==EINVAL)	text += "Invalid oflag or shflag argument.";      else if (errno==EMFILE)	text += "No more file handles available.";      else if (errno==ENOENT)	text += "File or path not found.";      text += "\nProgram will terminate.";      CString title = "Password Safe - " + fn;      AfxGetMainWnd()->MessageBox(text, title, MB_ICONEXCLAMATION|MB_OK);    }#endif}static BOOL EncryptFile(const CString &fn, const CMyString &passwd){  unsigned int len;  unsigned char* buf;#if defined(UNICODE)  FILE *in = _wfopen(fn, _T("rb"));#else  FILE *in = fopen(fn, _T("rb"));#endif  if (in != NULL) {    len = fileLength(in);    buf = new unsigned char[len];    fread(buf, 1, len, in);    fclose(in);  } else {    ErrorMessages(fn, in);    return FALSE;  }  CString out_fn = fn;  out_fn += CIPHERTEXT_SUFFIX;#if defined(UNICODE)  FILE *out = _wfopen(out_fn, _T("wb"));#else  FILE *out = fopen(out_fn, _T("wb"));#endif  if (out != NULL) {#ifdef KEEP_FILE_MODE_BWD_COMPAT    fwrite( &len, 1, sizeof(len), out);#else    unsigned char randstuff[StuffSize];    unsigned char randhash[20];   // HashSize    for (int i=0; i < 8; i++)      randstuff[i] = newrand();    // miserable bug - have to fix this way to avoid breaking existing files    randstuff[8] = randstuff[9] = '\0';    GenRandhash(passwd,		randstuff,		randhash);   fwrite(randstuff, 1,  8, out);   fwrite(randhash,  1, 20, out);#endif // KEEP_FILE_MODE_BWD_COMPAT		    unsigned char thesalt[SaltLength];    for (int x=0;x<SaltLength;x++)      thesalt[x] = newrand();    fwrite(thesalt, 1, SaltLength, out);		    unsigned char ipthing[8];    for (x=0;x<8;x++)      ipthing[x] = newrand();    fwrite(ipthing, 1, 8, out);    LPCSTR pwd = LPCSTR(passwd);    _writecbc(out, buf, len, (unsigned char)0,	      (unsigned char *)pwd, passwd.GetLength(),	      thesalt, SaltLength,	      ipthing);		    fclose(out);  } else {    ErrorMessages(out_fn, out);    delete [] buf;    return FALSE;  }  delete[] buf;  return TRUE;}static BOOL DecryptFile(const CString &fn, const CMyString &passwd){  unsigned int len;  unsigned char* buf;#if defined(UNICODE)  FILE *in = _wfopen(fn, _T("rb"));#else  FILE *in = fopen(fn, _T("rb"));#endif  if (in != NULL) {    unsigned char salt[SaltLength];    unsigned char ipthing[8];    unsigned char randstuff[StuffSize];    unsigned char randhash[20];   // HashSize#ifdef KEEP_FILE_MODE_BWD_COMPAT      fread(&len, 1, sizeof(len), in); // XXX portability issue#else      fread(randstuff, 1, 8, in);      randstuff[8] = randstuff[9] = '\0'; // ugly bug workaround      fread(randhash, 1, 20, in);      unsigned char temphash[20]; // HashSize      GenRandhash(passwd,		  randstuff,		  temphash);      if (0 != memcmp((char*)randhash,		      (char*)temphash,		      20)) // HashSize	{	  fclose(in);	  AfxMessageBox(_T("Incorrect password"));	  return FALSE;	}#endif // KEEP_FILE_MODE_BWD_COMPAT      buf = NULL; // allocated by _readcbc - see there for apologia      fread(salt,    1, SaltLength, in);      fread(ipthing, 1, 8,          in);      LPCSTR pwd = LPCSTR(passwd);      unsigned char dummyType;      if (_readcbc(in, buf, len,dummyType,		   (unsigned char *)pwd, passwd.GetLength(),		   salt, SaltLength, ipthing) == 0) {	delete[] buf; // if not yet allocated, delete[] NULL, which is OK	return FALSE;      }		      fclose(in);    } else {      ErrorMessages(fn, in);      return FALSE;    }  int suffix_len = strlen(CIPHERTEXT_SUFFIX);  int filepath_len = fn.GetLength();  CString out_fn = fn;  out_fn = out_fn.Left(filepath_len - suffix_len);#if defined(UNICODE)  FILE *out = _wfopen(out_fn, _T("wb"));#else  FILE *out = fopen(out_fn, _T("wb"));#endif  if (out != NULL) {    fwrite(buf, 1, len, out);    fclose(out);    } else      ErrorMessages(out_fn, out);  delete[] buf; // allocated by _readcbc  return TRUE;}#endifBOOLThisMfcApp::InitInstance(){   /*    * It's always best to start at the beginning.  [Glinda, Witch of the North]	*/	#if defined(POCKET_PC)	SHInitExtraControls();#endif  /*    this instructs the app to use the registry instead of .ini files.  The    path ends up being	    HKEY_CURRENT_USER\Software\(companyname)\(appname)\(sectionname)\(valuename)	      Assuming the open-source version of this is going to become less    Counterpane-centric, I expect this may change, but if it does, an    automagic migration ought to happen. -- {jpr}    Of course, this is legacy, and will go away once the registry is fully replaced    by the in-database preference storage. -- ronys  */   CString companyname("Counterpane Systems");   SetRegistryKey(companyname);   int	nMRUItems = PWSprefs::GetInstance()->     GetPref(PWSprefs::IntPrefs::MaxMRUItems);   m_pMRU = new CRecentFileList( 0, _T("MRU"), _T("Safe%d"), nMRUItems );;	m_pMRU->ReadList();		DboxMain dbox(NULL);		/*	* Command line processing:	* Historically, it appears that if a filename was passed as a commadline argument,	* the application would prompt the user for the password, and the encrypt or decrypt	* the named file, based on the file's suffix. Ugh.	*	* What I'll do is as follows:	* If a file is given in the command line, it is used as the database, overriding the	* registry value. This will allow the user to have several databases, say, one for work	* and one for personal use, and to set up a different shortcut for each.	*	* I think I'll keep the old functionality, but activate it with a "-e" or "-d" flag. (ronys)	* {kjp} ... and I've removed all of it from the Pocket PC build.	*/	#if !defined(POCKET_PC)	if (m_lpCmdLine[0] != '\0') {		CString args = m_lpCmdLine;				if (args[0] != _T('-')) {			StripFileQuotes( args );						if (CheckFile(args)) {				dbox.SetCurFile(args);			} else {				return FALSE;			}		} else { // here if first char of arg is '-'			// first, let's check that there's a second arg			CString fn = args.Right(args.GetLength()-2);			fn.TrimLeft();			StripFileQuotes( fn );			if (fn.IsEmpty() || !CheckFile(fn)) {				Usage();				return FALSE;			}						CMyString passkey;			if (args[1] == 'e' || args[1] == 'E' || args[1] == 'd' || args[1] == 'D') {				// get password from user if valid flag given. If note, default below will				// pop usage message				CCryptKeyEntry dlg(NULL);				int nResponse = dlg.DoModal();								if (nResponse==IDOK) {					passkey = dlg.m_cryptkey1;				} else {					return FALSE;				}			}			BOOL status;			switch (args[1]) {			case 'e': case 'E': // do encrpytion				status = EncryptFile(fn, passkey);				if (!status) {	   AfxMessageBox(_T("Encryption failed"));				}				break;			case 'd': case 'D': // do decryption				status = DecryptFile(fn, passkey);				if (!status) {					// nothing to do - DecryptFile displays its own error messages				}				break;			default:				Usage();				return FALSE;			} // switch			return FALSE;		} // else	} // m_lpCmdLine[0] != '\0';#endif		  /*	  * normal startup	*/		/*	Here's where PWS currently does DboxMain, which in turn will do	the initial PasskeyEntry (the one that looks like a splash screen).	This makes things very hard to control.	The app object (here) should instead do the initial PasskeyEntry,	and, if successful, move on to DboxMain.  I think. {jpr}	*/	m_maindlg = &dbox;	m_pMainWnd = m_maindlg;		HICON stIcon = app.LoadIcon(IDI_TRAY);	ASSERT(stIcon != NULL);	m_TrayIcon.SetTarget(&dbox);	if (!m_TrayIcon.Create(NULL, WM_ICON_NOTIFY, _T("PasswordSafe"),			       stIcon, IDR_POPTRAY))	  return FALSE;	// Set up an Accelerator table#if !defined(POCKET_PC)	m_ghAccelTable = LoadAccelerators(AfxGetInstanceHandle(),		MAKEINTRESOURCE(IDR_ACCS));#endif	//Run dialog	(void) dbox.DoModal();		/*	note that we don't particularly care what the response was	*/			// Since the dialog has been closed, return FALSE so that we exit the	//	application, rather than start the application's message pump.		return FALSE;}#if !defined(POCKET_PC)// Removes quotation marks from file name parameters// as in "file with spaces.dat"voidThisMfcApp::StripFileQuotes( CString& strFilename ){	const char* szFilename	= strFilename;	int			nLen		= strFilename.GetLength();	// if the filenames starts with a quote...	if ( *szFilename == '\"' )	{		// remove leading quote		++szFilename;		--nLen;		// trailing quote is optional, remove if present		if ( szFilename[nLen - 1] == '\"' )			--nLen;		strFilename = CString( szFilename, nLen );	}}#endif#if !defined(POCKET_PC)//Copied from Knowledge Base article Q100770//But not for WinCE {kjp}BOOLThisMfcApp::ProcessMessageFilter(int code,                                 LPMSG lpMsg){   if (code < 0)      CWinApp::ProcessMessageFilter(code, lpMsg);	   if (m_bUseAccelerator &&	   m_maindlg != NULL       && m_ghAccelTable != NULL)   {      if (::TranslateAccelerator(m_maindlg->m_hWnd, m_ghAccelTable, lpMsg))         return TRUE;   }   return CWinApp::ProcessMessageFilter(code, lpMsg);}#endifvoidThisMfcApp::OnHelp(){#if defined(POCKET_PC)  CreateProcess( _T("PegHelp.exe"), _T("pws_ce_help.html#mainhelp"), NULL, NULL, FALSE, 0, NULL, NULL, NULL, NULL );#else  /*   * Following mess because CPropertySheet is too smart for its own   * good. The "Help" button there is mapped to the App framework,   * and that's that...   */  CString title;  CWnd *wnd = CWnd::GetCapture();  if (wnd == NULL)    wnd = CWnd::GetFocus();  if (wnd != NULL)    wnd = wnd->GetParent();  if (wnd != NULL) {    wnd->GetWindowText(title);  }  if (title != _T("Options"))    ::HtmlHelp(NULL,	       "pwsafe.chm::/html/pws_main.htm",	       HH_DISPLAY_TOPIC, 0);  else    ::HtmlHelp(NULL,	       "pwsafe.chm::/html/pws_opts.htm",	       HH_DISPLAY_TOPIC, 0);#endif}//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -