Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/oledb32/dslocator.c | 115 ++++++++++++++++++++++++++++++++++++++-
dlls/oledb32/resource.h | 1 +
dlls/oledb32/version.rc | 1 +
3 files changed, 115 insertions(+), 2 deletions(-)
diff --git a/dlls/oledb32/dslocator.c b/dlls/oledb32/dslocator.c
index 006330b004..8a7f2d134c 100644
--- a/dlls/oledb32/dslocator.c
+++ b/dlls/oledb32/dslocator.c
@@ -41,6 +41,75 @@
WINE_DEFAULT_DEBUG_CHANNEL(oledb);
+struct datasource
+{
+ CLSID clsid;
+ IDBProperties *provider;
+ DBPROPINFOSET *propinfoset;
+ WCHAR *description;
+};
+
+static struct datasource *create_datasource(WCHAR *guid)
+{
+ struct datasource *data = heap_alloc_zero(sizeof(struct datasource));
+ if (data)
+ {
+ CLSIDFromString(guid, &data->clsid);
+ }
+
+ return data;
+}
+
+static void destroy_datasource(struct datasource *data)
+{
+ if (data->propinfoset)
+ {
+ ULONG i;
+
+ for (i = 0; i < data->propinfoset->cPropertyInfos; i++)
+ VariantClear(&data->propinfoset->rgPropertyInfos[i].vValues);
+
+ CoTaskMemFree(data->propinfoset->rgPropertyInfos);
+ CoTaskMemFree(data->propinfoset);
+ }
+ if (data->description)
+ CoTaskMemFree(data->description);
+
+ if (data->provider)
+ IDBProperties_Release(data->provider);
+
+ heap_free(data);
+}
+
+static BOOL initialize_datasource(struct datasource *data)
+{
+ HRESULT hr;
+ DBPROPIDSET propidset;
+ ULONG infocount;
+
+ hr = CoCreateInstance(&data->clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IDBProperties, (void**)&data->provider);
+ if (FAILED(hr))
+ {
+ WARN("Datasource cannot be created (0x%08x)\n", hr);
+ return FALSE;
+ }
+
+ propidset.rgPropertyIDs = NULL;
+ propidset.cPropertyIDs = 0;
+ propidset.guidPropertySet = DBPROPSET_DBINITALL;
+
+ hr = IDBProperties_GetPropertyInfo(data->provider, 1, &propidset, &infocount, &data->propinfoset, &data->description);
+ if (FAILED(hr))
+ {
+ WARN("Failed to get DB Properties (0x%08x)\n", hr);
+
+ IDBProperties_Release(data->provider);
+ data->provider = NULL;
+ return FALSE;
+ }
+
+ return TRUE;
+}
typedef struct DSLocatorImpl
{
@@ -240,12 +309,17 @@ static void add_connections_providers(HWND lv)
if (res == ERROR_SUCCESS)
{
LVITEMW item;
- item.mask = LVIF_TEXT;
+ struct datasource *data;
+
+ data = create_datasource(guidkey);
+
+ item.mask = LVIF_TEXT | LVIF_PARAM;
item.iItem = SendMessageW(lv, LVM_GETITEMCOUNT, 0, 0);
item.iSubItem = 0;
item.pszText = description;
+ item.lParam = (LPARAM)data;
+
SendMessageW(lv, LVM_INSERTITEMW, 0, (LPARAM)&item);
- /* TODO - Add ProgID to item data */
}
RegCloseKey(subkey);
}
@@ -274,6 +348,22 @@ static LRESULT CALLBACK data_link_properties_dlg_proc(HWND hwnd, UINT msg, WPARA
break;
}
+ case WM_DESTROY:
+ {
+ HWND lv = GetDlgItem(hwnd, IDC_LST_CONNECTIONS);
+ LVITEMA item;
+
+ item.iItem = 0;
+ item.iSubItem = 0;
+ item.mask = LVIF_PARAM;
+
+ while(ListView_GetItemA(lv, &item))
+ {
+ destroy_datasource( (struct datasource *)item.lParam);
+ item.iItem++;
+ }
+ break;
+ }
case WM_NOTIFY:
{
NMHDR *hdr = ((LPNMHDR)lp);
@@ -281,6 +371,7 @@ static LRESULT CALLBACK data_link_properties_dlg_proc(HWND hwnd, UINT msg, WPARA
{
case PSN_KILLACTIVE:
{
+ LVITEMA item;
/*
* FIXME: This needs to replace the connection page based off the selection.
* We only care about the ODBC for now which is the default.
@@ -298,6 +389,26 @@ static LRESULT CALLBACK data_link_properties_dlg_proc(HWND hwnd, UINT msg, WPARA
return TRUE;
}
+ item.iItem = 0;
+ item.iSubItem = 0;
+ item.stateMask = LVIS_SELECTED;
+ item.mask = LVIF_PARAM | LVIF_STATE;
+
+ if(ListView_GetItemA(lv, &item))
+ {
+ if(!initialize_datasource( (struct datasource*)item.lParam))
+ {
+ WCHAR title[256], msg[256];
+ LoadStringW(instance, IDS_PROVIDER_TITLE, title, ARRAY_SIZE(title));
+ LoadStringW(instance, IDS_PROVIDER_NOT_AVAIL, msg, ARRAY_SIZE(msg));
+ MessageBoxW(hwnd, msg, title, MB_OK | MB_ICONEXCLAMATION);
+ SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, TRUE);
+ return TRUE;
+ }
+ }
+ else
+ ERR("Failed to get selected item\n");
+
return FALSE;
}
}
diff --git a/dlls/oledb32/resource.h b/dlls/oledb32/resource.h
index dfedb34a54..42f984c013 100644
--- a/dlls/oledb32/resource.h
+++ b/dlls/oledb32/resource.h
@@ -21,6 +21,7 @@
#define IDC_LST_CONNECTIONS 1002
#define IDS_PROVIDER_TITLE 1003
#define IDS_PROVIDER_ERROR 1004
+#define IDS_PROVIDER_NOT_AVAIL 1005
#define IDS_PROPSHEET_TITLE 2000
#define IDS_COL_PROVIDER 2001
diff --git a/dlls/oledb32/version.rc b/dlls/oledb32/version.rc
index 247709dec2..86b5a317b2 100644
--- a/dlls/oledb32/version.rc
+++ b/dlls/oledb32/version.rc
@@ -48,6 +48,7 @@ STRINGTABLE
IDS_PROVIDER_TITLE "Data Link Error"
IDS_PROVIDER_ERROR "Please select a provider."
+ IDS_PROVIDER_NOT_AVAIL "Provider is no longer available. Ensure that the provider is installed properly."
}
IDD_PROVIDER DIALOG 0, 0, 227, 225
--
2.17.1