ReactOS 0.4.15-dev-8241-g63935f8
msiexec.c File Reference
#include <windows.h>
#include <commctrl.h>
#include <msi.h>
#include <winsvc.h>
#include <objbase.h>
#include <stdio.h>
#include "wine/debug.h"
#include "wine/heap.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)
 
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 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 39 of file msiexec.c.

◆ DLLUNREGISTERSERVER

typedef HRESULT(WINAPI * DLLUNREGISTERSERVER) (void)

Definition at line 40 of file msiexec.c.

Enumeration Type Documentation

◆ chomp_state

Enumerator
CS_WHITESPACE 
CS_TOKEN 
CS_QUOTE 

Definition at line 455 of file msiexec.c.

456{
458 CS_TOKEN,
460};
@ CS_TOKEN
Definition: msiexec.c:458
@ CS_WHITESPACE
Definition: msiexec.c:457
@ CS_QUOTE
Definition: msiexec.c:459

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 );
554 }
555
557 if (!hModule)
558 {
559 ERR( "failed to load dll %s (%lu)\n", debugstr_w( dll ), GetLastError() );
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
591
593 return r;
594}
#define ARRAY_SIZE(A)
Definition: main.h:33
#define WARN(fmt,...)
Definition: debug.h:115
#define ERR(fmt,...)
Definition: debug.h:113
#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:7479
static void handle_msi_break(const WCHAR *action)
Definition: custom.c:458
UINT(WINAPI * MsiCustomActionEntryPoint)(MSIHANDLE)
Definition: custom.c:61
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
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:386
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 122 of file msiexec.c.

123{
124 struct string_list *list;
125 LPWSTR ret, p, value;
126 DWORD len;
127 BOOL needs_quote;
128
129 if(!property_list)
130 return NULL;
131
132 /* count the space we need */
133 len = 1;
134 for(list = property_list; list; list = list->next)
135 len += lstrlenW(list->str) + 3;
136
137 ret = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
138
139 /* add a space before each string, and quote the value */
140 p = ret;
141 for(list = property_list; list; list = list->next)
142 {
143 value = wcschr(list->str,'=');
144 if(!value)
145 continue;
146 len = value - list->str;
147 *p++ = ' ';
148 memcpy(p, list->str, len * sizeof(WCHAR));
149 p += len;
150 *p++ = '=';
151
152 /* check if the value contains spaces and maybe quote it */
153 value++;
154 needs_quote = wcschr(value,' ') ? 1 : 0;
155 if(needs_quote)
156 *p++ = '"';
157 len = lstrlenW(value);
158 memcpy(p, value, len * sizeof(WCHAR));
159 p += len;
160 if(needs_quote)
161 *p++ = '"';
162 }
163 *p = 0;
164
165 WINE_TRACE("properties -> %s\n", wine_dbgstr_w(ret) );
166
167 return ret;
168}
Definition: list.h:37
struct list * next
Definition: list.h:38
#define wcschr
Definition: compat.h:17
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#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 170 of file msiexec.c.

171{
172 struct string_list *list;
173 LPWSTR ret, p;
174 DWORD len;
175
176 /* count the space we need */
177 len = 1;
178 for(list = transform_list; list; list = list->next)
179 len += lstrlenW(list->str) + 1;
180
181 ret = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
182
183 /* add all the transforms with a semicolon between each one */
184 p = ret;
185 for(list = transform_list; list; list = list->next)
186 {
187 len = lstrlenW(list->str);
188 lstrcpynW(p, list->str, len );
189 p += len;
190 if(list->next)
191 *p++ = ';';
192 }
193 *p = 0;
194
195 return ret;
196}
#define lstrcpynW
Definition: compat.h:738

Referenced by WinMain().

◆ chomp()

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

Definition at line 462 of file msiexec.c.

