8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 22:43:04 +01:00

1. Use Firebird::string to avoid BOFs in NT services installation code

2. Move fake gds__log from install_svc into services to please control panel applet
3. Quote service .exe and instance names when it contains space
4. Configure installed services to restart after fail automatically
This commit is contained in:
hvlad 2007-09-30 14:03:40 +00:00
parent 1cc34ce68d
commit 8ba5a8cae0
4 changed files with 62 additions and 38 deletions

View File

@ -925,7 +925,7 @@ bool CFBDialog::ServiceInstall( CFBDialog::STATUS status )
guard_service, guard_display_name,
ISCGUARD_DISPLAY_DESCR, ISCGUARD_EXECUTABLE,
ServerPath, NULL, NULL, status.AutoStart,
NULL, NULL, false, svc_error);
NULL, NULL, false, true, svc_error);
if (m_Error_Status != FB_SUCCESS)
{
CloseServiceManager();
@ -941,7 +941,7 @@ bool CFBDialog::ServiceInstall( CFBDialog::STATUS status )
remote_service, remote_display_name,
REMOTE_DISPLAY_DESCR, (LPCTSTR) status.ServiceExecutable,
ServerPath, NULL, NULL, status.AutoStart,
NULL, NULL, false, svc_error);
NULL, NULL, false, !new_settings.UseGuardian, svc_error);
if (m_Error_Status != FB_SUCCESS)
{
CloseServiceManager();

View File

@ -277,7 +277,10 @@ int CLIB_ROUTINE main( int argc, char **argv)
remote_display_name.printf(REMOTE_DISPLAY_NAME, instance);
Firebird::string switches;
switches.printf("-s %s", instance);
if (strchr(instance, ' '))
switches.printf("-s \"%s\"", instance);
else
switches.printf("-s %s", instance);
switch (sw_command)
{
@ -288,7 +291,7 @@ int CLIB_ROUTINE main( int argc, char **argv)
status = SERVICES_install(manager, guard_service_name.c_str(),
guard_display_name.c_str(), ISCGUARD_DISPLAY_DESCR,
ISCGUARD_EXECUTABLE, directory, switches.c_str(), NULL,
sw_startup, username, password, false, svc_error);
sw_startup, username, password, false, true, svc_error);
status2 = FB_SUCCESS;
@ -313,7 +316,7 @@ int CLIB_ROUTINE main( int argc, char **argv)
status = SERVICES_install(manager, remote_service_name.c_str(),
remote_display_name.c_str(), REMOTE_DISPLAY_DESCR,
REMOTE_EXECUTABLE, directory, switches.c_str(), NULL,
sw_startup, username, password, sw_interactive, svc_error);
sw_startup, username, password, sw_interactive, !sw_guardian, svc_error);
status2 = FB_SUCCESS;
@ -712,17 +715,3 @@ static void usage_exit(void)
exit(FINI_ERROR);
}
//
// Until the fb_assert could be converted to a function/object linked with each module
// we need this ugly workaround.
//
extern "C" void API_ROUTINE gds__log(const TEXT* text, ...)
{
va_list ptr;
va_start(ptr, text);
vprintf(text, ptr);
va_end(ptr);
printf("\n\n");
}

View File

@ -31,7 +31,7 @@ typedef USHORT (*pfnSvcError)(SLONG, const TEXT*, SC_HANDLE);
USHORT SERVICES_install(SC_HANDLE, const char*, const char*, const char*,
const TEXT*, const TEXT*, const TEXT*, const TEXT*, USHORT, const TEXT*,
const TEXT*, bool, pfnSvcError);
const TEXT*, bool, bool, pfnSvcError);
USHORT SERVICES_remove(SC_HANDLE, const char*, const char*, pfnSvcError);

View File

