ReactOS 0.4.17-dev-966-gf06eace
msiexec.c File Reference
#include <windows.h>
#include <commctrl.h>
#include <msi.h>
#include <winsvc.h>
#include <objbase.h>
#include "wine/debug.h"
#include "msiexec_internal.h"
#include "initguid.h"
Include dependency graph for msiexec.c:

Go to the source code of this file.

Classes

struct  string_list
 

Macros

#define WIN32_LEAN_AND_MEAN
 

Typedefs

typedef HRESULT(WINAPI * DLLREGISTERSERVER) (void)
 
typedef HRESULT(WINAPI * DLLUNREGISTERSERVER) (void)
 

Enumerations

enum  chomp_state { CS_WHITESPACE , CS_TOKEN , CS_QUOTE }
 

Functions

 DEFINE_GUID (GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
 
 WINE_DEFAULT_DEBUG_CHANNEL (msiexec)
 
DWORD DoService (void)
 
void report_error (const char *msg,...)
 
static void ShowUsage (int ExitCode)
 
static BOOL IsProductCode (LPWSTR str)
 
static VOID StringListAppend (struct string_list **list, LPCWSTR str)
 
static LPWSTR build_properties (struct string_list *property_list)
 
static LPWSTR build_transforms (struct string_list *transform_list)
 
static DWORD msi_atou (LPCWSTR str)
 
static BOOL msi_strequal (LPCWSTR str1, LPCSTR str2)
 
static BOOL msi_option_equal (LPCWSTR str1, LPCSTR str2)
 
static BOOL msi_strprefix (LPCWSTR str1, LPCSTR str2)
 
static BOOL msi_option_prefix (LPCWSTR str1, LPCSTR str2)
 
static VOID * LoadProc (LPCWSTR DllName, LPCSTR ProcName, HMODULE *DllHandle)
 
static DWORD DoDllRegisterServer (LPCWSTR DllName)
 
static DWORD DoDllUnregisterServer (LPCWSTR DllName)
 
static DWORD DoRegServer (void)
 
static DWORD DoUnregServer (void)
 
UINT CDECL __wine_msi_call_dll_function (DWORD client_pid, const GUID *guid)
 
static DWORD CALLBACK custom_action_thread (void *arg)
 
static int custom_action_server (const WCHAR *arg)
 
static int chomp (const WCHAR *in, WCHAR *out)
 
static void process_args (WCHAR *cmdline, int *pargc, WCHAR ***pargv)
 
static BOOL process_args_from_reg (const WCHAR *ident, int *pargc, WCHAR ***pargv)
 
static WCHAR * get_path_with_extension (const WCHAR *package_name)
 
static WCHAR * remove_quotes (const WCHAR *filename)
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
 

Variables

static BOOL silent
 
static DWORD client_pid
 

Macro Definition Documentation

◆ WIN32_LEAN_AND_MEAN

#define WIN32_LEAN_AND_MEAN

Definition at line 22 of file msiexec.c.

Typedef Documentation

◆ DLLREGISTERSERVER

typedef HRESULT(WINAPI * DLLREGISTERSERVER) (void)

Definition at line 38 of file msiexec.c.

◆ DLLUNREGISTERSERVER

typedef HRESULT(WINAPI * DLLUNREGISTERSERVER) (void)

Definition at line 39 of file msiexec.c.

Enumeration Type Documentation

◆ chomp_state

Enumerator
CS_WHITESPACE 
CS_TOKEN 
CS_QUOTE 

Definition at line 474 of file msiexec.c.

475{
477 CS_TOKEN,
479};
@ CS_TOKEN
Definition: msiexec.c:477
@ CS_WHITESPACE
Definition: msiexec.c:476
@ CS_QUOTE
Definition: msiexec.c:478

Function Documentation

◆ __wine_msi_call_dll_function()

UINT CDECL __wine_msi_call_dll_function ( DWORD  client_pid,
const GUID *  guid 
)

Definition at line 507 of file custom.c.

508{
510 MSIHANDLE remote_package = 0;
511 RPC_WSTR binding_str;
512 MSIHANDLE hPackage;
514 WCHAR *dll = NULL, *action = NULL;
515 LPSTR proc = NULL;
517 INT type;
518 UINT r;
519
520 TRACE("%s\n", debugstr_guid( guid ));
521
522 if (!rpc_handle)
523 {
524 WCHAR endpoint[12];
525
527 status = RpcStringBindingComposeW(NULL, (WCHAR *)L"ncalrpc", NULL, endpoint, NULL, &binding_str);
528 if (status != RPC_S_OK)
529 {
530 ERR("RpcStringBindingCompose failed: %#lx\n", status);
531 return status;
532 }
533 status = RpcBindingFromStringBindingW(binding_str, &rpc_handle);
534 if (status != RPC_S_OK)
535 {
536 ERR("RpcBindingFromStringBinding failed: %#lx\n", status);
537 return status;
538 }
539 RpcStringFreeW(&binding_str);
540 }
541
542 r = remote_GetActionInfo(guid, &action, &type, &dll, &proc, &remote_package);
543 if (r != ERROR_SUCCESS)
544 return r;
545
546 hPackage = alloc_msi_remote_handle( remote_package );
547 if (!hPackage)
548 {
549 ERR( "failed to create handle for %#lx\n", remote_package );
551 midl_user_free( dll );
554 }
555
556 hModule = LoadLibraryW( dll );
557 if (!hModule)
558 {
559 ERR( "failed to load dll %s (%lu)\n", debugstr_w( dll ), GetLastError() );
561 midl_user_free( dll );
563 MsiCloseHandle( hPackage );
564 return ERROR_SUCCESS;
565 }
566
568 if (!fn) WARN( "GetProcAddress(%s) failed\n", debugstr_a(proc) );
569 else
570 {
572
573 __TRY
574 {
575 r = custom_proc_wrapper( fn, hPackage );
576 }
578 {
579 ERR( "Custom action (%s:%s) caused a page fault: %#lx\n",
582 }
583 __ENDTRY;
584 }
585
587
589 midl_user_free(dll);
591
593 return r;
594}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
HMODULE hModule
Definition: animate.c:44
#define GetProcAddress(x, y)
Definition: compat.h:753
#define __TRY
Definition: compat.h:80
#define FreeLibrary(x)
Definition: compat.h:748
#define __ENDTRY
Definition: compat.h:82
#define LoadLibraryW(x)
Definition: compat.h:747
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:81
GUID guid
Definition: version.c:147
static void handle_msi_break(const WCHAR *action)
Definition: custom.c:458
UINT(WINAPI * MsiCustomActionEntryPoint)(MSIHANDLE)
Definition: custom.c:60
static UINT custom_proc_wrapper(MsiCustomActionEntryPoint entry, MSIHANDLE hinst)
Definition: custom.c:501
UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
Definition: handle.c:269
MSIHANDLE alloc_msi_remote_handle(MSIHANDLE remote)
Definition: handle.c:135
UINT WINAPI MsiCloseAllHandles(void)
Definition: handle.c:325
#define swprintf
Definition: precomp.h:40
action
Definition: namespace.c:707
#define L(x)
Definition: resources.c:13
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
unsigned int UINT
Definition: sysinfo.c:13
#define GetExceptionCode
Definition: excpt.h:83
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
static DWORD client_pid
Definition: msiexec.c:401
static HANDLE proc()
Definition: pdb.c:32
short WCHAR
Definition: pedump.c:58
RPC_STATUS WINAPI RpcBindingFromStringBindingW(RPC_WSTR StringBinding, RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:862
RPC_STATUS WINAPI RpcStringBindingComposeW(RPC_WSTR ObjUuid, RPC_WSTR Protseq, RPC_WSTR NetworkAddr, RPC_WSTR Endpoint, RPC_WSTR Options, RPC_WSTR *StringBinding)
Definition: rpc_binding.c:493
unsigned short * RPC_WSTR
Definition: rpcdce.h:46
#define RPC_S_OK
Definition: rpcnterr.h:22
RPC_STATUS WINAPI RpcStringFreeW(RPC_WSTR *String)
Definition: rpcrt4_main.c:181
#define midl_user_free
Definition: rpc.h:41
long RPC_STATUS
Definition: rpc.h:48
#define TRACE(s)
Definition: solgame.cpp:4
Definition: nis.h:10
Definition: ps.c:97
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
unsigned long MSIHANDLE
Definition: winemsi.idl:27
#define ERROR_INSTALL_FAILURE
Definition: winerror.h:1309

Referenced by custom_action_thread().

◆ build_properties()

static LPWSTR build_properties ( struct string_list *  property_list)
static

Definition at line 137 of file msiexec.c.

138{
139 struct string_list *list;
140 LPWSTR ret, p, value;
141 DWORD len;
142 BOOL needs_quote;
143
144 if(!property_list)
145 return NULL;
146
147 /* count the space we need */
148 len = 1;
149 for(list = property_list; list; list = list->next)
150 len += lstrlenW(list->str) + 3;
151
152 ret = malloc(len * sizeof(WCHAR));
153
154 /* add a space before each string, and quote the value */
155 p = ret;
156 for(list = property_list; list; list = list->next)
157 {
158 value = wcschr(list->str,'=');
159 if(!value)
160 continue;
161 len = value - list->str;
162 *p++ = ' ';
163 memcpy(p, list->str, len * sizeof(WCHAR));
164 p += len;
165 *p++ = '=';
166
167 /* check if the value contains spaces and maybe quote it */
168 value++;
169 needs_quote = *value != '"' && wcschr(value, ' ');
170 if(needs_quote)
171 *p++ = '"';
172 len = lstrlenW(value);
173 memcpy(p, value, len * sizeof(WCHAR));
174 p += len;
175 if(needs_quote)
176 *p++ = '"';
177 }
178 *p = 0;
179
180 WINE_TRACE("properties -> %s\n", wine_dbgstr_w(ret) );
181
182 return ret;
183}
Definition: list.h:39
struct list * next
Definition: list.h:40
#define malloc
Definition: debug_ros.c:4
#define wcschr
Definition: compat.h:17
#define lstrlenW
Definition: compat.h:750
return ret
Definition: mutex.c:147
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
#define wine_dbgstr_w
Definition: kernel32.h:34
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define list
Definition: rosglue.h:35
#define WINE_TRACE
Definition: debug.h:357
uint16_t * LPWSTR
Definition: typedefs.h:56
Definition: pdh_main.c:64

Referenced by WinMain().

◆ build_transforms()

static LPWSTR build_transforms ( struct string_list *  transform_list)
static

Definition at line 185 of file msiexec.c.

186{
187 struct string_list *list;
188 LPWSTR ret, p;
189 DWORD len;
190
191 /* count the space we need */
192 len = 1;
193 for(list = transform_list; list; list = list->next)
194 len += lstrlenW(list->str) + 1;
195
196 ret = malloc(len * sizeof(WCHAR));
197
198 /* add all the transforms with a semicolon between each one */
199 p = ret;
200 for(list = transform_list; list; list = list->next)
201 {
202 len = lstrlenW(list->str);
203 lstrcpynW(p, list->str, len );
204 p += len;
205 if(list->next)
206 *p++ = ';';
207 }
208 *p = 0;
209
210 return ret;
211}
#define lstrcpynW
Definition: compat.h:738

Referenced by WinMain().

◆ chomp()

static int chomp ( const WCHAR *  in,
WCHAR *  out 
)
static

Definition at line 481 of file msiexec.c.

482{
484 const WCHAR *p;
485 int count = 1;
486 BOOL ignore;
487
488 for (p = in; *p; p++)
489 {
490 ignore = TRUE;
491 switch (state)
492 {
493 case CS_WHITESPACE:
494 switch (*p)
495 {
496 case ' ':
497 break;
498 case '"':
499 state = CS_QUOTE;
500 count++;
501 ignore = FALSE;
502 break;
503 default:
504 count++;
505 ignore = FALSE;
506 state = CS_TOKEN;
507 }
508 break;
509
510 case CS_TOKEN:
511 switch (*p)
512 {
513 case '"':
514 state = CS_QUOTE;
515 ignore = FALSE;
516 break;
517 case ' ':
519 if (out) *out++ = 0;
520 break;
521 default:
522 if (p > in && p[-1] == '"')
523 {
524 if (out) *out++ = 0;
525 count++;
526 }
527 ignore = FALSE;
528 }
529 break;
530
531 case CS_QUOTE:
532 switch (*p)
533 {
534 case '"':
535 state = CS_TOKEN;
536 ignore = FALSE;
537 break;
538 default:
539 ignore = FALSE;
540 }
541 break;
542 }
543 if (!ignore && out) *out++ = *p;
544 }
545 if (out) *out = 0;
546 return count;
547}
static int state
Definition: maze.c:121
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint in
Definition: glext.h:9616
chomp_state
Definition: msiexec.c:475
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

Referenced by process_args().

◆ custom_action_server()

static int custom_action_server ( const WCHAR *  arg)
static

Definition at line 410 of file msiexec.c.

411{
412 GUID guid, *thread_guid;
413 DWORD64 thread64;
414 WCHAR buffer[24];
416 HANDLE pipe;
417 DWORD size;
418
419 TRACE("%s\n", debugstr_w(arg));
420
421 if (!(client_pid = wcstol(arg, NULL, 10)))
422 {
423 ERR("Invalid parameter %s\n", debugstr_w(arg));
424 return 1;
425 }
426
427#ifdef __REACTOS__
428 swprintf(buffer, ARRAY_SIZE(buffer), L"\\\\.\\pipe\\msica_%x_%d", client_pid, (int)(sizeof(void *) * 8));
429#else
430 swprintf(buffer, ARRAY_SIZE(buffer), L"\\\\.\\pipe\\msica_%x_%d", client_pid, sizeof(void *) * 8);
431#endif
433 if (pipe == INVALID_HANDLE_VALUE)
434 {
435 ERR("Failed to create custom action server pipe: %lu\n", GetLastError());
436 return GetLastError();
437 }
438
439 /* We need this to unmarshal streams, and some apps expect it to be present. */
441
442 while (ReadFile(pipe, &guid, sizeof(guid), &size, NULL) && size == sizeof(guid))
443 {
444 if (IsEqualGUID(&guid, &GUID_NULL))
445 {
446 /* package closed; time to shut down */
448 return 0;
449 }
450
451 thread_guid = malloc(sizeof(GUID));
452 memcpy(thread_guid, &guid, sizeof(GUID));
453 thread = CreateThread(NULL, 0, custom_action_thread, thread_guid, 0, NULL);
454
455 /* give the thread handle to the client to wait on, since we might have
456 * to run a nested action and can't block during this one */
457 thread64 = (DWORD_PTR)thread;
458 if (!WriteFile(pipe, &thread64, sizeof(thread64), &size, NULL) || size != sizeof(thread64))
459 {
460 ERR("Failed to write to custom action server pipe: %lu\n", GetLastError());
462 return GetLastError();
463 }
464 }
465 ERR("Failed to read from custom action server pipe: %lu\n", GetLastError());
467 return GetLastError();
468}
static HANDLE thread
Definition: service.c:33
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(void *reserved, DWORD model)
Definition: combase.c:2803
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define CreateFileW
Definition: compat.h:741
BOOL WINAPI WriteFile(_In_ HANDLE hFile, _In_reads_bytes_opt_(nNumberOfBytesToWrite) LPCVOID lpBuffer, _In_ DWORD nNumberOfBytesToWrite, _Out_opt_ LPDWORD lpNumberOfBytesWritten, _Inout_opt_ LPOVERLAPPED lpOverlapped)
Definition: rw.c:25
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
_ACRTIMP __msvcrt_long __cdecl wcstol(const wchar_t *, wchar_t **, int)
Definition: wcs.c:2752
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
#define GUID_NULL
Definition: ks.h:106
static DWORD CALLBACK custom_action_thread(void *arg)
Definition: msiexec.c:403
#define GENERIC_WRITE
Definition: nt_native.h:90
@ COINIT_MULTITHREADED
Definition: objbase.h:280
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define DWORD_PTR
Definition: treelist.c:76
uint64_t DWORD64
Definition: typedefs.h:67

Referenced by WinMain().

◆ custom_action_thread()

static DWORD CALLBACK custom_action_thread ( void *  arg)
static

Definition at line 403 of file msiexec.c.

404{
405 GUID guid = *(GUID *)arg;
406 free(arg);
408}
#define free
Definition: debug_ros.c:5
UINT CDECL __wine_msi_call_dll_function(DWORD client_pid, const GUID *guid)
Definition: custom.c:507

Referenced by custom_action_server().

◆ DEFINE_GUID()

DEFINE_GUID ( GUID_NULL  ,
0  ,
0  ,
0  ,
0  ,
0  ,
0  ,
0  ,
0  ,
0  ,
0  ,
0   
)

◆ DoDllRegisterServer()

static DWORD DoDllRegisterServer ( LPCWSTR  DllName)
static

Definition at line 303 of file msiexec.c.

304{
305 HRESULT hr;
306 DLLREGISTERSERVER pfDllRegisterServer = NULL;
307 HMODULE DllHandle = NULL;
308
309 pfDllRegisterServer = LoadProc(DllName, "DllRegisterServer", &DllHandle);
310
311 hr = pfDllRegisterServer();
312 if(FAILED(hr))
313 {
314 report_error("Failed to register dll %s\n", wine_dbgstr_w(DllName));
315 return 1;
316 }
317 MESSAGE("Successfully registered dll %s\n", wine_dbgstr_w(DllName));
318 if(DllHandle)
319 FreeLibrary(DllHandle);
320 return 0;
321}
HRESULT hr
Definition: delayimp.cpp:582
#define FAILED(hr)
Definition: intsafe.h:51
#define MESSAGE
Definition: options.h:86
void report_error(const char *msg,...)
Definition: msiexec.c:50
static VOID * LoadProc(LPCWSTR DllName, LPCSTR ProcName, HMODULE *DllHandle)
Definition: msiexec.c:281
HRESULT(WINAPI * DLLREGISTERSERVER)(void)
Definition: msiexec.c:38

Referenced by WinMain().

◆ DoDllUnregisterServer()

static DWORD DoDllUnregisterServer ( LPCWSTR  DllName)
static

Definition at line 323 of file msiexec.c.

324{
325 HRESULT hr;
326 DLLUNREGISTERSERVER pfDllUnregisterServer = NULL;
327 HMODULE DllHandle = NULL;
328
329 pfDllUnregisterServer = LoadProc(DllName, "DllUnregisterServer", &DllHandle);
330
331 hr = pfDllUnregisterServer();
332 if(FAILED(hr))
333 {
334 report_error("Failed to unregister dll %s\n", wine_dbgstr_w(DllName));
335 return 1;
336 }
337 MESSAGE("Successfully unregistered dll %s\n", wine_dbgstr_w(DllName));
338 if(DllHandle)
339 FreeLibrary(DllHandle);
340 return 0;
341}
HRESULT(WINAPI * DLLUNREGISTERSERVER)(void)
Definition: msiexec.c:39

Referenced by WinMain().

◆ DoRegServer()

static DWORD DoRegServer ( void  )
static

Definition at line 343 of file msiexec.c.

344{
345 SC_HANDLE scm, service;
346 WCHAR path[MAX_PATH+12];
347 DWORD len, ret = 0;
348
350 {
351 report_error("Failed to open the service control manager.\n");
352 return 1;
353 }
355 lstrcpyW(path + len, L"\\msiexec /V");
356 if ((service = CreateServiceW(scm, L"MSIServer", L"MSIServer", GENERIC_ALL,
359 {
360 CloseServiceHandle(service);
361 }
363 {
364 report_error("Failed to create MSI service\n");
365 ret = 1;
366 }
368 return ret;
369}
#define MAX_PATH
Definition: compat.h:34
#define lstrcpyW
Definition: compat.h:749
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2331
#define GENERIC_ALL
Definition: nt_native.h:92
#define SC_MANAGER_CREATE_SERVICE
Definition: winsvc.h:15
#define SERVICES_ACTIVE_DATABASEW
Definition: winsvc.h:8
SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:2107
SC_HANDLE WINAPI CreateServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, LPCWSTR lpDisplayName, DWORD dwDesiredAccess, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCWSTR lpBinaryPathName, LPCWSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCWSTR lpDependencies, LPCWSTR lpServiceStartName, LPCWSTR lpPassword)
Definition: scm.c:812
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:580
#define ERROR_SERVICE_EXISTS
Definition: winerror.h:948
#define SERVICE_DEMAND_START
Definition: cmtypes.h:979
#define SERVICE_WIN32_SHARE_PROCESS
Definition: cmtypes.h:964
#define SERVICE_ERROR_NORMAL
Definition: cmtypes.h:983

Referenced by WinMain().

◆ DoService()

DWORD DoService ( void  )

Definition at line 155 of file service.c.

156{
157 char service_name[] = "MSIServer";
158
159 const SERVICE_TABLE_ENTRYA service[] =
160 {
162 {NULL, NULL},
163 };
164
165 WINE_TRACE("Starting MSIServer service\n");
166
167 if (!StartServiceCtrlDispatcherA(service))
168 {
169 report_error("Failed to start MSIServer service\n");
170 return 1;
171 }
172
173 return 0;
174}
static char service_name[100]
static void WINAPI ServiceMain(DWORD argc, LPSTR *argv)
Definition: service.c:123
BOOL WINAPI StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA *lpServiceStartTable)
Definition: sctrl.c:1054

Referenced by WinMain().

◆ DoUnregServer()

static DWORD DoUnregServer ( void  )
static

Definition at line 371 of file msiexec.c.

372{
373 SC_HANDLE scm, service;
374 DWORD ret = 0;
375
377 {
378 report_error("Failed to open service control manager\n");
379 return 1;
380 }
381 if ((service = OpenServiceW(scm, L"MSIServer", DELETE)))
382 {
383 if (!DeleteService(service))
384 {
385 report_error("Failed to delete MSI service\n");
386 ret = 1;
387 }
388 CloseServiceHandle(service);
389 }
391 {
392 report_error("Failed to open MSI service\n");
393 ret = 1;
394 }
396 return ret;
397}
#define DELETE
Definition: nt_native.h:57
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
BOOL WINAPI DeleteService(SC_HANDLE hService)
Definition: scm.c:921
SC_HANDLE WINAPI OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2199
#define ERROR_SERVICE_DOES_NOT_EXIST
Definition: winerror.h:935

Referenced by WinMain().

◆ get_path_with_extension()

static WCHAR * get_path_with_extension ( const WCHAR *  package_name)
static

Definition at line 613 of file msiexec.c.

614{
615 static const WCHAR ext[] = L".msi";
616 unsigned int p;
617 WCHAR *path;
618
619 if (!(path = malloc(wcslen(package_name) * sizeof(WCHAR) + sizeof(ext))))
620 {
621 WINE_ERR("No memory.\n");
622 return NULL;
623 }
624
625 lstrcpyW(path, package_name);
626 p = lstrlenW(path);
627 while (p && path[p] != '.' && path[p] != L'\\' && path[p] != '/')
628 --p;
629 if (path[p] == '.')
630 {
631 free(path);
632 return NULL;
633 }
634 lstrcatW(path, ext);
635 return path;
636}
static const WCHAR *const ext[]
Definition: module.c:53
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define WINE_ERR
Definition: debug.h:374

Referenced by WinMain().

◆ IsProductCode()

static BOOL IsProductCode ( LPWSTR  str)
static

Definition at line 105 of file msiexec.c.

106{
107 GUID ProductCode;
108
109 if(lstrlenW(str) != 38)
110 return FALSE;
111 return ( (CLSIDFromString(str, &ProductCode) == NOERROR) );
112
113}
HRESULT WINAPI CLSIDFromString(LPCOLESTR str, LPCLSID clsid)
Definition: combase.c:1470
const WCHAR * str
#define NOERROR
Definition: winerror.h:3448

Referenced by WinMain().

◆ LoadProc()

static VOID * LoadProc ( LPCWSTR  DllName,
LPCSTR  ProcName,
HMODULE *  DllHandle 
)
static

Definition at line 281 of file msiexec.c.

282{
283 VOID* (*proc)(void);
284
285 *DllHandle = LoadLibraryExW(DllName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
286 if(!*DllHandle)
287 {
288 report_error("Unable to load dll %s\n", wine_dbgstr_w(DllName));
289 ExitProcess(1);
290 }
291 proc = (VOID *) GetProcAddress(*DllHandle, ProcName);
292 if(!proc)
293 {
294 report_error("Dll %s does not implement function %s\n",
295 wine_dbgstr_w(DllName), ProcName);
296 FreeLibrary(*DllHandle);
297 ExitProcess(1);
298 }
299
300 return proc;
301}
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1380
#define LOAD_WITH_ALTERED_SEARCH_PATH
Definition: winbase.h:340

Referenced by DoDllRegisterServer(), DoDllUnregisterServer(), and load_data().

◆ msi_atou()

static DWORD msi_atou ( LPCWSTR  str)
static

Definition at line 213 of file msiexec.c.

214{
215 DWORD ret = 0;
216 while(*str >= '0' && *str <= '9')
217 {
218 ret *= 10;
219 ret += (*str - '0');
220 str++;
221 }
222 return ret;
223}

Referenced by WinMain().

◆ msi_option_equal()

static BOOL msi_option_equal ( LPCWSTR  str1,
LPCSTR  str2 
)
static

Definition at line 244 of file msiexec.c.

245{
246 if (str1[0] != '/' && str1[0] != '-')
247 return FALSE;
248
249 /* skip over the hyphen or slash */
250 return msi_strequal(str1 + 1, str2);
251}
static BOOL msi_strequal(LPCWSTR str1, LPCSTR str2)
Definition: msiexec.c:226
XML_HIDDEN void xmlParserErrors const char const xmlChar const xmlChar * str2
Definition: parser.h:35
XML_HIDDEN void xmlParserErrors const char const xmlChar * str1
Definition: parser.h:35

Referenced by WinMain().

◆ msi_option_prefix()

static BOOL msi_option_prefix ( LPCWSTR  str1,
LPCSTR  str2 
)
static

Definition at line 272 of file msiexec.c.

273{
274 if (str1[0] != '/' && str1[0] != '-')
275 return FALSE;
276
277 /* skip over the hyphen or slash */
278 return msi_strprefix(str1 + 1, str2);
279}
static BOOL msi_strprefix(LPCWSTR str1, LPCSTR str2)
Definition: msiexec.c:254

Referenced by WinMain().

◆ msi_strequal()

static BOOL msi_strequal ( LPCWSTR  str1,
LPCSTR  str2 
)
static

Definition at line 226 of file msiexec.c.

227{
228 DWORD len, ret;
229 LPWSTR strW;
230
231 len = MultiByteToWideChar( CP_ACP, 0, str2, -1, NULL, 0);
232 if( !len )
233 return FALSE;
234 if( lstrlenW(str1) != (len-1) )
235 return FALSE;
236 strW = malloc(sizeof(WCHAR) * len);
239 free(strW);
240 return (ret == CSTR_EQUAL);
241}
#define CP_ACP
Definition: compat.h:109
#define MultiByteToWideChar
Definition: compat.h:110
LCID WINAPI GetThreadLocale(void)
Definition: locale.c:2803
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: locale.c:3946
WCHAR strW[12]
Definition: clipboard.c:2216
#define NORM_IGNORECASE
Definition: winnls.h:191
#define CSTR_EQUAL
Definition: winnls.h:508

Referenced by msi_option_equal(), and WinMain().

◆ msi_strprefix()

static BOOL msi_strprefix ( LPCWSTR  str1,
LPCSTR  str2 
)
static

Definition at line 254 of file msiexec.c.

255{
256 DWORD len, ret;
257 LPWSTR strW;
258
259 len = MultiByteToWideChar( CP_ACP, 0, str2, -1, NULL, 0);
260 if( !len )
261 return FALSE;
262 if( lstrlenW(str1) < (len-1) )
263 return FALSE;
264 strW = malloc(sizeof(WCHAR) * len);
267 free(strW);
268 return (ret == CSTR_EQUAL);
269}

Referenced by msi_option_prefix(), and WinMain().

◆ process_args()

static void process_args ( WCHAR *  cmdline,
int *  pargc,
WCHAR ***  pargv 
)
static

Definition at line 549 of file msiexec.c.

550{
551 WCHAR **argv, *p;
552 int i, count;
553
554 *pargc = 0;
555 *pargv = NULL;
556
557 count = chomp( cmdline, NULL );
558 if (!(p = malloc( (wcslen(cmdline) + count + 1) * sizeof(WCHAR) )))
559 return;
560
561 count = chomp( cmdline, p );
562 if (!(argv = malloc( (count + 1) * sizeof(WCHAR *) )))
563 {
564 free( p );
565 return;
566 }
567 for (i = 0; i < count; i++)
568 {
569 argv[i] = p;
570 p += lstrlenW( p ) + 1;
571 }
572 argv[i] = NULL;
573
574 *pargc = count;
575 *pargv = argv;
576}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define argv
Definition: mplay32.c:18
static int chomp(const WCHAR *in, WCHAR *out)
Definition: msiexec.c:481
TCHAR * cmdline
Definition: stretchblt.cpp:32

Referenced by process_args_from_reg(), and WinMain().

◆ process_args_from_reg()

static BOOL process_args_from_reg ( const WCHAR *  ident,
int *  pargc,
WCHAR ***  pargv 
)
static

Definition at line 578 of file msiexec.c.

579{
580 LONG r;
581 HKEY hkey;
582 DWORD sz = 0, type = 0;
583 WCHAR *buf;
584 BOOL ret = FALSE;
585
587 L"Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\RunOnceEntries", &hkey);
588 if(r != ERROR_SUCCESS)
589 return FALSE;
590 r = RegQueryValueExW(hkey, ident, 0, &type, 0, &sz);
591 if(r == ERROR_SUCCESS && type == REG_SZ)
592 {
593 int len = lstrlenW( *pargv[0] );
594 if (!(buf = malloc( (len + 1) * sizeof(WCHAR) )))
595 {
596 RegCloseKey( hkey );
597 return FALSE;
598 }
599 memcpy( buf, *pargv[0], len * sizeof(WCHAR) );
600 buf[len++] = ' ';
601 r = RegQueryValueExW(hkey, ident, 0, &type, (LPBYTE)(buf + len), &sz);
602 if( r == ERROR_SUCCESS )
603 {
604 process_args(buf, pargc, pargv);
605 ret = TRUE;
606 }
607 free(buf);
608 }
609 RegCloseKey(hkey);
610 return ret;
611}
#define REG_SZ
Definition: layer.c:22
#define RegCloseKey(hKey)
Definition: registry.h:49
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static void process_args(WCHAR *cmdline, int *pargc, WCHAR ***pargv)
Definition: msiexec.c:549
long LONG
Definition: pedump.c:60
unsigned char * LPBYTE
Definition: typedefs.h:53
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by WinMain().

◆ remove_quotes()

static WCHAR * remove_quotes ( const WCHAR *  filename)
static

Definition at line 638 of file msiexec.c.

639{
640 const WCHAR *ptr = filename;
641 int len = wcslen( filename );
642 WCHAR *ret;
643
644 if (!(ret = malloc( (len + 1) * sizeof(WCHAR) ))) return NULL;
645 if (*ptr == '"')
646 {
647 ptr++;
648 len--;
649 }
650 wcscpy( ret, ptr );
651 if (len && ret[len - 1] == '"') ret[len - 1] = 0;
652 return ret;
653}
const char * filename
Definition: ioapi.h:137
static PVOID ptr
Definition: dispmode.c:27
wcscpy

Referenced by WinMain().

◆ report_error()

void report_error ( const char *  msg,
  ... 
)

Definition at line 50 of file msiexec.c.

51{
52 char buffer[2048];
53 va_list va_args;
54
55 va_start(va_args, msg);
56 vsnprintf(buffer, sizeof(buffer), msg, va_args);
57 va_end(va_args);
58
59 if (silent)
60 MESSAGE("%s", buffer);
61 else
62 MsiMessageBoxA(NULL, buffer, "MsiExec", 0, GetUserDefaultLangID(), 0);
63}
#define vsnprintf
Definition: acwin.h:108
#define msg(x)
Definition: auth_time.c:54
LANGID WINAPI GetUserDefaultLangID(void)
Definition: locale.c:1182
UINT WINAPI MsiMessageBoxA(HWND hWnd, const char *lpText, const char *lpCaption, UINT uType, WORD wLanguageId, DWORD f)
Definition: msi.c:2451
#define va_end(v)
Definition: stdarg.h:28
#define va_start(v, l)
Definition: stdarg.h:26
char * va_list
Definition: vadefs.h:50
static BOOL silent
Definition: msiexec.c:42

Referenced by DoDllRegisterServer(), DoDllUnregisterServer(), DoRegServer(), DoService(), DoUnregServer(), LoadProc(), ServiceCtrlHandler(), ServiceMain(), StartServiceThread(), UpdateSCMStatus(), and WinMain().

◆ ShowUsage()

static void ShowUsage ( int  ExitCode)
static

Definition at line 65 of file msiexec.c.

66{
67 WCHAR msiexec_version[40];
69 LPWSTR msi_res;
70 LPWSTR msiexec_help;
71 HMODULE hmsi = GetModuleHandleA("msi.dll");
72 DWORD len;
73 DWORD res;
74
75 /* MsiGetFileVersion need the full path */
76 *filename = 0;
78 if (!res)
79 WINE_ERR("GetModuleFileName failed: %ld\n", GetLastError());
80
81 len = ARRAY_SIZE(msiexec_version);
82 *msiexec_version = 0;
83 res = MsiGetFileVersionW(filename, msiexec_version, &len, NULL, NULL);
84 if (res)
85 WINE_ERR("MsiGetFileVersion failed with %ld\n", res);
86
87 /* Return the length of the resource.
88 No typo: The LPWSTR parameter must be a LPWSTR * for this mode */
89 len = LoadStringW(hmsi, 10, (LPWSTR) &msi_res, 0);
90
91 msi_res = malloc((len + 1) * sizeof(WCHAR));
92 msiexec_help = malloc((len + 1) * sizeof(WCHAR) + sizeof(msiexec_version));
93 if (msi_res && msiexec_help) {
94 *msi_res = 0;
95 LoadStringW(hmsi, 10, msi_res, len + 1);
96
97 swprintf(msiexec_help, len + 1 + ARRAY_SIZE(msiexec_version), msi_res, msiexec_version);
98 MsiMessageBoxW(0, msiexec_help, NULL, 0, GetUserDefaultLangID(), 0);
99 }
100 free(msi_res);
101 free(msiexec_help);
102 ExitProcess(ExitCode);
103}
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
UINT WINAPI MsiGetFileVersionW(const WCHAR *path, WCHAR *verbuf, DWORD *verlen, WCHAR *langbuf, DWORD *langlen)
Definition: msi.c:3208
UINT WINAPI MsiMessageBoxW(HWND hWnd, const WCHAR *lpText, const WCHAR *lpCaption, UINT uType, WORD wLanguageId, DWORD f)
Definition: msi.c:2458
GLuint res
Definition: glext.h:9613
#define LoadStringW
Definition: utils.h:64

Referenced by CCABManager::ParseCmdline(), ParseCmdline(), and WinMain().

◆ StringListAppend()

static VOID StringListAppend ( struct string_list **  list,
LPCWSTR  str 
)
static

Definition at line 115 of file msiexec.c.

116{
117 struct string_list *entry;
118
120 if(!entry)
121 {
122 WINE_ERR("Out of memory!\n");
123 ExitProcess(1);
124 }
125 lstrcpyW(entry->str, str);
126 entry->next = NULL;
127
128 /*
129 * Ignoring o(n^2) time complexity to add n strings for simplicity,
130 * add the string to the end of the list to preserve the order.
131 */
132 while( *list )
133 list = &(*list)->next;
134 *list = entry;
135}
uint32_t entry
Definition: isohybrid.c:63
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255

Referenced by WinMain().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msiexec  )

◆ WinMain()

int WINAPI WinMain ( HINSTANCE  hInstance,
HINSTANCE  hPrevInstance,
LPSTR  lpCmdLine,
int  nCmdShow 
)

Definition at line 655 of file msiexec.c.

656{
657 int i;
658 BOOL FunctionInstall = FALSE;
659 BOOL FunctionInstallAdmin = FALSE;
660 BOOL FunctionRepair = FALSE;
661 BOOL FunctionAdvertise = FALSE;
662 BOOL FunctionPatch = FALSE;
663 BOOL FunctionDllRegisterServer = FALSE;
664 BOOL FunctionDllUnregisterServer = FALSE;
665 BOOL FunctionRegServer = FALSE;
666 BOOL FunctionUnregServer = FALSE;
667 BOOL FunctionServer = FALSE;
668 BOOL FunctionUnknown = FALSE;
669
670 LPWSTR PackageName = NULL;
671 LPWSTR Properties = NULL;
672 struct string_list *property_list = NULL;
673
674 DWORD RepairMode = 0;
675
676 DWORD_PTR AdvertiseMode = 0;
677 struct string_list *transform_list = NULL;
678 LANGID Language = 0;
679
680 DWORD LogMode = 0;
681 DWORD LogAttributes = 0;
682
683 LPWSTR PatchFileName = NULL;
684 INSTALLTYPE InstallType = INSTALLTYPE_DEFAULT;
685
686 INSTALLUILEVEL InstallUILevel = INSTALLUILEVEL_FULL;
687
688 LPWSTR DllName = NULL;
689 DWORD ReturnCode;
690 int argc;
691 LPWSTR *argvW = NULL;
692 WCHAR *path, *package_unquoted = NULL, *dll_unquoted = NULL, *patch_unquoted = NULL, *log_unquoted;
693
695
696 /* parse the command line */
697 process_args( GetCommandLineW(), &argc, &argvW );
698
699 /*
700 * If the args begin with /@ IDENT then we need to load the real
701 * command line out of the RunOnceEntries key in the registry.
702 * We do that before starting to process the real commandline,
703 * then overwrite the commandline again.
704 */
705 if(argc>1 && msi_option_equal(argvW[1], "@"))
706 {
707 if(!process_args_from_reg( argvW[2], &argc, &argvW ))
708 return 1;
709 }
710
711 if (argc == 3 && msi_option_equal(argvW[1], "Embedding"))
712 return custom_action_server(argvW[2]);
713
714 for(i = 1; i < argc; i++)
715 {
716 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
717
718 if (msi_option_equal(argvW[i], "regserver"))
719 {
720 FunctionRegServer = TRUE;
721 }
722 else if (msi_option_equal(argvW[i], "unregserver") || msi_option_equal(argvW[i], "unregister")
723 || msi_option_equal(argvW[i], "unreg"))
724 {
725 FunctionUnregServer = TRUE;
726 }
727 else if(msi_option_prefix(argvW[i], "i") || msi_option_prefix(argvW[i], "package"))
728 {
729 LPWSTR argvWi = argvW[i];
730 int argLen = (msi_option_prefix(argvW[i], "i") ? 2 : 8);
731 FunctionInstall = TRUE;
732 if(lstrlenW(argvW[i]) > argLen)
733 argvWi += argLen;
734 else
735 {
736 i++;
737 if(i >= argc)
738 ShowUsage(1);
739 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
740 argvWi = argvW[i];
741 }
742 PackageName = argvWi;
743 }
744 else if(msi_option_equal(argvW[i], "a"))
745 {
746 FunctionInstall = TRUE;
747 FunctionInstallAdmin = TRUE;
748 InstallType = INSTALLTYPE_NETWORK_IMAGE;
749 i++;
750 if(i >= argc)
751 ShowUsage(1);
752 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
753 PackageName = argvW[i];
754 StringListAppend(&property_list, L"ACTION=ADMIN");
755 }
756 else if(msi_option_prefix(argvW[i], "f"))
757 {
758 int j;
759 int len = lstrlenW(argvW[i]);
760 FunctionRepair = TRUE;
761 for(j = 2; j < len; j++)
762 {
763 switch(argvW[i][j])
764 {
765 case 'P':
766 case 'p':
767 RepairMode |= REINSTALLMODE_FILEMISSING;
768 break;
769 case 'O':
770 case 'o':
771 RepairMode |= REINSTALLMODE_FILEOLDERVERSION;
772 break;
773 case 'E':
774 case 'e':
775 RepairMode |= REINSTALLMODE_FILEEQUALVERSION;
776 break;
777 case 'D':
778 case 'd':
779 RepairMode |= REINSTALLMODE_FILEEXACT;
780 break;
781 case 'C':
782 case 'c':
783 RepairMode |= REINSTALLMODE_FILEVERIFY;
784 break;
785 case 'A':
786 case 'a':
787 RepairMode |= REINSTALLMODE_FILEREPLACE;
788 break;
789 case 'U':
790 case 'u':
791 RepairMode |= REINSTALLMODE_USERDATA;
792 break;
793 case 'M':
794 case 'm':
795 RepairMode |= REINSTALLMODE_MACHINEDATA;
796 break;
797 case 'S':
798 case 's':
799 RepairMode |= REINSTALLMODE_SHORTCUT;
800 break;
801 case 'V':
802 case 'v':
803 RepairMode |= REINSTALLMODE_PACKAGE;
804 break;
805 default:
806 report_error("Unknown option \"%c\" in Repair mode\n", argvW[i][j]);
807 break;
808 }
809 }
810 if(len == 2)
811 {
812 RepairMode = REINSTALLMODE_FILEMISSING |
817 }
818 i++;
819 if(i >= argc)
820 ShowUsage(1);
821 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
822 PackageName = argvW[i];
823 }
824 else if(msi_option_prefix(argvW[i], "x") || msi_option_equal(argvW[i], "uninstall"))
825 {
826 FunctionInstall = TRUE;
827 if(msi_option_prefix(argvW[i], "x")) PackageName = argvW[i]+2;
828 if(!PackageName || !PackageName[0])
829 {
830 i++;
831 if (i >= argc)
832 ShowUsage(1);
833 PackageName = argvW[i];
834 }
835 WINE_TRACE("PackageName = %s\n", wine_dbgstr_w(PackageName));
836 StringListAppend(&property_list, L"REMOVE=ALL");
837 }
838 else if(msi_option_prefix(argvW[i], "j"))
839 {
840 int j;
841 int len = lstrlenW(argvW[i]);
842 FunctionAdvertise = TRUE;
843 for(j = 2; j < len; j++)
844 {
845 switch(argvW[i][j])
846 {
847 case 'U':
848 case 'u':
849 AdvertiseMode = ADVERTISEFLAGS_USERASSIGN;
850 break;
851 case 'M':
852 case 'm':
853 AdvertiseMode = ADVERTISEFLAGS_MACHINEASSIGN;
854 break;
855 default:
856 report_error("Unknown option \"%c\" in Advertise mode\n", argvW[i][j]);
857 break;
858 }
859 }
860 i++;
861 if(i >= argc)
862 ShowUsage(1);
863 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
864 PackageName = argvW[i];
865 }
866 else if(msi_strequal(argvW[i], "u"))
867 {
868 FunctionAdvertise = TRUE;
869 AdvertiseMode = ADVERTISEFLAGS_USERASSIGN;
870 i++;
871 if(i >= argc)
872 ShowUsage(1);
873 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
874 PackageName = argvW[i];
875 }
876 else if(msi_strequal(argvW[i], "m"))
877 {
878 FunctionAdvertise = TRUE;
879 AdvertiseMode = ADVERTISEFLAGS_MACHINEASSIGN;
880 i++;
881 if(i >= argc)
882 ShowUsage(1);
883 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
884 PackageName = argvW[i];
885 }
886 else if(msi_option_equal(argvW[i], "t"))
887 {
888 i++;
889 if(i >= argc)
890 ShowUsage(1);
891 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
892 StringListAppend(&transform_list, argvW[i]);
893 }
894 else if(msi_option_equal(argvW[i], "g"))
895 {
896 i++;
897 if(i >= argc)
898 ShowUsage(1);
899 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
900 Language = msi_atou(argvW[i]);
901 }
902 else if(msi_option_prefix(argvW[i], "l"))
903 {
904 int j;
905 int len = lstrlenW(argvW[i]);
906 for(j = 2; j < len; j++)
907 {
908 switch(argvW[i][j])
909 {
910 case 'I':
911 case 'i':
912 LogMode |= INSTALLLOGMODE_INFO;
913 break;
914 case 'W':
915 case 'w':
916 LogMode |= INSTALLLOGMODE_WARNING;
917 break;
918 case 'E':
919 case 'e':
920 LogMode |= INSTALLLOGMODE_ERROR;
921 break;
922 case 'A':
923 case 'a':
925 break;
926 case 'R':
927 case 'r':
928 LogMode |= INSTALLLOGMODE_ACTIONDATA;
929 break;
930 case 'U':
931 case 'u':
932 LogMode |= INSTALLLOGMODE_USER;
933 break;
934 case 'C':
935 case 'c':
936 LogMode |= INSTALLLOGMODE_COMMONDATA;
937 break;
938 case 'M':
939 case 'm':
940 LogMode |= INSTALLLOGMODE_FATALEXIT;
941 break;
942 case 'O':
943 case 'o':
945 break;
946 case 'P':
947 case 'p':
949 break;
950 case 'V':
951 case 'v':
952 LogMode |= INSTALLLOGMODE_VERBOSE;
953 break;
954 case '*':
955 LogMode = INSTALLLOGMODE_FATALEXIT |
970 break;
971 case '+':
972 LogAttributes |= INSTALLLOGATTRIBUTES_APPEND;
973 break;
974 case '!':
975 LogAttributes |= INSTALLLOGATTRIBUTES_FLUSHEACHLINE;
976 break;
977 default:
978 break;
979 }
980 }
981 i++;
982 if(i >= argc)
983 ShowUsage(1);
984 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
985 if (!(log_unquoted = remove_quotes(argvW[i]))) return 1;
986 if (MsiEnableLogW(LogMode, log_unquoted, LogAttributes) != ERROR_SUCCESS)
987 {
988 report_error("Logging in %s (0x%08lx, %lu) failed\n",
989 wine_dbgstr_w(log_unquoted), LogMode, LogAttributes);
990 ExitProcess(1);
991 }
992 }
993 else if(msi_option_equal(argvW[i], "p") || msi_option_equal(argvW[i], "update"))
994 {
995 FunctionPatch = TRUE;
996 i++;
997 if(i >= argc)
998 ShowUsage(1);
999 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
1000 PatchFileName = argvW[i];
1001 }
1002 else if(msi_option_prefix(argvW[i], "q"))
1003 {
1004 if(lstrlenW(argvW[i]) == 2 || msi_strequal(argvW[i]+2, "n") ||
1005 msi_strequal(argvW[i] + 2, "uiet"))
1006 {
1007 silent = TRUE;
1008 InstallUILevel = INSTALLUILEVEL_NONE;
1009 }
1010 else if(msi_strequal(argvW[i]+2, "r"))
1011 {
1012 InstallUILevel = INSTALLUILEVEL_REDUCED;
1013 }
1014 else if(msi_strequal(argvW[i]+2, "f"))
1015 {
1017 }
1018 else if(msi_strequal(argvW[i]+2, "n+"))
1019 {
1021 }
1022 else if(msi_strprefix(argvW[i]+2, "b"))
1023 {
1024 const WCHAR *ptr = argvW[i] + 3;
1025
1026 InstallUILevel = INSTALLUILEVEL_BASIC;
1027
1028 while (*ptr)
1029 {
1030 if (msi_strprefix(ptr, "+"))
1031 InstallUILevel |= INSTALLUILEVEL_ENDDIALOG;
1032 if (msi_strprefix(ptr, "-"))
1033 InstallUILevel |= INSTALLUILEVEL_PROGRESSONLY;
1034 if (msi_strprefix(ptr, "!"))
1035 {
1036 WINE_FIXME("Unhandled modifier: !\n");
1037 InstallUILevel |= INSTALLUILEVEL_HIDECANCEL;
1038 }
1039 ptr++;
1040 }
1041 }
1042 else
1043 {
1044 report_error("Unknown option \"%s\" for UI level\n",
1045 wine_dbgstr_w(argvW[i]+2));
1046 }
1047 }
1048 else if(msi_option_equal(argvW[i], "passive"))
1049 {
1051 StringListAppend(&property_list, L"REBOOTPROMPT=\"S\"");
1052 }
1053 else if(msi_option_equal(argvW[i], "y"))
1054 {
1055 FunctionDllRegisterServer = TRUE;
1056 i++;
1057 if(i >= argc)
1058 ShowUsage(1);
1059 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
1060 DllName = argvW[i];
1061 }
1062 else if(msi_option_equal(argvW[i], "z"))
1063 {
1064 FunctionDllUnregisterServer = TRUE;
1065 i++;
1066 if(i >= argc)
1067 ShowUsage(1);
1068 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
1069 DllName = argvW[i];
1070 }
1071 else if(msi_option_equal(argvW[i], "help") || msi_option_equal(argvW[i], "?"))
1072 {
1073 ShowUsage(0);
1074 }
1075 else if(msi_option_equal(argvW[i], "m"))
1076 {
1077 FunctionUnknown = TRUE;
1078 WINE_FIXME("Unknown parameter /m\n");
1079 }
1080 else if(msi_option_equal(argvW[i], "D"))
1081 {
1082 FunctionUnknown = TRUE;
1083 WINE_FIXME("Unknown parameter /D\n");
1084 }
1085 else if (msi_option_equal(argvW[i], "V"))
1086 {
1087 FunctionServer = TRUE;
1088 }
1089 else
1090 StringListAppend(&property_list, argvW[i]);
1091 }
1092
1093 /* start the GUI */
1094 MsiSetInternalUI(InstallUILevel, NULL);
1095
1096 Properties = build_properties( property_list );
1097
1098 if(FunctionInstallAdmin && FunctionPatch)
1099 FunctionInstall = FALSE;
1100
1101 if (PackageName && !(package_unquoted = remove_quotes(PackageName))) return 1;
1102 if (PatchFileName && !(patch_unquoted = remove_quotes(PatchFileName))) return 1;
1103 if (DllName && !(dll_unquoted = remove_quotes(DllName))) return 1;
1104
1105 ReturnCode = 1;
1106 if(FunctionInstall)
1107 {
1108 if(IsProductCode(package_unquoted))
1109 ReturnCode = MsiConfigureProductExW(package_unquoted, 0, INSTALLSTATE_DEFAULT, Properties);
1110 else
1111 {
1112 if ((ReturnCode = MsiInstallProductW(package_unquoted, Properties)) == ERROR_FILE_NOT_FOUND
1113 && (path = get_path_with_extension(package_unquoted)))
1114 {
1115 ReturnCode = MsiInstallProductW(path, Properties);
1116 free(path);
1117 }
1118 }
1119 }
1120 else if(FunctionRepair)
1121 {
1122 if(IsProductCode(package_unquoted))
1123 WINE_FIXME("Product code treatment not implemented yet\n");
1124 else
1125 {
1126 if ((ReturnCode = MsiReinstallProductW(package_unquoted, RepairMode)) == ERROR_FILE_NOT_FOUND
1127 && (path = get_path_with_extension(package_unquoted)))
1128 {
1129 ReturnCode = MsiReinstallProductW(path, RepairMode);
1130 free(path);
1131 }
1132 }
1133 }
1134 else if(FunctionAdvertise)
1135 {
1136 LPWSTR Transforms = build_transforms( property_list );
1137 ReturnCode = MsiAdvertiseProductW(package_unquoted, (LPWSTR) AdvertiseMode, Transforms, Language);
1138 }
1139 else if(FunctionPatch)
1140 {
1141 ReturnCode = MsiApplyPatchW(patch_unquoted, package_unquoted, InstallType, Properties);
1142 }
1143 else if(FunctionDllRegisterServer)
1144 {
1145 ReturnCode = DoDllRegisterServer(dll_unquoted);
1146 }
1147 else if(FunctionDllUnregisterServer)
1148 {
1149 ReturnCode = DoDllUnregisterServer(dll_unquoted);
1150 }
1151 else if (FunctionRegServer)
1152 {
1153 ReturnCode = DoRegServer();
1154 }
1155 else if (FunctionUnregServer)
1156 {
1157 ReturnCode = DoUnregServer();
1158 }
1159 else if (FunctionServer)
1160 {
1161 ReturnCode = DoService();
1162 }
1163 else if (FunctionUnknown)
1164 {
1165 WINE_FIXME( "Unknown function, ignoring\n" );
1166 }
1167 else
1168 ShowUsage(1);
1169
1170 return ReturnCode;
1171}
VOID WINAPI InitCommonControls(void)
Definition: commctrl.c:874
LPWSTR WINAPI GetCommandLineW(void)
Definition: process.c:1356
MonoAssembly int argc
Definition: metahost.c:107
UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
Definition: msi.c:831
UINT WINAPI MsiEnableLogW(DWORD dwLogMode, const WCHAR *szLogFile, DWORD attributes)
Definition: msi.c:1900
UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
Definition: msi.c:228
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
Definition: msi.c:2281
UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath, LPCWSTR szTransforms, LANGID lgidLanguage)
Definition: msi.c:174
UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage, INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
Definition: msi.c:408
UINT WINAPI MsiReinstallProductW(const WCHAR *szProduct, DWORD dwReinstallMode)
Definition: msi.c:279
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
USHORT LANGID
Definition: mui.h:9
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
enum tagINSTALLTYPE INSTALLTYPE
@ INSTALLLOGATTRIBUTES_FLUSHEACHLINE
Definition: msi.h:157
@ INSTALLLOGATTRIBUTES_APPEND
Definition: msi.h:156
@ ADVERTISEFLAGS_USERASSIGN
Definition: msi.h:172
@ ADVERTISEFLAGS_MACHINEASSIGN
Definition: msi.h:171
@ INSTALLLOGMODE_VERBOSE
Definition: msi.h:145
@ INSTALLLOGMODE_ACTIONDATA
Definition: msi.h:140
@ INSTALLLOGMODE_ACTIONSTART
Definition: msi.h:139
@ INSTALLLOGMODE_FATALEXIT
Definition: msi.h:131
@ INSTALLLOGMODE_PROPERTYDUMP
Definition: msi.h:142
@ INSTALLLOGMODE_RESOLVESOURCE
Definition: msi.h:137
@ INSTALLLOGMODE_COMMONDATA
Definition: msi.h:143
@ INSTALLLOGMODE_WARNING
Definition: msi.h:133
@ INSTALLLOGMODE_INITIALIZE
Definition: msi.h:144
@ INSTALLLOGMODE_TERMINATE
Definition: msi.h:146
@ INSTALLLOGMODE_OUTOFDISKSPACE
Definition: msi.h:138
@ INSTALLLOGMODE_ERROR
Definition: msi.h:132
@ INSTALLLOGMODE_INFO
Definition: msi.h:135
@ INSTALLLOGMODE_PROGRESS
Definition: msi.h:141
@ INSTALLLOGMODE_SHOWDIALOG
Definition: msi.h:148
@ INSTALLLOGMODE_USER
Definition: msi.h:134
@ INSTALLTYPE_DEFAULT
Definition: msi.h:189
@ INSTALLTYPE_NETWORK_IMAGE
Definition: msi.h:190
@ REINSTALLMODE_MACHINEDATA
Definition: msi.h:123
@ REINSTALLMODE_FILEREPLACE
Definition: msi.h:122
@ REINSTALLMODE_FILEOLDERVERSION
Definition: msi.h:118
@ REINSTALLMODE_FILEEXACT
Definition: msi.h:120
@ REINSTALLMODE_FILEEQUALVERSION
Definition: msi.h:119
@ REINSTALLMODE_USERDATA
Definition: msi.h:124
@ REINSTALLMODE_PACKAGE
Definition: msi.h:126
@ REINSTALLMODE_FILEVERIFY
Definition: msi.h:121
@ REINSTALLMODE_SHORTCUT
Definition: msi.h:125
@ REINSTALLMODE_FILEMISSING
Definition: msi.h:117
@ INSTALLSTATE_DEFAULT
Definition: msi.h:48
enum tagINSTALLUILEVEL INSTALLUILEVEL
@ INSTALLUILEVEL_ENDDIALOG
Definition: msi.h:72
@ INSTALLUILEVEL_FULL
Definition: msi.h:69
@ INSTALLUILEVEL_BASIC
Definition: msi.h:67
@ INSTALLUILEVEL_HIDECANCEL
Definition: msi.h:70
@ INSTALLUILEVEL_REDUCED
Definition: msi.h:68
@ INSTALLUILEVEL_NONE
Definition: msi.h:66
@ INSTALLUILEVEL_PROGRESSONLY
Definition: msi.h:71
static BOOL IsProductCode(LPWSTR str)
Definition: msiexec.c:105
static DWORD DoUnregServer(void)
Definition: msiexec.c:371
static DWORD DoDllRegisterServer(LPCWSTR DllName)
Definition: msiexec.c:303
static void ShowUsage(int ExitCode)
Definition: msiexec.c:65
static LPWSTR build_transforms(struct string_list *transform_list)
Definition: msiexec.c:185
static int custom_action_server(const WCHAR *arg)
Definition: msiexec.c:410
static LPWSTR build_properties(struct string_list *property_list)
Definition: msiexec.c:137
static WCHAR * get_path_with_extension(const WCHAR *package_name)
Definition: msiexec.c:613
static BOOL msi_option_prefix(LPCWSTR str1, LPCSTR str2)
Definition: msiexec.c:272
DWORD DoService(void)
Definition: service.c:155
static VOID StringListAppend(struct string_list **list, LPCWSTR str)
Definition: msiexec.c:115
static WCHAR * remove_quotes(const WCHAR *filename)
Definition: msiexec.c:638
static BOOL msi_option_equal(LPCWSTR str1, LPCSTR str2)
Definition: msiexec.c:244
static DWORD DoDllUnregisterServer(LPCWSTR DllName)
Definition: msiexec.c:323
static DWORD DoRegServer(void)
Definition: msiexec.c:343
static BOOL process_args_from_reg(const WCHAR *ident, int *pargc, WCHAR ***pargv)
Definition: msiexec.c:578
static DWORD msi_atou(LPCWSTR str)
Definition: msiexec.c:213
#define WINE_FIXME
Definition: debug.h:369
uint32_t DWORD_PTR
Definition: typedefs.h:65

Variable Documentation

◆ client_pid

◆ silent