From: Piotr Caban <piotr(a)codeweavers.com> --- dlls/msado15/recordset.c | 41 ++++++++++++++++++++++++++++++++++-- dlls/msado15/tests/msado15.c | 19 ++++++++++++++--- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c index 6737f8240ab..aab91a58a42 100644 --- a/dlls/msado15/recordset.c +++ b/dlls/msado15/recordset.c @@ -2700,16 +2700,53 @@ static HRESULT WINAPI recordset_Update( _Recordset *iface, VARIANT fields, VARIA struct recordset *recordset = impl_from_Recordset( iface ); DBPENDINGSTATUS pending_status; DBROWSTATUS *status; + HACCESSOR hacc; HRESULT hr; + void *data; HROW *row; TRACE( "%p, %s, %s\n", iface, debugstr_variant(&fields), debugstr_variant(&values) ); - if (V_VT(&fields) != VT_ERROR) - FIXME( "ignoring field list and values\n" ); + + if ((V_VT(&fields) & VT_ARRAY) != (V_VT(&values) & VT_ARRAY)) + return MAKE_ADO_HRESULT( adErrInvalidArgument ); + if (V_VT(&fields) & VT_ARRAY) + { + if (V_ARRAY(&fields)->rgsabound[0].cElements != V_ARRAY(&values)->rgsabound[0].cElements || + V_VT(&fields) != (VT_ARRAY | VT_VARIANT) || + V_VT(&values) != (VT_ARRAY | VT_VARIANT)) + return MAKE_ADO_HRESULT( adErrInvalidArgument ); + } if (recordset->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed ); if (!recordset->current_row) return MAKE_ADO_HRESULT( adErrNoCurrentRecord ); + if (V_VT(&fields) != VT_ERROR) + { + if (!recordset->rowset_change) + { + hr = IRowset_QueryInterface( recordset->row_set, &IID_IRowsetChange, + (void **)&recordset->rowset_change ); + if (FAILED(hr) || !recordset->rowset_change) + recordset->rowset_change = NO_INTERFACE; + } + if (recordset->rowset_change == NO_INTERFACE) + return MAKE_ADO_HRESULT( adErrFeatureNotAvailable ); + + hr = get_accessor( recordset, &fields, &hacc ); + if (FAILED(hr)) return hr; + + if (V_VT(&fields) == VT_ERROR) + data = NULL; + else if (V_VT(&values) & VT_ARRAY) + data = V_ARRAY(&values)->pvData; + else + data = &values; + + hr = IRowsetChange_SetData(recordset->rowset_change, recordset->current_row, hacc, data); + IAccessor_ReleaseAccessor( recordset->accessor, hacc, NULL ); + if (FAILED(hr)) return hr; + } + if (recordset->lock_type != adLockPessimistic && recordset->lock_type != adLockOptimistic) return S_OK; diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 67609d9bd8f..5276e1113b2 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -918,7 +918,7 @@ static HRESULT WINAPI rowset_update_SetData(IRowsetUpdate *iface, CHECK_EXPECT(rowset_update_SetData); - ok(row == 1, "row = %Id\n", row); + ok(row == 1 || row == 10, "row = %Id\n", row); ok(accessor, "accessor = 0\n"); ok(data != NULL, "data = NULL\n"); @@ -2069,6 +2069,21 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) hr = _Recordset_Update( recordset, missing, missing ); ok( hr == S_OK, "got %08lx\n", hr ); + V_VT(&index) = VT_I4; + V_I4(&index) = 0; + V_VT(&v) = VT_I4; + V_I4(&v) = 123; + SET_EXPECT(accessor_CreateAccessor); + SET_EXPECT(accessor_AddRefAccessor); + SET_EXPECT(rowset_update_SetData); + SET_EXPECT(accessor_ReleaseAccessor); + hr = _Recordset_Update( recordset, index, v ); + ok( hr == S_OK, "got %08lx\n", hr ); + CHECK_CALLED(accessor_CreateAccessor); + CHECK_CALLED(accessor_AddRefAccessor); + CHECK_CALLED(rowset_update_SetData); + CHECK_CALLED(accessor_ReleaseAccessor); + SET_EXPECT(rowset_update_GetRowStatus); SET_EXPECT(rowset_update_Undo); SET_EXPECT(rowset_AddRefRows); @@ -2089,7 +2104,6 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) V_VT(&v) = VT_BSTR; V_BSTR(&v) = SysAllocString( L"Column1 = 1" ); SET_EXPECT(rowset_ReleaseRows); - SET_EXPECT(accessor_CreateAccessor); SET_EXPECT(accessor_AddRefAccessor); SET_EXPECT(rowset_view_CreateView); SET_EXPECT(view_filter_SetFilter); @@ -2108,7 +2122,6 @@ static void test_ADORecordsetConstruction(BOOL exact_scroll) hr = _Recordset_put_Filter( recordset, v ); todo_wine ok( hr == S_OK, "got %08lx\n", hr ); todo_wine CHECK_CALLED(rowset_ReleaseRows); - todo_wine CHECK_CALLED(accessor_CreateAccessor); todo_wine CHECK_CALLED(accessor_AddRefAccessor); todo_wine CHECK_CALLED(rowset_view_CreateView); todo_wine CHECK_CALLED(view_filter_SetFilter); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9691