Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6914 dpurdie 1
////////////////////////////////////////////////////////////////////// 
2
// NT Service Stub Code (For XYROOT )
3
//////////////////////////////////////////////////////////////////////
4
 
5
#include <stdio.h>
6
#include <windows.h>
7
#include <winbase.h>
8
#include <winsvc.h>
9
#include <process.h>
10
 
11
 
12
const int nBufferSize = 500;
13
char pServiceName[nBufferSize+1];
14
char pExeFile[nBufferSize+1];
15
char pInitFile[nBufferSize+1];
16
char pLogFile[nBufferSize+1];
17
const int nMaxProcCount = 127;
18
PROCESS_INFORMATION pProcInfo[nMaxProcCount];
19
 
20
 
21
SERVICE_STATUS          serviceStatus; 
22
SERVICE_STATUS_HANDLE   hServiceStatusHandle; 
23
 
24
VOID WINAPI XYNTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
25
VOID WINAPI XYNTServiceHandler( DWORD fdwControl );
26
 
27
CRITICAL_SECTION myCS;
28
 
29
void WriteLog(char* pMsg)
30
{
31
	// write error or other information into log file
32
	::EnterCriticalSection(&myCS);
33
	try
34
	{
35
		SYSTEMTIME oT;
36
		::GetLocalTime(&oT);
37
		FILE* pLog = fopen(pLogFile,"a");
38
		fprintf(pLog,"%02d/%02d/%04d, %02d:%02d:%02d\n    %s\n",oT.wMonth,oT.wDay,oT.wYear,oT.wHour,oT.wMinute,oT.wSecond,pMsg); 
39
		fclose(pLog);
40
	} catch(...) {}
41
	::LeaveCriticalSection(&myCS);
42
}
43
 
44
////////////////////////////////////////////////////////////////////// 
45
//
46
// Configuration Data and Tables
47
//
48
 
49
SERVICE_TABLE_ENTRY   DispatchTable[] = 
50
{ 
51
	{pServiceName, XYNTServiceMain}, 
52
	{NULL, NULL}
53
};
54
 
55
 
56
// helper functions
57
 
