msi: PublishComponents and MsiGetQualifiedComponentExW

Aric Stewart aric at codeweavers.com
Mon Apr 18 14:03:31 CDT 2005


Implement Publish Components in order for MsiGetQualifiedComponent apis to work. Also implement MsiGetQualifiedCompoent, or at least some of the functionality as it is suppose to install stuff if it is absent, which it does not do yet.

-------------- next part --------------
Index: dlls/msi/action.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/action.c,v
retrieving revision 1.107
diff -u -r1.107 action.c
--- dlls/msi/action.c	11 Apr 2005 16:10:33 -0000	1.107
+++ dlls/msi/action.c	18 Apr 2005 18:57:51 -0000
@@ -99,6 +99,7 @@
 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 @@
     { szInstallServices, NULL},
     { szPatchFiles, NULL},
     { szProcessComponents, ACTION_ProcessComponents },
-    { szPublishComponents, NULL},
+    { szPublishComponents, ACTION_PublishComponents },
     { szPublishFeatures, ACTION_PublishFeatures },
     { szPublishProduct, ACTION_PublishProduct },
     { szRegisterClassInfo, ACTION_RegisterClassInfo },
@@ -6288,6 +6289,113 @@
 
     RegCloseKey(hkey1);
     RegCloseKey(hkey2);
+
+    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 buf[21];
+    WCHAR buf2[21];
+    memset(buf,0,sizeof(buf));
+    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;
+
+    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);
+    FIXME("product id %s\n",debugstr_w(productid));
+    CLSIDFromString(productid, &clsid);
+    
+    encode_base85_guid(&clsid,buf);
+
+    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,buf2);
+
+    TRACE("Doing something with this... %s = %s %s %s %s\n", 
+            debugstr_w(qualifier), debugstr_w(buf), debugstr_w(feature), 
+            debugstr_w(text), debugstr_w(buf2));
+ 
+    sz = lstrlenW(buf) + lstrlenW(feature);
+    if (text)
+        sz += lstrlenW(text);
+    if (component && index >= 0)
+        sz += lstrlenW(buf2);
+
+    sz+=3;
+    sz *= sizeof(WCHAR);
+           
+    output = HeapAlloc(GetProcessHeap(),0,sz);
+    memset(output,0,sz);
+
+    if (ACTION_VerifyComponentForAction(package, index, INSTALLSTATE_LOCAL))
+        sprintfW(output,fmt1,buf,feature,buf2);
+    else
+        sprintfW(output,fmt2,buf,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);
 
     return rc;
 }
Index: dlls/msi/msi.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/msi.c,v
retrieving revision 1.71
diff -u -r1.71 msi.c
--- dlls/msi/msi.c	29 Mar 2005 11:28:57 -0000	1.71
+++ dlls/msi/msi.c	18 Apr 2005 18:57:52 -0000
@@ -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,93 @@
                 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;
+    WCHAR info[124];
+    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;
+
+    sz = sizeof(info);
+    rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, (LPVOID) info, &sz);
+    if (rc != ERROR_SUCCESS)
+        return ERROR_INDEX_ABSENT;
+
+    /* find the component */
+    ptr = strchrW(&info[20],'<');
+    if (ptr)
+        ptr++;
+    else
+    {
+        RegCloseKey(hkey);
+        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);
+   
+    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));
 
-    return ERROR_INDEX_ABSENT;
+    pcchwPathBuf = *pcchPathBuf;
+
+    rc = MsiProvideQualifiedComponentW(szwComponent, szwQualifier, 
+                    dwInstallMode, lpwPathBuf, &pcchwPathBuf);
+
+    HeapFree(GetProcessHeap(),0,szwComponent);
+    HeapFree(GetProcessHeap(),0,szwQualifier);
+    WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, pcchwPathBuf, lpPathBuf, 
+                    *pcchPathBuf, NULL, NULL);
+    *pcchPathBuf = pcchwPathBuf;
+
+    HeapFree(GetProcessHeap(),0,lpwPathBuf);
+    return rc;
 }
 
 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf,
Index: dlls/msi/msi.spec
===================================================================
RCS file: /home/wine/wine/dlls/msi/msi.spec,v
retrieving revision 1.34
diff -u -r1.34 msi.spec
--- dlls/msi/msi.spec	23 Mar 2005 10:24:53 -0000	1.34
+++ dlls/msi/msi.spec	18 Apr 2005 18:57:52 -0000
@@ -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)
Index: dlls/msi/msipriv.h
===================================================================
RCS file: /home/wine/wine/dlls/msi/msipriv.h,v
retrieving revision 1.52
diff -u -r1.52 msipriv.h
--- dlls/msi/msipriv.h	11 Apr 2005 12:47:20 -0000	1.52
+++ dlls/msi/msipriv.h	18 Apr 2005 18:57:52 -0000
@@ -357,6 +357,7 @@
 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);
Index: dlls/msi/registry.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/registry.c,v
retrieving revision 1.6
diff -u -r1.6 registry.c
--- dlls/msi/registry.c	24 Mar 2005 15:09:18 -0000	1.6
+++ dlls/msi/registry.c	18 Apr 2005 18:57:52 -0000
@@ -85,6 +85,13 @@
 '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','\\',
@@ -384,6 +391,26 @@
         rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,keypath,key);
     else
         rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,keypath,key);
+
+    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;
 }


More information about the wine-patches mailing list