msi: Install data sources in the InstallODBC custom action.
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index f0387b1..dbf48f4 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -4483,6 +4483,44 @@
     return r;
 }
 
+static UINT ITERATE_InstallODBCDataSource( MSIRECORD *rec, LPVOID param )
+{
+    LPWSTR attrs;
+    LPCWSTR desc, driver;
+    WORD request = ODBC_ADD_SYS_DSN;
+    INT registration;
+    DWORD len;
+    UINT r = ERROR_SUCCESS;
+
+    static const WCHAR attrs_fmt[] = {
+        'D','S','N','=','%','s',0 };
+
+    desc = MSI_RecordGetString(rec, 3);
+    driver = MSI_RecordGetString(rec, 4);
+    registration = MSI_RecordGetInteger(rec, 5);
+
+    if (registration == msidbODBCDataSourceRegistrationPerMachine) request = ODBC_ADD_SYS_DSN;
+    else if (registration == msidbODBCDataSourceRegistrationPerUser) request = ODBC_ADD_DSN;
+
+    len = lstrlenW(attrs_fmt) + lstrlenW(desc) + 1 + 1;
+    attrs = msi_alloc(len * sizeof(WCHAR));
+    if (!attrs)
+        return ERROR_OUTOFMEMORY;
+
+    sprintfW(attrs, attrs_fmt, desc);
+    attrs[len - 1] = '\0';
+
+    if (!SQLConfigDataSourceW(NULL, request, driver, attrs))
+    {
+        ERR("Failed to install SQL data source!\n");
+        r = ERROR_FUNCTION_FAILED;
+    }
+
+    msi_free(attrs);
+
+    return r;
+}
+
 static UINT ACTION_InstallODBC( MSIPACKAGE *package )
 {
     UINT rc;
@@ -4496,6 +4534,10 @@
         'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         'O','D','B','C','T','r','a','n','s','l','a','t','o','r',0 };
 
+    static const WCHAR source_query[] = {
+        'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+        'O','D','B','C','D','a','t','a','S','o','u','r','c','e',0 };
+
     rc = MSI_DatabaseOpenViewW(package->db, driver_query, &view);
     if (rc != ERROR_SUCCESS)
         return ERROR_SUCCESS;
@@ -4510,6 +4552,13 @@
     rc = MSI_IterateRecords(view, NULL, ITERATE_InstallODBCTranslator, package);
     msiobj_release(&view->hdr);
 
+    rc = MSI_DatabaseOpenViewW(package->db, source_query, &view);
+    if (rc != ERROR_SUCCESS)
+        return ERROR_SUCCESS;
+
+    rc = MSI_IterateRecords(view, NULL, ITERATE_InstallODBCDataSource, package);
+    msiobj_release(&view->hdr);
+
     return rc;
 }
 
diff --git a/include/msidefs.h b/include/msidefs.h
index b99537f..cf022d6 100644
--- a/include/msidefs.h
+++ b/include/msidefs.h
@@ -168,6 +168,12 @@
     msidbComponentAttributes64bit = 0x00000100
 };
 
+enum msidbODBCDataSourceRegistration
+{
+    msidbODBCDataSourceRegistrationPerMachine = 0x00000000,
+    msidbODBCDataSourceRegistrationPerUser = 0x00000001
+};
+
 enum msidbRegistryRoot
 {
     msidbRegistryRootClassesRoot = 0,
diff --git a/include/odbcinst.h b/include/odbcinst.h
index f377197..a1109d5 100644
--- a/include/odbcinst.h
+++ b/include/odbcinst.h
@@ -34,6 +34,14 @@
 #define ODBC_CONFIG_DRIVER	3
 #define ODBC_CONFIG_DRIVER_MAX  100
 
+#define ODBC_ADD_DSN            1
+#define ODBC_CONFIG_DSN         2
+#define ODBC_REMOVE_DSN         3
+#define ODBC_ADD_SYS_DSN        4
+#define ODBC_CONFIG_SYS_DSN     5
+#define ODBC_REMOVE_SYS_DSN     6
+#define ODBC_REMOVE_DEFAULT_DSN 7
+
 /* Mode values for SQLSetConfigMode/SQLGetConfigMode */
 #define ODBC_BOTH_DSN 0
 #define ODBC_USER_DSN 1