From fcbb7bb3c95ed9088736203ac54b1e4da00f7a81 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Thu, 13 Mar 2014 10:28:29 +0000 Subject: [PATCH] =?UTF-8?q?Dodal=20sem=20podporo=20za=20name=C5=A1=C4=8Dan?= =?UTF-8?q?je=20in=20odstranjevanje=20certifikatov.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MSICALib/L10N/sl_SI.po | 8 ++ MSICALib/MSICALib.h | 60 ++++++++++++++- MSICALib/MSICALib.vcxproj | 2 +- MSICALib/MSICALib.vcxproj.filters | 2 +- MSICALib/OpCert.cpp | 117 +++++++++++++++++++++++++++++- MSICALib/msm/Makefile | 3 + MSICATS/L10N/sl_SI.po | 8 -- MSICATS/MSICATS.cpp | 4 +- MSICATS/msm/Makefile | 27 ------- 9 files changed, 187 insertions(+), 44 deletions(-) diff --git a/MSICALib/L10N/sl_SI.po b/MSICALib/L10N/sl_SI.po index b669224..269dbcd 100644 --- a/MSICALib/L10N/sl_SI.po +++ b/MSICALib/L10N/sl_SI.po @@ -89,3 +89,11 @@ msgid "" msgstr "" "Pri premikanju datoteke »[2]« v »[3]« je prišlo do napake [4]. Obrnite se na " "svojo tehnično službo." + +#: ..\msm/Sl.DebugU.Win32.Error-2.idtx:4 +msgid "" +"Error [2] creating scheduled task list. Please, contact your support " +"personnel." +msgstr "" +"Pri pripravi seznama razvrščenih opravil je prišlo do napake [2]. Obrnite se " +"na svojo tehnično službo." diff --git a/MSICALib/MSICALib.h b/MSICALib/MSICALib.h index 691251a..be87731 100644 --- a/MSICALib/MSICALib.h +++ b/MSICALib/MSICALib.h @@ -12,10 +12,11 @@ //////////////////////////////////////////////////////////////////// -// Error codes (next unused 2569L) +// Error codes (next unused 2571L) //////////////////////////////////////////////////////////////////// #define ERROR_INSTALL_DATABASE_OPEN 2550L +#define ERROR_INSTALL_OPLIST_CREATE 2551L #define ERROR_INSTALL_PROPERTY_SET 2553L #define ERROR_INSTALL_SCRIPT_WRITE 2552L #define ERROR_INSTALL_SCRIPT_READ 2560L @@ -33,9 +34,8 @@ #define ERROR_INSTALL_TASK_DELETE_FAILED 2557L #define ERROR_INSTALL_TASK_ENABLE_FAILED 2558L #define ERROR_INSTALL_TASK_COPY_FAILED 2559L - -// Errors reported by MSITSCA -#define ERROR_INSTALL_SCHEDULED_TASKS_OPLIST_CREATE 2551L +#define ERROR_INSTALL_CERT_INSTALL_FAILED 2569L +#define ERROR_INSTALL_CERT_REMOVE_FAILED 2570L namespace MSICA { @@ -443,6 +443,18 @@ public: }; +//////////////////////////////////////////////////////////////////////////// +// COpCertRemove +//////////////////////////////////////////////////////////////////////////// + +class COpCertRemove : public COpCert +{ +public: + COpCertRemove(LPCVOID lpCert = NULL, SIZE_T nSize = 0, LPCWSTR pszStore = L"", DWORD dwEncodingType = 0, DWORD dwFlags = 0, int iTicks = 0); + virtual HRESULT Execute(CSession *pSession); +}; + + //////////////////////////////////////////////////////////////////////////// // COpList //////////////////////////////////////////////////////////////////////////// @@ -476,6 +488,8 @@ protected: OP_TASK_DELETE, OP_TASK_ENABLE, OP_TASK_COPY, + OP_CERT_INSTALL, + OP_CERT_REMOVE, OP_SUBLIST }; @@ -775,6 +789,34 @@ inline UINT MsiGetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder, ATL::CAtlStr } +inline DWORD CertGetNameStringA(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, void *pvTypePara, ATL::CAtlStringA &sNameString) +{ + // Query the final string length first. + DWORD dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0); + + // Prepare the buffer to format the string data into and read it. + LPSTR szBuffer = sNameString.GetBuffer(dwSize); + if (!szBuffer) return ERROR_OUTOFMEMORY; + dwSize = ::CertGetNameStringA(pCertContext, dwType, dwFlags, pvTypePara, szBuffer, dwSize); + sNameString.ReleaseBuffer(dwSize); + return dwSize; +} + + +inline DWORD CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, void *pvTypePara, ATL::CAtlStringW &sNameString) +{ + // Query the final string length first. + DWORD dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0); + + // Prepare the buffer to format the string data into and read it. + LPWSTR szBuffer = sNameString.GetBuffer(dwSize); + if (!szBuffer) return ERROR_OUTOFMEMORY; + dwSize = ::CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, szBuffer, dwSize); + sNameString.ReleaseBuffer(dwSize); + return dwSize; +} + + namespace MSICA { //////////////////////////////////////////////////////////////////////////// @@ -1340,6 +1382,10 @@ inline HRESULT operator <<(ATL::CAtlFile &f, const COpList &list) hr = list.Save(f, pOp); else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) + hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) + hr = list.Save(f, pOp); else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); else { @@ -1411,6 +1457,12 @@ inline HRESULT operator >>(ATL::CAtlFile &f, COpList &list) case COpList::OP_TASK_COPY: hr = list.LoadAndAddTail(f); break; + case COpList::OP_CERT_INSTALL: + hr = list.LoadAndAddTail(f); + break; + case COpList::OP_CERT_REMOVE: + hr = list.LoadAndAddTail(f); + break; case COpList::OP_SUBLIST: hr = list.LoadAndAddTail(f); break; diff --git a/MSICALib/MSICALib.vcxproj b/MSICALib/MSICALib.vcxproj index 1ae9067..cf1a6d1 100644 --- a/MSICALib/MSICALib.vcxproj +++ b/MSICALib/MSICALib.vcxproj @@ -36,7 +36,7 @@ - + {8552EE55-177E-4F51-B51B-BAF7D6462CDE} diff --git a/MSICALib/MSICALib.vcxproj.filters b/MSICALib/MSICALib.vcxproj.filters index 24b8750..9227914 100644 --- a/MSICALib/MSICALib.vcxproj.filters +++ b/MSICALib/MSICALib.vcxproj.filters @@ -43,7 +43,7 @@ - + Resource Files diff --git a/MSICALib/OpCert.cpp b/MSICALib/OpCert.cpp index a5109ee..9adf5b0 100644 --- a/MSICALib/OpCert.cpp +++ b/MSICALib/OpCert.cpp @@ -40,7 +40,122 @@ COpCertInstall::COpCertInstall(LPCVOID lpCert, SIZE_T nSize, LPCWSTR pszStore, D HRESULT COpCertInstall::Execute(CSession *pSession) { - return E_NOTIMPL; + 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 = ERROR_SUCCESS; + } else { + dwError = ::GetLastError(); + if (dwError == CRYPT_E_EXISTS) { + // Certificate store already contains given certificate. Nothing to install then. + dwError = ERROR_SUCCESS; + } + } + ::CertFreeCertificateContext(pCertContext); + } else + dwError = ::GetLastError(); + ::CertCloseStore(hCertStore, 0); + } else + dwError = ::GetLastError(); + + if (dwError == ERROR_SUCCESS) + 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 = ERROR_SUCCESS; + } else { + dwError = ::GetLastError(); + ::CertFreeCertificateContext(pCertContextExisting); + } + } else { + // We haven't found the certificate. Nothing to delete then. + dwError = ERROR_SUCCESS; + } + ::CertFreeCertificateContext(pCertContext); + } else + dwError = ::GetLastError(); + ::CertCloseStore(hCertStore, 0); + } else + dwError = ::GetLastError(); + + if (dwError == ERROR_SUCCESS) + 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 diff --git a/MSICALib/msm/Makefile b/MSICALib/msm/Makefile index 9811cee..4027b1c 100644 --- a/MSICALib/msm/Makefile +++ b/MSICALib/msm/Makefile @@ -25,6 +25,7 @@ Error Message i2 L0 1252 Error Error 2550 Error opening installation package. Please, contact your support personnel. +2551 Error [2] creating scheduled task list. Please, contact your support personnel. 2552 Error [3] writing to "[2]" task list file. Please, contact your support personnel. 2560 Error [3] reading from "[2]" task list file. Please, contact your support personnel. 2553 Error [3] setting "[2]" parameter. Please, contact your support personnel. @@ -34,6 +35,8 @@ i2 L0 2557 Error [3] deleting "[2]" scheduled task. Please, contact your support personnel. 2558 Error [3] enabling/disabling "[2]" scheduled task. Please, contact your support personnel. 2559 Error [4] copying "[2]" scheduled task to "[3]". Please, contact your support personnel. +2569 Error [3] installing certificate to certificate store "[2]". Please, contact your support personnel. +2570 Error [3] removing certificate from certificate store "[2]". Please, contact your support personnel. < NUL -Error Message -i2 L0 -1250 Error Error -2551 Error [2] creating scheduled task list. Please, contact your support personnel. -< NUL - -"It.$(CFG).$(PLAT).Error-2.idt" : "En.$(PLAT).$(CFG).Error-2.idtx" "..\L10N\it_IT.po" - rcxgettext.exe idtp $@ $** - -"Sl.$(CFG).$(PLAT).Error-2.idt" : "En.$(PLAT).$(CFG).Error-2.idtx" "..\L10N\sl_SI.po" - rcxgettext.exe idtp $@ $** - - ###################################################################### # InstallExecuteSequence