From: Alistair Leslie-Hughes Subject: odbccp32: Implement SQLWritePrivateProfileStringA/W Message-Id: Date: Fri, 6 Mar 2015 15:40:07 +1100 Hi, Changelog: odbccp32: Implement SQLWritePrivateProfileStringA/W Best Regards Alistair Leslie-Hughes From 7ac7e3404619f45e84a34c29d12643367bbd49b9 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 4 Mar 2015 16:26:28 +1100 Subject: [PATCH 10/10] Implement SQLWritePrivateProfileStringA/W --- dlls/odbccp32/odbccp32.c | 85 ++++++++++++++++++++++++++++++++++++++--- dlls/odbccp32/tests/Makefile.in | 2 +- dlls/odbccp32/tests/misc.c | 60 +++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 7 deletions(-) diff --git a/dlls/odbccp32/odbccp32.c b/dlls/odbccp32/odbccp32.c index fb4ea2c..92c5852 100644 --- a/dlls/odbccp32/odbccp32.c +++ b/dlls/odbccp32/odbccp32.c @@ -57,6 +57,7 @@ static const WCHAR odbc_error_invalid_buff_len[] = {'I','n','v','a','l','i','d', static const WCHAR odbc_error_component_not_found[] = {'C','o','m','p','o','n','e','n','t',' ','n','o','t',' ','f','o','u','n','d',0}; static const WCHAR odbc_error_out_of_mem[] = {'O','u','t',' ','o','f',' ','m','e','m','o','r','y',0}; static const WCHAR odbc_error_invalid_param_sequence[] = {'I','n','v','a','l','i','d',' ','p','a','r','a','m','e','t','e','r',' ','s','e','q','u','e','n','c','e',0}; +static const WCHAR odbc_error_invalid_param_string[] = {'I','n','v','a','l','i','d',' ','p','a','r','a','m','e','t','e','r',' ','s','t','r','i','n','g',0}; /* Push an error onto the error stack, taking care of ranges etc. */ static void push_error(int code, LPCWSTR msg) @@ -75,6 +76,33 @@ static void clear_errors(void) num_errors = 0; } +static inline void * heap_alloc(size_t len) +{ + return HeapAlloc(GetProcessHeap(), 0, len); +} + +static inline BOOL heap_free(void *mem) +{ + return HeapFree(GetProcessHeap(), 0, mem); +} + +static inline WCHAR *heap_strdupAtoW(const char *str) +{ + LPWSTR ret = NULL; + + if(str) { + DWORD len; + + len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + ret = heap_alloc(len*sizeof(WCHAR)); + if(ret) + MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); + } + + return ret; +} + + BOOL WINAPI ODBCCPlApplet( LONG i, LONG j, LONG * p1, LONG * p2) { clear_errors(); @@ -966,17 +994,62 @@ BOOL WINAPI SQLWriteFileDSN(LPCSTR lpszFileName, LPCSTR lpszAppName, BOOL WINAPI SQLWritePrivateProfileStringW(LPCWSTR lpszSection, LPCWSTR lpszEntry, LPCWSTR lpszString, LPCWSTR lpszFilename) { + LONG ret; + HKEY hkey; + WCHAR softwareodbc[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C',0}; + clear_errors(); - FIXME("\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + TRACE("%s %s %s %s\n", debugstr_w(lpszSection), debugstr_w(lpszEntry), + debugstr_w(lpszString), debugstr_w(lpszFilename)); + + if(!lpszFilename || !*lpszFilename) + { + push_error(ODBC_ERROR_INVALID_STR, odbc_error_invalid_param_string); + return FALSE; + } + + if ((ret = RegCreateKeyW(HKEY_CURRENT_USER, softwareodbc, &hkey)) == ERROR_SUCCESS) + { + HKEY hkeyfilename; + + if ((ret = RegCreateKeyW(hkey, lpszFilename, &hkeyfilename)) == ERROR_SUCCESS) + { + HKEY hkey_section; + + if ((ret = RegCreateKeyW(hkeyfilename, lpszSection, &hkey_section)) == ERROR_SUCCESS) + { + ret = RegSetValueExW(hkey_section, lpszEntry, 0, REG_SZ, (BYTE*)lpszString, (lstrlenW(lpszString)+1)*sizeof(WCHAR)); + RegCloseKey(hkey_section); + } + + RegCloseKey(hkeyfilename); + } + + RegCloseKey(hkey); + } + + return ret == ERROR_SUCCESS; } BOOL WINAPI SQLWritePrivateProfileString(LPCSTR lpszSection, LPCSTR lpszEntry, LPCSTR lpszString, LPCSTR lpszFilename) { + BOOL ret; + WCHAR *sect, *entry, *string, *file; clear_errors(); - FIXME("\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + TRACE("%s %s %s %s\n", lpszSection, lpszEntry, lpszString, lpszFilename); + + sect = heap_strdupAtoW(lpszSection); + entry = heap_strdupAtoW(lpszEntry); + string = heap_strdupAtoW(lpszString); + file = heap_strdupAtoW(lpszFilename); + + ret = SQLWritePrivateProfileStringW(sect, entry, string, file); + + heap_free(sect); + heap_free(entry); + heap_free(string); + heap_free(file); + + return ret; } diff --git a/dlls/odbccp32/tests/Makefile.in b/dlls/odbccp32/tests/Makefile.in index f6d7842..912f511 100644 --- a/dlls/odbccp32/tests/Makefile.in +++ b/dlls/odbccp32/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = odbccp32.dll -IMPORTS = odbccp32 +IMPORTS = odbccp32 advapi32 C_SRCS = \ misc.c diff --git a/dlls/odbccp32/tests/misc.c b/dlls/odbccp32/tests/misc.c index cfe9532..f1f3f00 100644 --- a/dlls/odbccp32/tests/misc.c +++ b/dlls/odbccp32/tests/misc.c @@ -21,6 +21,7 @@ #include "windef.h" #include "winbase.h" +#include "winreg.h" #include "odbcinst.h" static void test_SQLConfigMode(void) @@ -129,9 +130,68 @@ static void test_SQLInstallDriverManager(void) ok(path_out != 0xcafe, "Expected path_out to show the correct amount of bytes\n"); } +static void test_SQLWritePrivateProfileString(void) +{ + static const WCHAR odbc_key[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C','\\','O','D','B','C','.','I','N','I','\\','w','i','n','e','o','d','b','c',0}; + static const WCHAR abcd_key[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C','\\','a','b','c','d','.','I','N','I','\\','w','i','n','e','o','d','b','c',0}; + static const WCHAR abcdini_key[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C','\\','a','b','c','d','.','I','N','I',0 }; + BOOL ret; + LONG reg_ret; + DWORD error_code; + + ret = SQLWritePrivateProfileString("wineodbc", "testing" , "value", ""); + ok(!ret, "SQLWritePrivateProfileString passed\n"); + SQLInstallerErrorW(1, &error_code, NULL, 0, NULL); + ok(error_code == ODBC_ERROR_INVALID_STR, "SQLInstallerErrorW ret: %d\n", error_code); + + ret = SQLWritePrivateProfileString("wineodbc", "testing" , "value", NULL); + ok(!ret, "SQLWritePrivateProfileString passed\n"); + SQLInstallerErrorW(1, &error_code, NULL, 0, NULL); + ok(error_code == ODBC_ERROR_INVALID_STR, "SQLInstallerErrorW ret: %d\n", error_code); + + ret = SQLWritePrivateProfileString("wineodbc", "testing" , "value", "odbc.ini"); + ok(ret, "SQLWritePrivateProfileString failed\n"); + if(ret) + { + HKEY hkey; + + reg_ret = RegOpenKeyExW(HKEY_CURRENT_USER, odbc_key, 0, KEY_READ, &hkey); + ok(reg_ret == ERROR_SUCCESS, "RegOpenKeyExW failed\n"); + if(reg_ret == ERROR_SUCCESS) + { + reg_ret = RegDeleteKeyW(HKEY_CURRENT_USER, odbc_key); + ok(reg_ret == ERROR_SUCCESS, "RegDeleteKeyW failed\n"); + + RegCloseKey(hkey); + } + } + + ret = SQLWritePrivateProfileString("wineodbc", "testing" , "value", "abcd.ini"); + ok(ret, "SQLWritePrivateProfileString failed\n"); + if(ret) + { + HKEY hkey; + + reg_ret = RegOpenKeyExW(HKEY_CURRENT_USER, abcd_key, 0, KEY_READ, &hkey); + ok(reg_ret == ERROR_SUCCESS, "RegOpenKeyExW failed\n"); + if(reg_ret == ERROR_SUCCESS) + { + reg_ret = RegDeleteKeyW(HKEY_CURRENT_USER, abcd_key); + ok(reg_ret == ERROR_SUCCESS, "RegDeleteKeyW failed\n"); + + RegCloseKey(hkey); + } + + /* Cleanup key */ + reg_ret = RegDeleteKeyW(HKEY_CURRENT_USER, abcdini_key); + ok(reg_ret == ERROR_SUCCESS, "RegDeleteKeyW failed\n"); + } +} + START_TEST(misc) { test_SQLConfigMode(); test_SQLInstallerError(); test_SQLInstallDriverManager(); + test_SQLWritePrivateProfileString(); } -- 1.9.1