58
BOOL StartProcess(int nIndex) 
59
{ 
60
	// start a process with given index
61
	STARTUPINFO startUpInfo = { sizeof(STARTUPINFO),NULL,"",NULL,0,0,0,0,0,0,0,STARTF_USESHOWWINDOW,0,0,NULL,0,0,0};  
62
	char pItem[nBufferSize+1];
63
	sprintf(pItem,"Process%d\0",nIndex);
64
	char pCommandLine[nBufferSize+1];
65
	GetPrivateProfileString(pItem,"CommandLine","",pCommandLine,nBufferSize,pInitFile);
66
	if(strlen(pCommandLine)>4)
67
	{
68
		char pWorkingDir[nBufferSize+1];
69
		GetPrivateProfileString(pItem,"WorkingDir","",pWorkingDir,nBufferSize,pInitFile);
70
		char pUserName[nBufferSize+1];
71
		GetPrivateProfileString(pItem,"UserName","",pUserName,nBufferSize,pInitFile);
72
		char pPassword[nBufferSize+1];
73
		GetPrivateProfileString(pItem,"Password","",pPassword,nBufferSize,pInitFile);
74
		char pDomain[nBufferSize+1];
75
		GetPrivateProfileString(pItem,"Domain","",pDomain,nBufferSize,pInitFile);
76
		BOOL bImpersonate = (::strlen(pUserName)>0&&::strlen(pPassword)>0);
77
		char pUserInterface[nBufferSize+1];
78
		GetPrivateProfileString(pItem,"UserInterface","N",pUserInterface,nBufferSize,pInitFile);
79
		BOOL bUserInterface = (bImpersonate==FALSE)&&(pUserInterface[0]=='y'||pUserInterface[0]=='Y'||pUserInterface[0]=='1')?TRUE:FALSE;
80
		char CurrentDesktopName[512];
81
		// set the correct desktop for the process to be started
82
		if(bUserInterface)
83
		{
84
			startUpInfo.wShowWindow = SW_SHOW;
85
			startUpInfo.lpDesktop = NULL;
86
		}
87
		else
88
		{
89
			HDESK hCurrentDesktop = GetThreadDesktop(GetCurrentThreadId());
90
			DWORD len;
91
			GetUserObjectInformation(hCurrentDesktop,UOI_NAME,CurrentDesktopName,MAX_PATH,&len);
92
			startUpInfo.wShowWindow = SW_HIDE;
93
			startUpInfo.lpDesktop = (bImpersonate==FALSE)?CurrentDesktopName:"";
94
		}	
95
		if(bImpersonate==FALSE)
96
		{
97
 
98
			// create the process
99
			if(CreateProcess(NULL,pCommandLine,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,strlen(pWorkingDir)==0?NULL:pWorkingDir,&startUpInfo,&pProcInfo[nIndex]))
100
			{
101
				char pPause[nBufferSize+1];
102
				GetPrivateProfileString(pItem,"PauseStart","100",pPause,nBufferSize,pInitFile);
103
				Sleep(atoi(pPause));
104
				return TRUE;
105
			}
106
			else
107
			{
108
				long nError = GetLastError();
109
				char pTemp[121];
110
				sprintf(pTemp,"Failed to start program '%s', error code = %d", pCommandLine, nError); 
111
				WriteLog(pTemp);
112
				return FALSE;
113
			}
114
		}
115
		else
116
		{
117
			HANDLE hToken = NULL;
118
			if(LogonUser(pUserName,(::strlen(pDomain)==0)?".":pDomain,pPassword,LOGON32_LOGON_SERVICE,LOGON32_PROVIDER_DEFAULT,&hToken))
119
			{
120
				if(CreateProcessAsUser(hToken,NULL,pCommandLine,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,(strlen(pWorkingDir)==0)?NULL:pWorkingDir,&startUpInfo,&pProcInfo[nIndex]))
121
				{
122
						char pPause[nBufferSize+1];
123
						GetPrivateProfileString(pItem,"PauseStart","100",pPause,nBufferSize,pInitFile);
124
						Sleep(atoi(pPause));
125
						return TRUE;
126
				}
127
				long nError = GetLastError();
128
				char pTemp[121];
129
				sprintf(pTemp,"Failed to start program '%s' as user '%s', error code = %d", pCommandLine, pUserName, nError); 
130
				WriteLog(pTemp);
131
				return FALSE;
132
			}
133
			long nError = GetLastError();
134
			char pTemp[121];
135
			sprintf(pTemp,"Failed to logon as user '%s', error code = %d", pUserName, nError); 
136
			WriteLog(pTemp);
137
			return FALSE;
138
		}
139
	}
140
	else return FALSE;
141
}
142
 
143
void EndProcess(int nIndex) 
144
{	
145
	// end a program started by the service
146
	if(pProcInfo[nIndex].hProcess)
147
	{
148
		char pItem[nBufferSize+1];
149
		sprintf(pItem,"Process%d\0",nIndex);
150
		char pPause[nBufferSize+1];
151
		GetPrivateProfileString(pItem,"PauseEnd","100",pPause,nBufferSize,pInitFile);
152
		int nPauseEnd = atoi(pPause);
153
		// post a WM_QUIT message first
154
		PostThreadMessage(pProcInfo[nIndex].dwThreadId,WM_QUIT,0,0);
155
		// sleep for a while so that the process has a chance to terminate itself
156
		::Sleep(nPauseEnd>0?nPauseEnd:50);
157
		// terminate the process by force
158
		TerminateProcess(pProcInfo[nIndex].hProcess,0);
159
		try // close handles to avoid ERROR_NO_SYSTEM_RESOURCES
160
		{
161
			::CloseHandle(pProcInfo[nIndex].hThread);
162
			::CloseHandle(pProcInfo[nIndex].hProcess);
163
		}
164
		catch(...) {}
165
		pProcInfo[nIndex].hProcess = 0;
166
		pProcInfo[nIndex].hThread = 0;
167
	}
168
}
169
 
