MSI: breakout registry functions

Aric Stewart aric at codeweavers.com
Sat Jan 22 02:41:58 CST 2005


Move the guid squishing functions out of msi.c and make a new registry.c 
module. Also clean up all the various registry keys we need to open and 
create to this module and modify the functions for msi.c to call these 
functions.

Modifications to action.c to use these functions are also forthcoming 
with the next action.c patch.
-------------- next part --------------
--- /dev/null	Fri Aug 31 05:30:55 2001
+++ dlls/msi/registry.c	Sat Jan 22 17:28:12 2005
@@ -0,0 +1,389 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2004 Aric Stewart for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winnls.h"
+#include "shlwapi.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msipriv.h"
+#include "wincrypt.h"
+#include "wine/unicode.h"
+#include "winver.h"
+#include "winuser.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+
+/* 
+ * This module will be all the helper functions for registry access by the
+ * installer bits. 
+ */
+static const WCHAR szUserFeatures_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','\\',
+'F','e','a','t','u','r','e','s','\\',
+'%','s',0};
+
+static const WCHAR szInstaller_Features[] = {
+'S','o','f','t','w','a','r','e','\\',
+'M','i','c','r','o','s','o','f','t','\\',
+'W','i','n','d','o','w','s','\\',
+'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+'I','n','s','t','a','l','l','e','r','\\',
+'F','e','a','t','u','r','e','s',0 };
+
+static const WCHAR szInstaller_Features_fmt[] = {
+'S','o','f','t','w','a','r','e','\\',
+'M','i','c','r','o','s','o','f','t','\\',
+'W','i','n','d','o','w','s','\\',
+'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+'I','n','s','t','a','l','l','e','r','\\',
+'F','e','a','t','u','r','e','s','\\',
+'%','s',0};
+
+static const WCHAR szInstaller_Components[] = {
+'S','o','f','t','w','a','r','e','\\',
+'M','i','c','r','o','s','o','f','t','\\',
+'W','i','n','d','o','w','s','\\',
+'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+'I','n','s','t','a','l','l','e','r','\\',
+'C','o','m','p','o','n','e','n','t','s',0 };
+
+static const WCHAR szInstaller_Components_fmt[] = {
+'S','o','f','t','w','a','r','e','\\',
+'M','i','c','r','o','s','o','f','t','\\',
+'W','i','n','d','o','w','s','\\',
+'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+'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','\\',
+'W','i','n','d','o','w','s','\\',
+'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+'U','n','i','n','s','t','a','l','l','\\',
+'%','s',0 };
+
+static const WCHAR szUserProduct_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','\\',
+'P','r','o','d','u','c','t','s','\\',
+'%','s',0};
+
+static const WCHAR szInstaller_Products[] = {
+'S','o','f','t','w','a','r','e','\\',
+'M','i','c','r','o','s','o','f','t','\\',
+'W','i','n','d','o','w','s','\\',
+'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+'I','n','s','t','a','l','l','e','r','\\',
+'P','r','o','d','u','c','t','s',0};
+
+static const WCHAR szInstaller_Products_fmt[] = {
+'S','o','f','t','w','a','r','e','\\',
+'M','i','c','r','o','s','o','f','t','\\',
+'W','i','n','d','o','w','s','\\',
+'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+'I','n','s','t','a','l','l','e','r','\\',
+'P','r','o','d','u','c','t','s','\\',
+'%','s',0};
+
+BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
+{
+    DWORD i,n=0;
+
+    out[n++]='{';
+    for(i=0; i<8; i++)
+        out[n++] = in[7-i];
+    out[n++]='-';
+    for(i=0; i<4; i++)
+        out[n++] = in[11-i];
+    out[n++]='-';
+    for(i=0; i<4; i++)
+        out[n++] = in[15-i];
+    out[n++]='-';
+    for(i=0; i<2; i++)
+    {
+        out[n++] = in[17+i*2];
+        out[n++] = in[16+i*2];
+    }
+    out[n++]='-';
+    for( ; i<8; i++)
+    {
+        out[n++] = in[17+i*2];
+        out[n++] = in[16+i*2];
+    }
+    out[n++]='}';
+    out[n]=0;
+    return TRUE;
+}
+
+BOOL squash_guid(LPCWSTR in, LPWSTR out)
+{
+    DWORD i,n=0;
+
+    if(in[n++] != '{')
+        return FALSE;
+    for(i=0; i<8; i++)
+        out[7-i] = in[n++];
+    if(in[n++] != '-')
+        return FALSE;
+    for(i=0; i<4; i++)
+        out[11-i] = in[n++];
+    if(in[n++] != '-')
+        return FALSE;
+    for(i=0; i<4; i++)
+        out[15-i] = in[n++];
+    if(in[n++] != '-')
+        return FALSE;
+    for(i=0; i<2; i++)
+    {
+        out[17+i*2] = in[n++];
+        out[16+i*2] = in[n++];
+    }
+    if(in[n++] != '-')
+        return FALSE;
+    for( ; i<8; i++)
+    {
+        out[17+i*2] = in[n++];
+        out[16+i*2] = in[n++];
+    }
+    out[32]=0;
+    if(in[n++] != '}')
+        return FALSE;
+    if(in[n])
+        return FALSE;
+    return TRUE;
+}
+
+
+/* tables for encoding and decoding base85 */
+static const unsigned char table_dec85[0x80] = {
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0x00,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0xff,
+0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0xff,0xff,0xff,0x16,0xff,0x17,
+0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
+0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0x34,0x35,0x36,
+0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,
+0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0xff,0x53,0x54,0xff,
+};
+
+static const char table_enc85[] =
+"!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
+"PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
+"yz{}~";
+
+/*
+ *  Converts a base85 encoded guid into a GUID pointer
+ *  Base85 encoded GUIDs should be 20 characters long.
+ *
+ *  returns TRUE if successful, FALSE if not
+ */
+BOOL decode_base85_guid( LPCWSTR str, GUID *guid )
+{
+    DWORD i, val = 0, base = 1, *p;
+
+    p = (DWORD*) guid;
+    for( i=0; i<20; i++ )
+    {
+        if( (i%5) == 0 )
+        {
+            val = 0;
+            base = 1;
+        }
+        val += table_dec85[str[i]] * base;
+        if( str[i] >= 0x80 )
+            return FALSE;
+        if( table_dec85[str[i]] == 0xff )
+            return FALSE;
+        if( (i%5) == 4 )
+            p[i/5] = val;
+        base *= 85;
+    }
+    return TRUE;
+}
+
+/*
+ *  Encodes a base85 guid given a GUID pointer
+ *  Caller should provide a 21 character buffer for the encoded string.
+ *
+ *  returns TRUE if successful, FALSE if not
+ */
+BOOL encode_base85_guid( GUID *guid, LPWSTR str )
+{
+    unsigned int x, *p, i;
+
+    p = (unsigned int*) guid;
+    for( i=0; i<4; i++ )
+    {
+        x = p[i];
+        *str++ = table_enc85[x%85];
+        x = x/85;
+        *str++ = table_enc85[x%85];
+        x = x/85;
+        *str++ = table_enc85[x%85];
+        x = x/85;
+        *str++ = table_enc85[x%85];
+        x = x/85;
+        *str++ = table_enc85[x%85];
+    }
+    *str = 0;
+
+    return TRUE;
+}
+
+
+UINT MSIREG_OpenUninstallKey(LPCWSTR szProduct, HKEY* key, BOOL create)
+{
+    UINT rc;
+    WCHAR keypath[0x200];
+    TRACE("%s\n",debugstr_w(szProduct));
+
+    sprintfW(keypath,szUninstall_fmt,szProduct);
+
+    if (create)
+        rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+    else
+        rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+
+    return rc;
+}
+
+UINT MSIREG_OpenUserProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create)
+{
+    UINT rc;
+    WCHAR squished_pc[GUID_SIZE];
+    WCHAR keypath[0x200];
+
+    TRACE("%s\n",debugstr_w(szProduct));
+    squash_guid(szProduct,squished_pc);
+    TRACE("squished (%s)\n", debugstr_w(squished_pc));
+
+    sprintfW(keypath,szUserProduct_fmt,squished_pc);
+
+    if (create)
+        rc = RegCreateKeyW(HKEY_CURRENT_USER,keypath,key);
+    else
+        rc = RegOpenKeyW(HKEY_CURRENT_USER,keypath,key);
+
+    return rc;
+}
+
+UINT MSIREG_OpenUserFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create)
+{
+    UINT rc;
+    WCHAR squished_pc[GUID_SIZE];
+    WCHAR keypath[0x200];
+
+    TRACE("%s\n",debugstr_w(szProduct));
+    squash_guid(szProduct,squished_pc);
+    TRACE("squished (%s)\n", debugstr_w(squished_pc));
+
+    sprintfW(keypath,szUserFeatures_fmt,squished_pc);
+
+    if (create)
+        rc = RegCreateKeyW(HKEY_CURRENT_USER,keypath,key);
+    else
+        rc = RegOpenKeyW(HKEY_CURRENT_USER,keypath,key);
+
+    return rc;
+}
+
+UINT MSIREG_OpenFeatures(HKEY* key)
+{
+    return RegCreateKeyW(HKEY_LOCAL_MACHINE,szInstaller_Features,key);
+}
+
+UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create)
+{
+    UINT rc;
+    WCHAR squished_pc[GUID_SIZE];
+    WCHAR keypath[0x200];
+
+    TRACE("%s\n",debugstr_w(szProduct));
+    squash_guid(szProduct,squished_pc);
+    TRACE("squished (%s)\n", debugstr_w(squished_pc));
+
+    sprintfW(keypath,szInstaller_Features_fmt,squished_pc);
+
+    if (create)
+        rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,keypath,key);
+    else
+        rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,keypath,key);
+
+    return rc;
+}
+
+UINT MSIREG_OpenComponents(HKEY* key)
+{
+    return RegCreateKeyW(HKEY_LOCAL_MACHINE,szInstaller_Components,key);
+}
+
+UINT MSIREG_OpenComponentsKey(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,szInstaller_Components_fmt,squished_cc);
+
+    if (create)
+        rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,keypath,key);
+    else
+        rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,keypath,key);
+
+    return rc;
+}
+
+UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create)
+{
+    UINT rc;
+    WCHAR squished_pc[GUID_SIZE];
+    WCHAR keypath[0x200];
+
+    TRACE("%s\n",debugstr_w(szProduct));
+    squash_guid(szProduct,squished_pc);
+    TRACE("squished (%s)\n", debugstr_w(squished_pc));
+
+    sprintfW(keypath,szInstaller_Products_fmt,squished_pc);
+
+    if (create)
+        rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,keypath,key);
+    else
+        rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,keypath,key);
+
+    return rc;
+}
Index: dlls/msi/msi.c
===================================================================
RCS file: /home/wine/wine/dlls/msi/msi.c,v
retrieving revision 1.51
diff -u -u -r1.51 msi.c
--- dlls/msi/msi.c	20 Jan 2005 20:34:29 -0000	1.51
+++ dlls/msi/msi.c	22 Jan 2005 08:38:51 -0000
@@ -52,18 +52,6 @@
 
 DEFINE_GUID( CLSID_MsiDatabase, 0x000c1084, 0x0000, 0x0000, 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
 
-static const WCHAR szInstaller[] = {
-'S','o','f','t','w','a','r','e','\\',
-'M','i','c','r','o','s','o','f','t','\\',
-'W','i','n','d','o','w','s','\\',
-'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
-'I','n','s','t','a','l','l','e','r',0 };
-
-static const WCHAR szFeatures[] = {
-'F','e','a','t','u','r','e','s',0 };
-static const WCHAR szComponents[] = {
-'C','o','m','p','o','n','e','n','t','s',0 };
-
 /* the UI level */
 INSTALLUILEVEL gUILevel;
 HWND           gUIhwnd;
@@ -80,151 +68,6 @@
  *  It should contain a number of streams.
  */
 
-BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
-{
-    DWORD i,n=0;
-
-    out[n++]='{';
-    for(i=0; i<8; i++)
-        out[n++] = in[7-i];
-    out[n++]='-';
-    for(i=0; i<4; i++)
-        out[n++] = in[11-i];
-    out[n++]='-';
-    for(i=0; i<4; i++)
-        out[n++] = in[15-i];
-    out[n++]='-';
-    for(i=0; i<2; i++)
-    {
-        out[n++] = in[17+i*2];
-        out[n++] = in[16+i*2];
-    }
-    out[n++]='-';
-    for( ; i<8; i++)
-    {
-        out[n++] = in[17+i*2];
-        out[n++] = in[16+i*2];
-    }
-    out[n++]='}';
-    out[n]=0;
-    return TRUE;
-}
-
-BOOL squash_guid(LPCWSTR in, LPWSTR out)
-{
-    DWORD i,n=0;
-
-    if(in[n++] != '{')
-        return FALSE;
-    for(i=0; i<8; i++)
-        out[7-i] = in[n++];
-    if(in[n++] != '-')
-        return FALSE;
-    for(i=0; i<4; i++)
-        out[11-i] = in[n++];
-    if(in[n++] != '-')
-        return FALSE;
-    for(i=0; i<4; i++)
-        out[15-i] = in[n++];
-    if(in[n++] != '-')
-        return FALSE;
-    for(i=0; i<2; i++)
-    {
-        out[17+i*2] = in[n++];
-        out[16+i*2] = in[n++];
-    }
-    if(in[n++] != '-')
-        return FALSE;
-    for( ; i<8; i++)
-    {
-        out[17+i*2] = in[n++];
-        out[16+i*2] = in[n++];
-    }
-    out[32]=0;
-    if(in[n++] != '}')
-        return FALSE;
-    if(in[n])
-        return FALSE;
-    return TRUE;
-}
-
-/* tables for encoding and decoding base85 */
-static const unsigned char table_dec85[0x80] = {
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
-0xff,0x00,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0xff,
-0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0xff,0xff,0xff,0x16,0xff,0x17,
-0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
-0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0x34,0x35,0x36,
-0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,
-0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0xff,0x53,0x54,0xff,
-};
-
-static const char table_enc85[] =
-"!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
-"PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
-"yz{}~";
-
-/*
- *  Converts a base85 encoded guid into a GUID pointer
- *  Base85 encoded GUIDs should be 20 characters long.
- *
- *  returns TRUE if successful, FALSE if not
- */
-BOOL decode_base85_guid( LPCWSTR str, GUID *guid )
-{
-    DWORD i, val = 0, base = 1, *p;
-
-    p = (DWORD*) guid;
-    for( i=0; i<20; i++ )
-    {
-        if( (i%5) == 0 )
-        {
-            val = 0;
-            base = 1;
-        }
-        val += table_dec85[str[i]] * base;
-        if( str[i] >= 0x80 )
-            return FALSE;
-        if( table_dec85[str[i]] == 0xff )
-            return FALSE;
-        if( (i%5) == 4 )
-            p[i/5] = val;
-        base *= 85;
-    }
-    return TRUE;
-}
-
-/*
- *  Encodes a base85 guid given a GUID pointer
- *  Caller should provide a 21 character buffer for the encoded string.
- *
- *  returns TRUE if successful, FALSE if not
- */
-BOOL encode_base85_guid( GUID *guid, LPWSTR str )
-{
-    unsigned int x, *p, i;
-
-    p = (unsigned int*) guid;
-    for( i=0; i<4; i++ )
-    {
-        x = p[i];
-        *str++ = table_enc85[x%85];
-        x = x/85;
-        *str++ = table_enc85[x%85];
-        x = x/85;
-        *str++ = table_enc85[x%85];
-        x = x/85;
-        *str++ = table_enc85[x%85];
-        x = x/85;
-        *str++ = table_enc85[x%85];
-    }
-    *str = 0;
-    
-    return TRUE;
-}
-
-
 VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
 {
     MSIDATABASE *db = (MSIDATABASE *) arg;
@@ -414,27 +257,17 @@
 
 UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
 {
-    static const WCHAR szKey[] = {
-        'S','o','f','t','w','a','r','e','\\',
-        'M','i','c','r','o','s','o','f','t','\\',
-        'W','i','n','d','o','w','s','\\',
-        'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
-        'U','n','i','n','s','t','a','l','l',0 };
     static const WCHAR szLocalPackage[] = {
         'L','o','c','a','l','P','a','c','k','a','g','e', 0
     };
     LPWSTR path = NULL;
     UINT r;
-    HKEY hKeyProduct = NULL, hKeyUninstall = NULL;
+    HKEY hKeyProduct = NULL;
     DWORD count, type;
 
     TRACE("%s %p\n",debugstr_w(szProduct), phProduct);
 
-    r = RegOpenKeyW( HKEY_LOCAL_MACHINE, szKey, &hKeyUninstall );
-    if( r != ERROR_SUCCESS )
-        return ERROR_UNKNOWN_PRODUCT;
-
-    r = RegOpenKeyW( hKeyUninstall, szProduct, &hKeyProduct );
+    r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
     if( r != ERROR_SUCCESS )
     {
         r = ERROR_UNKNOWN_PRODUCT;
@@ -470,7 +303,6 @@
     HeapFree( GetProcessHeap(), 0, path );
     if( hKeyProduct )
         RegCloseKey( hKeyProduct );
-    RegCloseKey( hKeyUninstall );
 
     return r;
 }
@@ -590,14 +422,7 @@
     MSIHANDLE handle; 
     MSIPACKAGE* package;
     UINT rc;
-    WCHAR squished_pc[0x100];
-    HKEY hkey=0,hkey2=0,hkey3=0,hkey4=0;
-    static const WCHAR szInstaller[] = {
-         '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',0 };
-    static const WCHAR szProducts[] = {
-         'P','r','o','d','u','c','t','s',0 };
+    HKEY hkey=0,hkey1=0;
     DWORD sz;
     static const WCHAR szSouceList[] = {
         'S','o','u','r','c','e','L','i','s','t',0};
@@ -611,37 +436,27 @@
     FIXME("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
     debugstr_w(szCommandLine));
 
-    if (eInstallState != INSTALLSTATE_LOCAL)
+    if (eInstallState != INSTALLSTATE_LOCAL && 
+        eInstallState != INSTALLSTATE_DEFAULT)
     {
         FIXME("Not implemented for anything other than local installs\n");
         return ERROR_CALL_NOT_IMPLEMENTED;
     }
 
-    squash_guid(szProduct,squished_pc);
-
-    TRACE("squished (%s)\n", debugstr_w(squished_pc));
-
-    rc = RegOpenKeyW(HKEY_CURRENT_USER,szInstaller,&hkey);
-    if (rc != ERROR_SUCCESS)
-        goto end;
-
-    /* check the products key for the product */
-    rc = RegOpenKeyW(hkey,szProducts,&hkey2);
+    rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
     if (rc != ERROR_SUCCESS)
         goto end;
 
-    rc = RegOpenKeyW(hkey2,squished_pc,&hkey3);
-    if (rc != ERROR_SUCCESS)
-        goto end;
-
-    rc = RegOpenKeyW(hkey3,szSouceList,&hkey4);
+    rc = RegOpenKeyW(hkey,szSouceList,&hkey1);
     if (rc != ERROR_SUCCESS)
         goto end;
 
     sz = sizeof(sourcepath);
-    rc = RegQueryValueExW(hkey4, szLUS, NULL, NULL,(LPBYTE)sourcepath, &sz);
+    rc = RegQueryValueExW(hkey1, szLUS, NULL, NULL,(LPBYTE)sourcepath, &sz);
     if (rc != ERROR_SUCCESS)
         goto end;
+
+    RegCloseKey(hkey1);
     /*
      * ok 1, we need to find the msi file for this product.
      *    2, find the source dir for the files
@@ -654,8 +469,8 @@
         goto end;
 
     package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
-   
-    sz = strlenW(szInstalled);
+  
+     sz = strlenW(szInstalled);
 
     if (szCommandLine)
         sz += strlenW(szCommandLine);
@@ -667,20 +482,52 @@
     else
         commandline[0] = 0;
 
-    if (MsiQueryProductStateW(szProduct) == iInstallLevel)
+    if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
         strcatW(commandline,szInstalled);
 
     rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline);
 
     HeapFree(GetProcessHeap(),0,commandline);
 end:
-    RegCloseKey(hkey3);
-    RegCloseKey(hkey2);
     RegCloseKey(hkey);
 
     return rc;
 }
 
+UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
+                        INSTALLSTATE eInstallState, LPCSTR szCommandLine)
+{
+    LPWSTR szwProduct = NULL;
+    LPWSTR szwCommandLine = NULL;
+    UINT hr = ERROR_FUNCTION_FAILED;
+
+    if( szProduct )
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
+        szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if( !szwProduct )
+            goto end;
+        MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
+    }
+
+    if( szCommandLine)
+    {
+        UINT len = MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, NULL, 0 );
+        szwCommandLine= HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        if( !szwCommandLine)
+            goto end;
+        MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, szwCommandLine, len );
+    }
+
+    hr = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
+                                szwCommandLine );
+end:
+    HeapFree( GetProcessHeap(), 0, szwProduct );
+    HeapFree( GetProcessHeap(), 0, szwCommandLine);
+
+    return hr;
+}
+
 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel, 
                                  INSTALLSTATE eInstallState)
 {
@@ -913,59 +760,27 @@
 
 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
 {
-    WCHAR squished_pc[0x100];
     UINT rc;
     INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
-    HKEY hkey=0,hkey2=0,hkey3=0;
-    static const WCHAR szInstaller[] = {
-         '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',0 };
-     static const WCHAR szUninstaller[] = {
-         'S','o','f','t','w','a','r','e','\\',
-         'M','i','c','r','o','s','o','f','t','\\',
-         'W','i','n','d','o','w','s','\\',
-         'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
-         'U','n','i','n','s','t','a','l','l',0 };
-    static const WCHAR szProducts[] = {
-         'P','r','o','d','u','c','t','s',0 };
+    HKEY hkey=0;
     static const WCHAR szWindowsInstaller[] = {
          'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
     DWORD sz;
 
     TRACE("%s\n", debugstr_w(szProduct));
 
-    squash_guid(szProduct,squished_pc);
-
-    TRACE("squished (%s)\n", debugstr_w(squished_pc));
-
-    rc = RegOpenKeyW(HKEY_CURRENT_USER,szInstaller,&hkey);
-    if (rc != ERROR_SUCCESS)
-        goto end;
-
-    /* check the products key for the product */
-    rc = RegOpenKeyW(hkey,szProducts,&hkey2);
+    rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
     if (rc != ERROR_SUCCESS)
         goto end;
 
-    rc = RegOpenKeyW(hkey2,squished_pc,&hkey3);
-    if (rc != ERROR_SUCCESS)
-        goto end;
-
-    RegCloseKey(hkey3);
-    RegCloseKey(hkey2);
     RegCloseKey(hkey);
 
-    rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,szUninstaller,&hkey);
-    if (rc != ERROR_SUCCESS)
-        goto end;
-
-    rc = RegOpenKeyW(hkey,szProduct,&hkey2);
+    rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
     if (rc != ERROR_SUCCESS)
         goto end;
 
     sz = sizeof(rrc);
-    rc = RegQueryValueExW(hkey2,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
+    rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
     if (rc != ERROR_SUCCESS)
         goto end;
 
@@ -982,8 +797,6 @@
             break;
     }
 end:
-    RegCloseKey(hkey3);
-    RegCloseKey(hkey2);
     RegCloseKey(hkey);
     return rrc;
 }
@@ -1099,7 +912,7 @@
 
 UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid)
 {
-    HKEY hkey = 0, hkeyFeatures = 0;
+    HKEY hkeyFeatures = 0;
     DWORD r;
     WCHAR szKeyName[33];
 
@@ -1166,24 +979,12 @@
 UINT WINAPI MsiEnumFeaturesW(LPCWSTR szProduct, DWORD index, 
       LPWSTR szFeature, LPWSTR szParent)
 {
-    HKEY hkey = 0, hkeyFeatures = 0, hkeyProduct = 0;
+    HKEY hkeyProduct = 0;
     DWORD r, sz;
-    WCHAR szRegName[GUID_SIZE];
 
     TRACE("%s %ld %p %p\n",debugstr_w(szProduct),index,szFeature,szParent);
 
-    if( !squash_guid(szProduct, szRegName) )
-        return ERROR_INVALID_PARAMETER;
-
-    r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
-    if( r != ERROR_SUCCESS )
-        goto end;
-
-    r = RegOpenKeyW(hkey, szFeatures, &hkeyFeatures);
-    if( r != ERROR_SUCCESS )
-        goto end;
-
-    r = RegOpenKeyW(hkeyFeatures, szRegName, &hkeyProduct);
+    r = MSIREG_OpenFeaturesKey(szProduct,&hkeyProduct,FALSE);
     if( r != ERROR_SUCCESS )
         goto end;
 
@@ -1193,10 +994,6 @@
 end:
     if( hkeyProduct )
         RegCloseKey(hkeyProduct);
-    if( hkeyFeatures )
-        RegCloseKey(hkeyFeatures);
-    if( hkey )
-        RegCloseKey(hkey);
 
     return r;
 }
@@ -1217,17 +1014,13 @@
 
 UINT WINAPI MsiEnumComponentsW(DWORD index, LPWSTR lpguid)
 {
-    HKEY hkey = 0, hkeyComponents = 0;
+    HKEY hkeyComponents = 0;
     DWORD r;
     WCHAR szKeyName[33];
 
     TRACE("%ld %p\n",index,lpguid);
 
-    r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
-    if( r != ERROR_SUCCESS )
-        goto end;
-
-    r = RegOpenKeyW(hkey, szComponents, &hkeyComponents);
+    r = MSIREG_OpenComponents(&hkeyComponents);
     if( r != ERROR_SUCCESS )
         goto end;
 
@@ -1239,8 +1032,6 @@
 
     if( hkeyComponents )
         RegCloseKey(hkeyComponents);
-    if( hkey )
-        RegCloseKey(hkey);
 
     return r;
 }
@@ -1277,24 +1068,13 @@
 
 UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct)
 {
-    HKEY hkey = 0, hkeyComponents = 0, hkeyComp = 0;
+    HKEY hkeyComp = 0;
     DWORD r, sz;
-    WCHAR szRegName[GUID_SIZE], szValName[GUID_SIZE];
+    WCHAR szValName[GUID_SIZE];
 
     TRACE("%s %ld %p\n",debugstr_w(szComponent),index,szProduct);
 
-    if( !squash_guid(szComponent, szRegName) )
-        return ERROR_INVALID_PARAMETER;
-
-    r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
-    if( r != ERROR_SUCCESS )
-        goto end;
-
-    r = RegOpenKeyW(hkey, szComponents, &hkeyComponents);
-    if( r != ERROR_SUCCESS )
-        goto end;
-
-    r = RegOpenKeyW(hkeyComponents, szRegName, &hkeyComp);
+    r = MSIREG_OpenComponentsKey(szComponent,&hkeyComp,FALSE);
     if( r != ERROR_SUCCESS )
         goto end;
 
@@ -1308,10 +1088,6 @@
 end:
     if( hkeyComp )
         RegCloseKey(hkeyComp);
-    if( hkeyComponents )
-        RegCloseKey(hkeyComponents);
-    if( hkey )
-        RegCloseKey(hkey);
 
     return r;
 }
