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 */
28 #include "wine/debug.h"
33 #include "wine/unicode.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msi);
38 /***********************************************************************
39 * MsiDoActionA (MSI.@)
41 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
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 HeapFree( GetProcessHeap(), 0, szwAction );
57 /***********************************************************************
58 * MsiDoActionW (MSI.@)
60 UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
65 TRACE("%s\n",debugstr_w(szAction));
68 return ERROR_INVALID_PARAMETER;
70 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
72 return ERROR_INVALID_HANDLE;
74 ret = ACTION_PerformUIAction( package, szAction );
75 msiobj_release( &package->hdr );
80 static UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
82 UINT len, r = ERROR_SUCCESS;
84 if (awbuf->str.w && !sz )
85 return ERROR_INVALID_PARAMETER;
92 len = lstrlenW( str );
94 lstrcpynW( awbuf->str.w, str, *sz );
98 len = WideCharToMultiByte( CP_ACP, 0, str, -1,
99 awbuf->str.a, *sz, NULL, NULL );
109 /***********************************************************************
110 * MsiGetTargetPath (internal)
112 UINT WINAPI MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
113 awstring *szPathBuf, DWORD* pcchPathBuf )
120 return ERROR_INVALID_PARAMETER;
122 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
124 return ERROR_INVALID_HANDLE;
126 path = resolve_folder( package, szFolder, FALSE, FALSE, NULL );
127 msiobj_release( &package->hdr );
130 return ERROR_DIRECTORY;
132 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
133 HeapFree( GetProcessHeap(), 0, path );
137 /***********************************************************************
138 * MsiGetTargetPathA (MSI.@)
140 UINT WINAPI MsiGetTargetPathA( MSIHANDLE hInstall, LPCSTR szFolder,
141 LPSTR szPathBuf, DWORD* pcchPathBuf )
147 TRACE("%s %p %p\n", debugstr_a(szFolder), szPathBuf, pcchPathBuf);
149 szwFolder = strdupAtoW(szFolder);
150 if (szFolder && !szwFolder)
151 return ERROR_FUNCTION_FAILED;
153 path.unicode = FALSE;
154 path.str.a = szPathBuf;
156 r = MSI_GetTargetPath( hInstall, szwFolder, &path, pcchPathBuf );
158 HeapFree( GetProcessHeap(), 0, szwFolder );
163 /***********************************************************************
164 * MsiGetTargetPathW (MSI.@)
166 UINT WINAPI MsiGetTargetPathW( MSIHANDLE hInstall, LPCWSTR szFolder,
167 LPWSTR szPathBuf, DWORD* pcchPathBuf )
171 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf);
174 path.str.w = szPathBuf;
176 return MSI_GetTargetPath( hInstall, szFolder, &path, pcchPathBuf );
179 /***********************************************************************
180 * MsiGetSourcePath (internal)
182 static UINT MSI_GetSourcePath( MSIHANDLE hInstall, LPCWSTR szFolder,
183 awstring *szPathBuf, DWORD* pcchPathBuf )
189 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
192 return ERROR_INVALID_PARAMETER;
194 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
196 return ERROR_INVALID_HANDLE;
198 if (szPathBuf->str.w && !pcchPathBuf )
200 msiobj_release( &package->hdr );
201 return ERROR_INVALID_PARAMETER;
204 path = resolve_folder(package, szFolder, TRUE, FALSE, NULL);
205 msiobj_release( &package->hdr );
207 TRACE("path = %s\n",debugstr_w(path));
209 return ERROR_DIRECTORY;
211 r = msi_strcpy_to_awstring( path, szPathBuf, pcchPathBuf );
212 HeapFree( GetProcessHeap(), 0, path );
216 /***********************************************************************
217 * MsiGetSourcePathA (MSI.@)
219 UINT WINAPI MsiGetSourcePathA( MSIHANDLE hInstall, LPCSTR szFolder,
220 LPSTR szPathBuf, DWORD* pcchPathBuf )
226 TRACE("%s %p %p\n", szFolder, debugstr_a(szPathBuf), pcchPathBuf);
229 str.str.a = szPathBuf;
231 folder = strdupAtoW( szFolder );
232 r = MSI_GetSourcePath( hInstall, folder, &str, pcchPathBuf );
233 HeapFree( GetProcessHeap(), 0, folder );
238 /***********************************************************************
239 * MsiGetSourcePathW (MSI.@)
241 UINT WINAPI MsiGetSourcePathW( MSIHANDLE hInstall, LPCWSTR szFolder,
242 LPWSTR szPathBuf, DWORD* pcchPathBuf )
246 TRACE("%s %p %p\n", debugstr_w(szFolder), szPathBuf, pcchPathBuf );
249 str.str.w = szPathBuf;
251 return MSI_GetSourcePath( hInstall, szFolder, &str, pcchPathBuf );
254 /***********************************************************************
255 * MsiSetTargetPathA (MSI.@)
257 UINT WINAPI MsiSetTargetPathA(MSIHANDLE hInstall, LPCSTR szFolder,
261 LPWSTR szwFolderPath;
265 return ERROR_FUNCTION_FAILED;
267 return ERROR_FUNCTION_FAILED;
269 szwFolder = strdupAtoW(szFolder);
271 return ERROR_FUNCTION_FAILED;
273 szwFolderPath = strdupAtoW(szFolderPath);
276 HeapFree(GetProcessHeap(),0,szwFolder);
277 return ERROR_FUNCTION_FAILED;
280 rc = MsiSetTargetPathW(hInstall, szwFolder, szwFolderPath);
282 HeapFree(GetProcessHeap(),0,szwFolder);
283 HeapFree(GetProcessHeap(),0,szwFolderPath);
289 * Ok my original interpretation of this was wrong. And it looks like msdn has
290 * changed a bit also. The given folder path does not have to actually already
291 * exist, it just cannot be read only and must be a legal folder path.
293 UINT MSI_SetTargetPathW(MSIPACKAGE *package, LPCWSTR szFolder,
294 LPCWSTR szFolderPath)
301 TRACE("(%p %s %s)\n",package, debugstr_w(szFolder),debugstr_w(szFolderPath));
304 return ERROR_INVALID_HANDLE;
306 if (szFolderPath[0]==0)
307 return ERROR_FUNCTION_FAILED;
309 attrib = GetFileAttributesW(szFolderPath);
310 if ( attrib != INVALID_FILE_ATTRIBUTES &&
311 (!(attrib & FILE_ATTRIBUTE_DIRECTORY) ||
312 attrib & FILE_ATTRIBUTE_OFFLINE ||
313 attrib & FILE_ATTRIBUTE_READONLY))
314 return ERROR_FUNCTION_FAILED;
316 path = resolve_folder(package,szFolder,FALSE,FALSE,&folder);
319 return ERROR_INVALID_PARAMETER;
321 if (attrib == INVALID_FILE_ATTRIBUTES)
323 if (!CreateDirectoryW(szFolderPath,NULL))
324 return ERROR_FUNCTION_FAILED;
325 RemoveDirectoryW(szFolderPath);
328 HeapFree(GetProcessHeap(),0,folder->Property);
329 folder->Property = build_directory_name(2, szFolderPath, NULL);
331 if (lstrcmpiW(path, folder->Property) == 0)
334 * Resolved Target has not really changed, so just
335 * set this folder and do not recalculate everything.
337 HeapFree(GetProcessHeap(),0,folder->ResolvedTarget);
338 folder->ResolvedTarget = NULL;
339 path2 = resolve_folder(package,szFolder,FALSE,TRUE,NULL);
340 HeapFree(GetProcessHeap(),0,path2);
346 LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
348 HeapFree( GetProcessHeap(),0,f->ResolvedTarget);
349 f->ResolvedTarget=NULL;
352 LIST_FOR_EACH_ENTRY( f, &package->folders, MSIFOLDER, entry )
354 path2 = resolve_folder(package, f->Directory, FALSE, TRUE, NULL);
355 HeapFree(GetProcessHeap(),0,path2);
358 HeapFree(GetProcessHeap(),0,path);
360 return ERROR_SUCCESS;
363 /***********************************************************************
364 * MsiSetTargetPathW (MSI.@)
366 UINT WINAPI MsiSetTargetPathW(MSIHANDLE hInstall, LPCWSTR szFolder,
367 LPCWSTR szFolderPath)
372 TRACE("(%s %s)\n",debugstr_w(szFolder),debugstr_w(szFolderPath));
374 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
375 ret = MSI_SetTargetPathW( package, szFolder, szFolderPath );
376 msiobj_release( &package->hdr );
380 /***********************************************************************
383 * Returns an internal installer state (if it is running in a mode iRunMode)
386 * hInstall [I] Handle to the installation
387 * hRunMode [I] Checking run mode
388 * MSIRUNMODE_ADMIN Administrative mode
389 * MSIRUNMODE_ADVERTISE Advertisement mode
390 * MSIRUNMODE_MAINTENANCE Maintenance mode
391 * MSIRUNMODE_ROLLBACKENABLED Rollback is enabled
392 * MSIRUNMODE_LOGENABLED Log file is writing
393 * MSIRUNMODE_OPERATIONS Operations in progress??
394 * MSIRUNMODE_REBOOTATEND We need to reboot after installation completed
395 * MSIRUNMODE_REBOOTNOW We need to reboot to continue the installation
396 * MSIRUNMODE_CABINET Files from cabinet are installed
397 * MSIRUNMODE_SOURCESHORTNAMES Long names in source files is suppressed
398 * MSIRUNMODE_TARGETSHORTNAMES Long names in destination files is suppressed
399 * MSIRUNMODE_RESERVED11 Reserved
400 * MSIRUNMODE_WINDOWS9X Running under Windows95/98
401 * MSIRUNMODE_ZAWENABLED Demand installation is supported
402 * MSIRUNMODE_RESERVED14 Reserved
403 * MSIRUNMODE_RESERVED15 Reserved
404 * MSIRUNMODE_SCHEDULED called from install script
405 * MSIRUNMODE_ROLLBACK called from rollback script
406 * MSIRUNMODE_COMMIT called from commit script
410 * Not in the state: FALSE
414 BOOL WINAPI MsiGetMode(MSIHANDLE hInstall, MSIRUNMODE iRunMode)
416 FIXME("STUB (iRunMode=%i)\n",iRunMode);
420 /***********************************************************************
421 * MsiSetFeatureStateA (MSI.@)
423 * According to the docs, when this is called it immediately recalculates
424 * all the component states as well
426 UINT WINAPI MsiSetFeatureStateA(MSIHANDLE hInstall, LPCSTR szFeature,
429 LPWSTR szwFeature = NULL;
432 szwFeature = strdupAtoW(szFeature);
435 return ERROR_FUNCTION_FAILED;
437 rc = MsiSetFeatureStateW(hInstall,szwFeature, iState);
439 HeapFree(GetProcessHeap(),0,szwFeature);
446 UINT WINAPI MSI_SetFeatureStateW(MSIPACKAGE* package, LPCWSTR szFeature,
449 UINT rc = ERROR_SUCCESS;
450 MSIFEATURE *feature, *child;
452 TRACE(" %s to %i\n",debugstr_w(szFeature), iState);
454 feature = get_loaded_feature(package,szFeature);
456 return ERROR_UNKNOWN_FEATURE;
458 if (iState == INSTALLSTATE_ADVERTISED &&
459 feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
460 return ERROR_FUNCTION_FAILED;
462 feature->ActionRequest = iState;
463 feature->Action = iState;
465 ACTION_UpdateComponentStates(package,szFeature);
467 /* update all the features that are children of this feature */
468 LIST_FOR_EACH_ENTRY( child, &package->features, MSIFEATURE, entry )
470 if (lstrcmpW(szFeature, child->Feature_Parent) == 0)
471 MSI_SetFeatureStateW(package, child->Feature, iState);
477 /***********************************************************************
478 * MsiSetFeatureStateW (MSI.@)
480 UINT WINAPI MsiSetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
484 UINT rc = ERROR_SUCCESS;
486 TRACE(" %s to %i\n",debugstr_w(szFeature), iState);
488 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
490 return ERROR_INVALID_HANDLE;
492 rc = MSI_SetFeatureStateW(package,szFeature,iState);
494 msiobj_release( &package->hdr );
498 /***********************************************************************
499 * MsiGetFeatureStateA (MSI.@)
501 UINT WINAPI MsiGetFeatureStateA(MSIHANDLE hInstall, LPSTR szFeature,
502 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
504 LPWSTR szwFeature = NULL;
507 szwFeature = strdupAtoW(szFeature);
509 rc = MsiGetFeatureStateW(hInstall,szwFeature,piInstalled, piAction);
511 HeapFree( GetProcessHeap(), 0 , szwFeature);
516 UINT MSI_GetFeatureStateW(MSIPACKAGE *package, LPWSTR szFeature,
517 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
521 feature = get_loaded_feature(package,szFeature);
523 return ERROR_UNKNOWN_FEATURE;
526 *piInstalled = feature->Installed;
529 *piAction = feature->Action;
531 TRACE("returning %i %i\n", feature->Installed, feature->Action);
533 return ERROR_SUCCESS;
536 /***********************************************************************
537 * MsiGetFeatureStateW (MSI.@)
539 UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPWSTR szFeature,
540 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
545 TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szFeature), piInstalled,
548 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
550 return ERROR_INVALID_HANDLE;
551 ret = MSI_GetFeatureStateW(package, szFeature, piInstalled, piAction);
552 msiobj_release( &package->hdr );
556 /***********************************************************************
557 * MsiSetComponentStateA (MSI.@)
559 UINT WINAPI MsiSetComponentStateA(MSIHANDLE hInstall, LPCSTR szComponent,
563 LPWSTR szwComponent = strdupAtoW(szComponent);
565 rc = MsiSetComponentStateW(hInstall, szwComponent, iState);
567 HeapFree(GetProcessHeap(), 0, szwComponent);
572 /***********************************************************************
573 * MsiGetComponentStateA (MSI.@)
575 UINT WINAPI MsiGetComponentStateA(MSIHANDLE hInstall, LPSTR szComponent,
576 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
578 LPWSTR szwComponent= NULL;
581 szwComponent= strdupAtoW(szComponent);
583 rc = MsiGetComponentStateW(hInstall,szwComponent,piInstalled, piAction);
585 HeapFree( GetProcessHeap(), 0 , szwComponent);
590 static UINT MSI_SetComponentStateW(MSIPACKAGE *package, LPCWSTR szComponent,
595 TRACE("%p %s %d\n", package, debugstr_w(szComponent), iState);
597 comp = get_loaded_component(package, szComponent);
599 return ERROR_UNKNOWN_COMPONENT;
601 comp->Installed = iState;
603 return ERROR_SUCCESS;
606 UINT MSI_GetComponentStateW(MSIPACKAGE *package, LPWSTR szComponent,
607 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
611 TRACE("%p %s %p %p\n", package, debugstr_w(szComponent),
612 piInstalled, piAction);
614 comp = get_loaded_component(package,szComponent);
616 return ERROR_UNKNOWN_COMPONENT;
619 *piInstalled = comp->Installed;
622 *piAction = comp->Action;
624 TRACE("states (%i, %i)\n", comp->Installed, comp->Action );
626 return ERROR_SUCCESS;
629 /***********************************************************************
630 * MsiSetComponentStateW (MSI.@)
632 UINT WINAPI MsiSetComponentStateW(MSIHANDLE hInstall, LPCWSTR szComponent,
638 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
640 return ERROR_INVALID_HANDLE;
641 ret = MSI_SetComponentStateW(package, szComponent, iState);
642 msiobj_release(&package->hdr);
646 /***********************************************************************
647 * MsiGetComponentStateW (MSI.@)
649 UINT WINAPI MsiGetComponentStateW(MSIHANDLE hInstall, LPWSTR szComponent,
650 INSTALLSTATE *piInstalled, INSTALLSTATE *piAction)
655 TRACE("%ld %s %p %p\n", hInstall, debugstr_w(szComponent),
656 piInstalled, piAction);
658 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
660 return ERROR_INVALID_HANDLE;
661 ret = MSI_GetComponentStateW( package, szComponent, piInstalled, piAction);
662 msiobj_release( &package->hdr );
666 /***********************************************************************
667 * MsiGetLanguage (MSI.@)
669 LANGID WINAPI MsiGetLanguage(MSIHANDLE hInstall)
674 static const WCHAR szProductLanguage[] =
675 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
677 package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
679 return ERROR_INVALID_HANDLE;
681 buffer = load_dynamic_property(package,szProductLanguage,NULL);
682 langid = atoiW(buffer);
684 HeapFree(GetProcessHeap(),0,buffer);
685 msiobj_release (&package->hdr);