Correct user component publication.
Implement MsiEnumComponentQualifiers.
This commit is contained in:
parent
c4d25aec20
commit
2b8bf597b5
|
@ -6310,9 +6310,12 @@ static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param)
|
||||||
/*
|
/*
|
||||||
* I have a fair bit of confusion as to when a < is used and when a > is
|
* 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...
|
* used. I do not think i have it right...
|
||||||
|
*
|
||||||
|
* Ok it appears that the > is used if there is a guid for the compoenent
|
||||||
|
* and the < is used if not.
|
||||||
*/
|
*/
|
||||||
static WCHAR fmt1[] = {'%','s','%','s','<','%','s',0,0};
|
static WCHAR fmt1[] = {'%','s','%','s','<',0,0};
|
||||||
static WCHAR fmt2[] = {'%','s','%','s','>',0,0};
|
static WCHAR fmt2[] = {'%','s','%','s','>','%','s',0,0};
|
||||||
LPWSTR output = NULL;
|
LPWSTR output = NULL;
|
||||||
DWORD sz = 0;
|
DWORD sz = 0;
|
||||||
|
|
||||||
|
@ -6355,10 +6358,10 @@ static UINT ITERATE_PublishComponent(MSIRECORD *rec, LPVOID param)
|
||||||
output = HeapAlloc(GetProcessHeap(),0,sz);
|
output = HeapAlloc(GetProcessHeap(),0,sz);
|
||||||
memset(output,0,sz);
|
memset(output,0,sz);
|
||||||
|
|
||||||
if (ACTION_VerifyComponentForAction(package, index, INSTALLSTATE_LOCAL))
|
if (component && index >= 0)
|
||||||
sprintfW(output,fmt1,productid_85,feature,component_85);
|
sprintfW(output,fmt2,productid_85,feature,component_85);
|
||||||
else
|
else
|
||||||
sprintfW(output,fmt2,productid_85,feature);
|
sprintfW(output,fmt1,productid_85,feature);
|
||||||
|
|
||||||
if (text)
|
if (text)
|
||||||
strcatW(output,text);
|
strcatW(output,text);
|
||||||
|
|
|
@ -1425,7 +1425,7 @@ UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find the component */
|
/* find the component */
|
||||||
ptr = strchrW(&info[20],'<');
|
ptr = strchrW(&info[20],'>');
|
||||||
if (ptr)
|
if (ptr)
|
||||||
ptr++;
|
ptr++;
|
||||||
else
|
else
|
||||||
|
|
|
@ -726,20 +726,136 @@ UINT WINAPI MsiEnumComponentQualifiersA( LPSTR szComponent, DWORD iIndex,
|
||||||
LPSTR lpQualifierBuf, DWORD* pcchQualifierBuf,
|
LPSTR lpQualifierBuf, DWORD* pcchQualifierBuf,
|
||||||
LPSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf)
|
LPSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf)
|
||||||
{
|
{
|
||||||
FIXME("%s %08lx %p %p %p %p\n", debugstr_a(szComponent), iIndex,
|
LPWSTR szwComponent;
|
||||||
|
LPWSTR lpwQualifierBuf;
|
||||||
|
DWORD pcchwQualifierBuf;
|
||||||
|
LPWSTR lpwApplicationDataBuf;
|
||||||
|
DWORD pcchwApplicationDataBuf;
|
||||||
|
DWORD rc;
|
||||||
|
DWORD length;
|
||||||
|
|
||||||
|
TRACE("%s %08lx %p %p %p %p\n", debugstr_a(szComponent), iIndex,
|
||||||
lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf,
|
lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf,
|
||||||
pcchApplicationDataBuf);
|
pcchApplicationDataBuf);
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
|
||||||
|
szwComponent = strdupAtoW(szComponent);
|
||||||
|
|
||||||
|
if (lpQualifierBuf)
|
||||||
|
lpwQualifierBuf = HeapAlloc(GetProcessHeap(),0, (*pcchQualifierBuf) *
|
||||||
|
sizeof(WCHAR));
|
||||||
|
else
|
||||||
|
lpwQualifierBuf = NULL;
|
||||||
|
|
||||||
|
if (pcchQualifierBuf)
|
||||||
|
pcchwQualifierBuf = *pcchQualifierBuf;
|
||||||
|
else
|
||||||
|
pcchwQualifierBuf = 0;
|
||||||
|
|
||||||
|
if (lpApplicationDataBuf)
|
||||||
|
lpwApplicationDataBuf = HeapAlloc(GetProcessHeap(),0 ,
|
||||||
|
(*pcchApplicationDataBuf) * sizeof(WCHAR));
|
||||||
|
else
|
||||||
|
lpwApplicationDataBuf = NULL;
|
||||||
|
|
||||||
|
if (pcchApplicationDataBuf)
|
||||||
|
pcchwApplicationDataBuf = *pcchApplicationDataBuf;
|
||||||
|
else
|
||||||
|
pcchwApplicationDataBuf = 0;
|
||||||
|
|
||||||
|
rc = MsiEnumComponentQualifiersW( szwComponent, iIndex, lpwQualifierBuf,
|
||||||
|
&pcchwQualifierBuf, lpwApplicationDataBuf,
|
||||||
|
&pcchwApplicationDataBuf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A bit of wizardry to report back the length without the null.
|
||||||
|
* just in case the buffer is to small and is filled.
|
||||||
|
*/
|
||||||
|
if (lpQualifierBuf)
|
||||||
|
{
|
||||||
|
length = WideCharToMultiByte(CP_ACP, 0, lpwQualifierBuf, -1,
|
||||||
|
lpQualifierBuf, *pcchQualifierBuf, NULL, NULL);
|
||||||
|
|
||||||
|
if (*pcchQualifierBuf == length && lpQualifierBuf[length-1])
|
||||||
|
*pcchQualifierBuf = length;
|
||||||
|
else
|
||||||
|
*pcchQualifierBuf = length - 1;
|
||||||
|
}
|
||||||
|
if (lpApplicationDataBuf)
|
||||||
|
{
|
||||||
|
length = WideCharToMultiByte(CP_ACP, 0,
|
||||||
|
lpwApplicationDataBuf, -1, lpApplicationDataBuf,
|
||||||
|
*pcchApplicationDataBuf, NULL, NULL);
|
||||||
|
|
||||||
|
if (*pcchApplicationDataBuf == length && lpApplicationDataBuf[length-1])
|
||||||
|
*pcchApplicationDataBuf = length;
|
||||||
|
else
|
||||||
|
*pcchApplicationDataBuf = length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(),0,lpwApplicationDataBuf);
|
||||||
|
HeapFree(GetProcessHeap(),0,lpwQualifierBuf);
|
||||||
|
HeapFree(GetProcessHeap(),0,szwComponent);
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT WINAPI MsiEnumComponentQualifiersW( LPWSTR szComponent, DWORD iIndex,
|
UINT WINAPI MsiEnumComponentQualifiersW( LPWSTR szComponent, DWORD iIndex,
|
||||||
LPWSTR lpQualifierBuf, DWORD* pcchQualifierBuf,
|
LPWSTR lpQualifierBuf, DWORD* pcchQualifierBuf,
|
||||||
LPWSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf )
|
LPWSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf )
|
||||||
{
|
{
|
||||||
FIXME("%s %08lx %p %p %p %p\n", debugstr_w(szComponent), iIndex,
|
UINT rc;
|
||||||
|
HKEY key;
|
||||||
|
DWORD actual_pcchQualifierBuf = 0;
|
||||||
|
DWORD actual_pcchApplicationDataBuf = 0;
|
||||||
|
LPWSTR full_buffer = NULL;
|
||||||
|
DWORD full_buffer_size = 0;
|
||||||
|
LPWSTR ptr;
|
||||||
|
|
||||||
|
TRACE("%s %08lx %p %p %p %p\n", debugstr_w(szComponent), iIndex,
|
||||||
lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf,
|
lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf,
|
||||||
pcchApplicationDataBuf);
|
pcchApplicationDataBuf);
|
||||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
|
||||||
|
if (pcchQualifierBuf)
|
||||||
|
actual_pcchQualifierBuf = *pcchQualifierBuf * sizeof(WCHAR);
|
||||||
|
if (pcchApplicationDataBuf)
|
||||||
|
actual_pcchApplicationDataBuf = *pcchApplicationDataBuf * sizeof(WCHAR);
|
||||||
|
|
||||||
|
rc = MSIREG_OpenUserComponentsKey(szComponent, &key, FALSE);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
return ERROR_UNKNOWN_COMPONENT;
|
||||||
|
|
||||||
|
full_buffer_size = (52 * sizeof(WCHAR)) + actual_pcchApplicationDataBuf;
|
||||||
|
full_buffer = HeapAlloc(GetProcessHeap(),0,full_buffer_size);
|
||||||
|
|
||||||
|
rc = RegEnumValueW(key, iIndex, lpQualifierBuf, pcchQualifierBuf, NULL,
|
||||||
|
NULL, (LPBYTE)full_buffer, &full_buffer_size);
|
||||||
|
|
||||||
|
RegCloseKey(key);
|
||||||
|
|
||||||
|
if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA)
|
||||||
|
{
|
||||||
|
if (lpApplicationDataBuf && pcchApplicationDataBuf)
|
||||||
|
{
|
||||||
|
ptr = full_buffer;
|
||||||
|
/* Skip the first guid */
|
||||||
|
ptr += 21;
|
||||||
|
|
||||||
|
/* Skip the name and the component guid if it exists */
|
||||||
|
if (strchrW(ptr,'<'))
|
||||||
|
ptr = strchrW(ptr,'<');
|
||||||
|
else
|
||||||
|
ptr = strchrW(ptr,'>') + 21;
|
||||||
|
|
||||||
|
lstrcpynW(lpApplicationDataBuf,ptr,*pcchApplicationDataBuf);
|
||||||
|
*pcchApplicationDataBuf = strlenW(ptr);
|
||||||
|
}
|
||||||
|
if (lpQualifierBuf && pcchQualifierBuf)
|
||||||
|
*pcchQualifierBuf /= sizeof(WCHAR);
|
||||||
|
TRACE("Providing %s and %s\n", debugstr_w(lpQualifierBuf),
|
||||||
|
debugstr_w(lpApplicationDataBuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT WINAPI MsiEnumRelatedProductsW(LPCWSTR szUpgradeCode, DWORD dwReserved,
|
UINT WINAPI MsiEnumRelatedProductsW(LPCWSTR szUpgradeCode, DWORD dwReserved,
|
||||||
|
|
Loading…
Reference in New Issue