@ -30,11 +30,13 @@
#include <ntsecapi.h>
#include <aclapi.h>
#include "../jrd/common.h"
//#include "../jrd/license.h"
#include "../../common/classes/fb_string.h"
#include "../../jrd/os/path_utils.h"
#include "../utilities/install/install_nt.h"
#include "../utilities/install/servi_proto.h"
#include "../utilities/install/registry.h"
USHORT SERVICES_install(SC_HANDLE manager,
const char* service_name,
const char* display_name,
@ -47,6 +49,7 @@ USHORT SERVICES_install(SC_HANDLE manager,
const char* nt_user_name,
const char* nt_user_password,
bool interactive_mode,
bool auto_restart,
pfnSvcError err_handler)
{
/**************************************
@ -59,23 +62,24 @@ USHORT SERVICES_install(SC_HANDLE manager,
* Install a service in the service control panel.
*
**************************************/
TEXT path_name[MAXPATHLEN];
Firebird::PathName exe_name(directory);
PathUtils::ensureSeparator(exe_name);
exe_name += executable;
exe_name += ".exe";
// No check made on directory length?
strcpy(path_name, directory);
USHORT len = strlen(path_name);
if (len && path_name[len - 1] != '/' && path_name[len - 1] != '\\')
{
path_name[len++] = '\\';
path_name[len] = 0;
Firebird::string path_name;
if (exe_name.find(' ') != Firebird::AbstractString::npos) {
path_name.printf("\"%s\"", exe_name.c_str());
}
else {
path_name = exe_name.c_str();
}
// Again, no check for a buffer overrun!!!
strcpy(path_name + len, executable);
strcat(path_name, ".exe");
if (switches) {
strcat(path_name, " ");
strcat(path_name, switches);
if (switches)
{
path_name += " ";
path_name += switches;
}
DWORD dwServiceType = SERVICE_WIN32_OWN_PROCESS;
@ -97,7 +101,7 @@ USHORT SERVICES_install(SC_HANDLE manager,
(sw_startup ==
STARTUP_DEMAND) ? SERVICE_DEMAND_START :
SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
path_name, NULL, NULL, dependencies,
path_name.c_str(), NULL, NULL, dependencies,
nt_user_name, nt_user_password);
if (service == NULL)
@ -109,8 +113,8 @@ USHORT SERVICES_install(SC_HANDLE manager,
return (*err_handler) (errnum, "CreateService", NULL);
}
// Now enter the description string into the service config, if this is
// available on the current platform.
// Now enter the description string and failure actions into the service
// config, if this is available on the current platform.
HMODULE advapi32 = LoadLibrary("ADVAPI32.DLL");
if (advapi32 != 0)
{
@ -123,6 +127,23 @@ USHORT SERVICES_install(SC_HANDLE manager,
// LPSTR descr = display_description;
//(*config2)(service, SERVICE_CONFIG_DESCRIPTION, &descr);
(*config2)(service, SERVICE_CONFIG_DESCRIPTION, &display_description);
if (auto_restart)
{
SERVICE_FAILURE_ACTIONS fa;
SC_ACTION acts;
memset(&fa, 0, sizeof(fa));
fa.dwResetPeriod = 0;
fa.cActions = 1;
fa.lpsaActions = &acts;
memset(&acts, 0, sizeof(acts));
acts.Delay = 0;
acts.Type = SC_ACTION_RESTART;
(*config2)(service, SERVICE_CONFIG_FAILURE_ACTIONS, &fa);
}
}
FreeLibrary(advapi32);
}
@ -532,6 +553,20 @@ USHORT SERVICES_grant_access_rights(const char* service_name, TEXT* account,
return FB_SUCCESS;
}
//
// Until the fb_assert could be converted to a function/object linked with each module
// we need this ugly workaround.
//
extern "C" void API_ROUTINE gds__log(const TEXT* text, ...)
{
va_list ptr;
va_start(ptr, text);
vprintf(text, ptr);
va_end(ptr);
printf("\n\n");
}
//
// EOF
//