MSI: implement, test and document MsiDecomposeDescriptor
Mike McCormack
mike at codeweavers.com
Tue Jan 25 09:01:49 CST 2005
This function is undocumented by MSDN. Fixed conflict with Aric's patch.
Mike
ChangeLog:
* implement, test and document MsiDecomposeDescriptor
-------------- next part --------------
Index: dlls/msi/msi.spec
===================================================================
RCS file: /home/wine/wine/dlls/msi/msi.spec,v
retrieving revision 1.28
diff -u -p -r1.28 msi.spec
--- dlls/msi/msi.spec 21 Jan 2005 10:17:01 -0000 1.28
+++ dlls/msi/msi.spec 25 Jan 2005 15:00:37 -0000
@@ -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)
Index: dlls/msi/registry.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/registry.c,v
retrieving revision 1.1
diff -u -p -r1.1 registry.c
--- dlls/msi/registry.c 25 Jan 2005 10:58:36 -0000 1.1
+++ dlls/msi/registry.c 25 Jan 2005 15:00:37 -0000
@@ -388,3 +388,99 @@ UINT MSIREG_OpenProductsKey(LPCWSTR szPr
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;
+}
Index: dlls/msi/tests/db.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/tests/db.c,v
retrieving revision 1.3
diff -u -p -r1.3 db.c
--- dlls/msi/tests/db.c 20 Jan 2005 20:39:15 -0000 1.3
+++ dlls/msi/tests/db.c 25 Jan 2005 15:00:37 -0000
@@ -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();
}
More information about the wine-patches
mailing list