2 * Copyright 2020 Alistair Leslie-Hughes
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
28 #include "wine/heap.h"
29 #include "wine/debug.h"
35 #include "msdasql_private.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msdasql
);
48 static struct msdasql_prop msdasql_init_props
[] =
50 { DBPROP_ABORTPRESERVE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_DATASOURCEINFO
, VT_BOOL
, VARIANT_FALSE
},
51 { DBPROP_BLOCKINGSTORAGEOBJECTS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
52 { DBPROP_BOOKMARKS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
53 { DBPROP_BOOKMARKSKIPPED
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
54 { DBPROP_BOOKMARKTYPE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_I4
, 1 },
55 { DBPROP_CANFETCHBACKWARDS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
56 { DBPROP_CANHOLDROWS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
57 { DBPROP_CANSCROLLBACKWARDS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
58 { DBPROP_COLUMNRESTRICT
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
59 { DBPROP_COMMITPRESERVE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
60 { DBPROP_DELAYSTORAGEOBJECTS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
61 { DBPROP_IMMOBILEROWS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_TRUE
},
62 { DBPROP_LITERALBOOKMARKS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
63 { DBPROP_LITERALIDENTITY
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
64 { DBPROP_MAXOPENROWS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 0 },
65 { DBPROP_MAXPENDINGROWS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_I4
, 0 },
66 { DBPROP_MAXROWS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_I4
, 0 },
67 { DBPROP_NOTIFICATIONPHASES
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 31 },
68 { DBPROP_OTHERUPDATEDELETE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
69 { DBPROP_OWNINSERT
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
70 { DBPROP_OWNUPDATEDELETE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
71 { DBPROP_QUICKRESTART
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
72 { DBPROP_REENTRANTEVENTS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
73 { DBPROP_REMOVEDELETED
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
74 { DBPROP_REPORTMULTIPLECHANGES
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
75 { DBPROP_ROWRESTRICT
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
76 { DBPROP_ROWTHREADMODEL
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 2 },
77 { DBPROP_TRANSACTEDOBJECT
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
78 { DBPROP_UPDATABILITY
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 0 },
79 { DBPROP_STRONGIDENTITY
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
80 { DBPROP_IAccessor
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
81 { DBPROP_IColumnsInfo
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
82 { DBPROP_IColumnsRowset
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
83 { DBPROP_IConnectionPointContainer
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
84 { DBPROP_IRowset
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
85 { DBPROP_IRowsetChange
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
86 { DBPROP_IRowsetIdentity
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
87 { DBPROP_IRowsetInfo
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
88 { DBPROP_IRowsetLocate
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
89 { DBPROP_IRowsetResynch
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
90 { DBPROP_IRowsetUpdate
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
91 { DBPROP_ISupportErrorInfo
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
92 { DBPROP_ISequentialStream
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
93 { DBPROP_NOTIFYCOLUMNSET
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
94 { DBPROP_NOTIFYROWDELETE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
95 { DBPROP_NOTIFYROWFIRSTCHANGE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
96 { DBPROP_NOTIFYROWINSERT
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
97 { DBPROP_NOTIFYROWRESYNCH
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
98 { DBPROP_NOTIFYROWSETRELEASE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
99 { DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
100 { DBPROP_NOTIFYROWUNDOCHANGE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
101 { DBPROP_NOTIFYROWUNDODELETE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
102 { DBPROP_NOTIFYROWUNDOINSERT
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
103 { DBPROP_NOTIFYROWUPDATE
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 3 },
104 { DBPROP_CHANGEINSERTEDROWS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_TRUE
},
105 { DBPROP_RETURNPENDINGINSERTS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
106 { DBPROP_IConvertType
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_TRUE
},
107 { DBPROP_NOTIFICATIONGRANULARITY
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_I4
, 1 },
108 { DBPROP_IMultipleResults
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
109 { DBPROP_ACCESSORDER
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_I4
, 1 },
110 { DBPROP_BOOKMARKINFO
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 0 },
111 { DBPROP_UNIQUEROWS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
112 { DBPROP_IRowsetFind
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
113 { DBPROP_IRowsetScroll
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_TRUE
},
114 { DBPROP_IRowsetRefresh
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_TRUE
},
115 { DBPROP_FINDCOMPAREOPS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
, VT_I4
, 27 },
116 { DBPROP_ORDEREDBOOKMARKS
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_TRUE
},
117 { DBPROP_CLIENTCURSOR
, DBPROPFLAGS_ROWSET
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_TRUE
},
118 { DBPROP_ABORTPRESERVE
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
119 { DBPROP_ACTIVESESSIONS
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
120 { DBPROP_ASYNCTXNCOMMIT
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
, VT_BOOL
, VARIANT_FALSE
},
121 { DBPROP_AUTH_CACHE_AUTHINFO
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
122 { DBPROP_AUTH_ENCRYPT_PASSWORD
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_I4
, 0 },
123 { DBPROP_AUTH_INTEGRATED
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_I4
, 14 },
124 { DBPROP_AUTH_MASK_PASSWORD
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
125 { DBPROP_AUTH_PASSWORD
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
126 { DBPROP_AUTH_PERSIST_ENCRYPTED
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
127 { DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
128 { DBPROP_AUTH_USERID
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
129 { DBPROP_BLOCKINGSTORAGEOBJECTS
, DBPROPFLAGS_DATASOURCEINFO
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
, VT_BOOL
, VARIANT_FALSE
},
132 struct msdasql_session
134 IUnknown session_iface
;
135 IGetDataSource IGetDataSource_iface
;
136 IOpenRowset IOpenRowset_iface
;
137 ISessionProperties ISessionProperties_iface
;
138 IDBCreateCommand IDBCreateCommand_iface
;
139 ITransactionJoin ITransactionJoin_iface
;
140 ITransaction ITransaction_iface
;
143 IUnknown
*datasource
;
148 static inline struct msdasql_session
*impl_from_IUnknown( IUnknown
*iface
)
150 return CONTAINING_RECORD( iface
, struct msdasql_session
, session_iface
);
153 static inline struct msdasql_session
*impl_from_IGetDataSource( IGetDataSource
*iface
)
155 return CONTAINING_RECORD( iface
, struct msdasql_session
, IGetDataSource_iface
);
158 static inline struct msdasql_session
*impl_from_IOpenRowset( IOpenRowset
*iface
)
160 return CONTAINING_RECORD( iface
, struct msdasql_session
, IOpenRowset_iface
);
163 static inline struct msdasql_session
*impl_from_ISessionProperties( ISessionProperties
*iface
)
165 return CONTAINING_RECORD( iface
, struct msdasql_session
, ISessionProperties_iface
);
168 static inline struct msdasql_session
*impl_from_IDBCreateCommand( IDBCreateCommand
*iface
)
170 return CONTAINING_RECORD( iface
, struct msdasql_session
, IDBCreateCommand_iface
);
173 static inline struct msdasql_session
*impl_from_ITransactionJoin( ITransactionJoin
*iface
)
175 return CONTAINING_RECORD( iface
, struct msdasql_session
, ITransactionJoin_iface
);
178 static inline struct msdasql_session
*impl_from_ITransaction( ITransaction
*iface
)
180 return CONTAINING_RECORD( iface
, struct msdasql_session
, ITransaction_iface
);
183 static HRESULT WINAPI
session_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
185 struct msdasql_session
*session
= impl_from_IUnknown( iface
);
187 TRACE( "%p, %s, %p\n", iface
, debugstr_guid(riid
), ppv
);
190 if(IsEqualGUID(&IID_IUnknown
, riid
))
192 TRACE("(%p)->(IID_IUnknown %p)\n", iface
, ppv
);
193 *ppv
= &session
->session_iface
;
195 else if(IsEqualGUID(&IID_IGetDataSource
, riid
))
197 TRACE("(%p)->(IID_IGetDataSource %p)\n", iface
, ppv
);
198 *ppv
= &session
->IGetDataSource_iface
;
200 else if(IsEqualGUID(&IID_IOpenRowset
, riid
))
202 TRACE("(%p)->(IID_IOpenRowset %p)\n", iface
, ppv
);
203 *ppv
= &session
->IOpenRowset_iface
;
205 else if(IsEqualGUID(&IID_ISessionProperties
, riid
))
207 TRACE("(%p)->(IID_ISessionProperties %p)\n", iface
, ppv
);
208 *ppv
= &session
->ISessionProperties_iface
;
210 else if(IsEqualGUID(&IID_IDBCreateCommand
, riid
))
212 TRACE("(%p)->(IDBCreateCommand_iface %p)\n", iface
, ppv
);
213 *ppv
= &session
->IDBCreateCommand_iface
;
215 else if(IsEqualGUID(&IID_ITransactionJoin
, riid
))
217 TRACE("(%p)->(ITransactionJoin %p)\n", iface
, ppv
);
218 *ppv
= &session
->ITransactionJoin_iface
;
220 else if(IsEqualGUID(&IID_ITransaction
, riid
))
222 TRACE("(%p)->(ITransaction %p)\n", iface
, ppv
);
223 *ppv
= &session
->ITransaction_iface
;
225 else if(IsEqualGUID(&IID_IBindResource
, riid
))
227 TRACE("(%p)->(IID_IBindResource not support)\n", iface
);
228 return E_NOINTERFACE
;
230 else if(IsEqualGUID(&IID_ICreateRow
, riid
))
232 TRACE("(%p)->(IID_ICreateRow not support)\n", iface
);
233 return E_NOINTERFACE
;
238 IUnknown_AddRef((IUnknown
*)*ppv
);
242 FIXME("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
243 return E_NOINTERFACE
;
246 static ULONG WINAPI
session_AddRef(IUnknown
*iface
)
248 struct msdasql_session
*session
= impl_from_IUnknown( iface
);
249 LONG refs
= InterlockedIncrement( &session
->refs
);
250 TRACE( "%p new refcount %ld\n", session
, refs
);
254 static ULONG WINAPI
session_Release(IUnknown
*iface
)
256 struct msdasql_session
*session
= impl_from_IUnknown( iface
);
257 LONG refs
= InterlockedDecrement( &session
->refs
);
258 TRACE( "%p new refcount %ld\n", session
, refs
);
261 TRACE( "destroying %p\n", session
);
263 IUnknown_Release(session
->datasource
);
264 heap_free( session
);
269 static const IUnknownVtbl unkfactoryVtbl
=
271 session_QueryInterface
,
277 HRESULT WINAPI
datasource_QueryInterface(IGetDataSource
*iface
, REFIID riid
, void **out
)
279 struct msdasql_session
*session
= impl_from_IGetDataSource( iface
);
280 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
283 ULONG WINAPI
datasource_AddRef(IGetDataSource
*iface
)
285 struct msdasql_session
*session
= impl_from_IGetDataSource( iface
);
286 return IUnknown_AddRef(&session
->session_iface
);
289 ULONG WINAPI
datasource_Release(IGetDataSource
*iface
)
291 struct msdasql_session
*session
= impl_from_IGetDataSource( iface
);
292 return IUnknown_Release(&session
->session_iface
);
295 HRESULT WINAPI
datasource_GetDataSource(IGetDataSource
*iface
, REFIID riid
, IUnknown
**datasource
)
297 struct msdasql_session
*session
= impl_from_IGetDataSource( iface
);
299 TRACE("%p, %s, %p stub\n", session
, debugstr_guid(riid
), datasource
);
304 return IUnknown_QueryInterface(session
->datasource
, riid
, (void**)datasource
);
307 static const IGetDataSourceVtbl datasourceVtbl
=
309 datasource_QueryInterface
,
312 datasource_GetDataSource
315 HRESULT WINAPI
openrowset_QueryInterface(IOpenRowset
*iface
, REFIID riid
, void **out
)
317 struct msdasql_session
*session
= impl_from_IOpenRowset( iface
);
318 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
321 ULONG WINAPI
openrowset_AddRef(IOpenRowset
*iface
)
323 struct msdasql_session
*session
= impl_from_IOpenRowset( iface
);
324 return IUnknown_AddRef(&session
->session_iface
);
327 ULONG WINAPI
openrowset_Release(IOpenRowset
*iface
)
329 struct msdasql_session
*session
= impl_from_IOpenRowset( iface
);
330 return IUnknown_Release(&session
->session_iface
);
333 HRESULT WINAPI
openrowset_OpenRowset(IOpenRowset
*iface
, IUnknown
*pUnkOuter
, DBID
*table
,
334 DBID
*index
, REFIID riid
, ULONG count
, DBPROPSET propertysets
[], IUnknown
**rowset
)
336 struct msdasql_session
*session
= impl_from_IOpenRowset( iface
);
337 FIXME("%p, %p, %p %p %s, %ld %p %p stub\n", session
, pUnkOuter
, table
, index
, debugstr_guid(riid
),
338 count
, propertysets
, rowset
);
343 static const IOpenRowsetVtbl openrowsetVtbl
=
345 openrowset_QueryInterface
,
348 openrowset_OpenRowset
351 static HRESULT WINAPI
properties_QueryInterface(ISessionProperties
*iface
, REFIID riid
, void **out
)
353 struct msdasql_session
*session
= impl_from_ISessionProperties( iface
);
354 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
357 static ULONG WINAPI
properties_AddRef(ISessionProperties
*iface
)
359 struct msdasql_session
*session
= impl_from_ISessionProperties( iface
);
360 return IUnknown_AddRef(&session
->session_iface
);
363 static ULONG WINAPI
properties_Release(ISessionProperties
*iface
)
365 struct msdasql_session
*session
= impl_from_ISessionProperties( iface
);
366 return IUnknown_Release(&session
->session_iface
);
370 static HRESULT WINAPI
properties_GetProperties(ISessionProperties
*iface
, ULONG set_count
,
371 const DBPROPIDSET id_sets
[], ULONG
*count
, DBPROPSET
**sets
)
373 struct msdasql_session
*session
= impl_from_ISessionProperties( iface
);
374 FIXME("%p %lu %p %p %p\n", session
, set_count
, id_sets
, count
, sets
);
379 static HRESULT WINAPI
properties_SetProperties(ISessionProperties
*iface
, ULONG count
,
382 struct msdasql_session
*session
= impl_from_ISessionProperties( iface
);
383 FIXME("%p %lu %p\n", session
, count
, sets
);
388 static const ISessionPropertiesVtbl propertiesVtbl
=
390 properties_QueryInterface
,
393 properties_GetProperties
,
394 properties_SetProperties
397 static HRESULT WINAPI
createcommand_QueryInterface(IDBCreateCommand
*iface
, REFIID riid
, void **out
)
399 struct msdasql_session
*session
= impl_from_IDBCreateCommand( iface
);
400 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
403 static ULONG WINAPI
createcommand_AddRef(IDBCreateCommand
*iface
)
405 struct msdasql_session
*session
= impl_from_IDBCreateCommand( iface
);
406 return IUnknown_AddRef(&session
->session_iface
);
409 static ULONG WINAPI
createcommand_Release(IDBCreateCommand
*iface
)
411 struct msdasql_session
*session
= impl_from_IDBCreateCommand( iface
);
412 return IUnknown_Release(&session
->session_iface
);
417 ICommandText ICommandText_iface
;
418 ICommandProperties ICommandProperties_iface
;
419 IColumnsInfo IColumnsInfo_iface
;
420 IConvertType IConvertType_iface
;
421 ICommandPrepare ICommandPrepare_iface
;
422 ICommandWithParameters ICommandWithParameters_iface
;
429 struct msdasql_prop
*properties
;
433 static inline struct command
*impl_from_ICommandText( ICommandText
*iface
)
435 return CONTAINING_RECORD( iface
, struct command
, ICommandText_iface
);
438 static inline struct command
*impl_from_ICommandProperties( ICommandProperties
*iface
)
440 return CONTAINING_RECORD( iface
, struct command
, ICommandProperties_iface
);
443 static inline struct command
*impl_from_IColumnsInfo( IColumnsInfo
*iface
)
445 return CONTAINING_RECORD( iface
, struct command
, IColumnsInfo_iface
);
448 static inline struct command
*impl_from_IConvertType( IConvertType
*iface
)
450 return CONTAINING_RECORD( iface
, struct command
, IConvertType_iface
);
453 static inline struct command
*impl_from_ICommandPrepare( ICommandPrepare
*iface
)
455 return CONTAINING_RECORD( iface
, struct command
, ICommandPrepare_iface
);
458 static inline struct command
*impl_from_ICommandWithParameters( ICommandWithParameters
*iface
)
460 return CONTAINING_RECORD( iface
, struct command
, ICommandWithParameters_iface
);
463 static HRESULT WINAPI
command_QueryInterface(ICommandText
*iface
, REFIID riid
, void **ppv
)
465 struct command
*command
= impl_from_ICommandText( iface
);
467 TRACE( "%p, %s, %p\n", command
, debugstr_guid(riid
), ppv
);
470 if(IsEqualGUID(&IID_IUnknown
, riid
) ||
471 IsEqualGUID(&IID_ICommand
, riid
) ||
472 IsEqualGUID(&IID_ICommandText
, riid
))
474 *ppv
= &command
->ICommandText_iface
;
476 else if(IsEqualGUID(&IID_ICommandProperties
, riid
))
478 *ppv
= &command
->ICommandProperties_iface
;
480 else if(IsEqualGUID(&IID_IColumnsInfo
, riid
))
482 *ppv
= &command
->IColumnsInfo_iface
;
484 else if(IsEqualGUID(&IID_IConvertType
, riid
))
486 *ppv
= &command
->IConvertType_iface
;
488 else if(IsEqualGUID(&IID_ICommandPrepare
, riid
))
490 *ppv
= &command
->ICommandPrepare_iface
;
492 else if(IsEqualGUID(&IID_ICommandWithParameters
, riid
))
494 *ppv
= &command
->ICommandWithParameters_iface
;
499 IUnknown_AddRef((IUnknown
*)*ppv
);
502 else if (IsEqualGUID(&IID_IMultipleResults
, riid
))
504 TRACE("IID_IMultipleResults not supported\n");
505 return E_NOINTERFACE
;
507 else if(IsEqualGUID(&IID_ICommandStream
, riid
))
509 TRACE("ICommandStream not support\n");
510 return E_NOINTERFACE
;
512 else if (IsEqualGUID(&IID_IRowsetChange
, riid
))
514 TRACE("IID_IRowsetChange not supported\n");
515 return E_NOINTERFACE
;
517 else if (IsEqualGUID(&IID_IRowsetUpdate
, riid
))
519 TRACE("IID_IRowsetUpdate not supported\n");
520 return E_NOINTERFACE
;
522 else if (IsEqualGUID(&IID_IRowsetLocate
, riid
))
524 TRACE("IID_IRowsetLocate not supported\n");
525 return E_NOINTERFACE
;
528 FIXME("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
529 return E_NOINTERFACE
;
532 static ULONG WINAPI
command_AddRef(ICommandText
*iface
)
534 struct command
*command
= impl_from_ICommandText( iface
);
535 LONG refs
= InterlockedIncrement( &command
->refs
);
536 TRACE( "%p new refcount %ld\n", command
, refs
);
540 static ULONG WINAPI
command_Release(ICommandText
*iface
)
542 struct command
*command
= impl_from_ICommandText( iface
);
543 LONG refs
= InterlockedDecrement( &command
->refs
);
544 TRACE( "%p new refcount %ld\n", command
, refs
);
547 TRACE( "destroying %p\n", command
);
548 if (command
->properties
)
549 heap_free(command
->properties
);
550 if (command
->session
)
551 IUnknown_Release(command
->session
);
554 SQLFreeHandle(SQL_HANDLE_STMT
, command
->hstmt
);
556 heap_free( command
->query
);
557 heap_free( command
);
562 static HRESULT WINAPI
command_Cancel(ICommandText
*iface
)
564 struct command
*command
= impl_from_ICommandText( iface
);
565 FIXME("%p\n", command
);
569 struct msdasql_rowset
571 IRowset IRowset_iface
;
572 IRowsetInfo IRowsetInfo_iface
;
573 IColumnsInfo IColumnsInfo_iface
;
574 IAccessor IAccessor_iface
;
575 IColumnsRowset IColumnsRowset_iface
;
581 static inline struct msdasql_rowset
*impl_from_IRowset( IRowset
*iface
)
583 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IRowset_iface
);
586 static inline struct msdasql_rowset
*impl_from_IRowsetInfo( IRowsetInfo
*iface
)
588 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IRowsetInfo_iface
);
591 static inline struct msdasql_rowset
*rowset_impl_from_IColumnsInfo( IColumnsInfo
*iface
)
593 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IColumnsInfo_iface
);
596 static inline struct msdasql_rowset
*impl_from_IAccessor ( IAccessor
*iface
)
598 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IAccessor_iface
);
601 static inline struct msdasql_rowset
*impl_from_IColumnsRowset ( IColumnsRowset
*iface
)
603 return CONTAINING_RECORD( iface
, struct msdasql_rowset
, IColumnsRowset_iface
);
606 static HRESULT WINAPI
msdasql_rowset_QueryInterface(IRowset
*iface
, REFIID riid
, void **ppv
)
608 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
610 TRACE( "%p, %s, %p\n", rowset
, debugstr_guid(riid
), ppv
);
613 if(IsEqualGUID(&IID_IUnknown
, riid
) ||
614 IsEqualGUID(&IID_IRowset
, riid
))
616 *ppv
= &rowset
->IRowset_iface
;
618 else if (IsEqualGUID(&IID_IRowsetInfo
, riid
))
620 *ppv
= &rowset
->IRowsetInfo_iface
;
622 else if (IsEqualGUID(&IID_IColumnsInfo
, riid
))
624 *ppv
= &rowset
->IColumnsInfo_iface
;
626 else if(IsEqualGUID(&IID_IAccessor
, riid
))
628 *ppv
= &rowset
->IAccessor_iface
;
630 else if(IsEqualGUID(&IID_IColumnsRowset
, riid
))
632 *ppv
= &rowset
->IColumnsRowset_iface
;
634 else if (IsEqualGUID(&IID_IRowsetChange
, riid
))
636 TRACE("IID_IRowsetChange not supported\n");
637 return E_NOINTERFACE
;
639 else if (IsEqualGUID(&IID_IRowsetUpdate
, riid
))
641 TRACE("IID_IRowsetUpdate not supported\n");
642 return E_NOINTERFACE
;
644 else if (IsEqualGUID(&IID_IRowsetLocate
, riid
))
646 TRACE("IID_IRowsetLocate not supported\n");
647 return E_NOINTERFACE
;
652 IUnknown_AddRef((IUnknown
*)*ppv
);
656 FIXME("(%p)->(%s %p)\n", iface
, debugstr_guid(riid
), ppv
);
657 return E_NOINTERFACE
;
660 static ULONG WINAPI
msdasql_rowset_AddRef(IRowset
*iface
)
662 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
663 LONG refs
= InterlockedIncrement( &rowset
->refs
);
664 TRACE( "%p new refcount %ld\n", rowset
, refs
);
668 static ULONG WINAPI
msdasql_rowset_Release(IRowset
*iface
)
670 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
671 LONG refs
= InterlockedDecrement( &rowset
->refs
);
672 TRACE( "%p new refcount %ld\n", rowset
, refs
);
675 TRACE( "destroying %p\n", rowset
);
677 SQLFreeHandle(SQL_HANDLE_STMT
, rowset
->hstmt
);
680 IUnknown_Release(rowset
->caller
);
687 static HRESULT WINAPI
msdasql_rowset_AddRefRows(IRowset
*iface
, DBCOUNTITEM count
,
688 const HROW rows
[], DBREFCOUNT ref_counts
[], DBROWSTATUS status
[])
690 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
691 FIXME("%p, %Id, %p, %p, %p\n", rowset
, count
, rows
, ref_counts
, status
);
695 static HRESULT WINAPI
msdasql_rowset_GetData(IRowset
*iface
, HROW row
, HACCESSOR accessor
, void *data
)
697 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
698 FIXME("%p, %Id, %Id, %p\n", rowset
, row
, accessor
, data
);
702 static HRESULT WINAPI
msdasql_rowset_GetNextRows(IRowset
*iface
, HCHAPTER reserved
, DBROWOFFSET offset
,
703 DBROWCOUNT count
, DBCOUNTITEM
*obtained
, HROW
**rows
)
705 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
706 FIXME("%p, %Id, %Id, %Id, %p, %p\n", rowset
, reserved
, offset
, count
, obtained
, rows
);
710 static HRESULT WINAPI
msdasql_rowset_ReleaseRows(IRowset
*iface
, DBCOUNTITEM count
,
711 const HROW rows
[], DBROWOPTIONS options
[], DBREFCOUNT ref_counts
[], DBROWSTATUS status
[])
713 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
715 FIXME("%p, %Id, %p, %p, %p, %p\n", rowset
, count
, rows
, options
, ref_counts
, status
);
719 static HRESULT WINAPI
msdasql_rowset_RestartPosition(IRowset
*iface
, HCHAPTER reserved
)
721 struct msdasql_rowset
*rowset
= impl_from_IRowset( iface
);
722 FIXME("%p, %Id\n", rowset
, reserved
);
726 static const struct IRowsetVtbl msdasql_rowset_vtbl
=
728 msdasql_rowset_QueryInterface
,
729 msdasql_rowset_AddRef
,
730 msdasql_rowset_Release
,
731 msdasql_rowset_AddRefRows
,
732 msdasql_rowset_GetData
,
733 msdasql_rowset_GetNextRows
,
734 msdasql_rowset_ReleaseRows
,
735 msdasql_rowset_RestartPosition
738 static HRESULT WINAPI
rowset_info_QueryInterface(IRowsetInfo
*iface
, REFIID riid
, void **ppv
)
740 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
741 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, ppv
);
744 static ULONG WINAPI
rowset_info_AddRef(IRowsetInfo
*iface
)
746 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
747 return IRowset_AddRef(&rowset
->IRowset_iface
);
750 static ULONG WINAPI
rowset_info_Release(IRowsetInfo
*iface
)
752 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
753 return IRowset_Release(&rowset
->IRowset_iface
);
756 static HRESULT WINAPI
rowset_info_GetProperties(IRowsetInfo
*iface
, const ULONG count
,
757 const DBPROPIDSET propertyidsets
[], ULONG
*out_count
, DBPROPSET
**propertysets
)
759 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
760 FIXME("%p, %lu, %p, %p, %p\n", rowset
, count
, propertyidsets
, out_count
, propertysets
);
764 static HRESULT WINAPI
rowset_info_GetReferencedRowset(IRowsetInfo
*iface
, DBORDINAL ordinal
,
765 REFIID riid
, IUnknown
**unk
)
767 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
768 FIXME("%p, %Id, %s, %p\n", rowset
, ordinal
, debugstr_guid(riid
), unk
);
772 static HRESULT WINAPI
rowset_info_GetSpecification(IRowsetInfo
*iface
, REFIID riid
,
773 IUnknown
**specification
)
775 struct msdasql_rowset
*rowset
= impl_from_IRowsetInfo( iface
);
777 TRACE("%p, %s, %p\n", rowset
, debugstr_guid(riid
), specification
);
785 return IUnknown_QueryInterface(rowset
->caller
, riid
, (void**)specification
);
788 struct IRowsetInfoVtbl rowset_info_vtbl
=
790 rowset_info_QueryInterface
,
793 rowset_info_GetProperties
,
794 rowset_info_GetReferencedRowset
,
795 rowset_info_GetSpecification
798 static HRESULT WINAPI
rowset_colsinfo_QueryInterface(IColumnsInfo
*iface
, REFIID riid
, void **out
)
800 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
801 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, out
);
804 static ULONG WINAPI
rowset_colsinfo_AddRef(IColumnsInfo
*iface
)
806 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
807 return IRowset_AddRef(&rowset
->IRowset_iface
);
810 static ULONG WINAPI
rowset_colsinfo_Release(IColumnsInfo
*iface
)
812 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
813 return IRowset_Release(&rowset
->IRowset_iface
);
816 static HRESULT WINAPI
rowset_colsinfo_GetColumnInfo(IColumnsInfo
*iface
, DBORDINAL
*columns
,
817 DBCOLUMNINFO
**colinfo
, OLECHAR
**stringsbuffer
)
819 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
820 FIXME("%p, %p, %p, %p\n", rowset
, columns
, colinfo
, stringsbuffer
);
824 static HRESULT WINAPI
rowset_colsinfo_MapColumnIDs(IColumnsInfo
*iface
, DBORDINAL column_ids
,
825 const DBID
*dbids
, DBORDINAL
*columns
)
827 struct msdasql_rowset
*rowset
= rowset_impl_from_IColumnsInfo( iface
);
828 FIXME("%p, %Id, %p, %p\n", rowset
, column_ids
, dbids
, columns
);
832 static struct IColumnsInfoVtbl rowset_columninfo_vtbll
=
834 rowset_colsinfo_QueryInterface
,
835 rowset_colsinfo_AddRef
,
836 rowset_colsinfo_Release
,
837 rowset_colsinfo_GetColumnInfo
,
838 rowset_colsinfo_MapColumnIDs
841 static HRESULT WINAPI
rowset_accessor_QueryInterface(IAccessor
*iface
, REFIID riid
, void **out
)
843 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
844 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, out
);
847 static ULONG WINAPI
rowset_accessor_AddRef(IAccessor
*iface
)
849 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
850 return IRowset_AddRef(&rowset
->IRowset_iface
);
853 static ULONG WINAPI
rowset_accessor_Release(IAccessor
*iface
)
855 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
856 return IRowset_Release(&rowset
->IRowset_iface
);
859 static HRESULT WINAPI
rowset_accessor_AddRefAccessor(IAccessor
*iface
, HACCESSOR accessor
, DBREFCOUNT
*count
)
861 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
862 FIXME("%p, %Id, %p\n", rowset
, accessor
, count
);
866 static HRESULT WINAPI
rowset_accessor_CreateAccessor(IAccessor
*iface
, DBACCESSORFLAGS flags
,
867 DBCOUNTITEM count
, const DBBINDING bindings
[], DBLENGTH row_size
, HACCESSOR
*accessor
,
868 DBBINDSTATUS status
[])
870 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
871 FIXME("%p, 0x%08lx, %Id, %p, %Id, %p, %p\n", rowset
, flags
, count
, bindings
, row_size
, accessor
, status
);
875 static HRESULT WINAPI
rowset_accessor_GetBindings(IAccessor
*iface
, HACCESSOR accessor
,
876 DBACCESSORFLAGS
*flags
, DBCOUNTITEM
*count
, DBBINDING
**bindings
)
878 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
879 FIXME("%p, %Id, %p, %p, %p\n", rowset
, accessor
, flags
, count
, bindings
);
883 static HRESULT WINAPI
rowset_accessor_ReleaseAccessor(IAccessor
*iface
, HACCESSOR accessor
, DBREFCOUNT
*count
)
885 struct msdasql_rowset
*rowset
= impl_from_IAccessor( iface
);
886 FIXME("%p, %Id, %p\n", rowset
, accessor
, count
);
890 struct IAccessorVtbl accessor_vtbl
=
892 rowset_accessor_QueryInterface
,
893 rowset_accessor_AddRef
,
894 rowset_accessor_Release
,
895 rowset_accessor_AddRefAccessor
,
896 rowset_accessor_CreateAccessor
,
897 rowset_accessor_GetBindings
,
898 rowset_accessor_ReleaseAccessor
901 static HRESULT WINAPI
column_rs_QueryInterface(IColumnsRowset
*iface
, REFIID riid
, void **out
)
903 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
904 return IRowset_QueryInterface(&rowset
->IRowset_iface
, riid
, out
);
907 static ULONG WINAPI
column_rs_AddRef(IColumnsRowset
*iface
)
909 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
910 return IRowset_AddRef(&rowset
->IRowset_iface
);
913 static ULONG WINAPI
column_rs_Release(IColumnsRowset
*iface
)
915 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
916 return IRowset_Release(&rowset
->IRowset_iface
);
919 static HRESULT WINAPI
column_rs_GetAvailableColumns(IColumnsRowset
*iface
, DBORDINAL
*count
, DBID
**columns
)
921 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
922 FIXME("%p, %p, %p\n", rowset
, count
, columns
);
926 static HRESULT WINAPI
column_rs_GetColumnsRowset(IColumnsRowset
*iface
, IUnknown
*outer
, DBORDINAL count
,
927 const DBID columns
[], REFIID riid
, ULONG property_cnt
, DBPROPSET property_sets
[], IUnknown
**unk_rs
)
929 struct msdasql_rowset
*rowset
= impl_from_IColumnsRowset( iface
);
930 FIXME("(%p)->(%p, %Id, %p, %s, %lu, %p, %p): stub\n", rowset
, outer
, count
, columns
, debugstr_guid(riid
),
931 property_cnt
, property_sets
, unk_rs
);
935 struct IColumnsRowsetVtbl columnrs_rs_vtbl
=
937 column_rs_QueryInterface
,
940 column_rs_GetAvailableColumns
,
941 column_rs_GetColumnsRowset
944 static HRESULT WINAPI
command_Execute(ICommandText
*iface
, IUnknown
*outer
, REFIID riid
,
945 DBPARAMS
*params
, DBROWCOUNT
*affected
, IUnknown
**rowset
)
947 struct command
*command
= impl_from_ICommandText( iface
);
948 struct msdasql_rowset
*msrowset
;
951 SQLHSTMT hstmt
= command
->hstmt
;
954 TRACE("%p, %p, %s, %p %p %p\n", command
, outer
, debugstr_guid(riid
), params
, affected
, rowset
);
957 SQLAllocHandle(SQL_HANDLE_STMT
, command
->hdbc
, &hstmt
);
959 ret
= SQLExecDirectW(hstmt
, command
->query
, SQL_NTS
);
960 if (ret
!= SQL_SUCCESS
)
962 dump_sql_diag_records(SQL_HANDLE_STMT
, hstmt
);
966 ret
= SQLRowCount(hstmt
, &results
);
967 if (ret
!= SQL_SUCCESS
)
968 ERR("SQLRowCount failed (%d)\n", ret
);
974 if (!wcsnicmp( command
->query
, L
"select ", 7 ))
976 msrowset
= heap_alloc(sizeof(*msrowset
));
978 return E_OUTOFMEMORY
;
980 command
->hstmt
= NULL
;
982 msrowset
->IRowset_iface
.lpVtbl
= &msdasql_rowset_vtbl
;
983 msrowset
->IRowsetInfo_iface
.lpVtbl
= &rowset_info_vtbl
;
984 msrowset
->IColumnsInfo_iface
.lpVtbl
= &rowset_columninfo_vtbll
;
985 msrowset
->IAccessor_iface
.lpVtbl
= &accessor_vtbl
;
986 msrowset
->IColumnsRowset_iface
.lpVtbl
= &columnrs_rs_vtbl
;
988 ICommandText_QueryInterface(iface
, &IID_IUnknown
, (void**)&msrowset
->caller
);
989 msrowset
->hstmt
= hstmt
;
991 hr
= IRowset_QueryInterface(&msrowset
->IRowset_iface
, riid
, (void**)rowset
);
992 IRowset_Release(&msrowset
->IRowset_iface
);
995 SQLFreeStmt(hstmt
, SQL_CLOSE
);
1000 static HRESULT WINAPI
command_GetDBSession(ICommandText
*iface
, REFIID riid
, IUnknown
**session
)
1002 struct command
*command
= impl_from_ICommandText( iface
);
1004 TRACE("%p, %s, %p\n", command
, debugstr_guid(riid
), session
);
1007 return E_INVALIDARG
;
1011 if (!command
->session
)
1014 return IUnknown_QueryInterface(command
->session
, riid
, (void**)session
);
1017 static HRESULT WINAPI
command_GetCommandText(ICommandText
*iface
, GUID
*dialect
, LPOLESTR
*commandstr
)
1019 struct command
*command
= impl_from_ICommandText( iface
);
1021 TRACE("%p, %p, %p\n", command
, dialect
, commandstr
);
1023 if (!command
->query
)
1024 return DB_E_NOCOMMAND
;
1026 if (dialect
&& !IsEqualGUID(&DBGUID_DEFAULT
, dialect
))
1028 *dialect
= DBGUID_DEFAULT
;
1029 hr
= DB_S_DIALECTIGNORED
;
1032 *commandstr
= heap_alloc((lstrlenW(command
->query
)+1)*sizeof(WCHAR
));
1033 wcscpy(*commandstr
, command
->query
);
1037 static HRESULT WINAPI
command_SetCommandText(ICommandText
*iface
, REFGUID dialect
, LPCOLESTR commandstr
)
1039 struct command
*command
= impl_from_ICommandText( iface
);
1040 TRACE("%p, %s, %s\n", command
, debugstr_guid(dialect
), debugstr_w(commandstr
));
1042 if (!IsEqualGUID(&DBGUID_DEFAULT
, dialect
))
1043 FIXME("Currently non Default Dialect isn't supported\n");
1045 heap_free(command
->query
);
1049 command
->query
= heap_alloc((lstrlenW(commandstr
)+1)*sizeof(WCHAR
));
1050 if (!command
->query
)
1051 return E_OUTOFMEMORY
;
1053 wcscpy(command
->query
, commandstr
);
1056 command
->query
= NULL
;
1060 static const ICommandTextVtbl commandVtbl
=
1062 command_QueryInterface
,
1067 command_GetDBSession
,
1068 command_GetCommandText
,
1069 command_SetCommandText
1072 static HRESULT WINAPI
command_prop_QueryInterface(ICommandProperties
*iface
, REFIID riid
, void **out
)
1074 struct command
*command
= impl_from_ICommandProperties( iface
);
1075 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1078 static ULONG WINAPI
command_prop_AddRef(ICommandProperties
*iface
)
1080 struct command
*command
= impl_from_ICommandProperties( iface
);
1081 return ICommandText_AddRef(&command
->ICommandText_iface
);
1084 static ULONG WINAPI
command_prop_Release(ICommandProperties
*iface
)
1086 struct command
*command
= impl_from_ICommandProperties( iface
);
1087 return ICommandText_Release(&command
->ICommandText_iface
);
1090 static ULONG
get_property_count(DWORD flag
, struct msdasql_prop
*properties
, int prop_count
)
1094 for(i
=0; i
< prop_count
; i
++)
1096 if (properties
[i
].flags
& flag
)
1103 static HRESULT WINAPI
command_prop_GetProperties(ICommandProperties
*iface
, ULONG count
,
1104 const DBPROPIDSET propertyidsets
[], ULONG
*sets_cnt
, DBPROPSET
**propertyset
)
1106 struct command
*command
= impl_from_ICommandProperties( iface
);
1107 DBPROPSET
*propset
= NULL
;
1110 TRACE("%p %ld %p %p %p\n", command
, count
, propertyidsets
, sets_cnt
, propertyset
);
1112 /* All Properties */
1116 propset
= CoTaskMemAlloc(2 * sizeof(DBPROPSET
));
1118 return E_OUTOFMEMORY
;
1120 propset
[0].guidPropertySet
= DBPROPSET_ROWSET
;
1121 propset
[0].cProperties
= get_property_count(DBPROPFLAGS_ROWSET
, command
->properties
, command
->prop_count
);
1122 propset
[0].rgProperties
= CoTaskMemAlloc(propset
[0].cProperties
* sizeof(DBPROP
));
1123 if (!propset
[0].rgProperties
)
1125 CoTaskMemFree(propset
);
1126 return E_OUTOFMEMORY
;
1130 for (j
=0; j
< command
->prop_count
; j
++)
1132 if (!(command
->properties
[j
].flags
& DBPROPFLAGS_ROWSET
))
1134 propset
[0].rgProperties
[idx
].dwPropertyID
= command
->properties
[j
].property_id
;
1136 V_VT(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].vartype
;
1137 if (command
->properties
[j
].vartype
== VT_BOOL
)
1139 V_BOOL(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1141 else if (command
->properties
[j
].vartype
== VT_I4
)
1143 V_I4(&propset
[0].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1146 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1151 propset
[1].guidPropertySet
= DBPROPSET_PROVIDERROWSET
;
1152 propset
[1].cProperties
= get_property_count(DBPROPFLAGS_DATASOURCEINFO
, command
->properties
, command
->prop_count
);
1153 propset
[1].rgProperties
= CoTaskMemAlloc(propset
[1].cProperties
* sizeof(DBPROP
));
1154 if (!propset
[1].rgProperties
)
1156 CoTaskMemFree(propset
[0].rgProperties
);
1157 CoTaskMemFree(propset
);
1158 return E_OUTOFMEMORY
;
1162 for (j
=0; j
< command
->prop_count
; j
++)
1164 if (!(command
->properties
[j
].flags
& DBPROPFLAGS_DATASOURCEINFO
))
1166 propset
[1].rgProperties
[idx
].dwPropertyID
= command
->properties
[j
].property_id
;
1168 V_VT(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].vartype
;
1169 if (command
->properties
[j
].vartype
== VT_BOOL
)
1171 V_BOOL(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1173 else if (command
->properties
[j
].vartype
== VT_I4
)
1175 V_I4(&propset
[1].rgProperties
[idx
].vValue
) = command
->properties
[j
].value
;
1178 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1187 propset
= CoTaskMemAlloc(count
* sizeof(DBPROPSET
));
1189 return E_OUTOFMEMORY
;
1191 for (i
=0; i
< count
; i
++)
1193 TRACE("Property id %d (count %ld, set %s)\n", i
, propertyidsets
[i
].cPropertyIDs
,
1194 debugstr_guid(&propertyidsets
[i
].guidPropertySet
));
1196 propset
[i
].cProperties
= propertyidsets
[i
].cPropertyIDs
;
1197 propset
[i
].rgProperties
= CoTaskMemAlloc(propset
[i
].cProperties
* sizeof(DBPROP
));
1199 for (j
=0; j
< propset
[i
].cProperties
; j
++)
1201 propset
[i
].rgProperties
[j
].dwPropertyID
= propertyidsets
[i
].rgPropertyIDs
[j
];
1203 for(k
= 0; k
< command
->prop_count
; k
++)
1205 if (command
->properties
[k
].property_id
== propertyidsets
[i
].rgPropertyIDs
[j
])
1207 V_VT(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].vartype
;
1208 if (command
->properties
[j
].vartype
== VT_BOOL
)
1210 V_BOOL(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].value
;
1212 else if (command
->properties
[j
].vartype
== VT_I4
)
1214 V_I4(&propset
[i
].rgProperties
[i
].vValue
) = command
->properties
[j
].value
;
1217 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1227 *propertyset
= propset
;
1232 static HRESULT WINAPI
command_prop_SetProperties(ICommandProperties
*iface
, ULONG count
,
1233 DBPROPSET propertyset
[])
1235 struct command
*command
= impl_from_ICommandProperties( iface
);
1238 TRACE("%p %lu, %p\n", command
, count
, propertyset
);
1240 for(i
=0; i
< count
; i
++)
1242 TRACE("set %s, count %ld\n", debugstr_guid(&propertyset
[i
].guidPropertySet
), propertyset
[i
].cProperties
);
1243 for(j
=0; j
< propertyset
[i
].cProperties
; j
++)
1245 for(k
=0; k
< command
->prop_count
; k
++)
1247 if (command
->properties
[k
].property_id
== propertyset
[i
].rgProperties
[j
].dwPropertyID
)
1249 TRACE("Found property 0x%08lx\n", command
->properties
[k
].property_id
);
1250 if (command
->properties
[k
].flags
& DBPROPFLAGS_WRITE
)
1252 if (command
->properties
[k
].vartype
== VT_BOOL
)
1254 command
->properties
[k
].value
= V_BOOL(&propertyset
[i
].rgProperties
[j
].vValue
);
1256 else if (command
->properties
[k
].vartype
== VT_I4
)
1258 command
->properties
[k
].value
= V_I4(&propertyset
[i
].rgProperties
[j
].vValue
);
1261 ERR("Unknown variant type %d\n", command
->properties
[j
].vartype
);
1264 WARN("Attempting to set Readonly property\n");
1274 static const ICommandPropertiesVtbl commonpropsVtbl
=
1276 command_prop_QueryInterface
,
1277 command_prop_AddRef
,
1278 command_prop_Release
,
1279 command_prop_GetProperties
,
1280 command_prop_SetProperties
1283 static HRESULT WINAPI
colsinfo_QueryInterface(IColumnsInfo
*iface
, REFIID riid
, void **out
)
1285 struct command
*command
= impl_from_IColumnsInfo( iface
);
1286 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1289 static ULONG WINAPI
colsinfo_AddRef(IColumnsInfo
*iface
)
1291 struct command
*command
= impl_from_IColumnsInfo( iface
);
1292 return ICommandText_AddRef(&command
->ICommandText_iface
);
1295 static ULONG WINAPI
colsinfo_Release(IColumnsInfo
*iface
)
1297 struct command
*command
= impl_from_IColumnsInfo( iface
);
1298 return ICommandText_Release(&command
->ICommandText_iface
);
1301 static HRESULT WINAPI
colsinfo_GetColumnInfo(IColumnsInfo
*iface
, DBORDINAL
*columns
,
1302 DBCOLUMNINFO
**colinfo
, OLECHAR
**stringsbuffer
)
1304 struct command
*command
= impl_from_IColumnsInfo( iface
);
1305 FIXME("%p, %p, %p, %p\n", command
, columns
, colinfo
, stringsbuffer
);
1309 static HRESULT WINAPI
colsinfo_MapColumnIDs(IColumnsInfo
*iface
, DBORDINAL column_ids
,
1310 const DBID
*dbids
, DBORDINAL
*columns
)
1312 struct command
*command
= impl_from_IColumnsInfo( iface
);
1313 FIXME("%p, %Iu, %p, %p\n", command
, column_ids
, dbids
, columns
);
1317 static struct IColumnsInfoVtbl columninfoVtbl
=
1319 colsinfo_QueryInterface
,
1322 colsinfo_GetColumnInfo
,
1323 colsinfo_MapColumnIDs
1326 static HRESULT WINAPI
converttype_QueryInterface(IConvertType
*iface
, REFIID riid
, void **out
)
1328 struct command
*command
= impl_from_IConvertType( iface
);
1329 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1332 static ULONG WINAPI
converttype_AddRef(IConvertType
*iface
)
1334 struct command
*command
= impl_from_IConvertType( iface
);
1335 return ICommandText_AddRef(&command
->ICommandText_iface
);
1338 static ULONG WINAPI
converttype_Release(IConvertType
*iface
)
1340 struct command
*command
= impl_from_IConvertType( iface
);
1341 return ICommandText_Release(&command
->ICommandText_iface
);
1344 static HRESULT WINAPI
converttype_CanConvert(IConvertType
*iface
, DBTYPE from
, DBTYPE to
, DBCONVERTFLAGS flags
)
1346 struct command
*command
= impl_from_IConvertType( iface
);
1347 FIXME("%p, %u, %d, 0x%08lx\n", command
, from
, to
, flags
);
1351 static struct IConvertTypeVtbl converttypeVtbl
=
1353 converttype_QueryInterface
,
1355 converttype_Release
,
1356 converttype_CanConvert
1359 static HRESULT WINAPI
commandprepare_QueryInterface(ICommandPrepare
*iface
, REFIID riid
, void **out
)
1361 struct command
*command
= impl_from_ICommandPrepare( iface
);
1362 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1365 static ULONG WINAPI
commandprepare_AddRef(ICommandPrepare
*iface
)
1367 struct command
*command
= impl_from_ICommandPrepare( iface
);
1368 return ICommandText_AddRef(&command
->ICommandText_iface
);
1371 static ULONG WINAPI
commandprepare_Release(ICommandPrepare
*iface
)
1373 struct command
*command
= impl_from_ICommandPrepare( iface
);
1374 return ICommandText_Release(&command
->ICommandText_iface
);
1377 static HRESULT WINAPI
commandprepare_Prepare(ICommandPrepare
*iface
, ULONG runs
)
1379 struct command
*command
= impl_from_ICommandPrepare( iface
);
1382 TRACE("%p, %lu\n", command
, runs
);
1384 if (!command
->query
)
1385 return DB_E_NOCOMMAND
;
1388 SQLFreeHandle(SQL_HANDLE_STMT
, command
->hstmt
);
1390 SQLAllocHandle(SQL_HANDLE_STMT
, command
->hdbc
, &command
->hstmt
);
1392 ret
= SQLPrepareW(command
->hstmt
, command
->query
, SQL_NTS
);
1393 if (ret
!= SQL_SUCCESS
)
1395 dump_sql_diag_records(SQL_HANDLE_STMT
, command
->hstmt
);
1401 static HRESULT WINAPI
commandprepare_Unprepare(ICommandPrepare
*iface
)
1403 struct command
*command
= impl_from_ICommandPrepare( iface
);
1404 TRACE("%p\n", command
);
1408 struct ICommandPrepareVtbl commandprepareVtbl
=
1410 commandprepare_QueryInterface
,
1411 commandprepare_AddRef
,
1412 commandprepare_Release
,
1413 commandprepare_Prepare
,
1414 commandprepare_Unprepare
1417 static HRESULT WINAPI
cmd_with_params_QueryInterface(ICommandWithParameters
*iface
, REFIID riid
, void **out
)
1419 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1420 return ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, out
);
1423 static ULONG WINAPI
cmd_with_params_AddRef(ICommandWithParameters
*iface
)
1425 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1426 return ICommandText_AddRef(&command
->ICommandText_iface
);
1429 static ULONG WINAPI
cmd_with_params_Release(ICommandWithParameters
*iface
)
1431 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1432 return ICommandText_Release(&command
->ICommandText_iface
);
1435 static HRESULT WINAPI
cmd_with_params_GetParameterInfo(ICommandWithParameters
*iface
, DB_UPARAMS
*uparams
,
1436 DBPARAMINFO
**info
, OLECHAR
**buffer
)
1438 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1439 FIXME("%p, %p, %p, %p\n", command
, uparams
, info
, buffer
);
1443 static HRESULT WINAPI
cmd_with_params_MapParameterNames(ICommandWithParameters
*iface
, DB_UPARAMS uparams
,
1444 LPCWSTR names
[], DB_LPARAMS ordinals
[])
1446 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1447 FIXME("%p, %Iu, %p, %p\n", command
, uparams
, names
, ordinals
);
1451 static HRESULT WINAPI
cmd_with_params_SetParameterInfo(ICommandWithParameters
*iface
, DB_UPARAMS uparams
,
1452 const DB_UPARAMS ordinals
[], const DBPARAMBINDINFO bindinfo
[])
1454 struct command
*command
= impl_from_ICommandWithParameters( iface
);
1455 FIXME("%p, %Iu, %p, %p\n", command
, uparams
, ordinals
, bindinfo
);
1459 struct ICommandWithParametersVtbl command_with_params_vtbl
=
1461 cmd_with_params_QueryInterface
,
1462 cmd_with_params_AddRef
,
1463 cmd_with_params_Release
,
1464 cmd_with_params_GetParameterInfo
,
1465 cmd_with_params_MapParameterNames
,
1466 cmd_with_params_SetParameterInfo
1469 static HRESULT WINAPI
createcommand_CreateCommand(IDBCreateCommand
*iface
, IUnknown
*outer
, REFIID riid
,
1472 struct msdasql_session
*session
= impl_from_IDBCreateCommand( iface
);
1473 struct command
*command
;
1476 TRACE("%p, %p, %s, %p\n", session
, outer
, debugstr_guid(riid
), out
);
1479 FIXME("Outer not currently supported\n");
1481 command
= heap_alloc(sizeof(*command
));
1483 return E_OUTOFMEMORY
;
1485 command
->ICommandText_iface
.lpVtbl
= &commandVtbl
;
1486 command
->ICommandProperties_iface
.lpVtbl
= &commonpropsVtbl
;
1487 command
->IColumnsInfo_iface
.lpVtbl
= &columninfoVtbl
;
1488 command
->IConvertType_iface
.lpVtbl
= &converttypeVtbl
;
1489 command
->ICommandPrepare_iface
.lpVtbl
= &commandprepareVtbl
;
1490 command
->ICommandWithParameters_iface
.lpVtbl
= &command_with_params_vtbl
;
1492 command
->query
= NULL
;
1493 command
->hdbc
= session
->hdbc
;
1494 command
->hstmt
= NULL
;
1496 command
->prop_count
= ARRAY_SIZE(msdasql_init_props
);
1497 command
->properties
= heap_alloc(sizeof(msdasql_init_props
));
1498 memcpy(command
->properties
, msdasql_init_props
, sizeof(msdasql_init_props
));
1500 IUnknown_QueryInterface(&session
->session_iface
, &IID_IUnknown
, (void**)&command
->session
);
1502 hr
= ICommandText_QueryInterface(&command
->ICommandText_iface
, riid
, (void**)out
);
1503 ICommandText_Release(&command
->ICommandText_iface
);
1507 static const IDBCreateCommandVtbl createcommandVtbl
=
1509 createcommand_QueryInterface
,
1510 createcommand_AddRef
,
1511 createcommand_Release
,
1512 createcommand_CreateCommand
1515 static HRESULT WINAPI
transjoin_QueryInterface(ITransactionJoin
*iface
, REFIID riid
, void **out
)
1517 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1518 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
1521 static ULONG WINAPI
transjoin_AddRef(ITransactionJoin
*iface
)
1523 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1524 return IUnknown_AddRef(&session
->session_iface
);
1527 static ULONG WINAPI
transjoin_Release(ITransactionJoin
*iface
)
1529 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1530 return IUnknown_Release(&session
->session_iface
);
1533 static HRESULT WINAPI
transjoin_GetOptionsObject(ITransactionJoin
*iface
, ITransactionOptions
**options
)
1535 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1537 FIXME("%p, %p\n", session
, options
);
1542 static HRESULT WINAPI
transjoin_JoinTransaction(ITransactionJoin
*iface
, IUnknown
*unk
, ISOLEVEL level
,
1543 ULONG flags
, ITransactionOptions
*options
)
1545 struct msdasql_session
*session
= impl_from_ITransactionJoin( iface
);
1547 FIXME("%p, %p, %lu, 0x%08lx, %p\n", session
, unk
, level
, flags
, options
);
1552 static const ITransactionJoinVtbl transactionjoinVtbl
=
1554 transjoin_QueryInterface
,
1557 transjoin_GetOptionsObject
,
1558 transjoin_JoinTransaction
1561 static HRESULT WINAPI
transaction_QueryInterface(ITransaction
*iface
, REFIID riid
, void **out
)
1563 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1564 return IUnknown_QueryInterface(&session
->session_iface
, riid
, out
);
1567 static ULONG WINAPI
transaction_AddRef(ITransaction
*iface
)
1569 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1570 return IUnknown_AddRef(&session
->session_iface
);
1573 static ULONG WINAPI
transaction_Release(ITransaction
*iface
)
1575 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1576 return IUnknown_Release(&session
->session_iface
);
1579 static HRESULT WINAPI
transaction_Commit(ITransaction
*iface
, BOOL retaining
, DWORD tc
, DWORD rm
)
1581 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1583 FIXME("%p, %d, %ld, %ld\n", session
, retaining
, tc
, rm
);
1588 static HRESULT WINAPI
transaction_Abort(ITransaction
*iface
, BOID
*reason
, BOOL retaining
, BOOL async
)
1590 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1592 FIXME("%p, %p, %d, %d\n", session
, reason
, retaining
, async
);
1597 static HRESULT WINAPI
transaction_GetTransactionInfo(ITransaction
*iface
, XACTTRANSINFO
*info
)
1599 struct msdasql_session
*session
= impl_from_ITransaction( iface
);
1601 FIXME("%p, %p\n", session
, info
);
1606 static const ITransactionVtbl transactionVtbl
=
1608 transaction_QueryInterface
,
1610 transaction_Release
,
1613 transaction_GetTransactionInfo
1616 HRESULT
create_db_session(REFIID riid
, IUnknown
*datasource
, HDBC hdbc
, void **unk
)
1618 struct msdasql_session
*session
;
1621 session
= heap_alloc(sizeof(*session
));
1623 return E_OUTOFMEMORY
;
1625 session
->session_iface
.lpVtbl
= &unkfactoryVtbl
;
1626 session
->IGetDataSource_iface
.lpVtbl
= &datasourceVtbl
;
1627 session
->IOpenRowset_iface
.lpVtbl
= &openrowsetVtbl
;
1628 session
->ISessionProperties_iface
.lpVtbl
= &propertiesVtbl
;
1629 session
->IDBCreateCommand_iface
.lpVtbl
= &createcommandVtbl
;
1630 session
->ITransactionJoin_iface
.lpVtbl
= &transactionjoinVtbl
;
1631 session
->ITransaction_iface
.lpVtbl
= &transactionVtbl
;
1633 IUnknown_QueryInterface(datasource
, &IID_IUnknown
, (void**)&session
->datasource
);
1635 session
->hdbc
= hdbc
;
1637 hr
= IUnknown_QueryInterface(&session
->session_iface
, riid
, unk
);
1638 IUnknown_Release(&session
->session_iface
);