📄 cisocadoc.cpp
字号:
// CisoCADoc.cpp : implementation of the CCisoCADoc class
//
#include "stdafx.h"
#include "CisoCA.h"
#include "CisoCADoc.h"
#include "Shlwapi.h"
#include "UserInfo.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CInfoReport InfoReport;
extern DWORD dwMoudleID;
/////////////////////////////////////////////////////////////////////////////
// CCisoCADoc
IMPLEMENT_DYNCREATE(CCisoCADoc, CDocument)
BEGIN_MESSAGE_MAP(CCisoCADoc, CDocument)
//{{AFX_MSG_MAP(CCisoCADoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCisoCADoc construction/destruction
CCisoCADoc::CCisoCADoc()
{
// TODO: add one-time construction code here
m_ColHeader.AddHeader(_T("证书序列号"),50);
m_ColHeader.AddHeader(_T("通用名") ,100);
m_ColHeader.AddHeader(_T("部门名称") ,50);
m_ColHeader.AddHeader(_T("单位名称") ,50);
m_ColHeader.AddHeader(_T("所在城市") ,60);
m_ColHeader.AddHeader(_T("所在省份") ,60);
m_ColHeader.AddHeader(_T("所在国家") ,60);
m_ColHeader.AddHeader(_T("签发时间") ,120);
m_ColHeader.AddHeader(_T("到期时间") ,120);
m_pConF = NULL;
m_pConn = NULL;
m_pSet = NULL;
isInit = FALSE;
}
CCisoCADoc::~CCisoCADoc()
{
if(m_pConF)
{
delete m_pConF;
m_pConF = NULL;
}
if(m_pSet->State == adStateOpen)
{
m_pSet->Close();
}
if(m_pConn->State == adStateOpen)
{
m_pConn->Close();
}
}
BOOL CCisoCADoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// 连接字符串的格式如下:
// Provider=Microsoft.Jet.OLEDB.4.0;
// Data Source=databaseName;
// User ID=userName;
// Password=userPassword;
// 装入配置文件
CString strTmp;
m_ConnStr="Provider=Microsoft.Jet.OLEDB.4.0;Data Source";
m_ConnStr = m_ConnStr + "=" + CA_DATABASE+";";
char buf[MAX_CONF_BUF]= {0};
m_pConF = new CPropertyFile(CONFIG_FILE);
// 对各种目录进行检查
CheckDir();
// 对日志文件大小进行检查
m_pConF->GetValue("LogFileSize",buf);
if(strlen(buf)>0&&atoi(buf)>0&&atoi(buf)<101)
CheckFileSize((unsigned int)atoi(buf));
// 启动日志文件
dwMoudleID = InfoReport.Register("ca.exe");
InfoReport.WriteInfo(dwMoudleID,"------------------------");
InfoReport.WriteInfo(dwMoudleID,"CA中心主程序启动!");
// 取用户名
m_pConF->GetValue("UserName",buf);
strTmp.Format("%s",buf);
m_ConnStr = m_ConnStr + "User ID=" + strTmp+";";
// 取密码
m_pConF->GetValue("Password",buf);
strTmp.Format("%s",buf);
m_ConnStr = m_ConnStr + "Password=" + strTmp+";";
// 建立连接
InfoReport.WriteInfo(dwMoudleID,"连接数据库!");
if(!ConnectDB())
{
AfxMessageBox("连数据库失败!");
InfoReport.WriteInfo(dwMoudleID,"连数据库失败!");
}
// 判断CA是否已经初始化
m_pConF->GetValue("Initailized",buf);
strTmp.Format("%s",buf);
if(atoi((LPCTSTR)strTmp)==1)isInit = TRUE;
// 设置标题
m_pConF->GetValue("CompanyName",buf);
if(strlen(buf) == 0 )strcpy(buf,"CA未初始化");
SetTitle(buf);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CCisoCADoc serialization
void CCisoCADoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
m_CaCore.m_CaInfo.Serialize(ar);
}
/////////////////////////////////////////////////////////////////////////////
// CCisoCADoc diagnostics
#ifdef _DEBUG
void CCisoCADoc::AssertValid() const
{
CDocument::AssertValid();
}
void CCisoCADoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CCisoCADoc commands
// 连接数据库
BOOL CCisoCADoc::ConnectDB()
{
HRESULT hr;
try
{
if(m_pConn == NULL)
hr = m_pConn.CreateInstance(__uuidof(Connection));
}
catch (_com_error &e)
{
::MessageBox(NULL,e.Description(),"CA中心警告",
MB_OK|MB_ICONWARNING);
m_pConn = NULL;
InfoReport.WriteInfo(dwMoudleID,"错误:创建连接失败!");
}
if(FAILED(hr))return FALSE;
try
{
m_pConn->Open(_bstr_t(m_ConnStr),"","",0);
InfoReport.WriteInfo(dwMoudleID,"打开数据库连接!");
}
catch (_com_error &e)
{
::MessageBox(NULL,e.Description(),"CA中心警告",
MB_OK|MB_ICONWARNING);
InfoReport.WriteInfo(dwMoudleID,"错误:打开数据库连接失败!");
return FALSE;
}
try
{
if(m_pSet == NULL)
hr = m_pSet.CreateInstance( __uuidof( Recordset ));
InfoReport.WriteInfo(dwMoudleID,"创建记录集!");
}
catch (_com_error &e)
{
::MessageBox(NULL,e.Description(),"CA中心警告",
MB_OK|MB_ICONWARNING);
InfoReport.WriteInfo(dwMoudleID,"错误:创建记录集失败!");
m_pSet = NULL;
}
if(FAILED(hr))return FALSE;
return TRUE;
}
// 数据查询
int CCisoCADoc::SelectDB(int want,CListCtrl *pList)
{
BOOL ret = FALSE;
// 如果没有建立连接,重新建立连接
if(m_pConn == NULL)
{
ret = ConnectDB();
if(ret == FALSE)return 0;
}
try
{
CString strSql = "select * from UserInfo";
switch(want)
{
case WANT_TO_SHOW_VALID_CERT:
strSql+=" where CERT_STATE='1'";
break;
case WANT_TO_SHOW_REVOKE_CERT:
strSql+=" where CERT_STATE='0'";
break;
case WANT_TO_GENERATE_CRL:
strSql+=" where CERT_STATE='0'";
break;
default: //do nothing
break;
}
// 执行SQL语句得到一个记录集把其指针赋值给Recordset
if(m_pSet->State == adStateOpen)m_pSet->Close();
BSTR bstrSQL = strSql.AllocSysString();
m_pSet->Open(bstrSQL,(IDispatch*)m_pConn,
adOpenDynamic, // adOpenDynamic:动态
adLockOptimistic, // adLockOptimistic:乐观封锁法
adCmdText); // adCmdText:文本查询语句
if(want == WANT_TO_GENERATE_CRL) return 1;
pList->DeleteAllItems();
while(m_pSet->EndOfFile == VARIANT_FALSE)//遍历所有记录
{
// 逐条记录加入列表视图
_bstr_t bstrValue;
//_variant_t bstrValue;
int row = pList->GetItemCount();
LV_ITEM lvi;
lvi.mask = LVIF_TEXT|LVIF_IMAGE|LVIF_STATE;
lvi.iItem = row;
lvi.iSubItem = 0;
lvi.iImage = atoi((char*)(LPCTSTR)"0");
lvi.stateMask = LVIS_STATEIMAGEMASK;
lvi.state = INDEXTOSTATEIMAGEMASK(1);
// 证书序列号
bstrValue=m_pSet->Fields->GetItem("USER_CERT_SN")->Value;
lvi.pszText = (LPSTR)(LPCTSTR)bstrValue;
if (pList->InsertItem(&lvi) != -1)
{
// 通用名
bstrValue=m_pSet->Fields->GetItem("USER_NAME")->Value;
pList->SetItemText(row, 1, (LPSTR)(LPCTSTR)bstrValue);
// 部门
bstrValue=m_pSet->Fields->GetItem("USER_DEPT")->Value;
pList->SetItemText(row, 2, (LPSTR)(LPCTSTR)bstrValue);
// 单位
bstrValue=m_pSet->Fields->GetItem("USER_ORG")->Value;
pList->SetItemText(row, 3, (LPSTR)(LPCTSTR)bstrValue);
// 城市
bstrValue=m_pSet->Fields->GetItem("USER_CITY")->Value;
pList->SetItemText(row, 4, (LPSTR)(LPCTSTR)bstrValue);
// 省份
bstrValue=m_pSet->Fields->GetItem("USER_PROV")->Value;
pList->SetItemText(row, 5, (LPSTR)(LPCTSTR)bstrValue);
// 国家
bstrValue=m_pSet->Fields->GetItem("USER_COUNTRY")->Value;
pList->SetItemText(row, 6, (LPSTR)(LPCTSTR)bstrValue);
// 时间
bstrValue=m_pSet->Fields->GetItem("CERT_NOTBEFORE")->Value;
pList->SetItemText(row, 7, (LPSTR)(LPCTSTR)bstrValue);
bstrValue=m_pSet->Fields->GetItem("CERT_NOTAFTER")->Value;
pList->SetItemText(row, 8, (LPSTR)(LPCTSTR)bstrValue);
}
// 转到下一条纪录
m_pSet->MoveNext();
}
m_pSet->Close();
}
catch (_com_error e)//异常处理
{
AfxMessageBox(e.Description());
return 0;
}
return 1;
}
// 插入记录
int CCisoCADoc::InsertDB(CUserInfo *pUI)
{
InfoReport.WriteInfo(dwMoudleID,"向数据库插入一条记录!");
if(pUI == NULL)return 0;
BOOL ret = FALSE;
// 如果没有建立连接,重新建立连接
if(m_pConn == NULL)
{
ret = ConnectDB();
if(ret == FALSE)return 0;
}
try
{
if(m_pSet->State == adStateOpen)m_pSet->Close();
m_pSet->Open(_variant_t("UserInfo"),
_variant_t((IDispatch *)m_pConn,true), adOpenDynamic,
adLockPessimistic, adCmdTable);
if(!m_pSet->Supports(adAddNew)) return 0;
m_pSet->AddNew();
// 序列号
m_pSet->Fields->GetItem(_variant_t("USER_CERT_SN"))->Value
=_variant_t(pUI->m_strSN);
// 用户名
m_pSet->Fields->GetItem(_variant_t("USER_NAME"))->Value
=_variant_t(pUI->m_strName);
// 部门
m_pSet->Fields->GetItem(_variant_t("USER_DEPT"))->Value
=_variant_t(pUI->m_strDept);
// 组织
m_pSet->Fields->GetItem(_variant_t("USER_ORG"))->Value
=_variant_t(pUI->m_strOrg);
// 城市
m_pSet->Fields->GetItem(_variant_t("USER_CITY"))->Value
=_variant_t(pUI->m_strCity);
// 省份
m_pSet->Fields->GetItem(_variant_t("USER_PROV"))->Value
=_variant_t(pUI->m_strProvince);
// 国家
m_pSet->Fields->GetItem(_variant_t("USER_COUNTRY"))->Value
=_variant_t(pUI->m_strCountry);
// 状态
m_pSet->Fields->GetItem(_variant_t("CERT_STATE"))->Value
=_variant_t("1");
// 密码
m_pSet->Fields->GetItem(_variant_t("USER_PWD"))->Value
=_variant_t(pUI->m_strPwd);
// 时间
m_pSet->Fields->GetItem(_variant_t("CERT_NOTBEFORE"))->Value
=_variant_t(pUI->m_notBefore);
m_pSet->Fields->GetItem(_variant_t("CERT_NOTAFTER"))->Value
=_variant_t(pUI->m_notAfter);
//
// 定义证书与私钥操作所需要的变量(记得要释放内存)
//
CString cer = pUI->m_strCert;
CString pvk = pUI->m_strPvk;
BYTE *pCer = (unsigned char*)(LPCTSTR)cer;
BYTE *pPvk = (unsigned char*)(LPCTSTR)pvk;
VARIANT varCert,varPvk;
SAFEARRAY *psaCert,*psaPvk;
SAFEARRAYBOUND sabCert[1],sabPvk[1];
// 写入证书
sabCert[0].cElements = cer.GetLength();
sabCert[0].lLbound = 0;
psaCert = SafeArrayCreate(VT_UI1,1,sabCert);
for(long index=0;index < pUI->m_strCert.GetLength(); index++)
{
if(FAILED(SafeArrayPutElement(psaCert,&index,&pCer[index])))
{
::MessageBox(NULL,"写入证书失败!","提示",MB_OK | MB_ICONWARNING);
return 0;
}
}
varCert.vt = VT_ARRAY|VT_UI1;
varCert.parray = psaCert;
m_pSet->Fields->GetItem(_variant_t("USER_CERT"))->AppendChunk(varCert);
// 写入私钥
sabPvk[0].cElements = pvk.GetLength();
sabPvk[0].lLbound = 0;
psaPvk = SafeArrayCreate(VT_UI1,1,sabPvk);
for(index=0;index < pUI->m_strPvk.GetLength(); index++)
{
if(FAILED(SafeArrayPutElement(psaPvk,&index,&pPvk[index])))
{
::MessageBox(NULL,"写入私钥失败!","提示",MB_OK | MB_ICONWARNING);
return 0;
}
}
varPvk.vt = VT_ARRAY|VT_UI1;
varPvk.parray = psaPvk;
m_pSet->Fields->GetItem(_variant_t("USER_PVK"))->AppendChunk(varPvk);
// 释放内存
::VariantClear(&varCert);
::VariantClear(&varPvk);
::SafeArrayDestroyData(psaCert);
::SafeArrayDestroyData( psaPvk);
//
// 更新与关闭
//
m_pSet->Update();
m_pSet->Close();
}
catch (_com_error e)//异常处理
{
AfxMessageBox(e.Description());
InfoReport.WriteInfo(dwMoudleID,"错误:记录插入数据库失败!");
return 0;
}
return 1;
}
void CCisoCADoc::ClearAllData()
{
InfoReport.WriteInfo(dwMoudleID,"清除数据库中的所有记录!");
BOOL ret = FALSE;
// 如果没有建立连接,重新建立连接
if(m_pConn == NULL)
{
ret = ConnectDB();
if(ret == FALSE)return ;
}
try
{
_CommandPtr m_pCmd;
m_pCmd.CreateInstance("ADODB.Command");
// 命令字串
CString strSQL;
strSQL = "delete * from UserInfo";
m_pCmd->ActiveConnection=m_pConn;
m_pCmd->CommandType = adCmdText;
m_pCmd->CommandText = _bstr_t(strSQL);
_variant_t vNull;
vNull.vt = VT_ERROR;
vNull.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
m_pSet = m_pCmd->Execute(&vNull,&vNull,adCmdText);
}
catch (_com_error e)//异常处理
{
AfxMessageBox(e.Description());
InfoReport.WriteInfo(dwMoudleID,"错误:删除记录出错!");
}
}
int CCisoCADoc::UpdateCertState(CStringList *pList)
{
InfoReport.WriteInfo(dwMoudleID,"更新证书的状态为吊销!");
try
{
_CommandPtr m_pCmd;
m_pCmd.CreateInstance("ADODB.Command");
CString strTime;
CTime t = CTime::GetCurrentTime();
strTime.Format("%04d-%02d-%02d %02d:%02d:%02d",
t.GetYear(),t.GetMonth(),t.GetDay(), // date
t.GetHour(),t.GetMinute(),t.GetSecond());// time
// 命令字串
CString strSQL;
strSQL = "UPDATE UserInfo SET CERT_STATE='0' , ";
strSQL+= "CERT_REVOKE_TIME='"+strTime+"' WHERE ";
for( int i=0; i < pList->GetCount(); i++ )
{
strSQL += " USER_CERT_SN='"+pList->GetAt(pList->FindIndex(i))+"'";
if(i < pList->GetCount()-1)
strSQL += " OR ";
}
m_pCmd->ActiveConnection=m_pConn;
m_pCmd->CommandType = adCmdText;
m_pCmd->CommandText = _bstr_t(strSQL);
_variant_t vNull;
vNull.vt = VT_ERROR;
vNull.scode = DISP_E_PARAMNOTFOUND; //定义为无参数
m_pSet = m_pCmd->Execute(&vNull,&vNull,adCmdText);
}
catch (_com_error e)//异常处理
{
AfxMessageBox(e.Description());
InfoReport.WriteInfo(dwMoudleID,"错误:更新证书的状态失败!");
return 0;
}
return 1;
}
void CCisoCADoc::CheckDir()
{
if(!PathIsDirectory(CA_CERT_DIR))
CreateDirectory(CA_CERT_DIR,NULL);
if(!PathIsDirectory(USER_CERT_DIR))
CreateDirectory(USER_CERT_DIR,NULL);
if(!PathIsDirectory(CA_DB_DIR))
CreateDirectory(CA_DB_DIR,NULL);
if(!PathIsDirectory(CA_CONF_DIR))
CreateDirectory(CA_CONF_DIR,NULL);
}
void CCisoCADoc::CheckFileSize(unsigned int size)
{
CFile f;
DWORD dwSize;
CString strFileName;
CTime t = CTime::GetCurrentTime();
CString strTime;
strTime.Format("%04d年%02d月%02d日%02d时%02d分%02d秒",t.GetYear(),
t.GetMonth(),t.GetDay(),t.GetHour(),t.GetMinute(),
t.GetSecond());
try
{
if(f.Open(".\\log\\ca.log",CFile::shareDenyNone) == 0)return;
dwSize = f.GetLength();
f.Close();
strFileName = ".\\log\\ca_"+strTime+".log";
if(dwSize > size*1024*1024)
CFile::Rename(".\\log\\ca.log",strFileName);
}
catch(CFileException e)
{
AfxMessageBox("系统检查日志文件的时候出错!");
return;
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -