ReactOS 0.4.16-dev-136-g52192f1
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(WINAPIDLLREGISTERSERVER) (void)
 
typedef HRESULT(WINAPIDLLUNREGISTERSERVER) (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 VOIDLoadProc (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 WCHARget_path_with_extension (const WCHAR *package_name)
 
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 470 of file msiexec.c.

471{
473 CS_TOKEN,
475};
@ CS_TOKEN
Definition: msiexec.c:473
@ CS_WHITESPACE
Definition: msiexec.c:472
@ CS_QUOTE
Definition: msiexec.c:474

Function Documentation

◆ __wine_msi_call_dll_function()

UINT CDECL __wine_msi_call_dll_function ( DWORD  client_pid,
const GUID guid 
)

Definition at line 508 of file custom.c.

509{
511 MSIHANDLE remote_package = 0;
512 RPC_WSTR binding_str;
513 MSIHANDLE hPackage;
515 WCHAR *dll = NULL, *action = NULL;
516 LPSTR proc = NULL;
518 INT type;
519 UINT r;
520
521 TRACE("%s\n", debugstr_guid( guid ));
522
523 if (!rpc_handle)
524 {
525 WCHAR endpoint[12];
526
528 status = RpcStringBindingComposeW(NULL, (WCHAR *)L"ncalrpc", NULL, endpoint, NULL, &binding_str);
529 if (status != RPC_S_OK)
530 {
531 ERR("RpcStringBindingCompose failed: %#lx\n", status);
532 return status;
533 }
534 status = RpcBindingFromStringBindingW(binding_str, &rpc_handle);
535 if (status != RPC_S_OK)
536 {
537 ERR("RpcBindingFromStringBinding failed: %#lx\n", status);
538 return status;
539 }
540 RpcStringFreeW(&binding_str);
541 }
542
543 r = remote_GetActionInfo(guid, &action, &type, &dll, &proc, &remote_package);
544 if (r != ERROR_SUCCESS)
545 return r;
546
547 hPackage = alloc_msi_remote_handle( remote_package );
548 if (!hPackage)
549 {
550 ERR( "failed to create handle for %#lx\n", remote_package );
555 }
556
558 if (!hModule)
559 {
560 ERR( "failed to load dll %s (%lu)\n", debugstr_w( dll ), GetLastError() );
564 MsiCloseHandle( hPackage );
565 return ERROR_SUCCESS;
566 }
567
569 if (!fn) WARN( "GetProcAddress(%s) failed\n", debugstr_a(proc) );
570 else
571 {
573
574 __TRY
575 {
576 r = custom_proc_wrapper( fn, hPackage );
577 }
579 {
580 ERR( "Custom action (%s:%s) caused a page fault: %#lx\n",
583 }
584 __ENDTRY;
585 }
586
588
592
594 return r;
595}
#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
const WCHAR * action
Definition: action.c:7509
static void handle_msi_break(const WCHAR *action)
Definition: custom.c:459
UINT(WINAPI * MsiCustomActionEntryPoint)(MSIHANDLE)
Definition: custom.c:61
static UINT custom_proc_wrapper(MsiCustomActionEntryPoint entry, MSIHANDLE hinst)
Definition: custom.c:502
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
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
const GUID * guid
static HMODULE dll
Definition: str.c:188
static DWORD client_pid
Definition: msiexec.c:401
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
static HANDLE proc()
Definition: pdb.c:34
RPC_STATUS WINAPI RpcBindingFromStringBindingW(RPC_WSTR StringBinding, RPC_BINDING_HANDLE *Binding)
Definition: rpc_binding.c:880
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:510
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:175
#define midl_user_free
Definition: rpc.h:45
long RPC_STATUS
Definition: rpc.h:52
#define GetExceptionCode()
Definition: seh.h:27
#define TRACE(s)
Definition: solgame.cpp:4
Definition: nis.h:10
Definition: ps.c:97
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:961
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180

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 = wcschr(value,' ') ? 1 : 0;
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:37
struct list * next
Definition: list.h:38
#define malloc
Definition: debug_ros.c:4
#define wcschr
Definition: compat.h:17
#define lstrlenW
Definition: compat.h:750
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:354
Definition: pdh_main.c:94
int ret
WCHAR * LPWSTR
Definition: xmlstorage.h:184

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 477 of file msiexec.c.

478{
480 const WCHAR *p;
481 int count = 1;
482 BOOL ignore;
483
484 for (p = in; *p; p++)
485 {
486 ignore = TRUE;
487 switch (state)
488 {
489 case CS_WHITESPACE:
490 switch (*p)
491 {
492 case ' ':
493 break;
494 case '"':
495 state = CS_QUOTE;
496 count++;
497 break;
498 default:
499 count++;
500 ignore = FALSE;
501 state = CS_TOKEN;
502 }
503 break;
504
505 case CS_TOKEN:
506 switch (*p)
507 {
508 case '"':
509 state = CS_QUOTE;
510 break;
511 case ' ':
513 if (out) *out++ = 0;
514 break;
515 default:
516 if (p > in && p[-1] == '"')
517 {
518 if (out) *out++ = 0;
519 count++;
520 }
521 ignore = FALSE;
522 }
523 break;
524
525 case CS_QUOTE:
526 switch (*p)
527 {
528 case '"':
529 state = CS_TOKEN;
530 break;
531 default:
532 ignore = FALSE;
533 }
534 break;
535 }
536 if (!ignore && out) *out++ = *p;
537 }
538 if (out) *out = 0;
539 return count;
540}
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:471
static FILE * out
Definition: regtests2xml.c:44

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 swprintf(buffer, ARRAY_SIZE(buffer), L"\\\\.\\pipe\\msica_%x_%d", client_pid, (int)(sizeof(void *) * 8));
429 if (pipe == INVALID_HANDLE_VALUE)
430 {
431 ERR("Failed to create custom action server pipe: %lu\n", GetLastError());
432 return GetLastError();
433 }
434
435 /* We need this to unmarshal streams, and some apps expect it to be present. */
437
438 while (ReadFile(pipe, &guid, sizeof(guid), &size, NULL) && size == sizeof(guid))
439 {
440 if (IsEqualGUID(&guid, &GUID_NULL))
441 {
442 /* package closed; time to shut down */
444 return 0;
445 }
446
447 thread_guid = malloc(sizeof(GUID));
448 memcpy(thread_guid, &guid, sizeof(GUID));
449 thread = CreateThread(NULL, 0, custom_action_thread, thread_guid, 0, NULL);
450
451 /* give the thread handle to the client to wait on, since we might have
452 * to run a nested action and can't block during this one */
453 thread64 = (DWORD_PTR)thread;
454 if (!WriteFile(pipe, &thread64, sizeof(thread64), &size, NULL) || size != sizeof(thread64))
455 {
456 ERR("Failed to write to custom action server pipe: %lu\n", GetLastError());
458 return GetLastError();
459 }
460 }
461 ERR("Failed to read from custom action server pipe: %lu\n", GetLastError());
463 return GetLastError();
464}
static HANDLE thread
Definition: service.c:33
#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 LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
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
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#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:279
#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:508

Referenced by custom_action_server().

◆ DEFINE_GUID()

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

◆ 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}
#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
HRESULT hr
Definition: shlfolder.c:183

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:2313
#define GENERIC_ALL
Definition: nt_native.h:92
SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:2068
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:624
#define SC_MANAGER_CREATE_SERVICE
Definition: winsvc.h:15
#define SERVICES_ACTIVE_DATABASEW
Definition: winsvc.h:8
#define SERVICE_DEMAND_START
Definition: cmtypes.h:978
#define SERVICE_WIN32_SHARE_PROCESS
Definition: cmtypes.h:963
#define SERVICE_ERROR_NORMAL
Definition: cmtypes.h:982

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:1035

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
BOOL WINAPI DeleteService(SC_HANDLE hService)
Definition: scm.c:921
SC_HANDLE WINAPI OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2160
#define ERROR_SERVICE_DOES_NOT_EXIST
Definition: winerror.h:611
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14

Referenced by WinMain().

◆ get_path_with_extension()

static WCHAR * get_path_with_extension ( const WCHAR package_name)
static

Definition at line 606 of file msiexec.c.

607{
608 static const WCHAR ext[] = L".msi";
609 unsigned int p;
610 WCHAR *path;
611
612 if (!(path = malloc(wcslen(package_name) * sizeof(WCHAR) + sizeof(ext))))
613 {
614 WINE_ERR("No memory.\n");
615 return NULL;
616 }
617
618 lstrcpyW(path, package_name);
619 p = lstrlenW(path);
620 while (p && path[p] != '.' && path[p] != L'\\' && path[p] != '/')
621 --p;
622 if (path[p] == '.')
623 {
624 free(path);
625 return NULL;
626 }
627 lstrcatW(path, ext);
628 return path;
629}
static const WCHAR *const ext[]
Definition: module.c:53
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define WINE_ERR
Definition: debug.h:371

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 idstr, LPCLSID id)
Definition: compobj.c:2338
const WCHAR * str
#define NOERROR
Definition: winerror.h:2354

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:1487
#define LOAD_WITH_ALTERED_SEARCH_PATH
Definition: winbase.h:344

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

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);
237 MultiByteToWideChar( CP_ACP, 0, str2, -1, strW, 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:2800
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: locale.c:4013
WCHAR strW[12]
Definition: clipboard.c:2029
#define NORM_IGNORECASE
Definition: winnls.h:176
#define CSTR_EQUAL
Definition: winnls.h:456

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);
265 MultiByteToWideChar( CP_ACP, 0, str2, -1, strW, 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 542 of file msiexec.c.

543{
544 WCHAR **argv, *p;
545 int i, count;
546
547 *pargc = 0;
548 *pargv = NULL;
549
550 count = chomp( cmdline, NULL );
551 if (!(p = malloc( (wcslen(cmdline) + count + 1) * sizeof(WCHAR) )))
552 return;
553
554 count = chomp( cmdline, p );
555 if (!(argv = malloc( (count + 1) * sizeof(WCHAR *) )))
556 {
557 free( p );
558 return;
559 }
560 for (i = 0; i < count; i++)
561 {
562 argv[i] = p;
563 p += lstrlenW( p ) + 1;
564 }
565 argv[i] = NULL;
566
567 *pargc = count;
568 *pargv = argv;
569}
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:477
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 571 of file msiexec.c.

572{
573 LONG r;
574 HKEY hkey;
575 DWORD sz = 0, type = 0;
576 WCHAR *buf;
577 BOOL ret = FALSE;
578
580 L"Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\RunOnceEntries", &hkey);
581 if(r != ERROR_SUCCESS)
582 return FALSE;
583 r = RegQueryValueExW(hkey, ident, 0, &type, 0, &sz);
584 if(r == ERROR_SUCCESS && type == REG_SZ)
585 {
586 int len = lstrlenW( *pargv[0] );
587 if (!(buf = malloc( (len + 1) * sizeof(WCHAR) )))
588 {
589 RegCloseKey( hkey );
590 return FALSE;
591 }
592 memcpy( buf, *pargv[0], len * sizeof(WCHAR) );
593 buf[len++] = ' ';
594 r = RegQueryValueExW(hkey, ident, 0, &type, (LPBYTE)(buf + len), &sz);
595 if( r == ERROR_SUCCESS )
596 {
597 process_args(buf, pargc, pargv);
598 ret = TRUE;
599 }
600 free(buf);
601 }
602 RegCloseKey(hkey);
603 return ret;
604}
#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
#define REG_SZ
Definition: layer.c:22
static void process_args(WCHAR *cmdline, int *pargc, WCHAR ***pargv)
Definition: msiexec.c:542
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().

