sync msi to wine 1.1.33
authorChristoph von Wittich <christoph_vw@reactos.org>
Mon, 16 Nov 2009 01:13:42 +0000 (01:13 +0000)
committerChristoph von Wittich <christoph_vw@reactos.org>
Mon, 16 Nov 2009 01:13:42 +0000 (01:13 +0000)
svn path=/trunk/; revision=44191

26 files changed:
reactos/dll/win32/msi/action.c
reactos/dll/win32/msi/alter.c
reactos/dll/win32/msi/appsearch.c
reactos/dll/win32/msi/create.c
reactos/dll/win32/msi/delete.c
reactos/dll/win32/msi/dialog.c
reactos/dll/win32/msi/distinct.c
reactos/dll/win32/msi/insert.c
reactos/dll/win32/msi/install.c
reactos/dll/win32/msi/join.c
reactos/dll/win32/msi/media.c
reactos/dll/win32/msi/msi.c
reactos/dll/win32/msi/msi_main.c
reactos/dll/win32/msi/msipriv.h
reactos/dll/win32/msi/msiquery.c
reactos/dll/win32/msi/msiserver.idl
reactos/dll/win32/msi/package.c
reactos/dll/win32/msi/query.h
reactos/dll/win32/msi/select.c
reactos/dll/win32/msi/sql.tab.c
reactos/dll/win32/msi/sql.y
reactos/dll/win32/msi/storages.c
reactos/dll/win32/msi/streams.c
reactos/dll/win32/msi/table.c
reactos/dll/win32/msi/update.c
reactos/dll/win32/msi/where.c

index a6af7cc..3a11c61 100644 (file)
@@ -4888,7 +4888,6 @@ static UINT ACTION_InstallODBC( MSIPACKAGE *package )
 static LONG env_set_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags )
 {
     LPCWSTR cptr = *name;
-    LPCWSTR ptr = *value;
 
     static const WCHAR prefix[] = {'[','~',']',0};
     static const int prefix_len = 3;
@@ -4919,18 +4918,22 @@ static LONG env_set_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags )
         return ERROR_FUNCTION_FAILED;
     }
 
-    if (!strncmpW(ptr, prefix, prefix_len))
+    if (*value)
     {
-        *flags |= ENV_MOD_APPEND;
-        *value += lstrlenW(prefix);
-    }
-    else if (lstrlenW(*value) >= prefix_len)
-    {
-        ptr += lstrlenW(ptr) - prefix_len;
-        if (!lstrcmpW(ptr, prefix))
+        LPCWSTR ptr = *value;
+        if (!strncmpW(ptr, prefix, prefix_len))
         {
-            *flags |= ENV_MOD_PREFIX;
-            /* the "[~]" will be removed by deformat_string */;
+            *flags |= ENV_MOD_APPEND;
+            *value += lstrlenW(prefix);
+        }
+        else if (lstrlenW(*value) >= prefix_len)
+        {
+            ptr += lstrlenW(ptr) - prefix_len;
+            if (!lstrcmpW(ptr, prefix))
+            {
+                *flags |= ENV_MOD_PREFIX;
+                /* the "[~]" will be removed by deformat_string */;
+            }
         }
     }
 
@@ -4978,8 +4981,7 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
     if (res != ERROR_SUCCESS)
        goto done;
 
-    deformat_string(package, value, &deformatted);
-    if (!deformatted)
+    if (value && !deformat_string(package, value, &deformatted))
     {
         res = ERROR_OUTOFMEMORY;
         goto done;
@@ -5066,7 +5068,7 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
             }
         }
     }
-    else
+    else if (value)
     {
         size = (lstrlenW(value) + 1) * sizeof(WCHAR);
         newval = msi_alloc(size);
@@ -5079,8 +5081,13 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
         lstrcpyW(newval, value);
     }
 
-    TRACE("setting %s to %s\n", debugstr_w(name), debugstr_w(newval));
-    res = RegSetValueExW(env, name, 0, type, (LPVOID)newval, size);
+    if (newval)
+    {
+        TRACE("setting %s to %s\n", debugstr_w(name), debugstr_w(newval));
+        res = RegSetValueExW(env, name, 0, type, (LPVOID)newval, size);
+    }
+    else
+        res = ERROR_SUCCESS;
 
 done:
     if (env) RegCloseKey(env);
index 0f750d0..a62b13e 100644 (file)
@@ -183,11 +183,12 @@ static UINT ALTER_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col
 }
 
 static UINT ALTER_get_column_info( struct tagMSIVIEW *view,
-                UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+                UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+                LPWSTR *table_name)
 {
     MSIALTERVIEW *av = (MSIALTERVIEW*)view;
 
-    TRACE("%p %d %p %p %p\n", av, n, name, type, temporary );
+    TRACE("%p %d %p %p %p %p\n", av, n, name, type, temporary, table_name );
 
     return ERROR_FUNCTION_FAILED;
 }