@@ -1476,66 +1252,36 @@
 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
                                          LPWSTR lpPathBuf, DWORD* pcchBuf)
 {
-    WCHAR squished_pc[0x100];
-    WCHAR squished_cc[0x100];
+    WCHAR squished_cc[GUID_SIZE];
     UINT rc;
     INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
-    HKEY hkey=0,hkey2=0,hkey3=0;
-    static const WCHAR szInstaller[] = {
-         'S','o','f','t','w','a','r','e','\\',
-         'M','i','c','r','o','s','o','f','t','\\',
-         'W','i','n','d','o','w','s','\\',
-         'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
-         'I','n','s','t','a','l','l','e','r',0 };
-    static const WCHAR szComponents[] = {
-         'C','o','m','p','o','n','e','n','t','s',0 };
-    static const WCHAR szProducts[] = {
-         'P','r','o','d','u','c','t','s',0 };
+    HKEY hkey=0;
 
     TRACE("(%s %s %p %p)\n", debugstr_w(szProduct),
            debugstr_w(szComponent), lpPathBuf, pcchBuf);
 
     squash_guid(szProduct,squished_pc);
-    squash_guid(szComponent,squished_cc);
-
-    TRACE("squished (%s:%s)\n", debugstr_w(squished_cc),
-           debugstr_w(squished_pc));
-
-    rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,szInstaller,&hkey);
-    if (rc != ERROR_SUCCESS)
-        goto end;
-
-    /* check the products key for the product */
-    rc = RegOpenKeyW(hkey,szProducts,&hkey2);
-    if (rc != ERROR_SUCCESS)
-        goto end;
 
-    rc = RegOpenKeyW(hkey2,squished_pc,&hkey3);
+    rc = MSIREG_OpenProductsKey(szProduct,&hkey,FALSE);
     if (rc != ERROR_SUCCESS)
         goto end;
 
+    RegCloseKey(hkey);
 
-    RegCloseKey(hkey3);
-    RegCloseKey(hkey2);
-
-    rc = RegOpenKeyW(hkey,szComponents,&hkey2);
-    if (rc != ERROR_SUCCESS)
-        goto end;
-
-    rc = RegOpenKeyW(hkey2,squished_cc,&hkey3);
+    rc = MSIREG_OpenComponentsKey(szComponent,&hkey,FALSE);
     if (rc != ERROR_SUCCESS)
         goto end;
 
     *pcchBuf *= sizeof(WCHAR);
-    rc = RegQueryValueExW(hkey3,squished_pc,NULL,NULL,(LPVOID)lpPathBuf,
+    rc = RegQueryValueExW(hkey,squished_pc,NULL,NULL,(LPVOID)lpPathBuf,
                           pcchBuf);
     *pcchBuf /= sizeof(WCHAR);
 
     if (rc!= ERROR_SUCCESS)
         goto end;
 
-    TRACE("found path of (%s:%s)(%s)\n", debugstr_w(squished_cc),
-           debugstr_w(squished_pc), debugstr_w(lpPathBuf));
+    TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
+           debugstr_w(szProduct), debugstr_w(lpPathBuf));
 
     FIXME("Only working for installed files, not registry keys\n");
     if (GetFileAttributesW(lpPathBuf) != INVALID_FILE_ATTRIBUTES)
