msdasql: Support IAccessor in IRowset for Enumeration.
[wine.git] / dlls / oledb32 / tests / database.c
blob421f4258afd39f747658123366d5ba3dfc400a47
1 /* OLEDB Database tests
3 * Copyright 2012 Alistair Leslie-Hughes
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdarg.h>
20 #include <stdio.h>
22 #define COBJMACROS
23 #define CONST_VTABLE
24 #define DBINITCONSTANTS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "ole2.h"
29 #include "msdadc.h"
30 #include "msdasc.h"
31 #include "msdaguid.h"
32 #include "initguid.h"
33 #include "oledb.h"
34 #include "oledberr.h"
35 #include "msdasql.h"
37 #include "wine/test.h"
39 DEFINE_GUID(CSLID_MSDAER, 0xc8b522cf,0x5cf3,0x11ce,0xad,0xe5,0x00,0xaa,0x00,0x44,0x77,0x3d);
41 static WCHAR initstring_default[] = {'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',0};
43 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
44 static void _expect_ref(IUnknown* obj, ULONG ref, int line)
46 ULONG rc;
47 IUnknown_AddRef(obj);
48 rc = IUnknown_Release(obj);
49 ok_(__FILE__, line)(rc == ref, "expected refcount %d, got %d\n", ref, rc);
52 static void test_GetDataSource(WCHAR *initstring)
54 IDataInitialize *datainit = NULL;
55 IDBInitialize *dbinit = NULL;
56 HRESULT hr;
58 trace("Data Source: %s\n", wine_dbgstr_w(initstring));
60 hr = CoCreateInstance(&CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,(void**)&datainit);
61 ok(hr == S_OK, "got %08x\n", hr);
63 EXPECT_REF(datainit, 1);
65 /* a failure to create data source here may indicate provider is simply not present */
66 hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, initstring, &IID_IDBInitialize, (IUnknown**)&dbinit);
67 if(SUCCEEDED(hr))
69 IDBProperties *props = NULL;
71 EXPECT_REF(datainit, 1);
72 EXPECT_REF(dbinit, 1);
74 hr = IDBInitialize_QueryInterface(dbinit, &IID_IDBProperties, (void**)&props);
75 ok(hr == S_OK, "got %08x\n", hr);
76 if(SUCCEEDED(hr))
78 ULONG cnt;
79 DBPROPINFOSET *pInfoset;
80 OLECHAR *ary;
82 EXPECT_REF(dbinit, 2);
83 EXPECT_REF(props, 2);
84 hr = IDBProperties_GetPropertyInfo(props, 0, NULL, &cnt, &pInfoset, &ary);
85 ok(hr == S_OK, "got %08x\n", hr);
86 if(hr == S_OK)
88 ULONG i;
89 for(i =0; i < pInfoset->cPropertyInfos; i++)
91 trace("(0x%04x) '%s' %d\n", pInfoset->rgPropertyInfos[i].dwPropertyID, wine_dbgstr_w(pInfoset->rgPropertyInfos[i].pwszDescription),
92 pInfoset->rgPropertyInfos[i].vtType);
95 CoTaskMemFree(pInfoset);
96 CoTaskMemFree(ary);
99 IDBProperties_Release(props);
102 EXPECT_REF(dbinit, 1);
103 IDBInitialize_Release(dbinit);
106 EXPECT_REF(datainit, 1);
107 IDataInitialize_Release(datainit);
110 /* IDBProperties stub */
111 static HRESULT WINAPI dbprops_QI(IDBProperties *iface, REFIID riid, void **obj)
113 if (IsEqualIID(riid, &IID_IDBProperties) || IsEqualIID(riid, &IID_IUnknown)) {
114 *obj = iface;
115 IDBProperties_AddRef(iface);
116 return S_OK;
119 *obj = NULL;
120 return E_NOINTERFACE;
123 static ULONG WINAPI dbprops_AddRef(IDBProperties *iface)
125 return 2;
128 static ULONG WINAPI dbprops_Release(IDBProperties *iface)
130 return 1;
133 static HRESULT WINAPI dbprops_GetProperties(IDBProperties *iface, ULONG cPropertyIDSets,
134 const DBPROPIDSET rgPropertyIDSets[], ULONG *pcPropertySets, DBPROPSET **prgPropertySets)
136 ok(0, "unexpected call\n");
137 return E_NOTIMPL;
140 static HRESULT WINAPI dbprops_GetPropertyInfo(IDBProperties *iface, ULONG cPropertyIDSets,
141 const DBPROPIDSET rgPropertyIDSets[], ULONG *pcPropertyInfoSets, DBPROPINFOSET **prgPropertyInfoSets,
142 OLECHAR **ppDescBuffer)
144 ok(0, "unexpected call\n");
145 return E_NOTIMPL;
148 static HRESULT WINAPI dbprops_SetProperties(IDBProperties *iface, ULONG set_count, DBPROPSET propsets[])
150 ok(set_count == 1, "got %u\n", set_count);
152 ok(IsEqualIID(&propsets->guidPropertySet, &DBPROPSET_DBINIT), "set guid %s\n", wine_dbgstr_guid(&propsets->guidPropertySet));
153 ok(propsets->cProperties == 2, "got propcount %u\n", propsets->cProperties);
155 if (propsets->cProperties == 2) {
156 ok(propsets->rgProperties[0].dwPropertyID == DBPROP_INIT_DATASOURCE, "got propid[0] %u\n", propsets->rgProperties[0].dwPropertyID);
157 ok(propsets->rgProperties[0].dwOptions == DBPROPOPTIONS_REQUIRED, "got options[0] %u\n", propsets->rgProperties[0].dwOptions);
158 ok(propsets->rgProperties[0].dwStatus == 0, "got status[0] %u\n", propsets->rgProperties[0].dwStatus);
159 ok(V_VT(&propsets->rgProperties[0].vValue) == VT_BSTR, "got vartype[0] %u\n", V_VT(&propsets->rgProperties[0].vValue));
161 ok(propsets->rgProperties[1].dwPropertyID == DBPROP_INIT_PROVIDERSTRING, "got propid[1] %u\n", propsets->rgProperties[1].dwPropertyID);
162 ok(propsets->rgProperties[1].dwOptions == DBPROPOPTIONS_REQUIRED, "got options[1] %u\n", propsets->rgProperties[1].dwOptions);
163 ok(propsets->rgProperties[1].dwStatus == 0, "got status[1] %u\n", propsets->rgProperties[1].dwStatus);
164 ok(V_VT(&propsets->rgProperties[1].vValue) == VT_BSTR, "got vartype[1] %u\n", V_VT(&propsets->rgProperties[1].vValue));
166 return S_OK;
169 static const IDBPropertiesVtbl dbpropsvtbl = {
170 dbprops_QI,
171 dbprops_AddRef,
172 dbprops_Release,
173 dbprops_GetProperties,
174 dbprops_GetPropertyInfo,
175 dbprops_SetProperties
178 static IDBProperties dbprops = { &dbpropsvtbl };
180 /* IPersist stub */
181 static HRESULT WINAPI dbpersist_QI(IPersist *iface, REFIID riid, void **obj)
183 if (IsEqualIID(riid, &IID_IPersist) || IsEqualIID(riid, &IID_IUnknown)) {
184 *obj = iface;
185 IPersist_AddRef(iface);
186 return S_OK;
189 *obj = NULL;
190 return E_NOINTERFACE;
193 static ULONG WINAPI dbpersist_AddRef(IPersist *iface)
195 return 2;
198 static ULONG WINAPI dbpersist_Release(IPersist *iface)
200 return 1;
203 static HRESULT WINAPI dbpersist_GetClassID(IPersist *iface, CLSID *clsid)
205 static const WCHAR msdasqlW[] = {'M','S','D','A','S','Q','L',0};
206 return CLSIDFromProgID(msdasqlW, clsid);
209 static const IPersistVtbl dbpersistvtbl = {
210 dbpersist_QI,
211 dbpersist_AddRef,
212 dbpersist_Release,
213 dbpersist_GetClassID
216 static IPersist dbpersist = { &dbpersistvtbl };
218 /* IDBInitialize stub */
219 static HRESULT WINAPI dbinit_QI(IDBInitialize *iface, REFIID riid, void **obj)
221 if (IsEqualIID(riid, &IID_IDBInitialize) || IsEqualIID(riid, &IID_IUnknown)) {
222 *obj = iface;
223 IDBInitialize_AddRef(iface);
224 return S_OK;
226 else if (IsEqualIID(riid, &IID_IPersist)) {
227 *obj = &dbpersist;
228 return S_OK;
230 else if (IsEqualIID(riid, &IID_IDBProperties)) {
231 *obj = &dbprops;
232 return S_OK;
235 *obj = NULL;
236 return E_NOINTERFACE;
239 static ULONG WINAPI dbinit_AddRef(IDBInitialize *iface)
241 return 2;
244 static ULONG WINAPI dbinit_Release(IDBInitialize *iface)
246 return 1;
249 static HRESULT WINAPI dbinit_Initialize(IDBInitialize *iface)
251 ok(0, "unexpected call\n");
252 return E_NOTIMPL;
255 static HRESULT WINAPI dbinit_Uninitialize(IDBInitialize *iface)
257 ok(0, "unexpected call\n");
258 return E_NOTIMPL;
261 static const IDBInitializeVtbl dbinitvtbl = {
262 dbinit_QI,
263 dbinit_AddRef,
264 dbinit_Release,
265 dbinit_Initialize,
266 dbinit_Uninitialize
269 static IDBInitialize dbinittest = { &dbinitvtbl };
271 static void test_GetDataSource2(WCHAR *initstring)
273 IDataInitialize *datainit = NULL;
274 IDBInitialize *dbinit = NULL;
275 HRESULT hr;
277 hr = CoCreateInstance(&CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,(void**)&datainit);
278 ok(hr == S_OK, "got %08x\n", hr);
280 dbinit = &dbinittest;
281 hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, initstring, &IID_IDBInitialize, (IUnknown**)&dbinit);
282 ok(hr == S_OK, "got %08x\n", hr);
284 IDataInitialize_Release(datainit);
287 static void test_database(void)
289 static WCHAR initstring_jet[] = {'P','r','o','v','i','d','e','r','=','M','i','c','r','o','s','o','f','t','.',
290 'J','e','t','.','O','L','E','D','B','.','4','.','0',';',
291 'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',
292 'P','e','r','s','i','s','t',' ','S','e','c','u','r','i','t','y',' ','I','n','f','o','=','F','a','l','s','e',';',0};
293 static WCHAR initstring_lower[] = {'d','a','t','a',' ','s','o','u','r','c','e','=','d','u','m','m','y',';',0};
294 static WCHAR customprop[] = {'d','a','t','a',' ','s','o','u','r','c','e','=','d','u','m','m','y',';',
295 'c','u','s','t','o','m','p','r','o','p','=','1','2','3','.','4',';',0};
296 static WCHAR extended_prop[] = {'d','a','t','a',' ','s','o','u','r','c','e','=','d','u','m','m','y',';',
297 'E','x','t','e','n','d','e','d',' ','P','r','o','p','e','r','t','i','e','s','=','\"','D','R','I','V','E','R','=','A',
298 ' ','W','i','n','e',' ','O','D','B','C',' ','d','r','i','v','e','r',';','U','I','D','=','w','i','n','e',';','\"',';',0};
299 static WCHAR extended_prop2[] = {'d','a','t','a',' ','s','o','u','r','c','e','=','\'','d','u','m','m','y','\'',';',
300 'c','u','s','t','o','m','p','r','o','p','=','\'','1','2','3','.','4','\'',';',0};
301 IDataInitialize *datainit = NULL;
302 HRESULT hr;
304 hr = CoCreateInstance(&CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize, (void**)&datainit);
305 if (FAILED(hr))
307 win_skip("Unable to load oledb library\n");
308 return;
310 IDataInitialize_Release(datainit);
312 test_GetDataSource(NULL);
313 test_GetDataSource(initstring_jet);
314 test_GetDataSource(initstring_default);
315 test_GetDataSource(initstring_lower);
316 test_GetDataSource2(customprop);
317 test_GetDataSource2(extended_prop);
318 test_GetDataSource2(extended_prop2);
321 static void free_dispparams(DISPPARAMS *params)
323 unsigned int i;
325 for (i = 0; i < params->cArgs && params->rgvarg; i++)
326 VariantClear(&params->rgvarg[i]);
327 CoTaskMemFree(params->rgvarg);
328 CoTaskMemFree(params->rgdispidNamedArgs);
331 static void test_errorinfo(void)
333 ICreateErrorInfo *createerror;
334 ERRORINFO info, info2, info3;
335 IErrorInfo *errorinfo, *errorinfo2;
336 IErrorRecords *errrecs;
337 IUnknown *unk = NULL, *unk2;
338 DISPPARAMS dispparams;
339 DISPID dispid;
340 DWORD context;
341 ULONG cnt = 0;
342 VARIANT arg;
343 HRESULT hr;
344 GUID guid;
345 BSTR str;
347 hr = CoCreateInstance(&CSLID_MSDAER, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&unk);
348 ok(hr == S_OK, "got %08x\n", hr);
350 hr = IUnknown_QueryInterface(unk, &IID_IErrorInfo, (void**)&errorinfo);
351 ok(hr == S_OK, "got %08x\n", hr);
353 hr = IErrorInfo_GetGUID(errorinfo, NULL);
354 ok(hr == E_INVALIDARG, "got %08x\n", hr);
356 hr = IErrorInfo_GetSource(errorinfo, NULL);
357 ok(hr == E_INVALIDARG, "got %08x\n", hr);
359 hr = IErrorInfo_GetDescription(errorinfo, NULL);
360 ok(hr == E_INVALIDARG, "got %08x\n", hr);
362 hr = IErrorInfo_GetHelpFile(errorinfo, NULL);
363 ok(hr == E_INVALIDARG, "got %08x\n", hr);
365 hr = IErrorInfo_GetHelpContext(errorinfo, NULL);
366 ok(hr == E_INVALIDARG, "got %08x\n", hr);
368 memset(&guid, 0xac, sizeof(guid));
369 hr = IErrorInfo_GetGUID(errorinfo, &guid);
370 ok(hr == S_OK, "got %08x\n", hr);
371 ok(IsEqualGUID(&guid, &GUID_NULL), "got wrong guid\n");
373 str = (BSTR)0x1;
374 hr = IErrorInfo_GetSource(errorinfo, &str);
375 ok(hr == E_FAIL, "got %08x\n", hr);
376 ok(str == NULL, "got %s\n", wine_dbgstr_w(str));
378 str = (BSTR)0x1;
379 hr = IErrorInfo_GetDescription(errorinfo, &str);
380 ok(hr == E_FAIL, "got %08x\n", hr);
381 ok(str == NULL, "got %s\n", wine_dbgstr_w(str));
383 str = (BSTR)0x1;
384 hr = IErrorInfo_GetHelpFile(errorinfo, &str);
385 ok(hr == E_FAIL, "got %08x\n", hr);
386 ok(str == NULL, "got %s\n", wine_dbgstr_w(str));
388 context = 1;
389 hr = IErrorInfo_GetHelpContext(errorinfo, &context);
390 ok(hr == E_FAIL, "got %08x\n", hr);
391 ok(context == 0, "got %d\n", context);
393 IErrorInfo_Release(errorinfo);
395 hr = IErrorInfo_QueryInterface(errorinfo, &IID_ICreateErrorInfo, (void**)&createerror);
396 ok(hr == E_NOINTERFACE, "got %08x\n", hr);
398 hr = IUnknown_QueryInterface(unk, &IID_IErrorRecords, (void**)&errrecs);
399 ok(hr == S_OK, "got %08x\n", hr);
401 hr = IErrorRecords_GetRecordCount(errrecs, &cnt);
402 ok(hr == S_OK, "got %08x\n", hr);
403 ok(cnt == 0, "Got unexpected record count %u\n", cnt);
405 hr = IErrorRecords_GetBasicErrorInfo(errrecs, 0, &info3);
406 ok(hr == DB_E_BADRECORDNUM, "got %08x\n", hr);
408 hr = IErrorRecords_GetCustomErrorObject(errrecs, 0, &IID_IUnknown, &unk2);
409 ok(hr == DB_E_BADRECORDNUM, "got %08x\n", hr);
411 hr = IErrorRecords_GetErrorInfo(errrecs, 0, 0, &errorinfo2);
412 ok(hr == DB_E_BADRECORDNUM, "got %08x\n", hr);
414 hr = IErrorRecords_GetErrorParameters(errrecs, 0, &dispparams);
415 ok(hr == DB_E_BADRECORDNUM, "got %08x\n", hr);
417 memset(&info, 0, sizeof(ERRORINFO));
418 info.dwMinor = 1;
419 memset(&info2, 0, sizeof(ERRORINFO));
420 info2.dwMinor = 2;
421 memset(&info3, 0, sizeof(ERRORINFO));
423 hr = IErrorRecords_AddErrorRecord(errrecs, NULL, 268435456, NULL, NULL, 0);
424 ok(hr == E_INVALIDARG, "got %08x\n", hr);
426 hr = IErrorRecords_AddErrorRecord(errrecs, &info, 1, NULL, NULL, 0);
427 ok(hr == S_OK, "got %08x\n", hr);
429 hr = IErrorRecords_GetRecordCount(errrecs, &cnt);
430 ok(hr == S_OK, "got %08x\n", hr);
431 ok(cnt == 1, "expected 1 got %d\n", cnt);
433 /* Record does not contain custom error object. */
434 unk2 = (void*)0xdeadbeef;
435 hr = IErrorRecords_GetCustomErrorObject(errrecs, 0, &IID_IUnknown, &unk2);
436 ok(hr == S_OK, "got %08x\n", hr);
437 ok(unk2 == NULL, "Got custom object %p.\n", unk2);
439 hr = IErrorRecords_AddErrorRecord(errrecs, &info2, 2, NULL, NULL, 0);
440 ok(hr == S_OK, "got %08x\n", hr);
442 hr = IErrorRecords_GetRecordCount(errrecs, &cnt);
443 ok(hr == S_OK, "got %08x\n", hr);
444 ok(cnt == 2, "expected 2 got %d\n", cnt);
446 hr = IErrorRecords_GetBasicErrorInfo(errrecs, 0, NULL);
447 ok(hr == E_INVALIDARG, "got %08x\n", hr);
449 hr = IErrorRecords_GetBasicErrorInfo(errrecs, 100, &info3);
450 ok(hr == DB_E_BADRECORDNUM, "got %08x\n", hr);
452 hr = IErrorRecords_GetBasicErrorInfo(errrecs, 0, &info3);
453 ok(hr == S_OK, "got %08x\n", hr);
454 ok(info3.dwMinor == 2, "expected 2 got %d\n", info3.dwMinor);
456 hr = IErrorRecords_GetErrorParameters(errrecs, 0, NULL);
457 ok(hr == E_INVALIDARG, "got %08x\n", hr);
459 memset(&dispparams, 0xcc, sizeof(dispparams));
460 hr = IErrorRecords_GetErrorParameters(errrecs, 0, &dispparams);
461 ok(hr == S_OK, "got %08x\n", hr);
462 ok(dispparams.rgvarg == NULL, "Got arguments %p\n", dispparams.rgvarg);
463 ok(dispparams.rgdispidNamedArgs == NULL, "Got named arguments %p\n", dispparams.rgdispidNamedArgs);
464 ok(dispparams.cArgs == 0, "Got argument count %u\n", dispparams.cArgs);
465 ok(dispparams.cNamedArgs == 0, "Got named argument count %u\n", dispparams.cNamedArgs);
467 V_VT(&arg) = VT_BSTR;
468 V_BSTR(&arg) = SysAllocStringLen(NULL, 0);
469 dispid = 0x123;
471 dispparams.rgvarg = &arg;
472 dispparams.cArgs = 1;
473 dispparams.rgdispidNamedArgs = &dispid;
474 dispparams.cNamedArgs = 1;
475 hr = IErrorRecords_AddErrorRecord(errrecs, &info2, 0, &dispparams, NULL, 0);
476 ok(hr == S_OK, "got %08x\n", hr);
478 memset(&dispparams, 0, sizeof(dispparams));
479 hr = IErrorRecords_GetErrorParameters(errrecs, 0, &dispparams);
480 ok(hr == S_OK, "got %08x\n", hr);
482 ok(V_VT(&dispparams.rgvarg[0]) == VT_BSTR, "Got arg type %d\n", V_VT(&dispparams.rgvarg[0]));
483 ok(V_BSTR(&dispparams.rgvarg[0]) != V_BSTR(&arg), "Got arg bstr %d\n", V_VT(&dispparams.rgvarg[0]));
485 ok(dispparams.rgdispidNamedArgs[0] == 0x123, "Got named argument %d\n", dispparams.rgdispidNamedArgs[0]);
486 ok(dispparams.cArgs == 1, "Got argument count %u\n", dispparams.cArgs);
487 ok(dispparams.cNamedArgs == 1, "Got named argument count %u\n", dispparams.cNamedArgs);
489 EXPECT_REF(errrecs, 2);
490 EXPECT_REF(errorinfo, 2);
491 hr = IErrorRecords_GetErrorInfo(errrecs, 0, 0, &errorinfo2);
492 ok(hr == S_OK, "got %08x\n", hr);
493 ok(errorinfo == errorinfo2, "different object\n");
494 EXPECT_REF(errorinfo, 3);
495 IErrorInfo_Release(errorinfo2);
497 free_dispparams(&dispparams);
498 VariantClear(&arg);
500 IErrorRecords_Release(errrecs);
501 IUnknown_Release(unk);
504 static void test_initializationstring(void)
506 static const WCHAR initstring_msdasql[] = {'P','r','o','v','i','d','e','r','=','M','S','D','A','S','Q','L','.','1',';',
507 'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y', 0};
508 static const WCHAR initstring_msdasql2[] = {'p','R','o','V','i','D','e','R','=','M','S','D','A','S','Q','L','.','1',';',
509 'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y', 0};
510 static const WCHAR initstring_sqloledb[] = {'P','r','o','v','i','d','e','r','=','S','Q','L','O','L','E','D','B','.','1',';',
511 'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y', 0};
512 static const WCHAR initstring_mode[] = {'P','r','o','v','i','d','e','r','=','M','S','D','A','S','Q','L','.','1',';',
513 'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',
514 'M','o','d','e','=','i','n','v','a','l','i','d',0};
515 static const WCHAR initstring_mode2[] = {'P','r','o','v','i','d','e','r','=','M','S','D','A','S','Q','L','.','1',';',
516 'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',
517 'M','o','d','e','=','W','r','i','t','e','R','e','a','d',0};
518 static const WCHAR initstring_mode3[] = {'P','r','o','v','i','d','e','r','=','M','S','D','A','S','Q','L','.','1',';',
519 'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',
520 'M','o','d','e','=','R','e','a','d','W','R','I','T','E',0};
521 IDataInitialize *datainit = NULL;
522 IDBInitialize *dbinit;
523 HRESULT hr;
524 WCHAR *initstring = NULL;
526 hr = CoCreateInstance(&CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,(void**)&datainit);
527 ok(hr == S_OK, "got %08x\n", hr);
528 if(SUCCEEDED(hr))
530 EXPECT_REF(datainit, 1);
532 dbinit = NULL;
533 hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, initstring_default,
534 &IID_IDBInitialize, (IUnknown**)&dbinit);
535 if(SUCCEEDED(hr))
537 EXPECT_REF(datainit, 1);
538 EXPECT_REF(dbinit, 1);
540 hr = IDataInitialize_GetInitializationString(datainit, (IUnknown*)dbinit, 0, &initstring);
541 ok(hr == S_OK, "got %08x\n", hr);
542 if(hr == S_OK)
544 trace("Init String: %s\n", wine_dbgstr_w(initstring));
545 todo_wine ok(!lstrcmpW(initstring_msdasql, initstring) ||
546 !lstrcmpW(initstring_sqloledb, initstring), "got %s\n", wine_dbgstr_w(initstring));
547 CoTaskMemFree(initstring);
550 IDBInitialize_Release(dbinit);
552 /* mixed casing string */
553 dbinit = NULL;
554 hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, (WCHAR*)initstring_msdasql2,
555 &IID_IDBInitialize, (IUnknown**)&dbinit);
556 ok(hr == S_OK, "got 0x%08x\n", hr);
557 IDBInitialize_Release(dbinit);
559 /* Invalid Mode value */
560 dbinit = NULL;
561 hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, (WCHAR *)initstring_mode,
562 &IID_IDBInitialize, (IUnknown **)&dbinit);
563 ok(FAILED(hr), "got 0x%08x\n", hr);
565 dbinit = NULL;
566 hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, (WCHAR *)initstring_mode2,
567 &IID_IDBInitialize, (IUnknown **)&dbinit);
568 ok(FAILED(hr), "got 0x%08x\n", hr);
570 dbinit = NULL;
571 hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, (WCHAR *)initstring_mode3,
572 &IID_IDBInitialize, (IUnknown **)&dbinit);
573 ok(hr == S_OK, "got 0x%08x\n", hr);
574 IDBInitialize_Release(dbinit);
576 else
577 ok(dbinit == NULL, "got %p\n", dbinit);
579 IDataInitialize_Release(datainit);
583 static void test_rowposition(void)
585 IEnumConnectionPoints *enum_points;
586 IConnectionPointContainer *cpc;
587 IConnectionPoint *cp;
588 IRowPosition *rowpos;
589 HRESULT hr;
590 IID iid;
592 hr = CoCreateInstance(&CLSID_OLEDB_ROWPOSITIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IRowPosition, (void**)&rowpos);
593 ok(hr == S_OK, "got %08x\n", hr);
595 hr = IRowPosition_QueryInterface(rowpos, &IID_IConnectionPointContainer, (void**)&cpc);
596 ok(hr == S_OK, "got 0x%08x\n", hr);
598 hr = IConnectionPointContainer_EnumConnectionPoints(cpc, &enum_points);
599 todo_wine
600 ok(hr == S_OK, "got 0x%08x\n", hr);
601 if (hr == S_OK) {
602 hr = IEnumConnectionPoints_Next(enum_points, 1, &cp, NULL);
603 ok(hr == S_OK, "got 0x%08x\n", hr);
604 hr = IConnectionPoint_GetConnectionInterface(cp, &iid);
605 ok(hr == S_OK, "got 0x%08x\n", hr);
606 ok(IsEqualIID(&iid, &IID_IRowPositionChange), "got %s\n", wine_dbgstr_guid(&iid));
607 IConnectionPoint_Release(cp);
609 hr = IEnumConnectionPoints_Next(enum_points, 1, &cp, NULL);
610 ok(hr == S_FALSE, "got 0x%08x\n", hr);
612 IEnumConnectionPoints_Release(enum_points);
614 IConnectionPointContainer_Release(cpc);
615 IRowPosition_Release(rowpos);
618 typedef struct
620 IRowset IRowset_iface;
621 IChapteredRowset IChapteredRowset_iface;
622 } test_rset_t;
624 static test_rset_t test_rset;
626 static HRESULT WINAPI rset_QI(IRowset *iface, REFIID riid, void **obj)
628 if (IsEqualIID(riid, &IID_IUnknown) ||
629 IsEqualIID(riid, &IID_IRowset))
631 *obj = &test_rset.IRowset_iface;
632 return S_OK;
634 else if (IsEqualIID(riid, &IID_IChapteredRowset))
636 *obj = &test_rset.IChapteredRowset_iface;
637 return S_OK;
640 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
641 return E_NOINTERFACE;
644 static ULONG WINAPI rset_AddRef(IRowset *iface)
646 return 2;
649 static ULONG WINAPI rset_Release(IRowset *iface)
651 return 1;
654 static HRESULT WINAPI rset_AddRefRows(IRowset *iface, DBCOUNTITEM cRows,
655 const HROW rghRows[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
657 trace("AddRefRows: %ld\n", rghRows[0]);
658 return S_OK;
661 static HRESULT WINAPI rset_GetData(IRowset *iface, HROW hRow, HACCESSOR hAccessor, void *pData)
663 ok(0, "unexpected call\n");
664 return E_NOTIMPL;
667 static HRESULT WINAPI rset_GetNextRows(IRowset *iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
668 DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
670 ok(0, "unexpected call\n");
671 return E_NOTIMPL;
674 static HRESULT WINAPI rset_ReleaseRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[], DBROWOPTIONS rgRowOptions[],
675 DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
677 return S_OK;
680 static HRESULT WINAPI rset_RestartPosition(IRowset *iface, HCHAPTER hReserved)
682 ok(0, "unexpected call\n");
683 return E_NOTIMPL;
686 static const IRowsetVtbl rset_vtbl = {
687 rset_QI,
688 rset_AddRef,
689 rset_Release,
690 rset_AddRefRows,
691 rset_GetData,
692 rset_GetNextRows,
693 rset_ReleaseRows,
694 rset_RestartPosition
697 static HRESULT WINAPI chrset_QI(IChapteredRowset *iface, REFIID riid, void **obj)
699 return IRowset_QueryInterface(&test_rset.IRowset_iface, riid, obj);
702 static ULONG WINAPI chrset_AddRef(IChapteredRowset *iface)
704 return IRowset_AddRef(&test_rset.IRowset_iface);
707 static ULONG WINAPI chrset_Release(IChapteredRowset *iface)
709 return IRowset_Release(&test_rset.IRowset_iface);
712 static HRESULT WINAPI chrset_AddRefChapter(IChapteredRowset *iface, HCHAPTER chapter, DBREFCOUNT *refcount)
714 return S_OK;
717 static HRESULT WINAPI chrset_ReleaseChapter(IChapteredRowset *iface, HCHAPTER chapter, DBREFCOUNT *refcount)
719 return S_OK;
722 static const IChapteredRowsetVtbl chrset_vtbl = {
723 chrset_QI,
724 chrset_AddRef,
725 chrset_Release,
726 chrset_AddRefChapter,
727 chrset_ReleaseChapter
730 static void init_test_rset(void)
732 test_rset.IRowset_iface.lpVtbl = &rset_vtbl;
733 test_rset.IChapteredRowset_iface.lpVtbl = &chrset_vtbl;
736 static void test_rowpos_initialize(void)
738 IRowPosition *rowpos;
739 HRESULT hr;
741 hr = CoCreateInstance(&CLSID_OLEDB_ROWPOSITIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IRowPosition, (void**)&rowpos);
742 ok(hr == S_OK, "got %08x\n", hr);
744 init_test_rset();
745 hr = IRowPosition_Initialize(rowpos, (IUnknown*)&test_rset.IRowset_iface);
746 ok(hr == S_OK, "got %08x\n", hr);
748 IRowPosition_Release(rowpos);
751 static HRESULT WINAPI onchange_QI(IRowPositionChange *iface, REFIID riid, void **obj)
753 if (IsEqualIID(riid, &IID_IUnknown) ||
754 IsEqualIID(riid, &IID_IRowPositionChange))
756 *obj = iface;
757 return S_OK;
760 return E_NOINTERFACE;
763 static ULONG WINAPI onchange_AddRef(IRowPositionChange *iface)
765 return 2;
768 static ULONG WINAPI onchange_Release(IRowPositionChange *iface)
770 return 1;
773 static HRESULT WINAPI onchange_OnRowPositionChange(IRowPositionChange *iface, DBREASON reason,
774 DBEVENTPHASE phase, BOOL cant_deny)
776 trace("%d %d %d\n", reason, phase, cant_deny);
777 return S_OK;
780 static const IRowPositionChangeVtbl onchange_vtbl = {
781 onchange_QI,
782 onchange_AddRef,
783 onchange_Release,
784 onchange_OnRowPositionChange
787 static IRowPositionChange onchangesink = { &onchange_vtbl };
789 static void init_onchange_sink(IRowPosition *rowpos)
791 IConnectionPointContainer *cpc;
792 IConnectionPoint *cp;
793 DWORD cookie;
794 HRESULT hr;
796 hr = IRowPosition_QueryInterface(rowpos, &IID_IConnectionPointContainer, (void**)&cpc);
797 ok(hr == S_OK, "got %08x\n", hr);
798 hr = IConnectionPointContainer_FindConnectionPoint(cpc, &IID_IRowPositionChange, &cp);
799 ok(hr == S_OK, "got %08x\n", hr);
800 hr = IConnectionPoint_Advise(cp, (IUnknown*)&onchangesink, &cookie);
801 ok(hr == S_OK, "got %08x\n", hr);
802 IConnectionPoint_Release(cp);
803 IConnectionPointContainer_Release(cpc);
806 static void test_rowpos_clearrowposition(void)
808 DBPOSITIONFLAGS flags;
809 IRowPosition *rowpos;
810 HCHAPTER chapter;
811 IUnknown *unk;
812 HRESULT hr;
813 HROW row;
815 hr = CoCreateInstance(&CLSID_OLEDB_ROWPOSITIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IRowPosition, (void**)&rowpos);
816 ok(hr == S_OK, "got %08x\n", hr);
818 hr = IRowPosition_ClearRowPosition(rowpos);
819 ok(hr == E_UNEXPECTED, "got %08x\n", hr);
821 hr = IRowPosition_GetRowset(rowpos, &IID_IStream, &unk);
822 ok(hr == E_UNEXPECTED, "got %08x\n", hr);
824 chapter = 1;
825 row = 1;
826 flags = DBPOSITION_OK;
827 hr = IRowPosition_GetRowPosition(rowpos, &chapter, &row, &flags);
828 ok(hr == E_UNEXPECTED, "got %08x\n", hr);
829 ok(chapter == DB_NULL_HCHAPTER, "got %ld\n", chapter);
830 ok(row == DB_NULL_HROW, "got %ld\n", row);
831 ok(flags == DBPOSITION_NOROW, "got %d\n", flags);
833 init_test_rset();
834 hr = IRowPosition_Initialize(rowpos, (IUnknown*)&test_rset.IRowset_iface);
835 ok(hr == S_OK, "got %08x\n", hr);
837 chapter = 1;
838 row = 1;
839 flags = DBPOSITION_OK;
840 hr = IRowPosition_GetRowPosition(rowpos, &chapter, &row, &flags);
841 ok(hr == S_OK, "got %08x\n", hr);
842 ok(chapter == DB_NULL_HCHAPTER, "got %ld\n", chapter);
843 ok(row == DB_NULL_HROW, "got %ld\n", row);
844 ok(flags == DBPOSITION_NOROW, "got %d\n", flags);
846 hr = IRowPosition_GetRowset(rowpos, &IID_IRowset, &unk);
847 ok(hr == S_OK, "got %08x\n", hr);
849 init_onchange_sink(rowpos);
850 hr = IRowPosition_ClearRowPosition(rowpos);
851 ok(hr == S_OK, "got %08x\n", hr);
853 chapter = 1;
854 row = 1;
855 flags = DBPOSITION_OK;
856 hr = IRowPosition_GetRowPosition(rowpos, &chapter, &row, &flags);
857 ok(hr == S_OK, "got %08x\n", hr);
858 ok(chapter == DB_NULL_HCHAPTER, "got %ld\n", chapter);
859 ok(row == DB_NULL_HROW, "got %ld\n", row);
860 ok(flags == DBPOSITION_NOROW, "got %d\n", flags);
862 IRowPosition_Release(rowpos);
865 static void test_rowpos_setrowposition(void)
867 IRowPosition *rowpos;
868 HRESULT hr;
870 hr = CoCreateInstance(&CLSID_OLEDB_ROWPOSITIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IRowPosition, (void**)&rowpos);
871 ok(hr == S_OK, "got %08x\n", hr);
873 init_test_rset();
874 hr = IRowPosition_Initialize(rowpos, (IUnknown*)&test_rset.IRowset_iface);
875 ok(hr == S_OK, "got %08x\n", hr);
877 hr = IRowPosition_ClearRowPosition(rowpos);
878 ok(hr == S_OK, "got %08x\n", hr);
880 init_onchange_sink(rowpos);
881 hr = IRowPosition_SetRowPosition(rowpos, 0x123, 0x456, DBPOSITION_OK);
882 ok(hr == S_OK, "got %08x\n", hr);
884 IRowPosition_Release(rowpos);
887 static void test_dslocator(void)
889 IDataSourceLocator *dslocator = NULL;
890 HRESULT hr;
892 hr = CoCreateInstance(&CLSID_DataLinks, NULL, CLSCTX_INPROC_SERVER, &IID_IDataSourceLocator,(void**)&dslocator);
893 ok(hr == S_OK, "got %08x\n", hr);
894 if(SUCCEEDED(hr))
896 IDataInitialize *datainit, *datainit2;
897 IRunnableObject *runable;
898 IProvideClassInfo *info;
899 IMarshal *marshal;
900 IRpcOptions *opts;
901 COMPATIBLE_LONG hwnd = 0;
903 if (0) /* Crashes under Window 7 */
904 hr = IDataSourceLocator_get_hWnd(dslocator, NULL);
906 hr = IDataSourceLocator_get_hWnd(dslocator, &hwnd);
907 ok(hr == S_OK, "got %08x\n", hr);
908 ok(hwnd == 0, "got %p\n", (HWND)hwnd);
910 hwnd = 0xDEADBEEF;
911 hr = IDataSourceLocator_get_hWnd(dslocator, &hwnd);
912 ok(hr == S_OK, "got %08x\n", hr);
913 ok(hwnd == 0, "got %p\n", (HWND)hwnd);
915 hwnd = 0xDEADBEEF;
916 hr = IDataSourceLocator_put_hWnd(dslocator, hwnd);
917 ok(hr == S_OK, "got %08x\n", hr);
919 hwnd = 0;
920 hr = IDataSourceLocator_get_hWnd(dslocator, &hwnd);
921 ok(hr == S_OK, "got %08x\n", hr);
922 ok(hwnd == 0xDEADBEEF, "got %p\n", (HWND)hwnd);
924 hwnd = 0;
925 hr = IDataSourceLocator_put_hWnd(dslocator, hwnd);
926 ok(hr == S_OK, "got %08x\n", hr);
928 hwnd = 0xDEADBEEF;
929 hr = IDataSourceLocator_get_hWnd(dslocator, &hwnd);
930 ok(hr == S_OK, "got %08x\n", hr);
931 ok(hwnd == 0, "got %p\n", (HWND)hwnd);
933 hr = IDataSourceLocator_QueryInterface(dslocator, &IID_IDataInitialize, (void **)&datainit);
934 ok(hr == S_OK, "got %08x\n", hr);
936 hr = IDataSourceLocator_QueryInterface(dslocator, &IID_IDataInitialize, (void **)&datainit2);
937 ok(hr == S_OK, "got %08x\n", hr);
938 ok(datainit == datainit2, "Got %p, previous %p\n", datainit, datainit2);
940 hr = IDataSourceLocator_QueryInterface(dslocator, &IID_IRunnableObject, (void **)&runable);
941 ok(hr == E_NOINTERFACE, "got %08x\n", hr);
943 hr = IDataSourceLocator_QueryInterface(dslocator, &IID_IMarshal, (void **)&marshal);
944 ok(hr == E_NOINTERFACE, "got %08x\n", hr);
946 hr = IDataSourceLocator_QueryInterface(dslocator, &IID_IProvideClassInfo, (void **)&info);
947 ok(hr == E_NOINTERFACE, "got %08x\n", hr);
949 hr = IDataSourceLocator_QueryInterface(dslocator, &IID_IRpcOptions, (void **)&opts);
950 ok(hr == E_NOINTERFACE, "got %08x\n", hr);
952 if (winetest_interactive)
954 IDispatch *disp = NULL;
956 hr = IDataSourceLocator_PromptNew(dslocator, NULL);
957 ok(hr == E_INVALIDARG, "got %08x\n", hr);
959 hr = IDataSourceLocator_PromptNew(dslocator, &disp);
960 if (hr == S_OK)
962 ok(disp != NULL, "got %08x\n", hr);
963 IDispatch_Release(disp);
965 else
967 ok(hr == S_FALSE, "got %08x\n", hr);
968 ok(!disp, "got %08x\n", hr);
972 IDataInitialize_Release(datainit2);
973 IDataInitialize_Release(datainit);
975 IDataSourceLocator_Release(dslocator);
979 static void test_odbc_provider(void)
981 HRESULT hr;
982 IDBProperties *props;
983 DBPROPIDSET propidset;
984 ULONG infocount;
985 DBPROPINFOSET *propinfoset;
986 WCHAR *desc;
987 DBPROPID properties[14] =
989 DBPROP_AUTH_PASSWORD, DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO, DBPROP_AUTH_USERID,
990 DBPROP_INIT_DATASOURCE, DBPROP_INIT_HWND, DBPROP_INIT_LOCATION,
991 DBPROP_INIT_MODE, DBPROP_INIT_PROMPT, DBPROP_INIT_TIMEOUT,
992 DBPROP_INIT_PROVIDERSTRING, DBPROP_INIT_LCID, DBPROP_INIT_CATALOG,
993 DBPROP_INIT_OLEDBSERVICES, DBPROP_INIT_GENERALTIMEOUT
996 hr = CoCreateInstance( &CLSID_MSDASQL, NULL, CLSCTX_ALL, &IID_IDBProperties, (void **)&props);
997 ok(hr == S_OK, "Failed to create object 0x%08x\n", hr);
998 if (FAILED(hr))
1000 return;
1003 propidset.rgPropertyIDs = NULL;
1004 propidset.cPropertyIDs = 0;
1005 propidset.guidPropertySet = DBPROPSET_DBINITALL;
1007 infocount = 0;
1008 hr = IDBProperties_GetPropertyInfo(props, 1, &propidset, &infocount, &propinfoset, &desc);
1009 ok(hr == S_OK, "got 0x%08x\n", hr);
1010 if (hr == S_OK)
1012 ULONG i;
1013 DBPROPIDSET propidlist;
1014 ULONG propcnt;
1015 DBPROPSET *propset;
1017 ok(IsEqualGUID(&propinfoset->guidPropertySet, &DBPROPSET_DBINIT), "got %s\n",
1018 debugstr_guid(&propinfoset->guidPropertySet));
1019 ok(propinfoset->cPropertyInfos == 14, "got %d\n", propinfoset->cPropertyInfos);
1021 propidlist.guidPropertySet = DBPROPSET_DBINIT;
1022 propidlist.cPropertyIDs = propinfoset->cPropertyInfos;
1023 propidlist.rgPropertyIDs = CoTaskMemAlloc(propinfoset->cPropertyInfos * sizeof(DBPROP));
1025 for (i = 0; i < propinfoset->cPropertyInfos; i++)
1027 ok(properties[i] == propinfoset->rgPropertyInfos[i].dwPropertyID, "%d, got %d\n", i,
1028 propinfoset->rgPropertyInfos[i].dwPropertyID);
1029 ok(propinfoset->rgPropertyInfos[i].vtType != VT_EMPTY, "%d, got %d\n", i,
1030 propinfoset->rgPropertyInfos[i].vtType);
1032 propidlist.rgPropertyIDs[i] = propinfoset->rgPropertyInfos[i].dwPropertyID;
1035 for (i = 0; i < propinfoset->cPropertyInfos; i++)
1036 VariantClear(&propinfoset->rgPropertyInfos[i].vValues);
1038 CoTaskMemFree(propinfoset->rgPropertyInfos);
1039 CoTaskMemFree(propinfoset);
1041 hr = IDBProperties_GetProperties(props, 1, &propidlist, &propcnt, &propset);
1042 todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
1043 if (hr == S_OK) { /* Remove if, once _GetProperties is implemented */
1044 ok(propidlist.cPropertyIDs == 14, "got %d\n", propinfoset->cPropertyInfos);
1046 for (i = 0; i < propidlist.cPropertyIDs; i++)
1048 ok(properties[i] == propidlist.rgPropertyIDs[i], "%d, got %d\n", i,
1049 propidlist.rgPropertyIDs[i]);
1051 propidlist.rgPropertyIDs[i] = propinfoset->rgPropertyInfos[i].dwPropertyID;
1055 CoTaskMemFree(propidlist.rgPropertyIDs);
1056 CoTaskMemFree(propset);
1059 IDBProperties_Release(props);
1062 static void test_odbc_enumerator(void)
1064 HRESULT hr;
1065 ISourcesRowset *source;
1066 IRowset *rowset;
1068 hr = CoCreateInstance( &CLSID_MSDASQL_ENUMERATOR, NULL, CLSCTX_ALL, &IID_ISourcesRowset, (void **)&source);
1069 ok(hr == S_OK, "Failed to create object 0x%08x\n", hr);
1070 if (FAILED(hr))
1072 return;
1075 hr = ISourcesRowset_GetSourcesRowset(source, NULL, &IID_IRowset, 0, 0, (IUnknown**)&rowset);
1076 ok(hr == S_OK, "Failed to create object 0x%08x\n", hr);
1077 if (hr == S_OK)
1079 IAccessor *accessor;
1080 IRowsetInfo *info;
1082 hr = IRowset_QueryInterface(rowset, &IID_IAccessor, (void **)&accessor);
1083 ok(hr == S_OK, "got %08x\n", hr);
1084 if (hr == S_OK)
1085 IAccessor_Release(accessor);
1087 hr = IRowset_QueryInterface(rowset, &IID_IRowsetInfo, (void **)&info);
1088 todo_wine ok(hr == S_OK, "got %08x\n", hr);
1089 if (hr == S_OK)
1090 IRowsetInfo_Release(info);
1092 IRowset_Release(rowset);
1095 ISourcesRowset_Release(source);
1098 START_TEST(database)
1100 OleInitialize(NULL);
1102 test_database();
1103 test_errorinfo();
1104 test_initializationstring();
1105 test_dslocator();
1106 test_odbc_provider();
1107 test_odbc_enumerator();
1109 /* row position */
1110 test_rowposition();
1111 test_rowpos_initialize();
1112 test_rowpos_clearrowposition();
1113 test_rowpos_setrowposition();
1115 OleUninitialize();