463{
465 const WCHAR *p;
466 int count = 1;
467 BOOL ignore;
468
469 for (p = in; *p; p++)
470 {
471 ignore = TRUE;
472 switch (state)
473 {
474 case CS_WHITESPACE:
475 switch (*p)
476 {
477 case ' ':
478 break;
479 case '"':
480 state = CS_QUOTE;
481 count++;
482 break;
483 default:
484 count++;
485 ignore = FALSE;
486 state = CS_TOKEN;
487 }
488 break;
489
490 case CS_TOKEN:
491 switch (*p)
492 {
493 case '"':
494 state = CS_QUOTE;
495 break;
496 case ' ':
498 if (out) *out++ = 0;
499 break;
500 default:
501 if (p > in && p[-1] == '"')
502 {
503 if (out) *out++ = 0;
504 count++;
505 }
506 ignore = FALSE;
507 }
508 break;
509
510 case CS_QUOTE:
511 switch (*p)
512 {
513 case '"':
514 state = CS_TOKEN;
515 break;
516 default:
517 ignore = FALSE;
518 }
519 break;
520 }
521 if (!ignore && out) *out++ = *p;
522 }
523 if (out) *out = 0;
524 return count;
525}
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:456
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 395 of file msiexec.c.

396{
397 GUID guid, *thread_guid;
398 DWORD64 thread64;
399 WCHAR buffer[24];
401 HANDLE pipe;
402 DWORD size;
403
404 TRACE("%s\n", debugstr_w(arg));
405
406 if (!(client_pid = wcstol(arg, NULL, 10)))
407 {
408 ERR("Invalid parameter %s\n", debugstr_w(arg));
409 return 1;
410 }
411
412 swprintf(buffer, ARRAY_SIZE(buffer), L"\\\\.\\pipe\\msica_%x_%d", client_pid, (int)(sizeof(void *) * 8));
414 if (pipe == INVALID_HANDLE_VALUE)
415 {
416 ERR("Failed to create custom action server pipe: %lu\n", GetLastError());
417 return GetLastError();
418 }
419
420 /* We need this to unmarshal streams, and some apps expect it to be present. */
422
423 while (ReadFile(pipe, &guid, sizeof(guid), &size, NULL) && size == sizeof(guid))
424 {
425 if (IsEqualGUID(&guid, &GUID_NULL))
426 {
427 /* package closed; time to shut down */
429 return 0;
430 }
431
432 thread_guid = heap_alloc(sizeof(GUID));
433 memcpy(thread_guid, &guid, sizeof(GUID));
434 thread = CreateThread(NULL, 0, custom_action_thread, thread_guid, 0, NULL);
435
436 /* give the thread handle to the client to wait on, since we might have
437 * to run a nested action and can't block during this one */
438 thread64 = (DWORD_PTR)thread;
439 if (!WriteFile(pipe, &thread64, sizeof(thread64), &size, NULL) || size != sizeof(thread64))
440 {
441 ERR("Failed to write to custom action server pipe: %lu\n", GetLastError());
443 return GetLastError();
444 }
445 }
446 ERR("Failed to read from custom action server pipe: %lu\n", GetLastError());
448 return GetLastError();
449}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
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:388
#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 388 of file msiexec.c.

389{
390 GUID guid = *(GUID *)arg;
391 heap_free(arg);
393}
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
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  ,
,
,
,
,
,
,
,
,
,
,
 
)

◆ DoDllRegisterServer()

static DWORD DoDllRegisterServer ( LPCWSTR  DllName)
static

Definition at line 288 of file msiexec.c.

289{
290 HRESULT hr;
291 DLLREGISTERSERVER pfDllRegisterServer = NULL;
292 HMODULE DllHandle = NULL;
293
294 pfDllRegisterServer = LoadProc(DllName, "DllRegisterServer", &DllHandle);
295
296 hr = pfDllRegisterServer();
297 if(FAILED(hr))
298 {
299 fprintf(stderr, "Failed to register dll %s\n", wine_dbgstr_w(DllName));
300 return 1;
301 }
302 printf("Successfully registered dll %s\n", wine_dbgstr_w(DllName));
303 if(DllHandle)
304 FreeLibrary(DllHandle);
305 return 0;
306}
#define printf
Definition: freeldr.h:97
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define FAILED(hr)
Definition: intsafe.h:51
static VOID * LoadProc(LPCWSTR DllName, LPCSTR ProcName, HMODULE *DllHandle)
Definition: msiexec.c:266
HRESULT(WINAPI * DLLREGISTERSERVER)(void)
Definition: msiexec.c:39
HRESULT hr
Definition: shlfolder.c:183

