diff --git a/dlls/msdasql/Makefile.in b/dlls/msdasql/Makefile.in index 04d9cb29f2a..ee8fa672623 100644 --- a/dlls/msdasql/Makefile.in +++ b/dlls/msdasql/Makefile.in @@ -4,7 +4,8 @@ IMPORTS = uuid ole32 oleaut32 EXTRADLLFLAGS = -Wb,--prefer-native C_SRCS = \ - msdasql_main.c + msdasql_main.c \ + session.c RC_SRCS = msdasql.rc diff --git a/dlls/msdasql/msdasql_main.c b/dlls/msdasql/msdasql_main.c index 0a9421df12a..58fc8e378e0 100644 --- a/dlls/msdasql/msdasql_main.c +++ b/dlls/msdasql/msdasql_main.c @@ -30,6 +30,8 @@ #include "initguid.h" #include "msdasql.h" +#include "msdasql_private.h" + WINE_DEFAULT_DEBUG_CHANNEL(msdasql); DEFINE_GUID(DBPROPSET_DBINIT, 0xc8b522bc, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d); @@ -433,10 +435,16 @@ static HRESULT WINAPI dbsess_CreateSession(IDBCreateSession *iface, IUnknown *ou IUnknown **session) { struct msdasql *provider = impl_from_IDBCreateSession(iface); + HRESULT hr; - FIXME("%p, outer %p, riid %s, session %p stub\n", provider, outer, debugstr_guid(riid), session); + TRACE("%p, outer %p, riid %s, session %p stub\n", provider, outer, debugstr_guid(riid), session); - return E_FAIL; + if (outer) + FIXME("outer currently not supported.\n"); + + hr = create_db_session(riid, (void**)session); + + return hr; } static const struct IDBCreateSessionVtbl dbsess_vtbl = diff --git a/dlls/msdasql/msdasql_private.h b/dlls/msdasql/msdasql_private.h new file mode 100644 index 00000000000..a3d73498fe9 --- /dev/null +++ b/dlls/msdasql/msdasql_private.h @@ -0,0 +1,19 @@ +/* + * Copyright 2020 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +HRESULT create_db_session(REFIID riid, void **unk) DECLSPEC_HIDDEN; diff --git a/dlls/msdasql/session.c b/dlls/msdasql/session.c new file mode 100644 index 00000000000..57174be40f8 --- /dev/null +++ b/dlls/msdasql/session.c @@ -0,0 +1,114 @@ +/* + * Copyright 2020 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "rpcproxy.h" +#include "msdasc.h" +#include "wine/heap.h" +#include "wine/debug.h" + +#include "msdasql.h" + +#include "msdasql_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msdasql); + +struct msdasql_session +{ + IUnknown session_iface; + LONG refs; +}; + +static inline struct msdasql_session *impl_from_IUnknown( IUnknown *iface ) +{ + return CONTAINING_RECORD( iface, struct msdasql_session, session_iface ); +} + +static HRESULT WINAPI session_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) +{ + struct msdasql_session *session = impl_from_IUnknown( iface ); + + TRACE( "%p, %s, %p\n", iface, debugstr_guid(riid), ppv ); + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid)) + { + TRACE("(%p)->(IID_IUnknown %p)\n", iface, ppv); + *ppv = &session->session_iface; + } + + if(*ppv) + { + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; + } + + FIXME("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv); + return E_NOINTERFACE; +} + +static ULONG WINAPI session_AddRef(IUnknown *iface) +{ + struct msdasql_session *session = impl_from_IUnknown( iface ); + LONG refs = InterlockedIncrement( &session->refs ); + TRACE( "%p new refcount %d\n", session, refs ); + return refs; +} + +static ULONG WINAPI session_Release(IUnknown *iface) +{ + struct msdasql_session *session = impl_from_IUnknown( iface ); + LONG refs = InterlockedDecrement( &session->refs ); + TRACE( "%p new refcount %d\n", session, refs ); + if (!refs) + { + TRACE( "destroying %p\n", session ); + heap_free( session ); + } + return refs; +} + +static const IUnknownVtbl unkfactoryVtbl = +{ + session_QueryInterface, + session_AddRef, + session_Release, +}; + +HRESULT create_db_session(REFIID riid, void **unk) +{ + struct msdasql_session *session; + HRESULT hr; + + session = heap_alloc(sizeof(*session)); + if (!session) + return E_OUTOFMEMORY; + + session->session_iface.lpVtbl = &unkfactoryVtbl; + session->refs = 1; + + hr = IUnknown_QueryInterface(&session->session_iface, riid, unk); + IUnknown_Release(&session->session_iface); + return hr; +}