index 4ef4087..95daabb 100644 (file)
@@ -445,7 +445,8 @@ static UINT ACTION_AppSearchReg(MSIPACKAGE *package, LPWSTR *appValue, MSISIGNAT
     if (sz == 0)
         goto end;
 
-    if ((ptr = strchrW((LPWSTR)value, '"')) && (end = strchrW(++ptr, '"')))
+    if ((regType == REG_SZ || regType == REG_EXPAND_SZ) &&
+        (ptr = strchrW((LPWSTR)value, '"')) && (end = strchrW(++ptr, '"')))
         *end = '\0';
     else
         ptr = (LPWSTR)value;
index 63cd373..2e13d59 100644 (file)
@@ -91,11 +91,12 @@ static UINT CREATE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co
 }
 
 static UINT CREATE_get_column_info( struct tagMSIVIEW *view,
-                UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+                UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+                LPWSTR *table_name)
 {
     MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
 
-    TRACE("%p %d %p %p %p\n", cv, n, name, type, temporary );
+    TRACE("%p %d %p %p %p %p\n", cv, n, name, type, temporary, table_name );
 
     return ERROR_FUNCTION_FAILED;
 }
index c824d9e..210fc9e 100644 (file)
@@ -127,17 +127,18 @@ static UINT DELETE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co
 }
 
 static UINT DELETE_get_column_info( struct tagMSIVIEW *view,
-                UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+                UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+                LPWSTR *table_name)
 {
     MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
 
-    TRACE("%p %d %p %p %p\n", dv, n, name, type, temporary );
+    TRACE("%p %d %p %p %p %p\n", dv, n, name, type, temporary, table_name );
 
     if( !dv->table )
          return ERROR_FUNCTION_FAILED;
 
     return dv->table->ops->get_column_info( dv->table, n, name,
-                                            type, temporary );
+                                            type, temporary, table_name);
 }
 
 static UINT DELETE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
index 3f1b571..a22091f 100644 (file)
@@ -606,6 +606,8 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
         func = MSI_RecordGetInteger( rec , 1 );
         val = MSI_RecordGetInteger( rec , 2 );
 
+        TRACE("progress: func %u, val %u\n", func, val);
+
         switch (func)
         {
         case 0: /* init */
@@ -618,10 +620,12 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
             break;
         case 2: /* move */
             ctrl->progress_current += val;
-            SendMessageW(ctrl->hwnd, PBM_SETPOS, 100*(ctrl->progress_current/ctrl->progress_max), 0);
+            if (ctrl->progress_current > ctrl->progress_max)
+                ctrl->progress_current = ctrl->progress_max;
+            SendMessageW(ctrl->hwnd, PBM_SETPOS, MulDiv(100, ctrl->progress_current, ctrl->progress_max), 0);
             break;
         default:
-            ERR("Unknown progress message %d\n", func);
+            FIXME("Unknown progress message %u\n", func);
             break;
         }
     }
