home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2000 July
/
PCWorld_2000-07_cd.bin
/
Komunik
/
sambar
/
_SETUP.1
/
Ntmain.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-07-14
|
9KB
|
444 lines
/*
** NTMAIN
**
** This is the main driver for the Windows NT Service driver of
** the Sambar Server.
**
** Confidential Property of Tod Sambar
** (c) Copyright Tod Sambar 1997-1998
** All rights reserved.
**
**
** Syntax:
**
** ntserver [-i] [-u] [-d]
**
** -i Install the Sambar Server as an NT Service
** -u Uninstall the Sambar Server NT Service
** -d Start the Sambar Server in debug mode
**
**
** History:
** Chg# Date Description Resp
** ---- ------- ------------------------------------------------------- ----
** 26JUL97 Created sambar
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <direct.h>
#include <process.h>
#include <sambar.h>
/*
** Local Defines
*/
#define SERVICE_NAME "Sambar Server"
#define SERVICE_TITLE "Sambar Server"
#define NTSERVER_DEBUG (SA_INT)0x0001
#define NTSERVER_INSTALL (SA_INT)0x0002
#define NTSERVER_UNINSTALL (SA_INT)0x0004
/*
** Local Prototypes
*/
static SA_RETCODE get_args(int argc, char **argv, SA_INT *flagsp);
static void syntax_error(char *name, char *argv);
static SA_RETCODE install_service(void);
static SA_RETCODE uninstall_service(void);
VOID service_main(DWORD argc, LPTSTR *argv);
VOID service_ctrl(DWORD dwCtrlCode);
static SA_RETCODE service_cd(void);
static void service_status(int state, int exitCode, int waitHint);
/*
** Global Handles
*/
static SERVICE_STATUS_HANDLE hServiceStatus;
static int sState;
int
main(int argc, char *argv[])
{
SA_INT flags;
/*
** Read the command line arguments.
*/
if (get_args(argc, argv, &flags) != SA_SUCCEED)
return (0);
if (flags & NTSERVER_INSTALL)
{
if (install_service() != SA_SUCCEED)
return (-1);
fprintf(stdout,
"The %s NT Service can be started from the Service Panel.\n",
SERVICE_NAME);
return (0);
}
if (flags & NTSERVER_UNINSTALL)
{
if (uninstall_service() != SA_SUCCEED)
return (-1);
return (0);
}
/* Change to the appropriate working directory for execution */
if (service_cd() != SA_SUCCEED)
return (-1);
if (flags & NTSERVER_DEBUG)
{
/* Execute the Sambar Server Shell */
if (sa_server((SA_VOID *)NULL) != SA_SUCCEED)
return (-1);
}
else
{
SERVICE_TABLE_ENTRY ste[] =
{
{ SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)service_main },
{ NULL, NULL }
};
if (StartServiceCtrlDispatcher(ste) != TRUE)
{
fprintf(stderr, "Failed to start %s NT Service (%d)\n",
SERVICE_NAME, GetLastError());
return (-1);
}
}
return (0);
}
/*
** GET_ARGS
**
** This routine parses the command line arguments passed to the
** NT Server application.
**
*/
static SA_RETCODE
get_args(int argc, char **argv, SA_INT *flagsp)
{
int j;
SA_INT flags;
/* Initialization */
flags = 0;
/*
** Are there any arguments to parse?
*/
if (argc <= 1)
{
/*
** We don't have any arguments.
*/
*flagsp = 0;
return (SA_SUCCEED);
}
/* Loop through the arguments */
j = 1;
while (j < argc)
{
if (strcmp(argv[j], "-i") == 0)
{
flags |= NTSERVER_INSTALL;
}
else if (strcmp(argv[j], "-u") == 0)
{
flags |= NTSERVER_UNINSTALL;
}
else if (strcmp(argv[j], "-d") == 0)
{
flags |= NTSERVER_DEBUG;
}
else
{
syntax_error(argv[0], argv[j]);
return (SA_FAIL);
}
j++;
}
*flagsp = flags;
/*
** All done.
*/
return (SA_SUCCEED);
}
/*
** SYNTAX_ERROR
**
** This routine is used to inform the user that a command-line
** syntax error occurred.
*/
static void
syntax_error(char *name, char *argv)
{
/*
** Print the error string.
*/
if (argv != NULL)
fprintf(stderr, "\nUnexpected flag: %s\n", argv);
fprintf(stderr, "\nCorrect syntax is: %s\n", name);
fprintf(stderr, "\t\t[-i] # Install the NT Service\n");
fprintf(stderr, "\t\t[-u] # Unistall the NT Service\n");
fprintf(stderr, "\t\t[-d] # Start the Sambar Server in debug mode\n");
return;
}
static SA_RETCODE
install_service(void)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
TCHAR szPath[512];
if (GetModuleFileName(NULL, szPath, 512) == 0)
{
fprintf(stderr, "Failed to get exe for service %s (%d)\n",
SERVICE_NAME, GetLastError());
return (SA_FAIL);
}
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
{
fprintf(stderr, "Failed to open the service manager.\n");
return (SA_FAIL);
}
schService = CreateService(schSCManager, SERVICE_NAME, SERVICE_TITLE,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
szPath, NULL, NULL, NULL, NULL, NULL);
if (schService == NULL)
{
fprintf(stderr, "Failed to create service %s (%d)\n",
SERVICE_NAME, GetLastError());
CloseServiceHandle(schSCManager);
return (SA_FAIL);
}
fprintf(stdout, "Installed service %s.\n", SERVICE_NAME);
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return (SA_SUCCEED);
}
static SA_RETCODE
uninstall_service(void)
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
SERVICE_STATUS status;
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (schSCManager == NULL)
{
fprintf(stderr, "Failed to open the service manager.\n");
return (SA_FAIL);
}
schService = OpenService(schSCManager, SERVICE_NAME, SERVICE_ALL_ACCESS);
if (schService == NULL)
{
fprintf(stderr, "Failed to open service %s (%d).\n",
SERVICE_NAME, GetLastError());
CloseServiceHandle(schSCManager);
return (SA_FAIL);
}
/* Try to stop the service */
if (ControlService(schService, SERVICE_CONTROL_STOP, &status))
{
Sleep(1000);
while (QueryServiceStatus(schService, &status))
{
if (status.dwCurrentState == SERVICE_STOP_PENDING)
Sleep(1000);
else
break;
}
}
/* Delete the service */
if (DeleteService(schService) != TRUE)
{
fprintf(stderr, "Failed in attempt to delete service %s (%d).\n",
SERVICE_NAME, GetLastError());
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return (SA_FAIL);
}
fprintf(stdout, "Deleted service %s.\n", SERVICE_NAME);
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return (SA_SUCCEED);
}
VOID
service_main(DWORD argc, LPTSTR *argv)
{
hServiceStatus = RegisterServiceCtrlHandler(SERVICE_NAME,
(LPHANDLER_FUNCTION)service_ctrl);
if (!hServiceStatus)
{
fprintf(stderr, "Failed to register %s service control handler (%d).\n",
SERVICE_NAME, GetLastError());
return;
}
service_status(SERVICE_START_PENDING, NO_ERROR, 5000);
service_status(SERVICE_RUNNING, NO_ERROR, 0);
/* Start the Sambar Server */
sa_server((SA_VOID *)NULL);
service_status(SERVICE_STOPPED, NO_ERROR, 0);
return;
}
VOID
service_ctrl(DWORD dwCtrlCode)
{
int state;
state = sState;
switch(dwCtrlCode)
{
// Stop the service.
//
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
service_status(SERVICE_STOP_PENDING, NO_ERROR, 8000);
(SA_VOID)sa_shutdown(0);
return;
// Update the service status.
//
case SERVICE_CONTROL_INTERROGATE:
break;
// invalid control code
//
default:
break;
}
service_status(state, NO_ERROR, 0);
}
static void
service_status(int state, int exitCode, int waitHint)
{
SERVICE_STATUS status;
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
status.dwServiceSpecificExitCode = 0;
status.dwCheckPoint = 0;
if (state == SERVICE_START_PENDING)
{
status.dwControlsAccepted = 0;
}
else
{
status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_SHUTDOWN;
}
sState = state;
status.dwCurrentState = state;
status.dwWin32ExitCode = exitCode;
status.dwWaitHint = waitHint;
(VOID)SetServiceStatus(hServiceStatus, &status);
return;
}
static SA_RETCODE
service_cd(void)
{
int count;
DWORD len;
TCHAR szPath[512];
len = GetModuleFileName(NULL, szPath, 512);
if (len == 0)
{
fprintf(stderr, "Failed to get exe for service %s (%d)\n",
SERVICE_NAME, GetLastError());
return (SA_FAIL);
}
/*
** Change to the directory above the executable.
**
** The working directory for the Sambar Server application must
** be the installation directory.
*/
count = 0;
while ((len > 0) && (count < 2))
{
len--;
if (szPath[len] == '\\')
{
count++;
szPath[len] = '\0';
}
}
if (count != 2)
{
fprintf(stderr,
"Unable to change to the Sambar Server installation.\n");
return (SA_FAIL);
}
if (chdir(szPath) != 0)
{
fprintf(stderr,
"Unable to change to the Sambar Server installation.\n");
return (SA_FAIL);
}
return (SA_SUCCEED);
}