pwexport.cpp
来自「一款密码保险箱源码」· C++ 代码 · 共 818 行 · 第 1/2 页
CPP
818 行
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2007 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "StdAfx.h"
#include "PwExport.h"
#include <vector>
#include "../Util/MemUtil.h"
#include "../Util/StrUtil.h"
#include "../Util/Base64.h"
#include "../Util/TranslateEx.h"
CPwExport::CPwExport()
{
m_pMgr = NULL;
m_nFormat = 0;
m_fp = NULL;
SetNewLineSeq(FALSE);
ZeroMemory(&m_aDefaults[PWEXP_TXT], sizeof(PWEXPORT_OPTIONS));
m_aDefaults[PWEXP_TXT].bGroup = TRUE;
m_aDefaults[PWEXP_TXT].bTitle = TRUE;
m_aDefaults[PWEXP_TXT].bUserName = TRUE;
m_aDefaults[PWEXP_TXT].bURL = TRUE;
m_aDefaults[PWEXP_TXT].bPassword = TRUE;
m_aDefaults[PWEXP_TXT].bNotes = TRUE;
ZeroMemory(&m_aDefaults[PWEXP_HTML], sizeof(PWEXPORT_OPTIONS));
m_aDefaults[PWEXP_HTML].bGroup = TRUE;
m_aDefaults[PWEXP_HTML].bTitle = TRUE;
m_aDefaults[PWEXP_HTML].bUserName = TRUE;
m_aDefaults[PWEXP_HTML].bURL = TRUE;
m_aDefaults[PWEXP_HTML].bPassword = TRUE;
m_aDefaults[PWEXP_HTML].bNotes = TRUE;
ZeroMemory(&m_aDefaults[PWEXP_XML], sizeof(PWEXPORT_OPTIONS));
m_aDefaults[PWEXP_XML].bGroup = TRUE;
m_aDefaults[PWEXP_XML].bGroupTree = TRUE;
m_aDefaults[PWEXP_XML].bTitle = TRUE;
m_aDefaults[PWEXP_XML].bUserName = TRUE;
m_aDefaults[PWEXP_XML].bURL = TRUE;
m_aDefaults[PWEXP_XML].bPassword = TRUE;
m_aDefaults[PWEXP_XML].bNotes = TRUE;
m_aDefaults[PWEXP_XML].bUUID = TRUE;
m_aDefaults[PWEXP_XML].bImage = TRUE;
m_aDefaults[PWEXP_XML].bCreationTime = TRUE;
m_aDefaults[PWEXP_XML].bLastAccTime = TRUE;
m_aDefaults[PWEXP_XML].bLastModTime = TRUE;
m_aDefaults[PWEXP_XML].bExpireTime = TRUE;
m_aDefaults[PWEXP_XML].bAttachment = TRUE;
ZeroMemory(&m_aDefaults[PWEXP_CSV], sizeof(PWEXPORT_OPTIONS));
m_aDefaults[PWEXP_CSV].bTitle = TRUE;
m_aDefaults[PWEXP_CSV].bUserName = TRUE;
m_aDefaults[PWEXP_CSV].bURL = TRUE;
m_aDefaults[PWEXP_CSV].bPassword = TRUE;
m_aDefaults[PWEXP_CSV].bNotes = TRUE;
ZeroMemory(&m_aDefaults[PWEXP_KEEPASS], sizeof(PWEXPORT_OPTIONS));
m_aDefaults[PWEXP_KEEPASS].bGroup = TRUE;
m_aDefaults[PWEXP_KEEPASS].bGroupTree = TRUE;
m_aDefaults[PWEXP_KEEPASS].bTitle = TRUE;
m_aDefaults[PWEXP_KEEPASS].bUserName = TRUE;
m_aDefaults[PWEXP_KEEPASS].bURL = TRUE;
m_aDefaults[PWEXP_KEEPASS].bPassword = TRUE;
m_aDefaults[PWEXP_KEEPASS].bNotes = TRUE;
m_aDefaults[PWEXP_KEEPASS].bUUID = TRUE;
m_aDefaults[PWEXP_KEEPASS].bImage = TRUE;
m_aDefaults[PWEXP_KEEPASS].bCreationTime = TRUE;
m_aDefaults[PWEXP_KEEPASS].bLastAccTime = TRUE;
m_aDefaults[PWEXP_KEEPASS].bLastModTime = TRUE;
m_aDefaults[PWEXP_KEEPASS].bExpireTime = TRUE;
m_aDefaults[PWEXP_KEEPASS].bAttachment = TRUE;
m_aDefaults[PWEXP_KEEPASS].bExportBackups = TRUE;
}
CPwExport::~CPwExport()
{
m_pMgr = NULL;
m_nFormat = 0;
m_fp = NULL;
}
void CPwExport::SetManager(CPwManager *pMgr)
{
ASSERT(pMgr != NULL);
m_pMgr = pMgr;
}
void CPwExport::SetFormat(int nFormat)
{
ASSERT((nFormat > PWEXP_NULL) && (nFormat < PWEXP_LAST));
if((nFormat > PWEXP_NULL) && (nFormat < PWEXP_LAST))
m_nFormat = nFormat;
}
void CPwExport::SetNewLineSeq(BOOL bWindows)
{
if(bWindows == TRUE) m_pszNewLine = _T("\r\n");
else m_pszNewLine = _T("\n");
}
void CPwExport::_ExpStr(LPCTSTR lpString)
{
if(_tcslen(lpString) != 0)
{
UTF8_BYTE *pUtf8String = _StringToUTF8(lpString);
ASSERT(pUtf8String != NULL);
if(pUtf8String != NULL)
{
fwrite(pUtf8String, 1, strlen((char *)pUtf8String), m_fp);
SAFE_DELETE_ARRAY(pUtf8String);
}
}
}
void CPwExport::_ExpXmlStr(LPCTSTR lpString)
{
if(_tcslen(lpString) > 0)
{
TCHAR *pXmlString = MakeSafeXmlString(lpString);
ASSERT(pXmlString != NULL);
if(pXmlString != NULL)
{
UTF8_BYTE *pUtf8String = _StringToUTF8(pXmlString);
fwrite(pUtf8String, 1, strlen((char *)pUtf8String), m_fp);
SAFE_DELETE_ARRAY(pUtf8String);
SAFE_DELETE_ARRAY(pXmlString);
}
}
}
void CPwExport::_ExpHtmlStr(LPCTSTR lpString)
{
if(lpString[0] == 0) _ExpStr(_T(" "));
else _ExpXmlStr(lpString);
}
void CPwExport::_ExpStrIf(BOOL bCondition, LPCTSTR lpString)
{
if(bCondition == TRUE)
{
if(m_bOneSkipped == TRUE) _ExpStr(m_lpSep);
else m_bOneSkipped = TRUE;
if(m_pOptions->bEncodeNewlines == TRUE)
{
CString str = lpString;
str.Replace(_T("\r"), _T("\\r"));
str.Replace(_T("\n"), _T("\\n"));
_ExpStr(str);
}
else _ExpStr(lpString);
}
}
void CPwExport::_ExpXmlStrIf(BOOL bCondition, LPCTSTR lpString)
{
if(bCondition == TRUE)
{
if(m_bOneSkipped == TRUE) _ExpStr(m_lpSep);
else m_bOneSkipped = TRUE;
if(m_pOptions->bEncodeNewlines == TRUE)
{
CString str = lpString;
str.Replace(_T("\r"), _T("\\r"));
str.Replace(_T("\n"), _T("\\n"));
_ExpXmlStr(str);
}
else _ExpXmlStr(lpString);
}
}
void CPwExport::_ExpHtmlStrIf(BOOL bCondition, LPCTSTR lpString)
{
if(bCondition == TRUE)
{
if(m_bOneSkipped == TRUE) _ExpStr(m_lpSep);
else m_bOneSkipped = TRUE;
if(m_pOptions->bEncodeNewlines == TRUE)
{
CString str = lpString;
str.Replace(_T("\r"), _T("\\r"));
str.Replace(_T("\n"), _T("\\n"));
_ExpHtmlStr(str);
}
else _ExpHtmlStr(lpString);
}
}
void CPwExport::_ExpCsvStrIf(BOOL bCondition, LPCTSTR lpString)
{
if(bCondition == TRUE)
{
if(m_bOneSkipped == TRUE) _ExpStr(m_lpSep);
else m_bOneSkipped = TRUE;
CString str = lpString;
str.Replace(_T("\\"), _T("\\\\"));
str.Replace(_T("\""), _T("\\\""));
if(m_pOptions->bEncodeNewlines == TRUE)
{
str.Replace(_T("\r"), _T("\\r"));
str.Replace(_T("\n"), _T("\\n"));
_ExpStr(str);
}
else _ExpStr(str);
}
}
void CPwExport::_ExpResetSkip()
{
m_bOneSkipped = FALSE;
}
void CPwExport::_ExpSetSep(LPCTSTR lpSep)
{
if(lpSep == NULL) m_lpSep = _T("");
else m_lpSep = lpSep;
}
BOOL CPwExport::ExportAll(const TCHAR *pszFile, const PWEXPORT_OPTIONS *pOptions, CPwManager *pStoreMgr)
{
ASSERT(pszFile != NULL);
return ExportGroup(pszFile, DWORD_MAX, pOptions, pStoreMgr);
}
CString CPwExport::MakeGroupTreeString(DWORD dwGroupId) const
{
PW_GROUP *pg;
CString str;
pg = m_pMgr->GetGroupById(dwGroupId);
ASSERT(pg != NULL); if(pg == NULL) return str;
const USHORT usLevel = pg->usLevel;
ASSERT(usLevel != 0xFFFF); if(usLevel == 0xFFFF) return str;
if(usLevel == 0) return str;
DWORD *pdwIndices = new DWORD[usLevel + 2];
ASSERT(pdwIndices != NULL); if(pdwIndices == NULL) return str;
if(m_pMgr->GetGroupTree(dwGroupId, pdwIndices) == TRUE)
{
for(DWORD i = 0; i < (DWORD)usLevel; i++)
{
pg = m_pMgr->GetGroup(pdwIndices[i]);
if(pg != NULL)
{
if(i > 0) str += _T("\\");
CString strTemp = pg->pszGroupName;
strTemp.Replace(_T("\\"), _T("/"));
str += strTemp;
}
}
}
SAFE_DELETE_ARRAY(pdwIndices);
return str;
}
BOOL CPwExport::ExportGroup(const TCHAR *pszFile, DWORD dwGroupId, const PWEXPORT_OPTIONS *pOptions, CPwManager *pStoreMgr)
{
FILE *fp = NULL;
DWORD i, j, dwThisId, dwNumberOfGroups, dwInvalidId1, dwInvalidId2;
PW_ENTRY *p;
PW_GROUP *pg;
BYTE aInitUTF8[3] = { 0xEF, 0xBB, 0xBF };
CString str, strUUID, strImage, strCreationTime, strLastAccTime, strLastModTime;
CString strExpireTime, strGroupTree;
BYTE *pbEncodedAttachment = NULL;
PW_TIME tNever;
std::vector<DWORD> aGroupIds;
USHORT usLevel = 0;
BOOL bReturn = TRUE;
ASSERT(m_pMgr != NULL); if(m_pMgr == NULL) return FALSE;
m_pMgr->GetNeverExpireTime(&tNever);
ASSERT(pszFile != NULL); if(pszFile == NULL) return FALSE;
if(m_nFormat == PWEXP_KEEPASS) { ASSERT(pStoreMgr != NULL); if(pStoreMgr == NULL) return FALSE; }
if(pOptions == NULL)
{
if(m_nFormat == PWEXP_TXT) pOptions = &m_aDefaults[PWEXP_TXT];
else if(m_nFormat == PWEXP_HTML) pOptions = &m_aDefaults[PWEXP_HTML];
else if(m_nFormat == PWEXP_XML) pOptions = &m_aDefaults[PWEXP_XML];
else if(m_nFormat == PWEXP_CSV) pOptions = &m_aDefaults[PWEXP_CSV];
else if(m_nFormat == PWEXP_KEEPASS) pOptions = &m_aDefaults[PWEXP_KEEPASS];
else { ASSERT(FALSE); return FALSE; }
}
m_pOptions = pOptions;
dwNumberOfGroups = m_pMgr->GetNumberOfGroups();
dwInvalidId1 = m_pMgr->GetGroupId(PWS_BACKUPGROUP_SRC);
dwInvalidId2 = m_pMgr->GetGroupId(PWS_BACKUPGROUP);
if(dwGroupId != DWORD_MAX)
{
i = m_pMgr->GetGroupByIdN(dwGroupId);
ASSERT(i != DWORD_MAX); if(i == DWORD_MAX) return FALSE;
usLevel = m_pMgr->GetGroup(i)->usLevel;
while(1)
{
pg = m_pMgr->GetGroup(i);
ASSERT(pg != NULL); if(pg == NULL) break;
if((pg->uGroupId != dwGroupId) && (pg->usLevel <= usLevel)) break;
aGroupIds.push_back(pg->uGroupId);
i++;
if(i == dwNumberOfGroups) break;
}
}
else
{
for(i = 0; i < dwNumberOfGroups; i++)
{
pg = m_pMgr->GetGroup(i);
ASSERT(pg != NULL); if(pg == NULL) continue;
aGroupIds.push_back(pg->uGroupId);
}
}
if(m_nFormat != PWEXP_KEEPASS)
{
fp = NULL;
_tfopen_s(&fp, pszFile, _T("wb"));
if(fp == NULL) { aGroupIds.clear(); return FALSE; }
m_fp = fp;
fwrite(aInitUTF8, 1, 3, fp);
}
if(m_nFormat == PWEXP_TXT)
{
}
else if(m_nFormat == PWEXP_HTML)
{
_ExpStr(_T("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">"));
_ExpStr(m_pszNewLine);
_ExpStr(_T("<html><head>"));
_ExpStr(_T("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">"));
_ExpStr(_T("<title>"));
_ExpStr(TRL("Password List"));
_ExpStr(_T("</title></head><body>"));
_ExpStr(m_pszNewLine);
_ExpStr(_T("<h1>"));
_ExpStr(TRL("Password List"));
_ExpStr(_T("</h1>"));
_ExpStr(m_pszNewLine);
_ExpStr(_T("<table width=\"100%\" border=\"1px\" cellspacing=\"0\" cellpadding=\"1\"><tr><th>"));
_ExpSetSep(_T("</th><th>"));
_ExpResetSkip();
_ExpStrIf(pOptions->bGroup, TRL("Password Groups"));
_ExpStrIf(pOptions->bGroupTree, TRL("Group Tree"));
_ExpStrIf(pOptions->bTitle, TRL("Title"));
_ExpStrIf(pOptions->bUserName, TRL("UserName"));
_ExpStrIf(pOptions->bURL, TRL("URL"));
_ExpStrIf(pOptions->bPassword, TRL("Password"));
_ExpStrIf(pOptions->bNotes, TRL("Notes"));
_ExpStrIf(pOptions->bUUID, TRL("UUID"));
_ExpStrIf(pOptions->bImage, TRL("Icon"));
_ExpStrIf(pOptions->bCreationTime, TRL("Creation Time"));
_ExpStrIf(pOptions->bLastAccTime, TRL("Last Access"));
_ExpStrIf(pOptions->bLastModTime, TRL("Last Modification"));
_ExpStrIf(pOptions->bExpireTime, TRL("Expires"));
_ExpStrIf(pOptions->bAttachment, TRL("Attachment Description"));
_ExpStrIf(pOptions->bAttachment, TRL("Attachment"));
_ExpStr(_T("</th></tr>"));
_ExpStr(m_pszNewLine);
}
else if(m_nFormat == PWEXP_XML)
{
_ExpStr(_T("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>"));
_ExpStr(m_pszNewLine);
_ExpStr(_T("<pwlist>"));
_ExpStr(m_pszNewLine);
}
else if(m_nFormat == PWEXP_CSV)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?