From: Alistair Leslie-Hughes Subject: [PATCH 2/2] msado15: Add _Command stub interface Message-Id: Date: Thu, 12 Dec 2019 01:12:19 +0000 In-Reply-To: <20191212011204.11419-1-leslie_alistair@hotmail.com> References: <20191212011204.11419-1-leslie_alistair@hotmail.com> Signed-off-by: Alistair Leslie-Hughes --- dlls/msado15/Makefile.in | 1 + dlls/msado15/command.c | 388 +++++++++++++++++++++++++++++++ dlls/msado15/main.c | 5 + dlls/msado15/msado15_classes.idl | 8 + dlls/msado15/msado15_private.h | 1 + dlls/msado15/tests/msado15.c | 28 +++ 6 files changed, 431 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..9856b52e91 --- /dev/null +++ b/dlls/msado15/command.c @@ -0,0 +1,388 @@ +/* + * 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" +#include "msado15_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msado); + +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 **out) +{ + struct command *command = impl_from_Command(iface); + TRACE("(%p)->(%s, %p)\n", command, debugstr_guid(riid), out); + + *out = 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)) + { + *out = 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); + TRACE("(%p)\n", command); + + return InterlockedIncrement(&command->ref); +} + +static ULONG WINAPI command_Release(_Command *iface) +{ + struct command *command = impl_from_Command(iface); + LONG ref; + + TRACE("(%p)\n", command); + + ref = InterlockedDecrement(&command->ref); + if (!ref) + heap_free(command); + + return ref; +} + +static HRESULT WINAPI command_GetTypeInfoCount(_Command *iface, UINT *pctinfo) +{ + struct command *command = impl_from_Command(iface); + TRACE("(%p)->()\n", command); + + *pctinfo = 1; + return S_OK; +} + +static HRESULT WINAPI command_GetTypeInfo(_Command *iface, UINT iTInfo, LCID lcid, ITypeInfo **typeinfo) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%u %u %p)\n", command, iTInfo, lcid, typeinfo); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_GetIDsOfNames(_Command *iface, REFIID riid, LPOLESTR *rgszNames, + UINT cNames, LCID lcid, DISPID *rgDispId) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%s %p %u %u %p)\n", command, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_Invoke(_Command *iface, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, + UINT *puArgErr) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", command, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_Properties(_Command *iface, Properties **props) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p)\n", command, props); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_ActiveConnection(_Command *iface, _Connection **connection) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p)\n", command, connection); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_putref_ActiveConnection(_Command *iface, _Connection *connection) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p)\n", command, connection); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_ActiveConnection(_Command *iface, VARIANT connection) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->()\n", command); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_CommandText(_Command *iface, BSTR *text) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p)\n", command, text); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_CommandText(_Command *iface, BSTR text) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%s)\n", command, debugstr_w(text)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_CommandTimeout(_Command *iface, LONG *timeout) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p)\n", command, timeout); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_CommandTimeout(_Command *iface, LONG timeout) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%d)\n", command, timeout); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_Prepared(_Command *iface, VARIANT_BOOL *prepared) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p)\n", command, prepared); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_Prepared(_Command *iface, VARIANT_BOOL prepared) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%d)\n", command, prepared); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_Execute(_Command *iface, VARIANT *recordsaffected, VARIANT *parameters, + LONG options, _Recordset **recordset) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p %p %d %p)\n", command, recordsaffected, 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) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%s %d %d %d %p)\n", command, debugstr_w(name), type, direction, size, + parameter); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_Parameters(_Command *iface, Parameters **parameters) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p)\n", command, parameters); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_CommandType(_Command *iface, CommandTypeEnum cmdtype) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%d)\n", command, cmdtype); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_CommandType(_Command *iface, CommandTypeEnum *cmdtype) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p)\n", command, cmdtype); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_Name(_Command *iface, BSTR *name) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p)\n", command, name); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_Name(_Command *iface, BSTR name) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%s)\n", command, debugstr_w(name)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_State(_Command *iface, LONG *state) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p)\n", command, state); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_Cancel(_Command *iface) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->()\n", command); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_putref_CommandStream(_Command *iface, IUnknown *stream) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p)\n", command, stream); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_CommandStream(_Command *iface, VARIANT *stream) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p)\n", command, stream); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_Dialect(_Command *iface, BSTR dialect) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%s)\n", command, debugstr_w(dialect)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_Dialect(_Command *iface, BSTR *dialect) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p)\n", command, dialect); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_put_NamedParameters(_Command *iface, VARIANT_BOOL namedparameters) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%d)\n", command, namedparameters); + + return E_NOTIMPL; +} + +static HRESULT WINAPI command_get_NamedParameters(_Command *iface, VARIANT_BOOL *namedparameters) +{ + struct command *command = impl_from_Command(iface); + FIXME("(%p)->(%p)\n", command, namedparameters); + + 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 **out ) +{ + struct command *command; + + TRACE("(%p)\n", out); + + *out = NULL; + + command = heap_alloc(sizeof(*command)); + if (!command) + return E_OUTOFMEMORY; + + command->Command_iface.lpVtbl = &command_vtbl; + command->ref = 1; + + *out = &command->Command_iface; + + 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..7850c45231 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -444,6 +444,33 @@ 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 +478,6 @@ START_TEST(msado15) test_Fields(); test_Recordset(); test_Stream(); + test_Command(); CoUninitialize(); } -- 2.17.1