Implement, test and document MsiDecomposeDescriptor.

This commit is contained in:
Mike McCormack 2005-01-25 16:41:33 +00:00 committed by Alexandre Julliard
parent 6126fc75c9
commit 5af66fef43
3 changed files with 150 additions and 2 deletions

View file

@ -197,8 +197,8 @@
197 stdcall MsiLoadStringW(long long long long long)
198 stdcall MsiMessageBoxA(long long long long long long)
199 stdcall MsiMessageBoxW(long long long long long long)
200 stub MsiDecomposeDescriptorA
201 stub MsiDecomposeDescriptorW
200 stdcall MsiDecomposeDescriptorA(str str ptr ptr ptr)
201 stdcall MsiDecomposeDescriptorW(wstr wstr ptr ptr ptr)
202 stub MsiProvideQualifiedComponentExA
203 stdcall MsiProvideQualifiedComponentExW(wstr wstr long wstr long long ptr ptr)
204 stdcall MsiEnumRelatedProductsA(str long long ptr)

View file

@ -388,3 +388,99 @@ UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create)
return rc;
}
/*************************************************************************
* 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 for the product guid
* szFeature [O] buffer of MAX_FEATURE_CHARS for the feature code
* szComponent [O] buffer of MAX_FEATURE_CHARS 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, DWORD *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;
memcpy( szFeature, &szDescriptor[20], len*sizeof(WCHAR) );
szFeature[len] = 0;
TRACE("feature %s\n", debugstr_w( szFeature ));
r = decode_base85_guid( p+1, &component );
if( !r )
return ERROR_INVALID_PARAMETER;
TRACE("component %s\n", debugstr_guid( &component ));
StringFromGUID2( &product, szProduct, MAX_FEATURE_CHARS+1 );
StringFromGUID2( &component, szComponent, MAX_FEATURE_CHARS+1 );
len = ( &p[21] - szDescriptor );
TRACE("length = %d\n", len);
*pUsed = len;
return ERROR_SUCCESS;
}
UINT WINAPI MsiDecomposeDescriptorA( LPCSTR szDescriptor, LPSTR szProduct,
LPSTR szFeature, LPSTR szComponent, DWORD *pUsed )
{
WCHAR product[MAX_FEATURE_CHARS+1];
WCHAR feature[MAX_FEATURE_CHARS+1];
WCHAR component[MAX_FEATURE_CHARS+1];
LPWSTR str = NULL;
UINT r, len;
TRACE("%s %p %p %p %p\n", debugstr_a(szDescriptor), szProduct,
szFeature, szComponent, pUsed);
if( szDescriptor )
{
len = MultiByteToWideChar( CP_ACP, 0, szDescriptor, -1, NULL, 0 );
str = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, szDescriptor, -1, str, len );
}
r = MsiDecomposeDescriptorW( str, product, feature, component, pUsed );
WideCharToMultiByte( CP_ACP, 0, product, MAX_FEATURE_CHARS+1,
szProduct, MAX_FEATURE_CHARS+1, NULL, NULL );
WideCharToMultiByte( CP_ACP, 0, feature, MAX_FEATURE_CHARS+1,
szFeature, MAX_FEATURE_CHARS+1, NULL, NULL );
WideCharToMultiByte( CP_ACP, 0, component, MAX_FEATURE_CHARS+1,
szComponent, MAX_FEATURE_CHARS+1, NULL, NULL );
HeapFree( GetProcessHeap(), 0, str );
return r;
}

View file

@ -120,8 +120,60 @@ void test_msiinsert(void)
ok(r == TRUE, "file didn't exist after commit\n");
}
typedef UINT (WINAPI *fnMsiDecomposeDescriptorA)(LPCSTR, LPCSTR, LPSTR, LPSTR, DWORD *);
fnMsiDecomposeDescriptorA MsiDecomposeDescriptorA;
void test_msidecomposedesc(void)
{
char prod[MAX_FEATURE_CHARS+1], comp[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1];
char *desc;
UINT r;
DWORD len;
HMODULE hmod;
hmod = GetModuleHandle("msi.dll");
if (!hmod)
return;
MsiDecomposeDescriptorA = (fnMsiDecomposeDescriptorA)
GetProcAddress(hmod, "MsiDecomposeDescriptorA");
if (!MsiDecomposeDescriptorA)
return;
/* test a valid feature descriptor */
desc = "']gAVn-}f(ZXfeAR6.jiFollowTheWhiteRabbit>3w2x^IGfe?CxI5heAvk.";
len = 0;
r = MsiDecomposeDescriptorA(desc, prod, feature, comp, &len);
ok(r == ERROR_SUCCESS, "returned an error\n");
ok(len == strlen(desc), "length was wrong\n");
ok(strcmp(prod,"{90110409-6000-11D3-8CFE-0150048383C9}")==0, "product wrong\n");
ok(strcmp(feature,"FollowTheWhiteRabbit")==0, "feature wrong\n");
ok(strcmp(comp,"{A7CD68DB-EF74-49C8-FBB2-A7C463B2AC24}")==0,"component wrong\n");
/* test an invalid feature descriptor with too many characters */
desc = "']gAVn-}f(ZXfeAR6.ji"
"ThisWillFailIfTheresMoreThanAGuidsChars>"
"3w2x^IGfe?CxI5heAvk.";
len = 0;
r = MsiDecomposeDescriptorA(desc, prod, feature, comp, &len);
ok(r == ERROR_INVALID_PARAMETER, "returned wrong error\n");
/*
* Test a valid feature descriptor with the
* maximum number of characters and some trailing characters.
*/
desc = "']gAVn-}f(ZXfeAR6.ji"
"ThisWillWorkIfTheresLTEThanAGuidsChars>"
"3w2x^IGfe?CxI5heAvk."
"extra";
len = 0;
r = MsiDecomposeDescriptorA(desc, prod, feature, comp, &len);
ok(r == ERROR_SUCCESS, "returned wrong error\n");
ok(len == (strlen(desc) - strlen("extra")), "length wrong\n");
}
START_TEST(db)
{
test_msidatabase();
test_msiinsert();
test_msidecomposedesc();
}