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 ADO_LONGPTR rec_count
;
57 VARIANT missing
, val
, index
;
58 CursorLocationEnum location
;
59 CursorTypeEnum cursor
;
62 VARIANT bookmark
, filter
;
63 EditModeEnum editmode
;
65 hr
= CoCreateInstance( &CLSID_Recordset
, NULL
, CLSCTX_INPROC_SERVER
, &IID__Recordset
, (void **)&recordset
);
66 ok( hr
== S_OK
, "got %08lx\n", hr
);
68 hr
= _Recordset_QueryInterface( recordset
, &IID_IRunnableObject
, (void**)&runtime
);
69 ok(hr
== E_NOINTERFACE
, "Unexpected IRunnableObject interface\n");
70 ok(runtime
== NULL
, "expected NULL\n");
72 /* _Recordset object supports ISupportErrorInfo */
74 hr
= _Recordset_QueryInterface( recordset
, &IID_ISupportErrorInfo
, (void **)&errorinfo
);
75 ok( hr
== S_OK
, "got %08lx\n", hr
);
76 if (errorinfo
) ISupportErrorInfo_Release( errorinfo
);
78 hr
= _Recordset_get_Fields( recordset
, &fields
);
79 ok( hr
== S_OK
, "got %08lx\n", hr
);
81 /* calling get_Fields again returns the same object */
82 hr
= _Recordset_get_Fields( recordset
, &fields2
);
83 ok( hr
== S_OK
, "got %08lx\n", hr
);
84 ok( fields2
== fields
, "expected same object\n" );
87 hr
= Fields_get_Count( fields2
, &count
);
88 ok( hr
== S_OK
, "got %08lx\n", hr
);
89 ok( !count
, "got %ld\n", count
);
91 hr
= _Recordset_Close( recordset
);
92 ok( hr
== MAKE_ADO_HRESULT( adErrObjectClosed
), "got %08lx\n", hr
);
94 Fields_Release( fields2
);
96 hr
= CoCreateInstance( &CLSID_Recordset
, NULL
, CLSCTX_INPROC_SERVER
, &IID__Recordset
, (void **)&recordset
);
97 ok( hr
== S_OK
, "got %08lx\n", hr
);
100 hr
= _Recordset_get_State( recordset
, &state
);
101 ok( hr
== S_OK
, "got %08lx\n", hr
);
102 ok( state
== adStateClosed
, "got %ld\n", state
);
105 hr
= _Recordset_get_CursorLocation( recordset
, &location
);
106 ok( hr
== S_OK
, "got %08lx\n", hr
);
107 ok( location
== adUseServer
, "got %d\n", location
);
109 cursor
= adOpenUnspecified
;
110 hr
= _Recordset_get_CursorType( recordset
, &cursor
);
111 ok( hr
== S_OK
, "got %08lx\n", hr
);
112 ok( cursor
== adOpenForwardOnly
, "got %d\n", cursor
);
115 hr
= _Recordset_get_EditMode( recordset
, &editmode
);
116 ok( hr
== MAKE_ADO_HRESULT( adErrObjectClosed
), "got %08lx\n", hr
);
118 VariantInit( &bookmark
);
119 hr
= _Recordset_get_Bookmark( recordset
, &bookmark
);
120 ok( hr
== MAKE_ADO_HRESULT( adErrObjectClosed
), "got %08lx\n", hr
);
122 VariantInit( &bookmark
);
123 hr
= _Recordset_put_Bookmark( recordset
, bookmark
);
124 ok( hr
== MAKE_ADO_HRESULT( adErrObjectClosed
), "got %08lx\n", hr
);
126 VariantInit( &filter
);
127 hr
= _Recordset_put_Filter( recordset
, filter
);
128 ok( hr
== MAKE_ADO_HRESULT( adErrInvalidArgument
), "got %08lx\n", hr
);
130 V_VT(&filter
) = VT_BSTR
;
131 V_BSTR(&filter
) = SysAllocString( L
"field1 = 1" );
132 hr
= _Recordset_put_Filter( recordset
, filter
);
133 ok( hr
== S_OK
, "got %08lx\n", hr
);
134 VariantClear(&filter
);
136 V_VT(&filter
) = VT_I4
;
138 hr
= _Recordset_put_Filter( recordset
, filter
);
139 ok( hr
== S_OK
, "got %08lx\n", hr
);
141 V_VT(&filter
) = VT_I2
;
143 hr
= _Recordset_put_Filter( recordset
, filter
);
144 ok( hr
== S_OK
, "got %08lx\n", hr
);
146 VariantInit( &missing
);
147 hr
= _Recordset_AddNew( recordset
, missing
, missing
);
148 ok( hr
== MAKE_ADO_HRESULT( adErrObjectClosed
), "got %08lx\n", hr
);
150 V_VT( &missing
) = VT_ERROR
;
151 V_ERROR( &missing
) = DISP_E_PARAMNOTFOUND
;
152 hr
= _Recordset_Open( recordset
, missing
, missing
, adOpenStatic
, adLockBatchOptimistic
, adCmdUnspecified
);
153 ok( hr
== MAKE_ADO_HRESULT( adErrInvalidConnection
), "got %08lx\n", hr
);
155 hr
= _Recordset_get_Fields( recordset
, &fields
);
156 ok( hr
== S_OK
, "got %08lx\n", hr
);
158 name
= SysAllocString( L
"field" );
159 hr
= Fields__Append( fields
, name
, adInteger
, 4, adFldUnspecified
);
160 ok( hr
== S_OK
, "got %08lx\n", hr
);
162 V_VT( &index
) = VT_I4
;
163 V_I4( &index
) = 1000;
164 hr
= Fields_get_Item( fields
, index
, &field
);
165 ok( hr
== MAKE_ADO_HRESULT(adErrItemNotFound
), "got %08lx\n", hr
);
167 V_VT( &index
) = VT_I4
;
169 hr
= Fields_get_Item( fields
, index
, &field
);
170 ok( hr
== S_OK
, "got %08lx\n", hr
);
171 Field_Release(field
);
173 V_VT( &index
) = VT_I2
;
175 hr
= Fields_get_Item( fields
, index
, &field
);
176 ok( hr
== S_OK
, "got %08lx\n", hr
);
177 Field_Release(field
);
179 V_VT( &index
) = VT_I1
;
181 hr
= Fields_get_Item( fields
, index
, &field
);
182 ok( hr
== S_OK
, "got %08lx\n", hr
);
183 Field_Release(field
);
185 V_VT( &index
) = VT_R8
;
186 V_R8( &index
) = 0.1;
187 hr
= Fields_get_Item( fields
, index
, &field
);
188 ok( hr
== S_OK
, "got %08lx\n", hr
);
189 Field_Release(field
);
191 V_VT( &index
) = VT_UNKNOWN
;
192 V_UNKNOWN( &index
) = NULL
;
193 hr
= Fields_get_Item( fields
, index
, &field
);
194 ok( hr
== MAKE_ADO_HRESULT(adErrItemNotFound
), "got %08lx\n", hr
);
196 V_VT( &index
) = VT_BSTR
;
197 V_BSTR( &index
) = name
;
198 hr
= Fields_get_Item( fields
, index
, &field
);
199 ok( hr
== S_OK
, "got %08lx\n", hr
);
200 SysFreeString( name
);
202 hr
= Field_QueryInterface(field
, &IID_Properties
, (void**)&props
);
203 ok( hr
== E_NOINTERFACE
, "got %08lx\n", hr
);
205 hr
= Field_get_Properties(field
, &props
);
206 ok( hr
== S_OK
, "got %08lx\n", hr
);
209 hr
= Properties_get_Count(props
, &count
);
210 ok( hr
== S_OK
, "got %08lx\n", hr
);
211 ok( !count
, "got %ld\n", count
);
213 V_VT( &index
) = VT_I4
;
214 V_I4( &index
) = 1000;
215 hr
= Properties_get_Item(props
, index
, &prop
);
216 ok( hr
== MAKE_ADO_HRESULT(adErrItemNotFound
), "got %08lx\n", hr
);
218 Properties_Release(props
);
220 hr
= _Recordset_Open( recordset
, missing
, missing
, adOpenStatic
, adLockBatchOptimistic
, adCmdUnspecified
);
221 ok( hr
== S_OK
, "got %08lx\n", hr
);
222 ok( is_eof( recordset
), "not eof\n" );
223 ok( is_bof( recordset
), "not bof\n" );
226 hr
= _Recordset_get_EditMode( recordset
, &editmode
);
227 ok( hr
== MAKE_ADO_HRESULT( adErrNoCurrentRecord
), "got %08lx\n", hr
);
229 hr
= _Recordset_Open( recordset
, missing
, missing
, adOpenStatic
, adLockBatchOptimistic
, adCmdUnspecified
);
230 ok( hr
== MAKE_ADO_HRESULT( adErrObjectOpen
), "got %08lx\n", hr
);
233 hr
= _Recordset_get_State( recordset
, &state
);
234 ok( hr
== S_OK
, "got %08lx\n", hr
);
235 ok( state
== adStateOpen
, "got %ld\n", state
);
237 VariantInit( &bookmark
);
238 hr
= _Recordset_get_Bookmark( recordset
, &bookmark
);
239 ok( hr
== MAKE_ADO_HRESULT( adErrNoCurrentRecord
), "got %08lx\n", hr
);
241 VariantInit( &bookmark
);
242 hr
= _Recordset_put_Bookmark( recordset
, bookmark
);
243 ok( hr
== MAKE_ADO_HRESULT( adErrInvalidArgument
), "got %08lx\n", hr
);
246 hr
= _Recordset_get_RecordCount( recordset
, &rec_count
);
247 ok( hr
== S_OK
, "got %08lx\n", hr
);
248 ok( !rec_count
, "got %Id\n", rec_count
);
250 hr
= _Recordset_AddNew( recordset
, missing
, missing
);
251 ok( hr
== S_OK
, "got %08lx\n", hr
);
252 ok( !is_eof( recordset
), "eof\n" );
253 ok( !is_bof( recordset
), "bof\n" );
256 hr
= _Recordset_get_EditMode( recordset
, &editmode
);
257 ok( hr
== S_OK
, "got %08lx\n", hr
);
258 todo_wine
ok( editmode
== adEditAdd
, "got %d\n", editmode
);
261 hr
= _Recordset_get_RecordCount( recordset
, &rec_count
);
262 ok( hr
== S_OK
, "got %08lx\n", hr
);
263 ok( rec_count
== 1, "got %Id\n", rec_count
);
265 /* get_Fields still returns the same object */
266 hr
= _Recordset_get_Fields( recordset
, &fields2
);
267 ok( hr
== S_OK
, "got %08lx\n", hr
);
268 ok( fields2
== fields
, "expected same object\n" );
269 Fields_Release( fields2
);
271 V_VT(&filter
) = VT_BSTR
;
272 V_BSTR(&filter
) = SysAllocString( L
"field1 = 1" );
273 hr
= _Recordset_put_Filter( recordset
, filter
);
274 todo_wine
ok( hr
== MAKE_ADO_HRESULT( adErrItemNotFound
), "got %08lx\n", hr
);
275 VariantClear(&filter
);
277 V_VT(&filter
) = VT_BSTR
;
278 V_BSTR(&filter
) = SysAllocString( L
"field = 1" );
279 hr
= _Recordset_put_Filter( recordset
, filter
);
280 ok( hr
== S_OK
, "got %08lx\n", hr
);
281 VariantClear(&filter
);
283 V_VT(&filter
) = VT_I4
;
285 hr
= _Recordset_put_Filter( recordset
, filter
);
286 ok( hr
== S_OK
, "got %08lx\n", hr
);
289 hr
= Fields_get_Count( fields2
, &count
);
290 ok( count
== 1, "got %ld\n", count
);
292 hr
= Field_get_Value( field
, &val
);
293 ok( hr
== S_OK
, "got %08lx\n", hr
);
294 ok( V_VT( &val
) == VT_EMPTY
, "got %u\n", V_VT( &val
) );
296 V_VT( &val
) = VT_I4
;
298 hr
= Field_put_Value( field
, val
);
299 ok( hr
== S_OK
, "got %08lx\n", hr
);
301 V_VT( &val
) = VT_ERROR
;
302 V_ERROR( &val
) = DISP_E_PARAMNOTFOUND
;
303 hr
= Field_get_Value( field
, &val
);
304 ok( hr
== S_OK
, "got %08lx\n", hr
);
305 ok( V_VT( &val
) == VT_I4
, "got %u\n", V_VT( &val
) );
306 ok( V_I4( &val
) == -1, "got %ld\n", V_I4( &val
) );
308 hr
= _Recordset_AddNew( recordset
, missing
, missing
);
309 ok( hr
== S_OK
, "got %08lx\n", hr
);
311 /* field object returns different value after AddNew */
312 V_VT( &val
) = VT_ERROR
;
313 V_ERROR( &val
) = DISP_E_PARAMNOTFOUND
;
314 hr
= Field_get_Value( field
, &val
);
315 ok( hr
== S_OK
, "got %08lx\n", hr
);
316 ok( V_VT( &val
) == VT_EMPTY
, "got %u\n", V_VT( &val
) );
318 ok( !is_eof( recordset
), "eof\n" );
319 ok( !is_bof( recordset
), "bof\n" );
320 hr
= _Recordset_MoveFirst( recordset
);
321 ok( hr
== S_OK
, "got %08lx\n", hr
);
322 ok( !is_eof( recordset
), "eof\n" );
323 ok( !is_bof( recordset
), "bof\n" );
325 V_VT( &val
) = VT_ERROR
;
326 V_ERROR( &val
) = DISP_E_PARAMNOTFOUND
;
327 hr
= Field_get_Value( field
, &val
);
328 ok( hr
== S_OK
, "got %08lx\n", hr
);
329 ok( V_VT( &val
) == VT_I4
, "got %u\n", V_VT( &val
) );
330 ok( V_I4( &val
) == -1, "got %ld\n", V_I4( &val
) );
332 hr
= _Recordset_MoveNext( recordset
);
333 ok( hr
== S_OK
, "got %08lx\n", hr
);
334 ok( !is_eof( recordset
), "eof\n" );
335 ok( !is_bof( recordset
), "not bof\n" );
337 hr
= _Recordset_MoveNext( recordset
);
338 ok( hr
== S_OK
, "got %08lx\n", hr
);
339 ok( is_eof( recordset
), "not eof\n" );
340 ok( !is_bof( recordset
), "bof\n" );
342 hr
= _Recordset_MoveFirst( recordset
);
343 ok( hr
== S_OK
, "got %08lx\n", hr
);
344 ok( !is_eof( recordset
), "eof\n" );
345 ok( !is_bof( recordset
), "bof\n" );
347 hr
= _Recordset_MovePrevious( recordset
);
348 ok( hr
== S_OK
, "got %08lx\n", hr
);
349 ok( !is_eof( recordset
), "eof\n" );
350 ok( is_bof( recordset
), "not bof\n" );
352 /* try get value at BOF */
354 hr
= Field_get_Value( field
, &val
);
355 ok( hr
== MAKE_ADO_HRESULT( adErrNoCurrentRecord
), "got %08lx\n", hr
);
357 hr
= _Recordset_Close( recordset
);
358 ok( hr
== S_OK
, "got %08lx\n", hr
);
361 hr
= Fields_get_Count( fields
, &count
);
362 ok( !count
, "got %ld\n", count
);
364 hr
= Field_get_Name(field
, &name
);
365 todo_wine
ok( hr
== MAKE_ADO_HRESULT( adErrObjectNotSet
), "got %08lx\n", hr
);
368 hr
= _Recordset_get_State( recordset
, &state
);
369 ok( hr
== S_OK
, "got %08lx\n", hr
);
370 ok( state
== adStateClosed
, "got %ld\n", state
);
372 Field_Release( field
);
373 Fields_Release( fields
);
374 _Recordset_Release( recordset
);
377 /* This interface is queried for but is not documented anywhere. */
378 DEFINE_GUID(UKN_INTERFACE
, 0x6f1e39e1, 0x05c6, 0x11d0, 0xa7, 0x8b, 0x00, 0xaa, 0x00, 0xa3, 0xf0, 0x0d);
382 IRowset IRowset_iface
;
383 IRowsetInfo IRowsetInfo_iface
;
384 IColumnsInfo IColumnsInfo_iface
;
388 static inline struct test_rowset
*impl_from_IRowset( IRowset
*iface
)
390 return CONTAINING_RECORD( iface
, struct test_rowset
, IRowset_iface
);
393 static inline struct test_rowset
*impl_from_IRowsetInfo( IRowsetInfo
*iface
)
395 return CONTAINING_RECORD( iface
, struct test_rowset
, IRowsetInfo_iface
);
398 static inline struct test_rowset
*impl_from_IColumnsInfo( IColumnsInfo
*iface
)
400 return CONTAINING_RECORD( iface
, struct test_rowset
, IColumnsInfo_iface
);
403 static HRESULT WINAPI
rowset_info_QueryInterface(IRowsetInfo
*iface
, REFIID riid
, void **obj
)
405 struct test_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
406 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, obj
);
409 static ULONG WINAPI
rowset_info_AddRef(IRowsetInfo
*iface
)
411 struct test_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
412 return IRowset_AddRef(&rowset
->IRowset_iface
);
415 static ULONG WINAPI
rowset_info_Release(IRowsetInfo
*iface
)
417 struct test_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
418 return IRowset_Release(&rowset
->IRowset_iface
);
421 static HRESULT WINAPI
rowset_info_GetProperties(IRowsetInfo
*iface
, const ULONG count
,
422 const DBPROPIDSET propertyidsets
[], ULONG
*out_count
, DBPROPSET
**propertysets1
)
424 ok( count
== 2, "got %ld\n", count
);
426 ok( IsEqualIID(&DBPROPSET_ROWSET
, &propertyidsets
[0].guidPropertySet
), "got %s\n", wine_dbgstr_guid(&propertyidsets
[0].guidPropertySet
));
427 ok( propertyidsets
[0].cPropertyIDs
== 17, "got %ld\n", propertyidsets
[0].cPropertyIDs
);
429 ok( IsEqualIID(&DBPROPSET_PROVIDERROWSET
, &propertyidsets
[1].guidPropertySet
), "got %s\n", wine_dbgstr_guid(&propertyidsets
[1].guidPropertySet
));
430 ok( propertyidsets
[1].cPropertyIDs
== 1, "got %ld\n", propertyidsets
[1].cPropertyIDs
);
435 static HRESULT WINAPI
rowset_info_GetReferencedRowset(IRowsetInfo
*iface
, DBORDINAL ordinal
,
436 REFIID riid
, IUnknown
**unk
)
438 ok(0, "Unexpected call\n");
442 static HRESULT WINAPI
rowset_info_GetSpecification(IRowsetInfo
*iface
, REFIID riid
,
443 IUnknown
**specification
)
445 ok(0, "Unexpected call\n");
449 static const struct IRowsetInfoVtbl rowset_info
=
451 rowset_info_QueryInterface
,
454 rowset_info_GetProperties
,
455 rowset_info_GetReferencedRowset
,
456 rowset_info_GetSpecification
459 static HRESULT WINAPI
column_info_QueryInterface(IColumnsInfo
*iface
, REFIID riid
, void **obj
)
461 struct test_rowset
*rowset
= impl_from_IColumnsInfo( iface
);
462 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, obj
);
465 static ULONG WINAPI
column_info_AddRef(IColumnsInfo
*iface
)
467 struct test_rowset
*rowset
= impl_from_IColumnsInfo( iface
);
468 return IRowset_AddRef(&rowset
->IRowset_iface
);
471 static ULONG WINAPI
column_info_Release(IColumnsInfo
*iface
)
473 struct test_rowset
*rowset
= impl_from_IColumnsInfo( iface
);
474 return IRowset_Release(&rowset
->IRowset_iface
);
477 static HRESULT WINAPI
column_info_GetColumnInfo(IColumnsInfo
*This
, DBORDINAL
*columns
,
478 DBCOLUMNINFO
**colinfo
, OLECHAR
**stringsbuffer
)
480 DBCOLUMNINFO
*dbcolumn
;
483 *stringsbuffer
= CoTaskMemAlloc(sizeof(L
"Column1"));
484 lstrcpyW(*stringsbuffer
, L
"Column1");
486 dbcolumn
= CoTaskMemAlloc(sizeof(DBCOLUMNINFO
));
488 dbcolumn
->pwszName
= *stringsbuffer
;
489 dbcolumn
->pTypeInfo
= NULL
;
490 dbcolumn
->iOrdinal
= 1;
491 dbcolumn
->dwFlags
= DBCOLUMNFLAGS_MAYBENULL
;
492 dbcolumn
->ulColumnSize
= 5;
493 dbcolumn
->wType
= DBTYPE_I4
;
494 dbcolumn
->bPrecision
= 1;
495 dbcolumn
->bScale
= 1;
496 dbcolumn
->columnid
.eKind
= DBKIND_NAME
;
497 dbcolumn
->columnid
.uName
.pwszName
= *stringsbuffer
;
504 static HRESULT WINAPI
column_info_MapColumnIDs(IColumnsInfo
*This
, DBORDINAL column_ids
,
505 const DBID
*dbids
, DBORDINAL
*columns
)
507 ok(0, "Unexpected call\n");
511 static const struct IColumnsInfoVtbl column_info
=
513 column_info_QueryInterface
,
516 column_info_GetColumnInfo
,
517 column_info_MapColumnIDs
,
520 static HRESULT WINAPI
rowset_QueryInterface(IRowset
*iface
, REFIID riid
, void **obj
)
522 struct test_rowset
*rowset
= impl_from_IRowset( iface
);
526 if (IsEqualIID(riid
, &IID_IRowset
) ||
527 IsEqualIID(riid
, &IID_IUnknown
))
529 trace("Requested interface IID_IRowset\n");
530 *obj
= &rowset
->IRowset_iface
;
532 else if (IsEqualIID(riid
, &IID_IRowsetInfo
))
534 trace("Requested interface IID_IRowsetInfo\n");
535 *obj
= &rowset
->IRowsetInfo_iface
;
537 else if (IsEqualIID(riid
, &IID_IColumnsInfo
))
539 trace("Requested interface IID_IColumnsInfo\n");
540 *obj
= &rowset
->IColumnsInfo_iface
;
542 else if (IsEqualIID(riid
, &IID_IRowsetLocate
))
544 trace("Requested interface IID_IRowsetLocate\n");
545 return E_NOINTERFACE
;
547 else if (IsEqualIID(riid
, &IID_IDBAsynchStatus
))
549 trace("Requested interface IID_IDBAsynchStatus\n");
550 return E_NOINTERFACE
;
552 else if (IsEqualIID(riid
, &IID_IAccessor
))
554 trace("Requested interface IID_IAccessor\n");
555 return E_NOINTERFACE
;
557 else if (IsEqualIID(riid
, &UKN_INTERFACE
))
559 trace("Unknown interface\n");
560 return E_NOINTERFACE
;
564 IUnknown_AddRef((IUnknown
*)*obj
);
568 ok(0, "Unsupported interface %s\n", wine_dbgstr_guid(riid
));
569 return E_NOINTERFACE
;
572 static ULONG WINAPI
rowset_AddRef(IRowset
*iface
)
574 struct test_rowset
*rowset
= impl_from_IRowset( iface
);
575 return InterlockedIncrement( &rowset
->refs
);
578 static ULONG WINAPI
rowset_Release(IRowset
*iface
)
580 struct test_rowset
*rowset
= impl_from_IRowset( iface
);
581 /* Object not allocated no need to destroy */
582 return InterlockedDecrement( &rowset
->refs
);
585 static HRESULT WINAPI
rowset_AddRefRows(IRowset
*iface
, DBCOUNTITEM cRows
, const HROW rghRows
[],
586 DBREFCOUNT rgRefCounts
[], DBROWSTATUS rgRowStatus
[])
588 ok(0, "Unexpected call\n");
592 static HRESULT WINAPI
rowset_GetData(IRowset
*iface
, HROW hRow
, HACCESSOR hAccessor
, void *pData
)
594 ok(0, "Unexpected call\n");
598 static HRESULT WINAPI
rowset_GetNextRows(IRowset
*iface
, HCHAPTER hReserved
, DBROWOFFSET lRowsOffset
,
599 DBROWCOUNT cRows
, DBCOUNTITEM
*pcRowObtained
, HROW
**prghRows
)
601 ok(0, "Unexpected call\n");
605 static HRESULT WINAPI
rowset_ReleaseRows(IRowset
*iface
, DBCOUNTITEM cRows
, const HROW rghRows
[],
606 DBROWOPTIONS rgRowOptions
[], DBREFCOUNT rgRefCounts
[], DBROWSTATUS rgRowStatus
[])
608 ok(0, "Unexpected call\n");
612 static HRESULT WINAPI
rowset_RestartPosition(IRowset
*iface
, HCHAPTER hReserved
)
614 ok(0, "Unexpected call\n");
618 static const struct IRowsetVtbl rowset_vtbl
=
620 rowset_QueryInterface
,
627 rowset_RestartPosition
630 static ULONG
get_refcount(void *iface
)
632 IUnknown
*unknown
= iface
;
633 IUnknown_AddRef(unknown
);
634 return IUnknown_Release(unknown
);
637 static void test_ADORecordsetConstruction(void)
639 _Recordset
*recordset
;
640 ADORecordsetConstruction
*construct
;
641 Fields
*fields
= NULL
;
643 struct test_rowset testrowset
;
648 hr
= CoCreateInstance( &CLSID_Recordset
, NULL
, CLSCTX_INPROC_SERVER
, &IID__Recordset
, (void **)&recordset
);
649 ok( hr
== S_OK
, "got %08lx\n", hr
);
651 hr
= _Recordset_QueryInterface( recordset
, &IID_ADORecordsetConstruction
, (void**)&construct
);
652 ok( hr
== S_OK
, "got %08lx\n", hr
);
658 testrowset
.IRowset_iface
.lpVtbl
= &rowset_vtbl
;
659 testrowset
.IRowsetInfo_iface
.lpVtbl
= &rowset_info
;
660 testrowset
.IColumnsInfo_iface
.lpVtbl
= &column_info
;
663 rowset
= &testrowset
.IRowset_iface
;
665 ref
= get_refcount( rowset
);
666 ok( ref
== 1, "got %ld\n", ref
);
667 hr
= ADORecordsetConstruction_put_Rowset( construct
, (IUnknown
*)rowset
);
668 ok( hr
== S_OK
, "got %08lx\n", hr
);
670 ref
= get_refcount( rowset
);
671 ok( ref
== 2, "got %ld\n", ref
);
673 hr
= _Recordset_get_Fields( recordset
, &fields
);
674 ok( hr
== S_OK
, "got %08lx\n", hr
);
675 ok( fields
!= NULL
, "NULL value\n");
677 ref
= get_refcount( rowset
);
678 ok( ref
== 2, "got %ld\n", ref
);
681 hr
= Fields_get_Count( fields
, &count
);
682 ok( count
== 1, "got %ld\n", count
);
689 V_VT( &index
) = VT_BSTR
;
690 V_BSTR( &index
) = SysAllocString( L
"Column1" );
692 hr
= Fields_get_Item( fields
, index
, &field
);
693 ok( hr
== S_OK
, "got %08lx\n", hr
);
695 hr
= Field_get_Type( field
, &type
);
696 ok( hr
== S_OK
, "got %08lx\n", hr
);
697 ok( type
== adInteger
, "got %d\n", type
);
699 hr
= Field_get_DefinedSize( field
, &size
);
700 ok( hr
== S_OK
, "got %08lx\n", hr
);
701 ok( size
== 5, "got %Id\n", size
);
703 VariantClear(&index
);
705 Field_Release(field
);
708 ref
= get_refcount(rowset
);
709 ok( ref
== 2, "got %ld\n", ref
);
711 Fields_Release(fields
);
713 ADORecordsetConstruction_Release(construct
);
716 _Recordset_Release( recordset
);
719 static void test_Fields(void)
721 _Recordset
*recordset
;
722 ISupportErrorInfo
*errorinfo
;
724 Field
*field
, *field2
;
733 hr
= CoCreateInstance( &CLSID_Recordset
, NULL
, CLSCTX_INPROC_SERVER
, &IID__Recordset
, (void **)&recordset
);
734 ok( hr
== S_OK
, "got %08lx\n", hr
);
736 hr
= _Recordset_QueryInterface( recordset
, &IID_Fields
, (void **)&fields
);
737 ok( hr
== E_NOINTERFACE
, "got %08lx\n", hr
);
739 hr
= _Recordset_get_Fields( recordset
, &fields
);
740 ok( hr
== S_OK
, "got %08lx\n", hr
);
742 /* Fields object supports ISupportErrorInfo */
744 hr
= Fields_QueryInterface( fields
, &IID_ISupportErrorInfo
, (void **)&errorinfo
);
745 ok( hr
== S_OK
, "got %08lx\n", hr
);
746 if (errorinfo
) ISupportErrorInfo_Release( errorinfo
);
749 hr
= Fields_get_Count( fields
, &count
);
750 ok( !count
, "got %ld\n", count
);
752 name
= SysAllocString( L
"field" );
753 V_VT( &val
) = VT_ERROR
;
754 V_ERROR( &val
) = DISP_E_PARAMNOTFOUND
;
755 hr
= Fields_Append( fields
, name
, adInteger
, 4, adFldUnspecified
, val
);
756 ok( hr
== S_OK
, "got %08lx\n", hr
);
757 SysFreeString( name
);
760 hr
= Fields_get_Count( fields
, &count
);
761 ok( count
== 1, "got %ld\n", count
);
763 name
= SysAllocString( L
"field2" );
764 hr
= Fields__Append( fields
, name
, adInteger
, 4, adFldUnspecified
);
765 ok( hr
== S_OK
, "got %08lx\n", hr
);
766 SysFreeString( name
);
769 hr
= Fields_get_Count( fields
, &count
);
770 ok( count
== 2, "got %ld\n", count
);
772 /* handing out field object doesn't add reference to fields or recordset object */
773 name
= SysAllocString( L
"field" );
774 V_VT( &index
) = VT_BSTR
;
775 V_BSTR( &index
) = name
;
776 hr
= Fields_get_Item( fields
, index
, &field
);
778 /* calling get_Item again returns the same object and adds reference */
779 hr
= Fields_get_Item( fields
, index
, &field2
);
780 ok( hr
== S_OK
, "got %08lx\n", hr
);
781 ok( field2
== field
, "expected same object\n" );
782 Field_Release( field2
);
783 SysFreeString( name
);
785 /* Field object supports ISupportErrorInfo */
787 hr
= Field_QueryInterface( field
, &IID_ISupportErrorInfo
, (void **)&errorinfo
);
788 ok( hr
== S_OK
, "got %08lx\n", hr
);
789 if (errorinfo
) ISupportErrorInfo_Release( errorinfo
);
791 /* verify values set with _Append */
792 hr
= Field_get_Name( field
, &name
);
793 ok( hr
== S_OK
, "got %08lx\n", hr
);
794 ok( !lstrcmpW( name
, L
"field" ), "got %s\n", wine_dbgstr_w(name
) );
795 SysFreeString( name
);
797 hr
= Field_get_Type( field
, &type
);
798 ok( hr
== S_OK
, "got %08lx\n", hr
);
799 ok( type
== adInteger
, "got %d\n", type
);
801 hr
= Field_get_DefinedSize( field
, &size
);
802 ok( hr
== S_OK
, "got %08lx\n", hr
);
803 ok( size
== 4, "got %Id\n", size
);
805 hr
= Field_get_Attributes( field
, &attrs
);
806 ok( hr
== S_OK
, "got %08lx\n", hr
);
807 ok( !attrs
, "got %ld\n", attrs
);
809 Field_Release( field
);
810 Fields_Release( fields
);
811 _Recordset_Release( recordset
);
814 static HRESULT
str_to_byte_array( const char *data
, VARIANT
*ret
)
817 LONG i
, len
= strlen(data
);
820 if (!(vector
= SafeArrayCreateVector( VT_UI1
, 0, len
))) return E_OUTOFMEMORY
;
821 for (i
= 0; i
< len
; i
++)
823 if ((hr
= SafeArrayPutElement( vector
, &i
, (void *)&data
[i
] )) != S_OK
)
825 SafeArrayDestroy( vector
);
830 V_VT( ret
) = VT_ARRAY
| VT_UI1
;
831 V_ARRAY( ret
) = vector
;
835 static void test_Stream(void)
840 LineSeparatorEnum sep
;
842 ADO_LONGPTR size
, pos
;
843 ObjectStateEnum state
;
844 ConnectModeEnum mode
;
846 VARIANT missing
, val
;
849 hr
= CoCreateInstance( &CLSID_Stream
, NULL
, CLSCTX_INPROC_SERVER
, &IID__Stream
, (void **)&stream
);
850 ok( hr
== S_OK
, "got %08lx\n", hr
);
852 hr
= _Stream_get_Size( stream
, &size
);
853 ok( hr
== MAKE_ADO_HRESULT( adErrObjectClosed
), "got %08lx\n", hr
);
855 hr
= _Stream_get_EOS( stream
, &eos
);
856 ok( hr
== MAKE_ADO_HRESULT( adErrObjectClosed
), "got %08lx\n", hr
);
858 hr
= _Stream_get_Position( stream
, &pos
);
859 ok( hr
== MAKE_ADO_HRESULT( adErrObjectClosed
), "got %08lx\n", hr
);
861 hr
= _Stream_put_Position( stream
, 0 );
862 ok( hr
== MAKE_ADO_HRESULT( adErrObjectClosed
), "got %08lx\n", hr
);
864 /* check default type */
866 hr
= _Stream_get_Type( stream
, &type
);
867 ok( hr
== S_OK
, "got %08lx\n", hr
);
868 ok( type
== adTypeText
, "got %u\n", type
);
870 hr
= _Stream_put_Type( stream
, adTypeBinary
);
871 ok( hr
== S_OK
, "got %08lx\n", hr
);
874 hr
= _Stream_get_Type( stream
, &type
);
875 ok( hr
== S_OK
, "got %08lx\n", hr
);
876 ok( type
== adTypeBinary
, "got %u\n", type
);
879 hr
= _Stream_put_Type( stream
, adTypeText
);
880 ok( hr
== S_OK
, "got %08lx\n", hr
);
883 hr
= _Stream_get_LineSeparator( stream
, &sep
);
884 ok( hr
== S_OK
, "got %08lx\n", hr
);
885 ok( sep
== adCRLF
, "got %d\n", sep
);
887 hr
= _Stream_put_LineSeparator( stream
, adLF
);
888 ok( hr
== S_OK
, "got %08lx\n", hr
);
891 hr
= _Stream_get_State( stream
, &state
);
892 ok( hr
== S_OK
, "got %08lx\n", hr
);
893 ok( state
== adStateClosed
, "got %u\n", state
);
896 hr
= _Stream_get_Mode( stream
, &mode
);
897 ok( hr
== S_OK
, "got %08lx\n", hr
);
898 ok( mode
== adModeUnknown
, "got %u\n", mode
);
900 hr
= _Stream_put_Mode( stream
, adModeReadWrite
);
901 ok( hr
== S_OK
, "got %08lx\n", hr
);
903 hr
= _Stream_get_Charset( stream
, &charset
);
904 ok( hr
== S_OK
, "got %08lx\n", hr
);
905 ok( !lstrcmpW( charset
, L
"Unicode" ), "got %s\n", wine_dbgstr_w(charset
) );
906 SysFreeString( charset
);
908 str
= SysAllocString( L
"Unicode" );
909 hr
= _Stream_put_Charset( stream
, str
);
910 ok( hr
== S_OK
, "got %08lx\n", hr
);
911 SysFreeString( str
);
913 hr
= _Stream_Read( stream
, 2, &val
);
914 ok( hr
== MAKE_ADO_HRESULT( adErrObjectClosed
), "got %08lx\n", hr
);
916 V_VT( &missing
) = VT_ERROR
;
917 V_ERROR( &missing
) = DISP_E_PARAMNOTFOUND
;
918 hr
= _Stream_Open( stream
, missing
, adModeUnknown
, adOpenStreamUnspecified
, NULL
, NULL
);
919 ok( hr
== S_OK
, "got %08lx\n", hr
);
921 hr
= _Stream_Open( stream
, missing
, adModeUnknown
, adOpenStreamUnspecified
, NULL
, NULL
);
922 ok( hr
== MAKE_ADO_HRESULT( adErrObjectOpen
), "got %08lx\n", hr
);
925 hr
= _Stream_get_State( stream
, &state
);
926 ok( hr
== S_OK
, "got %08lx\n", hr
);
927 ok( state
== adStateOpen
, "got %u\n", state
);
930 hr
= _Stream_get_Size( stream
, &size
);
931 ok( hr
== S_OK
, "got %08lx\n", hr
);
932 ok( !size
, "got %Id\n", size
);
935 hr
= _Stream_get_EOS( stream
, &eos
);
936 ok( hr
== S_OK
, "got %08lx\n", hr
);
937 ok( eos
== VARIANT_TRUE
, "got %04x\n", eos
);
940 hr
= _Stream_get_Position( stream
, &pos
);
941 ok( hr
== S_OK
, "got %08lx\n", hr
);
942 ok( !pos
, "got %Id\n", pos
);
945 hr
= _Stream_get_Size( stream
, &size
);
946 ok( hr
== S_OK
, "got %08lx\n", hr
);
947 ok( !size
, "got %Id\n", size
);
949 hr
= _Stream_Read( stream
, 2, &val
);
950 ok( hr
== MAKE_ADO_HRESULT( adErrIllegalOperation
), "got %08lx\n", hr
);
952 hr
= _Stream_ReadText( stream
, 2, &str
);
953 ok( hr
== S_OK
, "got %08lx\n", hr
);
954 ok( !str
[0], "got %s\n", wine_dbgstr_w(str
) );
955 SysFreeString( str
);
958 hr
= _Stream_get_Position( stream
, &pos
);
959 ok( hr
== S_OK
, "got %08lx\n", hr
);
960 ok( !pos
, "got %Id\n", pos
);
962 str
= SysAllocString( L
"test" );
963 hr
= _Stream_WriteText( stream
, str
, adWriteChar
);
964 ok( hr
== S_OK
, "got %08lx\n", hr
);
965 SysFreeString( str
);
967 hr
= _Stream_ReadText( stream
, adReadAll
, &str
);
968 ok( hr
== S_OK
, "got %08lx\n", hr
);
969 ok( !str
[0], "got %s\n", wine_dbgstr_w(str
) );
970 SysFreeString( str
);
972 hr
= _Stream_put_Position( stream
, 0 );
973 ok( hr
== S_OK
, "got %08lx\n", hr
);
974 hr
= _Stream_ReadText( stream
, adReadAll
, &str
);
975 ok( hr
== S_OK
, "got %08lx\n", hr
);
976 ok( !lstrcmpW( str
, L
"test" ), "got %s\n", wine_dbgstr_w(str
) );
977 SysFreeString( str
);
980 hr
= _Stream_get_Position( stream
, &pos
);
981 ok( hr
== S_OK
, "got %08lx\n", hr
);
982 ok( pos
== 10, "got %Id\n", pos
);
985 hr
= _Stream_get_EOS( stream
, &eos
);
986 ok( hr
== S_OK
, "got %08lx\n", hr
);
987 ok( eos
== VARIANT_TRUE
, "got %04x\n", eos
);
989 hr
= _Stream_put_Position( stream
, 6 );
990 ok( hr
== S_OK
, "got %08lx\n", hr
);
993 hr
= _Stream_get_Size( stream
, &size
);
994 ok( hr
== S_OK
, "got %08lx\n", hr
);
995 ok( size
== 10, "got %Id\n", size
);
997 hr
= _Stream_put_Position( stream
, 2 );
998 ok( hr
== S_OK
, "got %08lx\n", hr
);
1000 hr
= _Stream_SetEOS( stream
);
1001 ok( hr
== S_OK
, "got %08lx\n", hr
);
1004 hr
= _Stream_get_Position( stream
, &pos
);
1005 ok( hr
== S_OK
, "got %08lx\n", hr
);
1006 ok( pos
== 2, "got %Id\n", pos
);
1009 hr
= _Stream_get_Size( stream
, &size
);
1010 ok( hr
== S_OK
, "got %08lx\n", hr
);
1011 ok( size
== 2, "got %Id\n", size
);
1013 hr
= _Stream_Close( stream
);
1014 ok( hr
== S_OK
, "got %08lx\n", hr
);
1017 hr
= _Stream_get_State( stream
, &state
);
1018 ok( hr
== S_OK
, "got %08lx\n", hr
);
1019 ok( state
== adStateClosed
, "got %u\n", state
);
1021 hr
= _Stream_Close( stream
);
1022 ok( hr
== MAKE_ADO_HRESULT( adErrObjectClosed
), "got %08lx\n", hr
);
1024 refs
= _Stream_Release( stream
);
1025 ok( !refs
, "got %ld\n", refs
);
1028 hr
= CoCreateInstance( &CLSID_Stream
, NULL
, CLSCTX_INPROC_SERVER
, &IID__Stream
, (void **)&stream
);
1029 ok( hr
== S_OK
, "got %08lx\n", hr
);
1031 hr
= _Stream_put_Type( stream
, adTypeBinary
);
1032 ok( hr
== S_OK
, "got %08lx\n", hr
);
1034 hr
= _Stream_Open( stream
, missing
, adModeUnknown
, adOpenStreamUnspecified
, NULL
, NULL
);
1035 ok( hr
== S_OK
, "got %08lx\n", hr
);
1037 hr
= _Stream_ReadText( stream
, adReadAll
, &str
);
1038 ok( hr
== MAKE_ADO_HRESULT( adErrIllegalOperation
), "got %08lx\n", hr
);
1040 str
= SysAllocString( L
"test" );
1041 hr
= _Stream_WriteText( stream
, str
, adWriteChar
);
1042 ok( hr
== MAKE_ADO_HRESULT( adErrIllegalOperation
), "got %08lx\n", hr
);
1043 SysFreeString( str
);
1045 VariantInit( &val
);
1046 hr
= _Stream_Read( stream
, 1, &val
);
1047 ok( hr
== S_OK
, "got %08lx\n", hr
);
1048 ok( V_VT( &val
) == VT_NULL
, "got %u\n", V_VT( &val
) );
1050 VariantInit( &val
);
1051 hr
= _Stream_Write( stream
, val
);
1052 ok( hr
== MAKE_ADO_HRESULT( adErrInvalidArgument
), "got %08lx\n", hr
);
1054 hr
= str_to_byte_array( "data", &val
);
1055 ok( hr
== S_OK
, "got %08lx\n", hr
);
1056 hr
= _Stream_Write( stream
, val
);
1057 ok( hr
== S_OK
, "got %08lx\n", hr
);
1058 VariantClear( &val
);
1061 hr
= _Stream_get_Position( stream
, &pos
);
1062 ok( hr
== S_OK
, "got %08lx\n", hr
);
1063 ok( pos
== 4, "got %Id\n", pos
);
1065 hr
= _Stream_put_Position( stream
, 0 );
1066 ok( hr
== S_OK
, "got %08lx\n", hr
);
1068 VariantInit( &val
);
1069 hr
= _Stream_Read( stream
, adReadAll
, &val
);
1070 ok( hr
== S_OK
, "got %08lx\n", hr
);
1071 ok( V_VT( &val
) == (VT_ARRAY
| VT_UI1
), "got %04x\n", V_VT( &val
) );
1072 VariantClear( &val
);
1075 hr
= _Stream_get_Position( stream
, &pos
);
1076 ok( hr
== S_OK
, "got %08lx\n", hr
);
1077 ok( pos
== 4, "got %Id\n", pos
);
1079 refs
= _Stream_Release( stream
);
1080 ok( !refs
, "got %ld\n", refs
);
1083 static void test_Connection(void)
1086 _Connection
*connection
;
1087 IRunnableObject
*runtime
;
1088 ISupportErrorInfo
*errorinfo
;
1089 IConnectionPointContainer
*pointcontainer
;
1090 ADOConnectionConstruction15
*construct
;
1091 LONG state
, timeout
;
1092 BSTR str
, str2
, str3
;
1093 ConnectModeEnum mode
;
1094 CursorLocationEnum location
;
1096 hr
= CoCreateInstance(&CLSID_Connection
, NULL
, CLSCTX_INPROC_SERVER
, &IID__Connection
, (void**)&connection
);
1097 ok( hr
== S_OK
, "got %08lx\n", hr
);
1099 hr
= _Connection_QueryInterface(connection
, &IID_IRunnableObject
, (void**)&runtime
);
1100 ok(hr
== E_NOINTERFACE
, "Unexpected IRunnableObject interface\n");
1101 ok(runtime
== NULL
, "expected NULL\n");
1103 hr
= _Connection_QueryInterface(connection
, &IID_ISupportErrorInfo
, (void**)&errorinfo
);
1104 ok(hr
== S_OK
, "Failed to get ISupportErrorInfo interface\n");
1105 ISupportErrorInfo_Release(errorinfo
);
1107 hr
= _Connection_QueryInterface(connection
, &IID_IConnectionPointContainer
, (void**)&pointcontainer
);
1108 ok(hr
== S_OK
, "Failed to get IConnectionPointContainer interface %08lx\n", hr
);
1109 IConnectionPointContainer_Release(pointcontainer
);
1111 hr
= _Connection_QueryInterface(connection
, &IID_ADOConnectionConstruction15
, (void**)&construct
);
1112 ok(hr
== S_OK
, "Failed to get ADOConnectionConstruction15 interface %08lx\n", hr
);
1114 ADOConnectionConstruction15_Release(construct
);
1116 if (0) /* Crashes on windows */
1118 hr
= _Connection_get_State(connection
, NULL
);
1119 ok(hr
== E_INVALIDARG
, "Unexpected hr 0x%08lx\n", hr
);
1123 hr
= _Connection_get_State(connection
, &state
);
1124 ok(hr
== S_OK
, "Failed to get state, hr 0x%08lx\n", hr
);
1125 ok(state
== adStateClosed
, "Unexpected state value 0x%08lx\n", state
);
1127 hr
= _Connection_Close(connection
);
1128 ok(hr
== MAKE_ADO_HRESULT(adErrObjectClosed
), "got %08lx\n", hr
);
1131 hr
= _Connection_get_CommandTimeout(connection
, &timeout
);
1132 ok(hr
== S_OK
, "Failed to get state, hr 0x%08lx\n", hr
);
1133 ok(timeout
== 30, "Unexpected timeout value %ld\n", timeout
);
1135 hr
= _Connection_put_CommandTimeout(connection
, 300);
1136 ok(hr
== S_OK
, "Failed to get state, hr 0x%08lx\n", hr
);
1139 hr
= _Connection_get_CommandTimeout(connection
, &timeout
);
1140 ok(hr
== S_OK
, "Failed to get state, hr 0x%08lx\n", hr
);
1141 ok(timeout
== 300, "Unexpected timeout value %ld\n", timeout
);
1144 hr
= _Connection_get_CursorLocation(connection
, &location
);
1145 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1146 ok(location
== adUseServer
, "Unexpected location value %d\n", location
);
1148 hr
= _Connection_put_CursorLocation(connection
, adUseClient
);
1149 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1152 hr
= _Connection_get_CursorLocation(connection
, &location
);
1153 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1154 ok(location
== adUseClient
, "Unexpected location value %d\n", location
);
1156 hr
= _Connection_put_CursorLocation(connection
, adUseServer
);
1157 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1160 hr
= _Connection_get_Mode(connection
, &mode
);
1161 ok(hr
== S_OK
, "Failed to get state, hr 0x%08lx\n", hr
);
1162 ok(mode
== adModeUnknown
, "Unexpected mode value %d\n", mode
);
1164 hr
= _Connection_put_Mode(connection
, adModeShareDenyNone
);
1165 ok(hr
== S_OK
, "Failed to get state, hr 0x%08lx\n", hr
);
1167 mode
= adModeUnknown
;
1168 hr
= _Connection_get_Mode(connection
, &mode
);
1169 ok(hr
== S_OK
, "Failed to get state, hr 0x%08lx\n", hr
);
1170 ok(mode
== adModeShareDenyNone
, "Unexpected mode value %d\n", mode
);
1172 hr
= _Connection_put_Mode(connection
, adModeUnknown
);
1173 ok(hr
== S_OK
, "Failed to get state, hr 0x%08lx\n", hr
);
1176 str
= (BSTR
)0xdeadbeef;
1177 hr
= _Connection_get_Provider(connection
, &str
);
1178 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1179 ok(!wcscmp(str
, L
"MSDASQL"), "wrong string %s\n", wine_dbgstr_w(str
));
1182 str
= SysAllocString(L
"MSDASQL.1");
1183 hr
= _Connection_put_Provider(connection
, str
);
1184 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1187 str
= (BSTR
)0xdeadbeef;
1188 hr
= _Connection_get_Provider(connection
, &str
);
1189 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1190 ok(!wcscmp(str
, L
"MSDASQL.1"), "wrong string %s\n", wine_dbgstr_w(str
));
1192 /* Restore default */
1193 str
= SysAllocString(L
"MSDASQL");
1194 hr
= _Connection_put_Provider(connection
, str
);
1195 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1198 hr
= _Connection_put_Provider(connection
, NULL
);
1199 ok(hr
== MAKE_ADO_HRESULT(adErrInvalidArgument
), "got 0x%08lx\n", hr
);
1202 str
= (BSTR
)0xdeadbeef;
1203 hr
= _Connection_get_ConnectionString(connection
, &str
);
1204 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
1205 ok(str
== NULL
, "got %p\n", str
);
1207 str
= SysAllocString(L
"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_test");
1208 hr
= _Connection_put_ConnectionString(connection
, str
);
1209 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1211 /* Show put_ConnectionString effects Provider */
1212 str3
= (BSTR
)0xdeadbeef;
1213 hr
= _Connection_get_Provider(connection
, &str3
);
1214 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1215 ok(str3
!= NULL
, "Expected value got NULL\n");
1216 todo_wine
ok(!wcscmp(str3
, L
"MSDASQL.1"), "wrong string %s\n", wine_dbgstr_w(str3
));
1217 SysFreeString(str3
);
1219 if (0) /* Crashes on windows */
1221 hr
= _Connection_get_ConnectionString(connection
, NULL
);
1222 ok(hr
== E_POINTER
, "Failed, hr 0x%08lx\n", hr
);
1226 hr
= _Connection_get_ConnectionString(connection
, &str2
);
1227 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1228 ok(!wcscmp(str
, str2
), "wrong string %s\n", wine_dbgstr_w(str2
));
1230 hr
= _Connection_Open(connection
, NULL
, NULL
, NULL
, 0);
1231 ok(hr
== E_FAIL
, "Failed, hr 0x%08lx\n", hr
);
1233 /* Open adds trailing ; if it's missing */
1234 str3
= SysAllocString(L
"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_test;");
1235 hr
= _Connection_Open(connection
, NULL
, NULL
, NULL
, adConnectUnspecified
);
1236 ok(hr
== E_FAIL
, "Failed, hr 0x%08lx\n", hr
);
1239 hr
= _Connection_get_ConnectionString(connection
, &str2
);
1240 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1241 todo_wine
ok(!wcscmp(str3
, str2
) || broken(!wcscmp(str
, str2
)) /* XP */, "wrong string %s\n", wine_dbgstr_w(str2
));
1243 hr
= _Connection_Open(connection
, str
, NULL
, NULL
, adConnectUnspecified
);
1244 ok(hr
== E_FAIL
, "Failed, hr 0x%08lx\n", hr
);
1248 hr
= _Connection_get_ConnectionString(connection
, &str2
);
1249 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1250 todo_wine
ok(!wcscmp(str3
, str2
) || broken(!wcscmp(str
, str2
)) /* XP */, "wrong string %s\n", wine_dbgstr_w(str2
));
1251 SysFreeString(str2
);
1252 SysFreeString(str3
);
1254 hr
= _Connection_put_ConnectionString(connection
, NULL
);
1255 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1257 str
= (BSTR
)0xdeadbeef;
1258 hr
= _Connection_get_ConnectionString(connection
, &str
);
1259 ok(hr
== S_OK
, "Failed, hr 0x%08lx\n", hr
);
1260 ok(str
== NULL
, "got %p\n", str
);
1261 _Connection_Release(connection
);
1264 static void test_Command(void)
1269 Command15
*command15
;
1270 Command25
*command25
;
1271 CommandTypeEnum cmd_type
= adCmdUnspecified
;
1272 BSTR cmd_text
= (BSTR
)"test";
1273 _Connection
*connection
;
1275 hr
= CoCreateInstance( &CLSID_Command
, NULL
, CLSCTX_INPROC_SERVER
, &IID__Command
, (void **)&command
);
1276 ok( hr
== S_OK
, "got %08lx\n", hr
);
1278 hr
= _Command_QueryInterface( command
, &IID__ADO
, (void **)&ado
);
1279 ok( hr
== S_OK
, "got %08lx\n", hr
);
1280 _ADO_Release( ado
);
1282 hr
= _Command_QueryInterface( command
, &IID_Command15
, (void **)&command15
);
1283 ok( hr
== S_OK
, "got %08lx\n", hr
);
1284 Command15_Release( command15
);
1286 hr
= _Command_QueryInterface( command
, &IID_Command25
, (void **)&command25
);
1287 ok( hr
== S_OK
, "got %08lx\n", hr
);
1288 Command25_Release( command25
);
1290 hr
= _Command_get_CommandType( command
, &cmd_type
);
1291 ok( hr
== S_OK
, "got %08lx\n", hr
);
1292 ok( cmd_type
== adCmdUnknown
, "got %08x\n", cmd_type
);
1294 _Command_put_CommandType( command
, adCmdText
);
1295 hr
= _Command_get_CommandType( command
, &cmd_type
);
1296 ok( hr
== S_OK
, "got %08lx\n", hr
);
1297 ok( cmd_type
== adCmdText
, "got %08x\n", cmd_type
);
1299 hr
= _Command_put_CommandType( command
, 0xdeadbeef );
1300 ok( hr
== MAKE_ADO_HRESULT( adErrInvalidArgument
), "got %08lx\n", hr
);
1302 hr
= _Command_get_CommandText( command
, &cmd_text
);
1303 ok( hr
== S_OK
, "got %08lx\n", hr
);
1304 ok( !cmd_text
, "got %s\n", wine_dbgstr_w( cmd_text
));
1306 hr
= _Command_put_CommandText( command
, NULL
);
1307 ok( hr
== S_OK
, "got %08lx\n", hr
);
1309 cmd_text
= SysAllocString( L
"" );
1310 hr
= _Command_put_CommandText( command
, cmd_text
);
1311 ok( hr
== S_OK
, "got %08lx\n", hr
);
1312 SysFreeString( cmd_text
);
1314 hr
= _Command_get_CommandText( command
, &cmd_text
);
1315 ok( hr
== S_OK
, "got %08lx\n", hr
);
1316 ok( cmd_text
&& !*cmd_text
, "got %p\n", cmd_text
);
1318 cmd_text
= SysAllocString( L
"test" );
1319 hr
= _Command_put_CommandText( command
, cmd_text
);
1320 ok( hr
== S_OK
, "got %08lx\n", hr
);
1321 SysFreeString( cmd_text
);
1323 hr
= _Command_get_CommandText( command
, &cmd_text
);
1324 ok( hr
== S_OK
, "got %08lx\n", hr
);
1325 ok( !wcscmp( L
"test", cmd_text
), "got %p\n", wine_dbgstr_w( cmd_text
) );
1327 connection
= (_Connection
*)0xdeadbeef;
1328 hr
= _Command_get_ActiveConnection( command
, &connection
);
1329 ok( hr
== S_OK
, "got %08lx\n", hr
);
1330 ok( connection
== NULL
, "got %p\n", connection
);
1332 hr
= _Command_putref_ActiveConnection( command
, NULL
);
1333 ok( hr
== S_OK
, "got %08lx\n", hr
);
1335 _Command_Release( command
);
1339 ConnectionEventsVt conn_event_sink
;
1343 static HRESULT WINAPI
conneventvt_QueryInterface( ConnectionEventsVt
*iface
, REFIID riid
, void **obj
)
1345 struct conn_event
*conn_event
= CONTAINING_RECORD( iface
, struct conn_event
, conn_event_sink
);
1347 if (IsEqualGUID( &IID_ConnectionEventsVt
, riid
))
1349 InterlockedIncrement( &conn_event
->refs
);
1354 ok( 0, "unexpected call\n" );
1355 return E_NOINTERFACE
;
1358 static ULONG WINAPI
conneventvt_AddRef( ConnectionEventsVt
*iface
)
1360 struct conn_event
*conn_event
= CONTAINING_RECORD( iface
, struct conn_event
, conn_event_sink
);
1361 return InterlockedIncrement( &conn_event
->refs
);
1364 static ULONG WINAPI
conneventvt_Release( ConnectionEventsVt
*iface
)
1366 struct conn_event
*conn_event
= CONTAINING_RECORD( iface
, struct conn_event
, conn_event_sink
);
1367 return InterlockedDecrement( &conn_event
->refs
);
1370 static HRESULT WINAPI
conneventvt_InfoMessage( ConnectionEventsVt
*iface
, Error
*error
,
1371 EventStatusEnum
*status
, _Connection
*Connection
)
1376 static HRESULT WINAPI
conneventvt_BeginTransComplete( ConnectionEventsVt
*iface
, LONG TransactionLevel
,
1377 Error
*error
, EventStatusEnum
*status
, _Connection
*connection
)
1382 static HRESULT WINAPI
conneventvt_CommitTransComplete( ConnectionEventsVt
*iface
, Error
*error
,
1383 EventStatusEnum
*status
, _Connection
*connection
)
1388 static HRESULT WINAPI
conneventvt_RollbackTransComplete( ConnectionEventsVt
*iface
, Error
*error
,
1389 EventStatusEnum
*status
, _Connection
*connection
)
1394 static HRESULT WINAPI
conneventvt_WillExecute( ConnectionEventsVt
*iface
, BSTR
*source
,
1395 CursorTypeEnum
*cursor_type
, LockTypeEnum
*lock_type
, LONG
*options
, EventStatusEnum
*status
,
1396 _Command
*command
, _Recordset
*record_set
, _Connection
*connection
)
1401 static HRESULT WINAPI
conneventvt_ExecuteComplete( ConnectionEventsVt
*iface
, LONG records_affected
,
1402 Error
*error
, EventStatusEnum
*status
, _Command
*command
, _Recordset
*record_set
,
1403 _Connection
*connection
)
1408 static HRESULT WINAPI
conneventvt_WillConnect( ConnectionEventsVt
*iface
, BSTR
*string
, BSTR
*userid
,
1409 BSTR
*password
, LONG
*options
, EventStatusEnum
*status
, _Connection
*connection
)
1414 static HRESULT WINAPI
conneventvt_ConnectComplete( ConnectionEventsVt
*iface
, Error
*error
,
1415 EventStatusEnum
*status
, _Connection
*connection
)
1420 static HRESULT WINAPI
conneventvt_Disconnect( ConnectionEventsVt
*iface
, EventStatusEnum
*status
,
1421 _Connection
*connection
)
1426 static const ConnectionEventsVtVtbl conneventvt_vtbl
= {
1427 conneventvt_QueryInterface
,
1429 conneventvt_Release
,
1430 conneventvt_InfoMessage
,
1431 conneventvt_BeginTransComplete
,
1432 conneventvt_CommitTransComplete
,
1433 conneventvt_RollbackTransComplete
,
1434 conneventvt_WillExecute
,
1435 conneventvt_ExecuteComplete
,
1436 conneventvt_WillConnect
,
1437 conneventvt_ConnectComplete
,
1438 conneventvt_Disconnect
1441 static HRESULT WINAPI
supporterror_QueryInterface( ISupportErrorInfo
*iface
, REFIID riid
, void **obj
)
1443 if (IsEqualGUID( &IID_ISupportErrorInfo
, riid
))
1449 return E_NOINTERFACE
;
1452 static ULONG WINAPI
supporterror_AddRef( ISupportErrorInfo
*iface
)
1457 static ULONG WINAPI
supporterror_Release( ISupportErrorInfo
*iface
)
1462 static HRESULT WINAPI
supporterror_InterfaceSupportsErrorInfo( ISupportErrorInfo
*iface
, REFIID riid
)
1467 static const struct ISupportErrorInfoVtbl support_error_vtbl
=
1469 supporterror_QueryInterface
,
1470 supporterror_AddRef
,
1471 supporterror_Release
,
1472 supporterror_InterfaceSupportsErrorInfo
1475 static void test_ConnectionPoint(void)
1480 IConnectionPoint
*point
;
1481 IConnectionPointContainer
*pointcontainer
;
1482 struct conn_event conn_event
= { { &conneventvt_vtbl
}, 0 };
1483 ISupportErrorInfo support_err_sink
= { &support_error_vtbl
};
1485 hr
= CoCreateInstance( &CLSID_Connection
, NULL
, CLSCTX_INPROC_SERVER
,
1486 &IID_IConnectionPointContainer
, (void**)&pointcontainer
);
1488 hr
= IConnectionPointContainer_FindConnectionPoint( pointcontainer
, &DIID_ConnectionEvents
, NULL
);
1489 ok( hr
== E_POINTER
, "got %08lx\n", hr
);
1491 hr
= IConnectionPointContainer_FindConnectionPoint( pointcontainer
, &DIID_RecordsetEvents
, &point
);
1492 ok( hr
== CONNECT_E_NOCONNECTION
, "got %08lx\n", hr
);
1494 hr
= IConnectionPointContainer_FindConnectionPoint( pointcontainer
, &DIID_ConnectionEvents
, &point
);
1495 ok( hr
== S_OK
, "got %08lx\n", hr
);
1497 /* nothing advised yet */
1498 hr
= IConnectionPoint_Unadvise( point
, 3 );
1499 ok( hr
== E_FAIL
, "got %08lx\n", hr
);
1501 hr
= IConnectionPoint_Advise( point
, NULL
, NULL
);
1502 ok( hr
== E_FAIL
, "got %08lx\n", hr
);
1504 hr
= IConnectionPoint_Advise( point
, (void*)&conn_event
.conn_event_sink
, NULL
);
1505 ok( hr
== E_FAIL
, "got %08lx\n", hr
);
1507 cookie
= 0xdeadbeef;
1508 hr
= IConnectionPoint_Advise( point
, NULL
, &cookie
);
1509 ok( hr
== E_FAIL
, "got %08lx\n", hr
);
1510 ok( cookie
== 0xdeadbeef, "got %08lx\n", cookie
);
1512 /* unsupported sink */
1513 cookie
= 0xdeadbeef;
1514 hr
= IConnectionPoint_Advise( point
, (void*)&support_err_sink
, &cookie
);
1515 ok( hr
== E_FAIL
, "got %08lx\n", hr
);
1516 ok( !cookie
, "got %08lx\n", cookie
);
1519 hr
= IConnectionPoint_Advise( point
, (void*)&conn_event
.conn_event_sink
, &cookie
);
1520 ok( hr
== S_OK
, "got %08lx\n", hr
);
1521 ok( cookie
, "got %08lx\n", cookie
);
1523 /* invalid cookie */
1524 hr
= IConnectionPoint_Unadvise( point
, 0 );
1525 ok( hr
== E_FAIL
, "got %08lx\n", hr
);
1528 hr
= IConnectionPoint_Unadvise( point
, cookie
+ 1 );
1529 ok( hr
== E_FAIL
, "got %08lx\n", hr
);
1531 hr
= IConnectionPoint_Unadvise( point
, cookie
);
1532 ok( hr
== S_OK
, "got %08lx\n", hr
);
1534 /* sinks are released when the connection is destroyed */
1536 hr
= IConnectionPoint_Advise( point
, (void*)&conn_event
.conn_event_sink
, &cookie
);
1537 ok( hr
== S_OK
, "got %08lx\n", hr
);
1538 ok( cookie
, "got %08lx\n", cookie
);
1539 ok( conn_event
.refs
== 1, "got %ld\n", conn_event
.refs
);
1541 refs
= IConnectionPoint_Release( point
);
1542 ok( refs
== 1, "got %lu", refs
);
1544 IConnectionPointContainer_Release( pointcontainer
);
1546 ok( !conn_event
.refs
, "got %ld\n", conn_event
.refs
);
1551 CoInitialize( NULL
);
1553 test_ADORecordsetConstruction();
1554 test_ConnectionPoint();