Convert MsiEnumComponentQualifiers to use msi_strcpy_to_awstring.

diff --git a/dlls/msi/registry.c b/dlls/msi/registry.c
index 14d54da..941608c 100644
--- a/dlls/msi/registry.c
+++ b/dlls/msi/registry.c
@@ -541,7 +541,7 @@
         szFeature[len] = 0;
     }
 
-    TRACE("feature %s\n", debugstr_w( szFeature ));
+    TRACE("feature %s\n", debugstr_w( &szDescriptor[20] ));
 
     r = decode_base85_guid( p+1, &component );
     if( !r )
@@ -769,157 +769,134 @@
     return r;
 }
 
+UINT WINAPI MSI_EnumComponentQualifiers( LPCWSTR szComponent, DWORD iIndex,
+                awstring *lpQualBuf, DWORD* pcchQual,
+                awstring *lpAppBuf, DWORD* pcchAppBuf )
+{
+    DWORD name_sz, val_sz, type, ofs;
+    LPWSTR name = NULL, val = NULL;
+    UINT r, r2;
+    HKEY key;
+
+    TRACE("%s %08lx %p %p %p %p\n", debugstr_w(szComponent), iIndex,
+          lpQualBuf, pcchQual, lpAppBuf, pcchAppBuf);
+
+    if (!szComponent)
+        return ERROR_INVALID_PARAMETER;
+
+    r = MSIREG_OpenUserComponentsKey( szComponent, &key, FALSE );
+    if (r != ERROR_SUCCESS)
+        return ERROR_UNKNOWN_COMPONENT;
+
+    /* figure out how big the name is we want to return */
+    name_sz = 0;
+    if (pcchQual)
+    {
+        r = ERROR_OUTOFMEMORY;
+        name_sz = *pcchQual * 4;
+        name = msi_alloc( name_sz * sizeof(WCHAR) );
+        if (!name)
+            goto end;
+    }
+
+    /* figure out how big the value is */
+    type = 0;
+    val_sz = 0;
+    r = RegEnumValueW( key, iIndex, NULL, NULL,
+                       NULL, &type, NULL, &val_sz );
+    if (r != ERROR_SUCCESS)
+        goto end;
+
+    if (type != REG_MULTI_SZ)
+    {
+        ERR("component data has wrong type (%ld)\n", type);
+        goto end;
+    }
+
+    /* the value size is in bytes */
+    val_sz += sizeof(WCHAR);
+    val = msi_alloc( val_sz );
+    if (!val)
+        goto end;
+
+    r = RegEnumValueW( key, iIndex, name, &name_sz,
+                       NULL, &type, (LPBYTE)val, &val_sz );
+    if (r != ERROR_SUCCESS)
+        goto end;
+
+    ofs = 0;
+    r = MsiDecomposeDescriptorW( val, NULL, NULL, NULL, &ofs );
+    if (r != ERROR_SUCCESS)
+        goto end;
+
+    TRACE("Providing %s and %s\n", debugstr_w(name), debugstr_w(val+ofs));
+
+    r = msi_strcpy_to_awstring( name, lpQualBuf, pcchQual );
+    r2 = msi_strcpy_to_awstring( val+ofs, lpAppBuf, pcchAppBuf );
+
+    if (r2 != ERROR_SUCCESS)
+        r = r2;
+
+end:
+    msi_free(val);
+    msi_free(name);
+    RegCloseKey(key);
+
+    return r;
+}
+
 /*************************************************************************
  *  MsiEnumComponentQualifiersA [MSI.@]
- *
  */
 UINT WINAPI MsiEnumComponentQualifiersA( LPCSTR szComponent, DWORD iIndex,
                 LPSTR lpQualifierBuf, DWORD* pcchQualifierBuf,
-                LPSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf)
+                LPSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf )
 {
-    LPWSTR szwComponent;
-    LPWSTR lpwQualifierBuf;
-    DWORD pcchwQualifierBuf;
-    LPWSTR lpwApplicationDataBuf;
-    DWORD pcchwApplicationDataBuf;
-    DWORD rc;
-    DWORD length;
+    awstring qual, appdata;
+    LPWSTR comp;
+    UINT r;
 
     TRACE("%s %08lx %p %p %p %p\n", debugstr_a(szComponent), iIndex,
           lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf,
           pcchApplicationDataBuf);
 
-    szwComponent = strdupAtoW(szComponent);
+    comp = strdupAtoW( szComponent );
+    if (szComponent && !comp)
+        return ERROR_OUTOFMEMORY;
 
-    if (lpQualifierBuf)
-        lpwQualifierBuf = msi_alloc( (*pcchQualifierBuf) * sizeof(WCHAR));
-    else
-        lpwQualifierBuf = NULL;
+    qual.unicode = FALSE;
+    qual.str.a = lpQualifierBuf;
 
-    if (pcchQualifierBuf)
-        pcchwQualifierBuf = *pcchQualifierBuf;
-    else
-        pcchwQualifierBuf = 0;
+    appdata.unicode = FALSE;
+    appdata.str.a = lpApplicationDataBuf;
 
-    if (lpApplicationDataBuf)
-       lpwApplicationDataBuf = msi_alloc( (*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 too 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;
-    }
-
-    msi_free(lpwApplicationDataBuf);
-    msi_free(lpwQualifierBuf);
-    msi_free(szwComponent);
-
-    return rc;
+    r = MSI_EnumComponentQualifiers( comp, iIndex,
+              &qual, pcchQualifierBuf, &appdata, pcchApplicationDataBuf );
+    msi_free( comp );
+    return r;
 }
 
 /*************************************************************************
  *  MsiEnumComponentQualifiersW [MSI.@]
- *
  */
 UINT WINAPI MsiEnumComponentQualifiersW( LPCWSTR szComponent, DWORD iIndex,
                 LPWSTR lpQualifierBuf, DWORD* pcchQualifierBuf,
                 LPWSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf )
 {
-    UINT rc;
-    HKEY key;
-    DWORD actual_pcchQualifierBuf = 0;
-    DWORD actual_pcchApplicationDataBuf = 0;
-    LPWSTR full_buffer = NULL;
-    DWORD full_buffer_size = 0;
-    LPWSTR ptr;
+    awstring qual, appdata;
 
     TRACE("%s %08lx %p %p %p %p\n", debugstr_w(szComponent), iIndex,
           lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf,
           pcchApplicationDataBuf);
 
-    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;
+    qual.unicode = TRUE;
+    qual.str.w = lpQualifierBuf;
 
-    full_buffer_size = (52 * sizeof(WCHAR)) + actual_pcchApplicationDataBuf;
-    full_buffer = msi_alloc(full_buffer_size);
-    
-    rc = RegEnumValueW(key, iIndex, lpQualifierBuf, pcchQualifierBuf, NULL, 
-                    NULL, (LPBYTE)full_buffer, &full_buffer_size);
+    appdata.unicode = TRUE;
+    appdata.str.w = lpApplicationDataBuf;
 
-    if (rc == ERROR_MORE_DATA)
-    {
-        msi_free(full_buffer);
-        full_buffer_size+=sizeof(WCHAR);
-        full_buffer = msi_alloc(full_buffer_size);
-        rc = RegEnumValueW(key, iIndex, lpQualifierBuf, pcchQualifierBuf, NULL, 
-                    NULL, (LPBYTE)full_buffer, &full_buffer_size);
-    }
-    
-    RegCloseKey(key);
-
-    if (rc == ERROR_SUCCESS)
-    {
-        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));
-    }
-
-    msi_free(full_buffer);
-
-    return rc;
+    return MSI_EnumComponentQualifiers( szComponent, iIndex,
+                 &qual, pcchQualifierBuf, &appdata, pcchApplicationDataBuf );
 }
 
 /*************************************************************************