user32/tests: Test pending redraw state with owner-drawn list box.
[wine.git] / dlls / msado15 / tests / msado15.c
blob25c9c6f8356d3fafe3f840cfd471d6489a298629
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_I1;
154 V_I1( &index ) = 0;
155 hr = Fields_get_Item( fields, index, &field );
156 ok( hr == S_OK, "got %08x\n", hr );
157 Field_Release(field);
159 V_VT( &index ) = VT_R8;
160 V_R8( &index ) = 0.1;
161 hr = Fields_get_Item( fields, index, &field );
162 ok( hr == S_OK, "got %08x\n", hr );
163 Field_Release(field);
165 V_VT( &index ) = VT_UNKNOWN;
166 V_UNKNOWN( &index ) = NULL;
167 hr = Fields_get_Item( fields, index, &field );
168 ok( hr == MAKE_ADO_HRESULT(adErrItemNotFound), "got %08x\n", hr );
170 V_VT( &index ) = VT_BSTR;
171 V_BSTR( &index ) = name;
172 hr = Fields_get_Item( fields, index, &field );
173 ok( hr == S_OK, "got %08x\n", hr );
174 SysFreeString( name );
176 hr = Field_QueryInterface(field, &IID_Properties, (void**)&props);
177 ok( hr == E_NOINTERFACE, "got %08x\n", hr );
179 hr = Field_get_Properties(field, &props);
180 ok( hr == S_OK, "got %08x\n", hr );
182 count = -1;
183 hr = Properties_get_Count(props, &count);
184 ok( hr == S_OK, "got %08x\n", hr );
185 ok( !count, "got %d\n", count );
187 V_VT( &index ) = VT_I4;
188 V_I4( &index ) = 1000;
189 hr = Properties_get_Item(props, index, &prop);
190 ok( hr == MAKE_ADO_HRESULT(adErrItemNotFound), "got %08x\n", hr );
192 Properties_Release(props);
194 hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified );
195 ok( hr == S_OK, "got %08x\n", hr );
196 ok( is_eof( recordset ), "not eof\n" );
197 ok( is_bof( recordset ), "not bof\n" );
199 hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified );
200 ok( hr == MAKE_ADO_HRESULT( adErrObjectOpen ), "got %08x\n", hr );
202 state = -1;
203 hr = _Recordset_get_State( recordset, &state );
204 ok( hr == S_OK, "got %08x\n", hr );
205 ok( state == adStateOpen, "got %d\n", state );
207 VariantInit( &bookmark );
208 hr = _Recordset_get_Bookmark( recordset, &bookmark );
209 ok( hr == MAKE_ADO_HRESULT( adErrNoCurrentRecord ), "got %08x\n", hr );
211 VariantInit( &bookmark );
212 hr = _Recordset_put_Bookmark( recordset, bookmark );
213 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08x\n", hr );
215 count = -1;
216 hr = _Recordset_get_RecordCount( recordset, &count );
217 ok( hr == S_OK, "got %08x\n", hr );
218 ok( !count, "got %d\n", count );
220 hr = _Recordset_AddNew( recordset, missing, missing );
221 ok( hr == S_OK, "got %08x\n", hr );
222 ok( !is_eof( recordset ), "eof\n" );
223 ok( !is_bof( recordset ), "bof\n" );
225 count = -1;
226 hr = _Recordset_get_RecordCount( recordset, &count );
227 ok( hr == S_OK, "got %08x\n", hr );
228 ok( count == 1, "got %d\n", count );
230 /* get_Fields still returns the same object */
231 hr = _Recordset_get_Fields( recordset, &fields2 );
232 ok( hr == S_OK, "got %08x\n", hr );
233 ok( fields2 == fields, "expected same object\n" );
234 Fields_Release( fields2 );
236 count = -1;
237 hr = Fields_get_Count( fields2, &count );
238 ok( count == 1, "got %d\n", count );
240 hr = Field_get_Value( field, &val );
241 ok( hr == S_OK, "got %08x\n", hr );
242 ok( V_VT( &val ) == VT_EMPTY, "got %u\n", V_VT( &val ) );
244 V_VT( &val ) = VT_I4;
245 V_I4( &val ) = -1;
246 hr = Field_put_Value( field, val );
247 ok( hr == S_OK, "got %08x\n", hr );
249 V_VT( &val ) = VT_ERROR;
250 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
251 hr = Field_get_Value( field, &val );
252 ok( hr == S_OK, "got %08x\n", hr );
253 ok( V_VT( &val ) == VT_I4, "got %u\n", V_VT( &val ) );
254 ok( V_I4( &val ) == -1, "got %d\n", V_I4( &val ) );
256 hr = _Recordset_AddNew( recordset, missing, missing );
257 ok( hr == S_OK, "got %08x\n", hr );
259 /* field object returns different value after AddNew */
260 V_VT( &val ) = VT_ERROR;
261 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
262 hr = Field_get_Value( field, &val );
263 ok( hr == S_OK, "got %08x\n", hr );
264 ok( V_VT( &val ) == VT_EMPTY, "got %u\n", V_VT( &val ) );
266 ok( !is_eof( recordset ), "eof\n" );
267 ok( !is_bof( recordset ), "bof\n" );
268 hr = _Recordset_MoveFirst( recordset );
269 ok( hr == S_OK, "got %08x\n", hr );
270 ok( !is_eof( recordset ), "eof\n" );
271 ok( !is_bof( recordset ), "bof\n" );
273 V_VT( &val ) = VT_ERROR;
274 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
275 hr = Field_get_Value( field, &val );
276 ok( hr == S_OK, "got %08x\n", hr );
277 ok( V_VT( &val ) == VT_I4, "got %u\n", V_VT( &val ) );
278 ok( V_I4( &val ) == -1, "got %d\n", V_I4( &val ) );
280 hr = _Recordset_MoveNext( recordset );
281 ok( hr == S_OK, "got %08x\n", hr );
282 ok( !is_eof( recordset ), "eof\n" );
283 ok( !is_bof( recordset ), "not bof\n" );
285 hr = _Recordset_MoveNext( recordset );
286 ok( hr == S_OK, "got %08x\n", hr );
287 ok( is_eof( recordset ), "not eof\n" );
288 ok( !is_bof( recordset ), "bof\n" );
290 hr = _Recordset_MoveFirst( recordset );
291 ok( hr == S_OK, "got %08x\n", hr );
292 ok( !is_eof( recordset ), "eof\n" );
293 ok( !is_bof( recordset ), "bof\n" );
295 hr = _Recordset_MovePrevious( recordset );
296 ok( hr == S_OK, "got %08x\n", hr );
297 ok( !is_eof( recordset ), "eof\n" );
298 ok( is_bof( recordset ), "not bof\n" );
300 /* try get value at BOF */
301 VariantInit( &val );
302 hr = Field_get_Value( field, &val );
303 ok( hr == MAKE_ADO_HRESULT( adErrNoCurrentRecord ), "got %08x\n", hr );
305 hr = _Recordset_Close( recordset );
306 ok( hr == S_OK, "got %08x\n", hr );
308 count = -1;
309 hr = Fields_get_Count( fields, &count );
310 ok( !count, "got %d\n", count );
312 hr = Field_get_Name(field, &name);
313 todo_wine ok( hr == MAKE_ADO_HRESULT( adErrObjectNotSet ), "got %08x\n", hr );
315 state = -1;
316 hr = _Recordset_get_State( recordset, &state );
317 ok( hr == S_OK, "got %08x\n", hr );
318 ok( state == adStateClosed, "got %d\n", state );
320 Field_Release( field );
321 Fields_Release( fields );
322 _Recordset_Release( recordset );
325 /* This interface is queried for but is not documented anywhere. */
326 DEFINE_GUID(UKN_INTERFACE, 0x6f1e39e1, 0x05c6, 0x11d0, 0xa7, 0x8b, 0x00, 0xaa, 0x00, 0xa3, 0xf0, 0x0d);
328 struct test_rowset
330 IRowset IRowset_iface;
331 IRowsetInfo IRowsetInfo_iface;
332 IColumnsInfo IColumnsInfo_iface;
333 LONG refs;
336 static inline struct test_rowset *impl_from_IRowset( IRowset *iface )
338 return CONTAINING_RECORD( iface, struct test_rowset, IRowset_iface );
341 static inline struct test_rowset *impl_from_IRowsetInfo( IRowsetInfo *iface )
343 return CONTAINING_RECORD( iface, struct test_rowset, IRowsetInfo_iface );
346 static inline struct test_rowset *impl_from_IColumnsInfo( IColumnsInfo *iface )
348 return CONTAINING_RECORD( iface, struct test_rowset, IColumnsInfo_iface );
351 static HRESULT WINAPI rowset_info_QueryInterface(IRowsetInfo *iface, REFIID riid, void **obj)
353 struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
354 return IRowset_QueryInterface(&rowset->IRowset_iface, riid, obj);
357 static ULONG WINAPI rowset_info_AddRef(IRowsetInfo *iface)
359 struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
360 return IRowset_AddRef(&rowset->IRowset_iface);
363 static ULONG WINAPI rowset_info_Release(IRowsetInfo *iface)
365 struct test_rowset *rowset = impl_from_IRowsetInfo( iface );
366 return IRowset_Release(&rowset->IRowset_iface);
369 static HRESULT WINAPI rowset_info_GetProperties(IRowsetInfo *iface, const ULONG count,
370 const DBPROPIDSET propertyidsets[], ULONG *out_count, DBPROPSET **propertysets1)
372 ok( count == 2, "got %d\n", count );
374 ok( IsEqualIID(&DBPROPSET_ROWSET, &propertyidsets[0].guidPropertySet), "got %s\n", wine_dbgstr_guid(&propertyidsets[0].guidPropertySet));
375 ok( propertyidsets[0].cPropertyIDs == 17, "got %d\n", propertyidsets[0].cPropertyIDs );
377 ok( IsEqualIID(&DBPROPSET_PROVIDERROWSET, &propertyidsets[1].guidPropertySet), "got %s\n", wine_dbgstr_guid(&propertyidsets[1].guidPropertySet));
378 ok( propertyidsets[1].cPropertyIDs == 1, "got %d\n", propertyidsets[1].cPropertyIDs );
380 return E_NOTIMPL;
383 static HRESULT WINAPI rowset_info_GetReferencedRowset(IRowsetInfo *iface, DBORDINAL ordinal,
384 REFIID riid, IUnknown **unk)
386 ok(0, "Unexpected call\n");
387 return E_NOTIMPL;
390 static HRESULT WINAPI rowset_info_GetSpecification(IRowsetInfo *iface, REFIID riid,
391 IUnknown **specification)
393 ok(0, "Unexpected call\n");
394 return E_NOTIMPL;
397 static const struct IRowsetInfoVtbl rowset_info =
399 rowset_info_QueryInterface,
400 rowset_info_AddRef,
401 rowset_info_Release,
402 rowset_info_GetProperties,
403 rowset_info_GetReferencedRowset,
404 rowset_info_GetSpecification
407 static HRESULT WINAPI column_info_QueryInterface(IColumnsInfo *iface, REFIID riid, void **obj)
409 struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
410 return IRowset_QueryInterface(&rowset->IRowset_iface, riid, obj);
413 static ULONG WINAPI column_info_AddRef(IColumnsInfo *iface)
415 struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
416 return IRowset_AddRef(&rowset->IRowset_iface);
419 static ULONG WINAPI column_info_Release(IColumnsInfo *iface)
421 struct test_rowset *rowset = impl_from_IColumnsInfo( iface );
422 return IRowset_Release(&rowset->IRowset_iface);
425 static HRESULT WINAPI column_info_GetColumnInfo(IColumnsInfo *This, DBORDINAL *columns,
426 DBCOLUMNINFO **colinfo, OLECHAR **stringsbuffer)
428 DBCOLUMNINFO *dbcolumn;
429 *columns = 1;
431 *stringsbuffer = CoTaskMemAlloc(sizeof(L"Column1"));
432 lstrcpyW(*stringsbuffer, L"Column1");
434 dbcolumn = CoTaskMemAlloc(sizeof(DBCOLUMNINFO));
436 dbcolumn->pwszName = *stringsbuffer;
437 dbcolumn->pTypeInfo = NULL;
438 dbcolumn->iOrdinal = 1;
439 dbcolumn->dwFlags = DBCOLUMNFLAGS_MAYBENULL;
440 dbcolumn->ulColumnSize = 5;
441 dbcolumn->wType = DBTYPE_I4;
442 dbcolumn->bPrecision = 1;
443 dbcolumn->bScale = 1;
444 dbcolumn->columnid.eKind = DBKIND_NAME;
445 dbcolumn->columnid.uName.pwszName = *stringsbuffer;
447 *colinfo = dbcolumn;
449 return S_OK;
452 static HRESULT WINAPI column_info_MapColumnIDs(IColumnsInfo *This, DBORDINAL column_ids,
453 const DBID *dbids, DBORDINAL *columns)
455 ok(0, "Unexpected call\n");
456 return E_NOTIMPL;
459 static const struct IColumnsInfoVtbl column_info =
461 column_info_QueryInterface,
462 column_info_AddRef,
463 column_info_Release,
464 column_info_GetColumnInfo,
465 column_info_MapColumnIDs,
468 static HRESULT WINAPI rowset_QueryInterface(IRowset *iface, REFIID riid, void **obj)
470 struct test_rowset *rowset = impl_from_IRowset( iface );
472 *obj = NULL;
474 if (IsEqualIID(riid, &IID_IRowset) ||
475 IsEqualIID(riid, &IID_IUnknown))
477 trace("Requested interface IID_IRowset\n");
478 *obj = &rowset->IRowset_iface;
480 else if (IsEqualIID(riid, &IID_IRowsetInfo))
482 trace("Requested interface IID_IRowsetInfo\n");
483 *obj = &rowset->IRowsetInfo_iface;
485 else if (IsEqualIID(riid, &IID_IColumnsInfo))
487 trace("Requested interface IID_IColumnsInfo\n");
488 *obj = &rowset->IColumnsInfo_iface;
490 else if (IsEqualIID(riid, &IID_IRowsetLocate))
492 trace("Requested interface IID_IRowsetLocate\n");
493 return E_NOINTERFACE;
495 else if (IsEqualIID(riid, &IID_IDBAsynchStatus))
497 trace("Requested interface IID_IDBAsynchStatus\n");
498 return E_NOINTERFACE;
500 else if (IsEqualIID(riid, &IID_IAccessor))
502 trace("Requested interface IID_IAccessor\n");
503 return E_NOINTERFACE;
505 else if (IsEqualIID(riid, &UKN_INTERFACE))
507 trace("Unknown interface\n");
508 return E_NOINTERFACE;
511 if(*obj) {
512 IUnknown_AddRef((IUnknown*)*obj);
513 return S_OK;
516 ok(0, "Unsupported interface %s\n", wine_dbgstr_guid(riid));
517 return E_NOINTERFACE;
520 static ULONG WINAPI rowset_AddRef(IRowset *iface)
522 struct test_rowset *rowset = impl_from_IRowset( iface );
523 return InterlockedIncrement( &rowset->refs );
526 static ULONG WINAPI rowset_Release(IRowset *iface)
528 struct test_rowset *rowset = impl_from_IRowset( iface );
529 /* Object not allocated no need to destroy */
530 return InterlockedDecrement( &rowset->refs );
533 static HRESULT WINAPI rowset_AddRefRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
534 DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
536 ok(0, "Unexpected call\n");
537 return E_NOTIMPL;
540 static HRESULT WINAPI rowset_GetData(IRowset *iface, HROW hRow, HACCESSOR hAccessor, void *pData)
542 ok(0, "Unexpected call\n");
543 return E_NOTIMPL;
546 static HRESULT WINAPI rowset_GetNextRows(IRowset *iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
547 DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
549 ok(0, "Unexpected call\n");
550 return E_NOTIMPL;
553 static HRESULT WINAPI rowset_ReleaseRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[],
554 DBROWOPTIONS rgRowOptions[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
556 ok(0, "Unexpected call\n");
557 return E_NOTIMPL;
560 static HRESULT WINAPI rowset_RestartPosition(IRowset *iface, HCHAPTER hReserved)
562 ok(0, "Unexpected call\n");
563 return E_NOTIMPL;
566 static const struct IRowsetVtbl rowset_vtbl =
568 rowset_QueryInterface,
569 rowset_AddRef,
570 rowset_Release,
571 rowset_AddRefRows,
572 rowset_GetData,
573 rowset_GetNextRows,
574 rowset_ReleaseRows,
575 rowset_RestartPosition
578 static ULONG get_refcount(void *iface)
580 IUnknown *unknown = iface;
581 IUnknown_AddRef(unknown);
582 return IUnknown_Release(unknown);
585 static void test_ADORecordsetConstruction(void)
587 _Recordset *recordset;
588 ADORecordsetConstruction *construct;
589 Fields *fields = NULL;
590 Field *field;
591 struct test_rowset testrowset;
592 IRowset *rowset;
593 HRESULT hr;
594 LONG ref, count;
596 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
597 ok( hr == S_OK, "got %08x\n", hr );
599 hr = _Recordset_QueryInterface( recordset, &IID_ADORecordsetConstruction, (void**)&construct );
600 ok( hr == S_OK, "got %08x\n", hr );
601 if (FAILED(hr))
603 goto done;
606 testrowset.IRowset_iface.lpVtbl = &rowset_vtbl;
607 testrowset.IRowsetInfo_iface.lpVtbl = &rowset_info;
608 testrowset.IColumnsInfo_iface.lpVtbl = &column_info;
609 testrowset.refs = 1;
611 rowset = &testrowset.IRowset_iface;
613 ref = get_refcount( rowset );
614 ok( ref == 1, "got %d\n", ref );
615 hr = ADORecordsetConstruction_put_Rowset( construct, (IUnknown*)rowset );
616 ok( hr == S_OK, "got %08x\n", hr );
618 ref = get_refcount( rowset );
619 ok( ref == 2, "got %d\n", ref );
621 hr = _Recordset_get_Fields( recordset, &fields );
622 ok( hr == S_OK, "got %08x\n", hr );
623 ok( fields != NULL, "NULL value\n");
625 ref = get_refcount( rowset );
626 ok( ref == 2, "got %d\n", ref );
628 count = -1;
629 hr = Fields_get_Count( fields, &count );
630 ok( count == 1, "got %d\n", count );
631 if (count > 0)
633 VARIANT index;
634 LONG size;
635 DataTypeEnum type;
637 V_VT( &index ) = VT_BSTR;
638 V_BSTR( &index ) = SysAllocString( L"Column1" );
640 hr = Fields_get_Item( fields, index, &field );
641 ok( hr == S_OK, "got %08x\n", hr );
643 hr = Field_get_Type( field, &type );
644 ok( hr == S_OK, "got %08x\n", hr );
645 ok( type == adInteger, "got %d\n", type );
646 size = -1;
647 hr = Field_get_DefinedSize( field, &size );
648 ok( hr == S_OK, "got %08x\n", hr );
649 ok( size == 5, "got %d\n", size );
651 VariantClear(&index);
653 Field_Release(field);
656 ref = get_refcount(rowset);
657 ok( ref == 2, "got %d\n", ref );
659 Fields_Release(fields);
661 ADORecordsetConstruction_Release(construct);
663 done:
664 _Recordset_Release( recordset );
667 static void test_Fields(void)
669 _Recordset *recordset;
670 ISupportErrorInfo *errorinfo;
671 Fields *fields;
672 Field *field, *field2;
673 VARIANT val, index;
674 BSTR name;
675 LONG count, size;
676 DataTypeEnum type;
677 FieldAttributeEnum attrs;
678 HRESULT hr;
680 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
681 ok( hr == S_OK, "got %08x\n", hr );
683 hr = _Recordset_QueryInterface( recordset, &IID_Fields, (void **)&fields );
684 ok( hr == E_NOINTERFACE, "got %08x\n", hr );
686 hr = _Recordset_get_Fields( recordset, &fields );
687 ok( hr == S_OK, "got %08x\n", hr );
689 /* Fields object supports ISupportErrorInfo */
690 errorinfo = NULL;
691 hr = Fields_QueryInterface( fields, &IID_ISupportErrorInfo, (void **)&errorinfo );
692 ok( hr == S_OK, "got %08x\n", hr );
693 if (errorinfo) ISupportErrorInfo_Release( errorinfo );
695 count = -1;
696 hr = Fields_get_Count( fields, &count );
697 ok( !count, "got %d\n", count );
699 name = SysAllocString( L"field" );
700 V_VT( &val ) = VT_ERROR;
701 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
702 hr = Fields_Append( fields, name, adInteger, 4, adFldUnspecified, val );
703 ok( hr == S_OK, "got %08x\n", hr );
704 SysFreeString( name );
706 count = -1;
707 hr = Fields_get_Count( fields, &count );
708 ok( count == 1, "got %d\n", count );
710 name = SysAllocString( L"field2" );
711 hr = Fields__Append( fields, name, adInteger, 4, adFldUnspecified );
712 ok( hr == S_OK, "got %08x\n", hr );
713 SysFreeString( name );
715 count = -1;
716 hr = Fields_get_Count( fields, &count );
717 ok( count == 2, "got %d\n", count );
719 /* handing out field object doesn't add reference to fields or recordset object */
720 name = SysAllocString( L"field" );
721 V_VT( &index ) = VT_BSTR;
722 V_BSTR( &index ) = name;
723 hr = Fields_get_Item( fields, index, &field );
725 /* calling get_Item again returns the same object and adds reference */
726 hr = Fields_get_Item( fields, index, &field2 );
727 ok( hr == S_OK, "got %08x\n", hr );
728 ok( field2 == field, "expected same object\n" );
729 Field_Release( field2 );
730 SysFreeString( name );
732 /* Field object supports ISupportErrorInfo */
733 errorinfo = NULL;
734 hr = Field_QueryInterface( field, &IID_ISupportErrorInfo, (void **)&errorinfo );
735 ok( hr == S_OK, "got %08x\n", hr );
736 if (errorinfo) ISupportErrorInfo_Release( errorinfo );
738 /* verify values set with _Append */
739 hr = Field_get_Name( field, &name );
740 ok( hr == S_OK, "got %08x\n", hr );
741 ok( !lstrcmpW( name, L"field" ), "got %s\n", wine_dbgstr_w(name) );
742 SysFreeString( name );
743 type = 0xdead;
744 hr = Field_get_Type( field, &type );
745 ok( hr == S_OK, "got %08x\n", hr );
746 ok( type == adInteger, "got %d\n", type );
747 size = -1;
748 hr = Field_get_DefinedSize( field, &size );
749 ok( hr == S_OK, "got %08x\n", hr );
750 ok( size == 4, "got %d\n", size );
751 attrs = 0xdead;
752 hr = Field_get_Attributes( field, &attrs );
753 ok( hr == S_OK, "got %08x\n", hr );
754 ok( !attrs, "got %d\n", attrs );
756 Field_Release( field );
757 Fields_Release( fields );
758 _Recordset_Release( recordset );
761 static HRESULT str_to_byte_array( const char *data, VARIANT *ret )
763 SAFEARRAY *vector;
764 LONG i, len = strlen(data);
765 HRESULT hr;
767 if (!(vector = SafeArrayCreateVector( VT_UI1, 0, len ))) return E_OUTOFMEMORY;
768 for (i = 0; i < len; i++)
770 if ((hr = SafeArrayPutElement( vector, &i, (void *)&data[i] )) != S_OK)
772 SafeArrayDestroy( vector );
773 return hr;
777 V_VT( ret ) = VT_ARRAY | VT_UI1;
778 V_ARRAY( ret ) = vector;
779 return S_OK;
782 static void test_Stream(void)
784 _Stream *stream;
785 VARIANT_BOOL eos;
786 StreamTypeEnum type;
787 LineSeparatorEnum sep;
788 LONG refs, size, pos;
789 ObjectStateEnum state;
790 ConnectModeEnum mode;
791 BSTR charset, str;
792 VARIANT missing, val;
793 HRESULT hr;
795 hr = CoCreateInstance( &CLSID_Stream, NULL, CLSCTX_INPROC_SERVER, &IID__Stream, (void **)&stream );
796 ok( hr == S_OK, "got %08x\n", hr );
798 hr = _Stream_get_Size( stream, &size );
799 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
801 hr = _Stream_get_EOS( stream, &eos );
802 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
804 hr = _Stream_get_Position( stream, &pos );
805 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
807 hr = _Stream_put_Position( stream, 0 );
808 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
810 /* check default type */
811 type = 0;
812 hr = _Stream_get_Type( stream, &type );
813 ok( hr == S_OK, "got %08x\n", hr );
814 ok( type == adTypeText, "got %u\n", type );
816 hr = _Stream_put_Type( stream, adTypeBinary );
817 ok( hr == S_OK, "got %08x\n", hr );
819 type = 0;
820 hr = _Stream_get_Type( stream, &type );
821 ok( hr == S_OK, "got %08x\n", hr );
822 ok( type == adTypeBinary, "got %u\n", type );
824 /* revert */
825 hr = _Stream_put_Type( stream, adTypeText );
826 ok( hr == S_OK, "got %08x\n", hr );
828 sep = 0;
829 hr = _Stream_get_LineSeparator( stream, &sep );
830 ok( hr == S_OK, "got %08x\n", hr );
831 ok( sep == adCRLF, "got %d\n", sep );
833 hr = _Stream_put_LineSeparator( stream, adLF );
834 ok( hr == S_OK, "got %08x\n", hr );
836 state = 0xdeadbeef;
837 hr = _Stream_get_State( stream, &state );
838 ok( hr == S_OK, "got %08x\n", hr );
839 ok( state == adStateClosed, "got %u\n", state );
841 mode = 0xdeadbeef;
842 hr = _Stream_get_Mode( stream, &mode );
843 ok( hr == S_OK, "got %08x\n", hr );
844 ok( mode == adModeUnknown, "got %u\n", mode );
846 hr = _Stream_put_Mode( stream, adModeReadWrite );
847 ok( hr == S_OK, "got %08x\n", hr );
849 hr = _Stream_get_Charset( stream, &charset );
850 ok( hr == S_OK, "got %08x\n", hr );
851 ok( !lstrcmpW( charset, L"Unicode" ), "got %s\n", wine_dbgstr_w(charset) );
852 SysFreeString( charset );
854 str = SysAllocString( L"Unicode" );
855 hr = _Stream_put_Charset( stream, str );
856 ok( hr == S_OK, "got %08x\n", hr );
857 SysFreeString( str );
859 hr = _Stream_Read( stream, 2, &val );
860 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
862 V_VT( &missing ) = VT_ERROR;
863 V_ERROR( &missing ) = DISP_E_PARAMNOTFOUND;
864 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
865 ok( hr == S_OK, "got %08x\n", hr );
867 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
868 ok( hr == MAKE_ADO_HRESULT( adErrObjectOpen ), "got %08x\n", hr );
870 state = 0xdeadbeef;
871 hr = _Stream_get_State( stream, &state );
872 ok( hr == S_OK, "got %08x\n", hr );
873 ok( state == adStateOpen, "got %u\n", state );
875 size = -1;
876 hr = _Stream_get_Size( stream, &size );
877 ok( hr == S_OK, "got %08x\n", hr );
878 ok( !size, "got %d\n", size );
880 eos = VARIANT_FALSE;
881 hr = _Stream_get_EOS( stream, &eos );
882 ok( hr == S_OK, "got %08x\n", hr );
883 ok( eos == VARIANT_TRUE, "got %04x\n", eos );
885 pos = -1;
886 hr = _Stream_get_Position( stream, &pos );
887 ok( hr == S_OK, "got %08x\n", hr );
888 ok( !pos, "got %d\n", pos );
890 size = -1;
891 hr = _Stream_get_Size( stream, &size );
892 ok( hr == S_OK, "got %08x\n", hr );
893 ok( !size, "got %d\n", size );
895 hr = _Stream_Read( stream, 2, &val );
896 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08x\n", hr );
898 hr = _Stream_ReadText( stream, 2, &str );
899 ok( hr == S_OK, "got %08x\n", hr );
900 ok( !str[0], "got %s\n", wine_dbgstr_w(str) );
901 SysFreeString( str );
903 pos = -1;
904 hr = _Stream_get_Position( stream, &pos );
905 ok( hr == S_OK, "got %08x\n", hr );
906 ok( !pos, "got %d\n", pos );
908 str = SysAllocString( L"test" );
909 hr = _Stream_WriteText( stream, str, adWriteChar );
910 ok( hr == S_OK, "got %08x\n", hr );
911 SysFreeString( str );
913 hr = _Stream_ReadText( stream, adReadAll, &str );
914 ok( hr == S_OK, "got %08x\n", hr );
915 ok( !str[0], "got %s\n", wine_dbgstr_w(str) );
916 SysFreeString( str );
918 hr = _Stream_put_Position( stream, 0 );
919 ok( hr == S_OK, "got %08x\n", hr );
920 hr = _Stream_ReadText( stream, adReadAll, &str );
921 ok( hr == S_OK, "got %08x\n", hr );
922 ok( !lstrcmpW( str, L"test" ), "got %s\n", wine_dbgstr_w(str) );
923 SysFreeString( str );
925 pos = -1;
926 hr = _Stream_get_Position( stream, &pos );
927 ok( hr == S_OK, "got %08x\n", hr );
928 ok( pos == 10, "got %d\n", pos );
930 eos = VARIANT_FALSE;
931 hr = _Stream_get_EOS( stream, &eos );
932 ok( hr == S_OK, "got %08x\n", hr );
933 ok( eos == VARIANT_TRUE, "got %04x\n", eos );
935 hr = _Stream_put_Position( stream, 6 );
936 ok( hr == S_OK, "got %08x\n", hr );
938 size = -1;
939 hr = _Stream_get_Size( stream, &size );
940 ok( hr == S_OK, "got %08x\n", hr );
941 ok( size == 10, "got %d\n", size );
943 hr = _Stream_put_Position( stream, 2 );
944 ok( hr == S_OK, "got %08x\n", hr );
946 hr = _Stream_SetEOS( stream );
947 ok( hr == S_OK, "got %08x\n", hr );
949 pos = -1;
950 hr = _Stream_get_Position( stream, &pos );
951 ok( hr == S_OK, "got %08x\n", hr );
952 ok( pos == 2, "got %d\n", pos );
954 size = -1;
955 hr = _Stream_get_Size( stream, &size );
956 ok( hr == S_OK, "got %08x\n", hr );
957 ok( size == 2, "got %d\n", size );
959 hr = _Stream_Close( stream );
960 ok( hr == S_OK, "got %08x\n", hr );
962 state = 0xdeadbeef;
963 hr = _Stream_get_State( stream, &state );
964 ok( hr == S_OK, "got %08x\n", hr );
965 ok( state == adStateClosed, "got %u\n", state );
967 hr = _Stream_Close( stream );
968 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
970 refs = _Stream_Release( stream );
971 ok( !refs, "got %d\n", refs );
973 /* binary type */
974 hr = CoCreateInstance( &CLSID_Stream, NULL, CLSCTX_INPROC_SERVER, &IID__Stream, (void **)&stream );
975 ok( hr == S_OK, "got %08x\n", hr );
977 hr = _Stream_put_Type( stream, adTypeBinary );
978 ok( hr == S_OK, "got %08x\n", hr );
980 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
981 ok( hr == S_OK, "got %08x\n", hr );
983 hr = _Stream_ReadText( stream, adReadAll, &str );
984 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08x\n", hr );
986 str = SysAllocString( L"test" );
987 hr = _Stream_WriteText( stream, str, adWriteChar );
988 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08x\n", hr );
989 SysFreeString( str );
991 VariantInit( &val );
992 hr = _Stream_Read( stream, 1, &val );
993 ok( hr == S_OK, "got %08x\n", hr );
994 ok( V_VT( &val ) == VT_NULL, "got %u\n", V_VT( &val ) );
996 VariantInit( &val );
997 hr = _Stream_Write( stream, val );
998 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08x\n", hr );
1000 hr = str_to_byte_array( "data", &val );
1001 ok( hr == S_OK, "got %08x\n", hr );
1002 hr = _Stream_Write( stream, val );
1003 ok( hr == S_OK, "got %08x\n", hr );
1004 VariantClear( &val );
1006 pos = -1;
1007 hr = _Stream_get_Position( stream, &pos );
1008 ok( hr == S_OK, "got %08x\n", hr );
1009 ok( pos == 4, "got %d\n", pos );
1011 hr = _Stream_put_Position( stream, 0 );
1012 ok( hr == S_OK, "got %08x\n", hr );
1014 VariantInit( &val );
1015 hr = _Stream_Read( stream, adReadAll, &val );
1016 ok( hr == S_OK, "got %08x\n", hr );
1017 ok( V_VT( &val ) == (VT_ARRAY | VT_UI1), "got %04x\n", V_VT( &val ) );
1018 VariantClear( &val );
1020 pos = -1;
1021 hr = _Stream_get_Position( stream, &pos );
1022 ok( hr == S_OK, "got %08x\n", hr );
1023 ok( pos == 4, "got %d\n", pos );
1025 refs = _Stream_Release( stream );
1026 ok( !refs, "got %d\n", refs );
1029 static void test_Connection(void)
1031 HRESULT hr;
1032 _Connection *connection;
1033 IRunnableObject *runtime;
1034 ISupportErrorInfo *errorinfo;
1035 IConnectionPointContainer *pointcontainer;
1036 ADOConnectionConstruction15 *construct;
1037 LONG state, timeout;
1038 BSTR str, str2, str3;
1039 ConnectModeEnum mode;
1040 CursorLocationEnum location;
1042 hr = CoCreateInstance(&CLSID_Connection, NULL, CLSCTX_INPROC_SERVER, &IID__Connection, (void**)&connection);
1043 ok( hr == S_OK, "got %08x\n", hr );
1045 hr = _Connection_QueryInterface(connection, &IID_IRunnableObject, (void**)&runtime);
1046 ok(hr == E_NOINTERFACE, "Unexpected IRunnableObject interface\n");
1047 ok(runtime == NULL, "expected NULL\n");
1049 hr = _Connection_QueryInterface(connection, &IID_ISupportErrorInfo, (void**)&errorinfo);
1050 ok(hr == S_OK, "Failed to get ISupportErrorInfo interface\n");
1051 ISupportErrorInfo_Release(errorinfo);
1053 hr = _Connection_QueryInterface(connection, &IID_IConnectionPointContainer, (void**)&pointcontainer);
1054 ok(hr == S_OK, "Failed to get IConnectionPointContainer interface %08x\n", hr);
1055 IConnectionPointContainer_Release(pointcontainer);
1057 hr = _Connection_QueryInterface(connection, &IID_ADOConnectionConstruction15, (void**)&construct);
1058 ok(hr == S_OK, "Failed to get ADOConnectionConstruction15 interface %08x\n", hr);
1059 if (hr == S_OK)
1060 ADOConnectionConstruction15_Release(construct);
1062 if (0) /* Crashes on windows */
1064 hr = _Connection_get_State(connection, NULL);
1065 ok(hr == E_INVALIDARG, "Unexpected hr 0x%08x\n", hr);
1068 state = -1;
1069 hr = _Connection_get_State(connection, &state);
1070 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1071 ok(state == adStateClosed, "Unexpected state value 0x%08x\n", state);
1073 hr = _Connection_Close(connection);
1074 ok(hr == MAKE_ADO_HRESULT(adErrObjectClosed), "got %08x\n", hr);
1076 timeout = 0;
1077 hr = _Connection_get_CommandTimeout(connection, &timeout);
1078 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1079 ok(timeout == 30, "Unexpected timeout value %d\n", timeout);
1081 hr = _Connection_put_CommandTimeout(connection, 300);
1082 ok(hr == S_OK, "Failed to get state, hr 0x%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 == 300, "Unexpected timeout value %d\n", timeout);
1089 location = 0;
1090 hr = _Connection_get_CursorLocation(connection, &location);
1091 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1092 ok(location == adUseServer, "Unexpected location value %d\n", location);
1094 hr = _Connection_put_CursorLocation(connection, adUseClient);
1095 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1097 location = 0;
1098 hr = _Connection_get_CursorLocation(connection, &location);
1099 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1100 ok(location == adUseClient, "Unexpected location value %d\n", location);
1102 hr = _Connection_put_CursorLocation(connection, adUseServer);
1103 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1105 mode = 0xdeadbeef;
1106 hr = _Connection_get_Mode(connection, &mode);
1107 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1108 ok(mode == adModeUnknown, "Unexpected mode value %d\n", mode);
1110 hr = _Connection_put_Mode(connection, adModeShareDenyNone);
1111 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1113 mode = adModeUnknown;
1114 hr = _Connection_get_Mode(connection, &mode);
1115 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1116 ok(mode == adModeShareDenyNone, "Unexpected mode value %d\n", mode);
1118 hr = _Connection_put_Mode(connection, adModeUnknown);
1119 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
1121 /* Default */
1122 str = (BSTR)0xdeadbeef;
1123 hr = _Connection_get_Provider(connection, &str);
1124 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1125 ok(!wcscmp(str, L"MSDASQL"), "wrong string %s\n", wine_dbgstr_w(str));
1126 SysFreeString(str);
1128 str = SysAllocString(L"MSDASQL.1");
1129 hr = _Connection_put_Provider(connection, str);
1130 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1131 SysFreeString(str);
1133 str = (BSTR)0xdeadbeef;
1134 hr = _Connection_get_Provider(connection, &str);
1135 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1136 ok(!wcscmp(str, L"MSDASQL.1"), "wrong string %s\n", wine_dbgstr_w(str));
1138 /* Restore default */
1139 str = SysAllocString(L"MSDASQL");
1140 hr = _Connection_put_Provider(connection, str);
1141 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1142 SysFreeString(str);
1144 hr = _Connection_put_Provider(connection, NULL);
1145 ok(hr == MAKE_ADO_HRESULT(adErrInvalidArgument), "got 0x%08x\n", hr);
1146 SysFreeString(str);
1148 str = (BSTR)0xdeadbeef;
1149 hr = _Connection_get_ConnectionString(connection, &str);
1150 ok(hr == S_OK, "got 0x%08x\n", hr);
1151 ok(str == NULL, "got %p\n", str);
1153 str = SysAllocString(L"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_test");
1154 hr = _Connection_put_ConnectionString(connection, str);
1155 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1157 /* Show put_ConnectionString effects Provider */
1158 str3 = (BSTR)0xdeadbeef;
1159 hr = _Connection_get_Provider(connection, &str3);
1160 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1161 ok(str3 != NULL, "Expected value got NULL\n");
1162 todo_wine ok(!wcscmp(str3, L"MSDASQL.1"), "wrong string %s\n", wine_dbgstr_w(str3));
1163 SysFreeString(str3);
1165 if (0) /* Crashes on windows */
1167 hr = _Connection_get_ConnectionString(connection, NULL);
1168 ok(hr == E_POINTER, "Failed, hr 0x%08x\n", hr);
1171 str2 = NULL;
1172 hr = _Connection_get_ConnectionString(connection, &str2);
1173 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1174 ok(!wcscmp(str, str2), "wrong string %s\n", wine_dbgstr_w(str2));
1176 hr = _Connection_Open(connection, NULL, NULL, NULL, 0);
1177 ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr);
1179 /* Open adds trailing ; if it's missing */
1180 str3 = SysAllocString(L"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_test;");
1181 hr = _Connection_Open(connection, NULL, NULL, NULL, adConnectUnspecified);
1182 ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr);
1184 str2 = NULL;
1185 hr = _Connection_get_ConnectionString(connection, &str2);
1186 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1187 todo_wine ok(!wcscmp(str3, str2) || broken(!wcscmp(str, str2)) /* XP */, "wrong string %s\n", wine_dbgstr_w(str2));
1189 hr = _Connection_Open(connection, str, NULL, NULL, adConnectUnspecified);
1190 todo_wine ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr);
1191 SysFreeString(str);
1193 str2 = NULL;
1194 hr = _Connection_get_ConnectionString(connection, &str2);
1195 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1196 todo_wine ok(!wcscmp(str3, str2) || broken(!wcscmp(str, str2)) /* XP */, "wrong string %s\n", wine_dbgstr_w(str2));
1197 SysFreeString(str2);
1198 SysFreeString(str3);
1200 hr = _Connection_put_ConnectionString(connection, NULL);
1201 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1203 str = (BSTR)0xdeadbeef;
1204 hr = _Connection_get_ConnectionString(connection, &str);
1205 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
1206 ok(str == NULL, "got %p\n", str);
1207 _Connection_Release(connection);
1210 static void test_Command(void)
1212 HRESULT hr;
1213 _Command *command;
1214 _ADO *ado;
1215 Command15 *command15;
1216 Command25 *command25;
1217 CommandTypeEnum cmd_type = adCmdUnspecified;
1218 BSTR cmd_text = (BSTR)"test";
1219 _Connection *connection;
1221 hr = CoCreateInstance( &CLSID_Command, NULL, CLSCTX_INPROC_SERVER, &IID__Command, (void **)&command );
1222 ok( hr == S_OK, "got %08x\n", hr );
1224 hr = _Command_QueryInterface( command, &IID__ADO, (void **)&ado );
1225 ok( hr == S_OK, "got %08x\n", hr );
1226 _ADO_Release( ado );
1228 hr = _Command_QueryInterface( command, &IID_Command15, (void **)&command15 );
1229 ok( hr == S_OK, "got %08x\n", hr );
1230 Command15_Release( command15 );
1232 hr = _Command_QueryInterface( command, &IID_Command25, (void **)&command25 );
1233 ok( hr == S_OK, "got %08x\n", hr );
1234 Command25_Release( command25 );
1236 hr = _Command_get_CommandType( command, &cmd_type );
1237 ok( hr == S_OK, "got %08x\n", hr );
1238 ok( cmd_type == adCmdUnknown, "got %08x\n", cmd_type );
1240 _Command_put_CommandType( command, adCmdText );
1241 hr = _Command_get_CommandType( command, &cmd_type );
1242 ok( hr == S_OK, "got %08x\n", hr );
1243 ok( cmd_type == adCmdText, "got %08x\n", cmd_type );
1245 hr = _Command_put_CommandType( command, 0xdeadbeef );
1246 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08x\n", hr );
1248 hr = _Command_get_CommandText( command, &cmd_text );
1249 ok( hr == S_OK, "got %08x\n", hr );
1250 ok( !cmd_text, "got %s\n", wine_dbgstr_w( cmd_text ));
1252 hr = _Command_put_CommandText( command, NULL );
1253 ok( hr == S_OK, "got %08x\n", hr );
1255 cmd_text = SysAllocString( L"" );
1256 hr = _Command_put_CommandText( command, cmd_text );
1257 ok( hr == S_OK, "got %08x\n", hr );
1258 SysFreeString( cmd_text );
1260 hr = _Command_get_CommandText( command, &cmd_text );
1261 ok( hr == S_OK, "got %08x\n", hr );
1262 ok( cmd_text && !*cmd_text, "got %p\n", cmd_text );
1264 cmd_text = SysAllocString( L"test" );
1265 hr = _Command_put_CommandText( command, cmd_text );
1266 ok( hr == S_OK, "got %08x\n", hr );
1267 SysFreeString( cmd_text );
1269 hr = _Command_get_CommandText( command, &cmd_text );
1270 ok( hr == S_OK, "got %08x\n", hr );
1271 ok( !wcscmp( L"test", cmd_text ), "got %p\n", wine_dbgstr_w( cmd_text ) );
1273 connection = (_Connection*)0xdeadbeef;
1274 hr = _Command_get_ActiveConnection( command, &connection );
1275 ok( hr == S_OK, "got %08x\n", hr );
1276 ok( connection == NULL, "got %p\n", connection );
1278 hr = _Command_putref_ActiveConnection( command, NULL );
1279 ok( hr == S_OK, "got %08x\n", hr );
1281 _Command_Release( command );
1284 struct conn_event {
1285 ConnectionEventsVt conn_event_sink;
1286 LONG refs;
1289 static HRESULT WINAPI conneventvt_QueryInterface( ConnectionEventsVt *iface, REFIID riid, void **obj )
1291 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
1293 if (IsEqualGUID( &IID_ConnectionEventsVt, riid ))
1295 InterlockedIncrement( &conn_event->refs );
1296 *obj = iface;
1297 return S_OK;
1300 ok( 0, "unexpected call\n" );
1301 return E_NOINTERFACE;
1304 static ULONG WINAPI conneventvt_AddRef( ConnectionEventsVt *iface )
1306 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
1307 return InterlockedIncrement( &conn_event->refs );
1310 static ULONG WINAPI conneventvt_Release( ConnectionEventsVt *iface )
1312 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
1313 return InterlockedDecrement( &conn_event->refs );
1316 static HRESULT WINAPI conneventvt_InfoMessage( ConnectionEventsVt *iface, Error *error,
1317 EventStatusEnum *status, _Connection *Connection )
1319 return E_NOTIMPL;
1322 static HRESULT WINAPI conneventvt_BeginTransComplete( ConnectionEventsVt *iface, LONG TransactionLevel,
1323 Error *error, EventStatusEnum *status, _Connection *connection )
1325 return E_NOTIMPL;
1328 static HRESULT WINAPI conneventvt_CommitTransComplete( ConnectionEventsVt *iface, Error *error,
1329 EventStatusEnum *status, _Connection *connection )
1331 return E_NOTIMPL;
1334 static HRESULT WINAPI conneventvt_RollbackTransComplete( ConnectionEventsVt *iface, Error *error,
1335 EventStatusEnum *status, _Connection *connection )
1337 return E_NOTIMPL;
1340 static HRESULT WINAPI conneventvt_WillExecute( ConnectionEventsVt *iface, BSTR *source,
1341 CursorTypeEnum *cursor_type, LockTypeEnum *lock_type, LONG *options, EventStatusEnum *status,
1342 _Command *command, _Recordset *record_set, _Connection *connection )
1344 return E_NOTIMPL;
1347 static HRESULT WINAPI conneventvt_ExecuteComplete( ConnectionEventsVt *iface, LONG records_affected,
1348 Error *error, EventStatusEnum *status, _Command *command, _Recordset *record_set,
1349 _Connection *connection )
1351 return E_NOTIMPL;
1354 static HRESULT WINAPI conneventvt_WillConnect( ConnectionEventsVt *iface, BSTR *string, BSTR *userid,
1355 BSTR *password, LONG *options, EventStatusEnum *status, _Connection *connection )
1357 return E_NOTIMPL;
1360 static HRESULT WINAPI conneventvt_ConnectComplete( ConnectionEventsVt *iface, Error *error,
1361 EventStatusEnum *status, _Connection *connection )
1363 return E_NOTIMPL;
1366 static HRESULT WINAPI conneventvt_Disconnect( ConnectionEventsVt *iface, EventStatusEnum *status,
1367 _Connection *connection )
1369 return E_NOTIMPL;
1372 static const ConnectionEventsVtVtbl conneventvt_vtbl = {
1373 conneventvt_QueryInterface,
1374 conneventvt_AddRef,
1375 conneventvt_Release,
1376 conneventvt_InfoMessage,
1377 conneventvt_BeginTransComplete,
1378 conneventvt_CommitTransComplete,
1379 conneventvt_RollbackTransComplete,
1380 conneventvt_WillExecute,
1381 conneventvt_ExecuteComplete,
1382 conneventvt_WillConnect,
1383 conneventvt_ConnectComplete,
1384 conneventvt_Disconnect
1387 static HRESULT WINAPI supporterror_QueryInterface( ISupportErrorInfo *iface, REFIID riid, void **obj )
1389 if (IsEqualGUID( &IID_ISupportErrorInfo, riid ))
1391 *obj = iface;
1392 return S_OK;
1395 return E_NOINTERFACE;
1398 static ULONG WINAPI supporterror_AddRef( ISupportErrorInfo *iface )
1400 return 2;
1403 static ULONG WINAPI supporterror_Release( ISupportErrorInfo *iface )
1405 return 1;
1408 static HRESULT WINAPI supporterror_InterfaceSupportsErrorInfo( ISupportErrorInfo *iface, REFIID riid )
1410 return E_NOTIMPL;
1413 static const struct ISupportErrorInfoVtbl support_error_vtbl =
1415 supporterror_QueryInterface,
1416 supporterror_AddRef,
1417 supporterror_Release,
1418 supporterror_InterfaceSupportsErrorInfo
1421 static void test_ConnectionPoint(void)
1423 HRESULT hr;
1424 ULONG refs;
1425 DWORD cookie;
1426 IConnectionPoint *point;
1427 IConnectionPointContainer *pointcontainer;
1428 struct conn_event conn_event = { { &conneventvt_vtbl }, 0 };
1429 ISupportErrorInfo support_err_sink = { &support_error_vtbl };
1431 hr = CoCreateInstance( &CLSID_Connection, NULL, CLSCTX_INPROC_SERVER,
1432 &IID_IConnectionPointContainer, (void**)&pointcontainer );
1434 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_ConnectionEvents, NULL );
1435 ok( hr == E_POINTER, "got %08x\n", hr );
1437 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_RecordsetEvents, &point );
1438 ok( hr == CONNECT_E_NOCONNECTION, "got %08x\n", hr );
1440 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_ConnectionEvents, &point );
1441 ok( hr == S_OK, "got %08x\n", hr );
1443 /* nothing advised yet */
1444 hr = IConnectionPoint_Unadvise( point, 3 );
1445 ok( hr == E_FAIL, "got %08x\n", hr );
1447 hr = IConnectionPoint_Advise( point, NULL, NULL );
1448 ok( hr == E_FAIL, "got %08x\n", hr );
1450 hr = IConnectionPoint_Advise( point, (void*)&conn_event.conn_event_sink, NULL );
1451 ok( hr == E_FAIL, "got %08x\n", hr );
1453 cookie = 0xdeadbeef;
1454 hr = IConnectionPoint_Advise( point, NULL, &cookie );
1455 ok( hr == E_FAIL, "got %08x\n", hr );
1456 ok( cookie == 0xdeadbeef, "got %08x\n", cookie );
1458 /* unsupported sink */
1459 cookie = 0xdeadbeef;
1460 hr = IConnectionPoint_Advise( point, (void*)&support_err_sink, &cookie );
1461 ok( hr == E_FAIL, "got %08x\n", hr );
1462 ok( !cookie, "got %08x\n", cookie );
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 );
1469 /* invalid cookie */
1470 hr = IConnectionPoint_Unadvise( point, 0 );
1471 ok( hr == E_FAIL, "got %08x\n", hr );
1473 /* wrong cookie */
1474 hr = IConnectionPoint_Unadvise( point, cookie + 1 );
1475 ok( hr == E_FAIL, "got %08x\n", hr );
1477 hr = IConnectionPoint_Unadvise( point, cookie );
1478 ok( hr == S_OK, "got %08x\n", hr );
1480 /* sinks are released when the connection is destroyed */
1481 cookie = 0;
1482 hr = IConnectionPoint_Advise( point, (void*)&conn_event.conn_event_sink, &cookie );
1483 ok( hr == S_OK, "got %08x\n", hr );
1484 ok( cookie, "got %08x\n", cookie );
1485 ok( conn_event.refs == 1, "got %d\n", conn_event.refs );
1487 refs = IConnectionPoint_Release( point );
1488 ok( refs == 1, "got %u", refs );
1490 IConnectionPointContainer_Release( pointcontainer );
1492 ok( !conn_event.refs, "got %d\n", conn_event.refs );
1495 START_TEST(msado15)
1497 CoInitialize( NULL );
1498 test_Connection();
1499 test_ADORecordsetConstruction();
1500 test_ConnectionPoint();
1501 test_Fields();
1502 test_Recordset();
1503 test_Stream();
1504 test_Command();
1505 CoUninitialize();