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