📄 main.c
字号:
// $Id: main.c,v 1.1.1.1 2002/09/24 11:12:16 dev Exp $
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include "tdi_fw_svc.h"
#define CONFIG_SUBKEY "SYSTEM\\CurrentControlSet\\Services\\tdi_fw_svc"
BOOL g_console = TRUE;
static SERVICE_STATUS ssStatus; // current status of the service
static SERVICE_STATUS_HANDLE sshStatusHandle;
static void AddEventSource(const char *ident);
static void install_service(const char *config);
static void remove_service(void);
static VOID WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv);
static VOID WINAPI service_ctrl(DWORD dwCtrlCode);
static BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);
static BOOL add_config_info(HANDLE schService, const char *config);
int
main(int argc, char **argv)
{
static SERVICE_TABLE_ENTRY dispatch_table[] = {
{"tdi_fw_svc", service_main},
{NULL, NULL}
};
_LEAK_CHECK;
if (argc >= 2) {
const char *param = argv[1];
if (strcmp(param, "install") == 0) {
if (argc < 3) {
fprintf(stderr, "Use: tdi_fw_svc install <config>\n");
return -1;
}
install_service(argv[2]);
} else if (strcmp(param, "remove") == 0)
remove_service();
else if (strcmp(param, "debug") == 0) {
if (argc < 3) {
fprintf(stderr, "Use: tdi_fw_svc debug <config>\n");
return -1;
}
if (start(argv[2])) {
printf("press any key to exit...\n");
getch();
printf("exiting...\n");
stop();
}
} else {
fprintf(stderr, "Use: tdi_fw_svc install|remove|debug\n");
}
} else {
g_console = FALSE;
// run as service
if (!StartServiceCtrlDispatcher(dispatch_table))
winerr("main: StartServiceCtrlDispatcher");
}
return 0;
}
void
install_service(const char *config)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
CHAR szPath[MAX_PATH];
AddEventSource("tdi_fw_svc");
if (GetModuleFileName(NULL, szPath, sizeof(szPath)) == 0) {
winerr("install_service: GetModuleFileName");
return;
}
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS); // access required
if (schSCManager != NULL) {
schService = CreateService(
schSCManager, // SCManager database
"tdi_fw_svc", // name of service
"tdi_fw_svc", // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szPath, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // dependencies
NULL, // LocalSystem account
NULL); // no password
if (schService != NULL) {
printf("tdi_fw_svc service has been installed\n");
if (!add_config_info(schService, config))
fprintf(stderr, "Can't store config info! Service will use defaults.\n");
CloseServiceHandle(schService);
} else
winerr("install_service: CreateService");
CloseServiceHandle(schSCManager);
}
else
winerr("install_service: OpenSCManager");
}
void
remove_service(void)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS); // access required
if (schSCManager != NULL) {
schService = OpenService(schSCManager, "tdi_fw_svc", SERVICE_ALL_ACCESS);
if (schService != NULL) {
// try to stop the service
if (ControlService(schService, SERVICE_CONTROL_STOP, &ssStatus)) {
printf("stopping...");
Sleep(1000);
while(QueryServiceStatus( schService, &ssStatus)) {
if (ssStatus.dwCurrentState == SERVICE_STOP_PENDING) {
printf(".");
Sleep( 1000 );
}
else
break;
}
printf("\n");
if (ssStatus.dwCurrentState == SERVICE_STOPPED)
printf("stopped\n");
else
printf("failed to stop\n");
}
// now remove the service
if (DeleteService(schService))
printf("service has been removed\n");
else
winerr("install_service: DeleteService");
CloseServiceHandle(schService);
}
else
winerr("install_service: OpenService");
CloseServiceHandle(schSCManager);
}
else
winerr("install_service: OpenSCManager");
}
VOID WINAPI
service_main(DWORD dwArgc, LPTSTR *lpszArgv)
{
HKEY hkey = NULL;
char *config = NULL;
DWORD type, config_size, status;
// register our service control handler:
//
sshStatusHandle = RegisterServiceCtrlHandler("tdi_fw_svc", service_ctrl);
if (sshStatusHandle == 0) {
winerr("install_service: RegisterServiceCtrlHandler");
goto cleanup;
}
// SERVICE_STATUS members that don't change in example
//
ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwServiceSpecificExitCode = 0;
// report the status to the service control manager.
//
if (!ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000)) // wait hint
goto cleanup;
/* get config name from registry */
if ((status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, CONFIG_SUBKEY, 0, KEY_QUERY_VALUE,
&hkey)) != ERROR_SUCCESS) {
SetLastError(status);
winerr("RegOpenKeyEx");
goto cleanup;
}
if ((status = RegQueryValueEx(hkey, "config", 0, &type, NULL, &config_size)) != ERROR_SUCCESS) {
SetLastError(status);
winerr("RegOpenKeyEx");
goto cleanup;
}
if (type != REG_SZ) {
error("Invalid type for config value in registry");
SetLastError(ERROR_INVALID_DATA);
goto cleanup;
}
config = (char *)malloc(config_size);
if (config == NULL) {
liberr("malloc");
goto cleanup;
}
if ((status = RegQueryValueEx(hkey, "config", 0, NULL, config, &config_size)) != ERROR_SUCCESS) {
SetLastError(status);
winerr("RegOpenKeyEx");
goto cleanup;
}
if (start(config)) {
// start success
// report the status to the service control manager.
//
if (!ReportStatusToSCMgr(
SERVICE_RUNNING, // service state
NO_ERROR, // exit code
0)) // wait hint
goto cleanup;
wait();
SetLastError(0);
}
cleanup:
// try to report the stopped status to the service control manager.
//
if (sshStatusHandle != 0)
ReportStatusToSCMgr(SERVICE_STOPPED, GetLastError(), 0);
if (hkey != NULL)
RegCloseKey(hkey);
free(config);
}
//
// FUNCTION: ReportStatusToSCMgr()
//
// PURPOSE: Sets the current status of the service and
// reports it to the Service Control Manager
//
// PARAMETERS:
// dwCurrentState - the state of the service
// dwWin32ExitCode - error code to report
// dwWaitHint - worst case estimate to next checkpoint
//
// RETURN VALUE:
// TRUE - success
// FALSE - failure
//
// COMMENTS:
//
BOOL
ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
if (dwCurrentState == SERVICE_START_PENDING)
ssStatus.dwControlsAccepted = 0;
else
ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
ssStatus.dwCurrentState = dwCurrentState;
ssStatus.dwWin32ExitCode = dwWin32ExitCode;
ssStatus.dwWaitHint = dwWaitHint;
if (dwCurrentState == SERVICE_RUNNING || dwCurrentState == SERVICE_STOPPED)
ssStatus.dwCheckPoint = 0;
else
ssStatus.dwCheckPoint = dwCheckPoint++;
// Report the status of the service to the service control manager.
//
if (!SetServiceStatus(sshStatusHandle, &ssStatus)) {
winerr("install_service: SetServiceStatus");
return FALSE;
}
return TRUE;
}
//
// FUNCTION: service_ctrl
//
// PURPOSE: This function is called by the SCM whenever
// ControlService() is called on this service.
//
// PARAMETERS:
// dwCtrlCode - type of control requested
//
// RETURN VALUE:
// none
//
// COMMENTS:
//
VOID WINAPI
service_ctrl(DWORD dwCtrlCode)
{
// Handle the requested control code.
//
switch(dwCtrlCode) {
// Stop the service.
//
// SERVICE_STOP_PENDING should be reported before
// setting the Stop Event - hServerStopEvent - in
// ServiceStop(). This avoids a race condition
// which may result in a 1053 - The Service did not respond...
// error.
case SERVICE_CONTROL_STOP:
ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
// stop it!
stop();
return;
// Update the service status.
//
case SERVICE_CONTROL_INTERROGATE:
break;
// invalid control code
//
default:
break;
}
ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
}
/* Taken from MSDN. */
void
AddEventSource(const char *ident)
{
HKEY hk;
DWORD dwData;
char szFilePath[_MAX_PATH];
char key[_MAX_PATH];
// Add your source name as a subkey under the Application
// key in the EventLog registry key.
_snprintf(key, sizeof(key), "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\%s", ident);
if (RegCreateKey(HKEY_LOCAL_MACHINE, key, &hk)) {
printf("Could not create the registry key.");
exit(-1);
}
// Set the name of the message file.
GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
// Add the name to the EventMessageFile subkey.
if (RegSetValueEx(hk, // subkey handle
"EventMessageFile", // value name
0, // must be zero
REG_EXPAND_SZ, // value type
(LPBYTE) szFilePath, // pointer to value data
strlen(szFilePath) + 1)) { // length of value data
printf("Could not set the event message file.");
exit(-1);
}
// Set the supported event types in the TypesSupported subkey.
dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
EVENTLOG_INFORMATION_TYPE | EVENTLOG_AUDIT_SUCCESS | EVENTLOG_AUDIT_FAILURE;
if (RegSetValueEx(hk, // subkey handle
"TypesSupported", // value name
0, // must be zero
REG_DWORD, // value type
(LPBYTE) &dwData, // pointer to value data
sizeof(DWORD))){ // length of value data
printf("Could not set the supported types.");
exit(-1);
}
RegCloseKey(hk);
}
BOOL
add_config_info(HANDLE schService, const char *config)
{
BOOL result = FALSE;
HKEY hkey = NULL;
DWORD status;
if ((status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, CONFIG_SUBKEY,
0, KEY_SET_VALUE, &hkey)) != ERROR_SUCCESS) {
SetLastError(status);
winerr("RegOpenKeyEx");
goto done;
}
if ((status = RegSetValueEx(hkey, "config", 0, REG_SZ, config,
strlen(config) + 1)) != ERROR_SUCCESS) {
SetLastError(status);
winerr("RegSetValueEx");
goto done;
}
result = TRUE;
done:
if (hkey != NULL)
RegCloseKey(hkey);
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -