2 * Copyright 2019 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
32 #include "wine/test.h"
34 DEFINE_GUID(DBPROPSET_DATASOURCEINFO
, 0xc8b522bb, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
35 DEFINE_GUID(DBPROPSET_DBINITALL
, 0xc8b522ca, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
36 DEFINE_GUID(DBPROPSET_DBINIT
, 0xc8b522bc, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
37 DEFINE_GUID(DBPROPSET_ROWSET
, 0xc8b522be, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
39 DEFINE_GUID(DBGUID_DEFAULT
, 0xc8b521fb, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
41 static BOOL db_created
;
42 static char mdbpath
[MAX_PATH
];
44 static const VARTYPE intptr_vartype
= (sizeof(void *) == 8 ? VT_I8
: VT_I4
);
46 static void free_dbpropset(ULONG count
, DBPROPSET
*propset
)
50 for (i
= 0; i
< count
; i
++)
52 for (j
= 0; j
< propset
[i
].cProperties
; j
++)
53 VariantClear(&propset
[i
].rgProperties
[j
].vValue
);
54 CoTaskMemFree(propset
[i
].rgProperties
);
56 CoTaskMemFree(propset
);
59 static void free_dbpropinfoset(ULONG count
, DBPROPINFOSET
*propinfoset
)
63 for (i
= 0; i
< count
; i
++)
65 for (j
= 0; j
< propinfoset
[i
].cPropertyInfos
; j
++)
66 VariantClear(&propinfoset
[i
].rgPropertyInfos
[j
].vValues
);
67 CoTaskMemFree(propinfoset
[i
].rgPropertyInfos
);
69 CoTaskMemFree(propinfoset
);
72 static void test_msdasql(void)
79 hr
= CoCreateInstance( &CLSID_MSDASQL
, NULL
, CLSCTX_ALL
, &IID_IUnknown
, (void **)&unk
);
80 ok(hr
== S_OK
, "Failed to create object 0x%08lx\n", hr
);
86 hr
= IUnknown_QueryInterface(unk
, &IID_IPersist
, (void**)&persist
);
87 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
89 hr
= IPersist_GetClassID(persist
, &classid
);
90 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
91 ok(IsEqualGUID(&classid
, &CLSID_MSDASQL
), "got %s\n", debugstr_guid(&classid
));
93 IPersist_Release(persist
);
95 IUnknown_Release(unk
);
98 static void test_Properties(void)
101 IDBProperties
*props
;
102 DBPROPIDSET propidset
;
105 DBPROPINFOSET
*propinfoset
;
106 DBPROPIDSET propidlist
;
111 DBPROPID properties
[14] =
113 DBPROP_AUTH_PASSWORD
, DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO
, DBPROP_AUTH_USERID
,
114 DBPROP_INIT_DATASOURCE
, DBPROP_INIT_HWND
, DBPROP_INIT_LOCATION
,
115 DBPROP_INIT_MODE
, DBPROP_INIT_PROMPT
, DBPROP_INIT_TIMEOUT
,
116 DBPROP_INIT_PROVIDERSTRING
, DBPROP_INIT_LCID
, DBPROP_INIT_CATALOG
,
117 DBPROP_INIT_OLEDBSERVICES
, DBPROP_INIT_GENERALTIMEOUT
120 hr
= CoCreateInstance( &CLSID_MSDASQL
, NULL
, CLSCTX_ALL
, &IID_IDBProperties
, (void **)&props
);
121 ok(hr
== S_OK
, "Failed to create object 0x%08lx\n", hr
);
123 propidset
.rgPropertyIDs
= NULL
;
124 propidset
.cPropertyIDs
= 0;
125 propidset
.guidPropertySet
= DBPROPSET_DBINITALL
;
128 hr
= IDBProperties_GetPropertyInfo(props
, 1, &propidset
, &infocount
, &propinfoset
, &desc
);
129 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
132 VARTYPE types
[14] = { VT_BSTR
, VT_BOOL
, VT_BSTR
, VT_BSTR
, intptr_vartype
, VT_BSTR
, VT_I4
, VT_I2
, VT_I4
, VT_BSTR
, VT_I4
, VT_BSTR
, VT_I4
, VT_I4
};
134 ok(IsEqualGUID(&propinfoset
->guidPropertySet
, &DBPROPSET_DBINIT
), "got %s\n", debugstr_guid(&propinfoset
->guidPropertySet
));
135 ok(propinfoset
->cPropertyInfos
== 14, "got %lu\n", propinfoset
->cPropertyInfos
);
137 propidlist
.guidPropertySet
= DBPROPSET_DBINIT
;
138 propidlist
.cPropertyIDs
= propinfoset
->cPropertyInfos
;
139 propidlist
.rgPropertyIDs
= CoTaskMemAlloc(propinfoset
->cPropertyInfos
* sizeof(DBPROP
));
141 for (i
= 0; i
< propinfoset
->cPropertyInfos
; i
++)
143 ok(propinfoset
->rgPropertyInfos
[i
].vtType
== types
[i
], "got %d\n", propinfoset
->rgPropertyInfos
[i
].vtType
);
144 ok(propinfoset
->rgPropertyInfos
[i
].dwFlags
== (DBPROPFLAGS_DBINIT
| DBPROPFLAGS_READ
| DBPROPFLAGS_WRITE
),
145 "got %lu\n", propinfoset
->rgPropertyInfos
[i
].dwFlags
);
146 ok(properties
[i
] == propinfoset
->rgPropertyInfos
[i
].dwPropertyID
, "%lu, got %lu\n", i
,
147 propinfoset
->rgPropertyInfos
[i
].dwPropertyID
);
148 ok(propinfoset
->rgPropertyInfos
[i
].vtType
!= VT_EMPTY
, "%lu, got %u\n", i
,
149 propinfoset
->rgPropertyInfos
[i
].vtType
);
151 propidlist
.rgPropertyIDs
[i
] = propinfoset
->rgPropertyInfos
[i
].dwPropertyID
;
154 free_dbpropinfoset(infocount
, propinfoset
);
157 /* Test specifying all supported properties */
158 hr
= IDBProperties_GetProperties(props
, 1, &propidlist
, &propcnt
, &propset
);
159 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
160 ok(propidlist
.cPropertyIDs
== 14, "got %lu\n", propidlist
.cPropertyIDs
);
161 ok(propset
->cProperties
== 14, "got %lu\n", propset
->cProperties
);
163 for (i
= 0; i
< propidlist
.cPropertyIDs
; i
++)
165 VARTYPE vartype
= VT_EMPTY
;
167 ok(properties
[i
] == propidlist
.rgPropertyIDs
[i
], "%lu, got %lu\n", i
, propidlist
.rgPropertyIDs
[i
]);
169 if(properties
[i
] == DBPROP_INIT_PROMPT
)
171 ok(V_I2(&propset
->rgProperties
[i
].vValue
) == 4, "wrong value %s\n", debugstr_variant(&propset
->rgProperties
[i
].vValue
));
174 else if(properties
[i
] == DBPROP_INIT_LCID
)
176 ok(V_I4(&propset
->rgProperties
[i
].vValue
) == GetUserDefaultLCID(), "wrong value %s\n", debugstr_variant(&propset
->rgProperties
[i
].vValue
));
179 else if(properties
[i
] == DBPROP_INIT_OLEDBSERVICES
)
181 ok(V_I4(&propset
->rgProperties
[i
].vValue
) == -1, "wrong value %s\n", debugstr_variant(&propset
->rgProperties
[i
].vValue
));
185 ok(V_VT(&propset
->rgProperties
[i
].vValue
) == vartype
, "%lu wrong type %d\n", i
, V_VT(&propset
->rgProperties
[i
].vValue
));
188 for (i
= 0; i
< propset
->cProperties
; i
++)
189 ok(propset
->rgProperties
[i
].dwPropertyID
== properties
[i
],
190 "%ld %ld, got %ld\n", i
, properties
[i
], propset
->rgProperties
[i
].dwPropertyID
);
192 free_dbpropset(propcnt
, propset
);
194 /* Test specifying only one supported properties */
195 propidlist
.cPropertyIDs
= 1;
196 hr
= IDBProperties_GetProperties(props
, 1, &propidlist
, &propcnt
, &propset
);
197 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
198 ok(propset
->cProperties
== 1, "expected 1, got %lu\n", propset
->cProperties
);
199 free_dbpropset(propcnt
, propset
);
201 /* Test when cPropertyIDSets is zero, all initialization properties should be returned */
202 hr
= IDBProperties_GetProperties(props
, 0, &propidlist
, &propcnt
, &propset
);
203 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
204 ok(propset
->cProperties
== ARRAY_SIZE(properties
), "got %lu\n", propset
->cProperties
);
205 for (i
= 0; i
< propset
->cProperties
; i
++)
206 ok(propset
->rgProperties
[i
].dwPropertyID
== properties
[i
],
207 "%ld %ld, got %ld\n", i
, properties
[i
], propset
->rgProperties
[i
].dwPropertyID
);
208 free_dbpropset(propcnt
, propset
);
210 /* Test when propidlist.cPropertyIDs is zero, all initialization properties should be returned */
211 CoTaskMemFree(propidlist
.rgPropertyIDs
);
212 propidlist
.guidPropertySet
= DBPROPSET_DBINIT
;
213 propidlist
.cPropertyIDs
= 0;
214 propidlist
.rgPropertyIDs
= NULL
;
216 hr
= IDBProperties_GetProperties(props
, 1, &propidlist
, &propcnt
, &propset
);
217 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
218 ok(propset
->cProperties
== ARRAY_SIZE(properties
), "got %lu\n", propset
->cProperties
);
219 for (i
= 0; i
< propset
->cProperties
; i
++)
220 ok(propset
->rgProperties
[i
].dwPropertyID
== properties
[i
],
221 "%ld %ld, got %ld\n", i
, properties
[i
], propset
->rgProperties
[i
].dwPropertyID
);
222 free_dbpropset(propcnt
, propset
);
225 propid
= DBPROP_MULTIPLERESULTS
;
226 propidlist
.rgPropertyIDs
= &propid
;
227 propidlist
.cPropertyIDs
= 1;
228 propidlist
.guidPropertySet
= DBPROPSET_DATASOURCEINFO
;
232 hr
= IDBProperties_GetProperties(props
, 1, &propidlist
, &propcnt
, &propset
);
233 ok(hr
== DB_E_ERRORSOCCURRED
, "got 0x%08lx\n", hr
);
234 ok(IsEqualGUID(&propset
->guidPropertySet
, &DBPROPSET_DATASOURCEINFO
), "got %s\n", debugstr_guid(&propset
->guidPropertySet
));
235 ok(propset
->cProperties
== 1, "got %lu\n", propset
->cProperties
);
236 ok(propset
->rgProperties
[0].dwPropertyID
== DBPROP_MULTIPLERESULTS
, "got %ld\n", propset
->rgProperties
[0].dwPropertyID
);
237 ok(propset
->rgProperties
[0].dwStatus
== DBPROPSTATUS_NOTSUPPORTED
, "got %ld\n", propset
->rgProperties
[0].dwStatus
);
239 free_dbpropset(propcnt
, propset
);
241 IDBProperties_Release(props
);
244 static void test_command_properties(ICommandProperties
*props
)
251 DWORD row_props
[68] = {
252 DBPROP_ABORTPRESERVE
, DBPROP_BLOCKINGSTORAGEOBJECTS
, DBPROP_BOOKMARKS
, DBPROP_BOOKMARKSKIPPED
,
253 DBPROP_BOOKMARKTYPE
, DBPROP_CANFETCHBACKWARDS
, DBPROP_CANHOLDROWS
, DBPROP_CANSCROLLBACKWARDS
,
254 DBPROP_COLUMNRESTRICT
, DBPROP_COMMITPRESERVE
, DBPROP_DELAYSTORAGEOBJECTS
, DBPROP_IMMOBILEROWS
,
255 DBPROP_LITERALBOOKMARKS
, DBPROP_LITERALIDENTITY
, DBPROP_MAXOPENROWS
, DBPROP_MAXPENDINGROWS
,
256 DBPROP_MAXROWS
, DBPROP_NOTIFICATIONPHASES
, DBPROP_OTHERUPDATEDELETE
, DBPROP_OWNINSERT
,
257 DBPROP_OWNUPDATEDELETE
, DBPROP_QUICKRESTART
, DBPROP_REENTRANTEVENTS
, DBPROP_REMOVEDELETED
,
258 DBPROP_REPORTMULTIPLECHANGES
, DBPROP_ROWRESTRICT
, DBPROP_ROWTHREADMODEL
, DBPROP_TRANSACTEDOBJECT
,
259 DBPROP_UPDATABILITY
, DBPROP_STRONGIDENTITY
, DBPROP_IAccessor
, DBPROP_IColumnsInfo
,
260 DBPROP_IColumnsRowset
, DBPROP_IConnectionPointContainer
, DBPROP_IRowset
, DBPROP_IRowsetChange
,
261 DBPROP_IRowsetIdentity
, DBPROP_IRowsetInfo
, DBPROP_IRowsetLocate
, DBPROP_IRowsetResynch
,
262 DBPROP_IRowsetUpdate
, DBPROP_ISupportErrorInfo
, DBPROP_ISequentialStream
, DBPROP_NOTIFYCOLUMNSET
,
263 DBPROP_NOTIFYROWDELETE
, DBPROP_NOTIFYROWFIRSTCHANGE
, DBPROP_NOTIFYROWINSERT
, DBPROP_NOTIFYROWRESYNCH
,
264 DBPROP_NOTIFYROWSETRELEASE
, DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE
, DBPROP_NOTIFYROWUNDOCHANGE
, DBPROP_NOTIFYROWUNDODELETE
,
265 DBPROP_NOTIFYROWUNDOINSERT
, DBPROP_NOTIFYROWUPDATE
, DBPROP_CHANGEINSERTEDROWS
, DBPROP_RETURNPENDINGINSERTS
,
266 DBPROP_IConvertType
, DBPROP_NOTIFICATIONGRANULARITY
, DBPROP_IMultipleResults
, DBPROP_ACCESSORDER
,
267 DBPROP_BOOKMARKINFO
, DBPROP_UNIQUEROWS
, DBPROP_IRowsetFind
, DBPROP_IRowsetScroll
,
268 DBPROP_IRowsetRefresh
, DBPROP_FINDCOMPAREOPS
, DBPROP_ORDEREDBOOKMARKS
, DBPROP_CLIENTCURSOR
271 DWORD prov_props
[12] = {
272 DBPROP_ABORTPRESERVE
, DBPROP_ACTIVESESSIONS
, DBPROP_ASYNCTXNCOMMIT
, DBPROP_AUTH_CACHE_AUTHINFO
,
273 DBPROP_AUTH_ENCRYPT_PASSWORD
, DBPROP_AUTH_INTEGRATED
, DBPROP_AUTH_MASK_PASSWORD
, DBPROP_AUTH_PASSWORD
,
274 DBPROP_AUTH_PERSIST_ENCRYPTED
, DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO
, DBPROP_AUTH_USERID
, DBPROP_BLOCKINGSTORAGEOBJECTS
277 hr
= ICommandProperties_GetProperties(props
, 0, NULL
, &count
, &propset
);
278 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
279 ok(count
== 2, "got %ld\n", count
);
280 ok(propset
[0].cProperties
== 68, "got %ld\n", propset
[0].cProperties
);
281 ok(propset
[1].cProperties
== 12, "got %ld\n", propset
[1].cProperties
);
283 ok(IsEqualGUID(&DBPROPSET_ROWSET
, &propset
[0].guidPropertySet
), "got %s\n",
284 debugstr_guid(&propset
[0].guidPropertySet
));
285 for (i
= 0; i
< propset
[0].cProperties
; i
++)
287 ok(propset
[0].rgProperties
[i
].dwPropertyID
== row_props
[i
], "%d: got 0x%08lx\n", i
, propset
[0].rgProperties
[i
].dwPropertyID
);
289 switch(propset
[0].rgProperties
[i
].dwPropertyID
)
291 case DBPROP_BOOKMARKTYPE
:
292 case DBPROP_NOTIFICATIONGRANULARITY
:
293 case DBPROP_ACCESSORDER
:
294 ok(V_VT(&propset
[0].rgProperties
[i
].vValue
) == VT_I4
, "%d: got %d\n", i
, V_VT(&propset
[0].rgProperties
[i
].vValue
));
295 ok(V_I4(&propset
[0].rgProperties
[i
].vValue
) == 1, "%d: got %ld\n", i
, V_I4(&propset
[0].rgProperties
[i
].vValue
));
297 case DBPROP_MAXOPENROWS
:
298 case DBPROP_MAXPENDINGROWS
:
300 case DBPROP_UPDATABILITY
:
301 case DBPROP_BOOKMARKINFO
:
302 ok(V_VT(&propset
[0].rgProperties
[i
].vValue
) == VT_I4
, "%d: got %d\n", i
, V_VT(&propset
[0].rgProperties
[i
].vValue
));
303 ok(V_I4(&propset
[0].rgProperties
[i
].vValue
) == 0, "%d: got %ld\n", i
, V_I4(&propset
[0].rgProperties
[i
].vValue
));
305 case DBPROP_FINDCOMPAREOPS
:
306 ok(V_VT(&propset
[0].rgProperties
[i
].vValue
) == VT_I4
, "%d: got %d\n", i
, V_VT(&propset
[0].rgProperties
[i
].vValue
));
307 ok(V_I4(&propset
[0].rgProperties
[i
].vValue
) == 27, "%d: got %ld\n", i
, V_I4(&propset
[0].rgProperties
[i
].vValue
));
309 case DBPROP_NOTIFICATIONPHASES
:
310 ok(V_VT(&propset
[0].rgProperties
[i
].vValue
) == VT_I4
, "%d: got %d\n", i
, V_VT(&propset
[0].rgProperties
[i
].vValue
));
311 ok(V_I4(&propset
[0].rgProperties
[i
].vValue
) == 31, "%d: got %ld\n", i
, V_I4(&propset
[0].rgProperties
[i
].vValue
));
313 case DBPROP_ROWTHREADMODEL
:
314 ok(V_VT(&propset
[0].rgProperties
[i
].vValue
) == VT_I4
, "%d: got %d\n", i
, V_VT(&propset
[0].rgProperties
[i
].vValue
));
315 ok(V_I4(&propset
[0].rgProperties
[i
].vValue
) == 2, "%d: got %ld\n", i
, V_I4(&propset
[0].rgProperties
[i
].vValue
));
317 case DBPROP_NOTIFYCOLUMNSET
:
318 case DBPROP_NOTIFYROWDELETE
:
319 case DBPROP_NOTIFYROWFIRSTCHANGE
:
320 case DBPROP_NOTIFYROWINSERT
:
321 case DBPROP_NOTIFYROWRESYNCH
:
322 case DBPROP_NOTIFYROWSETRELEASE
:
323 case DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE
:
324 case DBPROP_NOTIFYROWUNDOCHANGE
:
325 case DBPROP_NOTIFYROWUNDODELETE
:
326 case DBPROP_NOTIFYROWUNDOINSERT
:
327 case DBPROP_NOTIFYROWUPDATE
:
328 ok(V_VT(&propset
[0].rgProperties
[i
].vValue
) == VT_I4
, "%d: got %d\n", i
, V_VT(&propset
[0].rgProperties
[i
].vValue
));
329 ok(V_I4(&propset
[0].rgProperties
[i
].vValue
) == 3, "%d: got %ld\n", i
, V_I4(&propset
[0].rgProperties
[i
].vValue
));
331 case DBPROP_BLOCKINGSTORAGEOBJECTS
:
332 case DBPROP_IMMOBILEROWS
:
333 case DBPROP_LITERALIDENTITY
:
334 case DBPROP_REENTRANTEVENTS
:
335 case DBPROP_IAccessor
:
336 case DBPROP_IColumnsInfo
:
337 case DBPROP_IColumnsRowset
:
339 case DBPROP_IRowsetInfo
:
340 case DBPROP_ISupportErrorInfo
:
341 case DBPROP_CHANGEINSERTEDROWS
:
342 case DBPROP_IConvertType
:
343 case DBPROP_IRowsetScroll
:
344 case DBPROP_IRowsetRefresh
:
345 case DBPROP_ORDEREDBOOKMARKS
:
346 case DBPROP_CLIENTCURSOR
:
347 ok(V_VT(&propset
[0].rgProperties
[i
].vValue
) == VT_BOOL
, "%d: got %d\n", i
, V_VT(&propset
[0].rgProperties
[i
].vValue
));
348 ok(V_BOOL(&propset
[0].rgProperties
[i
].vValue
) == VARIANT_TRUE
, "%d: got %ld\n", i
, V_I4(&propset
[0].rgProperties
[i
].vValue
));
351 ok(V_VT(&propset
[0].rgProperties
[i
].vValue
) == VT_BOOL
, "%d: got %d\n", i
, V_VT(&propset
[0].rgProperties
[i
].vValue
));
352 ok(V_BOOL(&propset
[0].rgProperties
[i
].vValue
) == VARIANT_FALSE
, "%d: got %ld\n", i
, V_I4(&propset
[0].rgProperties
[i
].vValue
));
357 ok(IsEqualGUID(&DBPROPSET_PROVIDERROWSET
, &propset
[1].guidPropertySet
), "got %s\n",
358 debugstr_guid(&propset
[1].guidPropertySet
));
359 for (i
= 0; i
< propset
[1].cProperties
; i
++)
361 ok(propset
[1].rgProperties
[i
].dwPropertyID
== prov_props
[i
], "%d: got 0x%08lx\n", i
, propset
[1].rgProperties
[i
].dwPropertyID
);
363 switch(propset
[1].rgProperties
[i
].dwPropertyID
)
365 case DBPROP_AUTH_ENCRYPT_PASSWORD
:
366 ok(V_VT(&propset
[1].rgProperties
[i
].vValue
) == VT_I4
, "%d: got %d\n", i
, V_VT(&propset
[1].rgProperties
[i
].vValue
));
367 ok(V_I4(&propset
[1].rgProperties
[i
].vValue
) == 0, "%d: got %ld\n", i
, V_I4(&propset
[1].rgProperties
[i
].vValue
));
369 case DBPROP_AUTH_INTEGRATED
:
370 ok(V_VT(&propset
[1].rgProperties
[i
].vValue
) == VT_I4
, "%d: got %d\n", i
, V_VT(&propset
[1].rgProperties
[i
].vValue
));
371 ok(V_I4(&propset
[1].rgProperties
[i
].vValue
) == 14, "%d: got %ld\n", i
, V_I4(&propset
[1].rgProperties
[i
].vValue
));
373 case DBPROP_BLOCKINGSTORAGEOBJECTS
:
374 ok(V_VT(&propset
[1].rgProperties
[i
].vValue
) == VT_BOOL
, "%d: got %d\n", i
, V_VT(&propset
[1].rgProperties
[i
].vValue
));
375 ok(V_BOOL(&propset
[1].rgProperties
[i
].vValue
) == VARIANT_FALSE
, "%d: got %ld\n", i
, V_I4(&propset
[1].rgProperties
[i
].vValue
));
378 ok(V_VT(&propset
[1].rgProperties
[i
].vValue
) == VT_BOOL
, "%d: got %d\n", i
, V_VT(&propset
[1].rgProperties
[i
].vValue
));
379 ok(V_BOOL(&propset
[1].rgProperties
[i
].vValue
) == VARIANT_FALSE
, "%d: got %ld\n", i
, V_I4(&propset
[1].rgProperties
[i
].vValue
));
384 free_dbpropset(count
, propset
);
387 static void test_command_interfaces(IUnknown
*cmd
)
390 ICommandProperties
*commandProp
;
391 ICommandText
*command_text
;
392 IConvertType
*convertype
;
393 ICommandPrepare
*commandprepare
;
394 ICommandStream
*commandstream
;
395 IColumnsInfo
*colinfo
;
396 IMultipleResults
*multiple
;
397 ICommandWithParameters
*cmdwithparams
;
400 hr
= IUnknown_QueryInterface(cmd
, &IID_ICommandProperties
, (void**)&commandProp
);
401 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
402 test_command_properties(commandProp
);
403 ICommandProperties_Release(commandProp
);
405 hr
= IUnknown_QueryInterface(cmd
, &IID_ICommandWithParameters
, (void**)&cmdwithparams
);
406 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
407 ICommandWithParameters_Release(cmdwithparams
);
409 hr
= IUnknown_QueryInterface(cmd
, &IID_ICommandText
, (void**)&command_text
);
410 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
411 ICommandText_Release(command_text
);
413 hr
= IUnknown_QueryInterface(cmd
, &IID_IConvertType
, (void**)&convertype
);
414 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
415 IConvertType_Release(convertype
);
417 hr
= IUnknown_QueryInterface(cmd
, &IID_ICommandPrepare
, (void**)&commandprepare
);
418 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
419 ICommandPrepare_Release(commandprepare
);
421 hr
= IUnknown_QueryInterface(cmd
, &IID_IColumnsInfo
, (void**)&colinfo
);
422 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
423 IColumnsInfo_Release(colinfo
);
425 hr
= IUnknown_QueryInterface(cmd
, &IID_ICommandStream
, (void**)&commandstream
);
426 ok(hr
== E_NOINTERFACE
, "got 0x%08lx\n", hr
);
428 hr
= IUnknown_QueryInterface(cmd
, &IID_IMultipleResults
, (void**)&multiple
);
429 ok(hr
== E_NOINTERFACE
, "got 0x%08lx\n", hr
);
431 hr
= IUnknown_QueryInterface(cmd
, &IID_IRowsetChange
, (void**)&unk
);
432 ok(hr
== E_NOINTERFACE
, "got 0x%08lx\n", hr
);
434 hr
= IUnknown_QueryInterface(cmd
, &IID_IRowsetUpdate
, (void**)&unk
);
435 ok(hr
== E_NOINTERFACE
, "got 0x%08lx\n", hr
);
437 hr
= IUnknown_QueryInterface(cmd
, &IID_IRowsetLocate
, (void**)&unk
);
438 ok(hr
== E_NOINTERFACE
, "got 0x%08lx\n", hr
);
441 static void test_command_text(IUnknown
*cmd
)
443 ICommandText
*command_text
;
448 hr
= IUnknown_QueryInterface(cmd
, &IID_ICommandText
, (void**)&command_text
);
449 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
451 hr
= ICommandText_GetCommandText(command_text
, &dialect
, &str
);
452 ok(hr
== DB_E_NOCOMMAND
, "got 0x%08lx\n", hr
);
456 /* Crashes under windows */
457 hr
= ICommandText_SetCommandText(command_text
, NULL
, L
"select * from testing");
458 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
461 hr
= ICommandText_SetCommandText(command_text
, &DBGUID_DEFAULT
, NULL
);
462 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
464 hr
= ICommandText_GetCommandText(command_text
, &dialect
, &str
);
465 ok(hr
== DB_E_NOCOMMAND
, "got 0x%08lx\n", hr
);
467 hr
= ICommandText_SetCommandText(command_text
, &DBGUID_DEFAULT
, L
"select * from testing");
468 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
471 hr
= ICommandText_GetCommandText(command_text
, NULL
, &str
);
472 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
473 ok (!lstrcmpW(L
"select * from testing", str
), "got %s\n", debugstr_w(str
));
474 HeapFree(GetProcessHeap(), 0, str
);
476 /* dialect empty value */
477 hr
= ICommandText_GetCommandText(command_text
, &dialect
, &str
);
478 ok(hr
== DB_S_DIALECTIGNORED
, "got 0x%08lx\n", hr
);
479 ok(IsEqualGUID(&DBGUID_DEFAULT
, &dialect
), "got %s\n", debugstr_guid(&dialect
));
480 ok (!lstrcmpW(L
"select * from testing", str
), "got %s\n", debugstr_w(str
));
481 HeapFree(GetProcessHeap(), 0, str
);
483 dialect
= DBGUID_DEFAULT
;
484 hr
= ICommandText_GetCommandText(command_text
, &dialect
, &str
);
485 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
486 ok(IsEqualGUID(&DBGUID_DEFAULT
, &dialect
), "got %s\n", debugstr_guid(&dialect
));
487 ok (!lstrcmpW(L
"select * from testing", str
), "got %s\n", debugstr_w(str
));
488 HeapFree(GetProcessHeap(), 0, str
);
490 ICommandText_Release(command_text
);
493 static void test_command_dbsession(IUnknown
*cmd
, IUnknown
*session
)
495 ICommandText
*command_text
;
499 hr
= IUnknown_QueryInterface(cmd
, &IID_ICommandText
, (void**)&command_text
);
500 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
502 hr
= ICommandText_GetDBSession(command_text
, &IID_IUnknown
, &sess
);
503 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
504 ok(session
== sess
, "different session pointers\n");
506 ICommandText_Release(command_text
);
509 static void test_rowset_interfaces(IRowset
*rowset
, ICommandText
*commandtext
)
512 IColumnsInfo
*col_info
;
513 IColumnsRowset
*col_rs
;
515 ICommandText
*specification
= NULL
;
519 hr
= IRowset_QueryInterface(rowset
, &IID_IRowsetInfo
, (void**)&info
);
520 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
522 hr
= IRowsetInfo_GetSpecification(info
, &IID_ICommandText
, NULL
);
523 ok(hr
== E_INVALIDARG
, "got 0x%08lx\n", hr
);
525 hr
= IRowsetInfo_GetSpecification(info
, &IID_ICommandText
, (IUnknown
**)&specification
);
526 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
529 ok(commandtext
== specification
, "got 0x%08lx\n", hr
);
530 ICommandText_Release(specification
);
532 IRowsetInfo_Release(info
);
534 hr
= IRowset_QueryInterface(rowset
, &IID_IColumnsInfo
, (void**)&col_info
);
535 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
536 IColumnsInfo_Release(col_info
);
538 hr
= IRowset_QueryInterface(rowset
, &IID_IAccessor
, (void**)&accessor
);
539 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
540 IAccessor_Release(accessor
);
542 hr
= IRowset_QueryInterface(rowset
, &IID_IColumnsRowset
, (void**)&col_rs
);
543 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
544 IColumnsRowset_Release(col_rs
);
546 hr
= IRowset_QueryInterface(rowset
, &IID_IRowsetChange
, (void**)&unk
);
547 ok(hr
== E_NOINTERFACE
, "got 0x%08lx\n", hr
);
549 hr
= IRowset_QueryInterface(rowset
, &IID_IRowsetUpdate
, (void**)&unk
);
550 ok(hr
== E_NOINTERFACE
, "got 0x%08lx\n", hr
);
552 hr
= IRowset_QueryInterface(rowset
, &IID_IRowsetLocate
, (void**)&unk
);
553 ok(hr
== E_NOINTERFACE
, "got 0x%08lx\n", hr
);
556 static void test_rowset_info(IRowset
*rowset
)
561 DBPROPIDSET propidset
;
564 DWORD row_props
[] = {
565 DBPROP_CANSCROLLBACKWARDS
, DBPROP_IRowsetUpdate
, DBPROP_IRowsetResynch
,
566 DBPROP_IConnectionPointContainer
, DBPROP_BOOKMARKSKIPPED
, DBPROP_REMOVEDELETED
,
567 DBPROP_IConvertType
, DBPROP_NOTIFICATIONGRANULARITY
, DBPROP_IMultipleResults
, DBPROP_ACCESSORDER
,
568 DBPROP_BOOKMARKINFO
, DBPROP_UNIQUEROWS
571 hr
= IRowset_QueryInterface(rowset
, &IID_IRowsetInfo
, (void**)&info
);
572 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
574 propidset
.rgPropertyIDs
= row_props
;
575 propidset
.cPropertyIDs
= ARRAY_SIZE(row_props
);
576 propidset
.guidPropertySet
= DBPROPSET_ROWSET
;
578 hr
= IRowsetInfo_GetProperties(info
, 1, &propidset
, &propcnt
, &propset
);
579 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
580 ok(propset
->cProperties
== ARRAY_SIZE(row_props
), "got %lu\n", propset
->cProperties
);
582 for(i
=0; i
< ARRAY_SIZE(row_props
); i
++)
584 ok(propset
->rgProperties
[i
].dwPropertyID
== row_props
[i
], "expected 0x%08lx got 0x%08lx\n",
585 propset
->rgProperties
[i
].dwPropertyID
, row_props
[i
]);
588 free_dbpropset(propcnt
, propset
);
589 IRowsetInfo_Release(info
);
592 static void test_command_rowset(IUnknown
*cmd
)
594 ICommandText
*command_text
;
595 ICommandPrepare
*commandprepare
;
597 IUnknown
*unk
= NULL
;
601 hr
= IUnknown_QueryInterface(cmd
, &IID_ICommandText
, (void**)&command_text
);
602 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
604 hr
= IUnknown_QueryInterface(cmd
, &IID_ICommandPrepare
, (void**)&commandprepare
);
605 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
607 hr
= ICommandText_SetCommandText(command_text
, &DBGUID_DEFAULT
, NULL
);
608 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
610 hr
= ICommandPrepare_Prepare(commandprepare
, 1);
611 ok(hr
== DB_E_NOCOMMAND
, "got 0x%08lx\n", hr
);
613 hr
= ICommandText_SetCommandText(command_text
, &DBGUID_DEFAULT
, L
"CREATE TABLE testing (col1 INT, col2 VARCHAR(20) NOT NULL, col3 FLOAT)");
614 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
616 hr
= ICommandPrepare_Prepare(commandprepare
, 1);
617 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
618 ICommandPrepare_Release(commandprepare
);
621 hr
= ICommandText_Execute(command_text
, NULL
, &IID_IRowset
, NULL
, &affected
, &unk
);
622 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
623 ok(unk
== NULL
, "Unexpected value\n");
624 ok(affected
== -1, "got %Id\n", affected
);
626 IUnknown_Release(unk
);
628 /* Ensure all rows are deleted - Interactive Test */
629 hr
= ICommandText_SetCommandText(command_text
, &DBGUID_DEFAULT
, L
"delete from testing");
630 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
632 hr
= ICommandText_Execute(command_text
, NULL
, &IID_NULL
, NULL
, NULL
, NULL
);
633 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
635 hr
= ICommandText_SetCommandText(command_text
, &DBGUID_DEFAULT
, L
"insert into testing values(1, 'red', 1.0)");
636 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
639 hr
= ICommandText_Execute(command_text
, NULL
, &IID_IRowset
, NULL
, &affected
, &unk
);
640 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
641 ok(affected
== 1, "got %Id\n", affected
);
642 ok(unk
== NULL
, "Unexpected value\n");
644 hr
= ICommandText_SetCommandText(command_text
, &DBGUID_DEFAULT
, L
"select * from testing");
645 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
648 hr
= ICommandText_Execute(command_text
, NULL
, &IID_IRowset
, NULL
, &affected
, &unk
);
649 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
650 ok(unk
!= NULL
, "Unexpected value\n");
653 const DWORD flag1
= DBCOLUMNFLAGS_ISFIXEDLENGTH
| DBCOLUMNFLAGS_ISNULLABLE
| DBCOLUMNFLAGS_MAYBENULL
| DBCOLUMNFLAGS_WRITE
;
654 const DWORD flag2
= DBCOLUMNFLAGS_ISNULLABLE
| DBCOLUMNFLAGS_MAYBENULL
| DBCOLUMNFLAGS_WRITE
;
655 IColumnsInfo
*colinfo
;
657 DBCOLUMNINFO
*dbcolinfo
;
658 OLECHAR
*stringsbuffer
;
660 ok(affected
== -1 || affected
== 1, "got %Iu\n", affected
);
662 hr
= IUnknown_QueryInterface(unk
, &IID_IRowset
, (void**)&rowset
);
663 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
665 test_rowset_interfaces(rowset
, command_text
);
667 hr
= IRowset_QueryInterface(rowset
, &IID_IColumnsInfo
, (void**)&colinfo
);
668 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
671 hr
= IColumnsInfo_GetColumnInfo(colinfo
, &columns
, &dbcolinfo
, &stringsbuffer
);
672 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
673 ok(columns
== 3, "got %Iu\n", columns
);
675 ok(dbcolinfo
[0].dwFlags
== flag1
, "got 0x%08lx\n", dbcolinfo
[0].dwFlags
);
676 ok(dbcolinfo
[0].wType
== DBTYPE_I4
, "got 0x%08x\n", dbcolinfo
[0].wType
);
678 todo_wine
ok(dbcolinfo
[1].dwFlags
== flag2
, "got 0x%08lx\n", dbcolinfo
[1].dwFlags
);
679 ok(dbcolinfo
[1].wType
== DBTYPE_WSTR
/* Unicode MySQL Driver */ ||
680 dbcolinfo
[1].wType
== DBTYPE_STR
/* ASCII MySQL Driver */, "got 0x%08x\n", dbcolinfo
[1].wType
);
682 ok(dbcolinfo
[2].dwFlags
== flag1
, "got 0x%08lx\n", dbcolinfo
[2].dwFlags
);
683 ok(dbcolinfo
[2].wType
== DBTYPE_R4
/* MySQL */ ||
684 dbcolinfo
[2].wType
== DBTYPE_R8
/* Access */, "got 0x%08x\n", dbcolinfo
[2].wType
);
686 CoTaskMemFree(dbcolinfo
);
687 CoTaskMemFree(stringsbuffer
);
688 IColumnsInfo_Release(colinfo
);
690 test_rowset_info(rowset
);
692 IRowset_Release(rowset
);
693 IUnknown_Release(unk
);
696 ICommandText_Release(command_text
);
700 static void test_sessions(void)
702 IDBProperties
*props
, *dsource
= NULL
;
703 IDBInitialize
*dbinit
= NULL
;
704 IDataInitialize
*datainit
;
705 IDBCreateSession
*dbsession
= NULL
;
706 IUnknown
*session
= NULL
;
707 IOpenRowset
*openrowset
= NULL
;
708 IDBCreateCommand
*create_command
= NULL
;
709 IGetDataSource
*datasource
= NULL
;
710 ISessionProperties
*session_props
= NULL
;
711 IUnknown
*unimplemented
= NULL
;
712 ITransaction
*transaction
= NULL
;
713 ITransactionLocal
*local
= NULL
;
714 ITransactionObject
*object
= NULL
;
715 ITransactionJoin
*join
= NULL
;
716 IUnknown
*cmd
= NULL
;
722 skip("ODBC source wine_test not available.\n");
726 connect_str
= SysAllocString(L
"Provider=MSDASQL.1;Persist Security Info=False;Data Source=wine_test");
728 hr
= CoCreateInstance( &CLSID_MSDAINITIALIZE
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDataInitialize
,
729 (void **)&datainit
);
730 ok(hr
== S_OK
, "Failed to create object 0x%08lx\n", hr
);
731 hr
= IDataInitialize_GetDataSource( datainit
, NULL
, CLSCTX_INPROC_SERVER
, connect_str
, &IID_IDBInitialize
,
732 (IUnknown
**)&dbinit
);
733 SysFreeString(connect_str
);
734 todo_wine
ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
737 IDataInitialize_Release( datainit
);
741 hr
= IDBInitialize_QueryInterface( dbinit
, &IID_IDBProperties
, (void **)&props
);
742 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
743 IDBProperties_Release(props
);
745 hr
= IDBInitialize_Initialize( dbinit
);
746 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
749 IDBInitialize_Release( dbinit
);
750 IDataInitialize_Release( datainit
);
754 hr
= IDBInitialize_QueryInterface( dbinit
, &IID_IDBCreateSession
, (void **)&dbsession
);
755 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
757 hr
= IDBCreateSession_CreateSession( dbsession
, NULL
, &IID_IUnknown
, &session
);
758 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
760 hr
= IUnknown_QueryInterface(session
, &IID_IGetDataSource
, (void**)&datasource
);
761 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
763 hr
= IGetDataSource_GetDataSource(datasource
, &IID_IDBProperties
, (IUnknown
**)&dsource
);
764 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
765 ok(dsource
== props
, "different pointers\n");
766 IDBProperties_Release(dsource
);
767 IGetDataSource_Release(datasource
);
769 hr
= IUnknown_QueryInterface(session
, &IID_ITransaction
, (void**)&transaction
);
770 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
771 ITransaction_Release(transaction
);
773 hr
= IUnknown_QueryInterface(session
, &IID_ITransactionLocal
, (void**)&local
);
774 todo_wine
ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
776 ITransactionLocal_Release(local
);
778 hr
= IUnknown_QueryInterface(session
, &IID_ITransactionObject
, (void**)&object
);
779 ok(hr
== E_NOINTERFACE
, "got 0x%08lx\n", hr
);
781 hr
= IUnknown_QueryInterface(session
, &IID_ITransactionJoin
, (void**)&join
);
782 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
783 ITransactionJoin_Release(join
);
785 hr
= IUnknown_QueryInterface(session
, &IID_IBindResource
, (void**)&unimplemented
);
786 ok(hr
== E_NOINTERFACE
, "got 0x%08lx\n", hr
);
788 hr
= IUnknown_QueryInterface(session
, &IID_ICreateRow
, (void**)&unimplemented
);
789 ok(hr
== E_NOINTERFACE
, "got 0x%08lx\n", hr
);
791 hr
= IUnknown_QueryInterface(session
, &IID_ISessionProperties
, (void**)&session_props
);
792 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
793 ISessionProperties_Release(session_props
);
795 hr
= IUnknown_QueryInterface(session
, &IID_IOpenRowset
, (void**)&openrowset
);
796 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
798 hr
= IOpenRowset_QueryInterface(openrowset
, &IID_IDBCreateCommand
, (void**)&create_command
);
799 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
801 hr
= IDBCreateCommand_CreateCommand(create_command
, NULL
, &IID_IUnknown
, (IUnknown
**)&cmd
);
802 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
805 test_command_interfaces(cmd
);
806 test_command_text(cmd
);
807 test_command_dbsession(cmd
, session
);
808 test_command_rowset(cmd
);
809 IUnknown_Release(cmd
);
812 IDBCreateCommand_Release(create_command
);
813 IOpenRowset_Release(openrowset
);
814 IUnknown_Release( session
);
815 IDBCreateSession_Release(dbsession
);
816 IDBInitialize_Uninitialize( dbinit
);
817 IDBInitialize_Release( dbinit
);
818 IDataInitialize_Release( datainit
);
821 static void setup_database(void)
828 if (winetest_interactive
)
830 trace("assuming odbc 'wine_test' is available\n");
836 * 32 bit Windows has a default driver for "Microsoft Access Driver" (Windows 7+)
837 * and has the ability to create files on the fly.
839 * 64 bit Windows ONLY has a driver for "SQL Server", which we cannot use since we don't have a
840 * server to connect to.
842 * The filename passed to CREATE_DB must end in mdb.
844 GetTempPathA(sizeof(mdbpath
), mdbpath
);
845 strcat(mdbpath
, "wine_test.mdb");
847 driver
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof("DSN=wine_test\0CREATE_DB=") + strlen(mdbpath
) + 2);
848 memcpy(driver
, "DSN=wine_test\0CREATE_DB=", sizeof("DSN=wine_test\0CREATE_DB="));
849 strcat(driver
+sizeof("DSN=wine_test\0CREATE_DB=")-1, mdbpath
);
851 db_created
= SQLConfigDataSource(NULL
, ODBC_ADD_DSN
, "Microsoft Access Driver (*.mdb)", driver
);
854 SQLInstallerError(1, &code
, buffer
, sizeof(buffer
), &size
);
855 trace("code %ld, buffer %s, size %d\n", code
, debugstr_a(buffer
), size
);
857 HeapFree(GetProcessHeap(), 0, driver
);
862 memcpy(driver
, "DSN=wine_test\0DBQ=", sizeof("DSN=wine_test\0DBQ="));
863 strcat(driver
+sizeof("DSN=wine_test\0DBQ=")-1, mdbpath
);
864 db_created
= SQLConfigDataSource(NULL
, ODBC_ADD_DSN
, "Microsoft Access Driver (*.mdb)", driver
);
866 HeapFree(GetProcessHeap(), 0, driver
);
869 static void cleanup_database(void)
873 if (winetest_interactive
)
876 ret
= SQLConfigDataSource(NULL
, ODBC_REMOVE_DSN
, "Microsoft Access Driver (*.mdb)", "DSN=wine_test\0\0");
883 SQLInstallerError(1, &code
, buffer
, sizeof(buffer
), &size
);
884 trace("code %ld, buffer %s, size %d\n", code
, debugstr_a(buffer
), size
);
887 DeleteFileA(mdbpath
);
890 static void test_enumeration(void)
892 ISourcesRowset
*source
;
893 IRowset
*rowset
, *rowset2
;
894 IColumnsInfo
*columninfo
;
896 DBBINDING bindings
= { 1, 0, 0, 512, NULL
, NULL
, NULL
, DBPART_VALUE
| DBPART_STATUS
, DBMEMOWNER_CLIENTOWNED
, DBPARAMIO_NOTPARAM
, 514, 0, DBTYPE_WSTR
, 0, 0 };
900 DBCOLUMNINFO colinfo_data
[] =
902 { NULL
, NULL
, 0, DBCOLUMNFLAGS_ISFIXEDLENGTH
| DBCOLUMNFLAGS_ISBOOKMARK
, 4, DBTYPE_UI4
, 10, 255 },
903 { (WCHAR
*)L
"SOURCES_NAME", NULL
, 1, DBCOLUMNFLAGS_MAYBENULL
| DBCOLUMNFLAGS_WRITEUNKNOWN
, 128, DBTYPE_WSTR
, 255, 255 },
904 { (WCHAR
*)L
"SOURCES_PARSENAME", NULL
, 2, DBCOLUMNFLAGS_MAYBENULL
| DBCOLUMNFLAGS_WRITEUNKNOWN
, 128, DBTYPE_WSTR
, 255, 255 },
905 { (WCHAR
*)L
"SOURCES_DESCRIPTION", NULL
, 3, DBCOLUMNFLAGS_MAYBENULL
| DBCOLUMNFLAGS_WRITEUNKNOWN
, 128, DBTYPE_WSTR
, 255, 255 },
906 { (WCHAR
*)L
"SOURCES_TYPE", NULL
, 4, DBCOLUMNFLAGS_ISFIXEDLENGTH
| DBCOLUMNFLAGS_MAYBENULL
| DBCOLUMNFLAGS_WRITEUNKNOWN
, 2, DBTYPE_UI2
, 5, 255 },
907 { (WCHAR
*)L
"SOURCES_ISPARENT", NULL
, 5, DBCOLUMNFLAGS_ISFIXEDLENGTH
| DBCOLUMNFLAGS_MAYBENULL
| DBCOLUMNFLAGS_WRITEUNKNOWN
, 2, DBTYPE_BOOL
, 255, 255 }
910 hr
= CoCreateInstance( &CLSID_MSDASQL_ENUMERATOR
, NULL
, CLSCTX_INPROC_SERVER
, &IID_ISourcesRowset
,
914 skip("Failed create Enumerator object\n");
918 hr
= ISourcesRowset_GetSourcesRowset(source
, NULL
, &IID_IRowset
, 0, NULL
, (IUnknown
**)&rowset
);
919 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
921 hr
= ISourcesRowset_GetSourcesRowset(source
, NULL
, &IID_IRowset
, 0, NULL
, (IUnknown
**)&rowset2
);
922 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
923 ok(rowset
!= rowset2
, "same pointer\n");
924 IRowset_Release(rowset2
);
926 hr
= IRowset_QueryInterface(rowset
, &IID_IColumnsInfo
, (void**)&columninfo
);
927 todo_wine
ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
931 DBCOLUMNINFO
*dbcolumninfo
;
935 hr
= IColumnsInfo_GetColumnInfo(columninfo
, &columns
, &dbcolumninfo
, &buffer
);
936 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
937 ok(columns
== 6, "got %Iu\n", columns
);
939 for( i
= 0; i
< columns
; i
++ )
941 if (!dbcolumninfo
[i
].pwszName
|| !colinfo_data
[i
].pwszName
)
942 ok (dbcolumninfo
[i
].pwszName
== colinfo_data
[i
].pwszName
, "got %p/%p\n", dbcolumninfo
[i
].pwszName
, colinfo_data
[i
].pwszName
);
944 ok ( !wcscmp(dbcolumninfo
[i
].pwszName
, colinfo_data
[i
].pwszName
), "got %p/%p\n",
945 debugstr_w(dbcolumninfo
[i
].pwszName
), debugstr_w(colinfo_data
[i
].pwszName
));
947 ok (dbcolumninfo
[i
].pTypeInfo
== colinfo_data
[i
].pTypeInfo
, "got %p/%p\n", dbcolumninfo
[i
].pTypeInfo
, colinfo_data
[i
].pTypeInfo
);
948 ok (dbcolumninfo
[i
].iOrdinal
== colinfo_data
[i
].iOrdinal
, "got %Id/%Id\n", dbcolumninfo
[i
].iOrdinal
, colinfo_data
[i
].iOrdinal
);
949 ok (dbcolumninfo
[i
].dwFlags
== colinfo_data
[i
].dwFlags
, "got 0x%08lx/0x%08lx\n", dbcolumninfo
[i
].dwFlags
, colinfo_data
[i
].dwFlags
);
950 ok (dbcolumninfo
[i
].ulColumnSize
== colinfo_data
[i
].ulColumnSize
, "got %Iu/%Iu\n", dbcolumninfo
[i
].ulColumnSize
, colinfo_data
[i
].ulColumnSize
);
951 ok (dbcolumninfo
[i
].wType
== colinfo_data
[i
].wType
, "got %d/%d\n", dbcolumninfo
[i
].wType
, colinfo_data
[i
].wType
);
952 ok (dbcolumninfo
[i
].bPrecision
== colinfo_data
[i
].bPrecision
, "got %d/%d\n", dbcolumninfo
[i
].bPrecision
, colinfo_data
[i
].bPrecision
);
953 ok (dbcolumninfo
[i
].bScale
== colinfo_data
[i
].bScale
, "got %d/%d\n", dbcolumninfo
[i
].bScale
, colinfo_data
[i
].bScale
);
956 CoTaskMemFree(buffer
);
957 IColumnsInfo_Release(columninfo
);
960 hr
= IRowset_QueryInterface(rowset
, &IID_IAccessor
, (void**)&accessor
);
961 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
963 /* Request only SOURCES_NAME column */
964 hr
= IAccessor_CreateAccessor(accessor
, DBACCESSOR_ROWDATA
, 1, &bindings
, 0, &hacc
, NULL
);
965 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
966 ok(hacc
!= 0, "got %Ix\n", hacc
);
968 hr
= IAccessor_ReleaseAccessor(accessor
, hacc
, NULL
);
969 ok(hr
== S_OK
, "got 0x%08lx\n", hr
);
971 IAccessor_Release(accessor
);
973 IRowset_Release(rowset
);
974 ISourcesRowset_Release(source
);