mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
xxx
This commit is contained in:
parent
2dcb823631
commit
220dc1fd59
7 changed files with 283 additions and 79 deletions
|
@ -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);
|
||||
static int setval(const struct my_option *, void *, char *, my_bool, const char *);
|
||||
static char *check_struct_option(char *cur_arg, char *key_name);
|
||||
|
||||
/*
|
||||
|
@ -133,6 +133,48 @@ 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.
|
||||
|
@ -564,7 +606,7 @@ int handle_options(int *argc, char ***argv, const struct my_option *longopts,
|
|||
}
|
||||
}
|
||||
if ((error= setval(optp, optp->value, argument,
|
||||
set_maximum_value)))
|
||||
set_maximum_value,filename)))
|
||||
DBUG_RETURN(error);
|
||||
if (get_one_option(optp, argument, filename))
|
||||
DBUG_RETURN(EXIT_UNSPECIFIED_ERROR);
|
||||
|
@ -610,7 +652,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))) &&
|
||||
((error= setval(optp, value, argument, set_maximum_value,filename))) &&
|
||||
!option_is_loose)
|
||||
DBUG_RETURN(error);
|
||||
if (get_one_option(optp, argument, filename))
|
||||
|
@ -711,7 +753,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)
|
||||
my_bool set_maximum_value, const char *option_file)
|
||||
{
|
||||
int err= 0, res= 0;
|
||||
DBUG_ENTER("setval");
|
||||
|
@ -858,6 +900,7 @@ 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:
|
||||
|
|
|
@ -366,7 +366,6 @@ 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];
|
||||
|
@ -376,13 +375,17 @@ static void change_service_config()
|
|||
Write datadir to my.ini, after converting backslashes to
|
||||
unix style slashes.
|
||||
*/
|
||||
strcpy_s(buf, MAX_PATH, service_properties.datadir);
|
||||
for(i= 0; buf[i]; i++)
|
||||
if (service_properties.datadir[0])
|
||||
{
|
||||
if (buf[i] == '\\')
|
||||
buf[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);
|
||||
}
|
||||
WritePrivateProfileString("mysqld", "datadir",buf, service_properties.inifile);
|
||||
|
||||
/*
|
||||
Remove basedir from defaults file, otherwise the service wont come up in
|
||||
|
@ -397,19 +400,19 @@ static void change_service_config()
|
|||
*/
|
||||
default_character_set[0]= 0;
|
||||
GetPrivateProfileString("mysqld", "default-character-set", NULL,
|
||||
default_character_set, sizeof(default_character_set), defaults_file);
|
||||
default_character_set, sizeof(default_character_set), service_properties.inifile);
|
||||
if (default_character_set[0])
|
||||
{
|
||||
WritePrivateProfileString("mysqld", "default-character-set", NULL,
|
||||
defaults_file);
|
||||
service_properties.inifile);
|
||||
WritePrivateProfileString("mysqld", "character-set-server",
|
||||
default_character_set, defaults_file);
|
||||
default_character_set, service_properties.inifile);
|
||||
}
|
||||
|
||||
sprintf(defaults_file_param,"--defaults-file=%s", service_properties.inifile);
|
||||
sprintf_s(commandline, "\"%s\" \"%s\" \"%s\"", mysqld_path,
|
||||
defaults_file_param, opt_service);
|
||||
if (!ChangeServiceConfig(service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE,
|
||||
if (!my_ChangeServiceConfig(service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE,
|
||||
SERVICE_NO_CHANGE, commandline, NULL, NULL, NULL, NULL, NULL, NULL))
|
||||
{
|
||||
die("ChangeServiceConfig failed with %u", GetLastError());
|
||||
|
@ -483,13 +486,8 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
old_mysqld_exe_exists= (GetFileAttributes(service_properties.mysqld_exe) !=
|
||||
INVALID_FILE_ATTRIBUTES);
|
||||
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,
|
||||
|
@ -544,6 +542,14 @@ 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
|
||||
|
|
|
@ -127,6 +127,7 @@
|
|||
#ifdef _WIN32
|
||||
#include <handle_connections_win.h>
|
||||
#include <sddl.h>
|
||||
#include <winservice.h> /* SERVICE_STOPPED, SERVICE_RUNNING etc */
|
||||
#endif
|
||||
|
||||
#include <my_service_manager.h>
|
||||
|
|
|
@ -158,51 +158,196 @@ static int cmp_strings(const void* a, const void *b)
|
|||
return strcmp((const char *)a, *(const char **)b);
|
||||
}
|
||||
|
||||
/**
|
||||
Convert file from a previous version, by removing
|
||||
*/
|
||||
int upgrade_config_file(const char *myini_path)
|
||||
static bool is_utf8_str(const char *s)
|
||||
{
|
||||
#define MY_INI_SECTION_SIZE 32*1024 +3
|
||||
static char section_data[MY_INI_SECTION_SIZE];
|
||||
for (const char *section_name : { "mysqld","server","mariadb" })
|
||||
const unsigned char *bytes= (const unsigned char *) s;
|
||||
int num;
|
||||
|
||||
while (*bytes)
|
||||
{
|
||||
DWORD size = GetPrivateProfileSection(section_name, section_data, MY_INI_SECTION_SIZE, myini_path);
|
||||
if (size == MY_INI_SECTION_SIZE - 2)
|
||||
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++)
|
||||
{
|
||||
return -1;
|
||||
if ((*bytes & 0xC0) != 0x80)
|
||||
return false;
|
||||
bytes++;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
for (char *keyval = section_data; *keyval; keyval += strlen(keyval) + 1)
|
||||
|
||||
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))
|
||||
{
|
||||
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++)
|
||||
char *new_val= ansi_to_utf8(value);
|
||||
if (new_val)
|
||||
{
|
||||
if (p == key_end)
|
||||
{
|
||||
*q = 0;
|
||||
break;
|
||||
}
|
||||
*q = (*p == '-') ? '_' : *p;
|
||||
*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= '=';
|
||||
}
|
||||
const char *v = (const char *)bsearch(varname, removed_variables, sizeof(removed_variables) / sizeof(removed_variables[0]),
|
||||
sizeof(char *), cmp_strings);
|
||||
}
|
||||
if (!is_server)
|
||||
continue;
|
||||
|
||||
if (v)
|
||||
// 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)
|
||||
{
|
||||
fprintf(stdout, "Removing variable '%s' from config file\n", varname);
|
||||
// delete variable
|
||||
*key_end = 0;
|
||||
WritePrivateProfileString(section_name, keyval, 0, myini_path);
|
||||
*q= 0;
|
||||
break;
|
||||
}
|
||||
*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
|
||||
|
||||
|
|
|
@ -134,6 +134,20 @@ 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
|
||||
|
@ -183,7 +197,7 @@ int get_mysql_service_properties(const wchar_t *bin_path,
|
|||
}
|
||||
|
||||
/* Last parameter is the service name*/
|
||||
wcstombs(service_name, args[numargs-1], MAX_PATH);
|
||||
WideCharToMultiByte(CP_ACP, 0, args[numargs - 1], -1, service_name, MAX_PATH, NULL, NULL);
|
||||
|
||||
if(have_inifile && wcsncmp(args[1], L"--defaults-file=", 16) != 0)
|
||||
goto end;
|
||||
|
@ -202,7 +216,7 @@ int get_mysql_service_properties(const wchar_t *bin_path,
|
|||
goto end;
|
||||
}
|
||||
|
||||
wcstombs(props->mysqld_exe, mysqld_path, MAX_PATH);
|
||||
WideCharToMultiByte(CP_ACP, 0, mysqld_path, -1, props->mysqld_exe, MAX_PATH, NULL, NULL);
|
||||
/* If mysqld.exe exists, try to get its version from executable */
|
||||
if (GetFileAttributes(props->mysqld_exe) != INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
|
@ -213,7 +227,8 @@ int get_mysql_service_properties(const wchar_t *bin_path,
|
|||
if (have_inifile)
|
||||
{
|
||||
/* We have --defaults-file in service definition. */
|
||||
wcstombs(props->inifile, args[1]+16, MAX_PATH);
|
||||
WideCharToMultiByte(CP_ACP, 0, args[1] + 16, -1, props->inifile,
|
||||
MAX_PATH, NULL, NULL);
|
||||
normalize_path(props->inifile, MAX_PATH);
|
||||
if (GetFileAttributes(props->inifile) != INVALID_FILE_ATTRIBUTES)
|
||||
{
|
||||
|
@ -284,16 +299,9 @@ int get_mysql_service_properties(const wchar_t *bin_path,
|
|||
}
|
||||
}
|
||||
|
||||
if (props->datadir[0])
|
||||
if (props->datadir[0] == 0 || fix_and_check_datadir(props))
|
||||
{
|
||||
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, bail out.*/
|
||||
/* There is no datadir in ini file, or non-existing dir, bail out.*/
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2011, 2012, Monty Program Ab
|
||||
Copyright (c) 2011, 2021 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
|
||||
|
@ -37,6 +37,7 @@ typedef struct mysqld_service_properties_st
|
|||
extern int get_mysql_service_properties(const wchar_t *bin_path,
|
||||
mysqld_service_properties *props);
|
||||
|
||||
|
||||
#if !defined(UNICODE)
|
||||
#include <malloc.h>
|
||||
/*
|
||||
|
@ -92,15 +93,13 @@ end:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline SC_HANDLE my_CreateService(SC_HANDLE hSCManager, LPCSTR lpServiceName, LPCSTR lpDisplayName,
|
||||
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)
|
||||
LPCSTR lpBinaryPathName, LPCSTR lpLoadOrderGroup,
|
||||
LPDWORD lpdwTagId, LPCSTR lpDependencies,
|
||||
LPCSTR lpServiceStartName, LPCSTR lpPassword)
|
||||
{
|
||||
wchar_t *w_ServiceName= NULL;
|
||||
wchar_t *w_DisplayName= NULL;
|
||||
|
@ -146,11 +145,11 @@ end:
|
|||
}
|
||||
|
||||
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)
|
||||
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;
|
||||
|
@ -190,6 +189,7 @@ end:
|
|||
SetLastError(last_error);
|
||||
return ret;
|
||||
}
|
||||
#undef AWSTRDUP
|
||||
|
||||
#undef OpenService
|
||||
#define OpenService my_OpenService
|
||||
|
|
|
@ -5,6 +5,7 @@ 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)
|
||||
|
|
Loading…
Reference in a new issue