From: Alistair Leslie-Hughes leslie_alistair@hotmail.com
--- dlls/odbccp32/odbccp32.c | 49 +++++++++++++++++++++----------------- dlls/odbccp32/tests/misc.c | 40 +++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 22 deletions(-)
diff --git a/dlls/odbccp32/odbccp32.c b/dlls/odbccp32/odbccp32.c index fd02391a384..1183cbddd35 100644 --- a/dlls/odbccp32/odbccp32.c +++ b/dlls/odbccp32/odbccp32.c @@ -1802,6 +1802,7 @@ BOOL WINAPI SQLWritePrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry { LONG ret; HKEY hkey; + WCHAR *regpath;
clear_errors(); TRACE("%s %s %s %s\n", debugstr_w(lpszSection), debugstr_w(lpszEntry), @@ -1813,37 +1814,41 @@ BOOL WINAPI SQLWritePrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry return FALSE; }
+ regpath = malloc ( (wcslen(L"Software\ODBC\") + wcslen(lpszFilename) + wcslen(L"\") + + wcslen(lpszSection) + 1) * sizeof(WCHAR)); + if (!regpath) + { + push_error(ODBC_ERROR_OUT_OF_MEM, L"Out of memory"); + return FALSE; + } + wcscpy(regpath, L"Software\ODBC\"); + wcscat(regpath, lpszFilename); + wcscat(regpath, L"\"); + wcscat(regpath, lpszSection); + /* odbcinit.ini is only for drivers, so default to local Machine */ if (!wcsicmp(lpszFilename, L"ODBCINST.INI") || config_mode == ODBC_SYSTEM_DSN) - ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, L"Software\ODBC", &hkey); + ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, regpath, &hkey); else if (config_mode == ODBC_USER_DSN) - ret = RegCreateKeyW(HKEY_CURRENT_USER, L"Software\ODBC", &hkey); + ret = RegCreateKeyW(HKEY_CURRENT_USER, regpath, &hkey); else { - ret = RegCreateKeyW(HKEY_CURRENT_USER, L"Software\ODBC", &hkey); - if (ret) ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, L"Software\ODBC", &hkey); + /* Check existing keys first */ + if ((ret = RegOpenKeyW(HKEY_CURRENT_USER, regpath, &hkey)) != ERROR_SUCCESS) + ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, regpath, &hkey); + + if (ret != ERROR_SUCCESS) + ret = RegCreateKeyW(HKEY_CURRENT_USER, regpath, &hkey); }
+ free(regpath); + if (ret == ERROR_SUCCESS) { - HKEY hkeyfilename; - - if ((ret = RegCreateKeyW(hkey, lpszFilename, &hkeyfilename)) == ERROR_SUCCESS) - { - HKEY hkey_section; - - if ((ret = RegCreateKeyW(hkeyfilename, lpszSection, &hkey_section)) == ERROR_SUCCESS) - { - if(lpszString) - ret = RegSetValueExW(hkey_section, lpszEntry, 0, REG_SZ, (BYTE*)lpszString, (lstrlenW(lpszString)+1)*sizeof(WCHAR)); - else - ret = RegSetValueExW(hkey_section, lpszEntry, 0, REG_SZ, (BYTE*)L"", sizeof(L"")); - RegCloseKey(hkey_section); - } - - RegCloseKey(hkeyfilename); - } - + 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*)L"", sizeof(L"")); RegCloseKey(hkey); }
diff --git a/dlls/odbccp32/tests/misc.c b/dlls/odbccp32/tests/misc.c index ccd3caea977..e9f879edda6 100644 --- a/dlls/odbccp32/tests/misc.c +++ b/dlls/odbccp32/tests/misc.c @@ -432,6 +432,9 @@ static void test_SQLGetPrivateProfileStringW(void) } ok(ret, "SQLWritePrivateProfileString failed\n");
+ ret = SQLWritePrivateProfileStringW(L"wineodbc1", L"testing" , L"systemdsn", L"ODBC.INI"); + ok(ret, "SQLWritePrivateProfileString failed\n"); + ret = SQLGetPrivateProfileStringW(L"wineodbc", NULL, L"", buffer, 256, L"ODBC.INI"); ok(ret, "SQLGetPrivateProfileStringW failed\n");
@@ -441,6 +444,9 @@ static void test_SQLGetPrivateProfileStringW(void) ret = SQLGetPrivateProfileStringW(L"wineodbc", NULL, L"", buffer, 256, L"ODBC.INI"); ok(!ret, "SQLGetPrivateProfileStringW succeeded\n");
+ ret = SQLWritePrivateProfileStringW(L"wineodbc1", L"testing" , L"userdsn", L"ODBC.INI"); + ok(ret, "SQLWritePrivateProfileString failed\n"); + ret = SQLSetConfigMode(ODBC_BOTH_DSN); ok(ret, "SQLSetConfigMode failed\n");
@@ -450,6 +456,40 @@ static void test_SQLGetPrivateProfileStringW(void) reg_ret = RegDeleteKeyW(HKEY_LOCAL_MACHINE, L"Software\ODBC\ODBC.INI\wineodbc"); ok(reg_ret == ERROR_SUCCESS, "RegDeleteKeyW failed %ld\n", reg_ret);
+ /* Show existing USER DSN is checked before MACHINE */ + ret = SQLWritePrivateProfileStringW(L"wineodbc1", L"testing" , L"bothdsn", L"ODBC.INI"); + ok(ret, "SQLWritePrivateProfileString failed\n"); + + ret = SQLSetConfigMode(ODBC_SYSTEM_DSN); + ok(ret, "SQLSetConfigMode failed\n"); + + ret = SQLGetPrivateProfileStringW(L"wineodbc1", L"testing", L"", buffer, 256, L"ODBC.INI"); + ok(ret, "SQLGetPrivateProfileStringW failed\n"); + ok(!wcscmp(buffer, L"systemdsn"), "Wrong value\n"); + + reg_ret = RegDeleteKeyW(HKEY_CURRENT_USER, L"Software\ODBC\ODBC.INI\wineodbc1"); + ok(reg_ret == ERROR_SUCCESS, "RegDeleteKeyW failed %ld\n", reg_ret); + + reg_ret = RegDeleteKeyW(HKEY_LOCAL_MACHINE, L"Software\ODBC\ODBC.INI\wineodbc1"); + ok(reg_ret == ERROR_SUCCESS, "RegDeleteKeyW failed %ld\n", reg_ret); + + ret = SQLSetConfigMode(ODBC_BOTH_DSN); + ok(ret, "SQLSetConfigMode failed\n"); + + /* Writes to USER if no key found */ + ret = SQLWritePrivateProfileStringW(L"wineodbc1", L"testing" , L"userwrite", L"ODBC.INI"); + ok(ret, "SQLWritePrivateProfileString failed\n"); + + ret = SQLSetConfigMode(ODBC_USER_DSN); + ok(ret, "SQLSetConfigMode failed\n"); + + ret = SQLGetPrivateProfileStringW(L"wineodbc1", L"testing", L"", buffer, 256, L"ODBC.INI"); + ok(ret, "SQLGetPrivateProfileStringW failed\n"); + ok(!wcscmp(buffer, L"userwrite"), "Wrong value\n"); + + reg_ret = RegDeleteKeyW(HKEY_CURRENT_USER, L"Software\ODBC\ODBC.INI\wineodbc1"); + ok(reg_ret == ERROR_SUCCESS, "RegDeleteKeyW failed %ld\n", reg_ret); + ret = SQLSetConfigMode(ODBC_USER_DSN); ok(ret, "SQLSetConfigMode failed\n");