MSI: resubmit last patch

Aric Stewart aric at codeweavers.com
Thu Apr 28 08:39:20 CDT 2005


Missed a HeapFree.
-------------- next part --------------
Index: dlls/msi/action.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/action.c,v
retrieving revision 1.110
diff -u -r1.110 action.c
--- dlls/msi/action.c	27 Apr 2005 10:16:57 -0000	1.110
+++ dlls/msi/action.c	28 Apr 2005 13:38:18 -0000
@@ -6310,9 +6310,12 @@
     /*
      * 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...
+     *
+     * 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 fmt2[] = {'%','s','%','s','>',0,0};
+    static WCHAR fmt1[] = {'%','s','%','s','<',0,0};
+    static WCHAR fmt2[] = {'%','s','%','s','>','%','s',0,0};
     LPWSTR output = NULL;
     DWORD sz = 0;
 
@@ -6355,10 +6358,10 @@
     output = HeapAlloc(GetProcessHeap(),0,sz);
     memset(output,0,sz);
 
-    if (ACTION_VerifyComponentForAction(package, index, INSTALLSTATE_LOCAL))
-        sprintfW(output,fmt1,productid_85,feature,component_85);
+    if (component && index >= 0)
+        sprintfW(output,fmt2,productid_85,feature,component_85);
     else
-        sprintfW(output,fmt2,productid_85,feature);
+        sprintfW(output,fmt1,productid_85,feature);
 
     if (text)
         strcatW(output,text);
Index: dlls/msi/msi.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/msi.c,v
retrieving revision 1.78
diff -u -r1.78 msi.c
--- dlls/msi/msi.c	28 Apr 2005 12:01:06 -0000	1.78
+++ dlls/msi/msi.c	28 Apr 2005 13:38:19 -0000
@@ -1425,7 +1425,7 @@
     }
 
     /* find the component */
-    ptr = strchrW(&info[20],'<');
+    ptr = strchrW(&info[20],'>');
     if (ptr)
         ptr++;
     else
Index: dlls/msi/registry.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/registry.c,v
retrieving revision 1.7
diff -u -r1.7 registry.c
--- dlls/msi/registry.c	20 Apr 2005 12:50:05 -0000	1.7
+++ dlls/msi/registry.c	28 Apr 2005 13:38:19 -0000
@@ -726,20 +726,136 @@
                 LPSTR lpQualifierBuf, DWORD* pcchQualifierBuf,
                 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,
           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,
                 LPWSTR lpQualifierBuf, DWORD* pcchQualifierBuf,
                 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,
           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,


More information about the wine-patches mailing list