From c4a7c821f1c0eda8304c0287af52c18d42747046 Mon Sep 17 00:00:00 2001 From: Bill Medland Date: Fri, 12 Jan 2007 12:48:17 -0800 Subject: [PATCH] odbccp32: Implement SQLGet/SetConfigMode. --- dlls/odbccp32/odbccp32.c | 28 +++++++++++++++++++++------- dlls/odbccp32/tests/misc.c | 28 ++++++++++++++++++++++++++++ include/odbcinst.h | 5 +++++ 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/dlls/odbccp32/odbccp32.c b/dlls/odbccp32/odbccp32.c index eab71cc0a29..44957a21255 100644 --- a/dlls/odbccp32/odbccp32.c +++ b/dlls/odbccp32/odbccp32.c @@ -36,9 +36,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(odbc); -/* Registry key namess */ +/* Registry key names */ static const WCHAR drivers_key[] = {'S','o','f','t','w','a','r','e','\\','O','D','B','C','\\','O','D','B','C','I','N','S','T','.','I','N','I','\\','O','D','B','C',' ','D','r','i','v','e','r','s',0}; +/* This config mode is known to be process-wide. + * MSDN documentation suggests that the value is hidden somewhere in the registry but I haven't found it yet. + * Although both the registry and the ODBC.ini files appear to be maintained together they are not maintained automatically through the registry's IniFileMapping. + */ +static UWORD config_mode = ODBC_BOTH_DSN; + /* MSDN documentation suggests that the error subsystem handles errors 1 to 8 * only and experimentation (Windows 2000) shows that the errors are process- * wide so go for the simple solution; static arrays. @@ -50,6 +56,7 @@ static const WCHAR odbc_error_general_err[] = {'G','e','n','e','r','a','l',' ',' static const WCHAR odbc_error_invalid_buff_len[] = {'I','n','v','a','l','i','d',' ','b','u','f','f','e','r',' ','l','e','n','g','t','h',0}; 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}; /* Push an error onto the error stack, taking care of ranges etc. */ static void push_error(int code, LPCWSTR msg) @@ -264,9 +271,9 @@ BOOL WINAPI SQLGetAvailableDrivers(LPCSTR lpszInfFile, LPSTR lpszBuf, BOOL WINAPI SQLGetConfigMode(UWORD *pwConfigMode) { clear_errors(); - FIXME("\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + if (pwConfigMode) + *pwConfigMode = config_mode; + return TRUE; } /* This is implemented sensibly rather than according to exact conformance to Microsoft's buggy implementations @@ -886,9 +893,16 @@ BOOL WINAPI SQLRemoveTranslator(LPCSTR lpszTranslator, LPDWORD lpdwUsageCount) BOOL WINAPI SQLSetConfigMode(UWORD wConfigMode) { clear_errors(); - FIXME("\n"); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + if (wConfigMode > ODBC_SYSTEM_DSN) + { + push_error(ODBC_ERROR_INVALID_PARAM_SEQUENCE, odbc_error_invalid_param_sequence); + return FALSE; + } + else + { + config_mode = wConfigMode; + return TRUE; + } } BOOL WINAPI SQLValidDSNW(LPCWSTR lpszDSN) diff --git a/dlls/odbccp32/tests/misc.c b/dlls/odbccp32/tests/misc.c index 0a949a64ad6..20ba1ccd83a 100644 --- a/dlls/odbccp32/tests/misc.c +++ b/dlls/odbccp32/tests/misc.c @@ -23,6 +23,33 @@ #include "winbase.h" #include "odbcinst.h" +static void test_SQLConfigMode(void) +{ + BOOL bool_ret; + DWORD error_code; + RETCODE sql_ret; + UWORD config_mode; + int i; + + ok(SQLGetConfigMode(NULL), "SQLGetConfigMode(NULL) should succeed\n"); + + bool_ret = SQLGetConfigMode(&config_mode); + ok(bool_ret && config_mode == ODBC_BOTH_DSN, "Failed to get the initial SQLGetConfigMode or it was not both\n"); + + bool_ret = SQLSetConfigMode(3); + sql_ret = SQLInstallerErrorW(1, &error_code, NULL, 0, NULL); + ok(!bool_ret && sql_ret == SQL_SUCCESS_WITH_INFO && error_code == ODBC_ERROR_INVALID_PARAM_SEQUENCE, "SQLSetConfigMode with invalid argument did not fail correctly"); + + ok (ODBC_SYSTEM_DSN == 2 && ODBC_USER_DSN == 1 && ODBC_BOTH_DSN == 0, "SQLSetConfigMode modes not as expected\n"); + for (i = ODBC_SYSTEM_DSN; i >= ODBC_BOTH_DSN; --i) + { + ok(SQLSetConfigMode((UWORD)i), "SQLSetConfigMode Failed to set config mode\n"); + bool_ret = SQLGetConfigMode(&config_mode); + ok(bool_ret && config_mode == i, "Failed to confirm SQLSetConfigMode.\n"); + } + /* And that leaves it correctly on BOTH */ +} + static void test_SQLInstallerError(void) { RETCODE sql_ret; @@ -49,5 +76,6 @@ static void test_SQLInstallerError(void) START_TEST(misc) { + test_SQLConfigMode(); test_SQLInstallerError(); } diff --git a/include/odbcinst.h b/include/odbcinst.h index 430f83c95fa..f377197e7d7 100644 --- a/include/odbcinst.h +++ b/include/odbcinst.h @@ -34,6 +34,11 @@ extern "C" { #define ODBC_CONFIG_DRIVER 3 #define ODBC_CONFIG_DRIVER_MAX 100 +/* Mode values for SQLSetConfigMode/SQLGetConfigMode */ +#define ODBC_BOTH_DSN 0 +#define ODBC_USER_DSN 1 +#define ODBC_SYSTEM_DSN 2 + /* error values */ #define ODBC_ERROR_GENERAL_ERR 1 #define ODBC_ERROR_INVALID_BUFF_LEN 2