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, NULL, MSIINSTALLCONTEXT_USERMANAGED,
55 &hkey, FALSE) == ERROR_SUCCESS)
56 *context = MSIINSTALLCONTEXT_USERMANAGED;
57 else if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
58 &hkey, FALSE) == ERROR_SUCCESS)
59 *context = MSIINSTALLCONTEXT_MACHINE;
60 else if (MSIREG_OpenProductKey(szProduct, NULL,
61 MSIINSTALLCONTEXT_USERUNMANAGED,
62 &hkey, FALSE) == ERROR_SUCCESS)
63 *context = MSIINSTALLCONTEXT_USERUNMANAGED;
67 if (*context == MSIINSTALLCONTEXT_NONE)
68 return ERROR_UNKNOWN_PRODUCT;
73 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
76 LPWSTR szwProd = NULL;
78 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
82 szwProd = strdupAtoW( szProduct );
84 return ERROR_OUTOFMEMORY;
87 r = MsiOpenProductW( szwProd, phProduct );
94 static UINT MSI_OpenProductW(LPCWSTR szProduct, MSIPACKAGE **package)
99 MSIINSTALLCONTEXT context;
101 static const WCHAR managed[] = {
102 'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0};
103 static const WCHAR local[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
105 TRACE("%s %p\n", debugstr_w(szProduct), package);
107 r = msi_locate_product(szProduct, &context);
108 if (r != ERROR_SUCCESS)
111 r = MSIREG_OpenInstallProps(szProduct, context, NULL, &props, FALSE);
112 if (r != ERROR_SUCCESS)
113 return ERROR_UNKNOWN_PRODUCT;
115 if (context == MSIINSTALLCONTEXT_USERMANAGED)
116 path = msi_reg_get_val_str(props, managed);
118 path = msi_reg_get_val_str(props, local);
120 r = ERROR_UNKNOWN_PRODUCT;
122 if (!path || GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
125 if (PathIsRelativeW(path))
127 r = ERROR_INSTALL_PACKAGE_OPEN_FAILED;
131 r = MSI_OpenPackageW(path, package);
139 UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
141 MSIPACKAGE *package = NULL;
142 WCHAR squished_pc[GUID_SIZE];
145 if (!szProduct || !squash_guid(szProduct, squished_pc))
146 return ERROR_INVALID_PARAMETER;
149 return ERROR_INVALID_PARAMETER;
151 r = MSI_OpenProductW(szProduct, &package);
152 if (r != ERROR_SUCCESS)
155 *phProduct = alloc_msihandle(&package->hdr);
157 r = ERROR_NOT_ENOUGH_MEMORY;
159 msiobj_release(&package->hdr);
163 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
164 LPCSTR szTransforms, LANGID lgidLanguage)
166 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
167 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
168 return ERROR_CALL_NOT_IMPLEMENTED;
171 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
172 LPCWSTR szTransforms, LANGID lgidLanguage)
174 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
175 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
176 return ERROR_CALL_NOT_IMPLEMENTED;
179 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
180 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
182 FIXME("%s %s %s %08x %08x %08x\n", debugstr_a(szPackagePath),
183 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
184 lgidLanguage, dwPlatform, dwOptions);
185 return ERROR_CALL_NOT_IMPLEMENTED;
188 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
189 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
191 FIXME("%s %s %s %08x %08x %08x\n", debugstr_w(szPackagePath),
192 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
193 lgidLanguage, dwPlatform, dwOptions);
194 return ERROR_CALL_NOT_IMPLEMENTED;
197 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
199 LPWSTR szwPath = NULL, szwCommand = NULL;
200 UINT r = ERROR_OUTOFMEMORY;
202 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
206 szwPath = strdupAtoW( szPackagePath );
213 szwCommand = strdupAtoW( szCommandLine );
218 r = MsiInstallProductW( szwPath, szwCommand );
222 msi_free( szwCommand );
227 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
229 MSIPACKAGE *package = NULL;
232 TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
235 return ERROR_INVALID_PARAMETER;
238 return ERROR_PATH_NOT_FOUND;
240 r = MSI_OpenPackageW( szPackagePath, &package );
241 if (r == ERROR_SUCCESS)
243 r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
244 msiobj_release( &package->hdr );
250 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
252 FIXME("%s %08x\n", debugstr_a(szProduct), dwReinstallMode);
253 return ERROR_CALL_NOT_IMPLEMENTED;
256 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
258 FIXME("%s %08x\n", debugstr_w(szProduct), dwReinstallMode);
259 return ERROR_CALL_NOT_IMPLEMENTED;
262 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
263 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
265 LPWSTR patch_package = NULL;
266 LPWSTR install_package = NULL;
267 LPWSTR command_line = NULL;
268 UINT r = ERROR_OUTOFMEMORY;
270 TRACE("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
271 eInstallType, debugstr_a(szCommandLine));
273 if (szPatchPackage && !(patch_package = strdupAtoW(szPatchPackage)))
276 if (szInstallPackage && !(install_package = strdupAtoW(szInstallPackage)))
279 if (szCommandLine && !(command_line = strdupAtoW(szCommandLine)))
282 r = MsiApplyPatchW(patch_package, install_package, eInstallType, command_line);
285 msi_free(patch_package);
286 msi_free(install_package);
287 msi_free(command_line);
292 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
293 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
295 MSIHANDLE patch, info;
298 LPCWSTR cmd_ptr = szCommandLine;
300 LPWSTR cmd = NULL, codes = NULL;
302 static const WCHAR space[] = {' ',0};
303 static const WCHAR patcheq[] = {'P','A','T','C','H','=',0};
304 static WCHAR empty[] = {0};
306 TRACE("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
307 eInstallType, debugstr_w(szCommandLine));
309 if (szInstallPackage || eInstallType == INSTALLTYPE_NETWORK_IMAGE ||
310 eInstallType == INSTALLTYPE_SINGLE_INSTANCE)
312 FIXME("Only reading target products from patch\n");
313 return ERROR_CALL_NOT_IMPLEMENTED;
316 r = MsiOpenDatabaseW(szPatchPackage, MSIDBOPEN_READONLY, &patch);
317 if (r != ERROR_SUCCESS)
320 r = MsiGetSummaryInformationW(patch, NULL, 0, &info);
321 if (r != ERROR_SUCCESS)
324 r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, empty, &size);
325 if (r != ERROR_MORE_DATA || !size || type != VT_LPSTR)
327 ERR("Failed to read product codes from patch\n");
331 codes = msi_alloc(++size * sizeof(WCHAR));
334 r = ERROR_OUTOFMEMORY;
338 r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, codes, &size);
339 if (r != ERROR_SUCCESS)
345 size = lstrlenW(cmd_ptr) + lstrlenW(patcheq) + lstrlenW(szPatchPackage) + 1;
346 cmd = msi_alloc(size * sizeof(WCHAR));
349 r = ERROR_OUTOFMEMORY;
353 lstrcpyW(cmd, cmd_ptr);
354 if (szCommandLine) lstrcatW(cmd, space);
355 lstrcatW(cmd, patcheq);
356 lstrcatW(cmd, szPatchPackage);
359 while ((end = strchrW(beg, '}')))
363 r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd);
364 if (r != ERROR_SUCCESS)
374 MsiCloseHandle(info);
375 MsiCloseHandle(patch);
380 UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
381 DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
383 FIXME("(%s, %d, %p): stub!\n", debugstr_a(szProductPackagePath),
384 cPatchInfo, pPatchInfo);
386 return ERROR_CALL_NOT_IMPLEMENTED;
389 UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
390 DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
392 FIXME("(%s, %d, %p): stub!\n", debugstr_w(szProductPackagePath),
393 cPatchInfo, pPatchInfo);
395 return ERROR_CALL_NOT_IMPLEMENTED;
398 static UINT msi_open_package(LPCWSTR product, MSIINSTALLCONTEXT context,
399 MSIPACKAGE **package)
405 WCHAR sourcepath[MAX_PATH];
406 WCHAR filename[MAX_PATH];
408 static const WCHAR szLocalPackage[] = {
409 'L','o','c','a','l','P','a','c','k','a','g','e',0};
412 r = MSIREG_OpenInstallProps(product, context, NULL, &props, FALSE);
413 if (r != ERROR_SUCCESS)
414 return ERROR_BAD_CONFIGURATION;
416 localpack = msi_reg_get_val_str(props, szLocalPackage);
419 lstrcpyW(sourcepath, localpack);
423 if (!localpack || GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
425 sz = sizeof(sourcepath);
426 MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
427 INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
429 sz = sizeof(filename);
430 MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
431 INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
433 lstrcatW(sourcepath, filename);
436 if (GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
437 return ERROR_INSTALL_SOURCE_ABSENT;
439 return MSI_OpenPackageW(sourcepath, package);
442 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
443 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
445 MSIPACKAGE* package = NULL;
446 MSIINSTALLCONTEXT context;
449 WCHAR sourcepath[MAX_PATH];
452 static const WCHAR szInstalled[] = {
453 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
454 static const WCHAR szRemoveAll[] = {
455 ' ','R','E','M','O','V','E','=','A','L','L',0};
456 static const WCHAR szMachine[] = {
457 ' ','A','L','L','U','S','E','R','S','=','1',0};
459 TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
460 debugstr_w(szCommandLine));
462 if (!szProduct || lstrlenW(szProduct) != GUID_SIZE - 1)
463 return ERROR_INVALID_PARAMETER;
465 if (eInstallState == INSTALLSTATE_ADVERTISED ||
466 eInstallState == INSTALLSTATE_SOURCE)
468 FIXME("State %d not implemented\n", eInstallState);
469 return ERROR_CALL_NOT_IMPLEMENTED;
472 r = msi_locate_product(szProduct, &context);
473 if (r != ERROR_SUCCESS)
476 r = msi_open_package(szProduct, context, &package);
477 if (r != ERROR_SUCCESS)
480 sz = lstrlenW(szInstalled) + 1;
483 sz += lstrlenW(szCommandLine);
485 if (eInstallState == INSTALLSTATE_ABSENT)
486 sz += lstrlenW(szRemoveAll);
488 if (context == MSIINSTALLCONTEXT_MACHINE)
489 sz += lstrlenW(szMachine);
491 commandline = msi_alloc(sz * sizeof(WCHAR));
494 r = ERROR_OUTOFMEMORY;
500 lstrcpyW(commandline,szCommandLine);
502 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
503 lstrcatW(commandline,szInstalled);
505 if (eInstallState == INSTALLSTATE_ABSENT)
506 lstrcatW(commandline, szRemoveAll);
508 if (context == MSIINSTALLCONTEXT_MACHINE)
509 lstrcatW(commandline, szMachine);
511 r = MSI_InstallPackage( package, sourcepath, commandline );
513 msi_free(commandline);
516 msiobj_release( &package->hdr );
521 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
522 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
524 LPWSTR szwProduct = NULL;
525 LPWSTR szwCommandLine = NULL;
526 UINT r = ERROR_OUTOFMEMORY;
530 szwProduct = strdupAtoW( szProduct );
537 szwCommandLine = strdupAtoW( szCommandLine );
542 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
545 msi_free( szwProduct );
546 msi_free( szwCommandLine);
551 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
552 INSTALLSTATE eInstallState)
554 LPWSTR szwProduct = NULL;
557 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
561 szwProduct = strdupAtoW( szProduct );
563 return ERROR_OUTOFMEMORY;
566 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
567 msi_free( szwProduct );
572 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
573 INSTALLSTATE eInstallState)
575 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
578 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
580 LPWSTR szwComponent = NULL;
582 WCHAR szwBuffer[GUID_SIZE];
584 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
588 szwComponent = strdupAtoW( szComponent );
590 return ERROR_OUTOFMEMORY;
594 r = MsiGetProductCodeW( szwComponent, szwBuffer );
597 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
599 msi_free( szwComponent );
604 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
607 HKEY compkey, prodkey;
608 WCHAR squished_comp[GUID_SIZE];
609 WCHAR squished_prod[GUID_SIZE];
610 DWORD sz = GUID_SIZE;
612 TRACE("%s %p\n", debugstr_w(szComponent), szBuffer);
614 if (!szComponent || !*szComponent)
615 return ERROR_INVALID_PARAMETER;
617 if (!squash_guid(szComponent, squished_comp))
618 return ERROR_INVALID_PARAMETER;
620 if (MSIREG_OpenUserDataComponentKey(szComponent, NULL, &compkey, FALSE) != ERROR_SUCCESS &&
621 MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &compkey, FALSE) != ERROR_SUCCESS)
623 return ERROR_UNKNOWN_COMPONENT;
626 rc = RegEnumValueW(compkey, 0, squished_prod, &sz, NULL, NULL, NULL, NULL);
627 if (rc != ERROR_SUCCESS)
629 RegCloseKey(compkey);
630 return ERROR_UNKNOWN_COMPONENT;
633 /* check simple case, only one product */
634 rc = RegEnumValueW(compkey, 1, squished_prod, &sz, NULL, NULL, NULL, NULL);
635 if (rc == ERROR_NO_MORE_ITEMS)
642 while ((rc = RegEnumValueW(compkey, index, squished_prod, &sz,
643 NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS)
647 unsquash_guid(squished_prod, szBuffer);
649 if (MSIREG_OpenProductKey(szBuffer, NULL,
650 MSIINSTALLCONTEXT_USERMANAGED,
651 &prodkey, FALSE) == ERROR_SUCCESS ||
652 MSIREG_OpenProductKey(szBuffer, NULL,
653 MSIINSTALLCONTEXT_USERUNMANAGED,
654 &prodkey, FALSE) == ERROR_SUCCESS ||
655 MSIREG_OpenProductKey(szBuffer, NULL,
656 MSIINSTALLCONTEXT_MACHINE,
657 &prodkey, FALSE) == ERROR_SUCCESS)
659 RegCloseKey(prodkey);
665 rc = ERROR_INSTALL_FAILURE;
668 RegCloseKey(compkey);
669 unsquash_guid(squished_prod, szBuffer);
673 static LPWSTR msi_reg_get_value(HKEY hkey, LPCWSTR name, DWORD *type)
679 static const WCHAR format[] = {'%','d',0};
681 res = RegQueryValueExW(hkey, name, NULL, type, NULL, NULL);
682 if (res != ERROR_SUCCESS)
686 return msi_reg_get_val_str(hkey, name);
688 if (!msi_reg_get_val_dword(hkey, name, &dval))
691 sprintfW(temp, format, dval);
692 return strdupW(temp);
695 static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
696 awstring *szValue, LPDWORD pcchValueBuf)
698 MSIINSTALLCONTEXT context = MSIINSTALLCONTEXT_USERUNMANAGED;
699 UINT r = ERROR_UNKNOWN_PROPERTY;
700 HKEY prodkey, userdata, source;
702 WCHAR squished_pc[GUID_SIZE];
703 WCHAR packagecode[GUID_SIZE];
704 BOOL badconfig = FALSE;
706 DWORD save, type = REG_NONE;
708 static WCHAR empty[] = {0};
709 static const WCHAR sourcelist[] = {
710 'S','o','u','r','c','e','L','i','s','t',0};
711 static const WCHAR display_name[] = {
712 'D','i','s','p','l','a','y','N','a','m','e',0};
713 static const WCHAR display_version[] = {
714 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
715 static const WCHAR assignment[] = {
716 'A','s','s','i','g','n','m','e','n','t',0};
718 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
719 debugstr_w(szAttribute), szValue, pcchValueBuf);
721 if ((szValue->str.w && !pcchValueBuf) || !szProduct || !szAttribute)
722 return ERROR_INVALID_PARAMETER;
724 if (!squash_guid(szProduct, squished_pc))
725 return ERROR_INVALID_PARAMETER;
727 if ((r = MSIREG_OpenProductKey(szProduct, NULL,
728 MSIINSTALLCONTEXT_USERMANAGED,
729 &prodkey, FALSE)) != ERROR_SUCCESS &&
730 (r = MSIREG_OpenProductKey(szProduct, NULL,
731 MSIINSTALLCONTEXT_USERUNMANAGED,
732 &prodkey, FALSE)) != ERROR_SUCCESS &&
733 (r = MSIREG_OpenProductKey(szProduct, NULL,
734 MSIINSTALLCONTEXT_MACHINE,
735 &prodkey, FALSE)) == ERROR_SUCCESS)
737 context = MSIINSTALLCONTEXT_MACHINE;
740 MSIREG_OpenInstallProps(szProduct, context, NULL, &userdata, FALSE);
742 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) ||
743 !lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) ||
744 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLDATEW) ||
745 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
746 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLLOCATIONW) ||
747 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLSOURCEW) ||
748 !lstrcmpW(szAttribute, INSTALLPROPERTY_LOCALPACKAGEW) ||
749 !lstrcmpW(szAttribute, INSTALLPROPERTY_PUBLISHERW) ||
750 !lstrcmpW(szAttribute, INSTALLPROPERTY_URLINFOABOUTW) ||
751 !lstrcmpW(szAttribute, INSTALLPROPERTY_URLUPDATEINFOW) ||
752 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMINORW) ||
753 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMAJORW) ||
754 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW) ||
755 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTIDW) ||
756 !lstrcmpW(szAttribute, INSTALLPROPERTY_REGCOMPANYW) ||
757 !lstrcmpW(szAttribute, INSTALLPROPERTY_REGOWNERW))
761 r = ERROR_UNKNOWN_PRODUCT;
766 return ERROR_UNKNOWN_PROPERTY;
768 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
769 szAttribute = display_name;
770 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW))
771 szAttribute = display_version;
773 val = msi_reg_get_value(userdata, szAttribute, &type);
777 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTANCETYPEW) ||
778 !lstrcmpW(szAttribute, INSTALLPROPERTY_TRANSFORMSW) ||
779 !lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
780 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW) ||
781 !lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW) ||
782 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW) ||
783 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW) ||
784 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTICONW) ||
785 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW) ||
786 !lstrcmpW(szAttribute, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
790 r = ERROR_UNKNOWN_PRODUCT;
794 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
795 szAttribute = assignment;
797 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW))
799 res = RegOpenKeyW(prodkey, sourcelist, &source);
800 if (res != ERROR_SUCCESS)
802 r = ERROR_UNKNOWN_PRODUCT;
806 val = msi_reg_get_value(source, szAttribute, &type);
814 val = msi_reg_get_value(prodkey, szAttribute, &type);
819 if (val != empty && type != REG_DWORD &&
820 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
822 if (lstrlenW(val) != SQUISH_GUID_SIZE - 1)
826 unsquash_guid(val, packagecode);
828 val = strdupW(packagecode);
835 r = ERROR_UNKNOWN_PROPERTY;
841 save = *pcchValueBuf;
843 if (strlenW(val) < *pcchValueBuf)
844 r = msi_strcpy_to_awstring(val, szValue, pcchValueBuf);
845 else if (szValue->str.a || szValue->str.w)
849 *pcchValueBuf = lstrlenW(val);
850 else if (r == ERROR_SUCCESS)
852 *pcchValueBuf = save;
853 r = ERROR_BAD_CONFIGURATION;
857 r = ERROR_BAD_CONFIGURATION;
863 RegCloseKey(prodkey);
864 RegCloseKey(userdata);
868 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
869 LPSTR szBuffer, LPDWORD pcchValueBuf)
871 LPWSTR szwProduct, szwAttribute = NULL;
872 UINT r = ERROR_OUTOFMEMORY;
875 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
876 szBuffer, pcchValueBuf);
878 szwProduct = strdupAtoW( szProduct );
879 if( szProduct && !szwProduct )
882 szwAttribute = strdupAtoW( szAttribute );
883 if( szAttribute && !szwAttribute )
886 buffer.unicode = FALSE;
887 buffer.str.a = szBuffer;
889 r = MSI_GetProductInfo( szwProduct, szwAttribute,
890 &buffer, pcchValueBuf );
893 msi_free( szwProduct );
894 msi_free( szwAttribute );
899 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
900 LPWSTR szBuffer, LPDWORD pcchValueBuf)
904 TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute),
905 szBuffer, pcchValueBuf);
907 buffer.unicode = TRUE;
908 buffer.str.w = szBuffer;
910 return MSI_GetProductInfo( szProduct, szAttribute,
911 &buffer, pcchValueBuf );
914 UINT WINAPI MsiGetProductInfoExA(LPCSTR szProductCode, LPCSTR szUserSid,
915 MSIINSTALLCONTEXT dwContext, LPCSTR szProperty,
916 LPSTR szValue, LPDWORD pcchValue)
918 LPWSTR product = NULL;
919 LPWSTR usersid = NULL;
920 LPWSTR property = NULL;
925 TRACE("(%s, %s, %d, %s, %p, %p)\n", debugstr_a(szProductCode),
926 debugstr_a(szUserSid), dwContext, debugstr_a(szProperty),
929 if (szValue && !pcchValue)
930 return ERROR_INVALID_PARAMETER;
932 if (szProductCode) product = strdupAtoW(szProductCode);
933 if (szUserSid) usersid = strdupAtoW(szUserSid);
934 if (szProperty) property = strdupAtoW(szProperty);
936 r = MsiGetProductInfoExW(product, usersid, dwContext, property,
938 if (r != ERROR_SUCCESS)
941 value = msi_alloc(++len * sizeof(WCHAR));
944 r = ERROR_OUTOFMEMORY;
948 r = MsiGetProductInfoExW(product, usersid, dwContext, property,
950 if (r != ERROR_SUCCESS)
956 len = WideCharToMultiByte(CP_ACP, 0, value, -1, NULL, 0, NULL, NULL);
957 if (*pcchValue >= len)
958 WideCharToMultiByte(CP_ACP, 0, value, -1, szValue, len, NULL, NULL);
966 if (*pcchValue <= len || !szValue)
967 len = len * sizeof(WCHAR) - 1;
969 *pcchValue = len - 1;
980 static UINT msi_copy_outval(LPWSTR val, LPWSTR out, LPDWORD size)
985 return ERROR_UNKNOWN_PROPERTY;
989 if (strlenW(val) >= *size)
1000 *size = lstrlenW(val);
1002 return ERROR_SUCCESS;
1005 UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
1006 MSIINSTALLCONTEXT dwContext, LPCWSTR szProperty,
1007 LPWSTR szValue, LPDWORD pcchValue)
1009 WCHAR squished_pc[GUID_SIZE];
1011 LPCWSTR package = NULL;
1012 HKEY props = NULL, prod;
1013 HKEY classes = NULL, managed;
1016 UINT r = ERROR_UNKNOWN_PRODUCT;
1018 static const WCHAR one[] = {'1',0};
1019 static const WCHAR five[] = {'5',0};
1020 static const WCHAR empty[] = {0};
1021 static const WCHAR displayname[] = {
1022 'D','i','s','p','l','a','y','N','a','m','e',0};
1023 static const WCHAR displayversion[] = {
1024 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
1025 static const WCHAR managed_local_package[] = {
1026 'M','a','n','a','g','e','d','L','o','c','a','l',
1027 'P','a','c','k','a','g','e',0};
1029 TRACE("(%s, %s, %d, %s, %p, %p)\n", debugstr_w(szProductCode),
1030 debugstr_w(szUserSid), dwContext, debugstr_w(szProperty),
1031 szValue, pcchValue);
1033 if (!szProductCode || !squash_guid(szProductCode, squished_pc))
1034 return ERROR_INVALID_PARAMETER;
1036 if (szValue && !pcchValue)
1037 return ERROR_INVALID_PARAMETER;
1039 if (dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
1040 dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
1041 dwContext != MSIINSTALLCONTEXT_MACHINE)
1042 return ERROR_INVALID_PARAMETER;
1044 if (!szProperty || !*szProperty)
1045 return ERROR_INVALID_PARAMETER;
1047 if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
1048 return ERROR_INVALID_PARAMETER;
1050 /* FIXME: dwContext is provided, no need to search for it */
1051 MSIREG_OpenProductKey(szProductCode, NULL,MSIINSTALLCONTEXT_USERMANAGED,
1053 MSIREG_OpenProductKey(szProductCode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1056 MSIREG_OpenInstallProps(szProductCode, dwContext, NULL, &props, FALSE);
1058 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
1060 package = INSTALLPROPERTY_LOCALPACKAGEW;
1062 if (!props && !prod)
1065 else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
1067 package = managed_local_package;
1069 if (!props && !managed)
1072 else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1074 package = INSTALLPROPERTY_LOCALPACKAGEW;
1075 MSIREG_OpenProductKey(szProductCode, NULL, dwContext, &classes, FALSE);
1077 if (!props && !classes)
1081 if (!lstrcmpW(szProperty, INSTALLPROPERTY_HELPLINKW) ||
1082 !lstrcmpW(szProperty, INSTALLPROPERTY_HELPTELEPHONEW) ||
1083 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW) ||
1084 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
1085 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLLOCATIONW) ||
1086 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLSOURCEW) ||
1087 !lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW) ||
1088 !lstrcmpW(szProperty, INSTALLPROPERTY_PUBLISHERW) ||
1089 !lstrcmpW(szProperty, INSTALLPROPERTY_URLINFOABOUTW) ||
1090 !lstrcmpW(szProperty, INSTALLPROPERTY_URLUPDATEINFOW) ||
1091 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMINORW) ||
1092 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMAJORW) ||
1093 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW) ||
1094 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTIDW) ||
1095 !lstrcmpW(szProperty, INSTALLPROPERTY_REGCOMPANYW) ||
1096 !lstrcmpW(szProperty, INSTALLPROPERTY_REGOWNERW) ||
1097 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTANCETYPEW))
1099 val = msi_reg_get_value(props, package, &type);
1102 if (prod || classes)
1103 r = ERROR_UNKNOWN_PROPERTY;
1110 if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
1111 szProperty = displayname;
1112 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW))
1113 szProperty = displayversion;
1115 val = msi_reg_get_value(props, szProperty, &type);
1117 val = strdupW(empty);
1119 r = msi_copy_outval(val, szValue, pcchValue);
1121 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW) ||
1122 !lstrcmpW(szProperty, INSTALLPROPERTY_LANGUAGEW) ||
1123 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTNAMEW) ||
1124 !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGECODEW) ||
1125 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONW) ||
1126 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTICONW) ||
1127 !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGENAMEW) ||
1128 !lstrcmpW(szProperty, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
1130 if (!prod && !classes)
1133 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
1135 else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
1137 else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1140 val = msi_reg_get_value(hkey, szProperty, &type);
1142 val = strdupW(empty);
1144 r = msi_copy_outval(val, szValue, pcchValue);
1146 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTSTATEW))
1148 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1152 val = msi_reg_get_value(props, package, &type);
1157 val = strdupW(five);
1162 r = msi_copy_outval(val, szValue, pcchValue);
1165 else if (props && (val = msi_reg_get_value(props, package, &type)))
1168 val = strdupW(five);
1169 r = msi_copy_outval(val, szValue, pcchValue);
1173 if (prod || managed)
1178 r = msi_copy_outval(val, szValue, pcchValue);
1180 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW))
1182 if (!prod && !classes)
1186 val = strdupW(empty);
1187 r = msi_copy_outval(val, szValue, pcchValue);
1190 r = ERROR_UNKNOWN_PROPERTY;
1195 RegCloseKey(managed);
1196 RegCloseKey(classes);
1202 UINT WINAPI MsiGetPatchInfoExA(LPCSTR szPatchCode, LPCSTR szProductCode,
1203 LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1204 LPCSTR szProperty, LPSTR lpValue, DWORD *pcchValue)
1206 LPWSTR patch = NULL, product = NULL, usersid = NULL;
1207 LPWSTR property = NULL, val = NULL;
1211 TRACE("(%s, %s, %s, %d, %s, %p, %p)\n", debugstr_a(szPatchCode),
1212 debugstr_a(szProductCode), debugstr_a(szUserSid), dwContext,
1213 debugstr_a(szProperty), lpValue, pcchValue);
1215 if (lpValue && !pcchValue)
1216 return ERROR_INVALID_PARAMETER;
1218 if (szPatchCode) patch = strdupAtoW(szPatchCode);
1219 if (szProductCode) product = strdupAtoW(szProductCode);
1220 if (szUserSid) usersid = strdupAtoW(szUserSid);
1221 if (szProperty) property = strdupAtoW(szProperty);
1224 r = MsiGetPatchInfoExW(patch, product, usersid, dwContext, property,
1226 if (r != ERROR_SUCCESS)
1229 val = msi_alloc(++len * sizeof(WCHAR));
1232 r = ERROR_OUTOFMEMORY;
1236 r = MsiGetPatchInfoExW(patch, product, usersid, dwContext, property,
1238 if (r != ERROR_SUCCESS || !pcchValue)
1242 WideCharToMultiByte(CP_ACP, 0, val, -1, lpValue,
1243 *pcchValue - 1, NULL, NULL);
1245 len = lstrlenW(val);
1246 if ((*val && *pcchValue < len + 1) || !lpValue)
1250 r = ERROR_MORE_DATA;
1251 lpValue[*pcchValue - 1] = '\0';
1254 *pcchValue = len * sizeof(WCHAR);
1269 UINT WINAPI MsiGetPatchInfoExW(LPCWSTR szPatchCode, LPCWSTR szProductCode,
1270 LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1271 LPCWSTR szProperty, LPWSTR lpValue, DWORD *pcchValue)
1273 WCHAR squished_pc[GUID_SIZE];
1274 WCHAR squished_patch[GUID_SIZE];
1275 HKEY udprod = 0, prod = 0, props = 0;
1276 HKEY patch = 0, patches = 0;
1277 HKEY udpatch = 0, datakey = 0;
1278 HKEY prodpatches = 0;
1280 UINT r = ERROR_UNKNOWN_PRODUCT;
1284 static const WCHAR szEmpty[] = {0};
1285 static const WCHAR szPatches[] = {'P','a','t','c','h','e','s',0};
1286 static const WCHAR szInstalled[] = {'I','n','s','t','a','l','l','e','d',0};
1287 static const WCHAR szManagedPackage[] = {'M','a','n','a','g','e','d',
1288 'L','o','c','a','l','P','a','c','k','a','g','e',0};
1290 TRACE("(%s, %s, %s, %d, %s, %p, %p)\n", debugstr_w(szPatchCode),
1291 debugstr_w(szProductCode), debugstr_w(szUserSid), dwContext,
1292 debugstr_w(szProperty), lpValue, pcchValue);
1294 if (!szProductCode || !squash_guid(szProductCode, squished_pc))
1295 return ERROR_INVALID_PARAMETER;
1297 if (!szPatchCode || !squash_guid(szPatchCode, squished_patch))
1298 return ERROR_INVALID_PARAMETER;
1301 return ERROR_INVALID_PARAMETER;
1303 if (lpValue && !pcchValue)
1304 return ERROR_INVALID_PARAMETER;
1306 if (dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
1307 dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
1308 dwContext != MSIINSTALLCONTEXT_MACHINE)
1309 return ERROR_INVALID_PARAMETER;
1311 if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
1312 return ERROR_INVALID_PARAMETER;
1314 if (!lstrcmpW(szUserSid, szLocalSid))
1315 return ERROR_INVALID_PARAMETER;
1317 if (MSIREG_OpenUserDataProductKey(szProductCode, dwContext, NULL,
1318 &udprod, FALSE) != ERROR_SUCCESS)
1321 if (MSIREG_OpenInstallProps(szProductCode, dwContext, NULL,
1322 &props, FALSE) != ERROR_SUCCESS)
1325 r = ERROR_UNKNOWN_PATCH;
1327 res = RegOpenKeyExW(udprod, szPatches, 0, KEY_READ, &patches);
1328 if (res != ERROR_SUCCESS)
1331 res = RegOpenKeyExW(patches, squished_patch, 0, KEY_READ, &patch);
1332 if (res != ERROR_SUCCESS)
1335 if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW))
1337 if (MSIREG_OpenProductKey(szProductCode, NULL, dwContext,
1338 &prod, FALSE) != ERROR_SUCCESS)
1341 res = RegOpenKeyExW(prod, szPatches, 0, KEY_ALL_ACCESS, &prodpatches);
1342 if (res != ERROR_SUCCESS)
1345 datakey = prodpatches;
1346 szProperty = squished_patch;
1350 if (MSIREG_OpenUserDataPatchKey(szPatchCode, dwContext,
1351 &udpatch, FALSE) != ERROR_SUCCESS)
1354 if (!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW))
1356 if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
1357 szProperty = szManagedPackage;
1360 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW))
1363 szProperty = szInstalled;
1365 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW))
1369 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_UNINSTALLABLEW) ||
1370 !lstrcmpW(szProperty, INSTALLPROPERTY_PATCHSTATEW) ||
1371 !lstrcmpW(szProperty, INSTALLPROPERTY_DISPLAYNAMEW) ||
1372 !lstrcmpW(szProperty, INSTALLPROPERTY_MOREINFOURLW))
1378 r = ERROR_UNKNOWN_PROPERTY;
1383 val = msi_reg_get_val_str(datakey, szProperty);
1385 val = strdupW(szEmpty);
1393 lstrcpynW(lpValue, val, *pcchValue);
1395 len = lstrlenW(val);
1396 if ((*val && *pcchValue < len + 1) || !lpValue)
1399 r = ERROR_MORE_DATA;
1401 *pcchValue = len * sizeof(WCHAR);
1408 RegCloseKey(prodpatches);
1411 RegCloseKey(patches);
1412 RegCloseKey(udpatch);
1414 RegCloseKey(udprod);
1419 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
1421 LPWSTR szwLogFile = NULL;
1424 TRACE("%08x %s %08x\n", dwLogMode, debugstr_a(szLogFile), attributes);
1428 szwLogFile = strdupAtoW( szLogFile );
1430 return ERROR_OUTOFMEMORY;
1432 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
1433 msi_free( szwLogFile );
1437 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
1439 HANDLE file = INVALID_HANDLE_VALUE;
1441 TRACE("%08x %s %08x\n", dwLogMode, debugstr_w(szLogFile), attributes);
1445 lstrcpyW(gszLogFile,szLogFile);
1446 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
1447 DeleteFileW(szLogFile);
1448 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
1449 FILE_ATTRIBUTE_NORMAL, NULL);
1450 if (file != INVALID_HANDLE_VALUE)
1453 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
1456 gszLogFile[0] = '\0';
1458 return ERROR_SUCCESS;
1461 UINT WINAPI MsiEnumComponentCostsW(MSIHANDLE hInstall, LPCWSTR szComponent,
1462 DWORD dwIndex, INSTALLSTATE iState,
1463 LPWSTR lpDriveBuf, DWORD *pcchDriveBuf,
1464 int *piCost, int *pTempCost)
1466 FIXME("(%d, %s, %d, %d, %p, %p, %p %p): stub!\n", hInstall,
1467 debugstr_w(szComponent), dwIndex, iState, lpDriveBuf,
1468 pcchDriveBuf, piCost, pTempCost);
1470 return ERROR_NO_MORE_ITEMS;
1473 UINT WINAPI MsiQueryComponentStateA(LPCSTR szProductCode,
1474 LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1475 LPCSTR szComponent, INSTALLSTATE *pdwState)
1477 LPWSTR prodcode = NULL, usersid = NULL, comp = NULL;
1480 TRACE("(%s, %s, %d, %s, %p)\n", debugstr_a(szProductCode),
1481 debugstr_a(szUserSid), dwContext, debugstr_a(szComponent), pdwState);
1483 if (szProductCode && !(prodcode = strdupAtoW(szProductCode)))
1484 return ERROR_OUTOFMEMORY;
1486 if (szUserSid && !(usersid = strdupAtoW(szUserSid)))
1487 return ERROR_OUTOFMEMORY;
1489 if (szComponent && !(comp = strdupAtoW(szComponent)))
1490 return ERROR_OUTOFMEMORY;
1492 r = MsiQueryComponentStateW(prodcode, usersid, dwContext, comp, pdwState);
1501 static BOOL msi_comp_find_prod_key(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
1506 r = MSIREG_OpenProductKey(prodcode, NULL, context, &hkey, FALSE);
1508 return (r == ERROR_SUCCESS);
1511 static BOOL msi_comp_find_package(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
1519 static const WCHAR local_package[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
1520 static const WCHAR managed_local_package[] = {
1521 'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0
1524 r = MSIREG_OpenInstallProps(prodcode, context, NULL, &hkey, FALSE);
1525 if (r != ERROR_SUCCESS)
1528 if (context == MSIINSTALLCONTEXT_USERMANAGED)
1529 package = managed_local_package;
1531 package = local_package;
1534 res = RegQueryValueExW(hkey, package, NULL, NULL, NULL, &sz);
1537 return (res == ERROR_SUCCESS);
1540 static BOOL msi_comp_find_prodcode(LPWSTR squished_pc,
1541 MSIINSTALLCONTEXT context,
1542 LPCWSTR comp, LPWSTR val, DWORD *sz)
1548 if (context == MSIINSTALLCONTEXT_MACHINE)
1549 r = MSIREG_OpenUserDataComponentKey(comp, szLocalSid, &hkey, FALSE);
1551 r = MSIREG_OpenUserDataComponentKey(comp, NULL, &hkey, FALSE);
1553 if (r != ERROR_SUCCESS)
1556 res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, (BYTE *)val, sz);
1557 if (res != ERROR_SUCCESS)
1564 UINT WINAPI MsiQueryComponentStateW(LPCWSTR szProductCode,
1565 LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1566 LPCWSTR szComponent, INSTALLSTATE *pdwState)
1568 WCHAR squished_pc[GUID_SIZE];
1569 WCHAR val[MAX_PATH];
1573 TRACE("(%s, %s, %d, %s, %p)\n", debugstr_w(szProductCode),
1574 debugstr_w(szUserSid), dwContext, debugstr_w(szComponent), pdwState);
1576 if (!pdwState || !szComponent)
1577 return ERROR_INVALID_PARAMETER;
1579 if (!szProductCode || !*szProductCode || lstrlenW(szProductCode) != GUID_SIZE - 1)
1580 return ERROR_INVALID_PARAMETER;
1582 if (!squash_guid(szProductCode, squished_pc))
1583 return ERROR_INVALID_PARAMETER;
1585 found = msi_comp_find_prod_key(szProductCode, dwContext);
1587 if (!msi_comp_find_package(szProductCode, dwContext))
1591 *pdwState = INSTALLSTATE_UNKNOWN;
1592 return ERROR_UNKNOWN_COMPONENT;
1595 return ERROR_UNKNOWN_PRODUCT;
1598 *pdwState = INSTALLSTATE_UNKNOWN;
1601 if (!msi_comp_find_prodcode(squished_pc, dwContext, szComponent, val, &sz))
1602 return ERROR_UNKNOWN_COMPONENT;
1605 *pdwState = INSTALLSTATE_NOTUSED;
1608 if (lstrlenW(val) > 2 &&
1609 val[0] >= '0' && val[0] <= '9' && val[1] >= '0' && val[1] <= '9')
1611 *pdwState = INSTALLSTATE_SOURCE;
1614 *pdwState = INSTALLSTATE_LOCAL;
1617 return ERROR_SUCCESS;
1620 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
1622 LPWSTR szwProduct = NULL;
1627 szwProduct = strdupAtoW( szProduct );
1629 return ERROR_OUTOFMEMORY;
1631 r = MsiQueryProductStateW( szwProduct );
1632 msi_free( szwProduct );
1636 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
1638 MSIINSTALLCONTEXT context = MSIINSTALLCONTEXT_USERUNMANAGED;
1639 INSTALLSTATE state = INSTALLSTATE_ADVERTISED;
1640 HKEY prodkey = 0, userdata = 0;
1644 static const WCHAR szWindowsInstaller[] = {
1645 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
1647 TRACE("%s\n", debugstr_w(szProduct));
1649 if (!szProduct || !*szProduct)
1650 return INSTALLSTATE_INVALIDARG;
1652 if (lstrlenW(szProduct) != GUID_SIZE - 1)
1653 return INSTALLSTATE_INVALIDARG;
1655 if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1656 &prodkey, FALSE) != ERROR_SUCCESS &&
1657 MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
1658 &prodkey, FALSE) != ERROR_SUCCESS &&
1659 MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
1660 &prodkey, FALSE) == ERROR_SUCCESS)
1662 context = MSIINSTALLCONTEXT_MACHINE;
1665 r = MSIREG_OpenInstallProps(szProduct, context, NULL, &userdata, FALSE);
1666 if (r != ERROR_SUCCESS)
1669 if (!msi_reg_get_val_dword(userdata, szWindowsInstaller, &val))
1673 state = INSTALLSTATE_DEFAULT;
1675 state = INSTALLSTATE_UNKNOWN;
1680 state = INSTALLSTATE_UNKNOWN;
1683 state = INSTALLSTATE_ABSENT;
1686 RegCloseKey(prodkey);
1687 RegCloseKey(userdata);
1691 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
1693 INSTALLUILEVEL old = gUILevel;
1694 HWND oldwnd = gUIhwnd;
1696 TRACE("%08x %p\n", dwUILevel, phWnd);
1698 gUILevel = dwUILevel;
1707 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
1708 DWORD dwMessageFilter, LPVOID pvContext)
1710 INSTALLUI_HANDLERA prev = gUIHandlerA;
1712 TRACE("%p %x %p\n",puiHandler, dwMessageFilter,pvContext);
1713 gUIHandlerA = puiHandler;
1714 gUIFilter = dwMessageFilter;
1715 gUIContext = pvContext;
1720 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
1721 DWORD dwMessageFilter, LPVOID pvContext)
1723 INSTALLUI_HANDLERW prev = gUIHandlerW;
1725 TRACE("%p %x %p\n",puiHandler,dwMessageFilter,pvContext);
1726 gUIHandlerW = puiHandler;
1727 gUIFilter = dwMessageFilter;
1728 gUIContext = pvContext;
1733 /******************************************************************
1734 * MsiLoadStringW [MSI.@]
1736 * Loads a string from MSI's string resources.
1740 * handle [I] only -1 is handled currently
1741 * id [I] id of the string to be loaded
1742 * lpBuffer [O] buffer for the string to be written to
1743 * nBufferMax [I] maximum size of the buffer in characters
1744 * lang [I] the preferred language for the string
1748 * If successful, this function returns the language id of the string loaded
1749 * If the function fails, the function returns zero.
1753 * The type of the first parameter is unknown. LoadString's prototype
1754 * suggests that it might be a module handle. I have made it an MSI handle
1755 * for starters, as -1 is an invalid MSI handle, but not an invalid module
1756 * handle. Maybe strings can be stored in an MSI database somehow.
1758 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
1759 int nBufferMax, LANGID lang )
1766 TRACE("%d %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
1769 FIXME("don't know how to deal with handle = %08x\n", handle);
1772 lang = GetUserDefaultLangID();
1774 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
1778 hResData = LoadResource( msi_hInstance, hres );
1781 p = LockResource( hResData );
1785 for (i = 0; i < (id&0xf); i++)
1789 if( nBufferMax <= len )
1792 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
1793 lpBuffer[ len ] = 0;
1795 TRACE("found -> %s\n", debugstr_w(lpBuffer));
1800 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
1801 int nBufferMax, LANGID lang )
1807 bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
1808 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
1811 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
1812 if( len <= nBufferMax )
1813 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
1814 lpBuffer, nBufferMax, NULL, NULL );
1822 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
1825 char szProduct[GUID_SIZE];
1827 TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
1829 if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
1830 return INSTALLSTATE_UNKNOWN;
1832 return MsiGetComponentPathA( szProduct, szComponent, lpPathBuf, pcchBuf );
1835 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
1838 WCHAR szProduct[GUID_SIZE];
1840 TRACE("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
1842 if (MsiGetProductCodeW( szComponent, szProduct ) != ERROR_SUCCESS)
1843 return INSTALLSTATE_UNKNOWN;
1845 return MsiGetComponentPathW( szProduct, szComponent, lpPathBuf, pcchBuf );
1848 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
1849 WORD wLanguageId, DWORD f)
1851 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_a(lpText), debugstr_a(lpCaption),
1852 uType, wLanguageId, f);
1853 return MessageBoxExA(hWnd,lpText,lpCaption,uType,wLanguageId);
1856 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
1857 WORD wLanguageId, DWORD f)
1859 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_w(lpText), debugstr_w(lpCaption),
1860 uType, wLanguageId, f);
1861 return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId);
1864 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
1865 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
1866 LPDWORD pcchPathBuf )
1868 FIXME("%s %s %08x %08x %p %p\n", debugstr_a(szAssemblyName),
1869 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
1871 return ERROR_CALL_NOT_IMPLEMENTED;
1874 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
1875 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
1876 LPDWORD pcchPathBuf )
1878 FIXME("%s %s %08x %08x %p %p\n", debugstr_w(szAssemblyName),
1879 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
1881 return ERROR_CALL_NOT_IMPLEMENTED;
1884 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
1885 LPSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs )
1887 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
1888 return ERROR_CALL_NOT_IMPLEMENTED;
1891 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
1892 LPWSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs )
1894 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
1895 return ERROR_CALL_NOT_IMPLEMENTED;
1898 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
1899 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData,
1900 LPDWORD pcbHashData)
1902 FIXME("%s %08x %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
1903 ppcCertContext, pbHashData, pcbHashData);
1904 return ERROR_CALL_NOT_IMPLEMENTED;
1907 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
1908 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData,
1909 LPDWORD pcbHashData)
1911 FIXME("%s %08x %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
1912 ppcCertContext, pbHashData, pcbHashData);
1913 return ERROR_CALL_NOT_IMPLEMENTED;
1916 /******************************************************************
1917 * MsiGetProductPropertyA [MSI.@]
1919 UINT WINAPI MsiGetProductPropertyA(MSIHANDLE hProduct, LPCSTR szProperty,
1920 LPSTR szValue, LPDWORD pccbValue)
1922 LPWSTR prop = NULL, val = NULL;
1926 TRACE("(%d, %s, %p, %p)\n", hProduct, debugstr_a(szProperty),
1927 szValue, pccbValue);
1929 if (szValue && !pccbValue)
1930 return ERROR_INVALID_PARAMETER;
1932 if (szProperty) prop = strdupAtoW(szProperty);
1935 r = MsiGetProductPropertyW(hProduct, prop, NULL, &len);
1936 if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
1939 if (r == ERROR_SUCCESS)
1941 if (szValue) *szValue = '\0';
1942 if (pccbValue) *pccbValue = 0;
1946 val = msi_alloc(++len * sizeof(WCHAR));
1949 r = ERROR_OUTOFMEMORY;
1953 r = MsiGetProductPropertyW(hProduct, prop, val, &len);
1954 if (r != ERROR_SUCCESS)
1957 len = WideCharToMultiByte(CP_ACP, 0, val, -1, NULL, 0, NULL, NULL);
1960 WideCharToMultiByte(CP_ACP, 0, val, -1, szValue,
1961 *pccbValue, NULL, NULL);
1965 if (len > *pccbValue)
1966 r = ERROR_MORE_DATA;
1968 *pccbValue = len - 1;
1978 /******************************************************************
1979 * MsiGetProductPropertyW [MSI.@]
1981 UINT WINAPI MsiGetProductPropertyW(MSIHANDLE hProduct, LPCWSTR szProperty,
1982 LPWSTR szValue, LPDWORD pccbValue)
1984 MSIPACKAGE *package;
1985 MSIQUERY *view = NULL;
1986 MSIRECORD *rec = NULL;
1990 static const WCHAR query[] = {
1991 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
1992 '`','P','r','o','p','e','r','t','y','`',' ','W','H','E','R','E',' ',
1993 '`','P','r','o','p','e','r','t','y','`','=','\'','%','s','\'',0};
1995 TRACE("(%d, %s, %p, %p)\n", hProduct, debugstr_w(szProperty),
1996 szValue, pccbValue);
1999 return ERROR_INVALID_PARAMETER;
2001 if (szValue && !pccbValue)
2002 return ERROR_INVALID_PARAMETER;
2004 package = msihandle2msiinfo(hProduct, MSIHANDLETYPE_PACKAGE);
2006 return ERROR_INVALID_HANDLE;
2008 r = MSI_OpenQuery(package->db, &view, query, szProperty);
2009 if (r != ERROR_SUCCESS)
2012 r = MSI_ViewExecute(view, 0);
2013 if (r != ERROR_SUCCESS)
2016 r = MSI_ViewFetch(view, &rec);
2017 if (r != ERROR_SUCCESS)
2020 val = MSI_RecordGetString(rec, 2);
2024 if (lstrlenW(val) >= *pccbValue)
2026 lstrcpynW(szValue, val, *pccbValue);
2027 *pccbValue = lstrlenW(val);
2028 r = ERROR_MORE_DATA;
2032 lstrcpyW(szValue, val);
2033 *pccbValue = lstrlenW(val);
2040 MSI_ViewClose(view);
2041 msiobj_release(&view->hdr);
2042 if (rec) msiobj_release(&rec->hdr);
2047 if (szValue) *szValue = '\0';
2048 if (pccbValue) *pccbValue = 0;
2055 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
2058 LPWSTR szPack = NULL;
2060 TRACE("%s\n", debugstr_a(szPackage) );
2064 szPack = strdupAtoW( szPackage );
2066 return ERROR_OUTOFMEMORY;
2069 r = MsiVerifyPackageW( szPack );
2076 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
2081 TRACE("%s\n", debugstr_w(szPackage) );
2083 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
2084 MsiCloseHandle( handle );
2089 static INSTALLSTATE MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
2090 awstring* lpPathBuf, LPDWORD pcchBuf)
2092 WCHAR squished_pc[GUID_SIZE];
2093 WCHAR squished_comp[GUID_SIZE];
2099 static const WCHAR wininstaller[] = {
2100 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
2102 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
2103 debugstr_w(szComponent), lpPathBuf->str.w, pcchBuf);
2105 if (!szProduct || !szComponent)
2106 return INSTALLSTATE_INVALIDARG;
2108 if (lpPathBuf->str.w && !pcchBuf)
2109 return INSTALLSTATE_INVALIDARG;
2111 if (!squash_guid(szProduct, squished_pc) ||
2112 !squash_guid(szComponent, squished_comp))
2113 return INSTALLSTATE_INVALIDARG;
2115 state = INSTALLSTATE_UNKNOWN;
2117 if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS ||
2118 MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
2120 path = msi_reg_get_val_str(hkey, squished_pc);
2123 state = INSTALLSTATE_ABSENT;
2125 if ((MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE, NULL,
2126 &hkey, FALSE) == ERROR_SUCCESS ||
2127 MSIREG_OpenUserDataProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
2128 NULL, &hkey, FALSE) == ERROR_SUCCESS) &&
2129 msi_reg_get_val_dword(hkey, wininstaller, &version) &&
2130 GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
2133 state = INSTALLSTATE_LOCAL;
2137 if (state != INSTALLSTATE_LOCAL &&
2138 (MSIREG_OpenProductKey(szProduct, NULL,
2139 MSIINSTALLCONTEXT_USERUNMANAGED,
2140 &hkey, FALSE) == ERROR_SUCCESS ||
2141 MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
2142 &hkey, FALSE) == ERROR_SUCCESS))
2146 if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS ||
2147 MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
2150 path = msi_reg_get_val_str(hkey, squished_pc);
2153 state = INSTALLSTATE_ABSENT;
2155 if (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
2156 state = INSTALLSTATE_LOCAL;
2161 return INSTALLSTATE_UNKNOWN;
2163 if (state == INSTALLSTATE_LOCAL && !*path)
2164 state = INSTALLSTATE_NOTUSED;
2166 msi_strcpy_to_awstring(path, lpPathBuf, pcchBuf);
2171 /******************************************************************
2172 * MsiGetComponentPathW [MSI.@]
2174 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
2175 LPWSTR lpPathBuf, LPDWORD pcchBuf)
2179 path.unicode = TRUE;
2180 path.str.w = lpPathBuf;
2182 return MSI_GetComponentPath( szProduct, szComponent, &path, pcchBuf );
2185 /******************************************************************
2186 * MsiGetComponentPathA [MSI.@]
2188 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
2189 LPSTR lpPathBuf, LPDWORD pcchBuf)
2191 LPWSTR szwProduct, szwComponent = NULL;
2192 INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
2195 szwProduct = strdupAtoW( szProduct );
2196 if( szProduct && !szwProduct)
2199 szwComponent = strdupAtoW( szComponent );
2200 if( szComponent && !szwComponent )
2203 path.unicode = FALSE;
2204 path.str.a = lpPathBuf;
2206 r = MSI_GetComponentPath( szwProduct, szwComponent, &path, pcchBuf );
2209 msi_free( szwProduct );
2210 msi_free( szwComponent );
2215 /******************************************************************
2216 * MsiQueryFeatureStateA [MSI.@]
2218 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
2220 LPWSTR szwProduct = NULL, szwFeature= NULL;
2221 INSTALLSTATE rc = INSTALLSTATE_UNKNOWN;
2223 szwProduct = strdupAtoW( szProduct );
2224 if ( szProduct && !szwProduct )
2227 szwFeature = strdupAtoW( szFeature );
2228 if ( szFeature && !szwFeature )
2231 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
2234 msi_free( szwProduct);
2235 msi_free( szwFeature);
2240 /******************************************************************
2241 * MsiQueryFeatureStateW [MSI.@]
2243 * Checks the state of a feature
2246 * szProduct [I] Product's GUID string
2247 * szFeature [I] Feature's GUID string
2250 * INSTALLSTATE_LOCAL Feature is installed and usable
2251 * INSTALLSTATE_ABSENT Feature is absent
2252 * INSTALLSTATE_ADVERTISED Feature should be installed on demand
2253 * INSTALLSTATE_UNKNOWN An error occurred
2254 * INSTALLSTATE_INVALIDARG One of the GUIDs was invalid
2257 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
2259 WCHAR squishProduct[33], comp[GUID_SIZE];
2261 LPWSTR components, p, parent_feature, path;
2265 BOOL missing = FALSE;
2266 BOOL machine = FALSE;
2267 BOOL source = FALSE;
2269 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
2271 if (!szProduct || !szFeature)
2272 return INSTALLSTATE_INVALIDARG;
2274 if (!squash_guid( szProduct, squishProduct ))
2275 return INSTALLSTATE_INVALIDARG;
2277 if (MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
2278 &hkey, FALSE) != ERROR_SUCCESS &&
2279 MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
2280 &hkey, FALSE) != ERROR_SUCCESS)
2282 rc = MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
2284 if (rc != ERROR_SUCCESS)
2285 return INSTALLSTATE_UNKNOWN;
2290 parent_feature = msi_reg_get_val_str( hkey, szFeature );
2293 if (!parent_feature)
2294 return INSTALLSTATE_UNKNOWN;
2296 r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
2297 msi_free(parent_feature);
2298 if (r == INSTALLSTATE_ABSENT)
2302 rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
2303 MSIINSTALLCONTEXT_MACHINE,
2306 rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
2307 MSIINSTALLCONTEXT_USERUNMANAGED,
2310 if (rc != ERROR_SUCCESS)
2311 return INSTALLSTATE_ADVERTISED;
2313 components = msi_reg_get_val_str( hkey, szFeature );
2316 TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
2319 return INSTALLSTATE_ADVERTISED;
2321 for( p = components; *p && *p != 2 ; p += 20)
2323 if (!decode_base85_guid( p, &guid ))
2325 if (p != components)
2328 msi_free(components);
2329 return INSTALLSTATE_BADCONFIG;
2332 StringFromGUID2(&guid, comp, GUID_SIZE);
2335 rc = MSIREG_OpenUserDataComponentKey(comp, szLocalSid, &hkey, FALSE);
2337 rc = MSIREG_OpenUserDataComponentKey(comp, NULL, &hkey, FALSE);
2339 if (rc != ERROR_SUCCESS)
2341 msi_free(components);
2342 return INSTALLSTATE_ADVERTISED;
2345 path = msi_reg_get_val_str(hkey, squishProduct);
2348 else if (lstrlenW(path) > 2 &&
2349 path[0] >= '0' && path[0] <= '9' &&
2350 path[1] >= '0' && path[1] <= '9')
2358 TRACE("%s %s -> %d\n", debugstr_w(szProduct), debugstr_w(szFeature), r);
2359 msi_free(components);
2362 return INSTALLSTATE_ADVERTISED;
2365 return INSTALLSTATE_SOURCE;
2367 return INSTALLSTATE_LOCAL;
2370 /******************************************************************
2371 * MsiGetFileVersionA [MSI.@]
2373 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
2374 LPDWORD pcchVersionBuf, LPSTR lpLangBuf, LPDWORD pcchLangBuf)
2376 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
2377 UINT ret = ERROR_OUTOFMEMORY;
2379 if ((lpVersionBuf && !pcchVersionBuf) ||
2380 (lpLangBuf && !pcchLangBuf))
2381 return ERROR_INVALID_PARAMETER;
2385 szwFilePath = strdupAtoW( szFilePath );
2390 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
2392 lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
2393 if( !lpwVersionBuff )
2397 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
2399 lpwLangBuff = msi_alloc(*pcchLangBuf*sizeof(WCHAR));
2404 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
2405 lpwLangBuff, pcchLangBuf);
2407 if( (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && lpwVersionBuff )
2408 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
2409 lpVersionBuf, *pcchVersionBuf + 1, NULL, NULL);
2410 if( (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && lpwLangBuff )
2411 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
2412 lpLangBuf, *pcchLangBuf + 1, NULL, NULL);
2415 msi_free(szwFilePath);
2416 msi_free(lpwVersionBuff);
2417 msi_free(lpwLangBuff);
2422 /******************************************************************
2423 * MsiGetFileVersionW [MSI.@]
2425 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
2426 LPDWORD pcchVersionBuf, LPWSTR lpLangBuf, LPDWORD pcchLangBuf)
2428 static const WCHAR szVersionResource[] = {'\\',0};
2429 static const WCHAR szVersionFormat[] = {
2430 '%','d','.','%','d','.','%','d','.','%','d',0};
2431 static const WCHAR szLangResource[] = {
2432 '\\','V','a','r','F','i','l','e','I','n','f','o','\\',
2433 'T','r','a','n','s','l','a','t','i','o','n',0};
2434 static const WCHAR szLangFormat[] = {'%','d',0};
2436 DWORD dwVerLen, gle;
2437 LPVOID lpVer = NULL;
2438 VS_FIXEDFILEINFO *ffi;
2443 TRACE("%s %p %d %p %d\n", debugstr_w(szFilePath),
2444 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
2445 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
2447 if ((lpVersionBuf && !pcchVersionBuf) ||
2448 (lpLangBuf && !pcchLangBuf))
2449 return ERROR_INVALID_PARAMETER;
2451 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
2454 gle = GetLastError();
2455 if (gle == ERROR_BAD_PATHNAME)
2456 return ERROR_FILE_NOT_FOUND;
2457 else if (gle == ERROR_RESOURCE_DATA_NOT_FOUND)
2458 return ERROR_FILE_INVALID;
2463 lpVer = msi_alloc(dwVerLen);
2466 ret = ERROR_OUTOFMEMORY;
2470 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
2472 ret = GetLastError();
2478 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
2481 wsprintfW(tmp, szVersionFormat,
2482 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
2483 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
2484 if (lpVersionBuf) lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
2486 if (strlenW(tmp) >= *pcchVersionBuf)
2487 ret = ERROR_MORE_DATA;
2489 *pcchVersionBuf = lstrlenW(tmp);
2493 if (lpVersionBuf) *lpVersionBuf = 0;
2494 *pcchVersionBuf = 0;
2500 if (VerQueryValueW(lpVer, szLangResource, (LPVOID*)&lang, &puLen) &&
2503 wsprintfW(tmp, szLangFormat, *lang);
2504 if (lpLangBuf) lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
2506 if (strlenW(tmp) >= *pcchLangBuf)
2507 ret = ERROR_MORE_DATA;
2509 *pcchLangBuf = lstrlenW(tmp);
2513 if (lpLangBuf) *lpLangBuf = 0;
2523 /***********************************************************************
2524 * MsiGetFeatureUsageW [MSI.@]
2526 UINT WINAPI MsiGetFeatureUsageW( LPCWSTR szProduct, LPCWSTR szFeature,
2527 LPDWORD pdwUseCount, LPWORD pwDateUsed )
2529 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
2530 pdwUseCount, pwDateUsed);
2531 return ERROR_CALL_NOT_IMPLEMENTED;
2534 /***********************************************************************
2535 * MsiGetFeatureUsageA [MSI.@]
2537 UINT WINAPI MsiGetFeatureUsageA( LPCSTR szProduct, LPCSTR szFeature,
2538 LPDWORD pdwUseCount, LPWORD pwDateUsed )
2540 LPWSTR prod = NULL, feat = NULL;
2541 UINT ret = ERROR_OUTOFMEMORY;
2543 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
2544 pdwUseCount, pwDateUsed);
2546 prod = strdupAtoW( szProduct );
2547 if (szProduct && !prod)
2550 feat = strdupAtoW( szFeature );
2551 if (szFeature && !feat)
2554 ret = MsiGetFeatureUsageW( prod, feat, pdwUseCount, pwDateUsed );
2563 /***********************************************************************
2564 * MsiUseFeatureExW [MSI.@]
2566 INSTALLSTATE WINAPI MsiUseFeatureExW( LPCWSTR szProduct, LPCWSTR szFeature,
2567 DWORD dwInstallMode, DWORD dwReserved )
2571 TRACE("%s %s %i %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
2572 dwInstallMode, dwReserved);
2574 state = MsiQueryFeatureStateW( szProduct, szFeature );
2577 return INSTALLSTATE_INVALIDARG;
2579 if (state == INSTALLSTATE_LOCAL && dwInstallMode != INSTALLMODE_NODETECTION)
2581 FIXME("mark product %s feature %s as used\n",
2582 debugstr_w(szProduct), debugstr_w(szFeature) );
2588 /***********************************************************************
2589 * MsiUseFeatureExA [MSI.@]
2591 INSTALLSTATE WINAPI MsiUseFeatureExA( LPCSTR szProduct, LPCSTR szFeature,
2592 DWORD dwInstallMode, DWORD dwReserved )
2594 INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
2595 LPWSTR prod = NULL, feat = NULL;
2597 TRACE("%s %s %i %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
2598 dwInstallMode, dwReserved);
2600 prod = strdupAtoW( szProduct );
2601 if (szProduct && !prod)
2604 feat = strdupAtoW( szFeature );
2605 if (szFeature && !feat)
2608 ret = MsiUseFeatureExW( prod, feat, dwInstallMode, dwReserved );
2617 /***********************************************************************
2618 * MsiUseFeatureW [MSI.@]
2620 INSTALLSTATE WINAPI MsiUseFeatureW( LPCWSTR szProduct, LPCWSTR szFeature )
2622 return MsiUseFeatureExW(szProduct, szFeature, 0, 0);
2625 /***********************************************************************
2626 * MsiUseFeatureA [MSI.@]
2628 INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
2630 return MsiUseFeatureExA(szProduct, szFeature, 0, 0);
2633 /***********************************************************************
2634 * MSI_ProvideQualifiedComponentEx [internal]
2636 static UINT MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
2637 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
2638 DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
2639 LPDWORD pcchPathBuf)
2641 WCHAR product[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1],
2642 feature[MAX_FEATURE_CHARS+1];
2648 TRACE("%s %s %i %s %i %i %p %p\n", debugstr_w(szComponent),
2649 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
2650 Unused1, Unused2, lpPathBuf, pcchPathBuf);
2652 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
2653 if (rc != ERROR_SUCCESS)
2654 return ERROR_INDEX_ABSENT;
2656 info = msi_reg_get_val_str( hkey, szQualifier );
2660 return ERROR_INDEX_ABSENT;
2662 MsiDecomposeDescriptorW(info, product, feature, component, &sz);
2665 rc = MSI_GetComponentPath(product, component, lpPathBuf, pcchPathBuf);
2667 rc = MSI_GetComponentPath(szProduct, component, lpPathBuf, pcchPathBuf);
2671 if (rc != INSTALLSTATE_LOCAL)
2672 return ERROR_FILE_NOT_FOUND;
2674 return ERROR_SUCCESS;
2677 /***********************************************************************
2678 * MsiProvideQualifiedComponentExW [MSI.@]
2680 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
2681 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
2682 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
2683 LPDWORD pcchPathBuf)
2687 path.unicode = TRUE;
2688 path.str.w = lpPathBuf;
2690 return MSI_ProvideQualifiedComponentEx(szComponent, szQualifier,
2691 dwInstallMode, szProduct, Unused1, Unused2, &path, pcchPathBuf);
2694 /***********************************************************************
2695 * MsiProvideQualifiedComponentExA [MSI.@]
2697 UINT WINAPI MsiProvideQualifiedComponentExA(LPCSTR szComponent,
2698 LPCSTR szQualifier, DWORD dwInstallMode, LPCSTR szProduct,
2699 DWORD Unused1, DWORD Unused2, LPSTR lpPathBuf,
2700 LPDWORD pcchPathBuf)
2702 LPWSTR szwComponent, szwQualifier = NULL, szwProduct = NULL;
2703 UINT r = ERROR_OUTOFMEMORY;
2706 TRACE("%s %s %u %s %u %u %p %p\n", debugstr_a(szComponent),
2707 debugstr_a(szQualifier), dwInstallMode, debugstr_a(szProduct),
2708 Unused1, Unused2, lpPathBuf, pcchPathBuf);
2710 szwComponent = strdupAtoW( szComponent );
2711 if (szComponent && !szwComponent)
2714 szwQualifier = strdupAtoW( szQualifier );
2715 if (szQualifier && !szwQualifier)
2718 szwProduct = strdupAtoW( szProduct );
2719 if (szProduct && !szwProduct)
2722 path.unicode = FALSE;
2723 path.str.a = lpPathBuf;
2725 r = MSI_ProvideQualifiedComponentEx(szwComponent, szwQualifier,
2726 dwInstallMode, szwProduct, Unused1,
2727 Unused2, &path, pcchPathBuf);
2729 msi_free(szwProduct);
2730 msi_free(szwComponent);
2731 msi_free(szwQualifier);
2736 /***********************************************************************
2737 * MsiProvideQualifiedComponentW [MSI.@]
2739 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
2740 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
2741 LPDWORD pcchPathBuf)
2743 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
2744 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
2747 /***********************************************************************
2748 * MsiProvideQualifiedComponentA [MSI.@]
2750 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
2751 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
2752 LPDWORD pcchPathBuf)
2754 return MsiProvideQualifiedComponentExA(szComponent, szQualifier,
2755 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
2758 /***********************************************************************
2759 * MSI_GetUserInfo [internal]
2761 static USERINFOSTATE MSI_GetUserInfo(LPCWSTR szProduct,
2762 awstring *lpUserNameBuf, LPDWORD pcchUserNameBuf,
2763 awstring *lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2764 awstring *lpSerialBuf, LPDWORD pcchSerialBuf)
2766 WCHAR squished_pc[SQUISH_GUID_SIZE];
2767 LPWSTR user, org, serial;
2768 USERINFOSTATE state;
2773 static const WCHAR szEmpty[] = {0};
2775 TRACE("%s %p %p %p %p %p %p\n", debugstr_w(szProduct), lpUserNameBuf,
2776 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
2779 if (!szProduct || !squash_guid(szProduct, squished_pc))
2780 return USERINFOSTATE_INVALIDARG;
2782 if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
2783 &hkey, FALSE) != ERROR_SUCCESS &&
2784 MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2785 &hkey, FALSE) != ERROR_SUCCESS &&
2786 MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
2787 &hkey, FALSE) != ERROR_SUCCESS)
2789 return USERINFOSTATE_UNKNOWN;
2792 if (MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
2793 NULL, &props, FALSE) != ERROR_SUCCESS &&
2794 MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE,
2795 NULL, &props, FALSE) != ERROR_SUCCESS)
2798 return USERINFOSTATE_ABSENT;
2801 user = msi_reg_get_val_str(props, INSTALLPROPERTY_REGOWNERW);
2802 org = msi_reg_get_val_str(props, INSTALLPROPERTY_REGCOMPANYW);
2803 serial = msi_reg_get_val_str(props, INSTALLPROPERTY_PRODUCTIDW);
2804 state = USERINFOSTATE_ABSENT;
2810 state = USERINFOSTATE_PRESENT;
2812 if (pcchUserNameBuf)
2814 if (lpUserNameBuf && !user)
2816 (*pcchUserNameBuf)--;
2820 r = msi_strcpy_to_awstring(user, lpUserNameBuf, pcchUserNameBuf);
2821 if (r == ERROR_MORE_DATA)
2823 state = USERINFOSTATE_MOREDATA;
2831 if (!orgptr) orgptr = szEmpty;
2833 r = msi_strcpy_to_awstring(orgptr, lpOrgNameBuf, pcchOrgNameBuf);
2834 if (r == ERROR_MORE_DATA)
2836 state = USERINFOSTATE_MOREDATA;
2849 r = msi_strcpy_to_awstring(serial, lpSerialBuf, pcchSerialBuf);
2850 if (r == ERROR_MORE_DATA)
2851 state = USERINFOSTATE_MOREDATA;
2862 /***********************************************************************
2863 * MsiGetUserInfoW [MSI.@]
2865 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct,
2866 LPWSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
2867 LPWSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2868 LPWSTR lpSerialBuf, LPDWORD pcchSerialBuf)
2870 awstring user, org, serial;
2872 if ((lpUserNameBuf && !pcchUserNameBuf) ||
2873 (lpOrgNameBuf && !pcchOrgNameBuf) ||
2874 (lpSerialBuf && !pcchSerialBuf))
2875 return USERINFOSTATE_INVALIDARG;
2877 user.unicode = TRUE;
2878 user.str.w = lpUserNameBuf;
2880 org.str.w = lpOrgNameBuf;
2881 serial.unicode = TRUE;
2882 serial.str.w = lpSerialBuf;
2884 return MSI_GetUserInfo( szProduct, &user, pcchUserNameBuf,
2885 &org, pcchOrgNameBuf,
2886 &serial, pcchSerialBuf );
2889 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct,
2890 LPSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
2891 LPSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2892 LPSTR lpSerialBuf, LPDWORD pcchSerialBuf)
2894 awstring user, org, serial;
2898 if ((lpUserNameBuf && !pcchUserNameBuf) ||
2899 (lpOrgNameBuf && !pcchOrgNameBuf) ||
2900 (lpSerialBuf && !pcchSerialBuf))
2901 return USERINFOSTATE_INVALIDARG;
2903 prod = strdupAtoW( szProduct );
2904 if (szProduct && !prod)
2905 return ERROR_OUTOFMEMORY;
2907 user.unicode = FALSE;
2908 user.str.a = lpUserNameBuf;
2909 org.unicode = FALSE;
2910 org.str.a = lpOrgNameBuf;
2911 serial.unicode = FALSE;
2912 serial.str.a = lpSerialBuf;
2914 r = MSI_GetUserInfo( prod, &user, pcchUserNameBuf,
2915 &org, pcchOrgNameBuf,
2916 &serial, pcchSerialBuf );
2923 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
2927 MSIPACKAGE *package;
2928 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
2930 TRACE("(%s)\n",debugstr_w(szProduct));
2932 rc = MsiOpenProductW(szProduct,&handle);
2933 if (rc != ERROR_SUCCESS)
2934 return ERROR_INVALID_PARAMETER;
2936 /* MsiCollectUserInfo cannot be called from a custom action. */
2937 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
2939 return ERROR_CALL_NOT_IMPLEMENTED;
2941 rc = ACTION_PerformUIAction(package, szFirstRun, -1);
2942 msiobj_release( &package->hdr );
2944 MsiCloseHandle(handle);
2949 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
2953 MSIPACKAGE *package;
2954 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
2956 TRACE("(%s)\n",debugstr_a(szProduct));
2958 rc = MsiOpenProductA(szProduct,&handle);
2959 if (rc != ERROR_SUCCESS)
2960 return ERROR_INVALID_PARAMETER;
2962 /* MsiCollectUserInfo cannot be called from a custom action. */
2963 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
2965 return ERROR_CALL_NOT_IMPLEMENTED;
2967 rc = ACTION_PerformUIAction(package, szFirstRun, -1);
2968 msiobj_release( &package->hdr );
2970 MsiCloseHandle(handle);
2975 /***********************************************************************
2976 * MsiConfigureFeatureA [MSI.@]
2978 UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
2980 LPWSTR prod, feat = NULL;
2981 UINT r = ERROR_OUTOFMEMORY;
2983 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
2985 prod = strdupAtoW( szProduct );
2986 if (szProduct && !prod)
2989 feat = strdupAtoW( szFeature );
2990 if (szFeature && !feat)
2993 r = MsiConfigureFeatureW(prod, feat, eInstallState);
3002 /***********************************************************************
3003 * MsiConfigureFeatureW [MSI.@]
3005 UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
3007 static const WCHAR szCostInit[] = { 'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0 };
3008 MSIPACKAGE *package = NULL;
3010 WCHAR sourcepath[MAX_PATH], filename[MAX_PATH];
3013 TRACE("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
3015 if (!szProduct || !szFeature)
3016 return ERROR_INVALID_PARAMETER;
3018 switch (eInstallState)
3020 case INSTALLSTATE_DEFAULT:
3021 /* FIXME: how do we figure out the default location? */
3022 eInstallState = INSTALLSTATE_LOCAL;
3024 case INSTALLSTATE_LOCAL:
3025 case INSTALLSTATE_SOURCE:
3026 case INSTALLSTATE_ABSENT:
3027 case INSTALLSTATE_ADVERTISED:
3030 return ERROR_INVALID_PARAMETER;
3033 r = MSI_OpenProductW( szProduct, &package );
3034 if (r != ERROR_SUCCESS)
3037 sz = sizeof(sourcepath);
3038 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3039 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
3041 sz = sizeof(filename);
3042 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3043 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
3045 lstrcatW( sourcepath, filename );
3047 MsiSetInternalUI( INSTALLUILEVEL_BASIC, NULL );
3049 r = ACTION_PerformUIAction( package, szCostInit, -1 );
3050 if (r != ERROR_SUCCESS)
3053 r = MSI_SetFeatureStateW( package, szFeature, eInstallState);
3054 if (r != ERROR_SUCCESS)
3057 r = MSI_InstallPackage( package, sourcepath, NULL );
3060 msiobj_release( &package->hdr );
3065 /***********************************************************************
3066 * MsiCreateAndVerifyInstallerDirectory [MSI.@]
3068 * Notes: undocumented
3070 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
3072 WCHAR path[MAX_PATH];
3074 TRACE("%d\n", dwReserved);
3078 FIXME("dwReserved=%d\n", dwReserved);
3079 return ERROR_INVALID_PARAMETER;
3082 if (!GetWindowsDirectoryW(path, MAX_PATH))
3083 return ERROR_FUNCTION_FAILED;
3085 lstrcatW(path, installerW);
3087 if (!CreateDirectoryW(path, NULL))
3088 return ERROR_FUNCTION_FAILED;
3090 return ERROR_SUCCESS;
3093 /***********************************************************************
3094 * MsiGetShortcutTargetA [MSI.@]
3096 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
3097 LPSTR szProductCode, LPSTR szFeatureId,
3098 LPSTR szComponentCode )
3101 const int len = MAX_FEATURE_CHARS+1;
3102 WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1];
3105 target = strdupAtoW( szShortcutTarget );
3106 if (szShortcutTarget && !target )
3107 return ERROR_OUTOFMEMORY;
3111 r = MsiGetShortcutTargetW( target, product, feature, component );
3113 if (r == ERROR_SUCCESS)
3115 WideCharToMultiByte( CP_ACP, 0, product, -1, szProductCode, len, NULL, NULL );
3116 WideCharToMultiByte( CP_ACP, 0, feature, -1, szFeatureId, len, NULL, NULL );
3117 WideCharToMultiByte( CP_ACP, 0, component, -1, szComponentCode, len, NULL, NULL );
3122 /***********************************************************************
3123 * MsiGetShortcutTargetW [MSI.@]
3125 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
3126 LPWSTR szProductCode, LPWSTR szFeatureId,
3127 LPWSTR szComponentCode )
3129 IShellLinkDataList *dl = NULL;
3130 IPersistFile *pf = NULL;
3131 LPEXP_DARWIN_LINK darwin = NULL;
3134 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget),
3135 szProductCode, szFeatureId, szComponentCode );
3137 init = CoInitialize(NULL);
3139 r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
3140 &IID_IPersistFile, (LPVOID*) &pf );
3141 if( SUCCEEDED( r ) )
3143 r = IPersistFile_Load( pf, szShortcutTarget,
3144 STGM_READ | STGM_SHARE_DENY_WRITE );
3145 if( SUCCEEDED( r ) )
3147 r = IPersistFile_QueryInterface( pf, &IID_IShellLinkDataList,
3149 if( SUCCEEDED( r ) )
3151 IShellLinkDataList_CopyDataBlock( dl, EXP_DARWIN_ID_SIG,
3153 IShellLinkDataList_Release( dl );
3156 IPersistFile_Release( pf );
3159 if (SUCCEEDED(init))
3162 TRACE("darwin = %p\n", darwin);
3169 ret = MsiDecomposeDescriptorW( darwin->szwDarwinID,
3170 szProductCode, szFeatureId, szComponentCode, &sz );
3171 LocalFree( darwin );
3175 return ERROR_FUNCTION_FAILED;
3178 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
3179 DWORD dwReinstallMode )
3181 MSIPACKAGE* package = NULL;
3183 WCHAR sourcepath[MAX_PATH];
3184 WCHAR filename[MAX_PATH];
3185 static const WCHAR szLogVerbose[] = {
3186 ' ','L','O','G','V','E','R','B','O','S','E',0 };
3187 static const WCHAR szInstalled[] = { 'I','n','s','t','a','l','l','e','d',0};
3188 static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
3189 static const WCHAR szReinstallMode[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
3190 static const WCHAR szOne[] = {'1',0};
3191 WCHAR reinstallmode[11];
3195 FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
3198 ptr = reinstallmode;
3200 if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
3202 if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
3204 if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
3206 if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
3208 if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
3210 if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
3212 if (dwReinstallMode & REINSTALLMODE_USERDATA)
3214 if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
3216 if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
3218 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
3222 sz = sizeof(sourcepath);
3223 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3224 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
3226 sz = sizeof(filename);
3227 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3228 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
3230 lstrcatW( sourcepath, filename );
3232 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
3233 r = MSI_OpenPackageW( sourcepath, &package );
3235 r = MSI_OpenProductW( szProduct, &package );
3237 if (r != ERROR_SUCCESS)
3240 MSI_SetPropertyW( package, szReinstallMode, reinstallmode );
3241 MSI_SetPropertyW( package, szInstalled, szOne );
3242 MSI_SetPropertyW( package, szLogVerbose, szOne );
3243 MSI_SetPropertyW( package, szReinstall, szFeature );
3245 r = MSI_InstallPackage( package, sourcepath, NULL );
3247 msiobj_release( &package->hdr );
3252 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
3253 DWORD dwReinstallMode )
3259 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
3262 wszProduct = strdupAtoW(szProduct);
3263 wszFeature = strdupAtoW(szFeature);
3265 rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
3267 msi_free(wszProduct);
3268 msi_free(wszFeature);
3275 unsigned int buf[4];
3276 unsigned char in[64];
3277 unsigned char digest[16];
3280 extern VOID WINAPI MD5Init( MD5_CTX *);
3281 extern VOID WINAPI MD5Update( MD5_CTX *, const unsigned char *, unsigned int );
3282 extern VOID WINAPI MD5Final( MD5_CTX *);
3284 /***********************************************************************
3285 * MsiGetFileHashW [MSI.@]
3287 UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions,
3288 PMSIFILEHASHINFO pHash )
3290 HANDLE handle, mapping;
3293 UINT r = ERROR_FUNCTION_FAILED;
3295 TRACE("%s %08x %p\n", debugstr_w(szFilePath), dwOptions, pHash );
3298 return ERROR_INVALID_PARAMETER;
3301 return ERROR_PATH_NOT_FOUND;
3304 return ERROR_INVALID_PARAMETER;
3306 return ERROR_INVALID_PARAMETER;
3307 if (pHash->dwFileHashInfoSize < sizeof *pHash)
3308 return ERROR_INVALID_PARAMETER;
3310 handle = CreateFileW( szFilePath, GENERIC_READ,
3311 FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL );
3312 if (handle == INVALID_HANDLE_VALUE)
3313 return ERROR_FILE_NOT_FOUND;
3315 length = GetFileSize( handle, NULL );
3317 mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
3320 p = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, length );
3326 MD5Update( &ctx, p, length );
3328 UnmapViewOfFile( p );
3330 memcpy( pHash->dwData, ctx.digest, sizeof pHash->dwData );
3333 CloseHandle( mapping );
3335 CloseHandle( handle );
3340 /***********************************************************************
3341 * MsiGetFileHashA [MSI.@]
3343 UINT WINAPI MsiGetFileHashA( LPCSTR szFilePath, DWORD dwOptions,
3344 PMSIFILEHASHINFO pHash )
3349 TRACE("%s %08x %p\n", debugstr_a(szFilePath), dwOptions, pHash );
3351 file = strdupAtoW( szFilePath );
3352 if (szFilePath && !file)
3353 return ERROR_OUTOFMEMORY;
3355 r = MsiGetFileHashW( file, dwOptions, pHash );
3360 /***********************************************************************
3361 * MsiAdvertiseScriptW [MSI.@]
3363 UINT WINAPI MsiAdvertiseScriptW( LPCWSTR szScriptFile, DWORD dwFlags,
3364 PHKEY phRegData, BOOL fRemoveItems )
3366 FIXME("%s %08x %p %d\n",
3367 debugstr_w( szScriptFile ), dwFlags, phRegData, fRemoveItems );
3368 return ERROR_CALL_NOT_IMPLEMENTED;
3371 /***********************************************************************
3372 * MsiAdvertiseScriptA [MSI.@]
3374 UINT WINAPI MsiAdvertiseScriptA( LPCSTR szScriptFile, DWORD dwFlags,
3375 PHKEY phRegData, BOOL fRemoveItems )
3377 FIXME("%s %08x %p %d\n",
3378 debugstr_a( szScriptFile ), dwFlags, phRegData, fRemoveItems );
3379 return ERROR_CALL_NOT_IMPLEMENTED;
3382 /***********************************************************************
3383 * MsiIsProductElevatedW [MSI.@]
3385 UINT WINAPI MsiIsProductElevatedW( LPCWSTR szProduct, BOOL *pfElevated )
3387 FIXME("%s %p - stub\n",
3388 debugstr_w( szProduct ), pfElevated );
3390 return ERROR_SUCCESS;
3393 /***********************************************************************
3394 * MsiIsProductElevatedA [MSI.@]
3396 UINT WINAPI MsiIsProductElevatedA( LPCSTR szProduct, BOOL *pfElevated )
3398 FIXME("%s %p - stub\n",
3399 debugstr_a( szProduct ), pfElevated );
3401 return ERROR_SUCCESS;
3404 /***********************************************************************
3405 * MsiSetExternalUIRecord [MSI.@]
3407 UINT WINAPI MsiSetExternalUIRecord( INSTALLUI_HANDLER_RECORD puiHandler,
3408 DWORD dwMessageFilter, LPVOID pvContext,
3409 PINSTALLUI_HANDLER_RECORD ppuiPrevHandler)
3411 FIXME("%p %08x %p %p\n", puiHandler, dwMessageFilter ,pvContext,
3413 return ERROR_CALL_NOT_IMPLEMENTED;
3416 /***********************************************************************
3417 * MsiInstallMissingComponentW [MSI.@]
3419 UINT WINAPI MsiInstallMissingComponentW(LPCWSTR szProduct, LPCWSTR szComponent, INSTALLSTATE eInstallState)
3421 FIXME("(%s %s %d\n", debugstr_w(szProduct), debugstr_w(szComponent), eInstallState);
3422 return ERROR_SUCCESS;