170
BOOL BounceProcess(char* pName, int nIndex) 
171
{ 
172
	// bounce the process with given index
173
	SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); 
174
	if (schSCManager==0) 
175
	{
176
		long nError = GetLastError();
177
		char pTemp[121];
178
		sprintf(pTemp, "OpenSCManager failed, error code = %d", nError);
179
		WriteLog(pTemp);
180
	}
181
	else
182
	{
183
		// open the service
184
		SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
185
		if (schService==0) 
186
		{
187
			long nError = GetLastError();
188
			char pTemp[121];
189
			sprintf(pTemp, "OpenService failed, error code = %d", nError); 
190
			WriteLog(pTemp);
191
		}
192
		else
193
		{
194
			// call ControlService to invoke handler
195
			SERVICE_STATUS status;
196
			if(nIndex>=0&&nIndex<128)
197
			{
198
				if(ControlService(schService,(nIndex|0x80),&status))
199
				{
200
					CloseServiceHandle(schService); 
201
					CloseServiceHandle(schSCManager); 
202
					return TRUE;
203
				}
204
				long nError = GetLastError();
205
				char pTemp[121];
206
				sprintf(pTemp, "ControlService failed, error code = %d", nError); 
207
				WriteLog(pTemp);
208
			}
209
			else
210
			{
211
				char pTemp[121];
212
				sprintf(pTemp, "Invalid argument to BounceProcess: %d", nIndex); 
213
				WriteLog(pTemp);
214
			}
215
			CloseServiceHandle(schService); 
216
		}
217
		CloseServiceHandle(schSCManager); 
218
	}
219
	return FALSE;
220
}
221
 
222
BOOL KillService(char* pName) 
223
{ 
224
	// kill service with given name
225
	SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); 
226
	if (schSCManager==0) 
227
	{
228
		long nError = GetLastError();
229
		char pTemp[121];
230
		sprintf(pTemp, "OpenSCManager failed, error code = %d", nError);
231
		WriteLog(pTemp);
232
	}
233
	else
234
	{
235
		// open the service
236
		SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
237
		if (schService==0) 
238
		{
239
			long nError = GetLastError();
240
			char pTemp[121];
241
			sprintf(pTemp, "OpenService failed, error code = %d", nError);
242
			WriteLog(pTemp);
243
		}
244
		else
245
		{
246
			// call ControlService to kill the given service
247
			SERVICE_STATUS status;
248
			if(ControlService(schService,SERVICE_CONTROL_STOP,&status))
249
			{
250
				CloseServiceHandle(schService); 
251
				CloseServiceHandle(schSCManager); 
252
				return TRUE;
253
			}
254
			else
255
			{
256
				long nError = GetLastError();
257
				char pTemp[121];
258
				sprintf(pTemp, "ControlService failed, error code = %d", nError);
259
				WriteLog(pTemp);
260
			}
261
			CloseServiceHandle(schService); 
262
		}
263
		CloseServiceHandle(schSCManager); 
264
	}
265
	return FALSE;
266
}
267
 
268
BOOL RunService(char* pName, int nArg, char** pArg) 
269
{ 
270
	// run service with given name
271
	SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); 
272
	if (schSCManager==0) 
273
	{
274
		long nError = GetLastError();
275
		char pTemp[121];
276
		sprintf(pTemp, "OpenSCManager failed, error code = %d", nError);
277
		WriteLog(pTemp);
278
	}
279
	else
