MSI: Implement RegisterTypeLibrarys

Mike McCormack mike at codeweavers.com
Sat Jul 3 20:26:14 CDT 2004


ChangeLog:
<aric at codeweavers.com>
* Implement RegisterTypeLibrarys
-------------- next part --------------
diff -ur dlls/msi.old/action.c dlls/msi/action.c
--- dlls/msi.old/action.c	2004-07-03 20:24:15.000000000 -0500
+++ dlls/msi/action.c	2004-07-03 20:24:24.000000000 -0500
@@ -142,6 +142,7 @@
 static UINT ACTION_InstallInitialize(MSIHANDLE hPackage);
 static UINT ACTION_InstallValidate(MSIHANDLE hPackage);
 static UINT ACTION_ProcessComponents(MSIHANDLE hPackage);
+static UINT ACTION_RegisterTypeLibraries(MSIHANDLE hPackage);
 
 static UINT HANDLE_CustomType1(MSIHANDLE hPackage, const LPWSTR source, 
                                 const LPWSTR target, const INT type);
@@ -189,7 +190,9 @@
     {'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};
-
+const static WCHAR szRegisterTypeLibraries[] = 
+{'R','e','g','i','s','t','e','r','T','y','p','e','L','i','b','r','a','r',
+'i','e','s',0};
 
 /******************************************************** 
  * helper functions to get around current HACKS and such
@@ -249,6 +252,22 @@
     return rc;
 }
 
+inline static int get_loaded_file(MSIPACKAGE* package, LPCWSTR file)
+{
+    INT rc = -1;
+    INT i;
+
+    for (i = 0; i < package->loaded_files; i++)
+    {
+        if (strcmpW(file,package->files[i].File)==0)
+        {
+            rc = i;
+            break;
+        }
+    }
+    return rc;
+}
+
 static UINT track_tempfile(MSIHANDLE hPackage, LPCWSTR name, LPCWSTR path)
 {
     MSIPACKAGE *package;
@@ -821,17 +840,16 @@
         rc = ACTION_DuplicateFiles(hPackage);
     else if (strcmpW(action,szWriteRegistryValues)==0)
         rc = ACTION_WriteRegistryValues(hPackage);
+     else if (strcmpW(action,szRegisterTypeLibraries)==0)
+        rc = ACTION_RegisterTypeLibraries(hPackage);
 
     /*
      Current called during itunes but unimplemented and seem important
 
      ResolveSource  (sets SourceDir)
-     ValidateProductID (sets ProductID)
      CreateShortcuts (would be nice to have soon)
      RegisterClassInfo
      RegisterProgIdInfo (Lots to do)
-     RegisterTypeLibraries
-     RegisterUser
      RegisterProduct
      InstallFinalize
      */
@@ -3016,10 +3034,9 @@
     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)
+        j = get_loaded_file(package,cmp->KeyPath);
+
+        if (j>=0)
             strcpyW(keypath,package->files[j].TargetPath);
     }
 }
@@ -3115,6 +3132,119 @@
     return rc;
 }
 
+static UINT ACTION_RegisterTypeLibraries(MSIHANDLE hPackage)
+{
+    /* 
+     * ok this is a bit confusting.. I am given a _Component key and i believe
+     * that the file that is being registered as a type library is the "key file
+     * of that component" which i interpert to mean "The file in the KeyPath of
+     * that component" 
+     */
+    UINT rc;
+    MSIHANDLE view;
+    MSIHANDLE row = 0;
+    static const CHAR *Query = "SELECT * from TypeLib";
+    MSIPACKAGE* package;
+    ITypeLib *ptLib;
+    HRESULT res;
+
+    package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
+    if (!package)
+        return ERROR_INVALID_HANDLE;
+
+    rc = MsiDatabaseOpenViewA(package->db, Query, &view);
+
+    if (rc != ERROR_SUCCESS)
+        return rc;
+
+    rc = MsiViewExecute(view, 0);
+    if (rc != ERROR_SUCCESS)
+    {
+        MsiViewClose(view);
+        MsiCloseHandle(view);
+        return rc;
+    }
+
+    while (1)
+    {   
+        WCHAR component[0x100];
+        DWORD sz;
+        INT index;
+
+        rc = MsiViewFetch(view,&row);
+        if (rc != ERROR_SUCCESS)
+        {
+            rc = ERROR_SUCCESS;
+            break;
+        }
+
+        sz = 0x100;
+        MsiRecordGetStringW(row,3,component,&sz);
+
+        index = get_loaded_component(package,component);
+        if (index < 0)
+        {
+            MsiCloseHandle(row);
+            continue;
+        }
+
+        if (!package->components[index].Enabled ||
+            !package->components[index].FeatureState)
+        {
+            TRACE("Skipping typelib reg due to disabled component\n");
+            MsiCloseHandle(row);
+            continue;
+        }
+
+        index = get_loaded_file(package,package->components[index].KeyPath); 
+   
+        if (index < 0)
+        {
+            MsiCloseHandle(row);
+            continue;
+        }
+
+        res = LoadTypeLib(package->files[index].TargetPath,&ptLib);
+        if (SUCCEEDED(res))
+        {
+            WCHAR help[MAX_PATH];
+            WCHAR helpid[0x100];
+
+            sz = 0x100;
+            MsiRecordGetStringW(row,6,helpid,&sz);
+
+            resolve_folder(hPackage,helpid,help,FALSE,FALSE,NULL);
+
+            res = RegisterTypeLib(ptLib,package->files[index].TargetPath,help);
+            if (!SUCCEEDED(res))
+                ERR("Failed to register type library %s\n",
+                     debugstr_w(package->files[index].TargetPath));
+            else
+            {
+                /* yes the row has more fields than i need, but #1 is 
+                   correct and the only one i need. why make a new row */
+
+                ui_actiondata(hPackage,szRegisterTypeLibraries,row);
+                
+                TRACE("Registered %s\n",
+                       debugstr_w(package->files[index].TargetPath));
+            }
+
+            if (ptLib)
+                ITypeLib_Release(ptLib);
+        }
+        else
+            ERR("Failed to load type library %s\n",
+                debugstr_w(package->files[index].TargetPath));
+        
+        MsiCloseHandle(row);
+    }
+    MsiViewClose(view);
+    MsiCloseHandle(view);
+    return rc;
+   
+}
+
 /* Msi functions that seem approperate here */
 UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
 {


More information about the wine-patches mailing list