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"
29 #include "wine/heap.h"
31 #include "msado15_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(msado15
);
38 _Recordset Recordset_iface
;
39 ADORecordsetConstruction ADORecordsetConstruction_iface
;
40 ISupportErrorInfo ISupportErrorInfo_iface
;
43 struct fields
*fields
;
48 CursorLocationEnum cursor_location
;
49 CursorTypeEnum cursor_type
;
56 ISupportErrorInfo ISupportErrorInfo_iface
;
61 struct recordset
*recordset
;
67 ISupportErrorInfo ISupportErrorInfo_iface
;
74 struct recordset
*recordset
;
77 static inline struct field
*impl_from_Field( Field
*iface
)
79 return CONTAINING_RECORD( iface
, struct field
, Field_iface
);
82 static ULONG WINAPI
field_AddRef( Field
*iface
)
84 struct field
*field
= impl_from_Field( iface
);
85 LONG refs
= InterlockedIncrement( &field
->refs
);
86 TRACE( "%p new refcount %d\n", field
, refs
);
90 static ULONG WINAPI
field_Release( Field
*iface
)
92 struct field
*field
= impl_from_Field( iface
);
93 LONG refs
= InterlockedDecrement( &field
->refs
);
94 TRACE( "%p new refcount %d\n", field
, refs
);
97 TRACE( "destroying %p\n", field
);
98 heap_free( field
->name
);
104 static HRESULT WINAPI
field_QueryInterface( Field
*iface
, REFIID riid
, void **obj
)
106 struct field
*field
= impl_from_Field( iface
);
107 TRACE( "%p, %s, %p\n", iface
, debugstr_guid(riid
), obj
);
109 if (IsEqualGUID( riid
, &IID_Field
) || IsEqualGUID( riid
, &IID_IDispatch
) ||
110 IsEqualGUID( riid
, &IID_IUnknown
))
114 else if (IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
116 *obj
= &field
->ISupportErrorInfo_iface
;
120 FIXME( "interface %s not implemented\n", debugstr_guid(riid
) );
121 return E_NOINTERFACE
;
123 field_AddRef( iface
);
127 static HRESULT WINAPI
field_GetTypeInfoCount( Field
*iface
, UINT
*count
)
129 struct field
*field
= impl_from_Field( iface
);
130 TRACE( "%p, %p\n", field
, count
);
135 static HRESULT WINAPI
field_GetTypeInfo( Field
*iface
, UINT index
, LCID lcid
, ITypeInfo
**info
)
137 struct field
*field
= impl_from_Field( iface
);
138 TRACE( "%p, %u, %u, %p\n", field
, index
, lcid
, info
);
139 return get_typeinfo(Field_tid
, info
);
142 static HRESULT WINAPI
field_GetIDsOfNames( Field
*iface
, REFIID riid
, LPOLESTR
*names
, UINT count
,
143 LCID lcid
, DISPID
*dispid
)
145 struct field
*field
= impl_from_Field( iface
);
149 TRACE( "%p, %s, %p, %u, %u, %p\n", field
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
151 hr
= get_typeinfo(Field_tid
, &typeinfo
);
154 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, count
, dispid
);
155 ITypeInfo_Release(typeinfo
);
161 static HRESULT WINAPI
field_Invoke( Field
*iface
, DISPID member
, REFIID riid
, LCID lcid
, WORD flags
,
162 DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excep_info
, UINT
*arg_err
)
164 struct field
*field
= impl_from_Field( iface
);
168 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", field
, member
, debugstr_guid(riid
), lcid
, flags
, params
,
169 result
, excep_info
, arg_err
);
171 hr
= get_typeinfo(Field_tid
, &typeinfo
);
174 hr
= ITypeInfo_Invoke(typeinfo
, &field
->Field_iface
, member
, flags
, params
,
175 result
, excep_info
, arg_err
);
176 ITypeInfo_Release(typeinfo
);
182 static HRESULT WINAPI
field_get_Properties( Field
*iface
, Properties
**obj
)
184 FIXME( "%p, %p\n", iface
, obj
);
188 static HRESULT WINAPI
field_get_ActualSize( Field
*iface
, LONG
*size
)
190 FIXME( "%p, %p\n", iface
, size
);
194 static HRESULT WINAPI
field_get_Attributes( Field
*iface
, LONG
*attrs
)
196 struct field
*field
= impl_from_Field( iface
);
198 TRACE( "%p, %p\n", field
, attrs
);
200 *attrs
= field
->attrs
;
204 static HRESULT WINAPI
field_get_DefinedSize( Field
*iface
, LONG
*size
)
206 struct field
*field
= impl_from_Field( iface
);
208 TRACE( "%p, %p\n", field
, size
);
210 *size
= field
->defined_size
;
214 static HRESULT WINAPI
field_get_Name( Field
*iface
, BSTR
*str
)
216 struct field
*field
= impl_from_Field( iface
);
219 TRACE( "%p, %p\n", field
, str
);
221 if (!(name
= SysAllocString( field
->name
))) return E_OUTOFMEMORY
;
226 static HRESULT WINAPI
field_get_Type( Field
*iface
, DataTypeEnum
*type
)
228 struct field
*field
= impl_from_Field( iface
);
230 TRACE( "%p, %p\n", field
, type
);
236 static LONG
get_column_count( struct recordset
*recordset
)
238 return recordset
->fields
->count
;
241 static HRESULT WINAPI
field_get_Value( Field
*iface
, VARIANT
*val
)
243 struct field
*field
= impl_from_Field( iface
);
244 ULONG row
= field
->recordset
->index
, col
= field
->index
, col_count
;
248 TRACE( "%p, %p\n", field
, val
);
250 if (field
->recordset
->state
== adStateClosed
) return MAKE_ADO_HRESULT( adErrObjectClosed
);
251 if (field
->recordset
->index
< 0) return MAKE_ADO_HRESULT( adErrNoCurrentRecord
);
253 col_count
= get_column_count( field
->recordset
);
255 VariantInit( ©
);
256 if ((hr
= VariantCopy( ©
, &field
->recordset
->data
[row
* col_count
+ col
] )) != S_OK
) return hr
;
262 static HRESULT WINAPI
field_put_Value( Field
*iface
, VARIANT val
)
264 struct field
*field
= impl_from_Field( iface
);
265 ULONG row
= field
->recordset
->index
, col
= field
->index
, col_count
;
269 TRACE( "%p, %s\n", field
, debugstr_variant(&val
) );
271 if (field
->recordset
->state
== adStateClosed
) return MAKE_ADO_HRESULT( adErrObjectClosed
);
272 if (field
->recordset
->index
< 0) return MAKE_ADO_HRESULT( adErrNoCurrentRecord
);
274 col_count
= get_column_count( field
->recordset
);
276 VariantInit( ©
);
277 if ((hr
= VariantCopy( ©
, &val
)) != S_OK
) return hr
;
279 field
->recordset
->data
[row
* col_count
+ col
] = copy
;
283 static HRESULT WINAPI
field_get_Precision( Field
*iface
, unsigned char *precision
)
285 FIXME( "%p, %p\n", iface
, precision
);
289 static HRESULT WINAPI
field_get_NumericScale( Field
*iface
, unsigned char *scale
)
291 FIXME( "%p, %p\n", iface
, scale
);
295 static HRESULT WINAPI
field_AppendChunk( Field
*iface
, VARIANT data
)
297 FIXME( "%p, %s\n", iface
, debugstr_variant(&data
) );
301 static HRESULT WINAPI
field_GetChunk( Field
*iface
, LONG length
, VARIANT
*var
)
303 FIXME( "%p, %d, %p\n", iface
, length
, var
);
307 static HRESULT WINAPI
field_get_OriginalValue( Field
*iface
, VARIANT
*val
)
309 FIXME( "%p, %p\n", iface
, val
);
313 static HRESULT WINAPI
field_get_UnderlyingValue( Field
*iface
, VARIANT
*val
)
315 FIXME( "%p, %p\n", iface
, val
);
319 static HRESULT WINAPI
field_get_DataFormat( Field
*iface
, IUnknown
**format
)
321 FIXME( "%p, %p\n", iface
, format
);
325 static HRESULT WINAPI
field_putref_DataFormat( Field
*iface
, IUnknown
*format
)
327 FIXME( "%p, %p\n", iface
, format
);
331 static HRESULT WINAPI
field_put_Precision( Field
*iface
, unsigned char precision
)
333 FIXME( "%p, %c\n", iface
, precision
);
337 static HRESULT WINAPI
field_put_NumericScale( Field
*iface
, unsigned char scale
)
339 FIXME( "%p, %c\n", iface
, scale
);
343 static HRESULT WINAPI
field_put_Type( Field
*iface
, DataTypeEnum type
)
345 struct field
*field
= impl_from_Field( iface
);
347 TRACE( "%p, %u\n", field
, type
);
353 static HRESULT WINAPI
field_put_DefinedSize( Field
*iface
, LONG size
)
355 struct field
*field
= impl_from_Field( iface
);
357 TRACE( "%p, %d\n", field
, size
);
359 field
->defined_size
= size
;
363 static HRESULT WINAPI
field_put_Attributes( Field
*iface
, LONG attrs
)
365 struct field
*field
= impl_from_Field( iface
);
367 TRACE( "%p, %d\n", field
, attrs
);
369 field
->attrs
= attrs
;
373 static HRESULT WINAPI
field_get_Status( Field
*iface
, LONG
*status
)
375 FIXME( "%p, %p\n", iface
, status
);
379 static const struct FieldVtbl field_vtbl
=
381 field_QueryInterface
,
384 field_GetTypeInfoCount
,
388 field_get_Properties
,
389 field_get_ActualSize
,
390 field_get_Attributes
,
391 field_get_DefinedSize
,
397 field_get_NumericScale
,
400 field_get_OriginalValue
,
401 field_get_UnderlyingValue
,
402 field_get_DataFormat
,
403 field_putref_DataFormat
,
405 field_put_NumericScale
,
407 field_put_DefinedSize
,
408 field_put_Attributes
,
412 static inline struct field
*field_from_ISupportErrorInfo( ISupportErrorInfo
*iface
)
414 return CONTAINING_RECORD( iface
, struct field
, ISupportErrorInfo_iface
);
417 static HRESULT WINAPI
field_supporterrorinfo_QueryInterface( ISupportErrorInfo
*iface
, REFIID riid
, void **obj
)
419 struct field
*field
= field_from_ISupportErrorInfo( iface
);
420 return Field_QueryInterface( &field
->Field_iface
, riid
, obj
);
423 static ULONG WINAPI
field_supporterrorinfo_AddRef( ISupportErrorInfo
*iface
)
425 struct field
*field
= field_from_ISupportErrorInfo( iface
);
426 return Field_AddRef( &field
->Field_iface
);
429 static ULONG WINAPI
field_supporterrorinfo_Release( ISupportErrorInfo
*iface
)
431 struct field
*field
= field_from_ISupportErrorInfo( iface
);
432 return Field_Release( &field
->Field_iface
);
435 static HRESULT WINAPI
field_supporterrorinfo_InterfaceSupportsErrorInfo( ISupportErrorInfo
*iface
, REFIID riid
)
437 struct field
*field
= field_from_ISupportErrorInfo( iface
);
438 FIXME( "%p, %s\n", field
, debugstr_guid(riid
) );
442 static const ISupportErrorInfoVtbl field_supporterrorinfo_vtbl
=
444 field_supporterrorinfo_QueryInterface
,
445 field_supporterrorinfo_AddRef
,
446 field_supporterrorinfo_Release
,
447 field_supporterrorinfo_InterfaceSupportsErrorInfo
450 static HRESULT
Field_create( const WCHAR
*name
, LONG index
, struct recordset
*recordset
, Field
**obj
)
454 if (!(field
= heap_alloc_zero( sizeof(*field
) ))) return E_OUTOFMEMORY
;
455 field
->Field_iface
.lpVtbl
= &field_vtbl
;
456 field
->ISupportErrorInfo_iface
.lpVtbl
= &field_supporterrorinfo_vtbl
;
457 if (!(field
->name
= strdupW( name
)))
460 return E_OUTOFMEMORY
;
462 field
->index
= index
;
463 field
->recordset
= recordset
;
465 *obj
= &field
->Field_iface
;
466 TRACE( "returning iface %p\n", *obj
);
470 static inline struct fields
*impl_from_Fields( Fields
*iface
)
472 return CONTAINING_RECORD( iface
, struct fields
, Fields_iface
);
475 static ULONG WINAPI
fields_AddRef( Fields
*iface
)
477 struct fields
*fields
= impl_from_Fields( iface
);
478 LONG refs
= InterlockedIncrement( &fields
->refs
);
479 TRACE( "%p new refcount %d\n", fields
, refs
);
483 static ULONG WINAPI
fields_Release( Fields
*iface
)
485 struct fields
*fields
= impl_from_Fields( iface
);
486 LONG refs
= InterlockedDecrement( &fields
->refs
);
487 TRACE( "%p new refcount %d\n", fields
, refs
);
490 if (fields
->recordset
) _Recordset_Release( &fields
->recordset
->Recordset_iface
);
491 fields
->recordset
= NULL
;
492 WARN( "not destroying %p\n", fields
);
493 return InterlockedIncrement( &fields
->refs
);
498 static HRESULT WINAPI
fields_QueryInterface( Fields
*iface
, REFIID riid
, void **obj
)
500 struct fields
*fields
= impl_from_Fields( iface
);
501 TRACE( "%p, %s, %p\n", iface
, debugstr_guid(riid
), obj
);
503 if (IsEqualGUID( riid
, &IID_Fields
) || IsEqualGUID( riid
, &IID_IDispatch
) ||
504 IsEqualGUID( riid
, &IID_IUnknown
))
508 else if (IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
510 *obj
= &fields
->ISupportErrorInfo_iface
;
514 FIXME( "interface %s not implemented\n", debugstr_guid(riid
) );
515 return E_NOINTERFACE
;
517 fields_AddRef( iface
);
521 static HRESULT WINAPI
fields_GetTypeInfoCount( Fields
*iface
, UINT
*count
)
523 struct fields
*fields
= impl_from_Fields( iface
);
524 TRACE( "%p, %p\n", fields
, count
);
529 static HRESULT WINAPI
fields_GetTypeInfo( Fields
*iface
, UINT index
, LCID lcid
, ITypeInfo
**info
)
531 struct fields
*fields
= impl_from_Fields( iface
);
532 TRACE( "%p, %u, %u, %p\n", fields
, index
, lcid
, info
);
533 return get_typeinfo(Fields_tid
, info
);
536 static HRESULT WINAPI
fields_GetIDsOfNames( Fields
*iface
, REFIID riid
, LPOLESTR
*names
, UINT count
,
537 LCID lcid
, DISPID
*dispid
)
539 struct fields
*fields
= impl_from_Fields( iface
);
543 TRACE( "%p, %s, %p, %u, %u, %p\n", fields
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
545 hr
= get_typeinfo(Fields_tid
, &typeinfo
);
548 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, count
, dispid
);
549 ITypeInfo_Release(typeinfo
);
555 static HRESULT WINAPI
fields_Invoke( Fields
*iface
, DISPID member
, REFIID riid
, LCID lcid
, WORD flags
,
556 DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excep_info
, UINT
*arg_err
)
558 struct fields
*fields
= impl_from_Fields( iface
);
562 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", fields
, member
, debugstr_guid(riid
), lcid
, flags
, params
,
563 result
, excep_info
, arg_err
);
565 hr
= get_typeinfo(Fields_tid
, &typeinfo
);
568 hr
= ITypeInfo_Invoke(typeinfo
, &fields
->Fields_iface
, member
, flags
, params
,
569 result
, excep_info
, arg_err
);
570 ITypeInfo_Release(typeinfo
);
576 static HRESULT WINAPI
fields_get_Count( Fields
*iface
, LONG
*count
)
578 struct fields
*fields
= impl_from_Fields( iface
);
580 TRACE( "%p, %p\n", fields
, count
);
582 *count
= fields
->count
;
586 static HRESULT WINAPI
fields__NewEnum( Fields
*iface
, IUnknown
**obj
)
588 FIXME( "%p, %p\n", iface
, obj
);
592 static HRESULT WINAPI
fields_Refresh( Fields
*iface
)
594 FIXME( "%p\n", iface
);
598 static HRESULT
map_index( struct fields
*fields
, VARIANT
*index
, ULONG
*ret
)
602 if (V_VT( index
) != VT_BSTR
)
604 FIXME( "variant type %u not supported\n", V_VT( index
) );
608 for (i
= 0; i
< fields
->count
; i
++)
614 if ((hr
= Field_get_Name( fields
->field
[i
], &name
)) != S_OK
) return hr
;
615 match
= !wcsicmp( V_BSTR( index
), name
);
616 SysFreeString( name
);
624 return MAKE_ADO_HRESULT(adErrItemNotFound
);
627 static HRESULT WINAPI
fields_get_Item( Fields
*iface
, VARIANT index
, Field
**obj
)
629 struct fields
*fields
= impl_from_Fields( iface
);
633 TRACE( "%p, %s, %p\n", fields
, debugstr_variant(&index
), obj
);
635 if ((hr
= map_index( fields
, &index
, &i
)) != S_OK
) return hr
;
637 Field_AddRef( fields
->field
[i
] );
638 *obj
= fields
->field
[i
];
642 static BOOL
resize_fields( struct fields
*fields
, ULONG count
)
644 if (count
> fields
->allocated
)
647 ULONG new_size
= max( count
, fields
->allocated
* 2 );
648 if (!(tmp
= heap_realloc( fields
->field
, new_size
* sizeof(*tmp
) ))) return FALSE
;
650 fields
->allocated
= new_size
;
653 fields
->count
= count
;
657 static HRESULT
append_field( struct fields
*fields
, BSTR name
, DataTypeEnum type
, LONG size
, FieldAttributeEnum attr
,
663 if ((hr
= Field_create( name
, fields
->count
, fields
->recordset
, &field
)) != S_OK
) return hr
;
664 Field_put_Type( field
, type
);
665 Field_put_DefinedSize( field
, size
);
666 if (attr
!= adFldUnspecified
) Field_put_Attributes( field
, attr
);
667 if (value
) FIXME( "ignoring value %s\n", debugstr_variant(value
) );
669 if (!(resize_fields( fields
, fields
->count
+ 1 )))
671 Field_Release( field
);
672 return E_OUTOFMEMORY
;
675 fields
->field
[fields
->count
- 1] = field
;
679 static HRESULT WINAPI
fields__Append( Fields
*iface
, BSTR name
, DataTypeEnum type
, LONG size
, FieldAttributeEnum attr
)
681 struct fields
*fields
= impl_from_Fields( iface
);
683 TRACE( "%p, %s, %u, %d, %d\n", fields
, debugstr_w(name
), type
, size
, attr
);
685 return append_field( fields
, name
, type
, size
, attr
, NULL
);
688 static HRESULT WINAPI
fields_Delete( Fields
*iface
, VARIANT index
)
690 FIXME( "%p, %s\n", iface
, debugstr_variant(&index
) );
694 static HRESULT WINAPI
fields_Append( Fields
*iface
, BSTR name
, DataTypeEnum type
, LONG size
, FieldAttributeEnum attr
,
697 struct fields
*fields
= impl_from_Fields( iface
);
699 TRACE( "%p, %s, %u, %d, %d, %s\n", fields
, debugstr_w(name
), type
, size
, attr
, debugstr_variant(&value
) );
701 return append_field( fields
, name
, type
, size
, attr
, &value
);
704 static HRESULT WINAPI
fields_Update( Fields
*iface
)
706 FIXME( "%p\n", iface
);
710 static HRESULT WINAPI
fields_Resync( Fields
*iface
, ResyncEnum resync_values
)
712 FIXME( "%p, %u\n", iface
, resync_values
);
716 static HRESULT WINAPI
fields_CancelUpdate( Fields
*iface
)
718 FIXME( "%p\n", iface
);
722 static const struct FieldsVtbl fields_vtbl
=
724 fields_QueryInterface
,
727 fields_GetTypeInfoCount
,
729 fields_GetIDsOfNames
,
743 static inline struct fields
*fields_from_ISupportErrorInfo( ISupportErrorInfo
*iface
)
745 return CONTAINING_RECORD( iface
, struct fields
, ISupportErrorInfo_iface
);
748 static HRESULT WINAPI
fields_supporterrorinfo_QueryInterface( ISupportErrorInfo
*iface
, REFIID riid
, void **obj
)
750 struct fields
*fields
= fields_from_ISupportErrorInfo( iface
);
751 return Fields_QueryInterface( &fields
->Fields_iface
, riid
, obj
);
754 static ULONG WINAPI
fields_supporterrorinfo_AddRef( ISupportErrorInfo
*iface
)
756 struct fields
*fields
= fields_from_ISupportErrorInfo( iface
);
757 return Fields_AddRef( &fields
->Fields_iface
);
760 static ULONG WINAPI
fields_supporterrorinfo_Release( ISupportErrorInfo
*iface
)
762 struct fields
*fields
= fields_from_ISupportErrorInfo( iface
);
763 return Fields_Release( &fields
->Fields_iface
);
766 static HRESULT WINAPI
fields_supporterrorinfo_InterfaceSupportsErrorInfo( ISupportErrorInfo
*iface
, REFIID riid
)
768 struct fields
*fields
= fields_from_ISupportErrorInfo( iface
);
769 FIXME( "%p, %s\n", fields
, debugstr_guid(riid
) );
773 static const ISupportErrorInfoVtbl fields_supporterrorinfo_vtbl
=
775 fields_supporterrorinfo_QueryInterface
,
776 fields_supporterrorinfo_AddRef
,
777 fields_supporterrorinfo_Release
,
778 fields_supporterrorinfo_InterfaceSupportsErrorInfo
781 static void map_rowset_fields(struct recordset
*recordset
, struct fields
*fields
)
784 IColumnsInfo
*columninfo
;
785 DBORDINAL columns
, i
;
786 DBCOLUMNINFO
*colinfo
;
787 OLECHAR
*stringsbuffer
;
789 /* Not Finding the interface or GetColumnInfo failing just causes 0 Fields to be returned */
790 hr
= IRowset_QueryInterface(recordset
->row_set
, &IID_IColumnsInfo
, (void**)&columninfo
);
794 hr
= IColumnsInfo_GetColumnInfo(columninfo
, &columns
, &colinfo
, &stringsbuffer
);
797 for (i
=0; i
< columns
; i
++)
799 TRACE("Adding Column %lu, pwszName: %s, pTypeInfo %p, iOrdinal %lu, dwFlags 0x%08x, "
800 "ulColumnSize %lu, wType %d, bPrecision %d, bScale %d\n",
801 i
, debugstr_w(colinfo
[i
].pwszName
), colinfo
[i
].pTypeInfo
, colinfo
[i
].iOrdinal
,
802 colinfo
[i
].dwFlags
, colinfo
[i
].ulColumnSize
, colinfo
[i
].wType
,
803 colinfo
[i
].bPrecision
, colinfo
[i
].bScale
);
805 hr
= append_field(fields
, colinfo
[i
].pwszName
, colinfo
[i
].wType
, colinfo
[i
].ulColumnSize
,
806 colinfo
[i
].dwFlags
, NULL
);
809 ERR("Failed to add Field name - 0x%08x\n", hr
);
814 CoTaskMemFree(colinfo
);
815 CoTaskMemFree(stringsbuffer
);
818 IColumnsInfo_Release(columninfo
);
821 static HRESULT
fields_create( struct recordset
*recordset
, struct fields
**ret
)
823 struct fields
*fields
;
825 if (!(fields
= heap_alloc_zero( sizeof(*fields
) ))) return E_OUTOFMEMORY
;
826 fields
->Fields_iface
.lpVtbl
= &fields_vtbl
;
827 fields
->ISupportErrorInfo_iface
.lpVtbl
= &fields_supporterrorinfo_vtbl
;
829 fields
->recordset
= recordset
;
830 _Recordset_AddRef( &fields
->recordset
->Recordset_iface
);
832 if ( recordset
->row_set
)
833 map_rowset_fields(recordset
, fields
);
836 TRACE( "returning %p\n", *ret
);
840 static inline struct recordset
*impl_from_Recordset( _Recordset
*iface
)
842 return CONTAINING_RECORD( iface
, struct recordset
, Recordset_iface
);
845 static inline struct recordset
*impl_from_ADORecordsetConstruction( ADORecordsetConstruction
*iface
)
847 return CONTAINING_RECORD( iface
, struct recordset
, ADORecordsetConstruction_iface
);
850 static ULONG WINAPI
recordset_AddRef( _Recordset
*iface
)
852 struct recordset
*recordset
= impl_from_Recordset( iface
);
853 LONG refs
= InterlockedIncrement( &recordset
->refs
);
854 TRACE( "%p new refcount %d\n", recordset
, refs
);
858 static void close_recordset( struct recordset
*recordset
)
860 ULONG row
, col
, col_count
;
862 if ( recordset
->row_set
) IRowset_Release( recordset
->row_set
);
863 recordset
->row_set
= NULL
;
865 if (!recordset
->fields
) return;
866 col_count
= get_column_count( recordset
);
868 Fields_Release( &recordset
->fields
->Fields_iface
);
869 recordset
->fields
= NULL
;
871 for (row
= 0; row
< recordset
->count
; row
++)
872 for (col
= 0; col
< col_count
; col
++) VariantClear( &recordset
->data
[row
* col_count
+ col
] );
874 recordset
->count
= recordset
->allocated
= recordset
->index
= 0;
875 heap_free( recordset
->data
);
876 recordset
->data
= NULL
;
879 static ULONG WINAPI
recordset_Release( _Recordset
*iface
)
881 struct recordset
*recordset
= impl_from_Recordset( iface
);
882 LONG refs
= InterlockedDecrement( &recordset
->refs
);
883 TRACE( "%p new refcount %d\n", recordset
, refs
);
886 TRACE( "destroying %p\n", recordset
);
887 close_recordset( recordset
);
888 heap_free( recordset
);
893 static HRESULT WINAPI
recordset_QueryInterface( _Recordset
*iface
, REFIID riid
, void **obj
)
895 struct recordset
*recordset
= impl_from_Recordset( iface
);
896 TRACE( "%p, %s, %p\n", iface
, debugstr_guid(riid
), obj
);
900 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDispatch
) ||
901 IsEqualIID(riid
, &IID__ADO
) || IsEqualIID(riid
, &IID_Recordset15
) ||
902 IsEqualIID(riid
, &IID_Recordset20
) || IsEqualIID(riid
, &IID_Recordset21
) ||
903 IsEqualIID(riid
, &IID__Recordset
))
907 else if (IsEqualGUID( riid
, &IID_ISupportErrorInfo
))
909 *obj
= &recordset
->ISupportErrorInfo_iface
;
911 else if (IsEqualGUID( riid
, &IID_ADORecordsetConstruction
))
913 *obj
= &recordset
->ADORecordsetConstruction_iface
;
915 else if (IsEqualGUID( riid
, &IID_IRunnableObject
))
917 TRACE("IID_IRunnableObject not supported returning NULL\n");
918 return E_NOINTERFACE
;
922 FIXME( "interface %s not implemented\n", debugstr_guid(riid
) );
923 return E_NOINTERFACE
;
925 recordset_AddRef( iface
);
929 static HRESULT WINAPI
recordset_GetTypeInfoCount( _Recordset
*iface
, UINT
*count
)
931 struct recordset
*recordset
= impl_from_Recordset( iface
);
932 TRACE( "%p, %p\n", recordset
, count
);
937 static HRESULT WINAPI
recordset_GetTypeInfo( _Recordset
*iface
, UINT index
, LCID lcid
, ITypeInfo
**info
)
939 struct recordset
*recordset
= impl_from_Recordset( iface
);
940 TRACE( "%p, %u, %u, %p\n", recordset
, index
, lcid
, info
);
941 return get_typeinfo(Recordset_tid
, info
);
944 static HRESULT WINAPI
recordset_GetIDsOfNames( _Recordset
*iface
, REFIID riid
, LPOLESTR
*names
, UINT count
,
945 LCID lcid
, DISPID
*dispid
)
947 struct recordset
*recordset
= impl_from_Recordset( iface
);
951 TRACE( "%p, %s, %p, %u, %u, %p\n", recordset
, debugstr_guid(riid
), names
, count
, lcid
, dispid
);
953 hr
= get_typeinfo(Recordset_tid
, &typeinfo
);
956 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, count
, dispid
);
957 ITypeInfo_Release(typeinfo
);
963 static HRESULT WINAPI
recordset_Invoke( _Recordset
*iface
, DISPID member
, REFIID riid
, LCID lcid
, WORD flags
,
964 DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excep_info
, UINT
*arg_err
)
966 struct recordset
*recordset
= impl_from_Recordset( iface
);
970 TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", recordset
, member
, debugstr_guid(riid
), lcid
, flags
, params
,
971 result
, excep_info
, arg_err
);
973 hr
= get_typeinfo(Recordset_tid
, &typeinfo
);
976 hr
= ITypeInfo_Invoke(typeinfo
, &recordset
->Recordset_iface
, member
, flags
, params
,
977 result
, excep_info
, arg_err
);
978 ITypeInfo_Release(typeinfo
);
984 static HRESULT WINAPI
recordset_get_Properties( _Recordset
*iface
, Properties
**obj
)
986 FIXME( "%p, %p\n", iface
, obj
);
990 static HRESULT WINAPI
recordset_get_AbsolutePosition( _Recordset
*iface
, PositionEnum_Param
*pos
)
992 FIXME( "%p, %p\n", iface
, pos
);
996 static HRESULT WINAPI
recordset_put_AbsolutePosition( _Recordset
*iface
, PositionEnum_Param pos
)
998 FIXME( "%p, %d\n", iface
, pos
);
1002 static HRESULT WINAPI
recordset_putref_ActiveConnection( _Recordset
*iface
, IDispatch
*connection
)
1004 FIXME( "%p, %p\n", iface
, connection
);
1008 static HRESULT WINAPI
recordset_put_ActiveConnection( _Recordset
*iface
, VARIANT connection
)
1010 FIXME( "%p, %s\n", iface
, debugstr_variant(&connection
) );
1014 static HRESULT WINAPI
recordset_get_ActiveConnection( _Recordset
*iface
, VARIANT
*connection
)
1016 FIXME( "%p, %p\n", iface
, connection
);
1020 static HRESULT WINAPI
recordset_get_BOF( _Recordset
*iface
, VARIANT_BOOL
*bof
)
1022 struct recordset
*recordset
= impl_from_Recordset( iface
);
1024 TRACE( "%p, %p\n", recordset
, bof
);
1026 *bof
= (recordset
->index
< 0) ? VARIANT_TRUE
: VARIANT_FALSE
;
1030 static HRESULT WINAPI
recordset_get_Bookmark( _Recordset
*iface
, VARIANT
*bookmark
)
1032 struct recordset
*recordset
= impl_from_Recordset( iface
);
1033 TRACE( "%p, %p\n", iface
, bookmark
);
1035 if (recordset
->state
== adStateClosed
) return MAKE_ADO_HRESULT( adErrObjectClosed
);
1036 if (recordset
->index
< 0) return MAKE_ADO_HRESULT( adErrNoCurrentRecord
);
1038 V_VT(bookmark
) = VT_I4
;
1039 V_I4(bookmark
) = recordset
->index
;
1043 static HRESULT WINAPI
recordset_put_Bookmark( _Recordset
*iface
, VARIANT bookmark
)
1045 struct recordset
*recordset
= impl_from_Recordset( iface
);
1046 TRACE( "%p, %s\n", iface
, debugstr_variant(&bookmark
) );
1048 if (recordset
->state
== adStateClosed
) return MAKE_ADO_HRESULT( adErrObjectClosed
);
1050 if (V_VT(&bookmark
) != VT_I4
) return MAKE_ADO_HRESULT( adErrInvalidArgument
);
1052 recordset
->index
= V_I4(&bookmark
);
1056 static HRESULT WINAPI
recordset_get_CacheSize( _Recordset
*iface
, LONG
*size
)
1058 FIXME( "%p, %p\n", iface
, size
);
1062 static HRESULT WINAPI
recordset_put_CacheSize( _Recordset
*iface
, LONG size
)
1064 FIXME( "%p, %d\n", iface
, size
);
1068 static HRESULT WINAPI
recordset_get_CursorType( _Recordset
*iface
, CursorTypeEnum
*cursor_type
)
1070 struct recordset
*recordset
= impl_from_Recordset( iface
);
1072 TRACE( "%p, %p\n", iface
, cursor_type
);
1074 *cursor_type
= recordset
->cursor_type
;
1078 static HRESULT WINAPI
recordset_put_CursorType( _Recordset
*iface
, CursorTypeEnum cursor_type
)
1080 struct recordset
*recordset
= impl_from_Recordset( iface
);
1082 TRACE( "%p, %d\n", iface
, cursor_type
);
1084 recordset
->cursor_type
= cursor_type
;
1088 static HRESULT WINAPI
recordset_get_EOF( _Recordset
*iface
, VARIANT_BOOL
*eof
)
1090 struct recordset
*recordset
= impl_from_Recordset( iface
);
1092 TRACE( "%p, %p\n", recordset
, eof
);
1094 *eof
= (!recordset
->count
|| recordset
->index
>= recordset
->count
) ? VARIANT_TRUE
: VARIANT_FALSE
;
1098 static HRESULT WINAPI
recordset_get_Fields( _Recordset
*iface
, Fields
**obj
)
1100 struct recordset
*recordset
= impl_from_Recordset( iface
);
1103 TRACE( "%p, %p\n", recordset
, obj
);
1105 if (recordset
->fields
)
1107 /* yes, this adds a reference to the recordset instead of the fields object */
1108 _Recordset_AddRef( &recordset
->Recordset_iface
);
1109 recordset
->fields
->recordset
= recordset
;
1110 *obj
= &recordset
->fields
->Fields_iface
;
1114 if ((hr
= fields_create( recordset
, &recordset
->fields
)) != S_OK
) return hr
;
1116 *obj
= &recordset
->fields
->Fields_iface
;
1120 static HRESULT WINAPI
recordset_get_LockType( _Recordset
*iface
, LockTypeEnum
*lock_type
)
1122 FIXME( "%p, %p\n", iface
, lock_type
);
1126 static HRESULT WINAPI
recordset_put_LockType( _Recordset
*iface
, LockTypeEnum lock_type
)
1128 FIXME( "%p, %d\n", iface
, lock_type
);
1132 static HRESULT WINAPI
recordset_get_MaxRecords( _Recordset
*iface
, LONG
*max_records
)
1134 FIXME( "%p, %p\n", iface
, max_records
);
1138 static HRESULT WINAPI
recordset_put_MaxRecords( _Recordset
*iface
, LONG max_records
)
1140 FIXME( "%p, %d\n", iface
, max_records
);
1144 static HRESULT WINAPI
recordset_get_RecordCount( _Recordset
*iface
, LONG
*count
)
1146 struct recordset
*recordset
= impl_from_Recordset( iface
);
1148 TRACE( "%p, %p\n", recordset
, count
);
1150 *count
= recordset
->count
;
1154 static HRESULT WINAPI
recordset_putref_Source( _Recordset
*iface
, IDispatch
*source
)
1156 FIXME( "%p, %p\n", iface
, source
);
1160 static HRESULT WINAPI
recordset_put_Source( _Recordset
*iface
, BSTR source
)
1162 FIXME( "%p, %s\n", iface
, debugstr_w(source
) );
1166 static HRESULT WINAPI
recordset_get_Source( _Recordset
*iface
, VARIANT
*source
)
1168 FIXME( "%p, %p\n", iface
, source
);
1172 static BOOL
resize_recordset( struct recordset
*recordset
, ULONG row_count
)
1174 ULONG row_size
= get_column_count( recordset
) * sizeof(*recordset
->data
);
1176 if (row_count
> recordset
->allocated
)
1179 ULONG count
= max( row_count
, recordset
->allocated
* 2 );
1180 if (!(tmp
= heap_realloc_zero( recordset
->data
, count
* row_size
))) return FALSE
;
1181 recordset
->data
= tmp
;
1182 recordset
->allocated
= count
;
1185 recordset
->count
= row_count
;
1189 static HRESULT WINAPI
recordset_AddNew( _Recordset
*iface
, VARIANT field_list
, VARIANT values
)
1191 struct recordset
*recordset
= impl_from_Recordset( iface
);
1193 TRACE( "%p, %s, %s\n", recordset
, debugstr_variant(&field_list
), debugstr_variant(&values
) );
1194 FIXME( "ignoring field list and values\n" );
1196 if (recordset
->state
== adStateClosed
) return MAKE_ADO_HRESULT( adErrObjectClosed
);
1198 if (!resize_recordset( recordset
, recordset
->count
+ 1 )) return E_OUTOFMEMORY
;
1203 static HRESULT WINAPI
recordset_CancelUpdate( _Recordset
*iface
)
1205 FIXME( "%p\n", iface
);
1209 static HRESULT WINAPI
recordset_Close( _Recordset
*iface
)
1211 struct recordset
*recordset
= impl_from_Recordset( iface
);
1213 TRACE( "%p\n", recordset
);
1215 if (recordset
->state
== adStateClosed
) return MAKE_ADO_HRESULT( adErrObjectClosed
);
1217 close_recordset( recordset
);
1218 recordset
->state
= adStateClosed
;
1222 static HRESULT WINAPI
recordset_Delete( _Recordset
*iface
, AffectEnum affect_records
)
1224 FIXME( "%p, %u\n", iface
, affect_records
);
1228 static HRESULT WINAPI
recordset_GetRows( _Recordset
*iface
, LONG rows
, VARIANT start
, VARIANT fields
, VARIANT
*var
)
1230 FIXME( "%p, %d, %s, %s, %p\n", iface
, rows
, debugstr_variant(&start
), debugstr_variant(&fields
), var
);
1234 static HRESULT WINAPI
recordset_Move( _Recordset
*iface
, LONG num_records
, VARIANT start
)
1236 FIXME( "%p, %d, %s\n", iface
, num_records
, debugstr_variant(&start
) );
1240 static HRESULT WINAPI
recordset_MoveNext( _Recordset
*iface
)
1242 struct recordset
*recordset
= impl_from_Recordset( iface
);
1244 TRACE( "%p\n", recordset
);
1246 if (recordset
->index
< recordset
->count
) recordset
->index
++;
1250 static HRESULT WINAPI
recordset_MovePrevious( _Recordset
*iface
)
1252 struct recordset
*recordset
= impl_from_Recordset( iface
);
1254 TRACE( "%p\n", recordset
);
1256 if (recordset
->index
>= 0) recordset
->index
--;
1260 static HRESULT WINAPI
recordset_MoveFirst( _Recordset
*iface
)
1262 struct recordset
*recordset
= impl_from_Recordset( iface
);
1264 TRACE( "%p\n", recordset
);
1266 recordset
->index
= 0;
1270 static HRESULT WINAPI
recordset_MoveLast( _Recordset
*iface
)
1272 struct recordset
*recordset
= impl_from_Recordset( iface
);
1274 TRACE( "%p\n", recordset
);
1276 recordset
->index
= (recordset
->count
> 0) ? recordset
->count
- 1 : 0;
1280 static HRESULT WINAPI
recordset_Open( _Recordset
*iface
, VARIANT source
, VARIANT active_connection
,
1281 CursorTypeEnum cursor_type
, LockTypeEnum lock_type
, LONG options
)
1283 struct recordset
*recordset
= impl_from_Recordset( iface
);
1284 ADOConnectionConstruction15
*construct
;
1286 ICommandText
*command_text
;
1287 DBROWCOUNT affected
;
1291 FIXME( "%p, %s, %s, %d, %d, %d Semi-stub\n", recordset
, debugstr_variant(&source
), debugstr_variant(&active_connection
),
1292 cursor_type
, lock_type
, options
);
1294 if (recordset
->state
== adStateOpen
) return MAKE_ADO_HRESULT( adErrObjectOpen
);
1296 if (recordset
->fields
)
1298 recordset
->state
= adStateOpen
;
1302 if (V_VT(&active_connection
) != VT_DISPATCH
)
1304 FIXME("Unsupported Active connection type %d\n", V_VT(&active_connection
));
1305 return MAKE_ADO_HRESULT( adErrInvalidConnection
);
1308 hr
= IDispatch_QueryInterface(V_DISPATCH(&active_connection
), &IID_ADOConnectionConstruction15
, (void**)&construct
);
1312 hr
= ADOConnectionConstruction15_get_Session(construct
, &session
);
1313 ADOConnectionConstruction15_Release(construct
);
1317 if (V_VT(&source
) != VT_BSTR
)
1319 FIXME("Unsupported source type!\n");
1320 IUnknown_Release(session
);
1324 hr
= create_command_text(session
, V_BSTR(&source
), &command_text
);
1325 IUnknown_Release(session
);
1329 hr
= ICommandText_Execute(command_text
, NULL
, &IID_IUnknown
, NULL
, &affected
, &rowset
);
1330 ICommandText_Release(command_text
);
1334 ADORecordsetConstruction_put_Rowset(&recordset
->ADORecordsetConstruction_iface
, rowset
);
1335 recordset
->cursor_type
= cursor_type
;
1336 recordset
->state
= adStateOpen
;
1338 IUnknown_Release(rowset
);
1343 static HRESULT WINAPI
recordset_Requery( _Recordset
*iface
, LONG options
)
1345 FIXME( "%p, %d\n", iface
, options
);
1349 static HRESULT WINAPI
recordset__xResync( _Recordset
*iface
, AffectEnum affect_records
)
1351 FIXME( "%p, %u\n", iface
, affect_records
);
1355 static HRESULT WINAPI
recordset_Update( _Recordset
*iface
, VARIANT fields
, VARIANT values
)
1357 FIXME( "%p, %s, %s\n", iface
, debugstr_variant(&fields
), debugstr_variant(&values
) );
1361 static HRESULT WINAPI
recordset_get_AbsolutePage( _Recordset
*iface
, PositionEnum_Param
*pos
)
1363 FIXME( "%p, %p\n", iface
, pos
);
1367 static HRESULT WINAPI
recordset_put_AbsolutePage( _Recordset
*iface
, PositionEnum_Param pos
)
1369 FIXME( "%p, %d\n", iface
, pos
);
1373 static HRESULT WINAPI
recordset_get_EditMode( _Recordset
*iface
, EditModeEnum
*mode
)
1375 FIXME( "%p, %p\n", iface
, mode
);
1379 static HRESULT WINAPI
recordset_get_Filter( _Recordset
*iface
, VARIANT
*criteria
)
1381 FIXME( "%p, %p\n", iface
, criteria
);
1385 static HRESULT WINAPI
recordset_put_Filter( _Recordset
*iface
, VARIANT criteria
)
1387 FIXME( "%p, %s\n", iface
, debugstr_variant(&criteria
) );
1391 static HRESULT WINAPI
recordset_get_PageCount( _Recordset
*iface
, LONG
*count
)
1393 FIXME( "%p, %p\n", iface
, count
);
1397 static HRESULT WINAPI
recordset_get_PageSize( _Recordset
*iface
, LONG
*size
)
1399 FIXME( "%p, %p\n", iface
, size
);
1403 static HRESULT WINAPI
recordset_put_PageSize( _Recordset
*iface
, LONG size
)
1405 FIXME( "%p, %d\n", iface
, size
);
1409 static HRESULT WINAPI
recordset_get_Sort( _Recordset
*iface
, BSTR
*criteria
)
1411 FIXME( "%p, %p\n", iface
, criteria
);
1415 static HRESULT WINAPI
recordset_put_Sort( _Recordset
*iface
, BSTR criteria
)
1417 FIXME( "%p, %s\n", iface
, debugstr_w(criteria
) );
1421 static HRESULT WINAPI
recordset_get_Status( _Recordset
*iface
, LONG
*status
)
1423 FIXME( "%p, %p\n", iface
, status
);
1427 static HRESULT WINAPI
recordset_get_State( _Recordset
*iface
, LONG
*state
)
1429 struct recordset
*recordset
= impl_from_Recordset( iface
);
1431 TRACE( "%p, %p\n", recordset
, state
);
1433 *state
= recordset
->state
;
1437 static HRESULT WINAPI
recordset__xClone( _Recordset
*iface
, _Recordset
**obj
)
1439 FIXME( "%p, %p\n", iface
, obj
);
1443 static HRESULT WINAPI
recordset_UpdateBatch( _Recordset
*iface
, AffectEnum affect_records
)
1445 FIXME( "%p, %u\n", iface
, affect_records
);
1449 static HRESULT WINAPI
recordset_CancelBatch( _Recordset
*iface
, AffectEnum affect_records
)
1451 FIXME( "%p, %u\n", iface
, affect_records
);
1455 static HRESULT WINAPI
recordset_get_CursorLocation( _Recordset
*iface
, CursorLocationEnum
*cursor_loc
)
1457 struct recordset
*recordset
= impl_from_Recordset( iface
);
1459 TRACE( "%p, %p\n", iface
, cursor_loc
);
1461 *cursor_loc
= recordset
->cursor_location
;
1466 static HRESULT WINAPI
recordset_put_CursorLocation( _Recordset
*iface
, CursorLocationEnum cursor_loc
)
1468 struct recordset
*recordset
= impl_from_Recordset( iface
);
1470 TRACE( "%p, %u\n", iface
, cursor_loc
);
1472 if (recordset
->state
== adStateOpen
) return MAKE_ADO_HRESULT( adErrObjectOpen
);
1474 recordset
->cursor_location
= cursor_loc
;
1479 static HRESULT WINAPI
recordset_NextRecordset( _Recordset
*iface
, VARIANT
*records_affected
, _Recordset
**record_set
)
1481 FIXME( "%p, %p, %p\n", iface
, records_affected
, record_set
);
1485 static HRESULT WINAPI
recordset_Supports( _Recordset
*iface
, CursorOptionEnum cursor_options
, VARIANT_BOOL
*ret
)
1487 FIXME( "%p, %08x, %p\n", iface
, cursor_options
, ret
);
1491 static HRESULT WINAPI
recordset_get_Collect( _Recordset
*iface
, VARIANT index
, VARIANT
*var
)
1493 FIXME( "%p, %s, %p\n", iface
, debugstr_variant(&index
), var
);
1497 static HRESULT WINAPI
recordset_put_Collect( _Recordset
*iface
, VARIANT index
, VARIANT var
)
1499 FIXME( "%p, %s, %s\n", iface
, debugstr_variant(&index
), debugstr_variant(&var
) );
1503 static HRESULT WINAPI
recordset_get_MarshalOptions( _Recordset
*iface
, MarshalOptionsEnum
*options
)
1505 FIXME( "%p, %p\n", iface
, options
);
1509 static HRESULT WINAPI
recordset_put_MarshalOptions( _Recordset
*iface
, MarshalOptionsEnum options
)
1511 FIXME( "%p, %u\n", iface
, options
);
1515 static HRESULT WINAPI
recordset_Find( _Recordset
*iface
, BSTR criteria
, LONG skip_records
,
1516 SearchDirectionEnum search_direction
, VARIANT start
)
1518 FIXME( "%p, %s, %d, %d, %s\n", iface
, debugstr_w(criteria
), skip_records
, search_direction
,
1519 debugstr_variant(&start
) );
1523 static HRESULT WINAPI
recordset_Cancel( _Recordset
*iface
)
1525 FIXME( "%p\n", iface
);
1529 static HRESULT WINAPI
recordset_get_DataSource( _Recordset
*iface
, IUnknown
**data_source
)
1531 FIXME( "%p, %p\n", iface
, data_source
);
1535 static HRESULT WINAPI
recordset_putref_DataSource( _Recordset
*iface
, IUnknown
*data_source
)
1537 FIXME( "%p, %p\n", iface
, data_source
);
1541 static HRESULT WINAPI
recordset__xSave( _Recordset
*iface
, BSTR filename
, PersistFormatEnum persist_format
)
1543 FIXME( "%p, %s, %u\n", iface
, debugstr_w(filename
), persist_format
);
1547 static HRESULT WINAPI
recordset_get_ActiveCommand( _Recordset
*iface
, IDispatch
**cmd
)
1549 FIXME( "%p, %p\n", iface
, cmd
);
1553 static HRESULT WINAPI
recordset_put_StayInSync( _Recordset
*iface
, VARIANT_BOOL stay_in_sync
)
1555 FIXME( "%p, %d\n", iface
, stay_in_sync
);
1559 static HRESULT WINAPI
recordset_get_StayInSync( _Recordset
*iface
, VARIANT_BOOL
*stay_in_sync
)
1561 FIXME( "%p, %p\n", iface
, stay_in_sync
);
1565 static HRESULT WINAPI
recordset_GetString( _Recordset
*iface
, StringFormatEnum string_format
, LONG num_rows
,
1566 BSTR column_delimiter
, BSTR row_delimiter
, BSTR null_expr
,
1569 FIXME( "%p, %u, %d, %s, %s, %s, %p\n", iface
, string_format
, num_rows
, debugstr_w(column_delimiter
),
1570 debugstr_w(row_delimiter
), debugstr_w(null_expr
), ret_string
);
1574 static HRESULT WINAPI
recordset_get_DataMember( _Recordset
*iface
, BSTR
*data_member
)
1576 FIXME( "%p, %p\n", iface
, data_member
);
1580 static HRESULT WINAPI
recordset_put_DataMember( _Recordset
*iface
, BSTR data_member
)
1582 FIXME( "%p, %s\n", iface
, debugstr_w(data_member
) );
1586 static HRESULT WINAPI
recordset_CompareBookmarks( _Recordset
*iface
, VARIANT bookmark1
, VARIANT bookmark2
, CompareEnum
*compare
)
1588 FIXME( "%p, %s, %s, %p\n", iface
, debugstr_variant(&bookmark1
), debugstr_variant(&bookmark2
), compare
);
1592 static HRESULT WINAPI
recordset_Clone( _Recordset
*iface
, LockTypeEnum lock_type
, _Recordset
**obj
)
1594 FIXME( "%p, %d, %p\n", iface
, lock_type
, obj
);
1598 static HRESULT WINAPI
recordset_Resync( _Recordset
*iface
, AffectEnum affect_records
, ResyncEnum resync_values
)
1600 FIXME( "%p, %u, %u\n", iface
, affect_records
, resync_values
);
1604 static HRESULT WINAPI
recordset_Seek( _Recordset
*iface
, VARIANT key_values
, SeekEnum seek_option
)
1606 FIXME( "%p, %s, %u\n", iface
, debugstr_variant(&key_values
), seek_option
);
1610 static HRESULT WINAPI
recordset_put_Index( _Recordset
*iface
, BSTR index
)
1612 FIXME( "%p, %s\n", iface
, debugstr_w(index
) );
1616 static HRESULT WINAPI
recordset_get_Index( _Recordset
*iface
, BSTR
*index
)
1618 FIXME( "%p, %p\n", iface
, index
);
1622 static HRESULT WINAPI
recordset_Save( _Recordset
*iface
, VARIANT destination
, PersistFormatEnum persist_format
)
1624 FIXME( "%p, %s, %u\n", iface
, debugstr_variant(&destination
), persist_format
);
1628 static const struct _RecordsetVtbl recordset_vtbl
=
1630 recordset_QueryInterface
,
1633 recordset_GetTypeInfoCount
,
1634 recordset_GetTypeInfo
,
1635 recordset_GetIDsOfNames
,
1637 recordset_get_Properties
,
1638 recordset_get_AbsolutePosition
,
1639 recordset_put_AbsolutePosition
,
1640 recordset_putref_ActiveConnection
,
1641 recordset_put_ActiveConnection
,
1642 recordset_get_ActiveConnection
,
1644 recordset_get_Bookmark
,
1645 recordset_put_Bookmark
,
1646 recordset_get_CacheSize
,
1647 recordset_put_CacheSize
,
1648 recordset_get_CursorType
,
1649 recordset_put_CursorType
,
1651 recordset_get_Fields
,
1652 recordset_get_LockType
,
1653 recordset_put_LockType
,
1654 recordset_get_MaxRecords
,
1655 recordset_put_MaxRecords
,
1656 recordset_get_RecordCount
,
1657 recordset_putref_Source
,
1658 recordset_put_Source
,
1659 recordset_get_Source
,
1661 recordset_CancelUpdate
,
1667 recordset_MovePrevious
,
1668 recordset_MoveFirst
,
1674 recordset_get_AbsolutePage
,
1675 recordset_put_AbsolutePage
,
1676 recordset_get_EditMode
,
1677 recordset_get_Filter
,
1678 recordset_put_Filter
,
1679 recordset_get_PageCount
,
1680 recordset_get_PageSize
,
1681 recordset_put_PageSize
,
1684 recordset_get_Status
,
1685 recordset_get_State
,
1687 recordset_UpdateBatch
,
1688 recordset_CancelBatch
,
1689 recordset_get_CursorLocation
,
1690 recordset_put_CursorLocation
,
1691 recordset_NextRecordset
,
1693 recordset_get_Collect
,
1694 recordset_put_Collect
,
1695 recordset_get_MarshalOptions
,
1696 recordset_put_MarshalOptions
,
1699 recordset_get_DataSource
,
1700 recordset_putref_DataSource
,
1702 recordset_get_ActiveCommand
,
1703 recordset_put_StayInSync
,
1704 recordset_get_StayInSync
,
1705 recordset_GetString
,
1706 recordset_get_DataMember
,
1707 recordset_put_DataMember
,
1708 recordset_CompareBookmarks
,
1712 recordset_put_Index
,
1713 recordset_get_Index
,
1717 static inline struct recordset
*recordset_from_ISupportErrorInfo( ISupportErrorInfo
*iface
)
1719 return CONTAINING_RECORD( iface
, struct recordset
, ISupportErrorInfo_iface
);
1722 static HRESULT WINAPI
recordset_supporterrorinfo_QueryInterface( ISupportErrorInfo
*iface
, REFIID riid
, void **obj
)
1724 struct recordset
*recordset
= recordset_from_ISupportErrorInfo( iface
);
1725 return _Recordset_QueryInterface( &recordset
->Recordset_iface
, riid
, obj
);
1728 static ULONG WINAPI
recordset_supporterrorinfo_AddRef( ISupportErrorInfo
*iface
)
1730 struct recordset
*recordset
= recordset_from_ISupportErrorInfo( iface
);
1731 return _Recordset_AddRef( &recordset
->Recordset_iface
);
1734 static ULONG WINAPI
recordset_supporterrorinfo_Release( ISupportErrorInfo
*iface
)
1736 struct recordset
*recordset
= recordset_from_ISupportErrorInfo( iface
);
1737 return _Recordset_Release( &recordset
->Recordset_iface
);
1740 static HRESULT WINAPI
recordset_supporterrorinfo_InterfaceSupportsErrorInfo( ISupportErrorInfo
*iface
, REFIID riid
)
1742 struct recordset
*recordset
= recordset_from_ISupportErrorInfo( iface
);
1743 FIXME( "%p, %s\n", recordset
, debugstr_guid(riid
) );
1747 static const ISupportErrorInfoVtbl recordset_supporterrorinfo_vtbl
=
1749 recordset_supporterrorinfo_QueryInterface
,
1750 recordset_supporterrorinfo_AddRef
,
1751 recordset_supporterrorinfo_Release
,
1752 recordset_supporterrorinfo_InterfaceSupportsErrorInfo
1755 static HRESULT WINAPI
rsconstruction_QueryInterface(ADORecordsetConstruction
*iface
,
1756 REFIID riid
, void **obj
)
1758 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1759 return _Recordset_QueryInterface( &recordset
->Recordset_iface
, riid
, obj
);
1762 static ULONG WINAPI
rsconstruction_AddRef(ADORecordsetConstruction
*iface
)
1764 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1765 return _Recordset_AddRef( &recordset
->Recordset_iface
);
1768 static ULONG WINAPI
rsconstruction_Release(ADORecordsetConstruction
*iface
)
1770 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1771 return _Recordset_Release( &recordset
->Recordset_iface
);
1774 static HRESULT WINAPI
rsconstruction_GetTypeInfoCount(ADORecordsetConstruction
*iface
, UINT
*pctinfo
)
1776 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1777 TRACE( "%p, %p\n", recordset
, pctinfo
);
1782 static HRESULT WINAPI
rsconstruction_GetTypeInfo(ADORecordsetConstruction
*iface
, UINT iTInfo
,
1783 LCID lcid
, ITypeInfo
**ppTInfo
)
1785 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1786 TRACE( "%p %u %u %p\n", recordset
, iTInfo
, lcid
, ppTInfo
);
1787 return get_typeinfo(ADORecordsetConstruction_tid
, ppTInfo
);
1790 static HRESULT WINAPI
rsconstruction_GetIDsOfNames(ADORecordsetConstruction
*iface
, REFIID riid
,
1791 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
1793 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1795 ITypeInfo
*typeinfo
;
1797 TRACE( "%p %s %p %u %u %p\n", recordset
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
1799 hr
= get_typeinfo(ADORecordsetConstruction_tid
, &typeinfo
);
1802 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, rgszNames
, cNames
, rgDispId
);
1803 ITypeInfo_Release(typeinfo
);
1809 static HRESULT WINAPI
rsconstruction_Invoke(ADORecordsetConstruction
*iface
, DISPID dispIdMember
,
1810 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
,
1811 EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1813 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1815 ITypeInfo
*typeinfo
;
1817 TRACE( "%p %d %s %d %d %p %p %p %p\n", recordset
, dispIdMember
, debugstr_guid(riid
),
1818 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1820 hr
= get_typeinfo(ADORecordsetConstruction_tid
, &typeinfo
);
1823 hr
= ITypeInfo_Invoke(typeinfo
, &recordset
->ADORecordsetConstruction_iface
, dispIdMember
, wFlags
,
1824 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1825 ITypeInfo_Release(typeinfo
);
1831 static HRESULT WINAPI
rsconstruction_get_Rowset(ADORecordsetConstruction
*iface
, IUnknown
**row_set
)
1833 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1836 TRACE( "%p, %p\n", recordset
, row_set
);
1838 hr
= IRowset_QueryInterface(recordset
->row_set
, &IID_IUnknown
, (void**)row_set
);
1839 if ( FAILED(hr
) ) return E_FAIL
;
1844 static HRESULT WINAPI
rsconstruction_put_Rowset(ADORecordsetConstruction
*iface
, IUnknown
*unk
)
1846 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1850 TRACE( "%p, %p\n", recordset
, unk
);
1852 hr
= IUnknown_QueryInterface(unk
, &IID_IRowset
, (void**)&rowset
);
1853 if ( FAILED(hr
) ) return E_FAIL
;
1855 if ( recordset
->row_set
) IRowset_Release( recordset
->row_set
);
1856 recordset
->row_set
= rowset
;
1861 static HRESULT WINAPI
rsconstruction_get_Chapter(ADORecordsetConstruction
*iface
, LONG
*chapter
)
1863 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1864 FIXME( "%p, %p\n", recordset
, chapter
);
1868 static HRESULT WINAPI
rsconstruction_put_Chapter(ADORecordsetConstruction
*iface
, LONG chapter
)
1870 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1871 FIXME( "%p, %d\n", recordset
, chapter
);
1875 static HRESULT WINAPI
rsconstruction_get_RowPosition(ADORecordsetConstruction
*iface
, IUnknown
**row_pos
)
1877 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1878 FIXME( "%p, %p\n", recordset
, row_pos
);
1882 static HRESULT WINAPI
rsconstruction_put_RowPosition(ADORecordsetConstruction
*iface
, IUnknown
*row_pos
)
1884 struct recordset
*recordset
= impl_from_ADORecordsetConstruction( iface
);
1885 FIXME( "%p, %p\n", recordset
, row_pos
);
1889 static const ADORecordsetConstructionVtbl rsconstruction_vtbl
=
1891 rsconstruction_QueryInterface
,
1892 rsconstruction_AddRef
,
1893 rsconstruction_Release
,
1894 rsconstruction_GetTypeInfoCount
,
1895 rsconstruction_GetTypeInfo
,
1896 rsconstruction_GetIDsOfNames
,
1897 rsconstruction_Invoke
,
1898 rsconstruction_get_Rowset
,
1899 rsconstruction_put_Rowset
,
1900 rsconstruction_get_Chapter
,
1901 rsconstruction_put_Chapter
,
1902 rsconstruction_get_RowPosition
,
1903 rsconstruction_put_RowPosition
1906 HRESULT
Recordset_create( void **obj
)
1908 struct recordset
*recordset
;
1910 if (!(recordset
= heap_alloc_zero( sizeof(*recordset
) ))) return E_OUTOFMEMORY
;
1911 recordset
->Recordset_iface
.lpVtbl
= &recordset_vtbl
;
1912 recordset
->ISupportErrorInfo_iface
.lpVtbl
= &recordset_supporterrorinfo_vtbl
;
1913 recordset
->ADORecordsetConstruction_iface
.lpVtbl
= &rsconstruction_vtbl
;
1914 recordset
->refs
= 1;
1915 recordset
->index
= -1;
1916 recordset
->cursor_location
= adUseServer
;
1917 recordset
->cursor_type
= adOpenForwardOnly
;
1918 recordset
->row_set
= NULL
;
1920 *obj
= &recordset
->Recordset_iface
;
1921 TRACE( "returning iface %p\n", *obj
);