280
	{
281
		// open the service
282
		SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
283
		if (schService==0) 
284
		{
285
			long nError = GetLastError();
286
			char pTemp[121];
287
			sprintf(pTemp, "OpenService failed, error code = %d", nError);
288
			WriteLog(pTemp);
289
		}
290
		else
291
		{
292
			// call StartService to run the service
293
			if(StartService(schService,nArg,(const char**)pArg))
294
			{
295
				CloseServiceHandle(schService); 
296
				CloseServiceHandle(schSCManager); 
297
				return TRUE;
298
			}
299
			else
300
			{
301
				long nError = GetLastError();
302
				char pTemp[121];
303
				sprintf(pTemp, "StartService failed, error code = %d", nError);
304
				WriteLog(pTemp);
305
			}
306
			CloseServiceHandle(schService); 
307
		}
308
		CloseServiceHandle(schSCManager); 
309
	}
310
	return FALSE;
311
}
312
 
313
////////////////////////////////////////////////////////////////////// 
314
//
315
// This routine gets used to start your service
316
//
317
VOID WINAPI XYNTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv )
318
{
319
	DWORD   status = 0; 
320
    DWORD   specificError = 0xfffffff; 
321
 
322
    serviceStatus.dwServiceType        = SERVICE_WIN32; 
323
    serviceStatus.dwCurrentState       = SERVICE_START_PENDING; 
324
    serviceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE; 
325
    serviceStatus.dwWin32ExitCode      = 0; 
326
    serviceStatus.dwServiceSpecificExitCode = 0; 
327
    serviceStatus.dwCheckPoint         = 0; 
328
    serviceStatus.dwWaitHint           = 0; 
329
 
330
    hServiceStatusHandle = RegisterServiceCtrlHandler(pServiceName, XYNTServiceHandler); 
331
    if (hServiceStatusHandle==0) 
332
    {
333
		long nError = GetLastError();
334
		char pTemp[121];
335
		sprintf(pTemp, "RegisterServiceCtrlHandler failed, error code = %d", nError);
336
		WriteLog(pTemp);
337
        return; 
338
    } 
339
 
340
    // Initialization complete - report running status 
341
    serviceStatus.dwCurrentState       = SERVICE_RUNNING; 
342
    serviceStatus.dwCheckPoint         = 0; 
343
    serviceStatus.dwWaitHint           = 0;  
344
    if(!SetServiceStatus(hServiceStatusHandle, &serviceStatus)) 
345
    { 
346
		long nError = GetLastError();
347
		char pTemp[121];
348
		sprintf(pTemp, "SetServiceStatus failed, error code = %d", nError);
349
		WriteLog(pTemp);
350
    } 
351
 
352
	for(int i=0;i<nMaxProcCount;i++)
353
	{
354
		pProcInfo[i].hProcess = 0;
355
		StartProcess(i);
356
	}
357
}
358
 
