msado15: Support VT_I4/I2 for Fields Item property.
[wine.git] / dlls / msado15 / tests / msado15.c
blob860144338c01924977f4f88c2b684dd93c0acf1d
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 VARIANT missing, val, index;
57 CursorLocationEnum location;
58 CursorTypeEnum cursor;
59 BSTR name;
60 HRESULT hr;
61 VARIANT bookmark;
63 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
64 ok( hr == S_OK, "got %08x\n", hr );
66 hr = _Recordset_QueryInterface( recordset, &IID_IRunnableObject, (void**)&runtime);
67 ok(hr == E_NOINTERFACE, "Unexpected IRunnableObject interface\n");
68 ok(runtime == NULL, "expected NULL\n");
70 /* _Recordset object supports ISupportErrorInfo */
71 errorinfo = NULL;
72 hr = _Recordset_QueryInterface( recordset, &IID_ISupportErrorInfo, (void **)&errorinfo );
73 ok( hr == S_OK, "got %08x\n", hr );
74 if (errorinfo) ISupportErrorInfo_Release( errorinfo );
76 hr = _Recordset_get_Fields( recordset, &fields );
77 ok( hr == S_OK, "got %08x\n", hr );
79 /* calling get_Fields again returns the same object */
80 hr = _Recordset_get_Fields( recordset, &fields2 );
81 ok( hr == S_OK, "got %08x\n", hr );
82 ok( fields2 == fields, "expected same object\n" );
84 count = -1;
85 hr = Fields_get_Count( fields2, &count );
86 ok( hr == S_OK, "got %08x\n", hr );
87 ok( !count, "got %d\n", count );
89 hr = _Recordset_Close( recordset );
90 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
92 Fields_Release( fields2 );
94 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
95 ok( hr == S_OK, "got %08x\n", hr );
97 state = -1;
98 hr = _Recordset_get_State( recordset, &state );
99 ok( hr == S_OK, "got %08x\n", hr );
100 ok( state == adStateClosed, "got %d\n", state );
102 location = -1;
103 hr = _Recordset_get_CursorLocation( recordset, &location );
104 ok( hr == S_OK, "got %08x\n", hr );
105 ok( location == adUseServer, "got %d\n", location );
107 cursor = adOpenUnspecified;
108 hr = _Recordset_get_CursorType( recordset, &cursor );
109 ok( hr == S_OK, "got %08x\n", hr );
110 ok( cursor == adOpenForwardOnly, "got %d\n", cursor );
112 VariantInit( &bookmark );
113 hr = _Recordset_get_Bookmark( recordset, &bookmark );
114 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
116 VariantInit( &bookmark );
117 hr = _Recordset_put_Bookmark( recordset, bookmark );
118 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
120 VariantInit( &missing );
121 hr = _Recordset_AddNew( recordset, missing, missing );
122 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
124 V_VT( &missing ) = VT_ERROR;
125 V_ERROR( &missing ) = DISP_E_PARAMNOTFOUND;
126 hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified );
127 ok( hr == MAKE_ADO_HRESULT( adErrInvalidConnection ), "got %08x\n", hr );
129 hr = _Recordset_get_Fields( recordset, &fields );
130 ok( hr == S_OK, "got %08x\n", hr );
132 name = SysAllocString( L"field" );
133 hr = Fields__Append( fields, name, adInteger, 4, adFldUnspecified );
134 ok( hr == S_OK, "got %08x\n", hr );
136 V_VT( &index ) = VT_I4;
137 V_I4( &index ) = 1000;
138 hr = Fields_get_Item( fields, index, &field );
139 ok( hr == MAKE_ADO_HRESULT(adErrItemNotFound), "got %08x\n", hr );
141 V_VT( &index ) = VT_I4;
142 V_I4( &index ) = 0;
143 hr = Fields_get_Item( fields, index, &field );
144 ok( hr == S_OK, "got %08x\n", hr );
145 Field_Release(field);
147 V_VT( &index ) = VT_I2;
148 V_I4( &index ) = 0;
149 hr = Fields_get_Item( fields, index, &field );
150 ok( hr == S_OK, "got %08x\n", hr );
151 Field_Release(field);
153 V_VT( &index ) = VT_BSTR;
154 V_BSTR( &index ) = name;
155 hr = Fields_get_Item( fields, index, &field );
156 ok( hr == S_OK, "got %08x\n", hr );
157 SysFreeString( name );
159 hr = Field_QueryInterface(field, &IID_Properties, (void**)&props);
160 ok( hr == E_NOINTERFACE, "got %08x\n", hr );
162 hr = Field_get_Properties(field, &props);
163 ok( hr == S_OK, "got %08x\n", hr );
165 count = -1;
166 hr = Properties_get_Count(props, &count);
167 ok( hr == S_OK, "got %08x\n", hr );
168 ok( !count, "got %d\n", count );
170 V_VT( &index ) = VT_I4;
171 V_I4( &index ) = 1000;
172 hr = Properties_get_Item(props, index, &prop);
173 ok( hr == MAKE_ADO_HRESULT(adErrItemNotFound), "got %08x\n", hr );
175 Properties_Release(props);
177 hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified );
178 ok( hr == S_OK, "got %08x\n", hr );
179 ok( is_eof( recordset ), "not eof\n" );
180 ok( is_bof( recordset ), "not bof\n" );
182 hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified );
183 ok( hr == MAKE_ADO_HRESULT( adErrObjectOpen ), "got %08x\n", hr );
185 state = -1;
186 hr = _Recordset_get_State( recordset, &state );
187 ok( hr == S_OK, "got %08x\n", hr );
188 ok( state == adStateOpen, "got %d\n", state );
190 VariantInit( &bookmark );
191 hr = _Recordset_get_Bookmark( recordset, &bookmark );
192 ok( hr == MAKE_ADO_HRESULT( adErrNoCurrentRecord ), "got %08x\n", hr );
194 VariantInit( &bookmark );
195 hr = _Recordset_put_Bookmark( recordset, bookmark );
196 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08x\n", hr );
198 count = -1;
199 hr = _Recordset_get_RecordCount( recordset, &count );
200 ok( hr == S_OK, "got %08x\n", hr );
201 ok( !count, "got %d\n", count );
203 hr = _Recordset_AddNew( recordset, missing, missing );
204 ok( hr == S_OK, "got %08x\n", hr );
205 ok( !is_eof( recordset ), "eof\n" );
206 ok( !is_bof( recordset ), "bof\n" );
208 count = -1;
209 hr = _Recordset_get_RecordCount( recordset, &count );
210 ok( hr == S_OK, "got %08x\n", hr );
211 ok( count == 1, "got %d\n", count );
213 /* get_Fields still returns the same object */
214 hr = _Recordset_get_Fields( recordset, &fields2 );
215 ok( hr == S_OK, "got %08x\n", hr );
216 ok( fields2 == fields, "expected same object\n" );
217 Fields_Release( fields2 );
219 count = -1;
220 hr = Fields_get_Count( fields2, &count );
221 ok( count == 1, "got %d\n", count );
223 hr = Field_get_Value( field, &val );
224 ok( hr == S_OK, "got %08x\n", hr );
225 ok( V_VT( &val ) == VT_EMPTY, "got %u\n", V_VT( &val ) );
227 V_VT( &val ) = VT_I4;
228 V_I4( &val ) = -1;
229 hr = Field_put_Value( field, val );
230 ok( hr == S_OK, "got %08x\n", hr );
232 V_VT( &val ) = VT_ERROR;
233 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
234 hr = Field_get_Value( field, &val );
235 ok( hr == S_OK, "got %08x\n", hr );
236 ok( V_VT( &val ) == VT_I4, "got %u\n", V_VT( &val ) );
237 ok( V_I4( &val ) == -1, "got %d\n", V_I4( &val ) );
239 hr = _Recordset_AddNew( recordset, missing, missing );
240 ok( hr == S_OK, "got %08x\n", hr );
242 /* field object returns different value after AddNew */
243 V_VT( &val ) = VT_ERROR;
244 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
245 hr = Field_get_Value( field, &val );
246 ok( hr == S_OK, "got %08x\n", hr );
247 ok( V_VT( &val ) == VT_EMPTY, "got %u\n", V_VT( &val ) );
249 ok( !is_eof( recordset ), "eof\n" );
250 ok( !is_bof( recordset ), "bof\n" );
251 hr = _Recordset_MoveFirst( recordset );
252 ok( hr == S_OK, "got %08x\n", hr );
253 ok( !is_eof( recordset ), "eof\n" );
254 ok( !is_bof( recordset ), "bof\n" );
256 V_VT( &val ) = VT_ERROR;
257 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
258 hr = Field_get_Value( field, &val );
259 ok( hr == S_OK, "got %08x\n", hr );
260 ok( V_VT( &val ) == VT_I4, "got %u\n", V_VT( &val ) );
261 ok( V_I4( &val ) == -1, "got %d\n", V_I4( &val ) );
263 hr = _Recordset_MoveNext( recordset );
264 ok( hr == S_OK, "got %08x\n", hr );
265 ok( !is_eof( recordset ), "eof\n" );
266 ok( !is_bof( recordset ), "not bof\n" );
268 hr = _Recordset_MoveNext( recordset );
269 ok( hr == S_OK, "got %08x\n", hr );
270 ok( is_eof( recordset ), "not eof\n" );
271 ok( !is_bof( recordset ), "bof\n" );
273 hr = _Recordset_MoveFirst( recordset );
274 ok( hr == S_OK, "got %08x\n", hr );
275 ok( !is_eof( recordset ), "eof\n" );
276 ok( !is_bof( recordset ), "bof\n" );
278 hr = _Recordset_MovePrevious( recordset );
279 ok( hr == S_OK, "got %08x\n", hr );
280 ok( !is_eof( recordset ), "eof\n" );
281 ok( is_bof( recordset ), "not bof\n" );
283 /* try get value at BOF */
284 VariantInit( &val );
285 hr = Field_get_Value( field, &val );
286 ok( hr == MAKE_ADO_HRESULT( adErrNoCurrentRecord ), "got %08x\n", hr );
288 hr = _Recordset_Close( recordset );
289 ok( hr == S_OK, "got %08x\n", hr );
291 count = -1;
292 hr = Fields_get_Count( fields, &count );
293 ok( !count, "got %d\n", count );
295 hr = Field_get_Name(field, &name);
296 todo_wine ok( hr == MAKE_ADO_HRESULT( adErrObjectNotSet ), "got %08x\n", hr );
298 state = -1;
299 hr = _Recordset_get_State( recordset, &state );
300 ok( hr == S_OK, "got %08x\n", hr );
301 ok( state == adStateClosed, "got %d\n", state );
303 Field_Release( field );
304 Fields_Release( fields );
305 _Recordset_Release( recordset );
308 /* This interface is queried for but is not documented anywhere. */
309 DEFINE_GUID(UKN_INTERFACE, 0x6f1e39e1, 0x05c6, 0x11d0, 0xa7, 0x8b, 0x00, 0xaa, 0x00, 0xa3, 0xf0, 0x0d);
311 struct test_rowset
313 IRowset IRowset_iface;
314 IRowsetInfo IRowsetInfo_iface;
315 IColumnsInfo IColumnsInfo_iface;
316 LONG refs;
319 static inline struct test_rowset *impl_from_IRowset( IRowset *iface )
321 return CONTAINING_RECORD( iface, struct test_rowset, IRowset_iface );
324 static inline struct test_rowset *impl_from_IRowsetInfo( IRowsetInfo *iface )
326 return CONTAINING_RECORD( iface, struct test_rowset, IRowsetInfo_iface );
329 static inline struct test_rowset *impl_from_IColumnsInfo( IColumnsInfo *iface )
331 return CONTAINING_RECORD( iface, struct test_rowset, IColumnsInfo_iface );
334 static HRESULT WINAPI rowset_info_QueryInterface(IRowsetInfo *iface, REFIID riid, void **obj)
336 struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
337 return IRowset_QueryInterface(&rowset->IRowset_iface, riid, obj);
340 static ULONG WINAPI rowset_info_AddRef(IRowsetInfo *iface)
342 struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
343 return IRowset_AddRef(&rowset->IRowset_iface);
346 static ULONG WINAPI rowset_info_Release(IRowsetInfo *iface)
348 struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
349 return IRowset_Release(&rowset->IRowset_iface);
352 static HRESULT WINAPI rowset_info_GetProperties(IRowsetInfo *iface, const ULONG count,
353 const DBPROPIDSET propertyidsets[], ULONG *out_count, DBPROPSET **propertysets1)
355 ok( count == 2, "got %d\n", count );
357 ok( IsEqualIID(&DBPROPSET_ROWSET, &propertyidsets[0].guidPropertySet), "got %s\n", wine_dbgstr_guid(&propertyidsets[0].guidPropertySet));
358 ok( propertyidsets[0].cPropertyIDs == 17, "got %d\n", propertyidsets[0].cPropertyIDs );
360 ok( IsEqualIID(&DBPROPSET_PROVIDERROWSET, &propertyidsets[1].guidPropertySet), "got %s\n", wine_dbgstr_guid(&propertyidsets[1].guidPropertySet));
361 ok( propertyidsets[1].cPropertyIDs == 1, "got %d\n", propertyidsets[1].cPropertyIDs );
363 return E_NOTIMPL;
366 static HRESULT WINAPI rowset_info_GetReferencedRowset(IRowsetInfo *iface, DBORDINAL ordinal,
367 REFIID riid, IUnknown **unk)
369 ok(0, "Unexpected call\n");
370 return E_NOTIMPL;
373 static HRESULT WINAPI rowset_info_GetSpecification(IRowsetInfo *iface, REFIID riid,
374 IUnknown **specification)
376 ok(0, "Unexpected call\n");
377 return E_NOTIMPL;
380 static const struct IRowsetInfoVtbl rowset_info =
382 rowset_info_QueryInterface,
383 rowset_info_AddRef,
384 rowset_info_Release,
385 rowset_info_GetProperties,
386 rowset_info_GetReferencedRowset,
387 rowset_info_GetSpecification
390 static HRESULT WINAPI column_info_QueryInterface(IColumnsInfo *iface, REFIID riid, void **obj)
392 struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
393 return IRowset_QueryInterface(&rowset->IRowset_iface, riid, obj);
396 static ULONG WINAPI column_info_AddRef(IColumnsInfo *iface)
398 struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
399 return IRowset_AddRef(&rowset->IRowset_iface);
402 static ULONG WINAPI column_info_Release(IColumnsInfo *iface)
404 struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
405 return IRowset_Release(&rowset->IRowset_iface);
408 static HRESULT WINAPI column_info_GetColumnInfo(IColumnsInfo *This, DBORDINAL *columns,
409 DBCOLUMNINFO **colinfo, OLECHAR **stringsbuffer)
411 DBCOLUMNINFO *dbcolumn;
412 *columns = 1;
414 *stringsbuffer = CoTaskMemAlloc(sizeof(L"Column1"));
415 lstrcpyW(*stringsbuffer, L"Column1");
417 dbcolumn = CoTaskMemAlloc(sizeof(DBCOLUMNINFO));
419 dbcolumn->pwszName = *stringsbuffer;
420 dbcolumn->pTypeInfo = NULL;
421 dbcolumn->iOrdinal = 1;
422 dbcolumn->dwFlags = DBCOLUMNFLAGS_MAYBENULL;
423 dbcolumn->ulColumnSize = 5;
424 dbcolumn->wType = DBTYPE_I4;
425 dbcolumn->bPrecision = 1;
426 dbcolumn->bScale = 1;
427 dbcolumn->columnid.eKind = DBKIND_NAME;
428 dbcolumn->columnid.uName.pwszName = *stringsbuffer;
430 *colinfo = dbcolumn;
432 return S_OK;
435 static HRESULT WINAPI column_info_MapColumnIDs(IColumnsInfo *This, DBORDINAL column_ids,
436 const DBID *dbids, DBORDINAL *columns)
438 ok(0, "Unexpected call\n");
439 return E_NOTIMPL;
442 static const struct IColumnsInfoVtbl column_info =
444 column_info_QueryInterface,
445 column_info_AddRef,
446 column_info_Release,
447 column_info_GetColumnInfo,
448 column_info_MapColumnIDs,
451 static HRESULT WINAPI rowset_QueryInterface(IRowset *iface, REFIID riid, void **obj)
453 struct test_rowset *rowset = impl_from_IRowset( iface );
455 *obj = NULL;
457 if (IsEqualIID(riid, &IID_IRowset) ||
458 IsEqualIID(riid, &IID_IUnknown))
460 trace("Requested interface IID_IRowset\n");
461 *obj = &rowset->IRowset_iface;
463 else if (IsEqualIID(riid, &IID_IRowsetInfo))
465 trace("Requested interface IID_IRowsetInfo\n");
466 *obj = &rowset->IRowsetInfo_iface;
468 else if (IsEqualIID(riid, &IID_IColumnsInfo))
470 trace("Requested interface IID_IColumnsInfo\n");
471 *obj = &rowset->IColumnsInfo_iface;
473 else if (IsEqualIID(riid, &IID_IRowsetLocate))
475 trace("Requested interface IID_IRowsetLocate\n");
476 return E_NOINTERFACE;
478 else if (IsEqualIID(riid, &IID_IDBAsynchStatus))
480 trace("Requested interface IID_IDBAsynchStatus\n");
481 return E_NOINTERFACE;
483 else if (IsEqualIID(riid, &IID_IAccessor))
485 trace("Requested interface IID_IAccessor\n");
486 return E_NOINTERFACE;
488 else if (IsEqualIID(riid, &UKN_INTERFACE))
490 trace("Unknown interface\n");
491 return E_NOINTERFACE;
494 if(*obj) {
495 IUnknown_AddRef((IUnknown*)*obj);
496 return S_OK;
499 ok(0, "Unsupported interface %s\n", wine_dbgstr_guid(riid));
500 return E_NOINTERFACE;
503 static ULONG WINAPI rowset_AddRef(IRowset *iface)
505 struct test_rowset *rowset = impl_from_IRowset( iface );
506 return InterlockedIncrement( &rowset->refs );
509 static ULONG WINAPI rowset_Release(IRowset *iface)
511 struct test_rowset *rowset = impl_from_IRowset( iface );
512 /* Object not allocated no need to destroy */
513 return InterlockedDecrement( &rowset->refs );
516 static HRESULT WINAPI rowset_AddRefRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
517 DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
519 ok(0, "Unexpected call\n");
520 return E_NOTIMPL;
523 static HRESULT WINAPI rowset_GetData(IRowset *iface, HROW hRow, HACCESSOR hAccessor, void *pData)
525 ok(0, "Unexpected call\n");
526 return E_NOTIMPL;
529 static HRESULT WINAPI rowset_GetNextRows(IRowset *iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
530 DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
532 ok(0, "Unexpected call\n");
533 return E_NOTIMPL;
536 static HRESULT WINAPI rowset_ReleaseRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
537 DBROWOPTIONS rgRowOptions[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
539 ok(0, "Unexpected call\n");
540 return E_NOTIMPL;
543 static HRESULT WINAPI rowset_RestartPosition(IRowset *iface, HCHAPTER hReserved)
545 ok(0, "Unexpected call\n");
546 return E_NOTIMPL;
549 static const struct IRowsetVtbl rowset_vtbl =
551 rowset_QueryInterface,
552 rowset_AddRef,
553 rowset_Release,
554 rowset_AddRefRows,
555 rowset_GetData,
556 rowset_GetNextRows,
557 rowset_ReleaseRows,
558 rowset_RestartPosition
561 static ULONG get_refcount(void *iface)
563 IUnknown *unknown = iface;
564 IUnknown_AddRef(unknown);
565 return IUnknown_Release(unknown);
568 static void test_ADORecordsetConstruction(void)
570 _Recordset *recordset;
571 ADORecordsetConstruction *construct;
572 Fields *fields = NULL;
573 Field *field;
574 struct test_rowset testrowset;
575 IRowset *rowset;
576 HRESULT hr;
577 LONG ref, count;
579 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
580 ok( hr == S_OK, "got %08x\n", hr );
582 hr = _Recordset_QueryInterface( recordset, &IID_ADORecordsetConstruction, (void**)&construct );
583 ok( hr == S_OK, "got %08x\n", hr );
584 if (FAILED(hr))
586 goto done;
589 testrowset.IRowset_iface.lpVtbl = &rowset_vtbl;
590 testrowset.IRowsetInfo_iface.lpVtbl = &rowset_info;
591 testrowset.IColumnsInfo_iface.lpVtbl = &column_info;
592 testrowset.refs = 1;
594 rowset = &testrowset.IRowset_iface;
596 ref = get_refcount( rowset );
597 ok( ref == 1, "got %d\n", ref );
598 hr = ADORecordsetConstruction_put_Rowset( construct, (IUnknown*)rowset );
599 ok( hr == S_OK, "got %08x\n", hr );
601 ref = get_refcount( rowset );
602 ok( ref == 2, "got %d\n", ref );
604 hr = _Recordset_get_Fields( recordset, &fields );
605 ok( hr == S_OK, "got %08x\n", hr );
606 ok( fields != NULL, "NULL value\n");
608 ref = get_refcount( rowset );
609 ok( ref == 2, "got %d\n", ref );
611 count = -1;
612 hr = Fields_get_Count( fields, &count );
613 ok( count == 1, "got %d\n", count );
614 if (count > 0)
616 VARIANT index;
617 LONG size;
618 DataTypeEnum type;
620 V_VT( &index ) = VT_BSTR;
621 V_BSTR( &index ) = SysAllocString( L"Column1" );
623 hr = Fields_get_Item( fields, index, &field );
624 ok( hr == S_OK, "got %08x\n", hr );
626 hr = Field_get_Type( field, &type );
627 ok( hr == S_OK, "got %08x\n", hr );
628 ok( type == adInteger, "got %d\n", type );
629 size = -1;
630 hr = Field_get_DefinedSize( field, &size );
631 ok( hr == S_OK, "got %08x\n", hr );
632 ok( size == 5, "got %d\n", size );
634 VariantClear(&index);
636 Field_Release(field);
639 ref = get_refcount(rowset);
640 ok( ref == 2, "got %d\n", ref );
642 Fields_Release(fields);
644 ADORecordsetConstruction_Release(construct);
646 done:
647 _Recordset_Release( recordset );
650 static void test_Fields(void)
652 _Recordset *recordset;
653 ISupportErrorInfo *errorinfo;
654 Fields *fields;
655 Field *field, *field2;
656 VARIANT val, index;
657 BSTR name;
658 LONG count, size;
659 DataTypeEnum type;
660 FieldAttributeEnum attrs;
661 HRESULT hr;
663 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
664 ok( hr == S_OK, "got %08x\n", hr );
666 hr = _Recordset_QueryInterface( recordset, &IID_Fields, (void **)&fields );
667 ok( hr == E_NOINTERFACE, "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 if (errorinfo) ISupportErrorInfo_Release( errorinfo );
678 count = -1;
679 hr = Fields_get_Count( fields, &count );
680 ok( !count, "got %d\n", count );
682 name = SysAllocString( L"field" );
683 V_VT( &val ) = VT_ERROR;
684 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
685 hr = Fields_Append( fields, name, adInteger, 4, adFldUnspecified, val );
686 ok( hr == S_OK, "got %08x\n", hr );
687 SysFreeString( name );
689 count = -1;
690 hr = Fields_get_Count( fields, &count );
691 ok( count == 1, "got %d\n", count );
693 name = SysAllocString( L"field2" );
694 hr = Fields__Append( fields, name, adInteger, 4, adFldUnspecified );
695 ok( hr == S_OK, "got %08x\n", hr );
696 SysFreeString( name );
698 count = -1;
699 hr = Fields_get_Count( fields, &count );
700 ok( count == 2, "got %d\n", count );
702 /* handing out field object doesn't add reference to fields or recordset object */
703 name = SysAllocString( L"field" );
704 V_VT( &index ) = VT_BSTR;
705 V_BSTR( &index ) = name;
706 hr = Fields_get_Item( fields, index, &field );
708 /* calling get_Item again returns the same object and adds reference */
709 hr = Fields_get_Item( fields, index, &field2 );
710 ok( hr == S_OK, "got %08x\n", hr );
711 ok( field2 == field, "expected same object\n" );
712 Field_Release( field2 );
713 SysFreeString( name );
715 /* Field object supports ISupportErrorInfo */
716 errorinfo = NULL;
717 hr = Field_QueryInterface( field, &IID_ISupportErrorInfo, (void **)&errorinfo );
718 ok( hr == S_OK, "got %08x\n", hr );
719 if (errorinfo) ISupportErrorInfo_Release( errorinfo );
721 /* verify values set with _Append */
722 hr = Field_get_Name( field, &name );
723 ok( hr == S_OK, "got %08x\n", hr );
724 ok( !lstrcmpW( name, L"field" ), "got %s\n", wine_dbgstr_w(name) );
725 SysFreeString( name );
726 type = 0xdead;
727 hr = Field_get_Type( field, &type );
728 ok( hr == S_OK, "got %08x\n", hr );
729 ok( type == adInteger, "got %d\n", type );
730 size = -1;
731 hr = Field_get_DefinedSize( field, &size );
732 ok( hr == S_OK, "got %08x\n", hr );
733 ok( size == 4, "got %d\n", size );
734 attrs = 0xdead;
735 hr = Field_get_Attributes( field, &attrs );
736 ok( hr == S_OK, "got %08x\n", hr );
737 ok( !attrs, "got %d\n", attrs );
739 Field_Release( field );
740 Fields_Release( fields );
741 _Recordset_Release( recordset );
744 static HRESULT str_to_byte_array( const char *data, VARIANT *ret )
746 SAFEARRAY *vector;
747 LONG i, len = strlen(data);
748 HRESULT hr;
750 if (!(vector = SafeArrayCreateVector( VT_UI1, 0, len ))) return E_OUTOFMEMORY;
751 for (i = 0; i < len; i++)
753 if ((hr = SafeArrayPutElement( vector, &i, (void *)&data[i] )) != S_OK)
755 SafeArrayDestroy( vector );
756 return hr;
760 V_VT( ret ) = VT_ARRAY | VT_UI1;
761 V_ARRAY( ret ) = vector;
762 return S_OK;
765 static void test_Stream(void)
767 _Stream *stream;
768 VARIANT_BOOL eos;
769 StreamTypeEnum type;
770 LineSeparatorEnum sep;
771 LONG refs, size, pos;
772 ObjectStateEnum state;
773 ConnectModeEnum mode;
774 BSTR charset, str;
775 VARIANT missing, val;
776 HRESULT hr;
778 hr = CoCreateInstance( &CLSID_Stream, NULL, CLSCTX_INPROC_SERVER, &IID__Stream, (void **)&stream );
779 ok( hr == S_OK, "got %08x\n", hr );
781 hr = _Stream_get_Size( stream, &size );
782 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
784 hr = _Stream_get_EOS( stream, &eos );
785 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
787 hr = _Stream_get_Position( stream, &pos );
788 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
790 hr = _Stream_put_Position( stream, 0 );
791 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
793 /* check default type */
794 type = 0;
795 hr = _Stream_get_Type( stream, &type );
796 ok( hr == S_OK, "got %08x\n", hr );
797 ok( type == adTypeText, "got %u\n", type );
799 hr = _Stream_put_Type( stream, adTypeBinary );
800 ok( hr == S_OK, "got %08x\n", hr );
802 type = 0;
803 hr = _Stream_get_Type( stream, &type );
804 ok( hr == S_OK, "got %08x\n", hr );
805 ok( type == adTypeBinary, "got %u\n", type );
807 /* revert */
808 hr = _Stream_put_Type( stream, adTypeText );
809 ok( hr == S_OK, "got %08x\n", hr );
811 sep = 0;
812 hr = _Stream_get_LineSeparator( stream, &sep );
813 ok( hr == S_OK, "got %08x\n", hr );
814 ok( sep == adCRLF, "got %d\n", sep );
816 hr = _Stream_put_LineSeparator( stream, adLF );
817 ok( hr == S_OK, "got %08x\n", hr );
819 state = 0xdeadbeef;
820 hr = _Stream_get_State( stream, &state );
821 ok( hr == S_OK, "got %08x\n", hr );
822 ok( state == adStateClosed, "got %u\n", state );
824 mode = 0xdeadbeef;
825 hr = _Stream_get_Mode( stream, &mode );
826 ok( hr == S_OK, "got %08x\n", hr );
827 ok( mode == adModeUnknown, "got %u\n", mode );
829 hr = _Stream_put_Mode( stream, adModeReadWrite );
830 ok( hr == S_OK, "got %08x\n", hr );
832 hr = _Stream_get_Charset( stream, &charset );
833 ok( hr == S_OK, "got %08x\n", hr );
834 ok( !lstrcmpW( charset, L"Unicode" ), "got %s\n", wine_dbgstr_w(charset) );
835 SysFreeString( charset );
837 str = SysAllocString( L"Unicode" );
838 hr = _Stream_put_Charset( stream, str );
839 ok( hr == S_OK, "got %08x\n", hr );
840 SysFreeString( str );
842 hr = _Stream_Read( stream, 2, &val );
843 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
845 V_VT( &missing ) = VT_ERROR;
846 V_ERROR( &missing ) = DISP_E_PARAMNOTFOUND;
847 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
848 ok( hr == S_OK, "got %08x\n", hr );
850 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
851 ok( hr == MAKE_ADO_HRESULT( adErrObjectOpen ), "got %08x\n", hr );
853 state = 0xdeadbeef;
854 hr = _Stream_get_State( stream, &state );
855 ok( hr == S_OK, "got %08x\n", hr );
856 ok( state == adStateOpen, "got %u\n", state );
858 size = -1;
859 hr = _Stream_get_Size( stream, &size );
860 ok( hr == S_OK, "got %08x\n", hr );
861 ok( !size, "got %d\n", size );
863 eos = VARIANT_FALSE;
864 hr = _Stream_get_EOS( stream, &eos );
865 ok( hr == S_OK, "got %08x\n", hr );
866 ok( eos == VARIANT_TRUE, "got %04x\n", eos );
868 pos = -1;
869 hr = _Stream_get_Position( stream, &pos );
870 ok( hr == S_OK, "got %08x\n", hr );
871 ok( !pos, "got %d\n", pos );
873 size = -1;
874 hr = _Stream_get_Size( stream, &size );
875 ok( hr == S_OK, "got %08x\n", hr );
876 ok( !size, "got %d\n", size );
878 hr = _Stream_Read( stream, 2, &val );
879 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08x\n", hr );
881 hr = _Stream_ReadText( stream, 2, &str );
882 ok( hr == S_OK, "got %08x\n", hr );
883 ok( !str[0], "got %s\n", wine_dbgstr_w(str) );
884 SysFreeString( str );
886 pos = -1;
887 hr = _Stream_get_Position( stream, &pos );
888 ok( hr == S_OK, "got %08x\n", hr );
889 ok( !pos, "got %d\n", pos );
891 str = SysAllocString( L"test" );
892 hr = _Stream_WriteText( stream, str, adWriteChar );
893 ok( hr == S_OK, "got %08x\n", hr );
894 SysFreeString( str );
896 hr = _Stream_ReadText( stream, adReadAll, &str );
897 ok( hr == S_OK, "got %08x\n", hr );
898 ok( !str[0], "got %s\n", wine_dbgstr_w(str) );
899 SysFreeString( str );
901 hr = _Stream_put_Position( stream, 0 );
902 ok( hr == S_OK, "got %08x\n", hr );
903 hr = _Stream_ReadText( stream, adReadAll, &str );
904 ok( hr == S_OK, "got %08x\n", hr );
905 ok( !lstrcmpW( str, L"test" ), "got %s\n", wine_dbgstr_w(str) );
906 SysFreeString( str );
908 pos = -1;
909 hr = _Stream_get_Position( stream, &pos );
910 ok( hr == S_OK, "got %08x\n", hr );
911 ok( pos == 10, "got %d\n", pos );
913 eos = VARIANT_FALSE;
914 hr = _Stream_get_EOS( stream, &eos );
915 ok( hr == S_OK, "got %08x\n", hr );
916 ok( eos == VARIANT_TRUE, "got %04x\n", eos );
918 hr = _Stream_put_Position( stream, 6 );
919 ok( hr == S_OK, "got %08x\n", hr );
921 size = -1;
922 hr = _Stream_get_Size( stream, &size );
923 ok( hr == S_OK, "got %08x\n", hr );
924 ok( size == 10, "got %d\n", size );
926 hr = _Stream_put_Position( stream, 2 );
927 ok( hr == S_OK, "got %08x\n", hr );
929 hr = _Stream_SetEOS( stream );
930 ok( hr == S_OK, "got %08x\n", hr );
932 pos = -1;
933 hr = _Stream_get_Position( stream, &pos );
934 ok( hr == S_OK, "got %08x\n", hr );
935 ok( pos == 2, "got %d\n", pos );
937 size = -1;
938 hr = _Stream_get_Size( stream, &size );
939 ok( hr == S_OK, "got %08x\n", hr );
940 ok( size == 2, "got %d\n", size );
942 hr = _Stream_Close( stream );
943 ok( hr == S_OK, "got %08x\n", hr );
945 state = 0xdeadbeef;
946 hr = _Stream_get_State( stream, &state );
947 ok( hr == S_OK, "got %08x\n", hr );
948 ok( state == adStateClosed, "got %u\n", state );
950 hr = _Stream_Close( stream );
951 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
953 refs = _Stream_Release( stream );
954 ok( !refs, "got %d\n", refs );
956 /* binary type */
957 hr = CoCreateInstance( &CLSID_Stream, NULL, CLSCTX_INPROC_SERVER, &IID__Stream, (void **)&stream );
958 ok( hr == S_OK, "got %08x\n", hr );
960 hr = _Stream_put_Type( stream, adTypeBinary );
961 ok( hr == S_OK, "got %08x\n", hr );
963 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
964 ok( hr == S_OK, "got %08x\n", hr );
966 hr = _Stream_ReadText( stream, adReadAll, &str );
967 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08x\n", hr );
969 str = SysAllocString( L"test" );
970 hr = _Stream_WriteText( stream, str, adWriteChar );
971 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08x\n", hr );
972 SysFreeString( str );
974 VariantInit( &val );
975 hr = _Stream_Read( stream, 1, &val );
976 ok( hr == S_OK, "got %08x\n", hr );
977 ok( V_VT( &val ) == VT_NULL, "got %u\n", V_VT( &val ) );
979 VariantInit( &val );
980 hr = _Stream_Write( stream, val );
981 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08x\n", hr );
983 hr = str_to_byte_array( "data", &val );
984 ok( hr == S_OK, "got %08x\n", hr );
985 hr = _Stream_Write( stream, val );
986 ok( hr == S_OK, "got %08x\n", hr );
987 VariantClear( &val );
989 pos = -1;
990 hr = _Stream_get_Position( stream, &pos );
991 ok( hr == S_OK, "got %08x\n", hr );
992 ok( pos == 4, "got %d\n", pos );
994 hr = _Stream_put_Position( stream, 0 );
995 ok( hr == S_OK, "got %08x\n", hr );
997 VariantInit( &val );
998 hr = _Stream_Read( stream, adReadAll, &val );
999 ok( hr == S_OK, "got %08x\n", hr );
1000 ok( V_VT( &val ) == (VT_ARRAY | VT_UI1), "got %04x\n", V_VT( &val ) );
1001 VariantClear( &val );
1003 pos = -1;
1004 hr = _Stream_get_Position( stream, &pos );
1005 ok( hr == S_OK, "got %08x\n", hr );
1006 ok( pos == 4, "got %d\n", pos );
1008 refs = _Stream_Release( stream );
1009 ok( !refs, "got %d\n", refs );
1012 static void test_Connection(void)
1014 HRESULT hr;
1015 _Connection *connection;
1016 IRunnableObject *runtime;
1017 ISupportErrorInfo *errorinfo;
1018 IConnectionPointContainer *pointcontainer;
1019 ADOConnectionConstruction15 *construct;
1020 LONG state, timeout;
1021 BSTR str, str2, str3;
1022 ConnectModeEnum mode;
1023 CursorLocationEnum location;
1025 hr = CoCreateInstance(&CLSID_Connection, NULL, CLSCTX_INPROC_SERVER, &IID__Connection, (void**)&connection);
1026 ok( hr == S_OK, "got %08x\n", hr );
1028 hr = _Connection_QueryInterface(connection, &IID_IRunnableObject, (void**)&runtime);
1029 ok(hr == E_NOINTERFACE, "Unexpected IRunnableObject interface\n");
1030 ok(runtime == NULL, "expected NULL\n");
1032 hr = _Connection_QueryInterface(connection, &IID_ISupportErrorInfo, (void**)&errorinfo);
1033 ok(hr == S_OK, "Failed to get ISupportErrorInfo interface\n");
1034 ISupportErrorInfo_Release(errorinfo);
1036 hr = _Connection_QueryInterface(connection, &IID_IConnectionPointContainer, (void**)&pointcontainer);
1037 ok(hr == S_OK, "Failed to get IConnectionPointContainer interface %08x\n", hr);
1038 IConnectionPointContainer_Release(pointcontainer);
1040 hr = _Connection_QueryInterface(connection, &IID_ADOConnectionConstruction15, (void**)&construct);
1041 ok(hr == S_OK, "Failed to get ADOConnectionConstruction15 interface %08x\n", hr);
1042 if (hr == S_OK)
1043 ADOConnectionConstruction15_Release(construct);
1045 if (0) /* Crashes on windows */
1047 hr = _Connection_get_State(connection, NULL);
1048 ok(hr == E_INVALIDARG, "Unexpected hr 0x%08x\n", hr);
1051 state = -1;
1052 hr = _Connection_get_State(connection, &state);
1053 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1054 ok(state == adStateClosed, "Unexpected state value 0x%08x\n", state);
1056 hr = _Connection_Close(connection);
1057 ok(hr == MAKE_ADO_HRESULT(adErrObjectClosed), "got %08x\n", hr);
1059 timeout = 0;
1060 hr = _Connection_get_CommandTimeout(connection, &timeout);
1061 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1062 ok(timeout == 30, "Unexpected timeout value %d\n", timeout);
1064 hr = _Connection_put_CommandTimeout(connection, 300);
1065 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1067 timeout = 0;
1068 hr = _Connection_get_CommandTimeout(connection, &timeout);
1069 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1070 ok(timeout == 300, "Unexpected timeout value %d\n", timeout);
1072 location = 0;
1073 hr = _Connection_get_CursorLocation(connection, &location);
1074 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1075 ok(location == adUseServer, "Unexpected location value %d\n", location);
1077 hr = _Connection_put_CursorLocation(connection, adUseClient);
1078 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1080 location = 0;
1081 hr = _Connection_get_CursorLocation(connection, &location);
1082 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1083 ok(location == adUseClient, "Unexpected location value %d\n", location);
1085 hr = _Connection_put_CursorLocation(connection, adUseServer);
1086 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1088 mode = 0xdeadbeef;
1089 hr = _Connection_get_Mode(connection, &mode);
1090 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1091 ok(mode == adModeUnknown, "Unexpected mode value %d\n", mode);
1093 hr = _Connection_put_Mode(connection, adModeShareDenyNone);
1094 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1096 mode = adModeUnknown;
1097 hr = _Connection_get_Mode(connection, &mode);
1098 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1099 ok(mode == adModeShareDenyNone, "Unexpected mode value %d\n", mode);
1101 hr = _Connection_put_Mode(connection, adModeUnknown);
1102 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1104 /* Default */
1105 str = (BSTR)0xdeadbeef;
1106 hr = _Connection_get_Provider(connection, &str);
1107 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1108 ok(!wcscmp(str, L"MSDASQL"), "wrong string %s\n", wine_dbgstr_w(str));
1109 SysFreeString(str);
1111 str = SysAllocString(L"MSDASQL.1");
1112 hr = _Connection_put_Provider(connection, str);
1113 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1114 SysFreeString(str);
1116 str = (BSTR)0xdeadbeef;
1117 hr = _Connection_get_Provider(connection, &str);
1118 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1119 ok(!wcscmp(str, L"MSDASQL.1"), "wrong string %s\n", wine_dbgstr_w(str));
1121 /* Restore default */
1122 str = SysAllocString(L"MSDASQL");
1123 hr = _Connection_put_Provider(connection, str);
1124 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1125 SysFreeString(str);
1127 hr = _Connection_put_Provider(connection, NULL);
1128 ok(hr == MAKE_ADO_HRESULT(adErrInvalidArgument), "got 0x%08x\n", hr);
1129 SysFreeString(str);
1131 str = (BSTR)0xdeadbeef;
1132 hr = _Connection_get_ConnectionString(connection, &str);
1133 ok(hr == S_OK, "got 0x%08x\n", hr);
1134 ok(str == NULL, "got %p\n", str);
1136 str = SysAllocString(L"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_test");
1137 hr = _Connection_put_ConnectionString(connection, str);
1138 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1140 /* Show put_ConnectionString effects Provider */
1141 str3 = (BSTR)0xdeadbeef;
1142 hr = _Connection_get_Provider(connection, &str3);
1143 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1144 ok(str3 != NULL, "Expected value got NULL\n");
1145 todo_wine ok(!wcscmp(str3, L"MSDASQL.1"), "wrong string %s\n", wine_dbgstr_w(str3));
1146 SysFreeString(str3);
1148 if (0) /* Crashes on windows */
1150 hr = _Connection_get_ConnectionString(connection, NULL);
1151 ok(hr == E_POINTER, "Failed, hr 0x%08x\n", hr);
1154 str2 = NULL;
1155 hr = _Connection_get_ConnectionString(connection, &str2);
1156 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1157 ok(!wcscmp(str, str2), "wrong string %s\n", wine_dbgstr_w(str2));
1159 hr = _Connection_Open(connection, NULL, NULL, NULL, 0);
1160 ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr);
1162 /* Open adds trailing ; if it's missing */
1163 str3 = SysAllocString(L"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_test;");
1164 hr = _Connection_Open(connection, NULL, NULL, NULL, adConnectUnspecified);
1165 ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr);
1167 str2 = NULL;
1168 hr = _Connection_get_ConnectionString(connection, &str2);
1169 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1170 todo_wine ok(!wcscmp(str3, str2) || broken(!wcscmp(str, str2)) /* XP */, "wrong string %s\n", wine_dbgstr_w(str2));
1172 hr = _Connection_Open(connection, str, NULL, NULL, adConnectUnspecified);
1173 todo_wine ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr);
1174 SysFreeString(str);
1176 str2 = NULL;
1177 hr = _Connection_get_ConnectionString(connection, &str2);
1178 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1179 todo_wine ok(!wcscmp(str3, str2) || broken(!wcscmp(str, str2)) /* XP */, "wrong string %s\n", wine_dbgstr_w(str2));
1180 SysFreeString(str2);
1181 SysFreeString(str3);
1183 hr = _Connection_put_ConnectionString(connection, NULL);
1184 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1186 str = (BSTR)0xdeadbeef;
1187 hr = _Connection_get_ConnectionString(connection, &str);
1188 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1189 ok(str == NULL, "got %p\n", str);
1190 _Connection_Release(connection);
1193 static void test_Command(void)
1195 HRESULT hr;
1196 _Command *command;
1197 _ADO *ado;
1198 Command15 *command15;
1199 Command25 *command25;
1200 CommandTypeEnum cmd_type = adCmdUnspecified;
1201 BSTR cmd_text = (BSTR)"test";
1202 _Connection *connection;
1204 hr = CoCreateInstance( &CLSID_Command, NULL, CLSCTX_INPROC_SERVER, &IID__Command, (void **)&command );
1205 ok( hr == S_OK, "got %08x\n", hr );
1207 hr = _Command_QueryInterface( command, &IID__ADO, (void **)&ado );
1208 ok( hr == S_OK, "got %08x\n", hr );
1209 _ADO_Release( ado );
1211 hr = _Command_QueryInterface( command, &IID_Command15, (void **)&command15 );
1212 ok( hr == S_OK, "got %08x\n", hr );
1213 Command15_Release( command15 );
1215 hr = _Command_QueryInterface( command, &IID_Command25, (void **)&command25 );
1216 ok( hr == S_OK, "got %08x\n", hr );
1217 Command25_Release( command25 );
1219 hr = _Command_get_CommandType( command, &cmd_type );
1220 ok( hr == S_OK, "got %08x\n", hr );
1221 ok( cmd_type == adCmdUnknown, "got %08x\n", cmd_type );
1223 _Command_put_CommandType( command, adCmdText );
1224 hr = _Command_get_CommandType( command, &cmd_type );
1225 ok( hr == S_OK, "got %08x\n", hr );
1226 ok( cmd_type == adCmdText, "got %08x\n", cmd_type );
1228 hr = _Command_put_CommandType( command, 0xdeadbeef );
1229 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08x\n", hr );
1231 hr = _Command_get_CommandText( command, &cmd_text );
1232 ok( hr == S_OK, "got %08x\n", hr );
1233 ok( !cmd_text, "got %s\n", wine_dbgstr_w( cmd_text ));
1235 hr = _Command_put_CommandText( command, NULL );
1236 ok( hr == S_OK, "got %08x\n", hr );
1238 cmd_text = SysAllocString( L"" );
1239 hr = _Command_put_CommandText( command, cmd_text );
1240 ok( hr == S_OK, "got %08x\n", hr );
1241 SysFreeString( cmd_text );
1243 hr = _Command_get_CommandText( command, &cmd_text );
1244 ok( hr == S_OK, "got %08x\n", hr );
1245 ok( cmd_text && !*cmd_text, "got %p\n", cmd_text );
1247 cmd_text = SysAllocString( L"test" );
1248 hr = _Command_put_CommandText( command, cmd_text );
1249 ok( hr == S_OK, "got %08x\n", hr );
1250 SysFreeString( cmd_text );
1252 hr = _Command_get_CommandText( command, &cmd_text );
1253 ok( hr == S_OK, "got %08x\n", hr );
1254 ok( !wcscmp( L"test", cmd_text ), "got %p\n", wine_dbgstr_w( cmd_text ) );
1256 connection = (_Connection*)0xdeadbeef;
1257 hr = _Command_get_ActiveConnection( command, &connection );
1258 ok( hr == S_OK, "got %08x\n", hr );
1259 ok( connection == NULL, "got %p\n", connection );
1261 hr = _Command_putref_ActiveConnection( command, NULL );
1262 ok( hr == S_OK, "got %08x\n", hr );
1264 _Command_Release( command );
1267 struct conn_event {
1268 ConnectionEventsVt conn_event_sink;
1269 LONG refs;
1272 static HRESULT WINAPI conneventvt_QueryInterface( ConnectionEventsVt *iface, REFIID riid, void **obj )
1274 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
1276 if (IsEqualGUID( &IID_ConnectionEventsVt, riid ))
1278 InterlockedIncrement( &conn_event->refs );
1279 *obj = iface;
1280 return S_OK;
1283 ok( 0, "unexpected call\n" );
1284 return E_NOINTERFACE;
1287 static ULONG WINAPI conneventvt_AddRef( ConnectionEventsVt *iface )
1289 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
1290 return InterlockedIncrement( &conn_event->refs );
1293 static ULONG WINAPI conneventvt_Release( ConnectionEventsVt *iface )
1295 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
1296 return InterlockedDecrement( &conn_event->refs );
1299 static HRESULT WINAPI conneventvt_InfoMessage( ConnectionEventsVt *iface, Error *error,
1300 EventStatusEnum *status, _Connection *Connection )
1302 return E_NOTIMPL;
1305 static HRESULT WINAPI conneventvt_BeginTransComplete( ConnectionEventsVt *iface, LONG TransactionLevel,
1306 Error *error, EventStatusEnum *status, _Connection *connection )
1308 return E_NOTIMPL;
1311 static HRESULT WINAPI conneventvt_CommitTransComplete( ConnectionEventsVt *iface, Error *error,
1312 EventStatusEnum *status, _Connection *connection )
1314 return E_NOTIMPL;
1317 static HRESULT WINAPI conneventvt_RollbackTransComplete( ConnectionEventsVt *iface, Error *error,
1318 EventStatusEnum *status, _Connection *connection )
1320 return E_NOTIMPL;
1323 static HRESULT WINAPI conneventvt_WillExecute( ConnectionEventsVt *iface, BSTR *source,
1324 CursorTypeEnum *cursor_type, LockTypeEnum *lock_type, LONG *options, EventStatusEnum *status,
1325 _Command *command, _Recordset *record_set, _Connection *connection )
1327 return E_NOTIMPL;
1330 static HRESULT WINAPI conneventvt_ExecuteComplete( ConnectionEventsVt *iface, LONG records_affected,
1331 Error *error, EventStatusEnum *status, _Command *command, _Recordset *record_set,
1332 _Connection *connection )
1334 return E_NOTIMPL;
1337 static HRESULT WINAPI conneventvt_WillConnect( ConnectionEventsVt *iface, BSTR *string, BSTR *userid,
1338 BSTR *password, LONG *options, EventStatusEnum *status, _Connection *connection )
1340 return E_NOTIMPL;
1343 static HRESULT WINAPI conneventvt_ConnectComplete( ConnectionEventsVt *iface, Error *error,
1344 EventStatusEnum *status, _Connection *connection )
1346 return E_NOTIMPL;
1349 static HRESULT WINAPI conneventvt_Disconnect( ConnectionEventsVt *iface, EventStatusEnum *status,
1350 _Connection *connection )
1352 return E_NOTIMPL;
1355 static const ConnectionEventsVtVtbl conneventvt_vtbl = {
1356 conneventvt_QueryInterface,
1357 conneventvt_AddRef,
1358 conneventvt_Release,
1359 conneventvt_InfoMessage,
1360 conneventvt_BeginTransComplete,
1361 conneventvt_CommitTransComplete,
1362 conneventvt_RollbackTransComplete,
1363 conneventvt_WillExecute,
1364 conneventvt_ExecuteComplete,
1365 conneventvt_WillConnect,
1366 conneventvt_ConnectComplete,
1367 conneventvt_Disconnect
1370 static HRESULT WINAPI supporterror_QueryInterface( ISupportErrorInfo *iface, REFIID riid, void **obj )
1372 if (IsEqualGUID( &IID_ISupportErrorInfo, riid ))
1374 *obj = iface;
1375 return S_OK;
1378 return E_NOINTERFACE;
1381 static ULONG WINAPI supporterror_AddRef( ISupportErrorInfo *iface )
1383 return 2;
1386 static ULONG WINAPI supporterror_Release( ISupportErrorInfo *iface )
1388 return 1;
1391 static HRESULT WINAPI supporterror_InterfaceSupportsErrorInfo( ISupportErrorInfo *iface, REFIID riid )
1393 return E_NOTIMPL;
1396 static const struct ISupportErrorInfoVtbl support_error_vtbl =
1398 supporterror_QueryInterface,
1399 supporterror_AddRef,
1400 supporterror_Release,
1401 supporterror_InterfaceSupportsErrorInfo
1404 static void test_ConnectionPoint(void)
1406 HRESULT hr;
1407 ULONG refs;
1408 DWORD cookie;
1409 IConnectionPoint *point;
1410 IConnectionPointContainer *pointcontainer;
1411 struct conn_event conn_event = { { &conneventvt_vtbl }, 0 };
1412 ISupportErrorInfo support_err_sink = { &support_error_vtbl };
1414 hr = CoCreateInstance( &CLSID_Connection, NULL, CLSCTX_INPROC_SERVER,
1415 &IID_IConnectionPointContainer, (void**)&pointcontainer );
1417 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_ConnectionEvents, NULL );
1418 ok( hr == E_POINTER, "got %08x\n", hr );
1420 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_RecordsetEvents, &point );
1421 ok( hr == CONNECT_E_NOCONNECTION, "got %08x\n", hr );
1423 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_ConnectionEvents, &point );
1424 ok( hr == S_OK, "got %08x\n", hr );
1426 /* nothing advised yet */
1427 hr = IConnectionPoint_Unadvise( point, 3 );
1428 ok( hr == E_FAIL, "got %08x\n", hr );
1430 hr = IConnectionPoint_Advise( point, NULL, NULL );
1431 ok( hr == E_FAIL, "got %08x\n", hr );
1433 hr = IConnectionPoint_Advise( point, (void*)&conn_event.conn_event_sink, NULL );
1434 ok( hr == E_FAIL, "got %08x\n", hr );
1436 cookie = 0xdeadbeef;
1437 hr = IConnectionPoint_Advise( point, NULL, &cookie );
1438 ok( hr == E_FAIL, "got %08x\n", hr );
1439 ok( cookie == 0xdeadbeef, "got %08x\n", cookie );
1441 /* unsupported sink */
1442 cookie = 0xdeadbeef;
1443 hr = IConnectionPoint_Advise( point, (void*)&support_err_sink, &cookie );
1444 ok( hr == E_FAIL, "got %08x\n", hr );
1445 ok( !cookie, "got %08x\n", cookie );
1447 cookie = 0;
1448 hr = IConnectionPoint_Advise( point, (void*)&conn_event.conn_event_sink, &cookie );
1449 ok( hr == S_OK, "got %08x\n", hr );
1450 ok( cookie, "got %08x\n", cookie );
1452 /* invalid cookie */
1453 hr = IConnectionPoint_Unadvise( point, 0 );
1454 ok( hr == E_FAIL, "got %08x\n", hr );
1456 /* wrong cookie */
1457 hr = IConnectionPoint_Unadvise( point, cookie + 1 );
1458 ok( hr == E_FAIL, "got %08x\n", hr );
1460 hr = IConnectionPoint_Unadvise( point, cookie );
1461 ok( hr == S_OK, "got %08x\n", hr );
1463 /* sinks are released when the connection is destroyed */
1464 cookie = 0;
1465 hr = IConnectionPoint_Advise( point, (void*)&conn_event.conn_event_sink, &cookie );
1466 ok( hr == S_OK, "got %08x\n", hr );
1467 ok( cookie, "got %08x\n", cookie );
1468 ok( conn_event.refs == 1, "got %d\n", conn_event.refs );
1470 refs = IConnectionPoint_Release( point );
1471 ok( refs == 1, "got %u", refs );
1473 IConnectionPointContainer_Release( pointcontainer );
1475 ok( !conn_event.refs, "got %d\n", conn_event.refs );
1478 START_TEST(msado15)
1480 CoInitialize( NULL );
1481 test_Connection();
1482 test_ADORecordsetConstruction();
1483 test_ConnectionPoint();
1484 test_Fields();
1485 test_Recordset();
1486 test_Stream();
1487 test_Command();
1488 CoUninitialize();