ReactOS 0.4.16-dev-197-g92996da
action.c
Go to the documentation of this file.
1/*
2 * Implementation of the Microsoft Installer (msi.dll)
3 *
4 * Copyright 2004,2005 Aric Stewart for CodeWeavers
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include <stdarg.h>
22
23#define COBJMACROS
24
25#include "windef.h"
26#include "winbase.h"
27#include "winerror.h"
28#include "winreg.h"
29#include "winsvc.h"
30#include "odbcinst.h"
31#include "wine/debug.h"
32#include "msidefs.h"
33#include "winuser.h"
34#include "shlobj.h"
35#include "objbase.h"
36#include "mscoree.h"
37#include "shlwapi.h"
38#include "imagehlp.h"
39#include "winver.h"
40
41#include "msipriv.h"
42#include "resource.h"
43
44#define REG_PROGRESS_VALUE 13200
45#define COMPONENT_PROGRESS_VALUE 24000
46
48
50{
54};
55
57{
58 MSIRECORD *row, *textrow;
59 INT rc;
60
61 textrow = MSI_QueryGetRecord(package->db, L"SELECT * FROM `ActionText` WHERE `Action` = '%s'", action);
62 if (textrow)
63 {
64 description = MSI_RecordGetString(textrow, 2);
65 template = MSI_RecordGetString(textrow, 3);
66 }
67
69 if (!row) return -1;
72 MSI_RecordSetStringW(row, 3, template);
74 if (textrow) msiobj_release(&textrow->hdr);
75 msiobj_release(&row->hdr);
76 return rc;
77}
78
79static void ui_actioninfo(MSIPACKAGE *package, const WCHAR *action, BOOL start, INT rc)
80{
82 WCHAR *template;
83
85
87 if (!row)
88 {
89 free(template);
90 return;
91 }
92 MSI_RecordSetStringW(row, 0, template);
96 msiobj_release(&row->hdr);
97 free(template);
98 if (!start) package->LastActionResult = rc;
99}
100
102{
107
108static int parse_prop( const WCHAR *str, WCHAR *value, int *quotes )
109{
111 const WCHAR *p;
112 WCHAR *out = value;
113 BOOL ignore, in_quotes = FALSE;
114 int count = 0, len = 0;
115
116 for (p = str; *p; p++)
117 {
118 ignore = FALSE;
119 switch (state)
120 {
121 case state_whitespace:
122 switch (*p)
123 {
124 case ' ':
125 in_quotes = TRUE;
126 ignore = TRUE;
127 len++;
128 break;
129 case '"':
131 if (in_quotes && p[1] != '\"') count--;
132 else count++;
133 break;
134 default:
136 in_quotes = TRUE;
137 len++;
138 break;
139 }
140 break;
141
142 case state_token:
143 switch (*p)
144 {
145 case '"':
147 if (in_quotes) count--;
148 else count++;
149 break;
150 case ' ':
152 if (!count) goto done;
153 in_quotes = TRUE;
154 len++;
155 break;
156 default:
157 if (count) in_quotes = TRUE;
158 len++;
159 break;
160 }
161 break;
162
163 case state_quote:
164 switch (*p)
165 {
166 case '"':
167 if (in_quotes && p[1] != '\"') count--;
168 else count++;
169 break;
170 case ' ':
172 if (!count || (count > 1 && !len)) goto done;
173 in_quotes = TRUE;
174 len++;
175 break;
176 default:
178 if (count) in_quotes = TRUE;
179 len++;
180 break;
181 }
182 break;
183
184 default: break;
185 }
186 if (!ignore && value) *out++ = *p;
187 if (!count) in_quotes = FALSE;
188 }
189
190done:
191 if (value)
192 {
193 if (!len) *value = 0;
194 else *out = 0;
195 }
196
197 if(quotes) *quotes = count;
198 return p - str;
199}
200
201static void remove_quotes( WCHAR *str )
202{
203 WCHAR *p = str;
204 int len = lstrlenW( str );
205
206 while ((p = wcschr( p, '"' )))
207 {
208 memmove( p, p + 1, (len - (p - str)) * sizeof(WCHAR) );
209 p++;
210 }
211}
212
214 BOOL preserve_case )
215{
216 LPCWSTR ptr, ptr2;
217 int num_quotes;
218 DWORD len;
219 WCHAR *prop, *val;
220 UINT r;
221
222 if (!szCommandLine)
223 return ERROR_SUCCESS;
224
225 ptr = szCommandLine;
226 while (*ptr)
227 {
228 while (*ptr == ' ') ptr++;
229 if (!*ptr) break;
230
231 ptr2 = wcschr( ptr, '=' );
232 if (!ptr2) return ERROR_INVALID_COMMAND_LINE;
233
234 len = ptr2 - ptr;
235 if (!len) return ERROR_INVALID_COMMAND_LINE;
236
237 while (ptr[len - 1] == ' ') len--;
238
239 prop = malloc( (len + 1) * sizeof(WCHAR) );
240 memcpy( prop, ptr, len * sizeof(WCHAR) );
241 prop[len] = 0;
242 if (!preserve_case) wcsupr( prop );
243
244 ptr2++;
245 while (*ptr2 == ' ') ptr2++;
246
247 num_quotes = 0;
248 val = malloc( (wcslen( ptr2 ) + 1) * sizeof(WCHAR) );
249 len = parse_prop( ptr2, val, &num_quotes );
250 if (num_quotes % 2)
251 {
252 WARN("unbalanced quotes\n");
253 free( val );
254 free( prop );
256 }
258 TRACE("Found commandline property %s = %s\n", debugstr_w(prop), debugstr_w(val));
259
260 r = msi_set_property( package->db, prop, val, -1 );
261 if (r == ERROR_SUCCESS && !wcscmp( prop, L"SourceDir" ))
262 msi_reset_source_folders( package );
263
264 free( val );
265 free( prop );
266
267 ptr = ptr2 + len;
268 }
269
270 return ERROR_SUCCESS;
271}
272
274{
275 DWORD opt_len = lstrlenW(option);
276
277 if (!cmd)
278 return NULL;
279
280 while (*cmd)
281 {
282 BOOL found = FALSE;
283
284 while (*cmd == ' ') cmd++;
285 if (!*cmd) break;
286
287 if(!wcsnicmp(cmd, option, opt_len))
288 found = TRUE;
289
290 cmd = wcschr( cmd, '=' );
291 if(!cmd) break;
292 cmd++;
293 while (*cmd == ' ') cmd++;
294 if (!*cmd) break;
295
296 *len = parse_prop( cmd, NULL, NULL);
297 if (found) return cmd;
298 cmd += *len;
299 }
300
301 return NULL;
302}
303
305{
306 LPCWSTR pc;
307 LPWSTR p, *ret = NULL;
308 UINT count = 0;
309
310 if (!str)
311 return ret;
312
313 /* count the number of substrings */
314 for ( pc = str, count = 0; pc; count++ )
315 {
316 pc = wcschr( pc, sep );
317 if (pc)
318 pc++;
319 }
320
321 /* allocate space for an array of substring pointers and the substrings */
322 ret = malloc( (count + 1) * sizeof(WCHAR *) + (wcslen(str) + 1) * sizeof(WCHAR) );
323 if (!ret)
324 return ret;
325
326 /* copy the string and set the pointers */
327 p = (LPWSTR) &ret[count+1];
328 lstrcpyW( p, str );
329 for( count = 0; (ret[count] = p); count++ )
330 {
331 p = wcschr( p, sep );
332 if (p)
333 *p++ = 0;
334 }
335
336 return ret;
337}
338
340{
341 MSIQUERY *view;
342 DWORD count = 0;
343
344 if (!(MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `InstallUISequence` WHERE `Sequence` > 0", &view )))
345 {
346 MSI_IterateRecords( view, &count, NULL, package );
347 msiobj_release( &view->hdr );
348 }
349 return count != 0;
350}
351
353{
354 WCHAR *source, *check, *p, *db;
355 DWORD len;
356
357 if (!(db = msi_dup_property( package->db, L"OriginalDatabase" )))
358 return ERROR_OUTOFMEMORY;
359
360 if (!(p = wcsrchr( db, '\\' )) && !(p = wcsrchr( db, '/' )))
361 {
362 free(db);
363 return ERROR_SUCCESS;
364 }
365 len = p - db + 2;
366 source = malloc( len * sizeof(WCHAR) );
367 lstrcpynW( source, db, len );
368 free( db );
369
370 check = msi_dup_property( package->db, L"SourceDir" );
371 if (!check || replace)
372 {
373 UINT r = msi_set_property( package->db, L"SourceDir", source, -1 );
374 if (r == ERROR_SUCCESS)
375 msi_reset_source_folders( package );
376 }
377 free( check );
378
379 check = msi_dup_property( package->db, L"SOURCEDIR" );
380 if (!check || replace)
381 msi_set_property( package->db, L"SOURCEDIR", source, -1 );
382
383 free( check );
384 free( source );
385
386 return ERROR_SUCCESS;
387}
388
390{
392}
393
395{
396 UINT r = msi_locate_product( package->ProductCode, &package->Context );
397 if (r != ERROR_SUCCESS)
398 {
399 int num = msi_get_property_int( package->db, L"ALLUSERS", 0 );
400 if (num == 1 || num == 2)
402 else
404 }
405 return ERROR_SUCCESS;
406}
407
409{
410 UINT rc;
411 LPCWSTR cond, action;
412 MSIPACKAGE *package = param;
413
415 if (!action)
416 {
417 ERR("Error is retrieving action name\n");
419 }
420
421 /* check conditions */
422 cond = MSI_RecordGetString(row,2);
423
424 /* this is a hack to skip errors in the condition code */
425 if (MSI_EvaluateConditionW(package, cond) == MSICONDITION_FALSE)
426 {
427 TRACE("Skipping action: %s (condition is false)\n", debugstr_w(action));
428 return ERROR_SUCCESS;
429 }
430
431 rc = ACTION_PerformAction(package, action);
432
434
436 rc = ERROR_SUCCESS;
437
438 if (rc != ERROR_SUCCESS)
439 ERR("Execution halted, action %s returned %i\n", debugstr_w(action), rc);
440
441 if (package->need_reboot_now)
442 {
443 TRACE("action %s asked for immediate reboot, suspending installation\n",
445 rc = ACTION_ForceReboot( package );
446 }
447 return rc;
448}
449
451{
452 MSIQUERY *view;
453 UINT r;
454
455 TRACE("%p %s\n", package, debugstr_w(table));
456
457 r = MSI_OpenQuery( package->db, &view, L"SELECT * FROM `%s` WHERE `Sequence` > 0 ORDER BY `Sequence`", table );
458 if (r == ERROR_SUCCESS)
459 {
461 msiobj_release(&view->hdr);
462 }
463 return r;
464}
465
467{
468 MSIQUERY *view;
469 UINT rc;
470
471 if (package->ExecuteSequenceRun)
472 {
473 TRACE("Execute Sequence already Run\n");
474 return ERROR_SUCCESS;
475 }
476
477 package->ExecuteSequenceRun = TRUE;
478
479 rc = MSI_OpenQuery(package->db, &view,
480 L"SELECT * FROM `InstallExecuteSequence` WHERE `Sequence` > 0 ORDER BY `Sequence`");
481 if (rc == ERROR_SUCCESS)
482 {
483 TRACE("Running the actions\n");
484
485 msi_set_property( package->db, L"SourceDir", NULL, -1 );
487 msiobj_release(&view->hdr);
488 }
489 return rc;
490}
491
493{
494 MSIQUERY *view;
495 UINT rc;
496
497 rc = MSI_DatabaseOpenViewW(package->db,
498 L"SELECT * FROM `InstallUISequence` WHERE `Sequence` > 0 ORDER BY `Sequence`",
499 &view);
500 if (rc == ERROR_SUCCESS)
501 {
502 TRACE("Running the actions\n");
504 msiobj_release(&view->hdr);
505 }
506 return rc;
507}
508
509/********************************************************
510 * ACTION helper functions and functions that perform the actions
511 *******************************************************/
513{
514 UINT arc;
515 INT uirc;
516
517 uirc = ui_actionstart(package, action, NULL, NULL);
518 if (uirc == IDCANCEL)
520 ui_actioninfo(package, action, TRUE, 0);
521 arc = ACTION_CustomAction(package, action);
522 uirc = !arc;
523
524 if (arc == ERROR_FUNCTION_NOT_CALLED && needs_ui_sequence(package))
525 {
526 uirc = ACTION_ShowDialog(package, action);
527 switch (uirc)
528 {
529 case -1:
530 return ERROR_SUCCESS; /* stop immediately */
531 case 0: arc = ERROR_FUNCTION_NOT_CALLED; break;
532 case 1: arc = ERROR_SUCCESS; break;
533 case 2: arc = ERROR_INSTALL_USEREXIT; break;
534 case 3: arc = ERROR_INSTALL_FAILURE; break;
535 case 4: arc = ERROR_INSTALL_SUSPEND; break;
536 case 5: arc = ERROR_MORE_DATA; break;
537 case 6: arc = ERROR_INVALID_HANDLE_STATE; break;
538 case 7: arc = ERROR_INVALID_DATA; break;
539 case 8: arc = ERROR_INSTALL_ALREADY_RUNNING; break;
540 case 9: arc = ERROR_INSTALL_PACKAGE_REJECTED; break;
541 default: arc = ERROR_FUNCTION_FAILED; break;
542 }
543 }
544
545 ui_actioninfo(package, action, FALSE, uirc);
546
547 return arc;
548}
549
551{
552 MSICOMPONENT *comp;
553
555 {
556 if (!wcscmp( Component, comp->Component )) return comp;
557 }
558 return NULL;
559}
560
562{
564
566 {
567 if (!wcscmp( Feature, feature->Feature )) return feature;
568 }
569 return NULL;
570}
571
573{
574 MSIFILE *file;
575
577 {
578 if (!wcscmp( key, file->File )) return file;
579 }
580 return NULL;
581}
582
584{
586
588 {
589 if (!wcscmp( dir, folder->Directory )) return folder;
590 }
591 return NULL;
592}
593
594void msi_ui_progress( MSIPACKAGE *package, int a, int b, int c, int d )
595{
596 MSIRECORD *row;
597
598 row = MSI_CreateRecord( 4 );
604 msiobj_release( &row->hdr );
605
607}
608
610{
611 if (!comp->Enabled)
612 {
613 TRACE("component is disabled: %s\n", debugstr_w(comp->Component));
615 }
616 if (package->need_rollback) return comp->Installed;
617 if (comp->num_clients > 0 && comp->ActionRequest == INSTALLSTATE_ABSENT)
618 {
619 TRACE("%s has %u clients left\n", debugstr_w(comp->Component), comp->num_clients);
621 }
622 return comp->ActionRequest;
623}
624
626{
627 if (package->need_rollback) return feature->Installed;
628 return feature->ActionRequest;
629}
630
632{
633 MSIPACKAGE *package = param;
634 LPCWSTR dir, component, full_path;
635 MSIRECORD *uirow;
637 MSICOMPONENT *comp;
638
639 component = MSI_RecordGetString(row, 2);
640 if (!component)
641 return ERROR_SUCCESS;
642
643 comp = msi_get_loaded_component(package, component);
644 if (!comp)
645 return ERROR_SUCCESS;
646
647 comp->Action = msi_get_component_action( package, comp );
648 if (comp->Action != INSTALLSTATE_LOCAL)
649 {
650 TRACE("component not scheduled for installation: %s\n", debugstr_w(component));
651 return ERROR_SUCCESS;
652 }
653
655 if (!dir)
656 {
657 ERR("Unable to get folder id\n");
658 return ERROR_SUCCESS;
659 }
660
661 uirow = MSI_CreateRecord(1);
662 MSI_RecordSetStringW(uirow, 1, dir);
664 msiobj_release(&uirow->hdr);
665
666 full_path = msi_get_target_folder( package, dir );
667 if (!full_path)
668 {
669 ERR("Unable to retrieve folder %s\n", debugstr_w(dir));
670 return ERROR_SUCCESS;
671 }
672 TRACE("folder is %s\n", debugstr_w(full_path));
673
674 folder = msi_get_loaded_folder( package, dir );
675 if (folder->State == FOLDER_STATE_UNINITIALIZED) msi_create_full_path( package, full_path );
677
678 return ERROR_SUCCESS;
679}
680
682{
683 MSIQUERY *view;
684 UINT rc;
685
686 if (package->script == SCRIPT_NONE)
687 return msi_schedule_action(package, SCRIPT_INSTALL, L"CreateFolders");
688
689 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `CreateFolder`", &view );
690 if (rc != ERROR_SUCCESS)
691 return ERROR_SUCCESS;
692
694 msiobj_release(&view->hdr);
695 return rc;
696}
697
699{
700 FolderList *fl;
701
703 {
704 remove_persistent_folder( fl->folder );
705 }
706 if (folder->persistent && folder->State != FOLDER_STATE_REMOVED)
707 {
708 if (RemoveDirectoryW( folder->ResolvedTarget )) folder->State = FOLDER_STATE_REMOVED;
709 }
710}
711
713{
714 MSIPACKAGE *package = param;
715 LPCWSTR dir, component, full_path;
716 MSIRECORD *uirow;
718 MSICOMPONENT *comp;
719
720 component = MSI_RecordGetString(row, 2);
721 if (!component)
722 return ERROR_SUCCESS;
723
724 comp = msi_get_loaded_component(package, component);
725 if (!comp)
726 return ERROR_SUCCESS;
727
728 comp->Action = msi_get_component_action( package, comp );
729 if (comp->Action != INSTALLSTATE_ABSENT)
730 {
731 TRACE("component not scheduled for removal %s\n", debugstr_w(component));
732 return ERROR_SUCCESS;
733 }
734
736 if (!dir)
737 {
738 ERR("Unable to get folder id\n");
739 return ERROR_SUCCESS;
740 }
741
742 full_path = msi_get_target_folder( package, dir );
743 if (!full_path)
744 {
745 ERR("Unable to resolve folder %s\n", debugstr_w(dir));
746 return ERROR_SUCCESS;
747 }
748 TRACE("folder is %s\n", debugstr_w(full_path));
749
750 uirow = MSI_CreateRecord( 1 );
751 MSI_RecordSetStringW( uirow, 1, dir );
753 msiobj_release( &uirow->hdr );
754
755 folder = msi_get_loaded_folder( package, dir );
757 return ERROR_SUCCESS;
758}
759
761{
762 MSIQUERY *view;
763 UINT rc;
764
765 if (package->script == SCRIPT_NONE)
766 return msi_schedule_action(package, SCRIPT_INSTALL, L"RemoveFolders");
767
768 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `CreateFolder`", &view );
769 if (rc != ERROR_SUCCESS)
770 return ERROR_SUCCESS;
771
773 msiobj_release( &view->hdr );
774 return rc;
775}
776
778{
779 MSIPACKAGE *package = param;
780 MSICOMPONENT *comp;
781
782 comp = calloc( 1, sizeof(MSICOMPONENT) );
783 if (!comp)
785
786 list_add_tail( &package->components, &comp->entry );
787
788 /* fill in the data */
789 comp->Component = msi_dup_record_field( row, 1 );
790
791 TRACE("Loading Component %s\n", debugstr_w(comp->Component));
792
793 comp->ComponentId = msi_dup_record_field( row, 2 );
794 comp->Directory = msi_dup_record_field( row, 3 );
795 comp->Attributes = MSI_RecordGetInteger(row,4);
796 comp->Condition = msi_dup_record_field( row, 5 );
797 comp->KeyPath = msi_dup_record_field( row, 6 );
798
799 comp->Installed = INSTALLSTATE_UNKNOWN;
800 comp->Action = INSTALLSTATE_UNKNOWN;
801 comp->ActionRequest = INSTALLSTATE_UNKNOWN;
802
803 comp->assembly = msi_load_assembly( package, comp );
804 return ERROR_SUCCESS;
805}
806
808{
809 MSIQUERY *view;
810 UINT r;
811
812 if (!list_empty(&package->components))
813 return ERROR_SUCCESS;
814
815 r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Component`", &view );
816 if (r != ERROR_SUCCESS)
817 return r;
818
820 msiobj_release(&view->hdr);
821 return r;
822}
823
825{
826 ComponentList *cl;
827
828 cl = malloc( sizeof(*cl) );
829 if ( !cl )
831 cl->component = comp;
832 list_add_tail( &feature->Components, &cl->entry );
833
834 return ERROR_SUCCESS;
835}
836
838{
840
841 fl = malloc( sizeof(*fl) );
842 if ( !fl )
844 fl->feature = child;
845 list_add_tail( &parent->Children, &fl->entry );
846
847 return ERROR_SUCCESS;
848}
849
851{
854};
855
857{
859 LPCWSTR component;
860 MSICOMPONENT *comp;
861
862 component = MSI_RecordGetString(row,1);
863
864 /* check to see if the component is already loaded */
866 if (!comp)
867 {
868 WARN("ignoring unknown component %s\n", debugstr_w(component));
869 return ERROR_SUCCESS;
870 }
872 comp->Enabled = TRUE;
873
874 return ERROR_SUCCESS;
875}
876
878{
879 MSIPACKAGE *package = param;
881 MSIQUERY *view;
883 UINT rc;
884
885 /* fill in the data */
886
887 feature = calloc( 1, sizeof(MSIFEATURE) );
888 if (!feature)
890
891 list_init( &feature->Children );
892 list_init( &feature->Components );
893
894 feature->Feature = msi_dup_record_field( row, 1 );
895
896 TRACE("Loading feature %s\n",debugstr_w(feature->Feature));
897
898 feature->Feature_Parent = msi_dup_record_field( row, 2 );
899 feature->Title = msi_dup_record_field( row, 3 );
900 feature->Description = msi_dup_record_field( row, 4 );
901
902 if (!MSI_RecordIsNull(row,5))
903 feature->Display = MSI_RecordGetInteger(row,5);
904
906 feature->Directory = msi_dup_record_field( row, 7 );
907 feature->Attributes = MSI_RecordGetInteger(row,8);
908
909 feature->Installed = INSTALLSTATE_UNKNOWN;
911 feature->ActionRequest = INSTALLSTATE_UNKNOWN;
912
913 list_add_tail( &package->features, &feature->entry );
914
915 /* load feature components */
916
917 rc = MSI_OpenQuery( package->db, &view, L"SELECT `Component_` FROM `FeatureComponents` WHERE `Feature_` = '%s'",
918 feature->Feature );
919 if (rc != ERROR_SUCCESS)
920 return ERROR_SUCCESS;
921
922 package_feature.package = package;
924
926 msiobj_release(&view->hdr);
927 return rc;
928}
929
931{
932 MSIPACKAGE *package = param;
934
936 if (!child)
938
939 if (!child->Feature_Parent)
940 return ERROR_SUCCESS;
941
942 parent = msi_get_loaded_feature( package, child->Feature_Parent );
943 if (!parent)
945
947 return ERROR_SUCCESS;
948}
949
951{
952 MSIQUERY *view;
953 UINT r;
954
955 if (!list_empty(&package->features))
956 return ERROR_SUCCESS;
957
958 r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Feature` ORDER BY `Display`", &view );
959 if (r != ERROR_SUCCESS)
960 return r;
961
962 r = MSI_IterateRecords( view, NULL, load_feature, package );
963 if (r != ERROR_SUCCESS)
964 {
965 msiobj_release( &view->hdr );
966 return r;
967 }
969 msiobj_release( &view->hdr );
970 return r;
971}
972
974{
975 if (!p)
976 return p;
977 p = wcschr(p, ch);
978 if (!p)
979 return p;
980 *p = 0;
981 return p+1;
982}
983
985{
986 MSIQUERY *view = NULL;
987 MSIRECORD *row = NULL;
988 UINT r;
989
990 TRACE("%s\n", debugstr_w(file->File));
991
992 r = MSI_OpenQuery(package->db, &view, L"SELECT * FROM `MsiFileHash` WHERE `File_` = '%s'", file->File);
993 if (r != ERROR_SUCCESS)
994 goto done;
995
997 if (r != ERROR_SUCCESS)
998 goto done;
999
1000 r = MSI_ViewFetch(view, &row);
1001 if (r != ERROR_SUCCESS)
1002 goto done;
1003
1004 file->hash.dwFileHashInfoSize = sizeof(MSIFILEHASHINFO);
1005 file->hash.dwData[0] = MSI_RecordGetInteger(row, 3);
1006 file->hash.dwData[1] = MSI_RecordGetInteger(row, 4);
1007 file->hash.dwData[2] = MSI_RecordGetInteger(row, 5);
1008 file->hash.dwData[3] = MSI_RecordGetInteger(row, 6);
1009
1010done:
1011 if (view) msiobj_release(&view->hdr);
1012 if (row) msiobj_release(&row->hdr);
1013 return r;
1014}
1015
1017{
1018 MSIRECORD *row = MSI_QueryGetRecord( package->db, L"SELECT `DiskId` FROM `Media` WHERE `LastSequence` >= %d",
1019 file->Sequence );
1020 if (!row)
1021 {
1022 WARN("query failed\n");
1023 return ERROR_FUNCTION_FAILED;
1024 }
1025
1026 file->disk_id = MSI_RecordGetInteger( row, 1 );
1027 msiobj_release( &row->hdr );
1028 return ERROR_SUCCESS;
1029}
1030
1032{
1033 MSIPACKAGE* package = param;
1034 LPCWSTR component;
1035 MSIFILE *file;
1036
1037 /* fill in the data */
1038
1039 file = calloc( 1, sizeof(MSIFILE) );
1040 if (!file)
1042
1043 file->File = msi_dup_record_field( row, 1 );
1044
1045 component = MSI_RecordGetString( row, 2 );
1046 file->Component = msi_get_loaded_component( package, component );
1047
1048 if (!file->Component)
1049 {
1050 WARN("Component not found: %s\n", debugstr_w(component));
1051 free(file->File);
1052 free(file);
1053 return ERROR_SUCCESS;
1054 }
1055
1056 file->FileName = msi_dup_record_field( row, 3 );
1057 msi_reduce_to_long_filename( file->FileName );
1058
1059 file->ShortName = msi_dup_record_field( row, 3 );
1060 file->LongName = wcsdup( folder_split_path(file->ShortName, '|') );
1061
1062 file->FileSize = MSI_RecordGetInteger( row, 4 );
1063 file->Version = msi_dup_record_field( row, 5 );
1064 file->Language = msi_dup_record_field( row, 6 );
1065 file->Attributes = MSI_RecordGetInteger( row, 7 );
1066 file->Sequence = MSI_RecordGetInteger( row, 8 );
1067
1068 file->state = msifs_invalid;
1069
1070 /* if the compressed bits are not set in the file attributes,
1071 * then read the information from the package word count property
1072 */
1073 if (package->WordCount & msidbSumInfoSourceTypeAdminImage)
1074 {
1075 file->IsCompressed = package->WordCount & msidbSumInfoSourceTypeCompressed;
1076 }
1078 {
1079 file->IsCompressed = TRUE;
1080 }
1081 else if (file->Attributes & msidbFileAttributesNoncompressed)
1082 {
1083 file->IsCompressed = FALSE;
1084 }
1085 else file->IsCompressed = package->WordCount & msidbSumInfoSourceTypeCompressed;
1086
1087 load_file_hash(package, file);
1088 load_file_disk_id(package, file);
1089
1090 TRACE("File loaded (file %s sequence %u)\n", debugstr_w(file->File), file->Sequence);
1091
1092 list_add_tail( &package->files, &file->entry );
1093 return ERROR_SUCCESS;
1094}
1095
1097{
1098 MSIQUERY *view;
1099 UINT rc;
1100
1101 if (!list_empty(&package->files))
1102 return ERROR_SUCCESS;
1103
1104 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `File` ORDER BY `Sequence`", &view);
1105 if (rc != ERROR_SUCCESS)
1106 return ERROR_SUCCESS;
1107
1108 rc = MSI_IterateRecords(view, NULL, load_file, package);
1109 msiobj_release(&view->hdr);
1110 return rc;
1111}
1112
1114{
1115 MSIPACKAGE *package = param;
1116 UINT disk_id = MSI_RecordGetInteger( row, 1 );
1117 const WCHAR *cabinet = MSI_RecordGetString( row, 4 );
1118
1119 /* FIXME: load external cabinets and directory sources too */
1120 if (!cabinet || cabinet[0] != '#' || disk_id >= MSI_INITIAL_MEDIA_TRANSFORM_DISKID)
1121 return ERROR_SUCCESS;
1122
1123 return msi_add_cabinet_stream( package, disk_id, package->db->storage, cabinet );
1124}
1125
1127{
1128 MSIQUERY *view;
1129 UINT r;
1130
1131 r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Media` ORDER BY `DiskId`", &view );
1132 if (r != ERROR_SUCCESS)
1133 return ERROR_SUCCESS;
1134
1135 r = MSI_IterateRecords( view, NULL, load_media, package );
1136 msiobj_release( &view->hdr );
1137 return r;
1138}
1139
1141{
1142 MSIRECORD *rec = MSI_QueryGetRecord( package->db, L"SELECT `DiskId` FROM `Media` WHERE `LastSequence` >= %u",
1143 patch->Sequence );
1144 if (!rec)
1145 {
1146 WARN("query failed\n");
1147 return ERROR_FUNCTION_FAILED;
1148 }
1149
1150 patch->disk_id = MSI_RecordGetInteger( rec, 1 );
1151 msiobj_release( &rec->hdr );
1152 return ERROR_SUCCESS;
1153}
1154
1156{
1157 MSIPACKAGE *package = param;
1158 MSIFILEPATCH *patch;
1159 const WCHAR *file_key;
1160
1161 patch = calloc( 1, sizeof(MSIFILEPATCH) );
1162 if (!patch)
1164
1165 file_key = MSI_RecordGetString( row, 1 );
1166 patch->File = msi_get_loaded_file( package, file_key );
1167 if (!patch->File)
1168 {
1169 ERR("Failed to find target for patch in File table\n");
1170 free(patch);
1171 return ERROR_FUNCTION_FAILED;
1172 }
1173
1174 patch->Sequence = MSI_RecordGetInteger( row, 2 );
1175 patch->PatchSize = MSI_RecordGetInteger( row, 3 );
1176 patch->Attributes = MSI_RecordGetInteger( row, 4 );
1177
1178 /* FIXME:
1179 * Header field - for patch validation.
1180 * _StreamRef - External key into MsiPatchHeaders (instead of the header field)
1181 */
1182
1183 load_patch_disk_id( package, patch );
1184
1185 TRACE("Patch loaded (file %s sequence %u)\n", debugstr_w(patch->File->File), patch->Sequence);
1186
1187 list_add_tail( &package->filepatches, &patch->entry );
1188
1189 return ERROR_SUCCESS;
1190}
1191
1193{
1194 MSIQUERY *view;
1195 UINT rc;
1196
1197 if (!list_empty(&package->filepatches))
1198 return ERROR_SUCCESS;
1199
1200 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `Patch` ORDER BY `Sequence`", &view);
1201 if (rc != ERROR_SUCCESS)
1202 return ERROR_SUCCESS;
1203
1204 rc = MSI_IterateRecords(view, NULL, load_patch, package);
1205 msiobj_release(&view->hdr);
1206 return rc;
1207}
1208
1210{
1211 MSIPACKAGE *package = param;
1212 const WCHAR *name;
1213 MSICOMPONENT *c;
1214
1216 TRACE( "found patched component: %s\n", wine_dbgstr_w(name) );
1217 c = msi_get_loaded_component( package, name );
1218 if (!c)
1219 return ERROR_SUCCESS;
1220
1221 c->updated = 1;
1222 if (!wcscmp( MSI_RecordGetString( row, 2 ), L"INSERT" ))
1223 c->added = 1;
1224 return ERROR_SUCCESS;
1225}
1226
1228{
1229 static const WCHAR select[] = L"SELECT `Row`, `Column` FROM `_TransformView` WHERE `Table`='Component'";
1230 MSIQUERY *q;
1231 UINT r;
1232
1233 r = MSI_OpenQuery( package->db, &q, select );
1234 if (r != ERROR_SUCCESS)
1235 return;
1236
1238 msiobj_release( &q->hdr );
1239
1240 while (1)
1241 {
1242 r = MSI_OpenQuery( package->db, &q, L"ALTER TABLE `_TransformView` FREE" );
1243 if (r != ERROR_SUCCESS)
1244 return;
1245 r = MSI_ViewExecute( q, NULL );
1246 msiobj_release( &q->hdr );
1247 if (r != ERROR_SUCCESS)
1248 return;
1249 }
1250}
1251
1253{
1254 MSIQUERY *view;
1255
1256 folder->persistent = FALSE;
1257 if (!MSI_OpenQuery( package->db, &view, L"SELECT * FROM `CreateFolder` WHERE `Directory_` = '%s'",
1258 folder->Directory ))
1259 {
1260 if (!MSI_ViewExecute( view, NULL ))
1261 {
1262 MSIRECORD *rec;
1263 if (!MSI_ViewFetch( view, &rec ))
1264 {
1265 TRACE("directory %s is persistent\n", debugstr_w(folder->Directory));
1266 folder->persistent = TRUE;
1267 msiobj_release( &rec->hdr );
1268 }
1269 }
1270 msiobj_release( &view->hdr );
1271 }
1272 return ERROR_SUCCESS;
1273}
1274
1276{
1277 MSIPACKAGE *package = param;
1278 static WCHAR szEmpty[] = L"";
1279 LPWSTR p, tgt_short, tgt_long, src_short, src_long;
1281
1282 if (!(folder = calloc( 1, sizeof(*folder) ))) return ERROR_NOT_ENOUGH_MEMORY;
1283 list_init( &folder->children );
1284 folder->Directory = msi_dup_record_field( row, 1 );
1285 folder->Parent = msi_dup_record_field( row, 2 );
1287
1288 TRACE("%s\n", debugstr_w(folder->Directory));
1289
1290 /* split src and target dir */
1291 tgt_short = p;
1292 src_short = folder_split_path( p, ':' );
1293
1294 /* split the long and short paths */
1295 tgt_long = folder_split_path( tgt_short, '|' );
1296 src_long = folder_split_path( src_short, '|' );
1297
1298 /* check for no-op dirs */
1299 if (tgt_short && !wcscmp( L".", tgt_short ))
1300 tgt_short = szEmpty;
1301 if (src_short && !wcscmp( L".", src_short ))
1302 src_short = szEmpty;
1303
1304 if (!tgt_long)
1305 tgt_long = tgt_short;
1306
1307 if (!src_short) {
1308 src_short = tgt_short;
1309 src_long = tgt_long;
1310 }
1311
1312 if (!src_long)
1313 src_long = src_short;
1314
1315 /* FIXME: use the target short path too */
1316 folder->TargetDefault = wcsdup(tgt_long);
1317 folder->SourceShortPath = wcsdup(src_short);
1318 folder->SourceLongPath = wcsdup(src_long);
1319 free(p);
1320
1321 TRACE("TargetDefault = %s\n",debugstr_w( folder->TargetDefault ));
1322 TRACE("SourceLong = %s\n", debugstr_w( folder->SourceLongPath ));
1323 TRACE("SourceShort = %s\n", debugstr_w( folder->SourceShortPath ));
1324
1325 load_folder_persistence( package, folder );
1326
1327 list_add_tail( &package->folders, &folder->entry );
1328 return ERROR_SUCCESS;
1329}
1330
1332{
1333 FolderList *fl;
1334
1335 if (!(fl = malloc( sizeof(*fl) ))) return ERROR_NOT_ENOUGH_MEMORY;
1336 fl->folder = child;
1337 list_add_tail( &parent->children, &fl->entry );
1338 return ERROR_SUCCESS;
1339}
1340
1342{
1343 MSIPACKAGE *package = param;
1345
1346 if (!(child = msi_get_loaded_folder( package, MSI_RecordGetString( row, 1 ) )))
1347 return ERROR_FUNCTION_FAILED;
1348
1349 if (!child->Parent) return ERROR_SUCCESS;
1350
1351 if (!(parent = msi_get_loaded_folder( package, child->Parent )))
1352 return ERROR_FUNCTION_FAILED;
1353
1354 return add_folder_child( parent, child );
1355}
1356
1358{
1359 MSIQUERY *view;
1360 UINT r;
1361
1362 if (!list_empty(&package->folders))
1363 return ERROR_SUCCESS;
1364
1365 r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Directory`", &view );
1366 if (r != ERROR_SUCCESS)
1367 return r;
1368
1369 r = MSI_IterateRecords( view, NULL, load_folder, package );
1370 if (r != ERROR_SUCCESS)
1371 {
1372 msiobj_release( &view->hdr );
1373 return r;
1374 }
1376 msiobj_release( &view->hdr );
1377 return r;
1378}
1379
1381{
1382 msi_set_property( package->db, L"CostingComplete", L"0", -1 );
1383 msi_set_property( package->db, L"ROOTDRIVE", L"C:\\", -1 );
1384
1385 load_all_folders( package );
1386 msi_load_all_components( package );
1387 msi_load_all_features( package );
1388 load_all_files( package );
1389 load_all_patches( package );
1390 mark_patched_components( package );
1391 load_all_media( package );
1392
1393 return ERROR_SUCCESS;
1394}
1395
1397{
1398 UINT i, rc = ERROR_SUCCESS;
1399
1400 TRACE("executing script %u\n", script);
1401
1402 package->script = script;
1403
1404 if (script == SCRIPT_ROLLBACK)
1405 {
1406 for (i = package->script_actions_count[script]; i > 0; i--)
1407 {
1408 rc = ACTION_PerformAction(package, package->script_actions[script][i-1]);
1409 if (rc != ERROR_SUCCESS)
1410 {
1411 ERR("Execution of script %i halted; action %s returned %u\n",
1412 script, debugstr_w(package->script_actions[script][i-1]), rc);
1413 break;
1414 }
1415 }
1416 }
1417 else
1418 {
1419 for (i = 0; i < package->script_actions_count[script]; i++)
1420 {
1421 rc = ACTION_PerformAction(package, package->script_actions[script][i]);
1422 if (rc != ERROR_SUCCESS)
1423 {
1424 ERR("Execution of script %i halted; action %s returned %u\n",
1425 script, debugstr_w(package->script_actions[script][i]), rc);
1426 break;
1427 }
1428 }
1429 }
1430
1431 package->script = SCRIPT_NONE;
1432
1434 return rc;
1435}
1436
1438{
1439 return ERROR_SUCCESS;
1440}
1441
1442static void get_client_counts( MSIPACKAGE *package )
1443{
1444 MSICOMPONENT *comp;
1445 HKEY hkey;
1446
1448 {
1449 if (!comp->ComponentId) continue;
1450
1451 if (MSIREG_OpenUserDataComponentKey( comp->ComponentId, L"S-1-5-18", &hkey, FALSE ) &&
1453 {
1454 comp->num_clients = 0;
1455 continue;
1456 }
1457 RegQueryInfoKeyW( hkey, NULL, NULL, NULL, NULL, NULL, NULL, (DWORD *)&comp->num_clients,
1458 NULL, NULL, NULL, NULL );
1459 RegCloseKey( hkey );
1460 }
1461}
1462
1464{
1465 MSICOMPONENT *comp;
1466 UINT r;
1467
1469 {
1470 if (!comp->ComponentId) continue;
1471
1474 &comp->Installed );
1475 if (r == ERROR_SUCCESS) continue;
1476
1479 &comp->Installed );
1480 if (r == ERROR_SUCCESS) continue;
1481
1484 &comp->Installed );
1485 if (r == ERROR_SUCCESS) continue;
1486
1488 }
1489}
1490
1492{
1494
1496 {
1498
1500 feature->Installed = INSTALLSTATE_ABSENT;
1501 else
1502 feature->Installed = state;
1503 }
1504}
1505
1507{
1508 return (feature->Level > 0 && feature->Level <= level);
1509}
1510
1513{
1514 LPWSTR override;
1516 BOOL remove = !wcscmp(property, L"REMOVE");
1517 BOOL reinstall = !wcscmp(property, L"REINSTALL");
1518
1519 override = msi_dup_property( package->db, property );
1520 if (!override)
1521 return FALSE;
1522
1524 {
1525 if (feature->Level <= 0)
1526 continue;
1527
1528 if (reinstall)
1529 state = (feature->Installed == INSTALLSTATE_ABSENT ? INSTALLSTATE_UNKNOWN : feature->Installed);
1530 else if (remove)
1532
1533 if (!wcsicmp( override, L"ALL" ))
1534 {
1535 feature->Action = state;
1536 feature->ActionRequest = state;
1537 }
1538 else
1539 {
1540 LPWSTR ptr = override;
1541 LPWSTR ptr2 = wcschr(override,',');
1542
1543 while (ptr)
1544 {
1545 int len = ptr2 - ptr;
1546
1547 if ((ptr2 && lstrlenW(feature->Feature) == len && !wcsncmp(ptr, feature->Feature, len))
1548 || (!ptr2 && !wcscmp(ptr, feature->Feature)))
1549 {
1550 feature->Action = state;
1551 feature->ActionRequest = state;
1552 break;
1553 }
1554 if (ptr2)
1555 {
1556 ptr=ptr2+1;
1557 ptr2 = wcschr(ptr,',');
1558 }
1559 else
1560 break;
1561 }
1562 }
1563 }
1564 free(override);
1565 return TRUE;
1566}
1567
1569{
1570 BOOL ret = FALSE;
1571
1572 /* all these activation/deactivation things happen in order and things
1573 * later on the list override things earlier on the list.
1574 *
1575 * 0 INSTALLLEVEL processing
1576 * 1 ADDLOCAL
1577 * 2 REMOVE
1578 * 3 ADDSOURCE
1579 * 4 ADDDEFAULT
1580 * 5 REINSTALL
1581 * 6 ADVERTISE
1582 * 7 COMPADDLOCAL
1583 * 8 COMPADDSOURCE
1584 * 9 FILEADDLOCAL
1585 * 10 FILEADDSOURCE
1586 * 11 FILEADDDEFAULT
1587 */
1588 ret |= process_state_property( package, level, L"ADDLOCAL", INSTALLSTATE_LOCAL );
1589 ret |= process_state_property( package, level, L"REMOVE", INSTALLSTATE_ABSENT );
1590 ret |= process_state_property( package, level, L"ADDSOURCE", INSTALLSTATE_SOURCE );
1591 ret |= process_state_property( package, level, L"REINSTALL", INSTALLSTATE_UNKNOWN );
1592 ret |= process_state_property( package, level, L"ADVERTISE", INSTALLSTATE_ADVERTISED );
1593
1594 if (ret)
1595 msi_set_property( package->db, L"Preselected", L"1", -1 );
1596
1597 return ret;
1598}
1599
1601{
1602 FeatureList *fl;
1603
1605 {
1607 {
1608 TRACE("child %s (level %d request %d) follows disabled parent %s (level %d request %d)\n",
1609 debugstr_w(fl->feature->Feature), fl->feature->Level, fl->feature->ActionRequest,
1610 debugstr_w(feature->Feature), feature->Level, feature->ActionRequest);
1611
1612 fl->feature->Level = feature->Level;
1613 fl->feature->Action = INSTALLSTATE_UNKNOWN;
1614 fl->feature->ActionRequest = INSTALLSTATE_UNKNOWN;
1615 }
1616 disable_children( fl->feature, level );
1617 }
1618}
1619
1621{
1622 FeatureList *fl;
1623
1625 {
1626 if (fl->feature->Attributes & msidbFeatureAttributesFollowParent)
1627 {
1628 TRACE("child %s (level %d request %d) follows parent %s (level %d request %d)\n",
1629 debugstr_w(fl->feature->Feature), fl->feature->Level, fl->feature->ActionRequest,
1630 debugstr_w(feature->Feature), feature->Level, feature->ActionRequest);
1631
1632 fl->feature->Action = feature->Action;
1633 fl->feature->ActionRequest = feature->ActionRequest;
1634 }
1635 follow_parent( fl->feature );
1636 }
1637}
1638
1640{
1641 int level;
1642 MSICOMPONENT* component;
1644
1645 TRACE("Checking Install Level\n");
1646
1647 level = msi_get_property_int(package->db, L"INSTALLLEVEL", 1);
1648
1649 if (msi_get_property_int( package->db, L"Preselected", 0 ))
1650 {
1652 {
1653 if (!is_feature_selected( feature, level )) continue;
1654
1655 if (feature->ActionRequest == INSTALLSTATE_UNKNOWN)
1656 {
1657 if (feature->Installed == INSTALLSTATE_ABSENT)
1658 {
1659 feature->Action = INSTALLSTATE_UNKNOWN;
1660 feature->ActionRequest = INSTALLSTATE_UNKNOWN;
1661 }
1662 else
1663 {
1664 feature->Action = feature->Installed;
1665 feature->ActionRequest = feature->Installed;
1666 }
1667 }
1668 }
1669 }
1670 else if (!msi_get_property_int( package->db, L"Installed", 0 ))
1671 {
1673 {
1674 if (!is_feature_selected( feature, level )) continue;
1675
1676 if (feature->ActionRequest == INSTALLSTATE_UNKNOWN)
1677 {
1679 {
1680 feature->Action = INSTALLSTATE_SOURCE;
1681 feature->ActionRequest = INSTALLSTATE_SOURCE;
1682 }
1683 else if (feature->Attributes & msidbFeatureAttributesFavorAdvertise)
1684 {
1686 feature->ActionRequest = INSTALLSTATE_ADVERTISED;
1687 }
1688 else
1689 {
1690 feature->Action = INSTALLSTATE_LOCAL;
1691 feature->ActionRequest = INSTALLSTATE_LOCAL;
1692 }
1693 }
1694 }
1695 }
1696 else
1697 {
1699 {
1700 ComponentList *cl;
1701 MSIFEATURE *cur;
1702
1703 if (!is_feature_selected( feature, level )) continue;
1704 if (feature->ActionRequest != INSTALLSTATE_UNKNOWN) continue;
1705
1706 LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
1707 {
1708 if (!cl->component->updated && !cl->component->added)
1709 continue;
1710
1711 cur = feature;
1712 while (cur)
1713 {
1714 if (cur->ActionRequest != INSTALLSTATE_UNKNOWN)
1715 break;
1716
1717 if (cur->Installed != INSTALLSTATE_ABSENT)
1718 {
1719 cur->Action = cur->Installed;
1720 cur->ActionRequest = cur->Installed;
1721 }
1722 else if (!cl->component->added)
1723 {
1724 break;
1725 }
1726 else if (cur->Attributes & msidbFeatureAttributesFavorSource)
1727 {
1728 cur->Action = INSTALLSTATE_SOURCE;
1729 cur->ActionRequest = INSTALLSTATE_SOURCE;
1730 }
1731 else if (cur->Attributes & msidbFeatureAttributesFavorAdvertise)
1732 {
1733 cur->Action = INSTALLSTATE_ADVERTISED;
1734 cur->ActionRequest = INSTALLSTATE_ADVERTISED;
1735 }
1736 else
1737 {
1738 cur->Action = INSTALLSTATE_LOCAL;
1739 cur->ActionRequest = INSTALLSTATE_LOCAL;
1740 }
1741
1742 if (!cur->Feature_Parent)
1743 break;
1744 cur = msi_get_loaded_feature(package, cur->Feature_Parent);
1745 }
1746 }
1747 }
1748 }
1749
1750 /* disable child features of unselected parent or follow parent */
1752 {
1753 if (feature->Feature_Parent) continue;
1756 }
1757
1758 /* now we want to set component state based based on feature state */
1760 {
1761 ComponentList *cl;
1762
1763 TRACE("examining feature %s (level %d installed %d request %d action %d)\n",
1764 debugstr_w(feature->Feature), feature->Level, feature->Installed,
1765 feature->ActionRequest, feature->Action);
1766
1767 /* features with components that have compressed files are made local */
1768 LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
1769 {
1770 if (cl->component->ForceLocalState &&
1771 feature->ActionRequest == INSTALLSTATE_SOURCE)
1772 {
1773 feature->Action = INSTALLSTATE_LOCAL;
1774 feature->ActionRequest = INSTALLSTATE_LOCAL;
1775 break;
1776 }
1777 }
1778
1779 LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
1780 {
1781 component = cl->component;
1782
1783 switch (feature->ActionRequest)
1784 {
1786 component->anyAbsent = 1;
1787 break;
1789 component->hasAdvertisedFeature = 1;
1790 break;
1792 component->hasSourceFeature = 1;
1793 break;
1794 case INSTALLSTATE_LOCAL:
1795 component->hasLocalFeature = 1;
1796 break;
1799 component->hasAdvertisedFeature = 1;
1800 else if (feature->Attributes & msidbFeatureAttributesFavorSource)
1801 component->hasSourceFeature = 1;
1802 else
1803 component->hasLocalFeature = 1;
1804 break;
1806 if (feature->Installed == INSTALLSTATE_ADVERTISED)
1807 component->hasAdvertisedFeature = 1;
1808 if (feature->Installed == INSTALLSTATE_SOURCE)
1809 component->hasSourceFeature = 1;
1810 if (feature->Installed == INSTALLSTATE_LOCAL)
1811 component->hasLocalFeature = 1;
1812 break;
1813 default:
1814 break;
1815 }
1816 }
1817 }
1818
1819 LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry )
1820 {
1821 /* check if it's local or source */
1822 if (!(component->Attributes & msidbComponentAttributesOptional) &&
1823 (component->hasLocalFeature || component->hasSourceFeature))
1824 {
1826 !component->ForceLocalState)
1827 {
1828 component->Action = INSTALLSTATE_SOURCE;
1830 }
1831 else
1832 {
1833 component->Action = INSTALLSTATE_LOCAL;
1834 component->ActionRequest = INSTALLSTATE_LOCAL;
1835 }
1836 continue;
1837 }
1838
1839 /* if any feature is local, the component must be local too */
1840 if (component->hasLocalFeature)
1841 {
1842 component->Action = INSTALLSTATE_LOCAL;
1843 component->ActionRequest = INSTALLSTATE_LOCAL;
1844 continue;
1845 }
1846 if (component->hasSourceFeature)
1847 {
1848 component->Action = INSTALLSTATE_SOURCE;
1850 continue;
1851 }
1852 if (component->hasAdvertisedFeature)
1853 {
1854 component->Action = INSTALLSTATE_ADVERTISED;
1856 continue;
1857 }
1858 TRACE("nobody wants component %s\n", debugstr_w(component->Component));
1859 if (component->anyAbsent && component->ComponentId)
1860 {
1861 component->Action = INSTALLSTATE_ABSENT;
1863 }
1864 }
1865
1866 LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry )
1867 {
1868 if (component->ActionRequest == INSTALLSTATE_DEFAULT)
1869 {
1870 TRACE("%s was default, setting to local\n", debugstr_w(component->Component));
1871 component->Action = INSTALLSTATE_LOCAL;
1872 component->ActionRequest = INSTALLSTATE_LOCAL;
1873 }
1874
1875 if (component->ActionRequest == INSTALLSTATE_SOURCE &&
1876 component->Installed == INSTALLSTATE_SOURCE &&
1877 component->hasSourceFeature)
1878 {
1879 component->Action = INSTALLSTATE_UNKNOWN;
1881 }
1882
1883 if (component->Action == INSTALLSTATE_LOCAL || component->Action == INSTALLSTATE_SOURCE)
1884 component->num_clients++;
1885 else if (component->Action == INSTALLSTATE_ABSENT)
1886 {
1887 component->num_clients--;
1888
1889 if (component->num_clients > 0)
1890 {
1891 TRACE("multiple clients uses %s - disallowing uninstallation\n", debugstr_w(component->Component));
1892 component->Action = INSTALLSTATE_UNKNOWN;
1893 }
1894 }
1895
1896 TRACE("component %s (installed %d request %d action %d)\n",
1897 debugstr_w(component->Component), component->Installed, component->ActionRequest, component->Action);
1898 }
1899
1900 return ERROR_SUCCESS;
1901}
1902
1904{
1905 MSIPACKAGE *package = param;
1906 LPCWSTR name;
1908
1910
1911 feature = msi_get_loaded_feature( package, name );
1912 if (!feature)
1913 ERR("FAILED to find loaded feature %s\n",debugstr_w(name));
1914 else
1915 {
1918
1920 {
1922 TRACE("Resetting feature %s to level %i\n", debugstr_w(name), level);
1923 feature->Level = level;
1924 }
1925 }
1926 return ERROR_SUCCESS;
1927}
1928
1930{
1931 DWORD ms, ls;
1932
1934
1935 if (fi->dwFileVersionMS > ms) return 1;
1936 else if (fi->dwFileVersionMS < ms) return -1;
1937 else if (fi->dwFileVersionLS > ls) return 1;
1938 else if (fi->dwFileVersionLS < ls) return -1;
1939 return 0;
1940}
1941
1942int msi_compare_font_versions( const WCHAR *ver1, const WCHAR *ver2 )
1943{
1944 DWORD ms1, ms2;
1945
1946 msi_parse_version_string( ver1, &ms1, NULL );
1947 msi_parse_version_string( ver2, &ms2, NULL );
1948
1949 if (ms1 > ms2) return 1;
1950 else if (ms1 < ms2) return -1;
1951 return 0;
1952}
1953
1955{
1956 static UINT id;
1957 WCHAR *ret;
1958
1959 if (!db->tempfolder)
1960 {
1961 WCHAR tmp[MAX_PATH];
1962 DWORD len = ARRAY_SIZE( tmp );
1963
1964 if (msi_get_property( db, L"TempFolder", tmp, &len ) ||
1966 {
1967 GetTempPathW( MAX_PATH, tmp );
1968 }
1969 if (!(db->tempfolder = wcsdup( tmp ))) return NULL;
1970 }
1971
1972 if ((ret = malloc( (wcslen( db->tempfolder ) + 20) * sizeof(WCHAR) )))
1973 {
1974 for (;;)
1975 {
1976 if (!GetTempFileNameW( db->tempfolder, L"msi", ++id, ret ))
1977 {
1978 free( ret );
1979 return NULL;
1980 }
1981 if (CreateDirectoryW( ret, NULL )) break;
1982 }
1983 }
1984
1985 return ret;
1986}
1987
1988/*
1989 * msi_build_directory_name()
1990 *
1991 * This function is to save messing round with directory names
1992 * It handles adding backslashes between path segments,
1993 * and can add \ at the end of the directory name if told to.
1994 *
1995 * It takes a variable number of arguments.
1996 * It always allocates a new string for the result, so make sure
1997 * to free the return value when finished with it.
1998 *
1999 * The first arg is the number of path segments that follow.
2000 * The arguments following count are a list of path segments.
2001 * A path segment may be NULL.
2002 *
2003 * Path segments will be added with a \ separating them.
2004 * A \ will not be added after the last segment, however if the
2005 * last segment is NULL, then the last character will be a \
2006 */
2008{
2009 DWORD sz = 1, i;
2010 WCHAR *dir;
2011 va_list va;
2012
2013 va_start( va, count );
2014 for (i = 0; i < count; i++)
2015 {
2016 const WCHAR *str = va_arg( va, const WCHAR * );
2017 if (str) sz += lstrlenW( str ) + 1;
2018 }
2019 va_end( va );
2020
2021 dir = malloc( sz * sizeof(WCHAR) );
2022 dir[0] = 0;
2023
2024 va_start( va, count );
2025 for (i = 0; i < count; i++)
2026 {
2027 const WCHAR *str = va_arg( va, const WCHAR * );
2028 if (!str) continue;
2029 lstrcatW( dir, str );
2030 if ( i + 1 != count && dir[0] && dir[lstrlenW( dir ) - 1] != '\\') lstrcatW( dir, L"\\" );
2031 }
2032 va_end( va );
2033 return dir;
2034}
2035
2037{
2038 return comp->assembly && !comp->assembly->application;
2039}
2040
2041static void set_target_path( MSIPACKAGE *package, MSIFILE *file )
2042{
2043 free( file->TargetPath );
2044 if (msi_is_global_assembly( file->Component ))
2045 {
2046 MSIASSEMBLY *assembly = file->Component->assembly;
2047
2048 if (!assembly->tempdir) assembly->tempdir = create_temp_dir( package->db );
2049 file->TargetPath = msi_build_directory_name( 2, assembly->tempdir, file->FileName );
2050 }
2051 else
2052 {
2053 const WCHAR *dir = msi_get_target_folder( package, file->Component->Directory );
2054 file->TargetPath = msi_build_directory_name( 2, dir, file->FileName );
2055 }
2056
2057 TRACE("file %s resolves to %s\n", debugstr_w(file->File), debugstr_w(file->TargetPath));
2058}
2059
2061{
2062 VS_FIXEDFILEINFO *file_version;
2063 WCHAR *font_version;
2064 MSIFILE *file;
2065
2067 {
2068 MSICOMPONENT *comp = file->Component;
2070
2071 if (!comp->Enabled) continue;
2072
2073 if (file->IsCompressed)
2074 comp->ForceLocalState = TRUE;
2075
2076 set_target_path( package, file );
2077
2078 if (msi_get_file_attributes( package, file->TargetPath ) == INVALID_FILE_ATTRIBUTES)
2079 {
2080 comp->cost += cost_from_size( file->FileSize );
2081 continue;
2082 }
2083 file_size = msi_get_disk_file_size( package, file->TargetPath );
2084 TRACE("%s (size %lu)\n", debugstr_w(file->TargetPath), file_size);
2085
2086 if (file->Version)
2087 {
2088 if ((file_version = msi_get_disk_file_version( package, file->TargetPath )))
2089 {
2090 if (msi_compare_file_versions( file_version, file->Version ) < 0)
2091 {
2092 comp->cost += cost_from_size( file->FileSize - file_size );
2093 }
2094 free( file_version );
2095 continue;
2096 }
2097 else if ((font_version = msi_get_font_file_version( package, file->TargetPath )))
2098 {
2099 if (msi_compare_font_versions( font_version, file->Version ) < 0)
2100 {
2101 comp->cost += cost_from_size( file->FileSize - file_size );
2102 }
2103 free( font_version );
2104 continue;
2105 }
2106 }
2107 if (file_size != file->FileSize)
2108 {
2109 comp->cost += cost_from_size( file->FileSize - file_size );
2110 }
2111 }
2112
2113 return ERROR_SUCCESS;
2114}
2115
2117{
2118 const WCHAR *p = in;
2119 WCHAR *q, *ret;
2120 int n, len = lstrlenW( in ) + 2;
2121
2122 if (!(q = ret = malloc( len * sizeof(WCHAR) ))) return NULL;
2123
2124 len = 0;
2125 while (1)
2126 {
2127 /* copy until the end of the string or a space */
2128 while (*p != ' ' && (*q = *p))
2129 {
2130 p++, len++;
2131 /* reduce many backslashes to one */
2132 if (*p != '\\' || *q != '\\')
2133 q++;
2134 }
2135
2136 /* quit at the end of the string */
2137 if (!*p)
2138 break;
2139
2140 /* count the number of spaces */
2141 n = 0;
2142 while (p[n] == ' ')
2143 n++;
2144
2145 /* if it's leading or trailing space, skip it */
2146 if ( len == 0 || p[-1] == '\\' || p[n] == '\\' )
2147 p += n;
2148 else /* copy n spaces */
2149 while (n && (*q++ = *p++)) n--;
2150 }
2151 while (q - ret > 0 && q[-1] == ' ') q--;
2152 if (q - ret > 0 && q[-1] != '\\')
2153 {
2154 q[0] = '\\';
2155 q[1] = 0;
2156 }
2157 return ret;
2158}
2159
2161{
2162 HKEY hkey;
2163 WCHAR *path;
2164
2165 if (!package->ProductCode) return NULL;
2166 if (MSIREG_OpenInstallProps( package->ProductCode, package->Context, NULL, &hkey, FALSE )) return NULL;
2167 if ((path = msi_reg_get_val_str( hkey, L"InstallLocation" )) && !path[0])
2168 {
2169 free( path );
2170 path = NULL;
2171 }
2172 RegCloseKey( hkey );
2173 return path;
2174}
2175
2176void msi_resolve_target_folder( MSIPACKAGE *package, const WCHAR *name, BOOL load_prop )
2177{
2178 FolderList *fl;
2180 WCHAR *path, *normalized_path;
2181
2182 TRACE("resolving %s\n", debugstr_w(name));
2183
2184 if (!(folder = msi_get_loaded_folder( package, name ))) return;
2185
2186 if (!wcscmp( folder->Directory, L"TARGETDIR" )) /* special resolving for target root dir */
2187 {
2188 if (!(path = get_install_location( package )) &&
2189 (!load_prop || !(path = msi_dup_property( package->db, L"TARGETDIR" ))))
2190 {
2191 path = msi_dup_property( package->db, L"ROOTDRIVE" );
2192 }
2193 }
2194 else if (!load_prop || !(path = msi_dup_property( package->db, folder->Directory )))
2195 {
2196 if (folder->Parent && wcscmp( folder->Directory, folder->Parent ))
2197 {
2198 parent = msi_get_loaded_folder( package, folder->Parent );
2199 path = msi_build_directory_name( 3, parent->ResolvedTarget, folder->TargetDefault, NULL );
2200 }
2201 else
2202 path = msi_build_directory_name( 2, folder->TargetDefault, NULL );
2203 }
2204
2205 normalized_path = msi_normalize_path( path );
2206 msi_set_property( package->db, folder->Directory, normalized_path, -1 );
2207 free( path );
2208
2209 free( folder->ResolvedTarget );
2210 folder->ResolvedTarget = normalized_path;
2211
2213 {
2214 child = fl->folder;
2215 msi_resolve_target_folder( package, child->Directory, load_prop );
2216 }
2217 TRACE("%s resolves to %s\n", debugstr_w(name), debugstr_w(folder->ResolvedTarget));
2218}
2219
2221{
2222 MSICOMPONENT *comp;
2223 ULONGLONG ret = 0;
2224
2226 {
2227 if (comp->Action == INSTALLSTATE_LOCAL) ret += comp->cost;
2228 }
2229 return ret;
2230}
2231
2233{
2234 MSICOMPONENT *comp;
2235 MSIQUERY *view;
2236 WCHAR *level, *primary_key, *primary_folder;
2237 UINT rc;
2238
2239 TRACE("Building directory properties\n");
2240 msi_resolve_target_folder( package, L"TARGETDIR", TRUE );
2241
2242 TRACE("Evaluating component conditions\n");
2244 {
2245 if (MSI_EvaluateConditionW( package, comp->Condition ) == MSICONDITION_FALSE)
2246 {
2247 TRACE("Disabling component %s\n", debugstr_w(comp->Component));
2248 comp->Enabled = FALSE;
2249 }
2250 else
2251 comp->Enabled = TRUE;
2252 }
2253 get_client_counts( package );
2254
2255 /* read components states from the registry */
2258
2259 if (!process_overrides( package, msi_get_property_int( package->db, L"INSTALLLEVEL", 1 ) ))
2260 {
2261 TRACE("Evaluating feature conditions\n");
2262
2263 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Condition`", &view );
2264 if (rc == ERROR_SUCCESS)
2265 {
2267 msiobj_release( &view->hdr );
2268 if (rc != ERROR_SUCCESS)
2269 return rc;
2270 }
2271 }
2272
2273 TRACE("Calculating file cost\n");
2274 calculate_file_cost( package );
2275
2276 msi_set_property( package->db, L"CostingComplete", L"1", -1 );
2277 /* set default run level if not set */
2278 level = msi_dup_property( package->db, L"INSTALLLEVEL" );
2279 if (!level) msi_set_property( package->db, L"INSTALLLEVEL", L"1", -1 );
2280 free(level);
2281
2282 if ((rc = MSI_SetFeatureStates( package ))) return rc;
2283
2284 if ((primary_key = msi_dup_property( package->db, L"PRIMARYFOLDER" )))
2285 {
2286 if ((primary_folder = msi_dup_property( package->db, primary_key )))
2287 {
2288 if (((primary_folder[0] >= 'A' && primary_folder[0] <= 'Z') ||
2289 (primary_folder[0] >= 'a' && primary_folder[0] <= 'z')) && primary_folder[1] == ':')
2290 {
2292 ULONGLONG required;
2293 WCHAR buf[21];
2294
2295 primary_folder[2] = 0;
2296 if (GetDiskFreeSpaceExW( primary_folder, &free, NULL, NULL ))
2297 {
2298#ifdef __REACTOS__
2299 swprintf(buf, ARRAY_SIZE(buf), L"%I64u", free.QuadPart / 512);
2300#else
2301 swprintf( buf, ARRAY_SIZE(buf), L"%lu", free.QuadPart / 512 );
2302#endif
2303 msi_set_property( package->db, L"PrimaryVolumeSpaceAvailable", buf, -1 );
2304 }
2305 required = get_volume_space_required( package );
2306#ifdef __REACTOS__
2307 swprintf( buf, ARRAY_SIZE(buf), L"%I64u", required );
2308#else
2309 swprintf( buf, ARRAY_SIZE(buf), L"%lu", required );
2310#endif
2311 msi_set_property( package->db, L"PrimaryVolumeSpaceRequired", buf, -1 );
2312
2313#ifdef __REACTOS__
2314 swprintf( buf, ARRAY_SIZE(buf), L"%I64u", (free.QuadPart / 512) - required );
2315#else
2316 swprintf( buf, ARRAY_SIZE(buf), L"%lu", (free.QuadPart / 512) - required );
2317#endif
2318 msi_set_property( package->db, L"PrimaryVolumeSpaceRemaining", buf, -1 );
2319 msi_set_property( package->db, L"PrimaryVolumePath", primary_folder, 2 );
2320 }
2321 free( primary_folder );
2322 }
2323 free( primary_key );
2324 }
2325
2326 /* FIXME: check volume disk space */
2327 msi_set_property( package->db, L"OutOfDiskSpace", L"0", -1 );
2328 msi_set_property( package->db, L"OutOfNoRbDiskSpace", L"0", -1 );
2329
2330 return ERROR_SUCCESS;
2331}
2332
2334{
2335 BYTE *data;
2336
2337 if (!value)
2338 {
2339 *size = sizeof(WCHAR);
2340 *type = REG_SZ;
2341 if ((data = malloc( *size ))) *(WCHAR *)data = 0;
2342 return data;
2343 }
2344 if (value[0]=='#' && value[1]!='#' && value[1]!='%')
2345 {
2346 if (value[1]=='x')
2347 {
2348 LPWSTR ptr;
2349 CHAR byte[5];
2350 LPWSTR deformated = NULL;
2351 int count;
2352
2353 deformat_string(package, &value[2], &deformated);
2354
2355 /* binary value type */
2356 ptr = deformated;
2357 *type = REG_BINARY;
2358 if (lstrlenW(ptr)%2)
2359 *size = (lstrlenW(ptr)/2)+1;
2360 else
2361 *size = lstrlenW(ptr)/2;
2362
2363 data = malloc(*size);
2364
2365 byte[0] = '0';
2366 byte[1] = 'x';
2367 byte[4] = 0;
2368 count = 0;
2369 /* if uneven pad with a zero in front */
2370 if (lstrlenW(ptr)%2)
2371 {
2372 byte[2]= '0';
2373 byte[3]= *ptr;
2374 ptr++;
2375 data[count] = (BYTE)strtol(byte,NULL,0);
2376 count ++;
2377 TRACE("Uneven byte count\n");
2378 }
2379 while (*ptr)
2380 {
2381 byte[2]= *ptr;
2382 ptr++;
2383 byte[3]= *ptr;
2384 ptr++;
2385 data[count] = (BYTE)strtol(byte,NULL,0);
2386 count ++;
2387 }
2388 free(deformated);
2389
2390 TRACE( "data %lu bytes(%u)\n", *size, count );
2391 }
2392 else
2393 {
2394 LPWSTR deformated;
2395 LPWSTR p;
2396 DWORD d = 0;
2397 deformat_string(package, &value[1], &deformated);
2398
2399 *type=REG_DWORD;
2400 *size = sizeof(DWORD);
2401 data = malloc(*size);
2402 p = deformated;
2403 if (*p == '-')
2404 p++;
2405 while (*p)
2406 {
2407 if ( (*p < '0') || (*p > '9') )
2408 break;
2409 d *= 10;
2410 d += (*p - '0');
2411 p++;
2412 }
2413 if (deformated[0] == '-')
2414 d = -d;
2415 *(DWORD *)data = d;
2416 TRACE( "DWORD %lu\n", *(DWORD *)data);
2417
2418 free(deformated);
2419 }
2420 }
2421 else
2422 {
2423 const WCHAR *ptr = value;
2424
2425 *type = REG_SZ;
2426 if (value[0] == '#')
2427 {
2428 ptr++; len--;
2429 if (value[1] == '%')
2430 {
2431 ptr++; len--;
2433 }
2434 }
2435 data = (BYTE *)msi_strdupW( ptr, len );
2436 if (len > lstrlenW( (const WCHAR *)data )) *type = REG_MULTI_SZ;
2437 *size = (len + 1) * sizeof(WCHAR);
2438 }
2439 return data;
2440}
2441
2442static const WCHAR *get_root_key( MSIPACKAGE *package, INT root, HKEY *root_key )
2443{
2444 const WCHAR *ret;
2445
2446 switch (root)
2447 {
2448 case -1:
2449 if (msi_get_property_int( package->db, L"ALLUSERS", 0 ))
2450 {
2451 *root_key = HKEY_LOCAL_MACHINE;
2452 ret = L"HKEY_LOCAL_MACHINE\\";
2453 }
2454 else
2455 {
2456 *root_key = HKEY_CURRENT_USER;
2457 ret = L"HKEY_CURRENT_USER\\";
2458 }
2459 break;
2460 case 0:
2461 *root_key = HKEY_CLASSES_ROOT;
2462 ret = L"HKEY_CLASSES_ROOT\\";
2463 break;
2464 case 1:
2465 *root_key = HKEY_CURRENT_USER;
2466 ret = L"HKEY_CURRENT_USER\\";
2467 break;
2468 case 2:
2469 *root_key = HKEY_LOCAL_MACHINE;
2470 ret = L"HKEY_LOCAL_MACHINE\\";
2471 break;
2472 case 3:
2473 *root_key = HKEY_USERS;
2474 ret = L"HKEY_USERS\\";
2475 break;
2476 default:
2477 ERR("Unknown root %i\n", root);
2478 return NULL;
2479 }
2480
2481 return ret;
2482}
2483
2484static inline REGSAM get_registry_view( const MSICOMPONENT *comp )
2485{
2486 REGSAM view = 0;
2487 if (is_wow64 || is_64bit)
2489 return view;
2490}
2491
2493{
2494 WCHAR *subkey, *p, *q;
2495 HKEY hkey, ret = NULL;
2496 LONG res;
2497
2498 access |= get_registry_view( comp );
2499
2500 if (!(subkey = wcsdup( path ))) return NULL;
2501 p = subkey;
2502 if ((q = wcschr( p, '\\' ))) *q = 0;
2503 if (create)
2504 res = RegCreateKeyExW( root, subkey, 0, NULL, 0, access, NULL, &hkey, NULL );
2505 else
2506 res = RegOpenKeyExW( root, subkey, 0, access, &hkey );
2507 if (res)
2508 {
2509 TRACE( "failed to open key %s (%ld)\n", debugstr_w(subkey), res );
2510 free( subkey );
2511 return NULL;
2512 }
2513 if (q && q[1])
2514 {
2515 ret = open_key( comp, hkey, q + 1, create, access );
2516 RegCloseKey( hkey );
2517 }
2518 else ret = hkey;
2519 free( subkey );
2520 return ret;
2521}
2522
2524{
2525 return (name && (name[0] == '*' || name[0] == '+') && !name[1]);
2526}
2527
2529{
2530 const WCHAR *p = str;
2531 WCHAR **ret;
2532 int i = 0;
2533
2534 *count = 0;
2535 if (!str) return NULL;
2536 while ((p - str) < len)
2537 {
2538 p += lstrlenW( p ) + 1;
2539 (*count)++;
2540 }
2541 if (!(ret = malloc( *count * sizeof(WCHAR *) ))) return NULL;
2542 p = str;
2543 while ((p - str) < len)
2544 {
2545 if (!(ret[i] = wcsdup( p )))
2546 {
2547 for (; i >= 0; i--) free( ret[i] );
2548 free( ret );
2549 return NULL;
2550 }
2551 p += lstrlenW( p ) + 1;
2552 i++;
2553 }
2554 return ret;
2555}
2556
2558 WCHAR **right, DWORD right_count, DWORD *size )
2559{
2560 WCHAR *ret, *p;
2561 unsigned int i;
2562
2563 *size = sizeof(WCHAR);
2564 for (i = 0; i < left_count; i++) *size += (lstrlenW( left[i] ) + 1) * sizeof(WCHAR);
2565 for (i = 0; i < right_count; i++) *size += (lstrlenW( right[i] ) + 1) * sizeof(WCHAR);
2566
2567 if (!(ret = p = malloc( *size ))) return NULL;
2568
2569 for (i = 0; i < left_count; i++)
2570 {
2571 lstrcpyW( p, left[i] );
2572 p += lstrlenW( p ) + 1;
2573 }
2574 for (i = 0; i < right_count; i++)
2575 {
2576 lstrcpyW( p, right[i] );
2577 p += lstrlenW( p ) + 1;
2578 }
2579 *p = 0;
2580 return ret;
2581}
2582
2583static DWORD remove_duplicate_values( WCHAR **old, DWORD old_count,
2584 WCHAR **new, DWORD new_count )
2585{
2586 DWORD ret = old_count;
2587 unsigned int i, j, k;
2588
2589 for (i = 0; i < new_count; i++)
2590 {
2591 for (j = 0; j < old_count; j++)
2592 {
2593 if (old[j] && !wcscmp( new[i], old[j] ))
2594 {
2595 free( old[j] );
2596 for (k = j; k < old_count - 1; k++) { old[k] = old[k + 1]; }
2597 old[k] = NULL;
2598 ret--;
2599 }
2600 }
2601 }
2602 return ret;
2603}
2604
2606{
2611
2612static WCHAR *join_multi_string_values( enum join_op op, WCHAR **old, DWORD old_count,
2613 WCHAR **new, DWORD new_count, DWORD *size )
2614{
2615 switch (op)
2616 {
2617 case JOIN_OP_APPEND:
2618 old_count = remove_duplicate_values( old, old_count, new, new_count );
2619 return flatten_multi_string_values( old, old_count, new, new_count, size );
2620
2621 case JOIN_OP_PREPEND:
2622 old_count = remove_duplicate_values( old, old_count, new, new_count );
2623 return flatten_multi_string_values( new, new_count, old, old_count, size );
2624
2625 case JOIN_OP_REPLACE:
2626 return flatten_multi_string_values( new, new_count, NULL, 0, size );
2627
2628 default:
2629 ERR("unhandled join op %u\n", op);
2630 return NULL;
2631 }
2632}
2633
2635 BYTE *new_value, DWORD new_size, DWORD *size )
2636{
2637 DWORD i, old_len = 0, new_len = 0, old_count = 0, new_count = 0;
2638 const WCHAR *new_ptr = NULL, *old_ptr = NULL;
2639 enum join_op op = JOIN_OP_REPLACE;
2640 WCHAR **old = NULL, **new = NULL;
2641 BYTE *ret;
2642
2643 if (new_size / sizeof(WCHAR) - 1 > 1)
2644 {
2645 new_ptr = (const WCHAR *)new_value;
2646 new_len = new_size / sizeof(WCHAR) - 1;
2647
2648 if (!new_ptr[0] && new_ptr[new_len - 1])
2649 {
2651 new_len--;
2652 new_ptr++;
2653 }
2654 else if (new_ptr[0] && !new_ptr[new_len - 1])
2655 {
2657 new_len--;
2658 }
2659 else if (new_len > 2 && !new_ptr[0] && !new_ptr[new_len - 1])
2660 {
2662 new_len -= 2;
2663 new_ptr++;
2664 }
2665 new = split_multi_string_values( new_ptr, new_len, &new_count );
2666 }
2667 if (old_size / sizeof(WCHAR) - 1 > 1)
2668 {
2669 old_ptr = (const WCHAR *)old_value;
2670 old_len = old_size / sizeof(WCHAR) - 1;
2671 old = split_multi_string_values( old_ptr, old_len, &old_count );
2672 }
2673 ret = (BYTE *)join_multi_string_values( op, old, old_count, new, new_count, size );
2674 for (i = 0; i < old_count; i++) free( old[i] );
2675 for (i = 0; i < new_count; i++) free( new[i] );
2676 free( old );
2677 free( new );
2678 return ret;
2679}
2680
2681static BYTE *reg_get_value( HKEY hkey, const WCHAR *name, DWORD *type, DWORD *size )
2682{
2683 BYTE *ret;
2684 if (RegQueryValueExW( hkey, name, NULL, NULL, NULL, size )) return NULL;
2685 if (!(ret = malloc( *size ))) return NULL;
2686 RegQueryValueExW( hkey, name, NULL, type, ret, size );
2687 return ret;
2688}
2689
2691{
2692 MSIPACKAGE *package = param;
2693 BYTE *new_value, *old_value = NULL;
2694 HKEY root_key, hkey;
2695 DWORD type, old_type, new_size, old_size = 0;
2696 LPWSTR deformated, uikey;
2697 const WCHAR *szRoot, *component, *name, *key, *str;
2698 MSICOMPONENT *comp;
2699 MSIRECORD * uirow;
2700 INT root;
2701 BOOL check_first = FALSE;
2702 int len;
2703
2704 msi_ui_progress( package, 2, REG_PROGRESS_VALUE, 0, 0 );
2705
2706 component = MSI_RecordGetString(row, 6);
2707 comp = msi_get_loaded_component(package,component);
2708 if (!comp)
2709 return ERROR_SUCCESS;
2710
2711 comp->Action = msi_get_component_action( package, comp );
2712 if (comp->Action != INSTALLSTATE_LOCAL && comp->Action != INSTALLSTATE_SOURCE)
2713 {
2714 TRACE("component not scheduled for installation %s\n", debugstr_w(component));
2715 return ERROR_SUCCESS;
2716 }
2717
2719 if( MSI_RecordIsNull(row,5) && name )
2720 {
2721 /* null values can have special meanings */
2722 if (name[0]=='-' && name[1] == 0)
2723 return ERROR_SUCCESS;
2724 if ((name[0] == '+' || name[0] == '*') && !name[1])
2725 check_first = TRUE;
2726 }
2727
2730
2731 szRoot = get_root_key( package, root, &root_key );
2732 if (!szRoot)
2733 return ERROR_SUCCESS;
2734
2735 deformat_string(package, key , &deformated);
2736 uikey = malloc( (wcslen(deformated) + wcslen(szRoot) + 1) * sizeof(WCHAR) );
2737 lstrcpyW(uikey,szRoot);
2738 lstrcatW(uikey,deformated);
2739
2740 if (!(hkey = open_key( comp, root_key, deformated, TRUE, KEY_QUERY_VALUE | KEY_SET_VALUE )))
2741 {
2742 ERR("Could not create key %s\n", debugstr_w(deformated));
2743 free(uikey);
2744 free(deformated);
2745 return ERROR_FUNCTION_FAILED;
2746 }
2747 free( deformated );
2749 len = deformat_string( package, str, &deformated );
2750 new_value = parse_value( package, deformated, len, &type, &new_size );
2751
2752 free( deformated );
2753 deformat_string(package, name, &deformated);
2754
2755 if (!is_special_entry( name ))
2756 {
2757 old_value = reg_get_value( hkey, deformated, &old_type, &old_size );
2758 if (type == REG_MULTI_SZ)
2759 {
2760 BYTE *new;
2761 if (old_value && old_type != REG_MULTI_SZ)
2762 {
2763 free( old_value );
2764 old_value = NULL;
2765 old_size = 0;
2766 }
2767 new = build_multi_string_value( old_value, old_size, new_value, new_size, &new_size );
2768 free( new_value );
2769 new_value = new;
2770 }
2771 if (!check_first)
2772 {
2773 TRACE( "setting value %s of %s type %lu\n", debugstr_w(deformated), debugstr_w(uikey), type );
2774 RegSetValueExW( hkey, deformated, 0, type, new_value, new_size );
2775 }
2776 else if (!old_value)
2777 {
2778 if (deformated || new_size)
2779 {
2780 TRACE( "setting value %s of %s type %lu\n", debugstr_w(deformated), debugstr_w(uikey), type );
2781 RegSetValueExW( hkey, deformated, 0, type, new_value, new_size );
2782 }
2783 }
2784 else TRACE("not overwriting existing value %s of %s\n", debugstr_w(deformated), debugstr_w(uikey));
2785 }
2786 RegCloseKey(hkey);
2787
2788 uirow = MSI_CreateRecord(3);
2789 MSI_RecordSetStringW(uirow,2,deformated);
2790 MSI_RecordSetStringW(uirow,1,uikey);
2791 if (type == REG_SZ || type == REG_EXPAND_SZ)
2792 MSI_RecordSetStringW(uirow, 3, (LPWSTR)new_value);
2794 msiobj_release( &uirow->hdr );
2795
2796 free(new_value);
2797 free(old_value);
2798 free(deformated);
2799 free(uikey);
2800
2801 return ERROR_SUCCESS;
2802}
2803
2805{
2806 MSIQUERY *view;
2807 UINT rc;
2808
2809 if (package->script == SCRIPT_NONE)
2810 return msi_schedule_action(package, SCRIPT_INSTALL, L"WriteRegistryValues");
2811
2812 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `Registry`", &view);
2813 if (rc != ERROR_SUCCESS)
2814 return ERROR_SUCCESS;
2815
2817 msiobj_release(&view->hdr);
2818 return rc;
2819}
2820
2821static int is_key_empty(const MSICOMPONENT *comp, HKEY root, const WCHAR *path)
2822{
2823 DWORD subkeys, values;
2824 HKEY key;
2825 LONG res;
2826
2827 key = open_key(comp, root, path, FALSE, KEY_READ);
2828 if (!key) return 0;
2829
2830 res = RegQueryInfoKeyW(key, 0, 0, 0, &subkeys, 0, 0, &values, 0, 0, 0, 0);
2832
2833 return !res && !subkeys && !values;
2834}
2835
2836static void delete_key( const MSICOMPONENT *comp, HKEY root, const WCHAR *path )
2837{
2840 WCHAR *subkey, *p;
2841 HKEY hkey;
2842
2843 if (!(subkey = wcsdup( path ))) return;
2844 do
2845 {
2846 if ((p = wcsrchr( subkey, '\\' )))
2847 {
2848 *p = 0;
2849 if (!p[1]) continue; /* trailing backslash */
2850 hkey = open_key( comp, root, subkey, FALSE, READ_CONTROL );
2851 if (!hkey) break;
2852 if (!is_key_empty(comp, hkey, p + 1))
2853 {
2854 RegCloseKey(hkey);
2855 break;
2856 }
2857 res = RegDeleteKeyExW( hkey, p + 1, access, 0 );
2858 RegCloseKey( hkey );
2859 }
2860 else if (is_key_empty(comp, root, subkey))
2861 res = RegDeleteKeyExW( root, subkey, access, 0 );
2862 if (res)
2863 {
2864 TRACE( "failed to delete key %s (%ld)\n", debugstr_w(subkey), res );
2865 break;
2866 }
2867 } while (p);
2868 free( subkey );
2869}
2870
2871static void delete_value( const MSICOMPONENT *comp, HKEY root, const WCHAR *path, const WCHAR *value )
2872{
2873 LONG res;
2874 HKEY hkey;
2875
2876 if ((hkey = open_key( comp, root, path, FALSE, KEY_SET_VALUE | KEY_QUERY_VALUE )))
2877 {
2878 if ((res = RegDeleteValueW( hkey, value )))
2879 TRACE( "failed to delete value %s (%ld)\n", debugstr_w(value), res );
2880
2881 RegCloseKey( hkey );
2882 if (is_key_empty(comp, root, path))
2883 {
2884 TRACE("removing empty key %s\n", debugstr_w(path));
2885 delete_key( comp, root, path );
2886 }
2887 }
2888}
2889
2890static void delete_tree( const MSICOMPONENT *comp, HKEY root, const WCHAR *path )
2891{
2892 LONG res;
2893 HKEY hkey;
2894
2895 if (!(hkey = open_key( comp, root, path, FALSE, KEY_ALL_ACCESS ))) return;
2896 res = RegDeleteTreeW( hkey, NULL );
2897 if (res) TRACE( "failed to delete subtree of %s (%ld)\n", debugstr_w(path), res );
2898 delete_key( comp, root, path );
2899 RegCloseKey( hkey );
2900}
2901
2903{
2904 MSIPACKAGE *package = param;
2905 LPCWSTR component, name, key_str, root_key_str;
2906 LPWSTR deformated_key, deformated_name, ui_key_str;
2907 MSICOMPONENT *comp;
2908 MSIRECORD *uirow;
2910 HKEY hkey_root;
2911 UINT size;
2912 INT root;
2913
2914 msi_ui_progress( package, 2, REG_PROGRESS_VALUE, 0, 0 );
2915
2916 component = MSI_RecordGetString( row, 6 );
2917 comp = msi_get_loaded_component( package, component );
2918 if (!comp)
2919 return ERROR_SUCCESS;
2920
2921 comp->Action = msi_get_component_action( package, comp );
2922 if (comp->Action != INSTALLSTATE_ABSENT)
2923 {
2924 TRACE("component not scheduled for removal %s\n", debugstr_w(component));
2925 return ERROR_SUCCESS;
2926 }
2927
2929 if (MSI_RecordIsNull( row, 5 ) && name )
2930 {
2931 if (name[0] == '+' && !name[1])
2932 return ERROR_SUCCESS;
2933 if ((name[0] == '-' || name[0] == '*') && !name[1])
2934 {
2935 delete_key = TRUE;
2936 name = NULL;
2937 }
2938 }
2939
2941 key_str = MSI_RecordGetString( row, 3 );
2942
2943 root_key_str = get_root_key( package, root, &hkey_root );
2944 if (!root_key_str)
2945 return ERROR_SUCCESS;
2946
2947 deformat_string( package, key_str, &deformated_key );
2948 size = lstrlenW( deformated_key ) + lstrlenW( root_key_str ) + 1;
2949 ui_key_str = malloc( size * sizeof(WCHAR) );
2950 lstrcpyW( ui_key_str, root_key_str );
2951 lstrcatW( ui_key_str, deformated_key );
2952
2953 deformat_string( package, name, &deformated_name );
2954
2955 if (delete_key) delete_tree( comp, hkey_root, deformated_key );
2956 else delete_value( comp, hkey_root, deformated_key, deformated_name );
2957 free( deformated_key );
2958
2959 uirow = MSI_CreateRecord( 2 );
2960 MSI_RecordSetStringW( uirow, 1, ui_key_str );
2961 MSI_RecordSetStringW( uirow, 2, deformated_name );
2963 msiobj_release( &uirow->hdr );
2964
2965 free( ui_key_str );
2966 free( deformated_name );
2967 return ERROR_SUCCESS;
2968}
2969
2971{
2972 MSIPACKAGE *package = param;
2973 LPCWSTR component, name, key_str, root_key_str;
2974 LPWSTR deformated_key, deformated_name, ui_key_str;
2975 MSICOMPONENT *comp;
2976 MSIRECORD *uirow;
2978 HKEY hkey_root;
2979 UINT size;
2980 INT root;
2981
2982 component = MSI_RecordGetString( row, 5 );
2983 comp = msi_get_loaded_component( package, component );
2984 if (!comp)
2985 return ERROR_SUCCESS;
2986
2987 comp->Action = msi_get_component_action( package, comp );
2988 if (comp->Action != INSTALLSTATE_LOCAL)
2989 {
2990 TRACE("component not scheduled for installation %s\n", debugstr_w(component));
2991 return ERROR_SUCCESS;
2992 }
2993
2994 if ((name = MSI_RecordGetString( row, 4 )))
2995 {
2996 if (name[0] == '-' && !name[1])
2997 {
2998 delete_key = TRUE;
2999 name = NULL;
3000 }
3001 }
3002
3004 key_str = MSI_RecordGetString( row, 3 );
3005
3006 root_key_str = get_root_key( package, root, &hkey_root );
3007 if (!root_key_str)
3008 return ERROR_SUCCESS;
3009
3010 deformat_string( package, key_str, &deformated_key );
3011 size = lstrlenW( deformated_key ) + lstrlenW( root_key_str ) + 1;
3012 ui_key_str = malloc( size * sizeof(WCHAR) );
3013 lstrcpyW( ui_key_str, root_key_str );
3014 lstrcatW( ui_key_str, deformated_key );
3015
3016 deformat_string( package, name, &deformated_name );
3017
3018 if (delete_key) delete_tree( comp, hkey_root, deformated_key );
3019 else delete_value( comp, hkey_root, deformated_key, deformated_name );
3020 free( deformated_key );
3021
3022 uirow = MSI_CreateRecord( 2 );
3023 MSI_RecordSetStringW( uirow, 1, ui_key_str );
3024 MSI_RecordSetStringW( uirow, 2, deformated_name );
3026 msiobj_release( &uirow->hdr );
3027
3028 free( ui_key_str );
3029 free( deformated_name );
3030 return ERROR_SUCCESS;
3031}
3032
3034{
3035 MSIQUERY *view;
3036 UINT rc;
3037
3038 if (package->script == SCRIPT_NONE)
3039 return msi_schedule_action(package, SCRIPT_INSTALL, L"RemoveRegistryValues");
3040
3041 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Registry`", &view );
3042 if (rc == ERROR_SUCCESS)
3043 {
3045 msiobj_release( &view->hdr );
3046 if (rc != ERROR_SUCCESS)
3047 return rc;
3048 }
3049 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `RemoveRegistry`", &view );
3050 if (rc == ERROR_SUCCESS)
3051 {
3053 msiobj_release( &view->hdr );
3054 if (rc != ERROR_SUCCESS)
3055 return rc;
3056 }
3057 return ERROR_SUCCESS;
3058}
3059
3061{
3062 return ERROR_SUCCESS;
3063}
3064
3065
3067{
3068 MSICOMPONENT *comp;
3069 DWORD total = 0, count = 0;
3070 MSIQUERY *view;
3072 MSIFILE *file;
3073 UINT rc;
3074
3075 TRACE("InstallValidate\n");
3076
3077 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Registry`", &view );
3078 if (rc == ERROR_SUCCESS)
3079 {
3080 rc = MSI_IterateRecords( view, &count, NULL, package );
3081 msiobj_release( &view->hdr );
3082 if (rc != ERROR_SUCCESS)
3083 return rc;
3085 }
3088
3090 total += file->FileSize;
3091
3092 msi_ui_progress( package, 0, total, 0, 0 );
3093
3095 {
3096 TRACE("Feature: %s Installed %d Request %d Action %d\n",
3097 debugstr_w(feature->Feature), feature->Installed,
3098 feature->ActionRequest, feature->Action);
3099 }
3100 return ERROR_SUCCESS;
3101}
3102
3104{
3105 MSIPACKAGE* package = param;
3106 const WCHAR *cond, *message;
3107 UINT r;
3108
3109 cond = MSI_RecordGetString(row, 1);
3110 r = MSI_EvaluateConditionW(package, cond);
3111 if (r == MSICONDITION_FALSE)
3112 {
3113 if ((package->ui_level & INSTALLUILEVEL_MASK) != INSTALLUILEVEL_NONE)
3114 {
3115 WCHAR *deformated;
3117 deformat_string(package, message, &deformated);
3118 MessageBoxW(NULL, deformated, L"Install Failed", MB_OK);
3119 free(deformated);
3120 }
3121
3122 return ERROR_INSTALL_FAILURE;
3123 }
3124
3125 return ERROR_SUCCESS;
3126}
3127
3129{
3130 MSIQUERY *view;
3131 UINT rc;
3132
3133 TRACE("Checking launch conditions\n");
3134
3135 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `LaunchCondition`", &view);
3136 if (rc != ERROR_SUCCESS)
3137 return ERROR_SUCCESS;
3138
3140 msiobj_release(&view->hdr);
3141 return rc;
3142}
3143
3145{
3146
3147 if (!cmp->KeyPath)
3148 return wcsdup( msi_get_target_folder( package, cmp->Directory ) );
3149
3151 {
3152 MSIRECORD *row;
3153 UINT root, len;
3154 LPWSTR deformated, buffer, deformated_name;
3155 LPCWSTR key, name;
3156
3157 row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Registry` WHERE `Registry` = '%s'", cmp->KeyPath);
3158 if (!row)
3159 return NULL;
3160
3164 deformat_string(package, key , &deformated);
3165 deformat_string(package, name, &deformated_name);
3166
3167 len = lstrlenW(deformated) + 6;
3168 if (deformated_name)
3169 len+=lstrlenW(deformated_name);
3170
3171 buffer = malloc(len * sizeof(WCHAR));
3172
3173 if (deformated_name)
3174 swprintf(buffer, len, L"%02d:\\%s\\%s", root, deformated, deformated_name);
3175 else
3176 swprintf(buffer, len, L"%02d:\\%s\\", root, deformated);
3177
3178 free(deformated);
3179 free(deformated_name);
3180 msiobj_release(&row->hdr);
3181
3182 return buffer;
3183 }
3184 else if (cmp->Attributes & msidbComponentAttributesODBCDataSource)
3185 {
3186 FIXME("UNIMPLEMENTED keypath as ODBC Source\n");
3187 return NULL;
3188 }
3189 else
3190 {
3191 MSIFILE *file = msi_get_loaded_file( package, cmp->KeyPath );
3192
3193 if (file)
3194 return wcsdup( file->TargetPath );
3195 }
3196 return NULL;
3197}
3198
3200{
3201 return open_key( comp, HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\SharedDLLs",
3202 create, access );
3203}
3204
3206{
3207 DWORD count, type, sz = sizeof(count);
3208 HKEY hkey = open_shared_dlls_key( comp, FALSE, KEY_READ );
3209 if (RegQueryValueExW( hkey, comp->FullKeypath, NULL, &type, (BYTE *)&count, &sz )) count = 0;
3210 RegCloseKey( hkey );
3211 return count;
3212}
3213
3215{
3217 if (count > 0)
3219 else
3220 RegDeleteValueW( hkey, path );
3221 RegCloseKey(hkey);
3222}
3223
3224static void refcount_component( MSIPACKAGE *package, MSICOMPONENT *comp )
3225{
3227 INT count = 0;
3228 BOOL write = FALSE;
3229
3230 /* only refcount DLLs */
3231 if (!comp->KeyPath || comp->assembly || comp->Attributes & msidbComponentAttributesRegistryKeyPath ||
3233 write = FALSE;
3234 else
3235 {
3236 count = get_shared_dlls_count( comp );
3237 write = (count > 0);
3239 write = TRUE;
3240 }
3241
3242 /* increment counts */
3244 {
3245 ComponentList *cl;
3246
3248 continue;
3249
3250 LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
3251 {
3252 if ( cl->component == comp )
3253 count++;
3254 }
3255 }
3256
3257 /* decrement counts */
3259 {
3260 ComponentList *cl;
3261
3263 continue;
3264
3265 LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
3266 {
3267 if ( cl->component == comp )
3268 count--;
3269 }
3270 }
3271
3272 /* ref count all the files in the component */
3273 if (write)
3274 {
3275 MSIFILE *file;
3276
3278 {
3279 if (file->Component == comp)
3280 write_shared_dlls_count( comp, file->TargetPath, count );
3281 }
3282 }
3283
3284 /* add a count for permanent */
3286 count ++;
3287
3288 comp->RefCount = count;
3289
3290 if (write)
3291 write_shared_dlls_count( comp, comp->FullKeypath, comp->RefCount );
3292}
3293
3295{
3296 if (comp->assembly)
3297 {
3298 DWORD len = lstrlenW( L"<\\" ) + lstrlenW( comp->assembly->display_name );
3299 WCHAR *keypath = malloc( (len + 1) * sizeof(WCHAR) );
3300
3301 if (keypath)
3302 {
3303 lstrcpyW( keypath, L"<\\" );
3304 lstrcatW( keypath, comp->assembly->display_name );
3305 }
3306 return keypath;
3307 }
3308 return resolve_keypath( package, comp );
3309}
3310
3312{
3313 WCHAR squashed_pc[SQUASHED_GUID_SIZE], squashed_cc[SQUASHED_GUID_SIZE];
3314 UINT rc;
3315 MSICOMPONENT *comp;
3316 HKEY hkey;
3317
3318 TRACE("\n");
3319
3321
3322 if (package->script == SCRIPT_NONE)
3323 return msi_schedule_action(package, SCRIPT_INSTALL, L"ProcessComponents");
3324
3325 squash_guid( package->ProductCode, squashed_pc );
3326
3328 {
3329 MSIRECORD *uirow;
3331
3332 msi_ui_progress( package, 2, COMPONENT_PROGRESS_VALUE, 0, 0 );
3333 if (!comp->ComponentId)
3334 continue;
3335
3336 squash_guid( comp->ComponentId, squashed_cc );
3337 free( comp->FullKeypath );
3338 comp->FullKeypath = build_full_keypath( package, comp );
3339
3340 refcount_component( package, comp );
3341
3342 if (package->need_rollback) action = comp->Installed;
3343 else action = comp->ActionRequest;
3344
3345 TRACE("Component %s (%s) Keypath=%s RefCount=%u Clients=%u Action=%u\n",
3346 debugstr_w(comp->Component), debugstr_w(squashed_cc),
3347 debugstr_w(comp->FullKeypath), comp->RefCount, comp->num_clients, action);
3348
3350 {
3351 if (package->Context == MSIINSTALLCONTEXT_MACHINE)
3352 rc = MSIREG_OpenUserDataComponentKey(comp->ComponentId, L"S-1-5-18", &hkey, TRUE);
3353 else
3355
3356 if (rc != ERROR_SUCCESS)
3357 continue;
3358
3360 {
3361 msi_reg_set_val_str(hkey, L"00000000000000000000000000000000", comp->FullKeypath);
3362 }
3364 msi_reg_set_val_str( hkey, squashed_pc, comp->FullKeypath );
3365 else
3366 {
3367 MSIFILE *file;
3368 MSIRECORD *row;
3369 LPWSTR ptr, ptr2;
3372 LPWSTR sourcepath;
3373
3374 if (!comp->KeyPath || !(file = msi_get_loaded_file(package, comp->KeyPath)))
3375 continue;
3376
3377 if (!(row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Media` WHERE `LastSequence` >= %d "
3378 L"ORDER BY `DiskId`", file->Sequence)))
3379 return ERROR_FUNCTION_FAILED;
3380
3382 ptr2 = wcsrchr(source, '\\') + 1;
3383 msiobj_release(&row->hdr);
3384
3385 lstrcpyW(base, package->PackagePath);
3386 ptr = wcsrchr(base, '\\');
3387 *(ptr + 1) = '\0';
3388
3389 sourcepath = msi_resolve_file_source(package, file);
3390 ptr = sourcepath + lstrlenW(base);
3391 lstrcpyW(ptr2, ptr);
3392 free(sourcepath);
3393
3394 msi_reg_set_val_str( hkey, squashed_pc, source );
3395 }
3396 RegCloseKey(hkey);
3397 }
3398 else if (action == INSTALLSTATE_ABSENT)
3399 {
3400 if (comp->num_clients <= 0)
3401 {
3402 if (package->Context == MSIINSTALLCONTEXT_MACHINE)
3403 rc = MSIREG_DeleteUserDataComponentKey( comp->ComponentId, L"S-1-5-18" );
3404 else
3406
3407 if (rc != ERROR_SUCCESS) WARN( "failed to delete component key %u\n", rc );
3408 }
3409 else
3410 {
3411 LONG res;
3412
3413 if (package->Context == MSIINSTALLCONTEXT_MACHINE)
3414 rc = MSIREG_OpenUserDataComponentKey( comp->ComponentId, L"S-1-5-18", &hkey, FALSE );
3415 else
3417
3418 if (rc != ERROR_SUCCESS)
3419 {
3420 WARN( "failed to open component key %u\n", rc );
3421 continue;
3422 }
3423 res = RegDeleteValueW( hkey, squashed_pc );
3424 RegCloseKey(hkey);
3425 if (res) WARN( "failed to delete component value %ld\n", res );
3426 }
3427 }
3428
3429 /* UI stuff */
3430 uirow = MSI_CreateRecord(3);
3431 MSI_RecordSetStringW(uirow,1,package->ProductCode);
3432 MSI_RecordSetStringW(uirow,2,comp->ComponentId);
3433 MSI_RecordSetStringW(uirow,3,comp->FullKeypath);
3435 msiobj_release( &uirow->hdr );
3436 }
3437 return ERROR_SUCCESS;
3438}
3439
3441{
3446};
3447
3449 LPWSTR lpszName, LONG_PTR lParam)
3450{
3451 TLIBATTR *attr;
3452 struct typelib *tl_struct = (struct typelib *)lParam;
3453 int sz;
3454 HRESULT res;
3455
3456 if (!IS_INTRESOURCE(lpszName))
3457 {
3458 ERR("Not Int Resource Name %s\n",debugstr_w(lpszName));
3459 return TRUE;
3460 }
3461
3462 sz = lstrlenW(tl_struct->source)+4;
3463
3464 if ((INT_PTR)lpszName == 1)
3465 tl_struct->path = wcsdup(tl_struct->source);
3466 else
3467 {
3468 tl_struct->path = malloc(sz * sizeof(WCHAR));
3469#ifdef __REACTOS__
3470 swprintf(tl_struct->path, sz, L"%s\\%d", tl_struct->source, (WORD)(INT_PTR)lpszName);
3471#else
3472 swprintf(tl_struct->path, sz, L"%s\\%d", tl_struct->source, lpszName);
3473#endif
3474 }
3475
3476 TRACE("trying %s\n", debugstr_w(tl_struct->path));
3477 res = LoadTypeLib(tl_struct->path,&tl_struct->ptLib);
3478 if (FAILED(res))
3479 {
3480 free(tl_struct->path);
3481 tl_struct->path = NULL;
3482
3483 return TRUE;
3484 }
3485
3486 ITypeLib_GetLibAttr(tl_struct->ptLib, &attr);
3487 if (IsEqualGUID(&(tl_struct->clsid),&(attr->guid)))
3488 {
3489 ITypeLib_ReleaseTLibAttr(tl_struct->ptLib, attr);
3490 return FALSE;
3491 }
3492
3493 free(tl_struct->path);
3494 tl_struct->path = NULL;
3495
3496 ITypeLib_ReleaseTLibAttr(tl_struct->ptLib, attr);
3497 ITypeLib_Release(tl_struct->ptLib);
3498
3499 return TRUE;
3500}
3501
3503{
3505 msi_disable_fs_redirection( package );
3507 msi_revert_fs_redirection( package );
3508 return module;
3509}
3510
3511static HRESULT load_typelib( MSIPACKAGE *package, const WCHAR *filename, REGKIND kind, ITypeLib **lib )
3512{
3513 HRESULT hr;
3514 msi_disable_fs_redirection( package );
3515 hr = LoadTypeLibEx( filename, kind, lib );
3516 msi_revert_fs_redirection( package );
3517 return hr;
3518}
3519
3521{
3522 MSIPACKAGE* package = param;
3523 LPCWSTR component;
3524 MSICOMPONENT *comp;
3525 MSIFILE *file;
3526 struct typelib tl_struct;
3527 ITypeLib *tlib;
3529 HRESULT hr;
3530
3531 component = MSI_RecordGetString(row,3);
3532 comp = msi_get_loaded_component(package,component);
3533 if (!comp)
3534 return ERROR_SUCCESS;
3535
3536 comp->Action = msi_get_component_action( package, comp );
3537 if (comp->Action != INSTALLSTATE_LOCAL)
3538 {
3539 TRACE("component not scheduled for installation %s\n", debugstr_w(component));
3540 return ERROR_SUCCESS;
3541 }
3542
3543 if (!comp->KeyPath || !(file = msi_get_loaded_file( package, comp->KeyPath )))
3544 {
3545 TRACE("component has no key path\n");
3546 return ERROR_SUCCESS;
3547 }
3549
3550 module = load_library( package, file->TargetPath, LOAD_LIBRARY_AS_DATAFILE );
3551 if (module)
3552 {
3553 LPCWSTR guid;
3555 CLSIDFromString( guid, &tl_struct.clsid);
3556 tl_struct.source = wcsdup( file->TargetPath );
3557 tl_struct.path = NULL;
3558
3560 (LONG_PTR)&tl_struct);
3561
3562 if (tl_struct.path)
3563 {
3564 LPCWSTR helpid, help_path = NULL;
3565 HRESULT res;
3566
3567 helpid = MSI_RecordGetString(row,6);
3568
3569 if (helpid) help_path = msi_get_target_folder( package, helpid );
3570 res = RegisterTypeLib( tl_struct.ptLib, tl_struct.path, (OLECHAR *)help_path );
3571
3572 if (FAILED(res))
3573 ERR("Failed to register type library %s\n", debugstr_w(tl_struct.path));
3574 else
3575 TRACE("Registered %s\n", debugstr_w(tl_struct.path));
3576
3577 ITypeLib_Release(tl_struct.ptLib);
3578 free(tl_struct.path);
3579 }
3580 else ERR("Failed to load type library %s\n", debugstr_w(tl_struct.source));
3581
3583 free(tl_struct.source);
3584 }
3585 else
3586 {
3587 hr = load_typelib( package, file->TargetPath, REGKIND_REGISTER, &tlib );
3588 if (FAILED(hr))
3589 {
3590 ERR( "failed to load type library: %#lx\n", hr );
3591 return ERROR_INSTALL_FAILURE;
3592 }
3593
3594 ITypeLib_Release(tlib);
3595 }
3596
3597 return ERROR_SUCCESS;
3598}
3599
3601{
3602 MSIQUERY *view;
3603 UINT rc;
3604
3605 if (package->script == SCRIPT_NONE)
3606 return msi_schedule_action(package, SCRIPT_INSTALL, L"RegisterTypeLibraries");
3607
3608 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `TypeLib`", &view);
3609 if (rc != ERROR_SUCCESS)
3610 return ERROR_SUCCESS;
3611
3613 msiobj_release(&view->hdr);
3614 return rc;
3615}
3616
3618{
3619 MSIPACKAGE *package = param;
3620 LPCWSTR component, guid;
3621 MSICOMPONENT *comp;
3622 GUID libid;
3623 UINT version;
3624 LCID language;
3625 SYSKIND syskind;
3626 HRESULT hr;
3627
3628 component = MSI_RecordGetString( row, 3 );
3629 comp = msi_get_loaded_component( package, component );
3630 if (!comp)
3631 return ERROR_SUCCESS;
3632
3633 comp->Action = msi_get_component_action( package, comp );
3634 if (comp->Action != INSTALLSTATE_ABSENT)
3635 {
3636 TRACE("component not scheduled for removal %s\n", debugstr_w(component));
3637 return ERROR_SUCCESS;
3638 }
3640
3642 CLSIDFromString( guid, &libid );
3644 language = MSI_RecordGetInteger( row, 2 );
3645
3646#ifdef _WIN64
3647 syskind = SYS_WIN64;
3648#else
3649 syskind = SYS_WIN32;
3650#endif
3651
3652 hr = UnRegisterTypeLib( &libid, (version >> 8) & 0xffff, version & 0xff, language, syskind );
3653 if (FAILED(hr))
3654 {
3655 WARN( "failed to unregister typelib: %#lx\n", hr );
3656 }
3657
3658 return ERROR_SUCCESS;
3659}
3660
3662{
3663 MSIQUERY *view;
3664 UINT rc;
3665
3666 if (package->script == SCRIPT_NONE)
3667 return msi_schedule_action(package, SCRIPT_INSTALL, L"UnregisterTypeLibraries");
3668
3669 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `TypeLib`", &view );
3670 if (rc != ERROR_SUCCESS)
3671 return ERROR_SUCCESS;
3672
3674 msiobj_release( &view->hdr );
3675 return rc;
3676}
3677
3679{
3680 LPCWSTR directory, extension, link_folder;
3681 WCHAR *link_file = NULL, *filename, *new_filename;
3682
3684 link_folder = msi_get_target_folder( package, directory );
3685 if (!link_folder)
3686 {
3687 ERR("unable to resolve folder %s\n", debugstr_w(directory));
3688 return NULL;
3689 }
3690 /* may be needed because of a bug somewhere else */
3691 msi_create_full_path( package, link_folder );
3692
3694 if (!filename) return NULL;
3696
3697 extension = wcsrchr( filename, '.' );
3698 if (!extension || wcsicmp( extension, L".lnk" ))
3699 {
3700 int len = lstrlenW( filename );
3701 new_filename = realloc( filename, len * sizeof(WCHAR) + sizeof(L".lnk") );
3702 if (!new_filename) goto done;
3703 filename = new_filename;
3704 memcpy( filename + len, L".lnk", sizeof(L".lnk") );
3705 }
3706 link_file = msi_build_directory_name( 2, link_folder, filename );
3707
3708done:
3709 free( filename );
3710 return link_file;
3711}
3712
3713WCHAR *msi_build_icon_path( MSIPACKAGE *package, const WCHAR *icon_name )
3714{
3715 WCHAR *folder, *dest, *path;
3716
3717 if (package->Context == MSIINSTALLCONTEXT_MACHINE)
3718 folder = msi_dup_property( package->db, L"WindowsFolder" );
3719 else
3720 {
3721 WCHAR *appdata = msi_dup_property( package->db, L"AppDataFolder" );
3722 folder = msi_build_directory_name( 2, appdata, L"Microsoft\\" );
3723 free( appdata );
3724 }
3725 dest = msi_build_directory_name( 3, folder, L"Installer\\", package->ProductCode );
3726 msi_create_full_path( package, dest );
3727 path = msi_build_directory_name( 2, dest, icon_name );
3728 free( folder );
3729 free( dest );
3730 return path;
3731}
3732
3734{
3735 MSIPACKAGE *package = param;
3736 LPWSTR link_file, deformated, path;
3737 LPCWSTR component, target;
3738 MSICOMPONENT *comp;
3739 IShellLinkW *sl = NULL;
3740 IPersistFile *pf = NULL;
3741 HRESULT res;
3742
3743 component = MSI_RecordGetString(row, 4);
3744 comp = msi_get_loaded_component(package, component);
3745 if (!comp)
3746 return ERROR_SUCCESS;
3747
3748 comp->Action = msi_get_component_action( package, comp );
3749 if (comp->Action != INSTALLSTATE_LOCAL)
3750 {
3751 TRACE("component not scheduled for installation %s\n", debugstr_w(component));
3752 return ERROR_SUCCESS;
3753 }
3755
3756 res = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
3757 &IID_IShellLinkW, (LPVOID *) &sl );
3758
3759 if (FAILED( res ))
3760 {
3761 ERR("CLSID_ShellLink not available\n");
3762 goto err;
3763 }
3764
3765 res = IShellLinkW_QueryInterface( sl, &IID_IPersistFile,(LPVOID*) &pf );
3766 if (FAILED( res ))
3767 {
3768 ERR("QueryInterface(IID_IPersistFile) failed\n");
3769 goto err;
3770 }
3771
3773 if (wcschr(target, '['))
3774 {
3775 deformat_string( package, target, &path );
3776 TRACE("target path is %s\n", debugstr_w(path));
3777 IShellLinkW_SetPath( sl, path );
3778 free( path );
3779 }
3780 else
3781 {
3782 FIXME("poorly handled shortcut format, advertised shortcut\n");
3783 path = resolve_keypath( package, comp );
3784 IShellLinkW_SetPath( sl, path );
3785 free( path );
3786 }
3787
3788 if (!MSI_RecordIsNull(row,6))
3789 {
3790 LPCWSTR arguments = MSI_RecordGetString(row, 6);
3791 deformat_string(package, arguments, &deformated);
3792 IShellLinkW_SetArguments(sl,deformated);
3793 free(deformated);
3794 }
3795
3796 if (!MSI_RecordIsNull(row,7))
3797 {
3799 IShellLinkW_SetDescription(sl, description);
3800 }
3801
3802 if (!MSI_RecordIsNull(row,8))
3803 IShellLinkW_SetHotkey(sl,MSI_RecordGetInteger(row,8));
3804
3805 if (!MSI_RecordIsNull(row,9))
3806 {
3807 INT index;
3808 LPCWSTR icon = MSI_RecordGetString(row, 9);
3809
3810 path = msi_build_icon_path(package, icon);
3812
3813 /* no value means 0 */
3814 if (index == MSI_NULL_INTEGER)
3815 index = 0;
3816
3817 IShellLinkW_SetIconLocation(sl, path, index);
3818 free(path);
3819 }
3820
3821 if (!MSI_RecordIsNull(row,11))
3822 IShellLinkW_SetShowCmd(sl,MSI_RecordGetInteger(row,11));
3823
3824 if (!MSI_RecordIsNull(row,12))
3825 {
3826 LPCWSTR full_path, wkdir = MSI_RecordGetString( row, 12 );
3827 full_path = msi_get_target_folder( package, wkdir );
3828 if (full_path) IShellLinkW_SetWorkingDirectory( sl, full_path );
3829 }
3830
3831 link_file = get_link_file(package, row);
3832 TRACE("Writing shortcut to %s\n", debugstr_w(link_file));
3833
3834 msi_disable_fs_redirection( package );
3835 IPersistFile_Save(pf, link_file, FALSE);
3836 msi_revert_fs_redirection( package );
3837
3838 free(link_file);
3839
3840err:
3841 if (pf)
3842 IPersistFile_Release( pf );
3843 if (sl)
3844 IShellLinkW_Release( sl );
3845
3846 return ERROR_SUCCESS;
3847}
3848
3850{
3851 MSIQUERY *view;
3852 HRESULT res;
3853 UINT rc;
3854
3855 if (package->script == SCRIPT_NONE)
3856 return msi_schedule_action(package, SCRIPT_INSTALL, L"CreateShortcuts");
3857
3858 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `Shortcut`", &view);
3859 if (rc != ERROR_SUCCESS)
3860 return ERROR_SUCCESS;
3861
3862 res = CoInitialize( NULL );
3863
3865 msiobj_release(&view->hdr);
3866
3868 return rc;
3869}
3870
3872{
3873 MSIPACKAGE *package = param;
3874 LPWSTR link_file;
3875 LPCWSTR component;
3876 MSICOMPONENT *comp;
3877
3878 component = MSI_RecordGetString( row, 4 );
3879 comp = msi_get_loaded_component( package, component );
3880 if (!comp)
3881 return ERROR_SUCCESS;
3882
3883 comp->Action = msi_get_component_action( package, comp );
3884 if (comp->Action != INSTALLSTATE_ABSENT)
3885 {
3886 TRACE("component not scheduled for removal %s\n", debugstr_w(component));
3887 return ERROR_SUCCESS;
3888 }
3890
3891 link_file = get_link_file( package, row );
3892 TRACE("Removing shortcut file %s\n", debugstr_w( link_file ));
3893 if (!msi_delete_file( package, link_file )) WARN( "failed to remove shortcut file %lu\n", GetLastError() );
3894 free( link_file );
3895
3896 return ERROR_SUCCESS;
3897}
3898
3900{
3901 MSIQUERY *view;
3902 UINT rc;
3903
3904 if (package->script == SCRIPT_NONE)
3905 return msi_schedule_action(package, SCRIPT_INSTALL, L"RemoveShortcuts");
3906
3907 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Shortcut`", &view );
3908 if (rc != ERROR_SUCCESS)
3909 return ERROR_SUCCESS;
3910
3912 msiobj_release( &view->hdr );
3913 return rc;
3914}
3915
3917{
3918 MSIPACKAGE *package = param;
3919 HANDLE handle;
3920 WCHAR *icon_path;
3921 const WCHAR *filename;
3922 char buffer[1024];
3923 DWORD sz;
3924 UINT rc;
3925
3927 if (!filename)
3928 {
3929 ERR("Unable to get filename\n");
3930 return ERROR_SUCCESS;
3931 }
3932
3933 icon_path = msi_build_icon_path( package, filename );
3934
3935 TRACE("Creating icon file at %s\n", debugstr_w(icon_path));
3936
3939 {
3940 ERR("Unable to create file %s\n", debugstr_w(icon_path));
3941 free( icon_path );
3942 return ERROR_SUCCESS;
3943 }
3944
3945 do
3946 {
3947 DWORD count;
3948 sz = 1024;
3949 rc = MSI_RecordReadStream( row, 2, buffer, &sz );
3950 if (rc != ERROR_SUCCESS)
3951 {
3952 ERR("Failed to get stream\n");
3953 msi_delete_file( package, icon_path );
3954 break;
3955 }
3956 WriteFile( handle, buffer, sz, &count, NULL );
3957 } while (sz == 1024);
3958
3959 free( icon_path );
3961
3962 return ERROR_SUCCESS;
3963}
3964
3966{
3967 MSIQUERY *view;
3968 UINT r;
3969
3970 r = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `Icon`", &view);
3971 if (r == ERROR_SUCCESS)
3972 {
3974 msiobj_release(&view->hdr);
3975 if (r != ERROR_SUCCESS)
3976 return r;
3977 }
3978 return ERROR_SUCCESS;
3979}
3980
3982{
3983 UINT r;
3984 HKEY source;
3985 LPWSTR buffer;
3986 MSIMEDIADISK *disk;
3988
3989 r = RegCreateKeyW(hkey, L"SourceList", &source);
3990 if (r != ERROR_SUCCESS)
3991 return r;
3992
3994
3995 buffer = wcsrchr(package->PackagePath, '\\') + 1;
3997 package->Context, MSICODE_PRODUCT,
3999 if (r != ERROR_SUCCESS)
4000 return r;
4001
4003 package->Context, MSICODE_PRODUCT,
4005 if (r != ERROR_SUCCESS)
4006 return r;
4007
4009 package->Context, MSICODE_PRODUCT,
4011 if (r != ERROR_SUCCESS)
4012 return r;
4013
4015 {
4016 if (!wcscmp( info->property, INSTALLPROPERTY_LASTUSEDSOURCEW ))
4017 msi_set_last_used_source(package->ProductCode, NULL, info->context,
4018 info->options, info->value);
4019 else
4021 info->context, info->options,
4022 info->property, info->value);
4023 }
4024
4026 {
4028 disk->context, disk->options,
4029 disk->disk_id, disk->volume_label, disk->disk_prompt);
4030 }
4031
4032 return ERROR_SUCCESS;
4033}
4034
4036{
4037 WCHAR *buffer, *ptr, *guids, packcode[SQUASHED_GUID_SIZE];
4038 DWORD langid;
4039
4042 free(buffer);
4043
4044 langid = msi_get_property_int(package->db, L"ProductLanguage", 0);
4046
4047 /* FIXME */
4049
4050 buffer = msi_dup_property(package->db, L"ARPPRODUCTICON");
4051 if (buffer)
4052 {
4055 free(path);
4056 free(buffer);
4057 }
4058
4059 buffer = msi_dup_property(package->db, L"ProductVersion");
4060 if (buffer)
4061 {
4064 free(buffer);
4065 }
4066
4067 msi_reg_set_val_dword(hkey, L"Assignment", 0);
4068 msi_reg_set_val_dword(hkey, L"AdvertiseFlags", 0x184);
4070 msi_reg_set_val_multi_str(hkey, L"Clients", L":\0");
4071
4072 if (!(guids = msi_get_package_code(package->db))) return ERROR_OUTOFMEMORY;
4073 if ((ptr = wcschr(guids, ';'))) *ptr = 0;
4074 squash_guid(guids, packcode);
4075 free(guids);
4077
4078 return ERROR_SUCCESS;
4079}
4080
4082{
4083 UINT r;
4084 HKEY hkey;
4085 WCHAR *upgrade, squashed_pc[SQUASHED_GUID_SIZE];
4086
4087 upgrade = msi_dup_property(package->db, L"UpgradeCode");
4088 if (!upgrade)
4089 return ERROR_SUCCESS;
4090
4091 if (package->Context == MSIINSTALLCONTEXT_MACHINE)
4092 r = MSIREG_OpenClassesUpgradeCodesKey(upgrade, &hkey, TRUE);
4093 else
4094 r = MSIREG_OpenUserUpgradeCodesKey(upgrade, &hkey, TRUE);
4095
4096 if (r != ERROR_SUCCESS)
4097 {
4098 WARN("failed to open upgrade code key\n");
4099 free(upgrade);
4100 return ERROR_SUCCESS;
4101 }
4102 squash_guid(package->ProductCode, squashed_pc);
4103 msi_reg_set_val_str(hkey, squashed_pc, NULL);
4104 RegCloseKey(hkey);
4105 free(upgrade);
4106 return ERROR_SUCCESS;
4107}
4108
4110{
4112
4114 {
4115 feature->Action = msi_get_feature_action( package, feature );
4116 if (feature->Action == INSTALLSTATE_LOCAL || feature->Action == INSTALLSTATE_SOURCE)
4117 return TRUE;
4118 }
4119
4120 return FALSE;
4121}
4122
4124{
4126
4128 {
4129 feature->Action = msi_get_feature_action( package, feature );
4130 if (feature->Action != INSTALLSTATE_ABSENT)
4131 return FALSE;
4132 }
4133
4134 return TRUE;
4135}
4136
4138{
4139 WCHAR patch_squashed[GUID_SIZE];
4140 HKEY patches_key = NULL, product_patches_key = NULL, product_key;
4141 LONG res;
4142 MSIPATCHINFO *patch;
4143 UINT r;
4144 WCHAR *p, *all_patches = NULL;
4145 DWORD len = 0;
4146
4147 r = MSIREG_OpenProductKey( package->ProductCode, NULL, package->Context, &product_key, TRUE );
4148 if (r != ERROR_SUCCESS)
4149 return ERROR_FUNCTION_FAILED;
4150
4151 res = RegCreateKeyExW( product_key, L"Patches", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patches_key, NULL );
4152 if (res != ERROR_SUCCESS)
4153 {
4155 goto done;
4156 }
4157
4158 r = MSIREG_OpenUserDataProductPatchesKey( package->ProductCode, package->Context, &product_patches_key, TRUE );
4159 if (r != ERROR_SUCCESS)
4160 goto done;
4161
4162 LIST_FOR_EACH_ENTRY( patch, &package->patches, MSIPATCHINFO, entry )
4163 {
4164 squash_guid( patch->patchcode, patch_squashed );
4165 len += lstrlenW( patch_squashed ) + 1;
4166 }
4167
4168 p = all_patches = malloc( (len + 1) * sizeof(WCHAR) );
4169 if (!all_patches)
4170 goto done;
4171
4172 LIST_FOR_EACH_ENTRY( patch, &package->patches, MSIPATCHINFO, entry )
4173 {
4174 HKEY patch_key;
4175
4176 squash_guid( patch->patchcode, p );
4177 p += lstrlenW( p ) + 1;
4178
4179 res = RegSetValueExW( patches_key, patch_squashed, 0, REG_SZ,
4180 (const BYTE *)patch->transforms,
4181 (lstrlenW(patch->transforms) + 1) * sizeof(WCHAR) );
4182 if (res != ERROR_SUCCESS)
4183 goto done;
4184
4185 r = MSIREG_OpenUserDataPatchKey( patch->patchcode, package->Context, &patch_key, TRUE );
4186 if (r != ERROR_SUCCESS)
4187 goto done;
4188
4189 res = RegSetValueExW( patch_key, L"LocalPackage", 0, REG_SZ, (const BYTE *)patch->localfile,
4190 (lstrlenW( patch->localfile ) + 1) * sizeof(WCHAR) );
4191 RegCloseKey( patch_key );
4192 if (res != ERROR_SUCCESS)
4193 goto done;
4194
4195 if (patch->filename && !CopyFileW( patch->filename, patch->localfile, FALSE ))
4196 {
4197 res = GetLastError();
4198 ERR( "unable to copy patch package %lu\n", res );
4199 goto done;
4200 }
4201 res = RegCreateKeyExW( product_patches_key, patch_squashed, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &patch_key, NULL );
4202 if (res != ERROR_SUCCESS)
4203 goto done;
4204
4205 res = RegSetValueExW( patch_key, L"State", 0, REG_DWORD, (const BYTE *)&patch->state,
4206 sizeof(patch->state) );
4207 if (res != ERROR_SUCCESS)
4208 {
4209 RegCloseKey( patch_key );
4210 goto done;
4211 }
4212
4213 res = RegSetValueExW( patch_key, L"Uninstallable", 0, REG_DWORD, (const BYTE *)&patch->uninstallable,
4214 sizeof(patch->uninstallable) );
4215 RegCloseKey( patch_key );
4216 if (res != ERROR_SUCCESS)
4217 goto done;
4218 }
4219
4220 all_patches[len] = 0;
4221 res = RegSetValueExW( patches_key, L"Patches", 0, REG_MULTI_SZ,
4222 (const BYTE *)all_patches, (len + 1) * sizeof(WCHAR) );
4223 if (res != ERROR_SUCCESS)
4224 goto done;
4225
4226 res = RegSetValueExW( product_patches_key, L"AllPatches", 0, REG_MULTI_SZ,
4227 (const BYTE *)all_patches, (len + 1) * sizeof(WCHAR) );
4228 if (res != ERROR_SUCCESS)
4230
4231done:
4232 RegCloseKey( product_patches_key );
4233 RegCloseKey( patches_key );
4234 RegCloseKey( product_key );
4235 free( all_patches );
4236 return r;
4237}
4238
4240{
4241 UINT rc;
4242 HKEY hukey = NULL, hudkey = NULL;
4243 MSIRECORD *uirow;
4244 BOOL republish = FALSE;
4245
4246 if (package->script == SCRIPT_NONE)
4247 return msi_schedule_action(package, SCRIPT_INSTALL, L"PublishProduct");
4248
4249 if (!list_empty(&package->patches))
4250 {
4251 rc = publish_patches(package);
4252 if (rc != ERROR_SUCCESS)
4253 goto end;
4254 }
4255
4256 rc = MSIREG_OpenProductKey(package->ProductCode, NULL, package->Context,
4257 &hukey, FALSE);
4258 if (rc == ERROR_SUCCESS)
4259 {
4260 WCHAR *package_code;
4261
4263 if (package_code)
4264 {
4265 WCHAR *guid;
4266
4267 guid = msi_get_package_code(package->db);
4268 if (guid)
4269 {
4271
4273 free(guid);
4274 if (!wcscmp(packed, package_code))
4275 {
4276 TRACE("re-publishing product - new package\n");
4277 republish = TRUE;
4278 }
4279 }
4280 free(package_code);
4281 }
4282 }
4283
4284 /* FIXME: also need to publish if the product is in advertise mode */
4285 if (!republish && !check_publish(package))
4286 {
4287 if (hukey)
4288 RegCloseKey(hukey);
4289 return ERROR_SUCCESS;
4290 }
4291
4292 if (!hukey)
4293 {
4294 rc = MSIREG_OpenProductKey(package->ProductCode, NULL, package->Context,
4295 &hukey, TRUE);
4296 if (rc != ERROR_SUCCESS)
4297 goto end;
4298 }
4299
4300 rc = MSIREG_OpenUserDataProductKey(package->ProductCode, package->Context,
4301 NULL, &hudkey, TRUE);
4302 if (rc != ERROR_SUCCESS)
4303 goto end;
4304
4305 rc = publish_upgrade_code(package);
4306 if (rc != ERROR_SUCCESS)
4307 goto end;
4308
4309 rc = publish_product_properties(package, hukey);
4310 if (rc != ERROR_SUCCESS)
4311 goto end;
4312
4313 rc = publish_sourcelist(package, hukey);
4314 if (rc != ERROR_SUCCESS)
4315 goto end;
4316
4317 rc = publish_icons(package);
4318
4319end:
4320 uirow = MSI_CreateRecord( 1 );
4321 MSI_RecordSetStringW( uirow, 1, package->ProductCode );
4323 msiobj_release( &uirow->hdr );
4324
4325 RegCloseKey(hukey);
4326 RegCloseKey(hudkey);
4327 return rc;
4328}
4329
4331{
4332 WCHAR *filename, *ptr, *folder, *ret;
4333 const WCHAR *dirprop;
4334
4336 if (filename && (ptr = wcschr( filename, '|' )))
4337 ptr++;
4338 else
4339 ptr = filename;
4340
4341 dirprop = MSI_RecordGetString( row, 3 );
4342 if (dirprop)
4343 {
4344 folder = wcsdup( msi_get_target_folder( package, dirprop ) );
4345 if (!folder) folder = msi_dup_property( package->db, dirprop );
4346 }
4347 else
4348 folder = msi_dup_property( package->db, L"WindowsFolder" );
4349
4350 if (!folder)
4351 {
4352 ERR("Unable to resolve folder %s\n", debugstr_w(dirprop));
4353 free( filename );
4354 return NULL;
4355 }
4356
4358
4359 free( filename );
4360 free( folder );
4361 return ret;
4362}
4363
4365{
4366 MSIPACKAGE *package = param;
4367 LPCWSTR component, section, key, value, identifier;
4368 LPWSTR deformated_section, deformated_key, deformated_value, fullname;
4369 MSIRECORD * uirow;
4370 INT action;
4371 MSICOMPONENT *comp;
4372
4373 component = MSI_RecordGetString(row, 8);
4374 comp = msi_get_loaded_component(package,component);
4375 if (!comp)
4376 return ERROR_SUCCESS;
4377
4378 comp->Action = msi_get_component_action( package, comp );
4379 if (comp->Action != INSTALLSTATE_LOCAL)
4380 {
4381 TRACE("component not scheduled for installation %s\n", debugstr_w(component));
4382 return ERROR_SUCCESS;
4383 }
4384
4385 identifier = MSI_RecordGetString(row,1);
4390
4391 deformat_string(package,section,&deformated_section);
4392 deformat_string(package,key,&deformated_key);
4393 deformat_string(package,value,&deformated_value);
4394
4395 fullname = get_ini_file_name(package, row);
4396
4397 if (action == 0)
4398 {
4399 TRACE("Adding value %s to section %s in %s\n",
4400 debugstr_w(deformated_key), debugstr_w(deformated_section),
4402 WritePrivateProfileStringW(deformated_section, deformated_key,
4403 deformated_value, fullname);
4404 }
4405 else if (action == 1)
4406 {
4407 WCHAR returned[10];
4408 GetPrivateProfileStringW(deformated_section, deformated_key, NULL,
4409 returned, 10, fullname);
4410 if (returned[0] == 0)
4411 {
4412 TRACE("Adding value %s to section %s in %s\n",
4413 debugstr_w(deformated_key), debugstr_w(deformated_section),
4415
4416 WritePrivateProfileStringW(deformated_section, deformated_key,
4417 deformated_value, fullname);
4418 }
4419 }
4420 else if (action == 3)
4421 FIXME("Append to existing section not yet implemented\n");
4422
4423 uirow = MSI_CreateRecord(4);
4424 MSI_RecordSetStringW(uirow,1,identifier);
4425 MSI_RecordSetStringW(uirow,2,deformated_section);
4426 MSI_RecordSetStringW(uirow,3,deformated_key);
4427 MSI_RecordSetStringW(uirow,4,deformated_value);
4429 msiobj_release( &uirow->hdr );
4430
4431 free(fullname);
4432 free(deformated_key);
4433 free(deformated_value);
4434 free(deformated_section);
4435 return ERROR_SUCCESS;
4436}
4437
4439{
4440 MSIQUERY *view;
4441 UINT rc;
4442
4443 if (package->script == SCRIPT_NONE)
4444 return msi_schedule_action(package, SCRIPT_INSTALL, L"WriteIniValues");
4445
4446 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `IniFile`", &view);
4447 if (rc != ERROR_SUCCESS)
4448 return ERROR_SUCCESS;
4449
4451 msiobj_release(&view->hdr);
4452 return rc;
4453}
4454
4456{
4457 MSIPACKAGE *package = param;
4458 LPCWSTR component, section, key, value, identifier;
4459 LPWSTR deformated_section, deformated_key, deformated_value, filename;
4460 MSICOMPONENT *comp;
4461 MSIRECORD *uirow;
4462 INT action;
4463
4464 component = MSI_RecordGetString( row, 8 );
4465 comp = msi_get_loaded_component( package, component );
4466 if (!comp)
4467 return ERROR_SUCCESS;
4468
4469 comp->Action = msi_get_component_action( package, comp );
4470 if (comp->Action != INSTALLSTATE_ABSENT)
4471 {
4472 TRACE("component not scheduled for removal %s\n", debugstr_w(component));
4473 return ERROR_SUCCESS;
4474 }
4475
4476 identifier = MSI_RecordGetString( row, 1 );
4478 key = MSI_RecordGetString( row, 5 );
4481
4482 deformat_string( package, section, &deformated_section );
4483 deformat_string( package, key, &deformated_key );
4484 deformat_string( package, value, &deformated_value );
4485
4487 {
4488 filename = get_ini_file_name( package, row );
4489
4490 TRACE("Removing key %s from section %s in %s\n",
4491 debugstr_w(deformated_key), debugstr_w(deformated_section), debugstr_w(filename));
4492
4493 if (!WritePrivateProfileStringW( deformated_section, deformated_key, NULL, filename ))
4494 {
4495 WARN( "unable to remove key %lu\n", GetLastError() );
4496 }
4497 free( filename );
4498 }
4499 else
4500 FIXME("Unsupported action %d\n", action);
4501
4502
4503 uirow = MSI_CreateRecord( 4 );
4504 MSI_RecordSetStringW( uirow, 1, identifier );
4505 MSI_RecordSetStringW( uirow, 2, deformated_section );
4506 MSI_RecordSetStringW( uirow, 3, deformated_key );
4507 MSI_RecordSetStringW( uirow, 4, deformated_value );
4509 msiobj_release( &uirow->hdr );
4510
4511 free( deformated_key );
4512 free( deformated_value );
4513 free( deformated_section );
4514 return ERROR_SUCCESS;
4515}
4516
4518{
4519 MSIPACKAGE *package = param;
4520 LPCWSTR component, section, key, value, identifier;
4521 LPWSTR deformated_section, deformated_key, deformated_value, filename;
4522 MSICOMPONENT *comp;
4523 MSIRECORD *uirow;
4524 INT action;
4525
4526 component = MSI_RecordGetString( row, 8 );
4527 comp = msi_get_loaded_component( package, component );
4528 if (!comp)
4529 return ERROR_SUCCESS;
4530
4531 comp->Action = msi_get_component_action( package, comp );
4532 if (comp->Action != INSTALLSTATE_LOCAL)
4533 {
4534 TRACE("component not scheduled for installation %s\n", debugstr_w(component));
4535 return ERROR_SUCCESS;
4536 }
4537
4538 identifier = MSI_RecordGetString( row, 1 );
4540 key = MSI_RecordGetString( row, 5 );
4543
4544 deformat_string( package, section, &deformated_section );
4545 deformat_string( package, key, &deformated_key );
4546 deformat_string( package, value, &deformated_value );
4547
4549 {
4550 filename = get_ini_file_name( package, row );
4551
4552 TRACE("Removing key %s from section %s in %s\n",
4553 debugstr_w(deformated_key), debugstr_w(deformated_section), debugstr_w(filename));
4554
4555 if (!WritePrivateProfileStringW( deformated_section, deformated_key, NULL, filename ))
4556 {
4557 WARN( "unable to remove key %lu\n", GetLastError() );
4558 }
4559 free( filename );
4560 }
4561 else
4562 FIXME("Unsupported action %d\n", action);
4563
4564 uirow = MSI_CreateRecord( 4 );
4565 MSI_RecordSetStringW( uirow, 1, identifier );
4566 MSI_RecordSetStringW( uirow, 2, deformated_section );
4567 MSI_RecordSetStringW( uirow, 3, deformated_key );
4568 MSI_RecordSetStringW( uirow, 4, deformated_value );
4570 msiobj_release( &uirow->hdr );
4571
4572 free( deformated_key );
4573 free( deformated_value );
4574 free( deformated_section );
4575 return ERROR_SUCCESS;
4576}
4577
4579{
4580 MSIQUERY *view;
4581 UINT rc;
4582
4583 if (package->script == SCRIPT_NONE)
4584 return msi_schedule_action(package, SCRIPT_INSTALL, L"RemoveIniValues");
4585
4586 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `IniFile`", &view );
4587 if (rc == ERROR_SUCCESS)
4588 {
4590 msiobj_release( &view->hdr );
4591 if (rc != ERROR_SUCCESS)
4592 return rc;
4593 }
4594 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `RemoveIniFile`", &view );
4595 if (rc == ERROR_SUCCESS)
4596 {
4598 msiobj_release( &view->hdr );
4599 if (rc != ERROR_SUCCESS)
4600 return rc;
4601 }
4602 return ERROR_SUCCESS;
4603}
4604
4605static void register_dll( const WCHAR *dll, BOOL unregister )
4606{
4607 static const WCHAR regW[] = L"regsvr32.exe /s \"%s\"";
4608 static const WCHAR unregW[] = L"regsvr32.exe /s /u \"%s\"";
4610 STARTUPINFOW si;
4611 WCHAR *cmd;
4612
4613 if (!(cmd = malloc( wcslen(dll) * sizeof(WCHAR) + sizeof(unregW) ))) return;
4614
4615 if (unregister) swprintf( cmd, lstrlenW(dll) + ARRAY_SIZE(unregW), unregW, dll );
4616 else swprintf( cmd, lstrlenW(dll) + ARRAY_SIZE(unregW), regW, dll );
4617
4618 memset( &si, 0, sizeof(STARTUPINFOW) );
4619 if (CreateProcessW( NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ))
4620 {
4621 CloseHandle( pi.hThread );
4622 msi_dialog_check_messages( pi.hProcess );
4623 CloseHandle( pi.hProcess );
4624 }
4625 free( cmd );
4626}
4627
4629{
4630 MSIPACKAGE *package = param;
4632 MSIFILE *file;
4633 MSIRECORD *uirow;
4634
4636 file = msi_get_loaded_file( package, filename );
4637 if (!file)
4638 {
4639 WARN("unable to find file %s\n", debugstr_w(filename));
4640 return ERROR_SUCCESS;
4641 }
4642 file->Component->Action = msi_get_component_action( package, file->Component );
4643 if (file->Component->Action != INSTALLSTATE_LOCAL)
4644 {
4645 TRACE("component not scheduled for installation %s\n", debugstr_w(file->Component->Component));
4646 return ERROR_SUCCESS;
4647 }
4648
4649 TRACE("Registering %s\n", debugstr_w( file->TargetPath ));
4650 register_dll( file->TargetPath, FALSE );
4651
4652 uirow = MSI_CreateRecord( 2 );
4653 MSI_RecordSetStringW( uirow, 1, file->File );
4654 MSI_RecordSetStringW( uirow, 2, file->Component->Directory );
4656 msiobj_release( &uirow->hdr );
4657
4658 return ERROR_SUCCESS;
4659}
4660
4662{
4663 MSIQUERY *view;
4664 UINT rc;
4665
4666 if (package->script == SCRIPT_NONE)
4667 return msi_schedule_action(package, SCRIPT_INSTALL, L"SelfRegModules");
4668
4669 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `SelfReg`", &view);
4670 if (rc != ERROR_SUCCESS)
4671 return ERROR_SUCCESS;
4672
4674 msiobj_release(&view->hdr);
4675 return rc;
4676}
4677
4679{
4680 MSIPACKAGE *package = param;
4682 MSIFILE *file;
4683 MSIRECORD *uirow;
4684
4686 file = msi_get_loaded_file( package, filename );
4687 if (!file)
4688 {
4689 WARN("unable to find file %s\n", debugstr_w(filename));
4690 return ERROR_SUCCESS;
4691 }
4692 file->Component->Action = msi_get_component_action( package, file->Component );
4693 if (file->Component->Action != INSTALLSTATE_ABSENT)
4694 {
4695 TRACE("component not scheduled for removal %s\n", debugstr_w(file->Component->Component));
4696 return ERROR_SUCCESS;
4697 }
4698
4699 TRACE("Unregistering %s\n", debugstr_w( file->TargetPath ));
4700 register_dll( file->TargetPath, TRUE );
4701
4702 uirow = MSI_CreateRecord( 2 );
4703 MSI_RecordSetStringW( uirow, 1, file->File );
4704 MSI_RecordSetStringW( uirow, 2, file->Component->Directory );
4706 msiobj_release( &uirow->hdr );
4707
4708 return ERROR_SUCCESS;
4709}
4710
4712{
4713 MSIQUERY *view;
4714 UINT rc;
4715
4716 if (package->script == SCRIPT_NONE)
4717 return msi_schedule_action(package, SCRIPT_INSTALL, L"SelfUnregModules");
4718
4719 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `SelfReg`", &view );
4720 if (rc != ERROR_SUCCESS)
4721 return ERROR_SUCCESS;
4722
4724 msiobj_release( &view->hdr );
4725 return rc;
4726}
4727
4729{
4731 UINT rc;
4732 HKEY hkey = NULL, userdata = NULL;
4733
4734 if (package->script == SCRIPT_NONE)
4735 return msi_schedule_action(package, SCRIPT_INSTALL, L"PublishFeatures");
4736
4737 if (!check_publish(package))
4738 return ERROR_SUCCESS;
4739
4740 rc = MSIREG_OpenFeaturesKey(package->ProductCode, NULL, package->Context,
4741 &hkey, TRUE);
4742 if (rc != ERROR_SUCCESS)
4743 goto end;
4744
4745 rc = MSIREG_OpenUserDataFeaturesKey(package->ProductCode, NULL, package->Context,
4746 &userdata, TRUE);
4747 if (rc != ERROR_SUCCESS)
4748 goto end;
4749
4750 /* here the guids are base 85 encoded */
4752 {
4753 ComponentList *cl;
4754 LPWSTR data = NULL;
4755 GUID clsid;
4756 INT size;
4757 BOOL absent = FALSE;
4758 MSIRECORD *uirow;
4759
4760 if (feature->Level <= 0) continue;
4761 if (feature->Action == INSTALLSTATE_UNKNOWN &&
4762 feature->Installed != INSTALLSTATE_ABSENT) continue;
4763
4764 if (feature->Action != INSTALLSTATE_LOCAL &&
4765 feature->Action != INSTALLSTATE_SOURCE &&
4766 feature->Action != INSTALLSTATE_ADVERTISED) absent = TRUE;
4767
4768 size = 1;
4769 LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
4770 {
4771 size += 21;
4772 }
4773 if (feature->Feature_Parent)
4774 size += lstrlenW( feature->Feature_Parent )+2;
4775
4776 data = malloc(size * sizeof(WCHAR));
4777
4778 data[0] = 0;
4779 LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
4780 {
4781 MSICOMPONENT* component = cl->component;
4782 WCHAR buf[21];
4783
4784 buf[0] = 0;
4785 if (component->ComponentId)
4786 {
4787 TRACE("From %s\n",debugstr_w(component->ComponentId));
4788 CLSIDFromString(component->ComponentId, &clsid);
4790 TRACE("to %s\n",debugstr_w(buf));
4791 lstrcatW(data,buf);
4792 }
4793 }
4794
4795 if (feature->Feature_Parent)
4796 {
4797 lstrcatW(data, L"\2");
4798 lstrcatW(data, feature->Feature_Parent);
4799 }
4800
4801 msi_reg_set_val_str( userdata, feature->Feature, data );
4802 free(data);
4803
4804 size = 0;
4805 if (feature->Feature_Parent)
4806 size = lstrlenW(feature->Feature_Parent)*sizeof(WCHAR);
4807 if (!absent)
4808 {
4809 size += sizeof(WCHAR);
4810 RegSetValueExW(hkey, feature->Feature, 0 ,REG_SZ,
4811 (const BYTE*)(feature->Feature_Parent ? feature->Feature_Parent : L""), size);
4812 }
4813 else
4814 {
4815 size += 2*sizeof(WCHAR);
4816 data = malloc(size);
4817 data[0] = 0x6;
4818 data[1] = 0;
4819 if (feature->Feature_Parent)
4820 lstrcpyW( &data[1], feature->Feature_Parent );
4821 RegSetValueExW(hkey,feature->Feature,0,REG_SZ,
4822 (LPBYTE)data,size);
4823 free(data);
4824 }
4825
4826 /* the UI chunk */
4827 uirow = MSI_CreateRecord( 1 );
4828 MSI_RecordSetStringW( uirow, 1, feature->Feature );
4830 msiobj_release( &uirow->hdr );
4831 /* FIXME: call msi_ui_progress? */
4832 }
4833
4834end:
4835 RegCloseKey(hkey);
4836 RegCloseKey(userdata);
4837 return rc;
4838}
4839
4841{
4842 UINT r;
4843 HKEY hkey;
4844 MSIRECORD *uirow;
4845
4846 TRACE("unpublishing feature %s\n", debugstr_w(feature->Feature));
4847
4848 r = MSIREG_OpenFeaturesKey(package->ProductCode, NULL, package->Context,
4849 &hkey, FALSE);
4850 if (r == ERROR_SUCCESS)
4851 {
4852 RegDeleteValueW(hkey, feature->Feature);
4853 RegCloseKey(hkey);
4854 }
4855
4857 &hkey, FALSE);
4858 if (r == ERROR_SUCCESS)
4859 {
4860 RegDeleteValueW(hkey, feature->Feature);
4861 RegCloseKey(hkey);
4862 }
4863
4864 uirow = MSI_CreateRecord( 1 );
4865 MSI_RecordSetStringW( uirow, 1, feature->Feature );
4867 msiobj_release( &uirow->hdr );
4868
4869 return ERROR_SUCCESS;
4870}
4871
4873{
4875
4876 if (package->script == SCRIPT_NONE)
4877 return msi_schedule_action(package, SCRIPT_INSTALL, L"UnpublishFeatures");
4878
4879 if (!check_unpublish(package))
4880 return ERROR_SUCCESS;
4881
4883 {
4884 unpublish_feature(package, feature);
4885 }
4886
4887 return ERROR_SUCCESS;
4888}
4889
4891{
4892 static const WCHAR *propval[] =
4893 {
4894 L"ARPAUTHORIZEDCDFPREFIX", L"AuthorizedCDFPrefix",
4895 L"ARPCONTACT", L"Contact",
4896 L"ARPCOMMENTS", L"Comments",
4897 L"ProductName", L"DisplayName",
4898 L"ARPHELPLINK", L"HelpLink",
4899 L"ARPHELPTELEPHONE", L"HelpTelephone",
4900 L"ARPINSTALLLOCATION", L"InstallLocation",
4901 L"SourceDir", L"InstallSource",
4902 L"Manufacturer", L"Publisher",
4903 L"ARPREADME", L"ReadMe",
4904 L"ARPSIZE", L"Size",
4905 L"ARPURLINFOABOUT", L"URLInfoAbout",
4906 L"ARPURLUPDATEINFO", L"URLUpdateInfo",
4907 NULL
4908 };
4909 const WCHAR **p = propval;
4910 SYSTEMTIME systime;
4911 DWORD size, langid;
4912 WCHAR date[9], *val, *buffer;
4913 const WCHAR *prop, *key;
4914
4915 while (*p)
4916 {
4917 prop = *p++;
4918 key = *p++;
4919 val = msi_dup_property(package->db, prop);
4920 msi_reg_set_val_str(hkey, key, val);
4921 free(val);
4922 }
4923
4924 msi_reg_set_val_dword(hkey, L"WindowsInstaller", 1);
4925 if (msi_get_property_int( package->db, L"ARPSYSTEMCOMPONENT", 0 ))
4926 {
4927 msi_reg_set_val_dword( hkey, L"SystemComponent", 1 );
4928 }
4929
4930 if (msi_get_property_int( package->db, L"ARPNOREMOVE", 0 ))
4931 msi_reg_set_val_dword( hkey, L"NoRemove", 1 );
4932 else
4933 {
4934 static const WCHAR fmt_install[] = L"MsiExec.exe /I[ProductCode]";
4935 static const WCHAR fmt_uninstall[] = L"MsiExec.exe /X[ProductCode]";
4936 const WCHAR *fmt = fmt_install;
4937
4938 if (msi_get_property_int( package->db, L"ARPNOREPAIR", 0 ))
4939 msi_reg_set_val_dword( hkey, L"NoRepair", 1 );
4940
4941 if (msi_get_property_int( package->db, L"ARPNOMODIFY", 0 ))
4942 {
4943 msi_reg_set_val_dword( hkey, L"NoModify", 1 );
4944 fmt = fmt_uninstall;
4945 }
4946
4947 size = deformat_string(package, fmt, &buffer) * sizeof(WCHAR);
4948 RegSetValueExW(hkey, L"ModifyPath", 0, REG_EXPAND_SZ, (LPBYTE)buffer, size);
4949 RegSetValueExW(hkey, L"UninstallString", 0, REG_EXPAND_SZ, (LPBYTE)buffer, size);
4950 free(buffer);
4951 }
4952
4953 /* FIXME: Write real Estimated Size when we have it */
4954 msi_reg_set_val_dword(hkey, L"EstimatedSize", 0);
4955
4956 GetLocalTime(&systime);
4957 swprintf(date, ARRAY_SIZE(date), L"%d%02d%02d", systime.wYear, systime.wMonth, systime.wDay);
4959
4960 langid = msi_get_property_int(package->db, L"ProductLanguage", 0);
4962
4963 buffer = msi_dup_property(package->db, L"ProductVersion");
4964 msi_reg_set_val_str(hkey, L"DisplayVersion", buffer);
4965 if (buffer)
4966 {
4968
4971 msi_reg_set_val_dword(hkey, INSTALLPROPERTY_VERSIONMINORW, (verdword >> 16) & 0xFF);
4972 free(buffer);
4973 }
4974
4975 return ERROR_SUCCESS;
4976}
4977
4979{
4980 WCHAR *upgrade_code, squashed_pc[SQUASHED_GUID_SIZE];
4981 MSIRECORD *uirow;
4982 HKEY hkey, props, upgrade_key;
4983 UINT rc;
4984
4985 if (package->script == SCRIPT_NONE)
4986 return msi_schedule_action(package, SCRIPT_INSTALL, L"RegisterProduct");
4987
4988 /* FIXME: also need to publish if the product is in advertise mode */
4989 if (!msi_get_property_int( package->db, L"ProductToBeRegistered", 0 ) && !check_publish(package))
4990 return ERROR_SUCCESS;
4991
4992 rc = MSIREG_OpenUninstallKey(package->ProductCode, package->platform, &hkey, TRUE);
4993 if (rc != ERROR_SUCCESS)
4994 return rc;
4995
4996 rc = MSIREG_OpenInstallProps(package->ProductCode, package->Context, NULL, &props, TRUE);
4997 if (rc != ERROR_SUCCESS)
4998 goto done;
4999
5000 rc = publish_install_properties(package, hkey);
5001 if (rc != ERROR_SUCCESS)
5002 goto done;
5003
5004 rc = publish_install_properties(package, props);
5005 if (rc != ERROR_SUCCESS)
5006 goto done;
5007
5008 upgrade_code = msi_dup_property(package->db, L"UpgradeCode");
5009 if (upgrade_code)
5010 {
5011 rc = MSIREG_OpenUpgradeCodesKey( upgrade_code, &upgrade_key, TRUE );
5012 if (rc == ERROR_SUCCESS)
5013 {
5014 squash_guid( package->ProductCode, squashed_pc );
5015 msi_reg_set_val_str( upgrade_key, squashed_pc, NULL );
5016 RegCloseKey( upgrade_key );
5017 }
5018 free( upgrade_code );
5019 }
5021 package->delete_on_close = FALSE;
5022
5023done:
5024 uirow = MSI_CreateRecord( 1 );
5025 MSI_RecordSetStringW( uirow, 1, package->ProductCode );
5027 msiobj_release( &uirow->hdr );
5028
5029 RegCloseKey(hkey);
5030 return ERROR_SUCCESS;
5031}
5032
5034{
5035 return execute_script(package, SCRIPT_INSTALL);
5036}
5037
5039{
5040 MSIPACKAGE *package = param;
5041 const WCHAR *icon = MSI_RecordGetString( row, 1 );
5042 WCHAR *p, *icon_path;
5043
5044 if (!icon) return ERROR_SUCCESS;
5045 if ((icon_path = msi_build_icon_path( package, icon )))
5046 {
5047 TRACE("removing icon file %s\n", debugstr_w(icon_path));
5048 msi_delete_file( package, icon_path );
5049 if ((p = wcsrchr( icon_path, '\\' )))
5050 {
5051 *p = 0;
5052 msi_remove_directory( package, icon_path );
5053 }
5054 free( icon_path );
5055 }
5056 return ERROR_SUCCESS;
5057}
5058
5060{
5061 MSIQUERY *view;
5062 UINT r;
5063
5064 r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Icon`", &view );
5065 if (r == ERROR_SUCCESS)
5066 {
5068 msiobj_release( &view->hdr );
5069 if (r != ERROR_SUCCESS)
5070 return r;
5071 }
5072 return ERROR_SUCCESS;
5073}
5074
5076{
5077 WCHAR *code, product[SQUASHED_GUID_SIZE];
5078 HKEY hkey;
5079 LONG res;
5080 DWORD count;
5081
5082 squash_guid( package->ProductCode, product );
5083 if (!(code = msi_dup_property( package->db, L"UpgradeCode" )))
5084 {
5085 WARN( "upgrade code not found\n" );
5086 return;
5087 }
5088 if (!MSIREG_OpenUpgradeCodesKey( code, &hkey, FALSE ))
5089 {
5090 RegDeleteValueW( hkey, product );
5092 RegCloseKey( hkey );
5094 }
5096 {
5097 RegDeleteValueW( hkey, product );
5099 RegCloseKey( hkey );
5101 }
5103 {
5104 RegDeleteValueW( hkey, product );
5106 RegCloseKey( hkey );
5108 }
5109
5110 free( code );
5111}
5112
5114{
5115 MSIPATCHINFO *patch;
5116
5120
5125
5126 remove_product_upgrade_code( package );
5127
5128 LIST_FOR_EACH_ENTRY(patch, &package->patches, MSIPATCHINFO, entry)
5129 {
5131 if (!wcscmp( package->ProductCode, patch->products ))
5132 {
5133 TRACE("removing local patch package %s\n", debugstr_w(patch->localfile));
5134 patch->delete_on_close = TRUE;
5135 }
5136 /* FIXME: remove local patch package if this is the last product */
5137 }
5138 TRACE("removing local package %s\n", debugstr_w(package->localfile));
5139 package->delete_on_close = TRUE;
5140
5141 unpublish_icons( package );
5142 return ERROR_SUCCESS;
5143}
5144
5146{
5148
5150 {
5151 if (feature->Action != INSTALLSTATE_ABSENT &&
5152 (feature->Installed != INSTALLSTATE_ABSENT || feature->Action != INSTALLSTATE_UNKNOWN))
5153 return FALSE;
5154 }
5155
5156 return TRUE;
5157}
5158
5160{
5161 UINT rc;
5162 MSIFILE *file;
5163 MSIFILEPATCH *patch;
5164
5165 /* first do the same as an InstallExecute */
5166 rc = execute_script(package, SCRIPT_INSTALL);
5167 if (rc != ERROR_SUCCESS)
5168 return rc;
5169
5170 /* install global assemblies */
5172 {
5173 MSICOMPONENT *comp = file->Component;
5174
5175 if (!msi_is_global_assembly( comp ) || (file->state != msifs_missing && file->state != msifs_overwrite))
5176 continue;
5177
5178 rc = msi_install_assembly( package, comp );
5179 if (rc != ERROR_SUCCESS)
5180 {
5181 ERR("Failed to install assembly\n");
5182 return ERROR_INSTALL_FAILURE;
5183 }
5184 file->state = msifs_installed;
5185 }
5186
5187 /* patch global assemblies */
5189 {
5190 MSICOMPONENT *comp = patch->File->Component;
5191
5192 if (!msi_is_global_assembly( comp ) || !patch->path) continue;
5193
5194 rc = msi_patch_assembly( package, comp->assembly, patch );
5195 if (rc && !(patch->Attributes & msidbPatchAttributesNonVital))
5196 {
5197 ERR("Failed to apply patch to file: %s\n", debugstr_w(patch->File->File));
5198 return rc;
5199 }
5200
5201 if ((rc = msi_install_assembly( package, comp )))
5202 {
5203 ERR("Failed to install patched assembly\n");
5204 return rc;
5205 }
5206 }
5207
5208 /* then handle commit actions */
5209 rc = execute_script(package, SCRIPT_COMMIT);
5210 if (rc != ERROR_SUCCESS)
5211 return rc;
5212
5213 if (is_full_uninstall(package))
5214 rc = ACTION_UnpublishProduct(package);
5215
5216 return rc;
5217}
5218
5220{
5221 WCHAR buffer[256], sysdir[MAX_PATH], squashed_pc[SQUASHED_GUID_SIZE];
5222 HKEY hkey;
5223
5224 squash_guid( package->ProductCode, squashed_pc );
5225
5226 GetSystemDirectoryW(sysdir, ARRAY_SIZE(sysdir));
5227 RegCreateKeyW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\RunOnce", &hkey);
5228 swprintf(buffer, ARRAY_SIZE(buffer), L"%s\\MsiExec.exe /@ \"%s\"", sysdir, squashed_pc);
5229
5230 msi_reg_set_val_str( hkey, squashed_pc, buffer );
5231 RegCloseKey(hkey);
5232
5233 TRACE("Reboot command %s\n",debugstr_w(buffer));
5234
5235 RegCreateKeyW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\RunOnceEntries",
5236 &hkey);
5237 swprintf( buffer, ARRAY_SIZE(buffer), L"/I \"%s\" AFTERREBOOT=1 RUNONCEENTRY=\"%s\"", package->ProductCode,
5238 squashed_pc );
5239
5240 msi_reg_set_val_str( hkey, squashed_pc, buffer );
5241 RegCloseKey(hkey);
5242
5243 return ERROR_INSTALL_SUSPEND;
5244}
5245
5247{
5248 DWORD attrib;
5249 UINT rc;
5250
5251 /*
5252 * We are currently doing what should be done here in the top level Install
5253 * however for Administrative and uninstalls this step will be needed
5254 */
5255 if (!package->PackagePath)
5256 return ERROR_SUCCESS;
5257
5258 msi_set_sourcedir_props(package, TRUE);
5259
5260 attrib = GetFileAttributesW(package->db->path);
5261 if (attrib == INVALID_FILE_ATTRIBUTES)
5262 {
5264 LPWSTR prompt;
5265 DWORD size = 0;
5266
5267 rc = MsiSourceListGetInfoW(package->ProductCode, NULL,
5268 package->Context, MSICODE_PRODUCT,
5270 if (rc == ERROR_MORE_DATA)
5271 {
5272 prompt = malloc(size * sizeof(WCHAR));
5274 package->Context, MSICODE_PRODUCT,
5276 }
5277 else
5278 prompt = wcsdup(package->db->path);
5279
5282 MSI_RecordSetStringW(record, 2, prompt);
5283 free(prompt);
5284 while(attrib == INVALID_FILE_ATTRIBUTES)
5285 {
5288 if (rc == IDCANCEL)
5289 {
5290 msiobj_release(&record->hdr);
5292 }
5293 attrib = GetFileAttributesW(package->db->path);
5294 }
5295 msiobj_release(&record->hdr);
5296 rc = ERROR_SUCCESS;
5297 }
5298 else
5299 return ERROR_SUCCESS;
5300
5301 return rc;
5302}
5303
5305{
5306 static const WCHAR szPropKeys[][80] =
5307 {
5308 L"ProductID",
5309 L"USERNAME",
5310 L"COMPANYNAME",
5311 L"",
5312 };
5313 static const WCHAR szRegKeys[][80] =
5314 {
5315 L"ProductID",
5316 L"RegOwner",
5317 L"RegCompany",
5318 L"",
5319 };
5320 HKEY hkey = 0;
5321 LPWSTR buffer, productid = NULL;
5322 UINT i, rc = ERROR_SUCCESS;
5323 MSIRECORD *uirow;
5324
5325 if (package->script == SCRIPT_NONE)
5326 return msi_schedule_action(package, SCRIPT_INSTALL, L"RegisterUser");
5327
5328 if (check_unpublish(package))
5329 {
5331 goto end;
5332 }
5333
5334 productid = msi_dup_property( package->db, INSTALLPROPERTY_PRODUCTIDW );
5335 if (!productid)
5336 goto end;
5337
5338 rc = MSIREG_OpenInstallProps(package->ProductCode, package->Context,
5339 NULL, &hkey, TRUE);
5340 if (rc != ERROR_SUCCESS)
5341 goto end;
5342
5343 for( i = 0; szPropKeys[i][0]; i++ )
5344 {
5345 buffer = msi_dup_property( package->db, szPropKeys[i] );
5346 msi_reg_set_val_str( hkey, szRegKeys[i], buffer );
5347 free( buffer );
5348 }
5349
5350end:
5351 uirow = MSI_CreateRecord( 1 );
5352 MSI_RecordSetStringW( uirow, 1, productid );
5354 msiobj_release( &uirow->hdr );
5355
5356 free(productid);
5357 RegCloseKey(hkey);
5358 return rc;
5359}
5360
5362{
5363 MSIRECORD *uirow;
5364
5365 uirow = MSI_CloneRecord(record);
5366 if (!uirow) return ERROR_OUTOFMEMORY;
5367 MSI_RecordSetStringW(uirow, 0, L"Property(S): [1] = [2]");
5369 msiobj_release(&uirow->hdr);
5370
5371 return ERROR_SUCCESS;
5372}
5373
5374
5376{
5377 WCHAR *productname;
5378 WCHAR *action;
5379 WCHAR *info_template;
5380 MSIQUERY *view;
5381 MSIRECORD *uirow, *uirow_info;
5382 UINT rc;
5383
5384 /* Send COMMONDATA and INFO messages. */
5385 /* FIXME: when should these messages be sent? [see also MsiOpenPackage()] */
5386 uirow = MSI_CreateRecord(3);
5387 if (!uirow) return ERROR_OUTOFMEMORY;
5388 MSI_RecordSetStringW(uirow, 0, NULL);
5389 MSI_RecordSetInteger(uirow, 1, 0);
5390 MSI_RecordSetInteger(uirow, 2, package->num_langids ? package->langids[0] : 0);
5393 /* FIXME: send INSTALLMESSAGE_PROGRESS */
5395
5396 if (!(needs_ui_sequence(package) && ui_sequence_exists(package)))
5397 {
5398 uirow_info = MSI_CreateRecord(0);
5399 if (!uirow_info)
5400 {
5401 msiobj_release(&uirow->hdr);
5402 return ERROR_OUTOFMEMORY;
5403 }
5404 info_template = msi_get_error_message(package->db, MSIERR_INFO_LOGGINGSTART);
5405 MSI_RecordSetStringW(uirow_info, 0, info_template);
5406 free(info_template);
5408 msiobj_release(&uirow_info->hdr);
5409 }
5410
5412
5413 productname = msi_dup_property(package->db, INSTALLPROPERTY_PRODUCTNAMEW);
5414 MSI_RecordSetInteger(uirow, 1, 1);
5415 MSI_RecordSetStringW(uirow, 2, productname);
5416 MSI_RecordSetStringW(uirow, 3, NULL);
5418 msiobj_release(&uirow->hdr);
5419
5421
5422 action = msi_dup_property(package->db, L"EXECUTEACTION");
5423 if (!action) action = msi_strdupW(L"INSTALL", ARRAY_SIZE(L"INSTALL") - 1);
5424
5425 /* Perform the action. Top-level actions trigger a sequence. */
5426 if (!wcscmp(action, L"INSTALL"))
5427 {
5428 /* Send ACTIONSTART/INFO and INSTALLSTART. */
5429 ui_actionstart(package, L"INSTALL", NULL, NULL);
5430 ui_actioninfo(package, L"INSTALL", TRUE, 0);
5431 uirow = MSI_CreateRecord(2);
5432 if (!uirow)
5433 {
5434 rc = ERROR_OUTOFMEMORY;
5435 goto end;
5436 }
5437 MSI_RecordSetStringW(uirow, 0, NULL);
5438 MSI_RecordSetStringW(uirow, 1, productname);
5439 MSI_RecordSetStringW(uirow, 2, package->ProductCode);
5441 msiobj_release(&uirow->hdr);
5442
5443 /* Perform the installation. Always use the ExecuteSequence. */
5444 package->InWhatSequence |= SEQUENCE_EXEC;
5445 rc = ACTION_ProcessExecSequence(package);
5446
5447 /* Send return value and INSTALLEND. */
5448 ui_actioninfo(package, L"INSTALL", FALSE, !rc);
5449 uirow = MSI_CreateRecord(3);
5450 if (!uirow)
5451 {
5452 rc = ERROR_OUTOFMEMORY;
5453 goto end;
5454 }
5455 MSI_RecordSetStringW(uirow, 0, NULL);
5456 MSI_RecordSetStringW(uirow, 1, productname);
5457 MSI_RecordSetStringW(uirow, 2, package->ProductCode);
5458 MSI_RecordSetInteger(uirow, 3, !rc);
5460 msiobj_release(&uirow->hdr);
5461 }
5462 else
5463 rc = ACTION_PerformAction(package, action);
5464
5465 /* Send all set properties. */
5466 if (!MSI_OpenQuery(package->db, &view, L"SELECT * FROM `_Property`"))
5467 {
5469 msiobj_release(&view->hdr);
5470 }
5471
5472 /* And finally, toggle the cancel off and on. */
5473 uirow = MSI_CreateRecord(2);
5474 if (!uirow)
5475 {
5476 rc = ERROR_OUTOFMEMORY;
5477 goto end;
5478 }
5479 MSI_RecordSetStringW(uirow, 0, NULL);
5480 MSI_RecordSetInteger(uirow, 1, 2);
5481 MSI_RecordSetInteger(uirow, 2, 0);
5483 MSI_RecordSetInteger(uirow, 2, 1);
5485 msiobj_release(&uirow->hdr);
5486
5487end:
5488 free(productname);
5489 free(action);
5490 return rc;
5491}
5492
5494{
5495 msi_set_property(package->db, L"EXECUTEACTION", L"INSTALL", -1);
5496 if (needs_ui_sequence(package) && ui_sequence_exists(package))
5497 {
5498 package->InWhatSequence |= SEQUENCE_UI;
5499 return ACTION_ProcessUISequence(package);
5500 }
5501 else
5502 return ACTION_ExecuteAction(package);
5503}
5504
5506{
5507 WCHAR productid_85[21], component_85[21], *ret;
5508 GUID clsid;
5509 DWORD sz;
5510
5511 /* > is used if there is a component GUID and < if not. */
5512
5513 productid_85[0] = 0;
5514 component_85[0] = 0;
5515 CLSIDFromString( package->ProductCode, &clsid );
5516
5517 encode_base85_guid( &clsid, productid_85 );
5518 if (component)
5519 {
5520 CLSIDFromString( component->ComponentId, &clsid );
5521 encode_base85_guid( &clsid, component_85 );
5522 }
5523
5524 TRACE("product=%s feature=%s component=%s\n", debugstr_w(productid_85), debugstr_w(feature),
5525 debugstr_w(component_85));
5526
5527 sz = 20 + lstrlenW( feature ) + 20 + 3;
5528 ret = calloc( 1, sz * sizeof(WCHAR) );
5529 if (ret) swprintf( ret, sz, L"%s%s%c%s", productid_85, feature, component ? '>' : '<', component_85 );
5530 return ret;
5531}
5532
5534{
5535 MSIPACKAGE *package = param;
5536 LPCWSTR compgroupid, component, feature, qualifier, text;
5537 LPWSTR advertise = NULL, output = NULL, existing = NULL, p, q;
5538 HKEY hkey = NULL;
5539 UINT rc;
5540 MSICOMPONENT *comp;
5541 MSIFEATURE *feat;
5542 DWORD sz;
5543 MSIRECORD *uirow;
5544 int len;
5545
5546 feature = MSI_RecordGetString(rec, 5);
5547 feat = msi_get_loaded_feature(package, feature);
5548 if (!feat)
5549 return ERROR_SUCCESS;
5550
5551 feat->Action = msi_get_feature_action( package, feat );
5552 if (feat->Action != INSTALLSTATE_LOCAL &&
5553 feat->Action != INSTALLSTATE_SOURCE &&
5555 {
5556 TRACE("feature not scheduled for installation %s\n", debugstr_w(feature));
5557 return ERROR_SUCCESS;
5558 }
5559
5560 component = MSI_RecordGetString(rec, 3);
5561 comp = msi_get_loaded_component(package, component);
5562 if (!comp)
5563 return ERROR_SUCCESS;
5564
5565 compgroupid = MSI_RecordGetString(rec,1);
5567
5568 rc = MSIREG_OpenUserComponentsKey(compgroupid, &hkey, TRUE);
5569 if (rc != ERROR_SUCCESS)
5570 goto end;
5571
5572 advertise = msi_create_component_advertise_string( package, comp, feature );
5573 text = MSI_RecordGetString( rec, 4 );
5574 if (text)
5575 {
5576 p = malloc( (wcslen( advertise ) + wcslen( text ) + 1) * sizeof(WCHAR) );
5577 lstrcpyW( p, advertise );
5578 lstrcatW( p, text );
5579 free( advertise );
5580 advertise = p;
5581 }
5582 existing = msi_reg_get_val_str( hkey, qualifier );
5583
5584 sz = lstrlenW( advertise ) + 1;
5585 if (existing)
5586 {
5587 for (p = existing; *p; p += len)
5588 {
5589 len = lstrlenW( p ) + 1;
5590 if (wcscmp( advertise, p )) sz += len;
5591 }
5592 }
5593 if (!(output = malloc( (sz + 1) * sizeof(WCHAR) )))
5594 {
5595 rc = ERROR_OUTOFMEMORY;
5596 goto end;
5597 }
5598 q = output;
5599 if (existing)
5600 {
5601 for (p = existing; *p; p += len)
5602 {
5603 len = lstrlenW( p ) + 1;
5604 if (wcscmp( advertise, p ))
5605 {
5606 memcpy( q, p, len * sizeof(WCHAR) );
5607 q += len;
5608 }
5609 }
5610 }
5611 lstrcpyW( q, advertise );
5612 q[lstrlenW( q ) + 1] = 0;
5613
5614 msi_reg_set_val_multi_str( hkey, qualifier, output );
5615
5616end:
5617 RegCloseKey(hkey);
5618 free( output );
5619 free( advertise );
5620 free( existing );
5621
5622 /* the UI chunk */
5623 uirow = MSI_CreateRecord( 2 );
5624 MSI_RecordSetStringW( uirow, 1, compgroupid );
5625 MSI_RecordSetStringW( uirow, 2, qualifier);
5627 msiobj_release( &uirow->hdr );
5628 /* FIXME: call ui_progress? */
5629
5630 return rc;
5631}
5632
5633/*
5634 * At present I am ignoring the advertised components part of this and only
5635 * focusing on the qualified component sets
5636 */
5638{
5639 MSIQUERY *view;
5640 UINT rc;
5641
5642 if (package->script == SCRIPT_NONE)
5643 return msi_schedule_action(package, SCRIPT_INSTALL, L"PublishComponents");
5644
5645 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `PublishComponent`", &view);
5646 if (rc != ERROR_SUCCESS)
5647 return ERROR_SUCCESS;
5648
5650 msiobj_release(&view->hdr);
5651 return rc;
5652}
5653
5655{
5656 MSIPACKAGE *package = param;
5657 LPCWSTR compgroupid, component, feature, qualifier;
5658 MSICOMPONENT *comp;
5659 MSIFEATURE *feat;
5660 MSIRECORD *uirow;
5661 WCHAR squashed[GUID_SIZE], keypath[MAX_PATH];
5662 LONG res;
5663
5664 feature = MSI_RecordGetString( rec, 5 );
5665 feat = msi_get_loaded_feature( package, feature );
5666 if (!feat)
5667 return ERROR_SUCCESS;
5668
5669 feat->Action = msi_get_feature_action( package, feat );
5670 if (feat->Action != INSTALLSTATE_ABSENT)
5671 {
5672 TRACE("feature not scheduled for removal %s\n", debugstr_w(feature));
5673 return ERROR_SUCCESS;
5674 }
5675
5676 component = MSI_RecordGetString( rec, 3 );
5677 comp = msi_get_loaded_component( package, component );
5678 if (!comp)
5679 return ERROR_SUCCESS;
5680
5681 compgroupid = MSI_RecordGetString( rec, 1 );
5682 qualifier = MSI_RecordGetString( rec, 2 );
5683
5684 squash_guid( compgroupid, squashed );
5685 lstrcpyW( keypath, L"Software\\Microsoft\\Installer\\Components\\" );
5686 lstrcatW( keypath, squashed );
5687
5688 res = RegDeleteKeyW( HKEY_CURRENT_USER, keypath );
5689 if (res != ERROR_SUCCESS)
5690 {
5691 WARN( "unable to delete component key %ld\n", res );
5692 }
5693
5694 uirow = MSI_CreateRecord( 2 );
5695 MSI_RecordSetStringW( uirow, 1, compgroupid );
5696 MSI_RecordSetStringW( uirow, 2, qualifier );
5698 msiobj_release( &uirow->hdr );
5699
5700 return ERROR_SUCCESS;
5701}
5702
5704{
5705 MSIQUERY *view;
5706 UINT rc;
5707
5708 if (package->script == SCRIPT_NONE)
5709 return msi_schedule_action(package, SCRIPT_INSTALL, L"UnpublishComponents");
5710
5711 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `PublishComponent`", &view );
5712 if (rc != ERROR_SUCCESS)
5713 return ERROR_SUCCESS;
5714
5716 msiobj_release( &view->hdr );
5717 return rc;
5718}
5719
5721{
5722 MSIPACKAGE *package = param;
5723 MSICOMPONENT *component;
5724 MSIRECORD *row;
5725 MSIFILE *file;
5726 SC_HANDLE hscm = NULL, service = NULL;
5727 LPCWSTR comp, key;
5728 LPWSTR name = NULL, disp = NULL, load_order = NULL, serv_name = NULL;
5729 LPWSTR depends = NULL, pass = NULL, args = NULL, image_path = NULL;
5730 DWORD serv_type, start_type, err_control;
5731 BOOL is_vital;
5734
5735 comp = MSI_RecordGetString( rec, 12 );
5736 component = msi_get_loaded_component( package, comp );
5737 if (!component)
5738 {
5739 WARN("service component not found\n");
5740 goto done;
5741 }
5742 component->Action = msi_get_component_action( package, component );
5743 if (component->Action != INSTALLSTATE_LOCAL)
5744 {
5745 TRACE("component not scheduled for installation %s\n", debugstr_w(comp));
5746 goto done;
5747 }
5749 if (!hscm)
5750 {
5751 ERR("Failed to open the SC Manager!\n");
5752 goto done;
5753 }
5754
5755 start_type = MSI_RecordGetInteger(rec, 5);
5756 if (start_type == SERVICE_BOOT_START || start_type == SERVICE_SYSTEM_START)
5757 goto done;
5758
5759 deformat_string(package, MSI_RecordGetString(rec, 2), &name);
5760 deformat_string(package, MSI_RecordGetString(rec, 3), &disp);
5761 serv_type = MSI_RecordGetInteger(rec, 4);
5762 err_control = MSI_RecordGetInteger(rec, 6);
5763 deformat_string(package, MSI_RecordGetString(rec, 7), &load_order);
5764 deformat_string(package, MSI_RecordGetString(rec, 8), &depends);
5765 deformat_string(package, MSI_RecordGetString(rec, 9), &serv_name);
5766 deformat_string(package, MSI_RecordGetString(rec, 10), &pass);
5767 deformat_string(package, MSI_RecordGetString(rec, 11), &args);
5768 deformat_string(package, MSI_RecordGetString(rec, 13), &sd.lpDescription);
5769
5770 /* Should the complete install fail if CreateService fails? */
5771 is_vital = (err_control & msidbServiceInstallErrorControlVital);
5772
5773 /* Remove the msidbServiceInstallErrorControlVital-flag from err_control.
5774 CreateService (under Windows) would fail if not. */
5775 err_control &= ~msidbServiceInstallErrorControlVital;
5776
5777 /* fetch the service path */
5778 row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Component` WHERE `Component` = '%s'", comp);
5779 if (!row)
5780 {
5781 ERR("Query failed\n");
5782 goto done;
5783 }
5784 if (!(key = MSI_RecordGetString(row, 6)))
5785 {
5786 msiobj_release(&row->hdr);
5787 goto done;
5788 }
5789 file = msi_get_loaded_file(package, key);
5790 msiobj_release(&row->hdr);
5791 if (!file)
5792 {
5793 ERR("Failed to load the service file\n");
5794 goto done;
5795 }
5796
5797 if (!args || !args[0]) image_path = file->TargetPath;
5798 else
5799 {
5800 int len = lstrlenW(file->TargetPath) + lstrlenW(args) + 2;
5801 if (!(image_path = malloc(len * sizeof(WCHAR))))
5802 {
5804 goto done;
5805 }
5806
5807 lstrcpyW(image_path, file->TargetPath);
5808 lstrcatW(image_path, L" ");
5809 lstrcatW(image_path, args);
5810 }
5811 service = CreateServiceW(hscm, name, disp, GENERIC_ALL, serv_type,
5812 start_type, err_control, image_path, load_order,
5813 NULL, depends, serv_name, pass);
5814
5815 if (!service)
5816 {
5818 {
5819 WARN( "failed to create service %s (%lu)\n", debugstr_w(name), GetLastError() );
5820 if (is_vital)
5822
5823 }
5824 }
5825 else if (sd.lpDescription)
5826 {
5828 WARN( "failed to set service description %lu\n", GetLastError() );
5829 }
5830
5831 if (image_path != file->TargetPath) free(image_path);
5832done:
5833 if (service) CloseServiceHandle(service);
5834 if (hscm) CloseServiceHandle(hscm);
5835 free(name);
5836 free(disp);
5837 free(sd.lpDescription);
5838 free(load_order);
5839 free(serv_name);
5840 free(pass);
5841 free(depends);
5842 free(args);
5843
5844 return ret;
5845}
5846
5848{
5849 MSIQUERY *view;
5850 UINT rc;
5851
5852 if (package->script == SCRIPT_NONE)
5853 return msi_schedule_action(package, SCRIPT_INSTALL, L"InstallServices");
5854
5855 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `ServiceInstall`", &view);
5856 if (rc != ERROR_SUCCESS)
5857 return ERROR_SUCCESS;
5858
5860 msiobj_release(&view->hdr);
5861 return rc;
5862}
5863
5864/* converts arg1[~]arg2[~]arg3 to a list of ptrs to the strings */
5865static const WCHAR **service_args_to_vector(WCHAR *args, DWORD *numargs)
5866{
5867 LPCWSTR *vector, *temp_vector;
5868 LPWSTR p, q;
5869 DWORD sep_len;
5870
5871 *numargs = 0;
5872 sep_len = ARRAY_SIZE(L"[~]") - 1;
5873
5874 if (!args)
5875 return NULL;
5876
5877 vector = malloc(sizeof(WCHAR *));
5878 if (!vector)
5879 return NULL;
5880
5881 p = args;
5882 do
5883 {
5884 (*numargs)++;
5885 vector[*numargs - 1] = p;
5886
5887 if ((q = wcsstr(p, L"[~]")))
5888 {
5889 *q = '\0';
5890
5891 temp_vector = realloc(vector, (*numargs + 1) * sizeof(WCHAR *));
5892 if (!temp_vector)
5893 {
5894 free(vector);
5895 return NULL;
5896 }
5897 vector = temp_vector;
5898
5899 p = q + sep_len;
5900 }
5901 } while (q);
5902
5903 return vector;
5904}
5905
5907{
5908 MSIPACKAGE *package = param;
5909 MSICOMPONENT *comp;
5910 MSIRECORD *uirow;
5911 SC_HANDLE scm = NULL, service = NULL;
5912 LPCWSTR component, *vector = NULL;
5913 LPWSTR name, args, display_name = NULL;
5914 DWORD event, numargs, len, wait, dummy;
5917 ULONGLONG start_time;
5918
5919 component = MSI_RecordGetString(rec, 6);
5920 comp = msi_get_loaded_component(package, component);
5921 if (!comp)
5922 return ERROR_SUCCESS;
5923
5924 event = MSI_RecordGetInteger( rec, 3 );
5925 deformat_string( package, MSI_RecordGetString( rec, 2 ), &name );
5926
5927 comp->Action = msi_get_component_action( package, comp );
5928 if (!(comp->Action == INSTALLSTATE_LOCAL && (event & msidbServiceControlEventStart)) &&
5930 {
5931 TRACE("not starting %s\n", debugstr_w(name));
5932 free(name);
5933 return ERROR_SUCCESS;
5934 }
5935
5936 deformat_string(package, MSI_RecordGetString(rec, 4), &args);
5937 wait = MSI_RecordGetInteger(rec, 5);
5938
5940 if (!scm)
5941 {
5942 ERR("Failed to open the service control manager\n");
5943 goto done;
5944 }
5945
5946 len = 0;
5947 if (!GetServiceDisplayNameW( scm, name, NULL, &len ) &&
5949 {
5950 if ((display_name = malloc(++len * sizeof(WCHAR))))
5951 GetServiceDisplayNameW( scm, name, display_name, &len );
5952 }
5953
5955 if (!service)
5956 {
5957 ERR( "failed to open service %s (%lu)\n", debugstr_w(name), GetLastError() );
5958 goto done;
5959 }
5960
5961 vector = service_args_to_vector(args, &numargs);
5962
5963 if (!StartServiceW(service, numargs, vector) &&
5965 {
5966 ERR( "failed to start service %s (%lu)\n", debugstr_w(name), GetLastError() );
5967 goto done;
5968 }
5969
5970 r = ERROR_SUCCESS;
5971 if (wait)
5972 {
5973 /* wait for at most 30 seconds for the service to be up and running */
5975 (BYTE *)&status, sizeof(SERVICE_STATUS_PROCESS), &dummy))
5976 {
5977 TRACE( "failed to query service status (%lu)\n", GetLastError() );
5978 goto done;
5979 }
5980 start_time = GetTickCount64();
5981 while (status.dwCurrentState == SERVICE_START_PENDING)
5982 {
5983 if (GetTickCount64() - start_time > 30000) break;
5984 Sleep(1000);
5986 (BYTE *)&status, sizeof(SERVICE_STATUS_PROCESS), &dummy))
5987 {
5988 TRACE( "failed to query service status (%lu)\n", GetLastError() );
5989 goto done;
5990 }
5991 }
5992 if (status.dwCurrentState != SERVICE_RUNNING)
5993 {
5994 WARN( "service failed to start %lu\n", status.dwCurrentState );
5996 }
5997 }
5998
5999done:
6000 uirow = MSI_CreateRecord( 2 );
6001 MSI_RecordSetStringW( uirow, 1, display_name );
6002 MSI_RecordSetStringW( uirow, 2, name );
6004 msiobj_release( &uirow->hdr );
6005
6006 if (service) CloseServiceHandle(service);
6007 if (scm) CloseServiceHandle(scm);
6008
6009 free(name);
6010 free(args);
6011 free(vector);
6012 free(display_name);
6013 return r;
6014}
6015
6017{
6018 MSIQUERY *view;
6019 UINT rc;
6020
6021 if (package->script == SCRIPT_NONE)
6022 return msi_schedule_action(package, SCRIPT_INSTALL, L"StartServices");
6023
6024 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `ServiceControl`", &view);
6025 if (rc != ERROR_SUCCESS)
6026 return ERROR_SUCCESS;
6027
6029 msiobj_release(&view->hdr);
6030 return rc;
6031}
6032
6033static BOOL stop_service_dependents(SC_HANDLE scm, SC_HANDLE service)
6034{
6035 DWORD i, needed, count;
6036 ENUM_SERVICE_STATUSW *dependencies;
6038 SC_HANDLE depserv;
6039 BOOL stopped, ret = FALSE;
6040
6042 0, &needed, &count))
6043 return TRUE;
6044
6046 return FALSE;
6047
6048 dependencies = malloc(needed);
6049 if (!dependencies)
6050 return FALSE;
6051
6052 if (!EnumDependentServicesW(service, SERVICE_ACTIVE, dependencies,
6053 needed, &needed, &count))
6054 goto done;
6055
6056 for (i = 0; i < count; i++)
6057 {
6058 depserv = OpenServiceW(scm, dependencies[i].lpServiceName,
6060 if (!depserv)
6061 goto done;
6062
6063 stopped = ControlService(depserv, SERVICE_CONTROL_STOP, &ss);
6064 CloseServiceHandle(depserv);
6065 if (!stopped)
6066 goto done;
6067 }
6068
6069 ret = TRUE;
6070
6071done:
6072 free(dependencies);
6073 return ret;
6074}
6075
6077{
6078 SC_HANDLE scm = NULL, service = NULL;
6081 DWORD needed;
6082
6084 if (!scm)
6085 {
6086 WARN( "failed to open the SCM (%lu)\n", GetLastError() );
6087 goto done;
6088 }
6089
6091 if (!service)
6092 {
6093 WARN( "failed to open service %s (%lu)\n", debugstr_w(name), GetLastError() );
6094 goto done;
6095 }
6096
6097 if (!QueryServiceStatusEx( service, SC_STATUS_PROCESS_INFO, (BYTE *)&ssp, sizeof(ssp), &needed) )
6098 {
6099 WARN( "failed to query service status %s (%lu)\n", debugstr_w(name), GetLastError() );
6100 goto done;
6101 }
6102
6104 goto done;
6105
6106 stop_service_dependents(scm, service);
6107
6109 WARN( "failed to stop service %s (%lu)\n", debugstr_w(name), GetLastError() );
6110
6111done:
6112 if (service) CloseServiceHandle(service);
6113 if (scm) CloseServiceHandle(scm);
6114
6115 return ERROR_SUCCESS;
6116}
6117
6119{
6120 MSIPACKAGE *package = param;
6121 MSICOMPONENT *comp;
6122 MSIRECORD *uirow;
6123 LPCWSTR component;
6124 WCHAR *name, *display_name = NULL;
6125 DWORD event, len;
6126 SC_HANDLE scm;
6127
6128 component = MSI_RecordGetString( rec, 6 );
6129 comp = msi_get_loaded_component( package, component );
6130 if (!comp)
6131 return ERROR_SUCCESS;
6132
6133 event = MSI_RecordGetInteger( rec, 3 );
6134 deformat_string( package, MSI_RecordGetString( rec, 2 ), &name );
6135
6136 comp->Action = msi_get_component_action( package, comp );
6137 if (!(comp->Action == INSTALLSTATE_LOCAL && (event & msidbServiceControlEventStop)) &&
6139 {
6140 TRACE("not stopping %s\n", debugstr_w(name));
6141 free( name );
6142 return ERROR_SUCCESS;
6143 }
6144
6146 if (!scm)
6147 {
6148 ERR("Failed to open the service control manager\n");
6149 goto done;
6150 }
6151
6152 len = 0;
6153 if (!GetServiceDisplayNameW( scm, name, NULL, &len ) &&
6155 {
6156 if ((display_name = malloc( ++len * sizeof(WCHAR ))))
6157 GetServiceDisplayNameW( scm, name, display_name, &len );
6158 }
6159 CloseServiceHandle( scm );
6160
6161 stop_service( name );
6162
6163done:
6164 uirow = MSI_CreateRecord( 2 );
6165 MSI_RecordSetStringW( uirow, 1, display_name );
6166 MSI_RecordSetStringW( uirow, 2, name );
6168 msiobj_release( &uirow->hdr );
6169
6170 free( name );
6171 free( display_name );
6172 return ERROR_SUCCESS;
6173}
6174
6176{
6177 MSIQUERY *view;
6178 UINT rc;
6179
6180 if (package->script == SCRIPT_NONE)
6181 return msi_schedule_action(package, SCRIPT_INSTALL, L"StopServices");
6182
6183 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `ServiceControl`", &view);
6184 if (rc != ERROR_SUCCESS)
6185 return ERROR_SUCCESS;
6186
6188 msiobj_release(&view->hdr);
6189 return rc;
6190}
6191
6193{
6194 MSIPACKAGE *package = param;
6195 MSICOMPONENT *comp;
6196 MSIRECORD *uirow;
6197 LPWSTR name = NULL, display_name = NULL;
6198 DWORD event, len;
6199 SC_HANDLE scm = NULL, service = NULL;
6200
6201 comp = msi_get_loaded_component( package, MSI_RecordGetString(rec, 6) );
6202 if (!comp)
6203 return ERROR_SUCCESS;
6204
6205 event = MSI_RecordGetInteger( rec, 3 );
6206 deformat_string( package, MSI_RecordGetString(rec, 2), &name );
6207
6208 comp->Action = msi_get_component_action( package, comp );
6209 if (!(comp->Action == INSTALLSTATE_LOCAL && (event & msidbServiceControlEventDelete)) &&
6211 {
6212 TRACE("service %s not scheduled for removal\n", debugstr_w(name));
6213 free( name );
6214 return ERROR_SUCCESS;
6215 }
6216 stop_service( name );
6217
6219 if (!scm)
6220 {
6221 WARN( "failed to open the SCM (%lu)\n", GetLastError() );
6222 goto done;
6223 }
6224
6225 len = 0;
6226 if (!GetServiceDisplayNameW( scm, name, NULL, &len ) &&
6228 {
6229 if ((display_name = malloc( ++len * sizeof(WCHAR ))))
6230 GetServiceDisplayNameW( scm, name, display_name, &len );
6231 }
6232
6233 service = OpenServiceW( scm, name, DELETE );
6234 if (!service)
6235 {
6236 WARN( "failed to open service %s (%lu)\n", debugstr_w(name), GetLastError() );
6237 goto done;
6238 }
6239
6240 if (!DeleteService( service ))
6241 WARN( "failed to delete service %s (%lu)\n", debugstr_w(name), GetLastError() );
6242
6243done:
6244 uirow = MSI_CreateRecord( 2 );
6245 MSI_RecordSetStringW( uirow, 1, display_name );
6246 MSI_RecordSetStringW( uirow, 2, name );
6248 msiobj_release( &uirow->hdr );
6249
6250 if (service) CloseServiceHandle( service );
6251 if (scm) CloseServiceHandle( scm );
6252 free( name );
6253 free( display_name );
6254
6255 return ERROR_SUCCESS;
6256}
6257
6259{
6260 MSIQUERY *view;
6261 UINT rc;
6262
6263 if (package->script == SCRIPT_NONE)
6264 return msi_schedule_action(package, SCRIPT_INSTALL, L"DeleteServices");
6265
6266 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `ServiceControl`", &view );
6267 if (rc != ERROR_SUCCESS)
6268 return ERROR_SUCCESS;
6269
6271 msiobj_release( &view->hdr );
6272 return rc;
6273}
6274
6276{
6277 MSIPACKAGE *package = param;
6278 LPWSTR driver, driver_path, ptr;
6279 WCHAR outpath[MAX_PATH];
6280 MSIFILE *driver_file = NULL, *setup_file = NULL;
6281 MSICOMPONENT *comp;
6282 MSIRECORD *uirow;
6283 LPCWSTR desc, file_key, component;
6284 DWORD len, usage;
6286
6287 component = MSI_RecordGetString( rec, 2 );
6288 comp = msi_get_loaded_component( package, component );
6289 if (!comp)
6290 return ERROR_SUCCESS;
6291
6292 comp->Action = msi_get_component_action( package, comp );
6293 if (comp->Action != INSTALLSTATE_LOCAL)
6294 {
6295 TRACE("component not scheduled for installation %s\n", debugstr_w(component));
6296 return ERROR_SUCCESS;
6297 }
6298 desc = MSI_RecordGetString(rec, 3);
6299
6300 file_key = MSI_RecordGetString( rec, 4 );
6301 if (file_key) driver_file = msi_get_loaded_file( package, file_key );
6302
6303 file_key = MSI_RecordGetString( rec, 5 );
6304 if (file_key) setup_file = msi_get_loaded_file( package, file_key );
6305
6306 if (!driver_file)
6307 {
6308 ERR("ODBC Driver entry not found!\n");
6309 return ERROR_FUNCTION_FAILED;
6310 }
6311
6312 len = lstrlenW(desc) + lstrlenW(L"Driver=%s") + lstrlenW(driver_file->FileName);
6313 if (setup_file)
6314 len += lstrlenW(L"Setup=%s") + lstrlenW(setup_file->FileName);
6315 len += lstrlenW(L"FileUsage=1") + 2; /* \0\0 */
6316
6317 driver = malloc(len * sizeof(WCHAR));
6318 if (!driver)
6319 return ERROR_OUTOFMEMORY;
6320
6321 ptr = driver;
6322 lstrcpyW(ptr, desc);
6323 ptr += lstrlenW(ptr) + 1;
6324
6325 len = swprintf(ptr, len - (ptr - driver), L"Driver=%s", driver_file->FileName);
6326 ptr += len + 1;
6327
6328 if (setup_file)
6329 {
6330 len = swprintf(ptr, len - (ptr - driver), L"Setup=%s", setup_file->FileName);
6331 ptr += len + 1;
6332 }
6333
6334 lstrcpyW(ptr, L"FileUsage=1");
6335 ptr += lstrlenW(ptr) + 1;
6336 *ptr = '\0';
6337
6338 if (!driver_file->TargetPath)
6339 {
6340 const WCHAR *dir = msi_get_target_folder( package, driver_file->Component->Directory );
6341 driver_file->TargetPath = msi_build_directory_name( 2, dir, driver_file->FileName );
6342 }
6343 driver_path = wcsdup(driver_file->TargetPath);
6344 ptr = wcsrchr(driver_path, '\\');
6345 if (ptr) *ptr = '\0';
6346
6347 if (!SQLInstallDriverExW(driver, driver_path, outpath, MAX_PATH,
6349 {
6350 ERR("Failed to install SQL driver!\n");
6352 }
6353
6354 uirow = MSI_CreateRecord( 5 );
6355 MSI_RecordSetStringW( uirow, 1, desc );
6356 MSI_RecordSetStringW( uirow, 2, MSI_RecordGetString(rec, 2) );
6357 MSI_RecordSetStringW( uirow, 3, driver_file->Component->Directory );
6359 msiobj_release( &uirow->hdr );
6360
6361 free(driver);
6362 free(driver_path);
6363
6364 return r;
6365}
6366
6368{
6369 MSIPACKAGE *package = param;
6370 LPWSTR translator, translator_path, ptr;
6371 WCHAR outpath[MAX_PATH];
6372 MSIFILE *translator_file = NULL, *setup_file = NULL;
6373 MSICOMPONENT *comp;
6374 MSIRECORD *uirow;
6375 LPCWSTR desc, file_key, component;
6376 DWORD len, usage;
6378
6379 component = MSI_RecordGetString( rec, 2 );
6380 comp = msi_get_loaded_component( package, component );
6381 if (!comp)
6382 return ERROR_SUCCESS;
6383
6384 comp->Action = msi_get_component_action( package, comp );
6385 if (comp->Action != INSTALLSTATE_LOCAL)
6386 {
6387 TRACE("component not scheduled for installation %s\n", debugstr_w(component));
6388 return ERROR_SUCCESS;
6389 }
6390 desc = MSI_RecordGetString(rec, 3);
6391
6392 file_key = MSI_RecordGetString( rec, 4 );
6393 if (file_key) translator_file = msi_get_loaded_file( package, file_key );
6394
6395 file_key = MSI_RecordGetString( rec, 5 );
6396 if (file_key) setup_file = msi_get_loaded_file( package, file_key );
6397
6398 if (!translator_file)
6399 {
6400 ERR("ODBC Translator entry not found!\n");
6401 return ERROR_FUNCTION_FAILED;
6402 }
6403
6404 len = lstrlenW(desc) + lstrlenW(L"Translator=%s") + lstrlenW(translator_file->FileName) + 2; /* \0\0 */
6405 if (setup_file)
6406 len += lstrlenW(L"Setup=%s") + lstrlenW(setup_file->FileName);
6407
6408 translator = malloc(len * sizeof(WCHAR));
6409 if (!translator)
6410 return ERROR_OUTOFMEMORY;
6411
6412 ptr = translator;
6413 lstrcpyW(ptr, desc);
6414 ptr += lstrlenW(ptr) + 1;
6415
6416 len = swprintf(ptr, len - (ptr - translator), L"Translator=%s", translator_file->FileName);
6417 ptr += len + 1;
6418
6419 if (setup_file)
6420 {
6421 len = swprintf(ptr, len - (ptr - translator), L"Setup=%s", setup_file->FileName);
6422 ptr += len + 1;
6423 }
6424 *ptr = '\0';
6425
6426 translator_path = wcsdup(translator_file->TargetPath);
6427 ptr = wcsrchr(translator_path, '\\');
6428 if (ptr) *ptr = '\0';
6429
6430 if (!SQLInstallTranslatorExW(translator, translator_path, outpath, MAX_PATH,
6432 {
6433 ERR("Failed to install SQL translator!\n");
6435 }
6436
6437 uirow = MSI_CreateRecord( 5 );
6438 MSI_RecordSetStringW( uirow, 1, desc );
6439 MSI_RecordSetStringW( uirow, 2, MSI_RecordGetString(rec, 2) );
6440 MSI_RecordSetStringW( uirow, 3, translator_file->Component->Directory );
6442 msiobj_release( &uirow->hdr );
6443
6444 free(translator);
6445 free(translator_path);
6446
6447 return r;
6448}
6449
6451{
6452 MSIPACKAGE *package = param;
6453 MSICOMPONENT *comp;
6454 LPWSTR attrs;
6455 LPCWSTR desc, driver, component;
6457 INT registration;
6458 DWORD len;
6460 MSIRECORD *uirow;
6461
6462 component = MSI_RecordGetString( rec, 2 );
6463 comp = msi_get_loaded_component( package, component );
6464 if (!comp)
6465 return ERROR_SUCCESS;
6466
6467 comp->Action = msi_get_component_action( package, comp );
6468 if (comp->Action != INSTALLSTATE_LOCAL)
6469 {
6470 TRACE("component not scheduled for installation %s\n", debugstr_w(component));
6471 return ERROR_SUCCESS;
6472 }
6473
6474 desc = MSI_RecordGetString(rec, 3);
6475 driver = MSI_RecordGetString(rec, 4);
6476 registration = MSI_RecordGetInteger(rec, 5);
6477
6480
6481 len = lstrlenW(L"DSN=%s") + lstrlenW(desc) + 2; /* \0\0 */
6482 attrs = malloc(len * sizeof(WCHAR));
6483 if (!attrs)
6484 return ERROR_OUTOFMEMORY;
6485
6486 len = swprintf(attrs, len, L"DSN=%s", desc);
6487 attrs[len + 1] = 0;
6488
6489 if (!SQLConfigDataSourceW(NULL, request, driver, attrs))
6490 WARN("Failed to install SQL data source!\n");
6491
6492 uirow = MSI_CreateRecord( 5 );
6493 MSI_RecordSetStringW( uirow, 1, desc );
6494 MSI_RecordSetStringW( uirow, 2, MSI_RecordGetString(rec, 2) );
6495 MSI_RecordSetInteger( uirow, 3, request );
6497 msiobj_release( &uirow->hdr );
6498
6499 free(attrs);
6500
6501 return r;
6502}
6503
6505{
6506 MSIQUERY *view;
6507 UINT rc;
6508
6509 if (package->script == SCRIPT_NONE)
6510 return msi_schedule_action(package, SCRIPT_INSTALL, L"InstallODBC");
6511
6512 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `ODBCDriver`", &view);
6513 if (rc == ERROR_SUCCESS)
6514 {
6516 msiobj_release(&view->hdr);
6517 if (rc != ERROR_SUCCESS)
6518 return rc;
6519 }
6520 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `ODBCTranslator`", &view);
6521 if (rc == ERROR_SUCCESS)
6522 {
6524 msiobj_release(&view->hdr);
6525 if (rc != ERROR_SUCCESS)
6526 return rc;
6527 }
6528 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `ODBCDataSource`", &view);
6529 if (rc == ERROR_SUCCESS)
6530 {
6532 msiobj_release(&view->hdr);
6533 if (rc != ERROR_SUCCESS)
6534 return rc;
6535 }
6536 return ERROR_SUCCESS;
6537}
6538
6540{
6541 MSIPACKAGE *package = param;
6542 MSICOMPONENT *comp;
6543 MSIRECORD *uirow;
6544 DWORD usage;
6545 LPCWSTR desc, component;
6546
6547 component = MSI_RecordGetString( rec, 2 );
6548 comp = msi_get_loaded_component( package, component );
6549 if (!comp)
6550 return ERROR_SUCCESS;
6551
6552 comp->Action = msi_get_component_action( package, comp );
6553 if (comp->Action != INSTALLSTATE_ABSENT)
6554 {
6555 TRACE("component not scheduled for removal %s\n", debugstr_w(component));
6556 return ERROR_SUCCESS;
6557 }
6558
6559 desc = MSI_RecordGetString( rec, 3 );
6560 if (!SQLRemoveDriverW( desc, FALSE, &usage ))
6561 {
6562 WARN("Failed to remove ODBC driver\n");
6563 }
6564 else if (!usage)
6565 {
6566 FIXME("Usage count reached 0\n");
6567 }
6568
6569 uirow = MSI_CreateRecord( 2 );
6570 MSI_RecordSetStringW( uirow, 1, desc );
6571 MSI_RecordSetStringW( uirow, 2, MSI_RecordGetString(rec, 2) );
6573 msiobj_release( &uirow->hdr );
6574
6575 return ERROR_SUCCESS;
6576}
6577
6579{
6580 MSIPACKAGE *package = param;
6581 MSICOMPONENT *comp;
6582 MSIRECORD *uirow;
6583 DWORD usage;
6584 LPCWSTR desc, component;
6585
6586 component = MSI_RecordGetString( rec, 2 );
6587 comp = msi_get_loaded_component( package, component );
6588 if (!comp)
6589 return ERROR_SUCCESS;
6590
6591 comp->Action = msi_get_component_action( package, comp );
6592 if (comp->Action != INSTALLSTATE_ABSENT)
6593 {
6594 TRACE("component not scheduled for removal %s\n", debugstr_w(component));
6595 return ERROR_SUCCESS;
6596 }
6597
6598 desc = MSI_RecordGetString( rec, 3 );
6600 {
6601 WARN("Failed to remove ODBC translator\n");
6602 }
6603 else if (!usage)
6604 {
6605 FIXME("Usage count reached 0\n");
6606 }
6607
6608 uirow = MSI_CreateRecord( 2 );
6609 MSI_RecordSetStringW( uirow, 1, desc );
6610 MSI_RecordSetStringW( uirow, 2, MSI_RecordGetString(rec, 2) );
6612 msiobj_release( &uirow->hdr );
6613
6614 return ERROR_SUCCESS;
6615}
6616
6618{
6619 MSIPACKAGE *package = param;
6620 MSICOMPONENT *comp;
6621 MSIRECORD *uirow;
6622 LPWSTR attrs;
6623 LPCWSTR desc, driver, component;
6625 INT registration;
6626 DWORD len;
6627
6628 component = MSI_RecordGetString( rec, 2 );
6629 comp = msi_get_loaded_component( package, component );
6630 if (!comp)
6631 return ERROR_SUCCESS;
6632
6633 comp->Action = msi_get_component_action( package, comp );
6634 if (comp->Action != INSTALLSTATE_ABSENT)
6635 {
6636 TRACE("component not scheduled for removal %s\n", debugstr_w(component));
6637 return ERROR_SUCCESS;
6638 }
6639
6640 desc = MSI_RecordGetString( rec, 3 );
6641 driver = MSI_RecordGetString( rec, 4 );
6642 registration = MSI_RecordGetInteger( rec, 5 );
6643
6646
6647 len = lstrlenW( L"DSN=%s" ) + lstrlenW( desc ) + 2; /* \0\0 */
6648 attrs = malloc( len * sizeof(WCHAR) );
6649 if (!attrs)
6650 return ERROR_OUTOFMEMORY;
6651
6652 FIXME("Use ODBCSourceAttribute table\n");
6653
6654 len = swprintf( attrs, len, L"DSN=%s", desc );
6655 attrs[len + 1] = 0;
6656
6657 if (!SQLConfigDataSourceW( NULL, request, driver, attrs ))
6658 {
6659 WARN("Failed to remove ODBC data source\n");
6660 }
6661 free( attrs );
6662
6663 uirow = MSI_CreateRecord( 3 );
6664 MSI_RecordSetStringW( uirow, 1, desc );
6665 MSI_RecordSetStringW( uirow, 2, MSI_RecordGetString(rec, 2) );
6666 MSI_RecordSetInteger( uirow, 3, request );
6668 msiobj_release( &uirow->hdr );
6669
6670 return ERROR_SUCCESS;
6671}
6672
6674{
6675 MSIQUERY *view;
6676 UINT rc;
6677
6678 if (package->script == SCRIPT_NONE)
6679 return msi_schedule_action(package, SCRIPT_INSTALL, L"RemoveODBC");
6680
6681 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `ODBCDriver`", &view );
6682 if (rc == ERROR_SUCCESS)
6683 {
6685 msiobj_release( &view->hdr );
6686 if (rc != ERROR_SUCCESS)
6687 return rc;
6688 }
6689 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `ODBCTranslator`", &view );
6690 if (rc == ERROR_SUCCESS)
6691 {
6693 msiobj_release( &view->hdr );
6694 if (rc != ERROR_SUCCESS)
6695 return rc;
6696 }
6697 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `ODBCDataSource`", &view );
6698 if (rc == ERROR_SUCCESS)
6699 {
6701 msiobj_release( &view->hdr );
6702 if (rc != ERROR_SUCCESS)
6703 return rc;
6704 }
6705 return ERROR_SUCCESS;
6706}
6707
6708#define ENV_ACT_SETALWAYS 0x1
6709#define ENV_ACT_SETABSENT 0x2
6710#define ENV_ACT_REMOVE 0x4
6711#define ENV_ACT_REMOVEMATCH 0x8
6712
6713#define ENV_MOD_MACHINE 0x20000000
6714#define ENV_MOD_APPEND 0x40000000
6715#define ENV_MOD_PREFIX 0x80000000
6716#define ENV_MOD_MASK 0xC0000000
6717
6718#define check_flag_combo(x, y) ((x) & ~(y)) == (y)
6719
6721{
6722 const WCHAR *cptr = *name;
6723
6724 *flags = 0;
6725 while (*cptr)
6726 {
6727 if (*cptr == '=')
6729 else if (*cptr == '+')
6731 else if (*cptr == '-')
6733 else if (*cptr == '!')
6735 else if (*cptr == '*')
6737 else
6738 break;
6739
6740 cptr++;
6741 (*name)++;
6742 }
6743
6744 if (!*cptr)
6745 {
6746 ERR("Missing environment variable\n");
6747 return ERROR_FUNCTION_FAILED;
6748 }
6749
6750 if (*value)
6751 {
6752 LPCWSTR ptr = *value;
6753 if (!wcsncmp(ptr, L"[~]", 3))
6754 {
6755 if (ptr[3] == ';')
6756 {
6758 *value += 3;
6759 }
6760 else
6761 {
6762 *value = NULL;
6763 }
6764 }
6765 else if (lstrlenW(*value) >= 3)
6766 {
6767 ptr += lstrlenW(ptr) - 3;
6768 if (!wcscmp( ptr, L"[~]" ))
6769 {
6770 if ((ptr-1) > *value && *(ptr-1) == ';')
6771 {
6773 /* the "[~]" will be removed by deformat_string */;
6774 }
6775 else
6776 {
6777 *value = NULL;
6778 }
6779 }
6780 }
6781 }
6782
6787 {
6788 ERR( "invalid flags: %#lx\n", *flags );
6789 return ERROR_FUNCTION_FAILED;
6790 }
6791
6792 if (!*flags)
6794
6795 return ERROR_SUCCESS;
6796}
6797
6799{
6800 const WCHAR *env;
6801 HKEY root;
6802 LONG res;
6803
6804 if (flags & ENV_MOD_MACHINE)
6805 {
6806 env = L"System\\CurrentControlSet\\Control\\Session Manager\\Environment";
6808 }
6809 else
6810 {
6811 env = L"Environment";
6813 }
6814
6816 if (res != ERROR_SUCCESS)
6817 {
6818 WARN( "failed to open key %s (%ld)\n", debugstr_w(env), res );
6819 return ERROR_FUNCTION_FAILED;
6820 }
6821
6822 return ERROR_SUCCESS;
6823}
6824
6826{
6827 MSIPACKAGE *package = param;
6828 LPCWSTR name, value, component;
6829 WCHAR *data = NULL, *newval = NULL, *deformatted = NULL, *p, *q;
6830 DWORD flags, type, size, len, len_value = 0;
6831 UINT res;
6832 HKEY env = NULL;
6833 MSICOMPONENT *comp;
6834 MSIRECORD *uirow;
6835 int action = 0, found = 0;
6836
6837 component = MSI_RecordGetString(rec, 4);
6838 comp = msi_get_loaded_component(package, component);
6839 if (!comp)
6840 return ERROR_SUCCESS;
6841
6842 comp->Action = msi_get_component_action( package, comp );
6843 if (comp->Action != INSTALLSTATE_LOCAL)
6844 {
6845 TRACE("component not scheduled for installation %s\n", debugstr_w(component));
6846 return ERROR_SUCCESS;
6847 }
6848 name = MSI_RecordGetString(rec, 2);
6849 value = MSI_RecordGetString(rec, 3);
6850
6851 TRACE("name %s value %s\n", debugstr_w(name), debugstr_w(value));
6852
6854 if (res != ERROR_SUCCESS || !value)
6855 goto done;
6856
6857 if (value)
6858 {
6859 DWORD len = deformat_string( package, value, &deformatted );
6860 if (!deformatted)
6861 {
6863 goto done;
6864 }
6865
6866 if (len)
6867 {
6868 value = deformatted;
6869 if (flags & ENV_MOD_PREFIX)
6870 {
6871 p = wcsrchr( value, ';' );
6872 len_value = p - value;
6873 }
6874 else if (flags & ENV_MOD_APPEND)
6875 {
6876 value = wcschr( value, ';' ) + 1;
6877 len_value = lstrlenW( value );
6878 }
6879 else len_value = lstrlenW( value );
6880 }
6881 else
6882 {
6883 value = NULL;
6884 }
6885 }
6886
6887 res = open_env_key( flags, &env );
6888 if (res != ERROR_SUCCESS)
6889 goto done;
6890
6891 if (flags & ENV_MOD_MACHINE)
6892 action |= 0x20000000;
6893
6894 size = 0;
6895 type = REG_SZ;
6897 if ((res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND) ||
6898 (res == ERROR_SUCCESS && type != REG_SZ && type != REG_EXPAND_SZ))
6899 goto done;
6900
6901 if ((res == ERROR_FILE_NOT_FOUND || !(flags & ENV_MOD_MASK)))
6902 {
6903 action = 0x2;
6904
6905 /* Nothing to do. */
6906 if (!value)
6907 {
6909 goto done;
6910 }
6911 size = (lstrlenW(value) + 1) * sizeof(WCHAR);
6912 newval = wcsdup(value);
6913 if (!newval)
6914 {
6916 goto done;
6917 }
6918 }
6919 else
6920 {
6921 action = 0x1;
6922
6923 /* Contrary to MSDN, +-variable to [~];path works */
6925 {
6927 goto done;
6928 }
6929
6930 if (!(p = q = data = malloc( size )))
6931 {
6932 free(deformatted);
6934 return ERROR_OUTOFMEMORY;
6935 }
6936
6938 if (res != ERROR_SUCCESS)
6939 goto done;
6940
6941 if (flags & ENV_ACT_REMOVEMATCH && (!value || !wcscmp( data, value )))
6942 {
6943 action = 0x4;
6945 if (res != ERROR_SUCCESS)
6946 WARN("Failed to remove value %s (%d)\n", debugstr_w(name), res);
6947 goto done;
6948 }
6949
6950 for (;;)
6951 {
6952 while (*q && *q != ';') q++;
6953 len = q - p;
6954 if (value && len == len_value && !memcmp( value, p, len * sizeof(WCHAR) ) &&
6955 (!p[len] || p[len] == ';'))
6956 {
6957 found = 1;
6958 break;
6959 }
6960 if (!*q) break;
6961 p = ++q;
6962 }
6963
6964 if (found)
6965 {
6966 TRACE("string already set\n");
6967 goto done;
6968 }
6969
6970 size = (len_value + 1 + lstrlenW( data ) + 1) * sizeof(WCHAR);
6971 if (!(p = newval = malloc( size )))
6972 {
6974 goto done;
6975 }
6976
6977 if (flags & ENV_MOD_PREFIX)
6978 {
6979 memcpy( newval, value, len_value * sizeof(WCHAR) );
6980 newval[len_value] = ';';
6981 p = newval + len_value + 1;
6982 action |= 0x80000000;
6983 }
6984
6985 lstrcpyW( p, data );
6986
6987 if (flags & ENV_MOD_APPEND)
6988 {
6989 p += lstrlenW( data );
6990 *p++ = ';';
6991 memcpy( p, value, (len_value + 1) * sizeof(WCHAR) );
6992 action |= 0x40000000;
6993 }
6994 }
6995 TRACE("setting %s to %s\n", debugstr_w(name), debugstr_w(newval));
6996 res = RegSetValueExW( env, name, 0, type, (BYTE *)newval, size );
6997 if (res)
6998 {
6999 WARN("Failed to set %s to %s (%d)\n", debugstr_w(name), debugstr_w(newval), res);
7000 }
7001
7002done:
7003 uirow = MSI_CreateRecord( 3 );
7004 MSI_RecordSetStringW( uirow, 1, name );
7005 MSI_RecordSetStringW( uirow, 2, newval );
7006 MSI_RecordSetInteger( uirow, 3, action );
7008 msiobj_release( &uirow->hdr );
7009
7010 if (env) RegCloseKey(env);
7011 free(deformatted);
7012 free(data);
7013 free(newval);
7014 return res;
7015}
7016
7018{
7019 MSIQUERY *view;
7020 UINT rc;
7021
7022 if (package->script == SCRIPT_NONE)
7023 return msi_schedule_action(package, SCRIPT_INSTALL, L"WriteEnvironmentStrings");
7024
7025 rc = MSI_DatabaseOpenViewW(package->db, L"SELECT * FROM `Environment`", &view);
7026 if (rc != ERROR_SUCCESS)
7027 return ERROR_SUCCESS;
7028
7030 msiobj_release(&view->hdr);
7031 return rc;
7032}
7033
7035{
7036 MSIPACKAGE *package = param;
7037 LPCWSTR name, value, component;
7038 WCHAR *p, *q, *deformatted = NULL, *new_value = NULL;
7039 DWORD flags, type, size, len, len_value = 0, len_new_value;
7040 HKEY env = NULL;
7041 MSICOMPONENT *comp;
7042 MSIRECORD *uirow;
7043 int action = 0;
7044 LONG res;
7045 UINT r;
7046
7047 component = MSI_RecordGetString( rec, 4 );
7048 comp = msi_get_loaded_component( package, component );
7049 if (!comp)
7050 return ERROR_SUCCESS;
7051
7052 comp->Action = msi_get_component_action( package, comp );
7053 if (comp->Action != INSTALLSTATE_ABSENT)
7054 {
7055 TRACE("component not scheduled for removal %s\n", debugstr_w(component));
7056 return ERROR_SUCCESS;
7057 }
7058 name = MSI_RecordGetString( rec, 2 );
7059 value = MSI_RecordGetString( rec, 3 );
7060
7061 TRACE("name %s value %s\n", debugstr_w(name), debugstr_w(value));
7062
7063 r = env_parse_flags( &name, &value, &flags );
7064 if (r != ERROR_SUCCESS)
7065 return r;
7066
7067 if (!(flags & ENV_ACT_REMOVE))
7068 {
7069 TRACE("Environment variable %s not marked for removal\n", debugstr_w(name));
7070 return ERROR_SUCCESS;
7071 }
7072
7073 if (value)
7074 {
7075 DWORD len = deformat_string( package, value, &deformatted );
7076 if (!deformatted)
7077 {
7079 goto done;
7080 }
7081
7082 if (len)
7083 {
7084 value = deformatted;
7085 if (flags & ENV_MOD_PREFIX)
7086 {
7087 p = wcsrchr( value, ';' );
7088 len_value = p - value;
7089 }
7090 else if (flags & ENV_MOD_APPEND)
7091 {
7092 value = wcschr( value, ';' ) + 1;
7093 len_value = lstrlenW( value );
7094 }
7095 else len_value = lstrlenW( value );
7096 }
7097 else
7098 {
7099 value = NULL;
7100 }
7101 }
7102
7103 r = open_env_key( flags, &env );
7104 if (r != ERROR_SUCCESS)
7105 {
7106 r = ERROR_SUCCESS;
7107 goto done;
7108 }
7109
7110 if (flags & ENV_MOD_MACHINE)
7111 action |= 0x20000000;
7112
7113 size = 0;
7114 type = REG_SZ;
7116 if (res != ERROR_SUCCESS || (type != REG_SZ && type != REG_EXPAND_SZ))
7117 goto done;
7118
7119 if (!(new_value = malloc( size ))) goto done;
7120
7121 res = RegQueryValueExW( env, name, NULL, &type, (BYTE *)new_value, &size );
7122 if (res != ERROR_SUCCESS)
7123 goto done;
7124
7125 len_new_value = size / sizeof(WCHAR) - 1;
7126 p = q = new_value;
7127 for (;;)
7128 {
7129 while (*q && *q != ';') q++;
7130 len = q - p;
7131 if (value && len == len_value && !memcmp( value, p, len * sizeof(WCHAR) ))
7132 {
7133 if (*q == ';') q++;
7134 memmove( p, q, (len_new_value - (q - new_value) + 1) * sizeof(WCHAR) );
7135 break;
7136 }
7137 if (!*q) break;
7138 p = ++q;
7139 }
7140
7141 if (!new_value[0] || !value)
7142 {
7143 TRACE("removing %s\n", debugstr_w(name));
7145 if (res != ERROR_SUCCESS)
7146 WARN( "failed to delete value %s (%ld)\n", debugstr_w(name), res );
7147 }
7148 else
7149 {
7150 TRACE("setting %s to %s\n", debugstr_w(name), debugstr_w(new_value));
7151 size = (lstrlenW( new_value ) + 1) * sizeof(WCHAR);
7152 res = RegSetValueExW( env, name, 0, type, (BYTE *)new_value, size );
7153 if (res != ERROR_SUCCESS)
7154 WARN( "failed to set %s to %s (%ld)\n", debugstr_w(name), debugstr_w(new_value), res );
7155 }
7156
7157done:
7158 uirow = MSI_CreateRecord( 3 );
7159 MSI_RecordSetStringW( uirow, 1, name );
7160 MSI_RecordSetStringW( uirow, 2, value );
7161 MSI_RecordSetInteger( uirow, 3, action );
7163 msiobj_release( &uirow->hdr );
7164
7165 if (env) RegCloseKey( env );
7166 free( deformatted );
7167 free( new_value );
7168 return r;
7169}
7170
7172{
7173 MSIQUERY *view;
7174 UINT rc;
7175
7176 if (package->script == SCRIPT_NONE)
7177 return msi_schedule_action(package, SCRIPT_INSTALL, L"RemoveEnvironmentStrings");
7178
7179 rc = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Environment`", &view );
7180 if (rc != ERROR_SUCCESS)
7181 return ERROR_SUCCESS;
7182
7184 msiobj_release( &view->hdr );
7185 return rc;
7186}
7187
7189{
7190 LPWSTR key, template, id;
7192
7193 id = msi_dup_property( package->db, L"ProductID" );
7194 if (id)
7195 {
7196 free( id );
7197 return ERROR_SUCCESS;
7198 }
7199 template = msi_dup_property( package->db, L"PIDTemplate" );
7200 key = msi_dup_property( package->db, L"PIDKEY" );
7201 if (key && template)
7202 {
7203 FIXME( "partial stub: template %s key %s\n", debugstr_w(template), debugstr_w(key) );
7204#ifdef __REACTOS__
7205 WARN("Product key validation HACK, see CORE-14710\n");
7206#else
7207 r = msi_set_property( package->db, L"ProductID", key, -1 );
7208#endif
7209 }
7210 free( template );
7211 free( key );
7212 return r;
7213}
7214
7216{
7217 return msi_validate_product_id( package );
7218}
7219
7221{
7222 TRACE("\n");
7223 package->need_reboot_at_end = 1;
7224 return ERROR_SUCCESS;
7225}
7226
7228{
7229 MSIRECORD *uirow;
7230 int space = msi_get_property_int( package->db, L"AVAILABLEFREEREG", 0 );
7231
7232 TRACE("%p %d kilobytes\n", package, space);
7233
7234 uirow = MSI_CreateRecord( 1 );
7235 MSI_RecordSetInteger( uirow, 1, space );
7237 msiobj_release( &uirow->hdr );
7238
7239 return ERROR_SUCCESS;
7240}
7241
7243{
7244 TRACE("%p\n", package);
7245
7246 msi_set_property( package->db, L"RollbackDisabled", L"1", -1 );
7247 return ERROR_SUCCESS;
7248}
7249
7251{
7252 FIXME("%p\n", package);
7253 return ERROR_SUCCESS;
7254}
7255
7257{
7258 MSIQUERY *view;
7259 UINT r;
7260 DWORD count;
7261
7262 r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `ODBCDriver`", &view );
7263 if (r == ERROR_SUCCESS)
7264 {
7265 count = 0;
7266 r = MSI_IterateRecords( view, &count, NULL, package );
7267 msiobj_release( &view->hdr );
7268 if (r != ERROR_SUCCESS)
7269 return r;
7270 if (count) FIXME( "ignored %lu rows in ODBCDriver table\n", count );
7271 }
7272 r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `ODBCTranslator`", &view );
7273 if (r == ERROR_SUCCESS)
7274 {
7275 count = 0;
7276 r = MSI_IterateRecords( view, &count, NULL, package );
7277 msiobj_release( &view->hdr );
7278 if (r != ERROR_SUCCESS)
7279 return r;
7280 if (count) FIXME( "ignored %lu rows in ODBCTranslator table\n", count );
7281 }
7282 return ERROR_SUCCESS;
7283}
7284
7286{
7287 MSIPACKAGE *package = param;
7288 const WCHAR *property = MSI_RecordGetString( rec, 7 );
7289 int attrs = MSI_RecordGetInteger( rec, 5 );
7290 UINT len = ARRAY_SIZE( L"msiexec /qn /i %s REMOVE=%s" );
7291 WCHAR *product, *features, *cmd;
7292 STARTUPINFOW si;
7294 BOOL ret;
7295
7297 if (!(product = msi_dup_property( package->db, property ))) return ERROR_SUCCESS;
7298
7299 deformat_string( package, MSI_RecordGetString( rec, 6 ), &features );
7300
7301 len += lstrlenW( product );
7302 if (features)
7303 len += lstrlenW( features );
7304 else
7305 len += ARRAY_SIZE( L"ALL" );
7306
7307 if (!(cmd = malloc( len * sizeof(WCHAR) )))
7308 {
7309 free( product );
7310 free( features );
7311 return ERROR_OUTOFMEMORY;
7312 }
7313 swprintf( cmd, len, L"msiexec /qn /i %s REMOVE=%s", product, features ? features : L"ALL" );
7314 free( product );
7315 free( features );
7316
7317 memset( &si, 0, sizeof(STARTUPINFOW) );
7318 ret = CreateProcessW( NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &info );
7319 free( cmd );
7320 if (!ret) return GetLastError();
7321 CloseHandle( info.hThread );
7322
7323 WaitForSingleObject( info.hProcess, INFINITE );
7324 CloseHandle( info.hProcess );
7325 return ERROR_SUCCESS;
7326}
7327
7329{
7330 MSIQUERY *view;
7331 UINT r;
7332
7333 r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Upgrade`", &view );
7334 if (r == ERROR_SUCCESS)
7335 {
7337 msiobj_release( &view->hdr );
7338 if (r != ERROR_SUCCESS)
7339 return r;
7340 }
7341 return ERROR_SUCCESS;
7342}
7343
7345{
7346 MSIPACKAGE *package = param;
7347 int attributes = MSI_RecordGetInteger( rec, 5 );
7348
7350 {
7351 const WCHAR *upgrade_code = MSI_RecordGetString( rec, 1 );
7352 const WCHAR *version_min = MSI_RecordGetString( rec, 2 );
7353 const WCHAR *version_max = MSI_RecordGetString( rec, 3 );
7354 const WCHAR *language = MSI_RecordGetString( rec, 4 );
7355 HKEY hkey;
7356 UINT r;
7357
7358 if (package->Context == MSIINSTALLCONTEXT_MACHINE)
7359 {
7360 r = MSIREG_OpenClassesUpgradeCodesKey( upgrade_code, &hkey, FALSE );
7361 if (r != ERROR_SUCCESS)
7362 return ERROR_SUCCESS;
7363 }
7364 else
7365 {
7366 r = MSIREG_OpenUserUpgradeCodesKey( upgrade_code, &hkey, FALSE );
7367 if (r != ERROR_SUCCESS)
7368 return ERROR_SUCCESS;
7369 }
7370 RegCloseKey( hkey );
7371
7372 FIXME("migrate feature states from %s version min %s version max %s language %s\n",
7373 debugstr_w(upgrade_code), debugstr_w(version_min),
7374 debugstr_w(version_max), debugstr_w(language));
7375 }
7376 return ERROR_SUCCESS;
7377}
7378
7380{
7381 MSIQUERY *view;
7382 UINT r;
7383
7384 if (msi_get_property_int( package->db, L"Installed", 0 ))
7385 {
7386 TRACE("product is installed, skipping action\n");
7387 return ERROR_SUCCESS;
7388 }
7389 if (msi_get_property_int( package->db, L"Preselected", 0 ))
7390 {
7391 TRACE("Preselected property is set, not migrating feature states\n");
7392 return ERROR_SUCCESS;
7393 }
7394 r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `Upgrade`", &view );
7395 if (r == ERROR_SUCCESS)
7396 {
7398 msiobj_release( &view->hdr );
7399 if (r != ERROR_SUCCESS)
7400 return r;
7401 }
7402 return ERROR_SUCCESS;
7403}
7404
7405static void bind_image( MSIPACKAGE *package, const char *filename, const char *path )
7406{
7407 msi_disable_fs_redirection( package );
7408 if (!BindImage( filename, path, NULL )) WARN( "failed to bind image %lu\n", GetLastError() );
7409 msi_revert_fs_redirection( package );
7410}
7411
7413{
7414 UINT i;
7415 MSIFILE *file;
7416 MSIPACKAGE *package = param;
7417 const WCHAR *key = MSI_RecordGetString( rec, 1 );
7418 const WCHAR *paths = MSI_RecordGetString( rec, 2 );
7419 char *filenameA, *pathA;
7420 WCHAR *pathW, **path_list;
7421
7422 if (!(file = msi_get_loaded_file( package, key )))
7423 {
7424 WARN("file %s not found\n", debugstr_w(key));
7425 return ERROR_SUCCESS;
7426 }
7427 if (!(filenameA = strdupWtoA( file->TargetPath ))) return ERROR_SUCCESS;
7428
7429 path_list = msi_split_string( paths, ';' );
7430 if (!path_list) bind_image( package, filenameA, NULL );
7431 else
7432 {
7433 for (i = 0; path_list[i] && path_list[i][0]; i++)
7434 {
7435 deformat_string( package, path_list[i], &pathW );
7436 if ((pathA = strdupWtoA( pathW )))
7437 {
7438 bind_image( package, filenameA, pathA );
7439 free( pathA );
7440 }
7441 free( pathW );
7442 }
7443 }
7444 free( path_list );
7445 free( filenameA );
7446
7447 return ERROR_SUCCESS;
7448}
7449
7451{
7452 MSIQUERY *view;
7453 UINT r;
7454
7455 r = MSI_DatabaseOpenViewW( package->db, L"SELECT * FROM `BindImage`", &view );
7456 if (r == ERROR_SUCCESS)
7457 {
7459 msiobj_release( &view->hdr );
7460 }
7461 return ERROR_SUCCESS;
7462}
7463
7465{
7466 MSIQUERY *view;
7467 DWORD count = 0;
7468 UINT r;
7469
7470 r = MSI_OpenQuery( package->db, &view, L"SELECT * FROM `%s`", table );
7471 if (r == ERROR_SUCCESS)
7472 {
7473 r = MSI_IterateRecords(view, &count, NULL, package);
7474 msiobj_release(&view->hdr);
7475 if (r != ERROR_SUCCESS)
7476 return r;
7477 }
7478 if (count) FIXME( "%s: ignored %lu rows from %s\n", action, count, debugstr_w(table) );
7479 return ERROR_SUCCESS;
7480}
7481
7483{
7484 return unimplemented_action_stub( package, "IsolateComponents", L"IsolateComponent" );
7485}
7486
7488{
7489 return unimplemented_action_stub( package, "RMCCPSearch", L"CCPSearch" );
7490}
7491
7493{
7494 return unimplemented_action_stub( package, "RegisterComPlus", L"Complus" );
7495}
7496
7498{
7499 return unimplemented_action_stub( package, "UnregisterComPlus", L"Complus" );
7500}
7501
7503{
7504 return unimplemented_action_stub( package, "InstallSFPCatalogFile", L"SFPCatalog" );
7505}
7506
7507static const struct
7508{
7511 const UINT template;
7514}
7516{
7520 { L"CCPSearch", IDS_DESC_CCPSEARCH, 0, ACTION_CCPSearch, NULL },
7521 { L"CostFinalize", IDS_DESC_COSTFINALIZE, 0, ACTION_CostFinalize, NULL },
7522 { L"CostInitialize", IDS_DESC_COSTINITIALIZE, 0, ACTION_CostInitialize, NULL },
7523 { L"CreateFolders", IDS_DESC_CREATEFOLDERS, IDS_TEMP_CREATEFOLDERS, ACTION_CreateFolders, L"RemoveFolders" },
7524 { L"CreateShortcuts", IDS_DESC_CREATESHORTCUTS, IDS_TEMP_CREATESHORTCUTS, ACTION_CreateShortcuts, L"RemoveShortcuts" },
7525 { L"DeleteServices", IDS_DESC_DELETESERVICES, IDS_TEMP_DELETESERVICES, ACTION_DeleteServices, L"InstallServices" },
7526 { L"DisableRollback", 0, 0, ACTION_DisableRollback, NULL },
7527 { L"DuplicateFiles", IDS_DESC_DUPLICATEFILES, IDS_TEMP_DUPLICATEFILES, ACTION_DuplicateFiles, L"RemoveDuplicateFiles" },
7528 { L"ExecuteAction", 0, 0, ACTION_ExecuteAction, NULL },
7529 { L"FileCost", IDS_DESC_FILECOST, 0, ACTION_FileCost, NULL },
7531 { L"ForceReboot", 0, 0, ACTION_ForceReboot, NULL },
7533 { L"InstallExecute", 0, 0, ACTION_InstallExecute, NULL },
7534 { L"InstallExecuteAgain", 0, 0, ACTION_InstallExecute, NULL },
7535 { L"InstallFiles", IDS_DESC_INSTALLFILES, IDS_TEMP_INSTALLFILES, ACTION_InstallFiles, L"RemoveFiles" },
7536 { L"InstallFinalize", 0, 0, ACTION_InstallFinalize, NULL },
7537 { L"InstallInitialize", 0, 0, ACTION_InstallInitialize, NULL },
7538 { L"InstallODBC", IDS_DESC_INSTALLODBC, 0, ACTION_InstallODBC, L"RemoveODBC" },
7539 { L"InstallServices", IDS_DESC_INSTALLSERVICES, IDS_TEMP_INSTALLSERVICES, ACTION_InstallServices, L"DeleteServices" },
7541 { L"InstallValidate", IDS_DESC_INSTALLVALIDATE, 0, ACTION_InstallValidate, NULL },
7542 { L"IsolateComponents", 0, 0, ACTION_IsolateComponents, NULL },
7543 { L"LaunchConditions", IDS_DESC_LAUNCHCONDITIONS, 0, ACTION_LaunchConditions, NULL },
7546 { L"MsiPublishAssemblies", IDS_DESC_MSIPUBLISHASSEMBLIES, IDS_TEMP_MSIPUBLISHASSEMBLIES, ACTION_MsiPublishAssemblies, L"MsiUnpublishAssemblies" },
7547 { L"MsiUnpublishAssemblies", IDS_DESC_MSIUNPUBLISHASSEMBLIES, IDS_TEMP_MSIUNPUBLISHASSEMBLIES, ACTION_MsiUnpublishAssemblies, L"MsiPublishAssemblies" },
7549 { L"ProcessComponents", IDS_DESC_PROCESSCOMPONENTS, 0, ACTION_ProcessComponents, L"ProcessComponents" },
7550 { L"PublishComponents", IDS_DESC_PUBLISHCOMPONENTS, IDS_TEMP_PUBLISHCOMPONENTS, ACTION_PublishComponents, L"UnpublishComponents" },
7551 { L"PublishFeatures", IDS_DESC_PUBLISHFEATURES, IDS_TEMP_PUBLISHFEATURES, ACTION_PublishFeatures, L"UnpublishFeatures" },
7552 { L"PublishProduct", IDS_DESC_PUBLISHPRODUCT, 0, ACTION_PublishProduct, L"UnpublishProduct" },
7553 { L"RegisterClassInfo", IDS_DESC_REGISTERCLASSINFO, IDS_TEMP_REGISTERCLASSINFO, ACTION_RegisterClassInfo, L"UnregisterClassInfo" },
7554 { L"RegisterComPlus", IDS_DESC_REGISTERCOMPLUS, IDS_TEMP_REGISTERCOMPLUS, ACTION_RegisterComPlus, L"UnregisterComPlus" },
7555 { L"RegisterExtensionInfo", IDS_DESC_REGISTEREXTENSIONINFO, 0, ACTION_RegisterExtensionInfo, L"UnregisterExtensionInfo" },
7556 { L"RegisterFonts", IDS_DESC_REGISTERFONTS, IDS_TEMP_REGISTERFONTS, ACTION_RegisterFonts, L"UnregisterFonts" },
7557 { L"RegisterMIMEInfo", IDS_DESC_REGISTERMIMEINFO, IDS_TEMP_REGISTERMIMEINFO, ACTION_RegisterMIMEInfo, L"UnregisterMIMEInfo" },
7558 { L"RegisterProduct", IDS_DESC_REGISTERPRODUCT, 0, ACTION_RegisterProduct, NULL },
7559 { L"RegisterProgIdInfo", IDS_DESC_REGISTERPROGIDINFO, IDS_TEMP_REGISTERPROGIDINFO, ACTION_RegisterProgIdInfo, L"UnregisterProgIdInfo" },
7560 { L"RegisterTypeLibraries", IDS_DESC_REGISTERTYPELIBRARIES, IDS_TEMP_REGISTERTYPELIBRARIES, ACTION_RegisterTypeLibraries, L"UnregisterTypeLibraries" },
7561 { L"RegisterUser", IDS_DESC_REGISTERUSER, 0, ACTION_RegisterUser, NULL },
7563 { L"RemoveEnvironmentStrings", IDS_DESC_REMOVEENVIRONMENTSTRINGS, IDS_TEMP_REMOVEENVIRONMENTSTRINGS, ACTION_RemoveEnvironmentStrings, L"WriteEnvironmentStrings" },
7565 { L"RemoveFiles", IDS_DESC_REMOVEFILES, IDS_TEMP_REMOVEFILES, ACTION_RemoveFiles, L"InstallFiles" },
7566 { L"RemoveFolders", IDS_DESC_REMOVEFOLDERS, IDS_TEMP_REMOVEFOLDERS, ACTION_RemoveFolders, L"CreateFolders" },
7567 { L"RemoveIniValues", IDS_DESC_REMOVEINIVALUES, IDS_TEMP_REMOVEINIVALUES, ACTION_RemoveIniValues, L"WriteIniValues" },
7568 { L"RemoveODBC", IDS_DESC_REMOVEODBC, 0, ACTION_RemoveODBC, L"InstallODBC" },
7569 { L"RemoveRegistryValues", IDS_DESC_REMOVEREGISTRYVALUES, IDS_TEMP_REMOVEREGISTRYVALUES, ACTION_RemoveRegistryValues, L"WriteRegistryValues" },
7570 { L"RemoveShortcuts", IDS_DESC_REMOVESHORTCUTS, IDS_TEMP_REMOVESHORTCUTS, ACTION_RemoveShortcuts, L"CreateShortcuts" },
7571 { L"ResolveSource", 0, 0, ACTION_ResolveSource, NULL },
7572 { L"RMCCPSearch", IDS_DESC_RMCCPSEARCH, 0, ACTION_RMCCPSearch, NULL },
7573 { L"ScheduleReboot", 0, 0, ACTION_ScheduleReboot, NULL },
7574 { L"SelfRegModules", IDS_DESC_SELFREGMODULES, IDS_TEMP_SELFREGMODULES, ACTION_SelfRegModules, L"SelfUnregModules" },
7575 { L"SelfUnregModules", IDS_DESC_SELFUNREGMODULES, IDS_TEMP_SELFUNREGMODULES, ACTION_SelfUnregModules, L"SelfRegModules" },
7576 { L"SetODBCFolders", IDS_DESC_SETODBCFOLDERS, 0, ACTION_SetODBCFolders, NULL },
7577 { L"StartServices", IDS_DESC_STARTSERVICES, IDS_TEMP_STARTSERVICES, ACTION_StartServices, L"StopServices" },
7578 { L"StopServices", IDS_DESC_STOPSERVICES, IDS_TEMP_STOPSERVICES, ACTION_StopServices, L"StartServices" },
7579 { L"UnpublishComponents", IDS_DESC_UNPUBLISHCOMPONENTS, IDS_TEMP_UNPUBLISHCOMPONENTS, ACTION_UnpublishComponents, L"PublishComponents" },
7580 { L"UnpublishFeatures", IDS_DESC_UNPUBLISHFEATURES, IDS_TEMP_UNPUBLISHFEATURES, ACTION_UnpublishFeatures, L"PublishFeatures" },
7581 { L"UnpublishProduct", IDS_DESC_UNPUBLISHPRODUCT, 0, ACTION_UnpublishProduct, NULL }, /* for rollback only */
7582 { L"UnregisterClassInfo", IDS_DESC_UNREGISTERCLASSINFO, IDS_TEMP_UNREGISTERCLASSINFO, ACTION_UnregisterClassInfo, L"RegisterClassInfo" },
7583 { L"UnregisterComPlus", IDS_DESC_UNREGISTERCOMPLUS, IDS_TEMP_UNREGISTERCOMPLUS, ACTION_UnregisterComPlus, L"RegisterComPlus" },
7584 { L"UnregisterExtensionInfo", IDS_DESC_UNREGISTEREXTENSIONINFO, IDS_TEMP_UNREGISTEREXTENSIONINFO, ACTION_UnregisterExtensionInfo, L"RegisterExtensionInfo" },
7585 { L"UnregisterFonts", IDS_DESC_UNREGISTERFONTS, IDS_TEMP_UNREGISTERFONTS, ACTION_UnregisterFonts, L"RegisterFonts" },
7586 { L"UnregisterMIMEInfo", IDS_DESC_UNREGISTERMIMEINFO, IDS_TEMP_UNREGISTERMIMEINFO, ACTION_UnregisterMIMEInfo, L"RegisterMIMEInfo" },
7587 { L"UnregisterProgIdInfo", IDS_DESC_UNREGISTERPROGIDINFO, IDS_TEMP_UNREGISTERPROGIDINFO, ACTION_UnregisterProgIdInfo, L"RegisterProgIdInfo" },
7588 { L"UnregisterTypeLibraries", IDS_DESC_UNREGISTERTYPELIBRARIES, IDS_TEMP_UNREGISTERTYPELIBRARIES, ACTION_UnregisterTypeLibraries, L"RegisterTypeLibraries" },
7589 { L"ValidateProductID", 0, 0, ACTION_ValidateProductID, NULL },
7590 { L"WriteEnvironmentStrings", IDS_DESC_WRITEENVIRONMENTSTRINGS, IDS_TEMP_WRITEENVIRONMENTSTRINGS, ACTION_WriteEnvironmentStrings, L"RemoveEnvironmentStrings" },
7591 { L"WriteIniValues", IDS_DESC_WRITEINIVALUES, IDS_TEMP_WRITEINIVALUES, ACTION_WriteIniValues, L"RemoveIniValues" },
7592 { L"WriteRegistryValues", IDS_DESC_WRITEREGISTRYVALUES, IDS_TEMP_WRITEREGISTRYVALUES, ACTION_WriteRegistryValues, L"RemoveRegistryValues" },
7593 { L"INSTALL", 0, 0, ACTION_INSTALL, NULL },
7594 { 0 }
7596
7598{
7600 UINT i;
7601
7602 i = 0;
7603 while (StandardActions[i].action != NULL)
7604 {
7606 {
7607 WCHAR description[100] = {0}, template[100] = {0};
7608
7609 if (StandardActions[i].description != 0)
7611 if (StandardActions[i].template != 0)
7612 LoadStringW(msi_hInstance, StandardActions[i].template, (LPWSTR)&template, 100);
7613
7614 ui_actionstart(package, action, description, template);
7616 {
7617 ui_actioninfo( package, action, TRUE, 0 );
7618 rc = StandardActions[i].handler( package );
7619 ui_actioninfo( package, action, FALSE, !rc );
7620
7622 {
7623 TRACE("scheduling rollback action\n");
7625 }
7626 }
7627 else
7628 {
7629 FIXME("unhandled standard action %s\n", debugstr_w(action));
7630 rc = ERROR_SUCCESS;
7631 }
7632 break;
7633 }
7634 i++;
7635 }
7636
7637 return rc;
7638}
7639
7641{
7642 UINT rc;
7643
7644 TRACE("Performing action (%s)\n", debugstr_w(action));
7645
7646 package->action_progress_increment = 0;
7647 rc = ACTION_HandleStandardAction(package, action);
7648
7649 if (rc == ERROR_FUNCTION_NOT_CALLED)
7650 rc = ACTION_HandleCustomAction(package, action);
7651
7652 if (rc == ERROR_FUNCTION_NOT_CALLED)
7653 WARN("unhandled msi action %s\n", debugstr_w(action));
7654
7655 return rc;
7656}
7657
7659{
7660 UINT rc = ERROR_SUCCESS;
7661 MSIRECORD *row;
7662
7663 if (needs_ui_sequence(package))
7664 row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `InstallUISequence` WHERE `Sequence` = %d", seq);
7665 else
7666 row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `InstallExecuteSequence` WHERE `Sequence` = %d", seq);
7667
7668 if (row)
7669 {
7670 LPCWSTR action, cond;
7671
7672 TRACE("Running the actions\n");
7673
7674 /* check conditions */
7675 cond = MSI_RecordGetString(row, 2);
7676
7677 /* this is a hack to skip errors in the condition code */
7678 if (MSI_EvaluateConditionW(package, cond) == MSICONDITION_FALSE)
7679 {
7680 msiobj_release(&row->hdr);
7681 return ERROR_SUCCESS;
7682 }
7683
7685 if (!action)
7686 {
7687 ERR("failed to fetch action\n");
7688 msiobj_release(&row->hdr);
7689 return ERROR_FUNCTION_FAILED;
7690 }
7691
7692 rc = ACTION_PerformAction(package, action);
7693
7694 msiobj_release(&row->hdr);
7695 }
7696
7697 return rc;
7698}
7699
7701{
7702 struct dummy_thread *info = arg;
7703 HRESULT hr;
7704
7706 if (FAILED(hr)) ERR("CoInitializeEx failed %08x\n", hr);
7707
7708 SetEvent(info->started);
7710
7712 return 0;
7713}
7714
7716{
7717 if (!(info->started = CreateEventA(NULL, TRUE, FALSE, NULL))) return;
7718 if (!(info->stopped = CreateEventA(NULL, TRUE, FALSE, NULL))) return;
7719 if (!(info->thread = CreateThread(NULL, 0, dummy_thread_proc, info, 0, NULL))) return;
7720
7722}
7723
7725{
7726 if (info->thread)
7727 {
7728 SetEvent(info->stopped);
7731 }
7732 if (info->started) CloseHandle(info->started);
7733 if (info->stopped) CloseHandle(info->stopped);
7734}
7735
7736/****************************************************
7737 * TOP level entry points
7738 *****************************************************/
7739
7741 LPCWSTR szCommandLine )
7742{
7743 WCHAR *reinstall = NULL, *productcode, *action;
7744 struct dummy_thread thread_info = {NULL, NULL, NULL};
7745 UINT rc;
7746 DWORD len = 0;
7747
7748 if (szPackagePath)
7749 {
7750 LPWSTR p, dir;
7751 LPCWSTR file;
7752
7753 dir = wcsdup(szPackagePath);
7754 p = wcsrchr(dir, '\\');
7755 if (p)
7756 {
7757 *(++p) = 0;
7758 file = szPackagePath + (p - dir);
7759 }
7760 else
7761 {
7762 free(dir);
7763 dir = malloc(MAX_PATH * sizeof(WCHAR));
7765 lstrcatW(dir, L"\\");
7766 file = szPackagePath;
7767 }
7768
7769 free(package->PackagePath);
7770 package->PackagePath = malloc((wcslen(dir) + wcslen(file) + 1) * sizeof(WCHAR));
7771 if (!package->PackagePath)
7772 {
7773 free(dir);
7774 return ERROR_OUTOFMEMORY;
7775 }
7776
7777 lstrcpyW(package->PackagePath, dir);
7778 lstrcatW(package->PackagePath, file);
7779 free(dir);
7780
7782 }
7783
7784 rc = msi_parse_command_line( package, szCommandLine, FALSE );
7785 if (rc != ERROR_SUCCESS)
7786 return rc;
7787
7788 msi_apply_transforms( package );
7789 msi_apply_patches( package );
7790
7791 if (msi_get_property( package->db, L"ACTION", NULL, &len ))
7792 msi_set_property( package->db, L"ACTION", L"INSTALL", -1 );
7793 action = msi_dup_property( package->db, L"ACTION" );
7795
7796 msi_set_original_database_property( package->db, szPackagePath );
7797 msi_parse_command_line( package, szCommandLine, FALSE );
7799 msi_set_context( package );
7800
7802
7803 productcode = msi_dup_property( package->db, L"ProductCode" );
7804 if (wcsicmp( productcode, package->ProductCode ))
7805 {
7806 TRACE( "product code changed %s -> %s\n", debugstr_w(package->ProductCode), debugstr_w(productcode) );
7807 free( package->ProductCode );
7808 package->ProductCode = productcode;
7809 }
7810 else free( productcode );
7811
7812 if (msi_get_property_int( package->db, L"DISABLEROLLBACK", 0 ))
7813 {
7814 TRACE("disabling rollback\n");
7815 msi_set_property( package->db, L"RollbackDisabled", L"1", -1 );
7816 }
7817
7818 rc = ACTION_PerformAction(package, action);
7819
7820 /* process the ending type action */
7821 if (rc == ERROR_SUCCESS)
7822 ACTION_PerformActionSequence(package, -1);
7823 else if (rc == ERROR_INSTALL_USEREXIT)
7824 ACTION_PerformActionSequence(package, -2);
7825 else if (rc == ERROR_INSTALL_SUSPEND)
7826 ACTION_PerformActionSequence(package, -4);
7827 else /* failed */
7828 {
7829 ACTION_PerformActionSequence(package, -3);
7830 if (!msi_get_property_int( package->db, L"RollbackDisabled", 0 ))
7831 {
7832 package->need_rollback = TRUE;
7833 }
7834 }
7835
7836 /* finish up running custom actions */
7838
7840
7841 if (package->need_rollback && !(reinstall = msi_dup_property( package->db, L"REINSTALL" )))
7842 {
7843 WARN("installation failed, running rollback script\n");
7844 execute_script( package, SCRIPT_ROLLBACK );
7845 }
7846 free( reinstall );
7847 free( action );
7848
7849 if (rc == ERROR_SUCCESS && package->need_reboot_at_end)
7851
7852 return rc;
7853}
ULONGLONG WINAPI GetTickCount64(VOID)
Definition: GetTickCount64.c:9
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define va_arg(ap, T)
Definition: acmsvcex.h:89
#define write
Definition: acwin.h:97
static int state
Definition: maze.c:121
unsigned int dir
Definition: maze.c:112
UINT ACTION_AppSearch(MSIPACKAGE *package)
Definition: appsearch.c:1078
UINT ACTION_CCPSearch(MSIPACKAGE *package)
Definition: appsearch.c:1125
void msi_parse_version_string(LPCWSTR verStr, PDWORD ms, PDWORD ls)
Definition: appsearch.c:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static BOOL load_typelib(void)
Definition: main.c:368
#define index(s, c)
Definition: various.h:29
void ls(int argc, const char *argv[])
Definition: cmds.c:1136
#define ARRAY_SIZE(A)
Definition: main.h:20
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define RegCloseKey(hKey)
Definition: registry.h:49
struct _root root
_In_ ULONG const _In_ FEATURE_NUMBER const Feature
Definition: cdrom.h:1077
LPARAM lParam
Definition: combotst.c:139
LSTATUS WINAPI RegDeleteTreeW(_In_ HKEY, _In_opt_ LPCWSTR)
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:170
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#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
UINT op
Definition: effect.c:236
static const WCHAR szEmpty[]
Definition: provider.c:50
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LONG WINAPI RegDeleteKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ REGSAM samDesired, _In_ DWORD Reserved)
Definition: reg.c:1286
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4882
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2330
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3662
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
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
HMODULE hModule
Definition: animate.c:44
#define CloseHandle
Definition: compat.h:739
#define wcschr
Definition: compat.h:17
#define wcsnicmp
Definition: compat.h:14
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define wcsrchr
Definition: compat.h:16
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
WCHAR OLECHAR
Definition: compat.h:2292
#define FreeLibrary(x)
Definition: compat.h:748
#define MAX_PATH
Definition: compat.h:34
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define wcsicmp
Definition: compat.h:15
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
static const WCHAR version[]
Definition: asmname.c:66
static WCHAR * parse_value(const WCHAR *str, unsigned int len)
Definition: asmname.c:661
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
BOOL WINAPI CreateDirectoryW(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:90
BOOL WINAPI RemoveDirectoryW(IN LPCWSTR lpPathName)
Definition: dir.c:732
BOOL WINAPI GetDiskFreeSpaceExW(IN LPCWSTR lpDirectoryName OPTIONAL, OUT PULARGE_INTEGER lpFreeBytesAvailableToCaller, OUT PULARGE_INTEGER lpTotalNumberOfBytes, OUT PULARGE_INTEGER lpTotalNumberOfFreeBytes)
Definition: disk.c:342
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
Definition: loader.c:288
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2080
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4598
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
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:286
BOOL WINAPI WritePrivateProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR string, LPCWSTR filename)
Definition: profile.c:1453
INT WINAPI GetPrivateProfileStringW(LPCWSTR section, LPCWSTR entry, LPCWSTR def_val, LPWSTR buffer, UINT len, LPCWSTR filename)
Definition: profile.c:1142
BOOL WINAPI EnumResourceNamesW(HMODULE hmod, LPCWSTR type, ENUMRESNAMEPROCW lpfun, LONG_PTR lparam)
Definition: res.c:358
static UINT load_file_disk_id(MSIPACKAGE *package, MSIFILE *file)
Definition: action.c:1016
static UINT iterate_patched_component(MSIRECORD *row, LPVOID param)
Definition: action.c:1209
const UINT description
Definition: action.c:7510
static UINT ACTION_RemoveIniValues(MSIPACKAGE *package)
Definition: action.c:4578
static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
Definition: action.c:2690
static UINT add_folder_child(MSIFOLDER *parent, MSIFOLDER *child)
Definition: action.c:1331
#define ENV_MOD_PREFIX
Definition: action.c:6715
UINT msi_set_context(MSIPACKAGE *package)
Definition: action.c:394
static void remove_product_upgrade_code(MSIPACKAGE *package)
Definition: action.c:5075
static UINT ACTION_RemoveExistingProducts(MSIPACKAGE *package)
Definition: action.c:7328
static UINT ACTION_MigrateFeatureStates(MSIPACKAGE *package)
Definition: action.c:7379
static UINT ACTION_RemoveODBC(MSIPACKAGE *package)
Definition: action.c:6673
static UINT open_env_key(DWORD flags, HKEY *key)
Definition: action.c:6798
static UINT ACTION_CreateShortcuts(MSIPACKAGE *package)
Definition: action.c:3849
static UINT ACTION_InstallODBC(MSIPACKAGE *package)
Definition: action.c:6504
static UINT ACTION_INSTALL(MSIPACKAGE *package)
Definition: action.c:5493
#define REG_PROGRESS_VALUE
Definition: action.c:44
static void write_shared_dlls_count(MSICOMPONENT *comp, const WCHAR *path, INT count)
Definition: action.c:3214
static UINT ITERATE_StopService(MSIRECORD *rec, LPVOID param)
Definition: action.c:6118
static BOOL CALLBACK Typelib_EnumResNameProc(HMODULE hModule, LPCWSTR lpszType, LPWSTR lpszName, LONG_PTR lParam)
Definition: action.c:3448
static UINT load_file_hash(MSIPACKAGE *package, MSIFILE *file)
Definition: action.c:984
static UINT ACTION_ProcessUISequence(MSIPACKAGE *package)
Definition: action.c:492
static UINT unpublish_icons(MSIPACKAGE *package)
Definition: action.c:5059
static BOOL stop_service_dependents(SC_HANDLE scm, SC_HANDLE service)
Definition: action.c:6033
static UINT ITERATE_UnregisterTypeLibraries(MSIRECORD *row, LPVOID param)
Definition: action.c:3617
static void register_dll(const WCHAR *dll, BOOL unregister)
Definition: action.c:4605
static UINT find_folder_children(MSIRECORD *row, LPVOID param)
Definition: action.c:1341
static UINT ITERATE_RemoveRegistryValuesOnUninstall(MSIRECORD *row, LPVOID param)
Definition: action.c:2902
INSTALLSTATE msi_get_component_action(MSIPACKAGE *package, MSICOMPONENT *comp)
Definition: action.c:609
int msi_compare_file_versions(VS_FIXEDFILEINFO *fi, const WCHAR *version)
Definition: action.c:1929
static const WCHAR ** service_args_to_vector(WCHAR *args, DWORD *numargs)
Definition: action.c:5865
static UINT publish_product_properties(MSIPACKAGE *package, HKEY hkey)
Definition: action.c:4035
static UINT publish_icons(MSIPACKAGE *package)
Definition: action.c:3965
static UINT ITERATE_UnpublishComponent(MSIRECORD *rec, LPVOID param)
Definition: action.c:5654
static UINT ACTION_InstallAdminPackage(MSIPACKAGE *package)
Definition: action.c:7250
static UINT ACTION_UnregisterTypeLibraries(MSIPACKAGE *package)
Definition: action.c:3661
static UINT ACTION_RegisterProduct(MSIPACKAGE *package)
Definition: action.c:4978
static int parse_prop(const WCHAR *str, WCHAR *value, int *quotes)
Definition: action.c:108
static void ui_actioninfo(MSIPACKAGE *package, const WCHAR *action, BOOL start, INT rc)
Definition: action.c:79
static int is_key_empty(const MSICOMPONENT *comp, HKEY root, const WCHAR *path)
Definition: action.c:2821
static UINT ACTION_FileCost(MSIPACKAGE *package)
Definition: action.c:1437
static UINT ITERATE_RegisterTypeLibraries(MSIRECORD *row, LPVOID param)
Definition: action.c:3520
static UINT stop_service(LPCWSTR name)
Definition: action.c:6076
const WCHAR * action
Definition: action.c:7509
static HMODULE load_library(MSIPACKAGE *package, const WCHAR *filename, DWORD flags)
Definition: action.c:3502
static BYTE * reg_get_value(HKEY hkey, const WCHAR *name, DWORD *type, DWORD *size)
Definition: action.c:2681
WCHAR ** msi_split_string(const WCHAR *str, WCHAR sep)
Definition: action.c:304
static void mark_patched_components(MSIPACKAGE *package)
Definition: action.c:1227
static void stop_dummy_thread(struct dummy_thread *info)
Definition: action.c:7724
static UINT ACTION_PublishComponents(MSIPACKAGE *package)
Definition: action.c:5637
static UINT add_feature_child(MSIFEATURE *parent, MSIFEATURE *child)
Definition: action.c:837
static BYTE * parse_value(MSIPACKAGE *package, const WCHAR *value, DWORD len, DWORD *type, DWORD *size)
Definition: action.c:2333
static void ACTION_GetComponentInstallStates(MSIPACKAGE *package)
Definition: action.c:1463
static UINT ACTION_RemoveFolders(MSIPACKAGE *package)
Definition: action.c:760
static UINT ITERATE_RemoveODBCDataSource(MSIRECORD *rec, LPVOID param)
Definition: action.c:6617
static UINT ITERATE_InstallService(MSIRECORD *rec, LPVOID param)
Definition: action.c:5720
UINT msi_load_all_components(MSIPACKAGE *package)
Definition: action.c:807
static void refcount_component(MSIPACKAGE *package, MSICOMPONENT *comp)
Definition: action.c:3224
UINT MSI_InstallPackage(MSIPACKAGE *package, LPCWSTR szPackagePath, LPCWSTR szCommandLine)
Definition: action.c:7740
static UINT ITERATE_InstallODBCTranslator(MSIRECORD *rec, LPVOID param)
Definition: action.c:6367
static WCHAR * get_link_file(MSIPACKAGE *package, MSIRECORD *row)
Definition: action.c:3678
static UINT ACTION_UnpublishFeatures(MSIPACKAGE *package)
Definition: action.c:4872
static HKEY open_shared_dlls_key(MSICOMPONENT *comp, BOOL create, REGSAM access)
Definition: action.c:3199
BOOL msi_is_global_assembly(MSICOMPONENT *comp)
Definition: action.c:2036
static UINT ITERATE_RemoveODBCDriver(MSIRECORD *rec, LPVOID param)
Definition: action.c:6539
static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package)
Definition: action.c:466
DWORD WINAPI dummy_thread_proc(void *arg)
Definition: action.c:7700
static UINT load_folder(MSIRECORD *row, LPVOID param)
Definition: action.c:1275
static UINT load_media(MSIRECORD *row, LPVOID param)
Definition: action.c:1113
static BOOL needs_ui_sequence(MSIPACKAGE *package)
Definition: action.c:389
static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
Definition: action.c:3311
static LPWSTR folder_split_path(LPWSTR p, WCHAR ch)
Definition: action.c:973
UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace)
Definition: action.c:352
MSIFOLDER * msi_get_loaded_folder(MSIPACKAGE *package, const WCHAR *dir)
Definition: action.c:583
#define ENV_ACT_REMOVEMATCH
Definition: action.c:6711
static UINT unimplemented_action_stub(MSIPACKAGE *package, LPCSTR action, LPCWSTR table)
Definition: action.c:7464
#define ENV_ACT_SETALWAYS
Definition: action.c:6708
static UINT ACTION_PublishFeatures(MSIPACKAGE *package)
Definition: action.c:4728
join_op
Definition: action.c:2606
@ JOIN_OP_PREPEND
Definition: action.c:2608
@ JOIN_OP_APPEND
Definition: action.c:2607
@ JOIN_OP_REPLACE
Definition: action.c:2609
static UINT ACTION_WriteIniValues(MSIPACKAGE *package)
Definition: action.c:4438
static UINT ACTION_RegisterComPlus(MSIPACKAGE *package)
Definition: action.c:7492
UINT ACTION_ForceReboot(MSIPACKAGE *package)
Definition: action.c:5219
UINT MSI_Sequence(MSIPACKAGE *package, LPCWSTR table)
Definition: action.c:450
static BOOL check_publish(MSIPACKAGE *package)
Definition: action.c:4109
static BOOL ui_sequence_exists(MSIPACKAGE *package)
Definition: action.c:339
static UINT ITERATE_BindImage(MSIRECORD *rec, LPVOID param)
Definition: action.c:7412
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7512
static UINT ACTION_UnregisterComPlus(MSIPACKAGE *package)
Definition: action.c:7497
static BOOL is_full_uninstall(MSIPACKAGE *package)
Definition: action.c:5145
static UINT ITERATE_SelfRegModules(MSIRECORD *row, LPVOID param)
Definition: action.c:4628
static DWORD remove_duplicate_values(WCHAR **old, DWORD old_count, WCHAR **new, DWORD new_count)
Definition: action.c:2583
static UINT ACTION_RMCCPSearch(MSIPACKAGE *package)
Definition: action.c:7487
#define check_flag_combo(x, y)
Definition: action.c:6718
static UINT ITERATE_InstallODBCDriver(MSIRECORD *rec, LPVOID param)
Definition: action.c:6275
#define ENV_MOD_APPEND
Definition: action.c:6714
#define ENV_ACT_REMOVE
Definition: action.c:6710
int msi_compare_font_versions(const WCHAR *ver1, const WCHAR *ver2)
Definition: action.c:1942
static UINT ACTION_InstallFinalize(MSIPACKAGE *package)
Definition: action.c:5159
static UINT ITERATE_InstallODBCDataSource(MSIRECORD *rec, LPVOID param)
Definition: action.c:6450
static BOOL is_special_entry(const WCHAR *name)
Definition: action.c:2523
static UINT ACTION_ValidateProductID(MSIPACKAGE *package)
Definition: action.c:7215
static UINT ACTION_InstallExecute(MSIPACKAGE *package)
Definition: action.c:5033
#define ENV_ACT_SETABSENT
Definition: action.c:6709
WCHAR * msi_normalize_path(const WCHAR *in)
Definition: action.c:2116
static UINT ITERATE_CostFinalizeConditions(MSIRECORD *row, LPVOID param)
Definition: action.c:1903
static UINT publish_patches(MSIPACKAGE *package)
Definition: action.c:4137
static UINT load_component(MSIRECORD *row, LPVOID param)
Definition: action.c:777
static BOOL check_unpublish(MSIPACKAGE *package)
Definition: action.c:4123
static UINT ACTION_WriteEnvironmentStrings(MSIPACKAGE *package)
Definition: action.c:7017
static WCHAR ** split_multi_string_values(const WCHAR *str, DWORD len, DWORD *count)
Definition: action.c:2528
static UINT ACTION_AllocateRegistrySpace(MSIPACKAGE *package)
Definition: action.c:7227
static UINT ACTION_InstallInitialize(MSIPACKAGE *package)
Definition: action.c:3060
static UINT ITERATE_RemoveFolders(MSIRECORD *row, LPVOID param)
Definition: action.c:712
static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq)
Definition: action.c:7658
static BOOL is_feature_selected(MSIFEATURE *feature, INT level)
Definition: action.c:1506
static REGSAM get_registry_view(const MSICOMPONENT *comp)
Definition: action.c:2484
static WCHAR * get_ini_file_name(MSIPACKAGE *package, MSIRECORD *row)
Definition: action.c:4330
static void remove_persistent_folder(MSIFOLDER *folder)
Definition: action.c:698
static UINT load_patch(MSIRECORD *row, LPVOID param)
Definition: action.c:1155
static UINT ACTION_StopServices(MSIPACKAGE *package)
Definition: action.c:6175
UINT msi_validate_product_id(MSIPACKAGE *package)
Definition: action.c:7188
static BOOL process_state_property(MSIPACKAGE *package, int level, LPCWSTR property, INSTALLSTATE state)
Definition: action.c:1511
static UINT ITERATE_Actions(MSIRECORD *row, LPVOID param)
Definition: action.c:408
static UINT env_parse_flags(LPCWSTR *name, LPCWSTR *value, DWORD *flags)
Definition: action.c:6720
static WCHAR * flatten_multi_string_values(WCHAR **left, DWORD left_count, WCHAR **right, DWORD right_count, DWORD *size)
Definition: action.c:2557
static UINT ITERATE_WriteIniValues(MSIRECORD *row, LPVOID param)
Definition: action.c:4364
static const struct @498 StandardActions[]
static UINT ITERATE_MigrateFeatureStates(MSIRECORD *rec, LPVOID param)
Definition: action.c:7344
@ state_token
Definition: action.c:104
@ state_whitespace
Definition: action.c:103
@ state_quote
Definition: action.c:105
static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param)
Definition: action.c:5533
static UINT ACTION_DisableRollback(MSIPACKAGE *package)
Definition: action.c:7242
static UINT ITERATE_RemoveExistingProducts(MSIRECORD *rec, LPVOID param)
Definition: action.c:7285
static void disable_children(MSIFEATURE *feature, int level)
Definition: action.c:1600
UINT MSI_SetFeatureStates(MSIPACKAGE *package)
Definition: action.c:1639
static void ACTION_GetFeatureInstallStates(MSIPACKAGE *package)
Definition: action.c:1491
static UINT load_folder_persistence(MSIPACKAGE *package, MSIFOLDER *folder)
Definition: action.c:1252
static UINT ACTION_RemoveShortcuts(MSIPACKAGE *package)
Definition: action.c:3899
void msi_ui_progress(MSIPACKAGE *package, int a, int b, int c, int d)
Definition: action.c:594
const WCHAR * action_rollback
Definition: action.c:7513
static UINT load_patch_disk_id(MSIPACKAGE *package, MSIFILEPATCH *patch)
Definition: action.c:1140
static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package)
Definition: action.c:3600
static void follow_parent(MSIFEATURE *feature)
Definition: action.c:1620
static UINT ACTION_ExecuteAction(MSIPACKAGE *package)
Definition: action.c:5375
static UINT load_all_files(MSIPACKAGE *package)
Definition: action.c:1096
static UINT ITERATE_SelfUnregModules(MSIRECORD *row, LPVOID param)
Definition: action.c:4678
MSIFEATURE * msi_get_loaded_feature(MSIPACKAGE *package, const WCHAR *Feature)
Definition: action.c:561
static UINT ACTION_CostFinalize(MSIPACKAGE *package)
Definition: action.c:2232
static UINT ITERATE_RemoveIniValuesOnInstall(MSIRECORD *row, LPVOID param)
Definition: action.c:4517
static UINT load_all_media(MSIPACKAGE *package)
Definition: action.c:1126
static BYTE * build_multi_string_value(BYTE *old_value, DWORD old_size, BYTE *new_value, DWORD new_size, DWORD *size)
Definition: action.c:2634
static UINT ITERATE_UnpublishIcon(MSIRECORD *row, LPVOID param)
Definition: action.c:5038
static UINT ACTION_UnpublishComponents(MSIPACKAGE *package)
Definition: action.c:5703
static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param)
Definition: action.c:631
static UINT ACTION_InstallSFPCatalogFile(MSIPACKAGE *package)
Definition: action.c:7502
UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action)
Definition: action.c:7640
WCHAR * msi_create_component_advertise_string(MSIPACKAGE *package, MSICOMPONENT *component, const WCHAR *feature)
Definition: action.c:5505
static UINT iterate_load_featurecomponents(MSIRECORD *row, LPVOID param)
Definition: action.c:856
#define ENV_MOD_MACHINE
Definition: action.c:6713
static UINT load_file(MSIRECORD *row, LPVOID param)
Definition: action.c:1031
static void set_target_path(MSIPACKAGE *package, MSIFILE *file)
Definition: action.c:2041
static UINT iterate_properties(MSIRECORD *record, void *param)
Definition: action.c:5361
static BOOL process_overrides(MSIPACKAGE *package, int level)
Definition: action.c:1568
static UINT ACTION_InstallValidate(MSIPACKAGE *package)
Definition: action.c:3066
static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package)
Definition: action.c:2804
static UINT load_feature(MSIRECORD *row, LPVOID param)
Definition: action.c:877
static void remove_quotes(WCHAR *str)
Definition: action.c:201
static UINT ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action)
Definition: action.c:7597
static UINT ACTION_InstallServices(MSIPACKAGE *package)
Definition: action.c:5847
static UINT ACTION_ScheduleReboot(MSIPACKAGE *package)
Definition: action.c:7220
static UINT ACTION_LaunchConditions(MSIPACKAGE *package)
Definition: action.c:3128
static UINT ITERATE_LaunchConditions(MSIRECORD *row, LPVOID param)
Definition: action.c:3103
static UINT ACTION_BindImage(MSIPACKAGE *package)
Definition: action.c:7450
static UINT ITERATE_WriteEnvironmentString(MSIRECORD *rec, LPVOID param)
Definition: action.c:6825
static UINT ACTION_IsolateComponents(MSIPACKAGE *package)
Definition: action.c:7482
UINT msi_parse_command_line(MSIPACKAGE *package, LPCWSTR szCommandLine, BOOL preserve_case)
Definition: action.c:213
static UINT ACTION_StartServices(MSIPACKAGE *package)
Definition: action.c:6016
static UINT add_feature_component(MSIFEATURE *feature, MSICOMPONENT *comp)
Definition: action.c:824
static UINT execute_script(MSIPACKAGE *package, UINT script)
Definition: action.c:1396
static void bind_image(MSIPACKAGE *package, const char *filename, const char *path)
Definition: action.c:7405
static UINT ITERATE_RemoveRegistryValuesOnInstall(MSIRECORD *row, LPVOID param)
Definition: action.c:2970
static INT ui_actionstart(MSIPACKAGE *package, LPCWSTR action, LPCWSTR description, LPCWSTR template)
Definition: action.c:56
MSICOMPONENT * msi_get_loaded_component(MSIPACKAGE *package, const WCHAR *Component)
Definition: action.c:550
static UINT calculate_file_cost(MSIPACKAGE *package)
Definition: action.c:2060
static UINT ITERATE_RemoveIniValuesOnUninstall(MSIRECORD *row, LPVOID param)
Definition: action.c:4455
static UINT ITERATE_RemoveODBCTranslator(MSIRECORD *rec, LPVOID param)
Definition: action.c:6578
UINT msi_load_all_features(MSIPACKAGE *package)
Definition: action.c:950
static UINT ACTION_SelfUnregModules(MSIPACKAGE *package)
Definition: action.c:4711
static UINT publish_upgrade_code(MSIPACKAGE *package)
Definition: action.c:4081
static UINT ACTION_ResolveSource(MSIPACKAGE *package)
Definition: action.c:5246
static WCHAR * join_multi_string_values(enum join_op op, WCHAR **old, DWORD old_count, WCHAR **new, DWORD new_count, DWORD *size)
Definition: action.c:2612
static UINT ITERATE_PublishIcon(MSIRECORD *row, LPVOID param)
Definition: action.c:3916
static UINT ITERATE_CreateShortcuts(MSIRECORD *row, LPVOID param)
Definition: action.c:3733
static UINT publish_sourcelist(MSIPACKAGE *package, HKEY hkey)
Definition: action.c:3981
static UINT get_shared_dlls_count(MSICOMPONENT *comp)
Definition: action.c:3205
static WCHAR * create_temp_dir(MSIDATABASE *db)
Definition: action.c:1954
static UINT ACTION_SelfRegModules(MSIPACKAGE *package)
Definition: action.c:4661
static UINT ITERATE_RemoveShortcuts(MSIRECORD *row, LPVOID param)
Definition: action.c:3871
void msi_resolve_target_folder(MSIPACKAGE *package, const WCHAR *name, BOOL load_prop)
Definition: action.c:2176
static UINT ITERATE_RemoveEnvironmentString(MSIRECORD *rec, LPVOID param)
Definition: action.c:7034
#define COMPONENT_PROGRESS_VALUE
Definition: action.c:45
static UINT ACTION_UnpublishProduct(MSIPACKAGE *package)
Definition: action.c:5113
const WCHAR * msi_get_command_line_option(const WCHAR *cmd, const WCHAR *option, UINT *len)
Definition: action.c:273
WCHAR * msi_build_icon_path(MSIPACKAGE *package, const WCHAR *icon_name)
Definition: action.c:3713
static UINT load_all_patches(MSIPACKAGE *package)
Definition: action.c:1192
static UINT ACTION_SetODBCFolders(MSIPACKAGE *package)
Definition: action.c:7256
static const WCHAR * get_root_key(MSIPACKAGE *package, INT root, HKEY *root_key)
Definition: action.c:2442
static UINT ACTION_RemoveEnvironmentStrings(MSIPACKAGE *package)
Definition: action.c:7171
static UINT ACTION_HandleCustomAction(MSIPACKAGE *package, LPCWSTR action)
Definition: action.c:512
static UINT ACTION_RegisterUser(MSIPACKAGE *package)
Definition: action.c:5304
static UINT ACTION_CreateFolders(MSIPACKAGE *package)
Definition: action.c:681
WCHAR *WINAPIV msi_build_directory_name(DWORD count,...)
Definition: action.c:2007
static void get_client_counts(MSIPACKAGE *package)
Definition: action.c:1442
static UINT unpublish_feature(MSIPACKAGE *package, MSIFEATURE *feature)
Definition: action.c:4840
static WCHAR * build_full_keypath(MSIPACKAGE *package, MSICOMPONENT *comp)
Definition: action.c:3294
static UINT ACTION_RemoveRegistryValues(MSIPACKAGE *package)
Definition: action.c:3033
static void start_dummy_thread(struct dummy_thread *info)
Definition: action.c:7715
static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param)
Definition: action.c:5906
static UINT ITERATE_DeleteService(MSIRECORD *rec, LPVOID param)
Definition: action.c:6192
static WCHAR * get_install_location(MSIPACKAGE *package)
Definition: action.c:2160
INSTALLSTATE msi_get_feature_action(MSIPACKAGE *package, MSIFEATURE *feature)
Definition: action.c:625
MSIFILE * msi_get_loaded_file(MSIPACKAGE *package, const WCHAR *key)
Definition: action.c:572
static UINT publish_install_properties(MSIPACKAGE *package, HKEY hkey)
Definition: action.c:4890
static UINT ACTION_PublishProduct(MSIPACKAGE *package)
Definition: action.c:4239
static UINT find_feature_children(MSIRECORD *row, LPVOID param)
Definition: action.c:930
#define ENV_MOD_MASK
Definition: action.c:6716
static UINT load_all_folders(MSIPACKAGE *package)
Definition: action.c:1357
static UINT ACTION_DeleteServices(MSIPACKAGE *package)
Definition: action.c:6258
static ULONGLONG get_volume_space_required(MSIPACKAGE *package)
Definition: action.c:2220
static UINT ACTION_CostInitialize(MSIPACKAGE *package)
Definition: action.c:1380
static LPWSTR resolve_keypath(MSIPACKAGE *package, MSICOMPONENT *cmp)
Definition: action.c:3144
UINT msi_schedule_action(MSIPACKAGE *package, UINT script, const WCHAR *action)
Definition: custom.c:90
void ACTION_FinishCustomActions(const MSIPACKAGE *package)
Definition: custom.c:1629
UINT ACTION_CustomAction(MSIPACKAGE *package, const WCHAR *action)
Definition: custom.c:1485
HINSTANCE msi_hInstance
Definition: msi_main.c:51
INT ACTION_ShowDialog(MSIPACKAGE *package, const WCHAR *dialog)
Definition: dialog.c:4454
void msi_dialog_check_messages(HANDLE handle)
Definition: dialog.c:3987
BOOL msi_create_full_path(MSIPACKAGE *package, const WCHAR *path)
Definition: files.c:211
BOOL msi_remove_directory(MSIPACKAGE *package, const WCHAR *path)
Definition: files.c:97
HANDLE msi_create_file(MSIPACKAGE *package, const WCHAR *filename, DWORD access, DWORD sharing, DWORD creation, DWORD flags)
Definition: files.c:60
UINT ACTION_InstallFiles(MSIPACKAGE *package)
Definition: files.c:564
UINT ACTION_RemoveFiles(MSIPACKAGE *package)
Definition: files.c:1528
UINT msi_patch_assembly(MSIPACKAGE *package, MSIASSEMBLY *assembly, MSIFILEPATCH *patch)
Definition: files.c:726
BOOL msi_delete_file(MSIPACKAGE *package, const WCHAR *filename)
Definition: files.c:79
WCHAR * msi_resolve_file_source(MSIPACKAGE *package, MSIFILE *file)
Definition: files.c:536
void msi_reduce_to_long_filename(WCHAR *filename)
Definition: files.c:1053
VS_FIXEDFILEINFO * msi_get_disk_file_version(MSIPACKAGE *package, const WCHAR *filename)
Definition: files.c:170
UINT ACTION_PatchFiles(MSIPACKAGE *package)
Definition: files.c:776
DWORD msi_get_file_attributes(MSIPACKAGE *package, const WCHAR *path)
Definition: files.c:115
UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
Definition: files.c:1315
DWORD msi_get_disk_file_size(MSIPACKAGE *package, const WCHAR *filename)
Definition: files.c:199
UINT ACTION_MoveFiles(MSIPACKAGE *package)
Definition: files.c:1185
UINT ACTION_RemoveDuplicateFiles(MSIPACKAGE *package)
Definition: files.c:1390
WCHAR * msi_get_font_file_version(MSIPACKAGE *package, const WCHAR *filename)
Definition: font.c:189
UINT ACTION_UnregisterFonts(MSIPACKAGE *package)
Definition: font.c:360
UINT ACTION_RegisterFonts(MSIPACKAGE *package)
Definition: font.c:279
DWORD deformat_string(MSIPACKAGE *package, const WCHAR *fmt, WCHAR **data)
Definition: format.c:1016
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
const WCHAR * msi_get_target_folder(MSIPACKAGE *package, const WCHAR *name)
Definition: install.c:232
UINT msi_add_cabinet_stream(MSIPACKAGE *package, UINT disk_id, IStorage *storage, const WCHAR *name)
Definition: media.c:923
UINT WINAPI MsiQueryComponentStateW(LPCWSTR szProductCode, LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext, LPCWSTR szComponent, INSTALLSTATE *pdwState)
Definition: msi.c:2140
UINT msi_locate_product(LPCWSTR szProduct, MSIINSTALLCONTEXT *context)
Definition: msi.c:54
BOOL is_wow64
Definition: msi.c:52
INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
Definition: msi.c:3062
const WCHAR * text
Definition: package.c:1794
#define IDS_TEMP_INSTALLFILES
Definition: resource.h:125
#define IDS_TEMP_REMOVEEXISTINGPRODUCTS
Definition: resource.h:144
#define IDS_DESC_PATCHFILES
Definition: resource.h:73
#define IDS_TEMP_INSTALLSFPCATALOGFILE
Definition: resource.h:127
#define IDS_DESC_REMOVEODBC
Definition: resource.h:93
#define IDS_DESC_WRITEINIVALUES
Definition: resource.h:113
#define IDS_DESC_SETODBCFOLDERS
Definition: resource.h:99
#define IDS_TEMP_DUPLICATEFILES
Definition: resource.h:122
#define IDS_DESC_CREATESHORTCUTS
Definition: resource.h:57
#define IDS_DESC_REGISTEREXTENSIONINFO
Definition: resource.h:80
#define IDS_DESC_WRITEENVIRONMENTSTRINGS
Definition: resource.h:112
#define IDS_TEMP_SELFUNREGMODULES
Definition: resource.h:151
#define IDS_TEMP_REGISTERCOMPLUS
Definition: resource.h:136
#define MSIERR_INSERTDISK
Definition: resource.h:30
#define IDS_TEMP_SELFREGMODULES
Definition: resource.h:150
#define IDS_DESC_REGISTERFONTS
Definition: resource.h:81
#define IDS_DESC_UNREGISTERCOMPLUS
Definition: resource.h:106
#define IDS_DESC_STOPSERVICES
Definition: resource.h:101
#define IDS_DESC_SELFREGMODULES
Definition: resource.h:97
#define IDS_DESC_PUBLISHPRODUCT
Definition: resource.h:77
#define IDS_DESC_INSTALLODBC
Definition: resource.h:64
#define IDS_DESC_REGISTERMIMEINFO
Definition: resource.h:82
#define IDS_TEMP_REMOVEFILES
Definition: resource.h:145
#define IDS_DESC_ALLOCATEREGISTRYSPACE
Definition: resource.h:50
#define IDS_DESC_REMOVEINIVALUES
Definition: resource.h:92
#define IDS_TEMP_UNPUBLISHFEATURES
Definition: resource.h:155
#define IDS_DESC_UNREGISTERTYPELIBRARIES
Definition: resource.h:111
#define IDS_TEMP_UNPUBLISHCOMPONENTS
Definition: resource.h:154
#define IDS_DESC_LAUNCHCONDITIONS
Definition: resource.h:68
#define IDS_DESC_APPSEARCH
Definition: resource.h:51
#define IDS_DESC_RMCCPSEARCH
Definition: resource.h:96
#define IDS_TEMP_DELETESERVICES
Definition: resource.h:121
#define IDS_TEMP_REMOVESHORTCUTS
Definition: resource.h:149
#define IDS_DESC_MOVEFILES
Definition: resource.h:70
#define IDS_DESC_REMOVEREGISTRYVALUES
Definition: resource.h:94
#define IDS_DESC_UNPUBLISHPRODUCT
Definition: resource.h:104
#define IDS_DESC_FILECOST
Definition: resource.h:60
#define MSIERR_INFO_ACTIONENDED
Definition: resource.h:26
#define IDS_DESC_MSIPUBLISHASSEMBLIES
Definition: resource.h:71
#define IDS_DESC_REGISTERCLASSINFO
Definition: resource.h:78
#define IDS_TEMP_REMOVEINIVALUES
Definition: resource.h:147
#define IDS_TEMP_REGISTERFONTS
Definition: resource.h:138
#define IDS_DESC_REGISTERPRODUCT
Definition: resource.h:83
#define IDS_DESC_STARTSERVICES
Definition: resource.h:100
#define IDS_TEMP_UNREGISTERTYPELIBRARIES
Definition: resource.h:162
#define IDS_DESC_COSTFINALIZE
Definition: resource.h:54
#define IDS_DESC_UNREGISTERMIMEINFO
Definition: resource.h:109
#define IDS_DESC_BINDIMAGE
Definition: resource.h:52
#define IDS_TEMP_WRITEENVIRONMENTSTRINGS
Definition: resource.h:163
#define IDS_DESC_REMOVEDUPLICATEFILES
Definition: resource.h:87
#define IDS_TEMP_UNREGISTERCOMPLUS
Definition: resource.h:157
#define IDS_DESC_UNPUBLISHCOMPONENTS
Definition: resource.h:102
#define IDS_TEMP_REMOVEDUPLICATEFILES
Definition: resource.h:142
#define IDS_TEMP_MSIUNPUBLISHASSEMBLIES
Definition: resource.h:131
#define IDS_DESC_REGISTERCOMPLUS
Definition: resource.h:79
#define IDS_DESC_MIGRATEFEATURESTATES
Definition: resource.h:69
#define IDS_DESC_REMOVEEXISTINGPRODUCTS
Definition: resource.h:89
#define IDS_TEMP_PUBLISHCOMPONENTS
Definition: resource.h:133
#define IDS_TEMP_BINDIMAGE
Definition: resource.h:118
#define IDS_TEMP_UNREGISTERCLASSINFO
Definition: resource.h:156
#define IDS_TEMP_STOPSERVICES
Definition: resource.h:153
#define IDS_TEMP_INSTALLSERVICES
Definition: resource.h:126
#define IDS_TEMP_UNREGISTEREXTENSIONINFO
Definition: resource.h:158
#define IDS_DESC_INSTALLSERVICES
Definition: resource.h:65
#define IDS_TEMP_MOVEFILES
Definition: resource.h:129
#define IDS_TEMP_REMOVEREGISTRYVALUES
Definition: resource.h:148
#define IDS_DESC_UNREGISTERPROGIDINFO
Definition: resource.h:110
#define IDS_DESC_UNPUBLISHFEATURES
Definition: resource.h:103
#define IDS_DESC_MSIUNPUBLISHASSEMBLIES
Definition: resource.h:72
#define IDS_DESC_PUBLISHCOMPONENTS
Definition: resource.h:75
#define IDS_TEMP_FINDRELATEDPRODUCTS
Definition: resource.h:123
#define IDS_TEMP_CREATESHORTCUTS
Definition: resource.h:120
#define IDS_DESC_WRITEREGISTRYVALUES
Definition: resource.h:114
#define IDS_TEMP_REGISTERCLASSINFO
Definition: resource.h:135
#define IDS_TEMP_PATCHFILES
Definition: resource.h:132
#define IDS_DESC_INSTALLSFPCATALOGFILE
Definition: resource.h:66
#define IDS_TEMP_UNREGISTERFONTS
Definition: resource.h:159
#define IDS_DESC_UNREGISTERCLASSINFO
Definition: resource.h:105
#define IDS_TEMP_REGISTERTYPELIBRARIES
Definition: resource.h:141
#define IDS_DESC_PUBLISHFEATURES
Definition: resource.h:76
#define IDS_DESC_REMOVEFOLDERS
Definition: resource.h:91
#define IDS_TEMP_WRITEINIVALUES
Definition: resource.h:164
#define IDS_TEMP_MSIPUBLISHASSEMBLIES
Definition: resource.h:130
#define IDS_TEMP_REGISTERPROGIDINFO
Definition: resource.h:140
#define IDS_DESC_DUPLICATEFILES
Definition: resource.h:59
#define IDS_DESC_CCPSEARCH
Definition: resource.h:53
#define IDS_DESC_SELFUNREGMODULES
Definition: resource.h:98
#define IDS_DESC_INSTALLFILES
Definition: resource.h:63
#define IDS_DESC_INSTALLADMINPACKAGE
Definition: resource.h:62
#define IDS_TEMP_UNREGISTERPROGIDINFO
Definition: resource.h:161
#define IDS_DESC_REGISTERTYPELIBRARIES
Definition: resource.h:85
#define IDS_TEMP_REMOVEFOLDERS
Definition: resource.h:146
#define IDS_DESC_CREATEFOLDERS
Definition: resource.h:56
#define IDS_TEMP_CREATEFOLDERS
Definition: resource.h:119
#define IDS_TEMP_WRITEREGISTRYVALUES
Definition: resource.h:165
#define IDS_TEMP_STARTSERVICES
Definition: resource.h:152
#define IDS_TEMP_ALLOCATEREGISTRYSPACE
Definition: resource.h:116
#define IDS_DESC_UNREGISTEREXTENSIONINFO
Definition: resource.h:107
#define MSIERR_INFO_LOGGINGSTART
Definition: resource.h:24
#define IDS_DESC_REGISTERUSER
Definition: resource.h:86
#define IDS_DESC_FINDRELATEDPRODUCTS
Definition: resource.h:61
#define IDS_DESC_REMOVESHORTCUTS
Definition: resource.h:95
#define MSIERR_INFO_ACTIONSTART
Definition: resource.h:25
#define IDS_DESC_DELETESERVICES
Definition: resource.h:58
#define IDS_DESC_REMOVEFILES
Definition: resource.h:90
#define IDS_DESC_UNREGISTERFONTS
Definition: resource.h:108
#define IDS_TEMP_INSTALLADMINPACKAGE
Definition: resource.h:124
#define IDS_TEMP_APPSEARCH
Definition: resource.h:117
#define IDS_TEMP_REMOVEENVIRONMENTSTRINGS
Definition: resource.h:143
#define IDS_DESC_REGISTERPROGIDINFO
Definition: resource.h:84
#define IDS_DESC_COSTINITIALIZE
Definition: resource.h:55
#define IDS_TEMP_MIGRATEFEATURESTATES
Definition: resource.h:128
#define IDS_TEMP_REGISTERMIMEINFO
Definition: resource.h:139
#define IDS_DESC_INSTALLVALIDATE
Definition: resource.h:67
#define IDS_TEMP_PUBLISHFEATURES
Definition: resource.h:134
#define IDS_DESC_PROCESSCOMPONENTS
Definition: resource.h:74
#define IDS_DESC_REMOVEENVIRONMENTSTRINGS
Definition: resource.h:88
#define IDS_TEMP_UNREGISTERMIMEINFO
Definition: resource.h:160
UINT WINAPI MsiSourceListSetInfoW(const WCHAR *szProduct, const WCHAR *szUserSid, MSIINSTALLCONTEXT dwContext, DWORD dwOptions, const WCHAR *szProperty, const WCHAR *szValue)
Definition: source.c:748
UINT WINAPI MsiSourceListAddMediaDiskW(const WCHAR *szProduct, const WCHAR *szUserSid, MSIINSTALLCONTEXT dwContext, DWORD dwOptions, DWORD dwDiskId, const WCHAR *szVolumeLabel, const WCHAR *szDiskPrompt)
Definition: source.c:1185
UINT WINAPI MsiSourceListGetInfoW(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCWSTR szProperty, LPWSTR szValue, LPDWORD pcchValue)
Definition: source.c:523
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT WINAPI RegisterTypeLib(ITypeLib *ptlib, const WCHAR *szFullPath, const WCHAR *szHelpDir)
Definition: typelib.c:656
HRESULT WINAPI LoadTypeLibEx(LPCOLESTR szFile, REGKIND regkind, ITypeLib **pptLib)
Definition: typelib.c:473
HRESULT WINAPI UnRegisterTypeLib(REFGUID libid, WORD wVerMajor, WORD wVerMinor, LCID lcid, SYSKIND syskind)
Definition: typelib.c:882
HRESULT WINAPI LoadTypeLib(const OLECHAR *szFile, ITypeLib **pptLib)
Definition: typelib.c:458
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
#define swprintf
Definition: precomp.h:40
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
#define check(expected, result)
Definition: dplayx.c:32
r parent
Definition: btrfs.c:3010
#define INFINITE
Definition: serial.h:102
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
FxCollectionEntry * cur
size_t total
GLuint start
Definition: gl.h:1545
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLsizeiptr size
Definition: glext.h:5919
struct _cl_event * event
Definition: glext.h:7739
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLdouble GLdouble right
Definition: glext.h:10859
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint in
Definition: glext.h:9616
GLint left
Definition: glext.h:7726
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLbitfield flags
Definition: glext.h:7161
GLuint GLfloat * val
Definition: glext.h:7180
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
GLfloat GLfloat p
Definition: glext.h:8902
GLuint GLuint num
Definition: glext.h:9618
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLuint pathA
Definition: glext.h:11719
GLuint GLenum GLsizei GLsizei GLint GLint GLboolean packed
Definition: glext.h:9271
GLuint id
Definition: glext.h:5910
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
GLenum target
Definition: glext.h:7315
GLsizei const GLuint * paths
Definition: glext.h:11717
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
static LPSTR strdupWtoA(LPCWSTR str)
Definition: hhctrl.h:299
#define ss
Definition: i386-dis.c:441
BOOL WINAPI BindImage(PCSTR ImageName, PCSTR DllPath, PCSTR SymbolPath)
Definition: modify.c:40
_Check_return_ long __cdecl strtol(_In_z_ const char *_Str, _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
uint32_t entry
Definition: isohybrid.c:63
#define d
Definition: ke_i.h:81
#define c
Definition: ke_i.h:80
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
#define REG_SZ
Definition: layer.c:22
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
const GUID * guid
__u16 date
Definition: mkdosfs.c:8
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define CREATE_ALWAYS
Definition: disk.h:72
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static PVOID ptr
Definition: dispmode.c:27
static const WCHAR desc[]
Definition: protectdata.c:36
static HMODULE dll
Definition: str.c:188
const char * fullname
Definition: shader.c:1766
static const struct access_res create[16]
Definition: package.c:7505
static const WCHAR sd[]
Definition: suminfo.c:286
static ULONG * old_value
Definition: directory.c:54
#define cmp(status, error)
Definition: error.c:114
static char * dest
Definition: rtl.c:135
static APTTYPEQUALIFIER * qualifier
Definition: compobj.c:79
static CHAR filenameA[MAX_PATH]
Definition: storage32.c:42
static OLECHAR OLECHAR *static SYSKIND
Definition: typelib.c:80
static refpint_t pi[]
Definition: server.c:96
INTERNETFEATURELIST feature
Definition: misc.c:1719
static HWND child
Definition: cursoricon.c:298
int k
Definition: mpi.c:3369
int remove
Definition: msacm.c:1366
struct @1673::@1674 driver
REFCLSID clsid
Definition: msctf.c:82
LANGID langid
Definition: msctf.idl:644
UINT ACTION_MsiUnpublishAssemblies(MSIPACKAGE *package)
Definition: assembly.c:615
MSIASSEMBLY * msi_load_assembly(MSIPACKAGE *package, MSICOMPONENT *comp)
Definition: assembly.c:292
UINT ACTION_MsiPublishAssemblies(MSIPACKAGE *package)
Definition: assembly.c:542
UINT msi_install_assembly(MSIPACKAGE *package, MSICOMPONENT *comp)
Definition: assembly.c:356
UINT ACTION_UnregisterMIMEInfo(MSIPACKAGE *package)
Definition: classes.c:1450
UINT ACTION_UnregisterExtensionInfo(MSIPACKAGE *package)
Definition: classes.c:1307
UINT ACTION_RegisterMIMEInfo(MSIPACKAGE *package)
Definition: classes.c:1392
UINT ACTION_RegisterExtensionInfo(MSIPACKAGE *package)
Definition: classes.c:1196
UINT ACTION_UnregisterClassInfo(MSIPACKAGE *package)
Definition: classes.c:857
UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
Definition: classes.c:690
UINT ACTION_UnregisterProgIdInfo(MSIPACKAGE *package)
Definition: classes.c:1088
UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package)
Definition: classes.c:1026
static const WCHAR INSTALLPROPERTY_PACKAGENAMEW[]
Definition: msi.h:265
static const WCHAR INSTALLPROPERTY_MEDIAPACKAGEPATHW[]
Definition: msi.h:413
static const WCHAR INSTALLPROPERTY_AUTHORIZED_LUA_APPW[]
Definition: msi.h:305
static const WCHAR INSTALLPROPERTY_PACKAGECODEW[]
Definition: msi.h:285
struct _MSIFILEHASHINFO MSIFILEHASHINFO
static const WCHAR INSTALLPROPERTY_PRODUCTIDW[]
Definition: msi.h:363
static const WCHAR INSTALLPROPERTY_VERSIONMAJORW[]
Definition: msi.h:359
@ MSICODE_PRODUCT
Definition: msi.h:215
static const WCHAR INSTALLPROPERTY_DISKPROMPTW[]
Definition: msi.h:417
static const WCHAR INSTALLPROPERTY_LOCALPACKAGEW[]
Definition: msi.h:343
static const WCHAR INSTALLPROPERTY_PRODUCTNAMEW[]
Definition: msi.h:277
static const WCHAR INSTALLPROPERTY_LASTUSEDSOURCEW[]
Definition: msi.h:405
@ INSTALLMESSAGE_ACTIONSTART
Definition: msi.h:102
@ INSTALLMESSAGE_ERROR
Definition: msi.h:95
@ INSTALLMESSAGE_PROGRESS
Definition: msi.h:104
@ INSTALLMESSAGE_ACTIONDATA
Definition: msi.h:103
@ INSTALLMESSAGE_COMMONDATA
Definition: msi.h:105
@ INSTALLMESSAGE_INFO
Definition: msi.h:98
@ INSTALLMESSAGE_INSTALLSTART
Definition: msi.h:110
@ INSTALLMESSAGE_INSTALLEND
Definition: msi.h:111
static const WCHAR INSTALLPROPERTY_PRODUCTICONW[]
Definition: msi.h:295
@ INSTALLSTATE_UNKNOWN
Definition: msi.h:42
@ INSTALLSTATE_LOCAL
Definition: msi.h:46
@ INSTALLSTATE_ABSENT
Definition: msi.h:45
@ INSTALLSTATE_INVALIDARG
Definition: msi.h:41
@ INSTALLSTATE_SOURCE
Definition: msi.h:47
@ INSTALLSTATE_DEFAULT
Definition: msi.h:48
@ INSTALLSTATE_ADVERTISED
Definition: msi.h:44
@ MSIINSTALLCONTEXT_MACHINE
Definition: msi.h:200
@ MSIINSTALLCONTEXT_USERUNMANAGED
Definition: msi.h:199
@ MSIINSTALLCONTEXT_USERMANAGED
Definition: msi.h:198
static const WCHAR INSTALLPROPERTY_INSTALLDATEW[]
Definition: msi.h:335
static const WCHAR INSTALLPROPERTY_INSTANCETYPEW[]
Definition: msi.h:300
static const WCHAR INSTALLPROPERTY_VERSIONW[]
Definition: msi.h:289
static const WCHAR INSTALLPROPERTY_VERSIONMINORW[]
Definition: msi.h:355
@ INSTALLUILEVEL_REDUCED
Definition: msi.h:68
@ INSTALLUILEVEL_NONE
Definition: msi.h:66
static const WCHAR INSTALLPROPERTY_LANGUAGEW[]
Definition: msi.h:273
@ msidbComponentAttributes64bit
Definition: msidefs.h:168
@ msidbComponentAttributesSharedDllRefCount
Definition: msidefs.h:163
@ msidbComponentAttributesOptional
Definition: msidefs.h:161
@ msidbComponentAttributesRegistryKeyPath
Definition: msidefs.h:162
@ msidbComponentAttributesPermanent
Definition: msidefs.h:164
@ msidbComponentAttributesSourceOnly
Definition: msidefs.h:160
@ msidbComponentAttributesODBCDataSource
Definition: msidefs.h:165
@ msidbPatchAttributesNonVital
Definition: msidefs.h:43
@ msidbUpgradeAttributesMigrateFeatures
Definition: msidefs.h:23
@ msidbUpgradeAttributesOnlyDetect
Definition: msidefs.h:24
@ msidbFeatureAttributesFavorAdvertise
Definition: msidefs.h:151
@ msidbFeatureAttributesFollowParent
Definition: msidefs.h:150
@ msidbFeatureAttributesFavorSource
Definition: msidefs.h:149
@ msidbIniFileActionRemoveLine
Definition: msidefs.h:238
@ msidbIniFileActionAddLine
Definition: msidefs.h:236
@ msidbIniFileActionCreateLine
Definition: msidefs.h:237
@ msidbFileAttributesCompressed
Definition: msidefs.h:39
@ msidbFileAttributesPatchAdded
Definition: msidefs.h:37
@ msidbFileAttributesNoncompressed
Definition: msidefs.h:38
@ msidbODBCDataSourceRegistrationPerUser
Definition: msidefs.h:174
@ msidbODBCDataSourceRegistrationPerMachine
Definition: msidefs.h:173
@ msidbSumInfoSourceTypeAdminImage
Definition: msidefs.h:223
@ msidbSumInfoSourceTypeCompressed
Definition: msidefs.h:222
@ msidbServiceInstallErrorControlVital
Definition: msidefs.h:205
@ msidbServiceControlEventStart
Definition: msidefs.h:195
@ msidbServiceControlEventUninstallDelete
Definition: msidefs.h:200
@ msidbServiceControlEventUninstallStop
Definition: msidefs.h:199
@ msidbServiceControlEventDelete
Definition: msidefs.h:197
@ msidbServiceControlEventStop
Definition: msidefs.h:196
@ msidbServiceControlEventUninstallStart
Definition: msidefs.h:198
int MSI_RecordGetInteger(MSIRECORD *, UINT)
Definition: record.c:213
#define SEQUENCE_UI
Definition: msipriv.h:718
UINT MSIREG_DeleteUserUpgradeCodesKey(LPCWSTR szUpgradeCode)
Definition: registry.c:829
UINT MSIREG_DeleteUpgradeCodesKey(const WCHAR *)
Definition: registry.c:812
UINT MSI_ViewExecute(MSIQUERY *, MSIRECORD *)
Definition: msiquery.c:502
UINT MSIREG_OpenProductKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
Definition: registry.c:338
#define MSI_INITIAL_MEDIA_TRANSFORM_DISKID
Definition: msipriv.h:84
static const BOOL is_64bit
Definition: msipriv.h:44
LONG msi_reg_set_val_dword(HKEY hkey, LPCWSTR name, DWORD val)
Definition: registry.c:225
static int cost_from_size(int size)
Definition: msipriv.h:1198
BOOL squash_guid(LPCWSTR in, LPWSTR out)
Definition: registry.c:74
UINT MSIREG_DeleteLocalClassesFeaturesKey(LPCWSTR szProductCode)
Definition: registry.c:858
UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid, MSIINSTALLCONTEXT context, DWORD options, LPCWSTR value)
Definition: source.c:686
#define INSTALLUILEVEL_MASK
Definition: msipriv.h:60
UINT msi_get_string_table_codepage(const string_table *st)
Definition: string.c:671
UINT ACTION_FindRelatedProducts(MSIPACKAGE *package)
Definition: upgrade.c:217
UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid, HKEY *key, BOOL create)
Definition: registry.c:526
UINT MSIREG_DeleteUninstallKey(const WCHAR *, enum platform)
void msi_reset_source_folders(MSIPACKAGE *package)
Definition: package.c:2089
const WCHAR * msi_record_get_string(const MSIRECORD *, UINT, int *)
Definition: record.c:420
BOOL encode_base85_guid(GUID *, LPWSTR)
Definition: registry.c:165
UINT MSIREG_OpenUserDataProductPatchesKey(LPCWSTR product, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
Definition: registry.c:666
UINT MSI_RecordSetInteger(MSIRECORD *, UINT, int)
Definition: record.c:280
UINT MSIREG_OpenClassesUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY *key, BOOL create)
Definition: registry.c:875
LONG msi_reg_set_val_multi_str(HKEY hkey, LPCWSTR name, LPCWSTR value)
Definition: registry.c:217
WCHAR * msi_dup_record_field(MSIRECORD *row, INT index)
Definition: record.c:1002
UINT msi_apply_patches(MSIPACKAGE *package)
Definition: patch.c:932
UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext, LPCWSTR szUserSid, HKEY *key, BOOL create)
Definition: registry.c:692
script
Definition: msipriv.h:383
@ SCRIPT_INSTALL
Definition: msipriv.h:385
@ SCRIPT_ROLLBACK
Definition: msipriv.h:387
@ SCRIPT_NONE
Definition: msipriv.h:384
@ SCRIPT_COMMIT
Definition: msipriv.h:386
UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid)
Definition: registry.c:552
#define GUID_SIZE
Definition: msipriv.h:733
UINT MSIREG_DeleteClassesUpgradeCodesKey(LPCWSTR szUpgradeCode)
Definition: registry.c:890
int msi_get_property_int(MSIDATABASE *package, LPCWSTR prop, int def)
Definition: package.c:2305
UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY **)
INT MSI_ProcessMessageVerbatim(MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD *)
Definition: package.c:1843
UINT MSI_RecordReadStream(MSIRECORD *, UINT, char *, LPDWORD)
Definition: record.c:761
UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY *key, BOOL create)
Definition: registry.c:505
UINT MSIREG_OpenUninstallKey(const WCHAR *, enum platform, HKEY *, BOOL)
UINT MSIREG_DeleteUserProductKey(LPCWSTR szProduct)
Definition: registry.c:378
MSICONDITION MSI_EvaluateConditionW(MSIPACKAGE *, LPCWSTR)
UINT msi_set_original_database_property(MSIDATABASE *, const WCHAR *)
Definition: package.c:1310
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT)
Definition: record.c:433
LONG msi_reg_set_val_str(HKEY hkey, LPCWSTR name, LPCWSTR value)
Definition: registry.c:209
UINT WINAPIV MSI_OpenQuery(MSIDATABASE *, MSIQUERY **, LPCWSTR,...)
Definition: msiquery.c:138
@ FOLDER_STATE_UNINITIALIZED
Definition: msipriv.h:565
@ FOLDER_STATE_REMOVED
Definition: msipriv.h:569
@ FOLDER_STATE_CREATED
Definition: msipriv.h:567
UINT MSIREG_DeleteUserDataProductKey(LPCWSTR, MSIINSTALLCONTEXT)
Definition: registry.c:720
UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
Definition: registry.c:404
UINT MSIREG_OpenUserUpgradeCodesKey(LPCWSTR szProduct, HKEY *key, BOOL create)
Definition: registry.c:798
UINT msi_set_property(MSIDATABASE *, const WCHAR *, const WCHAR *, int)
Definition: package.c:2100
MSIRECORD *WINAPIV MSI_QueryGetRecord(MSIDATABASE *db, LPCWSTR query,...)
Definition: msiquery.c:201
UINT msi_get_property(MSIDATABASE *, LPCWSTR, LPWSTR, LPDWORD)
Definition: package.c:2250
WCHAR * msi_get_package_code(MSIDATABASE *db)
Definition: package.c:1277
UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szProduct, HKEY *key, BOOL create)
Definition: registry.c:783
static void msi_revert_fs_redirection(MSIPACKAGE *package)
Definition: msipriv.h:1076
BOOL MSI_RecordIsNull(MSIRECORD *, UINT)
Definition: record.c:321
UINT MSIREG_DeleteLocalClassesProductKey(LPCWSTR szProductCode)
Definition: registry.c:841
WCHAR * msi_dup_property(MSIDATABASE *db, const WCHAR *prop)
static void msi_disable_fs_redirection(MSIPACKAGE *package)
Definition: msipriv.h:1072
INT MSI_ProcessMessage(MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD *)
Definition: package.c:1909
WCHAR * msi_strdupW(const WCHAR *value, int len)
Definition: record.c:155
UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct)
Definition: registry.c:445
UINT MSI_ViewFetch(MSIQUERY *, MSIRECORD **)
Definition: msiquery.c:377
UINT MSIREG_OpenUserDataPatchKey(LPCWSTR szPatch, MSIINSTALLCONTEXT dwContext, HKEY *key, BOOL create)
Definition: registry.c:610
void msi_free_action_script(MSIPACKAGE *package, UINT script)
Definition: package.c:137
UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext, LPCWSTR szUserSid, HKEY *key, BOOL create)
Definition: registry.c:582
WCHAR * msi_reg_get_val_str(HKEY hkey, const WCHAR *name)
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR)
Definition: record.c:597
MSIRECORD * MSI_CreateRecord(UINT)
Definition: record.c:76
UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
Definition: registry.c:472
UINT MSIREG_DeleteProductKey(LPCWSTR szProduct)
Definition: registry.c:751
UINT MSIREG_DeleteUserDataPatchKey(LPCWSTR patch, MSIINSTALLCONTEXT context)
Definition: registry.c:636
UINT msi_apply_transforms(MSIPACKAGE *package)
Definition: patch.c:950
WCHAR * msi_get_error_message(MSIDATABASE *, int)
Definition: package.c:1818
UINT MSI_IterateRecords(MSIQUERY *, LPDWORD, record_func, LPVOID)
Definition: msiquery.c:163
#define SQUASHED_GUID_SIZE
Definition: msipriv.h:734
#define SEQUENCE_EXEC
Definition: msipriv.h:719
void msi_adjust_privilege_properties(MSIPACKAGE *)
Definition: package.c:964
@ msifs_missing
Definition: msipriv.h:595
@ msifs_installed
Definition: msipriv.h:598
@ msifs_invalid
Definition: msipriv.h:594
@ msifs_overwrite
Definition: msipriv.h:596
MSIRECORD * MSI_CloneRecord(MSIRECORD *)
Definition: record.c:921
DWORD msi_version_str_to_dword(LPCWSTR p)
Definition: registry.c:188
@ MSICONDITION_FALSE
Definition: msiquery.h:26
@ MSICONDITION_TRUE
Definition: msiquery.h:27
#define MSI_NULL_INTEGER
Definition: msiquery.h:32
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_READ
Definition: nt_native.h:1023
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define GENERIC_ALL
Definition: nt_native.h:92
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define DELETE
Definition: nt_native.h:57
#define READ_CONTROL
Definition: nt_native.h:58
#define DWORD
Definition: nt_native.h:44
#define GENERIC_WRITE
Definition: nt_native.h:90
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define KEY_SET_VALUE
Definition: nt_native.h:1017
IN ULONG IN UCHAR Condition
#define L(x)
Definition: ntvdm.h:50
@ COINIT_MULTITHREADED
Definition: objbase.h:279
#define ODBC_INSTALL_COMPLETE
Definition: odbcinst.h:20
#define ODBC_REMOVE_SYS_DSN
Definition: odbcinst.h:18
#define ODBC_ADD_DSN
Definition: odbcinst.h:12
#define ODBC_REMOVE_DSN
Definition: odbcinst.h:14
#define ODBC_ADD_SYS_DSN
Definition: odbcinst.h:16
@ REGKIND_REGISTER
Definition: oleauto.h:926
enum tagREGKIND REGKIND
const GUID IID_IPersistFile
long LONG
Definition: pedump.c:60
parse_state
Definition: pop3transport.c:40
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define err(...)
#define delete_tree(r, p, s)
Definition: reg_test.h:67
#define open_key(r, p, s, k)
Definition: reg_test.h:49
#define delete_value(k, n)
Definition: reg_test.h:74
#define delete_key(r, p, s)
Definition: reg_test.h:64
static unsigned int file_size
Definition: regtests2xml.c:47
static FILE * out
Definition: regtests2xml.c:44
INT replace(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], DWORD dwFlags, BOOL *doMore)
Definition: replace.c:38
#define calloc
Definition: rosglue.h:14
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
BOOL WINAPI ControlService(SC_HANDLE hService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:622
BOOL WINAPI QueryServiceStatusEx(SC_HANDLE hService, SC_STATUS_TYPE InfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPDWORD pcbBytesNeeded)
Definition: scm.c:2887
SC_HANDLE WINAPI OpenServiceW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2160
BOOL WINAPI GetServiceDisplayNameW(SC_HANDLE hSCManager, LPCWSTR lpServiceName, LPWSTR lpDisplayName, LPDWORD lpcchBuffer)
Definition: scm.c:1684
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 StartServiceW(SC_HANDLE hService, DWORD dwNumServiceArgs, LPCWSTR *lpServiceArgVectors)
Definition: scm.c:2980
BOOL WINAPI ChangeServiceConfig2W(SC_HANDLE hService, DWORD dwInfoLevel, LPVOID lpInfo)
Definition: scm.c:305
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:580
BOOL WINAPI EnumDependentServicesW(SC_HANDLE hService, DWORD dwServiceState, LPENUM_SERVICE_STATUSW lpServices, DWORD cbBufSize, LPDWORD pcbBytesNeeded, LPDWORD lpServicesReturned)
Definition: scm.c:1033
#define REG_DWORD
Definition: sdbapi.c:596
#define WINAPIV
Definition: sdbpapi.h:64
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
_CRTIMP wchar_t *__cdecl wcsupr(_Inout_z_ wchar_t *_Str)
_Check_return_ _CRTIMP wchar_t *__cdecl wcsdup(_In_z_ const wchar_t *_Str)
DWORD LCID
Definition: nls.h:13
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define memset(x, y, z)
Definition: compat.h:39
#define args
Definition: format.c:66
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
WORD wYear
Definition: winbase.h:929
WORD wMonth
Definition: winbase.h:930
WORD wDay
Definition: winbase.h:932
Definition: match.c:390
Definition: cookie.c:202
Definition: ftp_var.h:139
Definition: inflate.c:139
HANDLE started
Definition: action.c:51
HANDLE thread
Definition: action.c:53
HANDLE stopped
Definition: action.c:52
Definition: fci.c:127
struct list entry
Definition: fci.c:128
Definition: dsound.c:943
Definition: fci.c:116
struct list entry
Definition: fci.c:117
DWORD thread
Definition: http.c:7380
Definition: copy.c:22
Definition: tftpd.h:60
Definition: name.c:39
Definition: getopt.h:109
MSIFEATURE * feature
Definition: action.c:853
MSIPACKAGE * package
Definition: action.c:852
Definition: tftpd.h:86
Definition: parser.c:56
Definition: ps.c:97
struct list entry
Definition: msipriv.h:553
MSICOMPONENT * component
Definition: msipriv.h:554
LPWSTR display_name
Definition: msipriv.h:516
LPWSTR application
Definition: msipriv.h:514
unsigned int hasLocalFeature
Definition: msipriv.h:545
unsigned int hasAdvertisedFeature
Definition: msipriv.h:544
unsigned int anyAbsent
Definition: msipriv.h:543
LPWSTR Component
Definition: msipriv.h:524
unsigned int updated
Definition: msipriv.h:548
unsigned int hasSourceFeature
Definition: msipriv.h:546
BOOL ForceLocalState
Definition: msipriv.h:533
INSTALLSTATE Action
Definition: msipriv.h:532
INSTALLSTATE ActionRequest
Definition: msipriv.h:531
unsigned int added
Definition: msipriv.h:547
LPWSTR ComponentId
Definition: msipriv.h:525
MSIASSEMBLY * assembly
Definition: msipriv.h:540
LPWSTR KeyPath
Definition: msipriv.h:529
LPWSTR Condition
Definition: msipriv.h:528
INSTALLSTATE Installed
Definition: msipriv.h:530
LPWSTR Directory
Definition: msipriv.h:526
LPWSTR FullKeypath
Definition: msipriv.h:538
LPWSTR tempfolder
Definition: msipriv.h:114
string_table * strings
Definition: msipriv.h:110
LPWSTR path
Definition: msipriv.h:112
INSTALLSTATE Action
Definition: msipriv.h:505
MSIFILE * File
Definition: msipriv.h:626
WCHAR * path
Definition: msipriv.h:632
LPWSTR File
Definition: msipriv.h:606
MSICOMPONENT * Component
Definition: msipriv.h:607
LPWSTR TargetPath
Definition: msipriv.h:617
LPWSTR FileName
Definition: msipriv.h:608
DWORD context
Definition: msipriv.h:169
DWORD options
Definition: msipriv.h:170
LPWSTR volume_label
Definition: msipriv.h:172
LPWSTR disk_prompt
Definition: msipriv.h:173
DWORD disk_id
Definition: msipriv.h:171
BOOL ExecuteSequenceRun
Definition: msipriv.h:437
UINT InWhatSequence
Definition: msipriv.h:438
BOOL delete_on_close
Definition: msipriv.h:450
struct list features
Definition: msipriv.h:402
struct list files
Definition: msipriv.h:403
MSIDATABASE * db
Definition: msipriv.h:394
enum platform platform
Definition: msipriv.h:396
struct list folders
Definition: msipriv.h:406
UINT num_langids
Definition: msipriv.h:397
struct list components
Definition: msipriv.h:401
LPWSTR ProductCode
Definition: msipriv.h:448
LPWSTR PackagePath
Definition: msipriv.h:447
INSTALLUILEVEL ui_level
Definition: msipriv.h:452
UINT action_progress_increment
Definition: msipriv.h:413
struct list sourcelist_media
Definition: msipriv.h:464
LANGID * langids
Definition: msipriv.h:398
enum script script
Definition: msipriv.h:432
MSIINSTALLCONTEXT Context
Definition: msipriv.h:459
struct list filepatches
Definition: msipriv.h:404
LPWSTR * script_actions[SCRIPT_MAX]
Definition: msipriv.h:433
unsigned char need_reboot_at_end
Definition: msipriv.h:469
LPWSTR localfile
Definition: msipriv.h:449
UINT LastActionResult
Definition: msipriv.h:412
struct list patches
Definition: msipriv.h:400
unsigned char need_rollback
Definition: msipriv.h:471
int script_actions_count[SCRIPT_MAX]
Definition: msipriv.h:434
struct list sourcelist_info
Definition: msipriv.h:463
DWORD uninstallable
Definition: msipriv.h:207
LPWSTR patchcode
Definition: msipriv.h:201
LPWSTR transforms
Definition: msipriv.h:203
MSIPATCHSTATE state
Definition: msipriv.h:206
LPWSTR localfile
Definition: msipriv.h:205
LPWSTR products
Definition: msipriv.h:202
BOOL delete_on_close
Definition: msipriv.h:208
LPWSTR filename
Definition: msipriv.h:204
MSIOBJECTHDR hdr
Definition: msipriv.h:151
DWORD dwFileVersionLS
Definition: compat.h:903
DWORD dwFileVersionMS
Definition: compat.h:902
CLSID clsid
Definition: action.c:3442
LPWSTR path
Definition: action.c:3444
LPWSTR source
Definition: action.c:3443
ITypeLib * ptLib
Definition: action.c:3445
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:637
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
int32_t INT_PTR
Definition: typedefs.h:64
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
uint64_t ULONGLONG
Definition: typedefs.h:67
pass
Definition: typegen.h:25
Definition: pdh_main.c:94
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
static const WCHAR props[]
Definition: wbemdisp.c:288
int ret
@ SYS_WIN32
Definition: widltypes.h:552
@ SYS_WIN64
Definition: widltypes.h:554
BOOL WINAPI SQLConfigDataSourceW(HWND hwndParent, WORD fRequest, LPCWSTR lpszDriver, LPCWSTR lpszAttributes)
Definition: odbccp32.c:225
BOOL WINAPI SQLInstallDriverExW(LPCWSTR lpszDriver, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:928
BOOL WINAPI SQLRemoveDriverW(LPCWSTR drivername, BOOL remove_dsn, LPDWORD usage_count)
Definition: odbccp32.c:1325
BOOL WINAPI SQLRemoveTranslatorW(const WCHAR *translator, DWORD *usage_count)
Definition: odbccp32.c:1421
BOOL WINAPI SQLInstallTranslatorExW(LPCWSTR lpszTranslator, LPCWSTR lpszPathIn, LPWSTR lpszPathOut, WORD cbPathOutMax, WORD *pcbPathOut, WORD fRequest, LPDWORD lpdwUsageCount)
Definition: odbccp32.c:1166
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define LOAD_LIBRARY_AS_DATAFILE
Definition: winbase.h:367
_In_ FLONG fl
Definition: winddi.h:1279
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
const char * description
Definition: directx.c:2497
int INSTALLSTATE
Definition: winemsi.idl:31
#define ERROR_INVALID_COMMAND_LINE
Definition: winerror.h:997
#define ERROR_INSTALL_FAILURE
Definition: winerror.h:961
#define ERROR_INSTALL_USEREXIT
Definition: winerror.h:960
#define ERROR_SERVICE_ALREADY_RUNNING
Definition: winerror.h:607
#define ERROR_INVALID_HANDLE_STATE
Definition: winerror.h:967
#define ERROR_INSTALL_PACKAGE_REJECTED
Definition: winerror.h:983
#define ERROR_SUCCESS_REBOOT_REQUIRED
Definition: winerror.h:1215
#define ERROR_INSTALL_ALREADY_RUNNING
Definition: winerror.h:976
#define ERROR_SERVICE_EXISTS
Definition: winerror.h:624
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
#define ERROR_INSTALL_SUSPEND
Definition: winerror.h:962
#define ERROR_FUNCTION_NOT_CALLED
Definition: winerror.h:984
#define ERROR_INVALID_DATA
Definition: winerror.h:116
static const char appdata[]
Definition: shdocvw.c:39
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
ACCESS_MASK REGSAM
Definition: winreg.h:69
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
#define HKEY_USERS
Definition: winreg.h:13
#define SERVICE_START
Definition: winsvc.h:57
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define SERVICE_QUERY_STATUS
Definition: winsvc.h:55
@ SC_STATUS_PROCESS_INFO
Definition: winsvc.h:119
#define SERVICE_CONFIG_DESCRIPTION
Definition: winsvc.h:65
#define SERVICE_ACTIVE
Definition: winsvc.h:50
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
#define SERVICE_STOP
Definition: winsvc.h:58
#define SERVICE_START_PENDING
Definition: winsvc.h:22
#define SERVICE_RUNNING
Definition: winsvc.h:24
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define SERVICE_ENUMERATE_DEPENDENTS
Definition: winsvc.h:56
#define SERVICES_ACTIVE_DATABASEW
Definition: winsvc.h:8
#define SC_MANAGER_ALL_ACCESS
Definition: winsvc.h:13
#define IDCANCEL
Definition: winuser.h:834
#define MB_ICONHAND
Definition: winuser.h:791
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define MB_OK
Definition: winuser.h:793
LPWSTR WINAPI CharUpperW(_Inout_ LPWSTR)
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
#define SERVICE_BOOT_START
Definition: cmtypes.h:975
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
#define SERVICE_SYSTEM_START
Definition: cmtypes.h:976
_In_ ULONG Component
Definition: potypes.h:496
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193