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:
parent
6c303a9ce9
commit
072c5e56a2
|
@ -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 )
|
||||
{
|
||||
|
|
101
dlls/msi/msi.c
101
dlls/msi/msi.c
|
@ -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;
|
||||
|
||||
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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue