MSI: Implement ProcessComponents

Mike McCormack mike at codeweavers.com
Sat Jul 3 20:23:48 CDT 2004


ChangeLog:
<aric at codeweavers.com>
* Implement ProcessComponents
-------------- next part --------------
diff -ur dlls/msi.old/action.c dlls/msi/action.c
--- dlls/msi.old/action.c	2004-07-03 20:20:24.000000000 -0500
+++ dlls/msi/action.c	2004-07-03 20:20:46.000000000 -0500
@@ -141,6 +141,7 @@
 static UINT ACTION_CustomAction(MSIHANDLE hPackage,const WCHAR *action);
 static UINT ACTION_InstallInitialize(MSIHANDLE hPackage);
 static UINT ACTION_InstallValidate(MSIHANDLE hPackage);
+static UINT ACTION_ProcessComponents(MSIHANDLE hPackage);
 
 static UINT HANDLE_CustomType1(MSIHANDLE hPackage, const LPWSTR source, 
                                 const LPWSTR target, const INT type);
@@ -186,6 +187,8 @@
     {'I','n','s','t','a','l','l','V','a','l','i','d','a','t','e',0};
 const static WCHAR szLaunchConditions[] = 
     {'L','a','u','n','c','h','C','o','n','d','i','t','i','o','n','s',0};
+const static WCHAR szProcessComponents[] = 
+    {'P','r','o','c','e','s','s','C','o','m','p','o','n','e','n','t','s',0};
 
 
 /******************************************************** 
@@ -806,6 +809,8 @@
         rc = ACTION_InstallValidate(hPackage);
 
     /* install block */
+    else if (strcmpW(action,szProcessComponents)==0)
+        rc = ACTION_ProcessComponents(hPackage);
     else if (strcmpW(action,szInstallInitialize)==0)
         rc = ACTION_InstallInitialize(hPackage);
     else if (strcmpW(action,szCreateFolders)==0)
@@ -818,64 +823,17 @@
         rc = ACTION_WriteRegistryValues(hPackage);
 
     /*
-     Current called during itunes but unimplemented
+     Current called during itunes but unimplemented and seem important
 
-     AppSearch
-     FindRelatedProducts
-     CostInitialize
-     MigrateFeatureStates
      ResolveSource  (sets SourceDir)
      ValidateProductID (sets ProductID)
-     IsolateComponents (Empty)
-     SetODBCFolders 
-     MigrateFeatureStates
-     RemoveExistingProducts
-     AllocateRegistrySpace
-     ProcessComponents
-     UnpublishComponents
-     UnpublishFeatures
-     StopServices
-     DeleteServices
-     UnregisterComPlus
-     SelfUnregModules (Empty)
-     UnregisterTypeLibraries
-     RemoveODBC
-     UnregisterFonts
-     RemoveRegistryValues
-     UnregisterClassInfo
-     UnregisterExtensionInfo
-     UnregisterProgIdInfo
-     UnregisterMIMEInfo
-     RemoveIniValues
-     RemoveShortcuts
-     RemoveEnviromentStrings
-     RemoveDuplicateFiles
-     RemoveFiles (Empty)
-     MoveFiles (Empty)
-     RemoveRegistryValues (Empty)
-     SelfRegModules (Empty)
-     RemoveFolders
-     PatchFiles
-     BindImage (Empty)
      CreateShortcuts (would be nice to have soon)
      RegisterClassInfo
-     RegisterExtensionInfo (Empty)
      RegisterProgIdInfo (Lots to do)
-     RegisterMIMEInfo (Empty)
-     WriteIniValues (Empty)
-     WriteEnvironmentStrings (Empty)
-     RegisterFonts(Empty)
-     InstallODBC
      RegisterTypeLibraries
-     SelfRegModules
-     RegisterComPlus
      RegisterUser
      RegisterProduct
-     PublishComponents
-     PublishFeatures
-     PublishProduct
      InstallFinalize
-     .
      */
      else if ((rc = ACTION_CustomAction(hPackage,action)) != ERROR_SUCCESS)
      {
@@ -2381,7 +2339,10 @@
             ui_progress(hPackage,2,0,0,0);
 
             if (rc)
-                ERR("Unable to move file\n");
+            {
+                ERR("Unable to move file (error %li)\n",GetLastError());
+                rc = ERROR_SUCCESS;
+            }
             else
                 file->State = 4;
         }
@@ -2779,6 +2740,7 @@
         HeapFree(GetProcessHeap(),0,value);
 
         MsiCloseHandle(row);
