summaryrefslogtreecommitdiffstats
path: root/libmsi
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2012-10-22 12:31:42 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2012-12-06 20:25:48 +0100
commit0d6fdca97e8d8c0ee138f644f9ac42672db77965 (patch)
tree37278579004beda02b6dd01179a78eb32779e844 /libmsi
parent149cfb4172e051be4220f8d15b37e258b424e024 (diff)
downloadmsitools-0d6fdca97e8d8c0ee138f644f9ac42672db77965.tar.gz
msitools-0d6fdca97e8d8c0ee138f644f9ac42672db77965.tar.xz
msitools-0d6fdca97e8d8c0ee138f644f9ac42672db77965.zip
kill registry.c
Diffstat (limited to 'libmsi')
-rw-r--r--libmsi/Makefile.am2
-rw-r--r--libmsi/msi.c1977
-rw-r--r--libmsi/package.c254
-rw-r--r--libmsi/patch.c54
-rw-r--r--libmsi/registry.c2479
5 files changed, 2 insertions, 4764 deletions
diff --git a/libmsi/Makefile.am b/libmsi/Makefile.am
index 049dbd5..3f8d2ad 100644
--- a/libmsi/Makefile.am
+++ b/libmsi/Makefile.am
@@ -13,7 +13,7 @@ noinst_HEADERS = \
libmsi_la_SOURCES = alter.c create.c database.c delete.c distinct.c \
drop.c handle.c insert.c media.c msi.c msi_main.c msiquery.c \
- package.c patch.c record.c registry.c select.c source.c \
+ package.c patch.c record.c select.c source.c \
storages.c streams.c string.c suminfo.c table.c tokenize.c update.c \
where.c \
sql-parser.y \
diff --git a/libmsi/msi.c b/libmsi/msi.c
index e44a2f5..248aa5f 100644
--- a/libmsi/msi.c
+++ b/libmsi/msi.c
@@ -53,122 +53,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
-UINT msi_locate_product(LPCWSTR szProduct, MSIINSTALLCONTEXT *context)
-{
- HKEY hkey = NULL;
-
- *context = MSIINSTALLCONTEXT_NONE;
- if (!szProduct) return ERROR_UNKNOWN_PRODUCT;
-
- if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
- &hkey, FALSE) == ERROR_SUCCESS)
- *context = MSIINSTALLCONTEXT_USERMANAGED;
- else if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
- &hkey, FALSE) == ERROR_SUCCESS)
- *context = MSIINSTALLCONTEXT_MACHINE;
- else if (MSIREG_OpenProductKey(szProduct, NULL,
- MSIINSTALLCONTEXT_USERUNMANAGED,
- &hkey, FALSE) == ERROR_SUCCESS)
- *context = MSIINSTALLCONTEXT_USERUNMANAGED;
-
- RegCloseKey(hkey);
-
- if (*context == MSIINSTALLCONTEXT_NONE)
- return ERROR_UNKNOWN_PRODUCT;
-
- return ERROR_SUCCESS;
-}
-
-UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
-{
- UINT r;
- LPWSTR szwProd = NULL;
-
- TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
-
- if( szProduct )
- {
- szwProd = strdupAtoW( szProduct );
- if( !szwProd )
- return ERROR_OUTOFMEMORY;
- }
-
- r = MsiOpenProductW( szwProd, phProduct );
-
- msi_free( szwProd );
-
- return r;
-}
-
-static UINT MSI_OpenProductW(LPCWSTR szProduct, MSIPACKAGE **package)
-{
- UINT r;
- HKEY props;
- LPWSTR path;
- MSIINSTALLCONTEXT context;
-
- static const WCHAR managed[] = {
- 'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0};
- static const WCHAR local[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
-
- TRACE("%s %p\n", debugstr_w(szProduct), package);
-
- r = msi_locate_product(szProduct, &context);
- if (r != ERROR_SUCCESS)
- return r;
-
- r = MSIREG_OpenInstallProps(szProduct, context, NULL, &props, FALSE);
- if (r != ERROR_SUCCESS)
- return ERROR_UNKNOWN_PRODUCT;
-
- if (context == MSIINSTALLCONTEXT_USERMANAGED)
- path = msi_reg_get_val_str(props, managed);
- else
- path = msi_reg_get_val_str(props, local);
-
- r = ERROR_UNKNOWN_PRODUCT;
-
- if (!path || GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
- goto done;
-
- if (PathIsRelativeW(path))
- {
- r = ERROR_INSTALL_PACKAGE_OPEN_FAILED;
- goto done;
- }
-
- r = MSI_OpenPackageW(path, package);
-
-done:
- RegCloseKey(props);
- msi_free(path);
- return r;
-}
-
-UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
-{
- MSIPACKAGE *package = NULL;
- WCHAR squished_pc[GUID_SIZE];
- UINT r;
-
- if (!szProduct || !squash_guid(szProduct, squished_pc))
- return ERROR_INVALID_PARAMETER;
-
- if (!phProduct)
- return ERROR_INVALID_PARAMETER;
-
- r = MSI_OpenProductW(szProduct, &package);
- if (r != ERROR_SUCCESS)
- return r;
-
- *phProduct = alloc_msihandle(&package->hdr);
- if (!*phProduct)
- r = ERROR_NOT_ENOUGH_MEMORY;
-
- msiobj_release(&package->hdr);
- return r;
-}
-
UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
LPCSTR szTransforms, LANGID lgidLanguage)
{
@@ -273,155 +157,6 @@ static MSIPATCHSEQUENCEINFOW *patchinfoAtoW( DWORD count, const MSIPATCHSEQUENCE
return ret;
}
-static UINT open_package( const WCHAR *product, const WCHAR *usersid,
- MSIINSTALLCONTEXT context, MSIPACKAGE **package )
-{
- UINT r;
- HKEY props;
- WCHAR *localpath, sourcepath[MAX_PATH], filename[MAX_PATH];
-
- r = MSIREG_OpenInstallProps( product, context, usersid, &props, FALSE );
- if (r != ERROR_SUCCESS) return ERROR_BAD_CONFIGURATION;
-
- if ((localpath = msi_reg_get_val_str( props, szLocalPackage )))
- {
- strcpyW( sourcepath, localpath );
- msi_free( localpath );
- }
- RegCloseKey( props );
- if (!localpath || GetFileAttributesW( sourcepath ) == INVALID_FILE_ATTRIBUTES)
- {
- DWORD sz = sizeof(sourcepath);
- MsiSourceListGetInfoW( product, usersid, context, MSICODE_PRODUCT,
- INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz );
- sz = sizeof(filename);
- MsiSourceListGetInfoW( product, usersid, context, MSICODE_PRODUCT,
- INSTALLPROPERTY_PACKAGENAMEW, filename, &sz );
- strcatW( sourcepath, filename );
- }
- if (GetFileAttributesW( sourcepath ) == INVALID_FILE_ATTRIBUTES)
- return ERROR_INSTALL_SOURCE_ABSENT;
-
- return MSI_OpenPackageW( sourcepath, package );
-}
-
-UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
-{
- LPWSTR szwComponent = NULL;
- UINT r;
- WCHAR szwBuffer[GUID_SIZE];
-
- TRACE("%s %p\n", debugstr_a(szComponent), szBuffer);
-
- if( szComponent )
- {
- szwComponent = strdupAtoW( szComponent );
- if( !szwComponent )
- return ERROR_OUTOFMEMORY;
- }
-
- *szwBuffer = '\0';
- r = MsiGetProductCodeW( szwComponent, szwBuffer );
-
- if(*szwBuffer)
- WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
-
- msi_free( szwComponent );
-
- return r;
-}
-
-UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
-{
- UINT rc, index;
- HKEY compkey, prodkey;
- WCHAR squished_comp[GUID_SIZE];
- WCHAR squished_prod[GUID_SIZE];
- DWORD sz = GUID_SIZE;
-
- TRACE("%s %p\n", debugstr_w(szComponent), szBuffer);
-
- if (!szComponent || !*szComponent)
- return ERROR_INVALID_PARAMETER;
-
- if (!squash_guid(szComponent, squished_comp))
- return ERROR_INVALID_PARAMETER;
-
- if (MSIREG_OpenUserDataComponentKey(szComponent, NULL, &compkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &compkey, FALSE) != ERROR_SUCCESS)
- {
- return ERROR_UNKNOWN_COMPONENT;
- }
-
- rc = RegEnumValueW(compkey, 0, squished_prod, &sz, NULL, NULL, NULL, NULL);
- if (rc != ERROR_SUCCESS)
- {
- RegCloseKey(compkey);
- return ERROR_UNKNOWN_COMPONENT;
- }
-
- /* check simple case, only one product */
- rc = RegEnumValueW(compkey, 1, squished_prod, &sz, NULL, NULL, NULL, NULL);
- if (rc == ERROR_NO_MORE_ITEMS)
- {
- rc = ERROR_SUCCESS;
- goto done;
- }
-
- index = 0;
- while ((rc = RegEnumValueW(compkey, index, squished_prod, &sz,
- NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS)
- {
- index++;
- sz = GUID_SIZE;
- unsquash_guid(squished_prod, szBuffer);
-
- if (MSIREG_OpenProductKey(szBuffer, NULL,
- MSIINSTALLCONTEXT_USERMANAGED,
- &prodkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenProductKey(szBuffer, NULL,
- MSIINSTALLCONTEXT_USERUNMANAGED,
- &prodkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenProductKey(szBuffer, NULL,
- MSIINSTALLCONTEXT_MACHINE,
- &prodkey, FALSE) == ERROR_SUCCESS)
- {
- RegCloseKey(prodkey);
- rc = ERROR_SUCCESS;
- goto done;
- }
- }
-
- rc = ERROR_INSTALL_FAILURE;
-
-done:
- RegCloseKey(compkey);
- unsquash_guid(squished_prod, szBuffer);
- return rc;
-}
-
-static LPWSTR msi_reg_get_value(HKEY hkey, LPCWSTR name, DWORD *type)
-{
- DWORD dval;
- LONG res;
- WCHAR temp[20];
-
- static const WCHAR format[] = {'%','d',0};
-
- res = RegQueryValueExW(hkey, name, NULL, type, NULL, NULL);
- if (res != ERROR_SUCCESS)
- return NULL;
-
- if (*type == REG_SZ)
- return msi_reg_get_val_str(hkey, name);
-
- if (!msi_reg_get_val_dword(hkey, name, &dval))
- return NULL;
-
- sprintfW(temp, format, dval);
- return strdupW(temp);
-}
-
UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
{
UINT len, r = ERROR_SUCCESS;
@@ -454,816 +189,6 @@ UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
return r;
}
-static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
- awstring *szValue, LPDWORD pcchValueBuf)
-{
- MSIINSTALLCONTEXT context = MSIINSTALLCONTEXT_USERUNMANAGED;
- UINT r = ERROR_UNKNOWN_PROPERTY;
- HKEY prodkey, userdata, source;
- LPWSTR val = NULL;
- WCHAR squished_pc[GUID_SIZE];
- WCHAR packagecode[GUID_SIZE];
- BOOL badconfig = FALSE;
- LONG res;
- DWORD type = REG_NONE;
-
- static WCHAR empty[] = {0};
- static const WCHAR sourcelist[] = {
- 'S','o','u','r','c','e','L','i','s','t',0};
- static const WCHAR display_name[] = {
- 'D','i','s','p','l','a','y','N','a','m','e',0};
- static const WCHAR display_version[] = {
- 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
- static const WCHAR assignment[] = {
- 'A','s','s','i','g','n','m','e','n','t',0};
-
- TRACE("%s %s %p %p\n", debugstr_w(szProduct),
- debugstr_w(szAttribute), szValue, pcchValueBuf);
-
- if ((szValue->str.w && !pcchValueBuf) || !szProduct || !szAttribute)
- return ERROR_INVALID_PARAMETER;
-
- if (!squash_guid(szProduct, squished_pc))
- return ERROR_INVALID_PARAMETER;
-
- if ((r = MSIREG_OpenProductKey(szProduct, NULL,
- MSIINSTALLCONTEXT_USERMANAGED,
- &prodkey, FALSE)) != ERROR_SUCCESS &&
- (r = MSIREG_OpenProductKey(szProduct, NULL,
- MSIINSTALLCONTEXT_USERUNMANAGED,
- &prodkey, FALSE)) != ERROR_SUCCESS &&
- (r = MSIREG_OpenProductKey(szProduct, NULL,
- MSIINSTALLCONTEXT_MACHINE,
- &prodkey, FALSE)) == ERROR_SUCCESS)
- {
- context = MSIINSTALLCONTEXT_MACHINE;
- }
-
- MSIREG_OpenInstallProps(szProduct, context, NULL, &userdata, FALSE);
-
- if (!strcmpW( szAttribute, INSTALLPROPERTY_HELPLINKW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_HELPTELEPHONEW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_INSTALLDATEW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_INSTALLLOCATIONW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_INSTALLSOURCEW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_LOCALPACKAGEW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_PUBLISHERW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_URLINFOABOUTW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_URLUPDATEINFOW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_VERSIONMINORW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_VERSIONMAJORW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_VERSIONSTRINGW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_PRODUCTIDW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_REGCOMPANYW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_REGOWNERW ))
- {
- if (!prodkey)
- {
- r = ERROR_UNKNOWN_PRODUCT;
- goto done;
- }
-
- if (!userdata)
- return ERROR_UNKNOWN_PROPERTY;
-
- if (!strcmpW( szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW ))
- szAttribute = display_name;
- else if (!strcmpW( szAttribute, INSTALLPROPERTY_VERSIONSTRINGW ))
- szAttribute = display_version;
-
- val = msi_reg_get_value(userdata, szAttribute, &type);
- if (!val)
- val = empty;
- }
- else if (!strcmpW( szAttribute, INSTALLPROPERTY_INSTANCETYPEW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_TRANSFORMSW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_LANGUAGEW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_PRODUCTNAMEW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_PACKAGECODEW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_VERSIONW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_PRODUCTICONW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_PACKAGENAMEW ) ||
- !strcmpW( szAttribute, INSTALLPROPERTY_AUTHORIZED_LUA_APPW ))
- {
- if (!prodkey)
- {
- r = ERROR_UNKNOWN_PRODUCT;
- goto done;
- }
-
- if (!strcmpW( szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW ))
- szAttribute = assignment;
-
- if (!strcmpW( szAttribute, INSTALLPROPERTY_PACKAGENAMEW ))
- {
- res = RegOpenKeyW(prodkey, sourcelist, &source);
- if (res != ERROR_SUCCESS)
- {
- r = ERROR_UNKNOWN_PRODUCT;
- goto done;
- }
-
- val = msi_reg_get_value(source, szAttribute, &type);
- if (!val)
- val = empty;
-
- RegCloseKey(source);
- }
- else
- {
- val = msi_reg_get_value(prodkey, szAttribute, &type);
- if (!val)
- val = empty;
- }
-
- if (val != empty && type != REG_DWORD &&
- !strcmpW( szAttribute, INSTALLPROPERTY_PACKAGECODEW ))
- {
- if (lstrlenW(val) != SQUISH_GUID_SIZE - 1)
- badconfig = TRUE;
- else
- {
- unsquash_guid(val, packagecode);
- msi_free(val);
- val = strdupW(packagecode);
- }
- }
- }
-
- if (!val)
- {
- r = ERROR_UNKNOWN_PROPERTY;
- goto done;
- }
-
- if (pcchValueBuf)
- {
- /* If szBuffer (szValue->str) is NULL, there's no need to copy the value
- * out. Also, *pcchValueBuf may be uninitialized in this case, so we
- * can't rely on its value.
- */
- if (szValue->str.a || szValue->str.w)
- {
- DWORD size = *pcchValueBuf;
- if (strlenW(val) < size)
- r = msi_strcpy_to_awstring(val, szValue, &size);
- else
- {
- r = ERROR_MORE_DATA;
- }
- }
-
- if (!badconfig)
- *pcchValueBuf = lstrlenW(val);
- }
-
- if (badconfig)
- r = ERROR_BAD_CONFIGURATION;
-
- if (val != empty)
- msi_free(val);
-
-done:
- RegCloseKey(prodkey);
- RegCloseKey(userdata);
- return r;
-}
-
-UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
- LPSTR szBuffer, LPDWORD pcchValueBuf)
-{
- LPWSTR szwProduct, szwAttribute = NULL;
- UINT r = ERROR_OUTOFMEMORY;
- awstring buffer;
-
- TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
- szBuffer, pcchValueBuf);
-
- szwProduct = strdupAtoW( szProduct );
- if( szProduct && !szwProduct )
- goto end;
-
- szwAttribute = strdupAtoW( szAttribute );
- if( szAttribute && !szwAttribute )
- goto end;
-
- buffer.unicode = FALSE;
- buffer.str.a = szBuffer;
-
- r = MSI_GetProductInfo( szwProduct, szwAttribute,
- &buffer, pcchValueBuf );
-
-end:
- msi_free( szwProduct );
- msi_free( szwAttribute );
-
- return r;
-}
-
-UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
- LPWSTR szBuffer, LPDWORD pcchValueBuf)
-{
- awstring buffer;
-
- TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute),
- szBuffer, pcchValueBuf);
-
- buffer.unicode = TRUE;
- buffer.str.w = szBuffer;
-
- return MSI_GetProductInfo( szProduct, szAttribute,
- &buffer, pcchValueBuf );
-}
-
-UINT WINAPI MsiGetProductInfoExA(LPCSTR szProductCode, LPCSTR szUserSid,
- MSIINSTALLCONTEXT dwContext, LPCSTR szProperty,
- LPSTR szValue, LPDWORD pcchValue)
-{
- LPWSTR product = NULL;
- LPWSTR usersid = NULL;
- LPWSTR property = NULL;
- LPWSTR value = NULL;
- DWORD len = 0;
- UINT r;
-
- TRACE("(%s, %s, %d, %s, %p, %p)\n", debugstr_a(szProductCode),
- debugstr_a(szUserSid), dwContext, debugstr_a(szProperty),
- szValue, pcchValue);
-
- if (szValue && !pcchValue)
- return ERROR_INVALID_PARAMETER;
-
- if (szProductCode) product = strdupAtoW(szProductCode);
- if (szUserSid) usersid = strdupAtoW(szUserSid);
- if (szProperty) property = strdupAtoW(szProperty);
-
- r = MsiGetProductInfoExW(product, usersid, dwContext, property,
- NULL, &len);
- if (r != ERROR_SUCCESS)
- goto done;
-
- value = msi_alloc(++len * sizeof(WCHAR));
- if (!value)
- {
- r = ERROR_OUTOFMEMORY;
- goto done;
- }
-
- r = MsiGetProductInfoExW(product, usersid, dwContext, property,
- value, &len);
- if (r != ERROR_SUCCESS)
- goto done;
-
- if (!pcchValue)
- goto done;
-
- len = WideCharToMultiByte(CP_ACP, 0, value, -1, NULL, 0, NULL, NULL);
- if (*pcchValue >= len)
- WideCharToMultiByte(CP_ACP, 0, value, -1, szValue, len, NULL, NULL);
- else if (szValue)
- {
- r = ERROR_MORE_DATA;
- if (*pcchValue > 0)
- *szValue = '\0';
- }
-
- if (*pcchValue <= len || !szValue)
- len = len * sizeof(WCHAR) - 1;
-
- *pcchValue = len - 1;
-
-done:
- msi_free(product);
- msi_free(usersid);
- msi_free(property);
- msi_free(value);
-
- return r;
-}
-
-static UINT msi_copy_outval(LPWSTR val, LPWSTR out, LPDWORD size)
-{
- UINT r = ERROR_SUCCESS;
-
- if (!val)
- return ERROR_UNKNOWN_PROPERTY;
-
- if (out)
- {
- if (strlenW(val) >= *size)
- {
- r = ERROR_MORE_DATA;
- if (*size > 0)
- *out = '\0';
- }
- else
- lstrcpyW(out, val);
- }
-
- if (size)
- *size = lstrlenW(val);
-
- return r;
-}
-
-UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
- MSIINSTALLCONTEXT dwContext, LPCWSTR szProperty,
- LPWSTR szValue, LPDWORD pcchValue)
-{
- WCHAR squished_pc[GUID_SIZE];
- LPWSTR val = NULL;
- LPCWSTR package = NULL;
- HKEY props = NULL, prod;
- HKEY classes = NULL, managed;
- HKEY hkey = NULL;
- DWORD type;
- UINT r = ERROR_UNKNOWN_PRODUCT;
-
- static const WCHAR five[] = {'5',0};
- static const WCHAR displayname[] = {
- 'D','i','s','p','l','a','y','N','a','m','e',0};
- static const WCHAR displayversion[] = {
- 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
- static const WCHAR managed_local_package[] = {
- 'M','a','n','a','g','e','d','L','o','c','a','l',
- 'P','a','c','k','a','g','e',0};
-
- TRACE("(%s, %s, %d, %s, %p, %p)\n", debugstr_w(szProductCode),
- debugstr_w(szUserSid), dwContext, debugstr_w(szProperty),
- szValue, pcchValue);
-
- if (!szProductCode || !squash_guid(szProductCode, squished_pc))
- return ERROR_INVALID_PARAMETER;
-
- if (szValue && !pcchValue)
- return ERROR_INVALID_PARAMETER;
-
- if (dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
- dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
- dwContext != MSIINSTALLCONTEXT_MACHINE)
- return ERROR_INVALID_PARAMETER;
-
- if (!szProperty || !*szProperty)
- return ERROR_INVALID_PARAMETER;
-
- if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
- return ERROR_INVALID_PARAMETER;
-
- /* FIXME: dwContext is provided, no need to search for it */
- MSIREG_OpenProductKey(szProductCode, NULL,MSIINSTALLCONTEXT_USERMANAGED,
- &managed, FALSE);
- MSIREG_OpenProductKey(szProductCode, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- &prod, FALSE);
-
- MSIREG_OpenInstallProps(szProductCode, dwContext, NULL, &props, FALSE);
-
- if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
- {
- package = INSTALLPROPERTY_LOCALPACKAGEW;
-
- if (!props && !prod)
- goto done;
- }
- else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
- {
- package = managed_local_package;
-
- if (!props && !managed)
- goto done;
- }
- else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
- {
- package = INSTALLPROPERTY_LOCALPACKAGEW;
- MSIREG_OpenProductKey(szProductCode, NULL, dwContext, &classes, FALSE);
-
- if (!props && !classes)
- goto done;
- }
-
- if (!strcmpW( szProperty, INSTALLPROPERTY_HELPLINKW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_HELPTELEPHONEW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_INSTALLDATEW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_INSTALLLOCATIONW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_INSTALLSOURCEW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_LOCALPACKAGEW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_PUBLISHERW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_URLINFOABOUTW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_URLUPDATEINFOW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_VERSIONMINORW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_VERSIONMAJORW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_VERSIONSTRINGW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_PRODUCTIDW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_REGCOMPANYW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_REGOWNERW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_INSTANCETYPEW ))
- {
- val = msi_reg_get_value(props, package, &type);
- if (!val)
- {
- if (prod || classes)
- r = ERROR_UNKNOWN_PROPERTY;
-
- goto done;
- }
-
- msi_free(val);
-
- if (!strcmpW( szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW ))
- szProperty = displayname;
- else if (!strcmpW( szProperty, INSTALLPROPERTY_VERSIONSTRINGW ))
- szProperty = displayversion;
-
- val = msi_reg_get_value(props, szProperty, &type);
- if (!val)
- val = strdupW(szEmpty);
-
- r = msi_copy_outval(val, szValue, pcchValue);
- }
- else if (!strcmpW( szProperty, INSTALLPROPERTY_TRANSFORMSW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_LANGUAGEW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_PRODUCTNAMEW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_PACKAGECODEW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_VERSIONW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_PRODUCTICONW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_PACKAGENAMEW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_AUTHORIZED_LUA_APPW ))
- {
- if (!prod && !classes)
- goto done;
-
- if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
- hkey = prod;
- else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
- hkey = managed;
- else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
- hkey = classes;
-
- val = msi_reg_get_value(hkey, szProperty, &type);
- if (!val)
- val = strdupW(szEmpty);
-
- r = msi_copy_outval(val, szValue, pcchValue);
- }
- else if (!strcmpW( szProperty, INSTALLPROPERTY_PRODUCTSTATEW ))
- {
- if (dwContext == MSIINSTALLCONTEXT_MACHINE)
- {
- if (props)
- {
- val = msi_reg_get_value(props, package, &type);
- if (!val)
- goto done;
-
- msi_free(val);
- val = strdupW(five);
- }
- else
- val = strdupW(szOne);
-
- r = msi_copy_outval(val, szValue, pcchValue);
- goto done;
- }
- else if (props && (val = msi_reg_get_value(props, package, &type)))
- {
- msi_free(val);
- val = strdupW(five);
- r = msi_copy_outval(val, szValue, pcchValue);
- goto done;
- }
-
- if (prod || managed)
- val = strdupW(szOne);
- else
- goto done;
-
- r = msi_copy_outval(val, szValue, pcchValue);
- }
- else if (!strcmpW( szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW ))
- {
- if (!prod && !classes)
- goto done;
-
- /* FIXME */
- val = strdupW(szEmpty);
- r = msi_copy_outval(val, szValue, pcchValue);
- }
- else
- r = ERROR_UNKNOWN_PROPERTY;
-
-done:
- RegCloseKey(props);
- RegCloseKey(prod);
- RegCloseKey(managed);
- RegCloseKey(classes);
- msi_free(val);
-
- return r;
-}
-
-UINT WINAPI MsiGetPatchInfoExA(LPCSTR szPatchCode, LPCSTR szProductCode,
- LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext,
- LPCSTR szProperty, LPSTR lpValue, DWORD *pcchValue)
-{
- LPWSTR patch = NULL, product = NULL, usersid = NULL;
- LPWSTR property = NULL, val = NULL;
- DWORD len;
- UINT r;
-
- TRACE("(%s, %s, %s, %d, %s, %p, %p)\n", debugstr_a(szPatchCode),
- debugstr_a(szProductCode), debugstr_a(szUserSid), dwContext,
- debugstr_a(szProperty), lpValue, pcchValue);
-
- if (lpValue && !pcchValue)
- return ERROR_INVALID_PARAMETER;
-
- if (szPatchCode) patch = strdupAtoW(szPatchCode);
- if (szProductCode) product = strdupAtoW(szProductCode);
- if (szUserSid) usersid = strdupAtoW(szUserSid);
- if (szProperty) property = strdupAtoW(szProperty);
-
- len = 0;
- r = MsiGetPatchInfoExW(patch, product, usersid, dwContext, property,
- NULL, &len);
- if (r != ERROR_SUCCESS)
- goto done;
-
- val = msi_alloc(++len * sizeof(WCHAR));
- if (!val)
- {
- r = ERROR_OUTOFMEMORY;
- goto done;
- }
-
- r = MsiGetPatchInfoExW(patch, product, usersid, dwContext, property,
- val, &len);
- if (r != ERROR_SUCCESS || !pcchValue)
- goto done;
-
- if (lpValue)
- WideCharToMultiByte(CP_ACP, 0, val, -1, lpValue,
- *pcchValue - 1, NULL, NULL);
-
- len = lstrlenW(val);
- if ((*val && *pcchValue < len + 1) || !lpValue)
- {
- if (lpValue)
- {
- r = ERROR_MORE_DATA;
- lpValue[*pcchValue - 1] = '\0';
- }
-
- *pcchValue = len * sizeof(WCHAR);
- }
- else
- *pcchValue = len;
-
-done:
- msi_free(val);
- msi_free(patch);
- msi_free(product);
- msi_free(usersid);
- msi_free(property);
-
- return r;
-}
-
-UINT WINAPI MsiGetPatchInfoExW(LPCWSTR szPatchCode, LPCWSTR szProductCode,
- LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
- LPCWSTR szProperty, LPWSTR lpValue, DWORD *pcchValue)
-{
- WCHAR squished_pc[GUID_SIZE];
- WCHAR squished_patch[GUID_SIZE];
- HKEY udprod = 0, prod = 0, props = 0;
- HKEY patch = 0, patches = 0;
- HKEY udpatch = 0, datakey = 0;
- HKEY prodpatches = 0;
- LPWSTR val = NULL;
- UINT r = ERROR_UNKNOWN_PRODUCT;
- DWORD len;
- LONG res;
-
- static const WCHAR szManagedPackage[] = {'M','a','n','a','g','e','d',
- 'L','o','c','a','l','P','a','c','k','a','g','e',0};
-
- TRACE("(%s, %s, %s, %d, %s, %p, %p)\n", debugstr_w(szPatchCode),
- debugstr_w(szProductCode), debugstr_w(szUserSid), dwContext,
- debugstr_w(szProperty), lpValue, pcchValue);
-
- if (!szProductCode || !squash_guid(szProductCode, squished_pc))
- return ERROR_INVALID_PARAMETER;
-
- if (!szPatchCode || !squash_guid(szPatchCode, squished_patch))
- return ERROR_INVALID_PARAMETER;
-
- if (!szProperty)
- return ERROR_INVALID_PARAMETER;
-
- if (lpValue && !pcchValue)
- return ERROR_INVALID_PARAMETER;
-
- if (dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
- dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
- dwContext != MSIINSTALLCONTEXT_MACHINE)
- return ERROR_INVALID_PARAMETER;
-
- if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
- return ERROR_INVALID_PARAMETER;
-
- if (szUserSid && !strcmpW( szUserSid, szLocalSid ))
- return ERROR_INVALID_PARAMETER;
-
- if (MSIREG_OpenUserDataProductKey(szProductCode, dwContext, NULL,
- &udprod, FALSE) != ERROR_SUCCESS)
- goto done;
-
- if (MSIREG_OpenInstallProps(szProductCode, dwContext, NULL,
- &props, FALSE) != ERROR_SUCCESS)
- goto done;
-
- r = ERROR_UNKNOWN_PATCH;
-
- res = RegOpenKeyExW(udprod, szPatches, 0, KEY_WOW64_64KEY|KEY_READ, &patches);
- if (res != ERROR_SUCCESS)
- goto done;
-
- res = RegOpenKeyExW(patches, squished_patch, 0, KEY_WOW64_64KEY|KEY_READ, &patch);
- if (res != ERROR_SUCCESS)
- goto done;
-
- if (!strcmpW( szProperty, INSTALLPROPERTY_TRANSFORMSW ))
- {
- if (MSIREG_OpenProductKey(szProductCode, NULL, dwContext,
- &prod, FALSE) != ERROR_SUCCESS)
- goto done;
-
- res = RegOpenKeyExW(prod, szPatches, 0, KEY_WOW64_64KEY|KEY_ALL_ACCESS, &prodpatches);
- if (res != ERROR_SUCCESS)
- goto done;
-
- datakey = prodpatches;
- szProperty = squished_patch;
- }
- else
- {
- if (MSIREG_OpenUserDataPatchKey(szPatchCode, dwContext,
- &udpatch, FALSE) != ERROR_SUCCESS)
- goto done;
-
- if (!strcmpW( szProperty, INSTALLPROPERTY_LOCALPACKAGEW ))
- {
- if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
- szProperty = szManagedPackage;
- datakey = udpatch;
- }
- else if (!strcmpW( szProperty, INSTALLPROPERTY_INSTALLDATEW ))
- {
- datakey = patch;
- szProperty = szInstalled;
- }
- else if (!strcmpW( szProperty, INSTALLPROPERTY_LOCALPACKAGEW ))
- {
- datakey = udpatch;
- }
- else if (!strcmpW( szProperty, INSTALLPROPERTY_UNINSTALLABLEW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_PATCHSTATEW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_DISPLAYNAMEW ) ||
- !strcmpW( szProperty, INSTALLPROPERTY_MOREINFOURLW ))
- {
- datakey = patch;
- }
- else
- {
- r = ERROR_UNKNOWN_PROPERTY;
- goto done;
- }
- }
-
- val = msi_reg_get_val_str(datakey, szProperty);
- if (!val)
- val = strdupW(szEmpty);
-
- r = ERROR_SUCCESS;
-
- if (!pcchValue)
- goto done;
-
- if (lpValue)
- lstrcpynW(lpValue, val, *pcchValue);
-
- len = lstrlenW(val);
- if ((*val && *pcchValue < len + 1) || !lpValue)
- {
- if (lpValue)
- r = ERROR_MORE_DATA;
-
- *pcchValue = len * sizeof(WCHAR);
- }
-
- *pcchValue = len;
-
-done:
- msi_free(val);
- RegCloseKey(prodpatches);
- RegCloseKey(prod);
- RegCloseKey(patch);
- RegCloseKey(patches);
- RegCloseKey(udpatch);
- RegCloseKey(props);
- RegCloseKey(udprod);
-
- return r;
-}
-
-UINT WINAPI MsiGetPatchInfoA( LPCSTR patch, LPCSTR attr, LPSTR buffer, LPDWORD buflen )
-{
- UINT r = ERROR_OUTOFMEMORY;
- DWORD size;
- LPWSTR patchW = NULL, attrW = NULL, bufferW = NULL;
-
- TRACE("%s %s %p %p\n", debugstr_a(patch), debugstr_a(attr), buffer, buflen);
-
- if (!patch || !attr)
- return ERROR_INVALID_PARAMETER;
-
- if (!(patchW = strdupAtoW( patch )))
- goto done;
-
- if (!(attrW = strdupAtoW( attr )))
- goto done;
-
- size = 0;
- r = MsiGetPatchInfoW( patchW, attrW, NULL, &size );
- if (r != ERROR_SUCCESS)
- goto done;
-
- size++;
- if (!(bufferW = msi_alloc( size * sizeof(WCHAR) )))
- {
- r = ERROR_OUTOFMEMORY;
- goto done;
- }
-
- r = MsiGetPatchInfoW( patchW, attrW, bufferW, &size );
- if (r == ERROR_SUCCESS)
- {
- int len = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
- if (len > *buflen)
- r = ERROR_MORE_DATA;
- else if (buffer)
- WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, *buflen, NULL, NULL );
-
- *buflen = len - 1;
- }
-
-done:
- msi_free( patchW );
- msi_free( attrW );
- msi_free( bufferW );
- return r;
-}
-
-UINT WINAPI MsiGetPatchInfoW( LPCWSTR patch, LPCWSTR attr, LPWSTR buffer, LPDWORD buflen )
-{
- UINT r;
- WCHAR product[GUID_SIZE];
- DWORD index;
-
- TRACE("%s %s %p %p\n", debugstr_w(patch), debugstr_w(attr), buffer, buflen);
-
- if (!patch || !attr)
- return ERROR_INVALID_PARAMETER;
-
- if (strcmpW( INSTALLPROPERTY_LOCALPACKAGEW, attr ))
- return ERROR_UNKNOWN_PROPERTY;
-
- index = 0;
- while (1)
- {
- r = MsiEnumProductsW( index, product );
- if (r != ERROR_SUCCESS)
- break;
-
- r = MsiGetPatchInfoExW( patch, product, NULL, MSIINSTALLCONTEXT_USERMANAGED, attr, buffer, buflen );
- if (r == ERROR_SUCCESS || r == ERROR_MORE_DATA)
- return r;
-
- r = MsiGetPatchInfoExW( patch, product, NULL, MSIINSTALLCONTEXT_USERUNMANAGED, attr, buffer, buflen );
- if (r == ERROR_SUCCESS || r == ERROR_MORE_DATA)
- return r;
-
- r = MsiGetPatchInfoExW( patch, product, NULL, MSIINSTALLCONTEXT_MACHINE, attr, buffer, buflen );
- if (r == ERROR_SUCCESS || r == ERROR_MORE_DATA)
- return r;
-
- index++;
- }
-
- return ERROR_UNKNOWN_PRODUCT;
-}
-
UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
{
LPWSTR szwLogFile = NULL;
@@ -1416,235 +341,6 @@ UINT WINAPI MsiEnumComponentCostsW( MSIHANDLE handle, LPCWSTR component, DWORD i
return r;
}
-UINT WINAPI MsiQueryComponentStateA(LPCSTR szProductCode,
- LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext,
- LPCSTR szComponent, INSTALLSTATE *pdwState)
-{
- LPWSTR prodcode = NULL, usersid = NULL, comp = NULL;
- UINT r;
-
- TRACE("(%s, %s, %d, %s, %p)\n", debugstr_a(szProductCode),
- debugstr_a(szUserSid), dwContext, debugstr_a(szComponent), pdwState);
-
- if (szProductCode && !(prodcode = strdupAtoW(szProductCode)))
- return ERROR_OUTOFMEMORY;
-
- if (szUserSid && !(usersid = strdupAtoW(szUserSid)))
- return ERROR_OUTOFMEMORY;
-
- if (szComponent && !(comp = strdupAtoW(szComponent)))
- return ERROR_OUTOFMEMORY;
-
- r = MsiQueryComponentStateW(prodcode, usersid, dwContext, comp, pdwState);
-
- msi_free(prodcode);
- msi_free(usersid);
- msi_free(comp);
-
- return r;
-}
-
-static BOOL msi_comp_find_prod_key(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
-{
- UINT r;
- HKEY hkey = NULL;
-
- r = MSIREG_OpenProductKey(prodcode, NULL, context, &hkey, FALSE);
- RegCloseKey(hkey);
- return (r == ERROR_SUCCESS);
-}
-
-static BOOL msi_comp_find_package(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
-{
- LPCWSTR package;
- HKEY hkey;
- DWORD sz;
- LONG res;
- UINT r;
-
- static const WCHAR local_package[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
- static const WCHAR managed_local_package[] = {
- 'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0
- };
-
- r = MSIREG_OpenInstallProps(prodcode, context, NULL, &hkey, FALSE);
- if (r != ERROR_SUCCESS)
- return FALSE;
-
- if (context == MSIINSTALLCONTEXT_USERMANAGED)
- package = managed_local_package;
- else
- package = local_package;
-
- sz = 0;
- res = RegQueryValueExW(hkey, package, NULL, NULL, NULL, &sz);
- RegCloseKey(hkey);
-
- return (res == ERROR_SUCCESS);
-}
-
-static UINT msi_comp_find_prodcode(LPWSTR squished_pc,
- MSIINSTALLCONTEXT context,
- LPCWSTR comp, LPWSTR val, DWORD *sz)
-{
- HKEY hkey;
- LONG res;
- UINT r;
-
- if (context == MSIINSTALLCONTEXT_MACHINE)
- r = MSIREG_OpenUserDataComponentKey(comp, szLocalSid, &hkey, FALSE);
- else
- r = MSIREG_OpenUserDataComponentKey(comp, NULL, &hkey, FALSE);
-
- if (r != ERROR_SUCCESS)
- return r;
-
- res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, (BYTE *)val, sz);
- if (res != ERROR_SUCCESS)
- return res;
-
- RegCloseKey(hkey);
- return res;
-}
-
-UINT WINAPI MsiQueryComponentStateW(LPCWSTR szProductCode,
- LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
- LPCWSTR szComponent, INSTALLSTATE *pdwState)
-{
- WCHAR squished_pc[GUID_SIZE];
- BOOL found;
- DWORD sz;
-
- TRACE("(%s, %s, %d, %s, %p)\n", debugstr_w(szProductCode),
- debugstr_w(szUserSid), dwContext, debugstr_w(szComponent), pdwState);
-
- if (!pdwState || !szComponent)
- return ERROR_INVALID_PARAMETER;
-
- if (!szProductCode || !*szProductCode || lstrlenW(szProductCode) != GUID_SIZE - 1)
- return ERROR_INVALID_PARAMETER;
-
- if (!squash_guid(szProductCode, squished_pc))
- return ERROR_INVALID_PARAMETER;
-
- found = msi_comp_find_prod_key(szProductCode, dwContext);
-
- if (!msi_comp_find_package(szProductCode, dwContext))
- {
- if (found)
- {
- *pdwState = INSTALLSTATE_UNKNOWN;
- return ERROR_UNKNOWN_COMPONENT;
- }
-
- return ERROR_UNKNOWN_PRODUCT;
- }
-
- *pdwState = INSTALLSTATE_UNKNOWN;
-
- sz = 0;
- if (msi_comp_find_prodcode(squished_pc, dwContext, szComponent, NULL, &sz))
- return ERROR_UNKNOWN_COMPONENT;
-
- if (sz == 0)
- *pdwState = INSTALLSTATE_NOTUSED;
- else
- {
- WCHAR *val;
- UINT r;
-
- if (!(val = msi_alloc( sz ))) return ERROR_OUTOFMEMORY;
- if ((r = msi_comp_find_prodcode(squished_pc, dwContext, szComponent, val, &sz)))
- return r;
-
- if (lstrlenW(val) > 2 &&
- val[0] >= '0' && val[0] <= '9' && val[1] >= '0' && val[1] <= '9' && val[2] != ':')
- {
- *pdwState = INSTALLSTATE_SOURCE;
- }
- else
- *pdwState = INSTALLSTATE_LOCAL;
- msi_free( val );
- }
-
- TRACE("-> %d\n", *pdwState);
- return ERROR_SUCCESS;
-}
-
-INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
-{
- LPWSTR szwProduct = NULL;
- INSTALLSTATE r;
-
- if( szProduct )
- {
- szwProduct = strdupAtoW( szProduct );
- if( !szwProduct )
- return ERROR_OUTOFMEMORY;
- }
- r = MsiQueryProductStateW( szwProduct );
- msi_free( szwProduct );
- return r;
-}
-
-INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
-{
- MSIINSTALLCONTEXT context = MSIINSTALLCONTEXT_USERUNMANAGED;
- INSTALLSTATE state = INSTALLSTATE_ADVERTISED;
- HKEY prodkey = 0, userdata = 0;
- DWORD val;
- UINT r;
-
- TRACE("%s\n", debugstr_w(szProduct));
-
- if (!szProduct || !*szProduct)
- return INSTALLSTATE_INVALIDARG;
-
- if (lstrlenW(szProduct) != GUID_SIZE - 1)
- return INSTALLSTATE_INVALIDARG;
-
- if (szProduct[0] != '{' || szProduct[37] != '}')
- return INSTALLSTATE_UNKNOWN;
-
- SetLastError( ERROR_SUCCESS );
-
- if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
- &prodkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- &prodkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
- &prodkey, FALSE) == ERROR_SUCCESS)
- {
- context = MSIINSTALLCONTEXT_MACHINE;
- }
-
- r = MSIREG_OpenInstallProps(szProduct, context, NULL, &userdata, FALSE);
- if (r != ERROR_SUCCESS)
- goto done;
-
- if (!msi_reg_get_val_dword(userdata, szWindowsInstaller, &val))
- goto done;
-
- if (val)
- state = INSTALLSTATE_DEFAULT;
- else
- state = INSTALLSTATE_UNKNOWN;
-
-done:
- if (!prodkey)
- {
- state = INSTALLSTATE_UNKNOWN;
-
- if (userdata)
- state = INSTALLSTATE_ABSENT;
- }
-
- RegCloseKey(prodkey);
- RegCloseKey(userdata);
- TRACE("-> %d\n", state);
- return state;
-}
-
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
{
INSTALLUILEVEL old = gUILevel;
@@ -1778,38 +474,6 @@ LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
return r;
}
-INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
- LPDWORD pcchBuf)
-{
- char szProduct[GUID_SIZE];
-
- TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
-
- if (!szComponent || !pcchBuf)
- return INSTALLSTATE_INVALIDARG;
-
- if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
- return INSTALLSTATE_UNKNOWN;
-
- return MsiGetComponentPathA( szProduct, szComponent, lpPathBuf, pcchBuf );
-}
-
-INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
- LPDWORD pcchBuf)
-{
- WCHAR szProduct[GUID_SIZE];
-
- TRACE("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
-
- if (!szComponent || !pcchBuf)
- return INSTALLSTATE_INVALIDARG;
-
- if (MsiGetProductCodeW( szComponent, szProduct ) != ERROR_SUCCESS)
- return INSTALLSTATE_UNKNOWN;
-
- return MsiGetComponentPathW( szProduct, szComponent, lpPathBuf, pcchBuf );
-}
-
UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
WORD wLanguageId, DWORD f)
{
@@ -2050,289 +714,6 @@ UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
return r;
}
-static INSTALLSTATE MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
- awstring* lpPathBuf, LPDWORD pcchBuf)
-{
- static const WCHAR wininstaller[] =
- {'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
- WCHAR squished_pc[GUID_SIZE];
- WCHAR squished_comp[GUID_SIZE];
- HKEY hkey;
- LPWSTR path = NULL;
- INSTALLSTATE state;
- DWORD version;
-
- if (!szProduct || !szComponent)
- return INSTALLSTATE_INVALIDARG;
-
- if (lpPathBuf->str.w && !pcchBuf)
- return INSTALLSTATE_INVALIDARG;
-
- if (!squash_guid(szProduct, squished_pc) ||
- !squash_guid(szComponent, squished_comp))
- return INSTALLSTATE_INVALIDARG;
-
- state = INSTALLSTATE_UNKNOWN;
-
- if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
- {
- path = msi_reg_get_val_str(hkey, squished_pc);
- RegCloseKey(hkey);
-
- state = INSTALLSTATE_ABSENT;
-
- if ((MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE, NULL,
- &hkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenUserDataProductKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
- NULL, &hkey, FALSE) == ERROR_SUCCESS) &&
- msi_reg_get_val_dword(hkey, wininstaller, &version) &&
- GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
- {
- RegCloseKey(hkey);
- state = INSTALLSTATE_LOCAL;
- }
- }
-
- if (state != INSTALLSTATE_LOCAL &&
- (MSIREG_OpenProductKey(szProduct, NULL,
- MSIINSTALLCONTEXT_USERUNMANAGED,
- &hkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
- &hkey, FALSE) == ERROR_SUCCESS))
- {
- RegCloseKey(hkey);
-
- if (MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkey, FALSE) == ERROR_SUCCESS ||
- MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkey, FALSE) == ERROR_SUCCESS)
- {
- msi_free(path);
- path = msi_reg_get_val_str(hkey, squished_pc);
- RegCloseKey(hkey);
-
- state = INSTALLSTATE_ABSENT;
-
- if (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
- state = INSTALLSTATE_LOCAL;
- }
- }
-
- if (!path)
- return INSTALLSTATE_UNKNOWN;
-
- if (state == INSTALLSTATE_LOCAL && !*path)
- state = INSTALLSTATE_NOTUSED;
-
- msi_strcpy_to_awstring(path, lpPathBuf, pcchBuf);
- msi_free(path);
- return state;
-}
-
-/******************************************************************
- * MsiGetComponentPathW [MSI.@]
- */
-INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
- LPWSTR lpPathBuf, LPDWORD pcchBuf)
-{
- awstring path;
-
- TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szComponent), lpPathBuf, pcchBuf);
-
- path.unicode = TRUE;
- path.str.w = lpPathBuf;
-
- return MSI_GetComponentPath( szProduct, szComponent, &path, pcchBuf );
-}
-
-/******************************************************************
- * MsiGetComponentPathA [MSI.@]
- */
-INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
- LPSTR lpPathBuf, LPDWORD pcchBuf)
-{
- LPWSTR szwProduct, szwComponent = NULL;
- INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
- awstring path;
-
- TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szComponent), lpPathBuf, pcchBuf);
-
- szwProduct = strdupAtoW( szProduct );
- if( szProduct && !szwProduct)
- goto end;
-
- szwComponent = strdupAtoW( szComponent );
- if( szComponent && !szwComponent )
- goto end;
-
- path.unicode = FALSE;
- path.str.a = lpPathBuf;
-
- r = MSI_GetComponentPath( szwProduct, szwComponent, &path, pcchBuf );
-
-end:
- msi_free( szwProduct );
- msi_free( szwComponent );
-
- return r;
-}
-
-/******************************************************************
- * MsiQueryFeatureStateA [MSI.@]
- */
-INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
-{
- LPWSTR szwProduct = NULL, szwFeature= NULL;
- INSTALLSTATE rc = INSTALLSTATE_UNKNOWN;
-
- szwProduct = strdupAtoW( szProduct );
- if ( szProduct && !szwProduct )
- goto end;
-
- szwFeature = strdupAtoW( szFeature );
- if ( szFeature && !szwFeature )
- goto end;
-
- rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
-
-end:
- msi_free( szwProduct);
- msi_free( szwFeature);
-
- return rc;
-}
-
-/******************************************************************
- * MsiQueryFeatureStateW [MSI.@]
- *
- * Checks the state of a feature
- *
- * PARAMS
- * szProduct [I] Product's GUID string
- * szFeature [I] Feature's GUID string
- *
- * RETURNS
- * INSTALLSTATE_LOCAL Feature is installed and usable
- * INSTALLSTATE_ABSENT Feature is absent
- * INSTALLSTATE_ADVERTISED Feature should be installed on demand
- * INSTALLSTATE_UNKNOWN An error occurred
- * INSTALLSTATE_INVALIDARG One of the GUIDs was invalid
- *
- */
-INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
-{
- WCHAR squishProduct[33], comp[GUID_SIZE];
- GUID guid;
- LPWSTR components, p, parent_feature, path;
- UINT rc;
- HKEY hkey;
- INSTALLSTATE r;
- BOOL missing = FALSE;
- BOOL machine = FALSE;
- BOOL source = FALSE;
-
- TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
-
- if (!szProduct || !szFeature)
- return INSTALLSTATE_INVALIDARG;
-
- if (!squash_guid( szProduct, squishProduct ))
- return INSTALLSTATE_INVALIDARG;
-
- SetLastError( ERROR_SUCCESS );
-
- if (MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERMANAGED,
- &hkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
- &hkey, FALSE) != ERROR_SUCCESS)
- {
- rc = MSIREG_OpenFeaturesKey(szProduct, MSIINSTALLCONTEXT_MACHINE,
- &hkey, FALSE);
- if (rc != ERROR_SUCCESS)
- return INSTALLSTATE_UNKNOWN;
-
- machine = TRUE;
- }
-
- parent_feature = msi_reg_get_val_str( hkey, szFeature );
- RegCloseKey(hkey);
-
- if (!parent_feature)
- return INSTALLSTATE_UNKNOWN;
-
- r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
- msi_free(parent_feature);
- if (r == INSTALLSTATE_ABSENT)
- return r;
-
- if (machine)
- rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
- MSIINSTALLCONTEXT_MACHINE,
- &hkey, FALSE);
- else
- rc = MSIREG_OpenUserDataFeaturesKey(szProduct,
- MSIINSTALLCONTEXT_USERUNMANAGED,
- &hkey, FALSE);
-
- if (rc != ERROR_SUCCESS)
- return INSTALLSTATE_ADVERTISED;
-
- components = msi_reg_get_val_str( hkey, szFeature );
- RegCloseKey(hkey);
-
- TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
-
- if (!components)
- return INSTALLSTATE_ADVERTISED;
-
- for( p = components; *p && *p != 2 ; p += 20)
- {
- if (!decode_base85_guid( p, &guid ))
- {
- if (p != components)
- break;
-
- msi_free(components);
- return INSTALLSTATE_BADCONFIG;
- }
-
- StringFromGUID2(&guid, comp, GUID_SIZE);
-
- if (machine)
- rc = MSIREG_OpenUserDataComponentKey(comp, szLocalSid, &hkey, FALSE);
- else
- rc = MSIREG_OpenUserDataComponentKey(comp, NULL, &hkey, FALSE);
-
- if (rc != ERROR_SUCCESS)
- {
- msi_free(components);
- return INSTALLSTATE_ADVERTISED;
- }
-
- path = msi_reg_get_val_str(hkey, squishProduct);
- if (!path)
- missing = TRUE;
- else if (lstrlenW(path) > 2 &&
- path[0] >= '0' && path[0] <= '9' &&
- path[1] >= '0' && path[1] <= '9')
- {
- source = TRUE;
- }
-
- msi_free(path);
- }
- msi_free(components);
-
- if (missing)
- r = INSTALLSTATE_ADVERTISED;
- else if (source)
- r = INSTALLSTATE_SOURCE;
- else
- r = INSTALLSTATE_LOCAL;
-
- TRACE("-> %d\n", r);
- return r;
-}
-
/***********************************************************************
* MsiGetFeatureUsageW [MSI.@]
*/
@@ -2374,364 +755,6 @@ end:
}
/***********************************************************************
- * MsiUseFeatureExW [MSI.@]
- */
-INSTALLSTATE WINAPI MsiUseFeatureExW( LPCWSTR szProduct, LPCWSTR szFeature,
- DWORD dwInstallMode, DWORD dwReserved )
-{
- INSTALLSTATE state;
-
- TRACE("%s %s %i %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
- dwInstallMode, dwReserved);
-
- state = MsiQueryFeatureStateW( szProduct, szFeature );
-
- if (dwReserved)
- return INSTALLSTATE_INVALIDARG;
-
- if (state == INSTALLSTATE_LOCAL && dwInstallMode != INSTALLMODE_NODETECTION)
- {
- FIXME("mark product %s feature %s as used\n",
- debugstr_w(szProduct), debugstr_w(szFeature) );
- }
-
- return state;
-}
-
-/***********************************************************************
- * MsiUseFeatureExA [MSI.@]
- */
-INSTALLSTATE WINAPI MsiUseFeatureExA( LPCSTR szProduct, LPCSTR szFeature,
- DWORD dwInstallMode, DWORD dwReserved )
-{
- INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
- LPWSTR prod = NULL, feat = NULL;
-
- TRACE("%s %s %i %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
- dwInstallMode, dwReserved);
-
- prod = strdupAtoW( szProduct );
- if (szProduct && !prod)
- goto end;
-
- feat = strdupAtoW( szFeature );
- if (szFeature && !feat)
- goto end;
-
- ret = MsiUseFeatureExW( prod, feat, dwInstallMode, dwReserved );
-
-end:
- msi_free( prod );
- msi_free( feat );
-
- return ret;
-}
-
-/***********************************************************************
- * MsiUseFeatureW [MSI.@]
- */
-INSTALLSTATE WINAPI MsiUseFeatureW( LPCWSTR szProduct, LPCWSTR szFeature )
-{
- return MsiUseFeatureExW(szProduct, szFeature, 0, 0);
-}
-
-/***********************************************************************
- * MsiUseFeatureA [MSI.@]
- */
-INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
-{
- return MsiUseFeatureExA(szProduct, szFeature, 0, 0);
-}
-
-/***********************************************************************
- * MSI_ProvideQualifiedComponentEx [internal]
- */
-static UINT MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
- LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
- DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
- LPDWORD pcchPathBuf)
-{
- WCHAR product[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1],
- feature[MAX_FEATURE_CHARS+1];
- LPWSTR info;
- HKEY hkey;
- DWORD sz;
- UINT rc;
-
- rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
- if (rc != ERROR_SUCCESS)
- return ERROR_INDEX_ABSENT;
-
- info = msi_reg_get_val_str( hkey, szQualifier );
- RegCloseKey(hkey);
-
- if (!info)
- return ERROR_INDEX_ABSENT;
-
- MsiDecomposeDescriptorW(info, product, feature, component, &sz);
-
- if (!szProduct)
- rc = MSI_GetComponentPath(product, component, lpPathBuf, pcchPathBuf);
- else
- rc = MSI_GetComponentPath(szProduct, component, lpPathBuf, pcchPathBuf);
-
- msi_free( info );
-
- if (rc != INSTALLSTATE_LOCAL)
- return ERROR_FILE_NOT_FOUND;
-
- return ERROR_SUCCESS;
-}
-
-/***********************************************************************
- * MsiProvideQualifiedComponentExW [MSI.@]
- */
-UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
- LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
- DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
- LPDWORD pcchPathBuf)
-{
- awstring path;
-
- TRACE("%s %s %u %s %u %u %p %p\n", debugstr_w(szComponent),
- debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
- Unused1, Unused2, lpPathBuf, pcchPathBuf);
-
- path.unicode = TRUE;
- path.str.w = lpPathBuf;
-
- return MSI_ProvideQualifiedComponentEx(szComponent, szQualifier,
- dwInstallMode, szProduct, Unused1, Unused2, &path, pcchPathBuf);
-}
-
-/***********************************************************************
- * MsiProvideQualifiedComponentExA [MSI.@]
- */
-UINT WINAPI MsiProvideQualifiedComponentExA(LPCSTR szComponent,
- LPCSTR szQualifier, DWORD dwInstallMode, LPCSTR szProduct,
- DWORD Unused1, DWORD Unused2, LPSTR lpPathBuf,
- LPDWORD pcchPathBuf)
-{
- LPWSTR szwComponent, szwQualifier = NULL, szwProduct = NULL;
- UINT r = ERROR_OUTOFMEMORY;
- awstring path;
-
- TRACE("%s %s %u %s %u %u %p %p\n", debugstr_a(szComponent),
- debugstr_a(szQualifier), dwInstallMode, debugstr_a(szProduct),
- Unused1, Unused2, lpPathBuf, pcchPathBuf);
-
- szwComponent = strdupAtoW( szComponent );
- if (szComponent && !szwComponent)
- goto end;
-
- szwQualifier = strdupAtoW( szQualifier );
- if (szQualifier && !szwQualifier)
- goto end;
-
- szwProduct = strdupAtoW( szProduct );
- if (szProduct && !szwProduct)
- goto end;
-
- path.unicode = FALSE;
- path.str.a = lpPathBuf;
-
- r = MSI_ProvideQualifiedComponentEx(szwComponent, szwQualifier,
- dwInstallMode, szwProduct, Unused1,
- Unused2, &path, pcchPathBuf);
-end:
- msi_free(szwProduct);
- msi_free(szwComponent);
- msi_free(szwQualifier);
-
- return r;
-}
-
-/***********************************************************************
- * MsiProvideQualifiedComponentW [MSI.@]
- */
-UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
- LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
- LPDWORD pcchPathBuf)
-{
- return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
- dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
-}
-
-/***********************************************************************
- * MsiProvideQualifiedComponentA [MSI.@]
- */
-UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
- LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
- LPDWORD pcchPathBuf)
-{
- return MsiProvideQualifiedComponentExA(szComponent, szQualifier,
- dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
-}
-
-/***********************************************************************
- * MSI_GetUserInfo [internal]
- */
-static USERINFOSTATE MSI_GetUserInfo(LPCWSTR szProduct,
- awstring *lpUserNameBuf, LPDWORD pcchUserNameBuf,
- awstring *lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
- awstring *lpSerialBuf, LPDWORD pcchSerialBuf)
-{
- WCHAR squished_pc[SQUISH_GUID_SIZE];
- LPWSTR user, org, serial;
- USERINFOSTATE state;
- HKEY hkey, props;
- LPCWSTR orgptr;
- UINT r;
-
- TRACE("%s %p %p %p %p %p %p\n", debugstr_w(szProduct), lpUserNameBuf,
- pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
- pcchSerialBuf);
-
- if (!szProduct || !squash_guid(szProduct, squished_pc))
- return USERINFOSTATE_INVALIDARG;
-
- if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
- &hkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- &hkey, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
- &hkey, FALSE) != ERROR_SUCCESS)
- {
- return USERINFOSTATE_UNKNOWN;
- }
-
- if (MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_USERUNMANAGED,
- NULL, &props, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenInstallProps(szProduct, MSIINSTALLCONTEXT_MACHINE,
- NULL, &props, FALSE) != ERROR_SUCCESS)
- {
- RegCloseKey(hkey);
- return USERINFOSTATE_ABSENT;
- }
-
- user = msi_reg_get_val_str(props, INSTALLPROPERTY_REGOWNERW);
- org = msi_reg_get_val_str(props, INSTALLPROPERTY_REGCOMPANYW);
- serial = msi_reg_get_val_str(props, INSTALLPROPERTY_PRODUCTIDW);
- state = USERINFOSTATE_ABSENT;
-
- RegCloseKey(hkey);
- RegCloseKey(props);
-
- if (user && serial)
- state = USERINFOSTATE_PRESENT;
-
- if (pcchUserNameBuf)
- {
- if (lpUserNameBuf && !user)
- {
- (*pcchUserNameBuf)--;
- goto done;
- }
-
- r = msi_strcpy_to_awstring(user, lpUserNameBuf, pcchUserNameBuf);
- if (r == ERROR_MORE_DATA)
- {
- state = USERINFOSTATE_MOREDATA;
- goto done;
- }
- }
-
- if (pcchOrgNameBuf)
- {
- orgptr = org;
- if (!orgptr) orgptr = szEmpty;
-
- r = msi_strcpy_to_awstring(orgptr, lpOrgNameBuf, pcchOrgNameBuf);
- if (r == ERROR_MORE_DATA)
- {
- state = USERINFOSTATE_MOREDATA;
- goto done;
- }
- }
-
- if (pcchSerialBuf)
- {
- if (!serial)
- {
- (*pcchSerialBuf)--;
- goto done;
- }
-
- r = msi_strcpy_to_awstring(serial, lpSerialBuf, pcchSerialBuf);
- if (r == ERROR_MORE_DATA)
- state = USERINFOSTATE_MOREDATA;
- }
-
-done:
- msi_free(user);
- msi_free(org);
- msi_free(serial);
-
- return state;
-}
-
-/***********************************************************************
- * MsiGetUserInfoW [MSI.@]
- */
-USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct,
- LPWSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
- LPWSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
- LPWSTR lpSerialBuf, LPDWORD pcchSerialBuf)
-{
- awstring user, org, serial;
-
- if ((lpUserNameBuf && !pcchUserNameBuf) ||
- (lpOrgNameBuf && !pcchOrgNameBuf) ||
- (lpSerialBuf && !pcchSerialBuf))
- return USERINFOSTATE_INVALIDARG;
-
- user.unicode = TRUE;
- user.str.w = lpUserNameBuf;
- org.unicode = TRUE;
- org.str.w = lpOrgNameBuf;
- serial.unicode = TRUE;
- serial.str.w = lpSerialBuf;
-
- return MSI_GetUserInfo( szProduct, &user, pcchUserNameBuf,
- &org, pcchOrgNameBuf,
- &serial, pcchSerialBuf );
-}
-
-USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct,
- LPSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
- LPSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
- LPSTR lpSerialBuf, LPDWORD pcchSerialBuf)
-{
- awstring user, org, serial;
- LPWSTR prod;
- UINT r;
-
- if ((lpUserNameBuf && !pcchUserNameBuf) ||
- (lpOrgNameBuf && !pcchOrgNameBuf) ||
- (lpSerialBuf && !pcchSerialBuf))
- return USERINFOSTATE_INVALIDARG;
-
- prod = strdupAtoW( szProduct );
- if (szProduct && !prod)
- return ERROR_OUTOFMEMORY;
-
- user.unicode = FALSE;
- user.str.a = lpUserNameBuf;
- org.unicode = FALSE;
- org.str.a = lpOrgNameBuf;
- serial.unicode = FALSE;
- serial.str.a = lpSerialBuf;
-
- r = MSI_GetUserInfo( prod, &user, pcchUserNameBuf,
- &org, pcchOrgNameBuf,
- &serial, pcchSerialBuf );
-
- msi_free( prod );
-
- return r;
-}
-
-/***********************************************************************
* MsiCreateAndVerifyInstallerDirectory [MSI.@]
*
* Notes: undocumented
diff --git a/libmsi/package.c b/libmsi/package.c
index 9bc7ff1..840040f 100644
--- a/libmsi/package.c
+++ b/libmsi/package.c
@@ -409,113 +409,6 @@ static void MSI_FreePackage( MSIOBJECTHDR *arg)
msi_free( package->localfile );
}
-static UINT create_temp_property_table(MSIPACKAGE *package)
-{
- static const WCHAR query[] = {
- 'C','R','E','A','T','E',' ','T','A','B','L','E',' ',
- '`','_','P','r','o','p','e','r','t','y','`',' ','(',' ',
- '`','_','P','r','o','p','e','r','t','y','`',' ',
- 'C','H','A','R','(','5','6',')',' ','N','O','T',' ','N','U','L','L',' ',
- 'T','E','M','P','O','R','A','R','Y',',',' ',
- '`','V','a','l','u','e','`',' ','C','H','A','R','(','9','8',')',' ',
- 'N','O','T',' ','N','U','L','L',' ','T','E','M','P','O','R','A','R','Y',
- ' ','P','R','I','M','A','R','Y',' ','K','E','Y',' ',
- '`','_','P','r','o','p','e','r','t','y','`',')',' ','H','O','L','D',0};
- MSIQUERY *view;
- UINT rc;
-
- rc = MSI_DatabaseOpenViewW(package->db, query, &view);
- if (rc != ERROR_SUCCESS)
- return rc;
-
- rc = MSI_ViewExecute(view, 0);
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
- return rc;
-}
-
-UINT msi_clone_properties(MSIPACKAGE *package)
-{
- static const WCHAR query_select[] = {
- 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','P','r','o','p','e','r','t','y','`',0};
- static const WCHAR query_insert[] = {
- 'I','N','S','E','R','T',' ','I','N','T','O',' ',
- '`','_','P','r','o','p','e','r','t','y','`',' ',
- '(','`','_','P','r','o','p','e','r','t','y','`',',','`','V','a','l','u','e','`',')',' ',
- 'V','A','L','U','E','S',' ','(','?',',','?',')',0};
- static const WCHAR query_update[] = {
- 'U','P','D','A','T','E',' ','`','_','P','r','o','p','e','r','t','y','`',' ',
- 'S','E','T',' ','`','V','a','l','u','e','`',' ','=',' ','?',' ',
- 'W','H','E','R','E',' ','`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','?',0};
- MSIQUERY *view_select;
- UINT rc;
-
- rc = MSI_DatabaseOpenViewW( package->db, query_select, &view_select );
- if (rc != ERROR_SUCCESS)
- return rc;
-
- rc = MSI_ViewExecute( view_select, 0 );
- if (rc != ERROR_SUCCESS)
- {
- MSI_ViewClose( view_select );
- msiobj_release( &view_select->hdr );
- return rc;
- }
-
- while (1)
- {
- MSIQUERY *view_insert, *view_update;
- MSIRECORD *rec_select;
-
- rc = MSI_ViewFetch( view_select, &rec_select );
- if (rc != ERROR_SUCCESS)
- break;
-
- rc = MSI_DatabaseOpenViewW( package->db, query_insert, &view_insert );
- if (rc != ERROR_SUCCESS)
- {
- msiobj_release( &rec_select->hdr );
- continue;
- }
-
- rc = MSI_ViewExecute( view_insert, rec_select );
- MSI_ViewClose( view_insert );
- msiobj_release( &view_insert->hdr );
- if (rc != ERROR_SUCCESS)
- {
- MSIRECORD *rec_update;
-
- TRACE("insert failed, trying update\n");
-
- rc = MSI_DatabaseOpenViewW( package->db, query_update, &view_update );
- if (rc != ERROR_SUCCESS)
- {
- WARN("open view failed %u\n", rc);
- msiobj_release( &rec_select->hdr );
- continue;
- }
-
- rec_update = MSI_CreateRecord( 2 );
- MSI_RecordCopyField( rec_select, 1, rec_update, 2 );
- MSI_RecordCopyField( rec_select, 2, rec_update, 1 );
- rc = MSI_ViewExecute( view_update, rec_update );
- if (rc != ERROR_SUCCESS)
- WARN("update failed %u\n", rc);
-
- MSI_ViewClose( view_update );
- msiobj_release( &view_update->hdr );
- msiobj_release( &rec_update->hdr );
- }
-
- msiobj_release( &rec_select->hdr );
- }
-
- MSI_ViewClose( view_select );
- msiobj_release( &view_select->hdr );
- return rc;
-}
-
static UINT set_user_sid_prop( MSIPACKAGE *package )
{
SID_NAME_USE use;
@@ -687,17 +580,6 @@ static UINT msi_load_admin_properties(MSIPACKAGE *package)
#endif
}
-void msi_adjust_privilege_properties( MSIPACKAGE *package )
-{
- /* FIXME: this should depend on the user's privileges */
- if (msi_get_property_int( package->db, szAllUsers, 0 ) == 2)
- {
- TRACE("resetting ALLUSERS property from 2 to 1\n");
- msi_set_property( package->db, szAllUsers, szOne );
- }
- msi_set_property( package->db, szAdminUser, szOne );
-}
-
MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
{
static const WCHAR fmtW[] = {'%','u',0};
@@ -717,10 +599,6 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
package->PackagePath = strdupW( db->path );
package->BaseURL = strdupW( base_url );
- create_temp_property_table( package );
- msi_clone_properties( package );
- msi_adjust_privilege_properties( package );
-
package->ProductCode = msi_dup_property( package->db, szProductCode );
package->script = msi_alloc_zero( sizeof(MSISCRIPT) );
@@ -931,50 +809,6 @@ static WCHAR *get_product_code( MSIDATABASE *db )
return ret;
}
-static UINT get_registered_local_package( const WCHAR *product, const WCHAR *package, WCHAR *localfile )
-{
- MSIINSTALLCONTEXT context;
- HKEY product_key, props_key;
- WCHAR *registered_package = NULL, unsquashed[GUID_SIZE];
- UINT r;
-
- r = msi_locate_product( product, &context );
- if (r != ERROR_SUCCESS)
- return r;
-
- r = MSIREG_OpenProductKey( product, NULL, context, &product_key, FALSE );
- if (r != ERROR_SUCCESS)
- return r;
-
- r = MSIREG_OpenInstallProps( product, context, NULL, &props_key, FALSE );
- if (r != ERROR_SUCCESS)
- {
- RegCloseKey( product_key );
- return r;
- }
- r = ERROR_FUNCTION_FAILED;
- registered_package = msi_reg_get_val_str( product_key, INSTALLPROPERTY_PACKAGECODEW );
- if (!registered_package)
- goto done;
-
- unsquash_guid( registered_package, unsquashed );
- if (!strcmpiW( package, unsquashed ))
- {
- WCHAR *filename = msi_reg_get_val_str( props_key, INSTALLPROPERTY_LOCALPACKAGEW );
- if (!filename)
- goto done;
-
- strcpyW( localfile, filename );
- msi_free( filename );
- r = ERROR_SUCCESS;
- }
-done:
- msi_free( registered_package );
- RegCloseKey( props_key );
- RegCloseKey( product_key );
- return r;
-}
-
static WCHAR *get_package_code( MSIDATABASE *db )
{
WCHAR *ret;
@@ -990,50 +824,6 @@ static WCHAR *get_package_code( MSIDATABASE *db )
return ret;
}
-static UINT get_local_package( const WCHAR *filename, WCHAR *localfile )
-{
- WCHAR *product_code, *package_code;
- MSIDATABASE *db;
- UINT r;
-
- if ((r = MSI_OpenDatabaseW( filename, MSIDBOPEN_READONLY, &db )) != ERROR_SUCCESS)
- {
- if (GetFileAttributesW( filename ) == INVALID_FILE_ATTRIBUTES)
- return ERROR_FILE_NOT_FOUND;
- return r;
- }
- if (!(product_code = get_product_code( db )))
- {
- msiobj_release( &db->hdr );
- return ERROR_INSTALL_PACKAGE_INVALID;
- }
- if (!(package_code = get_package_code( db )))
- {
- msi_free( product_code );
- msiobj_release( &db->hdr );
- return ERROR_INSTALL_PACKAGE_INVALID;
- }
- r = get_registered_local_package( product_code, package_code, localfile );
- msi_free( package_code );
- msi_free( product_code );
- msiobj_release( &db->hdr );
- return r;
-}
-
-static UINT msi_set_context(MSIPACKAGE *package)
-{
- UINT r = msi_locate_product( package->ProductCode, &package->Context );
- if (r != ERROR_SUCCESS)
- {
- int num = msi_get_property_int( package->db, szAllUsers, 0 );
- if (num == 1 || num == 2)
- package->Context = MSIINSTALLCONTEXT_MACHINE;
- else
- package->Context = MSIINSTALLCONTEXT_USERUNMANAGED;
- }
- return ERROR_SUCCESS;
-}
-
UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
{
static const WCHAR dotmsi[] = {'.','m','s','i',0};
@@ -1060,24 +850,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
}
else
{
- r = get_local_package( file, localfile );
- if (r != ERROR_SUCCESS || GetFileAttributesW( localfile ) == INVALID_FILE_ATTRIBUTES)
- {
- r = msi_create_empty_local_file( localfile, dotmsi );
- if (r != ERROR_SUCCESS)
- return r;
-
- if (!CopyFileW( file, localfile, FALSE ))
- {
- r = GetLastError();
- WARN("unable to copy package %s to %s (%u)\n", debugstr_w(file), debugstr_w(localfile), r);
- DeleteFileW( localfile );
- return r;
- }
- delete_on_close = TRUE;
- }
- TRACE("opening package %s\n", debugstr_w( localfile ));
- r = MSI_OpenDatabaseW( localfile, MSIDBOPEN_TRANSACT, &db );
+ r = MSI_OpenDatabaseW( file, MSIDBOPEN_TRANSACT, &db );
if (r != ERROR_SUCCESS)
return r;
}
@@ -1120,32 +893,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
GetFullPathNameW( szPackage, MAX_PATH, fullpath, NULL );
msi_set_property( package->db, szOriginalDatabase, fullpath );
}
- msi_set_context( package );
- while (1)
- {
- WCHAR patch_code[GUID_SIZE];
- r = MsiEnumPatchesExW( package->ProductCode, NULL, package->Context,
- MSIPATCHSTATE_APPLIED, index, patch_code, NULL, NULL, NULL, NULL );
- if (r != ERROR_SUCCESS)
- break;
-
- TRACE("found registered patch %s\n", debugstr_w(patch_code));
-
- r = msi_apply_registered_patch( package, patch_code );
- if (r != ERROR_SUCCESS)
- {
- ERR("registered patch failed to apply %u\n", r);
- msiobj_release( &package->hdr );
- return r;
- }
- index++;
- }
- if (index)
- {
- msi_clone_properties( package );
- msi_adjust_privilege_properties( package );
- }
if (gszLogFile)
package->log_file = CreateFileW( gszLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
diff --git a/libmsi/patch.c b/libmsi/patch.c
index 9410bb7..ca2458d 100644
--- a/libmsi/patch.c
+++ b/libmsi/patch.c
@@ -764,57 +764,3 @@ UINT msi_apply_transforms( MSIPACKAGE *package )
msi_free( xform_list );
return r;
}
-
-UINT msi_apply_registered_patch( MSIPACKAGE *package, LPCWSTR patch_code )
-{
- UINT r;
- DWORD len;
- WCHAR patch_file[MAX_PATH];
- MSIDATABASE *patch_db;
- MSIPATCHINFO *patch_info;
- MSISUMMARYINFO *si;
-
- len = sizeof(patch_file) / sizeof(WCHAR);
- r = MsiGetPatchInfoExW( patch_code, package->ProductCode, NULL, package->Context,
- INSTALLPROPERTY_LOCALPACKAGEW, patch_file, &len );
- if (r != ERROR_SUCCESS)
- {
- ERR("failed to get patch filename %u\n", r);
- return r;
- }
- r = MSI_OpenDatabaseW( patch_file, MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE, &patch_db );
- if (r != ERROR_SUCCESS)
- {
- ERR("failed to open patch database %s\n", debugstr_w( patch_file ));
- return r;
- }
- si = MSI_GetSummaryInformationW( patch_db->storage, 0 );
- if (!si)
- {
- msiobj_release( &patch_db->hdr );
- return ERROR_FUNCTION_FAILED;
- }
- r = msi_parse_patch_summary( si, &patch_info );
- msiobj_release( &si->hdr );
- if (r != ERROR_SUCCESS)
- {
- ERR("failed to parse patch summary %u\n", r);
- msiobj_release( &patch_db->hdr );
- return r;
- }
- patch_info->localfile = strdupW( patch_file );
- if (!patch_info->localfile)
- {
- msiobj_release( &patch_db->hdr );
- msi_free_patchinfo( patch_info );
- return ERROR_OUTOFMEMORY;
- }
- r = msi_apply_patch_db( package, patch_db, patch_info );
- msiobj_release( &patch_db->hdr );
- if (r != ERROR_SUCCESS)
- {
- ERR("failed to apply patch %u\n", r);
- msi_free_patchinfo( patch_info );
- }
- return r;
-}
diff --git a/libmsi/registry.c b/libmsi/registry.c
deleted file mode 100644
index 3418547..0000000
--- a/libmsi/registry.c
+++ /dev/null
@@ -1,2479 +0,0 @@
-/*
- * Implementation of the Microsoft Installer (msi.dll)
- *
- * Copyright 2005 Mike McCormack for CodeWeavers
- * Copyright 2005 Aric Stewart for CodeWeavers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <stdarg.h>
-
-#define COBJMACROS
-#define NONAMELESSUNION
-
-#include "windef.h"
-#include "winbase.h"
-#include "winreg.h"
-#include "winnls.h"
-#include "shlwapi.h"
-#include "wine/debug.h"
-#include "msi.h"
-#include "msipriv.h"
-#include "wincrypt.h"
-#include "wine/unicode.h"
-#include "winver.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "sddl.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(msi);
-
-/*
- * This module will be all the helper functions for registry access by the
- * installer bits.
- */
-
-static const WCHAR szUserDataFeatures_fmt[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
- '%','s','\\','P','r','o','d','u','c','t','s','\\','%','s','\\','F','e','a','t','u','r','e','s',0};
-
-static const WCHAR szUserDataComp_fmt[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
- '%','s','\\','C','o','m','p','o','n','e','n','t','s','\\','%','s',0};
-
-static const WCHAR szUserDataComponents_fmt[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
- '%','s','\\','C','o','m','p','o','n','e','n','t','s',0};
-
-static const WCHAR szUserDataProd_fmt[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
- '%','s','\\','P','r','o','d','u','c','t','s','\\','%','s',0};
-
-static const WCHAR szUserDataProducts_fmt[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
- '%','s','\\','P','r','o','d','u','c','t','s',0};
-
-static const WCHAR szUserDataPatch_fmt[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
- '%','s','\\','P','a','t','c','h','e','s','\\','%','s',0};
-
-static const WCHAR szUserDataPatches_fmt[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
- '%','s','\\','P','a','t','c','h','e','s',0};
-
-static const WCHAR szUserDataProductPatches_fmt[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
- '%','s','\\','P','r','o','d','u','c','t','s','\\','%','s','\\','P','a','t','c','h','e','s',0};
-
-static const WCHAR szInstallProperties_fmt[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
- '%','s','\\','P','r','o','d','u','c','t','s','\\','%','s','\\',
- 'I','n','s','t','a','l','l','P','r','o','p','e','r','t','i','e','s',0};
-
-static const WCHAR szInstaller_LocalManaged_fmt[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','M','a','n','a','g','e','d','\\','%','s','\\',
- 'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s',0};
-
-static const WCHAR szInstaller_LocalManagedProd_fmt[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','M','a','n','a','g','e','d','\\','%','s','\\',
- 'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s','\\','%','s',0};
-
-static const WCHAR szInstaller_LocalManagedFeat_fmt[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','M','a','n','a','g','e','d','\\','%','s','\\',
- 'I','n','s','t','a','l','l','e','r','\\','F','e','a','t','u','r','e','s','\\','%','s',0};
-
-static const WCHAR szInstaller_Products[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s',0};
-
-static const WCHAR szInstaller_Patches[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','P','a','t','c','h','e','s',0};
-
-static const WCHAR szInstaller_Components[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','C','o','m','p','o','n','e','n','t','s',0};
-
-static const WCHAR szInstaller_LocalClassesProducts[] = {
- 'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
- 'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s',0};
-
-static const WCHAR szInstaller_LocalClassesFeatures[] = {
- 'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
- 'I','n','s','t','a','l','l','e','r','\\','F','e','a','t','u','r','e','s',0};
-
-static const WCHAR szInstaller_LocalClassesProd[] = {
- 'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
- 'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s','\\',0};
-
-static const WCHAR szInstaller_LocalClassesFeat[] = {
- 'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
- 'I','n','s','t','a','l','l','e','r','\\','F','e','a','t','u','r','e','s','\\',0};
-
-static const WCHAR szInstaller_ClassesUpgradeCode[] = {
- 'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','p','g','r','a','d','e','C','o','d','e','s','\\',0};
-
-static const WCHAR szInstaller_ClassesUpgradeCodes[] = {
- 'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','p','g','r','a','d','e','C','o','d','e','s',0};
-
-static const WCHAR szInstaller_Features[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','F','e','a','t','u','r','e','s','\\',0};
-
-static const WCHAR szInstaller_UpgradeCodes[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','p','g','r','a','d','e','C','o','d','e','s','\\',0};
-
-static const WCHAR szInstaller_UserUpgradeCodes[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','p','g','r','a','d','e','C','o','d','e','s','\\',0};
-
-static const WCHAR szUninstall[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'U','n','i','n','s','t','a','l','l','\\',0};
-
-static const WCHAR szUninstall_32node[] = {
- 'S','o','f','t','w','a','r','e','\\','W','o','w','6','4','3','2','N','o','d','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
- 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','U','n','i','n','s','t','a','l','l','\\',0};
-
-static const WCHAR szUserComponents[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'I','n','s','t','a','l','l','e','r','\\','C','o','m','p','o','n','e','n','t','s','\\',0};
-
-static const WCHAR szUserFeatures[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'I','n','s','t','a','l','l','e','r','\\','F','e','a','t','u','r','e','s','\\',0};
-
-static const WCHAR szUserProducts[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s','\\',0};
-
-static const WCHAR szUserPatches[] = {
- 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'I','n','s','t','a','l','l','e','r','\\','P','a','t','c','h','e','s','\\',0};
-
-BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
-{
- DWORD i,n=0;
-
- if (lstrlenW(in) != 32)
- return FALSE;
-
- out[n++]='{';
- for(i=0; i<8; i++)
- out[n++] = in[7-i];
- out[n++]='-';
- for(i=0; i<4; i++)
- out[n++] = in[11-i];
- out[n++]='-';
- for(i=0; i<4; i++)
- out[n++] = in[15-i];
- out[n++]='-';
- for(i=0; i<2; i++)
- {
- out[n++] = in[17+i*2];
- out[n++] = in[16+i*2];
- }
- out[n++]='-';
- for( ; i<8; i++)
- {
- out[n++] = in[17+i*2];
- out[n++] = in[16+i*2];
- }
- out[n++]='}';
- out[n]=0;
- return TRUE;
-}
-
-BOOL squash_guid(LPCWSTR in, LPWSTR out)
-{
- DWORD i,n=1;
- GUID guid;
-
- out[0] = 0;
-
- if (FAILED(CLSIDFromString((LPCOLESTR)in, &guid)))
- return FALSE;
-
- for(i=0; i<8; i++)
- out[7-i] = in[n++];
- n++;
- for(i=0; i<4; i++)
- out[11-i] = in[n++];
- n++;
- for(i=0; i<4; i++)
- out[15-i] = in[n++];
- n++;
- for(i=0; i<2; i++)
- {
- out[17+i*2] = in[n++];
- out[16+i*2] = in[n++];
- }
- n++;
- for( ; i<8; i++)
- {
- out[17+i*2] = in[n++];
- out[16+i*2] = in[n++];
- }
- out[32]=0;
- return TRUE;
-}
-
-
-/* tables for encoding and decoding base85 */
-static const unsigned char table_dec85[0x80] = {
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0x00,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0xff,
-0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0xff,0xff,0xff,0x16,0xff,0x17,
-0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
-0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0x34,0x35,0x36,
-0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,
-0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0xff,0x53,0x54,0xff,
-};
-
-static const char table_enc85[] =
-"!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
-"PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
-"yz{}~";
-
-/*
- * Converts a base85 encoded guid into a GUID pointer
- * Base85 encoded GUIDs should be 20 characters long.
- *
- * returns TRUE if successful, FALSE if not
- */
-BOOL decode_base85_guid( LPCWSTR str, GUID *guid )
-{
- DWORD i, val = 0, base = 1, *p;
-
- if (!str)
- return FALSE;
-
- p = (DWORD*) guid;
- for( i=0; i<20; i++ )
- {
- if( (i%5) == 0 )
- {
- val = 0;
- base = 1;
- }
- val += table_dec85[str[i]] * base;
- if( str[i] >= 0x80 )
- return FALSE;
- if( table_dec85[str[i]] == 0xff )
- return FALSE;
- if( (i%5) == 4 )
- p[i/5] = val;
- base *= 85;
- }
- return TRUE;
-}
-
-/*
- * Encodes a base85 guid given a GUID pointer
- * Caller should provide a 21 character buffer for the encoded string.
- *
- * returns TRUE if successful, FALSE if not
- */
-BOOL encode_base85_guid( GUID *guid, LPWSTR str )
-{
- unsigned int x, *p, i;
-
- p = (unsigned int*) guid;
- for( i=0; i<4; i++ )
- {
- x = p[i];
- *str++ = table_enc85[x%85];
- x = x/85;
- *str++ = table_enc85[x%85];
- x = x/85;
- *str++ = table_enc85[x%85];
- x = x/85;
- *str++ = table_enc85[x%85];
- x = x/85;
- *str++ = table_enc85[x%85];
- }
- *str = 0;
-
- return TRUE;
-}
-
-DWORD msi_version_str_to_dword(LPCWSTR p)
-{
- DWORD major, minor = 0, build = 0, version = 0;
-
- if (!p)
- return version;
-
- major = atoiW(p);
-
- p = strchrW(p, '.');
- if (p)
- {
- minor = atoiW(p+1);
- p = strchrW(p+1, '.');
- if (p)
- build = atoiW(p+1);
- }
-
- return MAKELONG(build, MAKEWORD(minor, major));
-}
-
-LONG msi_reg_set_val_str( HKEY hkey, LPCWSTR name, LPCWSTR value )
-{
- DWORD len;
- if (!value) value = szEmpty;
- len = (lstrlenW(value) + 1) * sizeof (WCHAR);
- return RegSetValueExW( hkey, name, 0, REG_SZ, (const BYTE *)value, len );
-}
-
-LONG msi_reg_set_val_multi_str( HKEY hkey, LPCWSTR name, LPCWSTR value )
-{
- LPCWSTR p = value;
- while (*p) p += lstrlenW(p) + 1;
- return RegSetValueExW( hkey, name, 0, REG_MULTI_SZ,
- (const BYTE *)value, (p + 1 - value) * sizeof(WCHAR) );
-}
-
-LONG msi_reg_set_val_dword( HKEY hkey, LPCWSTR name, DWORD val )
-{
- return RegSetValueExW( hkey, name, 0, REG_DWORD, (LPBYTE)&val, sizeof (DWORD) );
-}
-
-LONG msi_reg_set_subkey_val( HKEY hkey, LPCWSTR path, LPCWSTR name, LPCWSTR val )
-{
- HKEY hsubkey = 0;
- LONG r;
-
- r = RegCreateKeyW( hkey, path, &hsubkey );
- if (r != ERROR_SUCCESS)
- return r;
- r = msi_reg_set_val_str( hsubkey, name, val );
- RegCloseKey( hsubkey );
- return r;
-}
-
-LPWSTR msi_reg_get_val_str( HKEY hkey, LPCWSTR name )
-{
- DWORD len = 0;
- LPWSTR val;
- LONG r;
-
- r = RegQueryValueExW(hkey, name, NULL, NULL, NULL, &len);
- if (r != ERROR_SUCCESS)
- return NULL;
-
- len += sizeof (WCHAR);
- val = msi_alloc( len );
- if (!val)
- return NULL;
- val[0] = 0;
- RegQueryValueExW(hkey, name, NULL, NULL, (LPBYTE) val, &len);
- return val;
-}
-
-BOOL msi_reg_get_val_dword( HKEY hkey, LPCWSTR name, DWORD *val)
-{
- DWORD type, len = sizeof (DWORD);
- LONG r = RegQueryValueExW(hkey, name, NULL, &type, (LPBYTE) val, &len);
- return r == ERROR_SUCCESS && type == REG_DWORD;
-}
-
-static WCHAR *get_user_sid(void)
-{
- HANDLE token;
- DWORD size = 256;
- TOKEN_USER *user;
- WCHAR *ret;
-
- if (!OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &token )) return NULL;
- if (!(user = msi_alloc( size )))
- {
- CloseHandle( token );
- return NULL;
- }
- if (!GetTokenInformation( token, TokenUser, user, size, &size ))
- {
- msi_free( user );
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || !(user = msi_alloc( size )))
- {
- CloseHandle( token );
- return NULL;
- }
- GetTokenInformation( token, TokenUser, user, size, &size );
- }
- CloseHandle( token );
- if (!ConvertSidToStringSidW( user->User.Sid, &ret ))
- {
- msi_free( user );
- return NULL;
- }
- msi_free( user );
- return ret;
-}
-
-UINT MSIREG_OpenUninstallKey(const WCHAR *product, enum platform platform, HKEY *key, BOOL create)
-{
- WCHAR keypath[0x200];
-
- TRACE("%s\n", debugstr_w(product));
-
- if (is_64bit && platform == PLATFORM_INTEL)
- {
- strcpyW(keypath, szUninstall_32node);
- strcatW(keypath, product);
- }
- else
- {
- strcpyW(keypath, szUninstall);
- strcatW(keypath, product);
- }
- if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, KEY_ALL_ACCESS, NULL, key, NULL);
- return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, KEY_ALL_ACCESS, key);
-}
-
-UINT MSIREG_DeleteUninstallKey(const WCHAR *product, enum platform platform)
-{
- WCHAR keypath[0x200];
-
- TRACE("%s\n", debugstr_w(product));
-
- if (is_64bit && platform == PLATFORM_INTEL)
- {
- strcpyW(keypath, szUninstall_32node);
- strcatW(keypath, product);
- }
- else
- {
- strcpyW(keypath, szUninstall);
- strcatW(keypath, product);
- }
- return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
-}
-
-UINT MSIREG_OpenProductKey(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
-{
- LPWSTR usersid = NULL;
- HKEY root = HKEY_LOCAL_MACHINE;
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_pc[GUID_SIZE], keypath[MAX_PATH];
-
- if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc));
-
- if (context == MSIINSTALLCONTEXT_MACHINE)
- {
- strcpyW(keypath, szInstaller_LocalClassesProd);
- strcatW(keypath, squished_pc);
- }
- else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
- {
- root = HKEY_CURRENT_USER;
- strcpyW(keypath, szUserProducts);
- strcatW(keypath, squished_pc);
- }
- else
- {
- if (!szUserSid)
- {
- if (!(usersid = get_user_sid()))
- {
- ERR("Failed to retrieve user SID\n");
- return ERROR_FUNCTION_FAILED;
- }
- szUserSid = usersid;
- }
- sprintfW(keypath, szInstaller_LocalManagedProd_fmt, szUserSid, squished_pc);
- LocalFree(usersid);
- }
- if (create) return RegCreateKeyExW(root, keypath, 0, NULL, 0, access, NULL, key, NULL);
- return RegOpenKeyExW(root, keypath, 0, access, key);
-}
-
-UINT MSIREG_DeleteUserProductKey(LPCWSTR szProduct)
-{
- WCHAR squished_pc[GUID_SIZE], keypath[0x200];
-
- if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc));
-
- strcpyW(keypath, szUserProducts);
- strcatW(keypath, squished_pc);
- return RegDeleteTreeW(HKEY_CURRENT_USER, keypath);
-}
-
-UINT MSIREG_OpenUserPatchesKey(LPCWSTR szPatch, HKEY *key, BOOL create)
-{
- WCHAR squished_pc[GUID_SIZE], keypath[0x200];
-
- if (!squash_guid(szPatch, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szPatch), debugstr_w(squished_pc));
-
- strcpyW(keypath, szUserPatches);
- strcatW(keypath, squished_pc);
-
- if (create) return RegCreateKeyW(HKEY_CURRENT_USER, keypath, key);
- return RegOpenKeyW(HKEY_CURRENT_USER, keypath, key);
-}
-
-UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
-{
- LPWSTR usersid;
- HKEY root = HKEY_LOCAL_MACHINE;
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_pc[GUID_SIZE], keypath[MAX_PATH];
-
- if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc));
-
- if (context == MSIINSTALLCONTEXT_MACHINE)
- {
- strcpyW(keypath, szInstaller_LocalClassesFeat);
- strcatW(keypath, squished_pc);
- }
- else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
- {
- root = HKEY_CURRENT_USER;
- strcpyW(keypath, szUserFeatures);
- strcatW(keypath, squished_pc);
- }
- else
- {
- if (!(usersid = get_user_sid()))
- {
- ERR("Failed to retrieve user SID\n");
- return ERROR_FUNCTION_FAILED;
- }
- sprintfW(keypath, szInstaller_LocalManagedFeat_fmt, usersid, squished_pc);
- LocalFree(usersid);
- }
- if (create) return RegCreateKeyExW(root, keypath, 0, NULL, 0, access, NULL, key, NULL);
- return RegOpenKeyExW(root, keypath, 0, access, key);
-}
-
-UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct)
-{
- WCHAR squished_pc[GUID_SIZE], keypath[0x200];
-
- if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc));
-
- strcpyW(keypath, szUserFeatures);
- strcatW(keypath, squished_pc);
- return RegDeleteTreeW(HKEY_CURRENT_USER, keypath);
-}
-
-static UINT MSIREG_OpenInstallerFeaturesKey(LPCWSTR szProduct, HKEY *key, BOOL create)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_pc[GUID_SIZE], keypath[0x200];
-
- if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc));
-
- strcpyW(keypath, szInstaller_Features);
- strcatW(keypath, squished_pc);
-
- if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
- return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
-}
-
-UINT MSIREG_OpenUserDataFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
-{
- LPWSTR usersid;
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_pc[GUID_SIZE], keypath[0x200];
-
- if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc));
-
- if (context == MSIINSTALLCONTEXT_MACHINE)
- {
- sprintfW(keypath, szUserDataFeatures_fmt, szLocalSid, squished_pc);
- }
- else
- {
- if (!(usersid = get_user_sid()))
- {
- ERR("Failed to retrieve user SID\n");
- return ERROR_FUNCTION_FAILED;
- }
- sprintfW(keypath, szUserDataFeatures_fmt, usersid, squished_pc);
- LocalFree(usersid);
- }
- if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
- return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
-}
-
-UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY *key, BOOL create)
-{
- WCHAR squished_cc[GUID_SIZE], keypath[0x200];
-
- if (!squash_guid(szComponent, squished_cc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szComponent), debugstr_w(squished_cc));
-
- strcpyW(keypath, szUserComponents);
- strcatW(keypath, squished_cc);
-
- if (create) return RegCreateKeyW(HKEY_CURRENT_USER, keypath, key);
- return RegOpenKeyW(HKEY_CURRENT_USER, keypath, key);
-}
-
-UINT MSIREG_OpenUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid, HKEY *key, BOOL create)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR comp[GUID_SIZE], keypath[0x200];
- LPWSTR usersid;
-
- if (!squash_guid(szComponent, comp)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szComponent), debugstr_w(comp));
-
- if (!szUserSid)
- {
- if (!(usersid = get_user_sid()))
- {
- ERR("Failed to retrieve user SID\n");
- return ERROR_FUNCTION_FAILED;
- }
- sprintfW(keypath, szUserDataComp_fmt, usersid, comp);
- LocalFree(usersid);
- }
- else
- sprintfW(keypath, szUserDataComp_fmt, szUserSid, comp);
-
- if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
- return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
-}
-
-UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR comp[GUID_SIZE], keypath[0x200];
- LPWSTR usersid;
- HKEY hkey;
- LONG r;
-
- if (!squash_guid(szComponent, comp)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szComponent), debugstr_w(comp));
-
- if (!szUserSid)
- {
- if (!(usersid = get_user_sid()))
- {
- ERR("Failed to retrieve user SID\n");
- return ERROR_FUNCTION_FAILED;
- }
- sprintfW(keypath, szUserDataComponents_fmt, usersid);
- LocalFree(usersid);
- }
- else
- sprintfW(keypath, szUserDataComponents_fmt, szUserSid);
-
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey)) return ERROR_SUCCESS;
- r = RegDeleteTreeW(hkey, comp);
- RegCloseKey(hkey);
- return r;
-}
-
-UINT MSIREG_OpenUserDataProductKey(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext, LPCWSTR szUserSid, HKEY *key, BOOL create)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_pc[GUID_SIZE], keypath[0x200];
- LPWSTR usersid;
-
- if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc));
-
- if (dwContext == MSIINSTALLCONTEXT_MACHINE)
- sprintfW(keypath, szUserDataProd_fmt, szLocalSid, squished_pc);
- else if (szUserSid)
- sprintfW(keypath, szUserDataProd_fmt, szUserSid, squished_pc);
- else
- {
- if (!(usersid = get_user_sid()))
- {
- ERR("Failed to retrieve user SID\n");
- return ERROR_FUNCTION_FAILED;
- }
- sprintfW(keypath, szUserDataProd_fmt, usersid, squished_pc);
- LocalFree(usersid);
- }
- if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
- return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
-}
-
-UINT MSIREG_OpenUserDataPatchKey(LPCWSTR szPatch, MSIINSTALLCONTEXT dwContext, HKEY *key, BOOL create)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_patch[GUID_SIZE], keypath[0x200];
- LPWSTR usersid;
-
- if (!squash_guid(szPatch, squished_patch)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szPatch), debugstr_w(squished_patch));
-
- if (dwContext == MSIINSTALLCONTEXT_MACHINE)
- sprintfW(keypath, szUserDataPatch_fmt, szLocalSid, squished_patch);
- else
- {
- if (!(usersid = get_user_sid()))
- {
- ERR("Failed to retrieve user SID\n");
- return ERROR_FUNCTION_FAILED;
- }
- sprintfW(keypath, szUserDataPatch_fmt, usersid, squished_patch);
- LocalFree(usersid);
- }
- if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
- return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
-}
-
-UINT MSIREG_DeleteUserDataPatchKey(LPCWSTR patch, MSIINSTALLCONTEXT context)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_patch[GUID_SIZE], keypath[0x200];
- LPWSTR usersid;
- HKEY hkey;
- LONG r;
-
- if (!squash_guid(patch, squished_patch)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(patch), debugstr_w(squished_patch));
-
- if (context == MSIINSTALLCONTEXT_MACHINE)
- sprintfW(keypath, szUserDataPatches_fmt, szLocalSid);
- else
- {
- if (!(usersid = get_user_sid()))
- {
- ERR("Failed to retrieve user SID\n");
- return ERROR_FUNCTION_FAILED;
- }
- sprintfW(keypath, szUserDataPatches_fmt, usersid);
- LocalFree(usersid);
- }
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey)) return ERROR_SUCCESS;
- r = RegDeleteTreeW(hkey, squished_patch);
- RegCloseKey(hkey);
- return r;
-}
-
-UINT MSIREG_OpenUserDataProductPatchesKey(LPCWSTR product, MSIINSTALLCONTEXT context, HKEY *key, BOOL create)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_product[GUID_SIZE], keypath[0x200];
- LPWSTR usersid;
-
- if (!squash_guid(product, squished_product)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(product), debugstr_w(squished_product));
-
- if (context == MSIINSTALLCONTEXT_MACHINE)
- sprintfW(keypath, szUserDataProductPatches_fmt, szLocalSid, squished_product);
- else
- {
- if (!(usersid = get_user_sid()))
- {
- ERR("Failed to retrieve user SID\n");
- return ERROR_FUNCTION_FAILED;
- }
- sprintfW(keypath, szUserDataProductPatches_fmt, usersid, squished_product);
- LocalFree(usersid);
- }
- if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
- return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
-}
-
-UINT MSIREG_OpenInstallProps(LPCWSTR szProduct, MSIINSTALLCONTEXT dwContext, LPCWSTR szUserSid, HKEY *key, BOOL create)
-{
- LPWSTR usersid;
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_pc[GUID_SIZE], keypath[0x200];
-
- if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc));
-
- if (dwContext == MSIINSTALLCONTEXT_MACHINE)
- sprintfW(keypath, szInstallProperties_fmt, szLocalSid, squished_pc);
- else if (szUserSid)
- sprintfW(keypath, szInstallProperties_fmt, szUserSid, squished_pc);
- else
- {
- if (!(usersid = get_user_sid()))
- {
- ERR("Failed to retrieve user SID\n");
- return ERROR_FUNCTION_FAILED;
- }
- sprintfW(keypath, szInstallProperties_fmt, usersid, squished_pc);
- LocalFree(usersid);
- }
- if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
- return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
-}
-
-UINT MSIREG_DeleteUserDataProductKey(LPCWSTR szProduct)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_pc[GUID_SIZE], keypath[0x200];
- LPWSTR usersid;
- HKEY hkey;
- LONG r;
-
- if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc));
-
- if (!(usersid = get_user_sid()))
- {
- ERR("Failed to retrieve user SID\n");
- return ERROR_FUNCTION_FAILED;
- }
- sprintfW(keypath, szUserDataProducts_fmt, usersid);
- LocalFree(usersid);
-
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey)) return ERROR_SUCCESS;
- r = RegDeleteTreeW(hkey, squished_pc);
- RegCloseKey(hkey);
- return r;
-}
-
-UINT MSIREG_DeleteProductKey(LPCWSTR szProduct)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_pc[GUID_SIZE];
- HKEY hkey;
- LONG r;
-
- if (!squash_guid(szProduct, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szProduct), debugstr_w(squished_pc));
-
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szInstaller_Products, 0, access, &hkey)) return ERROR_SUCCESS;
- r = RegDeleteTreeW(hkey, squished_pc);
- RegCloseKey(hkey);
- return r;
-}
-
-UINT MSIREG_OpenPatchesKey(LPCWSTR szPatch, HKEY *key, BOOL create)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_pc[GUID_SIZE], keypath[0x200];
-
- if (!squash_guid(szPatch, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szPatch), debugstr_w(squished_pc));
-
- sprintfW(keypath, szInstaller_Patches, squished_pc);
-
- if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
- return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
-}
-
-UINT MSIREG_OpenUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY *key, BOOL create)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_pc[GUID_SIZE], keypath[0x200];
-
- if (!squash_guid(szUpgradeCode, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szUpgradeCode), debugstr_w(squished_pc));
-
- strcpyW(keypath, szInstaller_UpgradeCodes);
- strcatW(keypath, squished_pc);
-
- if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
- return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
-}
-
-UINT MSIREG_OpenUserUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY* key, BOOL create)
-{
- WCHAR squished_pc[GUID_SIZE], keypath[0x200];
-
- if (!squash_guid(szUpgradeCode, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szUpgradeCode), debugstr_w(squished_pc));
-
- strcpyW(keypath, szInstaller_UserUpgradeCodes);
- strcatW(keypath, squished_pc);
-
- if (create) return RegCreateKeyW(HKEY_CURRENT_USER, keypath, key);
- return RegOpenKeyW(HKEY_CURRENT_USER, keypath, key);
-}
-
-UINT MSIREG_DeleteUserUpgradeCodesKey(LPCWSTR szUpgradeCode)
-{
- WCHAR squished_pc[GUID_SIZE], keypath[0x200];
-
- if (!squash_guid(szUpgradeCode, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szUpgradeCode), debugstr_w(squished_pc));
-
- strcpyW(keypath, szInstaller_UserUpgradeCodes);
- strcatW(keypath, squished_pc);
- return RegDeleteTreeW(HKEY_CURRENT_USER, keypath);
-}
-
-UINT MSIREG_DeleteLocalClassesProductKey(LPCWSTR szProductCode)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_pc[GUID_SIZE];
- HKEY hkey;
- LONG r;
-
- if (!squash_guid(szProductCode, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szProductCode), debugstr_w(squished_pc));
-
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szInstaller_LocalClassesProducts, 0, access, &hkey)) return ERROR_SUCCESS;
- r = RegDeleteTreeW(hkey, squished_pc);
- RegCloseKey(hkey);
- return r;
-}
-
-UINT MSIREG_DeleteLocalClassesFeaturesKey(LPCWSTR szProductCode)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_pc[GUID_SIZE];
- HKEY hkey;
- LONG r;
-
- if (!squash_guid(szProductCode, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szProductCode), debugstr_w(squished_pc));
-
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szInstaller_LocalClassesFeatures, 0, access, &hkey)) return ERROR_SUCCESS;
- r = RegDeleteTreeW(hkey, squished_pc);
- RegCloseKey(hkey);
- return r;
-}
-
-UINT MSIREG_OpenClassesUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY *key, BOOL create)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_pc[GUID_SIZE], keypath[0x200];
-
- if (!squash_guid(szUpgradeCode, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szUpgradeCode), debugstr_w(squished_pc));
-
- strcpyW(keypath, szInstaller_ClassesUpgradeCode);
- strcatW(keypath, squished_pc);
-
- if (create) return RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, key, NULL);
- return RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, access, key);
-}
-
-UINT MSIREG_DeleteClassesUpgradeCodesKey(LPCWSTR szUpgradeCode)
-{
- REGSAM access = KEY_WOW64_64KEY | KEY_ALL_ACCESS;
- WCHAR squished_pc[GUID_SIZE];
- HKEY hkey;
- LONG r;
-
- if (!squash_guid(szUpgradeCode, squished_pc)) return ERROR_FUNCTION_FAILED;
- TRACE("%s squished %s\n", debugstr_w(szUpgradeCode), debugstr_w(squished_pc));
-
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szInstaller_ClassesUpgradeCodes, 0, access, &hkey)) return ERROR_SUCCESS;
- r = RegDeleteTreeW(hkey, squished_pc);
- RegCloseKey(hkey);
- return r;
-}
-
-/*************************************************************************
- * MsiDecomposeDescriptorW [MSI.@]
- *
- * Decomposes an MSI descriptor into product, feature and component parts.
- * An MSI descriptor is a string of the form:
- * [base 85 guid] [feature code] '>' [base 85 guid]
- *
- * PARAMS
- * szDescriptor [I] the descriptor to decompose
- * szProduct [O] buffer of MAX_FEATURE_CHARS+1 for the product guid
- * szFeature [O] buffer of MAX_FEATURE_CHARS+1 for the feature code
- * szComponent [O] buffer of MAX_FEATURE_CHARS+1 for the component guid
- * pUsed [O] the length of the descriptor
- *
- * RETURNS
- * ERROR_SUCCESS if everything worked correctly
- * ERROR_INVALID_PARAMETER if the descriptor was invalid
- *
- */
-UINT WINAPI MsiDecomposeDescriptorW( LPCWSTR szDescriptor, LPWSTR szProduct,
- LPWSTR szFeature, LPWSTR szComponent, LPDWORD pUsed )
-{
- UINT r, len;
- LPWSTR p;
- GUID product, component;
-
- TRACE("%s %p %p %p %p\n", debugstr_w(szDescriptor), szProduct,
- szFeature, szComponent, pUsed);
-
- r = decode_base85_guid( szDescriptor, &product );
- if( !r )
- return ERROR_INVALID_PARAMETER;
-
- TRACE("product %s\n", debugstr_guid( &product ));
-
- p = strchrW(&szDescriptor[20],'>');
- if( !p )
- return ERROR_INVALID_PARAMETER;
-
- len = (p - &szDescriptor[20]);
- if( len > MAX_FEATURE_CHARS )
- return ERROR_INVALID_PARAMETER;
-
- TRACE("feature %s\n", debugstr_wn( &szDescriptor[20], len ));
-
- r = decode_base85_guid( p+1, &component );
- if( !r )
- return ERROR_INVALID_PARAMETER;
-
- TRACE("component %s\n", debugstr_guid( &component ));
-
- if (szProduct)
- StringFromGUID2( &product, szProduct, MAX_FEATURE_CHARS+1 );
- if (szComponent)
- StringFromGUID2( &component, szComponent, MAX_FEATURE_CHARS+1 );
- if (szFeature)
- {
- memcpy( szFeature, &szDescriptor[20], len*sizeof(WCHAR) );
- szFeature[len] = 0;
- }
- len = ( &p[21] - szDescriptor );
-
- TRACE("length = %d\n", len);
- if (pUsed) *pUsed = len;
-
- return ERROR_SUCCESS;
-}
-
-UINT WINAPI MsiDecomposeDescriptorA( LPCSTR szDescriptor, LPSTR szProduct,
- LPSTR szFeature, LPSTR szComponent, LPDWORD pUsed )
-{
- WCHAR product[MAX_FEATURE_CHARS+1];
- WCHAR feature[MAX_FEATURE_CHARS+1];
- WCHAR component[MAX_FEATURE_CHARS+1];
- LPWSTR str = NULL, p = NULL, f = NULL, c = NULL;
- UINT r;
-
- TRACE("%s %p %p %p %p\n", debugstr_a(szDescriptor), szProduct,
- szFeature, szComponent, pUsed);
-
- str = strdupAtoW( szDescriptor );
- if( szDescriptor && !str )
- return ERROR_OUTOFMEMORY;
-
- if (szProduct)
- p = product;
- if (szFeature)
- f = feature;
- if (szComponent)
- c = component;
-
- r = MsiDecomposeDescriptorW( str, p, f, c, pUsed );
-
- if (r == ERROR_SUCCESS)
- {
- WideCharToMultiByte( CP_ACP, 0, p, -1,
- szProduct, MAX_FEATURE_CHARS+1, NULL, NULL );
- WideCharToMultiByte( CP_ACP, 0, f, -1,
- szFeature, MAX_FEATURE_CHARS+1, NULL, NULL );
- WideCharToMultiByte( CP_ACP, 0, c, -1,
- szComponent, MAX_FEATURE_CHARS+1, NULL, NULL );
- }
-
- msi_free( str );
-
- return r;
-}
-
-UINT WINAPI MsiEnumProductsA(DWORD index, LPSTR lpguid)
-{
- DWORD r;
- WCHAR szwGuid[GUID_SIZE];
-
- TRACE("%d %p\n", index, lpguid);
-
- if (NULL == lpguid)
- return ERROR_INVALID_PARAMETER;
- r = MsiEnumProductsW(index, szwGuid);
- if( r == ERROR_SUCCESS )
- WideCharToMultiByte(CP_ACP, 0, szwGuid, -1, lpguid, GUID_SIZE, NULL, NULL);
-
- return r;
-}
-
-UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid)
-{
- TRACE("%d %p\n", index, lpguid);
-
- if (NULL == lpguid)
- return ERROR_INVALID_PARAMETER;
-
- return MsiEnumProductsExW( NULL, szAllSid, MSIINSTALLCONTEXT_ALL, index, lpguid,
- NULL, NULL, NULL );
-}
-
-UINT WINAPI MsiEnumFeaturesA(LPCSTR szProduct, DWORD index,
- LPSTR szFeature, LPSTR szParent)
-{
- DWORD r;
- WCHAR szwFeature[GUID_SIZE], szwParent[GUID_SIZE];
- LPWSTR szwProduct = NULL;
-
- TRACE("%s %d %p %p\n", debugstr_a(szProduct), index, szFeature, szParent);
-
- if( szProduct )
- {
- szwProduct = strdupAtoW( szProduct );
- if( !szwProduct )
- return ERROR_OUTOFMEMORY;
- }
-
- r = MsiEnumFeaturesW(szwProduct, index, szwFeature, szwParent);
- if( r == ERROR_SUCCESS )
- {
- WideCharToMultiByte(CP_ACP, 0, szwFeature, -1,
- szFeature, GUID_SIZE, NULL, NULL);
- WideCharToMultiByte(CP_ACP, 0, szwParent, -1,
- szParent, GUID_SIZE, NULL, NULL);
- }
-
- msi_free( szwProduct);
-
- return r;
-}
-
-UINT WINAPI MsiEnumFeaturesW(LPCWSTR szProduct, DWORD index,
- LPWSTR szFeature, LPWSTR szParent)
-{
- HKEY hkeyProduct = 0;
- DWORD r, sz;
-
- TRACE("%s %d %p %p\n", debugstr_w(szProduct), index, szFeature, szParent);
-
- if( !szProduct )
- return ERROR_INVALID_PARAMETER;
-
- r = MSIREG_OpenInstallerFeaturesKey(szProduct,&hkeyProduct,FALSE);
- if( r != ERROR_SUCCESS )
- return ERROR_NO_MORE_ITEMS;
-
- sz = GUID_SIZE;
- r = RegEnumValueW(hkeyProduct, index, szFeature, &sz, NULL, NULL, NULL, NULL);
- RegCloseKey(hkeyProduct);
-
- return r;
-}
-
-UINT WINAPI MsiEnumComponentsA(DWORD index, LPSTR lpguid)
-{
- DWORD r;
- WCHAR szwGuid[GUID_SIZE];
-
- TRACE("%u, %p\n", index, lpguid);
-
- if (!lpguid) return ERROR_INVALID_PARAMETER;
-
- r = MsiEnumComponentsW(index, szwGuid);
- if( r == ERROR_SUCCESS )
- WideCharToMultiByte(CP_ACP, 0, szwGuid, -1, lpguid, GUID_SIZE, NULL, NULL);
-
- return r;
-}
-
-UINT WINAPI MsiEnumComponentsW(DWORD index, LPWSTR lpguid)
-{
- TRACE("%u, %p\n", index, lpguid);
-
- if (!lpguid) return ERROR_INVALID_PARAMETER;
-
- return MsiEnumComponentsExW( szAllSid, MSIINSTALLCONTEXT_ALL, index, lpguid, NULL, NULL, NULL );
-}
-
-UINT WINAPI MsiEnumComponentsExA( LPCSTR user_sid, DWORD ctx, DWORD index, CHAR guid[39],
- MSIINSTALLCONTEXT *installed_ctx, LPSTR sid, LPDWORD sid_len )
-{
- UINT r;
- WCHAR *user_sidW = NULL, *sidW = NULL, guidW[GUID_SIZE];
-
- TRACE("%s, %u, %u, %p, %p, %p, %p\n", debugstr_a(user_sid), ctx, index, guid, installed_ctx,
- sid, sid_len);
-
- if (sid && !sid_len) return ERROR_INVALID_PARAMETER;
- if (user_sid && !(user_sidW = strdupAtoW( user_sid ))) return ERROR_OUTOFMEMORY;
- if (sid && !(sidW = msi_alloc( *sid_len * sizeof(WCHAR) )))
- {
- msi_free( user_sidW );
- return ERROR_OUTOFMEMORY;
- }
- r = MsiEnumComponentsExW( user_sidW, ctx, index, guidW, installed_ctx, sidW, sid_len );
- if (r == ERROR_SUCCESS)
- {
- if (guid) WideCharToMultiByte( CP_ACP, 0, guidW, GUID_SIZE, guid, GUID_SIZE, NULL, NULL );
- if (sid) WideCharToMultiByte( CP_ACP, 0, sidW, *sid_len + 1, sid, *sid_len + 1, NULL, NULL );
- }
- msi_free( user_sidW );
- msi_free( sidW );
- return r;
-}
-
-static UINT fetch_machine_component( DWORD ctx, DWORD index, DWORD *idx, WCHAR guid[39],
- MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len )
-{
- static const WCHAR componentsW[] =
- {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a','\\',
- 'S','-','1','-','5','-','1','8','\\','C','o','m','p','o','n','e','n','t','s',0};
- UINT r = ERROR_SUCCESS;
- WCHAR component[GUID_SIZE];
- DWORD i = 0, len_component;
- REGSAM access = KEY_ENUMERATE_SUB_KEYS | KEY_WOW64_64KEY;
- HKEY key_components;
-
- if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, componentsW, 0, access, &key_components ))
- return ERROR_NO_MORE_ITEMS;
-
- len_component = sizeof(component)/sizeof(component[0]);
- while (!RegEnumKeyExW( key_components, i, component, &len_component, NULL, NULL, NULL, NULL ))
- {
- if (*idx == index) goto found;
- (*idx)++;
- len_component = sizeof(component)/sizeof(component[0]);
- i++;
- }
- RegCloseKey( key_components );
- return ERROR_NO_MORE_ITEMS;
-
-found:
- if (sid_len)
- {
- if (*sid_len < 1)
- {
- *sid_len = 1;
- r = ERROR_MORE_DATA;
- }
- else if (sid)
- {
- *sid_len = 0;
- sid[0] = 0;
- }
- }
- if (guid) unsquash_guid( component, guid );
- if (installed_ctx) *installed_ctx = MSIINSTALLCONTEXT_MACHINE;
- RegCloseKey( key_components );
- return r;
-}
-
-static UINT fetch_user_component( const WCHAR *usersid, DWORD ctx, DWORD index, DWORD *idx,
- WCHAR guid[39], MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid,
- LPDWORD sid_len )
-{
- static const WCHAR userdataW[] =
- {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','s','t','a','l','l','e','r','\\','U','s','e','r','D','a','t','a',0};
- static const WCHAR componentsW[] = {'\\','C','o','m','p','o','n','e','n','t','s',0};
- UINT r = ERROR_SUCCESS;
- WCHAR path[MAX_PATH], component[GUID_SIZE], user[128];
- DWORD i = 0, j = 0, len_component, len_user;
- REGSAM access = KEY_ENUMERATE_SUB_KEYS | KEY_WOW64_64KEY;
- HKEY key_users, key_components;
-
- if (ctx == MSIINSTALLCONTEXT_USERMANAGED) /* FIXME: were to find these? */
- return ERROR_NO_MORE_ITEMS;
-
- if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, userdataW, 0, access, &key_users ))
- return ERROR_NO_MORE_ITEMS;
-
- len_user = sizeof(user)/sizeof(user[0]);
- while (!RegEnumKeyExW( key_users, i, user, &len_user, NULL, NULL, NULL, NULL ))
- {
- if ((strcmpW( usersid, szAllSid ) && strcmpW( usersid, user )) ||
- !strcmpW( szLocalSid, user ))
- {
- i++;
- len_user = sizeof(user)/sizeof(user[0]);
- continue;
- }
- strcpyW( path, user );
- strcatW( path, componentsW );
- if (RegOpenKeyExW( key_users, path, 0, access, &key_components ))
- {
- i++;
- len_user = sizeof(user)/sizeof(user[0]);
- continue;
- }
- len_component = sizeof(component)/sizeof(component[0]);
- while (!RegEnumKeyExW( key_components, j, component, &len_component, NULL, NULL, NULL, NULL ))
- {
- if (*idx == index) goto found;
- (*idx)++;
- len_component = sizeof(component)/sizeof(component[0]);
- j++;
- }
- RegCloseKey( key_components );
- len_user = sizeof(user)/sizeof(user[0]);
- i++;
- }
- RegCloseKey( key_users );
- return ERROR_NO_MORE_ITEMS;
-
-found:
- if (sid_len)
- {
- if (*sid_len < len_user + 1)
- {
- *sid_len = len_user + 1;
- r = ERROR_MORE_DATA;
- }
- else if (sid)
- {
- *sid_len = len_user;
- strcpyW( sid, user );
- }
- }
- if (guid) unsquash_guid( component, guid );
- if (installed_ctx) *installed_ctx = ctx;
- RegCloseKey( key_components );
- RegCloseKey( key_users );
- return r;
-}
-
-static UINT enum_components( const WCHAR *usersid, DWORD ctx, DWORD index, DWORD *idx, WCHAR guid[39],
- MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len )
-{
- UINT r = ERROR_NO_MORE_ITEMS;
- WCHAR *user = NULL;
-
- if (!usersid)
- {
- usersid = user = get_user_sid();
- if (!user) return ERROR_FUNCTION_FAILED;
- }
- if (ctx & MSIINSTALLCONTEXT_USERMANAGED)
- {
- r = fetch_user_component( usersid, MSIINSTALLCONTEXT_USERMANAGED, index, idx, guid,
- installed_ctx, sid, sid_len );
- if (r != ERROR_NO_MORE_ITEMS) goto done;
- }
- if (ctx & MSIINSTALLCONTEXT_USERUNMANAGED)
- {
- r = fetch_user_component( usersid, MSIINSTALLCONTEXT_USERUNMANAGED, index, idx, guid,
- installed_ctx, sid, sid_len );
- if (r != ERROR_NO_MORE_ITEMS) goto done;
- }
- if (ctx & MSIINSTALLCONTEXT_MACHINE)
- {
- r = fetch_machine_component( MSIINSTALLCONTEXT_MACHINE, index, idx, guid, installed_ctx,
- sid, sid_len );
- if (r != ERROR_NO_MORE_ITEMS) goto done;
- }
-
-done:
- LocalFree( user );
- return r;
-}
-
-UINT WINAPI MsiEnumComponentsExW( LPCWSTR user_sid, DWORD ctx, DWORD index, WCHAR guid[39],
- MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len )
-{
- UINT r;
- DWORD idx = 0;
- static DWORD last_index;
-
- TRACE("%s, %u, %u, %p, %p, %p, %p\n", debugstr_w(user_sid), ctx, index, guid, installed_ctx,
- sid, sid_len);
-
- if ((sid && !sid_len) || !ctx || (user_sid && ctx == MSIINSTALLCONTEXT_MACHINE))
- return ERROR_INVALID_PARAMETER;
-
- if (index && index - last_index != 1)
- return ERROR_INVALID_PARAMETER;
-
- if (!index) last_index = 0;
-
- r = enum_components( user_sid, ctx, index, &idx, guid, installed_ctx, sid, sid_len );
- if (r == ERROR_SUCCESS)
- last_index = index;
- else
- last_index = 0;
-
- return r;
-}
-
-UINT WINAPI MsiEnumClientsA(LPCSTR szComponent, DWORD index, LPSTR szProduct)
-{
- DWORD r;
- WCHAR szwProduct[GUID_SIZE];
- LPWSTR szwComponent = NULL;
-
- TRACE("%s %d %p\n", debugstr_a(szComponent), index, szProduct);
-
- if ( !szProduct )
- return ERROR_INVALID_PARAMETER;
-
- if( szComponent )
- {
- szwComponent = strdupAtoW( szComponent );
- if( !szwComponent )
- return ERROR_OUTOFMEMORY;
- }
-
- r = MsiEnumClientsW(szComponent?szwComponent:NULL, index, szwProduct);
- if( r == ERROR_SUCCESS )
- {
- WideCharToMultiByte(CP_ACP, 0, szwProduct, -1,
- szProduct, GUID_SIZE, NULL, NULL);
- }
-
- msi_free( szwComponent);
-
- return r;
-}
-
-UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct)
-{
- HKEY hkeyComp = 0;
- DWORD r, sz;
- WCHAR szValName[SQUISH_GUID_SIZE];
-
- TRACE("%s %d %p\n", debugstr_w(szComponent), index, szProduct);
-
- if (!szComponent || !*szComponent || !szProduct)
- return ERROR_INVALID_PARAMETER;
-
- if (MSIREG_OpenUserDataComponentKey(szComponent, NULL, &hkeyComp, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenUserDataComponentKey(szComponent, szLocalSid, &hkeyComp, FALSE) != ERROR_SUCCESS)
- return ERROR_UNKNOWN_COMPONENT;
-
- /* see if there are any products at all */
- sz = SQUISH_GUID_SIZE;
- r = RegEnumValueW(hkeyComp, 0, szValName, &sz, NULL, NULL, NULL, NULL);
- if (r != ERROR_SUCCESS)
- {
- RegCloseKey(hkeyComp);
-
- if (index != 0)
- return ERROR_INVALID_PARAMETER;
-
- return ERROR_UNKNOWN_COMPONENT;
- }
-
- sz = SQUISH_GUID_SIZE;
- r = RegEnumValueW(hkeyComp, index, szValName, &sz, NULL, NULL, NULL, NULL);
- if( r == ERROR_SUCCESS )
- {
- unsquash_guid(szValName, szProduct);
- TRACE("-> %s\n", debugstr_w(szProduct));
- }
- RegCloseKey(hkeyComp);
- return r;
-}
-
-static UINT MSI_EnumComponentQualifiers( LPCWSTR szComponent, DWORD iIndex,
- awstring *lpQualBuf, LPDWORD pcchQual,
- awstring *lpAppBuf, LPDWORD pcchAppBuf )
-{
- DWORD name_sz, val_sz, name_max, val_max, type, ofs;
- LPWSTR name = NULL, val = NULL;
- UINT r, r2;
- HKEY key;
-
- TRACE("%s %08x %p %p %p %p\n", debugstr_w(szComponent), iIndex,
- lpQualBuf, pcchQual, lpAppBuf, pcchAppBuf);
-
- if (!szComponent)
- return ERROR_INVALID_PARAMETER;
-
- r = MSIREG_OpenUserComponentsKey( szComponent, &key, FALSE );
- if (r != ERROR_SUCCESS)
- return ERROR_UNKNOWN_COMPONENT;
-
- /* figure out how big the name is we want to return */
- name_max = 0x10;
- r = ERROR_OUTOFMEMORY;
- name = msi_alloc( name_max * sizeof(WCHAR) );
- if (!name)
- goto end;
-
- val_max = 0x10;
- r = ERROR_OUTOFMEMORY;
- val = msi_alloc( val_max );
- if (!val)
- goto end;
-
- /* loop until we allocate enough memory */
- while (1)
- {
- name_sz = name_max;
- val_sz = val_max;
- r = RegEnumValueW( key, iIndex, name, &name_sz,
- NULL, &type, (LPBYTE)val, &val_sz );
- if (r == ERROR_SUCCESS)
- break;
- if (r != ERROR_MORE_DATA)
- goto end;
-
- if (type != REG_MULTI_SZ)
- {
- ERR("component data has wrong type (%d)\n", type);
- goto end;
- }
-
- r = ERROR_OUTOFMEMORY;
- if ((name_sz+1) >= name_max)
- {
- name_max *= 2;
- msi_free( name );
- name = msi_alloc( name_max * sizeof (WCHAR) );
- if (!name)
- goto end;
- continue;
- }
- if (val_sz > val_max)
- {
- val_max = val_sz + sizeof (WCHAR);
- msi_free( val );
- val = msi_alloc( val_max * sizeof (WCHAR) );
- if (!val)
- goto end;
- continue;
- }
- ERR("should be enough data, but isn't %d %d\n", name_sz, val_sz );
- goto end;
- }
-
- ofs = 0;
- r = MsiDecomposeDescriptorW( val, NULL, NULL, NULL, &ofs );
- if (r != ERROR_SUCCESS)
- goto end;
-
- TRACE("Providing %s and %s\n", debugstr_w(name), debugstr_w(val+ofs));
-
- r = msi_strcpy_to_awstring( name, lpQualBuf, pcchQual );
- r2 = msi_strcpy_to_awstring( val+ofs, lpAppBuf, pcchAppBuf );
-
- if (r2 != ERROR_SUCCESS)
- r = r2;
-
-end:
- msi_free(val);
- msi_free(name);
- RegCloseKey(key);
-
- return r;
-}
-
-/*************************************************************************
- * MsiEnumComponentQualifiersA [MSI.@]
- */
-UINT WINAPI MsiEnumComponentQualifiersA( LPCSTR szComponent, DWORD iIndex,
- LPSTR lpQualifierBuf, LPDWORD pcchQualifierBuf,
- LPSTR lpApplicationDataBuf, LPDWORD pcchApplicationDataBuf )
-{
- awstring qual, appdata;
- LPWSTR comp;
- UINT r;
-
- TRACE("%s %08x %p %p %p %p\n", debugstr_a(szComponent), iIndex,
- lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf,
- pcchApplicationDataBuf);
-
- comp = strdupAtoW( szComponent );
- if (szComponent && !comp)
- return ERROR_OUTOFMEMORY;
-
- qual.unicode = FALSE;
- qual.str.a = lpQualifierBuf;
-
- appdata.unicode = FALSE;
- appdata.str.a = lpApplicationDataBuf;
-
- r = MSI_EnumComponentQualifiers( comp, iIndex,
- &qual, pcchQualifierBuf, &appdata, pcchApplicationDataBuf );
- msi_free( comp );
- return r;
-}
-
-/*************************************************************************
- * MsiEnumComponentQualifiersW [MSI.@]
- */
-UINT WINAPI MsiEnumComponentQualifiersW( LPCWSTR szComponent, DWORD iIndex,
- LPWSTR lpQualifierBuf, LPDWORD pcchQualifierBuf,
- LPWSTR lpApplicationDataBuf, LPDWORD pcchApplicationDataBuf )
-{
- awstring qual, appdata;
-
- TRACE("%s %08x %p %p %p %p\n", debugstr_w(szComponent), iIndex,
- lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf,
- pcchApplicationDataBuf);
-
- qual.unicode = TRUE;
- qual.str.w = lpQualifierBuf;
-
- appdata.unicode = TRUE;
- appdata.str.w = lpApplicationDataBuf;
-
- return MSI_EnumComponentQualifiers( szComponent, iIndex,
- &qual, pcchQualifierBuf, &appdata, pcchApplicationDataBuf );
-}
-
-/*************************************************************************
- * MsiEnumRelatedProductsW [MSI.@]
- *
- */
-UINT WINAPI MsiEnumRelatedProductsW(LPCWSTR szUpgradeCode, DWORD dwReserved,
- DWORD iProductIndex, LPWSTR lpProductBuf)
-{
- UINT r;
- HKEY hkey;
- DWORD dwSize = SQUISH_GUID_SIZE;
- WCHAR szKeyName[SQUISH_GUID_SIZE];
-
- TRACE("%s %u %u %p\n", debugstr_w(szUpgradeCode), dwReserved,
- iProductIndex, lpProductBuf);
-
- if (NULL == szUpgradeCode)
- return ERROR_INVALID_PARAMETER;
- if (NULL == lpProductBuf)
- return ERROR_INVALID_PARAMETER;
-
- r = MSIREG_OpenUpgradeCodesKey(szUpgradeCode, &hkey, FALSE);
- if (r != ERROR_SUCCESS)
- return ERROR_NO_MORE_ITEMS;
-
- r = RegEnumValueW(hkey, iProductIndex, szKeyName, &dwSize, NULL, NULL, NULL, NULL);
- if( r == ERROR_SUCCESS )
- unsquash_guid(szKeyName, lpProductBuf);
- RegCloseKey(hkey);
-
- return r;
-}
-
-/*************************************************************************
- * MsiEnumRelatedProductsA [MSI.@]
- *
- */
-UINT WINAPI MsiEnumRelatedProductsA(LPCSTR szUpgradeCode, DWORD dwReserved,
- DWORD iProductIndex, LPSTR lpProductBuf)
-{
- LPWSTR szwUpgradeCode = NULL;
- WCHAR productW[GUID_SIZE];
- UINT r;
-
- TRACE("%s %u %u %p\n", debugstr_a(szUpgradeCode), dwReserved,
- iProductIndex, lpProductBuf);
-
- if (szUpgradeCode)
- {
- szwUpgradeCode = strdupAtoW( szUpgradeCode );
- if( !szwUpgradeCode )
- return ERROR_OUTOFMEMORY;
- }
-
- r = MsiEnumRelatedProductsW( szwUpgradeCode, dwReserved,
- iProductIndex, productW );
- if (r == ERROR_SUCCESS)
- {
- WideCharToMultiByte( CP_ACP, 0, productW, GUID_SIZE,
- lpProductBuf, GUID_SIZE, NULL, NULL );
- }
- msi_free( szwUpgradeCode);
- return r;
-}
-
-/***********************************************************************
- * MsiEnumPatchesExA [MSI.@]
- */
-UINT WINAPI MsiEnumPatchesExA(LPCSTR szProductCode, LPCSTR szUserSid,
- DWORD dwContext, DWORD dwFilter, DWORD dwIndex, LPSTR szPatchCode,
- LPSTR szTargetProductCode, MSIINSTALLCONTEXT *pdwTargetProductContext,
- LPSTR szTargetUserSid, LPDWORD pcchTargetUserSid)
-{
- LPWSTR prodcode = NULL;
- LPWSTR usersid = NULL;
- LPWSTR targsid = NULL;
- WCHAR patch[GUID_SIZE];
- WCHAR targprod[GUID_SIZE];
- DWORD len;
- UINT r;
-
- TRACE("(%s, %s, %d, %d, %d, %p, %p, %p, %p, %p)\n",
- debugstr_a(szProductCode), debugstr_a(szUserSid), dwContext, dwFilter,
- dwIndex, szPatchCode, szTargetProductCode, pdwTargetProductContext,
- szTargetUserSid, pcchTargetUserSid);
-
- if (szTargetUserSid && !pcchTargetUserSid)
- return ERROR_INVALID_PARAMETER;
-
- if (szProductCode) prodcode = strdupAtoW(szProductCode);
- if (szUserSid) usersid = strdupAtoW(szUserSid);
-
- r = MsiEnumPatchesExW(prodcode, usersid, dwContext, dwFilter, dwIndex,
- patch, targprod, pdwTargetProductContext,
- NULL, &len);
- if (r != ERROR_SUCCESS)
- goto done;
-
- WideCharToMultiByte(CP_ACP, 0, patch, -1, szPatchCode,
- GUID_SIZE, NULL, NULL);
- WideCharToMultiByte(CP_ACP, 0, targprod, -1, szTargetProductCode,
- GUID_SIZE, NULL, NULL);
-
- if (!szTargetUserSid)
- {
- if (pcchTargetUserSid)
- *pcchTargetUserSid = len;
-
- goto done;
- }
-
- targsid = msi_alloc(++len * sizeof(WCHAR));
- if (!targsid)
- {
- r = ERROR_OUTOFMEMORY;
- goto done;
- }
-
- r = MsiEnumPatchesExW(prodcode, usersid, dwContext, dwFilter, dwIndex,
- patch, targprod, pdwTargetProductContext,
- targsid, &len);
- if (r != ERROR_SUCCESS || !szTargetUserSid)
- goto done;
-
- WideCharToMultiByte(CP_ACP, 0, targsid, -1, szTargetUserSid,
- *pcchTargetUserSid, NULL, NULL);
-
- len = lstrlenW(targsid);
- if (*pcchTargetUserSid < len + 1)
- {
- r = ERROR_MORE_DATA;
- *pcchTargetUserSid = len * sizeof(WCHAR);
- }
- else
- *pcchTargetUserSid = len;
-
-done:
- msi_free(prodcode);
- msi_free(usersid);
- msi_free(targsid);
-
- return r;
-}
-
-static UINT msi_get_patch_state(LPCWSTR prodcode, LPCWSTR usersid,
- MSIINSTALLCONTEXT context,
- LPWSTR patch, MSIPATCHSTATE *state)
-{
- DWORD type, val, size;
- HKEY prod, hkey = 0;
- HKEY udpatch = 0;
- LONG res;
- UINT r = ERROR_NO_MORE_ITEMS;
-
- *state = MSIPATCHSTATE_INVALID;
-
- r = MSIREG_OpenUserDataProductKey(prodcode, context,
- usersid, &prod, FALSE);
- if (r != ERROR_SUCCESS)
- return ERROR_NO_MORE_ITEMS;
-
- res = RegOpenKeyExW(prod, szPatches, 0, KEY_READ, &hkey);
- if (res != ERROR_SUCCESS)
- goto done;
-
- res = RegOpenKeyExW(hkey, patch, 0, KEY_READ, &udpatch);
- if (res != ERROR_SUCCESS)
- goto done;
-
- size = sizeof(DWORD);
- res = RegGetValueW(udpatch, NULL, szState, RRF_RT_DWORD, &type, &val, &size);
- if (res != ERROR_SUCCESS ||
- val < MSIPATCHSTATE_APPLIED || val > MSIPATCHSTATE_REGISTERED)
- {
- r = ERROR_BAD_CONFIGURATION;
- goto done;
- }
-
- *state = val;
- r = ERROR_SUCCESS;
-
-done:
- RegCloseKey(udpatch);
- RegCloseKey(hkey);
- RegCloseKey(prod);
-
- return r;
-}
-
-static UINT msi_check_product_patches(LPCWSTR prodcode, LPCWSTR usersid,
- MSIINSTALLCONTEXT context, DWORD filter, DWORD index, DWORD *idx,
- LPWSTR patch, LPWSTR targetprod, MSIINSTALLCONTEXT *targetctx,
- LPWSTR targetsid, DWORD *sidsize, LPWSTR *transforms)
-{
- MSIPATCHSTATE state = MSIPATCHSTATE_INVALID;
- LPWSTR ptr, patches = NULL;
- HKEY prod, patchkey = 0;
- HKEY localprod = 0, localpatch = 0;
- DWORD type, size;
- LONG res;
- UINT temp, r = ERROR_NO_MORE_ITEMS;
-
- if (MSIREG_OpenProductKey(prodcode, usersid, context,
- &prod, FALSE) != ERROR_SUCCESS)
- return ERROR_NO_MORE_ITEMS;
-
- size = 0;
- res = RegGetValueW(prod, szPatches, szPatches, RRF_RT_ANY, &type, NULL,
- &size);
- if (res != ERROR_SUCCESS)
- goto done;
-
- if (type != REG_MULTI_SZ)
- {
- r = ERROR_BAD_CONFIGURATION;
- goto done;
- }
-
- patches = msi_alloc(size);
- if (!patches)
- {
- r = ERROR_OUTOFMEMORY;
- goto done;
- }
-
- res = RegGetValueW(prod, szPatches, szPatches, RRF_RT_ANY, &type,
- patches, &size);
- if (res != ERROR_SUCCESS)
- goto done;
-
- for (ptr = patches; *ptr && r == ERROR_NO_MORE_ITEMS; ptr += lstrlenW(ptr) + 1)
- {
- if (!unsquash_guid(ptr, patch))
- {
- r = ERROR_BAD_CONFIGURATION;
- goto done;
- }
-
- size = 0;
- res = RegGetValueW(prod, szPatches, ptr, RRF_RT_REG_SZ,
- &type, NULL, &size);
- if (res != ERROR_SUCCESS)
- continue;
-
- if (transforms)
- {
- *transforms = msi_alloc(size);
- if (!*transforms)
- {
- r = ERROR_OUTOFMEMORY;
- goto done;
- }
-
- res = RegGetValueW(prod, szPatches, ptr, RRF_RT_REG_SZ,
- &type, *transforms, &size);
- if (res != ERROR_SUCCESS)
- continue;
- }
-
- if (context == MSIINSTALLCONTEXT_USERMANAGED)
- {
- if (!(filter & MSIPATCHSTATE_APPLIED))
- {
- temp = msi_get_patch_state(prodcode, usersid, context,
- ptr, &state);
- if (temp == ERROR_BAD_CONFIGURATION)
- {
- r = ERROR_BAD_CONFIGURATION;
- goto done;
- }
-
- if (temp != ERROR_SUCCESS || !(filter & state))
- continue;
- }
- }
- else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
- {
- if (!(filter & MSIPATCHSTATE_APPLIED))
- {
- temp = msi_get_patch_state(prodcode, usersid, context,
- ptr, &state);
- if (temp == ERROR_BAD_CONFIGURATION)
- {
- r = ERROR_BAD_CONFIGURATION;
- goto done;
- }
-
- if (temp != ERROR_SUCCESS || !(filter & state))
- continue;
- }
- else
- {
- temp = MSIREG_OpenUserDataPatchKey(patch, context,
- &patchkey, FALSE);
- RegCloseKey(patchkey);
- if (temp != ERROR_SUCCESS)
- continue;
- }
- }
- else if (context == MSIINSTALLCONTEXT_MACHINE)
- {
- usersid = szEmpty;
-
- if (MSIREG_OpenUserDataProductKey(prodcode, context, NULL, &localprod, FALSE) == ERROR_SUCCESS &&
- RegOpenKeyExW(localprod, szPatches, 0, KEY_READ, &localpatch) == ERROR_SUCCESS &&
- RegOpenKeyExW(localpatch, ptr, 0, KEY_READ, &patchkey) == ERROR_SUCCESS)
- {
- res = RegGetValueW(patchkey, NULL, szState, RRF_RT_REG_DWORD,
- &type, &state, &size);
-
- if (!(filter & state))
- res = ERROR_NO_MORE_ITEMS;
-
- RegCloseKey(patchkey);
- }
-
- RegCloseKey(localpatch);
- RegCloseKey(localprod);
-
- if (res != ERROR_SUCCESS)
- continue;
- }
-
- if (*idx < index)
- {
- (*idx)++;
- continue;
- }
-
- r = ERROR_SUCCESS;
- if (targetprod)
- lstrcpyW(targetprod, prodcode);
-
- if (targetctx)
- *targetctx = context;
-
- if (targetsid)
- {
- lstrcpynW(targetsid, usersid, *sidsize);
- if (lstrlenW(usersid) >= *sidsize)
- r = ERROR_MORE_DATA;
- }
-
- if (sidsize)
- {
- *sidsize = lstrlenW(usersid);
- if (!targetsid)
- *sidsize *= sizeof(WCHAR);
- }
- }
-
-done:
- RegCloseKey(prod);
- msi_free(patches);
-
- return r;
-}
-
-static UINT msi_enum_patches(LPCWSTR szProductCode, LPCWSTR szUserSid,
- DWORD dwContext, DWORD dwFilter, DWORD dwIndex, DWORD *idx,
- LPWSTR szPatchCode, LPWSTR szTargetProductCode,
- MSIINSTALLCONTEXT *pdwTargetProductContext, LPWSTR szTargetUserSid,
- LPDWORD pcchTargetUserSid, LPWSTR *szTransforms)
-{
- LPWSTR usersid = NULL;
- UINT r = ERROR_INVALID_PARAMETER;
-
- if (!szUserSid)
- {
- szUserSid = usersid = get_user_sid();
- if (!usersid) return ERROR_FUNCTION_FAILED;
- }
-
- if (dwContext & MSIINSTALLCONTEXT_USERMANAGED)
- {
- r = msi_check_product_patches(szProductCode, szUserSid,
- MSIINSTALLCONTEXT_USERMANAGED, dwFilter,
- dwIndex, idx, szPatchCode,
- szTargetProductCode,
- pdwTargetProductContext, szTargetUserSid,
- pcchTargetUserSid, szTransforms);
- if (r != ERROR_NO_MORE_ITEMS)
- goto done;
- }
-
- if (dwContext & MSIINSTALLCONTEXT_USERUNMANAGED)
- {
- r = msi_check_product_patches(szProductCode, szUserSid,
- MSIINSTALLCONTEXT_USERUNMANAGED, dwFilter,
- dwIndex, idx, szPatchCode,
- szTargetProductCode,
- pdwTargetProductContext, szTargetUserSid,
- pcchTargetUserSid, szTransforms);
- if (r != ERROR_NO_MORE_ITEMS)
- goto done;
- }
-
- if (dwContext & MSIINSTALLCONTEXT_MACHINE)
- {
- r = msi_check_product_patches(szProductCode, szUserSid,
- MSIINSTALLCONTEXT_MACHINE, dwFilter,
- dwIndex, idx, szPatchCode,
- szTargetProductCode,
- pdwTargetProductContext, szTargetUserSid,
- pcchTargetUserSid, szTransforms);
- if (r != ERROR_NO_MORE_ITEMS)
- goto done;
- }
-
-done:
- LocalFree(usersid);
- return r;
-}
-
-/***********************************************************************
- * MsiEnumPatchesExW [MSI.@]
- */
-UINT WINAPI MsiEnumPatchesExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
- DWORD dwContext, DWORD dwFilter, DWORD dwIndex, LPWSTR szPatchCode,
- LPWSTR szTargetProductCode, MSIINSTALLCONTEXT *pdwTargetProductContext,
- LPWSTR szTargetUserSid, LPDWORD pcchTargetUserSid)
-{
- WCHAR squished_pc[GUID_SIZE];
- DWORD idx = 0;
- UINT r;
-
- static DWORD last_index;
-
- TRACE("(%s, %s, %d, %d, %d, %p, %p, %p, %p, %p)\n",
- debugstr_w(szProductCode), debugstr_w(szUserSid), dwContext, dwFilter,
- dwIndex, szPatchCode, szTargetProductCode, pdwTargetProductContext,
- szTargetUserSid, pcchTargetUserSid);
-
- if (!szProductCode || !squash_guid(szProductCode, squished_pc))
- return ERROR_INVALID_PARAMETER;
-
- if (szUserSid && !strcmpW( szUserSid, szLocalSid ))
- return ERROR_INVALID_PARAMETER;
-
- if (dwContext & MSIINSTALLCONTEXT_MACHINE && szUserSid)
- return ERROR_INVALID_PARAMETER;
-
- if (dwContext <= MSIINSTALLCONTEXT_NONE ||
- dwContext > MSIINSTALLCONTEXT_ALL)
- return ERROR_INVALID_PARAMETER;
-
- if (dwFilter <= MSIPATCHSTATE_INVALID || dwFilter > MSIPATCHSTATE_ALL)
- return ERROR_INVALID_PARAMETER;
-
- if (dwIndex && dwIndex - last_index != 1)
- return ERROR_INVALID_PARAMETER;
-
- if (dwIndex == 0)
- last_index = 0;
-
- r = msi_enum_patches(szProductCode, szUserSid, dwContext, dwFilter,
- dwIndex, &idx, szPatchCode, szTargetProductCode,
- pdwTargetProductContext, szTargetUserSid,
- pcchTargetUserSid, NULL);
-
- if (r == ERROR_SUCCESS)
- last_index = dwIndex;
- else
- last_index = 0;
-
- return r;
-}
-
-/***********************************************************************
- * MsiEnumPatchesA [MSI.@]
- */
-UINT WINAPI MsiEnumPatchesA(LPCSTR szProduct, DWORD iPatchIndex,
- LPSTR lpPatchBuf, LPSTR lpTransformsBuf, LPDWORD pcchTransformsBuf)
-{
- LPWSTR product, transforms;
- WCHAR patch[GUID_SIZE];
- DWORD len;
- UINT r;
-
- TRACE("(%s %d %p %p %p)\n", debugstr_a(szProduct), iPatchIndex,
- lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
-
- if (!szProduct || !lpPatchBuf || !lpTransformsBuf || !pcchTransformsBuf)
- return ERROR_INVALID_PARAMETER;
-
- product = strdupAtoW(szProduct);
- if (!product)
- return ERROR_OUTOFMEMORY;
-
- len = *pcchTransformsBuf;
- transforms = msi_alloc( len * sizeof(WCHAR) );
- if (!transforms)
- {
- r = ERROR_OUTOFMEMORY;
- goto done;
- }
-
- r = MsiEnumPatchesW(product, iPatchIndex, patch, transforms, &len);
- if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
- goto done;
-
- WideCharToMultiByte(CP_ACP, 0, patch, -1, lpPatchBuf,
- GUID_SIZE, NULL, NULL);
-
- if (!WideCharToMultiByte(CP_ACP, 0, transforms, -1, lpTransformsBuf,
- *pcchTransformsBuf, NULL, NULL))
- r = ERROR_MORE_DATA;
-
- if (r == ERROR_MORE_DATA)
- {
- lpTransformsBuf[*pcchTransformsBuf - 1] = '\0';
- *pcchTransformsBuf = len * 2;
- }
- else
- *pcchTransformsBuf = strlen( lpTransformsBuf );
-
-done:
- msi_free(transforms);
- msi_free(product);
-
- return r;
-}
-
-/***********************************************************************
- * MsiEnumPatchesW [MSI.@]
- */
-UINT WINAPI MsiEnumPatchesW(LPCWSTR szProduct, DWORD iPatchIndex,
- LPWSTR lpPatchBuf, LPWSTR lpTransformsBuf, LPDWORD pcchTransformsBuf)
-{
- WCHAR squished_pc[GUID_SIZE];
- LPWSTR transforms = NULL;
- HKEY prod;
- DWORD idx = 0;
- UINT r;
-
- TRACE("(%s %d %p %p %p)\n", debugstr_w(szProduct), iPatchIndex,
- lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
-
- if (!szProduct || !squash_guid(szProduct, squished_pc))
- return ERROR_INVALID_PARAMETER;
-
- if (!lpPatchBuf || !lpTransformsBuf || !pcchTransformsBuf)
- return ERROR_INVALID_PARAMETER;
-
- if (MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
- &prod, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
- &prod, FALSE) != ERROR_SUCCESS &&
- MSIREG_OpenProductKey(szProduct, NULL, MSIINSTALLCONTEXT_MACHINE,
- &prod, FALSE) != ERROR_SUCCESS)
- return ERROR_UNKNOWN_PRODUCT;
-
- RegCloseKey(prod);
-
- r = msi_enum_patches(szProduct, NULL, MSIINSTALLCONTEXT_ALL,
- MSIPATCHSTATE_ALL, iPatchIndex, &idx, lpPatchBuf,
- NULL, NULL, NULL, NULL, &transforms);
- if (r != ERROR_SUCCESS)
- goto done;
-
- lstrcpynW(lpTransformsBuf, transforms, *pcchTransformsBuf);
- if (*pcchTransformsBuf <= lstrlenW(transforms))
- {
- r = ERROR_MORE_DATA;
- *pcchTransformsBuf = lstrlenW(transforms);
- }
- else
- *pcchTransformsBuf = lstrlenW(transforms);
-
-done:
- msi_free(transforms);
- return r;
-}
-
-UINT WINAPI MsiEnumProductsExA( LPCSTR product, LPCSTR usersid, DWORD ctx, DWORD index,
- CHAR installed_product[GUID_SIZE],
- MSIINSTALLCONTEXT *installed_ctx, LPSTR sid, LPDWORD sid_len )
-{
- UINT r;
- WCHAR installed_productW[GUID_SIZE], *productW = NULL, *usersidW = NULL, *sidW = NULL;
-
- TRACE("%s, %s, %u, %u, %p, %p, %p, %p\n", debugstr_a(product), debugstr_a(usersid),
- ctx, index, installed_product, installed_ctx, sid, sid_len);
-
- if (sid && !sid_len) return ERROR_INVALID_PARAMETER;
- if (product && !(productW = strdupAtoW( product ))) return ERROR_OUTOFMEMORY;
- if (usersid && !(usersidW = strdupAtoW( usersid )))
- {
- msi_free( productW );
- return ERROR_OUTOFMEMORY;
- }
- if (sid && !(sidW = msi_alloc( *sid_len * sizeof(WCHAR) )))
- {
- msi_free( usersidW );
- msi_free( productW );
- return ERROR_OUTOFMEMORY;
- }
- r = MsiEnumProductsExW( productW, usersidW, ctx, index, installed_productW,
- installed_ctx, sidW, sid_len );
- if (r == ERROR_SUCCESS)
- {
- if (installed_product) WideCharToMultiByte( CP_ACP, 0, installed_productW, GUID_SIZE,
- installed_product, GUID_SIZE, NULL, NULL );
- if (sid) WideCharToMultiByte( CP_ACP, 0, sidW, *sid_len + 1, sid, *sid_len + 1, NULL, NULL );
- }
- msi_free( productW );
- msi_free( usersidW );
- msi_free( sidW );
- return r;
-}
-
-static UINT fetch_machine_product( const WCHAR *match, DWORD index, DWORD *idx,
- WCHAR installed_product[GUID_SIZE],
- MSIINSTALLCONTEXT *installed_ctx, WCHAR *sid, DWORD *sid_len )
-{
- static const WCHAR productsW[] =
- {'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s','\\',
- 'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s',0};
- UINT r;
- WCHAR product[GUID_SIZE];
- DWORD i = 0, len;
- REGSAM access = KEY_ENUMERATE_SUB_KEYS | KEY_WOW64_64KEY;
- HKEY key;
-
- if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, productsW, 0, access, &key ))
- return ERROR_NO_MORE_ITEMS;
-
- len = sizeof(product)/sizeof(product[0]);
- while (!RegEnumKeyExW( key, i, product, &len, NULL, NULL, NULL, NULL ))
- {
- if (match && strcmpW( match, product ))
- {
- i++;
- len = sizeof(product)/sizeof(product[0]);
- continue;
- }
- if (*idx == index) goto found;
- (*idx)++;
- len = sizeof(product)/sizeof(product[0]);
- i++;
- }
- RegCloseKey( key );
- return ERROR_NO_MORE_ITEMS;
-
-found:
- if (sid_len && *sid_len < 1)
- {
- *sid_len = 1;
- r = ERROR_MORE_DATA;
- }
- else
- {
- if (installed_product) unsquash_guid( product, installed_product );
- if (installed_ctx) *installed_ctx = MSIINSTALLCONTEXT_MACHINE;
- if (sid)
- {
- sid[0] = 0;
- *sid_len = 0;
- }
- r = ERROR_SUCCESS;
- }
- RegCloseKey( key );
- return r;
-}
-
-static UINT fetch_user_product( const WCHAR *match, const WCHAR *usersid, DWORD ctx, DWORD index,
- DWORD *idx, WCHAR installed_product[GUID_SIZE],
- MSIINSTALLCONTEXT *installed_ctx, WCHAR *sid, DWORD *sid_len )
-{
- static const WCHAR managedW[] =
- {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s',
- 'i','o','n','\\','I','n','s','t','a','l','l','e','r','\\','M','a','n','a','g','e','d',0};
- static const WCHAR managed_productsW[] =
- {'\\','I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s',0};
- static const WCHAR unmanaged_productsW[] =
- {'\\','S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'I','n','s','t','a','l','l','e','r','\\','P','r','o','d','u','c','t','s',0};
- UINT r;
- const WCHAR *subkey;
- WCHAR path[MAX_PATH], product[GUID_SIZE], user[128];
- DWORD i = 0, j = 0, len_product, len_user;
- REGSAM access = KEY_ENUMERATE_SUB_KEYS | KEY_WOW64_64KEY;
- HKEY key_users, key_products;
-
- if (ctx == MSIINSTALLCONTEXT_USERMANAGED)
- {
- subkey = managed_productsW;
- if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, managedW, 0, access, &key_users ))
- return ERROR_NO_MORE_ITEMS;
- }
- else if (ctx == MSIINSTALLCONTEXT_USERUNMANAGED)
- {
- subkey = unmanaged_productsW;
- if (RegOpenKeyExW( HKEY_USERS, NULL, 0, access, &key_users ))
- return ERROR_NO_MORE_ITEMS;
- }
- else return ERROR_INVALID_PARAMETER;
-
- len_user = sizeof(user)/sizeof(user[0]);
- while (!RegEnumKeyExW( key_users, i, user, &len_user, NULL, NULL, NULL, NULL ))
- {
- if (strcmpW( usersid, user ) && strcmpW( usersid, szAllSid ))
- {
- i++;
- len_user = sizeof(user)/sizeof(user[0]);
- continue;
- }
- strcpyW( path, user );
- strcatW( path, subkey );
- if (RegOpenKeyExW( key_users, path, 0, access, &key_products ))
- {
- i++;
- len_user = sizeof(user)/sizeof(user[0]);
- continue;
- }
- len_product = sizeof(product)/sizeof(product[0]);
- while (!RegEnumKeyExW( key_products, j, product, &len_product, NULL, NULL, NULL, NULL ))
- {
- if (match && strcmpW( match, product ))
- {
- j++;
- len_product = sizeof(product)/sizeof(product[0]);
- continue;
- }
- if (*idx == index) goto found;
- (*idx)++;
- len_product = sizeof(product)/sizeof(product[0]);
- j++;
- }
- RegCloseKey( key_products );
- len_user = sizeof(user)/sizeof(user[0]);
- i++;
- }
- RegCloseKey( key_users );
- return ERROR_NO_MORE_ITEMS;
-
-found:
- if (sid_len && *sid_len <= len_user)
- {
- *sid_len = len_user;
- r = ERROR_MORE_DATA;
- }
- else
- {
- if (installed_product) unsquash_guid( product, installed_product );
- if (installed_ctx) *installed_ctx = ctx;
- if (sid)
- {
- strcpyW( sid, user );
- *sid_len = len_user;
- }
- r = ERROR_SUCCESS;
- }
- RegCloseKey( key_products );
- RegCloseKey( key_users );
- return r;
-}
-
-static UINT enum_products( const WCHAR *product, const WCHAR *usersid, DWORD ctx, DWORD index,
- DWORD *idx, WCHAR installed_product[GUID_SIZE],
- MSIINSTALLCONTEXT *installed_ctx, WCHAR *sid, DWORD *sid_len )
-{
- UINT r = ERROR_NO_MORE_ITEMS;
- WCHAR *user = NULL;
-
- if (!usersid)
- {
- usersid = user = get_user_sid();
- if (!user) return ERROR_FUNCTION_FAILED;
- }
- if (ctx & MSIINSTALLCONTEXT_MACHINE)
- {
- r = fetch_machine_product( product, index, idx, installed_product, installed_ctx,
- sid, sid_len );
- if (r != ERROR_NO_MORE_ITEMS) goto done;
- }
- if (ctx & MSIINSTALLCONTEXT_USERUNMANAGED)
- {
- r = fetch_user_product( product, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, index,
- idx, installed_product, installed_ctx, sid, sid_len );
- if (r != ERROR_NO_MORE_ITEMS) goto done;
- }
- if (ctx & MSIINSTALLCONTEXT_USERMANAGED)
- {
- r = fetch_user_product( product, usersid, MSIINSTALLCONTEXT_USERMANAGED, index,
- idx, installed_product, installed_ctx, sid, sid_len );
- if (r != ERROR_NO_MORE_ITEMS) goto done;
- }
-
-done:
- LocalFree( user );
- return r;
-}
-
-UINT WINAPI MsiEnumProductsExW( LPCWSTR product, LPCWSTR usersid, DWORD ctx, DWORD index,
- WCHAR installed_product[GUID_SIZE],
- MSIINSTALLCONTEXT *installed_ctx, LPWSTR sid, LPDWORD sid_len )
-{
- UINT r;
- DWORD idx = 0;
- static DWORD last_index;
-
- TRACE("%s, %s, %u, %u, %p, %p, %p, %p\n", debugstr_w(product), debugstr_w(usersid),
- ctx, index, installed_product, installed_ctx, sid, sid_len);
-
- if ((sid && !sid_len) || !ctx || (usersid && ctx == MSIINSTALLCONTEXT_MACHINE))
- return ERROR_INVALID_PARAMETER;
-
- if (index && index - last_index != 1)
- return ERROR_INVALID_PARAMETER;
-
- if (!index) last_index = 0;
-
- r = enum_products( product, usersid, ctx, index, &idx, installed_product, installed_ctx,
- sid, sid_len );
- if (r == ERROR_SUCCESS)
- last_index = index;
- else
- last_index = 0;
-
- return r;
-}