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
23 #define DBINITCONSTANTS
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
);
40 struct connection_point
42 IConnectionPoint IConnectionPoint_iface
;
43 struct connection
*conn
;
51 _Connection Connection_iface
;
52 ISupportErrorInfo ISupportErrorInfo_iface
;
53 IConnectionPointContainer IConnectionPointContainer_iface
;
54 ADOConnectionConstruction15 ADOConnectionConstruction15_iface
;
56 ObjectStateEnum state
;
61 CursorLocationEnum location
;
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
);
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
);
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
);
126 if (IsEqualGUID( riid
, &IID__Connection
) || IsEqualGUID( riid
, &IID_IDispatch
) ||
127 IsEqualGUID( riid
, &IID_IUnknown
))
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
;
150 FIXME( "interface %s not implemented\n", debugstr_guid(riid
) );
151 return E_NOINTERFACE
;
153 connection_AddRef( iface
);
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
);
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
);
179 TRACE( "%p, %s, %p, %u, %u, %p\n", connection
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
181 hr
= get_typeinfo(Connection_tid
, &typeinfo
);
184 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, count
, dispid
);
185 ITypeInfo_Release(typeinfo
);
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
);
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
);
204 hr
= ITypeInfo_Invoke(typeinfo
, &connection
->Connection_iface
, member
, flags
, params
,
205 result
, excep_info
, arg_err
);
206 ITypeInfo_Release(typeinfo
);
212 static HRESULT WINAPI
connection_get_Properties( _Connection
*iface
, Properties
**obj
)
214 FIXME( "%p, %p\n", iface
, obj
);
218 static HRESULT WINAPI
connection_get_ConnectionString( _Connection
*iface
, BSTR
*str
)
220 struct connection
*connection
= impl_from_Connection( iface
);
223 TRACE( "%p, %p\n", connection
, str
);
225 if (connection
->datasource
&& !(source
= SysAllocString( connection
->datasource
))) return E_OUTOFMEMORY
;
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
;
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
;
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
;
259 static HRESULT WINAPI
connection_get_ConnectionTimeout( _Connection
*iface
, LONG
*timeout
)
261 FIXME( "%p, %p\n", iface
, timeout
);
265 static HRESULT WINAPI
connection_put_ConnectionTimeout( _Connection
*iface
, LONG timeout
)
267 FIXME( "%p, %d\n", iface
, timeout
);
271 static HRESULT WINAPI
connection_get_Version( _Connection
*iface
, BSTR
*str
)
273 FIXME( "%p, %p\n", iface
, str
);
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
;
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
);
300 _Recordset
*recordset
;
301 VARIANT source
, active
;
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
);
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
);
322 _Recordset_Release(recordset
);
326 V_VT(&active
) = VT_DISPATCH
;
327 V_DISPATCH(&active
) = dispatch
;
329 hr
= _Recordset_Open(recordset
, source
, active
, adOpenDynamic
, adLockPessimistic
, 0);
330 VariantClear(&active
);
333 _Recordset_Release(recordset
);
337 if (records_affected
)
339 V_VT(records_affected
) = VT_I4
;
340 _Recordset_get_RecordCount(recordset
, &V_I4(records_affected
));
343 *record_set
= recordset
;
348 static HRESULT WINAPI
connection_BeginTrans( _Connection
*iface
, LONG
*transaction_level
)
350 FIXME( "%p, %p\n", iface
, transaction_level
);
354 static HRESULT WINAPI
connection_CommitTrans( _Connection
*iface
)
356 FIXME( "%p\n", iface
);
360 static HRESULT WINAPI
connection_RollbackTrans( _Connection
*iface
)
362 FIXME( "%p\n", iface
);
366 static HRESULT WINAPI
connection_Open( _Connection
*iface
, BSTR connect_str
, BSTR userid
, BSTR password
,
369 struct connection
*connection
= impl_from_Connection( iface
);
370 IDBProperties
*props
;
371 IDBInitialize
*dbinit
= NULL
;
372 IDataInitialize
*datainit
;
373 IDBCreateSession
*session
= NULL
;
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
);
400 if (hr
!= S_OK
&& connection
->session
)
402 IUnknown_Release( connection
->session
);
403 connection
->session
= NULL
;
407 IDBInitialize_Uninitialize( dbinit
);
408 IDBInitialize_Release( dbinit
);
410 IDataInitialize_Release( datainit
);
412 TRACE("ret 0x%08x\n", hr
);
416 static HRESULT WINAPI
connection_get_Errors( _Connection
*iface
, Errors
**obj
)
418 FIXME( "%p, %p\n", iface
, obj
);
422 static HRESULT WINAPI
connection_get_DefaultDatabase( _Connection
*iface
, BSTR
*str
)
424 FIXME( "%p, %p\n", iface
, str
);
428 static HRESULT WINAPI
connection_put_DefaultDatabase( _Connection
*iface
, BSTR str
)
430 FIXME( "%p, %s\n", iface
, debugstr_w(str
) );
434 static HRESULT WINAPI
connection_get_IsolationLevel( _Connection
*iface
, IsolationLevelEnum
*level
)
436 FIXME( "%p, %p\n", iface
, level
);
440 static HRESULT WINAPI
connection_put_IsolationLevel( _Connection
*iface
, IsolationLevelEnum level
)
442 FIXME( "%p, %d\n", iface
, level
);
446 static HRESULT WINAPI
connection_get_Attributes( _Connection
*iface
, LONG
*attr
)
448 FIXME( "%p, %p\n", iface
, attr
);
452 static HRESULT WINAPI
connection_put_Attributes( _Connection
*iface
, LONG attr
)
454 FIXME( "%p, %d\n", iface
, attr
);
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
);
541 static HRESULT WINAPI
connection_Cancel( _Connection
*iface
)
543 FIXME( "%p\n", iface
);
547 static const struct _ConnectionVtbl connection_vtbl
=
549 connection_QueryInterface
,
552 connection_GetTypeInfoCount
,
553 connection_GetTypeInfo
,
554 connection_GetIDsOfNames
,
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
,
566 connection_BeginTrans
,
567 connection_CommitTrans
,
568 connection_RollbackTrans
,
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
,
581 connection_get_Provider
,
582 connection_put_Provider
,
583 connection_get_State
,
584 connection_OpenSchema
,
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
) );
613 static const struct ISupportErrorInfoVtbl support_error_vtbl
=
615 supporterror_QueryInterface
,
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
);
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
);
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
;
687 FIXME( "interface %s not implemented\n", debugstr_guid( riid
) );
688 return E_NOINTERFACE
;
691 connection_AddRef( &connpoint
->conn
->Connection_iface
);
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
);
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
);
722 static HRESULT WINAPI
connpoint_Advise( IConnectionPoint
*iface
, IUnknown
*unk_sink
,
725 struct connection_point
*connpoint
= impl_from_IConnectionPoint( iface
);
726 IUnknown
*sink
, **tmp
;
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
)))
741 if (connpoint
->sinks
)
743 for (i
= 0; i
< connpoint
->sinks_size
; ++i
)
745 if (!connpoint
->sinks
[i
])
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
;
760 if (!(connpoint
->sinks
= heap_alloc_zero( sizeof(*connpoint
->sinks
) ))) return E_OUTOFMEMORY
;
761 connpoint
->sinks_size
= 1;
765 connpoint
->sinks
[i
] = sink
;
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])
778 IUnknown_Release( connpoint
->sinks
[cookie
- 1] );
779 connpoint
->sinks
[cookie
- 1] = NULL
;
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
);
791 static const IConnectionPointVtbl connpoint_vtbl
=
793 connpoint_QueryInterface
,
796 connpoint_GetConnectionInterface
,
797 connpoint_GetConnectionPointContainer
,
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
);
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
;
835 IUnknown_AddRef(*session
);
839 static HRESULT WINAPI
adoconstruct_WrapDSOandSession(ADOConnectionConstruction15
*iface
, IUnknown
*dso
,
842 struct connection
*connection
= impl_from_ADOConnectionConstruction15( iface
);
843 FIXME("%p, %p, %p\n", connection
, dso
, session
);
847 struct ADOConnectionConstruction15Vtbl ado_construct_vtbl
=
849 adoconstruct_QueryInterface
,
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
);