diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2012-10-22 12:31:42 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2012-12-06 20:25:48 +0100 |
commit | 0d6fdca97e8d8c0ee138f644f9ac42672db77965 (patch) | |
tree | 37278579004beda02b6dd01179a78eb32779e844 /libmsi | |
parent | 149cfb4172e051be4220f8d15b37e258b424e024 (diff) | |
download | msitools-0d6fdca97e8d8c0ee138f644f9ac42672db77965.tar.gz msitools-0d6fdca97e8d8c0ee138f644f9ac42672db77965.tar.xz msitools-0d6fdca97e8d8c0ee138f644f9ac42672db77965.zip |
kill registry.c
Diffstat (limited to 'libmsi')
-rw-r--r-- | libmsi/Makefile.am | 2 | ||||
-rw-r--r-- | libmsi/msi.c | 1977 | ||||
-rw-r--r-- | libmsi/package.c | 254 | ||||
-rw-r--r-- | libmsi/patch.c | 54 | ||||
-rw-r--r-- | libmsi/registry.c | 2479 |
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; -} |