From: Hans Leidekker Subject: [PATCH 2/2] msado15: Add _Command stub interface. Message-Id: <20191212154206.13560-2-hans@codeweavers.com> Date: Thu, 12 Dec 2019 16:42:06 +0100 From: Alistair Leslie-Hughes Signed-off-by: Alistair Leslie-Hughes Signed-off-by: Hans Leidekker --- dlls/msado15/Makefile.in | 1 + dlls/msado15/command.c | 313 +++++++++++++++++++++++++++++++ dlls/msado15/main.c | 5 + dlls/msado15/msado15_classes.idl | 8 + dlls/msado15/msado15_private.h | 1 + dlls/msado15/tests/msado15.c | 27 +++ 6 files changed, 355 insertions(+) create mode 100644 dlls/msado15/command.c diff --git a/dlls/msado15/Makefile.in b/dlls/msado15/Makefile.in index 604f9ff018..9852e0863d 100644 --- a/dlls/msado15/Makefile.in +++ b/dlls/msado15/Makefile.in @@ -4,6 +4,7 @@ IMPORTS = oleaut32 EXTRADLLFLAGS = -mno-cygwin C_SRCS = \ + command.c \ connection.c \ main.c \ recordset.c \ diff --git a/dlls/msado15/command.c b/dlls/msado15/command.c new file mode 100644 index 0000000000..a96fd73990 --- /dev/null +++ b/dlls/msado15/command.c @@ -0,0 +1,313 @@ +/* + * Copyright 2019 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 + */ +#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 command +{ + _Command Command_iface; + LONG ref; +}; + +static inline struct command *impl_from_Command( _Command *iface ) +{ + return CONTAINING_RECORD( iface, struct command, Command_iface ); +} + +static HRESULT WINAPI command_QueryInterface( _Command *iface, REFIID riid, void **obj ) +{ + TRACE( "%p, %s, %p\n", iface, debugstr_guid(riid), obj ); + + *obj = NULL; + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IDispatch) || + IsEqualIID(riid, &IID__ADO) || + IsEqualIID(riid, &IID_Command15) || + IsEqualIID(riid, &IID_Command25) || + IsEqualIID(riid, &IID__Command)) + { + *obj = iface; + } + else + { + FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + return E_NOINTERFACE; + } + + _Command_AddRef( iface ); + return S_OK; +} + +static ULONG WINAPI command_AddRef( _Command *iface ) +{ + struct command *command = impl_from_Command( iface ); + return InterlockedIncrement( &command->ref ); +} + +static ULONG WINAPI command_Release( _Command *iface ) +{ + struct command *command = impl_from_Command( iface ); + LONG ref = InterlockedDecrement( &command->ref ); + if (!ref) + { + TRACE( "destroying %p\n", command ); + heap_free( command ); + } + return ref; +} + +static HRESULT WINAPI command_GetTypeInfoCount( _Command *iface, UINT *count ) +{ + FIXME( "%p, %p\n", iface, count ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_GetTypeInfo( _Command *iface, UINT index, LCID lcid, ITypeInfo **info ) +{ + FIXME( "%p, %u, %u, %p\n", iface, index, lcid, info ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_GetIDsOfNames( _Command *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 command_Invoke( _Command *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 command_get_Properties( _Command *iface, Properties **props ) +{ + FIXME( "%p, %p\n", iface, props ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_ActiveConnection( _Command *iface, _Connection **connection ) +{ + FIXME( "%p, %p\n", iface, connection ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_putref_ActiveConnection( _Command *iface, _Connection *connection ) +{ + FIXME( "%p, %p\n", iface, connection ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_ActiveConnection( _Command *iface, VARIANT connection ) +{ + FIXME( "%p, %s\n", iface, debugstr_variant(&connection) ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_CommandText( _Command *iface, BSTR *text ) +{ + FIXME( "%p, %p\n", iface, text ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_CommandText( _Command *iface, BSTR text ) +{ + FIXME( "%p, %s\n", iface, debugstr_w(text) ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_CommandTimeout( _Command *iface, LONG *timeout ) +{ + FIXME( "%p, %p\n", iface, timeout ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_CommandTimeout( _Command *iface, LONG timeout ) +{ + FIXME( "%p, %d\n", iface, timeout ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_Prepared( _Command *iface, VARIANT_BOOL *prepared ) +{ + FIXME( "%p, %p\n", iface, prepared ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_Prepared( _Command *iface, VARIANT_BOOL prepared ) +{ + FIXME( "%p, %d\n", iface, prepared ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_Execute( _Command *iface, VARIANT *affected, VARIANT *parameters, + LONG options, _Recordset **recordset ) +{ + FIXME( "%p, %p, %p, %d, %p\n", iface, affected, parameters, options, recordset ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_CreateParameter( _Command *iface, BSTR name, DataTypeEnum type, + ParameterDirectionEnum direction, LONG size, VARIANT value, + _Parameter **parameter ) +{ + FIXME( "%p, %s, %d, %d, %d, %p\n", iface, debugstr_w(name), type, direction, size, parameter ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_Parameters( _Command *iface, Parameters **parameters ) +{ + FIXME( "%p, %p\n", iface, parameters ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_CommandType( _Command *iface, CommandTypeEnum type ) +{ + FIXME( "%p, %d\n", iface, type ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_CommandType( _Command *iface, CommandTypeEnum *type ) +{ + FIXME( "%p, %p\n", iface, type ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_Name(_Command *iface, BSTR *name) +{ + FIXME( "%p, %p\n", iface, name ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_Name( _Command *iface, BSTR name ) +{ + FIXME( "%p, %s\n", iface, debugstr_w(name) ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_State( _Command *iface, LONG *state ) +{ + FIXME( "%p, %p\n", iface, state ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_Cancel( _Command *iface ) +{ + FIXME( "%p\n", iface ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_putref_CommandStream( _Command *iface, IUnknown *stream ) +{ + FIXME( "%p, %p\n", iface, stream ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_CommandStream( _Command *iface, VARIANT *stream ) +{ + FIXME( "%p, %p\n", iface, stream ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_Dialect( _Command *iface, BSTR dialect ) +{ + FIXME( "%p, %s\n", iface, debugstr_w(dialect) ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_Dialect( _Command *iface, BSTR *dialect ) +{ + FIXME( "%p, %p\n", iface, dialect ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_NamedParameters( _Command *iface, VARIANT_BOOL parameters ) +{ + FIXME( "%p, %d\n", iface, parameters ); + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_NamedParameters( _Command *iface, VARIANT_BOOL *parameters ) +{ + FIXME( "%p, %p\n", iface, parameters ); + return E_NOTIMPL; +} + +static const struct _CommandVtbl command_vtbl = +{ + command_QueryInterface, + command_AddRef, + command_Release, + command_GetTypeInfoCount, + command_GetTypeInfo, + command_GetIDsOfNames, + command_Invoke, + command_get_Properties, + command_get_ActiveConnection, + command_putref_ActiveConnection, + command_put_ActiveConnection, + command_get_CommandText, + command_put_CommandText, + command_get_CommandTimeout, + command_put_CommandTimeout, + command_get_Prepared, + command_put_Prepared, + command_Execute, + command_CreateParameter, + command_get_Parameters, + command_put_CommandType, + command_get_CommandType, + command_get_Name, + command_put_Name, + command_get_State, + command_Cancel, + command_putref_CommandStream, + command_get_CommandStream, + command_put_Dialect, + command_get_Dialect, + command_put_NamedParameters, + command_get_NamedParameters +}; + +HRESULT Command_create( void **obj ) +{ + struct command *command; + + if (!(command = heap_alloc( sizeof(*command) ))) return E_OUTOFMEMORY; + command->Command_iface.lpVtbl = &command_vtbl; + command->ref = 1; + + *obj = &command->Command_iface; + TRACE( "returning iface %p\n", *obj ); + return S_OK; +} diff --git a/dlls/msado15/main.c b/dlls/msado15/main.c index 32ae252337..3115474b84 100644 --- a/dlls/msado15/main.c +++ b/dlls/msado15/main.c @@ -117,6 +117,7 @@ static const struct IClassFactoryVtbl msadocf_vtbl = msadocf_LockServer }; +static struct msadocf command_cf = { { &msadocf_vtbl }, Command_create }; static struct msadocf connection_cf = { { &msadocf_vtbl }, Connection_create }; static struct msadocf recordset_cf = { { &msadocf_vtbl }, Recordset_create }; static struct msadocf stream_cf = { { &msadocf_vtbl }, Stream_create }; @@ -142,6 +143,10 @@ HRESULT WINAPI DllGetClassObject( REFCLSID clsid, REFIID iid, void **obj ) { cf = &stream_cf.IClassFactory_iface; } + else if (IsEqualGUID( clsid, &CLSID_Command )) + { + cf = &command_cf.IClassFactory_iface; + } if (!cf) return CLASS_E_CLASSNOTAVAILABLE; return IClassFactory_QueryInterface( cf, iid, obj ); } diff --git a/dlls/msado15/msado15_classes.idl b/dlls/msado15/msado15_classes.idl index 5ede180240..51f8bd77db 100644 --- a/dlls/msado15/msado15_classes.idl +++ b/dlls/msado15/msado15_classes.idl @@ -18,6 +18,14 @@ #pragma makedep register +[ + threading(apartment), + progid("ADODB.Command.6.0"), + vi_progid("ADODB.Command"), + uuid(00000507-0000-0010-8000-00aa006d2ea4) +] +coclass Command { interface _Command; } + [ threading(apartment), progid("ADODB.Connection.6.0"), diff --git a/dlls/msado15/msado15_private.h b/dlls/msado15/msado15_private.h index 7239e48b53..f6c60f0304 100644 --- a/dlls/msado15/msado15_private.h +++ b/dlls/msado15/msado15_private.h @@ -21,6 +21,7 @@ #define MAKE_ADO_HRESULT( err ) MAKE_HRESULT( SEVERITY_ERROR, FACILITY_CONTROL, err ) +HRESULT Command_create( void ** ) DECLSPEC_HIDDEN; HRESULT Connection_create( void ** ) DECLSPEC_HIDDEN; HRESULT Recordset_create( void ** ) DECLSPEC_HIDDEN; HRESULT Stream_create( void ** ) DECLSPEC_HIDDEN; diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 5a1813694b..03b2828d9f 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -444,6 +444,32 @@ if (0) /* Crashes on windows */ _Connection_Release(connection); } +static void test_Command(void) +{ + HRESULT hr; + _Command *command; + _ADO *ado; + Command15 *command15; + Command25 *command25; + + hr = CoCreateInstance( &CLSID_Command, NULL, CLSCTX_INPROC_SERVER, &IID__Command, (void **)&command ); + ok( hr == S_OK, "got %08x\n", hr ); + + hr = _Command_QueryInterface( command, &IID__ADO, (void **)&ado ); + ok( hr == S_OK, "got %08x\n", hr ); + _ADO_Release( ado ); + + hr = _Command_QueryInterface( command, &IID_Command15, (void **)&command15 ); + ok( hr == S_OK, "got %08x\n", hr ); + Command15_Release( command15 ); + + hr = _Command_QueryInterface( command, &IID_Command25, (void **)&command25 ); + ok( hr == S_OK, "got %08x\n", hr ); + Command25_Release( command25 ); + + _Command_Release( command ); +} + START_TEST(msado15) { CoInitialize( NULL ); @@ -451,5 +477,6 @@ START_TEST(msado15) test_Fields(); test_Recordset(); test_Stream(); + test_Command(); CoUninitialize(); } -- 2.20.1