2 * Copyright 2019 Hans Leidekker for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "msado15_backcompat.h"
28 #include "wine/debug.h"
30 #include "msado15_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(msado15
);
37 _Recordset Recordset_iface
;
38 ADORecordsetConstruction ADORecordsetConstruction_iface
;
39 ISupportErrorInfo ISupportErrorInfo_iface
;
42 struct fields
*fields
;
47 CursorLocationEnum cursor_location
;
48 CursorTypeEnum cursor_type
;
50 EditModeEnum editmode
;
57 ISupportErrorInfo ISupportErrorInfo_iface
;
62 struct recordset
*recordset
;
68 ISupportErrorInfo ISupportErrorInfo_iface
;
69 Properties Properties_iface
;
76 struct recordset
*recordset
;
79 static inline struct field
*impl_from_Field( Field
*iface
)
81 return CONTAINING_RECORD( iface
, struct field
, Field_iface
);
84 static inline struct field
*impl_from_Properties( Properties
*iface
)
86 return CONTAINING_RECORD( iface
, struct field
, Properties_iface
);
89 static ULONG WINAPI
field_AddRef( Field
*iface
)
91 struct field
*field
= impl_from_Field( iface
);
92 LONG refs
= InterlockedIncrement( &field
->refs
);
93 TRACE( "%p new refcount %ld\n", field
, refs
);
97 static ULONG WINAPI
field_Release( Field
*iface
)
99 struct field
*field
= impl_from_Field( iface
);
100 LONG refs
= InterlockedDecrement( &field
->refs
);
101 TRACE( "%p new refcount %ld\n", field
, refs
);
104 TRACE( "destroying %p\n", field
);
111 static HRESULT WINAPI
field_QueryInterface( Field
*iface
, REFIID riid
, void **obj
)
113 struct field
*field
= impl_from_Field( iface
);
114 TRACE( "%p, %s, %p\n", iface
, debugstr_guid(riid
), obj
);
116 if (IsEqualGUID( riid
, &IID_Field
) || IsEqualGUID( riid
, &IID_IDispatch
) ||
117 IsEqualGUID( riid
, &IID_IUnknown
))
121 else if (IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
123 *obj
= &field
->ISupportErrorInfo_iface
;
127 FIXME( "interface %s not implemented\n", debugstr_guid(riid
) );
128 return E_NOINTERFACE
;
130 field_AddRef( iface
);
134 static HRESULT WINAPI
field_GetTypeInfoCount( Field
*iface
, UINT
*count
)
136 struct field
*field
= impl_from_Field( iface
);
137 TRACE( "%p, %p\n", field
, count
);
142 static HRESULT WINAPI
field_GetTypeInfo( Field
*iface
, UINT index
, LCID lcid
, ITypeInfo
**info
)
144 struct field
*field
= impl_from_Field( iface
);
145 TRACE( "%p, %u, %lu, %p\n", field
, index
, lcid
, info
);
146 return get_typeinfo(Field_tid
, info
);
149 static HRESULT WINAPI
field_GetIDsOfNames( Field
*iface
, REFIID riid
, LPOLESTR
*names
, UINT count
,
150 LCID lcid
, DISPID
*dispid
)
152 struct field
*field
= impl_from_Field( iface
);
156 TRACE( "%p, %s, %p, %u, %lu, %p\n", field
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
158 hr
= get_typeinfo(Field_tid
, &typeinfo
);
161 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, count
, dispid
);
162 ITypeInfo_Release(typeinfo
);
168 static HRESULT WINAPI
field_Invoke( Field
*iface
, DISPID member
, REFIID riid
, LCID lcid
, WORD flags
,
169 DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excep_info
, UINT
*arg_err
)
171 struct field
*field
= impl_from_Field( iface
);
175 TRACE( "%p, %ld, %s, %ld, %d, %p, %p, %p, %p\n", field
, member
, debugstr_guid(riid
), lcid
, flags
, params
,
176 result
, excep_info
, arg_err
);
178 hr
= get_typeinfo(Field_tid
, &typeinfo
);
181 hr
= ITypeInfo_Invoke(typeinfo
, &field
->Field_iface
, member
, flags
, params
,
182 result
, excep_info
, arg_err
);
183 ITypeInfo_Release(typeinfo
);
189 static HRESULT WINAPI
field_get_Properties( Field
*iface
, Properties
**obj
)
191 struct field
*field
= impl_from_Field( iface
);
192 TRACE( "%p, %p\n", iface
, obj
);
194 *obj
= &field
->Properties_iface
;
195 Properties_AddRef(&field
->Properties_iface
);
199 static HRESULT WINAPI
field_get_ActualSize( Field
*iface
, ADO_LONGPTR
*size
)
201 FIXME( "%p, %p\n", iface
, size
);
205 static HRESULT WINAPI
field_get_Attributes( Field
*iface
, LONG
*attrs
)
207 struct field
*field
= impl_from_Field( iface
);
209 TRACE( "%p, %p\n", field
, attrs
);
211 *attrs
= field
->attrs
;
215 static HRESULT WINAPI
field_get_DefinedSize( Field
*iface
, ADO_LONGPTR
*size
)
217 struct field
*field
= impl_from_Field( iface
);
219 TRACE( "%p, %p\n", field
, size
);
221 *size
= field
->defined_size
;
225 static HRESULT WINAPI
field_get_Name( Field
*iface
, BSTR
*str
)
227 struct field
*field
= impl_from_Field( iface
);
230 TRACE( "%p, %p\n", field
, str
);
232 if (!(name
= SysAllocString( field
->name
))) return E_OUTOFMEMORY
;
237 static HRESULT WINAPI
field_get_Type( Field
*iface
, DataTypeEnum
*type
)
239 struct field
*field
= impl_from_Field( iface
);
241 TRACE( "%p, %p\n", field
, type
);
247 static LONG
get_column_count( struct recordset
*recordset
)
249 return recordset
->fields
->count
;
252 static HRESULT WINAPI
field_get_Value( Field
*iface
, VARIANT
*val
)
254 struct field
*field
= impl_from_Field( iface
);
255 ULONG row
= field
->recordset
->index
, col
= field
->index
, col_count
;
259 TRACE( "%p, %p\n", field
, val
);
261 if (field
->recordset
->state
== adStateClosed
) return MAKE_ADO_HRESULT( adErrObjectClosed
);
262 if (field
->recordset
->index
< 0) return MAKE_ADO_HRESULT( adErrNoCurrentRecord
);
264 col_count
= get_column_count( field
->recordset
);
266 VariantInit( ©
);
267 if ((hr
= VariantCopy( ©
, &field
->recordset
->data
[row
* col_count
+ col
] )) != S_OK
) return hr
;
273 static HRESULT WINAPI
field_put_Value( Field
*iface
, VARIANT val
)
275 struct field
*field
= impl_from_Field( iface
);
276 ULONG row
= field
->recordset
->index
, col
= field
->index
, col_count
;
280 TRACE( "%p, %s\n", field
, debugstr_variant(&val
) );
282 if (field
->recordset
->state
== adStateClosed
) return MAKE_ADO_HRESULT( adErrObjectClosed
);
283 if (field
->recordset
->index
< 0) return MAKE_ADO_HRESULT( adErrNoCurrentRecord
);
285 col_count
= get_column_count( field
->recordset
);
287 VariantInit( ©
);
288 if ((hr
= VariantCopy( ©
, &val
)) != S_OK
) return hr
;
290 field
->recordset
->data
[row
* col_count
+ col
] = copy
;
294 static HRESULT WINAPI
field_get_Precision( Field
*iface
, unsigned char *precision
)
296 FIXME( "%p, %p\n", iface
, precision
);
300 static HRESULT WINAPI
field_get_NumericScale( Field
*iface
, unsigned char *scale
)
302 FIXME( "%p, %p\n", iface
, scale
);
306 static HRESULT WINAPI
field_AppendChunk( Field
*iface
, VARIANT data
)
308 FIXME( "%p, %s\n", iface
, debugstr_variant(&data
) );
312 static HRESULT WINAPI
field_GetChunk( Field
*iface
, LONG length
, VARIANT
*var
)
314 FIXME( "%p, %ld, %p\n", iface
, length
, var
);
318 static HRESULT WINAPI
field_get_OriginalValue( Field
*iface
, VARIANT
*val
)
320 FIXME( "%p, %p\n", iface
, val
);
324 static HRESULT WINAPI
field_get_UnderlyingValue( Field
*iface
, VARIANT
*val
)
326 FIXME( "%p, %p\n", iface
, val
);
330 static HRESULT WINAPI
field_get_DataFormat( Field
*iface
, IUnknown
**format
)
332 FIXME( "%p, %p\n", iface
, format
);
336 static HRESULT WINAPI
field_putref_DataFormat( Field
*iface
, IUnknown
*format
)
338 FIXME( "%p, %p\n", iface
, format
);
342 static HRESULT WINAPI
field_put_Precision( Field
*iface
, unsigned char precision
)
344 FIXME( "%p, %c\n", iface
, precision
);
348 static HRESULT WINAPI
field_put_NumericScale( Field
*iface
, unsigned char scale
)
350 FIXME( "%p, %c\n", iface
, scale
);
354 static HRESULT WINAPI
field_put_Type( Field
*iface
, DataTypeEnum type
)
356 struct field
*field
= impl_from_Field( iface
);
358 TRACE( "%p, %u\n", field
, type
);
364 static HRESULT WINAPI
field_put_DefinedSize( Field
*iface
, ADO_LONGPTR size
)
366 struct field
*field
= impl_from_Field( iface
);
368 TRACE( "%p, %Id\n", field
, size
);
370 field
->defined_size
= size
;
374 static HRESULT WINAPI
field_put_Attributes( Field
*iface
, LONG attrs
)
376 struct field
*field
= impl_from_Field( iface
);
378 TRACE( "%p, %ld\n", field
, attrs
);
380 field
->attrs
= attrs
;
384 static HRESULT WINAPI
field_get_Status( Field
*iface
, LONG
*status
)
386 FIXME( "%p, %p\n", iface
, status
);
390 static const struct FieldVtbl field_vtbl
=
392 field_QueryInterface
,
395 field_GetTypeInfoCount
,
399 field_get_Properties
,
400 field_get_ActualSize
,
401 field_get_Attributes
,
402 field_get_DefinedSize
,
408 field_get_NumericScale
,
411 field_get_OriginalValue
,
412 field_get_UnderlyingValue
,
413 field_get_DataFormat
,
414 field_putref_DataFormat
,
416 field_put_NumericScale
,
418 field_put_DefinedSize
,
419 field_put_Attributes
,
423 static inline struct field
*field_from_ISupportErrorInfo( ISupportErrorInfo
*iface
)
425 return CONTAINING_RECORD( iface
, struct field
, ISupportErrorInfo_iface
);
428 static HRESULT WINAPI
field_supporterrorinfo_QueryInterface( ISupportErrorInfo
*iface
, REFIID riid
, void **obj
)
430 struct field
*field
= field_from_ISupportErrorInfo( iface
);
431 return Field_QueryInterface( &field
->Field_iface
, riid
, obj
);
434 static ULONG WINAPI
field_supporterrorinfo_AddRef( ISupportErrorInfo
*iface
)
436 struct field
*field
= field_from_ISupportErrorInfo( iface
);
437 return Field_AddRef( &field
->Field_iface
);
440 static ULONG WINAPI
field_supporterrorinfo_Release( ISupportErrorInfo
*iface
)
442 struct field
*field
= field_from_ISupportErrorInfo( iface
);
443 return Field_Release( &field
->Field_iface
);
446 static HRESULT WINAPI
field_supporterrorinfo_InterfaceSupportsErrorInfo( ISupportErrorInfo
*iface
, REFIID riid
)
448 struct field
*field
= field_from_ISupportErrorInfo( iface
);
449 FIXME( "%p, %s\n", field
, debugstr_guid(riid
) );
453 static const ISupportErrorInfoVtbl field_supporterrorinfo_vtbl
=
455 field_supporterrorinfo_QueryInterface
,
456 field_supporterrorinfo_AddRef
,
457 field_supporterrorinfo_Release
,
458 field_supporterrorinfo_InterfaceSupportsErrorInfo
461 static HRESULT WINAPI
field_props_QueryInterface(Properties
*iface
, REFIID riid
, void **ppv
)
463 struct field
*field
= impl_from_Properties( iface
);
465 if (IsEqualGUID( riid
, &IID_Properties
) || IsEqualGUID( riid
, &IID_IDispatch
) ||
466 IsEqualGUID( riid
, &IID_IUnknown
))
468 *ppv
= &field
->Properties_iface
;
472 FIXME( "interface %s not implemented\n", debugstr_guid(riid
) );
473 return E_NOINTERFACE
;
475 Field_AddRef(&field
->Field_iface
);
479 static ULONG WINAPI
field_props_AddRef(Properties
*iface
)
481 struct field
*field
= impl_from_Properties( iface
);
482 return Field_AddRef(&field
->Field_iface
);
485 static ULONG WINAPI
field_props_Release(Properties
*iface
)
487 struct field
*field
= impl_from_Properties( iface
);
488 return Field_Release(&field
->Field_iface
);
491 static HRESULT WINAPI
field_props_GetTypeInfoCount(Properties
*iface
, UINT
*count
)
493 struct field
*field
= impl_from_Properties( iface
);
494 TRACE( "%p, %p\n", field
, count
);
499 static HRESULT WINAPI
field_props_GetTypeInfo(Properties
*iface
, UINT index
, LCID lcid
, ITypeInfo
**info
)
501 struct field
*field
= impl_from_Properties( iface
);
502 TRACE( "%p, %u, %lu, %p\n", field
, index
, lcid
, info
);
503 return get_typeinfo(Properties_tid
, info
);
506 static HRESULT WINAPI
field_props_GetIDsOfNames(Properties
*iface
, REFIID riid
, LPOLESTR
*names
, UINT count
,
507 LCID lcid
, DISPID
*dispid
)
509 struct field
*field
= impl_from_Properties( iface
);
513 TRACE( "%p, %s, %p, %u, %lu, %p\n", field
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
515 hr
= get_typeinfo(Properties_tid
, &typeinfo
);
518 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, count
, dispid
);
519 ITypeInfo_Release(typeinfo
);
525 static HRESULT WINAPI
field_props_Invoke(Properties
*iface
, DISPID member
, REFIID riid
, LCID lcid
, WORD flags
,
526 DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excep_info
, UINT
*arg_err
)
528 struct field
*field
= impl_from_Properties( iface
);
532 TRACE( "%p, %ld, %s, %ld, %d, %p, %p, %p, %p\n", field
, member
, debugstr_guid(riid
), lcid
, flags
, params
,
533 result
, excep_info
, arg_err
);
535 hr
= get_typeinfo(Properties_tid
, &typeinfo
);
538 hr
= ITypeInfo_Invoke(typeinfo
, &field
->Field_iface
, member
, flags
, params
,
539 result
, excep_info
, arg_err
);
540 ITypeInfo_Release(typeinfo
);
546 static HRESULT WINAPI
field_props_get_Count(Properties
*iface
, LONG
*count
)
548 struct field
*field
= impl_from_Properties( iface
);
549 FIXME( "%p, %p\n", field
, count
);
554 static HRESULT WINAPI
field_props__NewEnum(Properties
*iface
, IUnknown
**object
)
556 struct field
*field
= impl_from_Properties( iface
);
557 FIXME( "%p, %p\n", field
, object
);
561 static HRESULT WINAPI
field_props_Refresh(Properties
*iface
)
563 struct field
*field
= impl_from_Properties( iface
);
564 FIXME( "%p\n", field
);
568 static HRESULT WINAPI
field_props_get_Item(Properties
*iface
, VARIANT index
, Property
**object
)
570 struct field
*field
= impl_from_Properties( iface
);
571 FIXME( "%p, %s, %p\n", field
, debugstr_variant(&index
), object
);
572 return MAKE_ADO_HRESULT(adErrItemNotFound
);
575 static struct PropertiesVtbl field_properties_vtbl
=
577 field_props_QueryInterface
,
580 field_props_GetTypeInfoCount
,
581 field_props_GetTypeInfo
,
582 field_props_GetIDsOfNames
,
584 field_props_get_Count
,
585 field_props__NewEnum
,
590 static HRESULT
Field_create( const WCHAR
*name
, LONG index
, struct recordset
*recordset
, Field
**obj
)
594 if (!(field
= calloc( 1, sizeof(*field
) ))) return E_OUTOFMEMORY
;
595 field
->Field_iface
.lpVtbl
= &field_vtbl
;
596 field
->ISupportErrorInfo_iface
.lpVtbl
= &field_supporterrorinfo_vtbl
;
597 field
->Properties_iface
.lpVtbl
= &field_properties_vtbl
;
599 if (!(field
->name
= wcsdup( name
)))
602 return E_OUTOFMEMORY
;
604 field
->index
= index
;
605 field
->recordset
= recordset
;
607 *obj
= &field
->Field_iface
;
608 TRACE( "returning iface %p\n", *obj
);
612 static inline struct fields
*impl_from_Fields( Fields
*iface
)
614 return CONTAINING_RECORD( iface
, struct fields
, Fields_iface
);
617 static ULONG WINAPI
fields_AddRef( Fields
*iface
)
619 struct fields
*fields
= impl_from_Fields( iface
);
620 LONG refs
= InterlockedIncrement( &fields
->refs
);
621 TRACE( "%p new refcount %ld\n", fields
, refs
);
625 static ULONG WINAPI
fields_Release( Fields
*iface
)
627 struct fields
*fields
= impl_from_Fields( iface
);
628 LONG refs
= InterlockedDecrement( &fields
->refs
);
629 TRACE( "%p new refcount %ld\n", fields
, refs
);
632 if (fields
->recordset
) _Recordset_Release( &fields
->recordset
->Recordset_iface
);
633 fields
->recordset
= NULL
;
634 WARN( "not destroying %p\n", fields
);
635 return InterlockedIncrement( &fields
->refs
);
640 static HRESULT WINAPI
fields_QueryInterface( Fields
*iface
, REFIID riid
, void **obj
)
642 struct fields
*fields
= impl_from_Fields( iface
);
643 TRACE( "%p, %s, %p\n", iface
, debugstr_guid(riid
), obj
);
645 if (IsEqualGUID( riid
, &IID_Fields
) || IsEqualGUID( riid
, &IID_IDispatch
) ||
646 IsEqualGUID( riid
, &IID_IUnknown
))
650 else if (IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
652 *obj
= &fields
->ISupportErrorInfo_iface
;
656 FIXME( "interface %s not implemented\n", debugstr_guid(riid
) );
657 return E_NOINTERFACE
;
659 fields_AddRef( iface
);
663 static HRESULT WINAPI
fields_GetTypeInfoCount( Fields
*iface
, UINT
*count
)
665 struct fields
*fields
= impl_from_Fields( iface
);
666 TRACE( "%p, %p\n", fields
, count
);
671 static HRESULT WINAPI
fields_GetTypeInfo( Fields
*iface
, UINT index
, LCID lcid
, ITypeInfo
**info
)
673 struct fields
*fields
= impl_from_Fields( iface
);
674 TRACE( "%p, %u, %lu, %p\n", fields
, index
, lcid
, info
);
675 return get_typeinfo(Fields_tid
, info
);
678 static HRESULT WINAPI
fields_GetIDsOfNames( Fields
*iface
, REFIID riid
, LPOLESTR
*names
, UINT count
,
679 LCID lcid
, DISPID
*dispid
)
681 struct fields
*fields
= impl_from_Fields( iface
);
685 TRACE( "%p, %s, %p, %u, %lu, %p\n", fields
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
687 hr
= get_typeinfo(Fields_tid
, &typeinfo
);
690 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, count
, dispid
);
691 ITypeInfo_Release(typeinfo
);
697 static HRESULT WINAPI
fields_Invoke( Fields
*iface
, DISPID member
, REFIID riid
, LCID lcid
, WORD flags
,
698 DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excep_info
, UINT
*arg_err
)
700 struct fields
*fields
= impl_from_Fields( iface
);
704 TRACE( "%p, %ld, %s, %ld, %d, %p, %p, %p, %p\n", fields
, member
, debugstr_guid(riid
), lcid
, flags
, params
,
705 result
, excep_info
, arg_err
);
707 hr
= get_typeinfo(Fields_tid
, &typeinfo
);
710 hr
= ITypeInfo_Invoke(typeinfo
, &fields
->Fields_iface
, member
, flags
, params
,
711 result
, excep_info
, arg_err
);
712 ITypeInfo_Release(typeinfo
);
718 static HRESULT WINAPI
fields_get_Count( Fields
*iface
, LONG
*count
)
720 struct fields
*fields
= impl_from_Fields( iface
);
722 TRACE( "%p, %p\n", fields
, count
);
724 *count
= fields
->count
;
728 static HRESULT WINAPI
fields__NewEnum( Fields
*iface
, IUnknown
**obj
)
730 FIXME( "%p, %p\n", iface
, obj
);
734 static HRESULT WINAPI
fields_Refresh( Fields
*iface
)
736 FIXME( "%p\n", iface
);
740 static HRESULT
map_index( struct fields
*fields
, VARIANT
*index
, ULONG
*ret
)
744 if (V_VT( index
) != VT_BSTR
)
749 if (VariantChangeType(&idx
, index
, 0, VT_UI4
) == S_OK
)
752 if (i
< fields
->count
)
759 return MAKE_ADO_HRESULT(adErrItemNotFound
);
762 for (i
= 0; i
< fields
->count
; i
++)
768 if ((hr
= Field_get_Name( fields
->field
[i
], &name
)) != S_OK
) return hr
;
769 match
= !wcsicmp( V_BSTR( index
), name
);
770 SysFreeString( name
);
778 return MAKE_ADO_HRESULT(adErrItemNotFound
);
781 static HRESULT WINAPI
fields_get_Item( Fields
*iface
, VARIANT index
, Field
**obj
)
783 struct fields
*fields
= impl_from_Fields( iface
);
787 TRACE( "%p, %s, %p\n", fields
, debugstr_variant(&index
), obj
);
789 if ((hr
= map_index( fields
, &index
, &i
)) != S_OK
) return hr
;
791 Field_AddRef( fields
->field
[i
] );
792 *obj
= fields
->field
[i
];
796 static BOOL
resize_fields( struct fields
*fields
, ULONG count
)
798 if (count
> fields
->allocated
)
801 ULONG new_size
= max( count
, fields
->allocated
* 2 );
802 if (!(tmp
= realloc( fields
->field
, new_size
* sizeof(*tmp
) ))) return FALSE
;
804 fields
->allocated
= new_size
;
807 fields
->count
= count
;
811 static HRESULT
append_field( struct fields
*fields
, BSTR name
, DataTypeEnum type
, LONG size
, FieldAttributeEnum attr
,
817 if ((hr
= Field_create( name
, fields
->count
, fields
->recordset
, &field
)) != S_OK
) return hr
;
818 Field_put_Type( field
, type
);
819 Field_put_DefinedSize( field
, size
);
820 if (attr
!= adFldUnspecified
) Field_put_Attributes( field
, attr
);
821 if (value
) FIXME( "ignoring value %s\n", debugstr_variant(value
) );
823 if (!(resize_fields( fields
, fields
->count
+ 1 )))
825 Field_Release( field
);
826 return E_OUTOFMEMORY
;
829 fields
->field
[fields
->count
- 1] = field
;
833 static HRESULT WINAPI
fields__Append( Fields
*iface
, BSTR name
, DataTypeEnum type
, ADO_LONGPTR size
, FieldAttributeEnum attr
)
835 struct fields
*fields
= impl_from_Fields( iface
);
837 TRACE( "%p, %s, %u, %Id, %d\n", fields
, debugstr_w(name
), type
, size
, attr
);
839 return append_field( fields
, name
, type
, size
, attr
, NULL
);
842 static HRESULT WINAPI
fields_Delete( Fields
*iface
, VARIANT index
)
844 FIXME( "%p, %s\n", iface
, debugstr_variant(&index
) );
848 static HRESULT WINAPI
fields_Append( Fields
*iface
, BSTR name
, DataTypeEnum type
, ADO_LONGPTR size
, FieldAttributeEnum attr
,
851 struct fields
*fields
= impl_from_Fields( iface
);
853 TRACE( "%p, %s, %u, %Id, %d, %s\n", fields
, debugstr_w(name
), type
, size
, attr
, debugstr_variant(&value
) );
855 return append_field( fields
, name
, type
, size
, attr
, &value
);
858 static HRESULT WINAPI
fields_Update( Fields
*iface
)
860 FIXME( "%p\n", iface
);
864 static HRESULT WINAPI
fields_Resync( Fields
*iface
, ResyncEnum resync_values
)
866 FIXME( "%p, %u\n", iface
, resync_values
);
870 static HRESULT WINAPI
fields_CancelUpdate( Fields
*iface
)
872 FIXME( "%p\n", iface
);
876 static const struct FieldsVtbl fields_vtbl
=
878 fields_QueryInterface
,
881 fields_GetTypeInfoCount
,
883 fields_GetIDsOfNames
,
897 static inline struct fields
*fields_from_ISupportErrorInfo( ISupportErrorInfo
*iface
)
899 return CONTAINING_RECORD( iface
, struct fields
, ISupportErrorInfo_iface
);
902 static HRESULT WINAPI
fields_supporterrorinfo_QueryInterface( ISupportErrorInfo
*iface
, REFIID riid
, void **obj
)
904 struct fields
*fields
= fields_from_ISupportErrorInfo( iface
);
905 return Fields_QueryInterface( &fields
->Fields_iface
, riid
, obj
);
908 static ULONG WINAPI
fields_supporterrorinfo_AddRef( ISupportErrorInfo
*iface
)
910 struct fields
*fields
= fields_from_ISupportErrorInfo( iface
);
911 return Fields_AddRef( &fields
->Fields_iface
);
914 static ULONG WINAPI
fields_supporterrorinfo_Release( ISupportErrorInfo
*iface
)
916 struct fields
*fields
= fields_from_ISupportErrorInfo( iface
);
917 return Fields_Release( &fields
->Fields_iface
);
920 static HRESULT WINAPI
fields_supporterrorinfo_InterfaceSupportsErrorInfo( ISupportErrorInfo
*iface
, REFIID riid
)
922 struct fields
*fields
= fields_from_ISupportErrorInfo( iface
);
923 FIXME( "%p, %s\n", fields
, debugstr_guid(riid
) );
927 static const ISupportErrorInfoVtbl fields_supporterrorinfo_vtbl
=
929 fields_supporterrorinfo_QueryInterface
,
930 fields_supporterrorinfo_AddRef
,
931 fields_supporterrorinfo_Release
,
932 fields_supporterrorinfo_InterfaceSupportsErrorInfo
935 static void map_rowset_fields(struct recordset
*recordset
, struct fields
*fields
)
938 IColumnsInfo
*columninfo
;
939 DBORDINAL columns
, i
;
940 DBCOLUMNINFO
*colinfo
;
941 OLECHAR
*stringsbuffer
;
943 /* Not Finding the interface or GetColumnInfo failing just causes 0 Fields to be returned */
944 hr
= IRowset_QueryInterface(recordset
->row_set
, &IID_IColumnsInfo
, (void**)&columninfo
);
948 hr
= IColumnsInfo_GetColumnInfo(columninfo
, &columns
, &colinfo
, &stringsbuffer
);
951 for (i
=0; i
< columns
; i
++)
953 TRACE("Adding Column %Iu, pwszName: %s, pTypeInfo %p, iOrdinal %Iu, dwFlags 0x%08lx, "
954 "ulColumnSize %Iu, wType %d, bPrecision %d, bScale %d\n",
955 i
, debugstr_w(colinfo
[i
].pwszName
), colinfo
[i
].pTypeInfo
, colinfo
[i
].iOrdinal
,
956 colinfo
[i
].dwFlags
, colinfo
[i
].ulColumnSize
, colinfo
[i
].wType
,
957 colinfo
[i
].bPrecision
, colinfo
[i
].bScale
);
959 hr
= append_field(fields
, colinfo
[i
].pwszName
, colinfo
[i
].wType
, colinfo
[i
].ulColumnSize
,
960 colinfo
[i
].dwFlags
, NULL
);
963 ERR("Failed to add Field name - 0x%08lx\n", hr
);
968 CoTaskMemFree(colinfo
);
969 CoTaskMemFree(stringsbuffer
);
972 IColumnsInfo_Release(columninfo
);
975 static HRESULT
fields_create( struct recordset
*recordset
, struct fields
**ret
)
977 struct fields
*fields
;
979 if (!(fields
= calloc( 1, sizeof(*fields
) ))) return E_OUTOFMEMORY
;
980 fields
->Fields_iface
.lpVtbl
= &fields_vtbl
;
981 fields
->ISupportErrorInfo_iface
.lpVtbl
= &fields_supporterrorinfo_vtbl
;
983 fields
->recordset
= recordset
;
984 _Recordset_AddRef( &fields
->recordset
->Recordset_iface
);
986 if ( recordset
->row_set
)
987 map_rowset_fields(recordset
, fields
);
990 TRACE( "returning %p\n", *ret
);
994 static inline struct recordset
*impl_from_Recordset( _Recordset
*iface
)
996 return CONTAINING_RECORD( iface
, struct recordset
, Recordset_iface
);
999 static inline struct recordset
*impl_from_ADORecordsetConstruction( ADORecordsetConstruction
*iface
)
1001 return CONTAINING_RECORD( iface
, struct recordset
, ADORecordsetConstruction_iface
);
1004 static ULONG WINAPI
recordset_AddRef( _Recordset
*iface
)
1006 struct recordset
*recordset
= impl_from_Recordset( iface
);
1007 LONG refs
= InterlockedIncrement( &recordset
->refs
);
1008 TRACE( "%p new refcount %ld\n", recordset
, refs
);
1012 static void close_recordset( struct recordset
*recordset
)
1014 ULONG row
, col
, col_count
;
1017 if ( recordset
->row_set
) IRowset_Release( recordset
->row_set
);
1018 recordset
->row_set
= NULL
;
1020 if (!recordset
->fields
) return;
1021 col_count
= get_column_count( recordset
);
1023 for (i
= 0; i
< col_count
; i
++)
1025 struct field
*field
= impl_from_Field( recordset
->fields
->field
[i
] );
1026 field
->recordset
= NULL
;
1027 Field_Release(&field
->Field_iface
);
1029 recordset
->fields
->count
= 0;
1030 Fields_Release( &recordset
->fields
->Fields_iface
);
1031 recordset
->fields
= NULL
;
1033 for (row
= 0; row
< recordset
->count
; row
++)
1034 for (col
= 0; col
< col_count
; col
++) VariantClear( &recordset
->data
[row
* col_count
+ col
] );
1036 recordset
->count
= recordset
->allocated
= recordset
->index
= 0;
1037 free( recordset
->data
);
1038 recordset
->data
= NULL
;
1041 static ULONG WINAPI
recordset_Release( _Recordset
*iface
)
1043 struct recordset
*recordset
= impl_from_Recordset( iface
);
1044 LONG refs
= InterlockedDecrement( &recordset
->refs
);
1045 TRACE( "%p new refcount %ld\n", recordset
, refs
);
1048 TRACE( "destroying %p\n", recordset
);
1049 close_recordset( recordset
);
1055 static HRESULT WINAPI
recordset_QueryInterface( _Recordset
*iface
, REFIID riid
, void **obj
)
1057 struct recordset
*recordset
= impl_from_Recordset( iface
);
1058 TRACE( "%p, %s, %p\n", iface
, debugstr_guid(riid
), obj
);
1062 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDispatch
) ||
1063 IsEqualIID(riid
, &IID__ADO
) || IsEqualIID(riid
, &IID_Recordset15
) ||
1064 IsEqualIID(riid
, &IID_Recordset20
) || IsEqualIID(riid
, &IID_Recordset21
) ||
1065 IsEqualIID(riid
, &IID__Recordset
))
1069 else if (IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
1071 *obj
= &recordset
->ISupportErrorInfo_iface
;
1073 else if (IsEqualGUID( riid
, &IID_ADORecordsetConstruction
))
1075 *obj
= &recordset
->ADORecordsetConstruction_iface
;
1077 else if (IsEqualGUID( riid
, &IID_IRunnableObject
))
1079 TRACE("IID_IRunnableObject not supported returning NULL\n");
1080 return E_NOINTERFACE
;
1084 FIXME( "interface %s not implemented\n", debugstr_guid(riid
) );
1085 return E_NOINTERFACE
;
1087 recordset_AddRef( iface
);
1091 static HRESULT WINAPI
recordset_GetTypeInfoCount( _Recordset
*iface
, UINT
*count
)
1093 struct recordset
*recordset
= impl_from_Recordset( iface
);
1094 TRACE( "%p, %p\n", recordset
, count
);
1099 static HRESULT WINAPI
recordset_GetTypeInfo( _Recordset
*iface
, UINT index
, LCID lcid
, ITypeInfo
**info
)
1101 struct recordset
*recordset
= impl_from_Recordset( iface
);
1102 TRACE( "%p, %u, %lu, %p\n", recordset
, index
, lcid
, info
);
1103 return get_typeinfo(Recordset_tid
, info
);
1106 static HRESULT WINAPI
recordset_GetIDsOfNames( _Recordset
*iface
, REFIID riid
, LPOLESTR
*names
, UINT count
,
1107 LCID lcid
, DISPID
*dispid
)
1109 struct recordset
*recordset
= impl_from_Recordset( iface
);
1111 ITypeInfo
*typeinfo
;
1113 TRACE( "%p, %s, %p, %u, %lu, %p\n", recordset
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
1115 hr
= get_typeinfo(Recordset_tid
, &typeinfo
);
1118 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, count
, dispid
);
1119 ITypeInfo_Release(typeinfo
);
1125 static HRESULT WINAPI
recordset_Invoke( _Recordset
*iface
, DISPID member
, REFIID riid
, LCID lcid
, WORD flags
,
1126 DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excep_info
, UINT
*arg_err
)
1128 struct recordset
*recordset
= impl_from_Recordset( iface
);
1130 ITypeInfo
*typeinfo
;
1132 TRACE( "%p, %ld, %s, %ld, %d, %p, %p, %p, %p\n", recordset
, member
, debugstr_guid(riid
), lcid
, flags
, params
,
1133 result
, excep_info
, arg_err
);
1135 hr
= get_typeinfo(Recordset_tid
, &typeinfo
);
1138 hr
= ITypeInfo_Invoke(typeinfo
, &recordset
->Recordset_iface
, member
, flags
, params
,
1139 result
, excep_info
, arg_err
);
1140 ITypeInfo_Release(typeinfo
);
1146 static HRESULT WINAPI
recordset_get_Properties( _Recordset
*iface
, Properties
**obj
)
1148 FIXME( "%p, %p\n", iface
, obj
);
1152 static HRESULT WINAPI
recordset_get_AbsolutePosition( _Recordset
*iface
, PositionEnum_Param
*pos
)
1154 FIXME( "%p, %p\n", iface
, pos
);
1158 static HRESULT WINAPI
recordset_put_AbsolutePosition( _Recordset
*iface
, PositionEnum_Param pos
)
1160 FIXME( "%p, %Id\n", iface
, pos
);
1164 static HRESULT WINAPI
recordset_putref_ActiveConnection( _Recordset
*iface
, IDispatch
*connection
)
1166 FIXME( "%p, %p\n", iface
, connection
);
1170 static HRESULT WINAPI
recordset_put_ActiveConnection( _Recordset
*iface
, VARIANT connection
)
1172 FIXME( "%p, %s\n", iface
, debugstr_variant(&connection
) );
1176 static HRESULT WINAPI
recordset_get_ActiveConnection( _Recordset
*iface
, VARIANT
*connection
)
1178 FIXME( "%p, %p\n", iface
, connection
);
1182 static HRESULT WINAPI
recordset_get_BOF( _Recordset
*iface
, VARIANT_BOOL
*bof
)
1184 struct recordset
*recordset
= impl_from_Recordset( iface
);
1186 TRACE( "%p, %p\n", recordset
, bof
);
1188 *bof
= (recordset
->index
< 0) ? VARIANT_TRUE
: VARIANT_FALSE
;
1192 static HRESULT WINAPI
recordset_get_Bookmark( _Recordset
*iface
, VARIANT
*bookmark
)
1194 struct recordset
*recordset
= impl_from_Recordset( iface
);
1195 TRACE( "%p, %p\n", iface
, bookmark
);
1197 if (recordset
->state
== adStateClosed
) return MAKE_ADO_HRESULT( adErrObjectClosed
);
1198 if (recordset
->index
< 0) return MAKE_ADO_HRESULT( adErrNoCurrentRecord
);
1200 V_VT(bookmark
) = VT_I4
;
1201 V_I4(bookmark
) = recordset
->index
;
1205 static HRESULT WINAPI
recordset_put_Bookmark( _Recordset
*iface
, VARIANT bookmark
)
1207 struct recordset
*recordset
= impl_from_Recordset( iface
);
1208 TRACE( "%p, %s\n", iface
, debugstr_variant(&bookmark
) );
1210 if (recordset
->state
== adStateClosed
) return MAKE_ADO_HRESULT( adErrObjectClosed
);
1212 if (V_VT(&bookmark
) != VT_I4
) return MAKE_ADO_HRESULT( adErrInvalidArgument
);
1214 recordset
->index
= V_I4(&bookmark
);
1218 static HRESULT WINAPI
recordset_get_CacheSize( _Recordset
*iface
, LONG
*size
)
1220 FIXME( "%p, %p\n", iface
, size
);
1224 static HRESULT WINAPI
recordset_put_CacheSize( _Recordset
*iface
, LONG size
)
1226 FIXME( "%p, %ld\n", iface
, size
);
1230 static HRESULT WINAPI
recordset_get_CursorType( _Recordset
*iface
, CursorTypeEnum
*cursor_type
)
1232 struct recordset
*recordset
= impl_from_Recordset( iface
);
1234 TRACE( "%p, %p\n", iface
, cursor_type
);
1236 *cursor_type
= recordset
->cursor_type
;
1240 static HRESULT WINAPI
recordset_put_CursorType( _Recordset
*iface
, CursorTypeEnum cursor_type
)
1242 struct recordset
*recordset
= impl_from_Recordset( iface
);
1244 TRACE( "%p, %d\n", iface
, cursor_type
);
1246 recordset
->cursor_type
= cursor_type
;
1250 static HRESULT WINAPI
recordset_get_EOF( _Recordset
*iface
, VARIANT_BOOL
*eof
)
1252 struct recordset
*recordset
= impl_from_Recordset( iface
);
1254 TRACE( "%p, %p\n", recordset
, eof
);
1256 *eof
= (!recordset
->count
|| recordset
->index
>= recordset
->count
) ? VARIANT_TRUE
: VARIANT_FALSE
;
1260 static HRESULT WINAPI
recordset_get_Fields( _Recordset
*iface
, Fields
**obj
)
1262 struct recordset
*recordset
= impl_from_Recordset( iface
);
1265 TRACE( "%p, %p\n", recordset
, obj
);
1267 if (recordset
->fields
)
1269 /* yes, this adds a reference to the recordset instead of the fields object */
1270 _Recordset_AddRef( &recordset
->Recordset_iface
);
1271 recordset
->fields
->recordset
= recordset
;
1272 *obj
= &recordset
->fields
->Fields_iface
;
1276 if ((hr
= fields_create( recordset
, &recordset
->fields
)) != S_OK
) return hr
;
1278 *obj
= &recordset
->fields
->Fields_iface
;
1282 static HRESULT WINAPI
recordset_get_LockType( _Recordset
*iface
, LockTypeEnum
*lock_type
)
1284 FIXME( "%p, %p\n", iface
, lock_type
);
1288 static HRESULT WINAPI
recordset_put_LockType( _Recordset
*iface
, LockTypeEnum lock_type
)
1290 FIXME( "%p, %d\n", iface
, lock_type
);
1294 static HRESULT WINAPI
recordset_get_MaxRecords( _Recordset
*iface
, ADO_LONGPTR
*max_records
)
1296 FIXME( "%p, %p\n", iface
, max_records
);
1300 static HRESULT WINAPI
recordset_put_MaxRecords( _Recordset
*iface
, ADO_LONGPTR max_records
)
1302 FIXME( "%p, %Id\n", iface
, max_records
);
1306 static HRESULT WINAPI
recordset_get_RecordCount( _Recordset
*iface
, ADO_LONGPTR
*count
)
1308 struct recordset
*recordset
= impl_from_Recordset( iface
);
1310 TRACE( "%p, %p\n", recordset
, count
);
1312 *count
= recordset
->count
;
1316 static HRESULT WINAPI
recordset_putref_Source( _Recordset
*iface
, IDispatch
*source
)
1318 FIXME( "%p, %p\n", iface
, source
);
1322 static HRESULT WINAPI
recordset_put_Source( _Recordset
*iface
, BSTR source
)
1324 FIXME( "%p, %s\n", iface
, debugstr_w(source
) );
1328 static HRESULT WINAPI
recordset_get_Source( _Recordset
*iface
, VARIANT
*source
)
1330 FIXME( "%p, %p\n", iface
, source
);
1334 static BOOL
resize_recordset( struct recordset
*recordset
, ULONG row_count
)
1336 ULONG row_size
= get_column_count( recordset
) * sizeof(*recordset
->data
);
1338 if (row_count
> recordset
->allocated
)
1341 ULONG count
= max( row_count
, recordset
->allocated
* 2 );
1342 if (!(tmp
= realloc( recordset
->data
, count
* row_size
))) return FALSE
;
1343 memset( tmp
+ recordset
->allocated
, 0, (count
- recordset
->allocated
) * row_size
);
1344 recordset
->data
= tmp
;
1345 recordset
->allocated
= count
;
1348 recordset
->count
= row_count
;
1352 static HRESULT WINAPI
recordset_AddNew( _Recordset
*iface
, VARIANT field_list
, VARIANT values
)
1354 struct recordset
*recordset
= impl_from_Recordset( iface
);
1356 TRACE( "%p, %s, %s\n", recordset
, debugstr_variant(&field_list
), debugstr_variant(&values
) );
1357 FIXME( "ignoring field list and values\n" );
1359 if (recordset
->state
== adStateClosed
) return MAKE_ADO_HRESULT( adErrObjectClosed
);
1361 if (!resize_recordset( recordset
, recordset
->count
+ 1 )) return E_OUTOFMEMORY
;
1366 static HRESULT WINAPI
recordset_CancelUpdate( _Recordset
*iface
)
1368 FIXME( "%p\n", iface
);
1372 static HRESULT WINAPI
recordset_Close( _Recordset
*iface
)
1374 struct recordset
*recordset
= impl_from_Recordset( iface
);
1376 TRACE( "%p\n", recordset
);
1378 if (recordset
->state
== adStateClosed
) return MAKE_ADO_HRESULT( adErrObjectClosed
);
1380 close_recordset( recordset
);
1381 recordset
->state
= adStateClosed
;
1385 static HRESULT WINAPI
recordset_Delete( _Recordset
*iface
, AffectEnum affect_records
)
1387 FIXME( "%p, %u\n", iface
, affect_records
);
1391 static HRESULT WINAPI
recordset_GetRows( _Recordset
*iface
, LONG rows
, VARIANT start
, VARIANT fields
, VARIANT
*var
)
1393 FIXME( "%p, %ld, %s, %s, %p\n", iface
, rows
, debugstr_variant(&start
), debugstr_variant(&fields
), var
);
1397 static HRESULT WINAPI
recordset_Move( _Recordset
*iface
, ADO_LONGPTR num_records
, VARIANT start
)
1399 FIXME( "%p, %Id, %s\n", iface
, num_records
, debugstr_variant(&start
) );
1403 static HRESULT WINAPI
recordset_MoveNext( _Recordset
*iface
)
1405 struct recordset
*recordset
= impl_from_Recordset( iface
);
1407 TRACE( "%p\n", recordset
);
1409 if (recordset
->index
< recordset
->count
) recordset
->index
++;
1413 static HRESULT WINAPI
recordset_MovePrevious( _Recordset
*iface
)
1415 struct recordset
*recordset
= impl_from_Recordset( iface
);
1417 TRACE( "%p\n", recordset
);
1419 if (recordset
->index
>= 0) recordset
->index
--;
1423 static HRESULT WINAPI
recordset_MoveFirst( _Recordset
*iface
)
1425 struct recordset
*recordset
= impl_from_Recordset( iface
);
1427 TRACE( "%p\n", recordset
);
1429 recordset
->index
= 0;
1433 static HRESULT WINAPI
recordset_MoveLast( _Recordset
*iface
)
1435 struct recordset
*recordset
= impl_from_Recordset( iface
);
1437 TRACE( "%p\n", recordset
);
1439 recordset
->index
= (recordset
->count
> 0) ? recordset
->count
- 1 : 0;
1443 static HRESULT
create_command_text(IUnknown
*session
, BSTR command
, ICommandText
**cmd_text
)
1446 IOpenRowset
*openrowset
;
1447 ICommandText
*command_text
;
1449 IDBCreateCommand
*create_command
;
1451 hr
= IUnknown_QueryInterface(session
, &IID_IOpenRowset
, (void**)&openrowset
);
1455 hr
= IOpenRowset_QueryInterface(openrowset
, &IID_IDBCreateCommand
, (void**)&create_command
);
1456 IOpenRowset_Release(openrowset
);
1460 hr
= IDBCreateCommand_CreateCommand(create_command
, NULL
, &IID_IUnknown
, (IUnknown
**)&cmd
);
1461 IDBCreateCommand_Release(create_command
);
1465 hr
= ICommand_QueryInterface(cmd
, &IID_ICommandText
, (void**)&command_text
);
1466 ICommand_Release(cmd
);
1469 FIXME("Currently only ICommandText interface is support\n");
1473 hr
= ICommandText_SetCommandText(command_text
, &DBGUID_DEFAULT
, command
);
1476 ICommandText_Release(command_text
);
1480 *cmd_text
= command_text
;
1485 static HRESULT WINAPI
recordset_Open( _Recordset
*iface
, VARIANT source
, VARIANT active_connection
,
1486 CursorTypeEnum cursor_type
, LockTypeEnum lock_type
, LONG options
)
1488 struct recordset
*recordset
= impl_from_Recordset( iface
);
1489 ADOConnectionConstruction15
*construct
;
1491 ICommandText
*command_text
;
1492 DBROWCOUNT affected
;
1496 FIXME( "%p, %s, %s, %d, %d, %ld Semi-stub\n", recordset
, debugstr_variant(&source
), debugstr_variant(&active_connection
),
1497 cursor_type
, lock_type
, options
);
1499 if (recordset
->state
== adStateOpen
) return MAKE_ADO_HRESULT( adErrObjectOpen
);
1501 if (recordset
->fields
)
1503 recordset
->state
= adStateOpen
;
1507 if (V_VT(&active_connection
) != VT_DISPATCH
)
1509 FIXME("Unsupported Active connection type %d\n", V_VT(&active_connection
));
1510 return MAKE_ADO_HRESULT( adErrInvalidConnection
);
1513 hr
= IDispatch_QueryInterface(V_DISPATCH(&active_connection
), &IID_ADOConnectionConstruction15
, (void**)&construct
);
1517 hr
= ADOConnectionConstruction15_get_Session(construct
, &session
);
1518 ADOConnectionConstruction15_Release(construct
);
1522 if (V_VT(&source
) != VT_BSTR
)
1524 FIXME("Unsupported source type!\n");
1525 IUnknown_Release(session
);
1529 hr
= create_command_text(session
, V_BSTR(&source
), &command_text
);
1530 IUnknown_Release(session
);
1534 hr
= ICommandText_Execute(command_text
, NULL
, &IID_IUnknown
, NULL
, &affected
, &rowset
);
1535 ICommandText_Release(command_text
);
1536 if (FAILED(hr
) || !rowset
)
1539 ADORecordsetConstruction_put_Rowset(&recordset
->ADORecordsetConstruction_iface
, rowset
);
1540 recordset
->cursor_type
= cursor_type
;
1541 recordset
->state
= adStateOpen
;
1543 IUnknown_Release(rowset
);
1548 static HRESULT WINAPI
recordset_Requery( _Recordset
*iface
, LONG options
)
1550 FIXME( "%p, %ld\n", iface
, options
);
1554 static HRESULT WINAPI
recordset__xResync( _Recordset
*iface
, AffectEnum affect_records
)
1556 FIXME( "%p, %u\n", iface
, affect_records
);
1560 static HRESULT WINAPI
recordset_Update( _Recordset
*iface
, VARIANT fields
, VARIANT values
)
1562 FIXME( "%p, %s, %s\n", iface
, debugstr_variant(&fields
), debugstr_variant(&values
) );
1566 static HRESULT WINAPI
recordset_get_AbsolutePage( _Recordset
*iface
, PositionEnum_Param
*pos
)
1568 FIXME( "%p, %p\n", iface
, pos
);
1572 static HRESULT WINAPI
recordset_put_AbsolutePage( _Recordset
*iface
, PositionEnum_Param pos
)
1574 FIXME( "%p, %Id\n", iface
, pos
);
1578 static HRESULT WINAPI
recordset_get_EditMode( _Recordset
*iface
, EditModeEnum
*mode
)
1580 struct recordset
*recordset
= impl_from_Recordset( iface
);
1581 TRACE( "%p, %p\n", iface
, mode
);
1583 if (recordset
->state
== adStateClosed
) return MAKE_ADO_HRESULT( adErrObjectClosed
);
1584 if (recordset
->index
< 0) return MAKE_ADO_HRESULT( adErrNoCurrentRecord
);
1586 *mode
= recordset
->editmode
;
1590 static HRESULT WINAPI
recordset_get_Filter( _Recordset
*iface
, VARIANT
*criteria
)
1592 struct recordset
*recordset
= impl_from_Recordset( iface
);
1593 TRACE( "%p, %p\n", iface
, criteria
);
1595 if (!criteria
) return MAKE_ADO_HRESULT( adErrInvalidArgument
);
1597 VariantCopy(criteria
, &recordset
->filter
);
1601 static HRESULT WINAPI
recordset_put_Filter( _Recordset
*iface
, VARIANT criteria
)
1603 struct recordset
*recordset
= impl_from_Recordset( iface
);
1604 TRACE( "%p, %s\n", recordset
, debugstr_variant(&criteria
) );
1606 if (V_VT(&criteria
) != VT_I2
&& V_VT(&criteria
) != VT_I4
&& V_VT(&criteria
) != VT_BSTR
)
1607 return MAKE_ADO_HRESULT( adErrInvalidArgument
);
1609 if (V_VT(&criteria
) == VT_BSTR
&& recordset
->state
== adStateOpen
)
1611 FIXME("Validating fields not preformed\n");
1614 VariantCopy(&recordset
->filter
, &criteria
);
1618 static HRESULT WINAPI
recordset_get_PageCount( _Recordset
*iface
, ADO_LONGPTR
*count
)
1620 FIXME( "%p, %p\n", iface
, count
);
1624 static HRESULT WINAPI
recordset_get_PageSize( _Recordset
*iface
, LONG
*size
)
1626 FIXME( "%p, %p\n", iface
, size
);
1630 static HRESULT WINAPI
recordset_put_PageSize( _Recordset
*iface
, LONG size
)
1632 FIXME( "%p, %ld\n", iface
, size
);
1636 static HRESULT WINAPI
recordset_get_Sort( _Recordset
*iface
, BSTR
*criteria
)
1638 FIXME( "%p, %p\n", iface
, criteria
);
1642 static HRESULT WINAPI
recordset_put_Sort( _Recordset
*iface
, BSTR criteria
)
1644 FIXME( "%p, %s\n", iface
, debugstr_w(criteria
) );
1648 static HRESULT WINAPI
recordset_get_Status( _Recordset
*iface
, LONG
*status
)
1650 FIXME( "%p, %p\n", iface
, status
);
1654 static HRESULT WINAPI
recordset_get_State( _Recordset
*iface
, LONG
*state
)
1656 struct recordset
*recordset
= impl_from_Recordset( iface
);
1658 TRACE( "%p, %p\n", recordset
, state
);
1660 *state
= recordset
->state
;
1664 static HRESULT WINAPI
recordset__xClone( _Recordset
*iface
, _Recordset
**obj
)
1666 FIXME( "%p, %p\n", iface
, obj
);
1670 static HRESULT WINAPI
recordset_UpdateBatch( _Recordset
*iface
, AffectEnum affect_records
)
1672 FIXME( "%p, %u\n", iface
, affect_records
);
1676 static HRESULT WINAPI
recordset_CancelBatch( _Recordset
*iface
, AffectEnum affect_records
)
1678 FIXME( "%p, %u\n", iface
, affect_records
);
1682 static HRESULT WINAPI
recordset_get_CursorLocation( _Recordset
*iface
, CursorLocationEnum
*cursor_loc
)
1684 struct recordset
*recordset
= impl_from_Recordset( iface
);
1686 TRACE( "%p, %p\n", iface
, cursor_loc
);
1688 *cursor_loc
= recordset
->cursor_location
;
1693 static HRESULT WINAPI
recordset_put_CursorLocation( _Recordset
*iface
, CursorLocationEnum cursor_loc
)
1695 struct recordset
*recordset
= impl_from_Recordset( iface
);
1697 TRACE( "%p, %u\n", iface
, cursor_loc
);
1699 if (recordset
->state
== adStateOpen
) return MAKE_ADO_HRESULT( adErrObjectOpen
);
1701 recordset
->cursor_location
= cursor_loc
;
1706 static HRESULT WINAPI
recordset_NextRecordset( _Recordset
*iface
, VARIANT
*records_affected
, _Recordset
**record_set
)
1708 FIXME( "%p, %p, %p\n", iface
, records_affected
, record_set
);
1712 static HRESULT WINAPI
recordset_Supports( _Recordset
*iface
, CursorOptionEnum cursor_options
, VARIANT_BOOL
*ret
)
1714 FIXME( "%p, %08x, %p\n", iface
, cursor_options
, ret
);
1718 static HRESULT WINAPI
recordset_get_Collect( _Recordset
*iface
, VARIANT index
, VARIANT
*var
)
1720 FIXME( "%p, %s, %p\n", iface
, debugstr_variant(&index
), var
);
1724 static HRESULT WINAPI
recordset_put_Collect( _Recordset
*iface
, VARIANT index
, VARIANT var
)
1726 FIXME( "%p, %s, %s\n", iface
, debugstr_variant(&index
), debugstr_variant(&var
) );
1730 static HRESULT WINAPI
recordset_get_MarshalOptions( _Recordset
*iface
, MarshalOptionsEnum
*options
)
1732 FIXME( "%p, %p\n", iface
, options
);
1736 static HRESULT WINAPI
recordset_put_MarshalOptions( _Recordset
*iface
, MarshalOptionsEnum options
)
1738 FIXME( "%p, %u\n", iface
, options
);
1742 static HRESULT WINAPI
recordset_Find( _Recordset
*iface
, BSTR criteria
, LONG skip_records
,
1743 SearchDirectionEnum search_direction
, VARIANT start
)
1745 FIXME( "%p, %s, %ld, %d, %s\n", iface
, debugstr_w(criteria
), skip_records
, search_direction
,
1746 debugstr_variant(&start
) );
1750 static HRESULT WINAPI
recordset_Cancel( _Recordset
*iface
)
1752 FIXME( "%p\n", iface
);
1756 static HRESULT WINAPI
recordset_get_DataSource( _Recordset
*iface
, IUnknown
**data_source
)
1758 FIXME( "%p, %p\n", iface
, data_source
);
1762 static HRESULT WINAPI
recordset_putref_DataSource( _Recordset
*iface
, IUnknown
*data_source
)
1764 FIXME( "%p, %p\n", iface
, data_source
);
1768 static HRESULT WINAPI
recordset__xSave( _Recordset
*iface
, BSTR filename
, PersistFormatEnum persist_format
)
1770 FIXME( "%p, %s, %u\n", iface
, debugstr_w(filename
), persist_format
);
1774 static HRESULT WINAPI
recordset_get_ActiveCommand( _Recordset
*iface
, IDispatch
**cmd
)
1776 FIXME( "%p, %p\n", iface
, cmd
);
1780 static HRESULT WINAPI
recordset_put_StayInSync( _Recordset
*iface
, VARIANT_BOOL stay_in_sync
)
1782 FIXME( "%p, %d\n", iface
, stay_in_sync
);
1786 static HRESULT WINAPI
recordset_get_StayInSync( _Recordset
*iface
, VARIANT_BOOL
*stay_in_sync
)
1788 FIXME( "%p, %p\n", iface
, stay_in_sync
);
1792 static HRESULT WINAPI
recordset_GetString( _Recordset
*iface
, StringFormatEnum string_format
, LONG num_rows
,
1793 BSTR column_delimiter
, BSTR row_delimiter
, BSTR null_expr
,
1796 FIXME( "%p, %u, %ld, %s, %s, %s, %p\n", iface
, string_format
, num_rows
, debugstr_w(column_delimiter
),
1797 debugstr_w(row_delimiter
), debugstr_w(null_expr
), ret_string
);
1801 static HRESULT WINAPI
recordset_get_DataMember( _Recordset
*iface
, BSTR
*data_member
)
1803 FIXME( "%p, %p\n", iface
, data_member
);
1807 static HRESULT WINAPI
recordset_put_DataMember( _Recordset
*iface
, BSTR data_member
)
1809 FIXME( "%p, %s\n", iface
, debugstr_w(data_member
) );
1813 static HRESULT WINAPI
recordset_CompareBookmarks( _Recordset
*iface
, VARIANT bookmark1
, VARIANT bookmark2
, CompareEnum
*compare
)
1815 FIXME( "%p, %s, %s, %p\n", iface
, debugstr_variant(&bookmark1
), debugstr_variant(&bookmark2
), compare
);
1819 static HRESULT WINAPI
recordset_Clone( _Recordset
*iface
, LockTypeEnum lock_type
, _Recordset
**obj
)
1821 struct recordset
*recordset
= impl_from_Recordset( iface
);
1822 FIXME( "%p, %d, %p\n", recordset
, lock_type
, obj
);
1825 recordset_AddRef( iface
);
1829 static HRESULT WINAPI
recordset_Resync( _Recordset
*iface
, AffectEnum affect_records
, ResyncEnum resync_values
)
1831 FIXME( "%p, %u, %u\n", iface
, affect_records
, resync_values
);
1835 static HRESULT WINAPI
recordset_Seek( _Recordset
*iface
, VARIANT key_values
, SeekEnum seek_option
)
1837 FIXME( "%p, %s, %u\n", iface
, debugstr_variant(&key_values
), seek_option
);
1841 static HRESULT WINAPI
recordset_put_Index( _Recordset
*iface
, BSTR index
)
1843 FIXME( "%p, %s\n", iface
, debugstr_w(index
) );
1847 static HRESULT WINAPI
recordset_get_Index( _Recordset
*iface
, BSTR
*index
)
1849 FIXME( "%p, %p\n", iface
, index
);
1853 static HRESULT WINAPI
recordset_Save( _Recordset
*iface
, VARIANT destination
, PersistFormatEnum persist_format
)
1855 FIXME( "%p, %s, %u\n", iface
, debugstr_variant(&destination
), persist_format
);
1859 static const struct _RecordsetVtbl recordset_vtbl
=
1861 recordset_QueryInterface
,
1864 recordset_GetTypeInfoCount
,
1865 recordset_GetTypeInfo
,
1866 recordset_GetIDsOfNames
,
1868 recordset_get_Properties
,
1869 recordset_get_AbsolutePosition
,
1870 recordset_put_AbsolutePosition
,
1871 recordset_putref_ActiveConnection
,
1872 recordset_put_ActiveConnection
,
1873 recordset_get_ActiveConnection
,
1875 recordset_get_Bookmark
,
1876 recordset_put_Bookmark
,
1877 recordset_get_CacheSize
,
1878 recordset_put_CacheSize
,
1879 recordset_get_CursorType
,
1880 recordset_put_CursorType
,
1882 recordset_get_Fields
,
1883 recordset_get_LockType
,
1884 recordset_put_LockType
,
1885 recordset_get_MaxRecords
,
1886 recordset_put_MaxRecords
,
1887 recordset_get_RecordCount
,
1888 recordset_putref_Source
,
1889 recordset_put_Source
,
1890 recordset_get_Source
,
1892 recordset_CancelUpdate
,
1898 recordset_MovePrevious
,
1899 recordset_MoveFirst
,
1905 recordset_get_AbsolutePage
,
1906 recordset_put_AbsolutePage
,
1907 recordset_get_EditMode
,
1908 recordset_get_Filter
,
1909 recordset_put_Filter
,
1910 recordset_get_PageCount
,
1911 recordset_get_PageSize
,
1912 recordset_put_PageSize
,
1915 recordset_get_Status
,
1916 recordset_get_State
,
1918 recordset_UpdateBatch
,
1919 recordset_CancelBatch
,
1920 recordset_get_CursorLocation
,
1921 recordset_put_CursorLocation
,
1922 recordset_NextRecordset
,
1924 recordset_get_Collect
,
1925 recordset_put_Collect
,
1926 recordset_get_MarshalOptions
,
1927 recordset_put_MarshalOptions
,
1930 recordset_get_DataSource
,
1931 recordset_putref_DataSource
,
1933 recordset_get_ActiveCommand
,
1934 recordset_put_StayInSync
,
1935 recordset_get_StayInSync
,
1936 recordset_GetString
,
1937 recordset_get_DataMember
,
1938 recordset_put_DataMember
,
1939 recordset_CompareBookmarks
,
1943 recordset_put_Index
,
1944 recordset_get_Index
,
1948 static inline struct recordset
*recordset_from_ISupportErrorInfo( ISupportErrorInfo
*iface
)
1950 return CONTAINING_RECORD( iface
, struct recordset
, ISupportErrorInfo_iface
);
1953 static HRESULT WINAPI
recordset_supporterrorinfo_QueryInterface( ISupportErrorInfo
*iface
, REFIID riid
, void **obj
)
1955 struct recordset
*recordset
= recordset_from_ISupportErrorInfo( iface
);
1956 return _Recordset_QueryInterface( &recordset
->Recordset_iface
, riid
, obj
);
1959 static ULONG WINAPI
recordset_supporterrorinfo_AddRef( ISupportErrorInfo
*iface
)
1961 struct recordset
*recordset
= recordset_from_ISupportErrorInfo( iface
);
1962 return _Recordset_AddRef( &recordset
->Recordset_iface
);
1965 static ULONG WINAPI
recordset_supporterrorinfo_Release( ISupportErrorInfo
*iface
)
1967 struct recordset
*recordset
= recordset_from_ISupportErrorInfo( iface
);
1968 return _Recordset_Release( &recordset
->Recordset_iface
);
1971 static HRESULT WINAPI
recordset_supporterrorinfo_InterfaceSupportsErrorInfo( ISupportErrorInfo
*iface
, REFIID riid
)
1973 struct recordset
*recordset
= recordset_from_ISupportErrorInfo( iface
);
1974 FIXME( "%p, %s\n", recordset
, debugstr_guid(riid
) );
1978 static const ISupportErrorInfoVtbl recordset_supporterrorinfo_vtbl
=
1980 recordset_supporterrorinfo_QueryInterface
,
1981 recordset_supporterrorinfo_AddRef
,
1982 recordset_supporterrorinfo_Release
,
1983 recordset_supporterrorinfo_InterfaceSupportsErrorInfo
1986 static HRESULT WINAPI
rsconstruction_QueryInterface(ADORecordsetConstruction
*iface
,
1987 REFIID riid
, void **obj
)
1989 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1990 return _Recordset_QueryInterface( &recordset
->Recordset_iface
, riid
, obj
);
1993 static ULONG WINAPI
rsconstruction_AddRef(ADORecordsetConstruction
*iface
)
1995 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1996 return _Recordset_AddRef( &recordset
->Recordset_iface
);
1999 static ULONG WINAPI
rsconstruction_Release(ADORecordsetConstruction
*iface
)
2001 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
2002 return _Recordset_Release( &recordset
->Recordset_iface
);
2005 static HRESULT WINAPI
rsconstruction_GetTypeInfoCount(ADORecordsetConstruction
*iface
, UINT
*pctinfo
)
2007 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
2008 TRACE( "%p, %p\n", recordset
, pctinfo
);
2013 static HRESULT WINAPI
rsconstruction_GetTypeInfo(ADORecordsetConstruction
*iface
, UINT iTInfo
,
2014 LCID lcid
, ITypeInfo
**ppTInfo
)
2016 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
2017 TRACE( "%p %u %lu %p\n", recordset
, iTInfo
, lcid
, ppTInfo
);
2018 return get_typeinfo(ADORecordsetConstruction_tid
, ppTInfo
);
2021 static HRESULT WINAPI
rsconstruction_GetIDsOfNames(ADORecordsetConstruction
*iface
, REFIID riid
,
2022 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
2024 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
2026 ITypeInfo
*typeinfo
;
2028 TRACE( "%p %s %p %u %lu %p\n", recordset
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
2030 hr
= get_typeinfo(ADORecordsetConstruction_tid
, &typeinfo
);
2033 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
2034 ITypeInfo_Release(typeinfo
);
2040 static HRESULT WINAPI
rsconstruction_Invoke(ADORecordsetConstruction
*iface
, DISPID dispIdMember
,
2041 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
2042 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
2044 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
2046 ITypeInfo
*typeinfo
;
2048 TRACE( "%p %ld %s %ld %d %p %p %p %p\n", recordset
, dispIdMember
, debugstr_guid(riid
),
2049 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2051 hr
= get_typeinfo(ADORecordsetConstruction_tid
, &typeinfo
);
2054 hr
= ITypeInfo_Invoke(typeinfo
, &recordset
->ADORecordsetConstruction_iface
, dispIdMember
, wFlags
,
2055 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
2056 ITypeInfo_Release(typeinfo
);
2062 static HRESULT WINAPI
rsconstruction_get_Rowset(ADORecordsetConstruction
*iface
, IUnknown
**row_set
)
2064 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
2067 TRACE( "%p, %p\n", recordset
, row_set
);
2069 hr
= IRowset_QueryInterface(recordset
->row_set
, &IID_IUnknown
, (void**)row_set
);
2070 if ( FAILED(hr
) ) return E_FAIL
;
2075 static HRESULT WINAPI
rsconstruction_put_Rowset(ADORecordsetConstruction
*iface
, IUnknown
*unk
)
2077 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
2081 TRACE( "%p, %p\n", recordset
, unk
);
2083 hr
= IUnknown_QueryInterface(unk
, &IID_IRowset
, (void**)&rowset
);
2084 if ( FAILED(hr
) ) return E_FAIL
;
2086 if ( recordset
->row_set
) IRowset_Release( recordset
->row_set
);
2087 recordset
->row_set
= rowset
;
2092 static HRESULT WINAPI
rsconstruction_get_Chapter(ADORecordsetConstruction
*iface
, ADO_LONGPTR
*chapter
)
2094 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
2095 FIXME( "%p, %p\n", recordset
, chapter
);
2099 static HRESULT WINAPI
rsconstruction_put_Chapter(ADORecordsetConstruction
*iface
, ADO_LONGPTR chapter
)
2101 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
2102 FIXME( "%p, %Id\n", recordset
, chapter
);
2106 static HRESULT WINAPI
rsconstruction_get_RowPosition(ADORecordsetConstruction
*iface
, IUnknown
**row_pos
)
2108 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
2109 FIXME( "%p, %p\n", recordset
, row_pos
);
2113 static HRESULT WINAPI
rsconstruction_put_RowPosition(ADORecordsetConstruction
*iface
, IUnknown
*row_pos
)
2115 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
2116 FIXME( "%p, %p\n", recordset
, row_pos
);
2120 static const ADORecordsetConstructionVtbl rsconstruction_vtbl
=
2122 rsconstruction_QueryInterface
,
2123 rsconstruction_AddRef
,
2124 rsconstruction_Release
,
2125 rsconstruction_GetTypeInfoCount
,
2126 rsconstruction_GetTypeInfo
,
2127 rsconstruction_GetIDsOfNames
,
2128 rsconstruction_Invoke
,
2129 rsconstruction_get_Rowset
,
2130 rsconstruction_put_Rowset
,
2131 rsconstruction_get_Chapter
,
2132 rsconstruction_put_Chapter
,
2133 rsconstruction_get_RowPosition
,
2134 rsconstruction_put_RowPosition
2137 HRESULT
Recordset_create( void **obj
)
2139 struct recordset
*recordset
;
2141 if (!(recordset
= calloc( 1, sizeof(*recordset
) ))) return E_OUTOFMEMORY
;
2142 recordset
->Recordset_iface
.lpVtbl
= &recordset_vtbl
;
2143 recordset
->ISupportErrorInfo_iface
.lpVtbl
= &recordset_supporterrorinfo_vtbl
;
2144 recordset
->ADORecordsetConstruction_iface
.lpVtbl
= &rsconstruction_vtbl
;
2145 recordset
->refs
= 1;
2146 recordset
->index
= -1;
2147 recordset
->cursor_location
= adUseServer
;
2148 recordset
->cursor_type
= adOpenForwardOnly
;
2149 recordset
->row_set
= NULL
;
2150 recordset
->editmode
= adEditNone
;
2151 VariantInit( &recordset
->filter
);
2153 *obj
= &recordset
->Recordset_iface
;
2154 TRACE( "returning iface %p\n", *obj
);