+        RegCloseKey(hkey);
     }
     MsiViewClose(view);
     MsiCloseHandle(view);
@@ -3036,6 +2998,123 @@
     return rc;
 }
 
+static void resolve_keypath(MSIHANDLE hPackage, MSIPACKAGE* package, INT
+                            component_index, WCHAR *keypath)
+{
+    MSICOMPONENT* cmp = &package->components[component_index];
+
+    if (cmp->KeyPath[0]==0)
+    {
+        resolve_folder(hPackage,cmp->Directory,keypath,FALSE,FALSE,NULL);
+        return;
+    }
+    if ((cmp->Attributes & 0x4) || (cmp->Attributes & 0x20))
+    {
+        FIXME("UNIMPLEMENTED keypath as Registry or ODBC Source\n");
+        keypath[0]=0;
+    }
+    else
+    {
+        int j;
+        for (j = 0; j < package->loaded_files; j++)
+            if (strcmpW(package->files[j].File,cmp->KeyPath)==0)
+                break;
+        if (j < package->loaded_files)
+            strcpyW(keypath,package->files[j].TargetPath);
+    }
+}
+
+static UINT ACTION_ProcessComponents(MSIHANDLE hPackage)
+{
+    MSIPACKAGE* package;
+    WCHAR productcode[0x100];
+    WCHAR squished_pc[0x100];
+    WCHAR squished_cc[0x100];
+    DWORD sz;
+    UINT rc;
+    INT i;
+    HKEY hkey=0,hkey2=0,hkey3=0;
+    static const WCHAR szProductCode[]=
+{'P','r','o','d','u','c','t','C','o','d','e',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 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 };
+
+    package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    /* writes the Component and Features values to the registry */
+    sz = 0x100;
+    rc = MsiGetPropertyW(hPackage,szProductCode,productcode,&sz);
+
+    if (rc != ERROR_SUCCESS)
+        return ERROR_SUCCESS;
+
+    squash_guid(productcode,squished_pc);
+    rc = RegCreateKeyW(HKEY_LOCAL_MACHINE,szInstaller,&hkey);
+    if (rc != ERROR_SUCCESS)
+        goto end;
+
+    rc = RegCreateKeyW(hkey,szFeatures,&hkey2);
+    if (rc != ERROR_SUCCESS)
+        goto end;
+
+    rc = RegCreateKeyW(hkey2,squished_pc,&hkey3);
+    if (rc != ERROR_SUCCESS)
+        goto end;
+
+    /* I have no idea what goes in here */
+    for (i = 0; i < package->loaded_features; i++)
+        RegSetValueExW(hkey3,package->features[i].Feature,0,REG_SZ,NULL,0);
+
+    RegCloseKey(hkey3);
+    RegCloseKey(hkey2);
+
+    rc = RegCreateKeyW(hkey,szComponents,&hkey2);
+    if (rc != ERROR_SUCCESS)
+        goto end;
+  
+    for (i = 0; i < package->loaded_components; i++)
+    {
+        if (package->components[i].ComponentId[0]!=0)
+        {
+            WCHAR keypath[0x1000];
+            MSIHANDLE uirow;
+
+            squash_guid(package->components[i].ComponentId,squished_cc);
+            rc = RegCreateKeyW(hkey2,squished_cc,&hkey3);
+            if (rc != ERROR_SUCCESS)
+                continue;
+           
+            resolve_keypath(hPackage,package,i,keypath);
+
+            RegSetValueExW(hkey3,squished_pc,0,REG_SZ,(LPVOID)keypath,
+                            (strlenW(keypath)+1)*sizeof(WCHAR));
+            RegCloseKey(hkey3);
+        
+            /* UI stuff */
+            uirow = MsiCreateRecord(3);
+            MsiRecordSetStringW(uirow,1,productcode);
+            MsiRecordSetStringW(uirow,2,package->components[i].ComponentId);
+            MsiRecordSetStringW(uirow,3,keypath);
+            ui_actiondata(hPackage,szProcessComponents,uirow);
+            MsiCloseHandle(uirow);
+        }
+    } 
+end:
+    RegCloseKey(hkey2);
+    RegCloseKey(hkey);
+    return rc;
+}
+
 /* Msi functions that seem approperate here */
 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
 {
diff -ur dlls/msi.old/cond.y dlls/msi/cond.y
--- dlls/msi.old/cond.y	2004-07-03 20:20:24.000000000 -0500
+++ dlls/msi/cond.y	2004-07-03 20:20:46.000000000 -0500
@@ -493,6 +493,19 @@
 %%
 
 
+static int COND_IsAlpha( WCHAR x )
+{
+    return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) ||
+            ( ( x >= 'a' ) && ( x <= 'z' ) ) ||
+            ( ( x == '_' ) ) );
+}
+
+static int COND_IsNumber( WCHAR x )
+{
+    return( ( x >= '0' ) && ( x <= '9' ) );
+}
+
+
 /* the mess of comparison functions */
 
 static INT comp_lt_i(INT a, INT b)
