3 * Copyright 2013 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
23 #define NONAMELESSUNION
36 #include "oledb_private.h"
39 #include "wine/debug.h"
40 #include "wine/heap.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(oledb
);
47 IDBProperties
*provider
;
48 DBPROPINFOSET
*propinfoset
;
52 static struct datasource
*create_datasource(WCHAR
*guid
)
54 struct datasource
*data
= heap_alloc_zero(sizeof(struct datasource
));
57 CLSIDFromString(guid
, &data
->clsid
);
63 static void destroy_datasource(struct datasource
*data
)
65 if (data
->propinfoset
)
69 for (i
= 0; i
< data
->propinfoset
->cPropertyInfos
; i
++)
70 VariantClear(&data
->propinfoset
->rgPropertyInfos
[i
].vValues
);
72 CoTaskMemFree(data
->propinfoset
->rgPropertyInfos
);
73 CoTaskMemFree(data
->propinfoset
);
75 CoTaskMemFree(data
->description
);
78 IDBProperties_Release(data
->provider
);
83 static BOOL
initialize_datasource(struct datasource
*data
)
86 DBPROPIDSET propidset
;
89 hr
= CoCreateInstance(&data
->clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDBProperties
, (void**)&data
->provider
);
92 WARN("Datasource cannot be created (0x%08x)\n", hr
);
96 propidset
.rgPropertyIDs
= NULL
;
97 propidset
.cPropertyIDs
= 0;
98 propidset
.guidPropertySet
= DBPROPSET_DBINITALL
;
100 hr
= IDBProperties_GetPropertyInfo(data
->provider
, 1, &propidset
, &infocount
, &data
->propinfoset
, &data
->description
);
103 WARN("Failed to get DB Properties (0x%08x)\n", hr
);
105 IDBProperties_Release(data
->provider
);
106 data
->provider
= NULL
;
113 typedef struct DSLocatorImpl
115 IDataSourceLocator IDataSourceLocator_iface
;
116 IDataInitialize IDataInitialize_iface
;
122 static inline DSLocatorImpl
*impl_from_IDataSourceLocator( IDataSourceLocator
*iface
)
124 return CONTAINING_RECORD(iface
, DSLocatorImpl
, IDataSourceLocator_iface
);
127 static inline DSLocatorImpl
*impl_from_IDataInitialize(IDataInitialize
*iface
)
129 return CONTAINING_RECORD(iface
, DSLocatorImpl
, IDataInitialize_iface
);
132 static HRESULT WINAPI
dslocator_QueryInterface(IDataSourceLocator
*iface
, REFIID riid
, void **ppvoid
)
134 DSLocatorImpl
*This
= impl_from_IDataSourceLocator(iface
);
135 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
),ppvoid
);
139 if (IsEqualIID(riid
, &IID_IUnknown
) ||
140 IsEqualIID(riid
, &IID_IDispatch
) ||
141 IsEqualIID(riid
, &IID_IDataSourceLocator
))
143 *ppvoid
= &This
->IDataSourceLocator_iface
;
145 else if (IsEqualIID(riid
, &IID_IDataInitialize
))
147 *ppvoid
= &This
->IDataInitialize_iface
;
149 else if (IsEqualIID(riid
, &IID_IRunnableObject
))
151 TRACE("IID_IRunnableObject returning NULL\n");
152 return E_NOINTERFACE
;
154 else if (IsEqualIID(riid
, &IID_IProvideClassInfo
))
156 TRACE("IID_IProvideClassInfo returning NULL\n");
157 return E_NOINTERFACE
;
159 else if (IsEqualIID(riid
, &IID_IMarshal
))
161 TRACE("IID_IMarshal returning NULL\n");
162 return E_NOINTERFACE
;
164 else if (IsEqualIID(riid
, &IID_IRpcOptions
))
166 TRACE("IID_IRpcOptions returning NULL\n");
167 return E_NOINTERFACE
;
172 IUnknown_AddRef( (IUnknown
*)*ppvoid
);
176 FIXME("interface %s not implemented\n", debugstr_guid(riid
));
177 return E_NOINTERFACE
;
180 static ULONG WINAPI
dslocator_AddRef(IDataSourceLocator
*iface
)
182 DSLocatorImpl
*This
= impl_from_IDataSourceLocator(iface
);
183 TRACE("(%p)->%u\n",This
,This
->ref
);
184 return InterlockedIncrement(&This
->ref
);
187 static ULONG WINAPI
dslocator_Release(IDataSourceLocator
*iface
)
189 DSLocatorImpl
*This
= impl_from_IDataSourceLocator(iface
);
190 ULONG ref
= InterlockedDecrement(&This
->ref
);
192 TRACE("(%p)->%u\n",This
,ref
+1);
202 static HRESULT WINAPI
dslocator_GetTypeInfoCount(IDataSourceLocator
*iface
, UINT
*pctinfo
)
204 DSLocatorImpl
*This
= impl_from_IDataSourceLocator(iface
);
206 FIXME("(%p)->()\n", This
);
211 static HRESULT WINAPI
dslocator_GetTypeInfo(IDataSourceLocator
*iface
, UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
213 DSLocatorImpl
*This
= impl_from_IDataSourceLocator(iface
);
215 FIXME("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
220 static HRESULT WINAPI
dslocator_GetIDsOfNames(IDataSourceLocator
*iface
, REFIID riid
, LPOLESTR
*rgszNames
,
221 UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
223 DSLocatorImpl
*This
= impl_from_IDataSourceLocator(iface
);
225 FIXME("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
, lcid
, rgDispId
);
230 static HRESULT WINAPI
dslocator_Invoke(IDataSourceLocator
*iface
, DISPID dispIdMember
, REFIID riid
,
231 LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
233 DSLocatorImpl
*This
= impl_from_IDataSourceLocator(iface
);
235 FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
236 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
241 static HRESULT WINAPI
dslocator_get_hWnd(IDataSourceLocator
*iface
, COMPATIBLE_LONG
*phwndParent
)
243 DSLocatorImpl
*This
= impl_from_IDataSourceLocator(iface
);
245 TRACE("(%p)->(%p)\n",This
, phwndParent
);
247 *phwndParent
= (COMPATIBLE_LONG
)This
->hwnd
;
252 static HRESULT WINAPI
dslocator_put_hWnd(IDataSourceLocator
*iface
, COMPATIBLE_LONG hwndParent
)
254 DSLocatorImpl
*This
= impl_from_IDataSourceLocator(iface
);
256 TRACE("(%p)->(%p)\n",This
, (HWND
)hwndParent
);
258 This
->hwnd
= (HWND
)hwndParent
;
263 static void create_connections_columns(HWND lv
)
269 SendMessageW(lv
, LVM_SETEXTENDEDLISTVIEWSTYLE
, 0, LVS_EX_FULLROWSELECT
);
270 GetWindowRect(lv
, &rc
);
271 LoadStringW(instance
, IDS_COL_PROVIDER
, buf
, ARRAY_SIZE(buf
));
272 column
.mask
= LVCF_WIDTH
| LVCF_TEXT
;
273 column
.cx
= (rc
.right
- rc
.left
) - 5;
274 column
.pszText
= buf
;
275 SendMessageW(lv
, LVM_INSERTCOLUMNW
, 0, (LPARAM
)&column
);
278 static void add_connections_providers(HWND lv
)
281 HKEY key
= NULL
, subkey
;
284 WCHAR provider
[MAX_PATH
];
285 WCHAR guidkey
[MAX_PATH
];
288 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, L
"CLSID", 0, KEY_READ
, &key
);
289 if (res
== ERROR_FILE_NOT_FOUND
)
292 next_key
= RegEnumKeyW(key
, index
, provider
, MAX_PATH
);
293 while (next_key
== ERROR_SUCCESS
)
295 WCHAR description
[MAX_PATH
];
297 lstrcpyW(guidkey
, provider
);
298 lstrcatW(guidkey
, L
"\\OLE DB Provider");
300 res
= RegOpenKeyW(key
, guidkey
, &subkey
);
301 if (res
== ERROR_SUCCESS
)
303 TRACE("Found %s\n", debugstr_w(guidkey
));
306 res
= RegQueryValueW(subkey
, NULL
, description
, &size
);
307 if (res
== ERROR_SUCCESS
)
310 struct datasource
*data
;
312 data
= create_datasource(guidkey
);
314 item
.mask
= LVIF_TEXT
| LVIF_PARAM
;
315 item
.iItem
= SendMessageW(lv
, LVM_GETITEMCOUNT
, 0, 0);
317 item
.pszText
= description
;
318 item
.lParam
= (LPARAM
)data
;
320 SendMessageW(lv
, LVM_INSERTITEMW
, 0, (LPARAM
)&item
);
326 next_key
= RegEnumKeyW(key
, index
, provider
, MAX_PATH
);
332 static LRESULT CALLBACK
data_link_properties_dlg_proc(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
334 TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd
, msg
, wp
, lp
);
340 HWND btn
, lv
= GetDlgItem(hwnd
, IDC_LST_CONNECTIONS
);
341 create_connections_columns(lv
);
342 add_connections_providers(lv
);
344 btn
= GetDlgItem(GetParent(hwnd
), IDOK
);
345 EnableWindow(btn
, FALSE
);
351 HWND lv
= GetDlgItem(hwnd
, IDC_LST_CONNECTIONS
);
356 item
.mask
= LVIF_PARAM
;
358 while(ListView_GetItemA(lv
, &item
))
360 destroy_datasource( (struct datasource
*)item
.lParam
);
367 NMHDR
*hdr
= ((LPNMHDR
)lp
);
374 * FIXME: This needs to replace the connection page based off the selection.
375 * We only care about the ODBC for now which is the default.
378 HWND lv
= GetDlgItem(hwnd
, IDC_LST_CONNECTIONS
);
379 if (!SendMessageW(lv
, LVM_GETSELECTEDCOUNT
, 0, 0))
381 WCHAR title
[256], msg
[256];
383 LoadStringW(instance
, IDS_PROVIDER_TITLE
, title
, ARRAY_SIZE(title
));
384 LoadStringW(instance
, IDS_PROVIDER_ERROR
, msg
, ARRAY_SIZE(msg
));
385 MessageBoxW(hwnd
, msg
, title
, MB_OK
| MB_ICONEXCLAMATION
);
386 SetWindowLongPtrW(hwnd
, DWLP_MSGRESULT
, TRUE
);
392 item
.stateMask
= LVIS_SELECTED
;
393 item
.mask
= LVIF_PARAM
| LVIF_STATE
;
395 if(ListView_GetItemA(lv
, &item
))
397 if(!initialize_datasource( (struct datasource
*)item
.lParam
))
399 WCHAR title
[256], msg
[256];
400 LoadStringW(instance
, IDS_PROVIDER_TITLE
, title
, ARRAY_SIZE(title
));
401 LoadStringW(instance
, IDS_PROVIDER_NOT_AVAIL
, msg
, ARRAY_SIZE(msg
));
402 MessageBoxW(hwnd
, msg
, title
, MB_OK
| MB_ICONEXCLAMATION
);
403 SetWindowLongPtrW(hwnd
, DWLP_MSGRESULT
, TRUE
);
408 ERR("Failed to get selected item\n");
418 if (LOWORD(wp
) == IDC_BTN_NEXT
)
419 SendMessageW(GetParent(hwnd
), PSM_SETCURSEL
, 1, 0);
428 static void connection_fill_odbc_list(HWND parent
)
433 WCHAR name
[MAX_PATH
];
436 HWND combo
= GetDlgItem(parent
, IDC_CBO_NAMES
);
440 res
= RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\ODBC\\ODBC.INI\\ODBC Data Sources", 0, KEY_READ
, &key
);
441 if (res
== ERROR_FILE_NOT_FOUND
)
444 SendMessageW (combo
, CB_RESETCONTENT
, 0, 0);
449 if (RegEnumValueW(key
, index
, name
, &nameLen
, NULL
, NULL
, NULL
, NULL
) != ERROR_SUCCESS
)
452 SendMessageW(combo
, CB_ADDSTRING
, 0, (LPARAM
)name
);
458 static void connection_initialize_controls(HWND parent
)
460 HWND hwnd
= GetDlgItem(parent
, IDC_RDO_SRC_NAME
);
462 SendMessageA(hwnd
, BM_SETCHECK
, BST_CHECKED
, 0);
465 static void connection_toggle_controls(HWND parent
)
468 HWND hwnd
= GetDlgItem(parent
, IDC_RDO_SRC_NAME
);
470 checked
= SendMessageA(hwnd
, BM_GETCHECK
, 0, 0);
472 EnableWindow(GetDlgItem(parent
, IDC_CBO_NAMES
), checked
);
473 EnableWindow(GetDlgItem(parent
, IDC_BTN_REFRESH
), checked
);
475 EnableWindow(GetDlgItem(parent
, IDC_LBL_CONNECTION
), !checked
);
476 EnableWindow(GetDlgItem(parent
, IDC_EDT_CONNECTION
), !checked
);
477 EnableWindow(GetDlgItem(parent
, IDC_BTN_BUILD
), !checked
);
480 static LRESULT CALLBACK
data_link_connection_dlg_proc(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
482 TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd
, msg
, wp
, lp
);
488 connection_initialize_controls(hwnd
);
489 connection_fill_odbc_list(hwnd
);
490 connection_toggle_controls(hwnd
);
497 case IDC_RDO_SRC_NAME
:
498 case IDC_BTN_CONNECTION
:
499 connection_toggle_controls(hwnd
);
501 case IDC_BTN_REFRESH
:
502 connection_fill_odbc_list(hwnd
);
506 /* TODO: Implement dialogs */
507 MessageBoxA(hwnd
, "Not implemented yet.", "Error", MB_OK
| MB_ICONEXCLAMATION
);
519 static void advanced_fill_permission_list(HWND parent
)
524 int resources
[] = {IDS_PERM_READ
, IDS_PERM_READWRITE
, IDS_PERM_SHAREDENYNONE
,
525 IDS_PERM_SHAREDENYREAD
, IDS_PERM_SHAREDENYWRITE
, IDS_PERM_SHAREEXCLUSIVE
,
529 HWND lv
= GetDlgItem(parent
, IDC_LST_PERMISSIONS
);
533 SendMessageW(lv
, LVM_SETEXTENDEDLISTVIEWSTYLE
, 0, LVS_EX_CHECKBOXES
);
534 GetWindowRect(lv
, &rc
);
535 column
.mask
= LVCF_WIDTH
| LVCF_FMT
;
536 column
.fmt
= LVCFMT_FIXED_WIDTH
;
537 column
.cx
= (rc
.right
- rc
.left
) - 25;
538 column
.pszText
= buf
;
539 SendMessageW(lv
, LVM_INSERTCOLUMNW
, 0, (LPARAM
)&column
);
541 for(i
=0; i
< ARRAY_SIZE(resources
); i
++)
543 item
.mask
= LVIF_TEXT
;
544 item
.iItem
= SendMessageW(lv
, LVM_GETITEMCOUNT
, 0, 0);
546 LoadStringW(instance
, resources
[i
], buf
, ARRAY_SIZE(buf
));
548 SendMessageW(lv
, LVM_INSERTITEMW
, 0, (LPARAM
)&item
);
552 static LRESULT CALLBACK
data_link_advanced_dlg_proc(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
554 TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd
, msg
, wp
, lp
);
560 EnableWindow(GetDlgItem(hwnd
, IDC_LBL_LEVEL
), FALSE
);
561 EnableWindow(GetDlgItem(hwnd
, IDC_CBO_LEVEL
), FALSE
);
562 EnableWindow(GetDlgItem(hwnd
, IDC_LBL_PROTECTION
), FALSE
);
563 EnableWindow(GetDlgItem(hwnd
, IDC_CBO_PROTECTION
), FALSE
);
565 advanced_fill_permission_list(hwnd
);
575 static void create_page_all_columns(HWND lv
)
581 SendMessageW(lv
, LVM_SETEXTENDEDLISTVIEWSTYLE
, 0, LVS_EX_FULLROWSELECT
);
582 GetWindowRect(lv
, &rc
);
583 LoadStringW(instance
, IDS_COL_NAME
, buf
, ARRAY_SIZE(buf
));
584 column
.mask
= LVCF_WIDTH
| LVCF_TEXT
;
585 column
.cx
= (rc
.right
/ 2);
586 column
.pszText
= buf
;
587 SendMessageW(lv
, LVM_INSERTCOLUMNW
, 0, (LPARAM
)&column
);
589 LoadStringW(instance
, IDS_COL_VALUE
, buf
, ARRAY_SIZE(buf
));
590 column
.mask
= LVCF_WIDTH
| LVCF_TEXT
;
591 column
.cx
= (rc
.right
/ 2);
592 column
.pszText
= buf
;
593 SendMessageW(lv
, LVM_INSERTCOLUMNW
, 0, (LPARAM
)&column
);
596 static LRESULT CALLBACK
data_link_all_dlg_proc(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
598 TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd
, msg
, wp
, lp
);
604 HWND lv
= GetDlgItem(hwnd
, IDC_LST_PROPERTIES
);
605 create_page_all_columns(lv
);
610 if (LOWORD(wp
) == IDC_BTN_EDIT
)
612 /* TODO: Implement Connection dialog */
613 MessageBoxA(hwnd
, "Not implemented yet.", "Error", MB_OK
| MB_ICONEXCLAMATION
);
621 static HRESULT WINAPI
dslocator_PromptNew(IDataSourceLocator
*iface
, IDispatch
**connection
)
623 DSLocatorImpl
*This
= impl_from_IDataSourceLocator(iface
);
624 PROPSHEETHEADERW hdr
;
625 PROPSHEETPAGEW pages
[4];
628 FIXME("(%p, %p) Semi-stub\n", iface
, connection
);
635 memset(&pages
, 0, sizeof(pages
));
637 pages
[0].dwSize
= sizeof(PROPSHEETPAGEW
);
638 pages
[0].hInstance
= instance
;
639 pages
[0].u
.pszTemplate
= MAKEINTRESOURCEW(IDD_PROVIDER
);
640 pages
[0].pfnDlgProc
= data_link_properties_dlg_proc
;
642 pages
[1].dwSize
= sizeof(PROPSHEETPAGEW
);
643 pages
[1].hInstance
= instance
;
644 pages
[1].u
.pszTemplate
= MAKEINTRESOURCEW(IDD_CONNECTION
);
645 pages
[1].pfnDlgProc
= data_link_connection_dlg_proc
;
647 pages
[2].dwSize
= sizeof(PROPSHEETPAGEW
);
648 pages
[2].hInstance
= instance
;
649 pages
[2].u
.pszTemplate
= MAKEINTRESOURCEW(IDD_ADVANCED
);
650 pages
[2].pfnDlgProc
= data_link_advanced_dlg_proc
;
652 pages
[3].dwSize
= sizeof(pages
[0]);
653 pages
[3].hInstance
= instance
;
654 pages
[3].u
.pszTemplate
= MAKEINTRESOURCEW(IDD_ALL
);
655 pages
[3].pfnDlgProc
= data_link_all_dlg_proc
;
657 memset(&hdr
, 0, sizeof(hdr
));
658 hdr
.dwSize
= sizeof(hdr
);
659 hdr
.hwndParent
= This
->hwnd
;
660 hdr
.dwFlags
= PSH_NOAPPLYNOW
| PSH_PROPSHEETPAGE
;
661 hdr
.hInstance
= instance
;
662 hdr
.pszCaption
= MAKEINTRESOURCEW(IDS_PROPSHEET_TITLE
);
664 hdr
.nPages
= ARRAY_SIZE(pages
);
665 ret
= PropertySheetW(&hdr
);
667 return ret
? S_OK
: S_FALSE
;
670 static HRESULT WINAPI
dslocator_PromptEdit(IDataSourceLocator
*iface
, IDispatch
**ppADOConnection
, VARIANT_BOOL
*success
)
672 DSLocatorImpl
*This
= impl_from_IDataSourceLocator(iface
);
674 FIXME("(%p)->(%p %p)\n",This
, ppADOConnection
, success
);
679 static const IDataSourceLocatorVtbl DSLocatorVtbl
=
681 dslocator_QueryInterface
,
684 dslocator_GetTypeInfoCount
,
685 dslocator_GetTypeInfo
,
686 dslocator_GetIDsOfNames
,
694 static HRESULT WINAPI
datainitialize_QueryInterface(IDataInitialize
*iface
, REFIID riid
, void **obj
)
696 DSLocatorImpl
*This
= impl_from_IDataInitialize(iface
);
697 return IDataSourceLocator_QueryInterface(&This
->IDataSourceLocator_iface
, riid
, obj
);
700 static ULONG WINAPI
datainitialize_AddRef(IDataInitialize
*iface
)
702 DSLocatorImpl
*This
= impl_from_IDataInitialize(iface
);
703 return IDataSourceLocator_AddRef(&This
->IDataSourceLocator_iface
);
706 static ULONG WINAPI
datainitialize_Release(IDataInitialize
*iface
)
708 DSLocatorImpl
*This
= impl_from_IDataInitialize(iface
);
709 return IDataSourceLocator_Release(&This
->IDataSourceLocator_iface
);
712 static HRESULT WINAPI
datainitialize_GetDataSource(IDataInitialize
*iface
,
713 IUnknown
*outer
, DWORD context
, LPWSTR initstring
, REFIID riid
, IUnknown
**datasource
)
715 TRACE("(%p)->(%p %#x %s %s %p)\n", iface
, outer
, context
, debugstr_w(initstring
), debugstr_guid(riid
),
718 return get_data_source(outer
, context
, initstring
, riid
, datasource
);
721 static HRESULT WINAPI
datainitialize_GetInitializationString(IDataInitialize
*iface
, IUnknown
*datasource
,
722 boolean include_password
, LPWSTR
*initstring
)
724 FIXME("(%p)->(%d %p): stub\n", iface
, include_password
, initstring
);
728 static HRESULT WINAPI
datainitialize_CreateDBInstance(IDataInitialize
*iface
, REFCLSID prov
, IUnknown
*outer
,
729 DWORD clsctx
, LPWSTR reserved
, REFIID riid
, IUnknown
**datasource
)
731 FIXME("(%p)->(%s %p %#x %p %s %p): stub\n", iface
, debugstr_guid(prov
), outer
, clsctx
, reserved
,
732 debugstr_guid(riid
), datasource
);
736 static HRESULT WINAPI
datainitialize_CreateDBInstanceEx(IDataInitialize
*iface
, REFCLSID prov
, IUnknown
*outer
,
737 DWORD clsctx
, LPWSTR reserved
, COSERVERINFO
*server_info
, DWORD cmq
, MULTI_QI
*results
)
739 FIXME("(%p)->(%s %p %#x %p %p %u %p): stub\n", iface
, debugstr_guid(prov
), outer
, clsctx
, reserved
,
740 server_info
, cmq
, results
);
744 static HRESULT WINAPI
datainitialize_LoadStringFromStorage(IDataInitialize
*iface
, LPWSTR filename
, LPWSTR
*initstring
)
746 FIXME("(%p)->(%s %p): stub\n", iface
, debugstr_w(filename
), initstring
);
750 static HRESULT WINAPI
datainitialize_WriteStringToStorage(IDataInitialize
*iface
, LPWSTR filename
, LPWSTR initstring
,
753 FIXME("(%p)->(%s %s %#x): stub\n", iface
, debugstr_w(filename
), debugstr_w(initstring
), disposition
);
757 static const IDataInitializeVtbl ds_datainitialize_vtbl
=
759 datainitialize_QueryInterface
,
760 datainitialize_AddRef
,
761 datainitialize_Release
,
762 datainitialize_GetDataSource
,
763 datainitialize_GetInitializationString
,
764 datainitialize_CreateDBInstance
,
765 datainitialize_CreateDBInstanceEx
,
766 datainitialize_LoadStringFromStorage
,
767 datainitialize_WriteStringToStorage
,
770 HRESULT
create_dslocator(IUnknown
*outer
, void **obj
)
774 TRACE("(%p, %p)\n", outer
, obj
);
778 if(outer
) return CLASS_E_NOAGGREGATION
;
780 This
= heap_alloc(sizeof(*This
));
781 if(!This
) return E_OUTOFMEMORY
;
783 This
->IDataSourceLocator_iface
.lpVtbl
= &DSLocatorVtbl
;
784 This
->IDataInitialize_iface
.lpVtbl
= &ds_datainitialize_vtbl
;
788 *obj
= &This
->IDataSourceLocator_iface
;