ReactOS  0.4.12-dev-919-gfc3b8d5
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 <msi.h>
26 #include <winsvc.h>
27 #include <objbase.h>
28 #include <stdio.h>
29 
30 #include "wine/debug.h"
31 #include "wine/unicode.h"
32 
34 
37 
38 DWORD DoService(void);
39 
40 struct string_list
41 {
42  struct string_list *next;
43  WCHAR str[1];
44 };
45 
46 static const WCHAR ActionAdmin[] = {
47  'A','C','T','I','O','N','=','A','D','M','I','N',0 };
48 static const WCHAR RemoveAll[] = {
49  'R','E','M','O','V','E','=','A','L','L',0 };
50 
51 static const WCHAR InstallRunOnce[] = {
52  'S','o','f','t','w','a','r','e','\\',
53  'M','i','c','r','o','s','o','f','t','\\',
54  'W','i','n','d','o','w','s','\\',
55  'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
56  'I','n','s','t','a','l','l','e','r','\\',
57  'R','u','n','O','n','c','e','E','n','t','r','i','e','s',0};
58 
59 static void ShowUsage(int ExitCode)
60 {
61  WCHAR msiexec_version[40];
63  LPWSTR msi_res;
64  LPWSTR msiexec_help;
65  HMODULE hmsi = GetModuleHandleA("msi.dll");
66  DWORD len;
67  DWORD res;
68 
69  /* MsiGetFileVersion need the full path */
70  *filename = 0;
71  res = GetModuleFileNameW(hmsi, filename, sizeof(filename) / sizeof(filename[0]));
72  if (!res)
73  WINE_ERR("GetModuleFileName failed: %d\n", GetLastError());
74 
75  len = sizeof(msiexec_version) / sizeof(msiexec_version[0]);
76  *msiexec_version = 0;
77  res = MsiGetFileVersionW(filename, msiexec_version, &len, NULL, NULL);
78  if (res)
79  WINE_ERR("MsiGetFileVersion failed with %d\n", res);
80 
81  /* Return the length of the resource.
82  No typo: The LPWSTR parameter must be a LPWSTR * for this mode */
83  len = LoadStringW(hmsi, 10, (LPWSTR) &msi_res, 0);
84 
85  msi_res = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
86  msiexec_help = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) + sizeof(msiexec_version));
87  if (msi_res && msiexec_help) {
88  *msi_res = 0;
89  LoadStringW(hmsi, 10, msi_res, len + 1);
90 
91  sprintfW(msiexec_help, msi_res, msiexec_version);
92  MsiMessageBoxW(0, msiexec_help, NULL, 0, GetUserDefaultLangID(), 0);
93  }
94  HeapFree(GetProcessHeap(), 0, msi_res);
95  HeapFree(GetProcessHeap(), 0, msiexec_help);
96  ExitProcess(ExitCode);
97 }
98 
100 {
101  GUID ProductCode;
102 
103  if(lstrlenW(str) != 38)
104  return FALSE;
105  return ( (CLSIDFromString(str, &ProductCode) == NOERROR) );
106 
107 }
108 
110 {
111  struct string_list *entry;
112 
114  if(!entry)
115  {
116  WINE_ERR("Out of memory!\n");
117  ExitProcess(1);
118  }
119  lstrcpyW(entry->str, str);
120  entry->next = NULL;
121 
122  /*
123  * Ignoring o(n^2) time complexity to add n strings for simplicity,
124  * add the string to the end of the list to preserve the order.
125  */
126  while( *list )
127  list = &(*list)->next;
128  *list = entry;
129 }
130 
131 static LPWSTR build_properties(struct string_list *property_list)
132 {
133  struct string_list *list;
134  LPWSTR ret, p, value;
135  DWORD len;
136  BOOL needs_quote;
137 
138  if(!property_list)
139  return NULL;
140 
141  /* count the space we need */
142  len = 1;
143  for(list = property_list; list; list = list->next)
144  len += lstrlenW(list->str) + 3;
145 
146  ret = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
147 
148  /* add a space before each string, and quote the value */
149  p = ret;
150  for(list = property_list; list; list = list->next)
151  {
152  value = strchrW(list->str,'=');
153  if(!value)
154  continue;
155  len = value - list->str;
156  *p++ = ' ';
157  memcpy(p, list->str, len * sizeof(WCHAR));
158  p += len;
159  *p++ = '=';
160 
161  /* check if the value contains spaces and maybe quote it */
162  value++;
163  needs_quote = strchrW(value,' ') ? 1 : 0;
164  if(needs_quote)
165  *p++ = '"';
166  len = lstrlenW(value);
167  memcpy(p, value, len * sizeof(WCHAR));
168  p += len;
169  if(needs_quote)
170  *p++ = '"';
171  }
172  *p = 0;
173 
174  WINE_TRACE("properties -> %s\n", wine_dbgstr_w(ret) );
175 
176  return ret;
177 }
178 
179 static LPWSTR build_transforms(struct string_list *transform_list)
180 {
181  struct string_list *list;
182  LPWSTR ret, p;
183  DWORD len;
184 
185  /* count the space we need */
186  len = 1;
187  for(list = transform_list; list; list = list->next)
188  len += lstrlenW(list->str) + 1;
189 
190  ret = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
191 
192  /* add all the transforms with a semicolon between each one */
193  p = ret;
194  for(list = transform_list; list; list = list->next)
195  {
196  len = lstrlenW(list->str);
197  lstrcpynW(p, list->str, len );
198  p += len;
199  if(list->next)
200  *p++ = ';';
201  }
202  *p = 0;
203 
204  return ret;
205 }
206 
208 {
209  DWORD ret = 0;
210  while(*str >= '0' && *str <= '9')
211  {
212  ret *= 10;
213  ret += (*str - '0');
214  str++;
215  }
216  return ret;
217 }
218 
219 /* str1 is the same as str2, ignoring case */
220 static BOOL msi_strequal(LPCWSTR str1, LPCSTR str2)
221 {
222  DWORD len, ret;
223  LPWSTR strW;
224 
225  len = MultiByteToWideChar( CP_ACP, 0, str2, -1, NULL, 0);
226  if( !len )
227  return FALSE;
228  if( lstrlenW(str1) != (len-1) )
229  return FALSE;
230  strW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len);
231  MultiByteToWideChar( CP_ACP, 0, str2, -1, strW, len);
234  return (ret == CSTR_EQUAL);
235 }
236 
237 /* prefix is hyphen or dash, and str1 is the same as str2, ignoring case */
239 {
240  if (str1[0] != '/' && str1[0] != '-')
241  return FALSE;
242 
243  /* skip over the hyphen or slash */
244  return msi_strequal(str1 + 1, str2);
245 }
246 
247 /* str2 is at the beginning of str1, ignoring case */
248 static BOOL msi_strprefix(LPCWSTR str1, LPCSTR str2)
249 {
250  DWORD len, ret;
251  LPWSTR strW;
252 
253  len = MultiByteToWideChar( CP_ACP, 0, str2, -1, NULL, 0);
254  if( !len )
255  return FALSE;
256  if( lstrlenW(str1) < (len-1) )
257  return FALSE;
258  strW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len);
259  MultiByteToWideChar( CP_ACP, 0, str2, -1, strW, len);
262  return (ret == CSTR_EQUAL);
263 }
264 
265 /* prefix is hyphen or dash, and str2 is at the beginning of str1, ignoring case */
267 {
268  if (str1[0] != '/' && str1[0] != '-')
269  return FALSE;
270 
271  /* skip over the hyphen or slash */
272  return msi_strprefix(str1 + 1, str2);
273 }
274 
275 static VOID *LoadProc(LPCWSTR DllName, LPCSTR ProcName, HMODULE* DllHandle)
276 {
277  VOID* (*proc)(void);
278 
279  *DllHandle = LoadLibraryExW(DllName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
280  if(!*DllHandle)
281  {
282  fprintf(stderr, "Unable to load dll %s\n", wine_dbgstr_w(DllName));
283  ExitProcess(1);
284  }
285  proc = (VOID *) GetProcAddress(*DllHandle, ProcName);
286  if(!proc)
287  {
288  fprintf(stderr, "Dll %s does not implement function %s\n",
289  wine_dbgstr_w(DllName), ProcName);
290  FreeLibrary(*DllHandle);
291  ExitProcess(1);
292  }
293 
294  return proc;
295 }
296 
298 {
299  HRESULT hr;
300  DLLREGISTERSERVER pfDllRegisterServer = NULL;
301  HMODULE DllHandle = NULL;
302 
303  pfDllRegisterServer = LoadProc(DllName, "DllRegisterServer", &DllHandle);
304 
305  hr = pfDllRegisterServer();
306  if(FAILED(hr))
307  {
308  fprintf(stderr, "Failed to register dll %s\n", wine_dbgstr_w(DllName));
309  return 1;
310  }
311  printf("Successfully registered dll %s\n", wine_dbgstr_w(DllName));
312  if(DllHandle)
313  FreeLibrary(DllHandle);
314  return 0;
315 }
316 
318 {
319  HRESULT hr;
320  DLLUNREGISTERSERVER pfDllUnregisterServer = NULL;
321  HMODULE DllHandle = NULL;
322 
323  pfDllUnregisterServer = LoadProc(DllName, "DllUnregisterServer", &DllHandle);
324 
325  hr = pfDllUnregisterServer();
326  if(FAILED(hr))
327  {
328  fprintf(stderr, "Failed to unregister dll %s\n", wine_dbgstr_w(DllName));
329  return 1;
330  }
331  printf("Successfully unregistered dll %s\n", wine_dbgstr_w(DllName));
332  if(DllHandle)
333  FreeLibrary(DllHandle);
334  return 0;
335 }
336 
337 static DWORD DoRegServer(void)
338 {
339  static const WCHAR msiserverW[] = {'M','S','I','S','e','r','v','e','r',0};
340  static const WCHAR msiexecW[] = {'\\','m','s','i','e','x','e','c',' ','/','V',0};
341  SC_HANDLE scm, service;
342  WCHAR path[MAX_PATH+12];
343  DWORD len, ret = 0;
344 
346  {
347  fprintf(stderr, "Failed to open the service control manager.\n");
348  return 1;
349  }
351  lstrcpyW(path + len, msiexecW);
352  if ((service = CreateServiceW(scm, msiserverW, msiserverW, GENERIC_ALL,
355  {
356  CloseServiceHandle(service);
357  }
358  else if (GetLastError() != ERROR_SERVICE_EXISTS)
359  {
360  fprintf(stderr, "Failed to create MSI service\n");
361  ret = 1;
362  }
363  CloseServiceHandle(scm);
364  return ret;
365 }
366 
367 static DWORD DoUnregServer(void)
368 {
369  static const WCHAR msiserverW[] = {'M','S','I','S','e','r','v','e','r',0};
370  SC_HANDLE scm, service;
371  DWORD ret = 0;
372 
374  {
375  fprintf(stderr, "Failed to open service control manager\n");
376  return 1;
377  }
378  if ((service = OpenServiceW(scm, msiserverW, DELETE)))
379  {
380  if (!DeleteService(service))
381  {
382  fprintf(stderr, "Failed to delete MSI service\n");
383  ret = 1;
384  }
385  CloseServiceHandle(service);
386  }
388  {
389  fprintf(stderr, "Failed to open MSI service\n");
390  ret = 1;
391  }
392  CloseServiceHandle(scm);
393  return ret;
394 }
395 
397 {
398  printf("Remote custom actions are not supported yet\n");
399  return 1;
400 }
401 
402 /*
403  * state machine to break up the command line properly
404  */
405 
407 {
411 };
412 
413 static int chomp( const WCHAR *in, WCHAR *out )
414 {
415  enum chomp_state state = CS_TOKEN;
416  const WCHAR *p;
417  int count = 1;
418  BOOL ignore;
419 
420  for (p = in; *p; p++)
421  {
422  ignore = TRUE;
423  switch (state)
424  {
425  case CS_WHITESPACE:
426  switch (*p)
427  {
428  case ' ':
429  break;
430  case '"':
431  state = CS_QUOTE;
432  count++;
433  break;
434  default:
435  count++;
436  ignore = FALSE;
437  state = CS_TOKEN;
438  }
439  break;
440 
441  case CS_TOKEN:
442  switch (*p)
443  {
444  case '"':
445  state = CS_QUOTE;
446  break;
447  case ' ':
449  if (out) *out++ = 0;
450  break;
451  default:
452  if (p > in && p[-1] == '"')
453  {
454  if (out) *out++ = 0;
455  count++;
456  }
457  ignore = FALSE;
458  }
459  break;
460 
461  case CS_QUOTE:
462  switch (*p)
463  {
464  case '"':
465  state = CS_TOKEN;
466  break;
467  default:
468  ignore = FALSE;
469  }
470  break;
471  }
472  if (!ignore && out) *out++ = *p;
473  }
474  if (out) *out = 0;
475  return count;
476 }
477 
478 static void process_args( WCHAR *cmdline, int *pargc, WCHAR ***pargv )
479 {
480  WCHAR **argv, *p;
481  int i, count;
482 
483  *pargc = 0;
484  *pargv = NULL;
485 
486  count = chomp( cmdline, NULL );
487  if (!(p = HeapAlloc( GetProcessHeap(), 0, (lstrlenW(cmdline) + count + 1) * sizeof(WCHAR) )))
488  return;
489 
490  count = chomp( cmdline, p );
491  if (!(argv = HeapAlloc( GetProcessHeap(), 0, (count + 1) * sizeof(WCHAR *) )))
492  {
493  HeapFree( GetProcessHeap(), 0, p );
494  return;
495  }
496  for (i = 0; i < count; i++)
497  {
498  argv[i] = p;
499  p += lstrlenW( p ) + 1;
500  }
501  argv[i] = NULL;
502 
503  *pargc = count;
504  *pargv = argv;
505 }
506 
507 static BOOL process_args_from_reg( const WCHAR *ident, int *pargc, WCHAR ***pargv )
508 {
509  LONG r;
510  HKEY hkey;
511  DWORD sz = 0, type = 0;
512  WCHAR *buf;
513  BOOL ret = FALSE;
514 
516  if(r != ERROR_SUCCESS)
517  return FALSE;
518  r = RegQueryValueExW(hkey, ident, 0, &type, 0, &sz);
519  if(r == ERROR_SUCCESS && type == REG_SZ)
520  {
521  int len = lstrlenW( *pargv[0] );
522  if (!(buf = HeapAlloc( GetProcessHeap(), 0, sz + (len + 1) * sizeof(WCHAR) )))
523  {
524  RegCloseKey( hkey );
525  return FALSE;
526  }
527  memcpy( buf, *pargv[0], len * sizeof(WCHAR) );
528  buf[len++] = ' ';
529  r = RegQueryValueExW(hkey, ident, 0, &type, (LPBYTE)(buf + len), &sz);
530  if( r == ERROR_SUCCESS )
531  {
532  process_args(buf, pargc, pargv);
533  ret = TRUE;
534  }
535  HeapFree(GetProcessHeap(), 0, buf);
536  }
537  RegCloseKey(hkey);
538  return ret;
539 }
540 
541 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
542 {
543  int i;
544  BOOL FunctionInstall = FALSE;
545  BOOL FunctionInstallAdmin = FALSE;
546  BOOL FunctionRepair = FALSE;
547  BOOL FunctionAdvertise = FALSE;
548  BOOL FunctionPatch = FALSE;
549  BOOL FunctionDllRegisterServer = FALSE;
550  BOOL FunctionDllUnregisterServer = FALSE;
551  BOOL FunctionRegServer = FALSE;
552  BOOL FunctionUnregServer = FALSE;
553  BOOL FunctionServer = FALSE;
554  BOOL FunctionUnknown = FALSE;
555 
556  LPWSTR PackageName = NULL;
557  LPWSTR Properties = NULL;
558  struct string_list *property_list = NULL;
559 
560  DWORD RepairMode = 0;
561 
562  DWORD_PTR AdvertiseMode = 0;
563  struct string_list *transform_list = NULL;
564  LANGID Language = 0;
565 
566  DWORD LogMode = 0;
568  DWORD LogAttributes = 0;
569 
570  LPWSTR PatchFileName = NULL;
571  INSTALLTYPE InstallType = INSTALLTYPE_DEFAULT;
572 
573  INSTALLUILEVEL InstallUILevel = INSTALLUILEVEL_FULL;
574 
575  LPWSTR DllName = NULL;
576  DWORD ReturnCode;
577  int argc;
578  LPWSTR *argvW = NULL;
579 
580  /* parse the command line */
581  process_args( GetCommandLineW(), &argc, &argvW );
582 
583  /*
584  * If the args begin with /@ IDENT then we need to load the real
585  * command line out of the RunOnceEntries key in the registry.
586  * We do that before starting to process the real commandline,
587  * then overwrite the commandline again.
588  */
589  if(argc>1 && msi_option_equal(argvW[1], "@"))
590  {
591  if(!process_args_from_reg( argvW[2], &argc, &argvW ))
592  return 1;
593  }
594 
595  if (argc == 3 && msi_option_equal(argvW[1], "Embedding"))
596  return DoEmbedding( argvW[2] );
597 
598  for(i = 1; i < argc; i++)
599  {
600  WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
601 
602  if (msi_option_equal(argvW[i], "regserver"))
603  {
604  FunctionRegServer = TRUE;
605  }
606  else if (msi_option_equal(argvW[i], "unregserver") || msi_option_equal(argvW[i], "unregister")
607  || msi_option_equal(argvW[i], "unreg"))
608  {
609  FunctionUnregServer = TRUE;
610  }
611  else if(msi_option_prefix(argvW[i], "i") || msi_option_prefix(argvW[i], "package"))
612  {
613  LPWSTR argvWi = argvW[i];
614  int argLen = (msi_option_prefix(argvW[i], "i") ? 2 : 8);
615  FunctionInstall = TRUE;
616  if(lstrlenW(argvW[i]) > argLen)
617  argvWi += argLen;
618  else
619  {
620  i++;
621  if(i >= argc)
622  ShowUsage(1);
623  WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
624  argvWi = argvW[i];
625  }
626  PackageName = argvWi;
627  }
628  else if(msi_option_equal(argvW[i], "a"))
629  {
630  FunctionInstall = TRUE;
631  FunctionInstallAdmin = TRUE;
632  InstallType = INSTALLTYPE_NETWORK_IMAGE;
633  i++;
634  if(i >= argc)
635  ShowUsage(1);
636  WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
637  PackageName = argvW[i];
638  StringListAppend(&property_list, ActionAdmin);
639  WINE_FIXME("Administrative installs are not currently supported\n");
640  }
641  else if(msi_option_prefix(argvW[i], "f"))
642  {
643  int j;
644  int len = lstrlenW(argvW[i]);
645  FunctionRepair = TRUE;
646  for(j = 2; j < len; j++)
647  {
648  switch(argvW[i][j])
649  {
650  case 'P':
651  case 'p':
652  RepairMode |= REINSTALLMODE_FILEMISSING;
653  break;
654  case 'O':
655  case 'o':
656  RepairMode |= REINSTALLMODE_FILEOLDERVERSION;
657  break;
658  case 'E':
659  case 'e':
660  RepairMode |= REINSTALLMODE_FILEEQUALVERSION;
661  break;
662  case 'D':
663  case 'd':
664  RepairMode |= REINSTALLMODE_FILEEXACT;
665  break;
666  case 'C':
667  case 'c':
668  RepairMode |= REINSTALLMODE_FILEVERIFY;
669  break;
670  case 'A':
671  case 'a':
672  RepairMode |= REINSTALLMODE_FILEREPLACE;
673  break;
674  case 'U':
675  case 'u':
676  RepairMode |= REINSTALLMODE_USERDATA;
677  break;
678  case 'M':
679  case 'm':
680  RepairMode |= REINSTALLMODE_MACHINEDATA;
681  break;
682  case 'S':
683  case 's':
684  RepairMode |= REINSTALLMODE_SHORTCUT;
685  break;
686  case 'V':
687  case 'v':
688  RepairMode |= REINSTALLMODE_PACKAGE;
689  break;
690  default:
691  fprintf(stderr, "Unknown option \"%c\" in Repair mode\n", argvW[i][j]);
692  break;
693  }
694  }
695  if(len == 2)
696  {
697  RepairMode = REINSTALLMODE_FILEMISSING |
702  }
703  i++;
704  if(i >= argc)
705  ShowUsage(1);
706  WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
707  PackageName = argvW[i];
708  }
709  else if(msi_option_prefix(argvW[i], "x") || msi_option_equal(argvW[i], "uninstall"))
710  {
711  FunctionInstall = TRUE;
712  if(msi_option_prefix(argvW[i], "x")) PackageName = argvW[i]+2;
713  if(!PackageName || !PackageName[0])
714  {
715  i++;
716  if (i >= argc)
717  ShowUsage(1);
718  PackageName = argvW[i];
719  }
720  WINE_TRACE("PackageName = %s\n", wine_dbgstr_w(PackageName));
721  StringListAppend(&property_list, RemoveAll);
722  }
723  else if(msi_option_prefix(argvW[i], "j"))
724  {
725  int j;
726  int len = lstrlenW(argvW[i]);
727  FunctionAdvertise = TRUE;
728  for(j = 2; j < len; j++)
729  {
730  switch(argvW[i][j])
731  {
732  case 'U':
733  case 'u':
734  AdvertiseMode = ADVERTISEFLAGS_USERASSIGN;
735  break;
736  case 'M':
737  case 'm':
738  AdvertiseMode = ADVERTISEFLAGS_MACHINEASSIGN;
739  break;
740  default:
741  fprintf(stderr, "Unknown option \"%c\" in Advertise mode\n", argvW[i][j]);
742  break;
743  }
744  }
745  i++;
746  if(i >= argc)
747  ShowUsage(1);
748  WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
749  PackageName = argvW[i];
750  }
751  else if(msi_strequal(argvW[i], "u"))
752  {
753  FunctionAdvertise = TRUE;
754  AdvertiseMode = ADVERTISEFLAGS_USERASSIGN;
755  i++;
756  if(i >= argc)
757  ShowUsage(1);
758  WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
759  PackageName = argvW[i];
760  }
761  else if(msi_strequal(argvW[i], "m"))
762  {
763  FunctionAdvertise = TRUE;
764  AdvertiseMode = ADVERTISEFLAGS_MACHINEASSIGN;
765  i++;
766  if(i >= argc)
767  ShowUsage(1);
768  WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
769  PackageName = argvW[i];
770  }
771  else if(msi_option_equal(argvW[i], "t"))
772  {
773  i++;
774  if(i >= argc)
775  ShowUsage(1);
776  WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
777  StringListAppend(&transform_list, argvW[i]);
778  }
779  else if(msi_option_equal(argvW[i], "g"))
780  {
781  i++;
782  if(i >= argc)
783  ShowUsage(1);
784  WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
785  Language = msi_atou(argvW[i]);
786  }
787  else if(msi_option_prefix(argvW[i], "l"))
788  {
789  int j;
790  int len = lstrlenW(argvW[i]);
791  for(j = 2; j < len; j++)
792  {
793  switch(argvW[i][j])
794  {
795  case 'I':
796  case 'i':
797  LogMode |= INSTALLLOGMODE_INFO;
798  break;
799  case 'W':
800  case 'w':
801  LogMode |= INSTALLLOGMODE_WARNING;
802  break;
803  case 'E':
804  case 'e':
805  LogMode |= INSTALLLOGMODE_ERROR;
806  break;
807  case 'A':
808  case 'a':
809  LogMode |= INSTALLLOGMODE_ACTIONSTART;
810  break;
811  case 'R':
812  case 'r':
813  LogMode |= INSTALLLOGMODE_ACTIONDATA;
814  break;
815  case 'U':
816  case 'u':
817  LogMode |= INSTALLLOGMODE_USER;
818  break;
819  case 'C':
820  case 'c':
821  LogMode |= INSTALLLOGMODE_COMMONDATA;
822  break;
823  case 'M':
824  case 'm':
825  LogMode |= INSTALLLOGMODE_FATALEXIT;
826  break;
827  case 'O':
828  case 'o':
830  break;
831  case 'P':
832  case 'p':
833  LogMode |= INSTALLLOGMODE_PROPERTYDUMP;
834  break;
835  case 'V':
836  case 'v':
837  LogMode |= INSTALLLOGMODE_VERBOSE;
838  break;
839  case '*':
840  LogMode = INSTALLLOGMODE_FATALEXIT |
855  break;
856  case '+':
857  LogAttributes |= INSTALLLOGATTRIBUTES_APPEND;
858  break;
859  case '!':
860  LogAttributes |= INSTALLLOGATTRIBUTES_FLUSHEACHLINE;
861  break;
862  default:
863  break;
864  }
865  }
866  i++;
867  if(i >= argc)
868  ShowUsage(1);
869  WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
870  LogFileName = argvW[i];
871  if(MsiEnableLogW(LogMode, LogFileName, LogAttributes) != ERROR_SUCCESS)
872  {
873  fprintf(stderr, "Logging in %s (0x%08x, %u) failed\n",
874  wine_dbgstr_w(LogFileName), LogMode, LogAttributes);
875  ExitProcess(1);
876  }
877  }
878  else if(msi_option_equal(argvW[i], "p") || msi_option_equal(argvW[i], "update"))
879  {
880  FunctionPatch = TRUE;
881  i++;
882  if(i >= argc)
883  ShowUsage(1);
884  WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
885  PatchFileName = argvW[i];
886  }
887  else if(msi_option_prefix(argvW[i], "q"))
888  {
889  if(lstrlenW(argvW[i]) == 2 || msi_strequal(argvW[i]+2, "n") ||
890  msi_strequal(argvW[i] + 2, "uiet"))
891  {
892  InstallUILevel = INSTALLUILEVEL_NONE;
893  }
894  else if(msi_strequal(argvW[i]+2, "r"))
895  {
896  InstallUILevel = INSTALLUILEVEL_REDUCED;
897  }
898  else if(msi_strequal(argvW[i]+2, "f"))
899  {
901  }
902  else if(msi_strequal(argvW[i]+2, "n+"))
903  {
905  }
906  else if(msi_strprefix(argvW[i]+2, "b"))
907  {
908  const WCHAR *ptr = argvW[i] + 3;
909 
910  InstallUILevel = INSTALLUILEVEL_BASIC;
911 
912  while (*ptr)
913  {
914  if (msi_strprefix(ptr, "+"))
915  InstallUILevel |= INSTALLUILEVEL_ENDDIALOG;
916  if (msi_strprefix(ptr, "-"))
917  InstallUILevel |= INSTALLUILEVEL_PROGRESSONLY;
918  if (msi_strprefix(ptr, "!"))
919  {
920  WINE_FIXME("Unhandled modifier: !\n");
921  InstallUILevel |= INSTALLUILEVEL_HIDECANCEL;
922  }
923  ptr++;
924  }
925  }
926  else
927  {
928  fprintf(stderr, "Unknown option \"%s\" for UI level\n",
929  wine_dbgstr_w(argvW[i]+2));
930  }
931  }
932  else if(msi_option_equal(argvW[i], "passive"))
933  {
934  static const WCHAR rebootpromptW[] =
935  {'R','E','B','O','O','T','P','R','O','M','P','T','=','"','S','"',0};
936 
938  StringListAppend(&property_list, rebootpromptW);
939  }
940  else if(msi_option_equal(argvW[i], "y"))
941  {
942  FunctionDllRegisterServer = TRUE;
943  i++;
944  if(i >= argc)
945  ShowUsage(1);
946  WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
947  DllName = argvW[i];
948  }
949  else if(msi_option_equal(argvW[i], "z"))
950  {
951  FunctionDllUnregisterServer = TRUE;
952  i++;
953  if(i >= argc)
954  ShowUsage(1);
955  WINE_TRACE("argvW[%d] = %s\n", i, wine_dbgstr_w(argvW[i]));
956  DllName = argvW[i];
957  }
958  else if(msi_option_equal(argvW[i], "help") || msi_option_equal(argvW[i], "?"))
959  {
960  ShowUsage(0);
961  }
962  else if(msi_option_equal(argvW[i], "m"))
963  {
964  FunctionUnknown = TRUE;
965  WINE_FIXME("Unknown parameter /m\n");
966  }
967  else if(msi_option_equal(argvW[i], "D"))
968  {
969  FunctionUnknown = TRUE;
970  WINE_FIXME("Unknown parameter /D\n");
971  }
972  else if (msi_option_equal(argvW[i], "V"))
973  {
974  FunctionServer = TRUE;
975  }
976  else
977  StringListAppend(&property_list, argvW[i]);
978  }
979 
980  /* start the GUI */
981  MsiSetInternalUI(InstallUILevel, NULL);
982 
983  Properties = build_properties( property_list );
984 
985  if(FunctionInstallAdmin && FunctionPatch)
986  FunctionInstall = FALSE;
987 
988  ReturnCode = 1;
989  if(FunctionInstall)
990  {
991  if(IsProductCode(PackageName))
992  ReturnCode = MsiConfigureProductExW(PackageName, 0, INSTALLSTATE_DEFAULT, Properties);
993  else
994  ReturnCode = MsiInstallProductW(PackageName, Properties);
995  }
996  else if(FunctionRepair)
997  {
998  if(IsProductCode(PackageName))
999  WINE_FIXME("Product code treatment not implemented yet\n");
1000  else
1001  ReturnCode = MsiReinstallProductW(PackageName, RepairMode);
1002  }
1003  else if(FunctionAdvertise)
1004  {
1005  LPWSTR Transforms = build_transforms( property_list );
1006  ReturnCode = MsiAdvertiseProductW(PackageName, (LPWSTR) AdvertiseMode, Transforms, Language);
1007  }
1008  else if(FunctionPatch)
1009  {
1010  ReturnCode = MsiApplyPatchW(PatchFileName, PackageName, InstallType, Properties);
1011  }
1012  else if(FunctionDllRegisterServer)
1013  {
1014  ReturnCode = DoDllRegisterServer(DllName);
1015  }
1016  else if(FunctionDllUnregisterServer)
1017  {
1018  ReturnCode = DoDllUnregisterServer(DllName);
1019  }
1020  else if (FunctionRegServer)
1021  {
1022  ReturnCode = DoRegServer();
1023  }
1024  else if (FunctionUnregServer)
1025  {
1026  ReturnCode = DoUnregServer();
1027  }
1028  else if (FunctionServer)
1029  {
1030  ReturnCode = DoService();
1031  }
1032  else if (FunctionUnknown)
1033  {
1034  WINE_FIXME( "Unknown function, ignoring\n" );
1035  }
1036  else
1037  ShowUsage(1);
1038 
1039  return ReturnCode;
1040 }
static BOOL process_args_from_reg(const WCHAR *ident, int *pargc, WCHAR ***pargv)
Definition: msiexec.c:507
static void process_args(WCHAR *cmdline, int *pargc, WCHAR ***pargv)
Definition: msiexec.c:478
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:607
struct string_list * next
Definition: dhcpd.h:121
#define HRESULT
Definition: msvc.h:9
static int argc
Definition: ServiceArgs.c:12
DWORD DoService(void)
Definition: service.c:155
#define GENERIC_ALL
Definition: nt_native.h:92
#define SERVICE_ERROR_NORMAL
Definition: cmtypes.h:980
#define TRUE
Definition: types.h:120
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
HRESULT hr
Definition: shlfolder.c:183
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
enum tagINSTALLUILEVEL INSTALLUILEVEL
#define NOERROR
Definition: winerror.h:2354
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
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:808
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
WINE_UNICODE_INLINE WCHAR * strchrW(const WCHAR *str, WCHAR ch)
Definition: unicode.h:248
#define CP_ACP
Definition: compat.h:99
GLuint GLuint GLsizei count
Definition: gl.h:1545
int ignore(int trapCode, ppc_trap_frame_t *trap)
Definition: mmuobject.c:296
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:286
UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
Definition: msi.c:235
uint8_t entry
Definition: isohybrid.c:63
static INT DoEmbedding(LPWSTR key)
Definition: msiexec.c:396
static const WCHAR ActionAdmin[]
Definition: msiexec.c:46
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1517
#define WINE_TRACE
Definition: debug.h:353
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
static LPWSTR build_transforms(struct string_list *transform_list)
Definition: msiexec.c:179
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
Definition: msi.c:2313
WORD LANGID
Definition: typedefs.h:79
#define NORM_IGNORECASE
Definition: winnls.h:173
static HANDLE proc()
Definition: pdb.c:32
TCHAR * cmdline
Definition: stretchblt.cpp:32
#define LOAD_WITH_ALTERED_SEARCH_PATH
Definition: winbase.h:339
BOOL WINAPI DeleteService(SC_HANDLE hService)
Definition: scm.c:916
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
Definition: msiexec.c:541
#define argv
Definition: mplay32.c:18
char * LPSTR
Definition: xmlstorage.h:182
const char * filename
Definition: ioapi.h:135
#define lstrlenW
Definition: compat.h:407
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int32_t INT
Definition: typedefs.h:56
UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage, INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
Definition: msi.c:405
#define lstrcpynW
Definition: compat.h:397
static DWORD DoDllUnregisterServer(LPCWSTR DllName)
Definition: msiexec.c:317
UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath, LPCWSTR szTransforms, LANGID lgidLanguage)
Definition: msi.c:179
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
HINSTANCE hInstance
Definition: charmap.c:20
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned char * LPBYTE
Definition: typedefs.h:52
unsigned int BOOL
Definition: ntddk_ex.h:94
WCHAR strW[12]
Definition: clipboard.c:2029
long LONG
Definition: pedump.c:60
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
Definition: msi.c:1926
LPWSTR WINAPI GetCommandLineW(VOID)
Definition: proc.c:2043
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3311
static BOOL msi_option_prefix(LPCWSTR str1, LPCSTR str2)
Definition: msiexec.c:266
static PVOID ptr
Definition: dispmode.c:27
SC_HANDLE WINAPI OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2103
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: CString.cpp:62
UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
Definition: msi.c:833
static DWORD DoUnregServer(void)
Definition: msiexec.c:367
const WCHAR * str
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:577
#define WINE_ERR
Definition: debug.h:370
smooth NULL
Definition: ftsmooth.c:416
HRESULT(WINAPI * DLLREGISTERSERVER)(void)
Definition: msiexec.c:35
static DWORD msi_atou(LPCWSTR str)
Definition: msiexec.c:207
const char * LPCSTR
Definition: xmlstorage.h:183
#define SC_MANAGER_CREATE_SERVICE
Definition: winsvc.h:15
static VOID * LoadProc(LPCWSTR DllName, LPCSTR ProcName, HMODULE *DllHandle)
Definition: msiexec.c:275
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
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3993
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: lang.c:2272
#define FreeLibrary(x)
Definition: compat.h:405
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
UINT WINAPI MsiGetFileVersionW(LPCWSTR path, LPWSTR verbuf, LPDWORD verlen, LPWSTR langbuf, LPDWORD langlen)
Definition: msi.c:3266
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4134
__wchar_t WCHAR
Definition: xmlstorage.h:180
static const WCHAR InstallRunOnce[]
Definition: msiexec.c:51
LONG HRESULT
Definition: typedefs.h:77
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
static DWORD DoRegServer(void)
Definition: msiexec.c:337
static const WCHAR RemoveAll[]
Definition: msiexec.c:48
struct list * next
Definition: list.h:38
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
Definition: msi.c:273
static VOID StringListAppend(struct string_list **list, LPCWSTR str)
Definition: msiexec.c:109
_Must_inspect_result_ _In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PUNICODE_STRING LogFileName
Definition: nttmapi.h:322
#define SERVICE_WIN32_SHARE_PROCESS
Definition: cmtypes.h:961
chomp_state
Definition: msiexec.c:406
#define SERVICES_ACTIVE_DATABASEW
Definition: winsvc.h:8
int ret
#define ERROR_SERVICE_EXISTS
Definition: winerror.h:624
static BOOL msi_option_equal(LPCWSTR str1, LPCSTR str2)
Definition: msiexec.c:238
WINE_DEFAULT_DEBUG_CHANNEL(msiexec)
SC_HANDLE WINAPI OpenSCManagerW(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:2011
static int state
Definition: maze.c:121
WCHAR str[1]
Definition: msiexec.c:43
static BOOL msi_strequal(LPCWSTR str1, LPCSTR str2)
Definition: msiexec.c:220
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:819
#define CSTR_EQUAL
Definition: winnls.h:453
Definition: _list.h:228
uint32_t DWORD_PTR
Definition: typedefs.h:63
GLsizei const GLfloat * value
Definition: glext.h:6069
static void ShowUsage(int ExitCode)
Definition: msiexec.c:59
UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD f)
Definition: msi.c:2495
GLuint in
Definition: glext.h:9616
#define lstrcpyW
Definition: compat.h:406
static BOOL IsProductCode(LPWSTR str)
Definition: msiexec.c:99
Definition: services.c:325
#define sprintfW
Definition: unicode.h:58
static DWORD DoDllRegisterServer(LPCWSTR DllName)
Definition: msiexec.c:297
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2312
#define list
Definition: rosglue.h:35
#define MultiByteToWideChar
Definition: compat.h:100
#define ERROR_SERVICE_DOES_NOT_EXIST
Definition: winerror.h:611
GLuint res
Definition: glext.h:9613
enum tagINSTALLTYPE INSTALLTYPE
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2247
FILE * stderr
static int chomp(const WCHAR *in, WCHAR *out)
Definition: msiexec.c:413
#define GetProcAddress(x, y)
Definition: compat.h:410
LANGID WINAPI GetUserDefaultLangID(void)
Definition: lang.c:731
HRESULT(WINAPI * DLLUNREGISTERSERVER)(void)
Definition: msiexec.c:36
GLfloat GLfloat p
Definition: glext.h:8902
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define SERVICE_DEMAND_START
Definition: cmtypes.h:976
static LPWSTR build_properties(struct string_list *property_list)
Definition: msiexec.c:131
static BOOL msi_strprefix(LPCWSTR str1, LPCSTR str2)
Definition: msiexec.c:248
#define HeapFree(x, y, z)
Definition: compat.h:394
LCID WINAPI GetThreadLocale(void)
Definition: lang.c:1446
#define DELETE
Definition: nt_native.h:57
Definition: path.c:42
#define printf
Definition: config.h:203
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define WINE_FIXME
Definition: debug.h:365
#define REG_SZ
Definition: layer.c:22