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
)
280 static const WCHAR oledbprov
[] = {'\\','O','L','E',' ','D','B',' ','P','r','o','v','i','d','e','r',0};
282 HKEY key
= NULL
, subkey
;
285 WCHAR provider
[MAX_PATH
];
286 WCHAR guidkey
[MAX_PATH
];
289 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, L
"CLSID", 0, KEY_READ
, &key
);
290 if (res
== ERROR_FILE_NOT_FOUND
)
293 next_key
= RegEnumKeyW(key
, index
, provider
, MAX_PATH
);
294 while (next_key
== ERROR_SUCCESS
)
296 WCHAR description
[MAX_PATH
];
298 lstrcpyW(guidkey
, provider
);
299 lstrcatW(guidkey
, oledbprov
);
301 res
= RegOpenKeyW(key
, guidkey
, &subkey
);
302 if (res
== ERROR_SUCCESS
)
304 TRACE("Found %s\n", debugstr_w(guidkey
));
307 res
= RegQueryValueW(subkey
, NULL
, description
, &size
);
308 if (res
== ERROR_SUCCESS
)
311 struct datasource
*data
;
313 data
= create_datasource(guidkey
);
315 item
.mask
= LVIF_TEXT
| LVIF_PARAM
;
316 item
.iItem
= SendMessageW(lv
, LVM_GETITEMCOUNT
, 0, 0);
318 item
.pszText
= description
;
319 item
.lParam
= (LPARAM
)data
;
321 SendMessageW(lv
, LVM_INSERTITEMW
, 0, (LPARAM
)&item
);
327 next_key
= RegEnumKeyW(key
, index
, provider
, MAX_PATH
);
333 static LRESULT CALLBACK
data_link_properties_dlg_proc(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
335 TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd
, msg
, wp
, lp
);
341 HWND btn
, lv
= GetDlgItem(hwnd
, IDC_LST_CONNECTIONS
);
342 create_connections_columns(lv
);
343 add_connections_providers(lv
);
345 btn
= GetDlgItem(GetParent(hwnd
), IDOK
);
346 EnableWindow(btn
, FALSE
);
352 HWND lv
= GetDlgItem(hwnd
, IDC_LST_CONNECTIONS
);
357 item
.mask
= LVIF_PARAM
;
359 while(ListView_GetItemA(lv
, &item
))
361 destroy_datasource( (struct datasource
*)item
.lParam
);
368 NMHDR
*hdr
= ((LPNMHDR
)lp
);
375 * FIXME: This needs to replace the connection page based off the selection.
376 * We only care about the ODBC for now which is the default.
379 HWND lv
= GetDlgItem(hwnd
, IDC_LST_CONNECTIONS
);
380 if (!SendMessageW(lv
, LVM_GETSELECTEDCOUNT
, 0, 0))
382 WCHAR title
[256], msg
[256];
384 LoadStringW(instance
, IDS_PROVIDER_TITLE
, title
, ARRAY_SIZE(title
));
385 LoadStringW(instance
, IDS_PROVIDER_ERROR
, msg
, ARRAY_SIZE(msg
));
386 MessageBoxW(hwnd
, msg
, title
, MB_OK
| MB_ICONEXCLAMATION
);
387 SetWindowLongPtrW(hwnd
, DWLP_MSGRESULT
, TRUE
);
393 item
.stateMask
= LVIS_SELECTED
;
394 item
.mask
= LVIF_PARAM
| LVIF_STATE
;
396 if(ListView_GetItemA(lv
, &item
))
398 if(!initialize_datasource( (struct datasource
*)item
.lParam
))
400 WCHAR title
[256], msg
[256];
401 LoadStringW(instance
, IDS_PROVIDER_TITLE
, title
, ARRAY_SIZE(title
));
402 LoadStringW(instance
, IDS_PROVIDER_NOT_AVAIL
, msg
, ARRAY_SIZE(msg
));
403 MessageBoxW(hwnd
, msg
, title
, MB_OK
| MB_ICONEXCLAMATION
);
404 SetWindowLongPtrW(hwnd
, DWLP_MSGRESULT
, TRUE
);
409 ERR("Failed to get selected item\n");
419 if (LOWORD(wp
) == IDC_BTN_NEXT
)
420 SendMessageW(GetParent(hwnd
), PSM_SETCURSEL
, 1, 0);
429 static void connection_fill_odbc_list(HWND parent
)
434 WCHAR name
[MAX_PATH
];
437 HWND combo
= GetDlgItem(parent
, IDC_CBO_NAMES
);
441 res
= RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Software\\ODBC\\ODBC.INI\\ODBC Data Sources", 0, KEY_READ
, &key
);
442 if (res
== ERROR_FILE_NOT_FOUND
)
445 SendMessageW (combo
, CB_RESETCONTENT
, 0, 0);
450 if (RegEnumValueW(key
, index
, name
, &nameLen
, NULL
, NULL
, NULL
, NULL
) != ERROR_SUCCESS
)
453 SendMessageW(combo
, CB_ADDSTRING
, 0, (LPARAM
)name
);
459 static void connection_initialize_controls(HWND parent
)
461 HWND hwnd
= GetDlgItem(parent
, IDC_RDO_SRC_NAME
);
463 SendMessageA(hwnd
, BM_SETCHECK
, BST_CHECKED
, 0);
466 static void connection_toggle_controls(HWND parent
)
469 HWND hwnd
= GetDlgItem(parent
, IDC_RDO_SRC_NAME
);
471 checked
= SendMessageA(hwnd
, BM_GETCHECK
, 0, 0);
473 EnableWindow(GetDlgItem(parent
, IDC_CBO_NAMES
), checked
);
474 EnableWindow(GetDlgItem(parent
, IDC_BTN_REFRESH
), checked
);
476 EnableWindow(GetDlgItem(parent
, IDC_LBL_CONNECTION
), !checked
);
477 EnableWindow(GetDlgItem(parent
, IDC_EDT_CONNECTION
), !checked
);
478 EnableWindow(GetDlgItem(parent
, IDC_BTN_BUILD
), !checked
);
481 static LRESULT CALLBACK
data_link_connection_dlg_proc(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
483 TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd
, msg
, wp
, lp
);
489 connection_initialize_controls(hwnd
);
490 connection_fill_odbc_list(hwnd
);
491 connection_toggle_controls(hwnd
);
498 case IDC_RDO_SRC_NAME
:
499 case IDC_BTN_CONNECTION
:
500 connection_toggle_controls(hwnd
);
502 case IDC_BTN_REFRESH
:
503 connection_fill_odbc_list(hwnd
);
507 /* TODO: Implement dialogs */
508 MessageBoxA(hwnd
, "Not implemented yet.", "Error", MB_OK
| MB_ICONEXCLAMATION
);
520 static void advanced_fill_permission_list(HWND parent
)
525 int resources
[] = {IDS_PERM_READ
, IDS_PERM_READWRITE
, IDS_PERM_SHAREDENYNONE
,
526 IDS_PERM_SHAREDENYREAD
, IDS_PERM_SHAREDENYWRITE
, IDS_PERM_SHAREEXCLUSIVE
,
530 HWND lv
= GetDlgItem(parent
, IDC_LST_PERMISSIONS
);
534 SendMessageW(lv
, LVM_SETEXTENDEDLISTVIEWSTYLE
, 0, LVS_EX_CHECKBOXES
);
535 GetWindowRect(lv
, &rc
);
536 column
.mask
= LVCF_WIDTH
| LVCF_FMT
;
537 column
.fmt
= LVCFMT_FIXED_WIDTH
;
538 column
.cx
= (rc
.right
- rc
.left
) - 25;
539 column
.pszText
= buf
;
540 SendMessageW(lv
, LVM_INSERTCOLUMNW
, 0, (LPARAM
)&column
);
542 for(i
=0; i
< ARRAY_SIZE(resources
); i
++)
544 item
.mask
= LVIF_TEXT
;
545 item
.iItem
= SendMessageW(lv
, LVM_GETITEMCOUNT
, 0, 0);
547 LoadStringW(instance
, resources
[i
], buf
, ARRAY_SIZE(buf
));
549 SendMessageW(lv
, LVM_INSERTITEMW
, 0, (LPARAM
)&item
);
553 static LRESULT CALLBACK
data_link_advanced_dlg_proc(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
555 TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd
, msg
, wp
, lp
);
561 EnableWindow(GetDlgItem(hwnd
, IDC_LBL_LEVEL
), FALSE
);
562 EnableWindow(GetDlgItem(hwnd
, IDC_CBO_LEVEL
), FALSE
);
563 EnableWindow(GetDlgItem(hwnd
, IDC_LBL_PROTECTION
), FALSE
);
564 EnableWindow(GetDlgItem(hwnd
, IDC_CBO_PROTECTION
), FALSE
);
566 advanced_fill_permission_list(hwnd
);
576 static void create_page_all_columns(HWND lv
)
582 SendMessageW(lv
, LVM_SETEXTENDEDLISTVIEWSTYLE
, 0, LVS_EX_FULLROWSELECT
);
583 GetWindowRect(lv
, &rc
);
584 LoadStringW(instance
, IDS_COL_NAME
, buf
, ARRAY_SIZE(buf
));
585 column
.mask
= LVCF_WIDTH
| LVCF_TEXT
;
586 column
.cx
= (rc
.right
/ 2);
587 column
.pszText
= buf
;
588 SendMessageW(lv
, LVM_INSERTCOLUMNW
, 0, (LPARAM
)&column
);
590 LoadStringW(instance
, IDS_COL_VALUE
, buf
, ARRAY_SIZE(buf
));
591 column
.mask
= LVCF_WIDTH
| LVCF_TEXT
;
592 column
.cx
= (rc
.right
/ 2);
593 column
.pszText
= buf
;
594 SendMessageW(lv
, LVM_INSERTCOLUMNW
, 0, (LPARAM
)&column
);
597 static LRESULT CALLBACK
data_link_all_dlg_proc(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
599 TRACE("(%p, %08x, %08lx, %08lx)\n", hwnd
, msg
, wp
, lp
);
605 HWND lv
= GetDlgItem(hwnd
, IDC_LST_PROPERTIES
);
606 create_page_all_columns(lv
);
611 if (LOWORD(wp
) == IDC_BTN_EDIT
)
613 /* TODO: Implement Connection dialog */
614 MessageBoxA(hwnd
, "Not implemented yet.", "Error", MB_OK
| MB_ICONEXCLAMATION
);
622 static HRESULT WINAPI
dslocator_PromptNew(IDataSourceLocator
*iface
, IDispatch
**connection
)
624 DSLocatorImpl
*This
= impl_from_IDataSourceLocator(iface
);
625 PROPSHEETHEADERW hdr
;
626 PROPSHEETPAGEW pages
[4];
629 FIXME("(%p, %p) Semi-stub\n", iface
, connection
);
636 memset(&pages
, 0, sizeof(pages
));
638 pages
[0].dwSize
= sizeof(PROPSHEETPAGEW
);
639 pages
[0].hInstance
= instance
;
640 pages
[0].u
.pszTemplate
= MAKEINTRESOURCEW(IDD_PROVIDER
);
641 pages
[0].pfnDlgProc
= data_link_properties_dlg_proc
;
643 pages
[1].dwSize
= sizeof(PROPSHEETPAGEW
);
644 pages
[1].hInstance
= instance
;
645 pages
[1].u
.pszTemplate
= MAKEINTRESOURCEW(IDD_CONNECTION
);
646 pages
[1].pfnDlgProc
= data_link_connection_dlg_proc
;
648 pages
[2].dwSize
= sizeof(PROPSHEETPAGEW
);
649 pages
[2].hInstance
= instance
;
650 pages
[2].u
.pszTemplate
= MAKEINTRESOURCEW(IDD_ADVANCED
);
651 pages
[2].pfnDlgProc
= data_link_advanced_dlg_proc
;
653 pages
[3].dwSize
= sizeof(pages
[0]);
654 pages
[3].hInstance
= instance
;
655 pages
[3].u
.pszTemplate
= MAKEINTRESOURCEW(IDD_ALL
);
656 pages
[3].pfnDlgProc
= data_link_all_dlg_proc
;
658 memset(&hdr
, 0, sizeof(hdr
));
659 hdr
.dwSize
= sizeof(hdr
);
660 hdr
.hwndParent
= This
->hwnd
;
661 hdr
.dwFlags
= PSH_NOAPPLYNOW
| PSH_PROPSHEETPAGE
;
662 hdr
.hInstance
= instance
;
663 hdr
.pszCaption
= MAKEINTRESOURCEW(IDS_PROPSHEET_TITLE
);
665 hdr
.nPages
= ARRAY_SIZE(pages
);
666 ret
= PropertySheetW(&hdr
);
668 return ret
? S_OK
: S_FALSE
;
671 static HRESULT WINAPI
dslocator_PromptEdit(IDataSourceLocator
*iface
, IDispatch
**ppADOConnection
, VARIANT_BOOL
*success
)
673 DSLocatorImpl
*This
= impl_from_IDataSourceLocator(iface
);
675 FIXME("(%p)->(%p %p)\n",This
, ppADOConnection
, success
);
680 static const IDataSourceLocatorVtbl DSLocatorVtbl
=
682 dslocator_QueryInterface
,
685 dslocator_GetTypeInfoCount
,
686 dslocator_GetTypeInfo
,
687 dslocator_GetIDsOfNames
,
695 static HRESULT WINAPI
datainitialize_QueryInterface(IDataInitialize
*iface
, REFIID riid
, void **obj
)
697 DSLocatorImpl
*This
= impl_from_IDataInitialize(iface
);
698 return IDataSourceLocator_QueryInterface(&This
->IDataSourceLocator_iface
, riid
, obj
);
701 static ULONG WINAPI
datainitialize_AddRef(IDataInitialize
*iface
)
703 DSLocatorImpl
*This
= impl_from_IDataInitialize(iface
);
704 return IDataSourceLocator_AddRef(&This
->IDataSourceLocator_iface
);
707 static ULONG WINAPI
datainitialize_Release(IDataInitialize
*iface
)
709 DSLocatorImpl
*This
= impl_from_IDataInitialize(iface
);
710 return IDataSourceLocator_Release(&This
->IDataSourceLocator_iface
);
713 static HRESULT WINAPI
datainitialize_GetDataSource(IDataInitialize
*iface
,
714 IUnknown
*outer
, DWORD context
, LPWSTR initstring
, REFIID riid
, IUnknown
**datasource
)
716 TRACE("(%p)->(%p %#x %s %s %p)\n", iface
, outer
, context
, debugstr_w(initstring
), debugstr_guid(riid
),
719 return get_data_source(outer
, context
, initstring
, riid
, datasource
);
722 static HRESULT WINAPI
datainitialize_GetInitializationString(IDataInitialize
*iface
, IUnknown
*datasource
,
723 boolean include_password
, LPWSTR
*initstring
)
725 FIXME("(%p)->(%d %p): stub\n", iface
, include_password
, initstring
);
729 static HRESULT WINAPI
datainitialize_CreateDBInstance(IDataInitialize
*iface
, REFCLSID prov
, IUnknown
*outer
,
730 DWORD clsctx
, LPWSTR reserved
, REFIID riid
, IUnknown
**datasource
)
732 FIXME("(%p)->(%s %p %#x %p %s %p): stub\n", iface
, debugstr_guid(prov
), outer
, clsctx
, reserved
,
733 debugstr_guid(riid
), datasource
);
737 static HRESULT WINAPI
datainitialize_CreateDBInstanceEx(IDataInitialize
*iface
, REFCLSID prov
, IUnknown
*outer
,
738 DWORD clsctx
, LPWSTR reserved
, COSERVERINFO
*server_info
, DWORD cmq
, MULTI_QI
*results
)
740 FIXME("(%p)->(%s %p %#x %p %p %u %p): stub\n", iface
, debugstr_guid(prov
), outer
, clsctx
, reserved
,
741 server_info
, cmq
, results
);
745 static HRESULT WINAPI
datainitialize_LoadStringFromStorage(IDataInitialize
*iface
, LPWSTR filename
, LPWSTR
*initstring
)
747 FIXME("(%p)->(%s %p): stub\n", iface
, debugstr_w(filename
), initstring
);
751 static HRESULT WINAPI
datainitialize_WriteStringToStorage(IDataInitialize
*iface
, LPWSTR filename
, LPWSTR initstring
,
754 FIXME("(%p)->(%s %s %#x): stub\n", iface
, debugstr_w(filename
), debugstr_w(initstring
), disposition
);
758 static const IDataInitializeVtbl ds_datainitialize_vtbl
=
760 datainitialize_QueryInterface
,
761 datainitialize_AddRef
,
762 datainitialize_Release
,
763 datainitialize_GetDataSource
,
764 datainitialize_GetInitializationString
,
765 datainitialize_CreateDBInstance
,
766 datainitialize_CreateDBInstanceEx
,
767 datainitialize_LoadStringFromStorage
,
768 datainitialize_WriteStringToStorage
,
771 HRESULT
create_dslocator(IUnknown
*outer
, void **obj
)
775 TRACE("(%p, %p)\n", outer
, obj
);
779 if(outer
) return CLASS_E_NOAGGREGATION
;
781 This
= heap_alloc(sizeof(*This
));
782 if(!This
) return E_OUTOFMEMORY
;
784 This
->IDataSourceLocator_iface
.lpVtbl
= &DSLocatorVtbl
;
785 This
->IDataInitialize_iface
.lpVtbl
= &ds_datainitialize_vtbl
;
789 *obj
= &This
->IDataSourceLocator_iface
;