From 55c6ac70550af857d80ef233147dbc986e4095e1 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 7 Nov 1997 13:31:47 +0000 Subject: [PATCH] Added NT Service name part of statserv_options_block. Moved NT service utility to server library. --- include/statserv.h | 9 +- server/server.dsp | 4 + server/service.c | 476 ++++++++++++++++++++++++++++++++++++++++++++++++++++ server/service.h | 51 ++++++ server/statserv.c | 76 ++++++++- ztest/ztest.c | 69 +------- ztest/ztest.dsp | 8 - 7 files changed, 615 insertions(+), 78 deletions(-) create mode 100644 server/service.c create mode 100644 server/service.h diff --git a/include/statserv.h b/include/statserv.h index a8f3da2..89d2d29 100644 --- a/include/statserv.h +++ b/include/statserv.h @@ -24,7 +24,11 @@ * OF THIS SOFTWARE. * * $Log: statserv.h,v $ - * Revision 1.11 1997-10-27 14:03:01 adam + * Revision 1.12 1997-11-07 13:31:47 adam + * Added NT Service name part of statserv_options_block. Moved NT + * service utility to server library. + * + * Revision 1.11 1997/10/27 14:03:01 adam * Added new member to statserver_options_block, pre_init, which * specifies a callback to be invoked after command line parsing and * before the server listens for the first time. @@ -79,11 +83,12 @@ typedef struct statserv_options_block int maxrecordsize; /* maximum value for negotiation */ char configname[ODR_MAXNAME+1]; /* given to the backend in bend_init */ char setuid[ODR_MAXNAME+1]; /* setuid to this user after binding */ - void (*pre_init)(struct statserv_options_block *p); + char service_name[128]; /* NT Service Name */ } statserv_options_block; int statserv_main(int argc, char **argv); +int statserv_start(int argc, char **argv); void statserv_closedown(void); statserv_options_block *statserv_getcontrol(void); void statserv_setcontrol(statserv_options_block *block); diff --git a/server/server.dsp b/server/server.dsp index 90eb32d..15a1972 100644 --- a/server/server.dsp +++ b/server/server.dsp @@ -102,6 +102,10 @@ SOURCE=.\requestq.c # End Source File # Begin Source File +SOURCE=.\service.c +# End Source File +# Begin Source File + SOURCE=.\seshigh.c # End Source File # Begin Source File diff --git a/server/service.c b/server/service.c new file mode 100644 index 0000000..5780284 --- /dev/null +++ b/server/service.c @@ -0,0 +1,476 @@ +/* + * NT Service interface Utility. + * Based on code written by + * Chas Woodfield, Fretwell Downing Datasystems. + * $Log: service.c,v $ + * Revision 1.1 1997-11-07 13:31:52 adam + * Added NT Service name part of statserv_options_block. Moved NT + * service utility to server library. + * + * Revision 1.6 1997/09/18 08:49:14 adam + * Option -runnormal no needed to run server in standalone mode. + * + * Revision 1.5 1997/09/17 12:10:43 adam + * YAZ version 1.4. + * + * Revision 1.4 1997/09/09 10:10:20 adam + * Another MSV5.0 port. Changed projects to include proper + * library/include paths. + * Server starts server in test-mode when no options are given. + * + * Revision 1.3 1997/09/04 13:50:30 adam + * Bug fix in ztest. + * + */ + +/************************************************************/ +/* Note this file is shared by all processes */ +/* Should really put it somewhere other than here */ +/* For some strange reason it won't work when part of a lib */ +/************************************************************/ + +#ifdef WINDOWS + +#include +#include +#include + +#include "service.h" + +static AppService *pService = NULL; +static BOOL bRunAsService = TRUE; +static void *pAppHandle = NULL; + +/* Private functions to this module */ +void Service_Create(LPTSTR pAppName, LPTSTR pServiceName, LPTSTR pServiceDisplayName, LPTSTR pDependancies, int argc, char **argv); +void Service_Delete(); +void Service_Initialize(); +BOOL NotifyServiceController(); +BOOL UpdateServiceStatus(DWORD Status); +void FailServiceStart(DWORD Win32Code, DWORD PrivateCode); +void CmdInstallService(int argc, char *argv[], BOOL bAutoStart); +void CmdRemoveService(); +LPTSTR GetLastErrorText(LPTSTR lpszBuf, DWORD dwSize); +BOOL CheckServiceArguments(int argc, char *argv[]); + +/* Callback functions for thee service manager */ +void WINAPI ServiceMain(DWORD argc, LPTSTR argv[]); +void WINAPI ServiceControlHandler(DWORD fdwControl); + +/* Function to handle Ctrl + C etc... */ +BOOL EventHandlerRoutine(DWORD dwCtrlType); + +void Service_Create(LPTSTR pAppName, LPTSTR pServiceName, LPTSTR pServiceDisplayName, LPTSTR pDependancies, int argc, char **argv) +{ + pService = malloc(sizeof(AppService)); + pService->pAppName = pAppName; + pService->pServiceName = pServiceName; + pService->pServiceDisplayName = pServiceDisplayName; + pService->pDependancies = pDependancies; + pService->hService = 0; + pService->ServiceTable[0].lpServiceName = pServiceName; + pService->ServiceTable[0].lpServiceProc = ServiceMain; + pService->ServiceTable[1].lpServiceName = NULL; + pService->ServiceTable[1].lpServiceProc = NULL; + pService->argc = argc; + pService->argv = argv; +} + +void Service_Delete() +{ + if (pService != NULL) + { + /* Mark the service as stopping */ + UpdateServiceStatus(SERVICE_STOP_PENDING); + + /* Stop the service */ + StopAppService(pAppHandle); + + /* Service has now stopped */ + UpdateServiceStatus(SERVICE_STOPPED); + + /* Free the memory */ + free(pService); + pService = NULL; + } +} + +void Service_Initialize() +{ + if (pService != NULL) + { + /* Register ourselves with the control dispatcher */ + StartServiceCtrlDispatcher(pService->ServiceTable); + } +} + +void WINAPI ServiceMain(DWORD argc, LPTSTR argv[]) +{ + if (pService != NULL) + { + if (NotifyServiceController()) + { + /* Set the status to pending */ + UpdateServiceStatus(SERVICE_START_PENDING); + + /* Lets attempt to start the service */ + if (StartAppService(pAppHandle, pService->argc, pService->argv)) + { + /* Service is now up and running */ + UpdateServiceStatus(SERVICE_RUNNING); + + /* Lets wait for our clients */ + RunAppService(pAppHandle); + } + else + { + FailServiceStart(GetLastError(), 0); + Service_Delete(); + } + } + } +} + +BOOL NotifyServiceController() +{ + if (pService == NULL) + { + return(FALSE); + } + else + { + if (bRunAsService) + { + pService->ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + pService->ServiceStatus.dwCurrentState = SERVICE_STOPPED; + pService->ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + pService->ServiceStatus.dwWin32ExitCode = 0; + pService->ServiceStatus.dwServiceSpecificExitCode = 0; + pService->ServiceStatus.dwCheckPoint = 0; + pService->ServiceStatus.dwWaitHint = 0; + pService->hService = RegisterServiceCtrlHandler(pService->pServiceName, ServiceControlHandler); + + if (pService->hService) + UpdateServiceStatus(SERVICE_START_PENDING); + else + return(FALSE); + } + return(TRUE); + } +} + +void WINAPI ServiceControlHandler(DWORD fdwControl) +{ + if (pService != NULL) + { + switch (fdwControl) + { + case SERVICE_CONTROL_STOP: + /* Update the service status to be pending */ + Service_Delete(); + break; + + case SERVICE_CONTROL_INTERROGATE: + UpdateServiceStatus(pService->ServiceStatus.dwCurrentState); + break; + + default: + break; + } + } +} + +BOOL UpdateServiceStatus(DWORD Status) +{ + if (pService != NULL) + { + if (pService->hService) + { + pService->ServiceStatus.dwCurrentState = Status; + if ((Status == SERVICE_START_PENDING) || (Status == SERVICE_STOP_PENDING)) + { + pService->ServiceStatus.dwCheckPoint ++; + pService->ServiceStatus.dwWaitHint = 5000; /* 5 sec.*/ + } + else + { + pService->ServiceStatus.dwCheckPoint = 0; + pService->ServiceStatus.dwWaitHint = 0; + } + + return(SetServiceStatus(pService->hService, &pService->ServiceStatus)); + } + } + + return(FALSE); +} + +void FailServiceStart(DWORD Win32Code, DWORD PrivateCode) +{ + if (pService != NULL) + { + pService->ServiceStatus.dwWin32ExitCode = Win32Code; + pService->ServiceStatus.dwServiceSpecificExitCode = PrivateCode; + UpdateServiceStatus(SERVICE_STOPPED); + } +} + +void CmdInstallService(int argc, char *argv[], BOOL bAutoStart) +{ + if (pService != NULL) + { + SC_HANDLE schService; + SC_HANDLE schSCManager; + + TCHAR szPath[1024]; + + if (GetModuleFileName(NULL, szPath, 512) == 0) + { + _tprintf(TEXT("Unable to install %s - %s\n"), TEXT(pService->pServiceDisplayName), GetLastErrorText(pService->szErr, 256)); + } + else + { + int i; + + strcat (szPath, TEXT(" -runservice")); + for (i = 1; i < argc; i++) + { + /* We will add the given command line arguments to the command */ + /* We are not interested in the install and remove options */ + if ((stricmp("-install", argv[i]) != 0) && + (stricmp("-installa", argv[i]) != 0) && + (stricmp("-remove", argv[i]) != 0)) + { + strcat(szPath, TEXT(" ")); + strcat(szPath, argv[i]); + } + } + + schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */ + NULL, /* database (NULL == default) */ + SC_MANAGER_ALL_ACCESS); /* access required */ + if (schSCManager) + { + schService = CreateService(schSCManager, /* SCManager database */ + TEXT(pService->pServiceName), /* name of service */ + TEXT(pService->pServiceDisplayName), /* name to display */ + SERVICE_ALL_ACCESS, /* desired access */ + SERVICE_WIN32_OWN_PROCESS, /* service type */ + bAutoStart ? SERVICE_AUTO_START : + SERVICE_DEMAND_START, /* start type */ + SERVICE_ERROR_NORMAL, /* error control type */ + szPath, /* service's binary */ + NULL, /* no load ordering group */ + NULL, /* no tag identifier */ + TEXT(pService->pDependancies), /* dependencies */ + NULL, /* LocalSystem account */ + NULL); /* no password */ + + if (schService) + { + _tprintf(TEXT("%s installed.\n"), TEXT(pService->pServiceDisplayName)); + CloseServiceHandle(schService); + } + else + { + _tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(pService->szErr, 256)); + } + + CloseServiceHandle(schSCManager); + } + else + _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(pService->szErr,256)); + } + } +} + +void CmdRemoveService() +{ + if (pService != NULL) + { + SC_HANDLE schService; + SC_HANDLE schSCManager; + + schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */ + NULL, /* database (NULL == default) */ + SC_MANAGER_ALL_ACCESS); /* access required */ + if (schSCManager) + { + schService = OpenService(schSCManager, TEXT(pService->pServiceName), SERVICE_ALL_ACCESS); + + if (schService) + { + /* try to stop the service */ + if (ControlService(schService, SERVICE_CONTROL_STOP, &pService->ServiceStatus)) + { + _tprintf(TEXT("Stopping %s."), TEXT(pService->pServiceDisplayName)); + Sleep(1000); + + while (QueryServiceStatus(schService, &pService->ServiceStatus)) + { + if (pService->ServiceStatus.dwCurrentState == SERVICE_STOP_PENDING) + { + _tprintf(TEXT(".")); + Sleep( 1000 ); + } + else + break; + } + + if (pService->ServiceStatus.dwCurrentState == SERVICE_STOPPED) + _tprintf(TEXT("\n%s stopped.\n"), TEXT(pService->pServiceDisplayName)); + else + _tprintf(TEXT("\n%s failed to stop.\n"), TEXT(pService->pServiceDisplayName)); + + } + + /* now remove the service */ + if(DeleteService(schService)) + _tprintf(TEXT("%s removed.\n"), TEXT(pService->pServiceDisplayName)); + else + _tprintf(TEXT("DeleteService failed - %s\n"), GetLastErrorText(pService->szErr,256)); + + CloseServiceHandle(schService); + } + else + _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(pService->szErr,256)); + + CloseServiceHandle(schSCManager); + } + else + _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(pService->szErr,256)); + } +} + +LPTSTR GetLastErrorText(LPTSTR lpszBuf, DWORD dwSize) +{ + DWORD dwRet; + LPTSTR lpszTemp = NULL; + + dwRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY, + NULL, + GetLastError(), + LANG_NEUTRAL, + (LPTSTR)&lpszTemp, + 0, + NULL); + + /* supplied buffer is not long enough */ + if (!dwRet || ((long)dwSize < (long)dwRet + 14)) + lpszBuf[0] = TEXT('\0'); + else + { + lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0'); /* remove cr and newline character */ + _stprintf(lpszBuf, TEXT("%s (0x%x)"), lpszTemp, GetLastError()); + } + + if (lpszTemp) + LocalFree((HLOCAL)lpszTemp); + + return(lpszBuf); +} + +BOOL CheckServiceArguments(int argc, char *argv[]) +{ + int i; + + /* Lets process the arguments */ + for (i = 1; i < argc; i++) + { + if (stricmp("-install", argv[i]) == 0) + { + /* They want to install the service */ + CmdInstallService(argc, argv, FALSE); + + /* We don't carry on, after we have installed the service */ + return(FALSE); + } + else if (stricmp("-installa", argv[i]) == 0) + { + /* They want to install the service */ + CmdInstallService(argc, argv, TRUE); + + /* We don't carry on, after we have installed the service */ + return(FALSE); + } + else if (stricmp("-remove", argv[i]) == 0) + { + /* Here they want to remove it */ + CmdRemoveService(); + + /* We don't carry on, after we have removed the service */ + return(FALSE); + } + else if (stricmp ("-runservice", argv[i]) == 0) + { + /* We can carry on, if we reached here */ + argv[i] = ""; + return(TRUE); + } + } + bRunAsService = FALSE; + return(TRUE); +} + +BOOL SetupService(int argc, char *argv[], void *pHandle, LPTSTR pAppName, LPTSTR pServiceName, LPTSTR pServiceDisplayName, LPTSTR pDependancies) +{ + BOOL bDeleteService = TRUE; + BOOL bResult = FALSE; + + /* Save the handle for later use */ + pAppHandle = pHandle; + + /* Create our service class */ + Service_Create(pAppName, pServiceName, pServiceDisplayName, pDependancies, argc, argv); + + if (CheckServiceArguments(argc, argv)) + { + if (bRunAsService) + { + /* No need to set the console control handler, as the service manager handles all this for us */ + Service_Initialize(); + bDeleteService = FALSE; + } + else + { + /* Set the console control handler for exiting the program */ +/* SetConsoleCtrlHandler((PHANDLER_ROUTINE)EventHandlerRoutine, TRUE); +*/ + + /* Now do the main work */ + ServiceMain(argc, argv); + } + + /* We have been successful initializing, so let the caller know */ + bResult = TRUE; + } + + if (bDeleteService) + { + /* Finished with the service now */ + Service_Delete(); + } + return(bResult); +} + +BOOL EventHandlerRoutine(DWORD dwCtrlType) +{ + /* This routine dosn't seem to get called all the time, Why ??? */ + switch (dwCtrlType) + { + case CTRL_C_EVENT: /* A CTRL+C signal was received, either from keyboard input or from a signal generated by the GenerateConsoleCtrlEvent function.*/ + case CTRL_BREAK_EVENT: /* A CTRL+BREAK signal was received, either from keyboard input or from a signal generated by GenerateConsoleCtrlEvent.*/ + case CTRL_CLOSE_EVENT: /* A signal that the system sends to all processes attached to a console when the user closes the console (either by choosing the Close command from the console window's System menu, or by choosing the End Task command from the Task List).*/ + case CTRL_LOGOFF_EVENT: /* A signal that the system sends to all console processes when a user is logging off. This signal does not indicate which user is logging off, so no assumptions can be made.*/ + case CTRL_SHUTDOWN_EVENT: /* A signal that the system sends to all console processes when the system */ + /* We are basically shutting down, so call Service_Delete */ + Service_Delete(); + return(TRUE); + break; + + default: + /* we are not handling this one, so return FALSE */ + return(FALSE); + } +} +#endif diff --git a/server/service.h b/server/service.h new file mode 100644 index 0000000..347357c --- /dev/null +++ b/server/service.h @@ -0,0 +1,51 @@ +/* + * NT Service interface Utility. + * Based on code written by + * Chas Woodfield, Fretwell Downing Datasystems. + * $Log: service.h,v $ + * Revision 1.1 1997-11-07 13:31:52 adam + * Added NT Service name part of statserv_options_block. Moved NT + * service utility to server library. + * + * Revision 1.2 1997/09/04 13:50:30 adam + * Bug fix in ztest. + * + */ + +#ifndef SERVICE_INCLUDED +#define SERVICE_INCLUDED + +#ifdef WIN32 + +#include + +typedef struct _Service +{ + LPTSTR pAppName; + LPTSTR pServiceName; + LPTSTR pServiceDisplayName; + LPTSTR pDependancies; + TCHAR szErr[256]; + SERVICE_STATUS_HANDLE hService; + SERVICE_STATUS ServiceStatus; + SERVICE_TABLE_ENTRY ServiceTable[2]; + int argc; + char **argv; +} AppService; + +/* Called by the app to initialize the service */ +BOOL SetupService(int argc, char *argv[], void *pHandle, LPTSTR pAppName, LPTSTR pServiceName, LPTSTR pServiceDisplayName, LPTSTR pDependancies); + +#endif /* WIN32 */ + +/* Functions that must be in the main application */ +/* Initializes the app */ +int StartAppService(void *pHandle, int argc, char **argv); + +/* Now we wait for any connections */ +void RunAppService(void *pHandle); + +/* Time to tidyup and stop the service */ +void StopAppService(void *pHandle); + +#endif diff --git a/server/statserv.c b/server/statserv.c index ec506a5..9246daa 100644 --- a/server/statserv.c +++ b/server/statserv.c @@ -7,7 +7,11 @@ * Chas Woodfield, Fretwell Downing Datasystem. * * $Log: statserv.c,v $ - * Revision 1.43 1997-10-31 12:20:09 adam + * Revision 1.44 1997-11-07 13:31:52 adam + * Added NT Service name part of statserv_options_block. Moved NT + * service utility to server library. + * + * Revision 1.43 1997/10/31 12:20:09 adam * Improved memory debugging for xmalloc/nmem.c. References to NMEM * instead of ODR in n ESPEC-1 handling in source d1_espec.c. * Bug fix: missing fclose in data1_read_espec1. @@ -156,6 +160,7 @@ #include #include #include +#include "service.h" #else #include #include @@ -192,7 +197,8 @@ static statserv_options_block control_block = { 1024*1024, /* maximum PDU size (approx.) to allow */ "default-config", /* configuration name to pass to backend */ "", /* set user id */ - NULL + NULL, /* pre init handler */ + "Z39.50 Server" /* NT Service Name */ }; /* @@ -404,11 +410,11 @@ static void listener(IOCHAN h, int event) } logf(LOG_DEBUG, "Setting timeout %d", control_block.idle_timeout); iochan_setdata(new_chan, newas); - iochan_settimeout(new_chan, control_block.idle_timeout * 60); + iochan_settimeout(new_chan, control_block.idle_timeout * 60); #ifndef WINDOWS logf(LOG_DEBUG, "Determining client address"); a = cs_addrstr(new_line); - logf(LOG_LOG, "Accepted connection from %s", a ? a : "[Unknown]"); + logf(LOG_LOG, "Accepted connection from %s", a ? a : "[Unknown]"); #endif /* Now what we need todo is create a new thread with this iochan as the parameter */ @@ -708,7 +714,8 @@ void statserv_setcontrol(statserv_options_block *block) memcpy(&control_block, block, sizeof(*block)); } -int statserv_main(int argc, char **argv) + +int statserv_start(int argc, char **argv) { int ret, listeners = 0, inetd = 0, r; char *arg; @@ -829,3 +836,62 @@ int statserv_main(int argc, char **argv) nmem_exit (); return ret; } + +#ifdef WINDOWS +typedef struct _Args +{ + char **argv; + int argc; +} Args; + +static Args ArgDetails; + +/* name of the executable */ +#define SZAPPNAME "server" + +/* list of service dependencies - "dep1\0dep2\0\0" */ +#define SZDEPENDENCIES "" + +int statserv_main(int argc, char **argv) +{ + statserv_options_block *cb = statserv_getcontrol(); + + /* Lets setup the Arg structure */ + ArgDetails.argc = argc; + ArgDetails.argv = argv; + + /* Now setup the service with the service controller */ + SetupService(argc, argv, &ArgDetails, SZAPPNAME, + cb->service_name, /* internal service name */ + cb->service_name, /* displayed name of the service */ + SZDEPENDENCIES); + return 0; +} + +int StartAppService(void *pHandle, int argc, char **argv) +{ + /* Initializes the App */ + return 1; +} + +void RunAppService(void *pHandle) +{ + Args *pArgs = (Args *)pHandle; + + /* Starts the app running */ + statserv_start(pArgs->argc, pArgs->argv); +} + +void StopAppService(void *pHandle) +{ + /* Stops the app */ + statserv_closedown(); +} +#else +int statserv_main(int argc, char **argv) +{ + int ret = statserv_start (argc, argv); + statserv_closedown (); + return ret; +} +#endif diff --git a/ztest/ztest.c b/ztest/ztest.c index d8b1555..6b21057 100644 --- a/ztest/ztest.c +++ b/ztest/ztest.c @@ -7,7 +7,11 @@ * Chas Woodfield, Fretwell Downing Datasystems. * * $Log: ztest.c,v $ - * Revision 1.4 1997-09-17 12:10:43 adam + * Revision 1.5 1997-11-07 13:31:58 adam + * Added NT Service name part of statserv_options_block. Moved NT + * service utility to server library. + * + * Revision 1.4 1997/09/17 12:10:43 adam * YAZ version 1.4. * * Revision 1.3 1997/09/09 10:10:20 adam @@ -33,9 +37,6 @@ #include #include -/* Specifically for NT Services - Shouldn't cause problems on UNIX */ -#include "service.h" - Z_GenericRecord *read_grs1(FILE *f, ODR o); bend_initresult *bend_init(bend_initrequest *q) @@ -301,65 +302,7 @@ void bend_close(void *handle) return; } -#ifndef WINDOWS -/* UNIX version */ -int main(int argc, char **argv) -{ - statserv_main(argc, argv); - statserv_closedown(); - exit (0); -} -#else -/* Windows version with Service support */ - -typedef struct _Args -{ - char **argv; - int argc; -} Args; - -static Args ArgDetails; - -/* name of the executable */ -#define SZAPPNAME "server" - -/* internal name of the service */ -#define SZSERVICENAME "Z3950 Test Server" - -/* displayed name of the service */ -#define SZSERVICEDISPLAYNAME "Z3950 Test Server" - -/* list of service dependencies - "dep1\0dep2\0\0" */ -#define SZDEPENDENCIES "" - int main(int argc, char **argv) { - /* Lets setup the Arg structure */ - ArgDetails.argc = argc; - ArgDetails.argv = argv; - - /* Now setup the service with the service controller */ - SetupService(argc, argv, &ArgDetails, SZAPPNAME, SZSERVICENAME, SZSERVICEDISPLAYNAME, SZDEPENDENCIES); - return(0); + return statserv_main(argc, argv); } - -int StartAppService(void *pHandle, int argc, char **argv) -{ - /* Initializes the App */ - return 1; -} - -void RunAppService(void *pHandle) -{ - Args *pArgs = (Args *)pHandle; - - /* Starts the app running */ - statserv_main(pArgs->argc, pArgs->argv); -} - -void StopAppService(void *pHandle) -{ - /* Stops the app */ - statserv_closedown(); -} -#endif diff --git a/ztest/ztest.dsp b/ztest/ztest.dsp index 0e5a6de..ebfcef2 100644 --- a/ztest/ztest.dsp +++ b/ztest/ztest.dsp @@ -99,14 +99,6 @@ SOURCE=".\read-grs.c" # End Source File # Begin Source File -SOURCE=.\service.c -# End Source File -# Begin Source File - -SOURCE=.\service.h -# End Source File -# Begin Source File - SOURCE=.\ztest.c # End Source File # End Target -- 1.7.10.4