wined3d: Properly compare integers in wined3d_bo_slab_vk_compare().
[wine.git] / dlls / msado15 / connection.c
blobce7750fef6642d0a8a19cde8d951d78f0497e3d6
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 <stdarg.h>
20 #include "windef.h"
21 #include "winbase.h"
22 #define COBJMACROS
23 #define DBINITCONSTANTS
24 #include "initguid.h"
25 #include "ocidl.h"
26 #include "objbase.h"
27 #include "msdasc.h"
28 #include "olectl.h"
29 #include "msado15_backcompat.h"
31 #include "wine/debug.h"
32 #include "wine/heap.h"
34 #include "msado15_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(msado15);
38 struct connection;
40 struct connection_point
42 IConnectionPoint IConnectionPoint_iface;
43 struct connection *conn;
44 const IID *riid;
45 IUnknown **sinks;
46 ULONG sinks_size;
49 struct connection
51 _Connection Connection_iface;
52 ISupportErrorInfo ISupportErrorInfo_iface;
53 IConnectionPointContainer IConnectionPointContainer_iface;
54 ADOConnectionConstruction15 ADOConnectionConstruction15_iface;
55 LONG refs;
56 ObjectStateEnum state;
57 LONG timeout;
58 WCHAR *datasource;
59 WCHAR *provider;
60 ConnectModeEnum mode;
61 CursorLocationEnum location;
62 IUnknown *session;
63 struct connection_point cp_connev;
66 static inline struct connection *impl_from_Connection( _Connection *iface )
68 return CONTAINING_RECORD( iface, struct connection, Connection_iface );
71 static inline struct connection *impl_from_ISupportErrorInfo( ISupportErrorInfo *iface )
73 return CONTAINING_RECORD( iface, struct connection, ISupportErrorInfo_iface );
76 static inline struct connection *impl_from_IConnectionPointContainer( IConnectionPointContainer *iface )
78 return CONTAINING_RECORD( iface, struct connection, IConnectionPointContainer_iface );
81 static inline struct connection *impl_from_ADOConnectionConstruction15( ADOConnectionConstruction15 *iface )
83 return CONTAINING_RECORD( iface, struct connection, ADOConnectionConstruction15_iface );
86 static inline struct connection_point *impl_from_IConnectionPoint( IConnectionPoint *iface )
88 return CONTAINING_RECORD( iface, struct connection_point, IConnectionPoint_iface );
91 static ULONG WINAPI connection_AddRef( _Connection *iface )
93 struct connection *connection = impl_from_Connection( iface );
94 return InterlockedIncrement( &connection->refs );
97 static ULONG WINAPI connection_Release( _Connection *iface )
99 struct connection *connection = impl_from_Connection( iface );
100 LONG refs = InterlockedDecrement( &connection->refs );
101 ULONG i;
102 if (!refs)
104 TRACE( "destroying %p\n", connection );
105 for (i = 0; i < connection->cp_connev.sinks_size; ++i)
107 if (connection->cp_connev.sinks[i])
108 IUnknown_Release( connection->cp_connev.sinks[i] );
110 if (connection->session) IUnknown_Release( connection->session );
111 heap_free( connection->cp_connev.sinks );
112 heap_free( connection->provider );
113 heap_free( connection->datasource );
114 heap_free( connection );
116 return refs;
119 static HRESULT WINAPI connection_QueryInterface( _Connection *iface, REFIID riid, void **obj )
121 struct connection *connection = impl_from_Connection( iface );
122 TRACE( "%p, %s, %p\n", connection, debugstr_guid(riid), obj );
124 *obj = NULL;
126 if (IsEqualGUID( riid, &IID__Connection ) || IsEqualGUID( riid, &IID_IDispatch ) ||
127 IsEqualGUID( riid, &IID_IUnknown ))
129 *obj = iface;
131 else if(IsEqualGUID( riid, &IID_ISupportErrorInfo ))
133 *obj = &connection->ISupportErrorInfo_iface;
135 else if (IsEqualGUID( riid, &IID_IConnectionPointContainer ))
137 *obj = &connection->IConnectionPointContainer_iface;
139 else if (IsEqualGUID( riid, &IID_ADOConnectionConstruction15 ))
141 *obj = &connection->ADOConnectionConstruction15_iface;
143 else if (IsEqualGUID( riid, &IID_IRunnableObject ))
145 TRACE("IID_IRunnableObject not supported returning NULL\n");
146 return E_NOINTERFACE;
148 else
150 FIXME( "interface %s not implemented\n", debugstr_guid(riid) );
151 return E_NOINTERFACE;
153 connection_AddRef( iface );
154 return S_OK;
157 static HRESULT WINAPI connection_GetTypeInfoCount( _Connection *iface, UINT *count )
159 struct connection *connection = impl_from_Connection( iface );
160 TRACE( "%p, %p\n", connection, count );
161 *count = 1;
162 return S_OK;
165 static HRESULT WINAPI connection_GetTypeInfo( _Connection *iface, UINT index, LCID lcid, ITypeInfo **info )
167 struct connection *connection = impl_from_Connection( iface );
168 TRACE( "%p, %u, %u, %p\n", connection, index, lcid, info );
169 return get_typeinfo(Connection_tid, info);
172 static HRESULT WINAPI connection_GetIDsOfNames( _Connection *iface, REFIID riid, LPOLESTR *names, UINT count,
173 LCID lcid, DISPID *dispid )
175 struct connection *connection = impl_from_Connection( iface );
176 HRESULT hr;
177 ITypeInfo *typeinfo;
179 TRACE( "%p, %s, %p, %u, %u, %p\n", connection, debugstr_guid(riid), names, count, lcid, dispid );
181 hr = get_typeinfo(Connection_tid, &typeinfo);
182 if(SUCCEEDED(hr))
184 hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, dispid);
185 ITypeInfo_Release(typeinfo);
188 return hr;
191 static HRESULT WINAPI connection_Invoke( _Connection *iface, DISPID member, REFIID riid, LCID lcid, WORD flags,
192 DISPPARAMS *params, VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err )
194 struct connection *connection = impl_from_Connection( iface );
195 HRESULT hr;
196 ITypeInfo *typeinfo;
198 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", connection, member, debugstr_guid(riid), lcid, flags,
199 params, result, excep_info, arg_err );
201 hr = get_typeinfo(Connection_tid, &typeinfo);
202 if(SUCCEEDED(hr))
204 hr = ITypeInfo_Invoke(typeinfo, &connection->Connection_iface, member, flags, params,
205 result, excep_info, arg_err);
206 ITypeInfo_Release(typeinfo);
209 return hr;
212 static HRESULT WINAPI connection_get_Properties( _Connection *iface, Properties **obj )
214 FIXME( "%p, %p\n", iface, obj );
215 return E_NOTIMPL;
218 static HRESULT WINAPI connection_get_ConnectionString( _Connection *iface, BSTR *str )
220 struct connection *connection = impl_from_Connection( iface );
221 BSTR source = NULL;
223 TRACE( "%p, %p\n", connection, str );
225 if (connection->datasource && !(source = SysAllocString( connection->datasource ))) return E_OUTOFMEMORY;
226 *str = source;
227 return S_OK;
230 static HRESULT WINAPI connection_put_ConnectionString( _Connection *iface, BSTR str )
232 struct connection *connection = impl_from_Connection( iface );
233 WCHAR *source = NULL;
235 TRACE( "%p, %s\n", connection, debugstr_w( str && !wcsstr( str, L"Password" ) ? L"<hidden>" : str ) );
237 if (str && !(source = strdupW( str ))) return E_OUTOFMEMORY;
238 heap_free( connection->datasource );
239 connection->datasource = source;
240 return S_OK;
243 static HRESULT WINAPI connection_get_CommandTimeout( _Connection *iface, LONG *timeout )
245 struct connection *connection = impl_from_Connection( iface );
246 TRACE( "%p, %p\n", connection, timeout );
247 *timeout = connection->timeout;
248 return S_OK;
251 static HRESULT WINAPI connection_put_CommandTimeout( _Connection *iface, LONG timeout )
253 struct connection *connection = impl_from_Connection( iface );
254 TRACE( "%p, %d\n", connection, timeout );
255 connection->timeout = timeout;
256 return S_OK;
259 static HRESULT WINAPI connection_get_ConnectionTimeout( _Connection *iface, LONG *timeout )
261 FIXME( "%p, %p\n", iface, timeout );
262 return E_NOTIMPL;
265 static HRESULT WINAPI connection_put_ConnectionTimeout( _Connection *iface, LONG timeout )
267 FIXME( "%p, %d\n", iface, timeout );
268 return E_NOTIMPL;
271 static HRESULT WINAPI connection_get_Version( _Connection *iface, BSTR *str )
273 FIXME( "%p, %p\n", iface, str );
274 return E_NOTIMPL;
277 static HRESULT WINAPI connection_Close( _Connection *iface )
279 struct connection *connection = impl_from_Connection( iface );
281 TRACE( "%p\n", connection );
283 if (connection->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed );
285 if (connection->session)
287 IUnknown_Release( connection->session );
288 connection->session = NULL;
291 connection->state = adStateClosed;
292 return S_OK;
295 static HRESULT WINAPI connection_Execute( _Connection *iface, BSTR command, VARIANT *records_affected,
296 LONG options, _Recordset **record_set )
298 struct connection *connection = impl_from_Connection( iface );
299 HRESULT hr;
300 _Recordset *recordset;
301 VARIANT source, active;
302 IDispatch *dispatch;
304 FIXME( "%p, %s, %p, 0x%08x, %p Semi-stub\n", iface, debugstr_w(command), records_affected, options, record_set );
306 if (connection->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed );
308 hr = Recordset_create( (void**)&recordset);
309 if (FAILED(hr))
311 return hr;
314 _Recordset_put_CursorLocation(recordset, connection->location);
316 V_VT(&source) = VT_BSTR;
317 V_BSTR(&source) = command;
319 hr = _Connection_QueryInterface(&connection->Connection_iface, &IID_IDispatch, (void**)&dispatch);
320 if (FAILED(hr))
322 _Recordset_Release(recordset);
323 return hr;
326 V_VT(&active) = VT_DISPATCH;
327 V_DISPATCH(&active) = dispatch;
329 hr = _Recordset_Open(recordset, source, active, adOpenDynamic, adLockPessimistic, 0);
330 VariantClear(&active);
331 if (FAILED(hr))
333 _Recordset_Release(recordset);
334 return hr;
337 if (records_affected)
339 V_VT(records_affected) = VT_I4;
340 _Recordset_get_RecordCount(recordset, &V_I4(records_affected));
343 *record_set = recordset;
345 return hr;
348 static HRESULT WINAPI connection_BeginTrans( _Connection *iface, LONG *transaction_level )
350 FIXME( "%p, %p\n", iface, transaction_level );
351 return E_NOTIMPL;
354 static HRESULT WINAPI connection_CommitTrans( _Connection *iface )
356 FIXME( "%p\n", iface );
357 return E_NOTIMPL;
360 static HRESULT WINAPI connection_RollbackTrans( _Connection *iface )
362 FIXME( "%p\n", iface );
363 return E_NOTIMPL;
366 static HRESULT WINAPI connection_Open( _Connection *iface, BSTR connect_str, BSTR userid, BSTR password,
367 LONG options )
369 struct connection *connection = impl_from_Connection( iface );
370 IDBProperties *props;
371 IDBInitialize *dbinit = NULL;
372 IDataInitialize *datainit;
373 IDBCreateSession *session = NULL;
374 HRESULT hr;
376 TRACE( "%p, %s, %s, %p, %08x\n", iface, debugstr_w(connect_str), debugstr_w(userid), password, options );
378 if (connection->state == adStateOpen) return MAKE_ADO_HRESULT( adErrObjectOpen );
379 if (!connect_str) return E_FAIL;
381 if ((hr = CoCreateInstance( &CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,
382 (void **)&datainit )) != S_OK) return hr;
383 if ((hr = IDataInitialize_GetDataSource( datainit, NULL, CLSCTX_INPROC_SERVER, connect_str, &IID_IDBInitialize,
384 (IUnknown **)&dbinit )) != S_OK) goto done;
385 if ((hr = IDBInitialize_QueryInterface( dbinit, &IID_IDBProperties, (void **)&props )) != S_OK) goto done;
387 /* TODO - Update username/password if required. */
388 if ((userid && *userid) || (password && *password))
389 FIXME("Username/password parameters currently not supported\n");
391 if ((hr = IDBInitialize_Initialize( dbinit )) != S_OK) goto done;
392 if ((hr = IDBInitialize_QueryInterface( dbinit, &IID_IDBCreateSession, (void **)&session )) != S_OK) goto done;
393 if ((hr = IDBCreateSession_CreateSession( session, NULL, &IID_IUnknown, &connection->session )) == S_OK)
395 connection->state = adStateOpen;
397 IDBCreateSession_Release( session );
399 done:
400 if (hr != S_OK && connection->session)
402 IUnknown_Release( connection->session );
403 connection->session = NULL;
405 if (dbinit)
407 IDBInitialize_Uninitialize( dbinit );
408 IDBInitialize_Release( dbinit );
410 IDataInitialize_Release( datainit );
412 TRACE("ret 0x%08x\n", hr);
413 return hr;
416 static HRESULT WINAPI connection_get_Errors( _Connection *iface, Errors **obj )
418 FIXME( "%p, %p\n", iface, obj );
419 return E_NOTIMPL;
422 static HRESULT WINAPI connection_get_DefaultDatabase( _Connection *iface, BSTR *str )
424 FIXME( "%p, %p\n", iface, str );
425 return E_NOTIMPL;
428 static HRESULT WINAPI connection_put_DefaultDatabase( _Connection *iface, BSTR str )
430 FIXME( "%p, %s\n", iface, debugstr_w(str) );
431 return E_NOTIMPL;
434 static HRESULT WINAPI connection_get_IsolationLevel( _Connection *iface, IsolationLevelEnum *level )
436 FIXME( "%p, %p\n", iface, level );
437 return E_NOTIMPL;
440 static HRESULT WINAPI connection_put_IsolationLevel( _Connection *iface, IsolationLevelEnum level )
442 FIXME( "%p, %d\n", iface, level );
443 return E_NOTIMPL;
446 static HRESULT WINAPI connection_get_Attributes( _Connection *iface, LONG *attr )
448 FIXME( "%p, %p\n", iface, attr );
449 return E_NOTIMPL;
452 static HRESULT WINAPI connection_put_Attributes( _Connection *iface, LONG attr )
454 FIXME( "%p, %d\n", iface, attr );
455 return E_NOTIMPL;
458 static HRESULT WINAPI connection_get_CursorLocation( _Connection *iface, CursorLocationEnum *cursor_loc )
460 struct connection *connection = impl_from_Connection( iface );
462 TRACE( "%p, %p\n", iface, cursor_loc );
464 *cursor_loc = connection->location;
465 return S_OK;
468 static HRESULT WINAPI connection_put_CursorLocation( _Connection *iface, CursorLocationEnum cursor_loc )
470 struct connection *connection = impl_from_Connection( iface );
472 TRACE( "%p, %u\n", iface, cursor_loc );
474 connection->location = cursor_loc;
475 return S_OK;
478 static HRESULT WINAPI connection_get_Mode( _Connection *iface, ConnectModeEnum *mode )
480 struct connection *connection = impl_from_Connection( iface );
482 TRACE( "%p, %p\n", iface, mode );
484 *mode = connection->mode;
485 return S_OK;
488 static HRESULT WINAPI connection_put_Mode( _Connection *iface, ConnectModeEnum mode )
490 struct connection *connection = impl_from_Connection( iface );
492 TRACE( "%p, %u\n", iface, mode );
494 connection->mode = mode;
495 return S_OK;
498 static HRESULT WINAPI connection_get_Provider( _Connection *iface, BSTR *str )
500 struct connection *connection = impl_from_Connection( iface );
501 BSTR provider = NULL;
503 TRACE( "%p, %p\n", iface, str );
505 if (connection->provider && !(provider = SysAllocString( connection->provider ))) return E_OUTOFMEMORY;
506 *str = provider;
507 return S_OK;
510 static HRESULT WINAPI connection_put_Provider( _Connection *iface, BSTR str )
512 struct connection *connection = impl_from_Connection( iface );
513 WCHAR *provider = NULL;
515 TRACE( "%p, %s\n", iface, debugstr_w(str) );
517 if (!str) return MAKE_ADO_HRESULT(adErrInvalidArgument);
519 if (!(provider = strdupW( str ))) return E_OUTOFMEMORY;
520 heap_free( connection->provider );
521 connection->provider = provider;
522 return S_OK;
525 static HRESULT WINAPI connection_get_State( _Connection *iface, LONG *state )
527 struct connection *connection = impl_from_Connection( iface );
528 TRACE( "%p, %p\n", connection, state );
529 *state = connection->state;
530 return S_OK;
533 static HRESULT WINAPI connection_OpenSchema( _Connection *iface, SchemaEnum schema, VARIANT restrictions,
534 VARIANT schema_id, _Recordset **record_set )
536 FIXME( "%p, %d, %s, %s, %p\n", iface, schema, debugstr_variant(&restrictions),
537 debugstr_variant(&schema_id), record_set );
538 return E_NOTIMPL;
541 static HRESULT WINAPI connection_Cancel( _Connection *iface )
543 FIXME( "%p\n", iface );
544 return E_NOTIMPL;
547 static const struct _ConnectionVtbl connection_vtbl =
549 connection_QueryInterface,
550 connection_AddRef,
551 connection_Release,
552 connection_GetTypeInfoCount,
553 connection_GetTypeInfo,
554 connection_GetIDsOfNames,
555 connection_Invoke,
556 connection_get_Properties,
557 connection_get_ConnectionString,
558 connection_put_ConnectionString,
559 connection_get_CommandTimeout,
560 connection_put_CommandTimeout,
561 connection_get_ConnectionTimeout,
562 connection_put_ConnectionTimeout,
563 connection_get_Version,
564 connection_Close,
565 connection_Execute,
566 connection_BeginTrans,
567 connection_CommitTrans,
568 connection_RollbackTrans,
569 connection_Open,
570 connection_get_Errors,
571 connection_get_DefaultDatabase,
572 connection_put_DefaultDatabase,
573 connection_get_IsolationLevel,
574 connection_put_IsolationLevel,
575 connection_get_Attributes,
576 connection_put_Attributes,
577 connection_get_CursorLocation,
578 connection_put_CursorLocation,
579 connection_get_Mode,
580 connection_put_Mode,
581 connection_get_Provider,
582 connection_put_Provider,
583 connection_get_State,
584 connection_OpenSchema,
585 connection_Cancel
588 static HRESULT WINAPI supporterror_QueryInterface( ISupportErrorInfo *iface, REFIID riid, void **obj )
590 struct connection *connection = impl_from_ISupportErrorInfo( iface );
591 return connection_QueryInterface( &connection->Connection_iface, riid, obj );
594 static ULONG WINAPI supporterror_AddRef( ISupportErrorInfo *iface )
596 struct connection *connection = impl_from_ISupportErrorInfo( iface );
597 return connection_AddRef( &connection->Connection_iface );
600 static ULONG WINAPI supporterror_Release( ISupportErrorInfo *iface )
602 struct connection *connection = impl_from_ISupportErrorInfo( iface );
603 return connection_Release( &connection->Connection_iface );
606 static HRESULT WINAPI supporterror_InterfaceSupportsErrorInfo( ISupportErrorInfo *iface, REFIID riid )
608 struct connection *connection = impl_from_ISupportErrorInfo( iface );
609 FIXME( "%p, %s\n", connection, debugstr_guid(riid) );
610 return S_FALSE;
613 static const struct ISupportErrorInfoVtbl support_error_vtbl =
615 supporterror_QueryInterface,
616 supporterror_AddRef,
617 supporterror_Release,
618 supporterror_InterfaceSupportsErrorInfo
621 static HRESULT WINAPI connpointcontainer_QueryInterface( IConnectionPointContainer *iface,
622 REFIID riid, void **obj )
624 struct connection *connection = impl_from_IConnectionPointContainer( iface );
625 return connection_QueryInterface( &connection->Connection_iface, riid, obj );
628 static ULONG WINAPI connpointcontainer_AddRef( IConnectionPointContainer *iface )
630 struct connection *connection = impl_from_IConnectionPointContainer( iface );
631 return connection_AddRef( &connection->Connection_iface );
634 static ULONG WINAPI connpointcontainer_Release( IConnectionPointContainer *iface )
636 struct connection *connection = impl_from_IConnectionPointContainer( iface );
637 return connection_Release( &connection->Connection_iface );
640 static HRESULT WINAPI connpointcontainer_EnumConnectionPoints( IConnectionPointContainer *iface,
641 IEnumConnectionPoints **points )
643 struct connection *connection = impl_from_IConnectionPointContainer( iface );
644 FIXME( "%p, %p\n", connection, points );
645 return E_NOTIMPL;
648 static HRESULT WINAPI connpointcontainer_FindConnectionPoint( IConnectionPointContainer *iface,
649 REFIID riid, IConnectionPoint **point )
651 struct connection *connection = impl_from_IConnectionPointContainer( iface );
653 TRACE( "%p, %s %p\n", connection, debugstr_guid( riid ), point );
655 if (!point) return E_POINTER;
657 if (IsEqualIID( riid, connection->cp_connev.riid ))
659 *point = &connection->cp_connev.IConnectionPoint_iface;
660 IConnectionPoint_AddRef( *point );
661 return S_OK;
664 FIXME( "unsupported connection point %s\n", debugstr_guid( riid ) );
665 return CONNECT_E_NOCONNECTION;
668 static const struct IConnectionPointContainerVtbl connpointcontainer_vtbl =
670 connpointcontainer_QueryInterface,
671 connpointcontainer_AddRef,
672 connpointcontainer_Release,
673 connpointcontainer_EnumConnectionPoints,
674 connpointcontainer_FindConnectionPoint
677 static HRESULT WINAPI connpoint_QueryInterface( IConnectionPoint *iface, REFIID riid, void **obj )
679 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
681 if (IsEqualGUID( &IID_IUnknown, riid ) || IsEqualGUID( &IID_IConnectionPoint, riid ))
683 *obj = &connpoint->IConnectionPoint_iface;
685 else
687 FIXME( "interface %s not implemented\n", debugstr_guid( riid ) );
688 return E_NOINTERFACE;
691 connection_AddRef( &connpoint->conn->Connection_iface );
692 return S_OK;
695 static ULONG WINAPI connpoint_AddRef( IConnectionPoint *iface )
697 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
698 return IConnectionPointContainer_AddRef( &connpoint->conn->IConnectionPointContainer_iface );
701 static ULONG WINAPI connpoint_Release( IConnectionPoint *iface )
703 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
704 return IConnectionPointContainer_Release( &connpoint->conn->IConnectionPointContainer_iface );
707 static HRESULT WINAPI connpoint_GetConnectionInterface( IConnectionPoint *iface, IID *iid )
709 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
710 FIXME( "%p, %p\n", connpoint, iid );
711 return E_NOTIMPL;
714 static HRESULT WINAPI connpoint_GetConnectionPointContainer( IConnectionPoint *iface,
715 IConnectionPointContainer **container )
717 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
718 FIXME( "%p, %p\n", connpoint, container );
719 return E_NOTIMPL;
722 static HRESULT WINAPI connpoint_Advise( IConnectionPoint *iface, IUnknown *unk_sink,
723 DWORD *cookie )
725 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
726 IUnknown *sink, **tmp;
727 ULONG new_size;
728 HRESULT hr;
729 DWORD i;
731 TRACE( "%p, %p, %p\n", iface, unk_sink, cookie );
733 if (!unk_sink || !cookie) return E_FAIL;
735 if (FAILED(hr = IUnknown_QueryInterface( unk_sink, &IID_ConnectionEventsVt, (void**)&sink )))
737 *cookie = 0;
738 return E_FAIL;
741 if (connpoint->sinks)
743 for (i = 0; i < connpoint->sinks_size; ++i)
745 if (!connpoint->sinks[i])
746 break;
749 if (i == connpoint->sinks_size)
751 new_size = connpoint->sinks_size * 2;
752 if (!(tmp = heap_realloc_zero( connpoint->sinks, new_size * sizeof(*connpoint->sinks) )))
753 return E_OUTOFMEMORY;
754 connpoint->sinks = tmp;
755 connpoint->sinks_size = new_size;
758 else
760 if (!(connpoint->sinks = heap_alloc_zero( sizeof(*connpoint->sinks) ))) return E_OUTOFMEMORY;
761 connpoint->sinks_size = 1;
762 i = 0;
765 connpoint->sinks[i] = sink;
766 *cookie = i + 1;
767 return S_OK;
770 static HRESULT WINAPI connpoint_Unadvise( IConnectionPoint *iface, DWORD cookie )
772 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
773 TRACE( "%p, %u\n", connpoint, cookie );
775 if (!cookie || cookie > connpoint->sinks_size || !connpoint->sinks || !connpoint->sinks[cookie - 1])
776 return E_FAIL;
778 IUnknown_Release( connpoint->sinks[cookie - 1] );
779 connpoint->sinks[cookie - 1] = NULL;
780 return S_OK;
783 static HRESULT WINAPI connpoint_EnumConnections( IConnectionPoint *iface,
784 IEnumConnections **points )
786 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
787 FIXME( "%p, %p\n", connpoint, points );
788 return E_NOTIMPL;
791 static const IConnectionPointVtbl connpoint_vtbl =
793 connpoint_QueryInterface,
794 connpoint_AddRef,
795 connpoint_Release,
796 connpoint_GetConnectionInterface,
797 connpoint_GetConnectionPointContainer,
798 connpoint_Advise,
799 connpoint_Unadvise,
800 connpoint_EnumConnections
803 static HRESULT WINAPI adoconstruct_QueryInterface(ADOConnectionConstruction15 *iface, REFIID riid, void **obj)
805 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
806 return _Connection_QueryInterface( &connection->Connection_iface, riid, obj );
809 static ULONG WINAPI adoconstruct_AddRef(ADOConnectionConstruction15 *iface)
811 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
812 return _Connection_AddRef( &connection->Connection_iface );
815 static ULONG WINAPI adoconstruct_Release(ADOConnectionConstruction15 *iface)
817 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
818 return _Connection_Release( &connection->Connection_iface );
821 static HRESULT WINAPI adoconstruct_get_DSO(ADOConnectionConstruction15 *iface, IUnknown **dso)
823 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
824 FIXME("%p, %p\n", connection, dso);
825 return E_NOTIMPL;
828 static HRESULT WINAPI adoconstruct_get_Session(ADOConnectionConstruction15 *iface, IUnknown **session)
830 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
831 TRACE("%p, %p\n", connection, session);
833 *session = connection->session;
834 if (*session)
835 IUnknown_AddRef(*session);
836 return S_OK;
839 static HRESULT WINAPI adoconstruct_WrapDSOandSession(ADOConnectionConstruction15 *iface, IUnknown *dso,
840 IUnknown *session)
842 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
843 FIXME("%p, %p, %p\n", connection, dso, session);
844 return E_NOTIMPL;
847 struct ADOConnectionConstruction15Vtbl ado_construct_vtbl =
849 adoconstruct_QueryInterface,
850 adoconstruct_AddRef,
851 adoconstruct_Release,
852 adoconstruct_get_DSO,
853 adoconstruct_get_Session,
854 adoconstruct_WrapDSOandSession
857 HRESULT Connection_create( void **obj )
859 struct connection *connection;
861 if (!(connection = heap_alloc( sizeof(*connection) ))) return E_OUTOFMEMORY;
862 connection->Connection_iface.lpVtbl = &connection_vtbl;
863 connection->ISupportErrorInfo_iface.lpVtbl = &support_error_vtbl;
864 connection->IConnectionPointContainer_iface.lpVtbl = &connpointcontainer_vtbl;
865 connection->ADOConnectionConstruction15_iface.lpVtbl = &ado_construct_vtbl;
866 connection->refs = 1;
867 connection->state = adStateClosed;
868 connection->timeout = 30;
869 connection->datasource = NULL;
870 if (!(connection->provider = strdupW( L"MSDASQL" )))
872 heap_free( connection );
873 return E_OUTOFMEMORY;
875 connection->mode = adModeUnknown;
876 connection->location = adUseServer;
877 connection->session = NULL;
879 connection->cp_connev.conn = connection;
880 connection->cp_connev.riid = &DIID_ConnectionEvents;
881 connection->cp_connev.IConnectionPoint_iface.lpVtbl = &connpoint_vtbl;
882 connection->cp_connev.sinks = NULL;
883 connection->cp_connev.sinks_size = 0;
885 *obj = &connection->Connection_iface;
886 TRACE( "returning iface %p\n", *obj );
887 return S_OK;