diff --git a/reactos/dll/win32/msi/action.c b/reactos/dll/win32/msi/action.c index a6af7cc12e4..3a11c616a82 100644 --- a/reactos/dll/win32/msi/action.c +++ b/reactos/dll/win32/msi/action.c @@ -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); diff --git a/reactos/dll/win32/msi/alter.c b/reactos/dll/win32/msi/alter.c index 0f750d0166e..a62b13e9352 100644 --- a/reactos/dll/win32/msi/alter.c +++ b/reactos/dll/win32/msi/alter.c @@ -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; } diff --git a/reactos/dll/win32/msi/appsearch.c b/reactos/dll/win32/msi/appsearch.c index 4ef4087cb9d..95daabb40bb 100644 --- a/reactos/dll/win32/msi/appsearch.c +++ b/reactos/dll/win32/msi/appsearch.c @@ -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; diff --git a/reactos/dll/win32/msi/create.c b/reactos/dll/win32/msi/create.c index 63cd373dbdc..2e13d592552 100644 --- a/reactos/dll/win32/msi/create.c +++ b/reactos/dll/win32/msi/create.c @@ -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; } diff --git a/reactos/dll/win32/msi/delete.c b/reactos/dll/win32/msi/delete.c index c824d9e0f23..210fc9e8aac 100644 --- a/reactos/dll/win32/msi/delete.c +++ b/reactos/dll/win32/msi/delete.c @@ -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, diff --git a/reactos/dll/win32/msi/dialog.c b/reactos/dll/win32/msi/dialog.c index 3f1b5710f88..a22091f95fa 100644 --- a/reactos/dll/win32/msi/dialog.c +++ b/reactos/dll/win32/msi/dialog.c @@ -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; - control = msi_dialog_add_control( dialog, rec, PROGRESS_CLASSW, WS_VISIBLE ); + style = WS_VISIBLE; + attributes = MSI_RecordGetInteger( rec, 8 ); + if( !(attributes & msidbControlAttributesProgress95) ) + style |= PBS_SMOOTH; + + 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++; } diff --git a/reactos/dll/win32/msi/distinct.c b/reactos/dll/win32/msi/distinct.c index 1e0cc2fba9c..06beece8c77 100644 --- a/reactos/dll/win32/msi/distinct.c +++ b/reactos/dll/win32/msi/distinct.c @@ -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, diff --git a/reactos/dll/win32/msi/insert.c b/reactos/dll/win32/msi/insert.c index 0a1fbe6de77..61807e9534e 100644 --- a/reactos/dll/win32/msi/insert.c +++ b/reactos/dll/win32/msi/insert.c @@ -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) diff --git a/reactos/dll/win32/msi/install.c b/reactos/dll/win32/msi/install.c index 606caba1345..1a535eb0273 100644 --- a/reactos/dll/win32/msi/install.c +++ b/reactos/dll/win32/msi/install.c @@ -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; } /*********************************************************************** diff --git a/reactos/dll/win32/msi/join.c b/reactos/dll/win32/msi/join.c index 35db2fef160..1aeb17cdc03 100644 --- a/reactos/dll/win32/msi/join.c +++ b/reactos/dll/win32/msi/join.c @@ -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; } diff --git a/reactos/dll/win32/msi/media.c b/reactos/dll/win32/msi/media.c index 0ec76bd1ca9..67cb7dc22eb 100644 --- a/reactos/dll/win32/msi/media.c +++ b/reactos/dll/win32/msi/media.c @@ -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); diff --git a/reactos/dll/win32/msi/msi.c b/reactos/dll/win32/msi/msi.c index 14f8f134365..2515714ce73 100644 --- a/reactos/dll/win32/msi/msi.c +++ b/reactos/dll/win32/msi/msi.c @@ -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; } /*********************************************************************** diff --git a/reactos/dll/win32/msi/msi_main.c b/reactos/dll/win32/msi/msi_main.c index 9474b2a9597..df29184ab92 100644 --- a/reactos/dll/win32/msi/msi_main.c +++ b/reactos/dll/win32/msi/msi_main.c @@ -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; diff --git a/reactos/dll/win32/msi/msipriv.h b/reactos/dll/win32/msi/msipriv.h index 9692b64e14a..5b23f55b189 100644 --- a/reactos/dll/win32/msi/msipriv.h +++ b/reactos/dll/win32/msi/msipriv.h @@ -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]; diff --git a/reactos/dll/win32/msi/msiquery.c b/reactos/dll/win32/msi/msiquery.c index b9733820a69..ddbb28d6496 100644 --- a/reactos/dll/win32/msi/msiquery.c +++ b/reactos/dll/win32/msi/msiquery.c @@ -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; iops->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) diff --git a/reactos/dll/win32/msi/msiserver.idl b/reactos/dll/win32/msi/msiserver.idl index ac442dbd076..9972a023652 100644 --- a/reactos/dll/win32/msi/msiserver.idl +++ b/reactos/dll/win32/msi/msiserver.idl @@ -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); } [ diff --git a/reactos/dll/win32/msi/package.c b/reactos/dll/win32/msi/package.c index 13091d967e4..87f1092c9e9 100644 --- a/reactos/dll/win32/msi/package.c +++ b/reactos/dll/win32/msi/package.c @@ -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 ) diff --git a/reactos/dll/win32/msi/query.h b/reactos/dll/win32/msi/query.h index eb11a1c0321..a43663de697 100644 --- a/reactos/dll/win32/msi/query.h +++ b/reactos/dll/win32/msi/query.h @@ -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; }; diff --git a/reactos/dll/win32/msi/select.c b/reactos/dll/win32/msi/select.c index 8fd761ed0dd..c4b9e804c07 100644 --- a/reactos/dll/win32/msi/select.c +++ b/reactos/dll/win32/msi/select.c @@ -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; diff --git a/reactos/dll/win32/msi/sql.tab.c b/reactos/dll/win32/msi/sql.tab.c index 31eb33853b5..84597a4f6b7 100644 --- a/reactos/dll/win32/msi/sql.tab.c +++ b/reactos/dll/win32/msi/sql.tab.c @@ -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; } diff --git a/reactos/dll/win32/msi/sql.y b/reactos/dll/win32/msi/sql.y index 969c92cc817..e2484df9e98 100644 --- a/reactos/dll/win32/msi/sql.y +++ b/reactos/dll/win32/msi/sql.y @@ -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; } diff --git a/reactos/dll/win32/msi/storages.c b/reactos/dll/win32/msi/storages.c index 16b323c872e..005bcdb663e 100644 --- a/reactos/dll/win32/msi/storages.c +++ b/reactos/dll/win32/msi/storages.c @@ -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; diff --git a/reactos/dll/win32/msi/streams.c b/reactos/dll/win32/msi/streams.c index 12f707e5e57..23ae971c7d8 100644 --- a/reactos/dll/win32/msi/streams.c +++ b/reactos/dll/win32/msi/streams.c @@ -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; diff --git a/reactos/dll/win32/msi/table.c b/reactos/dll/win32/msi/table.c index 35f797975a6..33d1fce64c6 100644 --- a/reactos/dll/win32/msi/table.c +++ b/reactos/dll/win32/msi/table.c @@ -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; diff --git a/reactos/dll/win32/msi/update.c b/reactos/dll/win32/msi/update.c index 56d2391a731..c80d5a90d6a 100644 --- a/reactos/dll/win32/msi/update.c +++ b/reactos/dll/win32/msi/update.c @@ -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, diff --git a/reactos/dll/win32/msi/where.c b/reactos/dll/win32/msi/where.c index fc804a4d68f..32f71b9d1e0 100644 --- a/reactos/dll/win32/msi/where.c +++ b/reactos/dll/win32/msi/where.c @@ -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: