8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-27 20:03:03 +01:00
firebird-mirror/src/utilities/services.cpp
dimitr 5f61e44ddc Global names change:
FBOK=>FB_SUCCESS
FAILURE=>FB_FAILURE
xxx_FBOK=>xxx_SUCCESS
2002-11-14 08:33:08 +00:00

326 lines
7.8 KiB
C++

/*
* PROGRAM: Windows NT service control panel installation program
* MODULE: services.c
* DESCRIPTION: Functions which update the Windows service manager for IB
*
* The contents of this file are subject to the Interbase Public
* License Version 1.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy
* of the License at http://www.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
* 01-Feb-2002 Paul Reeves: Removed hard-coded registry path
*
*/
#include "firebird.h"
#include "../jrd/ib_stdio.h"
#include <windows.h>
#include "../jrd/common.h"
#include "../jrd/license.h"
#include "../utilities/install_nt.h"
#include "../utilities/servi_proto.h"
#include "../utilities/registry.h"
/* Defines */
#define RUNAS_SERVICE " -s"
USHORT SERVICES_config(SC_HANDLE manager,
TEXT * service_name,
TEXT * display_name,
USHORT sw_mode,
USHORT(*err_handler)(SLONG, TEXT *, SC_HANDLE))
{
/**************************************
*
* S E R V I C E S _ c o n f i g
*
**************************************
*
* Functional description
* Configure an installed service.
*
**************************************/
HKEY hkey;
SLONG status;
TEXT *mode;
if ((status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REG_KEY_ROOT_CUR_VER,
0, KEY_WRITE, &hkey)) != ERROR_SUCCESS) {
return (*err_handler) (status, "RegOpenKeyEx", NULL);
}
switch (sw_mode) {
case DEFAULT_CLIENT:
mode = "";
break;
case NORMAL_PRIORITY:
mode = "-r";
break;
case HIGH_PRIORITY:
mode = "-b";
break;
}
if ((status = RegSetValueEx(hkey, "DefaultClientMode", 0,
REG_SZ, reinterpret_cast<UCHAR*>(mode),
(DWORD) (strlen(mode) + 1))) !=
ERROR_SUCCESS) {
RegCloseKey(hkey);
return (*err_handler) (status, "RegSetValueEx", NULL);
}
RegCloseKey(hkey);
return FB_SUCCESS;
}
USHORT SERVICES_delete(SC_HANDLE manager,
TEXT * service_name,
TEXT * display_name,
USHORT(*err_handler)(SLONG, TEXT *, SC_HANDLE))
{
/**************************************
*
* S E R V I C E S _ d e l e t e
*
**************************************
*
* Functional description
* delete installed service param from registry.
*
**************************************/
HKEY hkey;
SLONG status;
TEXT *mode;
mode = "";
if ((status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REG_KEY_ROOT_CUR_VER,
0, KEY_WRITE, &hkey)) != ERROR_SUCCESS) {
return (*err_handler) (status, "RegOpenKeyEx", NULL);
}
if ((status = RegSetValueEx(hkey, "DefaultClientMode", 0,
REG_SZ, reinterpret_cast<UCHAR*>(mode),
(DWORD) (strlen(mode) + 1))) !=
ERROR_SUCCESS) {
RegCloseKey(hkey);
return (*err_handler) (status, "RegSetValueEx", NULL);
}
RegCloseKey(hkey);
return FB_SUCCESS;
}
USHORT SERVICES_install(SC_HANDLE manager,
TEXT * service_name,
TEXT * display_name,
TEXT * executable,
TEXT * directory,
TEXT * dependencies,
USHORT sw_startup,
USHORT(*err_handler)(SLONG, TEXT *, SC_HANDLE))
{
/**************************************
*
* S E R V I C E S _ i n s t a l l
*
**************************************
*
* Functional description
* Install a service in the service control panel.
*
**************************************/
SC_HANDLE service;
TEXT path_name[260];
USHORT len;
DWORD errnum;
strcpy(path_name, directory);
len = strlen(path_name);
if (len && path_name[len - 1] != '/' && path_name[len - 1] != '\\') {
path_name[len++] = '\\';
path_name[len] = 0;
}
strcpy(path_name + len, executable);
strcat(path_name, RUNAS_SERVICE);
service = CreateService(manager,
service_name,
display_name,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS |
SERVICE_INTERACTIVE_PROCESS,
(sw_startup ==
STARTUP_DEMAND) ? SERVICE_DEMAND_START :
SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
path_name, NULL, NULL, dependencies, NULL, NULL);
if (service == NULL) {
errnum = GetLastError();
if (errnum == ERROR_DUP_NAME || errnum == ERROR_SERVICE_EXISTS)
return IB_SERVICE_ALREADY_DEFINED;
else
return (*err_handler) (errnum, "CreateService", NULL);
}
CloseServiceHandle(service);
return FB_SUCCESS;
}
USHORT SERVICES_remove(SC_HANDLE manager,
TEXT * service_name,
TEXT * display_name,
USHORT(*err_handler)(SLONG, TEXT *, SC_HANDLE))
{
/**************************************
*
* S E R V I C E S _ r e m o v e
*
**************************************
*
* Functional description
* Remove a service from the service control panel.
*
**************************************/
SC_HANDLE service;
SERVICE_STATUS service_status;
service = OpenService(manager, service_name, SERVICE_ALL_ACCESS);
if (service == NULL)
return (*err_handler) (GetLastError(), "OpenService", NULL);
if (!QueryServiceStatus(service, &service_status)) {
CloseServiceHandle(service);
return (*err_handler) (GetLastError(), "QueryServiceStatus", service);
}
if (service_status.dwCurrentState != SERVICE_STOPPED) {
CloseServiceHandle(service);
return IB_SERVICE_RUNNING;
}
if (!DeleteService(service)) {
CloseServiceHandle(service);
return (*err_handler) (GetLastError(), "DeleteService", service);
}
CloseServiceHandle(service);
return FB_SUCCESS;
}
USHORT SERVICES_start(SC_HANDLE manager,
TEXT * service_name,
TEXT * display_name,
USHORT sw_mode,
USHORT(*err_handler)(SLONG, TEXT *, SC_HANDLE))
{
/**************************************
*
* S E R V I C E S _ s t a r t
*
**************************************
*
* Functional description
* Start an installed service.
*
**************************************/
SC_HANDLE service;
CONST TEXT *mode;
service = OpenService(manager, service_name, SERVICE_ALL_ACCESS);
if (service == NULL)
return (*err_handler) (GetLastError(), "OpenService", NULL);
switch (sw_mode) {
case DEFAULT_CLIENT:
mode = NULL;
break;
case NORMAL_PRIORITY:
mode = "-r";
break;
case HIGH_PRIORITY:
mode = "-b";
break;
}
if (!StartService(service, (mode) ? 1 : 0, &mode)) {
CloseServiceHandle(service);
return (*err_handler) (GetLastError(), "StartService", service);
}
CloseServiceHandle(service);
return FB_SUCCESS;
}
USHORT SERVICES_stop(SC_HANDLE manager,
TEXT * service_name,
TEXT * display_name,
USHORT(*err_handler)(SLONG, TEXT *, SC_HANDLE))
{
/**************************************
*
* S E R V I C E S _ s t o p
*
**************************************
*
* Functional description
* Start a running service.
*
**************************************/
SC_HANDLE service;
SERVICE_STATUS service_status;
DWORD errnum;
service = OpenService(manager, service_name, SERVICE_ALL_ACCESS);
if (service == NULL)
return (*err_handler) (GetLastError(), "OpenService", NULL);
if (!ControlService(service, SERVICE_CONTROL_STOP, &service_status)) {
CloseServiceHandle(service);
errnum = GetLastError();
if (errnum == ERROR_SERVICE_NOT_ACTIVE)
return FB_SUCCESS;
else
return (*err_handler) (errnum, "ControlService", service);
}
/* Wait for the service to actually stop before returning. */
do {
if (!QueryServiceStatus(service, &service_status)) {
CloseServiceHandle(service);
return (*err_handler) (GetLastError(), "QueryServiceStatus",
service);
}
}
while (service_status.dwCurrentState == SERVICE_STOP_PENDING);
CloseServiceHandle(service);
return FB_SUCCESS;
}