[PATCH] oledb32: Initialize data provider when switching tabs

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Mon Mar 2 18:01:21 CST 2020


Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at 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




More information about the wine-devel mailing list