Referenced by WinMain().

◆ DoDllUnregisterServer()

static DWORD DoDllUnregisterServer ( LPCWSTR  DllName)
static

Definition at line 308 of file msiexec.c.

309{
310 HRESULT hr;
311 DLLUNREGISTERSERVER pfDllUnregisterServer = NULL;
312 HMODULE DllHandle = NULL;
313
314 pfDllUnregisterServer = LoadProc(DllName, "DllUnregisterServer", &DllHandle);
315
316 hr = pfDllUnregisterServer();
317 if(FAILED(hr))
318 {
319 fprintf(stderr, "Failed to unregister dll %s\n", wine_dbgstr_w(DllName));
320 return 1;
321 }
322 printf("Successfully unregistered dll %s\n", wine_dbgstr_w(DllName));
323 if(DllHandle)
324 FreeLibrary(DllHandle);
325 return 0;
326}
HRESULT(WINAPI * DLLUNREGISTERSERVER)(void)
Definition: msiexec.c:40

Referenced by WinMain().

◆ DoRegServer()

static DWORD DoRegServer ( void  )
static

Definition at line 328 of file msiexec.c.

329{
330 SC_HANDLE scm, service;
331 WCHAR path[MAX_PATH+12];
332 DWORD len, ret = 0;
333
335 {
336 fprintf(stderr, "Failed to open the service control manager.\n");
337 return 1;
338 }
340 lstrcpyW(path + len, L"\\msiexec /V");
341 if ((service = CreateServiceW(scm, L"MSIServer", L"MSIServer", GENERIC_ALL,
344 {
345 CloseServiceHandle(service);
346 }
348 {
349 fprintf(stderr, "Failed to create MSI service\n");
350 ret = 1;
351 }
353 return ret;
354}
#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 fprintf(stderr, "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 356 of file msiexec.c.

357{
358 SC_HANDLE scm, service;
359 DWORD ret = 0;
360
362 {
363 fprintf(stderr, "Failed to open service control manager\n");
364 return 1;
365 }
366 if ((service = OpenServiceW(scm, L"MSIServer", DELETE)))
367 {
368 if (!DeleteService(service))
369 {
370 fprintf(stderr, "Failed to delete MSI service\n");
371 ret = 1;
372 }
373 CloseServiceHandle(service);
374 }
376 {
377 fprintf(stderr, "Failed to open MSI service\n");
378 ret = 1;
379 }
381 return ret;
382}
#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 591 of file msiexec.c.

592{
593 static const WCHAR ext[] = L".msi";
594 unsigned int p;
595 WCHAR *path;
596
597 if (!(path = heap_alloc(lstrlenW(package_name) * sizeof(WCHAR) + sizeof(ext))))
598 {
599 WINE_ERR("No memory.\n");
600 return NULL;
601 }
602
603 lstrcpyW(path, package_name);
604 p = lstrlenW(path);
605 while (p && path[p] != '.' && path[p] != L'\\' && path[p] != '/')
606 --p;
607 if (path[p] == '.')
608 {
610 return NULL;
611 }
612 lstrcatW(path, ext);
613 return path;
614}
static const WCHAR *const ext[]
Definition: module.c:53
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 90 of file msiexec.c.

91{
92 GUID ProductCode;
93
94 if(lstrlenW(str) != 38)
95 return FALSE;
96 return ( (CLSIDFromString(str, &ProductCode) == NOERROR) );
97
98}
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 266 of file msiexec.c.

267{
268 VOID* (*proc)(void);
269
270 *DllHandle = LoadLibraryExW(DllName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
271 if(!*DllHandle)
272 {
273 fprintf(stderr, "Unable to load dll %s\n", wine_dbgstr_w(DllName));
274 ExitProcess(1);
275 }
276 proc = (VOID *) GetProcAddress(*DllHandle, ProcName);
277 if(!proc)
278 {
279 fprintf(stderr, "Dll %s does not implement function %s\n",
280 wine_dbgstr_w(DllName), ProcName);
281 FreeLibrary(*DllHandle);
282 ExitProcess(1);
283 }
284
285 return proc;
286}
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 198 of file msiexec.c.

199{
200 DWORD ret = 0;
201 while(*str >= '0' && *str <= '9')
202 {
203 ret *= 10;
204 ret += (*str - '0');
205 str++;
206 }
207 return ret;
208}

Referenced by WinMain().

◆ msi_option_equal()

static BOOL msi_option_equal ( LPCWSTR  str1,
LPCSTR  str2 
)
static

Definition at line 229 of file msiexec.c.

230{
231 if (str1[0] != '/' && str1[0] != '-')
232 return FALSE;
233
234 /* skip over the hyphen or slash */
235 return msi_strequal(str1 + 1, str2);
236}
static BOOL msi_strequal(LPCWSTR str1, LPCSTR str2)
Definition: msiexec.c:211

Referenced by WinMain().

◆ msi_option_prefix()

static BOOL msi_option_prefix ( LPCWSTR  str1,
LPCSTR  str2 
)
static

Definition at line 257 of file msiexec.c.

258{
259 if (str1[0] != '/' && str1[0] != '-')
260 return FALSE;
261
262 /* skip over the hyphen or slash */
263 return msi_strprefix(str1 + 1, str2);
264}
static BOOL msi_strprefix(LPCWSTR str1, LPCSTR str2)
Definition: msiexec.c:239

Referenced by WinMain().

◆ msi_strequal()

static BOOL msi_strequal ( LPCWSTR  str1,
LPCSTR  str2 
)
static

Definition at line 211 of file msiexec.c.

212{
213 DWORD len, ret;
214 LPWSTR strW;
215
216 len = MultiByteToWideChar( CP_ACP, 0, str2, -1, NULL, 0);
217 if( !len )
218 return FALSE;
219 if( lstrlenW(str1) != (len-1) )
220 return FALSE;
221 strW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len);
222 MultiByteToWideChar( CP_ACP, 0, str2, -1, strW, len);
225 return (ret == CSTR_EQUAL);
226}
#define CP_ACP
Definition: compat.h:109
#define HeapFree(x, y, z)
Definition: compat.h:735
#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 239 of file msiexec.c.

240{
241 DWORD len, ret;
242 LPWSTR strW;
243
244 len = MultiByteToWideChar( CP_ACP, 0, str2, -1, NULL, 0);
245 if( !len )
246 return FALSE;
247 if( lstrlenW(str1) < (len-1) )
248 return FALSE;
249 strW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len);
250 MultiByteToWideChar( CP_ACP, 0, str2, -1, strW, len);
253 return (ret == CSTR_EQUAL);
254}

Referenced by msi_option_prefix(), and WinMain().

◆ process_args()

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

Definition at line 527 of file msiexec.c.

528{
529 WCHAR **argv, *p;
530 int i, count;
531
532 *pargc = 0;
533 *pargv = NULL;
534
535 count = chomp( cmdline, NULL );
536 if (!(p = HeapAlloc( GetProcessHeap(), 0, (lstrlenW(cmdline) + count + 1) * sizeof(WCHAR) )))
537 return;
538
539 count = chomp( cmdline, p );
540 if (!(argv = HeapAlloc( GetProcessHeap(), 0, (count + 1) * sizeof(WCHAR *) )))
541 {
542 HeapFree( GetProcessHeap(), 0, p );
543 return;
544 }
545 for (i = 0; i < count; i++)
546 {
547 argv[i] = p;
548 p += lstrlenW( p ) + 1;
549 }
550 argv[i] = NULL;
551
552 *pargc = count;
553 *pargv = argv;
554}
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:462
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 556 of file msiexec.c.

557{
558 LONG r;
559 HKEY hkey;
560 DWORD sz = 0, type = 0;
561 WCHAR *buf;
562 BOOL ret = FALSE;
563
565 L"Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\RunOnceEntries", &hkey);
566 if(r != ERROR_SUCCESS)
567 return FALSE;
568 r = RegQueryValueExW(hkey, ident, 0, &type, 0, &sz);
569 if(r == ERROR_SUCCESS && type == REG_SZ)
570 {
571 int len = lstrlenW( *pargv[0] );
572 if (!(buf = HeapAlloc( GetProcessHeap(), 0, sz + (len + 1) * sizeof(WCHAR) )))
573 {
574 RegCloseKey( hkey );
575 return FALSE;
576 }
577 memcpy( buf, *pargv[0], len * sizeof(WCHAR) );
578 buf[len++] = ' ';
579 r = RegQueryValueExW(hkey, ident, 0, &type, (LPBYTE)(buf + len), &sz);
580 if( r == ERROR_SUCCESS )
581 {
582 process_args(buf, pargc, pargv);
583 ret = TRUE;
584 }
586 }
587 RegCloseKey(hkey);
588 return ret;
589}
#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:527
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().

◆ ShowUsage()

static void ShowUsage ( int  ExitCode)
static

Definition at line 50 of file msiexec.c.

51{
52 WCHAR msiexec_version[40];
54 LPWSTR msi_res;
55 LPWSTR msiexec_help;
56 HMODULE hmsi = GetModuleHandleA("msi.dll");
57 DWORD len;
58 DWORD res;
59
60 /* MsiGetFileVersion need the full path */
61 *filename = 0;
63 if (!res)
64 WINE_ERR("GetModuleFileName failed: %ld\n", GetLastError());
65
66 len = ARRAY_SIZE(msiexec_version);
67 *msiexec_version = 0;
68 res = MsiGetFileVersionW(filename, msiexec_version, &len, NULL, NULL);
69 if (res)
70 WINE_ERR("MsiGetFileVersion failed with %ld\n", res);
71
72 /* Return the length of the resource.
73 No typo: The LPWSTR parameter must be a LPWSTR * for this mode */
74 len = LoadStringW(hmsi, 10, (LPWSTR) &msi_res, 0);
75
76 msi_res = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
77 msiexec_help = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) + sizeof(msiexec_version));
78 if (msi_res && msiexec_help) {
79 *msi_res = 0;
80 LoadStringW(hmsi, 10, msi_res, len + 1);
81
82 swprintf(msiexec_help, len + 1 + ARRAY_SIZE(msiexec_version), msi_res, msiexec_version);
83 MsiMessageBoxW(0, msiexec_help, NULL, 0, GetUserDefaultLangID(), 0);
84 }
85 HeapFree(GetProcessHeap(), 0, msi_res);
86 HeapFree(GetProcessHeap(), 0, msiexec_help);
87 ExitProcess(ExitCode);
88}
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
LANGID WINAPI GetUserDefaultLangID(void)
Definition: locale.c:1176
UINT WINAPI MsiGetFileVersionW(const WCHAR *path, WCHAR *verbuf, DWORD *verlen, WCHAR *langbuf, DWORD *langlen)
Definition: msi.c:3214
UINT WINAPI MsiMessageBoxW(HWND hWnd, const WCHAR *lpText, const WCHAR *lpCaption, UINT uType, WORD wLanguageId, DWORD f)
Definition: msi.c:2461
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 100 of file msiexec.c.

101{
102 struct string_list *entry;
103
105 if(!entry)
106 {
107 WINE_ERR("Out of memory!\n");
108 ExitProcess(1);
109 }
110 lstrcpyW(entry->str, str);
111 entry->next = NULL;
112
113 /*
114 * Ignoring o(n^2) time complexity to add n strings for simplicity,
115 * add the string to the end of the list to preserve the order.
116 */
117 while( *list )
118 list = &(*list)->next;
119 *list = entry;
120}
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 616 of file msiexec.c.

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