diff --git a/dlls/msi/action.c b/dlls/msi/action.c index f0387b12468..dbf48f4821b 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -4483,6 +4483,44 @@ static UINT ITERATE_InstallODBCTranslator( MSIRECORD *rec, LPVOID param ) 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 @@ static UINT ACTION_InstallODBC( MSIPACKAGE *package ) '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 @@ static UINT ACTION_InstallODBC( MSIPACKAGE *package ) 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 b99537f9193..cf022d6d789 100644 --- a/include/msidefs.h +++ b/include/msidefs.h @@ -168,6 +168,12 @@ enum msidbComponentAttributes msidbComponentAttributes64bit = 0x00000100 }; +enum msidbODBCDataSourceRegistration +{ + msidbODBCDataSourceRegistrationPerMachine = 0x00000000, + msidbODBCDataSourceRegistrationPerUser = 0x00000001 +}; + enum msidbRegistryRoot { msidbRegistryRootClassesRoot = 0, diff --git a/include/odbcinst.h b/include/odbcinst.h index f377197e7d7..a1109d5fcb6 100644 --- a/include/odbcinst.h +++ b/include/odbcinst.h @@ -34,6 +34,14 @@ extern "C" { #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