1 /*
2 * Implementation of the Microsoft Installer (msi.dll)
3 *
4 * Copyright 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 /* Msi top level apis directly related to installs */
22
23 #define COBJMACROS
24
25 #include <stdarg.h>
26
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "msi.h"
31 #include "msidefs.h"
32 #include "objbase.h"
33 #include "oleauto.h"
34
35 #include "msipriv.h"
36 #include "winemsi_s.h"
37 #include "wine/debug.h"
38 #include "wine/exception.h"
39
40 WINE_DEFAULT_DEBUG_CHANNEL(msi);
41
42 /***********************************************************************
43 * MsiDoActionA (MSI.@)
44 */
MsiDoActionA(MSIHANDLE hInstall,LPCSTR szAction)45 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
46 {
47 LPWSTR szwAction;
48 UINT ret;
49
50 TRACE("%s\n", debugstr_a(szAction));
51
52 szwAction = strdupAtoW(szAction);
53 if (szAction && !szwAction)
54 return ERROR_FUNCTION_FAILED;
55
56 ret = MsiDoActionW( hInstall, szwAction );
57 free( szwAction );
58 return ret;
59 }
60
61 /***********************************************************************
62 * MsiDoActionW (MSI.@)
63 */
MsiDoActionW(MSIHANDLE hInstall,LPCWSTR szAction)64 UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
65 {
66 MSIPACKAGE *package;
67 UINT ret;
68
69 TRACE("%s\n",debugstr_w(szAction));
70
71 if (!szAction)
72 return ERROR_INVALID_PARAMETER;
73
74 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
75 if (!package)
76 {
77 MSIHANDLE remote;
78
79 if (!(remote = msi_get_remote(hInstall)))
80 return ERROR_INVALID_HANDLE;
81
82 __TRY
83 {
84 ret = remote_DoAction(remote, szAction);
85 }
86 __EXCEPT(rpc_filter)
87 {
88 ret = GetExceptionCode();
89 }
90 __ENDTRY
91
92 return ret;
93 }
94
95 ret = ACTION_PerformAction(package, szAction);
96 msiobj_release( &package->hdr );
97
98 return ret;
99 }
100
101 /***********************************************************************
102 * MsiSequenceA (MSI.@)
103 */
MsiSequenceA(MSIHANDLE hInstall,LPCSTR szTable,INT iSequenceMode)104 UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode )
105 {
106 LPWSTR szwTable;
107 UINT ret;
108
109 TRACE("%s, %d\n", debugstr_a(szTable), iSequenceMode);
110
111 szwTable = strdupAtoW(szTable);
112 if (szTable && !szwTable)
113 return ERROR_FUNCTION_FAILED;
114
115 ret = MsiSequenceW( hInstall, szwTable, iSequenceMode );
116 free( szwTable );
117 return ret;
118 }
119
120 /***********************************************************************
121 * MsiSequenceW (MSI.@)
122 */
MsiSequenceW(MSIHANDLE hInstall,LPCWSTR szTable,INT iSequenceMode)123 UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode )
124 {
125 MSIPACKAGE *package;
126 UINT ret;
127
128 TRACE("%s, %d\n", debugstr_w(szTable), iSequenceMode);
129
130 if (!szTable)
131 return ERROR_INVALID_PARAMETER;
132
133 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
134 if (!package)
135 {
136 MSIHANDLE remote;
137
138 if (!(remote = msi_get_remote(hInstall)))
139 return ERROR_INVALID_HANDLE;
140
141 __TRY
142 {
143 ret = remote_Sequence(remote, szTable, iSequenceMode);
144 }
145 __EXCEPT(rpc_filter)
146 {
147 ret = GetExceptionCode();
148 }
149 __ENDTRY
150
151 return ret;
152 }
153 ret = MSI_Sequence( package, szTable );
154 msiobj_release( &package->hdr );
155 return ret;
156 }
157
msi_strcpy_to_awstring(const WCHAR * str,int len,awstring * awbuf,DWORD * sz)158 UINT msi_strcpy_to_awstring( const WCHAR *str, int len, awstring *awbuf, DWORD *sz )
159 {
160 UINT r = ERROR_SUCCESS;
161
162 if (awbuf->str.w && !sz)
163 return ERROR_INVALID_PARAMETER;
164 if (!sz)
165 return ERROR_SUCCESS;
166
167 if (len < 0) len = lstrlenW( str );
168
169 if (awbuf->unicode && awbuf->str.w)
170 {
171 memcpy( awbuf->str.w, str, min(len + 1, *sz) * sizeof(WCHAR) );
172 if (*sz && len >= *sz)
173 awbuf->str.w[*sz - 1] = 0;
174 }
175 else
176 {
177 int lenA = WideCharToMultiByte( CP_ACP, 0, str, len + 1, NULL, 0, NULL, NULL );
178 if (lenA) lenA--;
179 WideCharToMultiByte( CP_ACP, 0, str, len + 1, awbuf->str.a, *sz, NULL, NULL );
180 if (awbuf->str.a && *sz && lenA >= *sz)
181 awbuf->str.a[*sz - 1] = 0;
182 len = lenA;
183 }
184 if (awbuf->str.w && len >= *sz)
185 r = ERROR_MORE_DATA;
186 *sz = len;
187 return r;
188 }
189
msi_strncpyWtoA(const WCHAR * str,int lenW,char * buf,DWORD * sz,BOOL remote)190 UINT msi_strncpyWtoA(const WCHAR *str, int lenW, char *buf, DWORD *sz, BOOL remote)
191 {
192 UINT r = ERROR_SUCCESS;
193 DWORD lenA;
194
195 if (!sz)
196 return buf ? ERROR_INVALID_PARAMETER : ERROR_SUCCESS;
197
198 if (lenW < 0) lenW = lstrlenW(str);
199 lenA = WideCharToMultiByte(CP_ACP, 0, str, lenW + 1, NULL, 0, NULL, NULL);
200 WideCharToMultiByte(CP_ACP, 0, str, lenW + 1, buf, *sz, NULL, NULL);
201 lenA--;
202 if (buf && lenA >= *sz)
203 {
204 if (*sz) buf[*sz - 1] = 0;
205 r = ERROR_MORE_DATA;
206 }
207 if (remote && lenA >= *sz)
208 lenA *= 2;
209 *sz = lenA;
210 return r;
211 }
212
msi_strncpyW(const WCHAR * str,int len,WCHAR * buf,DWORD * sz)213 UINT msi_strncpyW(const WCHAR *str, int len, WCHAR *buf, DWORD *sz)
214 {
215 UINT r = ERROR_SUCCESS;
216
217 if (!sz)
218 return buf ? ERROR_INVALID_PARAMETER : ERROR_SUCCESS;
219
220 if (len < 0) len = lstrlenW(str);
221 if (buf)
222 memcpy(buf, str, min(len + 1, *sz) * sizeof(WCHAR));
223 if (buf && len >= *sz)
224 {
225 if (*sz) buf[*sz - 1] = 0;
226 r = ERROR_MORE_DATA;
227 }
228 *sz = len;
229 return r;
230 }
231
msi_get_target_folder(MSIPACKAGE * package,const WCHAR * name)232 const WCHAR *msi_get_target_folder( MSIPACKAGE *package, const WCHAR *name )
233 {
234 MSIFOLDER *folder = msi_get_loaded_folder( package, name );
235
236 if (!folder) return NULL;
237 if (!folder->ResolvedTarget)
238 {
239 MSIFOLDER *parent = folder;
240 while (parent->Parent && wcscmp( parent->Parent, parent->Directory ))
241 {
242 parent = msi_get_loaded_folder( package, parent->Parent );
243 }
244 msi_resolve_target_folder( package, parent->Directory, TRUE );
245 }
246 return folder->ResolvedTarget;
247 }
248
249 /***********************************************************************
250 * MsiGetTargetPathA (MSI.@)
251 */
MsiGetTargetPathA(MSIHANDLE hinst,const char * folder,char * buf,DWORD * sz)252 UINT WINAPI MsiGetTargetPathA(MSIHANDLE hinst, const char *folder, char *buf, DWORD *sz)
253 {
254 MSIPACKAGE *package;
255 const WCHAR *path;
256 WCHAR *folderW;
257 UINT r;
258
259 TRACE("%s %p %p\n", debugstr_a(folder), buf, sz);
260
261 if (!folder)
262 return ERROR_INVALID_PARAMETER;
263
264 if (!(folderW = strdupAtoW(folder)))
265 return ERROR_OUTOFMEMORY;
266
267 package = msihandle2msiinfo(hinst, MSIHANDLETYPE_PACKAGE);
268 if (!package)
269 {
270 WCHAR *path = NULL;
271 MSIHANDLE remote;
272
273 if (!(remote = msi_get_remote(hinst)))
274 {
275 free(folderW);
276 return ERROR_INVALID_HANDLE;
277 }
278
279 __TRY
280 {
281 r = remote_GetTargetPath(remote, folderW, &path);
282 }
283 __EXCEPT(rpc_filter)
284 {
285 r = GetExceptionCode();
286 }
287 __ENDTRY
288
289 if (!r)
290 r = msi_strncpyWtoA(path, -1, buf, sz, TRUE);
291
292 midl_user_free(path);
293 free(folderW);
294 return r;
295 }
296
297 path = msi_get_target_folder(package, folderW);
298 if (path)
299 r = msi_strncpyWtoA(path, -1, buf, sz, FALSE);
300 else
301 r = ERROR_DIRECTORY;
302
303 free(folderW);
304 msiobj_release(&package->hdr);
305 return r;
306 }
307
308 /***********************************************************************
309 * MsiGetTargetPathW (MSI.@)
310 */
MsiGetTargetPathW(MSIHANDLE hinst,const WCHAR * folder,WCHAR * buf,DWORD * sz)311 UINT WINAPI MsiGetTargetPathW(MSIHANDLE hinst, const WCHAR *folder, WCHAR *buf, DWORD *sz)
312 {
313 MSIPACKAGE *package;
314 const WCHAR *path;
315 UINT r;
316
317 TRACE("%s %p %p\n", debugstr_w(folder), buf, sz);
318
319 if (!folder)
320 return ERROR_INVALID_PARAMETER;
321
322 package = msihandle2msiinfo(hinst, MSIHANDLETYPE_PACKAGE);
323 if (!package)
324 {
325 WCHAR *path = NULL;
326 MSIHANDLE remote;
327
328 if (!(remote = msi_get_remote(hinst)))
329 return ERROR_INVALID_HANDLE;
330
331 __TRY
332 {
333 r = remote_GetTargetPath(remote, folder, &path);
334 }
335 __EXCEPT(rpc_filter)
336 {
337 r = GetExceptionCode();
338 }
339 __ENDTRY
340
341 if (!r)
342 r = msi_strncpyW(path, -1, buf, sz);
343
344 midl_user_free(path);
345 return r;
346 }
347
348 path = msi_get_target_folder(package, folder);
349 if (path)
350 r = msi_strncpyW(path, -1, buf, sz);
351 else
352 r = ERROR_DIRECTORY;
353
354 msiobj_release(&package->hdr);
355 return r;
356 }
357
get_source_root(MSIPACKAGE * package)358 static WCHAR *get_source_root( MSIPACKAGE *package )
359 {
360 msi_set_sourcedir_props( package, FALSE );
361 return msi_dup_property( package->db, L"SourceDir" );
362 }
363
msi_resolve_source_folder(MSIPACKAGE * package,const WCHAR * name,MSIFOLDER ** folder)364 WCHAR *msi_resolve_source_folder( MSIPACKAGE *package, const WCHAR *name, MSIFOLDER **folder )
365 {
366 MSIFOLDER *f;
367 LPWSTR p, path = NULL, parent;
368
369 TRACE("working to resolve %s\n", debugstr_w(name));
370
371 if (!wcscmp( name, L"SourceDir" )) name = L"TARGETDIR";
372 if (!(f = msi_get_loaded_folder( package, name ))) return NULL;
373
374 /* special resolving for root dir */
375 if (!wcscmp( name, L"TARGETDIR" ) && !f->ResolvedSource)
376 {
377 f->ResolvedSource = get_source_root( package );
378 }
379 if (folder) *folder = f;
380 if (f->ResolvedSource)
381 {
382 path = wcsdup( f->ResolvedSource );
383 TRACE(" already resolved to %s\n", debugstr_w(path));
384 return path;
385 }
386 if (!f->Parent) return path;
387 parent = f->Parent;
388 TRACE(" ! parent is %s\n", debugstr_w(parent));
389
390 p = msi_resolve_source_folder( package, parent, NULL );
391
392 if (package->WordCount & msidbSumInfoSourceTypeCompressed)
393 path = get_source_root( package );
394 else if (package->WordCount & msidbSumInfoSourceTypeSFN)
395 path = msi_build_directory_name( 3, p, f->SourceShortPath, NULL );
396 else
397 path = msi_build_directory_name( 3, p, f->SourceLongPath, NULL );
398
399 TRACE("-> %s\n", debugstr_w(path));
400 f->ResolvedSource = wcsdup( path );
401 free( p );
402
403 return path;
404 }
405
406 /***********************************************************************
407 * MsiGetSourcePathA (MSI.@)
408 */
MsiGetSourcePathA(MSIHANDLE hinst,const char * folder,char * buf,DWORD * sz)409 UINT WINAPI MsiGetSourcePathA(MSIHANDLE hinst, const char *folder, char *buf, DWORD *sz)
410 {
411 MSIPACKAGE *package;
412 WCHAR *path, *folderW;
413 UINT r;
414
415 TRACE("%s %p %p\n", debugstr_a(folder), buf, sz);
416
417 if (!folder)
418 return ERROR_INVALID_PARAMETER;
419
420 if (!(folderW = strdupAtoW(folder)))
421 return ERROR_OUTOFMEMORY;
422
423 package = msihandle2msiinfo(hinst, MSIHANDLETYPE_PACKAGE);
424 if (!package)
425 {
426 WCHAR *path = NULL;
427 MSIHANDLE remote;
428
429 if (!(remote = msi_get_remote(hinst)))
430 {
431 free(folderW);
432 return ERROR_INVALID_HANDLE;
433 }
434
435 __TRY
436 {
437 r = remote_GetSourcePath(remote, folderW, &path);
438 }
439 __EXCEPT(rpc_filter)
440 {
441 r = GetExceptionCode();
442 }
443 __ENDTRY
444
445 if (!r)
446 r = msi_strncpyWtoA(path, -1, buf, sz, TRUE);
447
448 midl_user_free(path);
449 free(folderW);
450 return r;
451 }
452
453 path = msi_resolve_source_folder(package, folderW, NULL);
454 if (path)
455 r = msi_strncpyWtoA(path, -1, buf, sz, FALSE);
456 else
457 r = ERROR_DIRECTORY;
458
459 free(path);
460 free(folderW);
461 msiobj_release(&package->hdr);
462 return r;
463 }
464
465 /***********************************************************************
466 * MsiGetSourcePathW (MSI.@)
467 */
MsiGetSourcePathW(MSIHANDLE hinst,const WCHAR * folder,WCHAR * buf,DWORD * sz)468 UINT WINAPI MsiGetSourcePathW(MSIHANDLE hinst, const WCHAR *folder, WCHAR *buf, DWORD *sz)
469 {
470 MSIPACKAGE *package;
471 WCHAR *path;
472 UINT r;
473
474 TRACE("%s %p %p\n", debugstr_w(folder), buf, sz);
475
476 if (!folder)
477 return ERROR_INVALID_PARAMETER;
478
479 package = msihandle2msiinfo(hinst, MSIHANDLETYPE_PACKAGE);
480 if (!package)
481 {
482 WCHAR *path = NULL;
483 MSIHANDLE remote;
484
485 if (!(remote = msi_get_remote(hinst)))
486 return ERROR_INVALID_HANDLE;
487
488 __TRY
489 {
490 r = remote_GetSourcePath(remote, folder, &path);
491 }
492 __EXCEPT(rpc_filter)
493 {
494 r = GetExceptionCode();
495 }
496 __ENDTRY
497
498 if (!r)
499 r = msi_strncpyW(path, -1, buf, sz);
500
501 midl_user_free(path);
502 return r;
503 }
504
505 path = msi_resolve_source_folder(package, folder, NULL);
506 if (path)
507 r = msi_strncpyW(path, -1, buf, sz);
508 else
509 r = ERROR_DIRECTORY;
510
511 free(path);
512 msiobj_release(&package->hdr);
513 return r;
514 }
515
516 /***********************************************************************
517 * MsiSetTargetPathA (MSI.@)
518 */
MsiSetTargetPathA(MSIHANDLE hInstall,LPCSTR szFolder,LPCSTR szFolderPath)519 UINT WINAPI MsiSetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
520 LPCSTR szFolderPath )
521 {
522 LPWSTR szwFolder = NULL, szwFolderPath = NULL;
523 UINT rc = ERROR_OUTOFMEMORY;
524
525 if ( !szFolder || !szFolderPath )
526 return ERROR_INVALID_PARAMETER;
527
528 szwFolder = strdupAtoW(szFolder);
529 szwFolderPath = strdupAtoW(szFolderPath);
530 if (!szwFolder || !szwFolderPath)
531 goto end;
532
533 rc = MsiSetTargetPathW( hInstall, szwFolder, szwFolderPath );
534
535 end:
536 free(szwFolder);
537 free(szwFolderPath);
538
539 return rc;
540 }
541
set_target_path(MSIPACKAGE * package,MSIFOLDER * folder,const WCHAR * path)542 static void set_target_path( MSIPACKAGE *package, MSIFOLDER *folder, const WCHAR *path )
543 {
544 FolderList *fl;
545 MSIFOLDER *child;
546 WCHAR *target_path;
547
548 if (!(target_path = msi_normalize_path( path ))) return;
549 if (wcscmp( target_path, folder->ResolvedTarget ))
550 {
551 free( folder->ResolvedTarget );
552 folder->ResolvedTarget = target_path;
553 msi_set_property( package->db, folder->Directory, folder->ResolvedTarget, -1 );
554
555 LIST_FOR_EACH_ENTRY( fl, &folder->children, FolderList, entry )
556 {
557 child = fl->folder;
558 msi_resolve_target_folder( package, child->Directory, FALSE );
559 }
560 }
561 else free( target_path );
562 }
563
MSI_SetTargetPathW(MSIPACKAGE * package,LPCWSTR szFolder,LPCWSTR szFolderPath)564 UINT MSI_SetTargetPathW( MSIPACKAGE *package, LPCWSTR szFolder, LPCWSTR szFolderPath )
565 {
566 DWORD attrib;
567 MSIFOLDER *folder;
568 MSIFILE *file;
569
570 TRACE("%p %s %s\n", package, debugstr_w(szFolder), debugstr_w(szFolderPath));
571
572 attrib = msi_get_file_attributes( package, szFolderPath );
573 /* native MSI tests writeability by making temporary files at each drive */
574 if (attrib != INVALID_FILE_ATTRIBUTES &&
575 (attrib & FILE_ATTRIBUTE_OFFLINE || attrib & FILE_ATTRIBUTE_READONLY))
576 {
577 return ERROR_FUNCTION_FAILED;
578 }
579 if (!(folder = msi_get_loaded_folder( package, szFolder ))) return ERROR_DIRECTORY;
580
581 set_target_path( package, folder, szFolderPath );
582
583 LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
584 {
585 const WCHAR *dir;
586 MSICOMPONENT *comp = file->Component;
587
588 if (!comp->Enabled || msi_is_global_assembly( comp )) continue;
589
590 dir = msi_get_target_folder( package, comp->Directory );
591 free( file->TargetPath );
592 file->TargetPath = msi_build_directory_name( 2, dir, file->FileName );
593 }
594 return ERROR_SUCCESS;
595 }
596
597 /***********************************************************************
598 * MsiSetTargetPathW (MSI.@)
599 */
MsiSetTargetPathW(MSIHANDLE hInstall,LPCWSTR szFolder,LPCWSTR szFolderPath)600 UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder,
601 LPCWSTR szFolderPath)
602 {
603 MSIPACKAGE *package;
604 UINT ret;
605
606 TRACE("%s %s\n",debugstr_w(szFolder),debugstr_w(szFolderPath));
607
608 if ( !szFolder || !szFolderPath )
609 return ERROR_INVALID_PARAMETER;
610
611 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
612 if (!package)
613 {
614 MSIHANDLE remote;
615
616 if (!(remote = msi_get_remote(hInstall)))
617 return ERROR_INVALID_HANDLE;
618
619 __TRY
620 {
621 ret = remote_SetTargetPath(remote, szFolder, szFolderPath);
622 }
623 __EXCEPT(rpc_filter)
624 {
625 ret = GetExceptionCode();
626 }
627 __ENDTRY
628
629 return ret;
630 }
631
632 ret = MSI_SetTargetPathW( package, szFolder, szFolderPath );
633 msiobj_release( &package->hdr );
634 return ret;
635 }
636
637 /***********************************************************************
638 * MsiGetMode (MSI.@)
639 *
640 * Returns an internal installer state (if it is running in a mode iRunMode)
641 *
642 * PARAMS
643 * hInstall [I] Handle to the installation
644 * hRunMode [I] Checking run mode
645 * MSIRUNMODE_ADMIN Administrative mode
646 * MSIRUNMODE_ADVERTISE Advertisement mode
647 * MSIRUNMODE_MAINTENANCE Maintenance mode
648 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
649 * MSIRUNMODE_LOGENABLED Log file is writing
650 * MSIRUNMODE_OPERATIONS Operations in progress??
651 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
652 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
653 * MSIRUNMODE_CABINET Files from cabinet are installed
654 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
655 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
656 * MSIRUNMODE_RESERVED11 Reserved
657 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
658 * MSIRUNMODE_ZAWENABLED Demand installation is supported
659 * MSIRUNMODE_RESERVED14 Reserved
660 * MSIRUNMODE_RESERVED15 Reserved
661 * MSIRUNMODE_SCHEDULED called from install script
662 * MSIRUNMODE_ROLLBACK called from rollback script
663 * MSIRUNMODE_COMMIT called from commit script
664 *
665 * RETURNS
666 * In the state: TRUE
667 * Not in the state: FALSE
668 *
669 */
MsiGetMode(MSIHANDLE hInstall,MSIRUNMODE iRunMode)670 BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
671 {
672 MSIPACKAGE *package;
673 BOOL r = FALSE;
674
675 TRACE( "%lu, %d\n", hInstall, iRunMode );
676
677 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
678 if (!package)
679 {
680 MSIHANDLE remote;
681
682 if (!(remote = msi_get_remote(hInstall)))
683 return FALSE;
684
685 __TRY
686 {
687 r = remote_GetMode(remote, iRunMode);
688 }
689 __EXCEPT(rpc_filter)
690 {
691 r = FALSE;
692 }
693 __ENDTRY
694
695 return r;
696 }
697
698 switch (iRunMode)
699 {
700 case MSIRUNMODE_ADMIN:
701 FIXME("no support for administrative installs\n");
702 break;
703
704 case MSIRUNMODE_ADVERTISE:
705 FIXME("no support for advertised installs\n");
706 break;
707
708 case MSIRUNMODE_WINDOWS9X:
709 if (GetVersion() & 0x80000000)
710 r = TRUE;
711 break;
712
713 case MSIRUNMODE_OPERATIONS:
714 case MSIRUNMODE_RESERVED11:
715 case MSIRUNMODE_RESERVED14:
716 case MSIRUNMODE_RESERVED15:
717 break;
718
719 case MSIRUNMODE_SCHEDULED:
720 r = package->scheduled_action_running;
721 break;
722
723 case MSIRUNMODE_ROLLBACK:
724 r = package->rollback_action_running;
725 break;
726
727 case MSIRUNMODE_COMMIT:
728 r = package->commit_action_running;
729 break;
730
731 case MSIRUNMODE_MAINTENANCE:
732 r = msi_get_property_int( package->db, L"Installed", 0 ) != 0;
733 break;
734
735 case MSIRUNMODE_ROLLBACKENABLED:
736 r = msi_get_property_int( package->db, L"RollbackDisabled", 0 ) == 0;
737 break;
738
739 case MSIRUNMODE_REBOOTATEND:
740 r = package->need_reboot_at_end;
741 break;
742
743 case MSIRUNMODE_REBOOTNOW:
744 r = package->need_reboot_now;
745 break;
746
747 case MSIRUNMODE_LOGENABLED:
748 r = (package->log_file != INVALID_HANDLE_VALUE);
749 break;
750
751 default:
752 FIXME("unimplemented run mode: %d\n", iRunMode);
753 r = TRUE;
754 }
755
756 msiobj_release( &package->hdr );
757 return r;
758 }
759
760 /***********************************************************************
761 * MsiSetMode (MSI.@)
762 */
MsiSetMode(MSIHANDLE hInstall,MSIRUNMODE iRunMode,BOOL fState)763 UINT WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState)
764 {
765 MSIPACKAGE *package;
766 UINT r;
767
768 TRACE( "%lu, %d, %d\n", hInstall, iRunMode, fState );
769
770 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
771 if (!package)
772 {
773 MSIHANDLE remote;
774
775 if (!(remote = msi_get_remote(hInstall)))
776 return FALSE;
777
778 __TRY
779 {
780 r = remote_SetMode(remote, iRunMode, fState);
781 }
782 __EXCEPT(rpc_filter)
783 {
784 r = GetExceptionCode();
785 }
786 __ENDTRY
787
788 return r;
789 }
790
791 switch (iRunMode)
792 {
793 case MSIRUNMODE_REBOOTATEND:
794 package->need_reboot_at_end = (fState != 0);
795 r = ERROR_SUCCESS;
796 break;
797
798 case MSIRUNMODE_REBOOTNOW:
799 package->need_reboot_now = (fState != 0);
800 r = ERROR_SUCCESS;
801 break;
802
803 default:
804 r = ERROR_ACCESS_DENIED;
805 }
806
807 msiobj_release( &package->hdr );
808 return r;
809 }
810
811 /***********************************************************************
812 * MsiSetFeatureStateA (MSI.@)
813 *
814 * According to the docs, when this is called it immediately recalculates
815 * all the component states as well
816 */
MsiSetFeatureStateA(MSIHANDLE hInstall,LPCSTR szFeature,INSTALLSTATE iState)817 UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
818 INSTALLSTATE iState)
819 {
820 LPWSTR szwFeature = NULL;
821 UINT rc;
822
823 szwFeature = strdupAtoW(szFeature);
824
825 rc = MsiSetFeatureStateW(hInstall,szwFeature, iState);
826
827 free(szwFeature);
828
829 return rc;
830 }
831
832 /* update component state based on a feature change */
ACTION_UpdateComponentStates(MSIPACKAGE * package,MSIFEATURE * feature)833 void ACTION_UpdateComponentStates( MSIPACKAGE *package, MSIFEATURE *feature )
834 {
835 INSTALLSTATE newstate;
836 ComponentList *cl;
837
838 newstate = feature->ActionRequest;
839 if (newstate == INSTALLSTATE_ABSENT) newstate = INSTALLSTATE_UNKNOWN;
840
841 LIST_FOR_EACH_ENTRY(cl, &feature->Components, ComponentList, entry)
842 {
843 MSICOMPONENT *component = cl->component;
844
845 if (!component->Enabled) continue;
846
847 TRACE("Modifying (%d): Component %s (Installed %d, Action %d, Request %d)\n",
848 newstate, debugstr_w(component->Component), component->Installed,
849 component->Action, component->ActionRequest);
850
851 if (newstate == INSTALLSTATE_LOCAL)
852 {
853 component->Action = INSTALLSTATE_LOCAL;
854 component->ActionRequest = INSTALLSTATE_LOCAL;
855 }
856 else
857 {
858 ComponentList *clist;
859 MSIFEATURE *f;
860
861 component->hasLocalFeature = FALSE;
862
863 component->Action = newstate;
864 component->ActionRequest = newstate;
865 /* if any other feature wants it local we need to set it local */
866 LIST_FOR_EACH_ENTRY(f, &package->features, MSIFEATURE, entry)
867 {
868 if ( f->ActionRequest != INSTALLSTATE_LOCAL &&
869 f->ActionRequest != INSTALLSTATE_SOURCE )
870 {
871 continue;
872 }
873 LIST_FOR_EACH_ENTRY(clist, &f->Components, ComponentList, entry)
874 {
875 if (clist->component == component &&
876 (f->ActionRequest == INSTALLSTATE_LOCAL ||
877 f->ActionRequest == INSTALLSTATE_SOURCE))
878 {
879 TRACE("Saved by %s\n", debugstr_w(f->Feature));
880 component->hasLocalFeature = TRUE;
881
882 if (component->Attributes & msidbComponentAttributesOptional)
883 {
884 if (f->Attributes & msidbFeatureAttributesFavorSource)
885 {
886 component->Action = INSTALLSTATE_SOURCE;
887 component->ActionRequest = INSTALLSTATE_SOURCE;
888 }
889 else
890 {
891 component->Action = INSTALLSTATE_LOCAL;
892 component->ActionRequest = INSTALLSTATE_LOCAL;
893 }
894 }
895 else if (component->Attributes & msidbComponentAttributesSourceOnly)
896 {
897 component->Action = INSTALLSTATE_SOURCE;
898 component->ActionRequest = INSTALLSTATE_SOURCE;
899 }
900 else
901 {
902 component->Action = INSTALLSTATE_LOCAL;
903 component->ActionRequest = INSTALLSTATE_LOCAL;
904 }
905 }
906 }
907 }
908 }
909 TRACE("Result (%d): Component %s (Installed %d, Action %d, Request %d)\n",
910 newstate, debugstr_w(component->Component), component->Installed,
911 component->Action, component->ActionRequest);
912 }
913 }
914
MSI_SetFeatureStateW(MSIPACKAGE * package,LPCWSTR szFeature,INSTALLSTATE iState)915 UINT MSI_SetFeatureStateW( MSIPACKAGE *package, LPCWSTR szFeature, INSTALLSTATE iState )
916 {
917 UINT rc = ERROR_SUCCESS;
918 MSIFEATURE *feature, *child;
919
920 TRACE("%s %i\n", debugstr_w(szFeature), iState);
921
922 feature = msi_get_loaded_feature( package, szFeature );
923 if (!feature)
924 return ERROR_UNKNOWN_FEATURE;
925
926 if (iState == INSTALLSTATE_ADVERTISED &&
927 feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
928 return ERROR_FUNCTION_FAILED;
929
930 feature->ActionRequest = iState;
931
932 ACTION_UpdateComponentStates( package, feature );
933
934 /* update all the features that are children of this feature */
935 LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry )
936 {
937 if (child->Feature_Parent && !wcscmp( szFeature, child->Feature_Parent ))
938 MSI_SetFeatureStateW(package, child->Feature, iState);
939 }
940
941 return rc;
942 }
943
944 /***********************************************************************
945 * MsiSetFeatureStateW (MSI.@)
946 */
MsiSetFeatureStateW(MSIHANDLE hInstall,LPCWSTR szFeature,INSTALLSTATE iState)947 UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
948 INSTALLSTATE iState)
949 {
950 MSIPACKAGE* package;
951 UINT rc = ERROR_SUCCESS;
952
953 TRACE("%s %i\n",debugstr_w(szFeature), iState);
954
955 if (!szFeature)
956 return ERROR_UNKNOWN_FEATURE;
957
958 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
959 if (!package)
960 {
961 MSIHANDLE remote;
962
963 if (!(remote = msi_get_remote(hInstall)))
964 return ERROR_INVALID_HANDLE;
965
966 __TRY
967 {
968 rc = remote_SetFeatureState(remote, szFeature, iState);
969 }
970 __EXCEPT(rpc_filter)
971 {
972 rc = GetExceptionCode();
973 }
974 __ENDTRY
975
976 return rc;
977 }
978
979 rc = MSI_SetFeatureStateW(package,szFeature,iState);
980
981 msiobj_release( &package->hdr );
982 return rc;
983 }
984
985 /***********************************************************************
986 * MsiSetFeatureAttributesA (MSI.@)
987 */
MsiSetFeatureAttributesA(MSIHANDLE handle,LPCSTR feature,DWORD attrs)988 UINT WINAPI MsiSetFeatureAttributesA( MSIHANDLE handle, LPCSTR feature, DWORD attrs )
989 {
990 UINT r;
991 WCHAR *featureW = NULL;
992
993 TRACE( "%lu, %s, %#lx\n", handle, debugstr_a(feature), attrs );
994
995 if (feature && !(featureW = strdupAtoW( feature ))) return ERROR_OUTOFMEMORY;
996
997 r = MsiSetFeatureAttributesW( handle, featureW, attrs );
998 free( featureW );
999 return r;
1000 }
1001
unmap_feature_attributes(DWORD attrs)1002 static DWORD unmap_feature_attributes( DWORD attrs )
1003 {
1004 DWORD ret = 0;
1005
1006 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORLOCAL) ret = msidbFeatureAttributesFavorLocal;
1007 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORSOURCE) ret |= msidbFeatureAttributesFavorSource;
1008 if (attrs & INSTALLFEATUREATTRIBUTE_FOLLOWPARENT) ret |= msidbFeatureAttributesFollowParent;
1009 if (attrs & INSTALLFEATUREATTRIBUTE_FAVORADVERTISE) ret |= msidbFeatureAttributesFavorAdvertise;
1010 if (attrs & INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE) ret |= msidbFeatureAttributesDisallowAdvertise;
1011 if (attrs & INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE) ret |= msidbFeatureAttributesNoUnsupportedAdvertise;
1012 return ret;
1013 }
1014
1015 /***********************************************************************
1016 * MsiSetFeatureAttributesW (MSI.@)
1017 */
MsiSetFeatureAttributesW(MSIHANDLE handle,LPCWSTR name,DWORD attrs)1018 UINT WINAPI MsiSetFeatureAttributesW( MSIHANDLE handle, LPCWSTR name, DWORD attrs )
1019 {
1020 MSIPACKAGE *package;
1021 MSIFEATURE *feature;
1022 WCHAR *costing;
1023
1024 TRACE( "%lu, %s, %#lx\n", handle, debugstr_w(name), attrs );
1025
1026 if (!name || !name[0]) return ERROR_UNKNOWN_FEATURE;
1027
1028 if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE )))
1029 return ERROR_INVALID_HANDLE;
1030
1031 costing = msi_dup_property( package->db, L"CostingComplete" );
1032 if (!costing || !wcscmp( costing, L"1" ))
1033 {
1034 free( costing );
1035 msiobj_release( &package->hdr );
1036 return ERROR_FUNCTION_FAILED;
1037 }
1038 free( costing );
1039 if (!(feature = msi_get_loaded_feature( package, name )))
1040 {
1041 msiobj_release( &package->hdr );
1042 return ERROR_UNKNOWN_FEATURE;
1043 }
1044 feature->Attributes = unmap_feature_attributes( attrs );
1045 msiobj_release( &package->hdr );
1046 return ERROR_SUCCESS;
1047 }
1048
1049 /***********************************************************************
1050 * MsiGetFeatureStateA (MSI.@)
1051 */
MsiGetFeatureStateA(MSIHANDLE hInstall,LPCSTR szFeature,INSTALLSTATE * piInstalled,INSTALLSTATE * piAction)1052 UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
1053 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1054 {
1055 LPWSTR szwFeature = NULL;
1056 UINT rc;
1057
1058 if (szFeature && !(szwFeature = strdupAtoW(szFeature))) return ERROR_OUTOFMEMORY;
1059
1060 rc = MsiGetFeatureStateW(hInstall, szwFeature, piInstalled, piAction);
1061 free(szwFeature);
1062 return rc;
1063 }
1064
MSI_GetFeatureStateW(MSIPACKAGE * package,LPCWSTR szFeature,INSTALLSTATE * piInstalled,INSTALLSTATE * piAction)1065 UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPCWSTR szFeature,
1066 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1067 {
1068 MSIFEATURE *feature;
1069
1070 feature = msi_get_loaded_feature(package,szFeature);
1071 if (!feature)
1072 return ERROR_UNKNOWN_FEATURE;
1073
1074 if (piInstalled)
1075 *piInstalled = feature->Installed;
1076
1077 if (piAction)
1078 *piAction = feature->ActionRequest;
1079
1080 TRACE("returning %i %i\n", feature->Installed, feature->ActionRequest);
1081
1082 return ERROR_SUCCESS;
1083 }
1084
1085 /***********************************************************************
1086 * MsiGetFeatureStateW (MSI.@)
1087 */
MsiGetFeatureStateW(MSIHANDLE hInstall,const WCHAR * szFeature,INSTALLSTATE * piInstalled,INSTALLSTATE * piAction)1088 UINT WINAPI MsiGetFeatureStateW( MSIHANDLE hInstall, const WCHAR *szFeature, INSTALLSTATE *piInstalled,
1089 INSTALLSTATE *piAction )
1090 {
1091 MSIPACKAGE* package;
1092 UINT ret;
1093
1094 TRACE( "%lu, %s, %p, %p\n", hInstall, debugstr_w(szFeature), piInstalled, piAction );
1095
1096 if (!szFeature)
1097 return ERROR_UNKNOWN_FEATURE;
1098
1099 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1100 if (!package)
1101 {
1102 MSIHANDLE remote;
1103
1104 if (!(remote = msi_get_remote(hInstall)))
1105 return ERROR_INVALID_HANDLE;
1106
1107 __TRY
1108 {
1109 ret = remote_GetFeatureState(remote, szFeature, piInstalled, piAction);
1110 }
1111 __EXCEPT(rpc_filter)
1112 {
1113 ret = GetExceptionCode();
1114 }
1115 __ENDTRY
1116
1117 return ret;
1118 }
1119
1120 ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction);
1121 msiobj_release( &package->hdr );
1122 return ret;
1123 }
1124
1125 /***********************************************************************
1126 * MsiGetFeatureCostA (MSI.@)
1127 */
MsiGetFeatureCostA(MSIHANDLE hInstall,LPCSTR szFeature,MSICOSTTREE iCostTree,INSTALLSTATE iState,LPINT piCost)1128 UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature,
1129 MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
1130 {
1131 LPWSTR szwFeature = NULL;
1132 UINT rc;
1133
1134 szwFeature = strdupAtoW(szFeature);
1135
1136 rc = MsiGetFeatureCostW(hInstall, szwFeature, iCostTree, iState, piCost);
1137
1138 free(szwFeature);
1139
1140 return rc;
1141 }
1142
feature_cost(MSIFEATURE * feature)1143 static INT feature_cost( MSIFEATURE *feature )
1144 {
1145 INT cost = 0;
1146 ComponentList *cl;
1147
1148 LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
1149 {
1150 cost += cl->component->cost;
1151 }
1152 return cost;
1153 }
1154
MSI_GetFeatureCost(MSIPACKAGE * package,MSIFEATURE * feature,MSICOSTTREE tree,INSTALLSTATE state,LPINT cost)1155 UINT MSI_GetFeatureCost( MSIPACKAGE *package, MSIFEATURE *feature, MSICOSTTREE tree,
1156 INSTALLSTATE state, LPINT cost )
1157 {
1158 TRACE("%s, %u, %d, %p\n", debugstr_w(feature->Feature), tree, state, cost);
1159
1160 *cost = 0;
1161 switch (tree)
1162 {
1163 case MSICOSTTREE_CHILDREN:
1164 {
1165 MSIFEATURE *child;
1166
1167 LIST_FOR_EACH_ENTRY( child, &feature->Children, MSIFEATURE, entry )
1168 {
1169 if (child->ActionRequest == state)
1170 *cost += feature_cost( child );
1171 }
1172 break;
1173 }
1174 case MSICOSTTREE_PARENTS:
1175 {
1176 const WCHAR *feature_parent = feature->Feature_Parent;
1177 for (;;)
1178 {
1179 MSIFEATURE *parent = msi_get_loaded_feature( package, feature_parent );
1180 if (!parent)
1181 break;
1182
1183 if (parent->ActionRequest == state)
1184 *cost += feature_cost( parent );
1185
1186 feature_parent = parent->Feature_Parent;
1187 }
1188 break;
1189 }
1190 case MSICOSTTREE_SELFONLY:
1191 if (feature->ActionRequest == state)
1192 *cost = feature_cost( feature );
1193 break;
1194
1195 default:
1196 WARN("unhandled cost tree %u\n", tree);
1197 break;
1198 }
1199
1200 return ERROR_SUCCESS;
1201 }
1202
1203 /***********************************************************************
1204 * MsiGetFeatureCostW (MSI.@)
1205 */
MsiGetFeatureCostW(MSIHANDLE hInstall,const WCHAR * szFeature,MSICOSTTREE iCostTree,INSTALLSTATE iState,INT * piCost)1206 UINT WINAPI MsiGetFeatureCostW( MSIHANDLE hInstall, const WCHAR *szFeature, MSICOSTTREE iCostTree,
1207 INSTALLSTATE iState, INT *piCost )
1208 {
1209 MSIPACKAGE *package;
1210 MSIFEATURE *feature;
1211 UINT ret;
1212
1213 TRACE( "%lu, %s, %d, %d, %p\n", hInstall, debugstr_w(szFeature), iCostTree, iState, piCost );
1214
1215 if (!szFeature)
1216 return ERROR_INVALID_PARAMETER;
1217
1218 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1219 if (!package)
1220 {
1221 MSIHANDLE remote;
1222
1223 if (!(remote = msi_get_remote(hInstall)))
1224 return ERROR_INVALID_HANDLE;
1225
1226 __TRY
1227 {
1228 ret = remote_GetFeatureCost(remote, szFeature, iCostTree, iState, piCost);
1229 }
1230 __EXCEPT(rpc_filter)
1231 {
1232 ret = GetExceptionCode();
1233 }
1234 __ENDTRY
1235
1236 return ret;
1237 }
1238
1239 if (!piCost)
1240 {
1241 msiobj_release( &package->hdr );
1242 return ERROR_INVALID_PARAMETER;
1243 }
1244
1245 feature = msi_get_loaded_feature(package, szFeature);
1246
1247 if (feature)
1248 ret = MSI_GetFeatureCost(package, feature, iCostTree, iState, piCost);
1249 else
1250 ret = ERROR_UNKNOWN_FEATURE;
1251
1252 msiobj_release( &package->hdr );
1253 return ret;
1254 }
1255
1256 /***********************************************************************
1257 * MsiGetFeatureInfoA (MSI.@)
1258 */
MsiGetFeatureInfoA(MSIHANDLE handle,const char * feature,DWORD * attrs,char * title,DWORD * title_len,char * help,DWORD * help_len)1259 UINT WINAPI MsiGetFeatureInfoA( MSIHANDLE handle, const char *feature, DWORD *attrs,
1260 char *title, DWORD *title_len, char *help, DWORD *help_len )
1261 {
1262 UINT r;
1263 WCHAR *titleW = NULL, *helpW = NULL, *featureW = NULL;
1264
1265 TRACE( "%lu, %s, %p, %p, %p, %p, %p\n", handle, debugstr_a(feature), attrs, title,
1266 title_len, help, help_len );
1267
1268 if (feature && !(featureW = strdupAtoW( feature ))) return ERROR_OUTOFMEMORY;
1269
1270 if (title && title_len && !(titleW = malloc( *title_len * sizeof(WCHAR) )))
1271 {
1272 free( featureW );
1273 return ERROR_OUTOFMEMORY;
1274 }
1275 if (help && help_len && !(helpW = malloc( *help_len * sizeof(WCHAR) )))
1276 {
1277 free( featureW );
1278 free( titleW );
1279 return ERROR_OUTOFMEMORY;
1280 }
1281 r = MsiGetFeatureInfoW( handle, featureW, attrs, titleW, title_len, helpW, help_len );
1282 if (r == ERROR_SUCCESS)
1283 {
1284 if (titleW) WideCharToMultiByte( CP_ACP, 0, titleW, -1, title, *title_len + 1, NULL, NULL );
1285 if (helpW) WideCharToMultiByte( CP_ACP, 0, helpW, -1, help, *help_len + 1, NULL, NULL );
1286 }
1287 free( titleW );
1288 free( helpW );
1289 free( featureW );
1290 return r;
1291 }
1292
map_feature_attributes(DWORD attrs)1293 static DWORD map_feature_attributes( DWORD attrs )
1294 {
1295 DWORD ret = 0;
1296
1297 if (attrs == msidbFeatureAttributesFavorLocal) ret |= INSTALLFEATUREATTRIBUTE_FAVORLOCAL;
1298 if (attrs & msidbFeatureAttributesFavorSource) ret |= INSTALLFEATUREATTRIBUTE_FAVORSOURCE;
1299 if (attrs & msidbFeatureAttributesFollowParent) ret |= INSTALLFEATUREATTRIBUTE_FOLLOWPARENT;
1300 if (attrs & msidbFeatureAttributesFavorAdvertise) ret |= INSTALLFEATUREATTRIBUTE_FAVORADVERTISE;
1301 if (attrs & msidbFeatureAttributesDisallowAdvertise) ret |= INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE;
1302 if (attrs & msidbFeatureAttributesNoUnsupportedAdvertise) ret |= INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE;
1303 return ret;
1304 }
1305
MSI_GetFeatureInfo(MSIPACKAGE * package,LPCWSTR name,LPDWORD attrs,LPWSTR title,LPDWORD title_len,LPWSTR help,LPDWORD help_len)1306 static UINT MSI_GetFeatureInfo( MSIPACKAGE *package, LPCWSTR name, LPDWORD attrs,
1307 LPWSTR title, LPDWORD title_len, LPWSTR help, LPDWORD help_len )
1308 {
1309 UINT r = ERROR_SUCCESS;
1310 MSIFEATURE *feature = msi_get_loaded_feature( package, name );
1311 int len;
1312
1313 if (!feature) return ERROR_UNKNOWN_FEATURE;
1314 if (attrs) *attrs = map_feature_attributes( feature->Attributes );
1315 if (title_len)
1316 {
1317 if (feature->Title) len = lstrlenW( feature->Title );
1318 else len = 0;
1319 if (*title_len <= len)
1320 {
1321 *title_len = len;
1322 if (title) r = ERROR_MORE_DATA;
1323 }
1324 else if (title)
1325 {
1326 if (feature->Title) lstrcpyW( title, feature->Title );
1327 else *title = 0;
1328 *title_len = len;
1329 }
1330 }
1331 if (help_len)
1332 {
1333 if (feature->Description) len = lstrlenW( feature->Description );
1334 else len = 0;
1335 if (*help_len <= len)
1336 {
1337 *help_len = len;
1338 if (help) r = ERROR_MORE_DATA;
1339 }
1340 else if (help)
1341 {
1342 if (feature->Description) lstrcpyW( help, feature->Description );
1343 else *help = 0;
1344 *help_len = len;
1345 }
1346 }
1347 return r;
1348 }
1349
1350 /***********************************************************************
1351 * MsiGetFeatureInfoW (MSI.@)
1352 */
MsiGetFeatureInfoW(MSIHANDLE handle,const WCHAR * feature,DWORD * attrs,WCHAR * title,DWORD * title_len,WCHAR * help,DWORD * help_len)1353 UINT WINAPI MsiGetFeatureInfoW( MSIHANDLE handle, const WCHAR *feature, DWORD *attrs,
1354 WCHAR *title, DWORD *title_len, WCHAR *help, DWORD *help_len )
1355 {
1356 UINT r;
1357 MSIPACKAGE *package;
1358
1359 TRACE( "%lu, %s, %p, %p, %p, %p, %p\n", handle, debugstr_w(feature), attrs, title,
1360 title_len, help, help_len );
1361
1362 if (!feature) return ERROR_INVALID_PARAMETER;
1363
1364 if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE )))
1365 return ERROR_INVALID_HANDLE;
1366
1367 /* features may not have been loaded yet */
1368 msi_load_all_components( package );
1369 msi_load_all_features( package );
1370
1371 r = MSI_GetFeatureInfo( package, feature, attrs, title, title_len, help, help_len );
1372 msiobj_release( &package->hdr );
1373 return r;
1374 }
1375
1376 /***********************************************************************
1377 * MsiSetComponentStateA (MSI.@)
1378 */
MsiSetComponentStateA(MSIHANDLE hInstall,LPCSTR szComponent,INSTALLSTATE iState)1379 UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
1380 INSTALLSTATE iState)
1381 {
1382 UINT rc;
1383 LPWSTR szwComponent = strdupAtoW(szComponent);
1384
1385 rc = MsiSetComponentStateW(hInstall, szwComponent, iState);
1386
1387 free(szwComponent);
1388
1389 return rc;
1390 }
1391
1392 /***********************************************************************
1393 * MsiGetComponentStateA (MSI.@)
1394 */
MsiGetComponentStateA(MSIHANDLE hInstall,LPCSTR szComponent,INSTALLSTATE * piInstalled,INSTALLSTATE * piAction)1395 UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
1396 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1397 {
1398 LPWSTR szwComponent= NULL;
1399 UINT rc;
1400
1401 szwComponent= strdupAtoW(szComponent);
1402
1403 rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);
1404
1405 free(szwComponent);
1406
1407 return rc;
1408 }
1409
MSI_SetComponentStateW(MSIPACKAGE * package,LPCWSTR szComponent,INSTALLSTATE iState)1410 static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
1411 INSTALLSTATE iState)
1412 {
1413 MSICOMPONENT *comp;
1414
1415 TRACE("%p %s %d\n", package, debugstr_w(szComponent), iState);
1416
1417 comp = msi_get_loaded_component(package, szComponent);
1418 if (!comp)
1419 return ERROR_UNKNOWN_COMPONENT;
1420
1421 if (comp->Enabled)
1422 comp->Action = iState;
1423
1424 return ERROR_SUCCESS;
1425 }
1426
MSI_GetComponentStateW(MSIPACKAGE * package,LPCWSTR szComponent,INSTALLSTATE * piInstalled,INSTALLSTATE * piAction)1427 UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
1428 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
1429 {
1430 MSICOMPONENT *comp;
1431
1432 TRACE("%p %s %p %p\n", package, debugstr_w(szComponent),
1433 piInstalled, piAction);
1434
1435 comp = msi_get_loaded_component(package,szComponent);
1436 if (!comp)
1437 return ERROR_UNKNOWN_COMPONENT;
1438
1439 if (piInstalled)
1440 {
1441 if (comp->Enabled)
1442 *piInstalled = comp->Installed;
1443 else
1444 *piInstalled = INSTALLSTATE_UNKNOWN;
1445 }
1446
1447 if (piAction)
1448 {
1449 if (comp->Enabled)
1450 *piAction = comp->Action;
1451 else
1452 *piAction = INSTALLSTATE_UNKNOWN;
1453 }
1454
1455 TRACE("states (%i, %i)\n", comp->Installed, comp->Action );
1456 return ERROR_SUCCESS;
1457 }
1458
1459 /***********************************************************************
1460 * MsiSetComponentStateW (MSI.@)
1461 */
MsiSetComponentStateW(MSIHANDLE hInstall,LPCWSTR szComponent,INSTALLSTATE iState)1462 UINT WINAPI MsiSetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
1463 INSTALLSTATE iState)
1464 {
1465 MSIPACKAGE* package;
1466 UINT ret;
1467
1468 if (!szComponent)
1469 return ERROR_UNKNOWN_COMPONENT;
1470
1471 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1472 if (!package)
1473 {
1474 MSIHANDLE remote;
1475
1476 if (!(remote = msi_get_remote(hInstall)))
1477 return ERROR_INVALID_HANDLE;
1478
1479 __TRY
1480 {
1481 ret = remote_SetComponentState(remote, szComponent, iState);
1482 }
1483 __EXCEPT(rpc_filter)
1484 {
1485 ret = GetExceptionCode();
1486 }
1487 __ENDTRY
1488
1489 return ret;
1490 }
1491
1492 ret = MSI_SetComponentStateW(package, szComponent, iState);
1493 msiobj_release(&package->hdr);
1494 return ret;
1495 }
1496
1497 /***********************************************************************
1498 * MsiGetComponentStateW (MSI.@)
1499 */
MsiGetComponentStateW(MSIHANDLE hInstall,const WCHAR * szComponent,INSTALLSTATE * piInstalled,INSTALLSTATE * piAction)1500 UINT WINAPI MsiGetComponentStateW( MSIHANDLE hInstall, const WCHAR *szComponent, INSTALLSTATE *piInstalled,
1501 INSTALLSTATE *piAction )
1502 {
1503 MSIPACKAGE* package;
1504 UINT ret;
1505
1506 TRACE( "%lu, %s, %p, %p\n", hInstall, debugstr_w(szComponent), piInstalled, piAction );
1507
1508 if (!szComponent)
1509 return ERROR_UNKNOWN_COMPONENT;
1510
1511 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1512 if (!package)
1513 {
1514 MSIHANDLE remote;
1515
1516 if (!(remote = msi_get_remote(hInstall)))
1517 return ERROR_INVALID_HANDLE;
1518
1519 __TRY
1520 {
1521 ret = remote_GetComponentState(remote, szComponent, piInstalled, piAction);
1522 }
1523 __EXCEPT(rpc_filter)
1524 {
1525 ret = GetExceptionCode();
1526 }
1527 __ENDTRY
1528
1529 return ret;
1530 }
1531
1532 ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction);
1533 msiobj_release( &package->hdr );
1534 return ret;
1535 }
1536
1537 /***********************************************************************
1538 * MsiGetLanguage (MSI.@)
1539 */
MsiGetLanguage(MSIHANDLE hInstall)1540 LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall)
1541 {
1542 MSIPACKAGE* package;
1543 LANGID langid;
1544
1545 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1546 if (!package)
1547 {
1548 MSIHANDLE remote;
1549
1550 if (!(remote = msi_get_remote(hInstall)))
1551 return ERROR_INVALID_HANDLE;
1552
1553 __TRY
1554 {
1555 langid = remote_GetLanguage(remote);
1556 }
1557 __EXCEPT(rpc_filter)
1558 {
1559 langid = 0;
1560 }
1561 __ENDTRY
1562
1563 return langid;
1564 }
1565
1566 langid = msi_get_property_int( package->db, L"ProductLanguage", 0 );
1567 msiobj_release( &package->hdr );
1568 return langid;
1569 }
1570
MSI_SetInstallLevel(MSIPACKAGE * package,int iInstallLevel)1571 UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel )
1572 {
1573 WCHAR level[6];
1574 int len;
1575 UINT r;
1576
1577 TRACE("%p %i\n", package, iInstallLevel);
1578
1579 if (iInstallLevel > 32767)
1580 return ERROR_INVALID_PARAMETER;
1581
1582 if (iInstallLevel < 1)
1583 return MSI_SetFeatureStates( package );
1584
1585 len = swprintf( level, ARRAY_SIZE(level), L"%d", iInstallLevel );
1586 r = msi_set_property( package->db, L"INSTALLLEVEL", level, len );
1587 if ( r == ERROR_SUCCESS )
1588 r = MSI_SetFeatureStates( package );
1589
1590 return r;
1591 }
1592
1593 /***********************************************************************
1594 * MsiSetInstallLevel (MSI.@)
1595 */
MsiSetInstallLevel(MSIHANDLE hInstall,int iInstallLevel)1596 UINT WINAPI MsiSetInstallLevel(MSIHANDLE hInstall, int iInstallLevel)
1597 {
1598 MSIPACKAGE* package;
1599 UINT r;
1600
1601 TRACE( "%lu %d\n", hInstall, iInstallLevel );
1602
1603 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
1604 if (!package)
1605 {
1606 MSIHANDLE remote;
1607
1608 if (!(remote = msi_get_remote(hInstall)))
1609 return ERROR_INVALID_HANDLE;
1610
1611 __TRY
1612 {
1613 r = remote_SetInstallLevel(remote, iInstallLevel);
1614 }
1615 __EXCEPT(rpc_filter)
1616 {
1617 r = GetExceptionCode();
1618 }
1619 __ENDTRY
1620
1621 return r;
1622 }
1623
1624 r = MSI_SetInstallLevel( package, iInstallLevel );
1625
1626 msiobj_release( &package->hdr );
1627
1628 return r;
1629 }
1630
1631 /***********************************************************************
1632 * MsiGetFeatureValidStatesW (MSI.@)
1633 */
MsiGetFeatureValidStatesW(MSIHANDLE hInstall,const WCHAR * szFeature,DWORD * pInstallState)1634 UINT WINAPI MsiGetFeatureValidStatesW( MSIHANDLE hInstall, const WCHAR *szFeature, DWORD *pInstallState )
1635 {
1636 if (pInstallState) *pInstallState = 1 << INSTALLSTATE_LOCAL;
1637 FIXME( "%lu, %s, %p stub returning %lu\n", hInstall, debugstr_w(szFeature), pInstallState,
1638 pInstallState ? *pInstallState : 0 );
1639 return ERROR_SUCCESS;
1640 }
1641
1642 /***********************************************************************
1643 * MsiGetFeatureValidStatesA (MSI.@)
1644 */
MsiGetFeatureValidStatesA(MSIHANDLE hInstall,const char * szFeature,DWORD * pInstallState)1645 UINT WINAPI MsiGetFeatureValidStatesA( MSIHANDLE hInstall, const char *szFeature, DWORD *pInstallState )
1646 {
1647 UINT ret;
1648 WCHAR *szwFeature = strdupAtoW(szFeature);
1649 ret = MsiGetFeatureValidStatesW(hInstall, szwFeature, pInstallState);
1650 free(szwFeature);
1651 return ret;
1652 }
1653