ReactOS 0.4.16-dev-178-g8ba6102
msiexec.c
Go to the documentation of this file.
1/*
2 * msiexec.exe implementation
3 *
4 * Copyright 2004 Vincent BĂ©ron
5 * Copyright 2005 Mike McCormack
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#define WIN32_LEAN_AND_MEAN
23
24#include <windows.h>
25#include <commctrl.h>
26#include <msi.h>
27#include <winsvc.h>
28#include <objbase.h>
29
30#include "wine/debug.h"
31#include "msiexec_internal.h"
32
33#include "initguid.h"
34DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
35
37
40
41DWORD DoService(void);
42static BOOL silent;
43
44struct string_list
45{
46 struct string_list *next;
48};
49
50void report_error(const char* msg, ...)
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}
64
65static void ShowUsage(int ExitCode)
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}
104
106{
107 GUID ProductCode;
108
109 if(lstrlenW(str) != 38)
110 return FALSE;
111 return ( (CLSIDFromString(str, &ProductCode) == NOERROR) );
112
113}
114
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}
136
137static LPWSTR build_properties(struct string_list *property_list)
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}
184
185static LPWSTR build_transforms(struct string_list *transform_list)
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}
212
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}
224
225/* str1 is the same as str2, ignoring case */
226static BOOL msi_strequal(LPCWSTR str1, LPCSTR str2)
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}
242
243/* prefix is hyphen or dash, and str1 is the same as str2, ignoring case */
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}
252
253/* str2 is at the beginning of str1, ignoring case */
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}
270
271/* prefix is hyphen or dash, and str2 is at the beginning of str1, ignoring case */
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}
280
281static VOID *LoadProc(LPCWSTR DllName, LPCSTR ProcName, HMODULE* DllHandle)
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}
302
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}
322
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}
342
343static DWORD DoRegServer(void)
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}
370
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}
398
400
402
404{
405 GUID guid = *(GUID *)arg;
406 free(arg);
408}
409
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}
465
466/*
467 * state machine to break up the command line properly
468 */
469
471{
476
477static int chomp( const WCHAR *in, WCHAR *out )
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}
541
542static void process_args( WCHAR *cmdline, int *pargc, WCHAR ***pargv )
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}
570
571static BOOL process_args_from_reg( const WCHAR *ident, int *pargc, WCHAR ***pargv )
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}
605
606static WCHAR *get_path_with_extension(const WCHAR *package_name)
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}
630
631int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
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
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
static int state
Definition: maze.c:121
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:20
#define ERR(fmt,...)
Definition: precomp.h:57
static HANDLE thread
Definition: service.c:33
#define RegCloseKey(hKey)
Definition: registry.h:49
HINSTANCE hInstance
Definition: charmap.c:19
Definition: list.h:37
struct list * next
Definition: list.h:38
VOID WINAPI InitCommonControls(void)
Definition: commctrl.c:870
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
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
#define CDECL
Definition: compat.h:29
#define wcschr
Definition: compat.h:17
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define FreeLibrary(x)
Definition: compat.h:748
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
static const WCHAR *const ext[]
Definition: module.c:53
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1487
LPWSTR WINAPI GetCommandLineW(VOID)
Definition: proc.c:2019
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
LCID WINAPI GetThreadLocale(void)
Definition: locale.c:2801
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: locale.c:4014
LANGID WINAPI GetUserDefaultLangID(void)
Definition: locale.c:1177
UINT WINAPI MsiGetFileVersionW(const WCHAR *path, WCHAR *verbuf, DWORD *verlen, WCHAR *langbuf, DWORD *langlen)
Definition: msi.c:3208
UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
Definition: msi.c:831
UINT WINAPI MsiMessageBoxW(HWND hWnd, const WCHAR *lpText, const WCHAR *lpCaption, UINT uType, WORD wLanguageId, DWORD f)
Definition: msi.c:2458
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
UINT WINAPI MsiMessageBoxA(HWND hWnd, const char *lpText, const char *lpCaption, UINT uType, WORD wLanguageId, DWORD f)
Definition: msi.c:2451
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
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define swprintf
Definition: precomp.h:40
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint in
Definition: glext.h:9616
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
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
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
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
#define GUID_NULL
Definition: ks.h:106
#define REG_SZ
Definition: layer.c:22
USHORT LANGID
Definition: mui.h:9
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
const GUID * guid
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define MESSAGE
Definition: options.h:86
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static PVOID ptr
Definition: dispmode.c:27
WCHAR strW[12]
Definition: clipboard.c:2029
#define argv
Definition: mplay32.c:18
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
HRESULT(WINAPI * DLLUNREGISTERSERVER)(void)
Definition: msiexec.c:39
static BOOL msi_strprefix(LPCWSTR str1, LPCSTR str2)
Definition: msiexec.c:254
static DWORD DoUnregServer(void)
Definition: msiexec.c:371
static DWORD DoDllRegisterServer(LPCWSTR DllName)
Definition: msiexec.c:303
void report_error(const char *msg,...)
Definition: msiexec.c:50
static void ShowUsage(int ExitCode)
Definition: msiexec.c:65
static VOID * LoadProc(LPCWSTR DllName, LPCSTR ProcName, HMODULE *DllHandle)
Definition: msiexec.c:281
static int chomp(const WCHAR *in, WCHAR *out)
Definition: msiexec.c:477
static LPWSTR build_transforms(struct string_list *transform_list)
Definition: msiexec.c:185
chomp_state
Definition: msiexec.c:471
@ CS_TOKEN
Definition: msiexec.c:473
@ CS_WHITESPACE
Definition: msiexec.c:472
@ CS_QUOTE
Definition: msiexec.c:474
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
Definition: msiexec.c:631
static int custom_action_server(const WCHAR *arg)
Definition: msiexec.c:410
static DWORD client_pid
Definition: msiexec.c:401
UINT CDECL __wine_msi_call_dll_function(DWORD client_pid, const GUID *guid)
Definition: custom.c:508
static BOOL msi_strequal(LPCWSTR str1, LPCSTR str2)
Definition: msiexec.c:226
static BOOL silent
Definition: msiexec.c:42
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 void process_args(WCHAR *cmdline, int *pargc, WCHAR ***pargv)
Definition: msiexec.c:542
static DWORD DoRegServer(void)
Definition: msiexec.c:343
static DWORD CALLBACK custom_action_thread(void *arg)
Definition: msiexec.c:403
HRESULT(WINAPI * DLLREGISTERSERVER)(void)
Definition: msiexec.c:38
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
unsigned int UINT
Definition: ndis.h:50
#define GENERIC_ALL
Definition: nt_native.h:92
#define DELETE
Definition: nt_native.h:57
#define GENERIC_WRITE
Definition: nt_native.h:90
_Must_inspect_result_ _In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PUNICODE_STRING LogFileName
Definition: nttmapi.h:324
#define L(x)
Definition: ntvdm.h:50
@ COINIT_MULTITHREADED
Definition: objbase.h:279
static HANDLE proc()
Definition: pdb.c:34
long LONG
Definition: pedump.c:60
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
Definition: guiddef.h:68
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
static FILE * out
Definition: regtests2xml.c:44
#define list
Definition: rosglue.h:35
const WCHAR * str
BOOL WINAPI DeleteService(SC_HANDLE hService)
Definition: scm.c:921
SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:2068
SC_HANDLE WINAPI OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2160
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 WINE_TRACE
Definition: debug.h:354
#define WINE_FIXME
Definition: debug.h:366
#define WINE_ERR
Definition: debug.h:371
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
TCHAR * cmdline
Definition: stretchblt.cpp:32
struct string_list * next
Definition: dhcpd.h:121
WCHAR str[1]
Definition: msiexec.c:47
#define vsnprintf
Definition: tif_win32.c:406
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint64_t DWORD64
Definition: typedefs.h:67
unsigned char * LPBYTE
Definition: typedefs.h:53
Definition: pdh_main.c:94
int ret
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LOAD_WITH_ALTERED_SEARCH_PATH
Definition: winbase.h:344
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define ERROR_SERVICE_DOES_NOT_EXIST
Definition: winerror.h:611
#define NOERROR
Definition: winerror.h:2354
#define ERROR_SERVICE_EXISTS
Definition: winerror.h:624
#define NORM_IGNORECASE
Definition: winnls.h:176
#define CSTR_EQUAL
Definition: winnls.h:456
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define SC_MANAGER_CREATE_SERVICE
Definition: winsvc.h:15
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
#define SERVICES_ACTIVE_DATABASEW
Definition: winsvc.h:8
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#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
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185