diff --git a/dlls/msado15/Makefile.in b/dlls/msado15/Makefile.in index f87e81af38d..b901944bc1e 100644 --- a/dlls/msado15/Makefile.in +++ b/dlls/msado15/Makefile.in @@ -1,8 +1,12 @@ MODULE = msado15.dll +IMPORTS = oleaut32 EXTRADLLFLAGS = -mno-cygwin C_SRCS = \ + connection.c \ main.c -IDL_SRCS = msado15_tlb.idl +IDL_SRCS = \ + msado15_classes.idl \ + msado15_tlb.idl diff --git a/dlls/msado15/connection.c b/dlls/msado15/connection.c new file mode 100644 index 00000000000..f33bc89a1ac --- /dev/null +++ b/dlls/msado15/connection.c @@ -0,0 +1,344 @@ +/* + * Copyright 2019 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#include +#include "windef.h" +#include "winbase.h" +#define COBJMACROS +#include "objbase.h" +#include "msado15_backcompat.h" + +#include "wine/debug.h" +#include "wine/heap.h" + +#include "msado15_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msado15); + +struct connection +{ + _Connection Connection_iface; + LONG refs; +}; + +static inline struct connection *impl_from_Connection( _Connection *iface ) +{ + return CONTAINING_RECORD( iface, struct connection, Connection_iface ); +} + +static ULONG WINAPI connection_AddRef( _Connection *iface ) +{ + struct connection *connection = impl_from_Connection( iface ); + return InterlockedIncrement( &connection->refs ); +} + +static ULONG WINAPI connection_Release( _Connection *iface ) +{ + struct connection *connection = impl_from_Connection( iface ); + LONG refs = InterlockedDecrement( &connection->refs ); + if (!refs) + { + TRACE( "destroying %p\n", connection ); + heap_free( connection ); + } + return refs; +} + +static HRESULT WINAPI connection_QueryInterface( _Connection *iface, REFIID riid, void **obj ) +{ + TRACE( "%p, %s, %p\n", iface, debugstr_guid(riid), obj ); + + if (IsEqualGUID( riid, &IID__Connection ) || IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown )) + { + *obj = iface; + } + else + { + FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + return E_NOINTERFACE; + } + connection_AddRef( iface ); + return S_OK; +} + +static HRESULT WINAPI connection_GetTypeInfoCount( _Connection *iface, UINT *count ) +{ + FIXME( "%p, %p\n", iface, count ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_GetTypeInfo( _Connection *iface, UINT index, LCID lcid, ITypeInfo **info ) +{ + FIXME( "%p, %u, %u, %p\n", iface, index, lcid, info ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_GetIDsOfNames( _Connection *iface, REFIID riid, LPOLESTR *names, UINT count, + LCID lcid, DISPID *dispid ) +{ + FIXME( "%p, %s, %p, %u, %u, %p\n", iface, debugstr_guid(riid), names, count, lcid, dispid ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_Invoke( _Connection *iface, DISPID member, REFIID riid, LCID lcid, WORD flags, + DISPPARAMS *params, VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err ) +{ + FIXME( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", iface, member, debugstr_guid(riid), lcid, flags, params, + result, excep_info, arg_err ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_get_Properties( _Connection *iface, Properties **obj ) +{ + FIXME( "%p, %p\n", iface, obj ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_get_ConnectionString( _Connection *iface, BSTR *str ) +{ + FIXME( "%p, %p\n", iface, str ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_put_ConnectionString( _Connection *iface, BSTR str ) +{ + FIXME( "%p, %s\n", iface, debugstr_w(str) ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_get_CommandTimeout( _Connection *iface, LONG *timeout ) +{ + FIXME( "%p, %p\n", iface, timeout ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_put_CommandTimeout( _Connection *iface, LONG timeout ) +{ + FIXME( "%p, %d\n", iface, timeout ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_get_ConnectionTimeout( _Connection *iface, LONG *timeout ) +{ + FIXME( "%p, %p\n", iface, timeout ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_put_ConnectionTimeout( _Connection *iface, LONG timeout ) +{ + FIXME( "%p, %d\n", iface, timeout ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_get_Version( _Connection *iface, BSTR *str ) +{ + FIXME( "%p, %p\n", iface, str ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_Close( _Connection *iface ) +{ + FIXME( "%p\n", iface ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_Execute( _Connection *iface, BSTR command, VARIANT *records_affected, + LONG options, _Recordset **record_set ) +{ + FIXME( "%p, %s, %p, %08x, %p\n", iface, debugstr_w(command), records_affected, options, record_set ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_BeginTrans( _Connection *iface, LONG *transaction_level ) +{ + FIXME( "%p, %p\n", iface, transaction_level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_CommitTrans( _Connection *iface ) +{ + FIXME( "%p\n", iface ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_RollbackTrans( _Connection *iface ) +{ + FIXME( "%p\n", iface ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_Open( _Connection *iface, BSTR connect_str, BSTR userid, BSTR password, + LONG options ) +{ + FIXME( "%p, %s, %s, %p, %08x\n", iface, debugstr_w(connect_str), debugstr_w(userid), + debugstr_w(password), options ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_get_Errors( _Connection *iface, Errors **obj ) +{ + FIXME( "%p, %p\n", iface, obj ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_get_DefaultDatabase( _Connection *iface, BSTR *str ) +{ + FIXME( "%p, %p\n", iface, str ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_put_DefaultDatabase( _Connection *iface, BSTR str ) +{ + FIXME( "%p, %s\n", iface, debugstr_w(str) ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_get_IsolationLevel( _Connection *iface, IsolationLevelEnum *level ) +{ + FIXME( "%p, %p\n", iface, level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_put_IsolationLevel( _Connection *iface, IsolationLevelEnum level ) +{ + FIXME( "%p, %d\n", iface, level ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_get_Attributes( _Connection *iface, LONG *attr ) +{ + FIXME( "%p, %p\n", iface, attr ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_put_Attributes( _Connection *iface, LONG attr ) +{ + FIXME( "%p, %d\n", iface, attr ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_get_CursorLocation( _Connection *iface, CursorLocationEnum *cursor_loc ) +{ + FIXME( "%p, %p\n", iface, cursor_loc ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_put_CursorLocation( _Connection *iface, CursorLocationEnum cursor_loc ) +{ + FIXME( "%p, %u\n", iface, cursor_loc ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_get_Mode( _Connection *iface, ConnectModeEnum *mode ) +{ + FIXME( "%p, %p\n", iface, mode ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_put_Mode( _Connection *iface, ConnectModeEnum mode ) +{ + FIXME( "%p, %u\n", iface, mode ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_get_Provider( _Connection *iface, BSTR *str ) +{ + FIXME( "%p, %p\n", iface, str ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_put_Provider( _Connection *iface, BSTR str ) +{ + FIXME( "%p, %s\n", iface, debugstr_w(str) ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_get_State( _Connection *iface, LONG *state ) +{ + FIXME( "%p, %p\n", iface, state ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_OpenSchema( _Connection *iface, SchemaEnum schema, VARIANT restrictions, + VARIANT schema_id, _Recordset **record_set ) +{ + FIXME( "%p, %d, %s, %s, %p\n", iface, schema, debugstr_variant(&restrictions), + debugstr_variant(&schema_id), record_set ); + return E_NOTIMPL; +} + +static HRESULT WINAPI connection_Cancel( _Connection *iface ) +{ + FIXME( "%p\n", iface ); + return E_NOTIMPL; +} + +static const struct _ConnectionVtbl connection_vtbl = +{ + connection_QueryInterface, + connection_AddRef, + connection_Release, + connection_GetTypeInfoCount, + connection_GetTypeInfo, + connection_GetIDsOfNames, + connection_Invoke, + connection_get_Properties, + connection_get_ConnectionString, + connection_put_ConnectionString, + connection_get_CommandTimeout, + connection_put_CommandTimeout, + connection_get_ConnectionTimeout, + connection_put_ConnectionTimeout, + connection_get_Version, + connection_Close, + connection_Execute, + connection_BeginTrans, + connection_CommitTrans, + connection_RollbackTrans, + connection_Open, + connection_get_Errors, + connection_get_DefaultDatabase, + connection_put_DefaultDatabase, + connection_get_IsolationLevel, + connection_put_IsolationLevel, + connection_get_Attributes, + connection_put_Attributes, + connection_get_CursorLocation, + connection_put_CursorLocation, + connection_get_Mode, + connection_put_Mode, + connection_get_Provider, + connection_put_Provider, + connection_get_State, + connection_OpenSchema, + connection_Cancel +}; + +HRESULT Connection_create( void **obj ) +{ + struct connection *connection; + + if (!(connection = heap_alloc( sizeof(*connection) ))) return E_OUTOFMEMORY; + connection->Connection_iface.lpVtbl = &connection_vtbl; + connection->refs = 1; + + *obj = &connection->Connection_iface; + TRACE( "returning iface %p\n", *obj ); + return S_OK; +} diff --git a/dlls/msado15/main.c b/dlls/msado15/main.c index 0c5b2615d0a..d292826b1f5 100644 --- a/dlls/msado15/main.c +++ b/dlls/msado15/main.c @@ -19,10 +19,18 @@ #include #include "windef.h" #include "winbase.h" +#include "initguid.h" +#define COBJMACROS #include "objbase.h" #include "rpcproxy.h" +#include "msado15_backcompat.h" #include "wine/debug.h" +#include "wine/heap.h" + +#include "msado15_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msado15); static HINSTANCE hinstance; @@ -38,6 +46,104 @@ BOOL WINAPI DllMain( HINSTANCE dll, DWORD reason, LPVOID reserved ) return TRUE; } +typedef HRESULT (*fnCreateInstance)( void **obj ); + +struct msadocf +{ + IClassFactory IClassFactory_iface; + fnCreateInstance pfnCreateInstance; +}; + +static inline struct msadocf *impl_from_IClassFactory( IClassFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct msadocf, IClassFactory_iface ); +} + +static HRESULT WINAPI msadocf_QueryInterface( IClassFactory *iface, REFIID riid, void **obj ) +{ + if (IsEqualGUID( riid, &IID_IUnknown ) || IsEqualGUID( riid, &IID_IClassFactory )) + { + IClassFactory_AddRef( iface ); + *obj = iface; + return S_OK; + } + FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + return E_NOINTERFACE; +} + +static ULONG WINAPI msadocf_AddRef( IClassFactory *iface ) +{ + return 2; +} + +static ULONG WINAPI msadocf_Release( IClassFactory *iface ) +{ + return 1; +} + +static HRESULT WINAPI msadocf_CreateInstance( IClassFactory *iface, LPUNKNOWN outer, REFIID riid, void **obj ) +{ + struct msadocf *cf = impl_from_IClassFactory( iface ); + IUnknown *unknown; + HRESULT hr; + + TRACE( "%p, %s, %p\n", outer, debugstr_guid(riid), obj ); + + *obj = NULL; + if (outer) + return CLASS_E_NOAGGREGATION; + + hr = cf->pfnCreateInstance( (void **)&unknown ); + if (FAILED(hr)) + return hr; + + hr = IUnknown_QueryInterface( unknown, riid, obj ); + IUnknown_Release( unknown ); + return hr; +} + +static HRESULT WINAPI msadocf_LockServer( IClassFactory *iface, BOOL dolock ) +{ + FIXME( "%p, %d\n", iface, dolock ); + return S_OK; +} + +static const struct IClassFactoryVtbl msadocf_vtbl = +{ + msadocf_QueryInterface, + msadocf_AddRef, + msadocf_Release, + msadocf_CreateInstance, + msadocf_LockServer +}; + +static struct msadocf connection_cf = { { &msadocf_vtbl }, Connection_create }; + +/*********************************************************************** + * DllGetClassObject + */ +HRESULT WINAPI DllGetClassObject( REFCLSID clsid, REFIID iid, void **obj ) +{ + IClassFactory *cf = NULL; + + TRACE( "%s, %s, %p\n", debugstr_guid(clsid), debugstr_guid(iid), obj ); + + if (IsEqualGUID( clsid, &CLSID_Connection )) + { + cf = &connection_cf.IClassFactory_iface; + } + if (!cf) return CLASS_E_CLASSNOTAVAILABLE; + return IClassFactory_QueryInterface( cf, iid, obj ); +} + +/****************************************************************** + * DllCanUnloadNow + */ +HRESULT WINAPI DllCanUnloadNow(void) +{ + return S_FALSE; +} + /*********************************************************************** * DllRegisterServer */ diff --git a/dlls/msado15/msado15.spec b/dlls/msado15/msado15.spec index 6d0e061a537..b16365d0c9f 100644 --- a/dlls/msado15/msado15.spec +++ b/dlls/msado15/msado15.spec @@ -1,4 +1,4 @@ -@ stub DllCanUnloadNow -@ stub DllGetClassObject +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() diff --git a/dlls/msado15/msado15_classes.idl b/dlls/msado15/msado15_classes.idl new file mode 100644 index 00000000000..f69fea0a1a1 --- /dev/null +++ b/dlls/msado15/msado15_classes.idl @@ -0,0 +1,27 @@ +/* + * Copyright 2019 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#pragma makedep register + +[ + threading(apartment), + progid("ADODB.Connection.6.0"), + vi_progid("ADODB.Connection"), + uuid(00000514-0000-0010-8000-00aa006d2ea4) +] +coclass Connection { interface _Connection; } diff --git a/dlls/msado15/msado15_private.h b/dlls/msado15/msado15_private.h new file mode 100644 index 00000000000..1d4c379443e --- /dev/null +++ b/dlls/msado15/msado15_private.h @@ -0,0 +1,24 @@ +/* + * Copyright 2019 Hans Leidekker for CodeWeavers + * + * 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 + */ + +#ifndef _WINE_MSADO15_PRIVATE_H_ +#define _WINE_MSADO15_PRIVATE_H_ + +HRESULT Connection_create( void ** ) DECLSPEC_HIDDEN; + +#endif /* _WINE_MSADO15_PRIVATE_H_ */