diff options
author | Vladislav Vaintroub <wlad@mariadb.com> | 2021-11-19 09:46:57 +0100 |
---|---|---|
committer | Vladislav Vaintroub <wlad@mariadb.com> | 2021-11-19 09:46:57 +0100 |
commit | 010273268665746e188324e49730704c83aa8752 (patch) | |
tree | 57e441ab2a65be79e7e54755619518f9f4468c74 | |
parent | 220dc1fd59e61a44718a38ea59de5dc1da5aab8f (diff) | |
download | mariadb-git-010273268665746e188324e49730704c83aa8752.tar.gz |
Revert "MDEV-26713 Windows - improve utf8 support for command line tools"st-10.8-wlad
This reverts commit several commits pushed by mistake.
25 files changed, 142 insertions, 655 deletions
diff --git a/client/mysql.cc b/client/mysql.cc index c41232d2185..ee963b9220d 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -88,7 +88,9 @@ extern "C" { #endif /* defined(HAVE_CURSES_H) && defined(HAVE_TERM_H) */ #undef bcmp // Fix problem with new readline -#if !defined(_WIN32) +#if defined(_WIN32) +#include <conio.h> +#else # ifdef __APPLE__ # include <editline/readline.h> # else @@ -102,101 +104,6 @@ extern "C" { #endif } - -#if defined(_WIN32) -/* - Set console mode for the whole duration of the client session. - - We need for input - - line input (i.e read lines from console) - - echo typed characters - - "cooked" mode, i.e we do not want to handle all keystrokes, - like DEL etc ourselves, yet. We might want handle keystrokes - in the future, to implement tab completion, and better - (multiline) history. - - Disable VT escapes for the output.We do not know what kind of escapes SELECT would return. -*/ -struct Console_mode -{ - HANDLE in= GetStdHandle(STD_INPUT_HANDLE); - HANDLE out= GetStdHandle(STD_OUTPUT_HANDLE); - DWORD mode_in=0; - DWORD mode_out=0; - - enum {STDIN_CHANGED = 1, STDOUT_CHANGED = 2}; - int changes=0; - - Console_mode() - { - if (in && in != INVALID_HANDLE_VALUE && GetConsoleMode(in, &mode_in)) - { - SetConsoleMode(in, ENABLE_ECHO_INPUT|ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT); - changes |= STDIN_CHANGED; - } - - if (out && out != INVALID_HANDLE_VALUE && GetConsoleMode(out, &mode_out)) - { -#ifdef ENABLE_VIRTUAL_TERMINAL_INPUT - SetConsoleMode(out, mode_out & ~ENABLE_VIRTUAL_TERMINAL_INPUT); - changes |= STDOUT_CHANGED; -#endif - } - } - - ~Console_mode() - { - if (changes & STDIN_CHANGED) - SetConsoleMode(in, mode_in); - - if(changes & STDOUT_CHANGED) - SetConsoleMode(out, mode_out); - } -}; - -static Console_mode my_conmode; - -#define MAX_CGETS_LINE_LEN 65535 -/** Read line from console in ANSI codepage, chomp EOL*/ -static char *win_readline() -{ - static wchar_t wstrbuf[MAX_CGETS_LINE_LEN]; - static char strbuf[MAX_CGETS_LINE_LEN*2]; - - DWORD nchars= 0; - SetLastError(0); - if (!ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), wstrbuf, MAX_CGETS_LINE_LEN-1, - &nchars, NULL)) - goto err; - if (nchars == 0 && GetLastError() == ERROR_OPERATION_ABORTED) - goto err; - - while (nchars > 0) - { - if (wstrbuf[nchars - 1] != '\n' && wstrbuf[nchars - 1] != '\r') - break; - wstrbuf[--nchars]= 0; - } - - wstrbuf[nchars]= 0; - if (nchars > 0) - { - int len = WideCharToMultiByte(GetConsoleCP(), 0, wstrbuf, nchars + 1, - strbuf, sizeof(strbuf),NULL, NULL); - if (len < 1) - strbuf[0]= 0; - } - else - { - strbuf[0]= 0; - } - return strbuf; -err: - return NULL; -} -#endif - - #ifdef HAVE_VIDATTR static int have_curses= 0; static void my_vidattr(chtype attrs) @@ -1812,10 +1719,8 @@ static void usage(int version) my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE, readline, rl_library_version); #else - printf("%s Ver %s Distrib %s, for %s (%s), source revision %s" - IF_WIN(", codepage %u",) "\n", my_progname, VER, - MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,SOURCE_REVISION, - IF_WIN(GetConsoleCP(),)); + printf("%s Ver %s Distrib %s, for %s (%s), source revision %s\n", my_progname, VER, + MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,SOURCE_REVISION); #endif if (version) @@ -2210,7 +2115,26 @@ static int read_and_execute(bool interactive) #if defined(_WIN32) tee_fputs(prompt, stdout); - line= win_readline(); + if (!tmpbuf.is_alloced()) + tmpbuf.alloc(65535); + tmpbuf.length(0); + buffer.length(0); + size_t clen; + do + { + line= my_cgets((char*)tmpbuf.ptr(), tmpbuf.alloced_length()-1, &clen); + buffer.append(line, clen); + /* + if we got buffer fully filled than there is a chance that + something else is still in console input buffer + */ + } while (tmpbuf.alloced_length() <= clen); + /* + An empty line is returned from my_cgets when there's error reading : + Ctrl-c for example + */ + if (line) + line= buffer.c_ptr(); #else if (opt_outfile) fputs(prompt, OUTFILE); diff --git a/cmake/os/Windows.cmake b/cmake/os/Windows.cmake index da75c73d585..d9a0dfba46a 100644 --- a/cmake/os/Windows.cmake +++ b/cmake/os/Windows.cmake @@ -60,8 +60,8 @@ ENDIF() ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE) ADD_DEFINITIONS(-D_WIN32_WINNT=0x0A00) -# We do not want the windows.h , or winsvc.h macros min/max -ADD_DEFINITIONS(-DNOMINMAX -DNOSERVICE) +# We do not want the windows.h macros min/max +ADD_DEFINITIONS(-DNOMINMAX) # Speed up build process excluding unused header files ADD_DEFINITIONS(-DWIN32_LEAN_AND_MEAN) diff --git a/cmake/win_compatibility.manifest b/cmake/win_compatibility.manifest index 0e7ce667d68..2e4b27a6dc4 100644 --- a/cmake/win_compatibility.manifest +++ b/cmake/win_compatibility.manifest @@ -19,9 +19,4 @@ </application> </compatibility> - <application> - <windowsSettings> - <activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage> - </windowsSettings> - </application> </asmv1:assembly> diff --git a/include/my_global.h b/include/my_global.h index ed213e69f85..224909116dd 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -29,14 +29,6 @@ #pragma GCC poison __WIN__ #endif -#if defined(_MSC_VER) -/* - Following functions have bugs, when used with UTF-8 active codepage. - #include <winservice.h> will use the non-buggy wrappers -*/ -#pragma deprecated("CreateServiceA", "OpenServiceA", "ChangeServiceConfigA") -#endif - /* InnoDB depends on some MySQL internals which other plugins should not need. This is because of InnoDB's foreign key support, "safe" binlog diff --git a/mysql-test/main/charset_client_win.test b/mysql-test/main/charset_client_win.test index dd0162ca23a..b4a21d4f0a4 100644 --- a/mysql-test/main/charset_client_win.test +++ b/mysql-test/main/charset_client_win.test @@ -1,2 +1,2 @@ --source include/windows.inc ---exec set MARIADB_DISABLE_UTF8_CONSOLE=1 && chcp 1257 > NUL && $MYSQL --default-character-set=auto -e "select @@character_set_client" +--exec chcp 1257 > NUL && $MYSQL --default-character-set=auto -e "select @@character_set_client" diff --git a/mysql-test/main/charset_client_win_utf8mb4.result b/mysql-test/main/charset_client_win_utf8mb4.result deleted file mode 100644 index f7b5d376f9a..00000000000 --- a/mysql-test/main/charset_client_win_utf8mb4.result +++ /dev/null @@ -1,2 +0,0 @@ -@@character_set_client -utf8mb4 diff --git a/mysql-test/main/charset_client_win_utf8mb4.test b/mysql-test/main/charset_client_win_utf8mb4.test deleted file mode 100644 index 3a4b486632d..00000000000 --- a/mysql-test/main/charset_client_win_utf8mb4.test +++ /dev/null @@ -1,2 +0,0 @@ ---source include/windows.inc ---exec $MYSQL --default-character-set=auto -e "select @@character_set_client" diff --git a/mysql-test/main/grant_utf8_cli.result b/mysql-test/main/grant_not_windows.result index fedfaf984b2..fedfaf984b2 100644 --- a/mysql-test/main/grant_utf8_cli.result +++ b/mysql-test/main/grant_not_windows.result diff --git a/mysql-test/main/grant_utf8_cli.test b/mysql-test/main/grant_not_windows.test index 97d9fdbff40..55b09232edc 100644 --- a/mysql-test/main/grant_utf8_cli.test +++ b/mysql-test/main/grant_not_windows.test @@ -1,3 +1,5 @@ + # UTF8 parameters to mysql client do not work on Windows +--source include/not_windows.inc --source include/not_embedded.inc # diff --git a/mysql-test/suite.pm b/mysql-test/suite.pm index 8dc76283fc6..4cc6b410fa1 100644 --- a/mysql-test/suite.pm +++ b/mysql-test/suite.pm @@ -87,23 +87,6 @@ sub skip_combinations { $skip{'main/ssl_verify_ip.test'} = 'x509v3 support required' unless $openssl_ver ge "1.0.2"; - sub utf8_command_line_ok() { - if (IS_WINDOWS) { - # Can use UTF8 on command line since Windows 10 1903 (10.0.18362) - my($os_name, $os_major, $os_minor, $os_build, $os_id) = Win32::GetOSVersion(); - if($os_major lt 10){ - return 0; - } elsif($os_major gt 10 or $os_minor gt 0 or $os_build ge 18362) { - return 1; - } - return 0; - } - return 1; - } - - $skip{'main/charset_client_win_utf8mb4.test'} = - $skip{'main/grant_utf8_cli.test'} = 'No utf8 command line support' - unless utf8_command_line_ok(); %skip; } diff --git a/mysys/charset.c b/mysys/charset.c index 5d4bc0e10c4..19cad76fdf4 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -1393,7 +1393,7 @@ static const MY_CSET_OS_NAME charsets[] = #ifdef UNCOMMENT_THIS_WHEN_WL_WL_4024_IS_DONE {"cp54936", "gb18030", my_cs_exact}, #endif - {"cp65001", "utf8mb4", my_cs_exact}, + {"cp65001", "utf8", my_cs_exact}, #else /* not Windows */ diff --git a/mysys/get_password.c b/mysys/get_password.c index a30a65c8590..24befa6b5df 100644 --- a/mysys/get_password.c +++ b/mysys/get_password.c @@ -62,40 +62,34 @@ char *get_tty_password(const char *opt_message) { - wchar_t wbuf[80]; - char to[80*3]; /* there is at most 3 bytes per wchar, in any codepage */ - wchar_t *pos=wbuf,*end=wbuf + array_elements(wbuf)-1; + char to[80]; + char *pos=to,*end=to+sizeof(to)-1; DBUG_ENTER("get_tty_password"); _cputs(opt_message ? opt_message : "Enter password: "); for (;;) { - int wc; - wc=_getwch(); - if (wc == '\b' || wc == 127) + char tmp; + tmp=_getch(); + if (tmp == '\b' || (int) tmp == 127) { - if (pos != wbuf) + if (pos != to) { - _cputs("\b \b"); - pos--; - continue; + _cputs("\b \b"); + pos--; + continue; } } - if (wc == '\n' || wc == '\r' || wc == 3 || pos == end) + if (tmp == '\n' || tmp == '\r' || tmp == 3) break; - if (iswcntrl(wc)) + if (iscntrl(tmp) || pos == end) continue; - - /* Do not print '*' for half-unicode char(high surrogate)*/ - if (wc < 0xD800 || wc > 0xDBFF) - { - _cputs("*"); - } - *(pos++)= (wchar_t)wc; + _cputs("*"); + *(pos++) = tmp; } + while (pos != to && isspace(pos[-1]) == ' ') + pos--; /* Allow dummy space at end */ *pos=0; _cputs("\n"); - if (!WideCharToMultiByte(GetConsoleCP(), 0 , wbuf , -1 , to, sizeof(to), NULL, NULL)) - to[0]=0; DBUG_RETURN(my_strdup(PSI_INSTRUMENT_ME, to,MYF(MY_FAE))); } diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 96f147c26c3..3fe025ba808 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -38,7 +38,7 @@ static double getopt_double(char *arg, const struct my_option *optp, int *err); static void init_variables(const struct my_option *, init_func_p); static void init_one_value(const struct my_option *, void *, longlong); static void fini_one_value(const struct my_option *, void *, longlong); -static int setval(const struct my_option *, void *, char *, my_bool, const char *); +static int setval(const struct my_option *, void *, char *, my_bool); static char *check_struct_option(char *cur_arg, char *key_name); /* @@ -133,48 +133,6 @@ double getopt_ulonglong2double(ulonglong v) return u.dbl; } -#ifdef _WIN32 -/** - - On Windows, if program is running in UTF8 mode, but some arguments are not UTF8. - - This will mostly likely be a sign of old "ANSI" my.ini, and it is likely that - something will go wrong, e.g file access error. -*/ -static void validate_value(const char *key, const char *value, - const char *filename) -{ - MY_STRCOPY_STATUS status; - const struct charset_info_st *cs= &my_charset_utf8mb4_bin; - size_t len; - if (GetACP() != CP_UTF8) - return; - len= strlen(value); - if (!len) - return; - cs->cset->well_formed_char_length(cs, value, value + len, len, &status); - if (!status.m_well_formed_error_pos) - return; - - if (filename && *filename) - { - my_getopt_error_reporter(WARNING_LEVEL, - "%s: invalid (non-UTF8) characters found for option '%s'" - " in file '%s'", - my_progname, key, filename); - } - else - { - DBUG_ASSERT(0); - my_getopt_error_reporter( - WARNING_LEVEL, "%s: invalid (non-UTF8) characters for option %s", - my_progname, key); - } -} -#else -#define validate_value(key, value, filename) (void)filename -#endif - /** Handle command line options. Sort options. @@ -606,7 +564,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, } } if ((error= setval(optp, optp->value, argument, - set_maximum_value,filename))) + set_maximum_value))) DBUG_RETURN(error); if (get_one_option(optp, argument, filename)) DBUG_RETURN(EXIT_UNSPECIFIED_ERROR); @@ -652,7 +610,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts, continue; } if ((!option_is_autoset) && - ((error= setval(optp, value, argument, set_maximum_value,filename))) && + ((error= setval(optp, value, argument, set_maximum_value))) && !option_is_loose) DBUG_RETURN(error); if (get_one_option(optp, argument, filename)) @@ -753,7 +711,7 @@ static my_bool get_bool_argument(const struct my_option *opts, */ static int setval(const struct my_option *opts, void *value, char *argument, - my_bool set_maximum_value, const char *option_file) + my_bool set_maximum_value) { int err= 0, res= 0; DBUG_ENTER("setval"); @@ -900,7 +858,6 @@ static int setval(const struct my_option *opts, void *value, char *argument, goto ret; }; } - validate_value(opts->name, argument, option_file); DBUG_RETURN(0); ret: diff --git a/mysys/my_init.c b/mysys/my_init.c index b52f593af1e..d201d45a4ee 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -67,38 +67,6 @@ static ulong atoi_octal(const char *str) MYSQL_FILE *mysql_stdin= NULL; static MYSQL_FILE instrumented_stdin; -#ifdef _WIN32 -UINT orig_console_cp, orig_console_output_cp; - -static void reset_console_cp(void) -{ - SetConsoleCP(orig_console_cp); - SetConsoleOutputCP(orig_console_output_cp); -} - -/* - The below fixes discrepancies in console output and - command line parameter encoding. command line is in - ANSI codepage, output to console by default is in OEM, but - we like them to be in the same encoding. - - We do this only if current codepage is UTF8, i.e when we - know we're on Windows that can handle UTF8 well. - */ -static void set_console_cp() -{ - UINT acp= GetACP(); - if (acp == CP_UTF8 && !getenv("MARIADB_DISABLE_UTF8_CONSOLE")) - { - orig_console_cp= GetConsoleCP(); - SetConsoleCP(acp); - orig_console_output_cp= GetConsoleOutputCP(); - SetConsoleOutputCP(acp); - atexit(reset_console_cp); - } -} -#endif - /** Initialize my_sys functions, resources and variables @@ -163,7 +131,6 @@ my_bool my_init(void) #ifdef _WIN32 if (win32_init_tcp_ip()) DBUG_RETURN(1); - set_console_cp(); #endif #ifdef CHECK_UNLIKELY init_my_likely(); diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 848495190b2..972cc0b736c 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -481,11 +481,10 @@ IF(WIN32) MYSQL_ADD_EXECUTABLE(mariadb-install-db mysql_install_db.cc ${CMAKE_CURRENT_BINARY_DIR}/mysql_bootstrap_sql.c - password.c COMPONENT Server ) SET_TARGET_PROPERTIES(mariadb-install-db PROPERTIES COMPILE_FLAGS -DINSTALL_PLUGINDIR=${INSTALL_PLUGINDIR}) - TARGET_LINK_LIBRARIES(mariadb-install-db mysys mysys_ssl shlwapi) + TARGET_LINK_LIBRARIES(mariadb-install-db mysys shlwapi) ADD_LIBRARY(winservice STATIC winservice.c) TARGET_LINK_LIBRARIES(winservice shell32) diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc index 925ff328564..f712e29b843 100644 --- a/sql/mysql_install_db.cc +++ b/sql/mysql_install_db.cc @@ -21,7 +21,6 @@ #include "mariadb.h" #include <my_getopt.h> #include <m_string.h> -#include <password.h> #include <windows.h> #include <shellapi.h> @@ -31,7 +30,6 @@ #include <sddl.h> struct IUnknown; #include <shlwapi.h> -#include <winservice.h> #include <string> @@ -444,14 +442,16 @@ static int create_myini() } -static constexpr const char* update_root_passwd= +static const char update_root_passwd_part1[]= "UPDATE mysql.global_priv SET priv=json_set(priv," "'$.password_last_changed', UNIX_TIMESTAMP()," "'$.plugin','mysql_native_password'," - "'$.authentication_string','%s') where User='root';\n"; -static constexpr char remove_default_user_cmd[]= + "'$.authentication_string',PASSWORD("; +static const char update_root_passwd_part2[]= + ")) where User='root';\n"; +static const char remove_default_user_cmd[]= "DELETE FROM mysql.user where User='';\n"; -static constexpr char allow_remote_root_access_cmd[]= +static const char allow_remote_root_access_cmd[]= "CREATE TEMPORARY TABLE tmp_user LIKE global_priv;\n" "INSERT INTO tmp_user SELECT * from global_priv where user='root' " " AND host='localhost';\n" @@ -870,10 +870,18 @@ static int create_db_instance(const char *datadir) /* Change root password if requested. */ if (opt_password && opt_password[0]) { - verbose("Setting root password"); - char buf[2 * MY_SHA1_HASH_SIZE + 2]; - my_make_scrambled_password(buf, opt_password, strlen(opt_password)); - fprintf(in, update_root_passwd, buf); + verbose("Setting root password",remove_default_user_cmd); + fputs(update_root_passwd_part1, in); + + /* Use hex encoding for password, to avoid escaping problems.*/ + fputc('0', in); + fputc('x', in); + for(int i= 0; opt_password[i]; i++) + { + fprintf(in,"%02x",opt_password[i]); + } + + fputs(update_root_passwd_part2, in); fflush(in); } diff --git a/sql/mysql_upgrade_service.cc b/sql/mysql_upgrade_service.cc index 3850816010d..61f9f2542e9 100644 --- a/sql/mysql_upgrade_service.cc +++ b/sql/mysql_upgrade_service.cc @@ -366,6 +366,7 @@ static void get_service_config() */ static void change_service_config() { + char defaults_file[MAX_PATH]; char default_character_set[64]; char buf[MAX_PATH]; char commandline[3 * MAX_PATH + 19]; @@ -375,17 +376,13 @@ static void change_service_config() Write datadir to my.ini, after converting backslashes to unix style slashes. */ - if (service_properties.datadir[0]) + strcpy_s(buf, MAX_PATH, service_properties.datadir); + for(i= 0; buf[i]; i++) { - strcpy_s(buf, MAX_PATH, service_properties.datadir); - for (i= 0; buf[i]; i++) - { - if (buf[i] == '\\') - buf[i]= '/'; - } - WritePrivateProfileString("mysqld", "datadir", buf, - service_properties.inifile); + if (buf[i] == '\\') + buf[i]= '/'; } + WritePrivateProfileString("mysqld", "datadir",buf, service_properties.inifile); /* Remove basedir from defaults file, otherwise the service wont come up in @@ -400,19 +397,19 @@ static void change_service_config() */ default_character_set[0]= 0; GetPrivateProfileString("mysqld", "default-character-set", NULL, - default_character_set, sizeof(default_character_set), service_properties.inifile); + default_character_set, sizeof(default_character_set), defaults_file); if (default_character_set[0]) { WritePrivateProfileString("mysqld", "default-character-set", NULL, - service_properties.inifile); + defaults_file); WritePrivateProfileString("mysqld", "character-set-server", - default_character_set, service_properties.inifile); + default_character_set, defaults_file); } sprintf(defaults_file_param,"--defaults-file=%s", service_properties.inifile); sprintf_s(commandline, "\"%s\" \"%s\" \"%s\"", mysqld_path, defaults_file_param, opt_service); - if (!my_ChangeServiceConfig(service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, + if (!ChangeServiceConfig(service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, commandline, NULL, NULL, NULL, NULL, NULL, NULL)) { die("ChangeServiceConfig failed with %u", GetLastError()); @@ -486,8 +483,13 @@ int main(int argc, char **argv) } } - old_mysqld_exe_exists= (GetFileAttributes(service_properties.mysqld_exe) != - INVALID_FILE_ATTRIBUTES); + old_mysqld_exe_exists = (GetFileAttributes(service_properties.mysqld_exe) != INVALID_FILE_ATTRIBUTES); + log("Phase %d/%d: Fixing server config file%s", ++phase, max_phases, my_ini_exists ? "" : "(skipped)"); + + snprintf(my_ini_bck, sizeof(my_ini_bck), "%s.BCK", service_properties.inifile); + CopyFile(service_properties.inifile, my_ini_bck, FALSE); + upgrade_config_file(service_properties.inifile); + bool do_start_stop_server = old_mysqld_exe_exists && initial_service_state != SERVICE_RUNNING; log("Phase %d/%d: Start and stop server in the old version, to avoid crash recovery %s", ++phase, max_phases, @@ -542,14 +544,6 @@ int main(int argc, char **argv) start_duration_ms += 500; } } - - log("Phase %d/%d: Fixing server config file%s", ++phase, max_phases, - my_ini_exists ? "" : "(skipped)"); - snprintf(my_ini_bck, sizeof(my_ini_bck), "%s.BCK", - service_properties.inifile); - CopyFile(service_properties.inifile, my_ini_bck, FALSE); - upgrade_config_file(service_properties.inifile); - /* Start mysqld.exe as non-service skipping privileges (so we do not care about the password). But disable networking and enable pipe diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c946f7fba55..93a548b476e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -127,7 +127,6 @@ #ifdef _WIN32 #include <handle_connections_win.h> #include <sddl.h> -#include <winservice.h> /* SERVICE_STOPPED, SERVICE_RUNNING etc */ #endif #include <my_service_manager.h> diff --git a/sql/upgrade_conf_file.cc b/sql/upgrade_conf_file.cc index c255026fd9c..543df7b9bdf 100644 --- a/sql/upgrade_conf_file.cc +++ b/sql/upgrade_conf_file.cc @@ -158,196 +158,51 @@ static int cmp_strings(const void* a, const void *b) return strcmp((const char *)a, *(const char **)b); } -static bool is_utf8_str(const char *s) +/** + Convert file from a previous version, by removing +*/ +int upgrade_config_file(const char *myini_path) { - const unsigned char *bytes= (const unsigned char *) s; - int num; - - while (*bytes) +#define MY_INI_SECTION_SIZE 32*1024 +3 + static char section_data[MY_INI_SECTION_SIZE]; + for (const char *section_name : { "mysqld","server","mariadb" }) { - if ((*bytes & 0x80) == 0x00) - num= 1; - else if ((*bytes & 0xE0) == 0xC0) - num= 2; - else if ((*bytes & 0xF0) == 0xE0) - num= 3; - else if ((*bytes & 0xF8) == 0xF0) - num= 4; - else - return false; - - bytes++; - for (int i= 1; i < num; i++) + DWORD size = GetPrivateProfileSection(section_name, section_data, MY_INI_SECTION_SIZE, myini_path); + if (size == MY_INI_SECTION_SIZE - 2) { - if ((*bytes & 0xC0) != 0x80) - return false; - bytes++; + return -1; } - } - return true; -} - - -static UINT get_system_acp() -{ - static DWORD system_acp; - if (system_acp) - return system_acp; - - char str_cp[10]; - int cch= GetLocaleInfo(GetSystemDefaultLCID(), LOCALE_IDEFAULTANSICODEPAGE, - str_cp, sizeof(str_cp)); - - system_acp= cch > 0 ? atoi(str_cp) : 1252; - - return system_acp; -} - -#define MY_INI_SECTION_SIZE 32 * 1024 + 3 - -static char *ansi_to_utf8(const char *s) -{ -#define MAX_STR_LEN MY_INI_SECTION_SIZE - static wchar_t utf16_buf[MAX_STR_LEN]; - static char utf8_buf[MAX_STR_LEN]; - if (MultiByteToWideChar(get_system_acp(), 0, s, -1, utf16_buf, MAX_STR_LEN)) - { - if (WideCharToMultiByte(CP_UTF8, 0, utf16_buf, -1, utf8_buf, MAX_STR_LEN, - 0, 0)) - return utf8_buf; - } - return 0; -} - - -int fix_section(const char *myini_path, const char *section_name, - bool is_server) -{ - if (!is_server && GetACP() != CP_UTF8) - return 0; - - static char section_data[MY_INI_SECTION_SIZE]; - DWORD size= GetPrivateProfileSection(section_name, section_data, - MY_INI_SECTION_SIZE, myini_path); - if (size == MY_INI_SECTION_SIZE - 2) - { - return -1; - } - - for (char *keyval= section_data; *keyval; keyval += strlen(keyval)+1) - { - char varname[256]; - char *value; - - char *key_end= strchr(keyval, '='); - if (!key_end) - key_end= keyval + strlen(keyval); - - if (key_end - keyval > sizeof(varname)) - continue; - value= key_end + 1; - if (GetACP() == CP_UTF8 && !is_utf8_str(value)) + for (char *keyval = section_data; *keyval; keyval += strlen(keyval) + 1) { - char *new_val= ansi_to_utf8(value); - if (new_val) + char varname[256]; + char *key_end = strchr(keyval, '='); + if (!key_end) + key_end = keyval+ strlen(keyval); + + if (key_end - keyval > sizeof(varname)) + continue; + // copy and normalize (convert dash to underscore) to variable names + for (char *p = keyval, *q = varname;; p++,q++) { - *key_end= 0; - fprintf(stdout, "Fixing variable '%s' charset, value=%s\n", keyval, - new_val); - WritePrivateProfileString(section_name, keyval, new_val, myini_path); - *key_end= '='; + if (p == key_end) + { + *q = 0; + break; + } + *q = (*p == '-') ? '_' : *p; } - } - if (!is_server) - continue; + const char *v = (const char *)bsearch(varname, removed_variables, sizeof(removed_variables) / sizeof(removed_variables[0]), + sizeof(char *), cmp_strings); - // Check if variable should be removed from config. - // First, copy and normalize (convert dash to underscore) to variable - // names - for (char *p= keyval, *q= varname;; p++, q++) - { - if (p == key_end) + if (v) { - *q= 0; - break; + fprintf(stdout, "Removing variable '%s' from config file\n", varname); + // delete variable + *key_end = 0; + WritePrivateProfileString(section_name, keyval, 0, myini_path); } - *q= (*p == '-') ? '_' : *p; - } - const char *v= (const char *) bsearch(varname, removed_variables, sizeof(removed_variables) / sizeof(removed_variables[0]), - sizeof(char *), cmp_strings); - - if (v) - { - fprintf(stdout, "Removing variable '%s' from config file\n", varname); - // delete variable - *key_end= 0; - WritePrivateProfileString(section_name, keyval, 0, myini_path); } } return 0; } - -static bool is_mariadb_section(const char *name, bool *is_server) -{ - if (strncmp(name, "mysql", 5) - && strncmp(name, "mariadb", 7) - && strcmp(name, "client") - && strcmp(name, "client-server") - && strcmp(name, "server")) - { - return false; - } - - for (const char *section_name : {"mysqld", "server", "mariadb"}) - if (*is_server= !strcmp(section_name, name)) - break; - - return *is_server; -} - - -/** - Convert file from a previous version, by removing obsolete variables - Also, fix values to be UTF8, if MariaDB is running in utf8 mode -*/ -int upgrade_config_file(const char *myini_path) -{ - static char all_sections[MY_INI_SECTION_SIZE]; - int sz= GetPrivateProfileSectionNamesA(all_sections, MY_INI_SECTION_SIZE, - myini_path); - if (!sz) - return 0; - if (sz > MY_INI_SECTION_SIZE - 2) - { - fprintf(stderr, "Too many sections in config file\n"); - return -1; - } - for (char *section= all_sections; *section; section+= strlen(section) + 1) - { - bool is_server_section; - if (is_mariadb_section(section, &is_server_section)) - fix_section(myini_path, section, is_server_section); - } - return 0; -} - -#ifdef MAIN -int main(int argc, char **argv) -{ - if (argc != 2) - { - fprintf(stderr, "Usage : %s <config_file>\n", argv[0]); - return 1; - } - int rc= upgrade_config_file(argv[1]); - if (rc) - { - fprintf(stderr, "upgrade_config_file(\"%s\") returned an error\n", - argv[1]); - return 1; - } - return 0; -} -#endif - diff --git a/sql/winmain.cc b/sql/winmain.cc index bdad409065d..f999767cb27 100644 --- a/sql/winmain.cc +++ b/sql/winmain.cc @@ -55,7 +55,6 @@ #include <windows.h> #include <string> #include <cassert> -#include <winservice.h> static SERVICE_STATUS svc_status{SERVICE_WIN32_OWN_PROCESS}; static SERVICE_STATUS_HANDLE svc_status_handle; diff --git a/sql/winservice.c b/sql/winservice.c index 193d914957f..a11087e5cd5 100644 --- a/sql/winservice.c +++ b/sql/winservice.c @@ -134,20 +134,6 @@ static void get_datadir_from_ini(const char *ini, char *service_name, char *data } -static int fix_and_check_datadir(mysqld_service_properties *props) -{ - normalize_path(props->datadir, MAX_PATH); - /* Check if datadir really exists */ - if (GetFileAttributes(props->datadir) != INVALID_FILE_ATTRIBUTES) - return 0; - /* - It is possible, that datadir contains some unconvertable character. - We just pretend not to know what's the data directory - */ - props->datadir[0]= 0; - return 0; -} - /* Retrieve some properties from windows mysqld service binary path. We're interested in ini file location and datadir, and also in version of @@ -197,7 +183,7 @@ int get_mysql_service_properties(const wchar_t *bin_path, } /* Last parameter is the service name*/ - WideCharToMultiByte(CP_ACP, 0, args[numargs - 1], -1, service_name, MAX_PATH, NULL, NULL); + wcstombs(service_name, args[numargs-1], MAX_PATH); if(have_inifile && wcsncmp(args[1], L"--defaults-file=", 16) != 0) goto end; @@ -216,7 +202,7 @@ int get_mysql_service_properties(const wchar_t *bin_path, goto end; } - WideCharToMultiByte(CP_ACP, 0, mysqld_path, -1, props->mysqld_exe, MAX_PATH, NULL, NULL); + wcstombs(props->mysqld_exe, mysqld_path, MAX_PATH); /* If mysqld.exe exists, try to get its version from executable */ if (GetFileAttributes(props->mysqld_exe) != INVALID_FILE_ATTRIBUTES) { @@ -227,8 +213,7 @@ int get_mysql_service_properties(const wchar_t *bin_path, if (have_inifile) { /* We have --defaults-file in service definition. */ - WideCharToMultiByte(CP_ACP, 0, args[1] + 16, -1, props->inifile, - MAX_PATH, NULL, NULL); + wcstombs(props->inifile, args[1]+16, MAX_PATH); normalize_path(props->inifile, MAX_PATH); if (GetFileAttributes(props->inifile) != INVALID_FILE_ATTRIBUTES) { @@ -299,9 +284,16 @@ int get_mysql_service_properties(const wchar_t *bin_path, } } - if (props->datadir[0] == 0 || fix_and_check_datadir(props)) + if (props->datadir[0]) + { + normalize_path(props->datadir, MAX_PATH); + /* Check if datadir really exists */ + if (GetFileAttributes(props->datadir) == INVALID_FILE_ATTRIBUTES) + goto end; + } + else { - /* There is no datadir in ini file, or non-existing dir, bail out.*/ + /* There is no datadir in ini file, bail out.*/ goto end; } diff --git a/sql/winservice.h b/sql/winservice.h index 3ac746d44ba..f9ab3eda332 100644 --- a/sql/winservice.h +++ b/sql/winservice.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2011, 2021 Monty Program Ab + Copyright (c) 2011, 2012, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,9 +21,7 @@ extern "C" { #endif -#include <windows.h> -#pragma warning(suppress : 4995) -#include <winsvc.h> +#include <windows.h> typedef struct mysqld_service_properties_st { char mysqld_exe[MAX_PATH]; @@ -34,171 +32,9 @@ typedef struct mysqld_service_properties_st int version_patch; } mysqld_service_properties; -extern int get_mysql_service_properties(const wchar_t *bin_path, +extern int get_mysql_service_properties(const wchar_t *bin_path, mysqld_service_properties *props); - -#if !defined(UNICODE) -#include <malloc.h> -/* - The following wrappers workaround Windows bugs - with CreateService/OpenService with ANSI codepage UTF8. - - Apparently, these function in ANSI mode, for this codepage only - do *not* behave as expected (as-if string parameters were - converted to UTF16 and "wide" function were called) -*/ -static inline wchar_t* awstrdup(const char *str) -{ - if (!str) - return NULL; - size_t len= strlen(str) + 1; - wchar_t *wstr= (wchar_t *) malloc(sizeof(wchar_t)*len); - if (MultiByteToWideChar(CP_ACP, 0, str, (int)len, wstr, (int)len) == 0) - { - free(wstr); - return NULL; - } - return wstr; -} - -#define AWSTRDUP(dest, src) \ - dest= awstrdup(src); \ - if (src && !dest) \ - { \ - ok= FALSE; \ - last_error = ERROR_OUTOFMEMORY; \ - goto end; \ - } - -static inline SC_HANDLE my_OpenService(SC_HANDLE hSCManager, LPCSTR lpServiceName, DWORD dwDesiredAccess) -{ - wchar_t *w_ServiceName= NULL; - BOOL ok=TRUE; - DWORD last_error; - SC_HANDLE sch; - - AWSTRDUP(w_ServiceName, lpServiceName); - sch= OpenServiceW(hSCManager, w_servicename, dwDesiredAccess); - if (!sch) - { - ok= FALSE; - last_error= GetLastError(); - } - -end: - free(w_ServiceName); - if (!ret) - SetLastError(last_error); - return ret; -} - -static inline SC_HANDLE my_CreateService(SC_HANDLE hSCManager, - LPCSTR lpServiceName, LPCSTR lpDisplayName, - DWORD dwDesiredAccess, DWORD dwServiceType, - DWORD dwStartType, DWORD dwErrorControl, - LPCSTR lpBinaryPathName, LPCSTR lpLoadOrderGroup, - LPDWORD lpdwTagId, LPCSTR lpDependencies, - LPCSTR lpServiceStartName, LPCSTR lpPassword) -{ - wchar_t *w_ServiceName= NULL; - wchar_t *w_DisplayName= NULL; - wchar_t *w_BinaryPathName= NULL; - wchar_t *w_LoadOrderGroup= NULL; - wchar_t *w_Depedencies= NULL; - wchar_t *w_ServiceStartName= NULL; - wchar_t *w_Password= NULL; - SC_HANDLE sch; - DWORD last_error; - BOOL ok= TRUE; - - AWSTRDUP(w_ServiceName,lpServiceName); - AWSTRDUP(w_DisplayName,lpDisplayName); - AWSTRDUP(w_BinaryPathName, lpBinaryPathName); - AWSTRDUP(w_LoadOrderGroup, lpLoadOrderGroup); - AWSTRDUP(w_Dependencies, lpDependencies); - AWSTRDUP(w_ServiceStartName, lpServiceStartName); - AWSTRDUP(w_Password, lpPassword); - - sch= CreateServiceW( - hSCManager, w_ServiceName, w_DisplayName, dwDesiredAccess, dwServiceType, - dwStartType, dwErrorControl, w_BinaryPathName, w_LoadOrderGroup, - lpdwTagId, w_Depedencies, w_ServiceStartName, w_Password); - if(!sch) - { - ok= FALSE; - last_error= GetLastError(); - } - -end: - free(w_ServiceName); - free(w_DisplayName); - free(w_BinaryPathName); - free(w_LoadOrderGroup); - free(w_Depedencies); - free(w_ServiceStartName); - free(w_Password); - - if (!ok) - SetLastError(last_error); - return sch; -} - -static inline BOOL my_ChangeServiceConfig(SC_HANDLE hService, DWORD dwServiceType, - DWORD dwStartType, DWORD dwErrorControl, - LPCSTR lpBinaryPathName, LPCSTR lpLoadOrderGroup, - LPDWORD lpdwTagId, LPCSTR lpDependencies, - LPCSTR lpServiceStartName, LPCSTR lpPassword, - LPCSTR lpDisplayName) -{ - wchar_t *w_DisplayName= NULL; - wchar_t *w_BinaryPathName= NULL; - wchar_t *w_LoadOrderGroup= NULL; - wchar_t *w_Depedencies= NULL; - wchar_t *w_ServiceStartName= NULL; - wchar_t *w_Password= NULL; - SC_HANDLE sch; - DWORD last_error; - BOOL ok= TRUE; - - AWSTRDUP(w_DisplayName, lpDisplayName); - AWSTRDUP(w_BinaryPathName, lpBinaryPathName); - AWSTRDUP(w_LoadOrderGroup, lpLoadOrderGroup); - AWSTRDUP(w_Dependencies, lpDependencies); - AWSTRDUP(w_ServiceStartName, lpServiceStartName); - AWSTRDUP(w_Password, lpPassword); - - ok= ChangeServiceConfigW( - hService, dwServiceType, dwStartType, dwErrorControl, w_BinaryPathName, - w_LoadOrderGroup, lpdwTagId, w_Depedencies, w_ServiceStartName, - w_Password, w_DisplayName); - if (!ok) - { - last_error= GetLastError(); - } - -end: - free(w_DisplayName); - free(w_BinaryPathName); - free(w_LoadOrderGroup); - free(w_Depedencies); - free(w_ServiceStartName); - free(w_Password); - - if (last_error) - SetLastError(last_error); - return ret; -} -#undef AWSTRDUP - -#undef OpenService -#define OpenService my_OpenService -#undef ChangeServiceConfig -#define ChangeServiceConfig my_ChangeServiceConfig -#undef CreateService -#define CreateService my_CreateService -#endif - #ifdef __cplusplus } #endif diff --git a/win/packaging/extra.wxs.in b/win/packaging/extra.wxs.in index dd76cc816f5..11fe60719ec 100644 --- a/win/packaging/extra.wxs.in +++ b/win/packaging/extra.wxs.in @@ -461,7 +461,7 @@ Section="mysqld" Name="my.ini" Key="character-set-server" - Value="utf8mb4" /> + Value="utf8" /> </Component> <!-- Shortcuts in program menu (mysql client etc) --> diff --git a/win/upgrade_wizard/CMakeLists.txt b/win/upgrade_wizard/CMakeLists.txt index fd3560e1ee6..20a06a41215 100644 --- a/win/upgrade_wizard/CMakeLists.txt +++ b/win/upgrade_wizard/CMakeLists.txt @@ -5,7 +5,6 @@ ENDIF() # We need MFC # /permissive- flag does not play well with MFC, disable it. STRING(REPLACE "/permissive-" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") -REMOVE_DEFINITIONS(-DNOSERVICE) # fixes "already defined" warning in an AFX header FIND_PACKAGE(MFC) IF(NOT MFC_FOUND) diff --git a/win/upgrade_wizard/upgradeDlg.cpp b/win/upgrade_wizard/upgradeDlg.cpp index 0ed1e6a79d7..a1b6c279fa6 100644 --- a/win/upgrade_wizard/upgradeDlg.cpp +++ b/win/upgrade_wizard/upgradeDlg.cpp @@ -141,24 +141,24 @@ void CUpgradeDlg::PopulateServicesList() ErrorExit("OpenSCManager failed"); } - static BYTE buf[2*64*1024]; + static BYTE buf[64*1024]; static BYTE configBuffer[8*1024]; DWORD bufsize= sizeof(buf); DWORD bufneed; DWORD num_services; - BOOL ok= EnumServicesStatusExW(scm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, + BOOL ok= EnumServicesStatusEx(scm, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, buf, bufsize, &bufneed, &num_services, NULL, NULL); if(!ok) ErrorExit("EnumServicesStatusEx failed"); - LPENUM_SERVICE_STATUS_PROCESSW info = - (LPENUM_SERVICE_STATUS_PROCESSW)buf; + LPENUM_SERVICE_STATUS_PROCESS info = + (LPENUM_SERVICE_STATUS_PROCESS)buf; int index=-1; for (ULONG i=0; i < num_services; i++) { - SC_HANDLE service= OpenServiceW(scm, info[i].lpServiceName, + SC_HANDLE service= OpenService(scm, info[i].lpServiceName, SERVICE_QUERY_CONFIG); if (!service) continue; @@ -187,11 +187,7 @@ void CUpgradeDlg::PopulateServicesList() ServiceProperties props; props.myini= service_props.inifile; props.datadir= service_props.datadir; - char service_name_buf[1024]; - WideCharToMultiByte(CP_ACP, 0, info[i].lpServiceName, -1, - service_name_buf, sizeof(service_name_buf), - 0, 0); - props.servicename= service_name_buf; + props.servicename = info[i].lpServiceName; if (service_props.version_major) { char ver[64]; @@ -202,7 +198,7 @@ void CUpgradeDlg::PopulateServicesList() else props.version= "<unknown>"; - index = m_Services.AddString(service_name_buf); + index = m_Services.AddString(info[i].lpServiceName); services.resize(index+1); services[index] = props; } |