msado15: Semi-stub _Recordset get/put Filter.
[wine.git] / dlls / msado15 / tests / msado15.c
blob724787870e0fd18914777be60686d467bdd72865
1 /*
2 * Copyright 2019 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdio.h>
20 #define COBJMACROS
21 #include <initguid.h>
22 #include <oledb.h>
23 #include <olectl.h>
24 #include <msado15_backcompat.h>
25 #include "wine/test.h"
26 #include "msdasql.h"
28 DEFINE_GUID(DBPROPSET_ROWSET, 0xc8b522be, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
30 #define MAKE_ADO_HRESULT( err ) MAKE_HRESULT( SEVERITY_ERROR, FACILITY_CONTROL, err )
32 static BOOL is_bof( _Recordset *recordset )
34 VARIANT_BOOL bof = VARIANT_FALSE;
35 _Recordset_get_BOF( recordset, &bof );
36 return bof == VARIANT_TRUE;
39 static BOOL is_eof( _Recordset *recordset )
41 VARIANT_BOOL eof = VARIANT_FALSE;
42 _Recordset_get_EOF( recordset, &eof );
43 return eof == VARIANT_TRUE;
46 static void test_Recordset(void)
48 _Recordset *recordset;
49 IRunnableObject *runtime;
50 ISupportErrorInfo *errorinfo;
51 Fields *fields, *fields2;
52 Field *field;
53 Properties *props;
54 Property *prop;
55 LONG count, state;
56 ADO_LONGPTR rec_count;
57 VARIANT missing, val, index;
58 CursorLocationEnum location;
59 CursorTypeEnum cursor;
60 BSTR name;
61 HRESULT hr;
62 VARIANT bookmark, filter;
63 EditModeEnum editmode;
65 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
66 ok( hr == S_OK, "got %08lx\n", hr );
68 hr = _Recordset_QueryInterface( recordset, &IID_IRunnableObject, (void**)&runtime);
69 ok(hr == E_NOINTERFACE, "Unexpected IRunnableObject interface\n");
70 ok(runtime == NULL, "expected NULL\n");
72 /* _Recordset object supports ISupportErrorInfo */
73 errorinfo = NULL;
74 hr = _Recordset_QueryInterface( recordset, &IID_ISupportErrorInfo, (void **)&errorinfo );
75 ok( hr == S_OK, "got %08lx\n", hr );
76 if (errorinfo) ISupportErrorInfo_Release( errorinfo );
78 hr = _Recordset_get_Fields( recordset, &fields );
79 ok( hr == S_OK, "got %08lx\n", hr );
81 /* calling get_Fields again returns the same object */
82 hr = _Recordset_get_Fields( recordset, &fields2 );
83 ok( hr == S_OK, "got %08lx\n", hr );
84 ok( fields2 == fields, "expected same object\n" );
86 count = -1;
87 hr = Fields_get_Count( fields2, &count );
88 ok( hr == S_OK, "got %08lx\n", hr );
89 ok( !count, "got %ld\n", count );
91 hr = _Recordset_Close( recordset );
92 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08lx\n", hr );
94 Fields_Release( fields2 );
96 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
97 ok( hr == S_OK, "got %08lx\n", hr );
99 state = -1;
100 hr = _Recordset_get_State( recordset, &state );
101 ok( hr == S_OK, "got %08lx\n", hr );
102 ok( state == adStateClosed, "got %ld\n", state );
104 location = -1;
105 hr = _Recordset_get_CursorLocation( recordset, &location );
106 ok( hr == S_OK, "got %08lx\n", hr );
107 ok( location == adUseServer, "got %d\n", location );
109 cursor = adOpenUnspecified;
110 hr = _Recordset_get_CursorType( recordset, &cursor );
111 ok( hr == S_OK, "got %08lx\n", hr );
112 ok( cursor == adOpenForwardOnly, "got %d\n", cursor );
114 editmode = -1;
115 hr = _Recordset_get_EditMode( recordset, &editmode );
116 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08lx\n", hr );
118 VariantInit( &bookmark );
119 hr = _Recordset_get_Bookmark( recordset, &bookmark );
120 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08lx\n", hr );
122 VariantInit( &bookmark );
123 hr = _Recordset_put_Bookmark( recordset, bookmark );
124 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08lx\n", hr );
126 VariantInit( &filter );
127 hr = _Recordset_put_Filter( recordset, filter );
128 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08lx\n", hr );
130 V_VT(&filter) = VT_BSTR;
131 V_BSTR(&filter) = SysAllocString( L"field1 = 1" );
132 hr = _Recordset_put_Filter( recordset, filter );
133 ok( hr == S_OK, "got %08lx\n", hr );
134 VariantClear(&filter);
136 V_VT(&filter) = VT_I4;
137 V_I4(&filter) = 0;
138 hr = _Recordset_put_Filter( recordset, filter );
139 ok( hr == S_OK, "got %08lx\n", hr );
141 V_VT(&filter) = VT_I2;
142 V_I2(&filter) = 0;
143 hr = _Recordset_put_Filter( recordset, filter );
144 ok( hr == S_OK, "got %08lx\n", hr );
146 VariantInit( &missing );
147 hr = _Recordset_AddNew( recordset, missing, missing );
148 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08lx\n", hr );
150 V_VT( &missing ) = VT_ERROR;
151 V_ERROR( &missing ) = DISP_E_PARAMNOTFOUND;
152 hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified );
153 ok( hr == MAKE_ADO_HRESULT( adErrInvalidConnection ), "got %08lx\n", hr );
155 hr = _Recordset_get_Fields( recordset, &fields );
156 ok( hr == S_OK, "got %08lx\n", hr );
158 name = SysAllocString( L"field" );
159 hr = Fields__Append( fields, name, adInteger, 4, adFldUnspecified );
160 ok( hr == S_OK, "got %08lx\n", hr );
162 V_VT( &index ) = VT_I4;
163 V_I4( &index ) = 1000;
164 hr = Fields_get_Item( fields, index, &field );
165 ok( hr == MAKE_ADO_HRESULT(adErrItemNotFound), "got %08lx\n", hr );
167 V_VT( &index ) = VT_I4;
168 V_I4( &index ) = 0;
169 hr = Fields_get_Item( fields, index, &field );
170 ok( hr == S_OK, "got %08lx\n", hr );
171 Field_Release(field);
173 V_VT( &index ) = VT_I2;
174 V_I4( &index ) = 0;
175 hr = Fields_get_Item( fields, index, &field );
176 ok( hr == S_OK, "got %08lx\n", hr );
177 Field_Release(field);
179 V_VT( &index ) = VT_I1;
180 V_I1( &index ) = 0;
181 hr = Fields_get_Item( fields, index, &field );
182 ok( hr == S_OK, "got %08lx\n", hr );
183 Field_Release(field);
185 V_VT( &index ) = VT_R8;
186 V_R8( &index ) = 0.1;
187 hr = Fields_get_Item( fields, index, &field );
188 ok( hr == S_OK, "got %08lx\n", hr );
189 Field_Release(field);
191 V_VT( &index ) = VT_UNKNOWN;
192 V_UNKNOWN( &index ) = NULL;
193 hr = Fields_get_Item( fields, index, &field );
194 ok( hr == MAKE_ADO_HRESULT(adErrItemNotFound), "got %08lx\n", hr );
196 V_VT( &index ) = VT_BSTR;
197 V_BSTR( &index ) = name;
198 hr = Fields_get_Item( fields, index, &field );
199 ok( hr == S_OK, "got %08lx\n", hr );
200 SysFreeString( name );
202 hr = Field_QueryInterface(field, &IID_Properties, (void**)&props);
203 ok( hr == E_NOINTERFACE, "got %08lx\n", hr );
205 hr = Field_get_Properties(field, &props);
206 ok( hr == S_OK, "got %08lx\n", hr );
208 count = -1;
209 hr = Properties_get_Count(props, &count);
210 ok( hr == S_OK, "got %08lx\n", hr );
211 ok( !count, "got %ld\n", count );
213 V_VT( &index ) = VT_I4;
214 V_I4( &index ) = 1000;
215 hr = Properties_get_Item(props, index, &prop);
216 ok( hr == MAKE_ADO_HRESULT(adErrItemNotFound), "got %08lx\n", hr );
218 Properties_Release(props);
220 hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified );
221 ok( hr == S_OK, "got %08lx\n", hr );
222 ok( is_eof( recordset ), "not eof\n" );
223 ok( is_bof( recordset ), "not bof\n" );
225 editmode = -1;
226 hr = _Recordset_get_EditMode( recordset, &editmode );
227 ok( hr == MAKE_ADO_HRESULT( adErrNoCurrentRecord ), "got %08lx\n", hr );
229 hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified );
230 ok( hr == MAKE_ADO_HRESULT( adErrObjectOpen ), "got %08lx\n", hr );
232 state = -1;
233 hr = _Recordset_get_State( recordset, &state );
234 ok( hr == S_OK, "got %08lx\n", hr );
235 ok( state == adStateOpen, "got %ld\n", state );
237 VariantInit( &bookmark );
238 hr = _Recordset_get_Bookmark( recordset, &bookmark );
239 ok( hr == MAKE_ADO_HRESULT( adErrNoCurrentRecord ), "got %08lx\n", hr );
241 VariantInit( &bookmark );
242 hr = _Recordset_put_Bookmark( recordset, bookmark );
243 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08lx\n", hr );
245 rec_count = -1;
246 hr = _Recordset_get_RecordCount( recordset, &rec_count );
247 ok( hr == S_OK, "got %08lx\n", hr );
248 ok( !rec_count, "got %Id\n", rec_count );
250 hr = _Recordset_AddNew( recordset, missing, missing );
251 ok( hr == S_OK, "got %08lx\n", hr );
252 ok( !is_eof( recordset ), "eof\n" );
253 ok( !is_bof( recordset ), "bof\n" );
255 editmode = -1;
256 hr = _Recordset_get_EditMode( recordset, &editmode );
257 ok( hr == S_OK, "got %08lx\n", hr );
258 todo_wine ok( editmode == adEditAdd, "got %d\n", editmode );
260 rec_count = -1;
261 hr = _Recordset_get_RecordCount( recordset, &rec_count );
262 ok( hr == S_OK, "got %08lx\n", hr );
263 ok( rec_count == 1, "got %Id\n", rec_count );
265 /* get_Fields still returns the same object */
266 hr = _Recordset_get_Fields( recordset, &fields2 );
267 ok( hr == S_OK, "got %08lx\n", hr );
268 ok( fields2 == fields, "expected same object\n" );
269 Fields_Release( fields2 );
271 V_VT(&filter) = VT_BSTR;
272 V_BSTR(&filter) = SysAllocString( L"field1 = 1" );
273 hr = _Recordset_put_Filter( recordset, filter );
274 todo_wine ok( hr == MAKE_ADO_HRESULT( adErrItemNotFound ), "got %08lx\n", hr );
275 VariantClear(&filter);
277 V_VT(&filter) = VT_BSTR;
278 V_BSTR(&filter) = SysAllocString( L"field = 1" );
279 hr = _Recordset_put_Filter( recordset, filter );
280 ok( hr == S_OK, "got %08lx\n", hr );
281 VariantClear(&filter);
283 V_VT(&filter) = VT_I4;
284 V_I4(&filter) = 0;
285 hr = _Recordset_put_Filter( recordset, filter );
286 ok( hr == S_OK, "got %08lx\n", hr );
288 count = -1;
289 hr = Fields_get_Count( fields2, &count );
290 ok( count == 1, "got %ld\n", count );
292 hr = Field_get_Value( field, &val );
293 ok( hr == S_OK, "got %08lx\n", hr );
294 ok( V_VT( &val ) == VT_EMPTY, "got %u\n", V_VT( &val ) );
296 V_VT( &val ) = VT_I4;
297 V_I4( &val ) = -1;
298 hr = Field_put_Value( field, val );
299 ok( hr == S_OK, "got %08lx\n", hr );
301 V_VT( &val ) = VT_ERROR;
302 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
303 hr = Field_get_Value( field, &val );
304 ok( hr == S_OK, "got %08lx\n", hr );
305 ok( V_VT( &val ) == VT_I4, "got %u\n", V_VT( &val ) );
306 ok( V_I4( &val ) == -1, "got %ld\n", V_I4( &val ) );
308 hr = _Recordset_AddNew( recordset, missing, missing );
309 ok( hr == S_OK, "got %08lx\n", hr );
311 /* field object returns different value after AddNew */
312 V_VT( &val ) = VT_ERROR;
313 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
314 hr = Field_get_Value( field, &val );
315 ok( hr == S_OK, "got %08lx\n", hr );
316 ok( V_VT( &val ) == VT_EMPTY, "got %u\n", V_VT( &val ) );
318 ok( !is_eof( recordset ), "eof\n" );
319 ok( !is_bof( recordset ), "bof\n" );
320 hr = _Recordset_MoveFirst( recordset );
321 ok( hr == S_OK, "got %08lx\n", hr );
322 ok( !is_eof( recordset ), "eof\n" );
323 ok( !is_bof( recordset ), "bof\n" );
325 V_VT( &val ) = VT_ERROR;
326 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
327 hr = Field_get_Value( field, &val );
328 ok( hr == S_OK, "got %08lx\n", hr );
329 ok( V_VT( &val ) == VT_I4, "got %u\n", V_VT( &val ) );
330 ok( V_I4( &val ) == -1, "got %ld\n", V_I4( &val ) );
332 hr = _Recordset_MoveNext( recordset );
333 ok( hr == S_OK, "got %08lx\n", hr );
334 ok( !is_eof( recordset ), "eof\n" );
335 ok( !is_bof( recordset ), "not bof\n" );
337 hr = _Recordset_MoveNext( recordset );
338 ok( hr == S_OK, "got %08lx\n", hr );
339 ok( is_eof( recordset ), "not eof\n" );
340 ok( !is_bof( recordset ), "bof\n" );
342 hr = _Recordset_MoveFirst( recordset );
343 ok( hr == S_OK, "got %08lx\n", hr );
344 ok( !is_eof( recordset ), "eof\n" );
345 ok( !is_bof( recordset ), "bof\n" );
347 hr = _Recordset_MovePrevious( recordset );
348 ok( hr == S_OK, "got %08lx\n", hr );
349 ok( !is_eof( recordset ), "eof\n" );
350 ok( is_bof( recordset ), "not bof\n" );
352 /* try get value at BOF */
353 VariantInit( &val );
354 hr = Field_get_Value( field, &val );
355 ok( hr == MAKE_ADO_HRESULT( adErrNoCurrentRecord ), "got %08lx\n", hr );
357 hr = _Recordset_Close( recordset );
358 ok( hr == S_OK, "got %08lx\n", hr );
360 count = -1;
361 hr = Fields_get_Count( fields, &count );
362 ok( !count, "got %ld\n", count );
364 hr = Field_get_Name(field, &name);
365 todo_wine ok( hr == MAKE_ADO_HRESULT( adErrObjectNotSet ), "got %08lx\n", hr );
367 state = -1;
368 hr = _Recordset_get_State( recordset, &state );
369 ok( hr == S_OK, "got %08lx\n", hr );
370 ok( state == adStateClosed, "got %ld\n", state );
372 Field_Release( field );
373 Fields_Release( fields );
374 _Recordset_Release( recordset );
377 /* This interface is queried for but is not documented anywhere. */
378 DEFINE_GUID(UKN_INTERFACE, 0x6f1e39e1, 0x05c6, 0x11d0, 0xa7, 0x8b, 0x00, 0xaa, 0x00, 0xa3, 0xf0, 0x0d);
380 struct test_rowset
382 IRowset IRowset_iface;
383 IRowsetInfo IRowsetInfo_iface;
384 IColumnsInfo IColumnsInfo_iface;
385 LONG refs;
388 static inline struct test_rowset *impl_from_IRowset( IRowset *iface )
390 return CONTAINING_RECORD( iface, struct test_rowset, IRowset_iface );
393 static inline struct test_rowset *impl_from_IRowsetInfo( IRowsetInfo *iface )
395 return CONTAINING_RECORD( iface, struct test_rowset, IRowsetInfo_iface );
398 static inline struct test_rowset *impl_from_IColumnsInfo( IColumnsInfo *iface )
400 return CONTAINING_RECORD( iface, struct test_rowset, IColumnsInfo_iface );
403 static HRESULT WINAPI rowset_info_QueryInterface(IRowsetInfo *iface, REFIID riid, void **obj)
405 struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
406 return IRowset_QueryInterface(&rowset->IRowset_iface, riid, obj);
409 static ULONG WINAPI rowset_info_AddRef(IRowsetInfo *iface)
411 struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
412 return IRowset_AddRef(&rowset->IRowset_iface);
415 static ULONG WINAPI rowset_info_Release(IRowsetInfo *iface)
417 struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
418 return IRowset_Release(&rowset->IRowset_iface);
421 static HRESULT WINAPI rowset_info_GetProperties(IRowsetInfo *iface, const ULONG count,
422 const DBPROPIDSET propertyidsets[], ULONG *out_count, DBPROPSET **propertysets1)
424 ok( count == 2, "got %ld\n", count );
426 ok( IsEqualIID(&DBPROPSET_ROWSET, &propertyidsets[0].guidPropertySet), "got %s\n", wine_dbgstr_guid(&propertyidsets[0].guidPropertySet));
427 ok( propertyidsets[0].cPropertyIDs == 17, "got %ld\n", propertyidsets[0].cPropertyIDs );
429 ok( IsEqualIID(&DBPROPSET_PROVIDERROWSET, &propertyidsets[1].guidPropertySet), "got %s\n", wine_dbgstr_guid(&propertyidsets[1].guidPropertySet));
430 ok( propertyidsets[1].cPropertyIDs == 1, "got %ld\n", propertyidsets[1].cPropertyIDs );
432 return E_NOTIMPL;
435 static HRESULT WINAPI rowset_info_GetReferencedRowset(IRowsetInfo *iface, DBORDINAL ordinal,
436 REFIID riid, IUnknown **unk)
438 ok(0, "Unexpected call\n");
439 return E_NOTIMPL;
442 static HRESULT WINAPI rowset_info_GetSpecification(IRowsetInfo *iface, REFIID riid,
443 IUnknown **specification)
445 ok(0, "Unexpected call\n");
446 return E_NOTIMPL;
449 static const struct IRowsetInfoVtbl rowset_info =
451 rowset_info_QueryInterface,
452 rowset_info_AddRef,
453 rowset_info_Release,
454 rowset_info_GetProperties,
455 rowset_info_GetReferencedRowset,
456 rowset_info_GetSpecification
459 static HRESULT WINAPI column_info_QueryInterface(IColumnsInfo *iface, REFIID riid, void **obj)
461 struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
462 return IRowset_QueryInterface(&rowset->IRowset_iface, riid, obj);
465 static ULONG WINAPI column_info_AddRef(IColumnsInfo *iface)
467 struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
468 return IRowset_AddRef(&rowset->IRowset_iface);
471 static ULONG WINAPI column_info_Release(IColumnsInfo *iface)
473 struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
474 return IRowset_Release(&rowset->IRowset_iface);
477 static HRESULT WINAPI column_info_GetColumnInfo(IColumnsInfo *This, DBORDINAL *columns,
478 DBCOLUMNINFO **colinfo, OLECHAR **stringsbuffer)
480 DBCOLUMNINFO *dbcolumn;
481 *columns = 1;
483 *stringsbuffer = CoTaskMemAlloc(sizeof(L"Column1"));
484 lstrcpyW(*stringsbuffer, L"Column1");
486 dbcolumn = CoTaskMemAlloc(sizeof(DBCOLUMNINFO));
488 dbcolumn->pwszName = *stringsbuffer;
489 dbcolumn->pTypeInfo = NULL;
490 dbcolumn->iOrdinal = 1;
491 dbcolumn->dwFlags = DBCOLUMNFLAGS_MAYBENULL;
492 dbcolumn->ulColumnSize = 5;
493 dbcolumn->wType = DBTYPE_I4;
494 dbcolumn->bPrecision = 1;
495 dbcolumn->bScale = 1;
496 dbcolumn->columnid.eKind = DBKIND_NAME;
497 dbcolumn->columnid.uName.pwszName = *stringsbuffer;
499 *colinfo = dbcolumn;
501 return S_OK;
504 static HRESULT WINAPI column_info_MapColumnIDs(IColumnsInfo *This, DBORDINAL column_ids,
505 const DBID *dbids, DBORDINAL *columns)
507 ok(0, "Unexpected call\n");
508 return E_NOTIMPL;
511 static const struct IColumnsInfoVtbl column_info =
513 column_info_QueryInterface,
514 column_info_AddRef,
515 column_info_Release,
516 column_info_GetColumnInfo,
517 column_info_MapColumnIDs,
520 static HRESULT WINAPI rowset_QueryInterface(IRowset *iface, REFIID riid, void **obj)
522 struct test_rowset *rowset = impl_from_IRowset( iface );
524 *obj = NULL;
526 if (IsEqualIID(riid, &IID_IRowset) ||
527 IsEqualIID(riid, &IID_IUnknown))
529 trace("Requested interface IID_IRowset\n");
530 *obj = &rowset->IRowset_iface;
532 else if (IsEqualIID(riid, &IID_IRowsetInfo))
534 trace("Requested interface IID_IRowsetInfo\n");
535 *obj = &rowset->IRowsetInfo_iface;
537 else if (IsEqualIID(riid, &IID_IColumnsInfo))
539 trace("Requested interface IID_IColumnsInfo\n");
540 *obj = &rowset->IColumnsInfo_iface;
542 else if (IsEqualIID(riid, &IID_IRowsetLocate))
544 trace("Requested interface IID_IRowsetLocate\n");
545 return E_NOINTERFACE;
547 else if (IsEqualIID(riid, &IID_IDBAsynchStatus))
549 trace("Requested interface IID_IDBAsynchStatus\n");
550 return E_NOINTERFACE;
552 else if (IsEqualIID(riid, &IID_IAccessor))
554 trace("Requested interface IID_IAccessor\n");
555 return E_NOINTERFACE;
557 else if (IsEqualIID(riid, &UKN_INTERFACE))
559 trace("Unknown interface\n");
560 return E_NOINTERFACE;
563 if(*obj) {
564 IUnknown_AddRef((IUnknown*)*obj);
565 return S_OK;
568 ok(0, "Unsupported interface %s\n", wine_dbgstr_guid(riid));
569 return E_NOINTERFACE;
572 static ULONG WINAPI rowset_AddRef(IRowset *iface)
574 struct test_rowset *rowset = impl_from_IRowset( iface );
575 return InterlockedIncrement( &rowset->refs );
578 static ULONG WINAPI rowset_Release(IRowset *iface)
580 struct test_rowset *rowset = impl_from_IRowset( iface );
581 /* Object not allocated no need to destroy */
582 return InterlockedDecrement( &rowset->refs );
585 static HRESULT WINAPI rowset_AddRefRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
586 DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
588 ok(0, "Unexpected call\n");
589 return E_NOTIMPL;
592 static HRESULT WINAPI rowset_GetData(IRowset *iface, HROW hRow, HACCESSOR hAccessor, void *pData)
594 ok(0, "Unexpected call\n");
595 return E_NOTIMPL;
598 static HRESULT WINAPI rowset_GetNextRows(IRowset *iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
599 DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
601 ok(0, "Unexpected call\n");
602 return E_NOTIMPL;
605 static HRESULT WINAPI rowset_ReleaseRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
606 DBROWOPTIONS rgRowOptions[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
608 ok(0, "Unexpected call\n");
609 return E_NOTIMPL;
612 static HRESULT WINAPI rowset_RestartPosition(IRowset *iface, HCHAPTER hReserved)
614 ok(0, "Unexpected call\n");
615 return E_NOTIMPL;
618 static const struct IRowsetVtbl rowset_vtbl =
620 rowset_QueryInterface,
621 rowset_AddRef,
622 rowset_Release,
623 rowset_AddRefRows,
624 rowset_GetData,
625 rowset_GetNextRows,
626 rowset_ReleaseRows,
627 rowset_RestartPosition
630 static ULONG get_refcount(void *iface)
632 IUnknown *unknown = iface;
633 IUnknown_AddRef(unknown);
634 return IUnknown_Release(unknown);
637 static void test_ADORecordsetConstruction(void)
639 _Recordset *recordset;
640 ADORecordsetConstruction *construct;
641 Fields *fields = NULL;
642 Field *field;
643 struct test_rowset testrowset;
644 IRowset *rowset;
645 HRESULT hr;
646 LONG ref, count;
648 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
649 ok( hr == S_OK, "got %08lx\n", hr );
651 hr = _Recordset_QueryInterface( recordset, &IID_ADORecordsetConstruction, (void**)&construct );
652 ok( hr == S_OK, "got %08lx\n", hr );
653 if (FAILED(hr))
655 goto done;
658 testrowset.IRowset_iface.lpVtbl = &rowset_vtbl;
659 testrowset.IRowsetInfo_iface.lpVtbl = &rowset_info;
660 testrowset.IColumnsInfo_iface.lpVtbl = &column_info;
661 testrowset.refs = 1;
663 rowset = &testrowset.IRowset_iface;
665 ref = get_refcount( rowset );
666 ok( ref == 1, "got %ld\n", ref );
667 hr = ADORecordsetConstruction_put_Rowset( construct, (IUnknown*)rowset );
668 ok( hr == S_OK, "got %08lx\n", hr );
670 ref = get_refcount( rowset );
671 ok( ref == 2, "got %ld\n", ref );
673 hr = _Recordset_get_Fields( recordset, &fields );
674 ok( hr == S_OK, "got %08lx\n", hr );
675 ok( fields != NULL, "NULL value\n");
677 ref = get_refcount( rowset );
678 ok( ref == 2, "got %ld\n", ref );
680 count = -1;
681 hr = Fields_get_Count( fields, &count );
682 ok( count == 1, "got %ld\n", count );
683 if (count > 0)
685 VARIANT index;
686 ADO_LONGPTR size;
687 DataTypeEnum type;
689 V_VT( &index ) = VT_BSTR;
690 V_BSTR( &index ) = SysAllocString( L"Column1" );
692 hr = Fields_get_Item( fields, index, &field );
693 ok( hr == S_OK, "got %08lx\n", hr );
695 hr = Field_get_Type( field, &type );
696 ok( hr == S_OK, "got %08lx\n", hr );
697 ok( type == adInteger, "got %d\n", type );
698 size = -1;
699 hr = Field_get_DefinedSize( field, &size );
700 ok( hr == S_OK, "got %08lx\n", hr );
701 ok( size == 5, "got %Id\n", size );
703 VariantClear(&index);
705 Field_Release(field);
708 ref = get_refcount(rowset);
709 ok( ref == 2, "got %ld\n", ref );
711 Fields_Release(fields);
713 ADORecordsetConstruction_Release(construct);
715 done:
716 _Recordset_Release( recordset );
719 static void test_Fields(void)
721 _Recordset *recordset;
722 ISupportErrorInfo *errorinfo;
723 Fields *fields;
724 Field *field, *field2;
725 VARIANT val, index;
726 BSTR name;
727 LONG count;
728 ADO_LONGPTR size;
729 DataTypeEnum type;
730 LONG attrs;
731 HRESULT hr;
733 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
734 ok( hr == S_OK, "got %08lx\n", hr );
736 hr = _Recordset_QueryInterface( recordset, &IID_Fields, (void **)&fields );
737 ok( hr == E_NOINTERFACE, "got %08lx\n", hr );
739 hr = _Recordset_get_Fields( recordset, &fields );
740 ok( hr == S_OK, "got %08lx\n", hr );
742 /* Fields object supports ISupportErrorInfo */
743 errorinfo = NULL;
744 hr = Fields_QueryInterface( fields, &IID_ISupportErrorInfo, (void **)&errorinfo );
745 ok( hr == S_OK, "got %08lx\n", hr );
746 if (errorinfo) ISupportErrorInfo_Release( errorinfo );
748 count = -1;
749 hr = Fields_get_Count( fields, &count );
750 ok( !count, "got %ld\n", count );
752 name = SysAllocString( L"field" );
753 V_VT( &val ) = VT_ERROR;
754 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
755 hr = Fields_Append( fields, name, adInteger, 4, adFldUnspecified, val );
756 ok( hr == S_OK, "got %08lx\n", hr );
757 SysFreeString( name );
759 count = -1;
760 hr = Fields_get_Count( fields, &count );
761 ok( count == 1, "got %ld\n", count );
763 name = SysAllocString( L"field2" );
764 hr = Fields__Append( fields, name, adInteger, 4, adFldUnspecified );
765 ok( hr == S_OK, "got %08lx\n", hr );
766 SysFreeString( name );
768 count = -1;
769 hr = Fields_get_Count( fields, &count );
770 ok( count == 2, "got %ld\n", count );
772 /* handing out field object doesn't add reference to fields or recordset object */
773 name = SysAllocString( L"field" );
774 V_VT( &index ) = VT_BSTR;
775 V_BSTR( &index ) = name;
776 hr = Fields_get_Item( fields, index, &field );
778 /* calling get_Item again returns the same object and adds reference */
779 hr = Fields_get_Item( fields, index, &field2 );
780 ok( hr == S_OK, "got %08lx\n", hr );
781 ok( field2 == field, "expected same object\n" );
782 Field_Release( field2 );
783 SysFreeString( name );
785 /* Field object supports ISupportErrorInfo */
786 errorinfo = NULL;
787 hr = Field_QueryInterface( field, &IID_ISupportErrorInfo, (void **)&errorinfo );
788 ok( hr == S_OK, "got %08lx\n", hr );
789 if (errorinfo) ISupportErrorInfo_Release( errorinfo );
791 /* verify values set with _Append */
792 hr = Field_get_Name( field, &name );
793 ok( hr == S_OK, "got %08lx\n", hr );
794 ok( !lstrcmpW( name, L"field" ), "got %s\n", wine_dbgstr_w(name) );
795 SysFreeString( name );
796 type = 0xdead;
797 hr = Field_get_Type( field, &type );
798 ok( hr == S_OK, "got %08lx\n", hr );
799 ok( type == adInteger, "got %d\n", type );
800 size = -1;
801 hr = Field_get_DefinedSize( field, &size );
802 ok( hr == S_OK, "got %08lx\n", hr );
803 ok( size == 4, "got %Id\n", size );
804 attrs = 0xdead;
805 hr = Field_get_Attributes( field, &attrs );
806 ok( hr == S_OK, "got %08lx\n", hr );
807 ok( !attrs, "got %ld\n", attrs );
809 Field_Release( field );
810 Fields_Release( fields );
811 _Recordset_Release( recordset );
814 static HRESULT str_to_byte_array( const char *data, VARIANT *ret )
816 SAFEARRAY *vector;
817 LONG i, len = strlen(data);
818 HRESULT hr;
820 if (!(vector = SafeArrayCreateVector( VT_UI1, 0, len ))) return E_OUTOFMEMORY;
821 for (i = 0; i < len; i++)
823 if ((hr = SafeArrayPutElement( vector, &i, (void *)&data[i] )) != S_OK)
825 SafeArrayDestroy( vector );
826 return hr;
830 V_VT( ret ) = VT_ARRAY | VT_UI1;
831 V_ARRAY( ret ) = vector;
832 return S_OK;
835 static void test_Stream(void)
837 _Stream *stream;
838 VARIANT_BOOL eos;
839 StreamTypeEnum type;
840 LineSeparatorEnum sep;
841 LONG refs;
842 ADO_LONGPTR size, pos;
843 ObjectStateEnum state;
844 ConnectModeEnum mode;
845 BSTR charset, str;
846 VARIANT missing, val;
847 HRESULT hr;
849 hr = CoCreateInstance( &CLSID_Stream, NULL, CLSCTX_INPROC_SERVER, &IID__Stream, (void **)&stream );
850 ok( hr == S_OK, "got %08lx\n", hr );
852 hr = _Stream_get_Size( stream, &size );
853 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08lx\n", hr );
855 hr = _Stream_get_EOS( stream, &eos );
856 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08lx\n", hr );
858 hr = _Stream_get_Position( stream, &pos );
859 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08lx\n", hr );
861 hr = _Stream_put_Position( stream, 0 );
862 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08lx\n", hr );
864 /* check default type */
865 type = 0;
866 hr = _Stream_get_Type( stream, &type );
867 ok( hr == S_OK, "got %08lx\n", hr );
868 ok( type == adTypeText, "got %u\n", type );
870 hr = _Stream_put_Type( stream, adTypeBinary );
871 ok( hr == S_OK, "got %08lx\n", hr );
873 type = 0;
874 hr = _Stream_get_Type( stream, &type );
875 ok( hr == S_OK, "got %08lx\n", hr );
876 ok( type == adTypeBinary, "got %u\n", type );
878 /* revert */
879 hr = _Stream_put_Type( stream, adTypeText );
880 ok( hr == S_OK, "got %08lx\n", hr );
882 sep = 0;
883 hr = _Stream_get_LineSeparator( stream, &sep );
884 ok( hr == S_OK, "got %08lx\n", hr );
885 ok( sep == adCRLF, "got %d\n", sep );
887 hr = _Stream_put_LineSeparator( stream, adLF );
888 ok( hr == S_OK, "got %08lx\n", hr );
890 state = 0xdeadbeef;
891 hr = _Stream_get_State( stream, &state );
892 ok( hr == S_OK, "got %08lx\n", hr );
893 ok( state == adStateClosed, "got %u\n", state );
895 mode = 0xdeadbeef;
896 hr = _Stream_get_Mode( stream, &mode );
897 ok( hr == S_OK, "got %08lx\n", hr );
898 ok( mode == adModeUnknown, "got %u\n", mode );
900 hr = _Stream_put_Mode( stream, adModeReadWrite );
901 ok( hr == S_OK, "got %08lx\n", hr );
903 hr = _Stream_get_Charset( stream, &charset );
904 ok( hr == S_OK, "got %08lx\n", hr );
905 ok( !lstrcmpW( charset, L"Unicode" ), "got %s\n", wine_dbgstr_w(charset) );
906 SysFreeString( charset );
908 str = SysAllocString( L"Unicode" );
909 hr = _Stream_put_Charset( stream, str );
910 ok( hr == S_OK, "got %08lx\n", hr );
911 SysFreeString( str );
913 hr = _Stream_Read( stream, 2, &val );
914 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08lx\n", hr );
916 V_VT( &missing ) = VT_ERROR;
917 V_ERROR( &missing ) = DISP_E_PARAMNOTFOUND;
918 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
919 ok( hr == S_OK, "got %08lx\n", hr );
921 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
922 ok( hr == MAKE_ADO_HRESULT( adErrObjectOpen ), "got %08lx\n", hr );
924 state = 0xdeadbeef;
925 hr = _Stream_get_State( stream, &state );
926 ok( hr == S_OK, "got %08lx\n", hr );
927 ok( state == adStateOpen, "got %u\n", state );
929 size = -1;
930 hr = _Stream_get_Size( stream, &size );
931 ok( hr == S_OK, "got %08lx\n", hr );
932 ok( !size, "got %Id\n", size );
934 eos = VARIANT_FALSE;
935 hr = _Stream_get_EOS( stream, &eos );
936 ok( hr == S_OK, "got %08lx\n", hr );
937 ok( eos == VARIANT_TRUE, "got %04x\n", eos );
939 pos = -1;
940 hr = _Stream_get_Position( stream, &pos );
941 ok( hr == S_OK, "got %08lx\n", hr );
942 ok( !pos, "got %Id\n", pos );
944 size = -1;
945 hr = _Stream_get_Size( stream, &size );
946 ok( hr == S_OK, "got %08lx\n", hr );
947 ok( !size, "got %Id\n", size );
949 hr = _Stream_Read( stream, 2, &val );
950 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08lx\n", hr );
952 hr = _Stream_ReadText( stream, 2, &str );
953 ok( hr == S_OK, "got %08lx\n", hr );
954 ok( !str[0], "got %s\n", wine_dbgstr_w(str) );
955 SysFreeString( str );
957 pos = -1;
958 hr = _Stream_get_Position( stream, &pos );
959 ok( hr == S_OK, "got %08lx\n", hr );
960 ok( !pos, "got %Id\n", pos );
962 str = SysAllocString( L"test" );
963 hr = _Stream_WriteText( stream, str, adWriteChar );
964 ok( hr == S_OK, "got %08lx\n", hr );
965 SysFreeString( str );
967 hr = _Stream_ReadText( stream, adReadAll, &str );
968 ok( hr == S_OK, "got %08lx\n", hr );
969 ok( !str[0], "got %s\n", wine_dbgstr_w(str) );
970 SysFreeString( str );
972 hr = _Stream_put_Position( stream, 0 );
973 ok( hr == S_OK, "got %08lx\n", hr );
974 hr = _Stream_ReadText( stream, adReadAll, &str );
975 ok( hr == S_OK, "got %08lx\n", hr );
976 ok( !lstrcmpW( str, L"test" ), "got %s\n", wine_dbgstr_w(str) );
977 SysFreeString( str );
979 pos = -1;
980 hr = _Stream_get_Position( stream, &pos );
981 ok( hr == S_OK, "got %08lx\n", hr );
982 ok( pos == 10, "got %Id\n", pos );
984 eos = VARIANT_FALSE;
985 hr = _Stream_get_EOS( stream, &eos );
986 ok( hr == S_OK, "got %08lx\n", hr );
987 ok( eos == VARIANT_TRUE, "got %04x\n", eos );
989 hr = _Stream_put_Position( stream, 6 );
990 ok( hr == S_OK, "got %08lx\n", hr );
992 size = -1;
993 hr = _Stream_get_Size( stream, &size );
994 ok( hr == S_OK, "got %08lx\n", hr );
995 ok( size == 10, "got %Id\n", size );
997 hr = _Stream_put_Position( stream, 2 );
998 ok( hr == S_OK, "got %08lx\n", hr );
1000 hr = _Stream_SetEOS( stream );
1001 ok( hr == S_OK, "got %08lx\n", hr );
1003 pos = -1;
1004 hr = _Stream_get_Position( stream, &pos );
1005 ok( hr == S_OK, "got %08lx\n", hr );
1006 ok( pos == 2, "got %Id\n", pos );
1008 size = -1;
1009 hr = _Stream_get_Size( stream, &size );
1010 ok( hr == S_OK, "got %08lx\n", hr );
1011 ok( size == 2, "got %Id\n", size );
1013 hr = _Stream_Close( stream );
1014 ok( hr == S_OK, "got %08lx\n", hr );
1016 state = 0xdeadbeef;
1017 hr = _Stream_get_State( stream, &state );
1018 ok( hr == S_OK, "got %08lx\n", hr );
1019 ok( state == adStateClosed, "got %u\n", state );
1021 hr = _Stream_Close( stream );
1022 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08lx\n", hr );
1024 refs = _Stream_Release( stream );
1025 ok( !refs, "got %ld\n", refs );
1027 /* binary type */
1028 hr = CoCreateInstance( &CLSID_Stream, NULL, CLSCTX_INPROC_SERVER, &IID__Stream, (void **)&stream );
1029 ok( hr == S_OK, "got %08lx\n", hr );
1031 hr = _Stream_put_Type( stream, adTypeBinary );
1032 ok( hr == S_OK, "got %08lx\n", hr );
1034 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
1035 ok( hr == S_OK, "got %08lx\n", hr );
1037 hr = _Stream_ReadText( stream, adReadAll, &str );
1038 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08lx\n", hr );
1040 str = SysAllocString( L"test" );
1041 hr = _Stream_WriteText( stream, str, adWriteChar );
1042 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08lx\n", hr );
1043 SysFreeString( str );
1045 VariantInit( &val );
1046 hr = _Stream_Read( stream, 1, &val );
1047 ok( hr == S_OK, "got %08lx\n", hr );
1048 ok( V_VT( &val ) == VT_NULL, "got %u\n", V_VT( &val ) );
1050 VariantInit( &val );
1051 hr = _Stream_Write( stream, val );
1052 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08lx\n", hr );
1054 hr = str_to_byte_array( "data", &val );
1055 ok( hr == S_OK, "got %08lx\n", hr );
1056 hr = _Stream_Write( stream, val );
1057 ok( hr == S_OK, "got %08lx\n", hr );
1058 VariantClear( &val );
1060 pos = -1;
1061 hr = _Stream_get_Position( stream, &pos );
1062 ok( hr == S_OK, "got %08lx\n", hr );
1063 ok( pos == 4, "got %Id\n", pos );
1065 hr = _Stream_put_Position( stream, 0 );
1066 ok( hr == S_OK, "got %08lx\n", hr );
1068 VariantInit( &val );
1069 hr = _Stream_Read( stream, adReadAll, &val );
1070 ok( hr == S_OK, "got %08lx\n", hr );
1071 ok( V_VT( &val ) == (VT_ARRAY | VT_UI1), "got %04x\n", V_VT( &val ) );
1072 VariantClear( &val );
1074 pos = -1;
1075 hr = _Stream_get_Position( stream, &pos );
1076 ok( hr == S_OK, "got %08lx\n", hr );
1077 ok( pos == 4, "got %Id\n", pos );
1079 refs = _Stream_Release( stream );
1080 ok( !refs, "got %ld\n", refs );
1083 static void test_Connection(void)
1085 HRESULT hr;
1086 _Connection *connection;
1087 IRunnableObject *runtime;
1088 ISupportErrorInfo *errorinfo;
1089 IConnectionPointContainer *pointcontainer;
1090 ADOConnectionConstruction15 *construct;
1091 LONG state, timeout;
1092 BSTR str, str2, str3;
1093 ConnectModeEnum mode;
1094 CursorLocationEnum location;
1096 hr = CoCreateInstance(&CLSID_Connection, NULL, CLSCTX_INPROC_SERVER, &IID__Connection, (void**)&connection);
1097 ok( hr == S_OK, "got %08lx\n", hr );
1099 hr = _Connection_QueryInterface(connection, &IID_IRunnableObject, (void**)&runtime);
1100 ok(hr == E_NOINTERFACE, "Unexpected IRunnableObject interface\n");
1101 ok(runtime == NULL, "expected NULL\n");
1103 hr = _Connection_QueryInterface(connection, &IID_ISupportErrorInfo, (void**)&errorinfo);
1104 ok(hr == S_OK, "Failed to get ISupportErrorInfo interface\n");
1105 ISupportErrorInfo_Release(errorinfo);
1107 hr = _Connection_QueryInterface(connection, &IID_IConnectionPointContainer, (void**)&pointcontainer);
1108 ok(hr == S_OK, "Failed to get IConnectionPointContainer interface %08lx\n", hr);
1109 IConnectionPointContainer_Release(pointcontainer);
1111 hr = _Connection_QueryInterface(connection, &IID_ADOConnectionConstruction15, (void**)&construct);
1112 ok(hr == S_OK, "Failed to get ADOConnectionConstruction15 interface %08lx\n", hr);
1113 if (hr == S_OK)
1114 ADOConnectionConstruction15_Release(construct);
1116 if (0) /* Crashes on windows */
1118 hr = _Connection_get_State(connection, NULL);
1119 ok(hr == E_INVALIDARG, "Unexpected hr 0x%08lx\n", hr);
1122 state = -1;
1123 hr = _Connection_get_State(connection, &state);
1124 ok(hr == S_OK, "Failed to get state, hr 0x%08lx\n", hr);
1125 ok(state == adStateClosed, "Unexpected state value 0x%08lx\n", state);
1127 hr = _Connection_Close(connection);
1128 ok(hr == MAKE_ADO_HRESULT(adErrObjectClosed), "got %08lx\n", hr);
1130 timeout = 0;
1131 hr = _Connection_get_CommandTimeout(connection, &timeout);
1132 ok(hr == S_OK, "Failed to get state, hr 0x%08lx\n", hr);
1133 ok(timeout == 30, "Unexpected timeout value %ld\n", timeout);
1135 hr = _Connection_put_CommandTimeout(connection, 300);
1136 ok(hr == S_OK, "Failed to get state, hr 0x%08lx\n", hr);
1138 timeout = 0;
1139 hr = _Connection_get_CommandTimeout(connection, &timeout);
1140 ok(hr == S_OK, "Failed to get state, hr 0x%08lx\n", hr);
1141 ok(timeout == 300, "Unexpected timeout value %ld\n", timeout);
1143 location = 0;
1144 hr = _Connection_get_CursorLocation(connection, &location);
1145 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1146 ok(location == adUseServer, "Unexpected location value %d\n", location);
1148 hr = _Connection_put_CursorLocation(connection, adUseClient);
1149 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1151 location = 0;
1152 hr = _Connection_get_CursorLocation(connection, &location);
1153 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1154 ok(location == adUseClient, "Unexpected location value %d\n", location);
1156 hr = _Connection_put_CursorLocation(connection, adUseServer);
1157 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1159 mode = 0xdeadbeef;
1160 hr = _Connection_get_Mode(connection, &mode);
1161 ok(hr == S_OK, "Failed to get state, hr 0x%08lx\n", hr);
1162 ok(mode == adModeUnknown, "Unexpected mode value %d\n", mode);
1164 hr = _Connection_put_Mode(connection, adModeShareDenyNone);
1165 ok(hr == S_OK, "Failed to get state, hr 0x%08lx\n", hr);
1167 mode = adModeUnknown;
1168 hr = _Connection_get_Mode(connection, &mode);
1169 ok(hr == S_OK, "Failed to get state, hr 0x%08lx\n", hr);
1170 ok(mode == adModeShareDenyNone, "Unexpected mode value %d\n", mode);
1172 hr = _Connection_put_Mode(connection, adModeUnknown);
1173 ok(hr == S_OK, "Failed to get state, hr 0x%08lx\n", hr);
1175 /* Default */
1176 str = (BSTR)0xdeadbeef;
1177 hr = _Connection_get_Provider(connection, &str);
1178 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1179 ok(!wcscmp(str, L"MSDASQL"), "wrong string %s\n", wine_dbgstr_w(str));
1180 SysFreeString(str);
1182 str = SysAllocString(L"MSDASQL.1");
1183 hr = _Connection_put_Provider(connection, str);
1184 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1185 SysFreeString(str);
1187 str = (BSTR)0xdeadbeef;
1188 hr = _Connection_get_Provider(connection, &str);
1189 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1190 ok(!wcscmp(str, L"MSDASQL.1"), "wrong string %s\n", wine_dbgstr_w(str));
1192 /* Restore default */
1193 str = SysAllocString(L"MSDASQL");
1194 hr = _Connection_put_Provider(connection, str);
1195 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1196 SysFreeString(str);
1198 hr = _Connection_put_Provider(connection, NULL);
1199 ok(hr == MAKE_ADO_HRESULT(adErrInvalidArgument), "got 0x%08lx\n", hr);
1200 SysFreeString(str);
1202 str = (BSTR)0xdeadbeef;
1203 hr = _Connection_get_ConnectionString(connection, &str);
1204 ok(hr == S_OK, "got 0x%08lx\n", hr);
1205 ok(str == NULL, "got %p\n", str);
1207 str = SysAllocString(L"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_test");
1208 hr = _Connection_put_ConnectionString(connection, str);
1209 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1211 /* Show put_ConnectionString effects Provider */
1212 str3 = (BSTR)0xdeadbeef;
1213 hr = _Connection_get_Provider(connection, &str3);
1214 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1215 ok(str3 != NULL, "Expected value got NULL\n");
1216 todo_wine ok(!wcscmp(str3, L"MSDASQL.1"), "wrong string %s\n", wine_dbgstr_w(str3));
1217 SysFreeString(str3);
1219 if (0) /* Crashes on windows */
1221 hr = _Connection_get_ConnectionString(connection, NULL);
1222 ok(hr == E_POINTER, "Failed, hr 0x%08lx\n", hr);
1225 str2 = NULL;
1226 hr = _Connection_get_ConnectionString(connection, &str2);
1227 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1228 ok(!wcscmp(str, str2), "wrong string %s\n", wine_dbgstr_w(str2));
1230 hr = _Connection_Open(connection, NULL, NULL, NULL, 0);
1231 ok(hr == E_FAIL, "Failed, hr 0x%08lx\n", hr);
1233 /* Open adds trailing ; if it's missing */
1234 str3 = SysAllocString(L"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_test;");
1235 hr = _Connection_Open(connection, NULL, NULL, NULL, adConnectUnspecified);
1236 ok(hr == E_FAIL, "Failed, hr 0x%08lx\n", hr);
1238 str2 = NULL;
1239 hr = _Connection_get_ConnectionString(connection, &str2);
1240 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1241 todo_wine ok(!wcscmp(str3, str2) || broken(!wcscmp(str, str2)) /* XP */, "wrong string %s\n", wine_dbgstr_w(str2));
1243 hr = _Connection_Open(connection, str, NULL, NULL, adConnectUnspecified);
1244 ok(hr == E_FAIL, "Failed, hr 0x%08lx\n", hr);
1245 SysFreeString(str);
1247 str2 = NULL;
1248 hr = _Connection_get_ConnectionString(connection, &str2);
1249 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1250 todo_wine ok(!wcscmp(str3, str2) || broken(!wcscmp(str, str2)) /* XP */, "wrong string %s\n", wine_dbgstr_w(str2));
1251 SysFreeString(str2);
1252 SysFreeString(str3);
1254 hr = _Connection_put_ConnectionString(connection, NULL);
1255 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1257 str = (BSTR)0xdeadbeef;
1258 hr = _Connection_get_ConnectionString(connection, &str);
1259 ok(hr == S_OK, "Failed, hr 0x%08lx\n", hr);
1260 ok(str == NULL, "got %p\n", str);
1261 _Connection_Release(connection);
1264 static void test_Command(void)
1266 HRESULT hr;
1267 _Command *command;
1268 _ADO *ado;
1269 Command15 *command15;
1270 Command25 *command25;
1271 CommandTypeEnum cmd_type = adCmdUnspecified;
1272 BSTR cmd_text = (BSTR)"test";
1273 _Connection *connection;
1275 hr = CoCreateInstance( &CLSID_Command, NULL, CLSCTX_INPROC_SERVER, &IID__Command, (void **)&command );
1276 ok( hr == S_OK, "got %08lx\n", hr );
1278 hr = _Command_QueryInterface( command, &IID__ADO, (void **)&ado );
1279 ok( hr == S_OK, "got %08lx\n", hr );
1280 _ADO_Release( ado );
1282 hr = _Command_QueryInterface( command, &IID_Command15, (void **)&command15 );
1283 ok( hr == S_OK, "got %08lx\n", hr );
1284 Command15_Release( command15 );
1286 hr = _Command_QueryInterface( command, &IID_Command25, (void **)&command25 );
1287 ok( hr == S_OK, "got %08lx\n", hr );
1288 Command25_Release( command25 );
1290 hr = _Command_get_CommandType( command, &cmd_type );
1291 ok( hr == S_OK, "got %08lx\n", hr );
1292 ok( cmd_type == adCmdUnknown, "got %08x\n", cmd_type );
1294 _Command_put_CommandType( command, adCmdText );
1295 hr = _Command_get_CommandType( command, &cmd_type );
1296 ok( hr == S_OK, "got %08lx\n", hr );
1297 ok( cmd_type == adCmdText, "got %08x\n", cmd_type );
1299 hr = _Command_put_CommandType( command, 0xdeadbeef );
1300 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08lx\n", hr );
1302 hr = _Command_get_CommandText( command, &cmd_text );
1303 ok( hr == S_OK, "got %08lx\n", hr );
1304 ok( !cmd_text, "got %s\n", wine_dbgstr_w( cmd_text ));
1306 hr = _Command_put_CommandText( command, NULL );
1307 ok( hr == S_OK, "got %08lx\n", hr );
1309 cmd_text = SysAllocString( L"" );
1310 hr = _Command_put_CommandText( command, cmd_text );
1311 ok( hr == S_OK, "got %08lx\n", hr );
1312 SysFreeString( cmd_text );
1314 hr = _Command_get_CommandText( command, &cmd_text );
1315 ok( hr == S_OK, "got %08lx\n", hr );
1316 ok( cmd_text && !*cmd_text, "got %p\n", cmd_text );
1318 cmd_text = SysAllocString( L"test" );
1319 hr = _Command_put_CommandText( command, cmd_text );
1320 ok( hr == S_OK, "got %08lx\n", hr );
1321 SysFreeString( cmd_text );
1323 hr = _Command_get_CommandText( command, &cmd_text );
1324 ok( hr == S_OK, "got %08lx\n", hr );
1325 ok( !wcscmp( L"test", cmd_text ), "got %p\n", wine_dbgstr_w( cmd_text ) );
1327 connection = (_Connection*)0xdeadbeef;
1328 hr = _Command_get_ActiveConnection( command, &connection );
1329 ok( hr == S_OK, "got %08lx\n", hr );
1330 ok( connection == NULL, "got %p\n", connection );
1332 hr = _Command_putref_ActiveConnection( command, NULL );
1333 ok( hr == S_OK, "got %08lx\n", hr );
1335 _Command_Release( command );
1338 struct conn_event {
1339 ConnectionEventsVt conn_event_sink;
1340 LONG refs;
1343 static HRESULT WINAPI conneventvt_QueryInterface( ConnectionEventsVt *iface, REFIID riid, void **obj )
1345 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
1347 if (IsEqualGUID( &IID_ConnectionEventsVt, riid ))
1349 InterlockedIncrement( &conn_event->refs );
1350 *obj = iface;
1351 return S_OK;
1354 ok( 0, "unexpected call\n" );
1355 return E_NOINTERFACE;
1358 static ULONG WINAPI conneventvt_AddRef( ConnectionEventsVt *iface )
1360 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
1361 return InterlockedIncrement( &conn_event->refs );
1364 static ULONG WINAPI conneventvt_Release( ConnectionEventsVt *iface )
1366 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
1367 return InterlockedDecrement( &conn_event->refs );
1370 static HRESULT WINAPI conneventvt_InfoMessage( ConnectionEventsVt *iface, Error *error,
1371 EventStatusEnum *status, _Connection *Connection )
1373 return E_NOTIMPL;
1376 static HRESULT WINAPI conneventvt_BeginTransComplete( ConnectionEventsVt *iface, LONG TransactionLevel,
1377 Error *error, EventStatusEnum *status, _Connection *connection )
1379 return E_NOTIMPL;
1382 static HRESULT WINAPI conneventvt_CommitTransComplete( ConnectionEventsVt *iface, Error *error,
1383 EventStatusEnum *status, _Connection *connection )
1385 return E_NOTIMPL;
1388 static HRESULT WINAPI conneventvt_RollbackTransComplete( ConnectionEventsVt *iface, Error *error,
1389 EventStatusEnum *status, _Connection *connection )
1391 return E_NOTIMPL;
1394 static HRESULT WINAPI conneventvt_WillExecute( ConnectionEventsVt *iface, BSTR *source,
1395 CursorTypeEnum *cursor_type, LockTypeEnum *lock_type, LONG *options, EventStatusEnum *status,
1396 _Command *command, _Recordset *record_set, _Connection *connection )
1398 return E_NOTIMPL;
1401 static HRESULT WINAPI conneventvt_ExecuteComplete( ConnectionEventsVt *iface, LONG records_affected,
1402 Error *error, EventStatusEnum *status, _Command *command, _Recordset *record_set,
1403 _Connection *connection )
1405 return E_NOTIMPL;
1408 static HRESULT WINAPI conneventvt_WillConnect( ConnectionEventsVt *iface, BSTR *string, BSTR *userid,
1409 BSTR *password, LONG *options, EventStatusEnum *status, _Connection *connection )
1411 return E_NOTIMPL;
1414 static HRESULT WINAPI conneventvt_ConnectComplete( ConnectionEventsVt *iface, Error *error,
1415 EventStatusEnum *status, _Connection *connection )
1417 return E_NOTIMPL;
1420 static HRESULT WINAPI conneventvt_Disconnect( ConnectionEventsVt *iface, EventStatusEnum *status,
1421 _Connection *connection )
1423 return E_NOTIMPL;
1426 static const ConnectionEventsVtVtbl conneventvt_vtbl = {
1427 conneventvt_QueryInterface,
1428 conneventvt_AddRef,
1429 conneventvt_Release,
1430 conneventvt_InfoMessage,
1431 conneventvt_BeginTransComplete,
1432 conneventvt_CommitTransComplete,
1433 conneventvt_RollbackTransComplete,
1434 conneventvt_WillExecute,
1435 conneventvt_ExecuteComplete,
1436 conneventvt_WillConnect,
1437 conneventvt_ConnectComplete,
1438 conneventvt_Disconnect
1441 static HRESULT WINAPI supporterror_QueryInterface( ISupportErrorInfo *iface, REFIID riid, void **obj )
1443 if (IsEqualGUID( &IID_ISupportErrorInfo, riid ))
1445 *obj = iface;
1446 return S_OK;
1449 return E_NOINTERFACE;
1452 static ULONG WINAPI supporterror_AddRef( ISupportErrorInfo *iface )
1454 return 2;
1457 static ULONG WINAPI supporterror_Release( ISupportErrorInfo *iface )
1459 return 1;
1462 static HRESULT WINAPI supporterror_InterfaceSupportsErrorInfo( ISupportErrorInfo *iface, REFIID riid )
1464 return E_NOTIMPL;
1467 static const struct ISupportErrorInfoVtbl support_error_vtbl =
1469 supporterror_QueryInterface,
1470 supporterror_AddRef,
1471 supporterror_Release,
1472 supporterror_InterfaceSupportsErrorInfo
1475 static void test_ConnectionPoint(void)
1477 HRESULT hr;
1478 ULONG refs;
1479 DWORD cookie;
1480 IConnectionPoint *point;
1481 IConnectionPointContainer *pointcontainer;
1482 struct conn_event conn_event = { { &conneventvt_vtbl }, 0 };
1483 ISupportErrorInfo support_err_sink = { &support_error_vtbl };
1485 hr = CoCreateInstance( &CLSID_Connection, NULL, CLSCTX_INPROC_SERVER,
1486 &IID_IConnectionPointContainer, (void**)&pointcontainer );
1488 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_ConnectionEvents, NULL );
1489 ok( hr == E_POINTER, "got %08lx\n", hr );
1491 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_RecordsetEvents, &point );
1492 ok( hr == CONNECT_E_NOCONNECTION, "got %08lx\n", hr );
1494 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_ConnectionEvents, &point );
1495 ok( hr == S_OK, "got %08lx\n", hr );
1497 /* nothing advised yet */
1498 hr = IConnectionPoint_Unadvise( point, 3 );
1499 ok( hr == E_FAIL, "got %08lx\n", hr );
1501 hr = IConnectionPoint_Advise( point, NULL, NULL );
1502 ok( hr == E_FAIL, "got %08lx\n", hr );
1504 hr = IConnectionPoint_Advise( point, (void*)&conn_event.conn_event_sink, NULL );
1505 ok( hr == E_FAIL, "got %08lx\n", hr );
1507 cookie = 0xdeadbeef;
1508 hr = IConnectionPoint_Advise( point, NULL, &cookie );
1509 ok( hr == E_FAIL, "got %08lx\n", hr );
1510 ok( cookie == 0xdeadbeef, "got %08lx\n", cookie );
1512 /* unsupported sink */
1513 cookie = 0xdeadbeef;
1514 hr = IConnectionPoint_Advise( point, (void*)&support_err_sink, &cookie );
1515 ok( hr == E_FAIL, "got %08lx\n", hr );
1516 ok( !cookie, "got %08lx\n", cookie );
1518 cookie = 0;
1519 hr = IConnectionPoint_Advise( point, (void*)&conn_event.conn_event_sink, &cookie );
1520 ok( hr == S_OK, "got %08lx\n", hr );
1521 ok( cookie, "got %08lx\n", cookie );
1523 /* invalid cookie */
1524 hr = IConnectionPoint_Unadvise( point, 0 );
1525 ok( hr == E_FAIL, "got %08lx\n", hr );
1527 /* wrong cookie */
1528 hr = IConnectionPoint_Unadvise( point, cookie + 1 );
1529 ok( hr == E_FAIL, "got %08lx\n", hr );
1531 hr = IConnectionPoint_Unadvise( point, cookie );
1532 ok( hr == S_OK, "got %08lx\n", hr );
1534 /* sinks are released when the connection is destroyed */
1535 cookie = 0;
1536 hr = IConnectionPoint_Advise( point, (void*)&conn_event.conn_event_sink, &cookie );
1537 ok( hr == S_OK, "got %08lx\n", hr );
1538 ok( cookie, "got %08lx\n", cookie );
1539 ok( conn_event.refs == 1, "got %ld\n", conn_event.refs );
1541 refs = IConnectionPoint_Release( point );
1542 ok( refs == 1, "got %lu", refs );
1544 IConnectionPointContainer_Release( pointcontainer );
1546 ok( !conn_event.refs, "got %ld\n", conn_event.refs );
1549 START_TEST(msado15)
1551 CoInitialize( NULL );
1552 test_Connection();
1553 test_ADORecordsetConstruction();
1554 test_ConnectionPoint();
1555 test_Fields();
1556 test_Recordset();
1557 test_Stream();
1558 test_Command();
1559 CoUninitialize();