If a DSN is System wide, we need to write to the HKEY_LOCAL_MACHINE part of the registry not HKEY_CURRENT_USER which it's currently doing.
-- v2: odbccp32: SQLWritePrivateProfileStringW check for existing DSN first odbccp32: Support System wide ODBC DSN keys
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
--- dlls/odbccp32/odbccp32.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/dlls/odbccp32/odbccp32.c b/dlls/odbccp32/odbccp32.c index 95bfb90781e..5eb70bd60b5 100644 --- a/dlls/odbccp32/odbccp32.c +++ b/dlls/odbccp32/odbccp32.c @@ -713,20 +713,29 @@ BOOL WINAPI SQLGetInstalledDrivers(char *buf, WORD size, WORD *sizeout)
static HKEY get_privateprofile_sectionkey(LPCWSTR section, LPCWSTR filename) { - HKEY hkey, hkeyfilename, hkeysection; + HKEY hkeysection; LONG ret; + WCHAR *regpath;
- if (RegOpenKeyW(HKEY_CURRENT_USER, odbcW, &hkey)) + regpath = malloc ( (wcslen(L"Software\ODBC\") + wcslen(filename) + wcslen(L"\") + + wcslen(section) + 1) * sizeof(WCHAR)); + if (!regpath) return NULL;
- ret = RegOpenKeyW(hkey, filename, &hkeyfilename); - RegCloseKey(hkey); + wcscpy(regpath, L"Software\ODBC\"); + wcscat(regpath, filename); + wcscat(regpath, L"\"); + wcscat(regpath, section); + + if ((ret = RegOpenKeyW(HKEY_CURRENT_USER, regpath, &hkeysection)) != ERROR_SUCCESS) + { + ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, regpath, &hkeysection); + } + free(regpath); + if (ret) return NULL;
- ret = RegOpenKeyW(hkeyfilename, section, &hkeysection); - RegCloseKey(hkeyfilename); - return ret ? NULL : hkeysection; }
From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
If a DSN is System wide, we need to write to the HKEY_LOCAL_MACHINE part of the registry not HKEY_CURRENT_USER which it's currently doing. --- dlls/odbccp32/odbccp32.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/dlls/odbccp32/odbccp32.c b/dlls/odbccp32/odbccp32.c index 5eb70bd60b5..e07e1addf1d 100644 --- a/dlls/odbccp32/odbccp32.c +++ b/dlls/odbccp32/odbccp32.c @@ -1813,6 +1813,7 @@ BOOL WINAPI SQLWritePrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry static const WCHAR empty[] = {0}; LONG ret; HKEY hkey; + WCHAR regpath[256];
clear_errors(); TRACE("%s %s %s %s\n", debugstr_w(lpszSection), debugstr_w(lpszEntry), @@ -1824,7 +1825,26 @@ BOOL WINAPI SQLWritePrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry return FALSE; }
- if ((ret = RegCreateKeyW(HKEY_CURRENT_USER, odbcW, &hkey)) == ERROR_SUCCESS) + wcscpy(regpath, L"Software\ODBC\"); + wcscat(regpath, lpszFilename); + wcscat(regpath, L"\"); + wcscat(regpath, lpszSection); + + /* Check an existing key first before writing a new one */ + if ((ret = RegOpenKeyW(HKEY_CURRENT_USER, regpath, &hkey)) != ERROR_SUCCESS) + { + ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, regpath, &hkey); + } + + if (ret == ERROR_SUCCESS) + { + if(lpszString) + ret = RegSetValueExW(hkey, lpszEntry, 0, REG_SZ, (BYTE*)lpszString, (lstrlenW(lpszString)+1)*sizeof(WCHAR)); + else + ret = RegSetValueExW(hkey, lpszEntry, 0, REG_SZ, (BYTE*)empty, sizeof(empty)); + RegCloseKey(hkey); + } + else if ((ret = RegCreateKeyW(HKEY_CURRENT_USER, odbcW, &hkey)) == ERROR_SUCCESS) { HKEY hkeyfilename;
Windows allows, both a system and a user DSN with the same name (stupid). Since I could only create a SQL database connection (DSN) and don't have an actual server wasn't able to verify what takes preference.
Wine has no concept of security, if we write to the SYSTEM vs USER isn't an issue. However, the application I was testing, has a service which connects to the a SYSTEM DSN and expects to writes back to that location.