@@ -544,43 +557,32 @@
 
 
 static INT comp_eq_m1(LPWSTR a, INT b)
-{ return atoiW(a)==b; }
+{ if (COND_IsNumber(a[0])) return atoiW(a)==b; else return 0;}
 static INT comp_ne_m1(LPWSTR a, INT b)
-{ return atoiW(a)!=b; }
+{ if (COND_IsNumber(a[0])) return atoiW(a)!=b; else return 1;}
 static INT comp_lt_m1(LPWSTR a, INT b)
-{ return atoiW(a)<b; }
+{ if (COND_IsNumber(a[0])) return atoiW(a)<b; else return 0;}
 static INT comp_gt_m1(LPWSTR a, INT b)
-{ return atoiW(a)>b; }
+{ if (COND_IsNumber(a[0])) return atoiW(a)>b; else return 0;}
 static INT comp_le_m1(LPWSTR a, INT b)
-{ return atoiW(a)<=b; }
+{ if (COND_IsNumber(a[0])) return atoiW(a)<=b; else return 0;}
 static INT comp_ge_m1(LPWSTR a, INT b)
-{ return atoiW(a)>=b; }
+{ if (COND_IsNumber(a[0])) return atoiW(a)>=b; else return 0;}
 
 static INT comp_eq_m2(INT a, LPWSTR b)
-{ return a == atoiW(b); }
+{ if (COND_IsNumber(b[0])) return a == atoiW(b); else return 0;}
 static INT comp_ne_m2(INT a, LPWSTR b)
-{ return a != atoiW(b); }
+{ if (COND_IsNumber(b[0])) return a != atoiW(b); else return 1;}
 static INT comp_lt_m2(INT a, LPWSTR b)
-{ return a < atoiW(b); }
+{ if (COND_IsNumber(b[0])) return a < atoiW(b); else return 0;}
 static INT comp_gt_m2(INT a, LPWSTR b)
-{ return a > atoiW(b); }
+{ if (COND_IsNumber(b[0])) return a > atoiW(b); else return 0;}
 static INT comp_le_m2(INT a, LPWSTR b)
-{ return a <= atoiW(b); }
+{ if (COND_IsNumber(b[0])) return a <= atoiW(b); else return 0;}
 static INT comp_ge_m2(INT a, LPWSTR b)
-{ return a >= atoiW(b); }
-
+{ if (COND_IsNumber(b[0])) return a >= atoiW(b); else return 0;}
 
-static int COND_IsAlpha( WCHAR x )
-{
-    return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) ||
-            ( ( x >= 'a' ) && ( x <= 'z' ) ) ||
-            ( ( x == '_' ) ) );
-}
 
-static int COND_IsNumber( WCHAR x )
-{
-    return( ( x >= '0' ) && ( x <= '9' ) );
-}
 
 static int COND_IsIdent( WCHAR x )
 {
diff -ur dlls/msi.old/msipriv.h dlls/msi/msipriv.h
--- dlls/msi.old/msipriv.h	2004-07-03 20:20:24.000000000 -0500
+++ dlls/msi/msipriv.h	2004-07-03 20:20:46.000000000 -0500
@@ -235,6 +235,8 @@
 extern UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm );
 extern void enum_stream_names( IStorage *stg );
 
+BOOL unsquash_guid(LPCWSTR in, LPWSTR out);
+BOOL squash_guid(LPCWSTR in, LPWSTR out);
 
 /* UI globals */
 extern INSTALLUILEVEL gUILevel;
diff -ur dlls/msi.old/package.c dlls/msi/package.c
--- dlls/msi.old/package.c	2004-07-03 20:20:24.000000000 -0500
+++ dlls/msi/package.c	2004-07-03 20:20:46.000000000 -0500
@@ -381,7 +381,7 @@
     DWORD total_size = 0;
     INT msg_field=1;
     INT i;
-    FIXME("STUB: %x \n",eMessageType);
+    TRACE("%x \n",eMessageType);
 
     if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ERROR)
         log_type |= INSTALLLOGMODE_ERROR;


More information about the wine-patches mailing list