Regular GUI apps don't.
Signed-off-by: Eric Pouech epouech@codeweavers.com
From: Eric Pouech epouech@codeweavers.com
Regular GUI apps don't.
Signed-off-by: Eric Pouech epouech@codeweavers.com --- programs/msiexec/msiexec.c | 60 ++++++++++++++++++----------- programs/msiexec/msiexec_internal.h | 28 ++++++++++++++ programs/msiexec/service.c | 18 ++++----- 3 files changed, 72 insertions(+), 34 deletions(-) create mode 100644 programs/msiexec/msiexec_internal.h
diff --git a/programs/msiexec/msiexec.c b/programs/msiexec/msiexec.c index 4770dfe4a02..74236c16af2 100644 --- a/programs/msiexec/msiexec.c +++ b/programs/msiexec/msiexec.c @@ -19,14 +19,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#define WIN32_LEAN_AND_MEAN +#include "msiexec_internal.h"
-#include <windows.h> #include <commctrl.h> #include <msi.h> -#include <winsvc.h> #include <objbase.h> -#include <stdio.h>
#include "wine/debug.h"
@@ -39,6 +36,7 @@ typedef HRESULT (WINAPI *DLLREGISTERSERVER)(void); typedef HRESULT (WINAPI *DLLUNREGISTERSERVER)(void);
DWORD DoService(void); +static BOOL silent;
struct string_list { @@ -46,6 +44,21 @@ struct string_list WCHAR str[1]; };
+void report_error(const char* msg, ...) +{ + char buffer[2048]; + va_list va_args; + + va_start(va_args, msg); + vsnprintf(buffer, sizeof(buffer), msg, va_args); + va_end(va_args); + + if (silent) + MESSAGE("%s", buffer); + else + MsiMessageBoxA(NULL, buffer, "MsiExec", 0, GetUserDefaultLangID(), 0); +} + static void ShowUsage(int ExitCode) { WCHAR msiexec_version[40]; @@ -269,14 +282,14 @@ static VOID *LoadProc(LPCWSTR DllName, LPCSTR ProcName, HMODULE* DllHandle) *DllHandle = LoadLibraryExW(DllName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if(!*DllHandle) { - fprintf(stderr, "Unable to load dll %s\n", wine_dbgstr_w(DllName)); + report_error("Unable to load dll %s\n", wine_dbgstr_w(DllName)); ExitProcess(1); } proc = (VOID *) GetProcAddress(*DllHandle, ProcName); if(!proc) { - fprintf(stderr, "Dll %s does not implement function %s\n", - wine_dbgstr_w(DllName), ProcName); + report_error("Dll %s does not implement function %s\n", + wine_dbgstr_w(DllName), ProcName); FreeLibrary(*DllHandle); ExitProcess(1); } @@ -295,10 +308,10 @@ static DWORD DoDllRegisterServer(LPCWSTR DllName) hr = pfDllRegisterServer(); if(FAILED(hr)) { - fprintf(stderr, "Failed to register dll %s\n", wine_dbgstr_w(DllName)); + report_error("Failed to register dll %s\n", wine_dbgstr_w(DllName)); return 1; } - printf("Successfully registered dll %s\n", wine_dbgstr_w(DllName)); + MESSAGE("Successfully registered dll %s\n", wine_dbgstr_w(DllName)); if(DllHandle) FreeLibrary(DllHandle); return 0; @@ -315,10 +328,10 @@ static DWORD DoDllUnregisterServer(LPCWSTR DllName) hr = pfDllUnregisterServer(); if(FAILED(hr)) { - fprintf(stderr, "Failed to unregister dll %s\n", wine_dbgstr_w(DllName)); + report_error("Failed to unregister dll %s\n", wine_dbgstr_w(DllName)); return 1; } - printf("Successfully unregistered dll %s\n", wine_dbgstr_w(DllName)); + MESSAGE("Successfully unregistered dll %s\n", wine_dbgstr_w(DllName)); if(DllHandle) FreeLibrary(DllHandle); return 0; @@ -332,7 +345,7 @@ static DWORD DoRegServer(void)
if (!(scm = OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASEW, SC_MANAGER_CREATE_SERVICE))) { - fprintf(stderr, "Failed to open the service control manager.\n"); + report_error("Failed to open the service control manager.\n"); return 1; } len = GetSystemDirectoryW(path, MAX_PATH); @@ -345,7 +358,7 @@ static DWORD DoRegServer(void) } else if (GetLastError() != ERROR_SERVICE_EXISTS) { - fprintf(stderr, "Failed to create MSI service\n"); + report_error("Failed to create MSI service\n"); ret = 1; } CloseServiceHandle(scm); @@ -359,21 +372,21 @@ static DWORD DoUnregServer(void)
if (!(scm = OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASEW, SC_MANAGER_CONNECT))) { - fprintf(stderr, "Failed to open service control manager\n"); + report_error("Failed to open service control manager\n"); return 1; } if ((service = OpenServiceW(scm, L"MSIServer", DELETE))) { if (!DeleteService(service)) { - fprintf(stderr, "Failed to delete MSI service\n"); + report_error("Failed to delete MSI service\n"); ret = 1; } CloseServiceHandle(service); } else if (GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST) { - fprintf(stderr, "Failed to open MSI service\n"); + report_error("Failed to open MSI service\n"); ret = 1; } CloseServiceHandle(scm); @@ -676,7 +689,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine { WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
- if (msi_option_equal(argvW[i], "regserver")) + if (msi_option_equal(argvW[i], "regserver")) { FunctionRegServer = TRUE; } @@ -765,7 +778,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine RepairMode |= REINSTALLMODE_PACKAGE; break; default: - fprintf(stderr, "Unknown option "%c" in Repair mode\n", argvW[i][j]); + report_error("Unknown option "%c" in Repair mode\n", argvW[i][j]); break; } } @@ -815,7 +828,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine AdvertiseMode = ADVERTISEFLAGS_MACHINEASSIGN; break; default: - fprintf(stderr, "Unknown option "%c" in Advertise mode\n", argvW[i][j]); + report_error("Unknown option "%c" in Advertise mode\n", argvW[i][j]); break; } } @@ -947,8 +960,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine LogFileName = argvW[i]; if(MsiEnableLogW(LogMode, LogFileName, LogAttributes) != ERROR_SUCCESS) { - fprintf(stderr, "Logging in %s (0x%08lx, %lu) failed\n", - wine_dbgstr_w(LogFileName), LogMode, LogAttributes); + report_error("Logging in %s (0x%08lx, %lu) failed\n", + wine_dbgstr_w(LogFileName), LogMode, LogAttributes); ExitProcess(1); } } @@ -966,6 +979,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine if(lstrlenW(argvW[i]) == 2 || msi_strequal(argvW[i]+2, "n") || msi_strequal(argvW[i] + 2, "uiet")) { + silent = TRUE; InstallUILevel = INSTALLUILEVEL_NONE; } else if(msi_strequal(argvW[i]+2, "r")) @@ -1002,8 +1016,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine } else { - fprintf(stderr, "Unknown option "%s" for UI level\n", - wine_dbgstr_w(argvW[i]+2)); + report_error("Unknown option "%s" for UI level\n", + wine_dbgstr_w(argvW[i]+2)); } } else if(msi_option_equal(argvW[i], "passive")) diff --git a/programs/msiexec/msiexec_internal.h b/programs/msiexec/msiexec_internal.h new file mode 100644 index 00000000000..9b3fc7a42f0 --- /dev/null +++ b/programs/msiexec/msiexec_internal.h @@ -0,0 +1,28 @@ +/* + * msiexec.exe implementation + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define WIN32_LEAN_AND_MEAN + +#include <windows.h> +#include <winsvc.h> + +#ifdef __WINE_CRT_PRINTF_ATTR +extern void report_error(const char* msg, ...) __WINE_CRT_PRINTF_ATTR(1, 2); +#else +extern void report_error(const char* msg, ...); +#endif diff --git a/programs/msiexec/service.c b/programs/msiexec/service.c index 573b3782473..f7c657880f2 100644 --- a/programs/msiexec/service.c +++ b/programs/msiexec/service.c @@ -18,11 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#define WIN32_LEAN_AND_MEAN - -#include <stdio.h> -#include <windows.h> -#include <winsvc.h> +#include "msiexec_internal.h"
#include "wine/debug.h"
@@ -73,7 +69,7 @@ static BOOL UpdateSCMStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
if (!SetServiceStatus(hstatus, &status)) { - fprintf(stderr, "Failed to set service status\n"); + report_error("Failed to set service status\n"); KillService(); return FALSE; } @@ -93,7 +89,7 @@ static void WINAPI ServiceCtrlHandler(DWORD code) KillService(); break; default: - fprintf(stderr, "Unhandled service control code: %ld\n", code); + report_error("Unhandled service control code: %ld\n", code); UpdateSCMStatus(SERVICE_RUNNING, NO_ERROR, 0); break; } @@ -113,7 +109,7 @@ static BOOL StartServiceThread(void) thread = CreateThread(0, 0, ServiceExecutionThread, 0, 0, &id); if (!thread) { - fprintf(stderr, "Failed to create thread\n"); + report_error("Failed to create thread\n"); return FALSE; }
@@ -125,7 +121,7 @@ static void WINAPI ServiceMain(DWORD argc, LPSTR *argv) hstatus = RegisterServiceCtrlHandlerA("MSIServer", ServiceCtrlHandler); if (!hstatus) { - fprintf(stderr, "Failed to register service ctrl handler\n"); + report_error("Failed to register service ctrl handler\n"); return; }
@@ -134,7 +130,7 @@ static void WINAPI ServiceMain(DWORD argc, LPSTR *argv) kill_event = CreateEventW(0, TRUE, FALSE, 0); if (!kill_event) { - fprintf(stderr, "Failed to create event\n"); + report_error("Failed to create event\n"); KillService(); UpdateSCMStatus(SERVICE_STOPPED, NO_ERROR, 0); return; @@ -166,7 +162,7 @@ DWORD DoService(void)
if (!StartServiceCtrlDispatcherA(service)) { - fprintf(stderr, "Failed to start MSIServer service\n"); + report_error("Failed to start MSIServer service\n"); return 1; }
@hans would you mind having a look at this MR. It changes error output of msiexec.exe (when /qn option is not passed) to use message boxes (as native does). (Note I've used the Msi message boxes).
msi and appwiz.cpl DLLs invoke msiexec.exe for performinng some tasks. Some call sites set option /qn to not have GUI output, but I'm not sure all that should actually do.
Hans Leidekker (@hans) commented about programs/msiexec/msiexec.c:
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#define WIN32_LEAN_AND_MEAN +#include "msiexec_internal.h"
-#include <windows.h> #include <commctrl.h> #include <msi.h> -#include <winsvc.h> #include <objbase.h> -#include <stdio.h>
Please keep the includes here (except for stdio.h) and include msiexec_internal.h last. Same for service.c.
Hans Leidekker (@hans) commented about programs/msiexec/msiexec.c:
{ WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
if (msi_option_equal(argvW[i], "regserver"))
if (msi_option_equal(argvW[i], "regserver"))
Accidental whitespace change?
uninstaller and appwiz don't pass /qn which seems fine.