@@ -1544,8 +1290,6 @@
         rrc = INSTALLSTATE_ABSENT;
 
 end:
-    RegCloseKey(hkey3);
-    RegCloseKey(hkey2);
     RegCloseKey(hkey);
     return rrc;
 }
Index: dlls/msi/msipriv.h
===================================================================
RCS file: /home/wine/wine/dlls/msi/msipriv.h,v
retrieving revision 1.38
diff -u -u -r1.38 msipriv.h
--- dlls/msi/msipriv.h	21 Jan 2005 16:19:11 -0000	1.38
+++ dlls/msi/msipriv.h	22 Jan 2005 08:42:05 -0000
@@ -334,6 +334,14 @@
 BOOL squash_guid(LPCWSTR in, LPWSTR out);
 BOOL encode_base85_guid(GUID *,LPWSTR);
 BOOL decode_base85_guid(LPCWSTR,GUID*);
+UINT MSIREG_OpenUninstallKey(LPCWSTR szProduct, HKEY* key, BOOL create);
+UINT MSIREG_OpenUserProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create);
+UINT MSIREG_OpenFeatures(HKEY* key);
+UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
+UINT MSIREG_OpenComponents(HKEY* key);
+UINT MSIREG_OpenComponentsKey(LPCWSTR szComponent, HKEY* key, BOOL create);
+UINT MSIREG_OpenProductsKey(LPCWSTR szProduct, HKEY* key, BOOL create);
+UINT MSIREG_OpenUserFeaturesKey(LPCWSTR szProduct, HKEY* key, BOOL create);
 
 /* UI globals */
 extern INSTALLUILEVEL gUILevel;


More information about the wine-patches mailing list