359
////////////////////////////////////////////////////////////////////// 
360
//
361
// This routine responds to events concerning your service, like start/stop
362
//
363
VOID WINAPI XYNTServiceHandler(DWORD fdwControl)
364
{
365
	switch(fdwControl) 
366
	{
367
		case SERVICE_CONTROL_STOP:
368
		case SERVICE_CONTROL_SHUTDOWN:
369
			serviceStatus.dwWin32ExitCode = 0; 
370
			serviceStatus.dwCurrentState  = SERVICE_STOPPED; 
371
			serviceStatus.dwCheckPoint    = 0; 
372
			serviceStatus.dwWaitHint      = 0;
373
			// terminate all processes started by this service before shutdown
374
			{
375
				for(int i=nMaxProcCount-1;i>=0;i--)
376
				{
377
					EndProcess(i);
378
				}			
379
				if (!SetServiceStatus(hServiceStatusHandle, &serviceStatus))
380
				{ 
381
					long nError = GetLastError();
382
					char pTemp[121];
383
					sprintf(pTemp, "SetServiceStatus failed, error code = %d", nError);
384
					WriteLog(pTemp);
385
				}
386
			}
387
			return; 
388
		case SERVICE_CONTROL_PAUSE:
389
			serviceStatus.dwCurrentState = SERVICE_PAUSED; 
390
			break;
391
		case SERVICE_CONTROL_CONTINUE:
392
			serviceStatus.dwCurrentState = SERVICE_RUNNING; 
393
			break;
394
		case SERVICE_CONTROL_INTERROGATE:
395
			break;
396
		default: 
397
			// bounce processes started by this service
398
			if(fdwControl>=128&&fdwControl<256)
399
			{
400
				int nIndex = fdwControl&0x7F;
401
				// bounce a single process
402
				if(nIndex>=0&&nIndex<nMaxProcCount)
403
				{
404
					EndProcess(nIndex);
405
					StartProcess(nIndex);
406
				}
407
				// bounce all processes
408
				else if(nIndex==127)
409
				{
410
					for(int i=nMaxProcCount-1;i>=0;i--)
411
					{
412
						EndProcess(i);
413
					}
414
					for(int i=0;i<nMaxProcCount;i++)
415
					{
416
						StartProcess(i);
417
					}
418
				}
419
			}
420
			else
421
			{
422
				long nError = GetLastError();
423
				char pTemp[121];
424
				sprintf(pTemp,  "Unrecognized opcode %d", fdwControl);
425
				WriteLog(pTemp);
426
			}
427
	};
428
    if (!SetServiceStatus(hServiceStatusHandle,  &serviceStatus)) 
429
	{ 
430
		long nError = GetLastError();
431
		char pTemp[121];
432
		sprintf(pTemp, "SetServiceStatus failed, error code = %d", nError);
433
		WriteLog(pTemp);
434
    } 
435
}
436
 
437
 
438
////////////////////////////////////////////////////////////////////// 
439
//
440
// Uninstall
441
//
442
VOID UnInstall(char* pName)
443
{
444
	SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); 
445
	if (schSCManager==0) 
446
	{
447
		long nError = GetLastError();
448
		char pTemp[121];
449
		sprintf(pTemp, "OpenSCManager failed, error code = %d", nError);
450
		WriteLog(pTemp);
451
	}
452
	else
453
	{
454
		SC_HANDLE schService = OpenService( schSCManager, pName, SERVICE_ALL_ACCESS);
455
		if (schService==0) 
456
		{
457
			long nError = GetLastError();
458
			char pTemp[121];
459
			sprintf(pTemp, "OpenService failed, error code = %d", nError);
460
			WriteLog(pTemp);
461
		}
462
		else
463
		{
464
			if(!DeleteService(schService)) 
465
			{
466
				char pTemp[121];
467
				sprintf(pTemp, "Failed to delete service %s", pName);
468
				WriteLog(pTemp);
469
			}
470
			else 
471
			{
472
				char pTemp[121];
473
				sprintf(pTemp, "Service %s removed",pName);
474
				WriteLog(pTemp);
475
			}
476
			CloseServiceHandle(schService); 
477
		}
478
		CloseServiceHandle(schSCManager);	
479
	}
480
}
481
 
482
////////////////////////////////////////////////////////////////////// 
483
//
484
// Install
485
//
486
VOID Install(char* pPath, char* pName) 
487
{  
488
	SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE); 
489
	if (schSCManager==0) 
490
	{
491
		long nError = GetLastError();
492
		char pTemp[121];
493
		sprintf(pTemp, "OpenSCManager failed, error code = %d", nError);
494
		WriteLog(pTemp);
495
	}
496
	else
