kernel32: Update version to Win 10.
[wine.git] / dlls / msado15 / connection.c
bloba3c9a450be6ed11a1fa423e06efa1499eebac2eb
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 HRESULT create_command_text(IUnknown *session, BSTR command, ICommandText **cmd_text)
297 HRESULT hr;
298 IOpenRowset *openrowset;
299 ICommandText *command_text;
300 ICommand *cmd;
301 IDBCreateCommand *create_command;
303 hr = IUnknown_QueryInterface(session, &IID_IOpenRowset, (void**)&openrowset);
304 if (FAILED(hr))
305 return hr;
307 hr = IOpenRowset_QueryInterface(openrowset, &IID_IDBCreateCommand, (void**)&create_command);
308 IOpenRowset_Release(openrowset);
309 if (FAILED(hr))
310 return hr;
312 hr = IDBCreateCommand_CreateCommand(create_command, NULL, &IID_IUnknown, (IUnknown **)&cmd);
313 IDBCreateCommand_Release(create_command);
314 if (FAILED(hr))
315 return hr;
317 hr = ICommand_QueryInterface(cmd, &IID_ICommandText, (void**)&command_text);
318 ICommand_Release(cmd);
319 if (FAILED(hr))
321 FIXME("Currently only ICommandText interface is support\n");
322 return hr;
325 hr = ICommandText_SetCommandText(command_text, &DBGUID_DEFAULT, command);
326 if (FAILED(hr))
328 ICommandText_Release(command_text);
329 return hr;
332 *cmd_text = command_text;
334 return S_OK;
337 static HRESULT WINAPI connection_Execute( _Connection *iface, BSTR command, VARIANT *records_affected,
338 LONG options, _Recordset **record_set )
340 struct connection *connection = impl_from_Connection( iface );
341 HRESULT hr;
342 ICommandText *command_text;
343 DBROWCOUNT affected;
344 IUnknown *rowset;
345 _Recordset *recordset;
346 ADORecordsetConstruction *construct;
348 FIXME( "%p, %s, %p, 0x%08x, %p Semi-stub\n", iface, debugstr_w(command), records_affected, options, record_set );
350 if (connection->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed );
352 hr = create_command_text(connection->session, command, &command_text);
353 if (FAILED(hr))
354 return hr;
356 hr = ICommandText_Execute(command_text, NULL, &IID_IUnknown, NULL, &affected, &rowset);
357 ICommandText_Release(command_text);
358 if (FAILED(hr))
359 return hr;
361 hr = Recordset_create( (void**)&recordset);
362 if (FAILED(hr))
364 IUnknown_Release(rowset);
365 return hr;
368 hr = _Recordset_QueryInterface(recordset, &IID_ADORecordsetConstruction, (void**)&construct);
369 if (FAILED(hr))
371 IUnknown_Release(rowset);
372 _Recordset_Release(recordset);
373 return hr;
376 ADORecordsetConstruction_put_Rowset(construct, rowset);
377 ADORecordsetConstruction_Release(construct);
378 IUnknown_Release(rowset);
380 if (records_affected)
382 V_VT(records_affected) = VT_I4;
383 V_I4(records_affected) = affected;
386 _Recordset_put_CursorLocation(recordset, connection->location);
387 *record_set = recordset;
389 return hr;
392 static HRESULT WINAPI connection_BeginTrans( _Connection *iface, LONG *transaction_level )
394 FIXME( "%p, %p\n", iface, transaction_level );
395 return E_NOTIMPL;
398 static HRESULT WINAPI connection_CommitTrans( _Connection *iface )
400 FIXME( "%p\n", iface );
401 return E_NOTIMPL;
404 static HRESULT WINAPI connection_RollbackTrans( _Connection *iface )
406 FIXME( "%p\n", iface );
407 return E_NOTIMPL;
410 static HRESULT WINAPI connection_Open( _Connection *iface, BSTR connect_str, BSTR userid, BSTR password,
411 LONG options )
413 struct connection *connection = impl_from_Connection( iface );
414 IDBProperties *props;
415 IDBInitialize *dbinit = NULL;
416 IDataInitialize *datainit;
417 IDBCreateSession *session = NULL;
418 HRESULT hr;
420 TRACE( "%p, %s, %s, %p, %08x\n", iface, debugstr_w(connect_str), debugstr_w(userid), password, options );
422 if (connection->state == adStateOpen) return MAKE_ADO_HRESULT( adErrObjectOpen );
423 if (!connect_str) return E_FAIL;
425 if ((hr = CoCreateInstance( &CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,
426 (void **)&datainit )) != S_OK) return hr;
427 if ((hr = IDataInitialize_GetDataSource( datainit, NULL, CLSCTX_INPROC_SERVER, connect_str, &IID_IDBInitialize,
428 (IUnknown **)&dbinit )) != S_OK) goto done;
429 if ((hr = IDBInitialize_QueryInterface( dbinit, &IID_IDBProperties, (void **)&props )) != S_OK) goto done;
431 /* TODO - Update username/password if required. */
432 if ((userid && *userid) || (password && *password))
433 FIXME("Username/password parameters currently not supported\n");
435 if ((hr = IDBInitialize_Initialize( dbinit )) != S_OK) goto done;
436 if ((hr = IDBInitialize_QueryInterface( dbinit, &IID_IDBCreateSession, (void **)&session )) != S_OK) goto done;
437 if ((hr = IDBCreateSession_CreateSession( session, NULL, &IID_IUnknown, &connection->session )) == S_OK)
439 connection->state = adStateOpen;
441 IDBCreateSession_Release( session );
443 done:
444 if (hr != S_OK && connection->session)
446 IUnknown_Release( connection->session );
447 connection->session = NULL;
449 if (dbinit)
451 IDBInitialize_Uninitialize( dbinit );
452 IDBInitialize_Release( dbinit );
454 IDataInitialize_Release( datainit );
456 TRACE("ret 0x%08x\n", hr);
457 return hr;
460 static HRESULT WINAPI connection_get_Errors( _Connection *iface, Errors **obj )
462 FIXME( "%p, %p\n", iface, obj );
463 return E_NOTIMPL;
466 static HRESULT WINAPI connection_get_DefaultDatabase( _Connection *iface, BSTR *str )
468 FIXME( "%p, %p\n", iface, str );
469 return E_NOTIMPL;
472 static HRESULT WINAPI connection_put_DefaultDatabase( _Connection *iface, BSTR str )
474 FIXME( "%p, %s\n", iface, debugstr_w(str) );
475 return E_NOTIMPL;
478 static HRESULT WINAPI connection_get_IsolationLevel( _Connection *iface, IsolationLevelEnum *level )
480 FIXME( "%p, %p\n", iface, level );
481 return E_NOTIMPL;
484 static HRESULT WINAPI connection_put_IsolationLevel( _Connection *iface, IsolationLevelEnum level )
486 FIXME( "%p, %d\n", iface, level );
487 return E_NOTIMPL;
490 static HRESULT WINAPI connection_get_Attributes( _Connection *iface, LONG *attr )
492 FIXME( "%p, %p\n", iface, attr );
493 return E_NOTIMPL;
496 static HRESULT WINAPI connection_put_Attributes( _Connection *iface, LONG attr )
498 FIXME( "%p, %d\n", iface, attr );
499 return E_NOTIMPL;
502 static HRESULT WINAPI connection_get_CursorLocation( _Connection *iface, CursorLocationEnum *cursor_loc )
504 struct connection *connection = impl_from_Connection( iface );
506 TRACE( "%p, %p\n", iface, cursor_loc );
508 *cursor_loc = connection->location;
509 return S_OK;
512 static HRESULT WINAPI connection_put_CursorLocation( _Connection *iface, CursorLocationEnum cursor_loc )
514 struct connection *connection = impl_from_Connection( iface );
516 TRACE( "%p, %u\n", iface, cursor_loc );
518 connection->location = cursor_loc;
519 return S_OK;
522 static HRESULT WINAPI connection_get_Mode( _Connection *iface, ConnectModeEnum *mode )
524 struct connection *connection = impl_from_Connection( iface );
526 TRACE( "%p, %p\n", iface, mode );
528 *mode = connection->mode;
529 return S_OK;
532 static HRESULT WINAPI connection_put_Mode( _Connection *iface, ConnectModeEnum mode )
534 struct connection *connection = impl_from_Connection( iface );
536 TRACE( "%p, %u\n", iface, mode );
538 connection->mode = mode;
539 return S_OK;
542 static HRESULT WINAPI connection_get_Provider( _Connection *iface, BSTR *str )
544 struct connection *connection = impl_from_Connection( iface );
545 BSTR provider = NULL;
547 TRACE( "%p, %p\n", iface, str );
549 if (connection->provider && !(provider = SysAllocString( connection->provider ))) return E_OUTOFMEMORY;
550 *str = provider;
551 return S_OK;
554 static HRESULT WINAPI connection_put_Provider( _Connection *iface, BSTR str )
556 struct connection *connection = impl_from_Connection( iface );
557 WCHAR *provider = NULL;
559 TRACE( "%p, %s\n", iface, debugstr_w(str) );
561 if (!str) return MAKE_ADO_HRESULT(adErrInvalidArgument);
563 if (!(provider = strdupW( str ))) return E_OUTOFMEMORY;
564 heap_free( connection->provider );
565 connection->provider = provider;
566 return S_OK;
569 static HRESULT WINAPI connection_get_State( _Connection *iface, LONG *state )
571 struct connection *connection = impl_from_Connection( iface );
572 TRACE( "%p, %p\n", connection, state );
573 *state = connection->state;
574 return S_OK;
577 static HRESULT WINAPI connection_OpenSchema( _Connection *iface, SchemaEnum schema, VARIANT restrictions,
578 VARIANT schema_id, _Recordset **record_set )
580 FIXME( "%p, %d, %s, %s, %p\n", iface, schema, debugstr_variant(&restrictions),
581 debugstr_variant(&schema_id), record_set );
582 return E_NOTIMPL;
585 static HRESULT WINAPI connection_Cancel( _Connection *iface )
587 FIXME( "%p\n", iface );
588 return E_NOTIMPL;
591 static const struct _ConnectionVtbl connection_vtbl =
593 connection_QueryInterface,
594 connection_AddRef,
595 connection_Release,
596 connection_GetTypeInfoCount,
597 connection_GetTypeInfo,
598 connection_GetIDsOfNames,
599 connection_Invoke,
600 connection_get_Properties,
601 connection_get_ConnectionString,
602 connection_put_ConnectionString,
603 connection_get_CommandTimeout,
604 connection_put_CommandTimeout,
605 connection_get_ConnectionTimeout,
606 connection_put_ConnectionTimeout,
607 connection_get_Version,
608 connection_Close,
609 connection_Execute,
610 connection_BeginTrans,
611 connection_CommitTrans,
612 connection_RollbackTrans,
613 connection_Open,
614 connection_get_Errors,
615 connection_get_DefaultDatabase,
616 connection_put_DefaultDatabase,
617 connection_get_IsolationLevel,
618 connection_put_IsolationLevel,
619 connection_get_Attributes,
620 connection_put_Attributes,
621 connection_get_CursorLocation,
622 connection_put_CursorLocation,
623 connection_get_Mode,
624 connection_put_Mode,
625 connection_get_Provider,
626 connection_put_Provider,
627 connection_get_State,
628 connection_OpenSchema,
629 connection_Cancel
632 static HRESULT WINAPI supporterror_QueryInterface( ISupportErrorInfo *iface, REFIID riid, void **obj )
634 struct connection *connection = impl_from_ISupportErrorInfo( iface );
635 return connection_QueryInterface( &connection->Connection_iface, riid, obj );
638 static ULONG WINAPI supporterror_AddRef( ISupportErrorInfo *iface )
640 struct connection *connection = impl_from_ISupportErrorInfo( iface );
641 return connection_AddRef( &connection->Connection_iface );
644 static ULONG WINAPI supporterror_Release( ISupportErrorInfo *iface )
646 struct connection *connection = impl_from_ISupportErrorInfo( iface );
647 return connection_Release( &connection->Connection_iface );
650 static HRESULT WINAPI supporterror_InterfaceSupportsErrorInfo( ISupportErrorInfo *iface, REFIID riid )
652 struct connection *connection = impl_from_ISupportErrorInfo( iface );
653 FIXME( "%p, %s\n", connection, debugstr_guid(riid) );
654 return S_FALSE;
657 static const struct ISupportErrorInfoVtbl support_error_vtbl =
659 supporterror_QueryInterface,
660 supporterror_AddRef,
661 supporterror_Release,
662 supporterror_InterfaceSupportsErrorInfo
665 static HRESULT WINAPI connpointcontainer_QueryInterface( IConnectionPointContainer *iface,
666 REFIID riid, void **obj )
668 struct connection *connection = impl_from_IConnectionPointContainer( iface );
669 return connection_QueryInterface( &connection->Connection_iface, riid, obj );
672 static ULONG WINAPI connpointcontainer_AddRef( IConnectionPointContainer *iface )
674 struct connection *connection = impl_from_IConnectionPointContainer( iface );
675 return connection_AddRef( &connection->Connection_iface );
678 static ULONG WINAPI connpointcontainer_Release( IConnectionPointContainer *iface )
680 struct connection *connection = impl_from_IConnectionPointContainer( iface );
681 return connection_Release( &connection->Connection_iface );
684 static HRESULT WINAPI connpointcontainer_EnumConnectionPoints( IConnectionPointContainer *iface,
685 IEnumConnectionPoints **points )
687 struct connection *connection = impl_from_IConnectionPointContainer( iface );
688 FIXME( "%p, %p\n", connection, points );
689 return E_NOTIMPL;
692 static HRESULT WINAPI connpointcontainer_FindConnectionPoint( IConnectionPointContainer *iface,
693 REFIID riid, IConnectionPoint **point )
695 struct connection *connection = impl_from_IConnectionPointContainer( iface );
697 TRACE( "%p, %s %p\n", connection, debugstr_guid( riid ), point );
699 if (!point) return E_POINTER;
701 if (IsEqualIID( riid, connection->cp_connev.riid ))
703 *point = &connection->cp_connev.IConnectionPoint_iface;
704 IConnectionPoint_AddRef( *point );
705 return S_OK;
708 FIXME( "unsupported connection point %s\n", debugstr_guid( riid ) );
709 return CONNECT_E_NOCONNECTION;
712 static const struct IConnectionPointContainerVtbl connpointcontainer_vtbl =
714 connpointcontainer_QueryInterface,
715 connpointcontainer_AddRef,
716 connpointcontainer_Release,
717 connpointcontainer_EnumConnectionPoints,
718 connpointcontainer_FindConnectionPoint
721 static HRESULT WINAPI connpoint_QueryInterface( IConnectionPoint *iface, REFIID riid, void **obj )
723 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
725 if (IsEqualGUID( &IID_IUnknown, riid ) || IsEqualGUID( &IID_IConnectionPoint, riid ))
727 *obj = &connpoint->IConnectionPoint_iface;
729 else
731 FIXME( "interface %s not implemented\n", debugstr_guid( riid ) );
732 return E_NOINTERFACE;
735 connection_AddRef( &connpoint->conn->Connection_iface );
736 return S_OK;
739 static ULONG WINAPI connpoint_AddRef( IConnectionPoint *iface )
741 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
742 return IConnectionPointContainer_AddRef( &connpoint->conn->IConnectionPointContainer_iface );
745 static ULONG WINAPI connpoint_Release( IConnectionPoint *iface )
747 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
748 return IConnectionPointContainer_Release( &connpoint->conn->IConnectionPointContainer_iface );
751 static HRESULT WINAPI connpoint_GetConnectionInterface( IConnectionPoint *iface, IID *iid )
753 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
754 FIXME( "%p, %p\n", connpoint, iid );
755 return E_NOTIMPL;
758 static HRESULT WINAPI connpoint_GetConnectionPointContainer( IConnectionPoint *iface,
759 IConnectionPointContainer **container )
761 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
762 FIXME( "%p, %p\n", connpoint, container );
763 return E_NOTIMPL;
766 static HRESULT WINAPI connpoint_Advise( IConnectionPoint *iface, IUnknown *unk_sink,
767 DWORD *cookie )
769 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
770 IUnknown *sink, **tmp;
771 ULONG new_size;
772 HRESULT hr;
773 DWORD i;
775 TRACE( "%p, %p, %p\n", iface, unk_sink, cookie );
777 if (!unk_sink || !cookie) return E_FAIL;
779 if (FAILED(hr = IUnknown_QueryInterface( unk_sink, &IID_ConnectionEventsVt, (void**)&sink )))
781 *cookie = 0;
782 return E_FAIL;
785 if (connpoint->sinks)
787 for (i = 0; i < connpoint->sinks_size; ++i)
789 if (!connpoint->sinks[i])
790 break;
793 if (i == connpoint->sinks_size)
795 new_size = connpoint->sinks_size * 2;
796 if (!(tmp = heap_realloc_zero( connpoint->sinks, new_size * sizeof(*connpoint->sinks) )))
797 return E_OUTOFMEMORY;
798 connpoint->sinks = tmp;
799 connpoint->sinks_size = new_size;
802 else
804 if (!(connpoint->sinks = heap_alloc_zero( sizeof(*connpoint->sinks) ))) return E_OUTOFMEMORY;
805 connpoint->sinks_size = 1;
806 i = 0;
809 connpoint->sinks[i] = sink;
810 *cookie = i + 1;
811 return S_OK;
814 static HRESULT WINAPI connpoint_Unadvise( IConnectionPoint *iface, DWORD cookie )
816 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
817 TRACE( "%p, %u\n", connpoint, cookie );
819 if (!cookie || cookie > connpoint->sinks_size || !connpoint->sinks || !connpoint->sinks[cookie - 1])
820 return E_FAIL;
822 IUnknown_Release( connpoint->sinks[cookie - 1] );
823 connpoint->sinks[cookie - 1] = NULL;
824 return S_OK;
827 static HRESULT WINAPI connpoint_EnumConnections( IConnectionPoint *iface,
828 IEnumConnections **points )
830 struct connection_point *connpoint = impl_from_IConnectionPoint( iface );
831 FIXME( "%p, %p\n", connpoint, points );
832 return E_NOTIMPL;
835 static const IConnectionPointVtbl connpoint_vtbl =
837 connpoint_QueryInterface,
838 connpoint_AddRef,
839 connpoint_Release,
840 connpoint_GetConnectionInterface,
841 connpoint_GetConnectionPointContainer,
842 connpoint_Advise,
843 connpoint_Unadvise,
844 connpoint_EnumConnections
847 static HRESULT WINAPI adoconstruct_QueryInterface(ADOConnectionConstruction15 *iface, REFIID riid, void **obj)
849 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
850 return _Connection_QueryInterface( &connection->Connection_iface, riid, obj );
853 static ULONG WINAPI adoconstruct_AddRef(ADOConnectionConstruction15 *iface)
855 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
856 return _Connection_AddRef( &connection->Connection_iface );
859 static ULONG WINAPI adoconstruct_Release(ADOConnectionConstruction15 *iface)
861 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
862 return _Connection_Release( &connection->Connection_iface );
865 static HRESULT WINAPI adoconstruct_get_DSO(ADOConnectionConstruction15 *iface, IUnknown **dso)
867 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
868 FIXME("%p, %p\n", connection, dso);
869 return E_NOTIMPL;
872 static HRESULT WINAPI adoconstruct_get_Session(ADOConnectionConstruction15 *iface, IUnknown **session)
874 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
875 TRACE("%p, %p\n", connection, session);
877 *session = connection->session;
878 if (*session)
879 IUnknown_AddRef(*session);
880 return S_OK;
883 static HRESULT WINAPI adoconstruct_WrapDSOandSession(ADOConnectionConstruction15 *iface, IUnknown *dso,
884 IUnknown *session)
886 struct connection *connection = impl_from_ADOConnectionConstruction15( iface );
887 FIXME("%p, %p, %p\n", connection, dso, session);
888 return E_NOTIMPL;
891 struct ADOConnectionConstruction15Vtbl ado_construct_vtbl =
893 adoconstruct_QueryInterface,
894 adoconstruct_AddRef,
895 adoconstruct_Release,
896 adoconstruct_get_DSO,
897 adoconstruct_get_Session,
898 adoconstruct_WrapDSOandSession
901 HRESULT Connection_create( void **obj )
903 struct connection *connection;
905 if (!(connection = heap_alloc( sizeof(*connection) ))) return E_OUTOFMEMORY;
906 connection->Connection_iface.lpVtbl = &connection_vtbl;
907 connection->ISupportErrorInfo_iface.lpVtbl = &support_error_vtbl;
908 connection->IConnectionPointContainer_iface.lpVtbl = &connpointcontainer_vtbl;
909 connection->ADOConnectionConstruction15_iface.lpVtbl = &ado_construct_vtbl;
910 connection->refs = 1;
911 connection->state = adStateClosed;
912 connection->timeout = 30;
913 connection->datasource = NULL;
914 if (!(connection->provider = strdupW( L"MSDASQL" )))
916 heap_free( connection );
917 return E_OUTOFMEMORY;
919 connection->mode = adModeUnknown;
920 connection->location = adUseServer;
921 connection->session = NULL;
923 connection->cp_connev.conn = connection;
924 connection->cp_connev.riid = &DIID_ConnectionEvents;
925 connection->cp_connev.IConnectionPoint_iface.lpVtbl = &connpoint_vtbl;
926 connection->cp_connev.sinks = NULL;
927 connection->cp_connev.sinks_size = 0;
929 *obj = &connection->Connection_iface;
930 TRACE( "returning iface %p\n", *obj );
931 return S_OK;