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 r = MSIREG_OpenInstallProps(szProduct, context, NULL, &props, FALSE);
111 if (r != ERROR_SUCCESS)
112 return ERROR_UNKNOWN_PRODUCT;
114 if (context == MSIINSTALLCONTEXT_USERMANAGED)
115 path = msi_reg_get_val_str(props, managed);
117 path = msi_reg_get_val_str(props, local);
119 r = ERROR_UNKNOWN_PRODUCT;
121 if (!path || GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
124 if (PathIsRelativeW(path))
126 r = ERROR_INSTALL_PACKAGE_OPEN_FAILED;
130 r = MSI_OpenPackageW(path, package);
138 UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
140 MSIPACKAGE *package = NULL;
141 WCHAR squished_pc[GUID_SIZE];
144 if (!szProduct || !squash_guid(szProduct, squished_pc))
145 return ERROR_INVALID_PARAMETER;
148 return ERROR_INVALID_PARAMETER;
150 r = MSI_OpenProductW(szProduct, &package);
151 if (r != ERROR_SUCCESS)
154 *phProduct = alloc_msihandle(&package->hdr);
156 r = ERROR_NOT_ENOUGH_MEMORY;
158 msiobj_release(&package->hdr);
162 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
163 LPCSTR szTransforms, LANGID lgidLanguage)
165 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
166 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
167 return ERROR_CALL_NOT_IMPLEMENTED;
170 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
171 LPCWSTR szTransforms, LANGID lgidLanguage)
173 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
174 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
175 return ERROR_CALL_NOT_IMPLEMENTED;
178 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
179 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
181 FIXME("%s %s %s %08x %08x %08x\n", debugstr_a(szPackagePath),
182 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
183 lgidLanguage, dwPlatform, dwOptions);
184 return ERROR_CALL_NOT_IMPLEMENTED;
187 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
188 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
190 FIXME("%s %s %s %08x %08x %08x\n", debugstr_w(szPackagePath),
191 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
192 lgidLanguage, dwPlatform, dwOptions);
193 return ERROR_CALL_NOT_IMPLEMENTED;
196 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
198 LPWSTR szwPath = NULL, szwCommand = NULL;
199 UINT r = ERROR_OUTOFMEMORY;
201 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
205 szwPath = strdupAtoW( szPackagePath );
212 szwCommand = strdupAtoW( szCommandLine );
217 r = MsiInstallProductW( szwPath, szwCommand );
221 msi_free( szwCommand );
226 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
228 MSIPACKAGE *package = NULL;
231 TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
233 r = MSI_OpenPackageW( szPackagePath, &package );
234 if (r == ERROR_SUCCESS)
236 r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
237 msiobj_release( &package->hdr );
243 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
245 FIXME("%s %08x\n", debugstr_a(szProduct), dwReinstallMode);
246 return ERROR_CALL_NOT_IMPLEMENTED;
249 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
251 FIXME("%s %08x\n", debugstr_w(szProduct), dwReinstallMode);
252 return ERROR_CALL_NOT_IMPLEMENTED;
255 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
256 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
258 LPWSTR patch_package = NULL;
259 LPWSTR install_package = NULL;
260 LPWSTR command_line = NULL;
261 UINT r = ERROR_OUTOFMEMORY;
263 TRACE("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
264 eInstallType, debugstr_a(szCommandLine));
266 if (szPatchPackage && !(patch_package = strdupAtoW(szPatchPackage)))
269 if (szInstallPackage && !(install_package = strdupAtoW(szInstallPackage)))
272 if (szCommandLine && !(command_line = strdupAtoW(szCommandLine)))
275 r = MsiApplyPatchW(patch_package, install_package, eInstallType, command_line);
278 msi_free(patch_package);
279 msi_free(install_package);
280 msi_free(command_line);
285 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
286 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
288 MSIHANDLE patch, info;
291 LPCWSTR cmd_ptr = szCommandLine;
293 LPWSTR cmd = NULL, codes = NULL;
295 static const WCHAR space[] = {' ',0};
296 static const WCHAR patcheq[] = {'P','A','T','C','H','=',0};
297 static WCHAR empty[] = {0};
299 TRACE("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
300 eInstallType, debugstr_w(szCommandLine));
302 if (szInstallPackage || eInstallType == INSTALLTYPE_NETWORK_IMAGE ||
303 eInstallType == INSTALLTYPE_SINGLE_INSTANCE)
305 FIXME("Only reading target products from patch\n");
306 return ERROR_CALL_NOT_IMPLEMENTED;
309 r = MsiOpenDatabaseW(szPatchPackage, MSIDBOPEN_READONLY, &patch);
310 if (r != ERROR_SUCCESS)
313 r = MsiGetSummaryInformationW(patch, NULL, 0, &info);
314 if (r != ERROR_SUCCESS)
317 r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, empty, &size);
318 if (r != ERROR_MORE_DATA || !size || type != VT_LPSTR)
320 ERR("Failed to read product codes from patch\n");
324 codes = msi_alloc(++size * sizeof(WCHAR));
327 r = ERROR_OUTOFMEMORY;
331 r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, codes, &size);
332 if (r != ERROR_SUCCESS)
338 size = lstrlenW(cmd_ptr) + lstrlenW(patcheq) + lstrlenW(szPatchPackage) + 1;
339 cmd = msi_alloc(size * sizeof(WCHAR));
342 r = ERROR_OUTOFMEMORY;
346 lstrcpyW(cmd, cmd_ptr);
347 if (szCommandLine) lstrcatW(cmd, space);
348 lstrcatW(cmd, patcheq);
349 lstrcatW(cmd, szPatchPackage);
352 while ((end = strchrW(beg, '}')))
356 r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd);
357 if (r != ERROR_SUCCESS)
367 MsiCloseHandle(info);
368 MsiCloseHandle(patch);
373 UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
374 DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOA pPatchInfo)
376 FIXME("(%s, %d, %p): stub!\n", debugstr_a(szProductPackagePath),
377 cPatchInfo, pPatchInfo);
379 return ERROR_CALL_NOT_IMPLEMENTED;
382 UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
383 DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
385 FIXME("(%s, %d, %p): stub!\n", debugstr_w(szProductPackagePath),
386 cPatchInfo, pPatchInfo);
388 return ERROR_CALL_NOT_IMPLEMENTED;
391 static UINT msi_open_package(LPCWSTR product, MSIINSTALLCONTEXT context,
392 MSIPACKAGE **package)
398 WCHAR sourcepath[MAX_PATH];
399 WCHAR filename[MAX_PATH];
401 static const WCHAR szLocalPackage[] = {
402 'L','o','c','a','l','P','a','c','k','a','g','e',0};
405 r = MSIREG_OpenInstallProps(product, context, NULL, &props, FALSE);
406 if (r != ERROR_SUCCESS)
407 return ERROR_BAD_CONFIGURATION;
409 localpack = msi_reg_get_val_str(props, szLocalPackage);
412 lstrcpyW(sourcepath, localpack);
416 if (!localpack || GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
418 sz = sizeof(sourcepath);
419 MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
420 INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
422 sz = sizeof(filename);
423 MsiSourceListGetInfoW(product, NULL, context, MSICODE_PRODUCT,
424 INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
426 lstrcatW(sourcepath, filename);
429 if (GetFileAttributesW(sourcepath) == INVALID_FILE_ATTRIBUTES)
430 return ERROR_INSTALL_SOURCE_ABSENT;
432 return MSI_OpenPackageW(sourcepath, package);
435 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
436 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
438 MSIPACKAGE* package = NULL;
439 MSIINSTALLCONTEXT context;
442 WCHAR sourcepath[MAX_PATH];
445 static const WCHAR szInstalled[] = {
446 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
447 static const WCHAR szRemoveAll[] = {
448 ' ','R','E','M','O','V','E','=','A','L','L',0};
449 static const WCHAR szMachine[] = {
450 ' ','A','L','L','U','S','E','R','S','=','1',0};
452 TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
453 debugstr_w(szCommandLine));
455 if (!szProduct || lstrlenW(szProduct) != GUID_SIZE - 1)
456 return ERROR_INVALID_PARAMETER;
458 if (eInstallState == INSTALLSTATE_ADVERTISED ||
459 eInstallState == INSTALLSTATE_SOURCE)
461 FIXME("State %d not implemented\n", eInstallState);
462 return ERROR_CALL_NOT_IMPLEMENTED;
465 r = msi_locate_product(szProduct, &context);
466 if (r != ERROR_SUCCESS)
469 r = msi_open_package(szProduct, context, &package);
470 if (r != ERROR_SUCCESS)
473 sz = lstrlenW(szInstalled) + 1;
476 sz += lstrlenW(szCommandLine);
478 if (eInstallState == INSTALLSTATE_ABSENT)
479 sz += lstrlenW(szRemoveAll);
481 if (context == MSIINSTALLCONTEXT_MACHINE)
482 sz += lstrlenW(szMachine);
484 commandline = msi_alloc(sz * sizeof(WCHAR));
487 r = ERROR_OUTOFMEMORY;
493 lstrcpyW(commandline,szCommandLine);
495 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
496 lstrcatW(commandline,szInstalled);
498 if (eInstallState == INSTALLSTATE_ABSENT)
499 lstrcatW(commandline, szRemoveAll);
501 if (context == MSIINSTALLCONTEXT_MACHINE)
502 lstrcatW(commandline, szMachine);
504 r = MSI_InstallPackage( package, sourcepath, commandline );
506 msi_free(commandline);
509 msiobj_release( &package->hdr );
514 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
515 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
517 LPWSTR szwProduct = NULL;
518 LPWSTR szwCommandLine = NULL;
519 UINT r = ERROR_OUTOFMEMORY;
523 szwProduct = strdupAtoW( szProduct );
530 szwCommandLine = strdupAtoW( szCommandLine );
535 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
538 msi_free( szwProduct );
539 msi_free( szwCommandLine);
544 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
545 INSTALLSTATE eInstallState)
547 LPWSTR szwProduct = NULL;
550 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
554 szwProduct = strdupAtoW( szProduct );
556 return ERROR_OUTOFMEMORY;
559 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
560 msi_free( szwProduct );
565 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
566 INSTALLSTATE eInstallState)
568 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
571 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
573 LPWSTR szwComponent = NULL;
575 WCHAR szwBuffer[GUID_SIZE];
577 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
581 szwComponent = strdupAtoW( szComponent );
583 return ERROR_OUTOFMEMORY;
587 r = MsiGetProductCodeW( szwComponent, szwBuffer );
590 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
592 msi_free( szwComponent );
597 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
600 HKEY compkey, prodkey;
601 WCHAR squished_comp[GUID_SIZE];
602 WCHAR squished_prod[GUID_SIZE];
603 DWORD sz = GUID_SIZE;
605 TRACE("%s %p\n", debugstr_w(szComponent), szBuffer);
607 if (!szComponent || !*szComponent)
608 return ERROR_INVALID_PARAMETER;
610 if (!squash_guid(szComponent, squished_comp))
611 return ERROR_INVALID_PARAMETER;
613 if (MSIREG_OpenUserDataComponentKey(szComponent, NULL, &compkey, FALSE) != ERROR_SUCCESS &&
614 MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &compkey, FALSE) != ERROR_SUCCESS)
616 return ERROR_UNKNOWN_COMPONENT;
619 rc = RegEnumValueW(compkey, 0, squished_prod, &sz, NULL, NULL, NULL, NULL);
620 if (rc != ERROR_SUCCESS)
622 RegCloseKey(compkey);
623 return ERROR_UNKNOWN_COMPONENT;
626 /* check simple case, only one product */
627 rc = RegEnumValueW(compkey, 1, squished_prod, &sz, NULL, NULL, NULL, NULL);
628 if (rc == ERROR_NO_MORE_ITEMS)
635 while ((rc = RegEnumValueW(compkey, index, squished_prod, &sz,
636 NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS)
640 unsquash_guid(squished_prod, szBuffer);
642 if (MSIREG_OpenProductKey(szBuffer, MSIINSTALLCONTEXT_USERMANAGED,
643 &prodkey, FALSE) == ERROR_SUCCESS ||
644 MSIREG_OpenProductKey(szBuffer, MSIINSTALLCONTEXT_USERUNMANAGED,
645 &prodkey, FALSE) == ERROR_SUCCESS ||
646 MSIREG_OpenProductKey(szBuffer, MSIINSTALLCONTEXT_MACHINE,
647 &prodkey, FALSE) == ERROR_SUCCESS)
649 RegCloseKey(prodkey);
655 rc = ERROR_INSTALL_FAILURE;
658 RegCloseKey(compkey);
659 unsquash_guid(squished_prod, szBuffer);
663 static LPWSTR msi_reg_get_value(HKEY hkey, LPCWSTR name, DWORD *type)
669 static const WCHAR format[] = {'%','d',0};
671 res = RegQueryValueExW(hkey, name, NULL, type, NULL, NULL);
672 if (res != ERROR_SUCCESS)
676 return msi_reg_get_val_str(hkey, name);
678 if (!msi_reg_get_val_dword(hkey, name, &dval))
681 sprintfW(temp, format, dval);
682 return strdupW(temp);
685 static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
686 awstring *szValue, LPDWORD pcchValueBuf)
688 MSIINSTALLCONTEXT context = MSIINSTALLCONTEXT_USERUNMANAGED;
689 UINT r = ERROR_UNKNOWN_PROPERTY;
690 HKEY prodkey, userdata, source;
692 WCHAR squished_pc[GUID_SIZE];
693 WCHAR packagecode[GUID_SIZE];
694 BOOL badconfig = FALSE;
696 DWORD save, type = REG_NONE;
698 static WCHAR empty[] = {0};
699 static const WCHAR sourcelist[] = {
700 'S','o','u','r','c','e','L','i','s','t',0};
701 static const WCHAR display_name[] = {
702 'D','i','s','p','l','a','y','N','a','m','e',0};
703 static const WCHAR display_version[] = {
704 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
705 static const WCHAR assignment[] = {
706 'A','s','s','i','g','n','m','e','n','t',0};
708 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
709 debugstr_w(szAttribute), szValue, pcchValueBuf);
711 if ((szValue->str.w && !pcchValueBuf) || !szProduct || !szAttribute)
712 return ERROR_INVALID_PARAMETER;
714 if (!squash_guid(szProduct, squished_pc))
715 return ERROR_INVALID_PARAMETER;
717 if ((r = MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
718 &prodkey, FALSE)) != ERROR_SUCCESS &&
719 (r = MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
720 &prodkey, FALSE)) != ERROR_SUCCESS &&
721 (r = MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
722 &prodkey, FALSE)) == ERROR_SUCCESS)
724 context = MSIINSTALLCONTEXT_MACHINE;
727 MSIREG_OpenInstallProps(szProduct, context, NULL, &userdata, FALSE);
729 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) ||
730 !lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) ||
731 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLDATEW) ||
732 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
733 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLLOCATIONW) ||
734 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLSOURCEW) ||
735 !lstrcmpW(szAttribute, INSTALLPROPERTY_LOCALPACKAGEW) ||
736 !lstrcmpW(szAttribute, INSTALLPROPERTY_PUBLISHERW) ||
737 !lstrcmpW(szAttribute, INSTALLPROPERTY_URLINFOABOUTW) ||
738 !lstrcmpW(szAttribute, INSTALLPROPERTY_URLUPDATEINFOW) ||
739 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMINORW) ||
740 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMAJORW) ||
741 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW) ||
742 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTIDW) ||
743 !lstrcmpW(szAttribute, INSTALLPROPERTY_REGCOMPANYW) ||
744 !lstrcmpW(szAttribute, INSTALLPROPERTY_REGOWNERW))
748 r = ERROR_UNKNOWN_PRODUCT;
753 return ERROR_UNKNOWN_PROPERTY;
755 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
756 szAttribute = display_name;
757 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW))
758 szAttribute = display_version;
760 val = msi_reg_get_value(userdata, szAttribute, &type);
764 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTANCETYPEW) ||
765 !lstrcmpW(szAttribute, INSTALLPROPERTY_TRANSFORMSW) ||
766 !lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
767 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW) ||
768 !lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW) ||
769 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW) ||
770 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW) ||
771 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTICONW) ||
772 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW) ||
773 !lstrcmpW(szAttribute, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
777 r = ERROR_UNKNOWN_PRODUCT;
781 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
782 szAttribute = assignment;
784 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW))
786 res = RegOpenKeyW(prodkey, sourcelist, &source);
787 if (res == ERROR_SUCCESS)
788 val = msi_reg_get_value(source, szAttribute, &type);
794 val = msi_reg_get_value(prodkey, szAttribute, &type);
799 if (val != empty && type != REG_DWORD &&
800 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
802 if (lstrlenW(val) != SQUISH_GUID_SIZE - 1)
806 unsquash_guid(val, packagecode);
808 val = strdupW(packagecode);
815 r = ERROR_UNKNOWN_PROPERTY;
821 save = *pcchValueBuf;
823 if (strlenW(val) < *pcchValueBuf)
824 r = msi_strcpy_to_awstring(val, szValue, pcchValueBuf);
825 else if (szValue->str.a || szValue->str.w)
829 *pcchValueBuf = lstrlenW(val);
830 else if (r == ERROR_SUCCESS)
832 *pcchValueBuf = save;
833 r = ERROR_BAD_CONFIGURATION;
837 r = ERROR_BAD_CONFIGURATION;
843 RegCloseKey(prodkey);
844 RegCloseKey(userdata);
848 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
849 LPSTR szBuffer, LPDWORD pcchValueBuf)
851 LPWSTR szwProduct, szwAttribute = NULL;
852 UINT r = ERROR_OUTOFMEMORY;
855 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
856 szBuffer, pcchValueBuf);
858 szwProduct = strdupAtoW( szProduct );
859 if( szProduct && !szwProduct )
862 szwAttribute = strdupAtoW( szAttribute );
863 if( szAttribute && !szwAttribute )
866 buffer.unicode = FALSE;
867 buffer.str.a = szBuffer;
869 r = MSI_GetProductInfo( szwProduct, szwAttribute,
870 &buffer, pcchValueBuf );
873 msi_free( szwProduct );
874 msi_free( szwAttribute );
879 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
880 LPWSTR szBuffer, LPDWORD pcchValueBuf)
884 TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute),
885 szBuffer, pcchValueBuf);
887 buffer.unicode = TRUE;
888 buffer.str.w = szBuffer;
890 return MSI_GetProductInfo( szProduct, szAttribute,
891 &buffer, pcchValueBuf );
894 UINT WINAPI MsiGetProductInfoExA(LPCSTR szProductCode, LPCSTR szUserSid,
895 MSIINSTALLCONTEXT dwContext, LPCSTR szProperty,
896 LPSTR szValue, LPDWORD pcchValue)
898 LPWSTR product = NULL;
899 LPWSTR usersid = NULL;
900 LPWSTR property = NULL;
905 TRACE("(%s, %s, %d, %s, %p, %p)\n", debugstr_a(szProductCode),
906 debugstr_a(szUserSid), dwContext, debugstr_a(szProperty),
909 if (szValue && !pcchValue)
910 return ERROR_INVALID_PARAMETER;
912 if (szProductCode) product = strdupAtoW(szProductCode);
913 if (szUserSid) usersid = strdupAtoW(szUserSid);
914 if (szProperty) property = strdupAtoW(szProperty);
916 r = MsiGetProductInfoExW(product, usersid, dwContext, property,
918 if (r != ERROR_SUCCESS)
921 value = msi_alloc(++len * sizeof(WCHAR));
924 r = ERROR_OUTOFMEMORY;
928 r = MsiGetProductInfoExW(product, usersid, dwContext, property,
930 if (r != ERROR_SUCCESS)
936 len = WideCharToMultiByte(CP_ACP, 0, value, -1, NULL, 0, NULL, NULL);
937 if (*pcchValue >= len)
938 WideCharToMultiByte(CP_ACP, 0, value, -1, szValue, len, NULL, NULL);
946 if (*pcchValue <= len || !szValue)
947 len = len * sizeof(WCHAR) - 1;
949 *pcchValue = len - 1;
960 static UINT msi_copy_outval(LPWSTR val, LPWSTR out, LPDWORD size)
965 return ERROR_UNKNOWN_PROPERTY;
969 if (strlenW(val) >= *size)
980 *size = lstrlenW(val);
982 return ERROR_SUCCESS;
985 UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
986 MSIINSTALLCONTEXT dwContext, LPCWSTR szProperty,
987 LPWSTR szValue, LPDWORD pcchValue)
989 WCHAR squished_pc[GUID_SIZE];
991 LPCWSTR package = NULL;
992 HKEY props = NULL, prod;
993 HKEY classes = NULL, managed;
996 UINT r = ERROR_UNKNOWN_PRODUCT;
998 static const WCHAR one[] = {'1',0};
999 static const WCHAR five[] = {'5',0};
1000 static const WCHAR empty[] = {0};
1001 static const WCHAR displayname[] = {
1002 'D','i','s','p','l','a','y','N','a','m','e',0};
1003 static const WCHAR displayversion[] = {
1004 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
1005 static const WCHAR managed_local_package[] = {
1006 'M','a','n','a','g','e','d','L','o','c','a','l',
1007 'P','a','c','k','a','g','e',0};
1009 TRACE("(%s, %s, %d, %s, %p, %p)\n", debugstr_w(szProductCode),
1010 debugstr_w(szUserSid), dwContext, debugstr_w(szProperty),
1011 szValue, pcchValue);
1013 if (!szProductCode || !squash_guid(szProductCode, squished_pc))
1014 return ERROR_INVALID_PARAMETER;
1016 if (szValue && !pcchValue)
1017 return ERROR_INVALID_PARAMETER;
1019 if (dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
1020 dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
1021 dwContext != MSIINSTALLCONTEXT_MACHINE)
1022 return ERROR_INVALID_PARAMETER;
1024 if (!szProperty || !*szProperty)
1025 return ERROR_INVALID_PARAMETER;
1027 if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
1028 return ERROR_INVALID_PARAMETER;
1030 /* FIXME: dwContext is provided, no need to search for it */
1031 MSIREG_OpenProductKey(szProductCode, MSIINSTALLCONTEXT_USERMANAGED,
1033 MSIREG_OpenProductKey(szProductCode, MSIINSTALLCONTEXT_USERUNMANAGED,
1036 MSIREG_OpenInstallProps(szProductCode, dwContext, NULL, &props, FALSE);
1038 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
1040 package = INSTALLPROPERTY_LOCALPACKAGEW;
1042 if (!props && !prod)
1045 else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
1047 package = managed_local_package;
1049 if (!props && !managed)
1052 else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1054 package = INSTALLPROPERTY_LOCALPACKAGEW;
1055 MSIREG_OpenProductKey(szProductCode, dwContext, &classes, FALSE);
1057 if (!props && !classes)
1061 if (!lstrcmpW(szProperty, INSTALLPROPERTY_HELPLINKW) ||
1062 !lstrcmpW(szProperty, INSTALLPROPERTY_HELPTELEPHONEW) ||
1063 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW) ||
1064 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
1065 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLLOCATIONW) ||
1066 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLSOURCEW) ||
1067 !lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW) ||
1068 !lstrcmpW(szProperty, INSTALLPROPERTY_PUBLISHERW) ||
1069 !lstrcmpW(szProperty, INSTALLPROPERTY_URLINFOABOUTW) ||
1070 !lstrcmpW(szProperty, INSTALLPROPERTY_URLUPDATEINFOW) ||
1071 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMINORW) ||
1072 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMAJORW) ||
1073 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW) ||
1074 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTIDW) ||
1075 !lstrcmpW(szProperty, INSTALLPROPERTY_REGCOMPANYW) ||
1076 !lstrcmpW(szProperty, INSTALLPROPERTY_REGOWNERW) ||
1077 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTANCETYPEW))
1079 val = msi_reg_get_value(props, package, &type);
1082 if (prod || classes)
1083 r = ERROR_UNKNOWN_PROPERTY;
1090 if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
1091 szProperty = displayname;
1092 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW))
1093 szProperty = displayversion;
1095 val = msi_reg_get_value(props, szProperty, &type);
1097 val = strdupW(empty);
1099 r = msi_copy_outval(val, szValue, pcchValue);
1101 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW) ||
1102 !lstrcmpW(szProperty, INSTALLPROPERTY_LANGUAGEW) ||
1103 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTNAMEW) ||
1104 !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGECODEW) ||
1105 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONW) ||
1106 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTICONW) ||
1107 !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGENAMEW) ||
1108 !lstrcmpW(szProperty, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
1110 if (!prod && !classes)
1113 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
1115 else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
1117 else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1120 val = msi_reg_get_value(hkey, szProperty, &type);
1122 val = strdupW(empty);
1124 r = msi_copy_outval(val, szValue, pcchValue);
1126 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTSTATEW))
1128 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1132 val = msi_reg_get_value(props, package, &type);
1137 val = strdupW(five);
1142 r = msi_copy_outval(val, szValue, pcchValue);
1145 else if (props && (val = msi_reg_get_value(props, package, &type)))
1148 val = strdupW(five);
1149 r = msi_copy_outval(val, szValue, pcchValue);
1153 if (prod || managed)
1158 r = msi_copy_outval(val, szValue, pcchValue);
1160 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW))
1162 if (!prod && !classes)
1166 val = strdupW(empty);
1167 r = msi_copy_outval(val, szValue, pcchValue);
1170 r = ERROR_UNKNOWN_PROPERTY;
1175 RegCloseKey(managed);
1176 RegCloseKey(classes);
1182 UINT WINAPI MsiGetPatchInfoExA(LPCSTR szPatchCode, LPCSTR szProductCode,
1183 LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1184 LPCSTR szProperty, LPSTR lpValue, DWORD *pcchValue)
1186 LPWSTR patch = NULL, product = NULL, usersid = NULL;
1187 LPWSTR property = NULL, val = NULL;
1191 TRACE("(%s, %s, %s, %d, %s, %p, %p)\n", debugstr_a(szPatchCode),
1192 debugstr_a(szProductCode), debugstr_a(szUserSid), dwContext,
1193 debugstr_a(szProperty), lpValue, pcchValue);
1195 if (lpValue && !pcchValue)
1196 return ERROR_INVALID_PARAMETER;
1198 if (szPatchCode) patch = strdupAtoW(szPatchCode);
1199 if (szProductCode) product = strdupAtoW(szProductCode);
1200 if (szUserSid) usersid = strdupAtoW(szUserSid);
1201 if (szProperty) property = strdupAtoW(szProperty);
1204 r = MsiGetPatchInfoExW(patch, product, usersid, dwContext, property,
1206 if (r != ERROR_SUCCESS)
1209 val = msi_alloc(++len * sizeof(WCHAR));
1212 r = ERROR_OUTOFMEMORY;
1216 r = MsiGetPatchInfoExW(patch, product, usersid, dwContext, property,
1218 if (r != ERROR_SUCCESS || !pcchValue)
1222 WideCharToMultiByte(CP_ACP, 0, val, -1, lpValue,
1223 *pcchValue - 1, NULL, NULL);
1225 len = lstrlenW(val);
1226 if ((*val && *pcchValue < len + 1) || !lpValue)
1230 r = ERROR_MORE_DATA;
1231 lpValue[*pcchValue - 1] = '\0';
1234 *pcchValue = len * sizeof(WCHAR);
1249 UINT WINAPI MsiGetPatchInfoExW(LPCWSTR szPatchCode, LPCWSTR szProductCode,
1250 LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1251 LPCWSTR szProperty, LPWSTR lpValue, DWORD *pcchValue)
1253 WCHAR squished_pc[GUID_SIZE];
1254 WCHAR squished_patch[GUID_SIZE];
1255 HKEY udprod = 0, prod = 0, props = 0;
1256 HKEY patch = 0, patches = 0;
1257 HKEY udpatch = 0, datakey = 0;
1258 HKEY prodpatches = 0;
1260 UINT r = ERROR_UNKNOWN_PRODUCT;
1264 static const WCHAR szEmpty[] = {0};
1265 static const WCHAR szPatches[] = {'P','a','t','c','h','e','s',0};
1266 static const WCHAR szInstalled[] = {'I','n','s','t','a','l','l','e','d',0};
1267 static const WCHAR szManagedPackage[] = {'M','a','n','a','g','e','d',
1268 'L','o','c','a','l','P','a','c','k','a','g','e',0};
1270 TRACE("(%s, %s, %s, %d, %s, %p, %p)\n", debugstr_w(szPatchCode),
1271 debugstr_w(szProductCode), debugstr_w(szUserSid), dwContext,
1272 debugstr_w(szProperty), lpValue, pcchValue);
1274 if (!szProductCode || !squash_guid(szProductCode, squished_pc))
1275 return ERROR_INVALID_PARAMETER;
1277 if (!szPatchCode || !squash_guid(szPatchCode, squished_patch))
1278 return ERROR_INVALID_PARAMETER;
1281 return ERROR_INVALID_PARAMETER;
1283 if (lpValue && !pcchValue)
1284 return ERROR_INVALID_PARAMETER;
1286 if (dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
1287 dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
1288 dwContext != MSIINSTALLCONTEXT_MACHINE)
1289 return ERROR_INVALID_PARAMETER;
1291 if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
1292 return ERROR_INVALID_PARAMETER;
1294 if (!lstrcmpW(szUserSid, szLocalSid))
1295 return ERROR_INVALID_PARAMETER;
1297 if (MSIREG_OpenUserDataProductKey(szProductCode, dwContext, NULL,
1298 &udprod, FALSE) != ERROR_SUCCESS)
1301 if (MSIREG_OpenInstallProps(szProductCode, dwContext, NULL,
1302 &props, FALSE) != ERROR_SUCCESS)
1305 r = ERROR_UNKNOWN_PATCH;
1307 res = RegOpenKeyExW(udprod, szPatches, 0, KEY_READ, &patches);
1308 if (res != ERROR_SUCCESS)
1311 res = RegOpenKeyExW(patches, squished_patch, 0, KEY_READ, &patch);
1312 if (res != ERROR_SUCCESS)
1315 if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW))
1317 if (MSIREG_OpenProductKey(szProductCode, dwContext,
1318 &prod, FALSE) != ERROR_SUCCESS)
1321 res = RegOpenKeyExW(prod, szPatches, 0, KEY_ALL_ACCESS, &prodpatches);
1322 if (res != ERROR_SUCCESS)
1325 datakey = prodpatches;
1326 szProperty = squished_patch;
1330 if (MSIREG_OpenUserDataPatchKey(szPatchCode, dwContext,
1331 &udpatch, FALSE) != ERROR_SUCCESS)
1334 if (!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW))
1336 if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
1337 szProperty = szManagedPackage;
1340 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW))
1343 szProperty = szInstalled;
1345 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW))
1349 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_UNINSTALLABLEW) ||
1350 !lstrcmpW(szProperty, INSTALLPROPERTY_PATCHSTATEW) ||
1351 !lstrcmpW(szProperty, INSTALLPROPERTY_DISPLAYNAMEW) ||
1352 !lstrcmpW(szProperty, INSTALLPROPERTY_MOREINFOURLW))
1358 r = ERROR_UNKNOWN_PROPERTY;
1363 val = msi_reg_get_val_str(datakey, szProperty);
1365 val = strdupW(szEmpty);
1373 lstrcpynW(lpValue, val, *pcchValue);
1375 len = lstrlenW(val);
1376 if ((*val && *pcchValue < len + 1) || !lpValue)
1379 r = ERROR_MORE_DATA;
1381 *pcchValue = len * sizeof(WCHAR);
1388 RegCloseKey(prodpatches);
1391 RegCloseKey(patches);
1392 RegCloseKey(udpatch);
1394 RegCloseKey(udprod);
1399 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
1401 LPWSTR szwLogFile = NULL;
1404 TRACE("%08x %s %08x\n", dwLogMode, debugstr_a(szLogFile), attributes);
1408 szwLogFile = strdupAtoW( szLogFile );
1410 return ERROR_OUTOFMEMORY;
1412 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
1413 msi_free( szwLogFile );
1417 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
1419 HANDLE file = INVALID_HANDLE_VALUE;
1421 TRACE("%08x %s %08x\n", dwLogMode, debugstr_w(szLogFile), attributes);
1425 lstrcpyW(gszLogFile,szLogFile);
1426 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
1427 DeleteFileW(szLogFile);
1428 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
1429 FILE_ATTRIBUTE_NORMAL, NULL);
1430 if (file != INVALID_HANDLE_VALUE)
1433 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
1436 gszLogFile[0] = '\0';
1438 return ERROR_SUCCESS;
1441 UINT WINAPI MsiEnumComponentCostsW(MSIHANDLE hInstall, LPCWSTR szComponent,
1442 DWORD dwIndex, INSTALLSTATE iState,
1443 LPWSTR lpDriveBuf, DWORD *pcchDriveBuf,
1444 int *piCost, int *pTempCost)
1446 FIXME("(%d, %s, %d, %d, %p, %p, %p %p): stub!\n", hInstall,
1447 debugstr_w(szComponent), dwIndex, iState, lpDriveBuf,
1448 pcchDriveBuf, piCost, pTempCost);
1450 return ERROR_NO_MORE_ITEMS;
1453 UINT WINAPI MsiQueryComponentStateA(LPCSTR szProductCode,
1454 LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1455 LPCSTR szComponent, INSTALLSTATE *pdwState)
1457 LPWSTR prodcode = NULL, usersid = NULL, comp = NULL;
1460 TRACE("(%s, %s, %d, %s, %p)\n", debugstr_a(szProductCode),
1461 debugstr_a(szUserSid), dwContext, debugstr_a(szComponent), pdwState);
1463 if (szProductCode && !(prodcode = strdupAtoW(szProductCode)))
1464 return ERROR_OUTOFMEMORY;
1466 if (szUserSid && !(usersid = strdupAtoW(szUserSid)))
1467 return ERROR_OUTOFMEMORY;
1469 if (szComponent && !(comp = strdupAtoW(szComponent)))
1470 return ERROR_OUTOFMEMORY;
1472 r = MsiQueryComponentStateW(prodcode, usersid, dwContext, comp, pdwState);
1481 static BOOL msi_comp_find_prod_key(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
1486 r = MSIREG_OpenProductKey(prodcode, context, &hkey, FALSE);
1488 return (r == ERROR_SUCCESS);
1491 static BOOL msi_comp_find_package(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
1499 static const WCHAR local_package[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
1500 static const WCHAR managed_local_package[] = {
1501 'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0
1504 r = MSIREG_OpenInstallProps(prodcode, context, NULL, &hkey, FALSE);
1505 if (r != ERROR_SUCCESS)
1508 if (context == MSIINSTALLCONTEXT_USERMANAGED)
1509 package = managed_local_package;
1511 package = local_package;
1514 res = RegQueryValueExW(hkey, package, NULL, NULL, NULL, &sz);
1517 return (res == ERROR_SUCCESS);
1520 static BOOL msi_comp_find_prodcode(LPWSTR squished_pc,
1521 MSIINSTALLCONTEXT context,
1522 LPCWSTR comp, LPWSTR val, DWORD *sz)
1528 if (context == MSIINSTALLCONTEXT_MACHINE)
1529 r = MSIREG_OpenUserDataComponentKey(comp, szLocalSid, &hkey, FALSE);
1531 r = MSIREG_OpenUserDataComponentKey(comp, NULL, &hkey, FALSE);
1533 if (r != ERROR_SUCCESS)
1536 res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, (BYTE *)val, sz);
1537 if (res != ERROR_SUCCESS)
1544 UINT WINAPI MsiQueryComponentStateW(LPCWSTR szProductCode,
1545 LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1546 LPCWSTR szComponent, INSTALLSTATE *pdwState)
1548 WCHAR squished_pc[GUID_SIZE];
1549 WCHAR val[MAX_PATH];
1553 TRACE("(%s, %s, %d, %s, %p)\n", debugstr_w(szProductCode),
1554 debugstr_w(szUserSid), dwContext, debugstr_w(szComponent), pdwState);
1556 if (!pdwState || !szComponent)
1557 return ERROR_INVALID_PARAMETER;
1559 if (!szProductCode || !*szProductCode || lstrlenW(szProductCode) != GUID_SIZE - 1)
1560 return ERROR_INVALID_PARAMETER;
1562 if (!squash_guid(szProductCode, squished_pc))
1563 return ERROR_INVALID_PARAMETER;
1565 found = msi_comp_find_prod_key(szProductCode, dwContext);
1567 if (!msi_comp_find_package(szProductCode, dwContext))
1571 *pdwState = INSTALLSTATE_UNKNOWN;
1572 return ERROR_UNKNOWN_COMPONENT;
1575 return ERROR_UNKNOWN_PRODUCT;
1578 *pdwState = INSTALLSTATE_UNKNOWN;
1581 if (!msi_comp_find_prodcode(squished_pc, dwContext, szComponent, val, &sz))
1582 return ERROR_UNKNOWN_COMPONENT;
1585 *pdwState = INSTALLSTATE_NOTUSED;
1588 if (lstrlenW(val) > 2 &&
1589 val[0] >= '0' && val[0] <= '9' && val[1] >= '0' && val[1] <= '9')
1591 *pdwState = INSTALLSTATE_SOURCE;
1594 *pdwState = INSTALLSTATE_LOCAL;
1597 return ERROR_SUCCESS;
1600 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
1602 LPWSTR szwProduct = NULL;
1607 szwProduct = strdupAtoW( szProduct );
1609 return ERROR_OUTOFMEMORY;
1611 r = MsiQueryProductStateW( szwProduct );
1612 msi_free( szwProduct );
1616 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
1618 MSIINSTALLCONTEXT context = MSIINSTALLCONTEXT_USERUNMANAGED;
1619 INSTALLSTATE state = INSTALLSTATE_ADVERTISED;
1620 HKEY prodkey = 0, userdata = 0;
1624 static const WCHAR szWindowsInstaller[] = {
1625 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
1627 TRACE("%s\n", debugstr_w(szProduct));
1629 if (!szProduct || !*szProduct)
1630 return INSTALLSTATE_INVALIDARG;
1632 if (lstrlenW(szProduct) != GUID_SIZE - 1)
1633 return INSTALLSTATE_INVALIDARG;
1635 if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
1636 &prodkey, FALSE) != ERROR_SUCCESS &&
1637 MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
1638 &prodkey, FALSE) != ERROR_SUCCESS &&
1639 MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
1640 &prodkey, FALSE) == ERROR_SUCCESS)
1642 context = MSIINSTALLCONTEXT_MACHINE;
1645 r = MSIREG_OpenInstallProps(szProduct, context, NULL, &userdata, FALSE);
1646 if (r != ERROR_SUCCESS)
1649 if (!msi_reg_get_val_dword(userdata, szWindowsInstaller, &val))
1653 state = INSTALLSTATE_DEFAULT;
1655 state = INSTALLSTATE_UNKNOWN;
1660 state = INSTALLSTATE_UNKNOWN;
1663 state = INSTALLSTATE_ABSENT;
1666 RegCloseKey(prodkey);
1667 RegCloseKey(userdata);
1671 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
1673 INSTALLUILEVEL old = gUILevel;
1674 HWND oldwnd = gUIhwnd;
1676 TRACE("%08x %p\n", dwUILevel, phWnd);
1678 gUILevel = dwUILevel;
1687 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
1688 DWORD dwMessageFilter, LPVOID pvContext)
1690 INSTALLUI_HANDLERA prev = gUIHandlerA;
1692 TRACE("%p %x %p\n",puiHandler, dwMessageFilter,pvContext);
1693 gUIHandlerA = puiHandler;
1694 gUIFilter = dwMessageFilter;
1695 gUIContext = pvContext;
1700 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
1701 DWORD dwMessageFilter, LPVOID pvContext)
1703 INSTALLUI_HANDLERW prev = gUIHandlerW;
1705 TRACE("%p %x %p\n",puiHandler,dwMessageFilter,pvContext);
1706 gUIHandlerW = puiHandler;
1707 gUIFilter = dwMessageFilter;
1708 gUIContext = pvContext;
1713 /******************************************************************
1714 * MsiLoadStringW [MSI.@]
1716 * Loads a string from MSI's string resources.
1720 * handle [I] only -1 is handled currently
1721 * id [I] id of the string to be loaded
1722 * lpBuffer [O] buffer for the string to be written to
1723 * nBufferMax [I] maximum size of the buffer in characters
1724 * lang [I] the preferred language for the string
1728 * If successful, this function returns the language id of the string loaded
1729 * If the function fails, the function returns zero.
1733 * The type of the first parameter is unknown. LoadString's prototype
1734 * suggests that it might be a module handle. I have made it an MSI handle
1735 * for starters, as -1 is an invalid MSI handle, but not an invalid module
1736 * handle. Maybe strings can be stored in an MSI database somehow.
1738 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
1739 int nBufferMax, LANGID lang )
1746 TRACE("%d %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
1749 FIXME("don't know how to deal with handle = %08x\n", handle);
1752 lang = GetUserDefaultLangID();
1754 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
1758 hResData = LoadResource( msi_hInstance, hres );
1761 p = LockResource( hResData );
1765 for (i = 0; i < (id&0xf); i++)
1769 if( nBufferMax <= len )
1772 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
1773 lpBuffer[ len ] = 0;
1775 TRACE("found -> %s\n", debugstr_w(lpBuffer));
1780 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
1781 int nBufferMax, LANGID lang )
1787 bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
1788 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
1791 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
1792 if( len <= nBufferMax )
1793 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
1794 lpBuffer, nBufferMax, NULL, NULL );
1802 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
1805 char szProduct[GUID_SIZE];
1807 TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
1809 if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
1810 return INSTALLSTATE_UNKNOWN;
1812 return MsiGetComponentPathA( szProduct, szComponent, lpPathBuf, pcchBuf );
1815 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
1818 WCHAR szProduct[GUID_SIZE];
1820 TRACE("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
1822 if (MsiGetProductCodeW( szComponent, szProduct ) != ERROR_SUCCESS)
1823 return INSTALLSTATE_UNKNOWN;
1825 return MsiGetComponentPathW( szProduct, szComponent, lpPathBuf, pcchBuf );
1828 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
1829 WORD wLanguageId, DWORD f)
1831 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_a(lpText), debugstr_a(lpCaption),
1832 uType, wLanguageId, f);
1833 return MessageBoxExA(hWnd,lpText,lpCaption,uType,wLanguageId);
1836 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
1837 WORD wLanguageId, DWORD f)
1839 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_w(lpText), debugstr_w(lpCaption),
1840 uType, wLanguageId, f);
1841 return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId);
1844 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
1845 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
1846 LPDWORD pcchPathBuf )
1848 FIXME("%s %s %08x %08x %p %p\n", debugstr_a(szAssemblyName),
1849 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
1851 return ERROR_CALL_NOT_IMPLEMENTED;
1854 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
1855 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
1856 LPDWORD pcchPathBuf )
1858 FIXME("%s %s %08x %08x %p %p\n", debugstr_w(szAssemblyName),
1859 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
1861 return ERROR_CALL_NOT_IMPLEMENTED;
1864 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
1865 LPSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs )
1867 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
1868 return ERROR_CALL_NOT_IMPLEMENTED;
1871 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
1872 LPWSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs )
1874 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
1875 return ERROR_CALL_NOT_IMPLEMENTED;
1878 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
1879 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData,
1880 LPDWORD pcbHashData)
1882 FIXME("%s %08x %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
1883 ppcCertContext, pbHashData, pcbHashData);
1884 return ERROR_CALL_NOT_IMPLEMENTED;
1887 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
1888 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData,
1889 LPDWORD pcbHashData)
1891 FIXME("%s %08x %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
1892 ppcCertContext, pbHashData, pcbHashData);
1893 return ERROR_CALL_NOT_IMPLEMENTED;
1896 /******************************************************************
1897 * MsiGetProductPropertyA [MSI.@]
1899 UINT WINAPI MsiGetProductPropertyA(MSIHANDLE hProduct, LPCSTR szProperty,
1900 LPSTR szValue, LPDWORD pccbValue)
1902 LPWSTR prop = NULL, val = NULL;
1906 TRACE("(%d, %s, %p, %p)\n", hProduct, debugstr_a(szProperty),
1907 szValue, pccbValue);
1909 if (szValue && !pccbValue)
1910 return ERROR_INVALID_PARAMETER;
1912 if (szProperty) prop = strdupAtoW(szProperty);
1915 r = MsiGetProductPropertyW(hProduct, prop, NULL, &len);
1916 if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
1919 if (r == ERROR_SUCCESS)
1921 if (szValue) *szValue = '\0';
1922 if (pccbValue) *pccbValue = 0;
1926 val = msi_alloc(++len * sizeof(WCHAR));
1929 r = ERROR_OUTOFMEMORY;
1933 r = MsiGetProductPropertyW(hProduct, prop, val, &len);
1934 if (r != ERROR_SUCCESS)
1937 len = WideCharToMultiByte(CP_ACP, 0, val, -1, NULL, 0, NULL, NULL);
1940 WideCharToMultiByte(CP_ACP, 0, val, -1, szValue,
1941 *pccbValue, NULL, NULL);
1945 if (len > *pccbValue)
1946 r = ERROR_MORE_DATA;
1948 *pccbValue = len - 1;
1958 /******************************************************************
1959 * MsiGetProductPropertyW [MSI.@]
1961 UINT WINAPI MsiGetProductPropertyW(MSIHANDLE hProduct, LPCWSTR szProperty,
1962 LPWSTR szValue, LPDWORD pccbValue)
1964 MSIPACKAGE *package;
1965 MSIQUERY *view = NULL;
1966 MSIRECORD *rec = NULL;
1970 static const WCHAR query[] = {
1971 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
1972 '`','P','r','o','p','e','r','t','y','`',' ','W','H','E','R','E',' ',
1973 '`','P','r','o','p','e','r','t','y','`','=','\'','%','s','\'',0};
1975 TRACE("(%d, %s, %p, %p)\n", hProduct, debugstr_w(szProperty),
1976 szValue, pccbValue);
1979 return ERROR_INVALID_PARAMETER;
1981 if (szValue && !pccbValue)
1982 return ERROR_INVALID_PARAMETER;
1984 package = msihandle2msiinfo(hProduct, MSIHANDLETYPE_PACKAGE);
1986 return ERROR_INVALID_HANDLE;
1988 r = MSI_OpenQuery(package->db, &view, query, szProperty);
1989 if (r != ERROR_SUCCESS)
1992 r = MSI_ViewExecute(view, 0);
1993 if (r != ERROR_SUCCESS)
1996 r = MSI_ViewFetch(view, &rec);
1997 if (r != ERROR_SUCCESS)
2000 val = MSI_RecordGetString(rec, 2);
2004 if (lstrlenW(val) >= *pccbValue)
2006 lstrcpynW(szValue, val, *pccbValue);
2007 *pccbValue = lstrlenW(val);
2008 r = ERROR_MORE_DATA;
2012 lstrcpyW(szValue, val);
2013 *pccbValue = lstrlenW(val);
2020 MSI_ViewClose(view);
2021 msiobj_release(&view->hdr);
2022 if (rec) msiobj_release(&rec->hdr);
2027 if (szValue) *szValue = '\0';
2028 if (pccbValue) *pccbValue = 0;
2035 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
2038 LPWSTR szPack = NULL;
2040 TRACE("%s\n", debugstr_a(szPackage) );
2044 szPack = strdupAtoW( szPackage );
2046 return ERROR_OUTOFMEMORY;
2049 r = MsiVerifyPackageW( szPack );
2056 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
2061 TRACE("%s\n", debugstr_w(szPackage) );
2063 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
2064 MsiCloseHandle( handle );
2069 static INSTALLSTATE MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
2070 awstring* lpPathBuf, LPDWORD pcchBuf)
2072 WCHAR squished_pc[GUID_SIZE];
2073 WCHAR squished_comp[GUID_SIZE];
2079 static const WCHAR wininstaller[] = {
2080 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
2082 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
2083 debugstr_w(szComponent), lpPathBuf->str.w, pcchBuf);
2085 if (!szProduct || !szComponent)
2086 return INSTALLSTATE_INVALIDARG;
2088 if (lpPathBuf->str.w && !pcchBuf)
2089 return INSTALLSTATE_INVALIDARG;
2091 if (!squash_guid(szProduct, squished_pc) ||
2092 !squash_guid(szComponent, squished_comp))
2093 return INSTALLSTATE_INVALIDARG;
2095 state = INSTALLSTATE_UNKNOWN;
2097 if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS ||
2098 MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
2100 path = msi_reg_get_val_str(hkey, squished_pc);
2103 state = INSTALLSTATE_ABSENT;
2105 if ((MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE, NULL,
2106 &hkey, FALSE) == ERROR_SUCCESS ||
2107 MSIREG_OpenUserDataProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
2108 NULL, &hkey, FALSE) == ERROR_SUCCESS) &&
2109 msi_reg_get_val_dword(hkey, wininstaller, &version) &&
2110 GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
2113 state = INSTALLSTATE_LOCAL;
2117 if (state != INSTALLSTATE_LOCAL &&
2118 (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
2119 &hkey, FALSE) == ERROR_SUCCESS ||
2120 MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
2121 &hkey, FALSE) == ERROR_SUCCESS))
2125 if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS ||
2126 MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
2129 path = msi_reg_get_val_str(hkey, squished_pc);
2132 state = INSTALLSTATE_ABSENT;
2134 if (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
2135 state = INSTALLSTATE_LOCAL;
2140 return INSTALLSTATE_UNKNOWN;
2142 if (state == INSTALLSTATE_LOCAL && !*path)
2143 state = INSTALLSTATE_NOTUSED;
2145 msi_strcpy_to_awstring(path, lpPathBuf, pcchBuf);
2150 /******************************************************************
2151 * MsiGetComponentPathW [MSI.@]
2153 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
2154 LPWSTR lpPathBuf, LPDWORD pcchBuf)
2158 path.unicode = TRUE;
2159 path.str.w = lpPathBuf;
2161 return MSI_GetComponentPath( szProduct, szComponent, &path, pcchBuf );
2164 /******************************************************************
2165 * MsiGetComponentPathA [MSI.@]
2167 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
2168 LPSTR lpPathBuf, LPDWORD pcchBuf)
2170 LPWSTR szwProduct, szwComponent = NULL;
2171 INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
2174 szwProduct = strdupAtoW( szProduct );
2175 if( szProduct && !szwProduct)
2178 szwComponent = strdupAtoW( szComponent );
2179 if( szComponent && !szwComponent )
2182 path.unicode = FALSE;
2183 path.str.a = lpPathBuf;
2185 r = MSI_GetComponentPath( szwProduct, szwComponent, &path, pcchBuf );
2188 msi_free( szwProduct );
2189 msi_free( szwComponent );
2194 /******************************************************************
2195 * MsiQueryFeatureStateA [MSI.@]
2197 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
2199 LPWSTR szwProduct = NULL, szwFeature= NULL;
2200 INSTALLSTATE rc = INSTALLSTATE_UNKNOWN;
2202 szwProduct = strdupAtoW( szProduct );
2203 if ( szProduct && !szwProduct )
2206 szwFeature = strdupAtoW( szFeature );
2207 if ( szFeature && !szwFeature )
2210 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
2213 msi_free( szwProduct);
2214 msi_free( szwFeature);
2219 /******************************************************************
2220 * MsiQueryFeatureStateW [MSI.@]
2222 * Checks the state of a feature
2225 * szProduct [I] Product's GUID string
2226 * szFeature [I] Feature's GUID string
2229 * INSTALLSTATE_LOCAL Feature is installed and usable
2230 * INSTALLSTATE_ABSENT Feature is absent
2231 * INSTALLSTATE_ADVERTISED Feature should be installed on demand
2232 * INSTALLSTATE_UNKNOWN An error occurred
2233 * INSTALLSTATE_INVALIDARG One of the GUIDs was invalid
2236 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
2238 WCHAR squishProduct[33], comp[GUID_SIZE];
2240 LPWSTR components, p, parent_feature, path;
2244 BOOL missing = FALSE;
2245 BOOL machine = FALSE;
2246 BOOL source = FALSE;
2248 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
2250 if (!szProduct || !szFeature)
2251 return INSTALLSTATE_INVALIDARG;
2253 if (!squash_guid( szProduct, squishProduct ))
2254 return INSTALLSTATE_INVALIDARG;
2256 if (MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
2257 &hkey, FALSE) != ERROR_SUCCESS &&
2258 MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
2259 &hkey, FALSE) != ERROR_SUCCESS)
2261 rc = MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
2263 if (rc != ERROR_SUCCESS)
2264 return INSTALLSTATE_UNKNOWN;
2269 parent_feature = msi_reg_get_val_str( hkey, szFeature );
2272 if (!parent_feature)
2273 return INSTALLSTATE_UNKNOWN;
2275 r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
2276 msi_free(parent_feature);
2277 if (r == INSTALLSTATE_ABSENT)
2281 rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
2282 MSIINSTALLCONTEXT_MACHINE,
2285 rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
2286 MSIINSTALLCONTEXT_USERUNMANAGED,
2289 if (rc != ERROR_SUCCESS)
2290 return INSTALLSTATE_ADVERTISED;
2292 components = msi_reg_get_val_str( hkey, szFeature );
2295 TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
2298 return INSTALLSTATE_ADVERTISED;
2300 for( p = components; *p && *p != 2 ; p += 20)
2302 if (!decode_base85_guid( p, &guid ))
2304 if (p != components)
2307 msi_free(components);
2308 return INSTALLSTATE_BADCONFIG;
2311 StringFromGUID2(&guid, comp, GUID_SIZE);
2314 rc = MSIREG_OpenUserDataComponentKey(comp, szLocalSid, &hkey, FALSE);
2316 rc = MSIREG_OpenUserDataComponentKey(comp, NULL, &hkey, FALSE);
2318 if (rc != ERROR_SUCCESS)
2320 msi_free(components);
2321 return INSTALLSTATE_ADVERTISED;
2324 path = msi_reg_get_val_str(hkey, squishProduct);
2327 else if (lstrlenW(path) > 2 &&
2328 path[0] >= '0' && path[0] <= '9' &&
2329 path[1] >= '0' && path[1] <= '9')
2337 TRACE("%s %s -> %d\n", debugstr_w(szProduct), debugstr_w(szFeature), r);
2338 msi_free(components);
2341 return INSTALLSTATE_ADVERTISED;
2344 return INSTALLSTATE_SOURCE;
2346 return INSTALLSTATE_LOCAL;
2349 /******************************************************************
2350 * MsiGetFileVersionA [MSI.@]
2352 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
2353 LPDWORD pcchVersionBuf, LPSTR lpLangBuf, LPDWORD pcchLangBuf)
2355 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
2356 UINT ret = ERROR_OUTOFMEMORY;
2358 if ((lpVersionBuf && !pcchVersionBuf) ||
2359 (lpLangBuf && !pcchLangBuf))
2360 return ERROR_INVALID_PARAMETER;
2364 szwFilePath = strdupAtoW( szFilePath );
2369 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
2371 lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
2372 if( !lpwVersionBuff )
2376 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
2378 lpwLangBuff = msi_alloc(*pcchLangBuf*sizeof(WCHAR));
2383 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
2384 lpwLangBuff, pcchLangBuf);
2386 if( (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && lpwVersionBuff )
2387 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
2388 lpVersionBuf, *pcchVersionBuf + 1, NULL, NULL);
2389 if( (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && lpwLangBuff )
2390 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
2391 lpLangBuf, *pcchLangBuf + 1, NULL, NULL);
2394 msi_free(szwFilePath);
2395 msi_free(lpwVersionBuff);
2396 msi_free(lpwLangBuff);
2401 /******************************************************************
2402 * MsiGetFileVersionW [MSI.@]
2404 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
2405 LPDWORD pcchVersionBuf, LPWSTR lpLangBuf, LPDWORD pcchLangBuf)
2407 static const WCHAR szVersionResource[] = {'\\',0};
2408 static const WCHAR szVersionFormat[] = {
2409 '%','d','.','%','d','.','%','d','.','%','d',0};
2410 static const WCHAR szLangResource[] = {
2411 '\\','V','a','r','F','i','l','e','I','n','f','o','\\',
2412 'T','r','a','n','s','l','a','t','i','o','n',0};
2413 static const WCHAR szLangFormat[] = {'%','d',0};
2415 DWORD dwVerLen, gle;
2416 LPVOID lpVer = NULL;
2417 VS_FIXEDFILEINFO *ffi;
2422 TRACE("%s %p %d %p %d\n", debugstr_w(szFilePath),
2423 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
2424 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
2426 if ((lpVersionBuf && !pcchVersionBuf) ||
2427 (lpLangBuf && !pcchLangBuf))
2428 return ERROR_INVALID_PARAMETER;
2430 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
2433 gle = GetLastError();
2434 if (gle == ERROR_BAD_PATHNAME)
2435 return ERROR_FILE_NOT_FOUND;
2436 else if (gle == ERROR_RESOURCE_DATA_NOT_FOUND)
2437 return ERROR_FILE_INVALID;
2442 lpVer = msi_alloc(dwVerLen);
2445 ret = ERROR_OUTOFMEMORY;
2449 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
2451 ret = GetLastError();
2457 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
2460 wsprintfW(tmp, szVersionFormat,
2461 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
2462 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
2463 if (lpVersionBuf) lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
2465 if (strlenW(tmp) >= *pcchVersionBuf)
2466 ret = ERROR_MORE_DATA;
2468 *pcchVersionBuf = lstrlenW(tmp);
2472 if (lpVersionBuf) *lpVersionBuf = 0;
2473 *pcchVersionBuf = 0;
2479 if (VerQueryValueW(lpVer, szLangResource, (LPVOID*)&lang, &puLen) &&
2482 wsprintfW(tmp, szLangFormat, *lang);
2483 if (lpLangBuf) lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
2485 if (strlenW(tmp) >= *pcchLangBuf)
2486 ret = ERROR_MORE_DATA;
2488 *pcchLangBuf = lstrlenW(tmp);
2492 if (lpLangBuf) *lpLangBuf = 0;
2502 /***********************************************************************
2503 * MsiGetFeatureUsageW [MSI.@]
2505 UINT WINAPI MsiGetFeatureUsageW( LPCWSTR szProduct, LPCWSTR szFeature,
2506 LPDWORD pdwUseCount, LPWORD pwDateUsed )
2508 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
2509 pdwUseCount, pwDateUsed);
2510 return ERROR_CALL_NOT_IMPLEMENTED;
2513 /***********************************************************************
2514 * MsiGetFeatureUsageA [MSI.@]
2516 UINT WINAPI MsiGetFeatureUsageA( LPCSTR szProduct, LPCSTR szFeature,
2517 LPDWORD pdwUseCount, LPWORD pwDateUsed )
2519 LPWSTR prod = NULL, feat = NULL;
2520 UINT ret = ERROR_OUTOFMEMORY;
2522 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
2523 pdwUseCount, pwDateUsed);
2525 prod = strdupAtoW( szProduct );
2526 if (szProduct && !prod)
2529 feat = strdupAtoW( szFeature );
2530 if (szFeature && !feat)
2533 ret = MsiGetFeatureUsageW( prod, feat, pdwUseCount, pwDateUsed );
2542 /***********************************************************************
2543 * MsiUseFeatureExW [MSI.@]
2545 INSTALLSTATE WINAPI MsiUseFeatureExW( LPCWSTR szProduct, LPCWSTR szFeature,
2546 DWORD dwInstallMode, DWORD dwReserved )
2550 TRACE("%s %s %i %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
2551 dwInstallMode, dwReserved);
2553 state = MsiQueryFeatureStateW( szProduct, szFeature );
2556 return INSTALLSTATE_INVALIDARG;
2558 if (state == INSTALLSTATE_LOCAL && dwInstallMode != INSTALLMODE_NODETECTION)
2560 FIXME("mark product %s feature %s as used\n",
2561 debugstr_w(szProduct), debugstr_w(szFeature) );
2567 /***********************************************************************
2568 * MsiUseFeatureExA [MSI.@]
2570 INSTALLSTATE WINAPI MsiUseFeatureExA( LPCSTR szProduct, LPCSTR szFeature,
2571 DWORD dwInstallMode, DWORD dwReserved )
2573 INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
2574 LPWSTR prod = NULL, feat = NULL;
2576 TRACE("%s %s %i %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
2577 dwInstallMode, dwReserved);
2579 prod = strdupAtoW( szProduct );
2580 if (szProduct && !prod)
2583 feat = strdupAtoW( szFeature );
2584 if (szFeature && !feat)
2587 ret = MsiUseFeatureExW( prod, feat, dwInstallMode, dwReserved );
2596 /***********************************************************************
2597 * MsiUseFeatureW [MSI.@]
2599 INSTALLSTATE WINAPI MsiUseFeatureW( LPCWSTR szProduct, LPCWSTR szFeature )
2601 return MsiUseFeatureExW(szProduct, szFeature, 0, 0);
2604 /***********************************************************************
2605 * MsiUseFeatureA [MSI.@]
2607 INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
2609 return MsiUseFeatureExA(szProduct, szFeature, 0, 0);
2612 /***********************************************************************
2613 * MSI_ProvideQualifiedComponentEx [internal]
2615 static UINT MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
2616 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
2617 DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
2618 LPDWORD pcchPathBuf)
2620 WCHAR product[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1],
2621 feature[MAX_FEATURE_CHARS+1];
2627 TRACE("%s %s %i %s %i %i %p %p\n", debugstr_w(szComponent),
2628 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
2629 Unused1, Unused2, lpPathBuf, pcchPathBuf);
2631 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
2632 if (rc != ERROR_SUCCESS)
2633 return ERROR_INDEX_ABSENT;
2635 info = msi_reg_get_val_str( hkey, szQualifier );
2639 return ERROR_INDEX_ABSENT;
2641 MsiDecomposeDescriptorW(info, product, feature, component, &sz);
2644 rc = MSI_GetComponentPath(product, component, lpPathBuf, pcchPathBuf);
2646 rc = MSI_GetComponentPath(szProduct, component, lpPathBuf, pcchPathBuf);
2650 if (rc != INSTALLSTATE_LOCAL)
2651 return ERROR_FILE_NOT_FOUND;
2653 return ERROR_SUCCESS;
2656 /***********************************************************************
2657 * MsiProvideQualifiedComponentExW [MSI.@]
2659 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
2660 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
2661 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
2662 LPDWORD pcchPathBuf)
2666 path.unicode = TRUE;
2667 path.str.w = lpPathBuf;
2669 return MSI_ProvideQualifiedComponentEx(szComponent, szQualifier,
2670 dwInstallMode, szProduct, Unused1, Unused2, &path, pcchPathBuf);
2673 /***********************************************************************
2674 * MsiProvideQualifiedComponentExA [MSI.@]
2676 UINT WINAPI MsiProvideQualifiedComponentExA(LPCSTR szComponent,
2677 LPCSTR szQualifier, DWORD dwInstallMode, LPCSTR szProduct,
2678 DWORD Unused1, DWORD Unused2, LPSTR lpPathBuf,
2679 LPDWORD pcchPathBuf)
2681 LPWSTR szwComponent, szwQualifier = NULL, szwProduct = NULL;
2682 UINT r = ERROR_OUTOFMEMORY;
2685 TRACE("%s %s %u %s %u %u %p %p\n", debugstr_a(szComponent),
2686 debugstr_a(szQualifier), dwInstallMode, debugstr_a(szProduct),
2687 Unused1, Unused2, lpPathBuf, pcchPathBuf);
2689 szwComponent = strdupAtoW( szComponent );
2690 if (szComponent && !szwComponent)
2693 szwQualifier = strdupAtoW( szQualifier );
2694 if (szQualifier && !szwQualifier)
2697 szwProduct = strdupAtoW( szProduct );
2698 if (szProduct && !szwProduct)
2701 path.unicode = FALSE;
2702 path.str.a = lpPathBuf;
2704 r = MSI_ProvideQualifiedComponentEx(szwComponent, szwQualifier,
2705 dwInstallMode, szwProduct, Unused1,
2706 Unused2, &path, pcchPathBuf);
2708 msi_free(szwProduct);
2709 msi_free(szwComponent);
2710 msi_free(szwQualifier);
2715 /***********************************************************************
2716 * MsiProvideQualifiedComponentW [MSI.@]
2718 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
2719 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
2720 LPDWORD pcchPathBuf)
2722 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
2723 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
2726 /***********************************************************************
2727 * MsiProvideQualifiedComponentA [MSI.@]
2729 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
2730 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
2731 LPDWORD pcchPathBuf)
2733 return MsiProvideQualifiedComponentExA(szComponent, szQualifier,
2734 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
2737 /***********************************************************************
2738 * MSI_GetUserInfo [internal]
2740 static USERINFOSTATE MSI_GetUserInfo(LPCWSTR szProduct,
2741 awstring *lpUserNameBuf, LPDWORD pcchUserNameBuf,
2742 awstring *lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2743 awstring *lpSerialBuf, LPDWORD pcchSerialBuf)
2745 WCHAR squished_pc[SQUISH_GUID_SIZE];
2746 LPWSTR user, org, serial;
2747 USERINFOSTATE state;
2752 static const WCHAR szEmpty[] = {0};
2754 TRACE("%s %p %p %p %p %p %p\n", debugstr_w(szProduct), lpUserNameBuf,
2755 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
2758 if (!szProduct || !squash_guid(szProduct, squished_pc))
2759 return USERINFOSTATE_INVALIDARG;
2761 if (MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
2762 &hkey, FALSE) != ERROR_SUCCESS &&
2763 MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
2764 &hkey, FALSE) != ERROR_SUCCESS &&
2765 MSIREG_OpenProductKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
2766 &hkey, FALSE) != ERROR_SUCCESS)
2768 return USERINFOSTATE_UNKNOWN;
2771 if (MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
2772 NULL, &props, FALSE) != ERROR_SUCCESS &&
2773 MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE,
2774 NULL, &props, FALSE) != ERROR_SUCCESS)
2777 return USERINFOSTATE_ABSENT;
2780 user = msi_reg_get_val_str(props, INSTALLPROPERTY_REGOWNERW);
2781 org = msi_reg_get_val_str(props, INSTALLPROPERTY_REGCOMPANYW);
2782 serial = msi_reg_get_val_str(props, INSTALLPROPERTY_PRODUCTIDW);
2783 state = USERINFOSTATE_ABSENT;
2789 state = USERINFOSTATE_PRESENT;
2791 if (pcchUserNameBuf)
2793 if (lpUserNameBuf && !user)
2795 (*pcchUserNameBuf)--;
2799 r = msi_strcpy_to_awstring(user, lpUserNameBuf, pcchUserNameBuf);
2800 if (r == ERROR_MORE_DATA)
2802 state = USERINFOSTATE_MOREDATA;
2810 if (!orgptr) orgptr = szEmpty;
2812 r = msi_strcpy_to_awstring(orgptr, lpOrgNameBuf, pcchOrgNameBuf);
2813 if (r == ERROR_MORE_DATA)
2815 state = USERINFOSTATE_MOREDATA;
2828 r = msi_strcpy_to_awstring(serial, lpSerialBuf, pcchSerialBuf);
2829 if (r == ERROR_MORE_DATA)
2830 state = USERINFOSTATE_MOREDATA;
2841 /***********************************************************************
2842 * MsiGetUserInfoW [MSI.@]
2844 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct,
2845 LPWSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
2846 LPWSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2847 LPWSTR lpSerialBuf, LPDWORD pcchSerialBuf)
2849 awstring user, org, serial;
2851 if ((lpUserNameBuf && !pcchUserNameBuf) ||
2852 (lpOrgNameBuf && !pcchOrgNameBuf) ||
2853 (lpSerialBuf && !pcchSerialBuf))
2854 return USERINFOSTATE_INVALIDARG;
2856 user.unicode = TRUE;
2857 user.str.w = lpUserNameBuf;
2859 org.str.w = lpOrgNameBuf;
2860 serial.unicode = TRUE;
2861 serial.str.w = lpSerialBuf;
2863 return MSI_GetUserInfo( szProduct, &user, pcchUserNameBuf,
2864 &org, pcchOrgNameBuf,
2865 &serial, pcchSerialBuf );
2868 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct,
2869 LPSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
2870 LPSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2871 LPSTR lpSerialBuf, LPDWORD pcchSerialBuf)
2873 awstring user, org, serial;
2877 if ((lpUserNameBuf && !pcchUserNameBuf) ||
2878 (lpOrgNameBuf && !pcchOrgNameBuf) ||
2879 (lpSerialBuf && !pcchSerialBuf))
2880 return USERINFOSTATE_INVALIDARG;
2882 prod = strdupAtoW( szProduct );
2883 if (szProduct && !prod)
2884 return ERROR_OUTOFMEMORY;
2886 user.unicode = FALSE;
2887 user.str.a = lpUserNameBuf;
2888 org.unicode = FALSE;
2889 org.str.a = lpOrgNameBuf;
2890 serial.unicode = FALSE;
2891 serial.str.a = lpSerialBuf;
2893 r = MSI_GetUserInfo( prod, &user, pcchUserNameBuf,
2894 &org, pcchOrgNameBuf,
2895 &serial, pcchSerialBuf );
2902 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
2906 MSIPACKAGE *package;
2907 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
2909 TRACE("(%s)\n",debugstr_w(szProduct));
2911 rc = MsiOpenProductW(szProduct,&handle);
2912 if (rc != ERROR_SUCCESS)
2913 return ERROR_INVALID_PARAMETER;
2915 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
2916 rc = ACTION_PerformUIAction(package, szFirstRun, -1);
2917 msiobj_release( &package->hdr );
2919 MsiCloseHandle(handle);
2924 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
2928 MSIPACKAGE *package;
2929 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
2931 TRACE("(%s)\n",debugstr_a(szProduct));
2933 rc = MsiOpenProductA(szProduct,&handle);
2934 if (rc != ERROR_SUCCESS)
2935 return ERROR_INVALID_PARAMETER;
2937 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
2938 rc = ACTION_PerformUIAction(package, szFirstRun, -1);
2939 msiobj_release( &package->hdr );
2941 MsiCloseHandle(handle);
2946 /***********************************************************************
2947 * MsiConfigureFeatureA [MSI.@]
2949 UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
2951 LPWSTR prod, feat = NULL;
2952 UINT r = ERROR_OUTOFMEMORY;
2954 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
2956 prod = strdupAtoW( szProduct );
2957 if (szProduct && !prod)
2960 feat = strdupAtoW( szFeature );
2961 if (szFeature && !feat)
2964 r = MsiConfigureFeatureW(prod, feat, eInstallState);
2973 /***********************************************************************
2974 * MsiConfigureFeatureW [MSI.@]
2976 UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
2978 static const WCHAR szCostInit[] = { 'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0 };
2979 MSIPACKAGE *package = NULL;
2981 WCHAR sourcepath[MAX_PATH], filename[MAX_PATH];
2984 TRACE("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
2986 if (!szProduct || !szFeature)
2987 return ERROR_INVALID_PARAMETER;
2989 switch (eInstallState)
2991 case INSTALLSTATE_DEFAULT:
2992 /* FIXME: how do we figure out the default location? */
2993 eInstallState = INSTALLSTATE_LOCAL;
2995 case INSTALLSTATE_LOCAL:
2996 case INSTALLSTATE_SOURCE:
2997 case INSTALLSTATE_ABSENT:
2998 case INSTALLSTATE_ADVERTISED:
3001 return ERROR_INVALID_PARAMETER;
3004 r = MSI_OpenProductW( szProduct, &package );
3005 if (r != ERROR_SUCCESS)
3008 sz = sizeof(sourcepath);
3009 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3010 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
3012 sz = sizeof(filename);
3013 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3014 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
3016 lstrcatW( sourcepath, filename );
3018 MsiSetInternalUI( INSTALLUILEVEL_BASIC, NULL );
3020 r = ACTION_PerformUIAction( package, szCostInit, -1 );
3021 if (r != ERROR_SUCCESS)
3024 r = MSI_SetFeatureStateW( package, szFeature, eInstallState);
3025 if (r != ERROR_SUCCESS)
3028 r = MSI_InstallPackage( package, sourcepath, NULL );
3031 msiobj_release( &package->hdr );
3036 /***********************************************************************
3037 * MsiCreateAndVerifyInstallerDirectory [MSI.@]
3039 * Notes: undocumented
3041 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
3043 WCHAR path[MAX_PATH];
3045 TRACE("%d\n", dwReserved);
3049 FIXME("dwReserved=%d\n", dwReserved);
3050 return ERROR_INVALID_PARAMETER;
3053 if (!GetWindowsDirectoryW(path, MAX_PATH))
3054 return ERROR_FUNCTION_FAILED;
3056 lstrcatW(path, installerW);
3058 if (!CreateDirectoryW(path, NULL))
3059 return ERROR_FUNCTION_FAILED;
3061 return ERROR_SUCCESS;
3064 /***********************************************************************
3065 * MsiGetShortcutTargetA [MSI.@]
3067 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
3068 LPSTR szProductCode, LPSTR szFeatureId,
3069 LPSTR szComponentCode )
3072 const int len = MAX_FEATURE_CHARS+1;
3073 WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1];
3076 target = strdupAtoW( szShortcutTarget );
3077 if (szShortcutTarget && !target )
3078 return ERROR_OUTOFMEMORY;
3082 r = MsiGetShortcutTargetW( target, product, feature, component );
3084 if (r == ERROR_SUCCESS)
3086 WideCharToMultiByte( CP_ACP, 0, product, -1, szProductCode, len, NULL, NULL );
3087 WideCharToMultiByte( CP_ACP, 0, feature, -1, szFeatureId, len, NULL, NULL );
3088 WideCharToMultiByte( CP_ACP, 0, component, -1, szComponentCode, len, NULL, NULL );
3093 /***********************************************************************
3094 * MsiGetShortcutTargetW [MSI.@]
3096 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
3097 LPWSTR szProductCode, LPWSTR szFeatureId,
3098 LPWSTR szComponentCode )
3100 IShellLinkDataList *dl = NULL;
3101 IPersistFile *pf = NULL;
3102 LPEXP_DARWIN_LINK darwin = NULL;
3105 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget),
3106 szProductCode, szFeatureId, szComponentCode );
3108 init = CoInitialize(NULL);
3110 r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
3111 &IID_IPersistFile, (LPVOID*) &pf );
3112 if( SUCCEEDED( r ) )
3114 r = IPersistFile_Load( pf, szShortcutTarget,
3115 STGM_READ | STGM_SHARE_DENY_WRITE );
3116 if( SUCCEEDED( r ) )
3118 r = IPersistFile_QueryInterface( pf, &IID_IShellLinkDataList,
3120 if( SUCCEEDED( r ) )
3122 IShellLinkDataList_CopyDataBlock( dl, EXP_DARWIN_ID_SIG,
3124 IShellLinkDataList_Release( dl );
3127 IPersistFile_Release( pf );
3130 if (SUCCEEDED(init))
3133 TRACE("darwin = %p\n", darwin);
3140 ret = MsiDecomposeDescriptorW( darwin->szwDarwinID,
3141 szProductCode, szFeatureId, szComponentCode, &sz );
3142 LocalFree( darwin );
3146 return ERROR_FUNCTION_FAILED;
3149 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
3150 DWORD dwReinstallMode )
3152 MSIPACKAGE* package = NULL;
3154 WCHAR sourcepath[MAX_PATH];
3155 WCHAR filename[MAX_PATH];
3156 static const WCHAR szLogVerbose[] = {
3157 ' ','L','O','G','V','E','R','B','O','S','E',0 };
3158 static const WCHAR szInstalled[] = { 'I','n','s','t','a','l','l','e','d',0};
3159 static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
3160 static const WCHAR szReinstallMode[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
3161 static const WCHAR szOne[] = {'1',0};
3162 WCHAR reinstallmode[11];
3166 FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
3169 ptr = reinstallmode;
3171 if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
3173 if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
3175 if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
3177 if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
3179 if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
3181 if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
3183 if (dwReinstallMode & REINSTALLMODE_USERDATA)
3185 if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
3187 if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
3189 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
3193 sz = sizeof(sourcepath);
3194 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3195 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
3197 sz = sizeof(filename);
3198 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
3199 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
3201 lstrcatW( sourcepath, filename );
3203 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
3204 r = MSI_OpenPackageW( sourcepath, &package );
3206 r = MSI_OpenProductW( szProduct, &package );
3208 if (r != ERROR_SUCCESS)
3211 MSI_SetPropertyW( package, szReinstallMode, reinstallmode );
3212 MSI_SetPropertyW( package, szInstalled, szOne );
3213 MSI_SetPropertyW( package, szLogVerbose, szOne );
3214 MSI_SetPropertyW( package, szReinstall, szFeature );
3216 r = MSI_InstallPackage( package, sourcepath, NULL );
3218 msiobj_release( &package->hdr );
3223 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
3224 DWORD dwReinstallMode )
3230 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
3233 wszProduct = strdupAtoW(szProduct);
3234 wszFeature = strdupAtoW(szFeature);
3236 rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
3238 msi_free(wszProduct);
3239 msi_free(wszFeature);
3246 unsigned int buf[4];
3247 unsigned char in[64];
3248 unsigned char digest[16];
3251 extern VOID WINAPI MD5Init( MD5_CTX *);
3252 extern VOID WINAPI MD5Update( MD5_CTX *, const unsigned char *, unsigned int );
3253 extern VOID WINAPI MD5Final( MD5_CTX *);
3255 /***********************************************************************
3256 * MsiGetFileHashW [MSI.@]
3258 UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions,
3259 PMSIFILEHASHINFO pHash )
3261 HANDLE handle, mapping;
3264 UINT r = ERROR_FUNCTION_FAILED;
3266 TRACE("%s %08x %p\n", debugstr_w(szFilePath), dwOptions, pHash );
3269 return ERROR_INVALID_PARAMETER;
3272 return ERROR_PATH_NOT_FOUND;
3275 return ERROR_INVALID_PARAMETER;
3277 return ERROR_INVALID_PARAMETER;
3278 if (pHash->dwFileHashInfoSize < sizeof *pHash)
3279 return ERROR_INVALID_PARAMETER;
3281 handle = CreateFileW( szFilePath, GENERIC_READ,
3282 FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL );
3283 if (handle == INVALID_HANDLE_VALUE)
3284 return ERROR_FILE_NOT_FOUND;
3286 length = GetFileSize( handle, NULL );
3288 mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
3291 p = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, length );
3297 MD5Update( &ctx, p, length );
3299 UnmapViewOfFile( p );
3301 memcpy( pHash->dwData, ctx.digest, sizeof pHash->dwData );
3304 CloseHandle( mapping );
3306 CloseHandle( handle );
3311 /***********************************************************************
3312 * MsiGetFileHashA [MSI.@]
3314 UINT WINAPI MsiGetFileHashA( LPCSTR szFilePath, DWORD dwOptions,
3315 PMSIFILEHASHINFO pHash )
3320 TRACE("%s %08x %p\n", debugstr_a(szFilePath), dwOptions, pHash );
3322 file = strdupAtoW( szFilePath );
3323 if (szFilePath && !file)
3324 return ERROR_OUTOFMEMORY;
3326 r = MsiGetFileHashW( file, dwOptions, pHash );
3331 /***********************************************************************
3332 * MsiAdvertiseScriptW [MSI.@]
3334 UINT WINAPI MsiAdvertiseScriptW( LPCWSTR szScriptFile, DWORD dwFlags,
3335 PHKEY phRegData, BOOL fRemoveItems )
3337 FIXME("%s %08x %p %d\n",
3338 debugstr_w( szScriptFile ), dwFlags, phRegData, fRemoveItems );
3339 return ERROR_CALL_NOT_IMPLEMENTED;
3342 /***********************************************************************
3343 * MsiAdvertiseScriptA [MSI.@]
3345 UINT WINAPI MsiAdvertiseScriptA( LPCSTR szScriptFile, DWORD dwFlags,
3346 PHKEY phRegData, BOOL fRemoveItems )
3348 FIXME("%s %08x %p %d\n",
3349 debugstr_a( szScriptFile ), dwFlags, phRegData, fRemoveItems );
3350 return ERROR_CALL_NOT_IMPLEMENTED;
3353 /***********************************************************************
3354 * MsiIsProductElevatedW [MSI.@]
3356 UINT WINAPI MsiIsProductElevatedW( LPCWSTR szProduct, BOOL *pfElevated )
3358 FIXME("%s %p - stub\n",
3359 debugstr_w( szProduct ), pfElevated );
3361 return ERROR_SUCCESS;
3364 /***********************************************************************
3365 * MsiIsProductElevatedA [MSI.@]
3367 UINT WINAPI MsiIsProductElevatedA( LPCSTR szProduct, BOOL *pfElevated )
3369 FIXME("%s %p - stub\n",
3370 debugstr_a( szProduct ), pfElevated );
3372 return ERROR_SUCCESS;
3375 /***********************************************************************
3376 * MsiSetExternalUIRecord [MSI.@]
3378 UINT WINAPI MsiSetExternalUIRecord( INSTALLUI_HANDLER_RECORD puiHandler,
3379 DWORD dwMessageFilter, LPVOID pvContext,
3380 PINSTALLUI_HANDLER_RECORD ppuiPrevHandler)
3382 FIXME("%p %08x %p %p\n", puiHandler, dwMessageFilter ,pvContext,
3384 return ERROR_CALL_NOT_IMPLEMENTED;
3387 /***********************************************************************
3388 * MsiInstallMissingComponentW [MSI.@]
3390 UINT WINAPI MsiInstallMissingComponentW(LPCWSTR szProduct, LPCWSTR szComponent, INSTALLSTATE eInstallState)
3392 FIXME("(%s %s %d\n", debugstr_w(szProduct), debugstr_w(szComponent), eInstallState);
3393 return ERROR_SUCCESS;