#include <windows.h>
#include <winnt.h>
#include <stdlib.h>
#include <stdio.h>
#include "lib.h"
#include "emsg.h"
#include "key.h"
#define SVC_NAME "dxmit6"

int nt_getkey(char *ex, int nchan);
int nt_setkey(char *s);
VOID svc_exiting(void);
VOID svc_exit(void);

SERVICE_STATUS_HANDLE ssh;
VOID svc_handler(DWORD msg);
void suck_setexit(void);
void svc_report(int status)
{
	static int cp;
	static int stop_pending;
	static SERVICE_STATUS ss;
	
	ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
	ss.dwCurrentState = status;	 
	ss.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;
	ss.dwWin32ExitCode = NO_ERROR;
	ss.dwServiceSpecificExitCode = 0;
	ss.dwWaitHint = 0;
	ss.dwCheckPoint = 0;
	
	if ((status==SERVICE_STOP_PENDING) || (status==SERVICE_START_PENDING)) {
		ss.dwWaitHint = 300;
		ss.dwCheckPoint = cp++;
	}
	if ((status==SERVICE_STOP_PENDING)) {
		ss.dwWaitHint = 100;
		ss.dwCheckPoint = cp++;
	}

	if (ssh!=0) SetServiceStatus(ssh,&ss);
}

VOID svc_handler(DWORD msg)
{
	static int cp;
	static int stop_pending;
/*	SERVICE_STATUS ss;*/
	int mde = SERVICE_RUNNING;	

	switch (msg) {
		case SERVICE_CONTROL_PAUSE:
		case SERVICE_CONTROL_CONTINUE:
		case SERVICE_CONTROL_INTERROGATE:
			/*dmsg("lib: Service pause,continue or interrogate\n");*/
			break;
		case SERVICE_CONTROL_SHUTDOWN:
		case SERVICE_CONTROL_STOP:
			/*emsg("Service stop or shutdown requested\n");*/
			mde = SERVICE_STOP_PENDING;
			break;
	}
	svc_report(mde);
	if (mde==SERVICE_STOP_PENDING) {
		suck_setexit();
#ifdef WIN32
		WSACancelBlockingCall(); /* To kill any lookups that are holding it up */ 
#endif
	}
}

VOID svc_exiting(void)
{
	svc_report(SERVICE_STOP_PENDING);
}
VOID svc_exit(void)
{
	svc_report(SERVICE_STOPPED);
}

VOID ServiceMain(DWORD  dwArgc, LPTSTR  *lpszArgv);
char xname[200];
char *main_msg(void);
int main(int argc, char *argv[])
{
	static SERVICE_TABLE_ENTRY stable[3];
	int isslave = FALSE;
	if (argc>0) strcpy(xname,argv[0]);
	stable[0].lpServiceName = SVC_NAME;
	stable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION) ServiceMain;
	stable[1].lpServiceName = NULL;
	stable[1].lpServiceProc = NULL;
	if (argc==3) if (strncmp(argv[1],"-s",2)==0) isslave = TRUE;
	if (argc==2) if (strcmp(argv[1],"-test")==0) {
		printf("Test running interactively\n");
		ServiceMain(argc,argv);
		return 0;
        }
	if (argc==3) if (strcmp(argv[1],"-test")==0) {
		printf("Test running interactively\n");
		ServiceMain(argc,argv);
		return 0;
        }
        if (argc==2) if (strcmp(argv[1],"-expire")==0) {
                printf("Dnews running in expire mode\n");
                ServiceMain(argc,argv);
                return 0;
        }
        if (isslave) {
		ServiceMain(argc,argv);
	} else {
	  if (!StartServiceCtrlDispatcher(stable)) {
	 	printf("%s\n",main_msg());
		ServiceMain(argc,argv);	
	  }
	  svc_exit();
	}
	return 0;
}
void svc_init(char *sname)
{
	int r;
	ssh = RegisterServiceCtrlHandler(sname,(LPHANDLER_FUNCTION)	svc_handler);

	if (ssh==0) {
	 	r = GetLastError();
		if (r==ERROR_INVALID_NAME) emsg("svc: Invalid name\n");
		else if (r==ERROR_SERVICE_DOES_NOT_EXIST) emsg("svc: Service doesn't exist\n");
		else emsg("Register service failed, error %d (ignore if running dmulti)\n",r);
	}
	svc_report(SERVICE_START_PENDING);
	svc_report(SERVICE_RUNNING);
}

char *svc_getargs(char *svcname)
{
	char key[400];
	static char val[400];
	int vallen=300,r;
	int valtype;
	HKEY skey;
	DWORD reserved=0;
	REGSAM sam;

	lprintf(key,400-1,"System\\CurrentControlSet\\Services\\%s",svcname);
	/* r = RegOpenKey(HKEY_LOCAL_MACHINE,key,&skey);*/
	sam = KEY_READ;
	r = RegOpenKeyEx(HKEY_LOCAL_MACHINE,key,reserved,sam,&skey);
	if (r!=ERROR_SUCCESS) emsg("failure: RegOpenKey %d(0x%02x)\n", r,GetLastError());
	r = RegQueryValueEx(skey,"DisplayName",NULL,&valtype,val,&vallen);
	if (r!=ERROR_SUCCESS) emsg("failure: RegQueryKey %d(0x%02x)\n", r,GetLastError());
	val[vallen] = 0;
	return val;
}

int sleep(int x)
{	 
	Sleep(x*1000);
	return TRUE;
}
#define KEY_COMPUTER_NAME "SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName"

char *nt_pcname(void);
char *nt_pcname(void)
{
    HKEY MyKey;
	static    char Line[64];
    int  linelen = 64;
    DWORD type_of_entry, result;

	RegCreateKey(HKEY_LOCAL_MACHINE, KEY_COMPUTER_NAME, &MyKey);
	result = RegQueryValueEx(MyKey, "ComputerName", 0, &type_of_entry, 
		(unsigned char *)Line, &linelen);
	RegCloseKey(MyKey);
	if (result == ERROR_SUCCESS && type_of_entry == REG_SZ) {
   		return Line;
	}
	return "lookup_failed";
}

char *nt_other(void)
{
	char sysdir[MAX_PATH];
 	static char bf[MAX_PATH];
	GetSystemDirectory((LPSTR) sysdir,MAX_PATH);
	lprintf(bf,MAX_PATH-1,"%s\\dxyntky.exe",sysdir);
	return bf;
/*
	strcpy(junk,nt_pcname());
	strcat(junk,nt_pcname());
	if (strlen(junk)<10) strcat(junk,"abcdefg");
	for (i=0; i<10; i++) {
		junk[i] = ((junk[i] + 15 +i) % 22) + 'a';
	}
	junk[10] = 0;

	lprintf(bf,MAX_PATH-1,"%s\\%s.exe",sysdir,junk);
	return bf;
*/
}
