summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--instsetoo_native/inc_openoffice/windows/msi_languages/Error.ulf3
-rw-r--r--instsetoo_native/inc_openoffice/windows/msi_templates/Error.idt1
-rw-r--r--scp2/source/ooo/ucrt.scp15
-rw-r--r--setup_native/source/win32/customactions/inst_msu/inst_msu.cxx114
4 files changed, 69 insertions, 64 deletions
diff --git a/instsetoo_native/inc_openoffice/windows/msi_languages/Error.ulf b/instsetoo_native/inc_openoffice/windows/msi_languages/Error.ulf
index a14f45e0cd54..315e35fe0b33 100644
--- a/instsetoo_native/inc_openoffice/windows/msi_languages/Error.ulf
+++ b/instsetoo_native/inc_openoffice/windows/msi_languages/Error.ulf
@@ -406,4 +406,7 @@ en-US = "This setup requires Internet Information Server 4.0 or higher for confi
[OOO_ERROR_130]
en-US = "This setup requires Administrator privileges for configuring IIS Virtual Roots."
+[OOO_ERROR_131]
+en-US = "Installing a pre-requisite KB2999226 failed. You might need to manually install it from Microsoft site to be able to run the product. [2]"
+
diff --git a/instsetoo_native/inc_openoffice/windows/msi_templates/Error.idt b/instsetoo_native/inc_openoffice/windows/msi_templates/Error.idt
index 2f3a5912817d..52cc797c643e 100644
--- a/instsetoo_native/inc_openoffice/windows/msi_templates/Error.idt
+++ b/instsetoo_native/inc_openoffice/windows/msi_templates/Error.idt
@@ -131,3 +131,4 @@ i2 L0
1932 OOO_ERROR_128
1933 OOO_ERROR_129
1934 OOO_ERROR_130
+25000 OOO_ERROR_131
diff --git a/scp2/source/ooo/ucrt.scp b/scp2/source/ooo/ucrt.scp
index ae2eb27a4dbe..8cba6cfc3cd0 100644
--- a/scp2/source/ooo/ucrt.scp
+++ b/scp2/source/ooo/ucrt.scp
@@ -85,11 +85,14 @@ WindowsCustomAction gid_Customaction_cleanup_msu
Assignment1 = ("InstallExecuteSequence", "Not Installed And cleanup_msu", "inst_msu");
End
+/* The "InstMSUBinary" property contains an error message number and a binary name, separated by "|".
+ The former is used when installing the MSU fails.
+*/
WindowsCustomAction gid_Customaction_check_win7x64_ucrt
Name = "check_win7x64_ucrt";
Typ = "51";
Source = "InstMSUBinary";
- Target = "Windows61-KB2999226-x64msu";
+ Target = "25000|Windows61-KB2999226-x64msu";
Inbinarytable = 0;
Assignment1 = ("InstallExecuteSequence", "Not Installed And VersionNT = 601 And VersionNT64", "FileCost");
Styles = "NO_FILE";
@@ -99,7 +102,7 @@ WindowsCustomAction gid_Customaction_check_win8x64_ucrt
Name = "check_win8x64_ucrt";
Typ = "51";
Source = "InstMSUBinary";
- Target = "Windows8-RT-KB2999226-x64msu";
+ Target = "25000|Windows8-RT-KB2999226-x64msu";
Inbinarytable = 0;
Assignment1 = ("InstallExecuteSequence", "Not Installed And VersionNT = 602 And VersionNT64", "check_win7x64_ucrt");
Styles = "NO_FILE";
@@ -109,7 +112,7 @@ WindowsCustomAction gid_Customaction_check_win81x64_ucrt
Name = "check_win81x64_ucrt";
Typ = "51";
Source = "InstMSUBinary";
- Target = "Windows81-KB2999226-x64msu";
+ Target = "25000|Windows81-KB2999226-x64msu";
Inbinarytable = 0;
Assignment1 = ("InstallExecuteSequence", "Not Installed And VersionNT = 603 And VersionNT64", "check_win8x64_ucrt");
Styles = "NO_FILE";
@@ -125,7 +128,7 @@ WindowsCustomAction gid_Customaction_check_win7x32_ucrt
Name = "check_win7x32_ucrt";
Typ = "51";
Source = "InstMSUBinary";
- Target = "Windows61-KB2999226-x86msu";
+ Target = "25000|Windows61-KB2999226-x86msu";
Inbinarytable = 0;
Assignment1 = ("InstallExecuteSequence", "Not Installed And VersionNT = 601 And Not VersionNT64", "check_win81x64_ucrt");
Styles = "NO_FILE";
@@ -135,7 +138,7 @@ WindowsCustomAction gid_Customaction_check_win8x32_ucrt
Name = "check_win8x32_ucrt";
Typ = "51";
Source = "InstMSUBinary";
- Target = "Windows8-RT-KB2999226-x86msu";
+ Target = "25000|Windows8-RT-KB2999226-x86msu";
Inbinarytable = 0;
Assignment1 = ("InstallExecuteSequence", "Not Installed And VersionNT = 602 And Not VersionNT64", "check_win7x32_ucrt");
Styles = "NO_FILE";
@@ -145,7 +148,7 @@ WindowsCustomAction gid_Customaction_check_win81x32_ucrt
Name = "check_win81x32_ucrt";
Typ = "51";
Source = "InstMSUBinary";
- Target = "Windows81-KB2999226-x86msu";
+ Target = "25000|Windows81-KB2999226-x86msu";
Inbinarytable = 0;
Assignment1 = ("InstallExecuteSequence", "Not Installed And VersionNT = 603 And Not VersionNT64", "check_win8x32_ucrt");
Styles = "NO_FILE";
diff --git a/setup_native/source/win32/customactions/inst_msu/inst_msu.cxx b/setup_native/source/win32/customactions/inst_msu/inst_msu.cxx
index 96fb88f4b889..5df2b26431d7 100644
--- a/setup_native/source/win32/customactions/inst_msu/inst_msu.cxx
+++ b/setup_native/source/win32/customactions/inst_msu/inst_msu.cxx
@@ -120,6 +120,17 @@ template <class... StrType> void WriteLog(MSIHANDLE hInst, const StrType&... ele
WriteLogElem(hInst, hRec, sTemplate, 1, elements...);
}
+void ShowWarning(MSIHANDLE hInst, const std::wstring& sErrNo, const char* sMessage)
+{
+ PMSIHANDLE hRec = MsiCreateRecord(2);
+ // To show a message from Error table, record's Field 0 must be null
+ MsiRecordSetStringW(hRec, 1, sErrNo.c_str());
+ std::string s("\n");
+ s += sMessage;
+ MsiRecordSetStringA(hRec, 2, s.c_str());
+ MsiProcessMessage(hInst, INSTALLMESSAGE_WARNING, hRec);
+}
+
typedef std::unique_ptr<void, decltype(&CloseHandle)> CloseHandleGuard;
CloseHandleGuard Guard(HANDLE h) { return CloseHandleGuard(h, CloseHandle); }
@@ -166,16 +177,6 @@ bool IsWow64Process()
#endif
}
-// An exception class to differentiate a non-fatal exception
-class nonfatal_exception : public std::exception
-{
-public:
- nonfatal_exception(const std::exception& e)
- : std::exception(e)
- {
- }
-};
-
// Checks if Windows Update service is disabled, and if it is, enables it temporarily.
class WUServiceEnabler
{
@@ -205,37 +206,27 @@ public:
private:
static CloseServiceHandleGuard EnableWUService(MSIHANDLE hInstall)
{
- try
- {
- auto hSCM = Guard(OpenSCManagerW(nullptr, nullptr, SC_MANAGER_ALL_ACCESS));
- if (!hSCM)
- ThrowLastError("OpenSCManagerW");
- WriteLog(hInstall, "Opened service control manager");
-
- auto hService = Guard(OpenServiceW(hSCM.get(), L"wuauserv",
- SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG
- | SERVICE_QUERY_STATUS | SERVICE_STOP));
- if (!hService)
- ThrowLastError("OpenServiceW");
- WriteLog(hInstall, "Obtained WU service handle");
-
- if (ServiceStatus(hInstall, hService.get()) == SERVICE_RUNNING
- || !EnsureServiceEnabled(hInstall, hService.get(), true))
- {
- // No need to restore anything back, since we didn't change config
- hService.reset();
- WriteLog(hInstall, "Service configuration is unchanged");
- }
-
- return hService;
- }
- catch (const std::exception& e)
+ auto hSCM = Guard(OpenSCManagerW(nullptr, nullptr, SC_MANAGER_ALL_ACCESS));
+ if (!hSCM)
+ ThrowLastError("OpenSCManagerW");
+ WriteLog(hInstall, "Opened service control manager");
+
+ auto hService = Guard(OpenServiceW(hSCM.get(), L"wuauserv",
+ SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG
+ | SERVICE_QUERY_STATUS | SERVICE_STOP));
+ if (!hService)
+ ThrowLastError("OpenServiceW");
+ WriteLog(hInstall, "Obtained WU service handle");
+
+ if (ServiceStatus(hInstall, hService.get()) == SERVICE_RUNNING
+ || !EnsureServiceEnabled(hInstall, hService.get(), true))
{
- // Allow errors opening service to be logged, but not interrupt installation.
- // They are likely to happen in situations where people hard-disable WU service,
- // and for these cases, let people deal with install logs instead of failing.
- throw nonfatal_exception(e);
+ // No need to restore anything back, since we didn't change config
+ hService.reset();
+ WriteLog(hInstall, "Service configuration is unchanged");
}
+
+ return hService;
}
// Returns if the service configuration was actually changed
@@ -354,11 +345,18 @@ extern "C" __declspec(dllexport) UINT __stdcall UnpackMSUForInstall(MSIHANDLE hI
WriteLog(hInstall, "started");
WriteLog(hInstall, "Checking value of InstMSUBinary");
- wchar_t sBinaryName[MAX_PATH + 1];
- DWORD nCCh = sizeof(sBinaryName) / sizeof(*sBinaryName);
+ wchar_t sInstMSUBinary[MAX_PATH + 10];
+ DWORD nCCh = sizeof(sInstMSUBinary) / sizeof(*sInstMSUBinary);
CheckWin32Error("MsiGetPropertyW",
- MsiGetPropertyW(hInstall, L"InstMSUBinary", sBinaryName, &nCCh));
- WriteLog(hInstall, "Got InstMSUBinary value:", sBinaryName);
+ MsiGetPropertyW(hInstall, L"InstMSUBinary", sInstMSUBinary, &nCCh));
+ WriteLog(hInstall,
+ "Got InstMSUBinary value:", sInstMSUBinary); // 123|Windows61-KB2999226-x64msu
+ const wchar_t* sBinaryName = wcschr(sInstMSUBinary, L'|');
+ if (!sBinaryName)
+ throw std::exception("No error code in InstMSUBinary!");
+ // "123" - # of the message in Error table to be shown on failure
+ const std::wstring sErrNo(sInstMSUBinary, sBinaryName - sInstMSUBinary);
+ ++sBinaryName;
PMSIHANDLE hDatabase = MsiGetActiveDatabase(hInstall);
if (!hDatabase)
@@ -415,8 +413,9 @@ extern "C" __declspec(dllexport) UINT __stdcall UnpackMSUForInstall(MSIHANDLE hI
WriteLog(hInstall, "Successfully wrote", Num2Dec(nTotal), "bytes");
}
-
- CheckWin32Error("MsiSetPropertyW", MsiSetPropertyW(hInstall, L"inst_msu", sBinary.c_str()));
+ const std::wstring s_inst_msu = sErrNo + L"|" + sBinary;
+ CheckWin32Error("MsiSetPropertyW",
+ MsiSetPropertyW(hInstall, L"inst_msu", s_inst_msu.c_str()));
// Don't delete the file: it will be done by following actions (inst_msu or cleanup_msu)
(void)aDeleteFileGuard.release();
@@ -433,17 +432,23 @@ extern "C" __declspec(dllexport) UINT __stdcall UnpackMSUForInstall(MSIHANDLE hI
// "CustomActionData" property, and runs wusa.exe to install it. Waits for it and checks exit code.
extern "C" __declspec(dllexport) UINT __stdcall InstallMSU(MSIHANDLE hInstall)
{
+ std::wstring sErrNo; // "123" - # of the message in Error table to be shown on failure
try
{
sLogPrefix = "InstallMSU:";
WriteLog(hInstall, "started");
WriteLog(hInstall, "Checking value of CustomActionData");
- wchar_t sBinaryName[MAX_PATH + 1];
- DWORD nCCh = sizeof(sBinaryName) / sizeof(*sBinaryName);
+ wchar_t sCustomActionData[MAX_PATH + 10]; // "123|C:\Temp\binary.tmp"
+ DWORD nCCh = sizeof(sCustomActionData) / sizeof(*sCustomActionData);
CheckWin32Error("MsiGetPropertyW",
- MsiGetPropertyW(hInstall, L"CustomActionData", sBinaryName, &nCCh));
- WriteLog(hInstall, "Got CustomActionData value:", sBinaryName);
+ MsiGetPropertyW(hInstall, L"CustomActionData", sCustomActionData, &nCCh));
+ WriteLog(hInstall, "Got CustomActionData value:", sCustomActionData);
+ const wchar_t* sBinaryName = wcschr(sCustomActionData, L'|');
+ if (!sBinaryName)
+ throw std::exception("No error code in CustomActionData!");
+ sErrNo = std::wstring(sCustomActionData, sBinaryName - sCustomActionData);
+ ++sBinaryName;
auto aDeleteFileGuard(Guard(sBinaryName));
// In case the Windows Update service is disabled, we temporarily enable it here
@@ -496,19 +501,12 @@ extern "C" __declspec(dllexport) UINT __stdcall InstallMSU(MSIHANDLE hInstall)
ThrowWin32Error("Execution of wusa.exe", nExitCode);
}
}
- catch (nonfatal_exception& e)
- {
- // An error that should not interrupt installation
- WriteLog(hInstall, e.what());
- WriteLog(hInstall, "Installation of MSU package failed, but installation of product will "
- "continue. You may need to install the required update manually");
- return ERROR_SUCCESS;
- }
catch (std::exception& e)
{
WriteLog(hInstall, e.what());
+ ShowWarning(hInstall, sErrNo, e.what());
}
- return ERROR_INSTALL_FAILURE;
+ return ERROR_SUCCESS; // Do not break on MSU installation errors
}
// Rollback deferred action "cleanup_msu" that is executed on error or cancel.