From e4711e98f03d35a51cb1e8b9fd86518a593002c3 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Mon, 17 Dec 2012 14:33:42 +0000 Subject: [PATCH] Delo se nadaljuje. --- MSICALib/MSITSCA.cpp | 46 ++++++++++++++++++++++------ MSICALib/MSITSCA.h | 73 +++++++++++++++++++++++++++++++++++++++++--- MSICALib/StdAfx.h | 1 + 3 files changed, 106 insertions(+), 14 deletions(-) diff --git a/MSICALib/MSITSCA.cpp b/MSICALib/MSITSCA.cpp index bfe8663..f313402 100644 --- a/MSICALib/MSITSCA.cpp +++ b/MSICALib/MSITSCA.cpp @@ -42,22 +42,37 @@ UINT MSITSCA_API EvaluateScheduledTasks(MSIHANDLE hInstall) UINT uiResult; BOOL bIsCoInitialized = SUCCEEDED(::CoInitialize(NULL)); - CString sComponent; + CString sSequenceFilename, sComponent; + CStringW sDisplayName; + CFile fSequence; PMSIHANDLE hDatabase, hViewST; assert(0); // Attach debugger here or press "Ignore"! - hDatabase = ::MsiGetActiveDatabase(hInstall); - if (!hDatabase) { - uiResult = ERROR_INVALID_HANDLE; + { + // Prepare our own "TODO" script. + LPTSTR szBuffer = sSequenceFilename.GetBuffer(MAX_PATH); + assert(szBuffer); + ::GetTempPath(MAX_PATH, szBuffer); + ::GetTempFileName(szBuffer, _T("TS"), 0, szBuffer); + sSequenceFilename.ReleaseBuffer(); + } + if (!fSequence.Open(sSequenceFilename, CFile::modeWrite | CFile::shareDenyWrite | CFile::modeCreate | CFile::osSequentialScan)) { + uiResult = ERROR_CREATE_FAILED; goto error1; } - uiResult = ::MsiDatabaseOpenView(hDatabase, _T("SELECT Component_ FROM ScheduledTask"), &hViewST); - if (uiResult != ERROR_SUCCESS) goto error1; + hDatabase = ::MsiGetActiveDatabase(hInstall); + if (!hDatabase) { + uiResult = ERROR_INVALID_HANDLE; + goto error2; + } + + uiResult = ::MsiDatabaseOpenView(hDatabase, _T("SELECT Component_, DisplayName FROM ScheduledTask"), &hViewST); + if (uiResult != ERROR_SUCCESS) goto error2; uiResult = ::MsiViewExecute(hViewST, NULL); - if (uiResult != ERROR_SUCCESS) goto error1; + if (uiResult != ERROR_SUCCESS) goto error2; for (;;) { PMSIHANDLE hRecord; @@ -68,19 +83,30 @@ UINT MSITSCA_API EvaluateScheduledTasks(MSIHANDLE hInstall) if (uiResult == ERROR_NO_MORE_ITEMS) break; else if (uiResult != ERROR_SUCCESS) - goto error1; + goto error2; + // Read Component ID. uiResult = ::MsiRecordGetString(hRecord, 1, sComponent); - if (uiResult != ERROR_SUCCESS) goto error1; + if (uiResult != ERROR_SUCCESS) goto error2; + // Get component state and save for deferred processing. uiResult = ::MsiGetComponentState(hInstall, sComponent, &iInstalled, &iAction); - if (uiResult != ERROR_SUCCESS) goto error1; + if (uiResult != ERROR_SUCCESS) goto error2; + fSequence << iAction; + + // Get task's display name and save for deferred processing. + uiResult = ::MsiRecordGetStringW(hRecord, 2, sDisplayName); + if (uiResult != ERROR_SUCCESS) goto error2; + fSequence << sDisplayName; } verify(::MsiViewClose(hViewST) == ERROR_SUCCESS); uiResult = ERROR_SUCCESS; +error2: + fSequence.Close(); error1: + if (uiResult != ERROR_SUCCESS) ::DeleteFile(sSequenceFilename); if (bIsCoInitialized) ::CoUninitialize(); return uiResult; } diff --git a/MSICALib/MSITSCA.h b/MSICALib/MSITSCA.h index e7f57e0..8cb5702 100644 --- a/MSICALib/MSITSCA.h +++ b/MSICALib/MSITSCA.h @@ -72,6 +72,9 @@ namespace MSITSCA { // Lokalni include //////////////////////////////////////////////////////////////////// +#include +#include +#include #include @@ -79,17 +82,18 @@ namespace MSITSCA { // Funkcije inline //////////////////////////////////////////////////////////////////// -inline UINT MsiRecordGetString(MSIHANDLE hRecord, unsigned int iField, CString &sValue) +inline UINT MsiRecordGetStringA(MSIHANDLE hRecord, unsigned int iField, CStringA &sValue) { DWORD dwSize = 0; UINT uiResult; // Query the actual string length first. - uiResult = ::MsiRecordGetString(hRecord, iField, _T(""), &dwSize); + uiResult = ::MsiRecordGetStringA(hRecord, iField, "", &dwSize); if (uiResult == ERROR_MORE_DATA) { // Prepare the buffer to read the string data into and read it. - LPTSTR szBuffer = sValue.GetBuffer(dwSize++); - uiResult = ::MsiRecordGetString(hRecord, iField, szBuffer, &dwSize); + LPSTR szBuffer = sValue.GetBuffer(dwSize++); + assert(szBuffer); + uiResult = ::MsiRecordGetStringA(hRecord, iField, szBuffer, &dwSize); if (uiResult == ERROR_SUCCESS) { // Read succeeded. sValue.ReleaseBuffer(dwSize); @@ -109,6 +113,67 @@ inline UINT MsiRecordGetString(MSIHANDLE hRecord, unsigned int iField, CString & } } + +inline UINT MsiRecordGetStringW(MSIHANDLE hRecord, unsigned int iField, CStringW &sValue) +{ + DWORD dwSize = 0; + UINT uiResult; + + // Query the actual string length first. + uiResult = ::MsiRecordGetStringW(hRecord, iField, L"", &dwSize); + if (uiResult == ERROR_MORE_DATA) { + // Prepare the buffer to read the string data into and read it. + LPWSTR szBuffer = sValue.GetBuffer(dwSize++); + assert(szBuffer); + uiResult = ::MsiRecordGetStringW(hRecord, iField, szBuffer, &dwSize); + if (uiResult == ERROR_SUCCESS) { + // Read succeeded. + sValue.ReleaseBuffer(dwSize); + return ERROR_SUCCESS; + } else { + // Read failed. Empty the string and return error code. + sValue.ReleaseBuffer(0); + return uiResult; + } + } else if (uiResult == ERROR_SUCCESS) { + // The string in database is empty. + sValue.Empty(); + return ERROR_SUCCESS; + } else { + // Return error code. + return uiResult; + } +} + + +//////////////////////////////////////////////////////////////////// +// Operatorji inline +//////////////////////////////////////////////////////////////////// + +inline CFile& operator <<(CFile &f, int i) +{ + f.Write(&i, sizeof(int)); + return f; +} + + +inline CFile& operator <<(CFile &f, const CStringA &str) +{ + int iLength = str.GetLength(); + f.Write(&iLength, sizeof(int)); + f.Write((LPCSTR)str, sizeof(CHAR) * iLength); + return f; +} + + +inline CFile& operator <<(CFile &f, const CStringW &str) +{ + int iLength = str.GetLength(); + f.Write(&iLength, sizeof(int)); + f.Write((LPCWSTR)str, sizeof(WCHAR) * iLength); + return f; +} + #endif // !defined(RC_INVOKED) && !defined(MIDL_PASS) #endif // __MSITSCA_H__ diff --git a/MSICALib/StdAfx.h b/MSICALib/StdAfx.h index a51426a..f4a066d 100644 --- a/MSICALib/StdAfx.h +++ b/MSICALib/StdAfx.h @@ -26,6 +26,7 @@ #define _ATL_NO_AUTOMATIC_NAMESPACE #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // Some CString constructors will be explicit +#include #include #include