2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2002,2003,2004,2005 Mike McCormack 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define NONAMELESSUNION
31 #include "wine/debug.h"
42 #include "wine/unicode.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msi);
46 static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
48 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
51 LPWSTR szwProd = NULL;
53 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
57 szwProd = strdupAtoW( szProduct );
59 return ERROR_OUTOFMEMORY;
62 r = MsiOpenProductW( szwProd, phProduct );
69 static UINT MSI_OpenProductW( LPCWSTR szProduct, MSIPACKAGE **ppackage )
73 HKEY hKeyProduct = NULL;
76 TRACE("%s %p\n", debugstr_w(szProduct), ppackage );
78 r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
79 if( r != ERROR_SUCCESS )
81 r = ERROR_UNKNOWN_PRODUCT;
85 /* find the size of the path */
87 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
88 NULL, &type, NULL, &count );
89 if( r != ERROR_SUCCESS )
91 r = ERROR_UNKNOWN_PRODUCT;
95 /* now alloc and fetch the path of the database to open */
96 path = msi_alloc( count );
100 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
101 NULL, &type, (LPBYTE) path, &count );
102 if( r != ERROR_SUCCESS )
104 r = ERROR_UNKNOWN_PRODUCT;
108 r = MSI_OpenPackageW( path, ppackage );
113 RegCloseKey( hKeyProduct );
118 UINT WINAPI MsiOpenProductW( LPCWSTR szProduct, MSIHANDLE *phProduct )
120 MSIPACKAGE *package = NULL;
123 r = MSI_OpenProductW( szProduct, &package );
124 if( r == ERROR_SUCCESS )
126 *phProduct = alloc_msihandle( &package->hdr );
128 r = ERROR_NOT_ENOUGH_MEMORY;
129 msiobj_release( &package->hdr );
134 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
135 LPCSTR szTransforms, LANGID lgidLanguage)
137 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
138 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
139 return ERROR_CALL_NOT_IMPLEMENTED;
142 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
143 LPCWSTR szTransforms, LANGID lgidLanguage)
145 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
146 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
147 return ERROR_CALL_NOT_IMPLEMENTED;
150 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
151 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
153 FIXME("%s %s %s %08x %08x %08x\n", debugstr_a(szPackagePath),
154 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
155 lgidLanguage, dwPlatform, dwOptions);
156 return ERROR_CALL_NOT_IMPLEMENTED;
159 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
160 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
162 FIXME("%s %s %s %08x %08x %08x\n", debugstr_w(szPackagePath),
163 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
164 lgidLanguage, dwPlatform, dwOptions);
165 return ERROR_CALL_NOT_IMPLEMENTED;
168 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
170 LPWSTR szwPath = NULL, szwCommand = NULL;
171 UINT r = ERROR_OUTOFMEMORY;
173 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
177 szwPath = strdupAtoW( szPackagePath );
184 szwCommand = strdupAtoW( szCommandLine );
189 r = MsiInstallProductW( szwPath, szwCommand );
193 msi_free( szwCommand );
198 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
200 MSIPACKAGE *package = NULL;
203 TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
205 r = MSI_OpenPackageW( szPackagePath, &package );
206 if (r == ERROR_SUCCESS)
208 r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
209 msiobj_release( &package->hdr );
215 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
217 FIXME("%s %08x\n", debugstr_a(szProduct), dwReinstallMode);
218 return ERROR_CALL_NOT_IMPLEMENTED;
221 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
223 FIXME("%s %08x\n", debugstr_w(szProduct), dwReinstallMode);
224 return ERROR_CALL_NOT_IMPLEMENTED;
227 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
228 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
230 LPWSTR patch_package = NULL;
231 LPWSTR install_package = NULL;
232 LPWSTR command_line = NULL;
233 UINT r = ERROR_OUTOFMEMORY;
235 TRACE("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
236 eInstallType, debugstr_a(szCommandLine));
238 if (szPatchPackage && !(patch_package = strdupAtoW(szPatchPackage)))
241 if (szInstallPackage && !(install_package = strdupAtoW(szInstallPackage)))
244 if (szCommandLine && !(command_line = strdupAtoW(szCommandLine)))
247 r = MsiApplyPatchW(patch_package, install_package, eInstallType, command_line);
250 msi_free(patch_package);
251 msi_free(install_package);
252 msi_free(command_line);
257 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
258 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
260 MSIHANDLE patch, info;
263 LPCWSTR cmd_ptr = szCommandLine;
265 LPWSTR cmd = NULL, codes = NULL;
267 static const WCHAR space[] = {' ',0};
268 static const WCHAR patcheq[] = {'P','A','T','C','H','=',0};
269 static WCHAR empty[] = {0};
271 TRACE("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
272 eInstallType, debugstr_w(szCommandLine));
274 if (szInstallPackage || eInstallType == INSTALLTYPE_NETWORK_IMAGE ||
275 eInstallType == INSTALLTYPE_SINGLE_INSTANCE)
277 FIXME("Only reading target products from patch\n");
278 return ERROR_CALL_NOT_IMPLEMENTED;
281 r = MsiOpenDatabaseW(szPatchPackage, MSIDBOPEN_READONLY, &patch);
282 if (r != ERROR_SUCCESS)
285 r = MsiGetSummaryInformationW(patch, NULL, 0, &info);
286 if (r != ERROR_SUCCESS)
289 r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, empty, &size);
290 if (r != ERROR_MORE_DATA || !size || type != VT_LPSTR)
292 ERR("Failed to read product codes from patch\n");
296 codes = msi_alloc(++size * sizeof(WCHAR));
299 r = ERROR_OUTOFMEMORY;
303 r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, codes, &size);
304 if (r != ERROR_SUCCESS)
310 size = lstrlenW(cmd_ptr) + lstrlenW(patcheq) + lstrlenW(szPatchPackage) + 1;
311 cmd = msi_alloc(size * sizeof(WCHAR));
314 r = ERROR_OUTOFMEMORY;
318 lstrcpyW(cmd, cmd_ptr);
319 if (szCommandLine) lstrcatW(cmd, space);
320 lstrcatW(cmd, patcheq);
321 lstrcatW(cmd, szPatchPackage);
324 while ((end = strchrW(beg, '}')))
328 r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd);
329 if (r != ERROR_SUCCESS)
339 MsiCloseHandle(info);
340 MsiCloseHandle(patch);
345 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
346 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
348 MSIPACKAGE* package = NULL;
351 WCHAR sourcepath[MAX_PATH];
352 WCHAR filename[MAX_PATH];
353 static const WCHAR szInstalled[] = {
354 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
357 TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
358 debugstr_w(szCommandLine));
360 if (eInstallState != INSTALLSTATE_LOCAL &&
361 eInstallState != INSTALLSTATE_DEFAULT)
363 FIXME("Not implemented for anything other than local installs\n");
364 return ERROR_CALL_NOT_IMPLEMENTED;
367 sz = sizeof(sourcepath);
368 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
369 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
372 sz = sizeof(filename);
373 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
374 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
376 lstrcatW(sourcepath,filename);
379 * ok 1, we need to find the msi file for this product.
380 * 2, find the source dir for the files
381 * 3, do the configure/install.
382 * 4, cleanupany runonce entry.
385 r = MSI_OpenProductW( szProduct, &package );
386 if (r != ERROR_SUCCESS)
389 sz = lstrlenW(szInstalled) + 1;
392 sz += lstrlenW(szCommandLine);
394 commandline = msi_alloc(sz * sizeof(WCHAR));
397 r = ERROR_OUTOFMEMORY;
403 lstrcpyW(commandline,szCommandLine);
405 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
406 lstrcatW(commandline,szInstalled);
408 r = MSI_InstallPackage( package, sourcepath, commandline );
410 msi_free(commandline);
413 msiobj_release( &package->hdr );
418 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
419 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
421 LPWSTR szwProduct = NULL;
422 LPWSTR szwCommandLine = NULL;
423 UINT r = ERROR_OUTOFMEMORY;
427 szwProduct = strdupAtoW( szProduct );
434 szwCommandLine = strdupAtoW( szCommandLine );
439 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
442 msi_free( szwProduct );
443 msi_free( szwCommandLine);
448 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
449 INSTALLSTATE eInstallState)
451 LPWSTR szwProduct = NULL;
454 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
458 szwProduct = strdupAtoW( szProduct );
460 return ERROR_OUTOFMEMORY;
463 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
464 msi_free( szwProduct );
469 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
470 INSTALLSTATE eInstallState)
472 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
475 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
477 LPWSTR szwComponent = NULL;
479 WCHAR szwBuffer[GUID_SIZE];
481 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
485 szwComponent = strdupAtoW( szComponent );
487 return ERROR_OUTOFMEMORY;
490 r = MsiGetProductCodeW( szwComponent, szwBuffer );
492 if( ERROR_SUCCESS == r )
493 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
495 msi_free( szwComponent );
500 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
504 WCHAR szSquished[GUID_SIZE];
505 DWORD sz = GUID_SIZE;
506 static const WCHAR szPermKey[] =
507 { '0','0','0','0','0','0','0','0','0','0','0','0',
508 '0','0','0','0','0','0','0','0','0','0','0','0',
509 '0','0','0','0','0','0','0','0',0};
511 TRACE("%s %p\n",debugstr_w(szComponent), szBuffer);
513 if (NULL == szComponent)
514 return ERROR_INVALID_PARAMETER;
516 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
517 if (rc != ERROR_SUCCESS)
518 return ERROR_UNKNOWN_COMPONENT;
520 rc = RegEnumValueW(hkey, 0, szSquished, &sz, NULL, NULL, NULL, NULL);
521 if (rc == ERROR_SUCCESS && strcmpW(szSquished,szPermKey)==0)
524 rc = RegEnumValueW(hkey, 1, szSquished, &sz, NULL, NULL, NULL, NULL);
529 if (rc != ERROR_SUCCESS)
530 return ERROR_INSTALL_FAILURE;
532 unsquash_guid(szSquished, szBuffer);
533 return ERROR_SUCCESS;
536 static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
537 awstring *szValue, LPDWORD pcchValueBuf)
543 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
544 debugstr_w(szAttribute), szValue, pcchValueBuf);
547 * FIXME: Values seem scattered/duplicated in the registry. Is there a system?
550 if ((szValue->str.w && !pcchValueBuf) || !szProduct || !szProduct[0] || !szAttribute)
551 return ERROR_INVALID_PARAMETER;
553 /* check for special properties */
554 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
557 WCHAR packagecode[35];
559 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
560 if (r != ERROR_SUCCESS)
561 return ERROR_UNKNOWN_PRODUCT;
563 regval = msi_reg_get_val_str( hkey, szAttribute );
566 if (unsquash_guid(regval, packagecode))
567 val = strdupW(packagecode);
573 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
575 static const WCHAR one[] = { '1',0 };
577 * FIXME: should be in the Product key (user or system?)
578 * but isn't written yet...
580 val = strdupW( one );
582 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
583 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW))
585 static const WCHAR fmt[] = { '%','u',0 };
589 r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
590 if (r != ERROR_SUCCESS)
591 return ERROR_UNKNOWN_PRODUCT;
593 if (msi_reg_get_val_dword( hkey, szAttribute, ®val))
595 sprintfW(szVal, fmt, regval);
596 val = strdupW( szVal );
601 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW))
603 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
604 if (r != ERROR_SUCCESS)
605 return ERROR_UNKNOWN_PRODUCT;
607 val = msi_reg_get_val_str( hkey, szAttribute );
611 else if (!szAttribute[0])
613 return ERROR_UNKNOWN_PROPERTY;
617 static const WCHAR szDisplayVersion[] = {
618 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0 };
620 FIXME("%s\n", debugstr_w(szAttribute));
621 /* FIXME: some attribute values not tested... */
623 if (!lstrcmpW( szAttribute, INSTALLPROPERTY_VERSIONSTRINGW ))
624 szAttribute = szDisplayVersion;
626 r = MSIREG_OpenUninstallKey( szProduct, &hkey, FALSE );
627 if (r != ERROR_SUCCESS)
628 return ERROR_UNKNOWN_PRODUCT;
630 val = msi_reg_get_val_str( hkey, szAttribute );
635 TRACE("returning %s\n", debugstr_w(val));
638 return ERROR_UNKNOWN_PROPERTY;
640 r = msi_strcpy_to_awstring( val, szValue, pcchValueBuf );
647 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
648 LPSTR szBuffer, LPDWORD pcchValueBuf)
650 LPWSTR szwProduct, szwAttribute = NULL;
651 UINT r = ERROR_OUTOFMEMORY;
654 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
655 szBuffer, pcchValueBuf);
657 szwProduct = strdupAtoW( szProduct );
658 if( szProduct && !szwProduct )
661 szwAttribute = strdupAtoW( szAttribute );
662 if( szAttribute && !szwAttribute )
665 buffer.unicode = FALSE;
666 buffer.str.a = szBuffer;
668 r = MSI_GetProductInfo( szwProduct, szwAttribute,
669 &buffer, pcchValueBuf );
672 msi_free( szwProduct );
673 msi_free( szwAttribute );
678 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
679 LPWSTR szBuffer, LPDWORD pcchValueBuf)
683 TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute),
684 szBuffer, pcchValueBuf);
686 buffer.unicode = TRUE;
687 buffer.str.w = szBuffer;
689 return MSI_GetProductInfo( szProduct, szAttribute,
690 &buffer, pcchValueBuf );
693 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
695 LPWSTR szwLogFile = NULL;
698 TRACE("%08x %s %08x\n", dwLogMode, debugstr_a(szLogFile), attributes);
702 szwLogFile = strdupAtoW( szLogFile );
704 return ERROR_OUTOFMEMORY;
706 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
707 msi_free( szwLogFile );
711 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
713 HANDLE file = INVALID_HANDLE_VALUE;
715 TRACE("%08x %s %08x\n", dwLogMode, debugstr_w(szLogFile), attributes);
719 lstrcpyW(gszLogFile,szLogFile);
720 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
721 DeleteFileW(szLogFile);
722 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
723 FILE_ATTRIBUTE_NORMAL, NULL);
724 if (file != INVALID_HANDLE_VALUE)
727 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
730 gszLogFile[0] = '\0';
732 return ERROR_SUCCESS;
735 UINT WINAPI MsiEnumComponentCostsW(MSIHANDLE hInstall, LPCWSTR szComponent,
736 DWORD dwIndex, INSTALLSTATE iState,
737 LPWSTR lpDriveBuf, DWORD *pcchDriveBuf,
738 int *piCost, int *pTempCost)
740 FIXME("(%ld, %s, %d, %d, %p, %p, %p %p): stub!\n", hInstall,
741 debugstr_w(szComponent), dwIndex, iState, lpDriveBuf,
742 pcchDriveBuf, piCost, pTempCost);
744 return ERROR_NO_MORE_ITEMS;
747 UINT WINAPI MsiQueryComponentStateA(LPCSTR szProductCode,
748 LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext,
749 LPCSTR szComponent, INSTALLSTATE *pdwState)
751 LPWSTR prodcode = NULL, usersid = NULL, comp = NULL;
754 TRACE("(%s, %s, %d, %s, %p)\n", debugstr_a(szProductCode),
755 debugstr_a(szUserSid), dwContext, debugstr_a(szComponent), pdwState);
757 if (szProductCode && !(prodcode = strdupAtoW(szProductCode)))
758 return ERROR_OUTOFMEMORY;
760 if (szUserSid && !(usersid = strdupAtoW(szUserSid)))
761 return ERROR_OUTOFMEMORY;
763 if (szComponent && !(comp = strdupAtoW(szComponent)))
764 return ERROR_OUTOFMEMORY;
766 r = MsiQueryComponentStateW(prodcode, usersid, dwContext, comp, pdwState);
775 static BOOL msi_comp_find_prod_key(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
780 if (context == MSIINSTALLCONTEXT_MACHINE)
781 r = MSIREG_OpenLocalClassesProductKey(prodcode, &hkey, FALSE);
782 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
783 r = MSIREG_OpenUserProductsKey(prodcode, &hkey, FALSE);
785 r = MSIREG_OpenLocalManagedProductKey(prodcode, &hkey, FALSE);
788 return (r == ERROR_SUCCESS);
791 static BOOL msi_comp_find_package(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
799 static const WCHAR local_package[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
800 static const WCHAR managed_local_package[] = {
801 'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0
804 if (context == MSIINSTALLCONTEXT_MACHINE)
805 r = MSIREG_OpenLocalSystemProductKey(prodcode, &hkey, FALSE);
807 r = MSIREG_OpenInstallPropertiesKey(prodcode, &hkey, FALSE);
809 if (r != ERROR_SUCCESS)
812 if (context == MSIINSTALLCONTEXT_USERMANAGED)
813 package = managed_local_package;
815 package = local_package;
818 res = RegQueryValueExW(hkey, package, NULL, NULL, NULL, &sz);
821 return (res == ERROR_SUCCESS);
824 static BOOL msi_comp_find_prodcode(LPCWSTR prodcode, LPWSTR squished_pc,
825 MSIINSTALLCONTEXT context,
826 LPCWSTR comp, DWORD *sz)
832 if (context == MSIINSTALLCONTEXT_MACHINE)
833 r = MSIREG_OpenLocalSystemComponentKey(comp, &hkey, FALSE);
835 r = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
837 if (r != ERROR_SUCCESS)
841 res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, NULL, sz);
842 if (res != ERROR_SUCCESS)
849 UINT WINAPI MsiQueryComponentStateW(LPCWSTR szProductCode,
850 LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
851 LPCWSTR szComponent, INSTALLSTATE *pdwState)
853 WCHAR squished_pc[GUID_SIZE];
857 TRACE("(%s, %s, %d, %s, %p)\n", debugstr_w(szProductCode),
858 debugstr_w(szUserSid), dwContext, debugstr_w(szComponent), pdwState);
861 return ERROR_INVALID_PARAMETER;
863 if (!szProductCode || !*szProductCode || lstrlenW(szProductCode) != GUID_SIZE - 1)
864 return ERROR_INVALID_PARAMETER;
866 if (!squash_guid(szProductCode, squished_pc))
867 return ERROR_INVALID_PARAMETER;
869 found = msi_comp_find_prod_key(szProductCode, dwContext);
871 if (!msi_comp_find_package(szProductCode, dwContext))
875 *pdwState = INSTALLSTATE_UNKNOWN;
876 return ERROR_UNKNOWN_COMPONENT;
879 return ERROR_UNKNOWN_PRODUCT;
882 *pdwState = INSTALLSTATE_UNKNOWN;
884 if (!msi_comp_find_prodcode(szProductCode, squished_pc, dwContext, szComponent, &sz))
885 return ERROR_UNKNOWN_COMPONENT;
888 *pdwState = INSTALLSTATE_NOTUSED;
890 *pdwState = INSTALLSTATE_LOCAL;
892 return ERROR_SUCCESS;
895 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
897 LPWSTR szwProduct = NULL;
902 szwProduct = strdupAtoW( szProduct );
904 return ERROR_OUTOFMEMORY;
906 r = MsiQueryProductStateW( szwProduct );
907 msi_free( szwProduct );
911 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
914 INSTALLSTATE state = INSTALLSTATE_UNKNOWN;
915 HKEY hkey = 0, props = 0;
917 BOOL userkey_exists = FALSE;
919 static const int GUID_LEN = 38;
920 static const WCHAR szInstallProperties[] = {
921 'I','n','s','t','a','l','l','P','r','o','p','e','r','t','i','e','s',0
923 static const WCHAR szWindowsInstaller[] = {
924 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0
927 TRACE("%s\n", debugstr_w(szProduct));
929 if (!szProduct || !*szProduct || lstrlenW(szProduct) != GUID_LEN)
930 return INSTALLSTATE_INVALIDARG;
932 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
933 if (rc == ERROR_SUCCESS)
935 userkey_exists = TRUE;
936 state = INSTALLSTATE_ADVERTISED;
940 rc = MSIREG_OpenUserDataProductKey(szProduct,&hkey,FALSE);
941 if (rc != ERROR_SUCCESS)
944 rc = RegOpenKeyW(hkey, szInstallProperties, &props);
945 if (rc != ERROR_SUCCESS)
949 rc = RegQueryValueExW(props,szWindowsInstaller,NULL,NULL,(LPVOID)&state, &sz);
950 if (rc != ERROR_SUCCESS)
954 state = INSTALLSTATE_DEFAULT;
956 state = INSTALLSTATE_UNKNOWN;
958 if (state == INSTALLSTATE_DEFAULT && !userkey_exists)
959 state = INSTALLSTATE_ABSENT;
967 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
969 INSTALLUILEVEL old = gUILevel;
970 HWND oldwnd = gUIhwnd;
972 TRACE("%08x %p\n", dwUILevel, phWnd);
974 gUILevel = dwUILevel;
983 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
984 DWORD dwMessageFilter, LPVOID pvContext)
986 INSTALLUI_HANDLERA prev = gUIHandlerA;
988 TRACE("%p %x %p\n",puiHandler, dwMessageFilter,pvContext);
989 gUIHandlerA = puiHandler;
990 gUIFilter = dwMessageFilter;
991 gUIContext = pvContext;
996 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
997 DWORD dwMessageFilter, LPVOID pvContext)
999 INSTALLUI_HANDLERW prev = gUIHandlerW;
1001 TRACE("%p %x %p\n",puiHandler,dwMessageFilter,pvContext);
1002 gUIHandlerW = puiHandler;
1003 gUIFilter = dwMessageFilter;
1004 gUIContext = pvContext;
1009 /******************************************************************
1010 * MsiLoadStringW [MSI.@]
1012 * Loads a string from MSI's string resources.
1016 * handle [I] only -1 is handled currently
1017 * id [I] id of the string to be loaded
1018 * lpBuffer [O] buffer for the string to be written to
1019 * nBufferMax [I] maximum size of the buffer in characters
1020 * lang [I] the preferred language for the string
1024 * If successful, this function returns the language id of the string loaded
1025 * If the function fails, the function returns zero.
1029 * The type of the first parameter is unknown. LoadString's prototype
1030 * suggests that it might be a module handle. I have made it an MSI handle
1031 * for starters, as -1 is an invalid MSI handle, but not an invalid module
1032 * handle. Maybe strings can be stored in an MSI database somehow.
1034 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
1035 int nBufferMax, LANGID lang )
1042 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
1045 FIXME("don't know how to deal with handle = %08lx\n", handle);
1048 lang = GetUserDefaultLangID();
1050 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
1054 hResData = LoadResource( msi_hInstance, hres );
1057 p = LockResource( hResData );
1061 for (i = 0; i < (id&0xf); i++)
1065 if( nBufferMax <= len )
1068 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
1069 lpBuffer[ len ] = 0;
1071 TRACE("found -> %s\n", debugstr_w(lpBuffer));
1076 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
1077 int nBufferMax, LANGID lang )
1083 bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
1084 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
1087 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
1088 if( len <= nBufferMax )
1089 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
1090 lpBuffer, nBufferMax, NULL, NULL );
1098 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
1101 char szProduct[GUID_SIZE];
1103 TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
1105 if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
1106 return INSTALLSTATE_UNKNOWN;
1108 return MsiGetComponentPathA( szProduct, szComponent, lpPathBuf, pcchBuf );
1111 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
1114 WCHAR szProduct[GUID_SIZE];
1116 TRACE("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
1118 if (MsiGetProductCodeW( szComponent, szProduct ) != ERROR_SUCCESS)
1119 return INSTALLSTATE_UNKNOWN;
1121 return MsiGetComponentPathW( szProduct, szComponent, lpPathBuf, pcchBuf );
1124 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
1125 WORD wLanguageId, DWORD f)
1127 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_a(lpText), debugstr_a(lpCaption),
1128 uType, wLanguageId, f);
1129 return MessageBoxExA(hWnd,lpText,lpCaption,uType,wLanguageId);
1132 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
1133 WORD wLanguageId, DWORD f)
1135 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_w(lpText), debugstr_w(lpCaption),
1136 uType, wLanguageId, f);
1137 return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId);
1140 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
1141 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
1142 LPDWORD pcchPathBuf )
1144 FIXME("%s %s %08x %08x %p %p\n", debugstr_a(szAssemblyName),
1145 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
1147 return ERROR_CALL_NOT_IMPLEMENTED;
1150 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
1151 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
1152 LPDWORD pcchPathBuf )
1154 FIXME("%s %s %08x %08x %p %p\n", debugstr_w(szAssemblyName),
1155 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
1157 return ERROR_CALL_NOT_IMPLEMENTED;
1160 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
1161 LPSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs )
1163 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
1164 return ERROR_CALL_NOT_IMPLEMENTED;
1167 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
1168 LPWSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs )
1170 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
1171 return ERROR_CALL_NOT_IMPLEMENTED;
1174 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
1175 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData,
1176 LPDWORD pcbHashData)
1178 FIXME("%s %08x %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
1179 ppcCertContext, pbHashData, pcbHashData);
1180 return ERROR_CALL_NOT_IMPLEMENTED;
1183 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
1184 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData,
1185 LPDWORD pcbHashData)
1187 FIXME("%s %08x %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
1188 ppcCertContext, pbHashData, pcbHashData);
1189 return ERROR_CALL_NOT_IMPLEMENTED;
1192 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
1193 LPSTR szValue, LPDWORD pccbValue )
1195 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
1196 return ERROR_CALL_NOT_IMPLEMENTED;
1199 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
1200 LPWSTR szValue, LPDWORD pccbValue )
1202 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
1203 return ERROR_CALL_NOT_IMPLEMENTED;
1206 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
1209 LPWSTR szPack = NULL;
1211 TRACE("%s\n", debugstr_a(szPackage) );
1215 szPack = strdupAtoW( szPackage );
1217 return ERROR_OUTOFMEMORY;
1220 r = MsiVerifyPackageW( szPack );
1227 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
1232 TRACE("%s\n", debugstr_w(szPackage) );
1234 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
1235 MsiCloseHandle( handle );
1240 static INSTALLSTATE WINAPI MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
1241 awstring* lpPathBuf, LPDWORD pcchBuf)
1243 WCHAR squished_pc[GUID_SIZE];
1244 WCHAR squished_comp[GUID_SIZE];
1250 static const WCHAR wininstaller[] = {
1251 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
1253 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
1254 debugstr_w(szComponent), lpPathBuf->str.w, pcchBuf);
1256 if (!szProduct || !szComponent)
1257 return INSTALLSTATE_INVALIDARG;
1259 if (lpPathBuf->str.w && !pcchBuf)
1260 return INSTALLSTATE_INVALIDARG;
1262 if (!squash_guid(szProduct, squished_pc) ||
1263 !squash_guid(szComponent, squished_comp))
1264 return INSTALLSTATE_INVALIDARG;
1266 state = INSTALLSTATE_UNKNOWN;
1268 if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
1269 MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
1271 path = msi_reg_get_val_str(hkey, squished_pc);
1274 state = INSTALLSTATE_ABSENT;
1276 if ((MSIREG_OpenLocalSystemProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
1277 MSIREG_OpenUserDataProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS) &&
1278 msi_reg_get_val_dword(hkey, wininstaller, &version) &&
1279 GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
1282 state = INSTALLSTATE_LOCAL;
1286 if (state != INSTALLSTATE_LOCAL &&
1287 (MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
1288 MSIREG_OpenLocalClassesProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS))
1292 if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
1293 MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
1296 path = msi_reg_get_val_str(hkey, squished_pc);
1299 state = INSTALLSTATE_ABSENT;
1301 if (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
1302 state = INSTALLSTATE_LOCAL;
1307 return INSTALLSTATE_UNKNOWN;
1309 if (state == INSTALLSTATE_LOCAL && !*path)
1310 state = INSTALLSTATE_NOTUSED;
1312 msi_strcpy_to_awstring(path, lpPathBuf, pcchBuf);
1317 /******************************************************************
1318 * MsiGetComponentPathW [MSI.@]
1320 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1321 LPWSTR lpPathBuf, LPDWORD pcchBuf)
1325 path.unicode = TRUE;
1326 path.str.w = lpPathBuf;
1328 return MSI_GetComponentPath( szProduct, szComponent, &path, pcchBuf );
1331 /******************************************************************
1332 * MsiGetComponentPathA [MSI.@]
1334 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
1335 LPSTR lpPathBuf, LPDWORD pcchBuf)
1337 LPWSTR szwProduct, szwComponent = NULL;
1338 INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
1341 szwProduct = strdupAtoW( szProduct );
1342 if( szProduct && !szwProduct)
1345 szwComponent = strdupAtoW( szComponent );
1346 if( szComponent && !szwComponent )
1349 path.unicode = FALSE;
1350 path.str.a = lpPathBuf;
1352 r = MSI_GetComponentPath( szwProduct, szwComponent, &path, pcchBuf );
1355 msi_free( szwProduct );
1356 msi_free( szwComponent );
1361 /******************************************************************
1362 * MsiQueryFeatureStateA [MSI.@]
1364 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1366 LPWSTR szwProduct = NULL, szwFeature= NULL;
1367 INSTALLSTATE rc = INSTALLSTATE_UNKNOWN;
1369 szwProduct = strdupAtoW( szProduct );
1370 if ( szProduct && !szwProduct )
1373 szwFeature = strdupAtoW( szFeature );
1374 if ( szFeature && !szwFeature )
1377 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1380 msi_free( szwProduct);
1381 msi_free( szwFeature);
1386 /******************************************************************
1387 * MsiQueryFeatureStateW [MSI.@]
1389 * Checks the state of a feature
1392 * szProduct [I] Product's GUID string
1393 * szFeature [I] Feature's GUID string
1396 * INSTALLSTATE_LOCAL Feature is installed and useable
1397 * INSTALLSTATE_ABSENT Feature is absent
1398 * INSTALLSTATE_ADVERTISED Feature should be installed on demand
1399 * INSTALLSTATE_UNKNOWN An error occurred
1400 * INSTALLSTATE_INVALIDARG One of the GUIDs was invalid
1403 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1405 WCHAR squishProduct[33], comp[GUID_SIZE];
1407 LPWSTR components, p, parent_feature, path;
1411 BOOL missing = FALSE;
1413 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1415 if (!szProduct || !szFeature)
1416 return INSTALLSTATE_INVALIDARG;
1418 if (!squash_guid( szProduct, squishProduct ))
1419 return INSTALLSTATE_INVALIDARG;
1421 /* check that it's installed at all */
1422 rc = MSIREG_OpenUserFeaturesKey(szProduct, &hkey, FALSE);
1423 if (rc != ERROR_SUCCESS)
1424 return INSTALLSTATE_UNKNOWN;
1426 parent_feature = msi_reg_get_val_str( hkey, szFeature );
1429 if (!parent_feature)
1430 return INSTALLSTATE_UNKNOWN;
1432 r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
1433 msi_free(parent_feature);
1434 if (r == INSTALLSTATE_ABSENT)
1437 /* now check if it's complete or advertised */
1438 rc = MSIREG_OpenUserDataFeaturesKey(szProduct, &hkey, FALSE);
1439 if (rc != ERROR_SUCCESS)
1440 return INSTALLSTATE_ADVERTISED;
1442 components = msi_reg_get_val_str( hkey, szFeature );
1445 TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
1448 return INSTALLSTATE_ADVERTISED;
1450 for( p = components; *p && *p != 2 ; p += 20)
1452 if (!decode_base85_guid( p, &guid ))
1454 if (p != components)
1457 msi_free(components);
1458 return INSTALLSTATE_BADCONFIG;
1461 StringFromGUID2(&guid, comp, GUID_SIZE);
1462 rc = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
1463 if (rc != ERROR_SUCCESS)
1465 msi_free(components);
1466 return INSTALLSTATE_ADVERTISED;
1469 path = msi_reg_get_val_str(hkey, squishProduct);
1476 TRACE("%s %s -> %d\n", debugstr_w(szProduct), debugstr_w(szFeature), r);
1477 msi_free(components);
1480 return INSTALLSTATE_ADVERTISED;
1482 return INSTALLSTATE_LOCAL;
1485 /******************************************************************
1486 * MsiGetFileVersionA [MSI.@]
1488 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1489 LPDWORD pcchVersionBuf, LPSTR lpLangBuf, LPDWORD pcchLangBuf)
1491 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1492 UINT ret = ERROR_OUTOFMEMORY;
1496 szwFilePath = strdupAtoW( szFilePath );
1501 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1503 lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1504 if( !lpwVersionBuff )
1508 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1510 lpwLangBuff = msi_alloc(*pcchLangBuf*sizeof(WCHAR));
1515 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1516 lpwLangBuff, pcchLangBuf);
1518 if( lpwVersionBuff )
1519 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1520 lpVersionBuf, *pcchVersionBuf, NULL, NULL);
1522 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1523 lpLangBuf, *pcchLangBuf, NULL, NULL);
1526 msi_free(szwFilePath);
1527 msi_free(lpwVersionBuff);
1528 msi_free(lpwLangBuff);
1533 /******************************************************************
1534 * MsiGetFileVersionW [MSI.@]
1536 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1537 LPDWORD pcchVersionBuf, LPWSTR lpLangBuf, LPDWORD pcchLangBuf)
1539 static const WCHAR szVersionResource[] = {'\\',0};
1540 static const WCHAR szVersionFormat[] = {
1541 '%','d','.','%','d','.','%','d','.','%','d',0};
1542 static const WCHAR szLangFormat[] = {'%','d',0};
1545 LPVOID lpVer = NULL;
1546 VS_FIXEDFILEINFO *ffi;
1550 TRACE("%s %p %d %p %d\n", debugstr_w(szFilePath),
1551 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1552 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1554 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1556 return GetLastError();
1558 lpVer = msi_alloc(dwVerLen);
1561 ret = ERROR_OUTOFMEMORY;
1565 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1567 ret = GetLastError();
1570 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1572 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1575 wsprintfW(tmp, szVersionFormat,
1576 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1577 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1578 lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1579 *pcchVersionBuf = lstrlenW(lpVersionBuf);
1584 *pcchVersionBuf = 0;
1588 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1590 DWORD lang = GetUserDefaultLangID();
1592 FIXME("Retrieve language from file\n");
1593 wsprintfW(tmp, szLangFormat, lang);
1594 lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
1595 *pcchLangBuf = lstrlenW(lpLangBuf);
1603 /***********************************************************************
1604 * MsiGetFeatureUsageW [MSI.@]
1606 UINT WINAPI MsiGetFeatureUsageW( LPCWSTR szProduct, LPCWSTR szFeature,
1607 LPDWORD pdwUseCount, LPWORD pwDateUsed )
1609 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
1610 pdwUseCount, pwDateUsed);
1611 return ERROR_CALL_NOT_IMPLEMENTED;
1614 /***********************************************************************
1615 * MsiGetFeatureUsageA [MSI.@]
1617 UINT WINAPI MsiGetFeatureUsageA( LPCSTR szProduct, LPCSTR szFeature,
1618 LPDWORD pdwUseCount, LPWORD pwDateUsed )
1620 LPWSTR prod = NULL, feat = NULL;
1621 UINT ret = ERROR_OUTOFMEMORY;
1623 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
1624 pdwUseCount, pwDateUsed);
1626 prod = strdupAtoW( szProduct );
1627 if (szProduct && !prod)
1630 feat = strdupAtoW( szFeature );
1631 if (szFeature && !feat)
1634 ret = MsiGetFeatureUsageW( prod, feat, pdwUseCount, pwDateUsed );
1643 /***********************************************************************
1644 * MsiUseFeatureExW [MSI.@]
1646 INSTALLSTATE WINAPI MsiUseFeatureExW( LPCWSTR szProduct, LPCWSTR szFeature,
1647 DWORD dwInstallMode, DWORD dwReserved )
1651 TRACE("%s %s %i %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
1652 dwInstallMode, dwReserved);
1654 state = MsiQueryFeatureStateW( szProduct, szFeature );
1657 return INSTALLSTATE_INVALIDARG;
1659 if (state == INSTALLSTATE_LOCAL && dwInstallMode != INSTALLMODE_NODETECTION)
1661 FIXME("mark product %s feature %s as used\n",
1662 debugstr_w(szProduct), debugstr_w(szFeature) );
1668 /***********************************************************************
1669 * MsiUseFeatureExA [MSI.@]
1671 INSTALLSTATE WINAPI MsiUseFeatureExA( LPCSTR szProduct, LPCSTR szFeature,
1672 DWORD dwInstallMode, DWORD dwReserved )
1674 INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
1675 LPWSTR prod = NULL, feat = NULL;
1677 TRACE("%s %s %i %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
1678 dwInstallMode, dwReserved);
1680 prod = strdupAtoW( szProduct );
1681 if (szProduct && !prod)
1684 feat = strdupAtoW( szFeature );
1685 if (szFeature && !feat)
1688 ret = MsiUseFeatureExW( prod, feat, dwInstallMode, dwReserved );
1697 /***********************************************************************
1698 * MsiUseFeatureW [MSI.@]
1700 INSTALLSTATE WINAPI MsiUseFeatureW( LPCWSTR szProduct, LPCWSTR szFeature )
1702 return MsiUseFeatureExW(szProduct, szFeature, 0, 0);
1705 /***********************************************************************
1706 * MsiUseFeatureA [MSI.@]
1708 INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
1710 return MsiUseFeatureExA(szProduct, szFeature, 0, 0);
1713 /***********************************************************************
1714 * MSI_ProvideQualifiedComponentEx [internal]
1716 static UINT WINAPI MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
1717 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
1718 DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
1719 LPDWORD pcchPathBuf)
1721 WCHAR product[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1],
1722 feature[MAX_FEATURE_CHARS+1];
1728 TRACE("%s %s %i %s %i %i %p %p\n", debugstr_w(szComponent),
1729 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
1730 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1732 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
1733 if (rc != ERROR_SUCCESS)
1734 return ERROR_INDEX_ABSENT;
1736 info = msi_reg_get_val_str( hkey, szQualifier );
1740 return ERROR_INDEX_ABSENT;
1742 MsiDecomposeDescriptorW(info, product, feature, component, &sz);
1745 rc = MSI_GetComponentPath(product, component, lpPathBuf, pcchPathBuf);
1747 rc = MSI_GetComponentPath(szProduct, component, lpPathBuf, pcchPathBuf);
1751 if (rc != INSTALLSTATE_LOCAL)
1752 return ERROR_FILE_NOT_FOUND;
1754 return ERROR_SUCCESS;
1757 /***********************************************************************
1758 * MsiProvideQualifiedComponentExW [MSI.@]
1760 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
1761 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
1762 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
1763 LPDWORD pcchPathBuf)
1767 path.unicode = TRUE;
1768 path.str.w = lpPathBuf;
1770 return MSI_ProvideQualifiedComponentEx(szComponent, szQualifier,
1771 dwInstallMode, szProduct, Unused1, Unused2, &path, pcchPathBuf);
1774 /***********************************************************************
1775 * MsiProvideQualifiedComponentExA [MSI.@]
1777 UINT WINAPI MsiProvideQualifiedComponentExA(LPCSTR szComponent,
1778 LPCSTR szQualifier, DWORD dwInstallMode, LPCSTR szProduct,
1779 DWORD Unused1, DWORD Unused2, LPSTR lpPathBuf,
1780 LPDWORD pcchPathBuf)
1782 LPWSTR szwComponent, szwQualifier = NULL, szwProduct = NULL;
1783 UINT r = ERROR_OUTOFMEMORY;
1786 TRACE("%s %s %u %s %u %u %p %p\n", debugstr_a(szComponent),
1787 debugstr_a(szQualifier), dwInstallMode, debugstr_a(szProduct),
1788 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1790 szwComponent = strdupAtoW( szComponent );
1791 if (szComponent && !szwComponent)
1794 szwQualifier = strdupAtoW( szQualifier );
1795 if (szQualifier && !szwQualifier)
1798 szwProduct = strdupAtoW( szProduct );
1799 if (szProduct && !szwProduct)
1802 path.unicode = FALSE;
1803 path.str.a = lpPathBuf;
1805 r = MSI_ProvideQualifiedComponentEx(szwComponent, szwQualifier,
1806 dwInstallMode, szwProduct, Unused1,
1807 Unused2, &path, pcchPathBuf);
1809 msi_free(szwProduct);
1810 msi_free(szwComponent);
1811 msi_free(szwQualifier);
1816 /***********************************************************************
1817 * MsiProvideQualifiedComponentW [MSI.@]
1819 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
1820 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
1821 LPDWORD pcchPathBuf)
1823 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
1824 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1827 /***********************************************************************
1828 * MsiProvideQualifiedComponentA [MSI.@]
1830 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
1831 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
1832 LPDWORD pcchPathBuf)
1834 return MsiProvideQualifiedComponentExA(szComponent, szQualifier,
1835 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1838 /***********************************************************************
1839 * MSI_GetUserInfo [internal]
1841 static USERINFOSTATE WINAPI MSI_GetUserInfo(LPCWSTR szProduct,
1842 awstring *lpUserNameBuf, LPDWORD pcchUserNameBuf,
1843 awstring *lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
1844 awstring *lpSerialBuf, LPDWORD pcchSerialBuf)
1847 LPWSTR user, org, serial;
1849 USERINFOSTATE state;
1851 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
1852 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1856 return USERINFOSTATE_INVALIDARG;
1858 r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
1859 if (r != ERROR_SUCCESS)
1860 return USERINFOSTATE_UNKNOWN;
1862 user = msi_reg_get_val_str( hkey, INSTALLPROPERTY_REGOWNERW );
1863 org = msi_reg_get_val_str( hkey, INSTALLPROPERTY_REGCOMPANYW );
1864 serial = msi_reg_get_val_str( hkey, INSTALLPROPERTY_PRODUCTIDW );
1868 state = USERINFOSTATE_PRESENT;
1872 r = msi_strcpy_to_awstring( user, lpUserNameBuf, pcchUserNameBuf );
1873 if (r == ERROR_MORE_DATA)
1874 state = USERINFOSTATE_MOREDATA;
1877 state = USERINFOSTATE_ABSENT;
1880 r = msi_strcpy_to_awstring( org, lpOrgNameBuf, pcchOrgNameBuf );
1881 if (r == ERROR_MORE_DATA && state == USERINFOSTATE_PRESENT)
1882 state = USERINFOSTATE_MOREDATA;
1884 /* msdn states: The user information is considered to be present even in the absence of a company name. */
1887 r = msi_strcpy_to_awstring( serial, lpSerialBuf, pcchSerialBuf );
1888 if (r == ERROR_MORE_DATA && state == USERINFOSTATE_PRESENT)
1889 state = USERINFOSTATE_MOREDATA;
1892 state = USERINFOSTATE_ABSENT;
1901 /***********************************************************************
1902 * MsiGetUserInfoW [MSI.@]
1904 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct,
1905 LPWSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
1906 LPWSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
1907 LPWSTR lpSerialBuf, LPDWORD pcchSerialBuf)
1909 awstring user, org, serial;
1911 user.unicode = TRUE;
1912 user.str.w = lpUserNameBuf;
1914 org.str.w = lpOrgNameBuf;
1915 serial.unicode = TRUE;
1916 serial.str.w = lpSerialBuf;
1918 return MSI_GetUserInfo( szProduct, &user, pcchUserNameBuf,
1919 &org, pcchOrgNameBuf,
1920 &serial, pcchSerialBuf );
1923 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct,
1924 LPSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
1925 LPSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
1926 LPSTR lpSerialBuf, LPDWORD pcchSerialBuf)
1928 awstring user, org, serial;
1932 prod = strdupAtoW( szProduct );
1933 if (szProduct && !prod)
1934 return ERROR_OUTOFMEMORY;
1936 user.unicode = FALSE;
1937 user.str.a = lpUserNameBuf;
1938 org.unicode = FALSE;
1939 org.str.a = lpOrgNameBuf;
1940 serial.unicode = FALSE;
1941 serial.str.a = lpSerialBuf;
1943 r = MSI_GetUserInfo( prod, &user, pcchUserNameBuf,
1944 &org, pcchOrgNameBuf,
1945 &serial, pcchSerialBuf );
1952 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
1956 MSIPACKAGE *package;
1957 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1959 TRACE("(%s)\n",debugstr_w(szProduct));
1961 rc = MsiOpenProductW(szProduct,&handle);
1962 if (rc != ERROR_SUCCESS)
1963 return ERROR_INVALID_PARAMETER;
1965 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1966 rc = ACTION_PerformUIAction(package, szFirstRun, -1);
1967 msiobj_release( &package->hdr );
1969 MsiCloseHandle(handle);
1974 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
1978 MSIPACKAGE *package;
1979 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1981 TRACE("(%s)\n",debugstr_a(szProduct));
1983 rc = MsiOpenProductA(szProduct,&handle);
1984 if (rc != ERROR_SUCCESS)
1985 return ERROR_INVALID_PARAMETER;
1987 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1988 rc = ACTION_PerformUIAction(package, szFirstRun, -1);
1989 msiobj_release( &package->hdr );
1991 MsiCloseHandle(handle);
1996 /***********************************************************************
1997 * MsiConfigureFeatureA [MSI.@]
1999 UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
2001 LPWSTR prod, feat = NULL;
2002 UINT r = ERROR_OUTOFMEMORY;
2004 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
2006 prod = strdupAtoW( szProduct );
2007 if (szProduct && !prod)
2010 feat = strdupAtoW( szFeature );
2011 if (szFeature && !feat)
2014 r = MsiConfigureFeatureW(prod, feat, eInstallState);
2023 /***********************************************************************
2024 * MsiConfigureFeatureW [MSI.@]
2026 UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
2028 static const WCHAR szCostInit[] = { 'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0 };
2029 MSIPACKAGE *package = NULL;
2031 WCHAR sourcepath[MAX_PATH], filename[MAX_PATH];
2034 TRACE("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
2036 if (!szProduct || !szFeature)
2037 return ERROR_INVALID_PARAMETER;
2039 switch (eInstallState)
2041 case INSTALLSTATE_DEFAULT:
2042 /* FIXME: how do we figure out the default location? */
2043 eInstallState = INSTALLSTATE_LOCAL;
2045 case INSTALLSTATE_LOCAL:
2046 case INSTALLSTATE_SOURCE:
2047 case INSTALLSTATE_ABSENT:
2048 case INSTALLSTATE_ADVERTISED:
2051 return ERROR_INVALID_PARAMETER;
2054 r = MSI_OpenProductW( szProduct, &package );
2055 if (r != ERROR_SUCCESS)
2058 sz = sizeof(sourcepath);
2059 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
2060 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
2062 sz = sizeof(filename);
2063 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
2064 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
2066 lstrcatW( sourcepath, filename );
2068 MsiSetInternalUI( INSTALLUILEVEL_BASIC, NULL );
2070 r = ACTION_PerformUIAction( package, szCostInit, -1 );
2071 if (r != ERROR_SUCCESS)
2074 r = MSI_SetFeatureStateW( package, szFeature, eInstallState);
2075 if (r != ERROR_SUCCESS)
2078 r = MSI_InstallPackage( package, sourcepath, NULL );
2081 msiobj_release( &package->hdr );
2086 /***********************************************************************
2087 * MsiCreateAndVerifyInstallerDirectory [MSI.@]
2089 * Notes: undocumented
2091 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
2093 WCHAR path[MAX_PATH];
2095 TRACE("%d\n", dwReserved);
2099 FIXME("dwReserved=%d\n", dwReserved);
2100 return ERROR_INVALID_PARAMETER;
2103 if (!GetWindowsDirectoryW(path, MAX_PATH))
2104 return ERROR_FUNCTION_FAILED;
2106 lstrcatW(path, installerW);
2108 if (!CreateDirectoryW(path, NULL))
2109 return ERROR_FUNCTION_FAILED;
2111 return ERROR_SUCCESS;
2114 /***********************************************************************
2115 * MsiGetShortcutTargetA [MSI.@]
2117 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
2118 LPSTR szProductCode, LPSTR szFeatureId,
2119 LPSTR szComponentCode )
2122 const int len = MAX_FEATURE_CHARS+1;
2123 WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1];
2126 target = strdupAtoW( szShortcutTarget );
2127 if (szShortcutTarget && !target )
2128 return ERROR_OUTOFMEMORY;
2132 r = MsiGetShortcutTargetW( target, product, feature, component );
2134 if (r == ERROR_SUCCESS)
2136 WideCharToMultiByte( CP_ACP, 0, product, -1, szProductCode, len, NULL, NULL );
2137 WideCharToMultiByte( CP_ACP, 0, feature, -1, szFeatureId, len, NULL, NULL );
2138 WideCharToMultiByte( CP_ACP, 0, component, -1, szComponentCode, len, NULL, NULL );
2143 /***********************************************************************
2144 * MsiGetShortcutTargetW [MSI.@]
2146 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
2147 LPWSTR szProductCode, LPWSTR szFeatureId,
2148 LPWSTR szComponentCode )
2150 IShellLinkDataList *dl = NULL;
2151 IPersistFile *pf = NULL;
2152 LPEXP_DARWIN_LINK darwin = NULL;
2155 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget),
2156 szProductCode, szFeatureId, szComponentCode );
2158 init = CoInitialize(NULL);
2160 r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
2161 &IID_IPersistFile, (LPVOID*) &pf );
2162 if( SUCCEEDED( r ) )
2164 r = IPersistFile_Load( pf, szShortcutTarget,
2165 STGM_READ | STGM_SHARE_DENY_WRITE );
2166 if( SUCCEEDED( r ) )
2168 r = IPersistFile_QueryInterface( pf, &IID_IShellLinkDataList,
2170 if( SUCCEEDED( r ) )
2172 IShellLinkDataList_CopyDataBlock( dl, EXP_DARWIN_ID_SIG,
2174 IShellLinkDataList_Release( dl );
2177 IPersistFile_Release( pf );
2180 if (SUCCEEDED(init))
2183 TRACE("darwin = %p\n", darwin);
2190 ret = MsiDecomposeDescriptorW( darwin->szwDarwinID,
2191 szProductCode, szFeatureId, szComponentCode, &sz );
2192 LocalFree( darwin );
2196 return ERROR_FUNCTION_FAILED;
2199 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
2200 DWORD dwReinstallMode )
2202 MSIPACKAGE* package = NULL;
2204 WCHAR sourcepath[MAX_PATH];
2205 WCHAR filename[MAX_PATH];
2206 static const WCHAR szLogVerbose[] = {
2207 ' ','L','O','G','V','E','R','B','O','S','E',0 };
2208 static const WCHAR szInstalled[] = { 'I','n','s','t','a','l','l','e','d',0};
2209 static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
2210 static const WCHAR szReinstallMode[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
2211 static const WCHAR szOne[] = {'1',0};
2212 WCHAR reinstallmode[11];
2216 FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
2219 ptr = reinstallmode;
2221 if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
2223 if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
2225 if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
2227 if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
2229 if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
2231 if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
2233 if (dwReinstallMode & REINSTALLMODE_USERDATA)
2235 if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
2237 if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
2239 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
2243 sz = sizeof(sourcepath);
2244 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
2245 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
2247 sz = sizeof(filename);
2248 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
2249 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
2251 lstrcatW( sourcepath, filename );
2253 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
2254 r = MSI_OpenPackageW( sourcepath, &package );
2256 r = MSI_OpenProductW( szProduct, &package );
2258 if (r != ERROR_SUCCESS)
2261 MSI_SetPropertyW( package, szReinstallMode, reinstallmode );
2262 MSI_SetPropertyW( package, szInstalled, szOne );
2263 MSI_SetPropertyW( package, szLogVerbose, szOne );
2264 MSI_SetPropertyW( package, szReinstall, szFeature );
2266 r = MSI_InstallPackage( package, sourcepath, NULL );
2268 msiobj_release( &package->hdr );
2273 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
2274 DWORD dwReinstallMode )
2280 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
2283 wszProduct = strdupAtoW(szProduct);
2284 wszFeature = strdupAtoW(szFeature);
2286 rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
2288 msi_free(wszProduct);
2289 msi_free(wszFeature);
2296 unsigned int buf[4];
2297 unsigned char in[64];
2298 unsigned char digest[16];
2301 extern VOID WINAPI MD5Init( MD5_CTX *);
2302 extern VOID WINAPI MD5Update( MD5_CTX *, const unsigned char *, unsigned int );
2303 extern VOID WINAPI MD5Final( MD5_CTX *);
2305 /***********************************************************************
2306 * MsiGetFileHashW [MSI.@]
2308 UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions,
2309 PMSIFILEHASHINFO pHash )
2311 HANDLE handle, mapping;
2314 UINT r = ERROR_FUNCTION_FAILED;
2316 TRACE("%s %08x %p\n", debugstr_w(szFilePath), dwOptions, pHash );
2319 return ERROR_INVALID_PARAMETER;
2322 return ERROR_PATH_NOT_FOUND;
2325 return ERROR_INVALID_PARAMETER;
2327 return ERROR_INVALID_PARAMETER;
2328 if (pHash->dwFileHashInfoSize < sizeof *pHash)
2329 return ERROR_INVALID_PARAMETER;
2331 handle = CreateFileW( szFilePath, GENERIC_READ,
2332 FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL );
2333 if (handle == INVALID_HANDLE_VALUE)
2334 return ERROR_FILE_NOT_FOUND;
2336 length = GetFileSize( handle, NULL );
2338 mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
2341 p = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, length );
2347 MD5Update( &ctx, p, length );
2349 UnmapViewOfFile( p );
2351 memcpy( pHash->dwData, &ctx.digest, sizeof pHash->dwData );
2354 CloseHandle( mapping );
2356 CloseHandle( handle );
2361 /***********************************************************************
2362 * MsiGetFileHashA [MSI.@]
2364 UINT WINAPI MsiGetFileHashA( LPCSTR szFilePath, DWORD dwOptions,
2365 PMSIFILEHASHINFO pHash )
2370 TRACE("%s %08x %p\n", debugstr_a(szFilePath), dwOptions, pHash );
2372 file = strdupAtoW( szFilePath );
2373 if (szFilePath && !file)
2374 return ERROR_OUTOFMEMORY;
2376 r = MsiGetFileHashW( file, dwOptions, pHash );
2381 /***********************************************************************
2382 * MsiAdvertiseScriptW [MSI.@]
2384 UINT WINAPI MsiAdvertiseScriptW( LPCWSTR szScriptFile, DWORD dwFlags,
2385 PHKEY phRegData, BOOL fRemoveItems )
2387 FIXME("%s %08x %p %d\n",
2388 debugstr_w( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2389 return ERROR_CALL_NOT_IMPLEMENTED;
2392 /***********************************************************************
2393 * MsiAdvertiseScriptA [MSI.@]
2395 UINT WINAPI MsiAdvertiseScriptA( LPCSTR szScriptFile, DWORD dwFlags,
2396 PHKEY phRegData, BOOL fRemoveItems )
2398 FIXME("%s %08x %p %d\n",
2399 debugstr_a( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2400 return ERROR_CALL_NOT_IMPLEMENTED;