mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / msado15 / tests / msado15.c
blobdb606f21fabe084c6311b65dc0ce823c77902f6c
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 LONG get_refs_field( Field *field )
48 Field_AddRef( field );
49 return Field_Release( field );
52 static LONG get_refs_fields( Fields *fields )
54 Fields_AddRef( fields );
55 return Fields_Release( fields );
58 static LONG get_refs_recordset( _Recordset *recordset )
60 _Recordset_AddRef( recordset );
61 return _Recordset_Release( recordset );
64 static void test_Recordset(void)
66 _Recordset *recordset;
67 IRunnableObject *runtime;
68 ISupportErrorInfo *errorinfo;
69 Fields *fields, *fields2;
70 Field *field;
71 LONG refs, count, state;
72 VARIANT missing, val, index;
73 CursorLocationEnum location;
74 CursorTypeEnum cursor;
75 BSTR name;
76 HRESULT hr;
77 VARIANT bookmark;
79 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
80 ok( hr == S_OK, "got %08x\n", hr );
82 hr = _Recordset_QueryInterface( recordset, &IID_IRunnableObject, (void**)&runtime);
83 ok(hr == E_NOINTERFACE, "Unexpected IRunnableObject interface\n");
84 ok(runtime == NULL, "expected NULL\n");
86 /* _Recordset object supports ISupportErrorInfo */
87 errorinfo = NULL;
88 hr = _Recordset_QueryInterface( recordset, &IID_ISupportErrorInfo, (void **)&errorinfo );
89 ok( hr == S_OK, "got %08x\n", hr );
90 refs = get_refs_recordset( recordset );
91 ok( refs == 2, "got %d\n", refs );
92 if (errorinfo) ISupportErrorInfo_Release( errorinfo );
93 refs = get_refs_recordset( recordset );
94 ok( refs == 1, "got %d\n", refs );
96 /* handing out fields object increases recordset refcount */
97 refs = get_refs_recordset( recordset );
98 ok( refs == 1, "got %d\n", refs );
99 hr = _Recordset_get_Fields( recordset, &fields );
100 ok( hr == S_OK, "got %08x\n", hr );
101 refs = get_refs_recordset( recordset );
102 ok( refs == 2, "got %d\n", refs );
103 refs = get_refs_fields( fields );
104 ok( refs == 1, "got %d\n", refs );
106 /* releasing fields object decreases recordset refcount, but fields refcount doesn't drop to zero */
107 Fields_Release( fields );
108 refs = get_refs_recordset( recordset );
109 ok( refs == 1, "got %d\n", refs );
110 refs = get_refs_fields( fields );
111 ok( refs == 1, "got %d\n", refs );
113 /* calling get_Fields again returns the same object with the same refcount and increases recordset refcount */
114 hr = _Recordset_get_Fields( recordset, &fields2 );
115 ok( hr == S_OK, "got %08x\n", hr );
116 refs = get_refs_recordset( recordset );
117 ok( refs == 2, "got %d\n", refs );
118 refs = get_refs_fields( fields2 );
119 ok( refs == 1, "got %d\n", refs );
120 ok( fields2 == fields, "expected same object\n" );
121 refs = Fields_Release( fields2 );
122 ok( refs == 1, "got %d\n", refs );
124 count = -1;
125 hr = Fields_get_Count( fields2, &count );
126 ok( hr == S_OK, "got %08x\n", hr );
127 ok( !count, "got %d\n", count );
129 hr = _Recordset_Close( recordset );
130 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
132 refs = _Recordset_Release( recordset );
133 ok( !refs, "got %d\n", refs );
135 /* fields object still has a reference */
136 refs = Fields_Release( fields2 );
137 ok( refs == 1, "got %d\n", refs );
139 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
140 ok( hr == S_OK, "got %08x\n", hr );
142 state = -1;
143 hr = _Recordset_get_State( recordset, &state );
144 ok( hr == S_OK, "got %08x\n", hr );
145 ok( state == adStateClosed, "got %d\n", state );
147 location = -1;
148 hr = _Recordset_get_CursorLocation( recordset, &location );
149 ok( hr == S_OK, "got %08x\n", hr );
150 ok( location == adUseServer, "got %d\n", location );
152 cursor = adOpenUnspecified;
153 hr = _Recordset_get_CursorType( recordset, &cursor );
154 ok( hr == S_OK, "got %08x\n", hr );
155 ok( cursor == adOpenForwardOnly, "got %d\n", cursor );
157 VariantInit( &bookmark );
158 hr = _Recordset_get_Bookmark( recordset, &bookmark );
159 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
161 VariantInit( &bookmark );
162 hr = _Recordset_put_Bookmark( recordset, bookmark );
163 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
165 VariantInit( &missing );
166 hr = _Recordset_AddNew( recordset, missing, missing );
167 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
169 V_VT( &missing ) = VT_ERROR;
170 V_ERROR( &missing ) = DISP_E_PARAMNOTFOUND;
171 hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified );
172 ok( hr == MAKE_ADO_HRESULT( adErrInvalidConnection ), "got %08x\n", hr );
174 hr = _Recordset_get_Fields( recordset, &fields );
175 ok( hr == S_OK, "got %08x\n", hr );
177 name = SysAllocString( L"field" );
178 hr = Fields__Append( fields, name, adInteger, 4, adFldUnspecified );
179 ok( hr == S_OK, "got %08x\n", hr );
181 V_VT( &index ) = VT_BSTR;
182 V_BSTR( &index ) = name;
183 hr = Fields_get_Item( fields, index, &field );
184 ok( hr == S_OK, "got %08x\n", hr );
185 SysFreeString( name );
187 hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified );
188 ok( hr == S_OK, "got %08x\n", hr );
189 ok( is_eof( recordset ), "not eof\n" );
190 ok( is_bof( recordset ), "not bof\n" );
192 hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified );
193 ok( hr == MAKE_ADO_HRESULT( adErrObjectOpen ), "got %08x\n", hr );
195 state = -1;
196 hr = _Recordset_get_State( recordset, &state );
197 ok( hr == S_OK, "got %08x\n", hr );
198 ok( state == adStateOpen, "got %d\n", state );
200 VariantInit( &bookmark );
201 hr = _Recordset_get_Bookmark( recordset, &bookmark );
202 ok( hr == MAKE_ADO_HRESULT( adErrNoCurrentRecord ), "got %08x\n", hr );
204 VariantInit( &bookmark );
205 hr = _Recordset_put_Bookmark( recordset, bookmark );
206 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08x\n", hr );
208 count = -1;
209 hr = _Recordset_get_RecordCount( recordset, &count );
210 ok( hr == S_OK, "got %08x\n", hr );
211 ok( !count, "got %d\n", count );
213 hr = _Recordset_AddNew( recordset, missing, missing );
214 ok( hr == S_OK, "got %08x\n", hr );
215 ok( !is_eof( recordset ), "eof\n" );
216 ok( !is_bof( recordset ), "bof\n" );
218 count = -1;
219 hr = _Recordset_get_RecordCount( recordset, &count );
220 ok( hr == S_OK, "got %08x\n", hr );
221 ok( count == 1, "got %d\n", count );
223 /* get_Fields still returns the same object */
224 hr = _Recordset_get_Fields( recordset, &fields2 );
225 ok( hr == S_OK, "got %08x\n", hr );
226 ok( fields2 == fields, "expected same object\n" );
227 Fields_Release( fields2 );
229 count = -1;
230 hr = Fields_get_Count( fields2, &count );
231 ok( count == 1, "got %d\n", count );
233 hr = Field_get_Value( field, &val );
234 ok( hr == S_OK, "got %08x\n", hr );
235 ok( V_VT( &val ) == VT_EMPTY, "got %u\n", V_VT( &val ) );
237 V_VT( &val ) = VT_I4;
238 V_I4( &val ) = -1;
239 hr = Field_put_Value( field, val );
240 ok( hr == S_OK, "got %08x\n", hr );
242 V_VT( &val ) = VT_ERROR;
243 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
244 hr = Field_get_Value( field, &val );
245 ok( hr == S_OK, "got %08x\n", hr );
246 ok( V_VT( &val ) == VT_I4, "got %u\n", V_VT( &val ) );
247 ok( V_I4( &val ) == -1, "got %d\n", V_I4( &val ) );
249 hr = _Recordset_AddNew( recordset, missing, missing );
250 ok( hr == S_OK, "got %08x\n", hr );
252 /* field object returns different value after AddNew */
253 V_VT( &val ) = VT_ERROR;
254 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
255 hr = Field_get_Value( field, &val );
256 ok( hr == S_OK, "got %08x\n", hr );
257 ok( V_VT( &val ) == VT_EMPTY, "got %u\n", V_VT( &val ) );
259 ok( !is_eof( recordset ), "eof\n" );
260 ok( !is_bof( recordset ), "bof\n" );
261 hr = _Recordset_MoveFirst( recordset );
262 ok( hr == S_OK, "got %08x\n", hr );
263 ok( !is_eof( recordset ), "eof\n" );
264 ok( !is_bof( recordset ), "bof\n" );
266 V_VT( &val ) = VT_ERROR;
267 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
268 hr = Field_get_Value( field, &val );
269 ok( hr == S_OK, "got %08x\n", hr );
270 ok( V_VT( &val ) == VT_I4, "got %u\n", V_VT( &val ) );
271 ok( V_I4( &val ) == -1, "got %d\n", V_I4( &val ) );
273 hr = _Recordset_MoveNext( recordset );
274 ok( hr == S_OK, "got %08x\n", hr );
275 ok( !is_eof( recordset ), "eof\n" );
276 ok( !is_bof( recordset ), "not bof\n" );
278 hr = _Recordset_MoveNext( recordset );
279 ok( hr == S_OK, "got %08x\n", hr );
280 ok( is_eof( recordset ), "not eof\n" );
281 ok( !is_bof( recordset ), "bof\n" );
283 hr = _Recordset_MoveFirst( recordset );
284 ok( hr == S_OK, "got %08x\n", hr );
285 ok( !is_eof( recordset ), "eof\n" );
286 ok( !is_bof( recordset ), "bof\n" );
288 hr = _Recordset_MovePrevious( recordset );
289 ok( hr == S_OK, "got %08x\n", hr );
290 ok( !is_eof( recordset ), "eof\n" );
291 ok( is_bof( recordset ), "not bof\n" );
293 /* try get value at BOF */
294 VariantInit( &val );
295 hr = Field_get_Value( field, &val );
296 ok( hr == MAKE_ADO_HRESULT( adErrNoCurrentRecord ), "got %08x\n", hr );
298 hr = _Recordset_Close( recordset );
299 ok( hr == S_OK, "got %08x\n", hr );
301 state = -1;
302 hr = _Recordset_get_State( recordset, &state );
303 ok( hr == S_OK, "got %08x\n", hr );
304 ok( state == adStateClosed, "got %d\n", state );
306 Field_Release( field );
307 Fields_Release( fields );
308 _Recordset_Release( recordset );
311 /* This interface is queried for but is not documented anywhere. */
312 DEFINE_GUID(UKN_INTERFACE, 0x6f1e39e1, 0x05c6, 0x11d0, 0xa7, 0x8b, 0x00, 0xaa, 0x00, 0xa3, 0xf0, 0x0d);
314 struct test_rowset
316 IRowset IRowset_iface;
317 IRowsetInfo IRowsetInfo_iface;
318 IColumnsInfo IColumnsInfo_iface;
319 LONG refs;
322 static inline struct test_rowset *impl_from_IRowset( IRowset *iface )
324 return CONTAINING_RECORD( iface, struct test_rowset, IRowset_iface );
327 static inline struct test_rowset *impl_from_IRowsetInfo( IRowsetInfo *iface )
329 return CONTAINING_RECORD( iface, struct test_rowset, IRowsetInfo_iface );
332 static inline struct test_rowset *impl_from_IColumnsInfo( IColumnsInfo *iface )
334 return CONTAINING_RECORD( iface, struct test_rowset, IColumnsInfo_iface );
337 static HRESULT WINAPI rowset_info_QueryInterface(IRowsetInfo *iface, REFIID riid, void **obj)
339 struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
340 return IRowset_QueryInterface(&rowset->IRowset_iface, riid, obj);
343 static ULONG WINAPI rowset_info_AddRef(IRowsetInfo *iface)
345 struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
346 return IRowset_AddRef(&rowset->IRowset_iface);
349 static ULONG WINAPI rowset_info_Release(IRowsetInfo *iface)
351 struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
352 return IRowset_Release(&rowset->IRowset_iface);
355 static HRESULT WINAPI rowset_info_GetProperties(IRowsetInfo *iface, const ULONG count,
356 const DBPROPIDSET propertyidsets[], ULONG *out_count, DBPROPSET **propertysets1)
358 ok( count == 2, "got %d\n", count );
360 ok( IsEqualIID(&DBPROPSET_ROWSET, &propertyidsets[0].guidPropertySet), "got %s\n", wine_dbgstr_guid(&propertyidsets[0].guidPropertySet));
361 ok( propertyidsets[0].cPropertyIDs == 17, "got %d\n", propertyidsets[0].cPropertyIDs );
363 ok( IsEqualIID(&DBPROPSET_PROVIDERROWSET, &propertyidsets[1].guidPropertySet), "got %s\n", wine_dbgstr_guid(&propertyidsets[1].guidPropertySet));
364 ok( propertyidsets[1].cPropertyIDs == 1, "got %d\n", propertyidsets[1].cPropertyIDs );
366 return E_NOTIMPL;
369 static HRESULT WINAPI rowset_info_GetReferencedRowset(IRowsetInfo *iface, DBORDINAL ordinal,
370 REFIID riid, IUnknown **unk)
372 ok(0, "Unexpected call\n");
373 return E_NOTIMPL;
376 static HRESULT WINAPI rowset_info_GetSpecification(IRowsetInfo *iface, REFIID riid,
377 IUnknown **specification)
379 ok(0, "Unexpected call\n");
380 return E_NOTIMPL;
383 static const struct IRowsetInfoVtbl rowset_info =
385 rowset_info_QueryInterface,
386 rowset_info_AddRef,
387 rowset_info_Release,
388 rowset_info_GetProperties,
389 rowset_info_GetReferencedRowset,
390 rowset_info_GetSpecification
393 static HRESULT WINAPI column_info_QueryInterface(IColumnsInfo *iface, REFIID riid, void **obj)
395 struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
396 return IRowset_QueryInterface(&rowset->IRowset_iface, riid, obj);
399 static ULONG WINAPI column_info_AddRef(IColumnsInfo *iface)
401 struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
402 return IRowset_AddRef(&rowset->IRowset_iface);
405 static ULONG WINAPI column_info_Release(IColumnsInfo *iface)
407 struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
408 return IRowset_Release(&rowset->IRowset_iface);
411 static HRESULT WINAPI column_info_GetColumnInfo(IColumnsInfo *This, DBORDINAL *columns,
412 DBCOLUMNINFO **colinfo, OLECHAR **stringsbuffer)
414 DBCOLUMNINFO *dbcolumn;
415 *columns = 1;
417 *stringsbuffer = CoTaskMemAlloc(sizeof(L"Column1"));
418 lstrcpyW(*stringsbuffer, L"Column1");
420 dbcolumn = CoTaskMemAlloc(sizeof(DBCOLUMNINFO));
422 dbcolumn->pwszName = *stringsbuffer;
423 dbcolumn->pTypeInfo = NULL;
424 dbcolumn->iOrdinal = 1;
425 dbcolumn->dwFlags = DBCOLUMNFLAGS_MAYBENULL;
426 dbcolumn->ulColumnSize = 5;
427 dbcolumn->wType = DBTYPE_I4;
428 dbcolumn->bPrecision = 1;
429 dbcolumn->bScale = 1;
430 dbcolumn->columnid.eKind = DBKIND_NAME;
431 dbcolumn->columnid.uName.pwszName = *stringsbuffer;
433 *colinfo = dbcolumn;
435 return S_OK;
438 static HRESULT WINAPI column_info_MapColumnIDs(IColumnsInfo *This, DBORDINAL column_ids,
439 const DBID *dbids, DBORDINAL *columns)
441 ok(0, "Unexpected call\n");
442 return E_NOTIMPL;
445 static const struct IColumnsInfoVtbl column_info =
447 column_info_QueryInterface,
448 column_info_AddRef,
449 column_info_Release,
450 column_info_GetColumnInfo,
451 column_info_MapColumnIDs,
454 static HRESULT WINAPI rowset_QueryInterface(IRowset *iface, REFIID riid, void **obj)
456 struct test_rowset *rowset = impl_from_IRowset( iface );
458 *obj = NULL;
460 if (IsEqualIID(riid, &IID_IRowset) ||
461 IsEqualIID(riid, &IID_IUnknown))
463 trace("Requested interface IID_IRowset\n");
464 *obj = &rowset->IRowset_iface;
466 else if (IsEqualIID(riid, &IID_IRowsetInfo))
468 trace("Requested interface IID_IRowsetInfo\n");
469 *obj = &rowset->IRowsetInfo_iface;
471 else if (IsEqualIID(riid, &IID_IColumnsInfo))
473 trace("Requested interface IID_IColumnsInfo\n");
474 *obj = &rowset->IColumnsInfo_iface;
476 else if (IsEqualIID(riid, &IID_IRowsetLocate))
478 trace("Requested interface IID_IRowsetLocate\n");
479 return E_NOINTERFACE;
481 else if (IsEqualIID(riid, &IID_IDBAsynchStatus))
483 trace("Requested interface IID_IDBAsynchStatus\n");
484 return E_NOINTERFACE;
486 else if (IsEqualIID(riid, &IID_IAccessor))
488 trace("Requested interface IID_IAccessor\n");
489 return E_NOINTERFACE;
491 else if (IsEqualIID(riid, &UKN_INTERFACE))
493 trace("Unknown interface\n");
494 return E_NOINTERFACE;
497 if(*obj) {
498 IUnknown_AddRef((IUnknown*)*obj);
499 return S_OK;
502 ok(0, "Unsupported interface %s\n", wine_dbgstr_guid(riid));
503 return E_NOINTERFACE;
506 static ULONG WINAPI rowset_AddRef(IRowset *iface)
508 struct test_rowset *rowset = impl_from_IRowset( iface );
509 return InterlockedIncrement( &rowset->refs );
512 static ULONG WINAPI rowset_Release(IRowset *iface)
514 struct test_rowset *rowset = impl_from_IRowset( iface );
515 /* Object not allocated no need to destroy */
516 return InterlockedDecrement( &rowset->refs );
519 static HRESULT WINAPI rowset_AddRefRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
520 DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
522 ok(0, "Unexpected call\n");
523 return E_NOTIMPL;
526 static HRESULT WINAPI rowset_GetData(IRowset *iface, HROW hRow, HACCESSOR hAccessor, void *pData)
528 ok(0, "Unexpected call\n");
529 return E_NOTIMPL;
532 static HRESULT WINAPI rowset_GetNextRows(IRowset *iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
533 DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
535 ok(0, "Unexpected call\n");
536 return E_NOTIMPL;
539 static HRESULT WINAPI rowset_ReleaseRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
540 DBROWOPTIONS rgRowOptions[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
542 ok(0, "Unexpected call\n");
543 return E_NOTIMPL;
546 static HRESULT WINAPI rowset_RestartPosition(IRowset *iface, HCHAPTER hReserved)
548 ok(0, "Unexpected call\n");
549 return E_NOTIMPL;
552 static const struct IRowsetVtbl rowset_vtbl =
554 rowset_QueryInterface,
555 rowset_AddRef,
556 rowset_Release,
557 rowset_AddRefRows,
558 rowset_GetData,
559 rowset_GetNextRows,
560 rowset_ReleaseRows,
561 rowset_RestartPosition
564 static ULONG get_refcount(void *iface)
566 IUnknown *unknown = iface;
567 IUnknown_AddRef(unknown);
568 return IUnknown_Release(unknown);
571 static void test_ADORecordsetConstruction(void)
573 _Recordset *recordset;
574 ADORecordsetConstruction *construct;
575 Fields *fields = NULL;
576 Field *field;
577 struct test_rowset testrowset;
578 IRowset *rowset;
579 HRESULT hr;
580 LONG ref, count;
582 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
583 ok( hr == S_OK, "got %08x\n", hr );
585 hr = _Recordset_QueryInterface( recordset, &IID_ADORecordsetConstruction, (void**)&construct );
586 ok( hr == S_OK, "got %08x\n", hr );
587 if (FAILED(hr))
589 goto done;
592 testrowset.IRowset_iface.lpVtbl = &rowset_vtbl;
593 testrowset.IRowsetInfo_iface.lpVtbl = &rowset_info;
594 testrowset.IColumnsInfo_iface.lpVtbl = &column_info;
595 testrowset.refs = 1;
597 rowset = &testrowset.IRowset_iface;
599 ref = get_refcount( rowset );
600 ok( ref == 1, "got %d\n", ref );
601 hr = ADORecordsetConstruction_put_Rowset( construct, (IUnknown*)rowset );
602 ok( hr == S_OK, "got %08x\n", hr );
604 ref = get_refcount( rowset );
605 ok( ref == 2, "got %d\n", ref );
607 hr = _Recordset_get_Fields( recordset, &fields );
608 ok( hr == S_OK, "got %08x\n", hr );
609 ok( fields != NULL, "NULL value\n");
611 ref = get_refcount( rowset );
612 ok( ref == 2, "got %d\n", ref );
614 count = -1;
615 hr = Fields_get_Count( fields, &count );
616 ok( count == 1, "got %d\n", count );
617 if (count > 0)
619 VARIANT index;
620 LONG size;
621 DataTypeEnum type;
623 V_VT( &index ) = VT_BSTR;
624 V_BSTR( &index ) = SysAllocString( L"Column1" );
626 hr = Fields_get_Item( fields, index, &field );
627 ok( hr == S_OK, "got %08x\n", hr );
629 hr = Field_get_Type( field, &type );
630 ok( hr == S_OK, "got %08x\n", hr );
631 ok( type == adInteger, "got %d\n", type );
632 size = -1;
633 hr = Field_get_DefinedSize( field, &size );
634 ok( hr == S_OK, "got %08x\n", hr );
635 ok( size == 5, "got %d\n", size );
637 VariantClear(&index);
639 Field_Release(field);
642 ref = get_refcount(rowset);
643 ok( ref == 2, "got %d\n", ref );
645 Fields_Release(fields);
647 ADORecordsetConstruction_Release(construct);
649 done:
650 _Recordset_Release( recordset );
653 static void test_Fields(void)
655 _Recordset *recordset;
656 ISupportErrorInfo *errorinfo;
657 Fields *fields;
658 Field *field, *field2;
659 VARIANT val, index;
660 BSTR name;
661 LONG refs, count, size;
662 DataTypeEnum type;
663 FieldAttributeEnum attrs;
664 HRESULT hr;
666 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
667 ok( hr == S_OK, "got %08x\n", hr );
669 hr = _Recordset_get_Fields( recordset, &fields );
670 ok( hr == S_OK, "got %08x\n", hr );
672 /* Fields object supports ISupportErrorInfo */
673 errorinfo = NULL;
674 hr = Fields_QueryInterface( fields, &IID_ISupportErrorInfo, (void **)&errorinfo );
675 ok( hr == S_OK, "got %08x\n", hr );
676 refs = get_refs_fields( fields );
677 ok( refs == 2, "got %d\n", refs );
678 if (errorinfo) ISupportErrorInfo_Release( errorinfo );
679 refs = get_refs_fields( fields );
680 ok( refs == 1, "got %d\n", refs );
682 count = -1;
683 hr = Fields_get_Count( fields, &count );
684 ok( !count, "got %d\n", count );
686 name = SysAllocString( L"field" );
687 V_VT( &val ) = VT_ERROR;
688 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
689 hr = Fields_Append( fields, name, adInteger, 4, adFldUnspecified, val );
690 ok( hr == S_OK, "got %08x\n", hr );
691 SysFreeString( name );
693 count = -1;
694 hr = Fields_get_Count( fields, &count );
695 ok( count == 1, "got %d\n", count );
697 name = SysAllocString( L"field2" );
698 hr = Fields__Append( fields, name, adInteger, 4, adFldUnspecified );
699 ok( hr == S_OK, "got %08x\n", hr );
700 SysFreeString( name );
702 count = -1;
703 hr = Fields_get_Count( fields, &count );
704 ok( count == 2, "got %d\n", count );
706 /* handing out field object doesn't add reference to fields or recordset object */
707 name = SysAllocString( L"field" );
708 V_VT( &index ) = VT_BSTR;
709 V_BSTR( &index ) = name;
710 refs = get_refs_recordset( recordset );
711 ok( refs == 2, "got %d\n", refs );
712 refs = get_refs_fields( fields );
713 ok( refs == 1, "got %d\n", refs );
714 hr = Fields_get_Item( fields, index, &field );
715 ok( hr == S_OK, "got %08x\n", hr );
716 refs = get_refs_field( field );
717 ok( refs == 1, "got %d\n", refs );
718 refs = get_refs_recordset( recordset );
719 ok( refs == 2, "got %d\n", refs );
720 refs = get_refs_fields( fields );
721 ok( refs == 1, "got %d\n", refs );
723 /* calling get_Item again returns the same object and adds reference */
724 hr = Fields_get_Item( fields, index, &field2 );
725 ok( hr == S_OK, "got %08x\n", hr );
726 ok( field2 == field, "expected same object\n" );
727 refs = get_refs_field( field2 );
728 ok( refs == 2, "got %d\n", refs );
729 refs = get_refs_recordset( recordset );
730 ok( refs == 2, "got %d\n", refs );
731 refs = get_refs_fields( fields );
732 ok( refs == 1, "got %d\n", refs );
733 Field_Release( field2 );
734 SysFreeString( name );
736 /* Field object supports ISupportErrorInfo */
737 errorinfo = NULL;
738 hr = Field_QueryInterface( field, &IID_ISupportErrorInfo, (void **)&errorinfo );
739 ok( hr == S_OK, "got %08x\n", hr );
740 refs = get_refs_field( field );
741 ok( refs == 2, "got %d\n", refs );
742 if (errorinfo) ISupportErrorInfo_Release( errorinfo );
743 refs = get_refs_field( field );
744 ok( refs == 1, "got %d\n", refs );
746 /* verify values set with _Append */
747 hr = Field_get_Name( field, &name );
748 ok( hr == S_OK, "got %08x\n", hr );
749 ok( !lstrcmpW( name, L"field" ), "got %s\n", wine_dbgstr_w(name) );
750 SysFreeString( name );
751 type = 0xdead;
752 hr = Field_get_Type( field, &type );
753 ok( hr == S_OK, "got %08x\n", hr );
754 ok( type == adInteger, "got %d\n", type );
755 size = -1;
756 hr = Field_get_DefinedSize( field, &size );
757 ok( hr == S_OK, "got %08x\n", hr );
758 ok( size == 4, "got %d\n", size );
759 attrs = 0xdead;
760 hr = Field_get_Attributes( field, &attrs );
761 ok( hr == S_OK, "got %08x\n", hr );
762 ok( !attrs, "got %d\n", attrs );
764 Field_Release( field );
765 Fields_Release( fields );
766 _Recordset_Release( recordset );
769 static HRESULT str_to_byte_array( const char *data, VARIANT *ret )
771 SAFEARRAY *vector;
772 LONG i, len = strlen(data);
773 HRESULT hr;
775 if (!(vector = SafeArrayCreateVector( VT_UI1, 0, len ))) return E_OUTOFMEMORY;
776 for (i = 0; i < len; i++)
778 if ((hr = SafeArrayPutElement( vector, &i, (void *)&data[i] )) != S_OK)
780 SafeArrayDestroy( vector );
781 return hr;
785 V_VT( ret ) = VT_ARRAY | VT_UI1;
786 V_ARRAY( ret ) = vector;
787 return S_OK;
790 static void test_Stream(void)
792 _Stream *stream;
793 VARIANT_BOOL eos;
794 StreamTypeEnum type;
795 LineSeparatorEnum sep;
796 LONG refs, size, pos;
797 ObjectStateEnum state;
798 ConnectModeEnum mode;
799 BSTR charset, str;
800 VARIANT missing, val;
801 HRESULT hr;
803 hr = CoCreateInstance( &CLSID_Stream, NULL, CLSCTX_INPROC_SERVER, &IID__Stream, (void **)&stream );
804 ok( hr == S_OK, "got %08x\n", hr );
806 hr = _Stream_get_Size( stream, &size );
807 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
809 hr = _Stream_get_EOS( stream, &eos );
810 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
812 hr = _Stream_get_Position( stream, &pos );
813 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
815 hr = _Stream_put_Position( stream, 0 );
816 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
818 /* check default type */
819 type = 0;
820 hr = _Stream_get_Type( stream, &type );
821 ok( hr == S_OK, "got %08x\n", hr );
822 ok( type == adTypeText, "got %u\n", type );
824 hr = _Stream_put_Type( stream, adTypeBinary );
825 ok( hr == S_OK, "got %08x\n", hr );
827 type = 0;
828 hr = _Stream_get_Type( stream, &type );
829 ok( hr == S_OK, "got %08x\n", hr );
830 ok( type == adTypeBinary, "got %u\n", type );
832 /* revert */
833 hr = _Stream_put_Type( stream, adTypeText );
834 ok( hr == S_OK, "got %08x\n", hr );
836 sep = 0;
837 hr = _Stream_get_LineSeparator( stream, &sep );
838 ok( hr == S_OK, "got %08x\n", hr );
839 ok( sep == adCRLF, "got %d\n", sep );
841 hr = _Stream_put_LineSeparator( stream, adLF );
842 ok( hr == S_OK, "got %08x\n", hr );
844 state = 0xdeadbeef;
845 hr = _Stream_get_State( stream, &state );
846 ok( hr == S_OK, "got %08x\n", hr );
847 ok( state == adStateClosed, "got %u\n", state );
849 mode = 0xdeadbeef;
850 hr = _Stream_get_Mode( stream, &mode );
851 ok( hr == S_OK, "got %08x\n", hr );
852 ok( mode == adModeUnknown, "got %u\n", mode );
854 hr = _Stream_put_Mode( stream, adModeReadWrite );
855 ok( hr == S_OK, "got %08x\n", hr );
857 hr = _Stream_get_Charset( stream, &charset );
858 ok( hr == S_OK, "got %08x\n", hr );
859 ok( !lstrcmpW( charset, L"Unicode" ), "got %s\n", wine_dbgstr_w(charset) );
860 SysFreeString( charset );
862 str = SysAllocString( L"Unicode" );
863 hr = _Stream_put_Charset( stream, str );
864 ok( hr == S_OK, "got %08x\n", hr );
865 SysFreeString( str );
867 hr = _Stream_Read( stream, 2, &val );
868 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
870 V_VT( &missing ) = VT_ERROR;
871 V_ERROR( &missing ) = DISP_E_PARAMNOTFOUND;
872 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
873 ok( hr == S_OK, "got %08x\n", hr );
875 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
876 ok( hr == MAKE_ADO_HRESULT( adErrObjectOpen ), "got %08x\n", hr );
878 state = 0xdeadbeef;
879 hr = _Stream_get_State( stream, &state );
880 ok( hr == S_OK, "got %08x\n", hr );
881 ok( state == adStateOpen, "got %u\n", state );
883 size = -1;
884 hr = _Stream_get_Size( stream, &size );
885 ok( hr == S_OK, "got %08x\n", hr );
886 ok( !size, "got %d\n", size );
888 eos = VARIANT_FALSE;
889 hr = _Stream_get_EOS( stream, &eos );
890 ok( hr == S_OK, "got %08x\n", hr );
891 ok( eos == VARIANT_TRUE, "got %04x\n", eos );
893 pos = -1;
894 hr = _Stream_get_Position( stream, &pos );
895 ok( hr == S_OK, "got %08x\n", hr );
896 ok( !pos, "got %d\n", pos );
898 size = -1;
899 hr = _Stream_get_Size( stream, &size );
900 ok( hr == S_OK, "got %08x\n", hr );
901 ok( !size, "got %d\n", size );
903 hr = _Stream_Read( stream, 2, &val );
904 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08x\n", hr );
906 hr = _Stream_ReadText( stream, 2, &str );
907 ok( hr == S_OK, "got %08x\n", hr );
908 ok( !str[0], "got %s\n", wine_dbgstr_w(str) );
909 SysFreeString( str );
911 pos = -1;
912 hr = _Stream_get_Position( stream, &pos );
913 ok( hr == S_OK, "got %08x\n", hr );
914 ok( !pos, "got %d\n", pos );
916 str = SysAllocString( L"test" );
917 hr = _Stream_WriteText( stream, str, adWriteChar );
918 ok( hr == S_OK, "got %08x\n", hr );
919 SysFreeString( str );
921 hr = _Stream_ReadText( stream, adReadAll, &str );
922 ok( hr == S_OK, "got %08x\n", hr );
923 ok( !str[0], "got %s\n", wine_dbgstr_w(str) );
924 SysFreeString( str );
926 hr = _Stream_put_Position( stream, 0 );
927 ok( hr == S_OK, "got %08x\n", hr );
928 hr = _Stream_ReadText( stream, adReadAll, &str );
929 ok( hr == S_OK, "got %08x\n", hr );
930 ok( !lstrcmpW( str, L"test" ), "got %s\n", wine_dbgstr_w(str) );
931 SysFreeString( str );
933 pos = -1;
934 hr = _Stream_get_Position( stream, &pos );
935 ok( hr == S_OK, "got %08x\n", hr );
936 ok( pos == 10, "got %d\n", pos );
938 eos = VARIANT_FALSE;
939 hr = _Stream_get_EOS( stream, &eos );
940 ok( hr == S_OK, "got %08x\n", hr );
941 ok( eos == VARIANT_TRUE, "got %04x\n", eos );
943 hr = _Stream_put_Position( stream, 6 );
944 ok( hr == S_OK, "got %08x\n", hr );
946 size = -1;
947 hr = _Stream_get_Size( stream, &size );
948 ok( hr == S_OK, "got %08x\n", hr );
949 ok( size == 10, "got %d\n", size );
951 hr = _Stream_put_Position( stream, 2 );
952 ok( hr == S_OK, "got %08x\n", hr );
954 hr = _Stream_SetEOS( stream );
955 ok( hr == S_OK, "got %08x\n", hr );
957 pos = -1;
958 hr = _Stream_get_Position( stream, &pos );
959 ok( hr == S_OK, "got %08x\n", hr );
960 ok( pos == 2, "got %d\n", pos );
962 size = -1;
963 hr = _Stream_get_Size( stream, &size );
964 ok( hr == S_OK, "got %08x\n", hr );
965 ok( size == 2, "got %d\n", size );
967 hr = _Stream_Close( stream );
968 ok( hr == S_OK, "got %08x\n", hr );
970 state = 0xdeadbeef;
971 hr = _Stream_get_State( stream, &state );
972 ok( hr == S_OK, "got %08x\n", hr );
973 ok( state == adStateClosed, "got %u\n", state );
975 hr = _Stream_Close( stream );
976 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
978 refs = _Stream_Release( stream );
979 ok( !refs, "got %d\n", refs );
981 /* binary type */
982 hr = CoCreateInstance( &CLSID_Stream, NULL, CLSCTX_INPROC_SERVER, &IID__Stream, (void **)&stream );
983 ok( hr == S_OK, "got %08x\n", hr );
985 hr = _Stream_put_Type( stream, adTypeBinary );
986 ok( hr == S_OK, "got %08x\n", hr );
988 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
989 ok( hr == S_OK, "got %08x\n", hr );
991 hr = _Stream_ReadText( stream, adReadAll, &str );
992 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08x\n", hr );
994 str = SysAllocString( L"test" );
995 hr = _Stream_WriteText( stream, str, adWriteChar );
996 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08x\n", hr );
997 SysFreeString( str );
999 VariantInit( &val );
1000 hr = _Stream_Read( stream, 1, &val );
1001 ok( hr == S_OK, "got %08x\n", hr );
1002 ok( V_VT( &val ) == VT_NULL, "got %u\n", V_VT( &val ) );
1004 VariantInit( &val );
1005 hr = _Stream_Write( stream, val );
1006 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08x\n", hr );
1008 hr = str_to_byte_array( "data", &val );
1009 ok( hr == S_OK, "got %08x\n", hr );
1010 hr = _Stream_Write( stream, val );
1011 ok( hr == S_OK, "got %08x\n", hr );
1012 VariantClear( &val );
1014 pos = -1;
1015 hr = _Stream_get_Position( stream, &pos );
1016 ok( hr == S_OK, "got %08x\n", hr );
1017 ok( pos == 4, "got %d\n", pos );
1019 hr = _Stream_put_Position( stream, 0 );
1020 ok( hr == S_OK, "got %08x\n", hr );
1022 VariantInit( &val );
1023 hr = _Stream_Read( stream, adReadAll, &val );
1024 ok( hr == S_OK, "got %08x\n", hr );
1025 ok( V_VT( &val ) == (VT_ARRAY | VT_UI1), "got %04x\n", V_VT( &val ) );
1026 VariantClear( &val );
1028 pos = -1;
1029 hr = _Stream_get_Position( stream, &pos );
1030 ok( hr == S_OK, "got %08x\n", hr );
1031 ok( pos == 4, "got %d\n", pos );
1033 refs = _Stream_Release( stream );
1034 ok( !refs, "got %d\n", refs );
1037 static void test_Connection(void)
1039 HRESULT hr;
1040 _Connection *connection;
1041 IRunnableObject *runtime;
1042 ISupportErrorInfo *errorinfo;
1043 IConnectionPointContainer *pointcontainer;
1044 ADOConnectionConstruction15 *construct;
1045 LONG state, timeout;
1046 BSTR str, str2, str3;
1047 ConnectModeEnum mode;
1048 CursorLocationEnum location;
1050 hr = CoCreateInstance(&CLSID_Connection, NULL, CLSCTX_INPROC_SERVER, &IID__Connection, (void**)&connection);
1051 ok( hr == S_OK, "got %08x\n", hr );
1053 hr = _Connection_QueryInterface(connection, &IID_IRunnableObject, (void**)&runtime);
1054 ok(hr == E_NOINTERFACE, "Unexpected IRunnableObject interface\n");
1055 ok(runtime == NULL, "expected NULL\n");
1057 hr = _Connection_QueryInterface(connection, &IID_ISupportErrorInfo, (void**)&errorinfo);
1058 ok(hr == S_OK, "Failed to get ISupportErrorInfo interface\n");
1059 ISupportErrorInfo_Release(errorinfo);
1061 hr = _Connection_QueryInterface(connection, &IID_IConnectionPointContainer, (void**)&pointcontainer);
1062 ok(hr == S_OK, "Failed to get IConnectionPointContainer interface %08x\n", hr);
1063 IConnectionPointContainer_Release(pointcontainer);
1065 hr = _Connection_QueryInterface(connection, &IID_ADOConnectionConstruction15, (void**)&construct);
1066 ok(hr == S_OK, "Failed to get ADOConnectionConstruction15 interface %08x\n", hr);
1067 if (hr == S_OK)
1068 ADOConnectionConstruction15_Release(construct);
1070 if (0) /* Crashes on windows */
1072 hr = _Connection_get_State(connection, NULL);
1073 ok(hr == E_INVALIDARG, "Unexpected hr 0x%08x\n", hr);
1076 state = -1;
1077 hr = _Connection_get_State(connection, &state);
1078 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1079 ok(state == adStateClosed, "Unexpected state value 0x%08x\n", state);
1081 hr = _Connection_Close(connection);
1082 ok(hr == MAKE_ADO_HRESULT(adErrObjectClosed), "got %08x\n", hr);
1084 timeout = 0;
1085 hr = _Connection_get_CommandTimeout(connection, &timeout);
1086 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1087 ok(timeout == 30, "Unexpected timeout value %d\n", timeout);
1089 hr = _Connection_put_CommandTimeout(connection, 300);
1090 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1092 timeout = 0;
1093 hr = _Connection_get_CommandTimeout(connection, &timeout);
1094 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1095 ok(timeout == 300, "Unexpected timeout value %d\n", timeout);
1097 location = 0;
1098 hr = _Connection_get_CursorLocation(connection, &location);
1099 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1100 ok(location == adUseServer, "Unexpected location value %d\n", location);
1102 hr = _Connection_put_CursorLocation(connection, adUseClient);
1103 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1105 location = 0;
1106 hr = _Connection_get_CursorLocation(connection, &location);
1107 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1108 ok(location == adUseClient, "Unexpected location value %d\n", location);
1110 hr = _Connection_put_CursorLocation(connection, adUseServer);
1111 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1113 mode = 0xdeadbeef;
1114 hr = _Connection_get_Mode(connection, &mode);
1115 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1116 ok(mode == adModeUnknown, "Unexpected mode value %d\n", mode);
1118 hr = _Connection_put_Mode(connection, adModeShareDenyNone);
1119 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1121 mode = adModeUnknown;
1122 hr = _Connection_get_Mode(connection, &mode);
1123 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1124 ok(mode == adModeShareDenyNone, "Unexpected mode value %d\n", mode);
1126 hr = _Connection_put_Mode(connection, adModeUnknown);
1127 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1129 /* Default */
1130 str = (BSTR)0xdeadbeef;
1131 hr = _Connection_get_Provider(connection, &str);
1132 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1133 ok(!wcscmp(str, L"MSDASQL"), "wrong string %s\n", wine_dbgstr_w(str));
1134 SysFreeString(str);
1136 str = SysAllocString(L"MSDASQL.1");
1137 hr = _Connection_put_Provider(connection, str);
1138 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1139 SysFreeString(str);
1141 str = (BSTR)0xdeadbeef;
1142 hr = _Connection_get_Provider(connection, &str);
1143 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1144 ok(!wcscmp(str, L"MSDASQL.1"), "wrong string %s\n", wine_dbgstr_w(str));
1146 /* Restore default */
1147 str = SysAllocString(L"MSDASQL");
1148 hr = _Connection_put_Provider(connection, str);
1149 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1150 SysFreeString(str);
1152 hr = _Connection_put_Provider(connection, NULL);
1153 ok(hr == MAKE_ADO_HRESULT(adErrInvalidArgument), "got 0x%08x\n", hr);
1154 SysFreeString(str);
1156 str = (BSTR)0xdeadbeef;
1157 hr = _Connection_get_ConnectionString(connection, &str);
1158 ok(hr == S_OK, "got 0x%08x\n", hr);
1159 ok(str == NULL, "got %p\n", str);
1161 str = SysAllocString(L"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_test");
1162 hr = _Connection_put_ConnectionString(connection, str);
1163 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1165 /* Show put_ConnectionString effects Provider */
1166 str3 = (BSTR)0xdeadbeef;
1167 hr = _Connection_get_Provider(connection, &str3);
1168 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1169 ok(str3 != NULL, "Expected value got NULL\n");
1170 todo_wine ok(!wcscmp(str3, L"MSDASQL.1"), "wrong string %s\n", wine_dbgstr_w(str3));
1171 SysFreeString(str3);
1173 if (0) /* Crashes on windows */
1175 hr = _Connection_get_ConnectionString(connection, NULL);
1176 ok(hr == E_POINTER, "Failed, hr 0x%08x\n", hr);
1179 str2 = NULL;
1180 hr = _Connection_get_ConnectionString(connection, &str2);
1181 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1182 ok(!wcscmp(str, str2), "wrong string %s\n", wine_dbgstr_w(str2));
1184 hr = _Connection_Open(connection, NULL, NULL, NULL, 0);
1185 ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr);
1187 /* Open adds trailing ; if it's missing */
1188 str3 = SysAllocString(L"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_test;");
1189 hr = _Connection_Open(connection, NULL, NULL, NULL, adConnectUnspecified);
1190 ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr);
1192 str2 = NULL;
1193 hr = _Connection_get_ConnectionString(connection, &str2);
1194 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1195 todo_wine ok(!wcscmp(str3, str2) || broken(!wcscmp(str, str2)) /* XP */, "wrong string %s\n", wine_dbgstr_w(str2));
1197 hr = _Connection_Open(connection, str, NULL, NULL, adConnectUnspecified);
1198 todo_wine ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr);
1199 SysFreeString(str);
1201 str2 = NULL;
1202 hr = _Connection_get_ConnectionString(connection, &str2);
1203 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1204 todo_wine ok(!wcscmp(str3, str2) || broken(!wcscmp(str, str2)) /* XP */, "wrong string %s\n", wine_dbgstr_w(str2));
1205 SysFreeString(str2);
1206 SysFreeString(str3);
1208 hr = _Connection_put_ConnectionString(connection, NULL);
1209 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1211 str = (BSTR)0xdeadbeef;
1212 hr = _Connection_get_ConnectionString(connection, &str);
1213 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1214 ok(str == NULL, "got %p\n", str);
1215 _Connection_Release(connection);
1218 static void test_Command(void)
1220 HRESULT hr;
1221 _Command *command;
1222 _ADO *ado;
1223 Command15 *command15;
1224 Command25 *command25;
1225 CommandTypeEnum cmd_type = adCmdUnspecified;
1226 BSTR cmd_text = (BSTR)"test";
1227 _Connection *connection;
1229 hr = CoCreateInstance( &CLSID_Command, NULL, CLSCTX_INPROC_SERVER, &IID__Command, (void **)&command );
1230 ok( hr == S_OK, "got %08x\n", hr );
1232 hr = _Command_QueryInterface( command, &IID__ADO, (void **)&ado );
1233 ok( hr == S_OK, "got %08x\n", hr );
1234 _ADO_Release( ado );
1236 hr = _Command_QueryInterface( command, &IID_Command15, (void **)&command15 );
1237 ok( hr == S_OK, "got %08x\n", hr );
1238 Command15_Release( command15 );
1240 hr = _Command_QueryInterface( command, &IID_Command25, (void **)&command25 );
1241 ok( hr == S_OK, "got %08x\n", hr );
1242 Command25_Release( command25 );
1244 hr = _Command_get_CommandType( command, &cmd_type );
1245 ok( hr == S_OK, "got %08x\n", hr );
1246 ok( cmd_type == adCmdUnknown, "got %08x\n", cmd_type );
1248 _Command_put_CommandType( command, adCmdText );
1249 hr = _Command_get_CommandType( command, &cmd_type );
1250 ok( hr == S_OK, "got %08x\n", hr );
1251 ok( cmd_type == adCmdText, "got %08x\n", cmd_type );
1253 hr = _Command_put_CommandType( command, 0xdeadbeef );
1254 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08x\n", hr );
1256 hr = _Command_get_CommandText( command, &cmd_text );
1257 ok( hr == S_OK, "got %08x\n", hr );
1258 ok( !cmd_text, "got %s\n", wine_dbgstr_w( cmd_text ));
1260 hr = _Command_put_CommandText( command, NULL );
1261 ok( hr == S_OK, "got %08x\n", hr );
1263 cmd_text = SysAllocString( L"" );
1264 hr = _Command_put_CommandText( command, cmd_text );
1265 ok( hr == S_OK, "got %08x\n", hr );
1266 SysFreeString( cmd_text );
1268 hr = _Command_get_CommandText( command, &cmd_text );
1269 ok( hr == S_OK, "got %08x\n", hr );
1270 ok( cmd_text && !*cmd_text, "got %p\n", cmd_text );
1272 cmd_text = SysAllocString( L"test" );
1273 hr = _Command_put_CommandText( command, cmd_text );
1274 ok( hr == S_OK, "got %08x\n", hr );
1275 SysFreeString( cmd_text );
1277 hr = _Command_get_CommandText( command, &cmd_text );
1278 ok( hr == S_OK, "got %08x\n", hr );
1279 ok( !wcscmp( L"test", cmd_text ), "got %p\n", wine_dbgstr_w( cmd_text ) );
1281 connection = (_Connection*)0xdeadbeef;
1282 hr = _Command_get_ActiveConnection( command, &connection );
1283 ok( hr == S_OK, "got %08x\n", hr );
1284 ok( connection == NULL, "got %p\n", connection );
1286 hr = _Command_putref_ActiveConnection( command, NULL );
1287 ok( hr == S_OK, "got %08x\n", hr );
1289 _Command_Release( command );
1292 struct conn_event {
1293 ConnectionEventsVt conn_event_sink;
1294 LONG refs;
1297 static HRESULT WINAPI conneventvt_QueryInterface( ConnectionEventsVt *iface, REFIID riid, void **obj )
1299 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
1301 if (IsEqualGUID( &IID_ConnectionEventsVt, riid ))
1303 InterlockedIncrement( &conn_event->refs );
1304 *obj = iface;
1305 return S_OK;
1308 ok( 0, "unexpected call\n" );
1309 return E_NOINTERFACE;
1312 static ULONG WINAPI conneventvt_AddRef( ConnectionEventsVt *iface )
1314 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
1315 return InterlockedIncrement( &conn_event->refs );
1318 static ULONG WINAPI conneventvt_Release( ConnectionEventsVt *iface )
1320 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
1321 return InterlockedDecrement( &conn_event->refs );
1324 static HRESULT WINAPI conneventvt_InfoMessage( ConnectionEventsVt *iface, Error *error,
1325 EventStatusEnum *status, _Connection *Connection )
1327 return E_NOTIMPL;
1330 static HRESULT WINAPI conneventvt_BeginTransComplete( ConnectionEventsVt *iface, LONG TransactionLevel,
1331 Error *error, EventStatusEnum *status, _Connection *connection )
1333 return E_NOTIMPL;
1336 static HRESULT WINAPI conneventvt_CommitTransComplete( ConnectionEventsVt *iface, Error *error,
1337 EventStatusEnum *status, _Connection *connection )
1339 return E_NOTIMPL;
1342 static HRESULT WINAPI conneventvt_RollbackTransComplete( ConnectionEventsVt *iface, Error *error,
1343 EventStatusEnum *status, _Connection *connection )
1345 return E_NOTIMPL;
1348 static HRESULT WINAPI conneventvt_WillExecute( ConnectionEventsVt *iface, BSTR *source,
1349 CursorTypeEnum *cursor_type, LockTypeEnum *lock_type, LONG *options, EventStatusEnum *status,
1350 _Command *command, _Recordset *record_set, _Connection *connection )
1352 return E_NOTIMPL;
1355 static HRESULT WINAPI conneventvt_ExecuteComplete( ConnectionEventsVt *iface, LONG records_affected,
1356 Error *error, EventStatusEnum *status, _Command *command, _Recordset *record_set,
1357 _Connection *connection )
1359 return E_NOTIMPL;
1362 static HRESULT WINAPI conneventvt_WillConnect( ConnectionEventsVt *iface, BSTR *string, BSTR *userid,
1363 BSTR *password, LONG *options, EventStatusEnum *status, _Connection *connection )
1365 return E_NOTIMPL;
1368 static HRESULT WINAPI conneventvt_ConnectComplete( ConnectionEventsVt *iface, Error *error,
1369 EventStatusEnum *status, _Connection *connection )
1371 return E_NOTIMPL;
1374 static HRESULT WINAPI conneventvt_Disconnect( ConnectionEventsVt *iface, EventStatusEnum *status,
1375 _Connection *connection )
1377 return E_NOTIMPL;
1380 static const ConnectionEventsVtVtbl conneventvt_vtbl = {
1381 conneventvt_QueryInterface,
1382 conneventvt_AddRef,
1383 conneventvt_Release,
1384 conneventvt_InfoMessage,
1385 conneventvt_BeginTransComplete,
1386 conneventvt_CommitTransComplete,
1387 conneventvt_RollbackTransComplete,
1388 conneventvt_WillExecute,
1389 conneventvt_ExecuteComplete,
1390 conneventvt_WillConnect,
1391 conneventvt_ConnectComplete,
1392 conneventvt_Disconnect
1395 static HRESULT WINAPI supporterror_QueryInterface( ISupportErrorInfo *iface, REFIID riid, void **obj )
1397 if (IsEqualGUID( &IID_ISupportErrorInfo, riid ))
1399 *obj = iface;
1400 return S_OK;
1403 return E_NOINTERFACE;
1406 static ULONG WINAPI supporterror_AddRef( ISupportErrorInfo *iface )
1408 return 2;
1411 static ULONG WINAPI supporterror_Release( ISupportErrorInfo *iface )
1413 return 1;
1416 static HRESULT WINAPI supporterror_InterfaceSupportsErrorInfo( ISupportErrorInfo *iface, REFIID riid )
1418 return E_NOTIMPL;
1421 static const struct ISupportErrorInfoVtbl support_error_vtbl =
1423 supporterror_QueryInterface,
1424 supporterror_AddRef,
1425 supporterror_Release,
1426 supporterror_InterfaceSupportsErrorInfo
1429 static void test_ConnectionPoint(void)
1431 HRESULT hr;
1432 ULONG refs;
1433 DWORD cookie;
1434 IConnectionPoint *point;
1435 IConnectionPointContainer *pointcontainer;
1436 struct conn_event conn_event = { { &conneventvt_vtbl }, 0 };
1437 ISupportErrorInfo support_err_sink = { &support_error_vtbl };
1439 hr = CoCreateInstance( &CLSID_Connection, NULL, CLSCTX_INPROC_SERVER,
1440 &IID_IConnectionPointContainer, (void**)&pointcontainer );
1442 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_ConnectionEvents, NULL );
1443 ok( hr == E_POINTER, "got %08x\n", hr );
1445 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_RecordsetEvents, &point );
1446 ok( hr == CONNECT_E_NOCONNECTION, "got %08x\n", hr );
1448 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_ConnectionEvents, &point );
1449 ok( hr == S_OK, "got %08x\n", hr );
1451 /* nothing advised yet */
1452 hr = IConnectionPoint_Unadvise( point, 3 );
1453 ok( hr == E_FAIL, "got %08x\n", hr );
1455 hr = IConnectionPoint_Advise( point, NULL, NULL );
1456 ok( hr == E_FAIL, "got %08x\n", hr );
1458 hr = IConnectionPoint_Advise( point, (void*)&conn_event.conn_event_sink, NULL );
1459 ok( hr == E_FAIL, "got %08x\n", hr );
1461 cookie = 0xdeadbeef;
1462 hr = IConnectionPoint_Advise( point, NULL, &cookie );
1463 ok( hr == E_FAIL, "got %08x\n", hr );
1464 ok( cookie == 0xdeadbeef, "got %08x\n", cookie );
1466 /* unsupported sink */
1467 cookie = 0xdeadbeef;
1468 hr = IConnectionPoint_Advise( point, (void*)&support_err_sink, &cookie );
1469 ok( hr == E_FAIL, "got %08x\n", hr );
1470 ok( !cookie, "got %08x\n", cookie );
1472 cookie = 0;
1473 hr = IConnectionPoint_Advise( point, (void*)&conn_event.conn_event_sink, &cookie );
1474 ok( hr == S_OK, "got %08x\n", hr );
1475 ok( cookie, "got %08x\n", cookie );
1477 /* invalid cookie */
1478 hr = IConnectionPoint_Unadvise( point, 0 );
1479 ok( hr == E_FAIL, "got %08x\n", hr );
1481 /* wrong cookie */
1482 hr = IConnectionPoint_Unadvise( point, cookie + 1 );
1483 ok( hr == E_FAIL, "got %08x\n", hr );
1485 hr = IConnectionPoint_Unadvise( point, cookie );
1486 ok( hr == S_OK, "got %08x\n", hr );
1488 /* sinks are released when the connection is destroyed */
1489 cookie = 0;
1490 hr = IConnectionPoint_Advise( point, (void*)&conn_event.conn_event_sink, &cookie );
1491 ok( hr == S_OK, "got %08x\n", hr );
1492 ok( cookie, "got %08x\n", cookie );
1493 ok( conn_event.refs == 1, "got %d\n", conn_event.refs );
1495 refs = IConnectionPoint_Release( point );
1496 ok( refs == 1, "got %u", refs );
1498 IConnectionPointContainer_Release( pointcontainer );
1500 ok( !conn_event.refs, "got %d\n", conn_event.refs );
1503 START_TEST(msado15)
1505 CoInitialize( NULL );
1506 test_Connection();
1507 test_ADORecordsetConstruction();
1508 test_ConnectionPoint();
1509 test_Fields();
1510 test_Recordset();
1511 test_Stream();
1512 test_Command();
1513 CoUninitialize();