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 static UINT msi_locate_product(LPCWSTR szProduct, MSIINSTALLCONTEXT *context)
52 *context = MSIINSTALLCONTEXT_NONE;
54 if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
55 &hkey, FALSE) == ERROR_SUCCESS)
56 *context = MSIINSTALLCONTEXT_USERMANAGED;
57 else if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
58 &hkey, FALSE) == ERROR_SUCCESS)
59 *context = MSIINSTALLCONTEXT_MACHINE;
60 else if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
61 &hkey, FALSE) == ERROR_SUCCESS)
62 *context = MSIINSTALLCONTEXT_USERUNMANAGED;
66 if (*context == MSIINSTALLCONTEXT_NONE)
67 return ERROR_UNKNOWN_PRODUCT;
72 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
75 LPWSTR szwProd = NULL;
77 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
81 szwProd = strdupAtoW( szProduct );
83 return ERROR_OUTOFMEMORY;
86 r = MsiOpenProductW( szwProd, phProduct );
93 static UINT MSI_OpenProductW(LPCWSTR szProduct, MSIPACKAGE **package)
98 MSIINSTALLCONTEXT context;
100 static const WCHAR managed[] = {
101 'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0};
102 static const WCHAR local[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
104 TRACE("%s %p\n", debugstr_w(szProduct), package);
106 r = msi_locate_product(szProduct, &context);
107 if (r != ERROR_SUCCESS)
110 if (context == MSIINSTALLCONTEXT_MACHINE)
111 r = MSIREG_OpenLocalSystemInstallProps(szProduct, &props, FALSE);
112 else if (context == MSIINSTALLCONTEXT_USERMANAGED ||
113 context == MSIINSTALLCONTEXT_USERUNMANAGED)
114 r = MSIREG_OpenCurrentUserInstallProps(szProduct, &props, FALSE);
116 if (r != ERROR_SUCCESS)
117 return ERROR_UNKNOWN_PRODUCT;
119 if (context == MSIINSTALLCONTEXT_USERMANAGED)
120 path = msi_reg_get_val_str(props, managed);
122 path = msi_reg_get_val_str(props, local);
124 r = ERROR_UNKNOWN_PRODUCT;
126 if (!path || GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
129 if (PathIsRelativeW(path))
131 r = ERROR_INSTALL_PACKAGE_OPEN_FAILED;
135 r = MSI_OpenPackageW(path, package);
143 UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
145 MSIPACKAGE *package = NULL;
146 WCHAR squished_pc[GUID_SIZE];
149 if (!szProduct || !squash_guid(szProduct, squished_pc))
150 return ERROR_INVALID_PARAMETER;
153 return ERROR_INVALID_PARAMETER;
155 r = MSI_OpenProductW(szProduct, &package);
156 if (r != ERROR_SUCCESS)
159 *phProduct = alloc_msihandle(&package->hdr);
161 r = ERROR_NOT_ENOUGH_MEMORY;
163 msiobj_release(&package->hdr);
167 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
168 LPCSTR szTransforms, LANGID lgidLanguage)
170 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
171 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
172 return ERROR_CALL_NOT_IMPLEMENTED;
175 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
176 LPCWSTR szTransforms, LANGID lgidLanguage)
178 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
179 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
180 return ERROR_CALL_NOT_IMPLEMENTED;
183 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
184 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
186 FIXME("%s %s %s %08x %08x %08x\n", debugstr_a(szPackagePath),
187 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
188 lgidLanguage, dwPlatform, dwOptions);
189 return ERROR_CALL_NOT_IMPLEMENTED;
192 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
193 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
195 FIXME("%s %s %s %08x %08x %08x\n", debugstr_w(szPackagePath),
196 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
197 lgidLanguage, dwPlatform, dwOptions);
198 return ERROR_CALL_NOT_IMPLEMENTED;
201 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
203 LPWSTR szwPath = NULL, szwCommand = NULL;
204 UINT r = ERROR_OUTOFMEMORY;
206 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
210 szwPath = strdupAtoW( szPackagePath );
217 szwCommand = strdupAtoW( szCommandLine );
222 r = MsiInstallProductW( szwPath, szwCommand );
226 msi_free( szwCommand );
231 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
233 MSIPACKAGE *package = NULL;
236 TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
238 r = MSI_OpenPackageW( szPackagePath, &package );
239 if (r == ERROR_SUCCESS)
241 r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
242 msiobj_release( &package->hdr );
248 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
250 FIXME("%s %08x\n", debugstr_a(szProduct), dwReinstallMode);
251 return ERROR_CALL_NOT_IMPLEMENTED;
254 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
256 FIXME("%s %08x\n", debugstr_w(szProduct), dwReinstallMode);
257 return ERROR_CALL_NOT_IMPLEMENTED;
260 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
261 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
263 LPWSTR patch_package = NULL;
264 LPWSTR install_package = NULL;
265 LPWSTR command_line = NULL;
266 UINT r = ERROR_OUTOFMEMORY;
268 TRACE("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
269 eInstallType, debugstr_a(szCommandLine));
271 if (szPatchPackage && !(patch_package = strdupAtoW(szPatchPackage)))
274 if (szInstallPackage && !(install_package = strdupAtoW(szInstallPackage)))
277 if (szCommandLine && !(command_line = strdupAtoW(szCommandLine)))
280 r = MsiApplyPatchW(patch_package, install_package, eInstallType, command_line);
283 msi_free(patch_package);
284 msi_free(install_package);
285 msi_free(command_line);
290 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
291 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
293 MSIHANDLE patch, info;
296 LPCWSTR cmd_ptr = szCommandLine;
298 LPWSTR cmd = NULL, codes = NULL;
300 static const WCHAR space[] = {' ',0};
301 static const WCHAR patcheq[] = {'P','A','T','C','H','=',0};
302 static WCHAR empty[] = {0};
304 TRACE("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
305 eInstallType, debugstr_w(szCommandLine));
307 if (szInstallPackage || eInstallType == INSTALLTYPE_NETWORK_IMAGE ||
308 eInstallType == INSTALLTYPE_SINGLE_INSTANCE)
310 FIXME("Only reading target products from patch\n");
311 return ERROR_CALL_NOT_IMPLEMENTED;
314 r = MsiOpenDatabaseW(szPatchPackage, MSIDBOPEN_READONLY, &patch);
315 if (r != ERROR_SUCCESS)
318 r = MsiGetSummaryInformationW(patch, NULL, 0, &info);
319 if (r != ERROR_SUCCESS)
322 r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, empty, &size);
323 if (r != ERROR_MORE_DATA || !size || type != VT_LPSTR)
325 ERR("Failed to read product codes from patch\n");
329 codes = msi_alloc(++size * sizeof(WCHAR));
332 r = ERROR_OUTOFMEMORY;
336 r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, codes, &size);
337 if (r != ERROR_SUCCESS)
343 size = lstrlenW(cmd_ptr) + lstrlenW(patcheq) + lstrlenW(szPatchPackage) + 1;
344 cmd = msi_alloc(size * sizeof(WCHAR));
347 r = ERROR_OUTOFMEMORY;
351 lstrcpyW(cmd, cmd_ptr);
352 if (szCommandLine) lstrcatW(cmd, space);
353 lstrcatW(cmd, patcheq);
354 lstrcatW(cmd, szPatchPackage);
357 while ((end = strchrW(beg, '}')))
361 r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd);
362 if (r != ERROR_SUCCESS)
372 MsiCloseHandle(info);
373 MsiCloseHandle(patch);
378 UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
379 DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
381 FIXME("(%s, %d, %p): stub!\n", debugstr_a(szProductPackagePath),
382 cPatchInfo, pPatchInfo);
384 return ERROR_CALL_NOT_IMPLEMENTED;
387 UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
388 DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
390 FIXME("(%s, %d, %p): stub!\n", debugstr_w(szProductPackagePath),
391 cPatchInfo, pPatchInfo);
393 return ERROR_CALL_NOT_IMPLEMENTED;
396 static UINT msi_open_package(LPCWSTR product, MSIINSTALLCONTEXT context,
397 MSIPACKAGE **package)
403 WCHAR sourcepath[MAX_PATH];
404 WCHAR filename[MAX_PATH];
406 static const WCHAR szLocalPackage[] = {
407 'L','o','c','a','l','P','a','c','k','a','g','e',0};
409 if (context == MSIINSTALLCONTEXT_MACHINE)
410 r = MSIREG_OpenLocalSystemInstallProps(product, &props, FALSE);
412 r = MSIREG_OpenCurrentUserInstallProps(product, &props, FALSE);
414 if (r != ERROR_SUCCESS)
415 return ERROR_BAD_CONFIGURATION;
417 localpack = msi_reg_get_val_str(props, szLocalPackage);
420 lstrcpyW(sourcepath, localpack);
424 if (!localpack || GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
426 sz = sizeof(sourcepath);
427 MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
428 INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
430 sz = sizeof(filename);
431 MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
432 INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
434 lstrcatW(sourcepath, filename);
437 if (GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
438 return ERROR_INSTALL_SOURCE_ABSENT;
440 return MSI_OpenPackageW(sourcepath, package);
443 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
444 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
446 MSIPACKAGE* package = NULL;
447 MSIINSTALLCONTEXT context;
450 WCHAR sourcepath[MAX_PATH];
453 static const WCHAR szInstalled[] = {
454 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
455 static const WCHAR szRemoveAll[] = {
456 ' ','R','E','M','O','V','E','=','A','L','L',0};
457 static const WCHAR szMachine[] = {
458 ' ','A','L','L','U','S','E','R','S','=','1',0};
460 TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
461 debugstr_w(szCommandLine));
463 if (!szProduct || lstrlenW(szProduct) != GUID_SIZE - 1)
464 return ERROR_INVALID_PARAMETER;
466 if (eInstallState == INSTALLSTATE_ADVERTISED ||
467 eInstallState == INSTALLSTATE_SOURCE)
469 FIXME("State %d not implemented\n", eInstallState);
470 return ERROR_CALL_NOT_IMPLEMENTED;
473 r = msi_locate_product(szProduct, &context);
474 if (r != ERROR_SUCCESS)
477 r = msi_open_package(szProduct, context, &package);
478 if (r != ERROR_SUCCESS)
481 sz = lstrlenW(szInstalled) + 1;
484 sz += lstrlenW(szCommandLine);
486 if (eInstallState == INSTALLSTATE_ABSENT)
487 sz += lstrlenW(szRemoveAll);
489 if (context == MSIINSTALLCONTEXT_MACHINE)
490 sz += lstrlenW(szMachine);
492 commandline = msi_alloc(sz * sizeof(WCHAR));
495 r = ERROR_OUTOFMEMORY;
501 lstrcpyW(commandline,szCommandLine);
503 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
504 lstrcatW(commandline,szInstalled);
506 if (eInstallState == INSTALLSTATE_ABSENT)
507 lstrcatW(commandline, szRemoveAll);
509 if (context == MSIINSTALLCONTEXT_MACHINE)
510 lstrcatW(commandline, szMachine);
512 r = MSI_InstallPackage( package, sourcepath, commandline );
514 msi_free(commandline);
517 msiobj_release( &package->hdr );
522 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
523 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
525 LPWSTR szwProduct = NULL;
526 LPWSTR szwCommandLine = NULL;
527 UINT r = ERROR_OUTOFMEMORY;
531 szwProduct = strdupAtoW( szProduct );
538 szwCommandLine = strdupAtoW( szCommandLine );
543 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
546 msi_free( szwProduct );
547 msi_free( szwCommandLine);
552 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
553 INSTALLSTATE eInstallState)
555 LPWSTR szwProduct = NULL;
558 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
562 szwProduct = strdupAtoW( szProduct );
564 return ERROR_OUTOFMEMORY;
567 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
568 msi_free( szwProduct );
573 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
574 INSTALLSTATE eInstallState)
576 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
579 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
581 LPWSTR szwComponent = NULL;
583 WCHAR szwBuffer[GUID_SIZE];
585 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
589 szwComponent = strdupAtoW( szComponent );
591 return ERROR_OUTOFMEMORY;
595 r = MsiGetProductCodeW( szwComponent, szwBuffer );
598 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
600 msi_free( szwComponent );
605 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
608 HKEY compkey, prodkey;
609 WCHAR squished_comp[GUID_SIZE];
610 WCHAR squished_prod[GUID_SIZE];
611 DWORD sz = GUID_SIZE;
613 TRACE("%s %p\n", debugstr_w(szComponent), szBuffer);
615 if (!szComponent || !*szComponent)
616 return ERROR_INVALID_PARAMETER;
618 if (!squash_guid(szComponent, squished_comp))
619 return ERROR_INVALID_PARAMETER;
621 if (MSIREG_OpenUserDataComponentKey(szComponent, &compkey, FALSE) != ERROR_SUCCESS &&
622 MSIREG_OpenLocalSystemComponentKey(szComponent, &compkey, FALSE) != ERROR_SUCCESS)
624 return ERROR_UNKNOWN_COMPONENT;
627 rc = RegEnumValueW(compkey, 0, squished_prod, &sz, NULL, NULL, NULL, NULL);
628 if (rc != ERROR_SUCCESS)
630 RegCloseKey(compkey);
631 return ERROR_UNKNOWN_COMPONENT;
634 /* check simple case, only one product */
635 rc = RegEnumValueW(compkey, 1, squished_prod, &sz, NULL, NULL, NULL, NULL);
636 if (rc == ERROR_NO_MORE_ITEMS)
643 while ((rc = RegEnumValueW(compkey, index, squished_prod, &sz,
644 NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS)
648 unsquash_guid(squished_prod, szBuffer);
650 if (MSIREG_OpenProductKey(szBuffer, MSIINSTALLCONTEXT_USERMANAGED,
651 &prodkey, FALSE) == ERROR_SUCCESS ||
652 MSIREG_OpenProductKey(szBuffer, MSIINSTALLCONTEXT_USERUNMANAGED,
653 &prodkey, FALSE) == ERROR_SUCCESS ||
654 MSIREG_OpenProductKey(szBuffer, MSIINSTALLCONTEXT_MACHINE,
655 &prodkey, FALSE) == ERROR_SUCCESS)
657 RegCloseKey(prodkey);
663 rc = ERROR_INSTALL_FAILURE;
666 RegCloseKey(compkey);
667 unsquash_guid(squished_prod, szBuffer);
671 static LPWSTR msi_reg_get_value(HKEY hkey, LPCWSTR name, DWORD *type)
677 static const WCHAR format[] = {'%','d',0};
679 res = RegQueryValueExW(hkey, name, NULL, type, NULL, NULL);
680 if (res != ERROR_SUCCESS)
684 return msi_reg_get_val_str(hkey, name);
686 if (!msi_reg_get_val_dword(hkey, name, &dval))
689 sprintfW(temp, format, dval);
690 return strdupW(temp);
693 static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
694 awstring *szValue, LPDWORD pcchValueBuf)
696 UINT r = ERROR_UNKNOWN_PROPERTY;
697 HKEY prodkey, userdata, source;
699 WCHAR squished_pc[GUID_SIZE];
700 WCHAR packagecode[GUID_SIZE];
701 BOOL classes = FALSE;
702 BOOL badconfig = FALSE;
704 DWORD save, type = REG_NONE;
706 static WCHAR empty[] = {0};
707 static const WCHAR sourcelist[] = {
708 'S','o','u','r','c','e','L','i','s','t',0};
709 static const WCHAR display_name[] = {
710 'D','i','s','p','l','a','y','N','a','m','e',0};
711 static const WCHAR display_version[] = {
712 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
713 static const WCHAR assignment[] = {
714 'A','s','s','i','g','n','m','e','n','t',0};
716 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
717 debugstr_w(szAttribute), szValue, pcchValueBuf);
719 if ((szValue->str.w && !pcchValueBuf) || !szProduct || !szAttribute)
720 return ERROR_INVALID_PARAMETER;
722 if (!squash_guid(szProduct, squished_pc))
723 return ERROR_INVALID_PARAMETER;
725 if ((r = MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
726 &prodkey, FALSE)) != ERROR_SUCCESS &&
727 (r = MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
728 &prodkey, FALSE)) != ERROR_SUCCESS &&
729 (r = MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
730 &prodkey, FALSE)) == ERROR_SUCCESS)
736 MSIREG_OpenLocalSystemProductKey(szProduct, &userdata, FALSE);
738 MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
740 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) ||
741 !lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) ||
742 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLDATEW) ||
743 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
744 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLLOCATIONW) ||
745 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLSOURCEW) ||
746 !lstrcmpW(szAttribute, INSTALLPROPERTY_LOCALPACKAGEW) ||
747 !lstrcmpW(szAttribute, INSTALLPROPERTY_PUBLISHERW) ||
748 !lstrcmpW(szAttribute, INSTALLPROPERTY_URLINFOABOUTW) ||
749 !lstrcmpW(szAttribute, INSTALLPROPERTY_URLUPDATEINFOW) ||
750 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMINORW) ||
751 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMAJORW) ||
752 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW) ||
753 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTIDW) ||
754 !lstrcmpW(szAttribute, INSTALLPROPERTY_REGCOMPANYW) ||
755 !lstrcmpW(szAttribute, INSTALLPROPERTY_REGOWNERW))
759 r = ERROR_UNKNOWN_PRODUCT;
764 return ERROR_UNKNOWN_PROPERTY;
766 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
767 szAttribute = display_name;
768 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW))
769 szAttribute = display_version;
771 val = msi_reg_get_value(userdata, szAttribute, &type);
775 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTANCETYPEW) ||
776 !lstrcmpW(szAttribute, INSTALLPROPERTY_TRANSFORMSW) ||
777 !lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
778 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW) ||
779 !lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW) ||
780 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW) ||
781 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW) ||
782 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTICONW) ||
783 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW) ||
784 !lstrcmpW(szAttribute, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
788 r = ERROR_UNKNOWN_PRODUCT;
792 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
793 szAttribute = assignment;
795 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW))
797 res = RegOpenKeyW(prodkey, sourcelist, &source);
798 if (res == ERROR_SUCCESS)
799 val = msi_reg_get_value(source, szAttribute, &type);
805 val = msi_reg_get_value(prodkey, szAttribute, &type);
810 if (val != empty && type != REG_DWORD &&
811 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
813 if (lstrlenW(val) != SQUISH_GUID_SIZE - 1)
817 unsquash_guid(val, packagecode);
819 val = strdupW(packagecode);
826 r = ERROR_UNKNOWN_PROPERTY;
832 save = *pcchValueBuf;
834 if (strlenW(val) < *pcchValueBuf)
835 r = msi_strcpy_to_awstring(val, szValue, pcchValueBuf);
836 else if (szValue->str.a || szValue->str.w)
840 *pcchValueBuf = lstrlenW(val);
841 else if (r == ERROR_SUCCESS)
843 *pcchValueBuf = save;
844 r = ERROR_BAD_CONFIGURATION;
848 r = ERROR_BAD_CONFIGURATION;
854 RegCloseKey(prodkey);
855 RegCloseKey(userdata);
859 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
860 LPSTR szBuffer, LPDWORD pcchValueBuf)
862 LPWSTR szwProduct, szwAttribute = NULL;
863 UINT r = ERROR_OUTOFMEMORY;
866 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
867 szBuffer, pcchValueBuf);
869 szwProduct = strdupAtoW( szProduct );
870 if( szProduct && !szwProduct )
873 szwAttribute = strdupAtoW( szAttribute );
874 if( szAttribute && !szwAttribute )
877 buffer.unicode = FALSE;
878 buffer.str.a = szBuffer;
880 r = MSI_GetProductInfo( szwProduct, szwAttribute,
881 &buffer, pcchValueBuf );
884 msi_free( szwProduct );
885 msi_free( szwAttribute );
890 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
891 LPWSTR szBuffer, LPDWORD pcchValueBuf)
895 TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute),
896 szBuffer, pcchValueBuf);
898 buffer.unicode = TRUE;
899 buffer.str.w = szBuffer;
901 return MSI_GetProductInfo( szProduct, szAttribute,
902 &buffer, pcchValueBuf );
905 UINT WINAPI MsiGetProductInfoExA(LPCSTR szProductCode, LPCSTR szUserSid,
906 MSIINSTALLCONTEXT dwContext, LPCSTR szProperty,
907 LPSTR szValue, LPDWORD pcchValue)
909 LPWSTR product = NULL;
910 LPWSTR usersid = NULL;
911 LPWSTR property = NULL;
916 TRACE("(%s, %s, %d, %s, %p, %p)\n", debugstr_a(szProductCode),
917 debugstr_a(szUserSid), dwContext, debugstr_a(szProperty),
920 if (szValue && !pcchValue)
921 return ERROR_INVALID_PARAMETER;
923 if (szProductCode) product = strdupAtoW(szProductCode);
924 if (szUserSid) usersid = strdupAtoW(szUserSid);
925 if (szProperty) property = strdupAtoW(szProperty);
927 r = MsiGetProductInfoExW(product, usersid, dwContext, property,
929 if (r != ERROR_SUCCESS)
932 value = msi_alloc(++len * sizeof(WCHAR));
935 r = ERROR_OUTOFMEMORY;
939 r = MsiGetProductInfoExW(product, usersid, dwContext, property,
941 if (r != ERROR_SUCCESS)
947 len = WideCharToMultiByte(CP_ACP, 0, value, -1, NULL, 0, NULL, NULL);
948 if (*pcchValue >= len)
949 WideCharToMultiByte(CP_ACP, 0, value, -1, szValue, len, NULL, NULL);
957 if (*pcchValue <= len || !szValue)
958 len = len * sizeof(WCHAR) - 1;
960 *pcchValue = len - 1;
971 static UINT msi_copy_outval(LPWSTR val, LPWSTR out, LPDWORD size)
976 return ERROR_UNKNOWN_PROPERTY;
980 if (strlenW(val) >= *size)
991 *size = lstrlenW(val);
993 return ERROR_SUCCESS;
996 UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
997 MSIINSTALLCONTEXT dwContext, LPCWSTR szProperty,
998 LPWSTR szValue, LPDWORD pcchValue)
1000 WCHAR squished_pc[GUID_SIZE];
1002 LPCWSTR package = NULL;
1003 HKEY props = NULL, prod;
1004 HKEY classes = NULL, managed;
1007 UINT r = ERROR_UNKNOWN_PRODUCT;
1009 static const WCHAR one[] = {'1',0};
1010 static const WCHAR five[] = {'5',0};
1011 static const WCHAR empty[] = {0};
1012 static const WCHAR displayname[] = {
1013 'D','i','s','p','l','a','y','N','a','m','e',0};
1014 static const WCHAR displayversion[] = {
1015 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
1016 static const WCHAR managed_local_package[] = {
1017 'M','a','n','a','g','e','d','L','o','c','a','l',
1018 'P','a','c','k','a','g','e',0};
1020 TRACE("(%s, %s, %d, %s, %p, %p)\n", debugstr_w(szProductCode),
1021 debugstr_w(szUserSid), dwContext, debugstr_w(szProperty),
1022 szValue, pcchValue);
1024 if (!szProductCode || !squash_guid(szProductCode, squished_pc))
1025 return ERROR_INVALID_PARAMETER;
1027 if (szValue && !pcchValue)
1028 return ERROR_INVALID_PARAMETER;
1030 if (dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
1031 dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
1032 dwContext != MSIINSTALLCONTEXT_MACHINE)
1033 return ERROR_INVALID_PARAMETER;
1035 if (!szProperty || !*szProperty)
1036 return ERROR_INVALID_PARAMETER;
1038 if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
1039 return ERROR_INVALID_PARAMETER;
1041 MSIREG_OpenProductKey(szProductCode, MSIINSTALLCONTEXT_USERMANAGED,
1043 MSIREG_OpenProductKey(szProductCode, MSIINSTALLCONTEXT_USERUNMANAGED,
1046 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
1048 package = INSTALLPROPERTY_LOCALPACKAGEW;
1049 MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
1051 if (!props && !prod)
1054 else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
1056 package = managed_local_package;
1057 MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
1059 if (!props && !managed)
1062 else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1064 package = INSTALLPROPERTY_LOCALPACKAGEW;
1065 MSIREG_OpenLocalSystemProductKey(szProductCode, &props, FALSE);
1066 MSIREG_OpenProductKey(szProductCode, dwContext, &classes, FALSE);
1068 if (!props && !classes)
1072 if (!lstrcmpW(szProperty, INSTALLPROPERTY_HELPLINKW) ||
1073 !lstrcmpW(szProperty, INSTALLPROPERTY_HELPTELEPHONEW) ||
1074 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW) ||
1075 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
1076 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLLOCATIONW) ||
1077 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLSOURCEW) ||
1078 !lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW) ||
1079 !lstrcmpW(szProperty, INSTALLPROPERTY_PUBLISHERW) ||
1080 !lstrcmpW(szProperty, INSTALLPROPERTY_URLINFOABOUTW) ||
1081 !lstrcmpW(szProperty, INSTALLPROPERTY_URLUPDATEINFOW) ||
1082 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMINORW) ||
1083 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMAJORW) ||
1084 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW) ||
1085 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTIDW) ||
1086 !lstrcmpW(szProperty, INSTALLPROPERTY_REGCOMPANYW) ||
1087 !lstrcmpW(szProperty, INSTALLPROPERTY_REGOWNERW) ||
1088 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTANCETYPEW))
1090 val = msi_reg_get_value(props, package, &type);
1093 if (prod || classes)
1094 r = ERROR_UNKNOWN_PROPERTY;
1101 if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
1102 szProperty = displayname;
1103 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW))
1104 szProperty = displayversion;
1106 val = msi_reg_get_value(props, szProperty, &type);
1108 val = strdupW(empty);
1110 r = msi_copy_outval(val, szValue, pcchValue);
1112 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW) ||
1113 !lstrcmpW(szProperty, INSTALLPROPERTY_LANGUAGEW) ||
1114 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTNAMEW) ||
1115 !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGECODEW) ||
1116 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONW) ||
1117 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTICONW) ||
1118 !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGENAMEW) ||
1119 !lstrcmpW(szProperty, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
1121 if (!prod && !classes)
1124 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
1126 else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
1128 else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1131 val = msi_reg_get_value(hkey, szProperty, &type);
1133 val = strdupW(empty);
1135 r = msi_copy_outval(val, szValue, pcchValue);
1137 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTSTATEW))
1139 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1143 val = msi_reg_get_value(props, package, &type);
1148 val = strdupW(five);
1153 r = msi_copy_outval(val, szValue, pcchValue);
1156 else if (props && (val = msi_reg_get_value(props, package, &type)))
1159 val = strdupW(five);
1160 r = msi_copy_outval(val, szValue, pcchValue);
1164 if (prod || managed)
1169 r = msi_copy_outval(val, szValue, pcchValue);
1171 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW))
1173 if (!prod && !classes)
1177 val = strdupW(empty);
1178 r = msi_copy_outval(val, szValue, pcchValue);
1181 r = ERROR_UNKNOWN_PROPERTY;
1186 RegCloseKey(managed);
1187 RegCloseKey(classes);
1193 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
1195 LPWSTR szwLogFile = NULL;
1198 TRACE("%08x %s %08x\n", dwLogMode, debugstr_a(szLogFile), attributes);
1202 szwLogFile = strdupAtoW( szLogFile );
1204 return ERROR_OUTOFMEMORY;
1206 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
1207 msi_free( szwLogFile );
1211 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
1213 HANDLE file = INVALID_HANDLE_VALUE;
1215 TRACE("%08x %s %08x\n", dwLogMode, debugstr_w(szLogFile), attributes);
1219 lstrcpyW(gszLogFile,szLogFile);
1220 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
1221 DeleteFileW(szLogFile);
1222 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
1223 FILE_ATTRIBUTE_NORMAL, NULL);
1224 if (file != INVALID_HANDLE_VALUE)
1227 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
1230 gszLogFile[0] = '\0';
1232 return ERROR_SUCCESS;
1235 UINT WINAPI MsiEnumComponentCostsW(MSIHANDLE hInstall, LPCWSTR szComponent,
1236 DWORD dwIndex, INSTALLSTATE iState,
1237 LPWSTR lpDriveBuf, DWORD *pcchDriveBuf,
1238 int *piCost, int *pTempCost)
1240 FIXME("(%ld, %s, %d, %d, %p, %p, %p %p): stub!\n", hInstall,
1241 debugstr_w(szComponent), dwIndex, iState, lpDriveBuf,
1242 pcchDriveBuf, piCost, pTempCost);
1244 return ERROR_NO_MORE_ITEMS;
1247 UINT WINAPI MsiQueryComponentStateA(LPCSTR szProductCode,
1248 LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1249 LPCSTR szComponent, INSTALLSTATE *pdwState)
1251 LPWSTR prodcode = NULL, usersid = NULL, comp = NULL;
1254 TRACE("(%s, %s, %d, %s, %p)\n", debugstr_a(szProductCode),
1255 debugstr_a(szUserSid), dwContext, debugstr_a(szComponent), pdwState);
1257 if (szProductCode && !(prodcode = strdupAtoW(szProductCode)))
1258 return ERROR_OUTOFMEMORY;
1260 if (szUserSid && !(usersid = strdupAtoW(szUserSid)))
1261 return ERROR_OUTOFMEMORY;
1263 if (szComponent && !(comp = strdupAtoW(szComponent)))
1264 return ERROR_OUTOFMEMORY;
1266 r = MsiQueryComponentStateW(prodcode, usersid, dwContext, comp, pdwState);
1275 static BOOL msi_comp_find_prod_key(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
1280 r = MSIREG_OpenProductKey(prodcode, context, &hkey, FALSE);
1282 return (r == ERROR_SUCCESS);
1285 static BOOL msi_comp_find_package(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
1293 static const WCHAR local_package[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
1294 static const WCHAR managed_local_package[] = {
1295 'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0
1298 if (context == MSIINSTALLCONTEXT_MACHINE)
1299 r = MSIREG_OpenLocalSystemProductKey(prodcode, &hkey, FALSE);
1301 r = MSIREG_OpenCurrentUserInstallProps(prodcode, &hkey, FALSE);
1303 if (r != ERROR_SUCCESS)
1306 if (context == MSIINSTALLCONTEXT_USERMANAGED)
1307 package = managed_local_package;
1309 package = local_package;
1312 res = RegQueryValueExW(hkey, package, NULL, NULL, NULL, &sz);
1315 return (res == ERROR_SUCCESS);
1318 static BOOL msi_comp_find_prodcode(LPWSTR squished_pc,
1319 MSIINSTALLCONTEXT context,
1320 LPCWSTR comp, LPWSTR val, DWORD *sz)
1326 if (context == MSIINSTALLCONTEXT_MACHINE)
1327 r = MSIREG_OpenLocalSystemComponentKey(comp, &hkey, FALSE);
1329 r = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
1331 if (r != ERROR_SUCCESS)
1334 res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, (BYTE *)val, sz);
1335 if (res != ERROR_SUCCESS)
1342 UINT WINAPI MsiQueryComponentStateW(LPCWSTR szProductCode,
1343 LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1344 LPCWSTR szComponent, INSTALLSTATE *pdwState)
1346 WCHAR squished_pc[GUID_SIZE];
1347 WCHAR val[MAX_PATH];
1351 TRACE("(%s, %s, %d, %s, %p)\n", debugstr_w(szProductCode),
1352 debugstr_w(szUserSid), dwContext, debugstr_w(szComponent), pdwState);
1355 return ERROR_INVALID_PARAMETER;
1357 if (!szProductCode || !*szProductCode || lstrlenW(szProductCode) != GUID_SIZE - 1)
1358 return ERROR_INVALID_PARAMETER;
1360 if (!squash_guid(szProductCode, squished_pc))
1361 return ERROR_INVALID_PARAMETER;
1363 found = msi_comp_find_prod_key(szProductCode, dwContext);
1365 if (!msi_comp_find_package(szProductCode, dwContext))
1369 *pdwState = INSTALLSTATE_UNKNOWN;
1370 return ERROR_UNKNOWN_COMPONENT;
1373 return ERROR_UNKNOWN_PRODUCT;
1376 *pdwState = INSTALLSTATE_UNKNOWN;
1379 if (!msi_comp_find_prodcode(squished_pc, dwContext, szComponent, val, &sz))
1380 return ERROR_UNKNOWN_COMPONENT;
1383 *pdwState = INSTALLSTATE_NOTUSED;
1386 if (lstrlenW(val) > 2 &&
1387 val[0] >= '0' && val[0] <= '9' && val[1] >= '0' && val[1] <= '9')
1389 *pdwState = INSTALLSTATE_SOURCE;
1392 *pdwState = INSTALLSTATE_LOCAL;
1395 return ERROR_SUCCESS;
1398 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
1400 LPWSTR szwProduct = NULL;
1405 szwProduct = strdupAtoW( szProduct );
1407 return ERROR_OUTOFMEMORY;
1409 r = MsiQueryProductStateW( szwProduct );
1410 msi_free( szwProduct );
1414 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
1416 INSTALLSTATE state = INSTALLSTATE_ADVERTISED;
1417 HKEY prodkey = 0, userdata = 0;
1422 static const WCHAR szWindowsInstaller[] = {
1423 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
1425 TRACE("%s\n", debugstr_w(szProduct));
1427 if (!szProduct || !*szProduct)
1428 return INSTALLSTATE_INVALIDARG;
1430 if (lstrlenW(szProduct) != GUID_SIZE - 1)
1431 return INSTALLSTATE_INVALIDARG;
1433 if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
1434 &prodkey, FALSE) != ERROR_SUCCESS &&
1435 MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
1436 &prodkey, FALSE) != ERROR_SUCCESS &&
1437 MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
1438 &prodkey, FALSE) == ERROR_SUCCESS)
1445 r = MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
1446 if (r != ERROR_SUCCESS)
1451 r = MSIREG_OpenLocalSystemInstallProps(szProduct, &userdata, FALSE);
1452 if (r != ERROR_SUCCESS)
1456 if (!msi_reg_get_val_dword(userdata, szWindowsInstaller, &val))
1460 state = INSTALLSTATE_DEFAULT;
1462 state = INSTALLSTATE_UNKNOWN;
1467 state = INSTALLSTATE_UNKNOWN;
1470 state = INSTALLSTATE_ABSENT;
1473 RegCloseKey(prodkey);
1474 RegCloseKey(userdata);
1478 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
1480 INSTALLUILEVEL old = gUILevel;
1481 HWND oldwnd = gUIhwnd;
1483 TRACE("%08x %p\n", dwUILevel, phWnd);
1485 gUILevel = dwUILevel;
1494 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
1495 DWORD dwMessageFilter, LPVOID pvContext)
1497 INSTALLUI_HANDLERA prev = gUIHandlerA;
1499 TRACE("%p %x %p\n",puiHandler, dwMessageFilter,pvContext);
1500 gUIHandlerA = puiHandler;
1501 gUIFilter = dwMessageFilter;
1502 gUIContext = pvContext;
1507 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
1508 DWORD dwMessageFilter, LPVOID pvContext)
1510 INSTALLUI_HANDLERW prev = gUIHandlerW;
1512 TRACE("%p %x %p\n",puiHandler,dwMessageFilter,pvContext);
1513 gUIHandlerW = puiHandler;
1514 gUIFilter = dwMessageFilter;
1515 gUIContext = pvContext;
1520 /******************************************************************
1521 * MsiLoadStringW [MSI.@]
1523 * Loads a string from MSI's string resources.
1527 * handle [I] only -1 is handled currently
1528 * id [I] id of the string to be loaded
1529 * lpBuffer [O] buffer for the string to be written to
1530 * nBufferMax [I] maximum size of the buffer in characters
1531 * lang [I] the preferred language for the string
1535 * If successful, this function returns the language id of the string loaded
1536 * If the function fails, the function returns zero.
1540 * The type of the first parameter is unknown. LoadString's prototype
1541 * suggests that it might be a module handle. I have made it an MSI handle
1542 * for starters, as -1 is an invalid MSI handle, but not an invalid module
1543 * handle. Maybe strings can be stored in an MSI database somehow.
1545 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
1546 int nBufferMax, LANGID lang )
1553 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
1556 FIXME("don't know how to deal with handle = %08lx\n", handle);
1559 lang = GetUserDefaultLangID();
1561 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
1565 hResData = LoadResource( msi_hInstance, hres );
1568 p = LockResource( hResData );
1572 for (i = 0; i < (id&0xf); i++)
1576 if( nBufferMax <= len )
1579 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
1580 lpBuffer[ len ] = 0;
1582 TRACE("found -> %s\n", debugstr_w(lpBuffer));
1587 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
1588 int nBufferMax, LANGID lang )
1594 bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
1595 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
1598 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
1599 if( len <= nBufferMax )
1600 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
1601 lpBuffer, nBufferMax, NULL, NULL );
1609 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
1612 char szProduct[GUID_SIZE];
1614 TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
1616 if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
1617 return INSTALLSTATE_UNKNOWN;
1619 return MsiGetComponentPathA( szProduct, szComponent, lpPathBuf, pcchBuf );
1622 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
1625 WCHAR szProduct[GUID_SIZE];
1627 TRACE("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
1629 if (MsiGetProductCodeW( szComponent, szProduct ) != ERROR_SUCCESS)
1630 return INSTALLSTATE_UNKNOWN;
1632 return MsiGetComponentPathW( szProduct, szComponent, lpPathBuf, pcchBuf );
1635 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
1636 WORD wLanguageId, DWORD f)
1638 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_a(lpText), debugstr_a(lpCaption),
1639 uType, wLanguageId, f);
1640 return MessageBoxExA(hWnd,lpText,lpCaption,uType,wLanguageId);
1643 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
1644 WORD wLanguageId, DWORD f)
1646 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_w(lpText), debugstr_w(lpCaption),
1647 uType, wLanguageId, f);
1648 return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId);
1651 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
1652 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
1653 LPDWORD pcchPathBuf )
1655 FIXME("%s %s %08x %08x %p %p\n", debugstr_a(szAssemblyName),
1656 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
1658 return ERROR_CALL_NOT_IMPLEMENTED;
1661 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
1662 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
1663 LPDWORD pcchPathBuf )
1665 FIXME("%s %s %08x %08x %p %p\n", debugstr_w(szAssemblyName),
1666 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
1668 return ERROR_CALL_NOT_IMPLEMENTED;
1671 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
1672 LPSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs )
1674 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
1675 return ERROR_CALL_NOT_IMPLEMENTED;
1678 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
1679 LPWSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs )
1681 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
1682 return ERROR_CALL_NOT_IMPLEMENTED;
1685 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
1686 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData,
1687 LPDWORD pcbHashData)
1689 FIXME("%s %08x %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
1690 ppcCertContext, pbHashData, pcbHashData);
1691 return ERROR_CALL_NOT_IMPLEMENTED;
1694 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
1695 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData,
1696 LPDWORD pcbHashData)
1698 FIXME("%s %08x %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
1699 ppcCertContext, pbHashData, pcbHashData);
1700 return ERROR_CALL_NOT_IMPLEMENTED;
1703 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
1704 LPSTR szValue, LPDWORD pccbValue )
1706 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
1707 return ERROR_CALL_NOT_IMPLEMENTED;
1710 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
1711 LPWSTR szValue, LPDWORD pccbValue )
1713 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
1714 return ERROR_CALL_NOT_IMPLEMENTED;
1717 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
1720 LPWSTR szPack = NULL;
1722 TRACE("%s\n", debugstr_a(szPackage) );
1726 szPack = strdupAtoW( szPackage );
1728 return ERROR_OUTOFMEMORY;
1731 r = MsiVerifyPackageW( szPack );
1738 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
1743 TRACE("%s\n", debugstr_w(szPackage) );
1745 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
1746 MsiCloseHandle( handle );
1751 static INSTALLSTATE MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
1752 awstring* lpPathBuf, LPDWORD pcchBuf)
1754 WCHAR squished_pc[GUID_SIZE];
1755 WCHAR squished_comp[GUID_SIZE];
1761 static const WCHAR wininstaller[] = {
1762 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
1764 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
1765 debugstr_w(szComponent), lpPathBuf->str.w, pcchBuf);
1767 if (!szProduct || !szComponent)
1768 return INSTALLSTATE_INVALIDARG;
1770 if (lpPathBuf->str.w && !pcchBuf)
1771 return INSTALLSTATE_INVALIDARG;
1773 if (!squash_guid(szProduct, squished_pc) ||
1774 !squash_guid(szComponent, squished_comp))
1775 return INSTALLSTATE_INVALIDARG;
1777 state = INSTALLSTATE_UNKNOWN;
1779 if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
1780 MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
1782 path = msi_reg_get_val_str(hkey, squished_pc);
1785 state = INSTALLSTATE_ABSENT;
1787 if ((MSIREG_OpenLocalSystemProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
1788 MSIREG_OpenUserDataProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS) &&
1789 msi_reg_get_val_dword(hkey, wininstaller, &version) &&
1790 GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
1793 state = INSTALLSTATE_LOCAL;
1797 if (state != INSTALLSTATE_LOCAL &&
1798 (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
1799 &hkey, FALSE) == ERROR_SUCCESS ||
1800 MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
1801 &hkey, FALSE) == ERROR_SUCCESS))
1805 if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
1806 MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
1809 path = msi_reg_get_val_str(hkey, squished_pc);
1812 state = INSTALLSTATE_ABSENT;
1814 if (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
1815 state = INSTALLSTATE_LOCAL;
1820 return INSTALLSTATE_UNKNOWN;
1822 if (state == INSTALLSTATE_LOCAL && !*path)
1823 state = INSTALLSTATE_NOTUSED;
1825 msi_strcpy_to_awstring(path, lpPathBuf, pcchBuf);
1830 /******************************************************************
1831 * MsiGetComponentPathW [MSI.@]
1833 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1834 LPWSTR lpPathBuf, LPDWORD pcchBuf)
1838 path.unicode = TRUE;
1839 path.str.w = lpPathBuf;
1841 return MSI_GetComponentPath( szProduct, szComponent, &path, pcchBuf );
1844 /******************************************************************
1845 * MsiGetComponentPathA [MSI.@]
1847 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
1848 LPSTR lpPathBuf, LPDWORD pcchBuf)
1850 LPWSTR szwProduct, szwComponent = NULL;
1851 INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
1854 szwProduct = strdupAtoW( szProduct );
1855 if( szProduct && !szwProduct)
1858 szwComponent = strdupAtoW( szComponent );
1859 if( szComponent && !szwComponent )
1862 path.unicode = FALSE;
1863 path.str.a = lpPathBuf;
1865 r = MSI_GetComponentPath( szwProduct, szwComponent, &path, pcchBuf );
1868 msi_free( szwProduct );
1869 msi_free( szwComponent );
1874 /******************************************************************
1875 * MsiQueryFeatureStateA [MSI.@]
1877 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1879 LPWSTR szwProduct = NULL, szwFeature= NULL;
1880 INSTALLSTATE rc = INSTALLSTATE_UNKNOWN;
1882 szwProduct = strdupAtoW( szProduct );
1883 if ( szProduct && !szwProduct )
1886 szwFeature = strdupAtoW( szFeature );
1887 if ( szFeature && !szwFeature )
1890 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1893 msi_free( szwProduct);
1894 msi_free( szwFeature);
1899 /******************************************************************
1900 * MsiQueryFeatureStateW [MSI.@]
1902 * Checks the state of a feature
1905 * szProduct [I] Product's GUID string
1906 * szFeature [I] Feature's GUID string
1909 * INSTALLSTATE_LOCAL Feature is installed and usable
1910 * INSTALLSTATE_ABSENT Feature is absent
1911 * INSTALLSTATE_ADVERTISED Feature should be installed on demand
1912 * INSTALLSTATE_UNKNOWN An error occurred
1913 * INSTALLSTATE_INVALIDARG One of the GUIDs was invalid
1916 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1918 WCHAR squishProduct[33], comp[GUID_SIZE];
1920 LPWSTR components, p, parent_feature, path;
1924 BOOL missing = FALSE;
1925 BOOL machine = FALSE;
1926 BOOL source = FALSE;
1928 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1930 if (!szProduct || !szFeature)
1931 return INSTALLSTATE_INVALIDARG;
1933 if (!squash_guid( szProduct, squishProduct ))
1934 return INSTALLSTATE_INVALIDARG;
1936 if (MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
1937 &hkey, FALSE) != ERROR_SUCCESS &&
1938 MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
1939 &hkey, FALSE) != ERROR_SUCCESS)
1941 rc = MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
1943 if (rc != ERROR_SUCCESS)
1944 return INSTALLSTATE_UNKNOWN;
1949 parent_feature = msi_reg_get_val_str( hkey, szFeature );
1952 if (!parent_feature)
1953 return INSTALLSTATE_UNKNOWN;
1955 r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
1956 msi_free(parent_feature);
1957 if (r == INSTALLSTATE_ABSENT)
1961 rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
1962 MSIINSTALLCONTEXT_MACHINE,
1965 rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
1966 MSIINSTALLCONTEXT_USERUNMANAGED,
1969 if (rc != ERROR_SUCCESS)
1970 return INSTALLSTATE_ADVERTISED;
1972 components = msi_reg_get_val_str( hkey, szFeature );
1975 TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
1978 return INSTALLSTATE_ADVERTISED;
1980 for( p = components; *p && *p != 2 ; p += 20)
1982 if (!decode_base85_guid( p, &guid ))
1984 if (p != components)
1987 msi_free(components);
1988 return INSTALLSTATE_BADCONFIG;
1991 StringFromGUID2(&guid, comp, GUID_SIZE);
1994 rc = MSIREG_OpenLocalUserDataComponentKey(comp, &hkey, FALSE);
1996 rc = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
1998 if (rc != ERROR_SUCCESS)
2000 msi_free(components);
2001 return INSTALLSTATE_ADVERTISED;
2004 path = msi_reg_get_val_str(hkey, squishProduct);
2007 else if (lstrlenW(path) > 2 &&
2008 path[0] >= '0' && path[0] <= '9' &&
2009 path[1] >= '0' && path[1] <= '9')
2017 TRACE("%s %s -> %d\n", debugstr_w(szProduct), debugstr_w(szFeature), r);
2018 msi_free(components);
2021 return INSTALLSTATE_ADVERTISED;
2024 return INSTALLSTATE_SOURCE;
2026 return INSTALLSTATE_LOCAL;
2029 /******************************************************************
2030 * MsiGetFileVersionA [MSI.@]
2032 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
2033 LPDWORD pcchVersionBuf, LPSTR lpLangBuf, LPDWORD pcchLangBuf)
2035 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
2036 UINT ret = ERROR_OUTOFMEMORY;
2038 if ((lpVersionBuf && !pcchVersionBuf) ||
2039 (lpLangBuf && !pcchLangBuf))
2040 return ERROR_INVALID_PARAMETER;
2044 szwFilePath = strdupAtoW( szFilePath );
2049 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
2051 lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
2052 if( !lpwVersionBuff )
2056 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
2058 lpwLangBuff = msi_alloc(*pcchLangBuf*sizeof(WCHAR));
2063 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
2064 lpwLangBuff, pcchLangBuf);
2066 if( (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && lpwVersionBuff )
2067 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
2068 lpVersionBuf, *pcchVersionBuf + 1, NULL, NULL);
2069 if( (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && lpwLangBuff )
2070 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
2071 lpLangBuf, *pcchLangBuf + 1, NULL, NULL);
2074 msi_free(szwFilePath);
2075 msi_free(lpwVersionBuff);
2076 msi_free(lpwLangBuff);
2081 /******************************************************************
2082 * MsiGetFileVersionW [MSI.@]
2084 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
2085 LPDWORD pcchVersionBuf, LPWSTR lpLangBuf, LPDWORD pcchLangBuf)
2087 static const WCHAR szVersionResource[] = {'\\',0};
2088 static const WCHAR szVersionFormat[] = {
2089 '%','d','.','%','d','.','%','d','.','%','d',0};
2090 static const WCHAR szLangResource[] = {
2091 '\\','V','a','r','F','i','l','e','I','n','f','o','\\',
2092 'T','r','a','n','s','l','a','t','i','o','n',0};
2093 static const WCHAR szLangFormat[] = {'%','d',0};
2095 DWORD dwVerLen, gle;
2096 LPVOID lpVer = NULL;
2097 VS_FIXEDFILEINFO *ffi;
2102 TRACE("%s %p %d %p %d\n", debugstr_w(szFilePath),
2103 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
2104 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
2106 if ((lpVersionBuf && !pcchVersionBuf) ||
2107 (lpLangBuf && !pcchLangBuf))
2108 return ERROR_INVALID_PARAMETER;
2110 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
2113 gle = GetLastError();
2114 if (gle == ERROR_BAD_PATHNAME)
2115 return ERROR_FILE_NOT_FOUND;
2116 else if (gle == ERROR_RESOURCE_DATA_NOT_FOUND)
2117 return ERROR_FILE_INVALID;
2122 lpVer = msi_alloc(dwVerLen);
2125 ret = ERROR_OUTOFMEMORY;
2129 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
2131 ret = GetLastError();
2137 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
2140 wsprintfW(tmp, szVersionFormat,
2141 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
2142 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
2143 if (lpVersionBuf) lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
2145 if (strlenW(tmp) >= *pcchVersionBuf)
2146 ret = ERROR_MORE_DATA;
2148 *pcchVersionBuf = lstrlenW(tmp);
2152 if (lpVersionBuf) *lpVersionBuf = 0;
2153 *pcchVersionBuf = 0;
2159 if (VerQueryValueW(lpVer, szLangResource, (LPVOID*)&lang, &puLen) &&
2162 wsprintfW(tmp, szLangFormat, *lang);
2163 if (lpLangBuf) lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
2165 if (strlenW(tmp) >= *pcchLangBuf)
2166 ret = ERROR_MORE_DATA;
2168 *pcchLangBuf = lstrlenW(tmp);
2172 if (lpLangBuf) *lpLangBuf = 0;
2182 /***********************************************************************
2183 * MsiGetFeatureUsageW [MSI.@]
2185 UINT WINAPI MsiGetFeatureUsageW( LPCWSTR szProduct, LPCWSTR szFeature,
2186 LPDWORD pdwUseCount, LPWORD pwDateUsed )
2188 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
2189 pdwUseCount, pwDateUsed);
2190 return ERROR_CALL_NOT_IMPLEMENTED;
2193 /***********************************************************************
2194 * MsiGetFeatureUsageA [MSI.@]
2196 UINT WINAPI MsiGetFeatureUsageA( LPCSTR szProduct, LPCSTR szFeature,
2197 LPDWORD pdwUseCount, LPWORD pwDateUsed )
2199 LPWSTR prod = NULL, feat = NULL;
2200 UINT ret = ERROR_OUTOFMEMORY;
2202 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
2203 pdwUseCount, pwDateUsed);
2205 prod = strdupAtoW( szProduct );
2206 if (szProduct && !prod)
2209 feat = strdupAtoW( szFeature );
2210 if (szFeature && !feat)
2213 ret = MsiGetFeatureUsageW( prod, feat, pdwUseCount, pwDateUsed );
2222 /***********************************************************************
2223 * MsiUseFeatureExW [MSI.@]
2225 INSTALLSTATE WINAPI MsiUseFeatureExW( LPCWSTR szProduct, LPCWSTR szFeature,
2226 DWORD dwInstallMode, DWORD dwReserved )
2230 TRACE("%s %s %i %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
2231 dwInstallMode, dwReserved);
2233 state = MsiQueryFeatureStateW( szProduct, szFeature );
2236 return INSTALLSTATE_INVALIDARG;
2238 if (state == INSTALLSTATE_LOCAL && dwInstallMode != INSTALLMODE_NODETECTION)
2240 FIXME("mark product %s feature %s as used\n",
2241 debugstr_w(szProduct), debugstr_w(szFeature) );
2247 /***********************************************************************
2248 * MsiUseFeatureExA [MSI.@]
2250 INSTALLSTATE WINAPI MsiUseFeatureExA( LPCSTR szProduct, LPCSTR szFeature,
2251 DWORD dwInstallMode, DWORD dwReserved )
2253 INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
2254 LPWSTR prod = NULL, feat = NULL;
2256 TRACE("%s %s %i %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
2257 dwInstallMode, dwReserved);
2259 prod = strdupAtoW( szProduct );
2260 if (szProduct && !prod)
2263 feat = strdupAtoW( szFeature );
2264 if (szFeature && !feat)
2267 ret = MsiUseFeatureExW( prod, feat, dwInstallMode, dwReserved );
2276 /***********************************************************************
2277 * MsiUseFeatureW [MSI.@]
2279 INSTALLSTATE WINAPI MsiUseFeatureW( LPCWSTR szProduct, LPCWSTR szFeature )
2281 return MsiUseFeatureExW(szProduct, szFeature, 0, 0);
2284 /***********************************************************************
2285 * MsiUseFeatureA [MSI.@]
2287 INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
2289 return MsiUseFeatureExA(szProduct, szFeature, 0, 0);
2292 /***********************************************************************
2293 * MSI_ProvideQualifiedComponentEx [internal]
2295 static UINT MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
2296 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
2297 DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
2298 LPDWORD pcchPathBuf)
2300 WCHAR product[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1],
2301 feature[MAX_FEATURE_CHARS+1];
2307 TRACE("%s %s %i %s %i %i %p %p\n", debugstr_w(szComponent),
2308 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
2309 Unused1, Unused2, lpPathBuf, pcchPathBuf);
2311 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
2312 if (rc != ERROR_SUCCESS)
2313 return ERROR_INDEX_ABSENT;
2315 info = msi_reg_get_val_str( hkey, szQualifier );
2319 return ERROR_INDEX_ABSENT;
2321 MsiDecomposeDescriptorW(info, product, feature, component, &sz);
2324 rc = MSI_GetComponentPath(product, component, lpPathBuf, pcchPathBuf);
2326 rc = MSI_GetComponentPath(szProduct, component, lpPathBuf, pcchPathBuf);
2330 if (rc != INSTALLSTATE_LOCAL)
2331 return ERROR_FILE_NOT_FOUND;
2333 return ERROR_SUCCESS;
2336 /***********************************************************************
2337 * MsiProvideQualifiedComponentExW [MSI.@]
2339 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
2340 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
2341 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
2342 LPDWORD pcchPathBuf)
2346 path.unicode = TRUE;
2347 path.str.w = lpPathBuf;
2349 return MSI_ProvideQualifiedComponentEx(szComponent, szQualifier,
2350 dwInstallMode, szProduct, Unused1, Unused2, &path, pcchPathBuf);
2353 /***********************************************************************
2354 * MsiProvideQualifiedComponentExA [MSI.@]
2356 UINT WINAPI MsiProvideQualifiedComponentExA(LPCSTR szComponent,
2357 LPCSTR szQualifier, DWORD dwInstallMode, LPCSTR szProduct,
2358 DWORD Unused1, DWORD Unused2, LPSTR lpPathBuf,
2359 LPDWORD pcchPathBuf)
2361 LPWSTR szwComponent, szwQualifier = NULL, szwProduct = NULL;
2362 UINT r = ERROR_OUTOFMEMORY;
2365 TRACE("%s %s %u %s %u %u %p %p\n", debugstr_a(szComponent),
2366 debugstr_a(szQualifier), dwInstallMode, debugstr_a(szProduct),
2367 Unused1, Unused2, lpPathBuf, pcchPathBuf);
2369 szwComponent = strdupAtoW( szComponent );
2370 if (szComponent && !szwComponent)
2373 szwQualifier = strdupAtoW( szQualifier );
2374 if (szQualifier && !szwQualifier)
2377 szwProduct = strdupAtoW( szProduct );
2378 if (szProduct && !szwProduct)
2381 path.unicode = FALSE;
2382 path.str.a = lpPathBuf;
2384 r = MSI_ProvideQualifiedComponentEx(szwComponent, szwQualifier,
2385 dwInstallMode, szwProduct, Unused1,
2386 Unused2, &path, pcchPathBuf);
2388 msi_free(szwProduct);
2389 msi_free(szwComponent);
2390 msi_free(szwQualifier);
2395 /***********************************************************************
2396 * MsiProvideQualifiedComponentW [MSI.@]
2398 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
2399 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
2400 LPDWORD pcchPathBuf)
2402 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
2403 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
2406 /***********************************************************************
2407 * MsiProvideQualifiedComponentA [MSI.@]
2409 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
2410 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
2411 LPDWORD pcchPathBuf)
2413 return MsiProvideQualifiedComponentExA(szComponent, szQualifier,
2414 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
2417 /***********************************************************************
2418 * MSI_GetUserInfo [internal]
2420 static USERINFOSTATE MSI_GetUserInfo(LPCWSTR szProduct,
2421 awstring *lpUserNameBuf, LPDWORD pcchUserNameBuf,
2422 awstring *lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2423 awstring *lpSerialBuf, LPDWORD pcchSerialBuf)
2425 WCHAR squished_pc[SQUISH_GUID_SIZE];
2426 LPWSTR user, org, serial;
2427 USERINFOSTATE state;
2432 static const WCHAR szEmpty[] = {0};
2434 TRACE("%s %p %p %p %p %p %p\n", debugstr_w(szProduct), lpUserNameBuf,
2435 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
2438 if (!szProduct || !squash_guid(szProduct, squished_pc))
2439 return USERINFOSTATE_INVALIDARG;
2441 if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
2442 &hkey, FALSE) != ERROR_SUCCESS &&
2443 MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
2444 &hkey, FALSE) != ERROR_SUCCESS &&
2445 MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
2446 &hkey, FALSE) != ERROR_SUCCESS)
2448 return USERINFOSTATE_UNKNOWN;
2451 if (MSIREG_OpenCurrentUserInstallProps(szProduct, &props, FALSE) != ERROR_SUCCESS &&
2452 MSIREG_OpenLocalSystemInstallProps(szProduct, &props, FALSE) != ERROR_SUCCESS)
2455 return USERINFOSTATE_ABSENT;
2458 user = msi_reg_get_val_str(props, INSTALLPROPERTY_REGOWNERW);
2459 org = msi_reg_get_val_str(props, INSTALLPROPERTY_REGCOMPANYW);
2460 serial = msi_reg_get_val_str(props, INSTALLPROPERTY_PRODUCTIDW);
2461 state = USERINFOSTATE_ABSENT;
2467 state = USERINFOSTATE_PRESENT;
2469 if (pcchUserNameBuf)
2471 if (lpUserNameBuf && !user)
2473 (*pcchUserNameBuf)--;
2477 r = msi_strcpy_to_awstring(user, lpUserNameBuf, pcchUserNameBuf);
2478 if (r == ERROR_MORE_DATA)
2480 state = USERINFOSTATE_MOREDATA;
2488 if (!orgptr) orgptr = szEmpty;
2490 r = msi_strcpy_to_awstring(orgptr, lpOrgNameBuf, pcchOrgNameBuf);
2491 if (r == ERROR_MORE_DATA)
2493 state = USERINFOSTATE_MOREDATA;
2506 r = msi_strcpy_to_awstring(serial, lpSerialBuf, pcchSerialBuf);
2507 if (r == ERROR_MORE_DATA)
2508 state = USERINFOSTATE_MOREDATA;
2519 /***********************************************************************
2520 * MsiGetUserInfoW [MSI.@]
2522 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct,
2523 LPWSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
2524 LPWSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2525 LPWSTR lpSerialBuf, LPDWORD pcchSerialBuf)
2527 awstring user, org, serial;
2529 if ((lpUserNameBuf && !pcchUserNameBuf) ||
2530 (lpOrgNameBuf && !pcchOrgNameBuf) ||
2531 (lpSerialBuf && !pcchSerialBuf))
2532 return USERINFOSTATE_INVALIDARG;
2534 user.unicode = TRUE;
2535 user.str.w = lpUserNameBuf;
2537 org.str.w = lpOrgNameBuf;
2538 serial.unicode = TRUE;
2539 serial.str.w = lpSerialBuf;
2541 return MSI_GetUserInfo( szProduct, &user, pcchUserNameBuf,
2542 &org, pcchOrgNameBuf,
2543 &serial, pcchSerialBuf );
2546 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct,
2547 LPSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
2548 LPSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2549 LPSTR lpSerialBuf, LPDWORD pcchSerialBuf)
2551 awstring user, org, serial;
2555 if ((lpUserNameBuf && !pcchUserNameBuf) ||
2556 (lpOrgNameBuf && !pcchOrgNameBuf) ||
2557 (lpSerialBuf && !pcchSerialBuf))
2558 return USERINFOSTATE_INVALIDARG;
2560 prod = strdupAtoW( szProduct );
2561 if (szProduct && !prod)
2562 return ERROR_OUTOFMEMORY;
2564 user.unicode = FALSE;
2565 user.str.a = lpUserNameBuf;
2566 org.unicode = FALSE;
2567 org.str.a = lpOrgNameBuf;
2568 serial.unicode = FALSE;
2569 serial.str.a = lpSerialBuf;
2571 r = MSI_GetUserInfo( prod, &user, pcchUserNameBuf,
2572 &org, pcchOrgNameBuf,
2573 &serial, pcchSerialBuf );
2580 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
2584 MSIPACKAGE *package;
2585 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
2587 TRACE("(%s)\n",debugstr_w(szProduct));
2589 rc = MsiOpenProductW(szProduct,&handle);
2590 if (rc != ERROR_SUCCESS)
2591 return ERROR_INVALID_PARAMETER;
2593 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
2594 rc = ACTION_PerformUIAction(package, szFirstRun, -1);
2595 msiobj_release( &package->hdr );
2597 MsiCloseHandle(handle);
2602 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
2606 MSIPACKAGE *package;
2607 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
2609 TRACE("(%s)\n",debugstr_a(szProduct));
2611 rc = MsiOpenProductA(szProduct,&handle);
2612 if (rc != ERROR_SUCCESS)
2613 return ERROR_INVALID_PARAMETER;
2615 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
2616 rc = ACTION_PerformUIAction(package, szFirstRun, -1);
2617 msiobj_release( &package->hdr );
2619 MsiCloseHandle(handle);
2624 /***********************************************************************
2625 * MsiConfigureFeatureA [MSI.@]
2627 UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
2629 LPWSTR prod, feat = NULL;
2630 UINT r = ERROR_OUTOFMEMORY;
2632 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
2634 prod = strdupAtoW( szProduct );
2635 if (szProduct && !prod)
2638 feat = strdupAtoW( szFeature );
2639 if (szFeature && !feat)
2642 r = MsiConfigureFeatureW(prod, feat, eInstallState);
2651 /***********************************************************************
2652 * MsiConfigureFeatureW [MSI.@]
2654 UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
2656 static const WCHAR szCostInit[] = { 'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0 };
2657 MSIPACKAGE *package = NULL;
2659 WCHAR sourcepath[MAX_PATH], filename[MAX_PATH];
2662 TRACE("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
2664 if (!szProduct || !szFeature)
2665 return ERROR_INVALID_PARAMETER;
2667 switch (eInstallState)
2669 case INSTALLSTATE_DEFAULT:
2670 /* FIXME: how do we figure out the default location? */
2671 eInstallState = INSTALLSTATE_LOCAL;
2673 case INSTALLSTATE_LOCAL:
2674 case INSTALLSTATE_SOURCE:
2675 case INSTALLSTATE_ABSENT:
2676 case INSTALLSTATE_ADVERTISED:
2679 return ERROR_INVALID_PARAMETER;
2682 r = MSI_OpenProductW( szProduct, &package );
2683 if (r != ERROR_SUCCESS)
2686 sz = sizeof(sourcepath);
2687 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2688 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
2690 sz = sizeof(filename);
2691 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2692 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
2694 lstrcatW( sourcepath, filename );
2696 MsiSetInternalUI( INSTALLUILEVEL_BASIC, NULL );
2698 r = ACTION_PerformUIAction( package, szCostInit, -1 );
2699 if (r != ERROR_SUCCESS)
2702 r = MSI_SetFeatureStateW( package, szFeature, eInstallState);
2703 if (r != ERROR_SUCCESS)
2706 r = MSI_InstallPackage( package, sourcepath, NULL );
2709 msiobj_release( &package->hdr );
2714 /***********************************************************************
2715 * MsiCreateAndVerifyInstallerDirectory [MSI.@]
2717 * Notes: undocumented
2719 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
2721 WCHAR path[MAX_PATH];
2723 TRACE("%d\n", dwReserved);
2727 FIXME("dwReserved=%d\n", dwReserved);
2728 return ERROR_INVALID_PARAMETER;
2731 if (!GetWindowsDirectoryW(path, MAX_PATH))
2732 return ERROR_FUNCTION_FAILED;
2734 lstrcatW(path, installerW);
2736 if (!CreateDirectoryW(path, NULL))
2737 return ERROR_FUNCTION_FAILED;
2739 return ERROR_SUCCESS;
2742 /***********************************************************************
2743 * MsiGetShortcutTargetA [MSI.@]
2745 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
2746 LPSTR szProductCode, LPSTR szFeatureId,
2747 LPSTR szComponentCode )
2750 const int len = MAX_FEATURE_CHARS+1;
2751 WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1];
2754 target = strdupAtoW( szShortcutTarget );
2755 if (szShortcutTarget && !target )
2756 return ERROR_OUTOFMEMORY;
2760 r = MsiGetShortcutTargetW( target, product, feature, component );
2762 if (r == ERROR_SUCCESS)
2764 WideCharToMultiByte( CP_ACP, 0, product, -1, szProductCode, len, NULL, NULL );
2765 WideCharToMultiByte( CP_ACP, 0, feature, -1, szFeatureId, len, NULL, NULL );
2766 WideCharToMultiByte( CP_ACP, 0, component, -1, szComponentCode, len, NULL, NULL );
2771 /***********************************************************************
2772 * MsiGetShortcutTargetW [MSI.@]
2774 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
2775 LPWSTR szProductCode, LPWSTR szFeatureId,
2776 LPWSTR szComponentCode )
2778 IShellLinkDataList *dl = NULL;
2779 IPersistFile *pf = NULL;
2780 LPEXP_DARWIN_LINK darwin = NULL;
2783 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget),
2784 szProductCode, szFeatureId, szComponentCode );
2786 init = CoInitialize(NULL);
2788 r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
2789 &IID_IPersistFile, (LPVOID*) &pf );
2790 if( SUCCEEDED( r ) )
2792 r = IPersistFile_Load( pf, szShortcutTarget,
2793 STGM_READ | STGM_SHARE_DENY_WRITE );
2794 if( SUCCEEDED( r ) )
2796 r = IPersistFile_QueryInterface( pf, &IID_IShellLinkDataList,
2798 if( SUCCEEDED( r ) )
2800 IShellLinkDataList_CopyDataBlock( dl, EXP_DARWIN_ID_SIG,
2802 IShellLinkDataList_Release( dl );
2805 IPersistFile_Release( pf );
2808 if (SUCCEEDED(init))
2811 TRACE("darwin = %p\n", darwin);
2818 ret = MsiDecomposeDescriptorW( darwin->szwDarwinID,
2819 szProductCode, szFeatureId, szComponentCode, &sz );
2820 LocalFree( darwin );
2824 return ERROR_FUNCTION_FAILED;
2827 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
2828 DWORD dwReinstallMode )
2830 MSIPACKAGE* package = NULL;
2832 WCHAR sourcepath[MAX_PATH];
2833 WCHAR filename[MAX_PATH];
2834 static const WCHAR szLogVerbose[] = {
2835 ' ','L','O','G','V','E','R','B','O','S','E',0 };
2836 static const WCHAR szInstalled[] = { 'I','n','s','t','a','l','l','e','d',0};
2837 static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
2838 static const WCHAR szReinstallMode[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
2839 static const WCHAR szOne[] = {'1',0};
2840 WCHAR reinstallmode[11];
2844 FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
2847 ptr = reinstallmode;
2849 if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
2851 if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
2853 if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
2855 if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
2857 if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
2859 if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
2861 if (dwReinstallMode & REINSTALLMODE_USERDATA)
2863 if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
2865 if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
2867 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
2871 sz = sizeof(sourcepath);
2872 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2873 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
2875 sz = sizeof(filename);
2876 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2877 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
2879 lstrcatW( sourcepath, filename );
2881 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
2882 r = MSI_OpenPackageW( sourcepath, &package );
2884 r = MSI_OpenProductW( szProduct, &package );
2886 if (r != ERROR_SUCCESS)
2889 MSI_SetPropertyW( package, szReinstallMode, reinstallmode );
2890 MSI_SetPropertyW( package, szInstalled, szOne );
2891 MSI_SetPropertyW( package, szLogVerbose, szOne );
2892 MSI_SetPropertyW( package, szReinstall, szFeature );
2894 r = MSI_InstallPackage( package, sourcepath, NULL );
2896 msiobj_release( &package->hdr );
2901 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
2902 DWORD dwReinstallMode )
2908 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
2911 wszProduct = strdupAtoW(szProduct);
2912 wszFeature = strdupAtoW(szFeature);
2914 rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
2916 msi_free(wszProduct);
2917 msi_free(wszFeature);
2924 unsigned int buf[4];
2925 unsigned char in[64];
2926 unsigned char digest[16];
2929 extern VOID WINAPI MD5Init( MD5_CTX *);
2930 extern VOID WINAPI MD5Update( MD5_CTX *, const unsigned char *, unsigned int );
2931 extern VOID WINAPI MD5Final( MD5_CTX *);
2933 /***********************************************************************
2934 * MsiGetFileHashW [MSI.@]
2936 UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions,
2937 PMSIFILEHASHINFO pHash )
2939 HANDLE handle, mapping;
2942 UINT r = ERROR_FUNCTION_FAILED;
2944 TRACE("%s %08x %p\n", debugstr_w(szFilePath), dwOptions, pHash );
2947 return ERROR_INVALID_PARAMETER;
2950 return ERROR_PATH_NOT_FOUND;
2953 return ERROR_INVALID_PARAMETER;
2955 return ERROR_INVALID_PARAMETER;
2956 if (pHash->dwFileHashInfoSize < sizeof *pHash)
2957 return ERROR_INVALID_PARAMETER;
2959 handle = CreateFileW( szFilePath, GENERIC_READ,
2960 FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL );
2961 if (handle == INVALID_HANDLE_VALUE)
2962 return ERROR_FILE_NOT_FOUND;
2964 length = GetFileSize( handle, NULL );
2966 mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
2969 p = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, length );
2975 MD5Update( &ctx, p, length );
2977 UnmapViewOfFile( p );
2979 memcpy( pHash->dwData, ctx.digest, sizeof pHash->dwData );
2982 CloseHandle( mapping );
2984 CloseHandle( handle );
2989 /***********************************************************************
2990 * MsiGetFileHashA [MSI.@]
2992 UINT WINAPI MsiGetFileHashA( LPCSTR szFilePath, DWORD dwOptions,
2993 PMSIFILEHASHINFO pHash )
2998 TRACE("%s %08x %p\n", debugstr_a(szFilePath), dwOptions, pHash );
3000 file = strdupAtoW( szFilePath );
3001 if (szFilePath && !file)
3002 return ERROR_OUTOFMEMORY;
3004 r = MsiGetFileHashW( file, dwOptions, pHash );
3009 /***********************************************************************
3010 * MsiAdvertiseScriptW [MSI.@]
3012 UINT WINAPI MsiAdvertiseScriptW( LPCWSTR szScriptFile, DWORD dwFlags,
3013 PHKEY phRegData, BOOL fRemoveItems )
3015 FIXME("%s %08x %p %d\n",
3016 debugstr_w( szScriptFile ), dwFlags, phRegData, fRemoveItems );
3017 return ERROR_CALL_NOT_IMPLEMENTED;
3020 /***********************************************************************
3021 * MsiAdvertiseScriptA [MSI.@]
3023 UINT WINAPI MsiAdvertiseScriptA( LPCSTR szScriptFile, DWORD dwFlags,
3024 PHKEY phRegData, BOOL fRemoveItems )
3026 FIXME("%s %08x %p %d\n",
3027 debugstr_a( szScriptFile ), dwFlags, phRegData, fRemoveItems );
3028 return ERROR_CALL_NOT_IMPLEMENTED;
3031 /***********************************************************************
3032 * MsiIsProductElevatedW [MSI.@]
3034 UINT WINAPI MsiIsProductElevatedW( LPCWSTR szProduct, BOOL *pfElevated )
3036 FIXME("%s %p - stub\n",
3037 debugstr_w( szProduct ), pfElevated );
3039 return ERROR_SUCCESS;
3042 /***********************************************************************
3043 * MsiIsProductElevatedA [MSI.@]
3045 UINT WINAPI MsiIsProductElevatedA( LPCSTR szProduct, BOOL *pfElevated )
3047 FIXME("%s %p - stub\n",
3048 debugstr_a( szProduct ), pfElevated );
3050 return ERROR_SUCCESS;
3053 /***********************************************************************
3054 * MsiSetExternalUIRecord [MSI.@]
3056 UINT WINAPI MsiSetExternalUIRecord( INSTALLUI_HANDLER_RECORD puiHandler,
3057 DWORD dwMessageFilter, LPVOID pvContext,
3058 PINSTALLUI_HANDLER_RECORD ppuiPrevHandler)
3060 FIXME("%p %08x %p %p\n", puiHandler, dwMessageFilter ,pvContext,
3062 return ERROR_CALL_NOT_IMPLEMENTED;
3065 /***********************************************************************
3066 * MsiInstallMissingComponentW [MSI.@]
3068 UINT WINAPI MsiInstallMissingComponentW(LPCWSTR szProduct, LPCWSTR szComponent, INSTALLSTATE eInstallState)
3070 FIXME("(%s %s %d\n", debugstr_w(szProduct), debugstr_w(szComponent), eInstallState);
3071 return ERROR_SUCCESS;