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