From e048f71ecbb103ae7c1876092cb8244b24a73cb7 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Tue, 28 Nov 2023 09:19:16 +0100 Subject: [PATCH] msiexec: No longer use console/file output APIs. Regular GUI apps don't. Signed-off-by: Eric Pouech --- programs/msiexec/msiexec.c | 55 +++++++++++++++++++---------- programs/msiexec/msiexec_internal.h | 27 ++++++++++++++ programs/msiexec/service.c | 14 ++++---- 3 files changed, 70 insertions(+), 26 deletions(-) create mode 100644 programs/msiexec/msiexec_internal.h diff --git a/programs/msiexec/msiexec.c b/programs/msiexec/msiexec.c index 4770dfe4a02..68b7c938097 100644 --- a/programs/msiexec/msiexec.c +++ b/programs/msiexec/msiexec.c @@ -26,9 +26,9 @@ #include #include #include -#include #include "wine/debug.h" +#include "msiexec_internal.h" #include "initguid.h" DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); @@ -39,6 +39,7 @@ typedef HRESULT (WINAPI *DLLREGISTERSERVER)(void); typedef HRESULT (WINAPI *DLLUNREGISTERSERVER)(void); DWORD DoService(void); +static BOOL silent; struct string_list { @@ -46,6 +47,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 +285,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 +311,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 +331,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 +348,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 +361,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 +375,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); @@ -765,7 +781,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 +831,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 +963,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 +982,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 +1019,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..258ee5a106c --- /dev/null +++ b/programs/msiexec/msiexec_internal.h @@ -0,0 +1,27 @@ +/* + * msiexec.exe internal definitions + * + * Copyright 2023 Eric Pouech for CodeWeavers + * + * 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 + */ + +#include + +#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..ee81da1bfcd 100644 --- a/programs/msiexec/service.c +++ b/programs/msiexec/service.c @@ -20,11 +20,11 @@ #define WIN32_LEAN_AND_MEAN -#include #include #include #include "wine/debug.h" +#include "msiexec_internal.h" WINE_DEFAULT_DEBUG_CHANNEL(msiexec); @@ -73,7 +73,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 +93,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 +113,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 +125,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 +134,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 +166,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; }