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
24 #include <msado15_backcompat.h>
25 #include "wine/test.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
;
56 VARIANT missing
, val
, index
;
57 CursorLocationEnum location
;
58 CursorTypeEnum cursor
;
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 */
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" );
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
);
98 hr
= _Recordset_get_State( recordset
, &state
);
99 ok( hr
== S_OK
, "got %08x\n", hr
);
100 ok( state
== adStateClosed
, "got %d\n", state
);
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
;
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
;
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
;
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
);
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
);
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
);
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" );
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
);
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
;
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 */
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
);
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
);
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);
330 IRowset IRowset_iface
;
331 IRowsetInfo IRowsetInfo_iface
;
332 IColumnsInfo IColumnsInfo_iface
;
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
);
383 static HRESULT WINAPI
rowset_info_GetReferencedRowset(IRowsetInfo
*iface
, DBORDINAL ordinal
,
384 REFIID riid
, IUnknown
**unk
)
386 ok(0, "Unexpected call\n");
390 static HRESULT WINAPI
rowset_info_GetSpecification(IRowsetInfo
*iface
, REFIID riid
,
391 IUnknown
**specification
)
393 ok(0, "Unexpected call\n");
397 static const struct IRowsetInfoVtbl rowset_info
=
399 rowset_info_QueryInterface
,
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
;
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
;
452 static HRESULT WINAPI
column_info_MapColumnIDs(IColumnsInfo
*This
, DBORDINAL column_ids
,
453 const DBID
*dbids
, DBORDINAL
*columns
)
455 ok(0, "Unexpected call\n");
459 static const struct IColumnsInfoVtbl column_info
=
461 column_info_QueryInterface
,
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
);
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
;
512 IUnknown_AddRef((IUnknown
*)*obj
);
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");
540 static HRESULT WINAPI
rowset_GetData(IRowset
*iface
, HROW hRow
, HACCESSOR hAccessor
, void *pData
)
542 ok(0, "Unexpected call\n");
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");
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");
560 static HRESULT WINAPI
rowset_RestartPosition(IRowset
*iface
, HCHAPTER hReserved
)
562 ok(0, "Unexpected call\n");
566 static const struct IRowsetVtbl rowset_vtbl
=
568 rowset_QueryInterface
,
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
;
591 struct test_rowset testrowset
;
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
);
606 testrowset
.IRowset_iface
.lpVtbl
= &rowset_vtbl
;
607 testrowset
.IRowsetInfo_iface
.lpVtbl
= &rowset_info
;
608 testrowset
.IColumnsInfo_iface
.lpVtbl
= &column_info
;
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
);
629 hr
= Fields_get_Count( fields
, &count
);
630 ok( count
== 1, "got %d\n", count
);
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
);
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
);
664 _Recordset_Release( recordset
);
667 static void test_Fields(void)
669 _Recordset
*recordset
;
670 ISupportErrorInfo
*errorinfo
;
672 Field
*field
, *field2
;
677 FieldAttributeEnum attrs
;
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 */
691 hr
= Fields_QueryInterface( fields
, &IID_ISupportErrorInfo
, (void **)&errorinfo
);
692 ok( hr
== S_OK
, "got %08x\n", hr
);
693 if (errorinfo
) ISupportErrorInfo_Release( errorinfo
);
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
);
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
);
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 */
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
);
744 hr
= Field_get_Type( field
, &type
);
745 ok( hr
== S_OK
, "got %08x\n", hr
);
746 ok( type
== adInteger
, "got %d\n", type
);
748 hr
= Field_get_DefinedSize( field
, &size
);
749 ok( hr
== S_OK
, "got %08x\n", hr
);
750 ok( size
== 4, "got %d\n", size
);
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
)
764 LONG i
, len
= strlen(data
);
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
);
777 V_VT( ret
) = VT_ARRAY
| VT_UI1
;
778 V_ARRAY( ret
) = vector
;
782 static void test_Stream(void)
787 LineSeparatorEnum sep
;
788 LONG refs
, size
, pos
;
789 ObjectStateEnum state
;
790 ConnectModeEnum mode
;
792 VARIANT missing
, val
;
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 */
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
);
820 hr
= _Stream_get_Type( stream
, &type
);
821 ok( hr
== S_OK
, "got %08x\n", hr
);
822 ok( type
== adTypeBinary
, "got %u\n", type
);
825 hr
= _Stream_put_Type( stream
, adTypeText
);
826 ok( hr
== S_OK
, "got %08x\n", hr
);
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
);
837 hr
= _Stream_get_State( stream
, &state
);
838 ok( hr
== S_OK
, "got %08x\n", hr
);
839 ok( state
== adStateClosed
, "got %u\n", state
);
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
);
871 hr
= _Stream_get_State( stream
, &state
);
872 ok( hr
== S_OK
, "got %08x\n", hr
);
873 ok( state
== adStateOpen
, "got %u\n", state
);
876 hr
= _Stream_get_Size( stream
, &size
);
877 ok( hr
== S_OK
, "got %08x\n", hr
);
878 ok( !size
, "got %d\n", size
);
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
);
886 hr
= _Stream_get_Position( stream
, &pos
);
887 ok( hr
== S_OK
, "got %08x\n", hr
);
888 ok( !pos
, "got %d\n", pos
);
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
);
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
);
926 hr
= _Stream_get_Position( stream
, &pos
);
927 ok( hr
== S_OK
, "got %08x\n", hr
);
928 ok( pos
== 10, "got %d\n", pos
);
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
);
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
);
950 hr
= _Stream_get_Position( stream
, &pos
);
951 ok( hr
== S_OK
, "got %08x\n", hr
);
952 ok( pos
== 2, "got %d\n", pos
);
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
);
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
);
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
);
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
) );
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
);
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
);
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)
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
));
1128 str
= SysAllocString(L
"MSDASQL.1");
1129 hr
= _Connection_put_Provider(connection
, str
);
1130 ok(hr
== S_OK
, "Failed, hr 0x%08x\n", hr
);
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
);
1144 hr
= _Connection_put_Provider(connection
, NULL
);
1145 ok(hr
== MAKE_ADO_HRESULT(adErrInvalidArgument
), "got 0x%08x\n", hr
);
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
);
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
);
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
);
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)
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
);
1285 ConnectionEventsVt conn_event_sink
;
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
);
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
)
1322 static HRESULT WINAPI
conneventvt_BeginTransComplete( ConnectionEventsVt
*iface
, LONG TransactionLevel
,
1323 Error
*error
, EventStatusEnum
*status
, _Connection
*connection
)
1328 static HRESULT WINAPI
conneventvt_CommitTransComplete( ConnectionEventsVt
*iface
, Error
*error
,
1329 EventStatusEnum
*status
, _Connection
*connection
)
1334 static HRESULT WINAPI
conneventvt_RollbackTransComplete( ConnectionEventsVt
*iface
, Error
*error
,
1335 EventStatusEnum
*status
, _Connection
*connection
)
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
)
1347 static HRESULT WINAPI
conneventvt_ExecuteComplete( ConnectionEventsVt
*iface
, LONG records_affected
,
1348 Error
*error
, EventStatusEnum
*status
, _Command
*command
, _Recordset
*record_set
,
1349 _Connection
*connection
)
1354 static HRESULT WINAPI
conneventvt_WillConnect( ConnectionEventsVt
*iface
, BSTR
*string
, BSTR
*userid
,
1355 BSTR
*password
, LONG
*options
, EventStatusEnum
*status
, _Connection
*connection
)
1360 static HRESULT WINAPI
conneventvt_ConnectComplete( ConnectionEventsVt
*iface
, Error
*error
,
1361 EventStatusEnum
*status
, _Connection
*connection
)
1366 static HRESULT WINAPI
conneventvt_Disconnect( ConnectionEventsVt
*iface
, EventStatusEnum
*status
,
1367 _Connection
*connection
)
1372 static const ConnectionEventsVtVtbl conneventvt_vtbl
= {
1373 conneventvt_QueryInterface
,
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
))
1395 return E_NOINTERFACE
;
1398 static ULONG WINAPI
supporterror_AddRef( ISupportErrorInfo
*iface
)
1403 static ULONG WINAPI
supporterror_Release( ISupportErrorInfo
*iface
)
1408 static HRESULT WINAPI
supporterror_InterfaceSupportsErrorInfo( ISupportErrorInfo
*iface
, REFIID riid
)
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)
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
);
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
);
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 */
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
);
1497 CoInitialize( NULL
);
1499 test_ADORecordsetConstruction();
1500 test_ConnectionPoint();