Release 20050930.
[wine/gsoc-2012-control.git] / dlls / msi / install.c
blob2098cb2fc140dacae4f155815f848670453db351
1 /*
2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2005 Aric Stewart for CodeWeavers
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /* Msi top level apis directly related to installs */
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winerror.h"
28 #include "wine/debug.h"
29 #include "msi.h"
30 #include "msidefs.h"
31 #include "msipriv.h"
32 #include "winuser.h"
33 #include "wine/unicode.h"
34 #include "action.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msi);
38 /***********************************************************************
39 * MsiDoActionA (MSI.@)
41 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
43 LPWSTR szwAction;
44 UINT ret;
46 TRACE("%s\n", debugstr_a(szAction));
48 szwAction = strdupAtoW(szAction);
49 if (szAction && !szwAction)
50 return ERROR_FUNCTION_FAILED;
52 ret = MsiDoActionW( hInstall, szwAction );
53 msi_free( szwAction );
54 return ret;
57 /***********************************************************************
58 * MsiDoActionW (MSI.@)
60 UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
62 MSIPACKAGE *package;
63 UINT ret;
65 TRACE("%s\n",debugstr_w(szAction));
67 if (!szAction)
68 return ERROR_INVALID_PARAMETER;
70 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
71 if (!package)
72 return ERROR_INVALID_HANDLE;
74 ret = ACTION_PerformUIAction( package, szAction );
75 msiobj_release( &package->hdr );
77 return ret;
80 /***********************************************************************
81 * MsiSequenceA (MSI.@)
83 UINT WINAPI MsiSequenceA( MSIHANDLE hInstall, LPCSTR szTable, INT iSequenceMode )
85 LPWSTR szwTable;
86 UINT ret;
88 TRACE("%s\n", debugstr_a(szTable));
90 szwTable = strdupAtoW(szTable);
91 if (szTable && !szwTable)
92 return ERROR_FUNCTION_FAILED;
94 ret = MsiSequenceW( hInstall, szwTable, iSequenceMode );
95 msi_free( szwTable );
96 return ret;
99 /***********************************************************************
100 * MsiSequenceW (MSI.@)
102 UINT WINAPI MsiSequenceW( MSIHANDLE hInstall, LPCWSTR szTable, INT iSequenceMode )
104 MSIPACKAGE *package;
105 UINT ret;
107 TRACE("%s\n", debugstr_w(szTable));
109 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
110 if (!package)
111 return ERROR_INVALID_HANDLE;
113 ret = MSI_Sequence( package, szTable, iSequenceMode );
114 msiobj_release( &package->hdr );
116 return ret;
119 static UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
121 UINT len, r = ERROR_SUCCESS;
123 if (awbuf->str.w && !sz )
124 return ERROR_INVALID_PARAMETER;
126 if (!sz)
127 return r;
129 if (awbuf->unicode)
131 len = lstrlenW( str );
132 if (awbuf->str.w)
133 lstrcpynW( awbuf->str.w, str, *sz );
135 else
137 len = WideCharToMultiByte( CP_ACP, 0, str, -1,
138 awbuf->str.a, *sz, NULL, NULL );
139 len--;
142 if (len >= *sz)
143 r = ERROR_MORE_DATA;
144 *sz = len;
145 return r;
148 /***********************************************************************
149 * MsiGetTargetPath (internal)
151 UINT WINAPI MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
152 awstring *szPathBuf, DWORD* pcchPathBuf )
154 MSIPACKAGE *package;
155 LPWSTR path;
156 UINT r;
158 if (!szFolder)
159 return ERROR_INVALID_PARAMETER;
161 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
162 if (!package)
163 return ERROR_INVALID_HANDLE;
165 path = resolve_folder( package, szFolder, FALSE, FALSE, NULL );
166 msiobj_release( &package->hdr );
168 if (!path)
169 return ERROR_DIRECTORY;
171 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
172 msi_free( path );
173 return r;
176 /***********************************************************************
177 * MsiGetTargetPathA (MSI.@)
179 UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
180 LPSTR szPathBuf, DWORD* pcchPathBuf )
182 LPWSTR szwFolder;
183 awstring path;
184 UINT r;
186 TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf);
188 szwFolder = strdupAtoW(szFolder);
189 if (szFolder && !szwFolder)
190 return ERROR_FUNCTION_FAILED;
192 path.unicode = FALSE;
193 path.str.a = szPathBuf;
195 r = MSI_GetTargetPath( hInstall, szwFolder, &path, pcchPathBuf );
197 msi_free( szwFolder );
199 return r;
202 /***********************************************************************
203 * MsiGetTargetPathW (MSI.@)
205 UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder,
206 LPWSTR szPathBuf, DWORD* pcchPathBuf )
208 awstring path;
210 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf);
212 path.unicode = TRUE;
213 path.str.w = szPathBuf;
215 return MSI_GetTargetPath( hInstall, szFolder, &path, pcchPathBuf );
218 /***********************************************************************
219 * MsiGetSourcePath (internal)
221 static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder,
222 awstring *szPathBuf, DWORD* pcchPathBuf )
224 MSIPACKAGE *package;
225 LPWSTR path;
226 UINT r;
228 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
230 if (!szFolder)
231 return ERROR_INVALID_PARAMETER;
233 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
234 if (!package)
235 return ERROR_INVALID_HANDLE;
237 if (szPathBuf->str.w && !pcchPathBuf )
239 msiobj_release( &package->hdr );
240 return ERROR_INVALID_PARAMETER;
243 path = resolve_folder(package, szFolder, TRUE, FALSE, NULL);
244 msiobj_release( &package->hdr );
246 TRACE("path = %s\n",debugstr_w(path));
247 if (!path)
248 return ERROR_DIRECTORY;
250 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
251 msi_free( path );
252 return r;
255 /***********************************************************************
256 * MsiGetSourcePathA (MSI.@)
258 UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder,
259 LPSTR szPathBuf, DWORD* pcchPathBuf )
261 LPWSTR folder;
262 awstring str;
263 UINT r;
265 TRACE("%s %p %p\n", szFolder, debugstr_a(szPathBuf), pcchPathBuf);
267 str.unicode = FALSE;
268 str.str.a = szPathBuf;
270 folder = strdupAtoW( szFolder );
271 r = MSI_GetSourcePath( hInstall, folder, &str, pcchPathBuf );
272 msi_free( folder );
274 return r;
277 /***********************************************************************
278 * MsiGetSourcePathW (MSI.@)
280 UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder,
281 LPWSTR szPathBuf, DWORD* pcchPathBuf )
283 awstring str;
285 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
287 str.unicode = TRUE;
288 str.str.w = szPathBuf;
290 return MSI_GetSourcePath( hInstall, szFolder, &str, pcchPathBuf );
293 /***********************************************************************
294 * MsiSetTargetPathA (MSI.@)
296 UINT WINAPI MsiSetTargetPathA(MSIHANDLE hInstall, LPCSTR szFolder,
297 LPCSTR szFolderPath)
299 LPWSTR szwFolder;
300 LPWSTR szwFolderPath;
301 UINT rc;
303 if (!szFolder)
304 return ERROR_FUNCTION_FAILED;
305 if (hInstall == 0)
306 return ERROR_FUNCTION_FAILED;
308 szwFolder = strdupAtoW(szFolder);
309 if (!szwFolder)
310 return ERROR_FUNCTION_FAILED;
312 szwFolderPath = strdupAtoW(szFolderPath);
313 if (!szwFolderPath)
315 msi_free(szwFolder);
316 return ERROR_FUNCTION_FAILED;
319 rc = MsiSetTargetPathW(hInstall, szwFolder, szwFolderPath);
321 msi_free(szwFolder);
322 msi_free(szwFolderPath);
324 return rc;
328 * Ok my original interpretation of this was wrong. And it looks like msdn has
329 * changed a bit also. The given folder path does not have to actually already
330 * exist, it just cannot be read only and must be a legal folder path.
332 UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder,
333 LPCWSTR szFolderPath)
335 DWORD attrib;
336 LPWSTR path = NULL;
337 LPWSTR path2 = NULL;
338 MSIFOLDER *folder;
340 TRACE("(%p %s %s)\n",package, debugstr_w(szFolder),debugstr_w(szFolderPath));
342 if (package==NULL)
343 return ERROR_INVALID_HANDLE;
345 if (szFolderPath[0]==0)
346 return ERROR_FUNCTION_FAILED;
348 attrib = GetFileAttributesW(szFolderPath);
349 if ( attrib != INVALID_FILE_ATTRIBUTES &&
350 (!(attrib & FILE_ATTRIBUTE_DIRECTORY) ||
351 attrib & FILE_ATTRIBUTE_OFFLINE ||
352 attrib & FILE_ATTRIBUTE_READONLY))
353 return ERROR_FUNCTION_FAILED;
355 path = resolve_folder(package,szFolder,FALSE,FALSE,&folder);
357 if (!path)
358 return ERROR_INVALID_PARAMETER;
360 if (attrib == INVALID_FILE_ATTRIBUTES)
362 if (!CreateDirectoryW(szFolderPath,NULL))
363 return ERROR_FUNCTION_FAILED;
364 RemoveDirectoryW(szFolderPath);
367 msi_free(folder->Property);
368 folder->Property = build_directory_name(2, szFolderPath, NULL);
370 if (lstrcmpiW(path, folder->Property) == 0)
373 * Resolved Target has not really changed, so just
374 * set this folder and do not recalculate everything.
376 msi_free(folder->ResolvedTarget);
377 folder->ResolvedTarget = NULL;
378 path2 = resolve_folder(package,szFolder,FALSE,TRUE,NULL);
379 msi_free(path2);
381 else
383 MSIFOLDER *f;
385 LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
387 msi_free(f->ResolvedTarget);
388 f->ResolvedTarget=NULL;
391 LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
393 path2 = resolve_folder(package, f->Directory, FALSE, TRUE, NULL);
394 msi_free(path2);
397 msi_free(path);
399 return ERROR_SUCCESS;
402 /***********************************************************************
403 * MsiSetTargetPathW (MSI.@)
405 UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder,
406 LPCWSTR szFolderPath)
408 MSIPACKAGE *package;
409 UINT ret;
411 TRACE("(%s %s)\n",debugstr_w(szFolder),debugstr_w(szFolderPath));
413 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
414 ret = MSI_SetTargetPathW( package, szFolder, szFolderPath );
415 msiobj_release( &package->hdr );
416 return ret;
419 /***********************************************************************
420 * MsiGetMode (MSI.@)
422 * Returns an internal installer state (if it is running in a mode iRunMode)
424 * PARAMS
425 * hInstall [I] Handle to the installation
426 * hRunMode [I] Checking run mode
427 * MSIRUNMODE_ADMIN Administrative mode
428 * MSIRUNMODE_ADVERTISE Advertisement mode
429 * MSIRUNMODE_MAINTENANCE Maintenance mode
430 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
431 * MSIRUNMODE_LOGENABLED Log file is writing
432 * MSIRUNMODE_OPERATIONS Operations in progress??
433 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
434 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
435 * MSIRUNMODE_CABINET Files from cabinet are installed
436 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
437 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
438 * MSIRUNMODE_RESERVED11 Reserved
439 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
440 * MSIRUNMODE_ZAWENABLED Demand installation is supported
441 * MSIRUNMODE_RESERVED14 Reserved
442 * MSIRUNMODE_RESERVED15 Reserved
443 * MSIRUNMODE_SCHEDULED called from install script
444 * MSIRUNMODE_ROLLBACK called from rollback script
445 * MSIRUNMODE_COMMIT called from commit script
447 * RETURNS
448 * In the state: TRUE
449 * Not in the state: FALSE
453 BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
455 FIXME("STUB (iRunMode=%i)\n",iRunMode);
456 return TRUE;
459 /***********************************************************************
460 * MsiSetFeatureStateA (MSI.@)
462 * According to the docs, when this is called it immediately recalculates
463 * all the component states as well
465 UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
466 INSTALLSTATE iState)
468 LPWSTR szwFeature = NULL;
469 UINT rc;
471 szwFeature = strdupAtoW(szFeature);
473 if (!szwFeature)
474 return ERROR_FUNCTION_FAILED;
476 rc = MsiSetFeatureStateW(hInstall,szwFeature, iState);
478 msi_free(szwFeature);
480 return rc;
485 UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE* package, LPCWSTR szFeature,
486 INSTALLSTATE iState)
488 UINT rc = ERROR_SUCCESS;
489 MSIFEATURE *feature, *child;
491 TRACE(" %s to %i\n",debugstr_w(szFeature), iState);
493 feature = get_loaded_feature(package,szFeature);
494 if (!feature)
495 return ERROR_UNKNOWN_FEATURE;
497 if (iState == INSTALLSTATE_ADVERTISED &&
498 feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
499 return ERROR_FUNCTION_FAILED;
501 feature->ActionRequest = iState;
502 feature->Action = iState;
504 ACTION_UpdateComponentStates(package,szFeature);
506 /* update all the features that are children of this feature */
507 LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry )
509 if (lstrcmpW(szFeature, child->Feature_Parent) == 0)
510 MSI_SetFeatureStateW(package, child->Feature, iState);
513 return rc;
516 /***********************************************************************
517 * MsiSetFeatureStateW (MSI.@)
519 UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
520 INSTALLSTATE iState)
522 MSIPACKAGE* package;
523 UINT rc = ERROR_SUCCESS;
525 TRACE(" %s to %i\n",debugstr_w(szFeature), iState);
527 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
528 if (!package)
529 return ERROR_INVALID_HANDLE;
531 rc = MSI_SetFeatureStateW(package,szFeature,iState);
533 msiobj_release( &package->hdr );
534 return rc;
537 /***********************************************************************
538 * MsiGetFeatureStateA (MSI.@)
540 UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPSTR szFeature,
541 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
543 LPWSTR szwFeature = NULL;
544 UINT rc;
546 szwFeature = strdupAtoW(szFeature);
548 rc = MsiGetFeatureStateW(hInstall,szwFeature,piInstalled, piAction);
550 msi_free( szwFeature);
552 return rc;
555 UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPWSTR szFeature,
556 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
558 MSIFEATURE *feature;
560 feature = get_loaded_feature(package,szFeature);
561 if (!feature)
562 return ERROR_UNKNOWN_FEATURE;
564 if (piInstalled)
565 *piInstalled = feature->Installed;
567 if (piAction)
568 *piAction = feature->Action;
570 TRACE("returning %i %i\n", feature->Installed, feature->Action);
572 return ERROR_SUCCESS;
575 /***********************************************************************
576 * MsiGetFeatureStateW (MSI.@)
578 UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPWSTR szFeature,
579 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
581 MSIPACKAGE* package;
582 UINT ret;
584 TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled,
585 piAction);
587 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
588 if (!package)
589 return ERROR_INVALID_HANDLE;
590 ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction);
591 msiobj_release( &package->hdr );
592 return ret;
595 /***********************************************************************
596 * MsiSetComponentStateA (MSI.@)
598 UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
599 INSTALLSTATE iState)
601 UINT rc;
602 LPWSTR szwComponent = strdupAtoW(szComponent);
604 rc = MsiSetComponentStateW(hInstall, szwComponent, iState);
606 msi_free(szwComponent);
608 return rc;
611 /***********************************************************************
612 * MsiGetComponentStateA (MSI.@)
614 UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPSTR szComponent,
615 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
617 LPWSTR szwComponent= NULL;
618 UINT rc;
620 szwComponent= strdupAtoW(szComponent);
622 rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);
624 msi_free( szwComponent);
626 return rc;
629 static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
630 INSTALLSTATE iState)
632 MSICOMPONENT *comp;
634 TRACE("%p %s %d\n", package, debugstr_w(szComponent), iState);
636 comp = get_loaded_component(package, szComponent);
637 if (!comp)
638 return ERROR_UNKNOWN_COMPONENT;
640 comp->Installed = iState;
642 return ERROR_SUCCESS;
645 UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPWSTR szComponent,
646 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
648 MSICOMPONENT *comp;
650 TRACE("%p %s %p %p\n", package, debugstr_w(szComponent),
651 piInstalled, piAction);
653 comp = get_loaded_component(package,szComponent);
654 if (!comp)
655 return ERROR_UNKNOWN_COMPONENT;
657 if (piInstalled)
658 *piInstalled = comp->Installed;
660 if (piAction)
661 *piAction = comp->Action;
663 TRACE("states (%i, %i)\n", comp->Installed, comp->Action );
665 return ERROR_SUCCESS;
668 /***********************************************************************
669 * MsiSetComponentStateW (MSI.@)
671 UINT WINAPI MsiSetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
672 INSTALLSTATE iState)
674 MSIPACKAGE* package;
675 UINT ret;
677 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
678 if (!package)
679 return ERROR_INVALID_HANDLE;
680 ret = MSI_SetComponentStateW(package, szComponent, iState);
681 msiobj_release(&package->hdr);
682 return ret;
685 /***********************************************************************
686 * MsiGetComponentStateW (MSI.@)
688 UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPWSTR szComponent,
689 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
691 MSIPACKAGE* package;
692 UINT ret;
694 TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szComponent),
695 piInstalled, piAction);
697 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
698 if (!package)
699 return ERROR_INVALID_HANDLE;
700 ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction);
701 msiobj_release( &package->hdr );
702 return ret;
705 /***********************************************************************
706 * MsiGetLanguage (MSI.@)
708 LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall)
710 MSIPACKAGE* package;
711 LANGID langid;
712 LPWSTR buffer;
713 static const WCHAR szProductLanguage[] =
714 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
716 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
717 if (!package)
718 return ERROR_INVALID_HANDLE;
720 buffer = msi_dup_property( package, szProductLanguage );
721 langid = atoiW(buffer);
723 msi_free(buffer);
724 msiobj_release (&package->hdr);
725 return langid;