MSICA/MSICALib/OpCert.cpp
Simon Rozman b4750608b3 ERROR_SUCCESS => NO_ERROR
Dodal sem podporo za upravljanje sistemskih servisov.
2014-03-20 12:17:08 +00:00

162 lines
6.8 KiB
C++

#include "stdafx.h"
#pragma comment(lib, "crypt32.lib")
namespace MSICA {
////////////////////////////////////////////////////////////////////////////
// COpCertStore
////////////////////////////////////////////////////////////////////////////
COpCertStore::COpCertStore(LPCWSTR pszStore, DWORD dwEncodingType, DWORD dwFlags, int iTicks) :
COpTypeSingleString(pszStore, iTicks),
m_dwEncodingType(dwEncodingType),
m_dwFlags(dwFlags)
{
}
////////////////////////////////////////////////////////////////////////////
// COpCert
////////////////////////////////////////////////////////////////////////////
COpCert::COpCert(LPCVOID lpCert, SIZE_T nSize, LPCWSTR pszStore, DWORD dwEncodingType, DWORD dwFlags, int iTicks) :
COpCertStore(pszStore, dwEncodingType, dwFlags, iTicks)
{
m_binCert.SetCount(nSize);
memcpy(m_binCert.GetData(), lpCert, nSize);
}
////////////////////////////////////////////////////////////////////////////
// COpCertInstall
////////////////////////////////////////////////////////////////////////////
COpCertInstall::COpCertInstall(LPCVOID lpCert, SIZE_T nSize, LPCWSTR pszStore, DWORD dwEncodingType, DWORD dwFlags, int iTicks) : COpCert(lpCert, nSize, pszStore, dwEncodingType, dwFlags, iTicks)
{
}
HRESULT COpCertInstall::Execute(CSession *pSession)
{
DWORD dwError;
HCERTSTORE hCertStore;
// Open certificate store.
hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM_W, m_dwEncodingType, NULL, m_dwFlags, m_sValue);
if (hCertStore) {
// Create certificate context.
PCCERT_CONTEXT pCertContext = ::CertCreateCertificateContext(m_dwEncodingType, m_binCert.GetData(), (DWORD)(m_binCert.GetCount()));
if (pCertContext) {
PMSIHANDLE hRecordMsg = ::MsiCreateRecord(1);
ATL::CAtlStringW sCertName;
// Display our custom message in the progress bar.
::CertGetNameStringW(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, sCertName);
::MsiRecordSetStringW(hRecordMsg, 1, sCertName);
if (MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ACTIONDATA, hRecordMsg) == IDCANCEL)
return AtlHresultFromWin32(ERROR_INSTALL_USEREXIT);
// Add certificate to certificate store.
if (::CertAddCertificateContextToStore(hCertStore, pCertContext, CERT_STORE_ADD_NEW, NULL)) {
if (pSession->m_bRollbackEnabled) {
// Order rollback action to delete the certificate.
pSession->m_olRollback.AddHead(new COpCertRemove(m_binCert.GetData(), m_binCert.GetCount(), m_sValue, m_dwEncodingType, m_dwFlags));
}
dwError = NO_ERROR;
} else {
dwError = ::GetLastError();
if (dwError == CRYPT_E_EXISTS) {
// Certificate store already contains given certificate. Nothing to install then.
dwError = NO_ERROR;
}
}
::CertFreeCertificateContext(pCertContext);
} else
dwError = ::GetLastError();
::CertCloseStore(hCertStore, 0);
} else
dwError = ::GetLastError();
if (dwError == NO_ERROR)
return S_OK;
else {
PMSIHANDLE hRecordProg = ::MsiCreateRecord(3);
::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_CERT_INSTALL_FAILED);
::MsiRecordSetStringW(hRecordProg, 2, m_sValue );
::MsiRecordSetInteger(hRecordProg, 3, dwError );
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
return AtlHresultFromWin32(dwError);
}
}
////////////////////////////////////////////////////////////////////////////
// COpCertRemove
////////////////////////////////////////////////////////////////////////////
COpCertRemove::COpCertRemove(LPCVOID lpCert, SIZE_T nSize, LPCWSTR pszStore, DWORD dwEncodingType, DWORD dwFlags, int iTicks) : COpCert(lpCert, nSize, pszStore, dwEncodingType, dwFlags, iTicks)
{
}
HRESULT COpCertRemove::Execute(CSession *pSession)
{
DWORD dwError;
HCERTSTORE hCertStore;
// Open certificate store.
hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM_W, m_dwEncodingType, NULL, m_dwFlags, m_sValue);
if (hCertStore) {
// Create certificate context.
PCCERT_CONTEXT pCertContext = ::CertCreateCertificateContext(m_dwEncodingType, m_binCert.GetData(), (DWORD)(m_binCert.GetCount()));
if (pCertContext) {
PMSIHANDLE hRecordMsg = ::MsiCreateRecord(1);
ATL::CAtlStringW sCertName;
PCCERT_CONTEXT pCertContextExisting;
// Display our custom message in the progress bar.
::CertGetNameStringW(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, sCertName);
::MsiRecordSetStringW(hRecordMsg, 1, sCertName);
if (MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ACTIONDATA, hRecordMsg) == IDCANCEL)
return AtlHresultFromWin32(ERROR_INSTALL_USEREXIT);
pCertContextExisting = ::CertFindCertificateInStore(hCertStore, m_dwEncodingType, 0, CERT_FIND_EXISTING, pCertContext, NULL);
if (pCertContextExisting) {
// Delete certificate from certificate store.
if (::CertDeleteCertificateFromStore(pCertContextExisting)) {
if (pSession->m_bRollbackEnabled) {
// Order rollback action to reinstall the certificate.
pSession->m_olRollback.AddHead(new COpCertInstall(m_binCert.GetData(), m_binCert.GetCount(), m_sValue, m_dwEncodingType, m_dwFlags));
}
dwError = NO_ERROR;
} else {
dwError = ::GetLastError();
::CertFreeCertificateContext(pCertContextExisting);
}
} else {
// We haven't found the certificate. Nothing to delete then.
dwError = NO_ERROR;
}
::CertFreeCertificateContext(pCertContext);
} else
dwError = ::GetLastError();
::CertCloseStore(hCertStore, 0);
} else
dwError = ::GetLastError();
if (dwError == NO_ERROR)
return S_OK;
else {
PMSIHANDLE hRecordProg = ::MsiCreateRecord(3);
::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_CERT_REMOVE_FAILED);
::MsiRecordSetStringW(hRecordProg, 2, m_sValue );
::MsiRecordSetInteger(hRecordProg, 3, dwError );
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
return AtlHresultFromWin32(dwError);
}
}
} // namespace MSICA