◆ 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}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define msg(x)
Definition: auth_time.c:54
LANGID WINAPI GetUserDefaultLangID(void)
Definition: locale.c:1176
UINT WINAPI MsiMessageBoxA(HWND hWnd, const char *lpText, const char *lpCaption, UINT uType, WORD wLanguageId, DWORD f)
Definition: msi.c:2451
static BOOL silent
Definition: msiexec.c:42
#define vsnprintf
Definition: tif_win32.c:406

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
const char * filename
Definition: ioapi.h:137
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)

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 631 of file msiexec.c.

632{
633 int i;
634 BOOL FunctionInstall = FALSE;
635 BOOL FunctionInstallAdmin = FALSE;
636 BOOL FunctionRepair = FALSE;
637 BOOL FunctionAdvertise = FALSE;
638 BOOL FunctionPatch = FALSE;
639 BOOL FunctionDllRegisterServer = FALSE;
640 BOOL FunctionDllUnregisterServer = FALSE;
641 BOOL FunctionRegServer = FALSE;
642 BOOL FunctionUnregServer = FALSE;
643 BOOL FunctionServer = FALSE;
644 BOOL FunctionUnknown = FALSE;
645
646 LPWSTR PackageName = NULL;
647 LPWSTR Properties = NULL;
648 struct string_list *property_list = NULL;
649
650 DWORD RepairMode = 0;
651
652 DWORD_PTR AdvertiseMode = 0;
653 struct string_list *transform_list = NULL;
654 LANGID Language = 0;
655
656 DWORD LogMode = 0;
658 DWORD LogAttributes = 0;
659
660 LPWSTR PatchFileName = NULL;
661 INSTALLTYPE InstallType = INSTALLTYPE_DEFAULT;
662
663 INSTALLUILEVEL InstallUILevel = INSTALLUILEVEL_FULL;
664
665 LPWSTR DllName = NULL;
666 DWORD ReturnCode;
667 int argc;
668 LPWSTR *argvW = NULL;
669 WCHAR *path;
670
672
673 /* parse the command line */
674 process_args( GetCommandLineW(), &argc, &argvW );
675
676 /*
677 * If the args begin with /@ IDENT then we need to load the real
678 * command line out of the RunOnceEntries key in the registry.
679 * We do that before starting to process the real commandline,
680 * then overwrite the commandline again.
681 */
682 if(argc>1 && msi_option_equal(argvW[1], "@"))
683 {
684 if(!process_args_from_reg( argvW[2], &argc, &argvW ))
685 return 1;
686 }
687
688 if (argc == 3 && msi_option_equal(argvW[1], "Embedding"))
689 return custom_action_server(argvW[2]);
690
691 for(i = 1; i < argc; i++)
692 {
693 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
694
695 if (msi_option_equal(argvW[i], "regserver"))
696 {
697 FunctionRegServer = TRUE;
698 }
699 else if (msi_option_equal(argvW[i], "unregserver") || msi_option_equal(argvW[i], "unregister")
700 || msi_option_equal(argvW[i], "unreg"))
701 {
702 FunctionUnregServer = TRUE;
703 }
704 else if(msi_option_prefix(argvW[i], "i") || msi_option_prefix(argvW[i], "package"))
705 {
706 LPWSTR argvWi = argvW[i];
707 int argLen = (msi_option_prefix(argvW[i], "i") ? 2 : 8);
708 FunctionInstall = TRUE;
709 if(lstrlenW(argvW[i]) > argLen)
710 argvWi += argLen;
711 else
712 {
713 i++;
714 if(i >= argc)
715 ShowUsage(1);
716 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
717 argvWi = argvW[i];
718 }
719 PackageName = argvWi;
720 }
721 else if(msi_option_equal(argvW[i], "a"))
722 {
723 FunctionInstall = TRUE;
724 FunctionInstallAdmin = TRUE;
725 InstallType = INSTALLTYPE_NETWORK_IMAGE;
726 i++;
727 if(i >= argc)
728 ShowUsage(1);
729 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
730 PackageName = argvW[i];
731 StringListAppend(&property_list, L"ACTION=ADMIN");
732 WINE_FIXME("Administrative installs are not currently supported\n");
733 }
734 else if(msi_option_prefix(argvW[i], "f"))
735 {
736 int j;
737 int len = lstrlenW(argvW[i]);
738 FunctionRepair = TRUE;
739 for(j = 2; j < len; j++)
740 {
741 switch(argvW[i][j])
742 {
743 case 'P':
744 case 'p':
745 RepairMode |= REINSTALLMODE_FILEMISSING;
746 break;
747 case 'O':
748 case 'o':
749 RepairMode |= REINSTALLMODE_FILEOLDERVERSION;
750 break;
751 case 'E':
752 case 'e':
753 RepairMode |= REINSTALLMODE_FILEEQUALVERSION;
754 break;
755 case 'D':
756 case 'd':
757 RepairMode |= REINSTALLMODE_FILEEXACT;
758 break;
759 case 'C':
760 case 'c':
761 RepairMode |= REINSTALLMODE_FILEVERIFY;
762 break;
763 case 'A':
764 case 'a':
765 RepairMode |= REINSTALLMODE_FILEREPLACE;
766 break;
767 case 'U':
768 case 'u':
769 RepairMode |= REINSTALLMODE_USERDATA;
770 break;
771 case 'M':
772 case 'm':
773 RepairMode |= REINSTALLMODE_MACHINEDATA;
774 break;
775 case 'S':
776 case 's':
777 RepairMode |= REINSTALLMODE_SHORTCUT;
778 break;
779 case 'V':
780 case 'v':
781 RepairMode |= REINSTALLMODE_PACKAGE;
782 break;
783 default:
784 report_error("Unknown option \"%c\" in Repair mode\n", argvW[i][j]);
785 break;
786 }
787 }
788 if(len == 2)
789 {
790 RepairMode = REINSTALLMODE_FILEMISSING |
795 }
796 i++;
797 if(i >= argc)
798 ShowUsage(1);
799 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
800 PackageName = argvW[i];
801 }
802 else if(msi_option_prefix(argvW[i], "x") || msi_option_equal(argvW[i], "uninstall"))
803 {
804 FunctionInstall = TRUE;
805 if(msi_option_prefix(argvW[i], "x")) PackageName = argvW[i]+2;
806 if(!PackageName || !PackageName[0])
807 {
808 i++;
809 if (i >= argc)
810 ShowUsage(1);
811 PackageName = argvW[i];
812 }
813 WINE_TRACE("PackageName = %s\n", wine_dbgstr_w(PackageName));
814 StringListAppend(&property_list, L"REMOVE=ALL");
815 }
816 else if(msi_option_prefix(argvW[i], "j"))
817 {
818 int j;
819 int len = lstrlenW(argvW[i]);
820 FunctionAdvertise = TRUE;
821 for(j = 2; j < len; j++)
822 {
823 switch(argvW[i][j])
824 {
825 case 'U':
826 case 'u':
827 AdvertiseMode = ADVERTISEFLAGS_USERASSIGN;
828 break;
829 case 'M':
830 case 'm':
831 AdvertiseMode = ADVERTISEFLAGS_MACHINEASSIGN;
832 break;
833 default:
834 report_error("Unknown option \"%c\" in Advertise mode\n", argvW[i][j]);
835 break;
836 }
837 }
838 i++;
839 if(i >= argc)
840 ShowUsage(1);
841 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
842 PackageName = argvW[i];
843 }
844 else if(msi_strequal(argvW[i], "u"))
845 {
846 FunctionAdvertise = TRUE;
847 AdvertiseMode = ADVERTISEFLAGS_USERASSIGN;
848 i++;
849 if(i >= argc)
850 ShowUsage(1);
851 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
852 PackageName = argvW[i];
853 }
854 else if(msi_strequal(argvW[i], "m"))
855 {
856 FunctionAdvertise = TRUE;
857 AdvertiseMode = ADVERTISEFLAGS_MACHINEASSIGN;
858 i++;
859 if(i >= argc)
860 ShowUsage(1);
861 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
862 PackageName = argvW[i];
863 }
864 else if(msi_option_equal(argvW[i], "t"))
865 {
866 i++;
867 if(i >= argc)
868 ShowUsage(1);
869 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
870 StringListAppend(&transform_list, argvW[i]);
871 }
872 else if(msi_option_equal(argvW[i], "g"))
873 {
874 i++;
875 if(i >= argc)
876 ShowUsage(1);
877 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
878 Language = msi_atou(argvW[i]);
879 }
880 else if(msi_option_prefix(argvW[i], "l"))
881 {
882 int j;
883 int len = lstrlenW(argvW[i]);
884 for(j = 2; j < len; j++)
885 {
886 switch(argvW[i][j])
887 {
888 case 'I':
889 case 'i':
890 LogMode |= INSTALLLOGMODE_INFO;
891 break;
892 case 'W':
893 case 'w':
894 LogMode |= INSTALLLOGMODE_WARNING;
895 break;
896 case 'E':
897 case 'e':
898 LogMode |= INSTALLLOGMODE_ERROR;
899 break;
900 case 'A':
901 case 'a':
903 break;
904 case 'R':
905 case 'r':
906 LogMode |= INSTALLLOGMODE_ACTIONDATA;
907 break;
908 case 'U':
909 case 'u':
910 LogMode |= INSTALLLOGMODE_USER;
911 break;
912 case 'C':
913 case 'c':
914 LogMode |= INSTALLLOGMODE_COMMONDATA;
915 break;
916 case 'M':
917 case 'm':
918 LogMode |= INSTALLLOGMODE_FATALEXIT;
919 break;
920 case 'O':
921 case 'o':
923 break;
924 case 'P':
925 case 'p':
927 break;
928 case 'V':
929 case 'v':
930 LogMode |= INSTALLLOGMODE_VERBOSE;
931 break;
932 case '*':
933 LogMode = INSTALLLOGMODE_FATALEXIT |
948 break;
949 case '+':
950 LogAttributes |= INSTALLLOGATTRIBUTES_APPEND;
951 break;
952 case '!':
953 LogAttributes |= INSTALLLOGATTRIBUTES_FLUSHEACHLINE;
954 break;
955 default:
956 break;
957 }
958 }
959 i++;
960 if(i >= argc)
961 ShowUsage(1);
962 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
963 LogFileName = argvW[i];
964 if(MsiEnableLogW(LogMode, LogFileName, LogAttributes) != ERROR_SUCCESS)
965 {
966 report_error("Logging in %s (0x%08lx, %lu) failed\n",
967 wine_dbgstr_w(LogFileName), LogMode, LogAttributes);
968 ExitProcess(1);
969 }
970 }
971 else if(msi_option_equal(argvW[i], "p") || msi_option_equal(argvW[i], "update"))
972 {
973 FunctionPatch = TRUE;
974 i++;
975 if(i >= argc)
976 ShowUsage(1);
977 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
978 PatchFileName = argvW[i];
979 }
980 else if(msi_option_prefix(argvW[i], "q"))
981 {
982 if(lstrlenW(argvW[i]) == 2 || msi_strequal(argvW[i]+2, "n") ||
983 msi_strequal(argvW[i] + 2, "uiet"))
984 {
985 silent = TRUE;
986 InstallUILevel = INSTALLUILEVEL_NONE;
987 }
988 else if(msi_strequal(argvW[i]+2, "r"))
989 {
990 InstallUILevel = INSTALLUILEVEL_REDUCED;
991 }
992 else if(msi_strequal(argvW[i]+2, "f"))
993 {
995 }
996 else if(msi_strequal(argvW[i]+2, "n+"))
997 {
999 }
1000 else if(msi_strprefix(argvW[i]+2, "b"))
1001 {
1002 const WCHAR *ptr = argvW[i] + 3;
1003
1004 InstallUILevel = INSTALLUILEVEL_BASIC;
1005
1006 while (*ptr)
1007 {
1008 if (msi_strprefix(ptr, "+"))
1009 InstallUILevel |= INSTALLUILEVEL_ENDDIALOG;
1010 if (msi_strprefix(ptr, "-"))
1011 InstallUILevel |= INSTALLUILEVEL_PROGRESSONLY;
1012 if (msi_strprefix(ptr, "!"))
1013 {
1014 WINE_FIXME("Unhandled modifier: !\n");
1015 InstallUILevel |= INSTALLUILEVEL_HIDECANCEL;
1016 }
1017 ptr++;
1018 }
1019 }
1020 else
1021 {
1022 report_error("Unknown option \"%s\" for UI level\n",
1023 wine_dbgstr_w(argvW[i]+2));
1024 }
1025 }
1026 else if(msi_option_equal(argvW[i], "passive"))
1027 {
1029 StringListAppend(&property_list, L"REBOOTPROMPT=\"S\"");
1030 }
1031 else if(msi_option_equal(argvW[i], "y"))
1032 {
1033 FunctionDllRegisterServer = TRUE;
1034 i++;
1035 if(i >= argc)
1036 ShowUsage(1);
1037 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
1038 DllName = argvW[i];
1039 }
1040 else if(msi_option_equal(argvW[i], "z"))
1041 {
1042 FunctionDllUnregisterServer = TRUE;
1043 i++;
1044 if(i >= argc)
1045 ShowUsage(1);
1046 WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
1047 DllName = argvW[i];
1048 }
1049 else if(msi_option_equal(argvW[i], "help") || msi_option_equal(argvW[i], "?"))
1050 {
1051 ShowUsage(0);
1052 }
1053 else if(msi_option_equal(argvW[i], "m"))
1054 {
1055 FunctionUnknown = TRUE;
1056 WINE_FIXME("Unknown parameter /m\n");
1057 }
1058 else if(msi_option_equal(argvW[i], "D"))
1059 {
1060 FunctionUnknown = TRUE;
1061 WINE_FIXME("Unknown parameter /D\n");
1062 }
1063 else if (msi_option_equal(argvW[i], "V"))
1064 {
1065 FunctionServer = TRUE;
1066 }
1067 else
1068 StringListAppend(&property_list, argvW[i]);
1069 }
1070
1071 /* start the GUI */
1072 MsiSetInternalUI(InstallUILevel, NULL);
1073
1074 Properties = build_properties( property_list );
1075
1076 if(FunctionInstallAdmin && FunctionPatch)
1077 FunctionInstall = FALSE;
1078
1079 ReturnCode = 1;
1080 if(FunctionInstall)
1081 {
1082 if(IsProductCode(PackageName))
1083 ReturnCode = MsiConfigureProductExW(PackageName, 0, INSTALLSTATE_DEFAULT, Properties);
1084 else
1085 {
1086 if ((ReturnCode = MsiInstallProductW(PackageName, Properties)) == ERROR_FILE_NOT_FOUND
1087 && (path = get_path_with_extension(PackageName)))
1088 {
1089 ReturnCode = MsiInstallProductW(path, Properties);
1090 free(path);
1091 }
1092 }
1093 }
1094 else if(FunctionRepair)
1095 {
1096 if(IsProductCode(PackageName))
1097 WINE_FIXME("Product code treatment not implemented yet\n");
1098 else
1099 {
1100 if ((ReturnCode = MsiReinstallProductW(PackageName, RepairMode)) == ERROR_FILE_NOT_FOUND
1101 && (path = get_path_with_extension(PackageName)))
1102 {
1103 ReturnCode = MsiReinstallProductW(path, RepairMode);
1104 free(path);
1105 }
1106 }
1107 }
1108 else if(FunctionAdvertise)
1109 {
1110 LPWSTR Transforms = build_transforms( property_list );
1111 ReturnCode = MsiAdvertiseProductW(PackageName, (LPWSTR) AdvertiseMode, Transforms, Language);
1112 }
1113 else if(FunctionPatch)
1114 {
1115 ReturnCode = MsiApplyPatchW(PatchFileName, PackageName, InstallType, Properties);
1116 }
1117 else if(FunctionDllRegisterServer)
1118 {
1119 ReturnCode = DoDllRegisterServer(DllName);
1120 }
1121 else if(FunctionDllUnregisterServer)
1122 {
1123 ReturnCode = DoDllUnregisterServer(DllName);
1124 }
1125 else if (FunctionRegServer)
1126 {
1127 ReturnCode = DoRegServer();
1128 }
1129 else if (FunctionUnregServer)
1130 {
1131 ReturnCode = DoUnregServer();
1132 }
1133 else if (FunctionServer)
1134 {
1135 ReturnCode = DoService();
1136 }
1137 else if (FunctionUnknown)
1138 {
1139 WINE_FIXME( "Unknown function, ignoring\n" );
1140 }
1141 else
1142 ShowUsage(1);
1143
1144 return ReturnCode;
1145}
static int argc
Definition: ServiceArgs.c:12
VOID WINAPI InitCommonControls(void)
Definition: commctrl.c:870
LPWSTR WINAPI GetCommandLineW(VOID)
Definition: proc.c:2019
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
static PVOID ptr
Definition: dispmode.c:27
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:606
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 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:571
static DWORD msi_atou(LPCWSTR str)
Definition: msiexec.c:213
_Must_inspect_result_ _In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PUNICODE_STRING LogFileName
Definition: nttmapi.h:324
#define WINE_FIXME
Definition: debug.h:366
uint32_t DWORD_PTR
Definition: typedefs.h:65

Variable Documentation

◆ client_pid

◆ silent