From cfb10615e177f2d98984bd4683e4c71dbced4fc5 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Tue, 25 Oct 2016 09:11:47 +0200 Subject: [PATCH] msi: Accept descriptors without component. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/msi/registry.c | 37 +++++++++++++++++++++++-------------- dlls/msi/tests/db.c | 23 +++++++++++++++++++++++ 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/dlls/msi/registry.c b/dlls/msi/registry.c index f3b1ddf2444..8e6f0a1101b 100644 --- a/dlls/msi/registry.c +++ b/dlls/msi/registry.c @@ -1024,7 +1024,8 @@ UINT MSIREG_DeleteClassesUpgradeCodesKey(LPCWSTR szUpgradeCode) * * 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] + * [base 85 guid] [feature code] '>' [base 85 guid] or + * [base 85 guid] [feature code] '<' * * PARAMS * szDescriptor [I] the descriptor to decompose @@ -1041,21 +1042,21 @@ UINT MSIREG_DeleteClassesUpgradeCodesKey(LPCWSTR szUpgradeCode) UINT WINAPI MsiDecomposeDescriptorW( LPCWSTR szDescriptor, LPWSTR szProduct, LPWSTR szFeature, LPWSTR szComponent, LPDWORD pUsed ) { - UINT r, len; - LPWSTR p; + UINT len; + const WCHAR *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 ) + if (!decode_base85_guid( szDescriptor, &product )) return ERROR_INVALID_PARAMETER; TRACE("product %s\n", debugstr_guid( &product )); - p = strchrW(&szDescriptor[20],'>'); - if( !p ) + if (!(p = strchrW( &szDescriptor[20], '>' ))) + p = strchrW( &szDescriptor[20], '<' ); + if (!p) return ERROR_INVALID_PARAMETER; len = (p - &szDescriptor[20]); @@ -1064,22 +1065,30 @@ UINT WINAPI MsiDecomposeDescriptorW( LPCWSTR szDescriptor, LPWSTR szProduct, 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 (*p == '>') + { + if (!decode_base85_guid( p+1, &component )) + 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 (*p == '>') + StringFromGUID2( &component, szComponent, MAX_FEATURE_CHARS+1 ); + else + szComponent[0] = 0; + } if (szFeature) { memcpy( szFeature, &szDescriptor[20], len*sizeof(WCHAR) ); szFeature[len] = 0; } - len = ( &p[21] - szDescriptor ); + + len = p - szDescriptor + 1; + if (*p == '>') len += 20; TRACE("length = %d\n", len); if (pUsed) *pUsed = len; diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index 9c1fcbad391..278b45f9580 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -470,6 +470,7 @@ static void test_msidecomposedesc(void) /* test a valid feature descriptor */ desc = "']gAVn-}f(ZXfeAR6.jiFollowTheWhiteRabbit>3w2x^IGfe?CxI5heAvk."; len = 0; + prod[0] = feature[0] = comp[0] = 0; r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len); ok(r == ERROR_SUCCESS, "returned an error\n"); ok(len == strlen(desc), "length was wrong\n"); @@ -485,6 +486,28 @@ static void test_msidecomposedesc(void) r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len); ok(r == ERROR_INVALID_PARAMETER, "returned wrong error\n"); + /* test a feature descriptor with < instead of > */ + desc = "']gAVn-}f(ZXfeAR6.jiFollowTheWhiteRabbit<3w2x^IGfe?CxI5heAvk."; + len = 0; + prod[0] = feature[0] = 0; + comp[0] = 0x55; + r = pMsiDecomposeDescriptorA(desc, prod, feature, comp, &len); + ok(r == ERROR_SUCCESS, "returned an error\n"); + ok(len == 41, "got %u\n", len); + ok(!strcmp(prod,"{90110409-6000-11D3-8CFE-0150048383C9}"), "got '%s'\n", prod); + ok(!strcmp(feature,"FollowTheWhiteRabbit"), "got '%s'\n", feature); + ok(!comp[0], "got '%s'\n", comp); + + len = 0; + prod[0] = feature[0] = 0; + comp[0] = 0x55; + r = pMsiDecomposeDescriptorA("yh1BVN)8A$!!!!!MKKSkAlwaysInstalledIntl_1033<", prod, feature, comp, &len); + ok(r == ERROR_SUCCESS, "got %u\n", r); + ok(len == 45, "got %u\n", len); + ok(!strcmp(prod, "{90150000-006E-0409-0000-0000000FF1CE}"), "got '%s'\n", prod); + ok(!strcmp(feature, "AlwaysInstalledIntl_1033"), "got '%s'\n", feature); + ok(!comp[0], "got '%s'\n", comp); + /* * Test a valid feature descriptor with the * maximum number of characters and some trailing characters.