oledb32: Fix memory leak.
[wine.git] / dlls / oledb32 / tests / database.c
blob9e20fece3210ab8c81f94b5d579e56345f1d296c
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
25 #include "windef.h"
26 #include "winbase.h"
27 #include "ole2.h"
28 #include "msdadc.h"
29 #include "msdasc.h"
30 #include "msdaguid.h"
31 #include "initguid.h"
32 #include "oledberr.h"
34 #include "wine/test.h"
36 DEFINE_GUID(CSLID_MSDAER, 0xc8b522cf,0x5cf3,0x11ce,0xad,0xe5,0x00,0xaa,0x00,0x44,0x77,0x3d);
38 static WCHAR initstring_default[] = {'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',0};
40 static void test_GetDataSource(WCHAR *initstring)
42 IDataInitialize *datainit = NULL;
43 IDBInitialize *dbinit = NULL;
44 HRESULT hr;
46 trace("Data Source: %s\n", wine_dbgstr_w(initstring));
48 hr = CoCreateInstance(&CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,(void**)&datainit);
49 ok(hr == S_OK, "got %08x\n", hr);
51 /* a failure to create data source here may indicate provider is simply not present */
52 hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, initstring, &IID_IDBInitialize, (IUnknown**)&dbinit);
53 if(SUCCEEDED(hr))
55 IDBProperties *props = NULL;
57 hr = IDBInitialize_QueryInterface(dbinit, &IID_IDBProperties, (void**)&props);
58 ok(hr == S_OK, "got %08x\n", hr);
59 if(SUCCEEDED(hr))
61 ULONG cnt;
62 DBPROPINFOSET *pInfoset;
63 OLECHAR *ary;
65 hr = IDBProperties_GetPropertyInfo(props, 0, NULL, &cnt, &pInfoset, &ary);
66 todo_wine ok(hr == S_OK, "got %08x\n", hr);
67 if(hr == S_OK)
69 ULONG i;
70 for(i =0; i < pInfoset->cPropertyInfos; i++)
72 trace("(0x%04x) '%s' %d\n", pInfoset->rgPropertyInfos[i].dwPropertyID, wine_dbgstr_w(pInfoset->rgPropertyInfos[i].pwszDescription),
73 pInfoset->rgPropertyInfos[i].vtType);
76 CoTaskMemFree(pInfoset);
77 CoTaskMemFree(ary);
80 IDBProperties_Release(props);
83 IDBInitialize_Release(dbinit);
86 IDataInitialize_Release(datainit);
89 static void test_database(void)
91 static WCHAR initstring_jet[] = {'P','r','o','v','i','d','e','r','=','M','i','c','r','o','s','o','f','t','.',
92 'J','e','t','.','O','L','E','D','B','.','4','.','0',';',
93 'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y',';',
94 '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};
95 static WCHAR initstring_lower[] = {'d','a','t','a',' ','s','o','u','r','c','e','=','d','u','m','m','y',';',0};
96 IDataInitialize *datainit = NULL;
97 HRESULT hr;
99 hr = CoCreateInstance(&CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize, (void**)&datainit);
100 if (FAILED(hr))
102 win_skip("Unable to load oledb library\n");
103 return;
105 IDataInitialize_Release(datainit);
107 test_GetDataSource(NULL);
108 test_GetDataSource(initstring_jet);
109 test_GetDataSource(initstring_default);
110 test_GetDataSource(initstring_lower);
113 static void test_errorinfo(void)
115 HRESULT hr;
116 IUnknown *unk = NULL;
118 hr = CoCreateInstance(&CSLID_MSDAER, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown,(void**)&unk);
119 ok(hr == S_OK, "got %08x\n", hr);
120 if(hr == S_OK)
122 IErrorInfo *errorinfo;
123 IErrorRecords *errrecs;
125 hr = IUnknown_QueryInterface(unk, &IID_IErrorInfo, (void**)&errorinfo);
126 ok(hr == S_OK, "got %08x\n", hr);
127 if(hr == S_OK)
129 IErrorInfo_Release(errorinfo);
132 hr = IUnknown_QueryInterface(unk, &IID_IErrorRecords, (void**)&errrecs);
133 ok(hr == S_OK, "got %08x\n", hr);
134 if(hr == S_OK)
136 ERRORINFO info, info2, info3;
137 ULONG cnt = 0;
139 memset(&info, 0, sizeof(ERRORINFO));
140 info.dwMinor = 1;
141 memset(&info2, 0, sizeof(ERRORINFO));
142 info2.dwMinor = 2;
143 memset(&info3, 0, sizeof(ERRORINFO));
145 hr = IErrorRecords_AddErrorRecord(errrecs, NULL, 268435456, NULL, NULL, 0);
146 ok(hr == E_INVALIDARG, "got %08x\n", hr);
148 hr = IErrorRecords_AddErrorRecord(errrecs, &info, 1, NULL, NULL, 0);
149 ok(hr == S_OK, "got %08x\n", hr);
151 hr = IErrorRecords_GetRecordCount(errrecs, &cnt);
152 ok(hr == S_OK, "got %08x\n", hr);
153 ok(cnt == 1, "expected 1 got %d\n", cnt);
155 hr = IErrorRecords_AddErrorRecord(errrecs, &info2, 2, NULL, NULL, 0);
156 ok(hr == S_OK, "got %08x\n", hr);
158 hr = IErrorRecords_GetRecordCount(errrecs, &cnt);
159 ok(hr == S_OK, "got %08x\n", hr);
160 ok(cnt == 2, "expected 2 got %d\n", cnt);
162 hr = IErrorRecords_GetBasicErrorInfo(errrecs, 0, NULL);
163 ok(hr == E_INVALIDARG, "got %08x\n", hr);
165 hr = IErrorRecords_GetBasicErrorInfo(errrecs, 100, &info3);
166 ok(hr == DB_E_BADRECORDNUM, "got %08x\n", hr);
168 hr = IErrorRecords_GetBasicErrorInfo(errrecs, 0, &info3);
169 todo_wine ok(hr == S_OK, "got %08x\n", hr);
170 if(hr == S_OK)
172 ok(info3.dwMinor == 2, "expected 2 got %d\n", info3.dwMinor);
175 IErrorRecords_Release(errrecs);
178 IUnknown_Release(unk);
182 static void test_initializationstring(void)
184 static const WCHAR initstring_msdasql[] = {'P','r','o','v','i','d','e','r','=','M','S','D','A','S','Q','L','.','1',';',
185 'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y', 0};
186 static const WCHAR initstring_sqloledb[] = {'P','r','o','v','i','d','e','r','=','S','Q','L','O','L','E','D','B','.','1',';',
187 'D','a','t','a',' ','S','o','u','r','c','e','=','d','u','m','m','y', 0};
188 IDataInitialize *datainit = NULL;
189 IDBInitialize *dbinit = NULL;
190 HRESULT hr;
191 WCHAR *initstring = NULL;
193 hr = CoCreateInstance(&CLSID_MSDAINITIALIZE, NULL, CLSCTX_INPROC_SERVER, &IID_IDataInitialize,(void**)&datainit);
194 ok(hr == S_OK, "got %08x\n", hr);
195 if(SUCCEEDED(hr))
197 hr = IDataInitialize_GetDataSource(datainit, NULL, CLSCTX_INPROC_SERVER, initstring_default,
198 &IID_IDBInitialize, (IUnknown**)&dbinit);
199 if(SUCCEEDED(hr))
201 hr = IDataInitialize_GetInitializationString(datainit, (IUnknown*)dbinit, 0, &initstring);
202 ok(hr == S_OK, "got %08x\n", hr);
203 if(hr == S_OK)
205 trace("Init String: %s\n", wine_dbgstr_w(initstring));
206 todo_wine ok(!lstrcmpW(initstring_msdasql, initstring) ||
207 !lstrcmpW(initstring_sqloledb, initstring), "got %s\n", wine_dbgstr_w(initstring));
208 CoTaskMemFree(initstring);
211 IDBInitialize_Release(dbinit);
214 IDataInitialize_Release(datainit);
218 static void test_rowposition(void)
220 IEnumConnectionPoints *enum_points;
221 IConnectionPointContainer *cpc;
222 IConnectionPoint *cp;
223 IRowPosition *rowpos;
224 HRESULT hr;
225 IID iid;
227 hr = CoCreateInstance(&CLSID_OLEDB_ROWPOSITIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IRowPosition, (void**)&rowpos);
228 ok(hr == S_OK, "got %08x\n", hr);
230 hr = IRowPosition_QueryInterface(rowpos, &IID_IConnectionPointContainer, (void**)&cpc);
231 ok(hr == S_OK, "got 0x%08x\n", hr);
233 hr = IConnectionPointContainer_EnumConnectionPoints(cpc, &enum_points);
234 todo_wine
235 ok(hr == S_OK, "got 0x%08x\n", hr);
236 if (hr == S_OK) {
237 hr = IEnumConnectionPoints_Next(enum_points, 1, &cp, NULL);
238 ok(hr == S_OK, "got 0x%08x\n", hr);
239 hr = IConnectionPoint_GetConnectionInterface(cp, &iid);
240 ok(hr == S_OK, "got 0x%08x\n", hr);
241 ok(IsEqualIID(&iid, &IID_IRowPositionChange), "got %s\n", wine_dbgstr_guid(&iid));
242 IConnectionPoint_Release(cp);
244 hr = IEnumConnectionPoints_Next(enum_points, 1, &cp, NULL);
245 ok(hr == S_FALSE, "got 0x%08x\n", hr);
247 IEnumConnectionPoints_Release(enum_points);
249 IConnectionPointContainer_Release(cpc);
250 IRowPosition_Release(rowpos);
253 typedef struct
255 IRowset IRowset_iface;
256 IChapteredRowset IChapteredRowset_iface;
257 } test_rset_t;
259 static test_rset_t test_rset;
261 static HRESULT WINAPI rset_QI(IRowset *iface, REFIID riid, void **obj)
263 if (IsEqualIID(riid, &IID_IUnknown) ||
264 IsEqualIID(riid, &IID_IRowset))
266 *obj = &test_rset.IRowset_iface;
267 return S_OK;
269 else if (IsEqualIID(riid, &IID_IChapteredRowset))
271 *obj = &test_rset.IChapteredRowset_iface;
272 return S_OK;
275 ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
276 return E_NOINTERFACE;
279 static ULONG WINAPI rset_AddRef(IRowset *iface)
281 return 2;
284 static ULONG WINAPI rset_Release(IRowset *iface)
286 return 1;
289 static HRESULT WINAPI rset_AddRefRows(IRowset *iface, DBCOUNTITEM cRows,
290 const HROW rghRows[], DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
292 trace("AddRefRows: %ld\n", rghRows[0]);
293 return S_OK;
296 static HRESULT WINAPI rset_GetData(IRowset *iface, HROW hRow, HACCESSOR hAccessor, void *pData)
298 ok(0, "unexpected call\n");
299 return E_NOTIMPL;
302 static HRESULT WINAPI rset_GetNextRows(IRowset *iface, HCHAPTER hReserved, DBROWOFFSET lRowsOffset,
303 DBROWCOUNT cRows, DBCOUNTITEM *pcRowObtained, HROW **prghRows)
305 ok(0, "unexpected call\n");
306 return E_NOTIMPL;
309 static HRESULT WINAPI rset_ReleaseRows(IRowset *iface, DBCOUNTITEM cRows, const HROW rghRows[], DBROWOPTIONS rgRowOptions[],
310 DBREFCOUNT rgRefCounts[], DBROWSTATUS rgRowStatus[])
312 return S_OK;
315 static HRESULT WINAPI rset_RestartPosition(IRowset *iface, HCHAPTER hReserved)
317 ok(0, "unexpected call\n");
318 return E_NOTIMPL;
321 static const IRowsetVtbl rset_vtbl = {
322 rset_QI,
323 rset_AddRef,
324 rset_Release,
325 rset_AddRefRows,
326 rset_GetData,
327 rset_GetNextRows,
328 rset_ReleaseRows,
329 rset_RestartPosition
332 static HRESULT WINAPI chrset_QI(IChapteredRowset *iface, REFIID riid, void **obj)
334 return IRowset_QueryInterface(&test_rset.IRowset_iface, riid, obj);
337 static ULONG WINAPI chrset_AddRef(IChapteredRowset *iface)
339 return IRowset_AddRef(&test_rset.IRowset_iface);
342 static ULONG WINAPI chrset_Release(IChapteredRowset *iface)
344 return IRowset_Release(&test_rset.IRowset_iface);
347 static HRESULT WINAPI chrset_AddRefChapter(IChapteredRowset *iface, HCHAPTER chapter, DBREFCOUNT *refcount)
349 return S_OK;
352 static HRESULT WINAPI chrset_ReleaseChapter(IChapteredRowset *iface, HCHAPTER chapter, DBREFCOUNT *refcount)
354 return S_OK;
357 static const IChapteredRowsetVtbl chrset_vtbl = {
358 chrset_QI,
359 chrset_AddRef,
360 chrset_Release,
361 chrset_AddRefChapter,
362 chrset_ReleaseChapter
365 static void init_test_rset(void)
367 test_rset.IRowset_iface.lpVtbl = &rset_vtbl;
368 test_rset.IChapteredRowset_iface.lpVtbl = &chrset_vtbl;
371 static void test_rowpos_initialize(void)
373 IRowPosition *rowpos;
374 HRESULT hr;
376 hr = CoCreateInstance(&CLSID_OLEDB_ROWPOSITIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IRowPosition, (void**)&rowpos);
377 ok(hr == S_OK, "got %08x\n", hr);
379 init_test_rset();
380 hr = IRowPosition_Initialize(rowpos, (IUnknown*)&test_rset.IRowset_iface);
381 ok(hr == S_OK, "got %08x\n", hr);
383 IRowPosition_Release(rowpos);
386 static HRESULT WINAPI onchange_QI(IRowPositionChange *iface, REFIID riid, void **obj)
388 if (IsEqualIID(riid, &IID_IUnknown) ||
389 IsEqualIID(riid, &IID_IRowPositionChange))
391 *obj = iface;
392 return S_OK;
395 return E_NOINTERFACE;
398 static ULONG WINAPI onchange_AddRef(IRowPositionChange *iface)
400 return 2;
403 static ULONG WINAPI onchange_Release(IRowPositionChange *iface)
405 return 1;
408 static HRESULT WINAPI onchange_OnRowPositionChange(IRowPositionChange *iface, DBREASON reason,
409 DBEVENTPHASE phase, BOOL cant_deny)
411 trace("%d %d %d\n", reason, phase, cant_deny);
412 return S_OK;
415 static const IRowPositionChangeVtbl onchange_vtbl = {
416 onchange_QI,
417 onchange_AddRef,
418 onchange_Release,
419 onchange_OnRowPositionChange
422 static IRowPositionChange onchangesink = { &onchange_vtbl };
424 static void init_onchange_sink(IRowPosition *rowpos)
426 IConnectionPointContainer *cpc;
427 IConnectionPoint *cp;
428 DWORD cookie;
429 HRESULT hr;
431 hr = IRowPosition_QueryInterface(rowpos, &IID_IConnectionPointContainer, (void**)&cpc);
432 ok(hr == S_OK, "got %08x\n", hr);
433 hr = IConnectionPointContainer_FindConnectionPoint(cpc, &IID_IRowPositionChange, &cp);
434 ok(hr == S_OK, "got %08x\n", hr);
435 hr = IConnectionPoint_Advise(cp, (IUnknown*)&onchangesink, &cookie);
436 ok(hr == S_OK, "got %08x\n", hr);
437 IConnectionPoint_Release(cp);
438 IConnectionPointContainer_Release(cpc);
441 static void test_rowpos_clearrowposition(void)
443 DBPOSITIONFLAGS flags;
444 IRowPosition *rowpos;
445 HCHAPTER chapter;
446 IUnknown *unk;
447 HRESULT hr;
448 HROW row;
450 hr = CoCreateInstance(&CLSID_OLEDB_ROWPOSITIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IRowPosition, (void**)&rowpos);
451 ok(hr == S_OK, "got %08x\n", hr);
453 hr = IRowPosition_ClearRowPosition(rowpos);
454 ok(hr == E_UNEXPECTED, "got %08x\n", hr);
456 hr = IRowPosition_GetRowset(rowpos, &IID_IStream, &unk);
457 ok(hr == E_UNEXPECTED, "got %08x\n", hr);
459 chapter = 1;
460 row = 1;
461 flags = DBPOSITION_OK;
462 hr = IRowPosition_GetRowPosition(rowpos, &chapter, &row, &flags);
463 ok(hr == E_UNEXPECTED, "got %08x\n", hr);
464 ok(chapter == DB_NULL_HCHAPTER, "got %ld\n", chapter);
465 ok(row == DB_NULL_HROW, "got %ld\n", row);
466 ok(flags == DBPOSITION_NOROW, "got %d\n", flags);
468 init_test_rset();
469 hr = IRowPosition_Initialize(rowpos, (IUnknown*)&test_rset.IRowset_iface);
470 ok(hr == S_OK, "got %08x\n", hr);
472 chapter = 1;
473 row = 1;
474 flags = DBPOSITION_OK;
475 hr = IRowPosition_GetRowPosition(rowpos, &chapter, &row, &flags);
476 ok(hr == S_OK, "got %08x\n", hr);
477 ok(chapter == DB_NULL_HCHAPTER, "got %ld\n", chapter);
478 ok(row == DB_NULL_HROW, "got %ld\n", row);
479 ok(flags == DBPOSITION_NOROW, "got %d\n", flags);
481 hr = IRowPosition_GetRowset(rowpos, &IID_IRowset, &unk);
482 ok(hr == S_OK, "got %08x\n", hr);
484 init_onchange_sink(rowpos);
485 hr = IRowPosition_ClearRowPosition(rowpos);
486 ok(hr == S_OK, "got %08x\n", hr);
488 chapter = 1;
489 row = 1;
490 flags = DBPOSITION_OK;
491 hr = IRowPosition_GetRowPosition(rowpos, &chapter, &row, &flags);
492 ok(hr == S_OK, "got %08x\n", hr);
493 ok(chapter == DB_NULL_HCHAPTER, "got %ld\n", chapter);
494 ok(row == DB_NULL_HROW, "got %ld\n", row);
495 ok(flags == DBPOSITION_NOROW, "got %d\n", flags);
497 IRowPosition_Release(rowpos);
500 static void test_rowpos_setrowposition(void)
502 IRowPosition *rowpos;
503 HRESULT hr;
505 hr = CoCreateInstance(&CLSID_OLEDB_ROWPOSITIONLIBRARY, NULL, CLSCTX_INPROC_SERVER, &IID_IRowPosition, (void**)&rowpos);
506 ok(hr == S_OK, "got %08x\n", hr);
508 init_test_rset();
509 hr = IRowPosition_Initialize(rowpos, (IUnknown*)&test_rset.IRowset_iface);
510 ok(hr == S_OK, "got %08x\n", hr);
512 hr = IRowPosition_ClearRowPosition(rowpos);
513 ok(hr == S_OK, "got %08x\n", hr);
515 init_onchange_sink(rowpos);
516 hr = IRowPosition_SetRowPosition(rowpos, 0x123, 0x456, DBPOSITION_OK);
517 ok(hr == S_OK, "got %08x\n", hr);
519 IRowPosition_Release(rowpos);
522 static void test_dslocator(void)
524 IDataSourceLocator *dslocator = NULL;
525 HRESULT hr;
527 hr = CoCreateInstance(&CLSID_DataLinks, NULL, CLSCTX_INPROC_SERVER, &IID_IDataSourceLocator,(void**)&dslocator);
528 ok(hr == S_OK, "got %08x\n", hr);
529 if(SUCCEEDED(hr))
531 COMPATIBLE_LONG hwnd = 0;
533 /* Crashes under Window 7
534 hr = IDataSourceLocator_get_hWnd(dslocator, NULL);
535 ok(hr == E_INVALIDARG, "got %08x\n", hr);
538 hr = IDataSourceLocator_get_hWnd(dslocator, &hwnd);
539 ok(hr == S_OK, "got %08x\n", hr);
540 ok(hwnd == 0, "got %p\n", (HWND)hwnd);
542 hwnd = 0xDEADBEEF;
543 hr = IDataSourceLocator_get_hWnd(dslocator, &hwnd);
544 ok(hr == S_OK, "got %08x\n", hr);
545 ok(hwnd == 0, "got %p\n", (HWND)hwnd);
547 hwnd = 0xDEADBEEF;
548 hr = IDataSourceLocator_put_hWnd(dslocator, hwnd);
549 ok(hr == S_OK, "got %08x\n", hr);
551 hwnd = 0xDEADBEEF;
552 hr = IDataSourceLocator_get_hWnd(dslocator, &hwnd);
553 ok(hr == S_OK, "got %08x\n", hr);
554 ok(hwnd == 0xDEADBEEF, "got %p\n", (HWND)hwnd);
556 hwnd = 0;
557 hr = IDataSourceLocator_put_hWnd(dslocator, hwnd);
558 ok(hr == S_OK, "got %08x\n", hr);
560 hwnd = 0xDEADBEEF;
561 hr = IDataSourceLocator_get_hWnd(dslocator, &hwnd);
562 ok(hr == S_OK, "got %08x\n", hr);
563 ok(hwnd == 0, "got %p\n", (HWND)hwnd);
565 IDataSourceLocator_Release(dslocator);
569 START_TEST(database)
571 OleInitialize(NULL);
573 test_database();
574 test_errorinfo();
575 test_initializationstring();
576 test_dslocator();
578 /* row position */
579 test_rowposition();
580 test_rowpos_initialize();
581 test_rowpos_clearrowposition();
582 test_rowpos_setrowposition();
584 OleUninitialize();