From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
--- dlls/msado15/command.c | 305 ++++++++++++++++++++++++++++++++- dlls/msado15/main.c | 1 + dlls/msado15/msado15_private.h | 1 + dlls/msado15/tests/msado15.c | 20 +++ 4 files changed, 323 insertions(+), 4 deletions(-)
diff --git a/dlls/msado15/command.c b/dlls/msado15/command.c index 99519527c1c..0aecf2a7c54 100644 --- a/dlls/msado15/command.c +++ b/dlls/msado15/command.c @@ -50,6 +50,23 @@ struct command struct list parameters; };
+struct parameter +{ + _Parameter Parameter_iface; + LONG ref; + + BSTR name; + DataTypeEnum datatype; + ParameterDirectionEnum direction; + ADO_LONGPTR size; + VARIANT value; +}; + +static inline struct parameter *impl_from_Parameter( _Parameter *iface ) +{ + return CONTAINING_RECORD( iface, struct parameter, Parameter_iface ); +} + static inline struct command *impl_from_Command( _Command *iface ) { return CONTAINING_RECORD( iface, struct command, Command_iface ); @@ -442,14 +459,294 @@ static HRESULT WINAPI command_Execute( _Command *iface, VARIANT *affected, VARIA return E_NOTIMPL; }
-static HRESULT WINAPI command_CreateParameter( _Command *iface, BSTR name, DataTypeEnum type, - ParameterDirectionEnum direction, ADO_LONGPTR size, VARIANT value, - _Parameter **parameter ) +static HRESULT WINAPI parameter_QueryInterface(_Parameter *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__Parameter)) + { + *obj = iface; + } + else + { + FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + return E_NOINTERFACE; + } + + _Parameter_AddRef( iface ); + return S_OK; +} + +static ULONG WINAPI parameter_AddRef(_Parameter *iface) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + return InterlockedIncrement( ¶meter->ref ); +} + +static ULONG WINAPI parameter_Release(_Parameter *iface) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + LONG ref = InterlockedDecrement( ¶meter->ref ); + if (!ref) + { + SysFreeString(parameter->name); + VariantClear(¶meter->value); + + free( parameter ); + } + + return ref; +} + +static HRESULT WINAPI parameter_GetTypeInfoCount(_Parameter *iface, UINT *count) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + TRACE( "%p, %p\n", parameter, count ); + *count = 1; + return S_OK; +} + +static HRESULT WINAPI parameter_GetTypeInfo(_Parameter *iface, UINT index, LCID lcid, ITypeInfo **info) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + TRACE( "%p, %u, %lu, %p\n", parameter, index, lcid, info ); + return get_typeinfo(Parameter_tid, info); +} + +static HRESULT WINAPI parameter_GetIDsOfNames(_Parameter *iface, REFIID riid, LPOLESTR *names, UINT count, + LCID lcid, DISPID *dispid) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + HRESULT hr; + ITypeInfo *typeinfo; + + TRACE( "%p, %s, %p, %u, %lu, %p\n", parameter, debugstr_guid(riid), names, count, lcid, dispid ); + + hr = get_typeinfo(Parameter_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, dispid); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI parameter_Invoke(_Parameter *iface, DISPID member, REFIID riid, LCID lcid, WORD flags, + DISPPARAMS *params, VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + HRESULT hr; + ITypeInfo *typeinfo; + + TRACE( "%p, %ld, %s, %ld, %d, %p, %p, %p, %p\n", parameter, member, debugstr_guid(riid), lcid, flags, params, + result, excep_info, arg_err ); + + hr = get_typeinfo(Parameter_tid, &typeinfo); + if(SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke(typeinfo, ¶meter->Parameter_iface, member, flags, params, + result, excep_info, arg_err); + ITypeInfo_Release(typeinfo); + } + + return hr; +} + +static HRESULT WINAPI parameter_get_Properties(_Parameter *iface, Properties **object) { - FIXME( "%p, %s, %d, %d, %Id, %p\n", iface, debugstr_w(name), type, direction, size, parameter ); + struct parameter *parameter = impl_from_Parameter( iface ); + FIXME("%p, %p\n", parameter, object); return E_NOTIMPL; }
+static HRESULT WINAPI parameter_get_Name(_Parameter *iface, BSTR *str) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + TRACE("%p, %p\n", parameter, str); + *str = SysAllocString(parameter->name); + return S_OK; +} + +static HRESULT WINAPI parameter_put_Name(_Parameter *iface, BSTR str) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + TRACE("%p, %s\n", parameter, debugstr_w(str)); + + SysFreeString(parameter->name); + parameter->name = SysAllocString(str); + return S_OK; +} + +static HRESULT WINAPI parameter_get_Value(_Parameter *iface, VARIANT *val) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + TRACE("%p, %p\n", parameter, val); + + return VariantCopy(val, ¶meter->value); +} + +static HRESULT WINAPI parameter_put_Value(_Parameter *iface, VARIANT val) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + TRACE("%p, %s\n", parameter, debugstr_variant(&val)); + + VariantClear(¶meter->value); + return VariantCopy(¶meter->value, &val); +} + +static HRESULT WINAPI parameter_get_Type(_Parameter *iface, DataTypeEnum *data_type) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + TRACE("%p, %p\n", parameter, data_type); + *data_type = parameter->datatype; + return S_OK; +} + +static HRESULT WINAPI parameter_put_Type(_Parameter *iface, DataTypeEnum data_type) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + TRACE("%p, %d\n", parameter, data_type); + parameter->datatype = data_type; + return S_OK; +} + +static HRESULT WINAPI parameter_put_Direction(_Parameter *iface, ParameterDirectionEnum direction) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + TRACE("%p, %d\n", parameter, direction); + parameter->direction = direction; + return S_OK; +} + +static HRESULT WINAPI parameter_get_Direction(_Parameter *iface, ParameterDirectionEnum *direction) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + TRACE("%p, %p\n", parameter, direction); + *direction = parameter->direction; + return S_OK; +} + +static HRESULT WINAPI parameter_put_Precision(_Parameter *iface, unsigned char precision) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + FIXME("%p, %d\n", parameter, precision); + return E_NOTIMPL; +} + +static HRESULT WINAPI parameter_get_Precision(_Parameter *iface, unsigned char *precision) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + FIXME("%p, %p\n", parameter, precision); + return E_NOTIMPL; +} + +static HRESULT WINAPI parameter_put_NumericScale(_Parameter *iface, unsigned char scale) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + FIXME("%p, %d\n", parameter, scale); + return E_NOTIMPL; +} + +static HRESULT WINAPI parameter_get_NumericScale(_Parameter *iface, unsigned char *scale) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + FIXME("%p, %p\n", parameter, scale); + return E_NOTIMPL; +} + +static HRESULT WINAPI parameter_put_Size(_Parameter *iface, ADO_LONGPTR size) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + TRACE("%p, %Id\n", parameter, size); + parameter->size = size; + return S_OK; +} + +static HRESULT WINAPI parameter_get_Size(_Parameter *iface, ADO_LONGPTR *size) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + TRACE("%p, %p\n", parameter, size); + *size = parameter->size; + return S_OK; +} + +static HRESULT WINAPI parameter_AppendChunk(_Parameter *iface, VARIANT val) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + FIXME("%p, %s\n", parameter, debugstr_variant(&val)); + return E_NOTIMPL; +} + +static HRESULT WINAPI parameter_get_Attributes(_Parameter *iface, LONG *attrs) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + FIXME("%p, %p\n", parameter, attrs); + return E_NOTIMPL; +} + +static HRESULT WINAPI parameter_put_Attributes(_Parameter *iface, LONG attrs) +{ + struct parameter *parameter = impl_from_Parameter( iface ); + FIXME("%p, %ld\n", parameter, attrs); + return E_NOTIMPL; +} + +static const _ParameterVtbl parameter_vtbl = +{ + parameter_QueryInterface, + parameter_AddRef, + parameter_Release, + parameter_GetTypeInfoCount, + parameter_GetTypeInfo, + parameter_GetIDsOfNames, + parameter_Invoke, + parameter_get_Properties, + parameter_get_Name, + parameter_put_Name, + parameter_get_Value, + parameter_put_Value, + parameter_get_Type, + parameter_put_Type, + parameter_put_Direction, + parameter_get_Direction, + parameter_put_Precision, + parameter_get_Precision, + parameter_put_NumericScale, + parameter_get_NumericScale, + parameter_put_Size, + parameter_get_Size, + parameter_AppendChunk, + parameter_get_Attributes, + parameter_put_Attributes +}; + +static HRESULT WINAPI command_CreateParameter( _Command *iface, BSTR name, DataTypeEnum type, + ParameterDirectionEnum direction, ADO_LONGPTR size, VARIANT value, + _Parameter **obj ) +{ + struct parameter *parameter; + TRACE( "%p, %s, %d, %d, %Id, %s, %p\n", iface, debugstr_w(name), type, direction, size, + debugstr_variant(&value), obj ); + + if (!(parameter = malloc( sizeof(*parameter) ))) return E_OUTOFMEMORY; + parameter->Parameter_iface.lpVtbl = ¶meter_vtbl; + parameter->ref = 1; + parameter->name = SysAllocString(name); + parameter->datatype = type; + parameter->direction = direction; + parameter->size = size; + VariantCopy(¶meter->value, &value); + + *obj = ¶meter->Parameter_iface; + TRACE( "returning iface %p\n", *obj ); + return S_OK; +} + static HRESULT WINAPI command_get_Parameters( _Command *iface, Parameters **parameters ) { struct command *command = impl_from_Command( iface ); diff --git a/dlls/msado15/main.c b/dlls/msado15/main.c index 2e2e5a83250..91b2a642771 100644 --- a/dlls/msado15/main.c +++ b/dlls/msado15/main.c @@ -145,6 +145,7 @@ static REFIID tid_ids[] = { &IID__Connection, &IID_Field, &IID_Fields, + &IID__Parameter, &IID_Parameters, &IID_Properties, &IID_Property, diff --git a/dlls/msado15/msado15_private.h b/dlls/msado15/msado15_private.h index 797354e7dc0..2944f9fce4f 100644 --- a/dlls/msado15/msado15_private.h +++ b/dlls/msado15/msado15_private.h @@ -32,6 +32,7 @@ typedef enum tid_t { Connection_tid, Field_tid, Fields_tid, + Parameter_tid, Parameters_tid, Properties_tid, Property_tid, diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 4b46848cbe7..76e1bb35b77 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -1333,6 +1333,10 @@ static void test_Command(void) _Connection *connection; ADOCommandConstruction *adocommand; Parameters *parameters, *parameters2; + _Parameter *parameter = NULL; + IDispatch *disp; + BSTR str; + VARIANT value;
hr = CoCreateInstance( &CLSID_Command, NULL, CLSCTX_INPROC_SERVER, &IID__Command, (void **)&command ); ok( hr == S_OK, "got %08lx\n", hr ); @@ -1401,9 +1405,25 @@ static void test_Command(void) hr = _Command_putref_ActiveConnection( command, NULL ); ok( hr == S_OK, "got %08lx\n", hr );
+ VariantInit(&value); + str = SysAllocString(L"_"); + hr = _Command_CreateParameter(command, str, adInteger, adParamInput, 0, value, ¶meter ); + SysFreeString(str); + ok( hr == S_OK, "got %08lx\n", hr ); + ok( parameter != NULL, "Invalid pointer\n"); + hr = _Command_get_Parameters( command, ¶meters ); ok( hr == S_OK, "got %08lx\n", hr );
+ hr = _Parameter_QueryInterface(parameter, &IID_IDispatch, (void**)&disp); + ok( hr == S_OK, "got %08lx\n", hr ); + + hr = Parameters_Append(parameters, disp); + ok( hr == S_OK, "got %08lx\n", hr ); + + IDispatch_Release(disp); + _Parameter_Release(parameter); + hr = _Command_get_Parameters( command, ¶meters2 ); ok( hr == S_OK, "got %08lx\n", hr ); ok( parameters == parameters2, "got %08lx\n", hr );