@@ -681,6 +685,10 @@ static msi_control *msi_dialog_add_control( msi_dialog *dialog,
     name = MSI_RecordGetString( rec, 2 );
     attributes = MSI_RecordGetInteger( rec, 8 );
     text = MSI_RecordGetString( rec, 10 );
+
+    TRACE("%s, %s, %08x, %s, %08x\n", debugstr_w(szCls), debugstr_w(name),
+          attributes, debugstr_w(text), style);
+
     if( attributes & msidbControlAttributesVisible )
         style |= WS_VISIBLE;
     if( ~attributes & msidbControlAttributesEnabled )
@@ -1571,8 +1579,14 @@ end:
 static UINT msi_dialog_progress_bar( msi_dialog *dialog, MSIRECORD *rec )
 {
     msi_control *control;
+    DWORD attributes, style;
+
+    style = WS_VISIBLE;
+    attributes = MSI_RecordGetInteger( rec, 8 );
+    if( !(attributes & msidbControlAttributesProgress95) )
+        style |= PBS_SMOOTH;
 
-    control = msi_dialog_add_control( dialog, rec, PROGRESS_CLASSW, WS_VISIBLE );
+    control = msi_dialog_add_control( dialog, rec, PROGRESS_CLASSW, style );
     if( !control )
         return ERROR_FUNCTION_FAILED;
 
@@ -2600,15 +2614,44 @@ static void msi_dialog_vcl_add_columns( msi_dialog *dialog, msi_control *control
     }
 }
 
+static LONGLONG msi_vcl_get_cost( msi_dialog *dialog )
+{
+    MSIFEATURE *feature;
+    INT each_cost;
+    LONGLONG total_cost = 0;
+
+    LIST_FOR_EACH_ENTRY( feature, &dialog->package->features, MSIFEATURE, entry )
+    {
+        if (ERROR_SUCCESS == (MSI_GetFeatureCost(dialog->package, feature,
+                MSICOSTTREE_SELFONLY, INSTALLSTATE_LOCAL, &each_cost)))
+        {
+            /* each_cost is in 512-byte units */
+            total_cost += each_cost * 512;
+        }
+        if (ERROR_SUCCESS == (MSI_GetFeatureCost(dialog->package, feature,
+                MSICOSTTREE_SELFONLY, INSTALLSTATE_ABSENT, &each_cost)))
+        {
+            /* each_cost is in 512-byte units */
+            total_cost -= each_cost * 512;
+        }
+    }
+    return total_cost;
+}
+
 static void msi_dialog_vcl_add_drives( msi_dialog *dialog, msi_control *control )
 {
     ULARGE_INTEGER total, free;
+    LONGLONG difference, cost;
     WCHAR size_text[MAX_PATH];
+    WCHAR cost_text[MAX_PATH];
     LPWSTR drives, ptr;
     LVITEMW lvitem;
     DWORD size;
     int i = 0;
 
+    cost = msi_vcl_get_cost(dialog);
+    StrFormatByteSizeW(cost, cost_text, MAX_PATH);
+
     size = GetLogicalDriveStringsW( 0, NULL );
     if ( !size ) return;
 
@@ -2628,6 +2671,7 @@ static void msi_dialog_vcl_add_drives( msi_dialog *dialog, msi_control *control
         SendMessageW( control->hwnd, LVM_INSERTITEMW, 0, (LPARAM)&lvitem );
 
         GetDiskFreeSpaceExW(ptr, &free, &total, NULL);
+        difference = free.QuadPart - cost;
 
         StrFormatByteSizeW(total.QuadPart, size_text, MAX_PATH);
         lvitem.iSubItem = 1;
@@ -2641,6 +2685,17 @@ static void msi_dialog_vcl_add_drives( msi_dialog *dialog, msi_control *control
         lvitem.cchTextMax = lstrlenW(size_text) + 1;
         SendMessageW( control->hwnd, LVM_SETITEMW, 0, (LPARAM)&lvitem );
 
+        lvitem.iSubItem = 3;
+        lvitem.pszText = cost_text;
+        lvitem.cchTextMax = lstrlenW(cost_text) + 1;
+        SendMessageW( control->hwnd, LVM_SETITEMW, 0, (LPARAM)&lvitem );
+
+        StrFormatByteSizeW(difference, size_text, MAX_PATH);
+        lvitem.iSubItem = 4;
+        lvitem.pszText = size_text;
+        lvitem.cchTextMax = lstrlenW(size_text) + 1;
+        SendMessageW( control->hwnd, LVM_SETITEMW, 0, (LPARAM)&lvitem );
+
         ptr += lstrlenW(ptr) + 1;
         i++;
     }
index 1e0cc2f..06beece 100644 (file)
@@ -205,17 +205,18 @@ static UINT DISTINCT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *
 }
 
 static UINT DISTINCT_get_column_info( struct tagMSIVIEW *view,
-                UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+                UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+                LPWSTR *table_name)
 {
     MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
 
-    TRACE("%p %d %p %p %p\n", dv, n, name, type, temporary );
+    TRACE("%p %d %p %p %p %p\n", dv, n, name, type, temporary, table_name );
 
     if( !dv->table )
          return ERROR_FUNCTION_FAILED;
 
     return dv->table->ops->get_column_info( dv->table, n, name,
-                                            type, temporary );
+                                            type, temporary, table_name );
 }
 
 static UINT DISTINCT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
index 0a1fbe6..61807e9 100644 (file)
@@ -114,8 +114,8 @@ static BOOL msi_columns_in_order(MSIINSERTVIEW *iv, UINT col_count)
 
     for (i = 1; i <= col_count; i++)
     {
-        iv->sv->ops->get_column_info(iv->sv, i, &a, NULL, NULL);
-        iv->table->ops->get_column_info(iv->table, i, &b, NULL, NULL);
+        iv->sv->ops->get_column_info(iv->sv, i, &a, NULL, NULL, NULL);
+        iv->table->ops->get_column_info(iv->table, i, &b, NULL, NULL, NULL);
 
         res = lstrcmpW(a, b);
         msi_free(a);
@@ -157,13 +157,14 @@ static UINT msi_arrange_record(MSIINSERTVIEW *iv, MSIRECORD **values)
 
     for (colidx = 1; colidx <= val_count; colidx++)
     {
-        r = iv->sv->ops->get_column_info(iv->sv, colidx, &a, NULL, NULL);
+        r = iv->sv->ops->get_column_info(iv->sv, colidx, &a, NULL, NULL, NULL);
         if (r != ERROR_SUCCESS)
             goto err;
 
         for (i = 1; i <= col_count; i++)
         {
-            r = iv->table->ops->get_column_info(iv->table, i, &b, NULL, NULL);
+            r = iv->table->ops->get_column_info(iv->table, i, &b, NULL,
+                                                NULL, NULL);
             if (r != ERROR_SUCCESS)
                 goto err;
 
@@ -200,7 +201,8 @@ static BOOL row_has_null_primary_keys(MSIINSERTVIEW *iv, MSIRECORD *row)
 
     for (i = 1; i <= col_count; i++)
     {
-        r = iv->table->ops->get_column_info(iv->table, i, NULL, &type, NULL);
+        r = iv->table->ops->get_column_info(iv->table, i, NULL, &type,
+                                            NULL, NULL);
         if (r != ERROR_SUCCESS)
             return FALSE;
 
@@ -291,18 +293,19 @@ static UINT INSERT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co
 }
 
 static UINT INSERT_get_column_info( struct tagMSIVIEW *view,
-                UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+                UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+                LPWSTR *table_name)
 {
     MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
     MSIVIEW *sv;
 
-    TRACE("%p %d %p %p %p\n", iv, n, name, type, temporary );
+    TRACE("%p %d %p %p %p %p\n", iv, n, name, type, temporary, table_name );
 
     sv = iv->sv;
     if( !sv )
         return ERROR_FUNCTION_FAILED;
 
-    return sv->ops->get_column_info( sv, n, name, type, temporary );
+    return sv->ops->get_column_info( sv, n, name, type, temporary, table_name );
 }
 
 static UINT INSERT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
index 606caba..1a535eb 100644 (file)
@@ -934,8 +934,24 @@ UINT WINAPI MsiGetFeatureStateW(MSIHANDLE hInstall, LPCWSTR szFeature,
 UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature,
                   MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
 {
-    FIXME("(%d %s %i %i %p): stub\n", hInstall, debugstr_a(szFeature),
-          iCostTree, iState, piCost);
+    LPWSTR szwFeature = NULL;
+    UINT rc;
+
+    szwFeature = strdupAtoW(szFeature);
+
+    rc = MsiGetFeatureCostW(hInstall, szwFeature, iCostTree, iState, piCost);
+
+    msi_free(szwFeature);
+
+    return rc;
+}
+
+UINT MSI_GetFeatureCost(MSIPACKAGE *package, MSIFEATURE *feature,
+                        MSICOSTTREE iCostTree, INSTALLSTATE iState,
+                        LPINT piCost)
+{
+    FIXME("(%s %i %i %p): not implemented yet\n",
+        debugstr_w(feature->Feature), iCostTree, iState, piCost);
     if (piCost) *piCost = 0;
     return ERROR_SUCCESS;
 }
@@ -946,10 +962,57 @@ UINT WINAPI MsiGetFeatureCostA(MSIHANDLE hInstall, LPCSTR szFeature,
 UINT WINAPI MsiGetFeatureCostW(MSIHANDLE hInstall, LPCWSTR szFeature,
                   MSICOSTTREE iCostTree, INSTALLSTATE iState, LPINT piCost)
 {
-    FIXME("(%d %s %i %i %p): stub\n", hInstall, debugstr_w(szFeature),
+    MSIPACKAGE *package;
+    MSIFEATURE *feature;
+    UINT ret;
+
+    TRACE("(%d %s %i %i %p)\n", hInstall, debugstr_w(szFeature),
           iCostTree, iState, piCost);
-    if (piCost) *piCost = 0;
-    return ERROR_SUCCESS;
+
+    package = msihandle2msiinfo(hInstall, MSIHANDLETYPE_PACKAGE);
+    if (!package)
+    {
+        HRESULT hr;
+        BSTR feature;
+        IWineMsiRemotePackage *remote_package;
+
+        remote_package = (IWineMsiRemotePackage *)msi_get_remote(hInstall);
+        if (!remote_package)
+            return ERROR_INVALID_HANDLE;
+
+        feature = SysAllocString(szFeature);
+        if (!feature)
+        {
+            IWineMsiRemotePackage_Release(remote_package);
+            return ERROR_OUTOFMEMORY;
+        }
+
+        hr = IWineMsiRemotePackage_GetFeatureCost(remote_package, feature,
+                                                  iCostTree, iState, piCost);
+
+        SysFreeString(feature);
+        IWineMsiRemotePackage_Release(remote_package);
+
+        if (FAILED(hr))
+        {
+            if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
+                return HRESULT_CODE(hr);
+
+            return ERROR_FUNCTION_FAILED;
+        }
+
+        return ERROR_SUCCESS;
+    }
+
+    feature = get_loaded_feature(package, szFeature);
+
+    if (feature)
+        ret = MSI_GetFeatureCost(package, feature, iCostTree, iState, piCost);
+    else
+        ret = ERROR_UNKNOWN_FEATURE;
+
+    msiobj_release( &package->hdr );
+    return ret;
 }
 
 /***********************************************************************
index 35db2fe..1aeb17c 100644 (file)
@@ -194,13 +194,14 @@ static UINT JOIN_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols
 }
 
 static UINT JOIN_get_column_info( struct tagMSIVIEW *view,
-                UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+                UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+                LPWSTR *table_name )
 {
     MSIJOINVIEW *jv = (MSIJOINVIEW*)view;
     JOINTABLE *table;
     UINT cols = 0;
 
-    TRACE("%p %d %p %p %p\n", jv, n, name, type, temporary );
+    TRACE("%p %d %p %p %p %p\n", jv, n, name, type, temporary, table_name );
 
     if (n == 0 || n > jv->columns)
         return ERROR_FUNCTION_FAILED;
@@ -209,7 +210,8 @@ static UINT JOIN_get_column_info( struct tagMSIVIEW *view,
     {
         if (n <= cols + table->columns)
             return table->view->ops->get_column_info(table->view, n - cols,
-                                                     name, type, temporary);
+                                                     name, type, temporary,
+                                                     table_name);
 
         cols += table->columns;
     }
index 0ec76bd..67cb7dc 100644 (file)
@@ -70,7 +70,6 @@ static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPCWSTR source_root)
 
 static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi)
 {
-    LPSTR msg;
     LPWSTR error, error_dialog;
     LPWSTR source_dir;
     UINT r = ERROR_SUCCESS;
@@ -78,24 +77,34 @@ static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi)
     static const WCHAR error_prop[] = {'E','r','r','o','r','D','i','a','l','o','g',0};
 
     if ((msi_get_property_int(package, szUILevel, 0) & INSTALLUILEVEL_MASK) ==
-         INSTALLUILEVEL_NONE && !gUIHandlerA)
+         INSTALLUILEVEL_NONE && !gUIHandlerA && !gUIHandlerW && !gUIHandlerRecord)
         return ERROR_SUCCESS;
 
     error = generate_error_string(package, 1302, 1, mi->disk_prompt);
     error_dialog = msi_dup_property(package, error_prop);
     source_dir = msi_dup_property(package, cszSourceDir);
 
-    while (r == ERROR_SUCCESS &&
-           !source_matches_volume(mi, source_dir))
+    while (r == ERROR_SUCCESS && !source_matches_volume(mi, source_dir))
     {
         r = msi_spawn_error_dialog(package, error_dialog, error);
 
-        if (gUIHandlerA)
+        if (gUIHandlerW)
         {
-            msg = strdupWtoA(error);
+            gUIHandlerW(gUIContext, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, error);
+        }
+        else if (gUIHandlerA)
+        {
+            char *msg = strdupWtoA(error);
             gUIHandlerA(gUIContext, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, msg);
             msi_free(msg);
         }
+        else if (gUIHandlerRecord)
+        {
+            MSIHANDLE rec = MsiCreateRecord(1);
+            MsiRecordSetStringW(rec, 0, error);
+            gUIHandlerRecord(gUIContext, MB_RETRYCANCEL | INSTALLMESSAGE_ERROR, rec);
+            MsiCloseHandle(rec);
+        }
     }
 
     msi_free(error);
index 14f8f13..2515714 100644 (file)
@@ -1902,10 +1902,12 @@ INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
 {
     INSTALLUI_HANDLERA prev = gUIHandlerA;
 
-    TRACE("%p %x %p\n",puiHandler, dwMessageFilter,pvContext);
+    TRACE("%p %08x %p\n", puiHandler, dwMessageFilter, pvContext);
+
     gUIHandlerA = puiHandler;
-    gUIFilter = dwMessageFilter;
-    gUIContext = pvContext;
+    gUIHandlerW = NULL;
+    gUIFilter   = dwMessageFilter;
+    gUIContext  = pvContext;
 
     return prev;
 }
@@ -1915,10 +1917,12 @@ INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
 {
     INSTALLUI_HANDLERW prev = gUIHandlerW;
 
-    TRACE("%p %x %p\n",puiHandler,dwMessageFilter,pvContext);
+    TRACE("%p %08x %p\n", puiHandler, dwMessageFilter, pvContext);
+
+    gUIHandlerA = NULL;
     gUIHandlerW = puiHandler;
-    gUIFilter = dwMessageFilter;
-    gUIContext = pvContext;
+    gUIFilter   = dwMessageFilter;
+    gUIContext  = pvContext;
 
     return prev;
 }
@@ -3591,13 +3595,20 @@ UINT WINAPI MsiIsProductElevatedA( LPCSTR szProduct, BOOL *pfElevated )
 /***********************************************************************
  * MsiSetExternalUIRecord     [MSI.@]
  */
-UINT WINAPI MsiSetExternalUIRecord( INSTALLUI_HANDLER_RECORD puiHandler,
-                                    DWORD dwMessageFilter, LPVOID pvContext,
-                                    PINSTALLUI_HANDLER_RECORD ppuiPrevHandler)
+UINT WINAPI MsiSetExternalUIRecord( INSTALLUI_HANDLER_RECORD handler,
+                                    DWORD filter, LPVOID context,
+                                    PINSTALLUI_HANDLER_RECORD prev )
 {
-    FIXME("%p %08x %p %p\n", puiHandler, dwMessageFilter ,pvContext,
-                             ppuiPrevHandler);
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    TRACE("%p %08x %p %p\n", handler, filter, context, prev);
+
+    if (prev)
+        *prev = gUIHandlerRecord;
+
+    gUIHandlerRecord = handler;
+    gUIFilter        = filter;
+    gUIContext       = context;
+
+    return ERROR_SUCCESS;
 }
 
 /***********************************************************************
index 9474b2a..df29184 100644 (file)
@@ -37,12 +37,13 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
 static LONG dll_count;
 
 /* the UI level */
-INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
-HWND           gUIhwnd = 0;
-INSTALLUI_HANDLERA gUIHandlerA = NULL;
-INSTALLUI_HANDLERW gUIHandlerW = NULL;
-DWORD gUIFilter = 0;
-LPVOID gUIContext = NULL;
+INSTALLUILEVEL           gUILevel         = INSTALLUILEVEL_BASIC;
+HWND                     gUIhwnd          = 0;
+INSTALLUI_HANDLERA       gUIHandlerA      = NULL;
+INSTALLUI_HANDLERW       gUIHandlerW      = NULL;
+INSTALLUI_HANDLER_RECORD gUIHandlerRecord = NULL;
+DWORD                    gUIFilter        = 0;
+LPVOID                   gUIContext       = NULL;
 WCHAR gszLogFile[MAX_PATH];
 HINSTANCE msi_hInstance;
 
index 9692b64..5b23f55 100644 (file)
@@ -228,11 +228,11 @@ typedef struct tagMSIVIEWOPS
     /*
      * get_column_info - returns the name and type of a specific column
      *
-     *  The name is HeapAlloc'ed by this function and should be freed by
-     *   the caller.
+     *  The name and tablename is HeapAlloc'ed by this function and should be
+     *  freed by the caller.
      *  The column information can be queried at any time.
      */
-    UINT (*get_column_info)( struct tagMSIVIEW *view, UINT n, LPWSTR *name, UINT *type, BOOL *temporary );
+    UINT (*get_column_info)( struct tagMSIVIEW *view, UINT n, LPWSTR *name, UINT *type, BOOL *temporary, LPWSTR *tableName);
 
     /*
      * modify - not yet implemented properly
@@ -737,7 +737,7 @@ extern UINT MSI_ViewFetch( MSIQUERY*, MSIRECORD ** );
 extern UINT MSI_ViewClose( MSIQUERY* );
 extern UINT MSI_ViewGetColumnInfo(MSIQUERY *, MSICOLINFO, MSIRECORD **);
 extern UINT MSI_ViewModify( MSIQUERY *, MSIMODIFY, MSIRECORD * );
-extern UINT VIEW_find_column( MSIVIEW *, LPCWSTR, UINT * );
+extern UINT VIEW_find_column( MSIVIEW *, LPCWSTR, LPCWSTR, UINT * );
 extern UINT msi_view_get_row(MSIDATABASE *, MSIVIEW *, UINT, MSIRECORD **);
 
 /* install internals */
@@ -759,6 +759,7 @@ extern LPCWSTR msi_download_file( LPCWSTR szUrl, LPWSTR filename );
 extern UINT msi_package_add_info(MSIPACKAGE *, DWORD, DWORD, LPCWSTR, LPWSTR);
 extern UINT msi_package_add_media_disk(MSIPACKAGE *, DWORD, DWORD, DWORD, LPWSTR, LPWSTR);
 extern UINT msi_clone_properties(MSIPACKAGE *);
+extern UINT MSI_GetFeatureCost(MSIPACKAGE *, MSIFEATURE *, MSICOSTTREE, INSTALLSTATE, LPINT);
 
 /* for deformating */
 extern UINT MSI_FormatRecordW( MSIPACKAGE *, MSIRECORD *, LPWSTR, LPDWORD );
@@ -843,6 +844,7 @@ extern INSTALLUILEVEL gUILevel;
 extern HWND gUIhwnd;
 extern INSTALLUI_HANDLERA gUIHandlerA;
 extern INSTALLUI_HANDLERW gUIHandlerW;
+extern INSTALLUI_HANDLER_RECORD gUIHandlerRecord;
 extern DWORD gUIFilter;
 extern LPVOID gUIContext;
 extern WCHAR gszLogFile[MAX_PATH];
index b973382..ddbb28d 100644 (file)
@@ -56,9 +56,10 @@ static void MSI_CloseView( MSIOBJECTHDR *arg )
     }
 }
 
-UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, UINT *n )
+UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, LPCWSTR table_name, UINT *n )
 {
     LPWSTR col_name;
+    LPWSTR haystack_table_name;
     UINT i, count, r;
 
     r = table->ops->get_dimensions( table, NULL, &count );
@@ -70,11 +71,15 @@ UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, UINT *n )
         INT x;
 
         col_name = NULL;
-        r = table->ops->get_column_info( table, i, &col_name, NULL, NULL );
+        r = table->ops->get_column_info( table, i, &col_name, NULL,
+                                         NULL, &haystack_table_name );
         if( r != ERROR_SUCCESS )
             return r;
         x = lstrcmpW( name, col_name );
+        if( table_name )
+            x |= lstrcmpW( table_name, haystack_table_name );
         msi_free( col_name );
+        msi_free( haystack_table_name );
         if( !x )
         {
             *n = i;
@@ -306,7 +311,7 @@ UINT msi_view_get_row(MSIDATABASE *db, MSIVIEW *view, UINT row, MSIRECORD **rec)
 
     for (i = 1; i <= col_count; i++)
     {
-        ret = view->ops->get_column_info(view, i, NULL, &type, NULL);
+        ret = view->ops->get_column_info(view, i, NULL, &type, NULL, NULL);
         if (ret)
         {
             ERR("Error getting column type for %d\n", i);
@@ -553,7 +558,8 @@ UINT MSI_ViewGetColumnInfo( MSIQUERY *query, MSICOLINFO info, MSIRECORD **prec )
     for( i=0; i<count; i++ )
     {
         name = NULL;
-        r = view->ops->get_column_info( view, i+1, &name, &type, &temporary );
+        r = view->ops->get_column_info( view, i+1, &name, &type, &temporary,
+                                        NULL );
         if( r != ERROR_SUCCESS )
             continue;
         if (info == MSICOLINFO_NAMES)
index ac442db..9972a02 100644 (file)
@@ -72,6 +72,7 @@ interface IWineMsiRemotePackage : IUnknown
     HRESULT SetInstallLevel( [in] int level );
     HRESULT FormatRecord( [in] MSIHANDLE record, [out] BSTR *value );
     HRESULT EvaluateCondition( [in] BSTR condition );
+    HRESULT GetFeatureCost( [in] BSTR feature, [in] INT cost_tree, [in] INSTALLSTATE state, [out] INT *cost);
 }
 
 [
index 13091d9..87f1092 100644 (file)
@@ -1203,19 +1203,28 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType,
         }
     }
 
-    TRACE("(%p %x %x %s)\n", gUIHandlerA, gUIFilter, log_type,
-                             debugstr_w(message));
+    TRACE("%p %p %p %x %x %s\n", gUIHandlerA, gUIHandlerW, gUIHandlerRecord,
+          gUIFilter, log_type, debugstr_w(message));
 
     /* convert it to ASCII */
-    len = WideCharToMultiByte( CP_ACP, 0, message, -1,
-                               NULL, 0, NULL, NULL );
+    len = WideCharToMultiByte( CP_ACP, 0, message, -1, NULL, 0, NULL, NULL );
     msg = msi_alloc( len );
-    WideCharToMultiByte( CP_ACP, 0, message, -1,
-                         msg, len, NULL, NULL );
+    WideCharToMultiByte( CP_ACP, 0, message, -1, msg, len, NULL, NULL );
 
-    if (gUIHandlerA && (gUIFilter & log_type))
+    if (gUIHandlerW && (gUIFilter & log_type))
     {
-        rc = gUIHandlerA(gUIContext,eMessageType,msg);
+        rc = gUIHandlerW( gUIContext, eMessageType, message );
+    }
+    else if (gUIHandlerA && (gUIFilter & log_type))
+    {
+        rc = gUIHandlerA( gUIContext, eMessageType, msg );
+    }
+    else if (gUIHandlerRecord && (gUIFilter & log_type))
+    {
+        MSIHANDLE rec = MsiCreateRecord( 1 );
+        MsiRecordSetStringW( rec, 0, message );
+        rc = gUIHandlerRecord( gUIContext, eMessageType, rec );
+        MsiCloseHandle( rec );
     }
 
     if ((!rc) && (gszLogFile[0]) && !((eMessageType & 0xff000000) ==
@@ -1234,8 +1243,7 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType,
         }
     }
     msi_free( msg );
-
-    msi_free( message);
+    msi_free( message );
 
     switch (eMessageType & 0xff000000)
     {
@@ -1890,6 +1898,14 @@ static HRESULT WINAPI mrp_EvaluateCondition( IWineMsiRemotePackage *iface, BSTR
     return HRESULT_FROM_WIN32(r);
 }
 
+static HRESULT WINAPI mrp_GetFeatureCost( IWineMsiRemotePackage *iface, BSTR feature,
+                                          INT cost_tree, INSTALLSTATE state, INT *cost )
+{
+    msi_remote_package_impl* This = mrp_from_IWineMsiRemotePackage( iface );
+    UINT r = MsiGetFeatureCostW(This->package, feature, cost_tree, state, cost);
+    return HRESULT_FROM_WIN32(r);
+}
+
 static const IWineMsiRemotePackageVtbl msi_remote_package_vtbl =
 {
     mrp_QueryInterface,
@@ -1914,6 +1930,7 @@ static const IWineMsiRemotePackageVtbl msi_remote_package_vtbl =
     mrp_SetInstallLevel,
     mrp_FormatRecord,
     mrp_EvaluateCondition,
+    mrp_GetFeatureCost,
 };
 
 HRESULT create_msi_remote_package( IUnknown *pOuter, LPVOID *ppObj )
index eb11a1c..a43663d 100644 (file)
@@ -68,6 +68,12 @@ struct complex_expr
     struct expr *right;
 };
 
+struct ext_column
+{
+    LPCWSTR column;
+    LPCWSTR table;
+};
+
 struct expr
 {
     int type;
@@ -77,7 +83,7 @@ struct expr
         INT   ival;
         UINT  uval;
         LPCWSTR sval;
-        LPCWSTR column;
+        struct ext_column column;
         UINT col_number;
     } u;
 };
index 8fd761e..c4b9e80 100644 (file)
@@ -209,11 +209,12 @@ static UINT SELECT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co
 }
 
 static UINT SELECT_get_column_info( struct tagMSIVIEW *view,
-                UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+                UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+                LPWSTR *table_name)
 {
     MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
 
-    TRACE("%p %d %p %p %p\n", sv, n, name, type, temporary );
+    TRACE("%p %d %p %p %p %p\n", sv, n, name, type, temporary, table_name );
 
     if( !sv->table )
          return ERROR_FUNCTION_FAILED;
@@ -224,7 +225,7 @@ static UINT SELECT_get_column_info( struct tagMSIVIEW *view,
     n = sv->cols[ n - 1 ];
 
     return sv->table->ops->get_column_info( sv->table, n, name,
-                                            type, temporary );
+                                            type, temporary, table_name );
 }
 
 static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row)
@@ -247,7 +248,7 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row)
     {
         col = sv->cols[i];
 
-        r = SELECT_get_column_info(view, i + 1, &name, &type, NULL);
+        r = SELECT_get_column_info(view, i + 1, &name, &type, NULL, NULL);
         msi_free(name);
         if (r != ERROR_SUCCESS)
         {
@@ -388,7 +389,7 @@ static UINT SELECT_AddColumn( MSISELECTVIEW *sv, LPCWSTR name )
     if( sv->num_cols >= sv->max_cols )
         return ERROR_FUNCTION_FAILED;
 
-    r = VIEW_find_column( table, name, &n );
+    r = VIEW_find_column( table, name, NULL, &n );
     if( r != ERROR_SUCCESS )
         return r;
 
index 31eb338..84597a4 100644 (file)
@@ -2778,7 +2778,8 @@ static struct expr * EXPR_column( void *info, const column_info *column )
     if( e )
     {
         e->type = EXPR_COLUMN;
-        e->u.sval = column->column;
+        e->u.column.column = column->column;
+        e->u.column.table = column->table;
     }
     return e;
 }
index 969c92c..e2484df 100644 (file)
@@ -856,7 +856,8 @@ static struct expr * EXPR_column( void *info, const column_info *column )
     if( e )
     {
         e->type = EXPR_COLUMN;
-        e->u.sval = column->column;
+        e->u.column.column = column->column;
+        e->u.column.table = column->table;
     }
     return e;
 }
index 16b323c..005bcdb 100644 (file)
@@ -289,14 +289,16 @@ static UINT STORAGES_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *c
 }
 
 static UINT STORAGES_get_column_info(struct tagMSIVIEW *view, UINT n,
-                                     LPWSTR *name, UINT *type, BOOL *temporary)
+                                     LPWSTR *name, UINT *type, BOOL *temporary,
+                                     LPWSTR *table_name)
 {
     LPCWSTR name_ptr = NULL;
 
     static const WCHAR Name[] = {'N','a','m','e',0};
     static const WCHAR Data[] = {'D','a','t','a',0};
 
-    TRACE("(%p, %d, %p, %p, %p)\n", view, n, name, type, temporary);
+    TRACE("(%p, %d, %p, %p, %p, %p)\n", view, n, name, type, temporary,
+          table_name);
 
     if (n == 0 || n > NUM_STORAGES_COLS)
         return ERROR_INVALID_PARAMETER;
index 12f707e..23ae971 100644 (file)
@@ -255,14 +255,16 @@ static UINT STREAMS_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *co
 }
 
 static UINT STREAMS_get_column_info(struct tagMSIVIEW *view, UINT n,
-                                    LPWSTR *name, UINT *type, BOOL *temporary)
+                                    LPWSTR *name, UINT *type, BOOL *temporary,
+                                    LPWSTR *table_name)
 {
     LPCWSTR name_ptr = NULL;
 
     static const WCHAR Name[] = {'N','a','m','e',0};
     static const WCHAR Data[] = {'D','a','t','a',0};
 
-    TRACE("(%p, %d, %p, %p, %p)\n", view, n, name, type, temporary);
+    TRACE("(%p, %d, %p, %p, %p, %p)\n", view, n, name, type, temporary,
+          table_name);
 
     if (n == 0 || n > NUM_STREAMS_COLS)
         return ERROR_INVALID_PARAMETER;
index 35f7979..33d1fce 100644 (file)
@@ -1582,7 +1582,8 @@ static UINT TABLE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col
 }
 
 static UINT TABLE_get_column_info( struct tagMSIVIEW *view,
-                UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+                UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+                LPWSTR *table_name )
 {
     MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
 
@@ -1598,6 +1599,13 @@ static UINT TABLE_get_column_info( struct tagMSIVIEW *view,
             return ERROR_FUNCTION_FAILED;
     }
 
+    if( table_name )
+    {
+        *table_name = strdupW( tv->columns[n-1].tablename );
+        if( !*table_name )
+            return ERROR_FUNCTION_FAILED;
+    }
+
     if( type )
         *type = tv->columns[n-1].type;
 
@@ -2118,6 +2126,7 @@ done:
 static UINT order_add_column(struct tagMSIVIEW *view, MSIORDERINFO *order, LPCWSTR name)
 {
     UINT n, r, count;
+    MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
 
     r = TABLE_get_dimensions(view, NULL, &count);
     if (r != ERROR_SUCCESS)
@@ -2126,7 +2135,7 @@ static UINT order_add_column(struct tagMSIVIEW *view, MSIORDERINFO *order, LPCWS
     if (order->num_cols >= count)
         return ERROR_FUNCTION_FAILED;
 
-    r = VIEW_find_column(view, name, &n);
+    r = VIEW_find_column(view, name, tv->name, &n);
     if (r != ERROR_SUCCESS)
         return r;
 
index 56d2391..c80d5a9 100644 (file)
@@ -155,18 +155,19 @@ static UINT UPDATE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co
 }
 
 static UINT UPDATE_get_column_info( struct tagMSIVIEW *view,
-                UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+                UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+                LPWSTR* table_name )
 {
     MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
     MSIVIEW *wv;
 
-    TRACE("%p %d %p %p %p\n", uv, n, name, type, temporary );
+    TRACE("%p %d %p %p %p %p\n", uv, n, name, type, temporary, table_name );
 
     wv = uv->wv;
     if( !wv )
         return ERROR_FUNCTION_FAILED;
 
-    return wv->ops->get_column_info( wv, n, name, type, temporary );
+    return wv->ops->get_column_info( wv, n, name, type, temporary, table_name );
 }
 
 static UINT UPDATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
index fc804a4..32f71b9 100644 (file)
@@ -490,17 +490,18 @@ static UINT WHERE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col
 }
 
 static UINT WHERE_get_column_info( struct tagMSIVIEW *view,
-                UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+                UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+                LPWSTR *table_name)
 {
     MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
 
-    TRACE("%p %d %p %p %p\n", wv, n, name, type, temporary );
+    TRACE("%p %d %p %p %p %p\n", wv, n, name, type, temporary, table_name );
 
     if( !wv->table )
          return ERROR_FUNCTION_FAILED;
 
     return wv->table->ops->get_column_info( wv->table, n, name,
-                                            type, temporary );
+                                            type, temporary, table_name );
 }
 
 static UINT WHERE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
@@ -597,11 +598,13 @@ static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr
     switch( cond->type )
     {
     case EXPR_COLUMN:
-        r = VIEW_find_column( table, cond->u.column, &val );
+        r = VIEW_find_column( table, cond->u.column.column,
+                              cond->u.column.table, &val );
         if( r == ERROR_SUCCESS )
         {
             UINT type = 0;
-            r = table->ops->get_column_info( table, val, NULL, &type, NULL );
+            r = table->ops->get_column_info( table, val, NULL, &type,
+                                             NULL, NULL );
             if( r == ERROR_SUCCESS )
             {
                 if (type&MSITYPE_STRING)
@@ -619,7 +622,7 @@ static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr
         else
         {
             *valid = 0;
-            WARN("Couldn't find column %s\n", debugstr_w( cond->u.column ) );
+            WARN("Couldn't find column %s.%s\n", debugstr_w( cond->u.column.table ), debugstr_w( cond->u.column.column ) );
         }
         break;
     case EXPR_COMPLEX: