Implement Publish Components in order for MsiGetQualifiedComponent

apis to work. Also implement MsiGetQualifiedComponent, or at least some
of the functionality as it is supposed to install stuff if it is
absent, which it does not do yet.
This commit is contained in:
Aric Stewart 2005-04-20 12:50:05 +00:00 committed by Alexandre Julliard
parent 6c303a9ce9
commit 072c5e56a2
5 changed files with 239 additions and 5 deletions

View File

@ -99,6 +99,7 @@ static UINT ACTION_ForceReboot(MSIPACKAGE *package);
static UINT ACTION_ResolveSource(MSIPACKAGE *package);
static UINT ACTION_ExecuteAction(MSIPACKAGE *package);
static UINT ACTION_RegisterFonts(MSIPACKAGE *package);
static UINT ACTION_PublishComponents(MSIPACKAGE *package);
/*
@ -324,7 +325,7 @@ static struct _actions StandardActions[] = {
{ szInstallServices, NULL},
{ szPatchFiles, NULL},
{ szProcessComponents, ACTION_ProcessComponents },
{ szPublishComponents, NULL},
{ szPublishComponents, ACTION_PublishComponents },
{ szPublishFeatures, ACTION_PublishFeatures },
{ szPublishProduct, ACTION_PublishProduct },
{ szRegisterClassInfo, ACTION_RegisterClassInfo },
@ -6292,6 +6293,114 @@ static UINT ACTION_RegisterFonts(MSIPACKAGE *package)
return rc;
}
static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param)
{
MSIPACKAGE *package = (MSIPACKAGE*)param;
LPWSTR productid=NULL, compgroupid=NULL;
LPWSTR feature=NULL;
LPWSTR text = NULL;
LPWSTR qualifier = NULL;
LPWSTR component = NULL;
GUID clsid;
WCHAR productid_85[21];
WCHAR component_85[21];
HKEY hkey;
UINT rc = ERROR_SUCCESS;
UINT index;
/*
* I have a fair bit of confusion as to when a < is used and when a > is
* used. I do not think i have it right...
*/
static WCHAR fmt1[] = {'%','s','%','s','<','%','s',0,0};
static WCHAR fmt2[] = {'%','s','%','s','>',0,0};
LPWSTR output = NULL;
DWORD sz = 0;
memset(productid_85,0,sizeof(productid_85));
memset(component_85,0,sizeof(component_85));
compgroupid = load_dynamic_stringW(rec,1);
rc = MSIREG_OpenUserComponentsKey(compgroupid, &hkey, TRUE);
if (rc != ERROR_SUCCESS)
goto end;
productid = load_dynamic_property(package,szProductCode,NULL);
CLSIDFromString(productid, &clsid);
encode_base85_guid(&clsid,productid_85);
text = load_dynamic_stringW(rec,4);
qualifier = load_dynamic_stringW(rec,2);
feature = load_dynamic_stringW(rec,5);
component = load_dynamic_stringW(rec,3);
index = get_loaded_component(package, component);
CLSIDFromString(package->components[index].ComponentId, &clsid);
encode_base85_guid(&clsid,component_85);
TRACE("Doing something with this... %s = %s %s %s %s\n",
debugstr_w(qualifier), debugstr_w(productid_85),
debugstr_w(feature), debugstr_w(text), debugstr_w(component_85));
sz = lstrlenW(productid_85) + lstrlenW(feature);
if (text)
sz += lstrlenW(text);
if (component && index >= 0)
sz += lstrlenW(component_85);
sz+=3;
sz *= sizeof(WCHAR);
output = HeapAlloc(GetProcessHeap(),0,sz);
memset(output,0,sz);
if (ACTION_VerifyComponentForAction(package, index, INSTALLSTATE_LOCAL))
sprintfW(output,fmt1,productid_85,feature,component_85);
else
sprintfW(output,fmt2,productid_85,feature);
if (text)
strcatW(output,text);
sz = (lstrlenW(output)+2) * sizeof(WCHAR);
RegSetValueExW(hkey, qualifier,0,REG_MULTI_SZ, (LPBYTE)output, sz);
end:
RegCloseKey(hkey);
HeapFree(GetProcessHeap(),0,output);
HeapFree(GetProcessHeap(),0,compgroupid);
HeapFree(GetProcessHeap(),0,component);
HeapFree(GetProcessHeap(),0,productid);
HeapFree(GetProcessHeap(),0,feature);
HeapFree(GetProcessHeap(),0,text);
HeapFree(GetProcessHeap(),0,qualifier);
return rc;
}
/*
* At present I am ignorning the advertised components part of this and only
* focusing on the qualified component sets
*/
static UINT ACTION_PublishComponents(MSIPACKAGE *package)
{
UINT rc;
MSIQUERY * view;
static const WCHAR ExecSeqQuery[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'P','u','b','l','i','s','h','C','o','m','p','o','n','e','n','t',0};
rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
rc = MSI_IterateRecords(view, NULL, ITERATE_PublishComponent, package);
msiobj_release(&view->hdr);
return rc;
}
/* Msi functions that seem appropriate here */
UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
{

View File

@ -35,6 +35,7 @@
#include "wincrypt.h"
#include "winver.h"
#include "winuser.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi);
@ -1297,11 +1298,107 @@ UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
DWORD* pcchPathBuf)
{
FIXME("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
HKEY hkey;
UINT rc;
LPWSTR info;
DWORD sz;
LPWSTR product = NULL;
LPWSTR component = NULL;
LPWSTR ptr;
GUID clsid;
TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
Unused1, Unused2, lpPathBuf, pcchPathBuf);
rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
if (rc != ERROR_SUCCESS)
return ERROR_INDEX_ABSENT;
sz = 0;
rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, NULL, &sz);
if (sz <= 0)
{
RegCloseKey(hkey);
return ERROR_INDEX_ABSENT;
}
info = HeapAlloc(GetProcessHeap(),0,sz);
rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, (LPBYTE)info, &sz);
if (rc != ERROR_SUCCESS)
{
RegCloseKey(hkey);
HeapFree(GetProcessHeap(),0,info);
return ERROR_INDEX_ABSENT;
}
/* find the component */
ptr = strchrW(&info[20],'<');
if (ptr)
ptr++;
else
{
RegCloseKey(hkey);
HeapFree(GetProcessHeap(),0,info);
return ERROR_INDEX_ABSENT;
}
if (!szProduct)
{
decode_base85_guid(info,&clsid);
StringFromCLSID(&clsid, &product);
}
decode_base85_guid(ptr,&clsid);
StringFromCLSID(&clsid, &component);
if (!szProduct)
rc = MsiGetComponentPathW(product, component, lpPathBuf, pcchPathBuf);
else
rc = MsiGetComponentPathW(szProduct, component, lpPathBuf, pcchPathBuf);
RegCloseKey(hkey);
HeapFree(GetProcessHeap(),0,info);
HeapFree(GetProcessHeap(),0,product);
HeapFree(GetProcessHeap(),0,component);
return rc;
}
UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
DWORD* pcchPathBuf)
{
return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
}
UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
DWORD* pcchPathBuf)
{
LPWSTR szwComponent, szwQualifier, lpwPathBuf;
DWORD pcchwPathBuf;
UINT rc;
TRACE("%s %s %li %p %p\n",szComponent, szQualifier,
dwInstallMode, lpPathBuf, pcchPathBuf);
szwComponent= strdupAtoW( szComponent);
szwQualifier= strdupAtoW( szQualifier);
lpwPathBuf = HeapAlloc(GetProcessHeap(),0,*pcchPathBuf * sizeof(WCHAR));
pcchwPathBuf = *pcchPathBuf;
rc = MsiProvideQualifiedComponentW(szwComponent, szwQualifier,
dwInstallMode, lpwPathBuf, &pcchwPathBuf);
HeapFree(GetProcessHeap(),0,szwComponent);
HeapFree(GetProcessHeap(),0,szwQualifier);
*pcchPathBuf = WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, pcchwPathBuf,
lpPathBuf, *pcchPathBuf, NULL, NULL);
HeapFree(GetProcessHeap(),0,lpwPathBuf);
return rc;
}
USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf,

View File

@ -105,8 +105,8 @@
105 stdcall MsiProvideComponentFromDescriptorA(str ptr ptr ptr)
106 stdcall MsiProvideComponentFromDescriptorW(wstr ptr ptr ptr)
107 stub MsiProvideComponentW
108 stub MsiProvideQualifiedComponentA
109 stub MsiProvideQualifiedComponentW
108 stdcall MsiProvideQualifiedComponentA(str str long ptr ptr)
109 stdcall MsiProvideQualifiedComponentW(str str long ptr ptr)
110 stdcall MsiQueryFeatureStateA(str str)
111 stdcall MsiQueryFeatureStateW(wstr wstr)
112 stdcall MsiQueryProductStateA(str)

View File

@ -357,6 +357,7 @@ extern UINT MSIREG_OpenUserProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create
extern UINT MSIREG_OpenFeatures(HKEY* key);
extern UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
extern UINT MSIREG_OpenComponents(HKEY* key);
extern UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create);
extern UINT MSIREG_OpenComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create);
extern UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create);
extern UINT MSIREG_OpenUserFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create);

View File

@ -85,6 +85,13 @@ static const WCHAR szInstaller_Components_fmt[] = {
'C','o','m','p','o','n','e','n','t','s','\\',
'%','s',0};
static const WCHAR szUser_Components_fmt[] = {
'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','\\',
'%','s',0};
static const WCHAR szUninstall_fmt[] = {
'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
@ -388,6 +395,26 @@ UINT MSIREG_OpenComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create)
return rc;
}
UINT MSIREG_OpenUserComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create)
{
UINT rc;
WCHAR squished_cc[GUID_SIZE];
WCHAR keypath[0x200];
TRACE("%s\n",debugstr_w(szComponent));
squash_guid(szComponent,squished_cc);
TRACE("squished (%s)\n", debugstr_w(squished_cc));
sprintfW(keypath,szUser_Components_fmt,squished_cc);
if (create)
rc = RegCreateKeyW(HKEY_CURRENT_USER,keypath,key);
else
rc = RegOpenKeyW(HKEY_CURRENT_USER,keypath,key);
return rc;
}
UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create)
{
UINT rc;