Delete all Trailing spaces in code.
[reactos.git] / reactos / dll / win32 / msi / install.c
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 #include <stdarg.h>
24
25 #include "stdio.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "wine/debug.h"
30 #include "msi.h"
31 #include "msidefs.h"
32 #include "msipriv.h"
33 #include "wine/unicode.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(msi);
36
37 /***********************************************************************
38 * MsiDoActionA (MSI.@)
39 */
40 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
41 {
42 LPWSTR szwAction;
43 UINT ret;
44
45 TRACE("%s\n", debugstr_a(szAction));
46
47 szwAction = strdupAtoW(szAction);
48 if (szAction && !szwAction)
49 return ERROR_FUNCTION_FAILED;
50
51 ret = MsiDoActionW( hInstall, szwAction );
52 msi_free( szwAction );
53 return ret;
54 }
55
56 /***********************************************************************
57 * MsiDoActionW (MSI.@)
58 */
59 UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
60 {
61 MSIPACKAGE *package;
62 UINT ret;
63
64 TRACE("%s\n",debugstr_w(szAction));
65
66 if (!szAction)
67 return ERROR_INVALID_PARAMETER;
68
69 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
70 if (!package)
71 return ERROR_INVALID_HANDLE;
72
73 ret = ACTION_PerformUIAction( package, szAction );
74 msiobj_release( &package->hdr );
75
76 return ret;
77 }
78
79 /***********************************************************************
80 * MsiSequenceA (MSI.@)
81 */
82 UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode )
83 {
84 LPWSTR szwTable;
85 UINT ret;
86
87 TRACE("%s\n", debugstr_a(szTable));
88
89 szwTable = strdupAtoW(szTable);
90 if (szTable && !szwTable)
91 return ERROR_FUNCTION_FAILED;
92
93 ret = MsiSequenceW( hInstall, szwTable, iSequenceMode );
94 msi_free( szwTable );
95 return ret;
96 }
97
98 /***********************************************************************
99 * MsiSequenceW (MSI.@)
100 */
101 UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode )
102 {
103 MSIPACKAGE *package;
104 UINT ret;
105
106 TRACE("%s\n", debugstr_w(szTable));
107
108 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
109 if (!package)
110 return ERROR_INVALID_HANDLE;
111
112 ret = MSI_Sequence( package, szTable, iSequenceMode );
113 msiobj_release( &package->hdr );
114
115 return ret;
116 }
117
118 UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
119 {
120 UINT len, r = ERROR_SUCCESS;
121
122 if (awbuf->str.w && !sz )
123 return ERROR_INVALID_PARAMETER;
124
125 if (!sz)
126 return r;
127
128 if (awbuf->unicode)
129 {
130 len = lstrlenW( str );
131 if (awbuf->str.w)
132 lstrcpynW( awbuf->str.w, str, *sz );
133 }
134 else
135 {
136 len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
137 if (len)
138 len--;
139 WideCharToMultiByte( CP_ACP, 0, str, -1, awbuf->str.a, *sz, NULL, NULL );
140 if ( awbuf->str.a && *sz && (len >= *sz) )
141 awbuf->str.a[*sz - 1] = 0;
142 }
143
144 if (awbuf->str.w && len >= *sz)
145 r = ERROR_MORE_DATA;
146 *sz = len;
147 return r;
148 }
149
150 /***********************************************************************
151 * MsiGetTargetPath (internal)
152 */
153 static UINT WINAPI MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
154 awstring *szPathBuf, DWORD* pcchPathBuf )
155 {
156 MSIPACKAGE *package;
157 LPWSTR path;
158 UINT r;
159
160 if (!szFolder)
161 return ERROR_INVALID_PARAMETER;
162
163 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
164 if (!package)
165 return ERROR_INVALID_HANDLE;
166
167 path = resolve_folder( package, szFolder, FALSE, FALSE, NULL );
168 msiobj_release( &package->hdr );
169
170 if (!path)
171 return ERROR_DIRECTORY;
172
173 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
174 msi_free( path );
175 return r;
176 }
177
178 /***********************************************************************
179 * MsiGetTargetPathA (MSI.@)
180 */
181 UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
182 LPSTR szPathBuf, DWORD* pcchPathBuf )
183 {
184 LPWSTR szwFolder;
185 awstring path;
186 UINT r;
187
188 TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf);
189
190 szwFolder = strdupAtoW(szFolder);
191 if (szFolder && !szwFolder)
192 return ERROR_FUNCTION_FAILED;
193
194 path.unicode = FALSE;
195 path.str.a = szPathBuf;
196
197 r = MSI_GetTargetPath( hInstall, szwFolder, &path, pcchPathBuf );
198
199 msi_free( szwFolder );
200
201 return r;
202 }
203
204 /***********************************************************************
205 * MsiGetTargetPathW (MSI.@)
206 */
207 UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder,
208 LPWSTR szPathBuf, DWORD* pcchPathBuf )
209 {
210 awstring path;
211
212 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf);
213
214 path.unicode = TRUE;
215 path.str.w = szPathBuf;
216
217 return MSI_GetTargetPath( hInstall, szFolder, &path, pcchPathBuf );
218 }
219
220 /***********************************************************************
221 * MsiGetSourcePath (internal)
222 */
223 static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder,
224 awstring *szPathBuf, DWORD* pcchPathBuf )
225 {
226 MSIPACKAGE *package;
227 LPWSTR path;
228 UINT r;
229
230 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
231
232 if (!szFolder)
233 return ERROR_INVALID_PARAMETER;
234
235 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
236 if (!package)
237 return ERROR_INVALID_HANDLE;
238
239 if (szPathBuf->str.w && !pcchPathBuf )
240 {
241 msiobj_release( &package->hdr );
242 return ERROR_INVALID_PARAMETER;
243 }
244
245 path = resolve_folder(package, szFolder, TRUE, FALSE, NULL);
246 msiobj_release( &package->hdr );
247
248 TRACE("path = %s\n",debugstr_w(path));
249 if (!path)
250 return ERROR_DIRECTORY;
251
252 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
253 msi_free( path );
254 return r;
255 }
256
257 /***********************************************************************
258 * MsiGetSourcePathA (MSI.@)
259 */
260 UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder,
261 LPSTR szPathBuf, DWORD* pcchPathBuf )
262 {
263 LPWSTR folder;
264 awstring str;
265 UINT r;
266
267 TRACE("%s %p %p\n", szFolder, debugstr_a(szPathBuf), pcchPathBuf);
268
269 str.unicode = FALSE;
270 str.str.a = szPathBuf;
271
272 folder = strdupAtoW( szFolder );
273 r = MSI_GetSourcePath( hInstall, folder, &str, pcchPathBuf );
274 msi_free( folder );
275
276 return r;
277 }
278
279 /***********************************************************************
280 * MsiGetSourcePathW (MSI.@)
281 */
282 UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder,
283 LPWSTR szPathBuf, DWORD* pcchPathBuf )
284 {
285 awstring str;
286
287 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
288
289 str.unicode = TRUE;
290 str.str.w = szPathBuf;
291
292 return MSI_GetSourcePath( hInstall, szFolder, &str, pcchPathBuf );
293 }
294
295 /***********************************************************************
296 * MsiSetTargetPathA (MSI.@)
297 */
298 UINT WINAPI MsiSetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
299 LPCSTR szFolderPath )
300 {
301 LPWSTR szwFolder = NULL, szwFolderPath = NULL;
302 UINT rc = ERROR_OUTOFMEMORY;
303
304 if ( !szFolder || !szFolderPath )
305 return ERROR_INVALID_PARAMETER;
306
307 szwFolder = strdupAtoW(szFolder);
308 szwFolderPath = strdupAtoW(szFolderPath);
309 if (!szwFolder || !szwFolderPath)
310 goto end;
311
312 rc = MsiSetTargetPathW( hInstall, szwFolder, szwFolderPath );
313
314 end:
315 msi_free(szwFolder);
316 msi_free(szwFolderPath);
317
318 return rc;
319 }
320
321 /*
322 * Ok my original interpretation of this was wrong. And it looks like msdn has
323 * changed a bit also. The given folder path does not have to actually already
324 * exist, it just cannot be read only and must be a legal folder path.
325 */
326 UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder,
327 LPCWSTR szFolderPath)
328 {
329 DWORD attrib;
330 LPWSTR path = NULL;
331 LPWSTR path2 = NULL;
332 MSIFOLDER *folder;
333 MSIFILE *file;
334
335 TRACE("%p %s %s\n",package, debugstr_w(szFolder),debugstr_w(szFolderPath));
336
337 attrib = GetFileAttributesW(szFolderPath);
338 /* native MSI tests writeability by making temporary files at each drive */
339 if ( attrib != INVALID_FILE_ATTRIBUTES &&
340 (attrib & FILE_ATTRIBUTE_OFFLINE ||
341 attrib & FILE_ATTRIBUTE_READONLY))
342 return ERROR_FUNCTION_FAILED;
343
344 path = resolve_folder(package,szFolder,FALSE,FALSE,&folder);
345 if (!path)
346 return ERROR_DIRECTORY;
347
348 msi_free(folder->Property);
349 folder->Property = build_directory_name(2, szFolderPath, NULL);
350
351 if (lstrcmpiW(path, folder->Property) == 0)
352 {
353 /*
354 * Resolved Target has not really changed, so just
355 * set this folder and do not recalculate everything.
356 */
357 msi_free(folder->ResolvedTarget);
358 folder->ResolvedTarget = NULL;
359 path2 = resolve_folder(package,szFolder,FALSE,TRUE,NULL);
360 msi_free(path2);
361 }
362 else
363 {
364 MSIFOLDER *f;
365
366 LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
367 {
368 msi_free(f->ResolvedTarget);
369 f->ResolvedTarget=NULL;
370 }
371
372 LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
373 {
374 path2 = resolve_folder(package, f->Directory, FALSE, TRUE, NULL);
375 msi_free(path2);
376 }
377
378 LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
379 {
380 MSICOMPONENT *comp = file->Component;
381 LPWSTR p;
382
383 if (!comp)
384 continue;
385
386 p = resolve_folder(package, comp->Directory, FALSE, FALSE, NULL);
387 msi_free(file->TargetPath);
388
389 file->TargetPath = build_directory_name(2, p, file->FileName);
390 msi_free(p);
391 }
392 }
393 msi_free(path);
394
395 return ERROR_SUCCESS;
396 }
397
398 /***********************************************************************
399 * MsiSetTargetPathW (MSI.@)
400 */
401 UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder,
402 LPCWSTR szFolderPath)
403 {
404 MSIPACKAGE *package;
405 UINT ret;
406
407 TRACE("%s %s\n",debugstr_w(szFolder),debugstr_w(szFolderPath));
408
409 if ( !szFolder || !szFolderPath )
410 return ERROR_INVALID_PARAMETER;
411
412 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
413 if (!package)
414 return ERROR_INVALID_HANDLE;
415
416 ret = MSI_SetTargetPathW( package, szFolder, szFolderPath );
417 msiobj_release( &package->hdr );
418 return ret;
419 }
420
421 /***********************************************************************
422 * MsiGetMode (MSI.@)
423 *
424 * Returns an internal installer state (if it is running in a mode iRunMode)
425 *
426 * PARAMS
427 * hInstall [I] Handle to the installation
428 * hRunMode [I] Checking run mode
429 * MSIRUNMODE_ADMIN Administrative mode
430 * MSIRUNMODE_ADVERTISE Advertisement mode
431 * MSIRUNMODE_MAINTENANCE Maintenance mode
432 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
433 * MSIRUNMODE_LOGENABLED Log file is writing
434 * MSIRUNMODE_OPERATIONS Operations in progress??
435 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
436 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
437 * MSIRUNMODE_CABINET Files from cabinet are installed
438 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
439 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
440 * MSIRUNMODE_RESERVED11 Reserved
441 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
442 * MSIRUNMODE_ZAWENABLED Demand installation is supported
443 * MSIRUNMODE_RESERVED14 Reserved
444 * MSIRUNMODE_RESERVED15 Reserved
445 * MSIRUNMODE_SCHEDULED called from install script
446 * MSIRUNMODE_ROLLBACK called from rollback script
447 * MSIRUNMODE_COMMIT called from commit script
448 *
449 * RETURNS
450 * In the state: TRUE
451 * Not in the state: FALSE
452 *
453 */
454 BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
455 {
456 BOOL r = FALSE;
457
458 switch (iRunMode)
459 {
460 case MSIRUNMODE_WINDOWS9X:
461 if (GetVersion() & 0x80000000)
462 r = TRUE;
463 break;
464
465 case MSIRUNMODE_RESERVED11:
466 case MSIRUNMODE_RESERVED14:
467 case MSIRUNMODE_RESERVED15:
468 break;
469
470 case MSIRUNMODE_SCHEDULED:
471 case MSIRUNMODE_ROLLBACK:
472 case MSIRUNMODE_COMMIT:
473 break;
474
475 default:
476 FIXME("%ld %d\n", hInstall, iRunMode);
477 r = TRUE;
478 }
479
480 return r;
481 }
482
483 /***********************************************************************
484 * MsiSetMode (MSI.@)
485 */
486 BOOL WINAPI MsiSetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode, BOOL fState)
487 {
488 switch (iRunMode)
489 {
490 case MSIRUNMODE_RESERVED11:
491 case MSIRUNMODE_WINDOWS9X:
492 case MSIRUNMODE_RESERVED14:
493 case MSIRUNMODE_RESERVED15:
494 return FALSE;
495 default:
496 FIXME("%ld %d %d\n", hInstall, iRunMode, fState);
497 }
498 return TRUE;
499 }
500
501 /***********************************************************************
502 * MsiSetFeatureStateA (MSI.@)
503 *
504 * According to the docs, when this is called it immediately recalculates
505 * all the component states as well
506 */
507 UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
508 INSTALLSTATE iState)
509 {
510 LPWSTR szwFeature = NULL;
511 UINT rc;
512
513 szwFeature = strdupAtoW(szFeature);
514
515 if (!szwFeature)
516 return ERROR_FUNCTION_FAILED;
517
518 rc = MsiSetFeatureStateW(hInstall,szwFeature, iState);
519
520 msi_free(szwFeature);
521
522 return rc;
523 }
524
525
526
527 UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE* package, LPCWSTR szFeature,
528 INSTALLSTATE iState)
529 {
530 UINT rc = ERROR_SUCCESS;
531 MSIFEATURE *feature, *child;
532
533 TRACE("%s %i\n", debugstr_w(szFeature), iState);
534
535 feature = get_loaded_feature(package,szFeature);
536 if (!feature)
537 return ERROR_UNKNOWN_FEATURE;
538
539 if (iState == INSTALLSTATE_ADVERTISED &&
540 feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
541 return ERROR_FUNCTION_FAILED;
542
543 msi_feature_set_state( feature, iState );
544
545 ACTION_UpdateComponentStates(package,szFeature);
546
547 /* update all the features that are children of this feature */
548 LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry )
549 {
550 if (lstrcmpW(szFeature, child->Feature_Parent) == 0)
551 MSI_SetFeatureStateW(package, child->Feature, iState);
552 }
553
554 return rc;
555 }
556
557 /***********************************************************************
558 * MsiSetFeatureStateW (MSI.@)
559 */
560 UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
561 INSTALLSTATE iState)
562 {
563 MSIPACKAGE* package;
564 UINT rc = ERROR_SUCCESS;
565
566 TRACE("%s %i\n",debugstr_w(szFeature), iState);
567
568 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
569 if (!package)
570 return ERROR_INVALID_HANDLE;
571
572 rc = MSI_SetFeatureStateW(package,szFeature,iState);
573
574 msiobj_release( &package->hdr );
575 return rc;
576 }
577
578 /***********************************************************************
579 * MsiGetFeatureStateA (MSI.@)
580 */
581 UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
582 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
583 {
584 LPWSTR szwFeature = NULL;
585 UINT rc;
586
587 szwFeature = strdupAtoW(szFeature);
588
589 rc = MsiGetFeatureStateW(hInstall,szwFeature,piInstalled, piAction);
590
591 msi_free( szwFeature);
592
593 return rc;
594 }
595
596 UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPCWSTR szFeature,
597 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
598 {
599 MSIFEATURE *feature;
600
601 feature = get_loaded_feature(package,szFeature);
602 if (!feature)
603 return ERROR_UNKNOWN_FEATURE;
604
605 if (piInstalled)
606 *piInstalled = feature->Installed;
607
608 if (piAction)
609 *piAction = feature->Action;
610
611 TRACE("returning %i %i\n", feature->Installed, feature->Action);
612
613 return ERROR_SUCCESS;
614 }
615
616 /***********************************************************************
617 * MsiGetFeatureStateW (MSI.@)
618 */
619 UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
620 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
621 {
622 MSIPACKAGE* package;
623 UINT ret;
624
625 TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled, piAction);
626
627 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
628 if (!package)
629 return ERROR_INVALID_HANDLE;
630 ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction);
631 msiobj_release( &package->hdr );
632 return ret;
633 }
634
635 /***********************************************************************
636 * MsiGetFeatureCostA (MSI.@)
637 */
638 UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature,
639 MSICOSTTREE iCostTree, INSTALLSTATE iState, INT *piCost)
640 {
641 FIXME("(%ld %s %i %i %p): stub\n", hInstall, debugstr_a(szFeature),
642 iCostTree, iState, piCost);
643 if (piCost) *piCost = 0;
644 return ERROR_SUCCESS;
645 }
646
647 /***********************************************************************
648 * MsiGetFeatureCostW (MSI.@)
649 */
650 UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature,
651 MSICOSTTREE iCostTree, INSTALLSTATE iState, INT *piCost)
652 {
653 FIXME("(%ld %s %i %i %p): stub\n", hInstall, debugstr_w(szFeature),
654 iCostTree, iState, piCost);
655 if (piCost) *piCost = 0;
656 return ERROR_SUCCESS;
657 }
658
659 /***********************************************************************
660 * MsiSetComponentStateA (MSI.@)
661 */
662 UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
663 INSTALLSTATE iState)
664 {
665 UINT rc;
666 LPWSTR szwComponent = strdupAtoW(szComponent);
667
668 rc = MsiSetComponentStateW(hInstall, szwComponent, iState);
669
670 msi_free(szwComponent);
671
672 return rc;
673 }
674
675 /***********************************************************************
676 * MsiGetComponentStateA (MSI.@)
677 */
678 UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
679 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
680 {
681 LPWSTR szwComponent= NULL;
682 UINT rc;
683
684 szwComponent= strdupAtoW(szComponent);
685
686 rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);
687
688 msi_free( szwComponent);
689
690 return rc;
691 }
692
693 static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
694 INSTALLSTATE iState)
695 {
696 MSICOMPONENT *comp;
697
698 TRACE("%p %s %d\n", package, debugstr_w(szComponent), iState);
699
700 comp = get_loaded_component(package, szComponent);
701 if (!comp)
702 return ERROR_UNKNOWN_COMPONENT;
703
704 comp->Installed = iState;
705
706 return ERROR_SUCCESS;
707 }
708
709 UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
710 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
711 {
712 MSICOMPONENT *comp;
713
714 TRACE("%p %s %p %p\n", package, debugstr_w(szComponent),
715 piInstalled, piAction);
716
717 comp = get_loaded_component(package,szComponent);
718 if (!comp)
719 return ERROR_UNKNOWN_COMPONENT;
720
721 if (piInstalled)
722 *piInstalled = comp->Installed;
723
724 if (piAction)
725 *piAction = comp->Action;
726
727 TRACE("states (%i, %i)\n", comp->Installed, comp->Action );
728
729 return ERROR_SUCCESS;
730 }
731
732 /***********************************************************************
733 * MsiSetComponentStateW (MSI.@)
734 */
735 UINT WINAPI MsiSetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
736 INSTALLSTATE iState)
737 {
738 MSIPACKAGE* package;
739 UINT ret;
740
741 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
742 if (!package)
743 return ERROR_INVALID_HANDLE;
744 ret = MSI_SetComponentStateW(package, szComponent, iState);
745 msiobj_release(&package->hdr);
746 return ret;
747 }
748
749 /***********************************************************************
750 * MsiGetComponentStateW (MSI.@)
751 */
752 UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
753 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
754 {
755 MSIPACKAGE* package;
756 UINT ret;
757
758 TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szComponent),
759 piInstalled, piAction);
760
761 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
762 if (!package)
763 return ERROR_INVALID_HANDLE;
764 ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction);
765 msiobj_release( &package->hdr );
766 return ret;
767 }
768
769 /***********************************************************************
770 * MsiGetLanguage (MSI.@)
771 */
772 LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall)
773 {
774 MSIPACKAGE* package;
775 LANGID langid;
776 static const WCHAR szProductLanguage[] =
777 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
778
779 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
780 if (!package)
781 return ERROR_INVALID_HANDLE;
782
783 langid = msi_get_property_int( package, szProductLanguage, 0 );
784 msiobj_release( &package->hdr );
785 return langid;
786 }
787
788 UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel )
789 {
790 static const WCHAR szInstallLevel[] = {
791 'I','N','S','T','A','L','L','L','E','V','E','L',0 };
792 static const WCHAR fmt[] = { '%','d',0 };
793 WCHAR level[6];
794 UINT r;
795
796 TRACE("%p %i\n", package, iInstallLevel);
797
798 if (iInstallLevel<1 || iInstallLevel>32767)
799 return ERROR_INVALID_PARAMETER;
800
801 sprintfW( level, fmt, iInstallLevel );
802 r = MSI_SetPropertyW( package, szInstallLevel, level );
803 if ( r == ERROR_SUCCESS )
804 {
805 r = MSI_SetFeatureStates( package );
806 }
807
808 return r;
809 }
810
811 /***********************************************************************
812 * MsiSetInstallLevel (MSI.@)
813 */
814 UINT WINAPI MsiSetInstallLevel(MSIHANDLE hInstall, int iInstallLevel)
815 {
816 MSIPACKAGE* package;
817 UINT r;
818
819 TRACE("%ld %i\n", hInstall, iInstallLevel);
820
821 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
822 if ( !package )
823 return ERROR_INVALID_HANDLE;
824
825 r = MSI_SetInstallLevel( package, iInstallLevel );
826
827 msiobj_release( &package->hdr );
828
829 return r;
830 }
831
832 /***********************************************************************
833 * MsiGetFeatureValidStatesW (MSI.@)
834 */
835 UINT WINAPI MsiGetFeatureValidStatesW(MSIHANDLE hInstall, LPCWSTR szFeature,
836 DWORD* pInstallState)
837 {
838 if(pInstallState) *pInstallState = 1<<INSTALLSTATE_LOCAL;
839 FIXME("%ld %s %p stub returning %d\n",
840 hInstall, debugstr_w(szFeature), pInstallState, pInstallState ? *pInstallState : 0);
841
842 return ERROR_SUCCESS;
843 }
844
845 /***********************************************************************
846 * MsiGetFeatureValidStatesA (MSI.@)
847 */
848 UINT WINAPI MsiGetFeatureValidStatesA(MSIHANDLE hInstall, LPCSTR szFeature,
849 DWORD* pInstallState)
850 {
851 UINT ret;
852 LPWSTR szwFeature = strdupAtoW(szFeature);
853
854 ret = MsiGetFeatureValidStatesW(hInstall, szwFeature, pInstallState);
855
856 msi_free(szwFeature);
857
858 return ret;
859 }