497
	{
498
		SC_HANDLE schService = CreateService
499
		( 
500
			schSCManager,	/* SCManager database      */ 
501
			pName,			/* name of service         */ 
502
			pName,			/* service name to display */ 
503
			SERVICE_ALL_ACCESS,        /* desired access          */ 
504
			SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS , /* service type            */ 
505
			SERVICE_AUTO_START,      /* start type              */ 
506
			SERVICE_ERROR_NORMAL,      /* error control type      */ 
507
			pPath,			/* service's binary        */ 
508
			NULL,                      /* no load ordering group  */ 
509
			NULL,                      /* no tag identifier       */ 
510
			NULL,                      /* no dependencies         */ 
511
			NULL,                      /* LocalSystem account     */ 
512
			NULL
513
		);                     /* no password             */ 
514
		if (schService==0) 
515
		{
516
			long nError =  GetLastError();
517
			char pTemp[121];
518
			sprintf(pTemp, "Failed to create service %s, error code = %d", pName, nError);
519
			WriteLog(pTemp);
520
		}
521
		else
522
		{
523
			char pTemp[121];
524
			sprintf(pTemp, "Service %s installed", pName);
525
			WriteLog(pTemp);
526
			CloseServiceHandle(schService); 
527
		}
528
		CloseServiceHandle(schSCManager);
529
	}	
530
}
531
 
532
void WorkerProc(void* pParam)
533
{
534
	int nCheckProcessSeconds = 0;
535
	char pCheckProcess[nBufferSize+1];
536
	GetPrivateProfileString("Settings","CheckProcess","0",pCheckProcess, nBufferSize,pInitFile);
537
	int nCheckProcess = atoi(pCheckProcess);
538
	if(nCheckProcess>0) nCheckProcessSeconds = nCheckProcess*60;
539
	else
540
	{
541
		GetPrivateProfileString("Settings","CheckProcessSeconds","600",pCheckProcess, nBufferSize,pInitFile);
542
		nCheckProcessSeconds = atoi(pCheckProcess);
543
	}
544
	while(nCheckProcessSeconds>0)
545
	{
546
		::Sleep(1000*nCheckProcessSeconds);
547
		for(int i=0;i<nMaxProcCount;i++)
548
		{
549
			if(pProcInfo[i].hProcess)
550
			{
551
				char pItem[nBufferSize+1];
552
				sprintf(pItem,"Process%d\0",i);
553
				char pRestart[nBufferSize+1];
554
				GetPrivateProfileString(pItem,"Restart","No",pRestart,nBufferSize,pInitFile);
555
				if(pRestart[0]=='Y'||pRestart[0]=='y'||pRestart[0]=='1')
556
				{
557
					DWORD dwCode;
558
					if(::GetExitCodeProcess(pProcInfo[i].hProcess, &dwCode))
559
					{
560
						if(dwCode!=STILL_ACTIVE)
561
						{
562
							try // close handles to avoid ERROR_NO_SYSTEM_RESOURCES
563
							{
564
								::CloseHandle(pProcInfo[i].hThread);
565
								::CloseHandle(pProcInfo[i].hProcess);
566
							}
567
							catch(...) {}
568
							if(StartProcess(i))
569
							{
570
								char pTemp[121];
571
								sprintf(pTemp, "Restarted process %d", i);
572
								WriteLog(pTemp);
573
							}
574
						}
575
					}
576
					else
577
					{
578
						long nError = GetLastError();
579
						char pTemp[121];
580
						sprintf(pTemp, "GetExitCodeProcess failed, error code = %d", nError);
581
						WriteLog(pTemp);
582
					}
583
				}
584
			}
585
		}
586
	}
587
}
588
 
