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