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
);
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
;