msado15: Implement _Command get/putref ActiveConnection.
[wine.git] / dlls / msado15 / tests / msado15.c
blob378c2eb918c1aad9e3dc505db0411f9b13ac93ea
1 /*
2 * Copyright 2019 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdio.h>
20 #define COBJMACROS
21 #include <initguid.h>
22 #include <oledb.h>
23 #include <olectl.h>
24 #include <msado15_backcompat.h>
25 #include "wine/test.h"
27 #define MAKE_ADO_HRESULT( err ) MAKE_HRESULT( SEVERITY_ERROR, FACILITY_CONTROL, err )
29 static BOOL is_bof( _Recordset *recordset )
31 VARIANT_BOOL bof = VARIANT_FALSE;
32 _Recordset_get_BOF( recordset, &bof );
33 return bof == VARIANT_TRUE;
36 static BOOL is_eof( _Recordset *recordset )
38 VARIANT_BOOL eof = VARIANT_FALSE;
39 _Recordset_get_EOF( recordset, &eof );
40 return eof == VARIANT_TRUE;
43 static LONG get_refs_field( Field *field )
45 Field_AddRef( field );
46 return Field_Release( field );
49 static LONG get_refs_fields( Fields *fields )
51 Fields_AddRef( fields );
52 return Fields_Release( fields );
55 static LONG get_refs_recordset( _Recordset *recordset )
57 _Recordset_AddRef( recordset );
58 return _Recordset_Release( recordset );
61 static void test_Recordset(void)
63 _Recordset *recordset;
64 IRunnableObject *runtime;
65 ISupportErrorInfo *errorinfo;
66 Fields *fields, *fields2;
67 Field *field;
68 LONG refs, count, state;
69 VARIANT missing, val, index;
70 CursorLocationEnum location;
71 BSTR name;
72 HRESULT hr;
74 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
75 ok( hr == S_OK, "got %08x\n", hr );
77 hr = _Recordset_QueryInterface( recordset, &IID_IRunnableObject, (void**)&runtime);
78 ok(hr == E_NOINTERFACE, "Unexpected IRunnableObject interface\n");
79 ok(runtime == NULL, "expected NULL\n");
81 /* _Recordset object supports ISupportErrorInfo */
82 errorinfo = NULL;
83 hr = _Recordset_QueryInterface( recordset, &IID_ISupportErrorInfo, (void **)&errorinfo );
84 ok( hr == S_OK, "got %08x\n", hr );
85 refs = get_refs_recordset( recordset );
86 ok( refs == 2, "got %d\n", refs );
87 if (errorinfo) ISupportErrorInfo_Release( errorinfo );
88 refs = get_refs_recordset( recordset );
89 ok( refs == 1, "got %d\n", refs );
91 /* handing out fields object increases recordset refcount */
92 refs = get_refs_recordset( recordset );
93 ok( refs == 1, "got %d\n", refs );
94 hr = _Recordset_get_Fields( recordset, &fields );
95 ok( hr == S_OK, "got %08x\n", hr );
96 refs = get_refs_recordset( recordset );
97 ok( refs == 2, "got %d\n", refs );
98 refs = get_refs_fields( fields );
99 ok( refs == 1, "got %d\n", refs );
101 /* releasing fields object decreases recordset refcount, but fields refcount doesn't drop to zero */
102 Fields_Release( fields );
103 refs = get_refs_recordset( recordset );
104 ok( refs == 1, "got %d\n", refs );
105 refs = get_refs_fields( fields );
106 ok( refs == 1, "got %d\n", refs );
108 /* calling get_Fields again returns the same object with the same refcount and increases recordset refcount */
109 hr = _Recordset_get_Fields( recordset, &fields2 );
110 ok( hr == S_OK, "got %08x\n", hr );
111 refs = get_refs_recordset( recordset );
112 ok( refs == 2, "got %d\n", refs );
113 refs = get_refs_fields( fields2 );
114 ok( refs == 1, "got %d\n", refs );
115 ok( fields2 == fields, "expected same object\n" );
116 refs = Fields_Release( fields2 );
117 ok( refs == 1, "got %d\n", refs );
119 count = -1;
120 hr = Fields_get_Count( fields2, &count );
121 ok( hr == S_OK, "got %08x\n", hr );
122 ok( !count, "got %d\n", count );
124 hr = _Recordset_Close( recordset );
125 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
127 refs = _Recordset_Release( recordset );
128 ok( !refs, "got %d\n", refs );
130 /* fields object still has a reference */
131 refs = Fields_Release( fields2 );
132 ok( refs == 1, "got %d\n", refs );
134 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
135 ok( hr == S_OK, "got %08x\n", hr );
137 state = -1;
138 hr = _Recordset_get_State( recordset, &state );
139 ok( hr == S_OK, "got %08x\n", hr );
140 ok( state == adStateClosed, "got %d\n", state );
142 location = -1;
143 hr = _Recordset_get_CursorLocation( recordset, &location );
144 ok( hr == S_OK, "got %08x\n", hr );
145 ok( location == adUseServer, "got %d\n", location );
147 VariantInit( &missing );
148 hr = _Recordset_AddNew( recordset, missing, missing );
149 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
151 V_VT( &missing ) = VT_ERROR;
152 V_ERROR( &missing ) = DISP_E_PARAMNOTFOUND;
153 hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified );
154 ok( hr == MAKE_ADO_HRESULT( adErrInvalidConnection ), "got %08x\n", hr );
156 hr = _Recordset_get_Fields( recordset, &fields );
157 ok( hr == S_OK, "got %08x\n", hr );
159 name = SysAllocString( L"field" );
160 hr = Fields__Append( fields, name, adInteger, 4, adFldUnspecified );
161 ok( hr == S_OK, "got %08x\n", hr );
163 V_VT( &index ) = VT_BSTR;
164 V_BSTR( &index ) = name;
165 hr = Fields_get_Item( fields, index, &field );
166 ok( hr == S_OK, "got %08x\n", hr );
167 SysFreeString( name );
169 hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified );
170 ok( hr == S_OK, "got %08x\n", hr );
171 ok( is_eof( recordset ), "not eof\n" );
172 ok( is_bof( recordset ), "not bof\n" );
174 hr = _Recordset_Open( recordset, missing, missing, adOpenStatic, adLockBatchOptimistic, adCmdUnspecified );
175 ok( hr == MAKE_ADO_HRESULT( adErrObjectOpen ), "got %08x\n", hr );
177 state = -1;
178 hr = _Recordset_get_State( recordset, &state );
179 ok( hr == S_OK, "got %08x\n", hr );
180 ok( state == adStateOpen, "got %d\n", state );
182 count = -1;
183 hr = _Recordset_get_RecordCount( recordset, &count );
184 ok( hr == S_OK, "got %08x\n", hr );
185 ok( !count, "got %d\n", count );
187 hr = _Recordset_AddNew( recordset, missing, missing );
188 ok( hr == S_OK, "got %08x\n", hr );
189 ok( !is_eof( recordset ), "eof\n" );
190 ok( !is_bof( recordset ), "bof\n" );
192 count = -1;
193 hr = _Recordset_get_RecordCount( recordset, &count );
194 ok( hr == S_OK, "got %08x\n", hr );
195 ok( count == 1, "got %d\n", count );
197 /* get_Fields still returns the same object */
198 hr = _Recordset_get_Fields( recordset, &fields2 );
199 ok( hr == S_OK, "got %08x\n", hr );
200 ok( fields2 == fields, "expected same object\n" );
201 Fields_Release( fields2 );
203 count = -1;
204 hr = Fields_get_Count( fields2, &count );
205 ok( count == 1, "got %d\n", count );
207 hr = Field_get_Value( field, &val );
208 ok( hr == S_OK, "got %08x\n", hr );
209 ok( V_VT( &val ) == VT_EMPTY, "got %u\n", V_VT( &val ) );
211 V_VT( &val ) = VT_I4;
212 V_I4( &val ) = -1;
213 hr = Field_put_Value( field, val );
214 ok( hr == S_OK, "got %08x\n", hr );
216 V_VT( &val ) = VT_ERROR;
217 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
218 hr = Field_get_Value( field, &val );
219 ok( hr == S_OK, "got %08x\n", hr );
220 ok( V_VT( &val ) == VT_I4, "got %u\n", V_VT( &val ) );
221 ok( V_I4( &val ) == -1, "got %d\n", V_I4( &val ) );
223 hr = _Recordset_AddNew( recordset, missing, missing );
224 ok( hr == S_OK, "got %08x\n", hr );
226 /* field object returns different value after AddNew */
227 V_VT( &val ) = VT_ERROR;
228 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
229 hr = Field_get_Value( field, &val );
230 ok( hr == S_OK, "got %08x\n", hr );
231 ok( V_VT( &val ) == VT_EMPTY, "got %u\n", V_VT( &val ) );
233 ok( !is_eof( recordset ), "eof\n" );
234 ok( !is_bof( recordset ), "bof\n" );
235 hr = _Recordset_MoveFirst( recordset );
236 ok( hr == S_OK, "got %08x\n", hr );
237 ok( !is_eof( recordset ), "eof\n" );
238 ok( !is_bof( recordset ), "bof\n" );
240 V_VT( &val ) = VT_ERROR;
241 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
242 hr = Field_get_Value( field, &val );
243 ok( hr == S_OK, "got %08x\n", hr );
244 ok( V_VT( &val ) == VT_I4, "got %u\n", V_VT( &val ) );
245 ok( V_I4( &val ) == -1, "got %d\n", V_I4( &val ) );
247 hr = _Recordset_MoveNext( recordset );
248 ok( hr == S_OK, "got %08x\n", hr );
249 ok( !is_eof( recordset ), "eof\n" );
250 ok( !is_bof( recordset ), "not bof\n" );
252 hr = _Recordset_MoveNext( recordset );
253 ok( hr == S_OK, "got %08x\n", hr );
254 ok( is_eof( recordset ), "not eof\n" );
255 ok( !is_bof( recordset ), "bof\n" );
257 hr = _Recordset_MoveFirst( recordset );
258 ok( hr == S_OK, "got %08x\n", hr );
259 ok( !is_eof( recordset ), "eof\n" );
260 ok( !is_bof( recordset ), "bof\n" );
262 hr = _Recordset_MovePrevious( recordset );
263 ok( hr == S_OK, "got %08x\n", hr );
264 ok( !is_eof( recordset ), "eof\n" );
265 ok( is_bof( recordset ), "not bof\n" );
267 /* try get value at BOF */
268 VariantInit( &val );
269 hr = Field_get_Value( field, &val );
270 ok( hr == MAKE_ADO_HRESULT( adErrNoCurrentRecord ), "got %08x\n", hr );
272 hr = _Recordset_Close( recordset );
273 ok( hr == S_OK, "got %08x\n", hr );
275 state = -1;
276 hr = _Recordset_get_State( recordset, &state );
277 ok( hr == S_OK, "got %08x\n", hr );
278 ok( state == adStateClosed, "got %d\n", state );
280 Field_Release( field );
281 Fields_Release( fields );
282 _Recordset_Release( recordset );
285 static void test_Fields(void)
287 _Recordset *recordset;
288 ISupportErrorInfo *errorinfo;
289 Fields *fields;
290 Field *field, *field2;
291 VARIANT val, index;
292 BSTR name;
293 LONG refs, count, size;
294 DataTypeEnum type;
295 FieldAttributeEnum attrs;
296 HRESULT hr;
298 hr = CoCreateInstance( &CLSID_Recordset, NULL, CLSCTX_INPROC_SERVER, &IID__Recordset, (void **)&recordset );
299 ok( hr == S_OK, "got %08x\n", hr );
301 hr = _Recordset_get_Fields( recordset, &fields );
302 ok( hr == S_OK, "got %08x\n", hr );
304 /* Fields object supports ISupportErrorInfo */
305 errorinfo = NULL;
306 hr = Fields_QueryInterface( fields, &IID_ISupportErrorInfo, (void **)&errorinfo );
307 ok( hr == S_OK, "got %08x\n", hr );
308 refs = get_refs_fields( fields );
309 ok( refs == 2, "got %d\n", refs );
310 if (errorinfo) ISupportErrorInfo_Release( errorinfo );
311 refs = get_refs_fields( fields );
312 ok( refs == 1, "got %d\n", refs );
314 count = -1;
315 hr = Fields_get_Count( fields, &count );
316 ok( !count, "got %d\n", count );
318 name = SysAllocString( L"field" );
319 V_VT( &val ) = VT_ERROR;
320 V_ERROR( &val ) = DISP_E_PARAMNOTFOUND;
321 hr = Fields_Append( fields, name, adInteger, 4, adFldUnspecified, val );
322 ok( hr == S_OK, "got %08x\n", hr );
323 SysFreeString( name );
325 count = -1;
326 hr = Fields_get_Count( fields, &count );
327 ok( count == 1, "got %d\n", count );
329 name = SysAllocString( L"field2" );
330 hr = Fields__Append( fields, name, adInteger, 4, adFldUnspecified );
331 ok( hr == S_OK, "got %08x\n", hr );
332 SysFreeString( name );
334 count = -1;
335 hr = Fields_get_Count( fields, &count );
336 ok( count == 2, "got %d\n", count );
338 /* handing out field object doesn't add reference to fields or recordset object */
339 name = SysAllocString( L"field" );
340 V_VT( &index ) = VT_BSTR;
341 V_BSTR( &index ) = name;
342 refs = get_refs_recordset( recordset );
343 ok( refs == 2, "got %d\n", refs );
344 refs = get_refs_fields( fields );
345 ok( refs == 1, "got %d\n", refs );
346 hr = Fields_get_Item( fields, index, &field );
347 ok( hr == S_OK, "got %08x\n", hr );
348 refs = get_refs_field( field );
349 ok( refs == 1, "got %d\n", refs );
350 refs = get_refs_recordset( recordset );
351 ok( refs == 2, "got %d\n", refs );
352 refs = get_refs_fields( fields );
353 ok( refs == 1, "got %d\n", refs );
355 /* calling get_Item again returns the same object and adds reference */
356 hr = Fields_get_Item( fields, index, &field2 );
357 ok( hr == S_OK, "got %08x\n", hr );
358 ok( field2 == field, "expected same object\n" );
359 refs = get_refs_field( field2 );
360 ok( refs == 2, "got %d\n", refs );
361 refs = get_refs_recordset( recordset );
362 ok( refs == 2, "got %d\n", refs );
363 refs = get_refs_fields( fields );
364 ok( refs == 1, "got %d\n", refs );
365 Field_Release( field2 );
366 SysFreeString( name );
368 /* Field object supports ISupportErrorInfo */
369 errorinfo = NULL;
370 hr = Field_QueryInterface( field, &IID_ISupportErrorInfo, (void **)&errorinfo );
371 ok( hr == S_OK, "got %08x\n", hr );
372 refs = get_refs_field( field );
373 ok( refs == 2, "got %d\n", refs );
374 if (errorinfo) ISupportErrorInfo_Release( errorinfo );
375 refs = get_refs_field( field );
376 ok( refs == 1, "got %d\n", refs );
378 /* verify values set with _Append */
379 hr = Field_get_Name( field, &name );
380 ok( hr == S_OK, "got %08x\n", hr );
381 ok( !lstrcmpW( name, L"field" ), "got %s\n", wine_dbgstr_w(name) );
382 SysFreeString( name );
383 type = 0xdead;
384 hr = Field_get_Type( field, &type );
385 ok( hr == S_OK, "got %08x\n", hr );
386 ok( type == adInteger, "got %d\n", type );
387 size = -1;
388 hr = Field_get_DefinedSize( field, &size );
389 ok( hr == S_OK, "got %08x\n", hr );
390 ok( size == 4, "got %d\n", size );
391 attrs = 0xdead;
392 hr = Field_get_Attributes( field, &attrs );
393 ok( hr == S_OK, "got %08x\n", hr );
394 ok( !attrs, "got %d\n", attrs );
396 Field_Release( field );
397 Fields_Release( fields );
398 _Recordset_Release( recordset );
401 static HRESULT str_to_byte_array( const char *data, VARIANT *ret )
403 SAFEARRAY *vector;
404 LONG i, len = strlen(data);
405 HRESULT hr;
407 if (!(vector = SafeArrayCreateVector( VT_UI1, 0, len ))) return E_OUTOFMEMORY;
408 for (i = 0; i < len; i++)
410 if ((hr = SafeArrayPutElement( vector, &i, (void *)&data[i] )) != S_OK)
412 SafeArrayDestroy( vector );
413 return hr;
417 V_VT( ret ) = VT_ARRAY | VT_UI1;
418 V_ARRAY( ret ) = vector;
419 return S_OK;
422 static void test_Stream(void)
424 _Stream *stream;
425 VARIANT_BOOL eos;
426 StreamTypeEnum type;
427 LineSeparatorEnum sep;
428 LONG refs, size, pos;
429 ObjectStateEnum state;
430 ConnectModeEnum mode;
431 BSTR charset, str;
432 VARIANT missing, val;
433 HRESULT hr;
435 hr = CoCreateInstance( &CLSID_Stream, NULL, CLSCTX_INPROC_SERVER, &IID__Stream, (void **)&stream );
436 ok( hr == S_OK, "got %08x\n", hr );
438 hr = _Stream_get_Size( stream, &size );
439 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
441 hr = _Stream_get_EOS( stream, &eos );
442 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
444 hr = _Stream_get_Position( stream, &pos );
445 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
447 hr = _Stream_put_Position( stream, 0 );
448 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
450 /* check default type */
451 type = 0;
452 hr = _Stream_get_Type( stream, &type );
453 ok( hr == S_OK, "got %08x\n", hr );
454 ok( type == adTypeText, "got %u\n", type );
456 hr = _Stream_put_Type( stream, adTypeBinary );
457 ok( hr == S_OK, "got %08x\n", hr );
459 type = 0;
460 hr = _Stream_get_Type( stream, &type );
461 ok( hr == S_OK, "got %08x\n", hr );
462 ok( type == adTypeBinary, "got %u\n", type );
464 /* revert */
465 hr = _Stream_put_Type( stream, adTypeText );
466 ok( hr == S_OK, "got %08x\n", hr );
468 sep = 0;
469 hr = _Stream_get_LineSeparator( stream, &sep );
470 ok( hr == S_OK, "got %08x\n", hr );
471 ok( sep == adCRLF, "got %d\n", sep );
473 hr = _Stream_put_LineSeparator( stream, adLF );
474 ok( hr == S_OK, "got %08x\n", hr );
476 state = 0xdeadbeef;
477 hr = _Stream_get_State( stream, &state );
478 ok( hr == S_OK, "got %08x\n", hr );
479 ok( state == adStateClosed, "got %u\n", state );
481 mode = 0xdeadbeef;
482 hr = _Stream_get_Mode( stream, &mode );
483 ok( hr == S_OK, "got %08x\n", hr );
484 ok( mode == adModeUnknown, "got %u\n", mode );
486 hr = _Stream_put_Mode( stream, adModeReadWrite );
487 ok( hr == S_OK, "got %08x\n", hr );
489 hr = _Stream_get_Charset( stream, &charset );
490 ok( hr == S_OK, "got %08x\n", hr );
491 ok( !lstrcmpW( charset, L"Unicode" ), "got %s\n", wine_dbgstr_w(charset) );
492 SysFreeString( charset );
494 str = SysAllocString( L"Unicode" );
495 hr = _Stream_put_Charset( stream, str );
496 ok( hr == S_OK, "got %08x\n", hr );
497 SysFreeString( str );
499 hr = _Stream_Read( stream, 2, &val );
500 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
502 V_VT( &missing ) = VT_ERROR;
503 V_ERROR( &missing ) = DISP_E_PARAMNOTFOUND;
504 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
505 ok( hr == S_OK, "got %08x\n", hr );
507 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
508 ok( hr == MAKE_ADO_HRESULT( adErrObjectOpen ), "got %08x\n", hr );
510 state = 0xdeadbeef;
511 hr = _Stream_get_State( stream, &state );
512 ok( hr == S_OK, "got %08x\n", hr );
513 ok( state == adStateOpen, "got %u\n", state );
515 size = -1;
516 hr = _Stream_get_Size( stream, &size );
517 ok( hr == S_OK, "got %08x\n", hr );
518 ok( !size, "got %d\n", size );
520 eos = VARIANT_FALSE;
521 hr = _Stream_get_EOS( stream, &eos );
522 ok( hr == S_OK, "got %08x\n", hr );
523 ok( eos == VARIANT_TRUE, "got %04x\n", eos );
525 pos = -1;
526 hr = _Stream_get_Position( stream, &pos );
527 ok( hr == S_OK, "got %08x\n", hr );
528 ok( !pos, "got %d\n", pos );
530 size = -1;
531 hr = _Stream_get_Size( stream, &size );
532 ok( hr == S_OK, "got %08x\n", hr );
533 ok( !size, "got %d\n", size );
535 hr = _Stream_Read( stream, 2, &val );
536 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08x\n", hr );
538 hr = _Stream_ReadText( stream, 2, &str );
539 ok( hr == S_OK, "got %08x\n", hr );
540 ok( !str[0], "got %s\n", wine_dbgstr_w(str) );
541 SysFreeString( str );
543 pos = -1;
544 hr = _Stream_get_Position( stream, &pos );
545 ok( hr == S_OK, "got %08x\n", hr );
546 ok( !pos, "got %d\n", pos );
548 str = SysAllocString( L"test" );
549 hr = _Stream_WriteText( stream, str, adWriteChar );
550 ok( hr == S_OK, "got %08x\n", hr );
551 SysFreeString( str );
553 hr = _Stream_ReadText( stream, adReadAll, &str );
554 ok( hr == S_OK, "got %08x\n", hr );
555 ok( !str[0], "got %s\n", wine_dbgstr_w(str) );
556 SysFreeString( str );
558 hr = _Stream_put_Position( stream, 0 );
559 ok( hr == S_OK, "got %08x\n", hr );
560 hr = _Stream_ReadText( stream, adReadAll, &str );
561 ok( hr == S_OK, "got %08x\n", hr );
562 ok( !lstrcmpW( str, L"test" ), "got %s\n", wine_dbgstr_w(str) );
563 SysFreeString( str );
565 pos = -1;
566 hr = _Stream_get_Position( stream, &pos );
567 ok( hr == S_OK, "got %08x\n", hr );
568 ok( pos == 10, "got %d\n", pos );
570 eos = VARIANT_FALSE;
571 hr = _Stream_get_EOS( stream, &eos );
572 ok( hr == S_OK, "got %08x\n", hr );
573 ok( eos == VARIANT_TRUE, "got %04x\n", eos );
575 hr = _Stream_put_Position( stream, 6 );
576 ok( hr == S_OK, "got %08x\n", hr );
578 size = -1;
579 hr = _Stream_get_Size( stream, &size );
580 ok( hr == S_OK, "got %08x\n", hr );
581 ok( size == 10, "got %d\n", size );
583 hr = _Stream_put_Position( stream, 2 );
584 ok( hr == S_OK, "got %08x\n", hr );
586 hr = _Stream_SetEOS( stream );
587 ok( hr == S_OK, "got %08x\n", hr );
589 pos = -1;
590 hr = _Stream_get_Position( stream, &pos );
591 ok( hr == S_OK, "got %08x\n", hr );
592 ok( pos == 2, "got %d\n", pos );
594 size = -1;
595 hr = _Stream_get_Size( stream, &size );
596 ok( hr == S_OK, "got %08x\n", hr );
597 ok( size == 2, "got %d\n", size );
599 hr = _Stream_Close( stream );
600 ok( hr == S_OK, "got %08x\n", hr );
602 state = 0xdeadbeef;
603 hr = _Stream_get_State( stream, &state );
604 ok( hr == S_OK, "got %08x\n", hr );
605 ok( state == adStateClosed, "got %u\n", state );
607 hr = _Stream_Close( stream );
608 ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
610 refs = _Stream_Release( stream );
611 ok( !refs, "got %d\n", refs );
613 /* binary type */
614 hr = CoCreateInstance( &CLSID_Stream, NULL, CLSCTX_INPROC_SERVER, &IID__Stream, (void **)&stream );
615 ok( hr == S_OK, "got %08x\n", hr );
617 hr = _Stream_put_Type( stream, adTypeBinary );
618 ok( hr == S_OK, "got %08x\n", hr );
620 hr = _Stream_Open( stream, missing, adModeUnknown, adOpenStreamUnspecified, NULL, NULL );
621 ok( hr == S_OK, "got %08x\n", hr );
623 hr = _Stream_ReadText( stream, adReadAll, &str );
624 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08x\n", hr );
626 str = SysAllocString( L"test" );
627 hr = _Stream_WriteText( stream, str, adWriteChar );
628 ok( hr == MAKE_ADO_HRESULT( adErrIllegalOperation ), "got %08x\n", hr );
629 SysFreeString( str );
631 VariantInit( &val );
632 hr = _Stream_Read( stream, 1, &val );
633 ok( hr == S_OK, "got %08x\n", hr );
634 ok( V_VT( &val ) == VT_NULL, "got %u\n", V_VT( &val ) );
636 VariantInit( &val );
637 hr = _Stream_Write( stream, val );
638 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08x\n", hr );
640 hr = str_to_byte_array( "data", &val );
641 ok( hr == S_OK, "got %08x\n", hr );
642 hr = _Stream_Write( stream, val );
643 ok( hr == S_OK, "got %08x\n", hr );
644 VariantClear( &val );
646 pos = -1;
647 hr = _Stream_get_Position( stream, &pos );
648 ok( hr == S_OK, "got %08x\n", hr );
649 ok( pos == 4, "got %d\n", pos );
651 hr = _Stream_put_Position( stream, 0 );
652 ok( hr == S_OK, "got %08x\n", hr );
654 VariantInit( &val );
655 hr = _Stream_Read( stream, adReadAll, &val );
656 ok( hr == S_OK, "got %08x\n", hr );
657 ok( V_VT( &val ) == (VT_ARRAY | VT_UI1), "got %04x\n", V_VT( &val ) );
658 VariantClear( &val );
660 pos = -1;
661 hr = _Stream_get_Position( stream, &pos );
662 ok( hr == S_OK, "got %08x\n", hr );
663 ok( pos == 4, "got %d\n", pos );
665 refs = _Stream_Release( stream );
666 ok( !refs, "got %d\n", refs );
669 static void test_Connection(void)
671 HRESULT hr;
672 _Connection *connection;
673 IRunnableObject *runtime;
674 ISupportErrorInfo *errorinfo;
675 IConnectionPointContainer *pointcontainer;
676 LONG state, timeout;
677 BSTR str, str2, str3;
678 ConnectModeEnum mode;
679 CursorLocationEnum location;
681 hr = CoCreateInstance(&CLSID_Connection, NULL, CLSCTX_INPROC_SERVER, &IID__Connection, (void**)&connection);
682 ok( hr == S_OK, "got %08x\n", hr );
684 hr = _Connection_QueryInterface(connection, &IID_IRunnableObject, (void**)&runtime);
685 ok(hr == E_NOINTERFACE, "Unexpected IRunnableObject interface\n");
686 ok(runtime == NULL, "expected NULL\n");
688 hr = _Connection_QueryInterface(connection, &IID_ISupportErrorInfo, (void**)&errorinfo);
689 ok(hr == S_OK, "Failed to get ISupportErrorInfo interface\n");
690 ISupportErrorInfo_Release(errorinfo);
692 hr = _Connection_QueryInterface(connection, &IID_IConnectionPointContainer, (void**)&pointcontainer);
693 ok(hr == S_OK, "Failed to get IConnectionPointContainer interface %08x\n", hr);
694 IConnectionPointContainer_Release(pointcontainer);
696 if (0) /* Crashes on windows */
698 hr = _Connection_get_State(connection, NULL);
699 ok(hr == E_INVALIDARG, "Unexpected hr 0x%08x\n", hr);
702 state = -1;
703 hr = _Connection_get_State(connection, &state);
704 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
705 ok(state == adStateClosed, "Unexpected state value 0x%08x\n", state);
707 hr = _Connection_Close(connection);
708 ok(hr == MAKE_ADO_HRESULT(adErrObjectClosed), "got %08x\n", hr);
710 timeout = 0;
711 hr = _Connection_get_CommandTimeout(connection, &timeout);
712 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
713 ok(timeout == 30, "Unexpected timeout value %d\n", timeout);
715 hr = _Connection_put_CommandTimeout(connection, 300);
716 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
718 timeout = 0;
719 hr = _Connection_get_CommandTimeout(connection, &timeout);
720 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
721 ok(timeout == 300, "Unexpected timeout value %d\n", timeout);
723 location = 0;
724 hr = _Connection_get_CursorLocation(connection, &location);
725 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
726 ok(location == adUseServer, "Unexpected location value %d\n", location);
728 hr = _Connection_put_CursorLocation(connection, adUseClient);
729 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
731 location = 0;
732 hr = _Connection_get_CursorLocation(connection, &location);
733 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
734 ok(location == adUseClient, "Unexpected location value %d\n", location);
736 hr = _Connection_put_CursorLocation(connection, adUseServer);
737 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
739 mode = 0xdeadbeef;
740 hr = _Connection_get_Mode(connection, &mode);
741 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
742 ok(mode == adModeUnknown, "Unexpected mode value %d\n", mode);
744 hr = _Connection_put_Mode(connection, adModeShareDenyNone);
745 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
747 mode = adModeUnknown;
748 hr = _Connection_get_Mode(connection, &mode);
749 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
750 ok(mode == adModeShareDenyNone, "Unexpected mode value %d\n", mode);
752 hr = _Connection_put_Mode(connection, adModeUnknown);
753 ok(hr == S_OK, "Failed to get state, hr 0x%08x\n", hr);
755 /* Default */
756 str = (BSTR)0xdeadbeef;
757 hr = _Connection_get_Provider(connection, &str);
758 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
759 ok(!wcscmp(str, L"MSDASQL"), "wrong string %s\n", wine_dbgstr_w(str));
760 SysFreeString(str);
762 str = SysAllocString(L"MSDASQL.1");
763 hr = _Connection_put_Provider(connection, str);
764 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
765 SysFreeString(str);
767 str = (BSTR)0xdeadbeef;
768 hr = _Connection_get_Provider(connection, &str);
769 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
770 ok(!wcscmp(str, L"MSDASQL.1"), "wrong string %s\n", wine_dbgstr_w(str));
772 /* Restore default */
773 str = SysAllocString(L"MSDASQL");
774 hr = _Connection_put_Provider(connection, str);
775 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
776 SysFreeString(str);
778 hr = _Connection_put_Provider(connection, NULL);
779 ok(hr == MAKE_ADO_HRESULT(adErrInvalidArgument), "got 0x%08x\n", hr);
780 SysFreeString(str);
782 str = (BSTR)0xdeadbeef;
783 hr = _Connection_get_ConnectionString(connection, &str);
784 ok(hr == S_OK, "got 0x%08x\n", hr);
785 ok(str == NULL, "got %p\n", str);
787 str = SysAllocString(L"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_test");
788 hr = _Connection_put_ConnectionString(connection, str);
789 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
791 /* Show put_ConnectionString effects Provider */
792 str3 = (BSTR)0xdeadbeef;
793 hr = _Connection_get_Provider(connection, &str3);
794 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
795 ok(str3 != NULL, "Expected value got NULL\n");
796 todo_wine ok(!wcscmp(str3, L"MSDASQL.1"), "wrong string %s\n", wine_dbgstr_w(str3));
797 SysFreeString(str3);
799 if (0) /* Crashes on windows */
801 hr = _Connection_get_ConnectionString(connection, NULL);
802 ok(hr == E_POINTER, "Failed, hr 0x%08x\n", hr);
805 str2 = NULL;
806 hr = _Connection_get_ConnectionString(connection, &str2);
807 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
808 ok(!wcscmp(str, str2), "wrong string %s\n", wine_dbgstr_w(str2));
810 hr = _Connection_Open(connection, NULL, NULL, NULL, 0);
811 todo_wine ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr);
813 /* Open adds trailing ; if it's missing */
814 str3 = SysAllocString(L"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_test;");
815 hr = _Connection_Open(connection, NULL, NULL, NULL, adConnectUnspecified);
816 todo_wine ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr);
818 str2 = NULL;
819 hr = _Connection_get_ConnectionString(connection, &str2);
820 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
821 todo_wine ok(!wcscmp(str3, str2) || broken(!wcscmp(str, str2)) /* XP */, "wrong string %s\n", wine_dbgstr_w(str2));
823 hr = _Connection_Open(connection, str, NULL, NULL, adConnectUnspecified);
824 todo_wine ok(hr == E_FAIL, "Failed, hr 0x%08x\n", hr);
825 SysFreeString(str);
827 str2 = NULL;
828 hr = _Connection_get_ConnectionString(connection, &str2);
829 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
830 todo_wine ok(!wcscmp(str3, str2) || broken(!wcscmp(str, str2)) /* XP */, "wrong string %s\n", wine_dbgstr_w(str2));
831 SysFreeString(str2);
832 SysFreeString(str3);
834 hr = _Connection_put_ConnectionString(connection, NULL);
835 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
837 str = (BSTR)0xdeadbeef;
838 hr = _Connection_get_ConnectionString(connection, &str);
839 ok(hr == S_OK, "Failed, hr 0x%08x\n", hr);
840 ok(str == NULL, "got %p\n", str);
841 _Connection_Release(connection);
844 static void test_Command(void)
846 HRESULT hr;
847 _Command *command;
848 _ADO *ado;
849 Command15 *command15;
850 Command25 *command25;
851 CommandTypeEnum cmd_type = adCmdUnspecified;
852 BSTR cmd_text = (BSTR)"test";
853 _Connection *connection;
855 hr = CoCreateInstance( &CLSID_Command, NULL, CLSCTX_INPROC_SERVER, &IID__Command, (void **)&command );
856 ok( hr == S_OK, "got %08x\n", hr );
858 hr = _Command_QueryInterface( command, &IID__ADO, (void **)&ado );
859 ok( hr == S_OK, "got %08x\n", hr );
860 _ADO_Release( ado );
862 hr = _Command_QueryInterface( command, &IID_Command15, (void **)&command15 );
863 ok( hr == S_OK, "got %08x\n", hr );
864 Command15_Release( command15 );
866 hr = _Command_QueryInterface( command, &IID_Command25, (void **)&command25 );
867 ok( hr == S_OK, "got %08x\n", hr );
868 Command25_Release( command25 );
870 hr = _Command_get_CommandType( command, &cmd_type );
871 ok( hr == S_OK, "got %08x\n", hr );
872 ok( cmd_type == adCmdUnknown, "got %08x\n", cmd_type );
874 _Command_put_CommandType( command, adCmdText );
875 hr = _Command_get_CommandType( command, &cmd_type );
876 ok( hr == S_OK, "got %08x\n", hr );
877 ok( cmd_type == adCmdText, "got %08x\n", cmd_type );
879 hr = _Command_put_CommandType( command, 0xdeadbeef );
880 ok( hr == MAKE_ADO_HRESULT( adErrInvalidArgument ), "got %08x\n", hr );
882 hr = _Command_get_CommandText( command, &cmd_text );
883 ok( hr == S_OK, "got %08x\n", hr );
884 ok( !cmd_text, "got %s\n", wine_dbgstr_w( cmd_text ));
886 hr = _Command_put_CommandText( command, NULL );
887 ok( hr == S_OK, "got %08x\n", hr );
889 cmd_text = SysAllocString( L"" );
890 hr = _Command_put_CommandText( command, cmd_text );
891 ok( hr == S_OK, "got %08x\n", hr );
892 SysFreeString( cmd_text );
894 hr = _Command_get_CommandText( command, &cmd_text );
895 ok( hr == S_OK, "got %08x\n", hr );
896 ok( cmd_text && !*cmd_text, "got %p\n", cmd_text );
898 cmd_text = SysAllocString( L"test" );
899 hr = _Command_put_CommandText( command, cmd_text );
900 ok( hr == S_OK, "got %08x\n", hr );
901 SysFreeString( cmd_text );
903 hr = _Command_get_CommandText( command, &cmd_text );
904 ok( hr == S_OK, "got %08x\n", hr );
905 ok( !wcscmp( L"test", cmd_text ), "got %p\n", wine_dbgstr_w( cmd_text ) );
907 connection = (_Connection*)0xdeadbeef;
908 hr = _Command_get_ActiveConnection( command, &connection );
909 ok( hr == S_OK, "got %08x\n", hr );
910 ok( connection == NULL, "got %p\n", connection );
912 hr = _Command_putref_ActiveConnection( command, NULL );
913 ok( hr == S_OK, "got %08x\n", hr );
915 _Command_Release( command );
918 struct conn_event {
919 ConnectionEventsVt conn_event_sink;
920 LONG refs;
923 static HRESULT WINAPI conneventvt_QueryInterface( ConnectionEventsVt *iface, REFIID riid, void **obj )
925 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
927 if (IsEqualGUID( &IID_ConnectionEventsVt, riid ))
929 InterlockedIncrement( &conn_event->refs );
930 *obj = iface;
931 return S_OK;
934 ok( 0, "unexpected call\n" );
935 return E_NOINTERFACE;
938 static ULONG WINAPI conneventvt_AddRef( ConnectionEventsVt *iface )
940 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
941 return InterlockedIncrement( &conn_event->refs );
944 static ULONG WINAPI conneventvt_Release( ConnectionEventsVt *iface )
946 struct conn_event *conn_event = CONTAINING_RECORD( iface, struct conn_event, conn_event_sink );
947 return InterlockedDecrement( &conn_event->refs );
950 static HRESULT WINAPI conneventvt_InfoMessage( ConnectionEventsVt *iface, Error *error,
951 EventStatusEnum *status, _Connection *Connection )
953 return E_NOTIMPL;
956 static HRESULT WINAPI conneventvt_BeginTransComplete( ConnectionEventsVt *iface, LONG TransactionLevel,
957 Error *error, EventStatusEnum *status, _Connection *connection )
959 return E_NOTIMPL;
962 static HRESULT WINAPI conneventvt_CommitTransComplete( ConnectionEventsVt *iface, Error *error,
963 EventStatusEnum *status, _Connection *connection )
965 return E_NOTIMPL;
968 static HRESULT WINAPI conneventvt_RollbackTransComplete( ConnectionEventsVt *iface, Error *error,
969 EventStatusEnum *status, _Connection *connection )
971 return E_NOTIMPL;
974 static HRESULT WINAPI conneventvt_WillExecute( ConnectionEventsVt *iface, BSTR *source,
975 CursorTypeEnum *cursor_type, LockTypeEnum *lock_type, LONG *options, EventStatusEnum *status,
976 _Command *command, _Recordset *record_set, _Connection *connection )
978 return E_NOTIMPL;
981 static HRESULT WINAPI conneventvt_ExecuteComplete( ConnectionEventsVt *iface, LONG records_affected,
982 Error *error, EventStatusEnum *status, _Command *command, _Recordset *record_set,
983 _Connection *connection )
985 return E_NOTIMPL;
988 static HRESULT WINAPI conneventvt_WillConnect( ConnectionEventsVt *iface, BSTR *string, BSTR *userid,
989 BSTR *password, LONG *options, EventStatusEnum *status, _Connection *connection )
991 return E_NOTIMPL;
994 static HRESULT WINAPI conneventvt_ConnectComplete( ConnectionEventsVt *iface, Error *error,
995 EventStatusEnum *status, _Connection *connection )
997 return E_NOTIMPL;
1000 static HRESULT WINAPI conneventvt_Disconnect( ConnectionEventsVt *iface, EventStatusEnum *status,
1001 _Connection *connection )
1003 return E_NOTIMPL;
1006 static const ConnectionEventsVtVtbl conneventvt_vtbl = {
1007 conneventvt_QueryInterface,
1008 conneventvt_AddRef,
1009 conneventvt_Release,
1010 conneventvt_InfoMessage,
1011 conneventvt_BeginTransComplete,
1012 conneventvt_CommitTransComplete,
1013 conneventvt_RollbackTransComplete,
1014 conneventvt_WillExecute,
1015 conneventvt_ExecuteComplete,
1016 conneventvt_WillConnect,
1017 conneventvt_ConnectComplete,
1018 conneventvt_Disconnect
1021 static HRESULT WINAPI supporterror_QueryInterface( ISupportErrorInfo *iface, REFIID riid, void **obj )
1023 if (IsEqualGUID( &IID_ISupportErrorInfo, riid ))
1025 *obj = iface;
1026 return S_OK;
1029 return E_NOINTERFACE;
1032 static ULONG WINAPI supporterror_AddRef( ISupportErrorInfo *iface )
1034 return 2;
1037 static ULONG WINAPI supporterror_Release( ISupportErrorInfo *iface )
1039 return 1;
1042 static HRESULT WINAPI supporterror_InterfaceSupportsErrorInfo( ISupportErrorInfo *iface, REFIID riid )
1044 return E_NOTIMPL;
1047 static const struct ISupportErrorInfoVtbl support_error_vtbl =
1049 supporterror_QueryInterface,
1050 supporterror_AddRef,
1051 supporterror_Release,
1052 supporterror_InterfaceSupportsErrorInfo
1055 static void test_ConnectionPoint(void)
1057 HRESULT hr;
1058 ULONG refs;
1059 DWORD cookie;
1060 IConnectionPoint *point;
1061 IConnectionPointContainer *pointcontainer;
1062 struct conn_event conn_event = { { &conneventvt_vtbl }, 0 };
1063 ISupportErrorInfo support_err_sink = { &support_error_vtbl };
1065 hr = CoCreateInstance( &CLSID_Connection, NULL, CLSCTX_INPROC_SERVER,
1066 &IID_IConnectionPointContainer, (void**)&pointcontainer );
1068 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_ConnectionEvents, NULL );
1069 ok( hr == E_POINTER, "got %08x\n", hr );
1071 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_RecordsetEvents, &point );
1072 ok( hr == CONNECT_E_NOCONNECTION, "got %08x\n", hr );
1074 hr = IConnectionPointContainer_FindConnectionPoint( pointcontainer, &DIID_ConnectionEvents, &point );
1075 ok( hr == S_OK, "got %08x\n", hr );
1077 /* nothing advised yet */
1078 hr = IConnectionPoint_Unadvise( point, 3 );
1079 ok( hr == E_FAIL, "got %08x\n", hr );
1081 hr = IConnectionPoint_Advise( point, NULL, NULL );
1082 ok( hr == E_FAIL, "got %08x\n", hr );
1084 hr = IConnectionPoint_Advise( point, (void*)&conn_event.conn_event_sink, NULL );
1085 ok( hr == E_FAIL, "got %08x\n", hr );
1087 cookie = 0xdeadbeef;
1088 hr = IConnectionPoint_Advise( point, NULL, &cookie );
1089 ok( hr == E_FAIL, "got %08x\n", hr );
1090 ok( cookie == 0xdeadbeef, "got %08x\n", cookie );
1092 /* unsupported sink */
1093 cookie = 0xdeadbeef;
1094 hr = IConnectionPoint_Advise( point, (void*)&support_err_sink, &cookie );
1095 ok( hr == E_FAIL, "got %08x\n", hr );
1096 ok( !cookie, "got %08x\n", cookie );
1098 cookie = 0;
1099 hr = IConnectionPoint_Advise( point, (void*)&conn_event.conn_event_sink, &cookie );
1100 ok( hr == S_OK, "got %08x\n", hr );
1101 ok( cookie, "got %08x\n", cookie );
1103 /* invalid cookie */
1104 hr = IConnectionPoint_Unadvise( point, 0 );
1105 ok( hr == E_FAIL, "got %08x\n", hr );
1107 /* wrong cookie */
1108 hr = IConnectionPoint_Unadvise( point, cookie + 1 );
1109 ok( hr == E_FAIL, "got %08x\n", hr );
1111 hr = IConnectionPoint_Unadvise( point, cookie );
1112 ok( hr == S_OK, "got %08x\n", hr );
1114 /* sinks are released when the connection is destroyed */
1115 cookie = 0;
1116 hr = IConnectionPoint_Advise( point, (void*)&conn_event.conn_event_sink, &cookie );
1117 ok( hr == S_OK, "got %08x\n", hr );
1118 ok( cookie, "got %08x\n", cookie );
1119 ok( conn_event.refs == 1, "got %d\n", conn_event.refs );
1121 refs = IConnectionPoint_Release( point );
1122 ok( refs == 1, "got %u", refs );
1124 IConnectionPointContainer_Release( pointcontainer );
1126 ok( !conn_event.refs, "got %d\n", conn_event.refs );
1129 START_TEST(msado15)
1131 CoInitialize( NULL );
1132 test_Connection();
1133 test_ConnectionPoint();
1134 test_Fields();
1135 test_Recordset();
1136 test_Stream();
1137 test_Command();
1138 CoUninitialize();