589
////////////////////////////////////////////////////////////////////// 
590
//
591
// Standard C Main
592
//
593
void main(int argc, char *argv[] )
594
{
595
	// initialize global critical section
596
	::InitializeCriticalSection(&myCS);
597
	// initialize variables for .exe, .ini, and .log file names
598
	char pModuleFile[nBufferSize+1];
599
	DWORD dwSize = GetModuleFileName(NULL,pModuleFile,nBufferSize);
600
	pModuleFile[dwSize] = 0;
601
	if(dwSize>4&&pModuleFile[dwSize-4]=='.')
602
	{
603
		sprintf(pExeFile,"%s",pModuleFile);
604
		pModuleFile[dwSize-4] = 0;
605
		sprintf(pInitFile,"%s.ini",pModuleFile);
606
		sprintf(pLogFile,"%s.log",pModuleFile);
607
	}
608
	else
609
	{
610
		printf("Invalid module file name: %s\r\n", pModuleFile);
611
		return;
612
	}
613
	WriteLog(pExeFile);
614
	WriteLog(pInitFile);
615
	WriteLog(pLogFile);
616
	// read service name from .ini file
617
	GetPrivateProfileString("Settings","ServiceName","XYNTService",pServiceName,nBufferSize,pInitFile);
618
	WriteLog(pServiceName);
619
	// uninstall service if switch is "-u"
620
	if(argc==2&&_stricmp("-u",argv[1])==0)
621
	{
622
		UnInstall(pServiceName);
623
	}
624
	// install service if switch is "-i"
625
	else if(argc==2&&_stricmp("-i",argv[1])==0)
626
	{			
627
		Install(pExeFile, pServiceName);
628
	}
629
	// bounce service if switch is "-b"
630
	else if(argc==2&&_stricmp("-b",argv[1])==0)
631
	{			
632
		KillService(pServiceName);
633
		RunService(pServiceName,0,NULL);
634
	}
635
	// bounce a specifc program if the index is supplied
636
	else if(argc==3&&_stricmp("-b",argv[1])==0)
637
	{
638
		int nIndex = atoi(argv[2]);
639
		if(BounceProcess(pServiceName, nIndex))
640
		{
641
			char pTemp[121];
642
			sprintf(pTemp, "Bounced process %d", nIndex);
643
			WriteLog(pTemp);
644
		}
645
		else
646
		{
647
			char pTemp[121];
648
			sprintf(pTemp, "Failed to bounce process %d", nIndex);
649
			WriteLog(pTemp);
650
		}
651
	}
652
	// kill a service with given name
653
	else if(argc==3&&_stricmp("-k",argv[1])==0)
654
	{
655
		if(KillService(argv[2]))
656
		{
657
			char pTemp[121];
658
			sprintf(pTemp, "Killed service %s", argv[2]);
659
			WriteLog(pTemp);
660
		}
661
		else
662
		{
663
			char pTemp[121];
664
			sprintf(pTemp, "Failed to kill service %s", argv[2]);
665
			WriteLog(pTemp);
666
		}
667
	}
668
	// run a service with given name
669
	else if(argc>=3&&_stricmp("-r",argv[1])==0)
670
	{
671
		if(RunService(argv[2], argc>3?(argc-3):0,argc>3?(&(argv[3])):NULL))
672
		{
673
			char pTemp[121];
674
			sprintf(pTemp, "Ran service %s", argv[2]);
675
			WriteLog(pTemp);
676
		}
677
		else
678
		{
679
			char pTemp[121];
680
			sprintf(pTemp, "Failed to run service %s", argv[2]);
681
			WriteLog(pTemp);
682
		}
683
	}
684
	// assume user is starting this service 
685
	else 
686
	{
687
		// start a worker thread to check for dead programs (and restart if necessary)
688
		if(_beginthread(WorkerProc, 0, NULL)==-1)
689
		{
690
			long nError = GetLastError();
691
			char pTemp[121];
692
			sprintf(pTemp, "_beginthread failed, error code = %d", nError);
693
			WriteLog(pTemp);
694
		}
695
		// pass dispatch table to service controller
696
		if(!StartServiceCtrlDispatcher(DispatchTable))
697
		{
698
			long nError = GetLastError();
699
			char pTemp[121];
700
			sprintf(pTemp, "StartServiceCtrlDispatcher failed, error code = %d", nError);
701
			WriteLog(pTemp);
702
		}
703
		// you don't get here unless the service is shutdown
704
	}
705
	::DeleteCriticalSection(&myCS);
706
}
707