00001 #ifdef WIN32
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <windows.h>
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <process.h>
00034 #include <tchar.h>
00035
00036 #include "service.h"
00037
00038
00039
00040
00041 SERVICE_STATUS ssStatus;
00042 SERVICE_STATUS_HANDLE sshStatusHandle;
00043 DWORD dwErr = 0;
00044 BOOL bDebug = FALSE;
00045 TCHAR szErr[256];
00046
00047
00048 VOID WINAPI service_ctrl(DWORD dwCtrlCode);
00049 VOID WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv);
00050 VOID CmdInstallService();
00051 VOID CmdRemoveService();
00052 VOID CmdDebugService(int argc, char **argv);
00053 BOOL WINAPI ControlHandler ( DWORD dwCtrlType );
00054 LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 void WINAPI service_main(DWORD dwArgc, LPTSTR *lpszArgv)
00076 {
00077
00078
00079
00080 sshStatusHandle = RegisterServiceCtrlHandler( TEXT(SZSERVICENAME), service_ctrl);
00081
00082 if (!sshStatusHandle)
00083 goto cleanup;
00084
00085
00086
00087 ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
00088 ssStatus.dwServiceSpecificExitCode = 0;
00089
00090
00091
00092
00093 if (!ReportStatusToSCMgr(
00094 SERVICE_START_PENDING,
00095 NO_ERROR,
00096 3000))
00097 goto cleanup;
00098
00099
00100 ServiceStart( dwArgc, lpszArgv );
00101
00102 cleanup:
00103
00104
00105
00106 if (sshStatusHandle)
00107 (VOID)ReportStatusToSCMgr(
00108 SERVICE_STOPPED,
00109 dwErr,
00110 0);
00111
00112 return;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 VOID WINAPI service_ctrl(DWORD dwCtrlCode)
00132 {
00133
00134
00135 switch(dwCtrlCode)
00136 {
00137
00138
00139
00140
00141
00142
00143
00144 case SERVICE_CONTROL_STOP:
00145 ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 0);
00146 ServiceStop();
00147 return;
00148
00149
00150
00151 case SERVICE_CONTROL_INTERROGATE:
00152 break;
00153
00154
00155
00156 default:
00157 break;
00158
00159 }
00160
00161 ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
00184 DWORD dwWin32ExitCode,
00185 DWORD dwWaitHint)
00186 {
00187 static DWORD dwCheckPoint = 1;
00188 BOOL fResult = TRUE;
00189
00190
00191 if ( !bDebug )
00192 {
00193 if (dwCurrentState == SERVICE_START_PENDING)
00194 ssStatus.dwControlsAccepted = 0;
00195 else
00196 ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
00197
00198 ssStatus.dwCurrentState = dwCurrentState;
00199 ssStatus.dwWin32ExitCode = dwWin32ExitCode;
00200 ssStatus.dwWaitHint = dwWaitHint;
00201
00202 if ( ( dwCurrentState == SERVICE_RUNNING ) ||
00203 ( dwCurrentState == SERVICE_STOPPED ) )
00204 ssStatus.dwCheckPoint = 0;
00205 else
00206 ssStatus.dwCheckPoint = dwCheckPoint++;
00207
00208
00209
00210
00211 if (!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus))) {
00212 AddToMessageLog(TEXT("SetServiceStatus"));
00213 }
00214 }
00215 return fResult;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 VOID AddToMessageLog(LPTSTR lpszMsg)
00234 {
00235 TCHAR szMsg[256];
00236 HANDLE hEventSource;
00237 LPTSTR lpszStrings[2];
00238
00239
00240 if ( !bDebug )
00241 {
00242 dwErr = GetLastError();
00243
00244
00245
00246 hEventSource = RegisterEventSource(NULL, TEXT(SZSERVICENAME));
00247
00248 _stprintf(szMsg, TEXT("%s error: %d"), TEXT(SZSERVICENAME), dwErr);
00249 lpszStrings[0] = szMsg;
00250 lpszStrings[1] = lpszMsg;
00251
00252 if (hEventSource != NULL) {
00253 ReportEvent(hEventSource,
00254 EVENTLOG_ERROR_TYPE,
00255 0,
00256 0,
00257 NULL,
00258 2,
00259 0,
00260 lpszStrings,
00261 NULL);
00262
00263 (VOID) DeregisterEventSource(hEventSource);
00264 }
00265 }
00266 }
00267
00268
00269
00270
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 void CmdInstallService(){
00291 SC_HANDLE schService;
00292 SC_HANDLE schSCManager;
00293
00294 TCHAR szPath[512];
00295
00296 if( GetModuleFileName( NULL, szPath, 512 ) == 0 ){
00297 _tprintf(TEXT("Unable to install %s - %s\n"), TEXT(SZSERVICEDISPLAYNAME), GetLastErrorText(szErr, 256));
00298 return;
00299 }
00300
00301 schSCManager = OpenSCManager(
00302 NULL,
00303 NULL,
00304 SC_MANAGER_ALL_ACCESS
00305 );
00306 if( ! schSCManager ){
00307 _tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(szErr, 256));
00308 return;
00309 }
00310 schService = CreateService(
00311 schSCManager,
00312 TEXT(SZSERVICENAME),
00313 TEXT(SZSERVICEDISPLAYNAME),
00314 SERVICE_ALL_ACCESS,
00315 SERVICE_WIN32_OWN_PROCESS,
00316 SERVICE_DEMAND_START,
00317 SERVICE_ERROR_NORMAL,
00318 szPath,
00319 NULL,
00320 NULL,
00321 TEXT(SZDEPENDENCIES),
00322 NULL,
00323 NULL);
00324
00325 if( schService ){
00326 _tprintf(TEXT("%s installed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
00327 CloseServiceHandle(schService);
00328 }
00329 CloseServiceHandle(schSCManager);
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 void CmdRemoveService()
00348 {
00349 SC_HANDLE schService;
00350 SC_HANDLE schSCManager;
00351
00352 schSCManager = OpenSCManager(
00353 NULL,
00354 NULL,
00355 SC_MANAGER_ALL_ACCESS
00356 );
00357 if ( schSCManager )
00358 {
00359 schService = OpenService(schSCManager, TEXT(SZSERVICENAME), SERVICE_ALL_ACCESS);
00360
00361 if (schService)
00362 {
00363
00364 if ( ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus ) )
00365 {
00366 _tprintf(TEXT("Stopping %s."), TEXT(SZSERVICEDISPLAYNAME));
00367 Sleep( 1000 );
00368
00369 while( QueryServiceStatus( schService, &ssStatus ) )
00370 {
00371 if ( ssStatus.dwCurrentState == SERVICE_STOP_PENDING )
00372 {
00373 _tprintf(TEXT("."));
00374 Sleep( 1000 );
00375 }
00376 else
00377 break;
00378 }
00379
00380 if ( ssStatus.dwCurrentState == SERVICE_STOPPED )
00381 _tprintf(TEXT("\n%s stopped.\n"), TEXT(SZSERVICEDISPLAYNAME) );
00382 else
00383 _tprintf(TEXT("\n%s failed to stop.\n"), TEXT(SZSERVICEDISPLAYNAME) );
00384
00385 }
00386
00387
00388 if( DeleteService(schService) )
00389 _tprintf(TEXT("%s removed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
00390 else
00391 _tprintf(TEXT("DeleteService failed - %s\n"), GetLastErrorText(szErr,256));
00392
00393
00394 CloseServiceHandle(schService);
00395 }
00396 else
00397 _tprintf(TEXT("OpenService failed - %s\n"), GetLastErrorText(szErr,256));
00398
00399 CloseServiceHandle(schSCManager);
00400 }
00401 else
00402 _tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
00403 }
00404
00405
00406
00407
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 void CmdDebugService(int argc, char ** argv)
00429 {
00430 DWORD dwArgc;
00431 LPTSTR *lpszArgv;
00432
00433 #ifdef UNICODE
00434 lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) );
00435 #else
00436 dwArgc = (DWORD) argc;
00437 lpszArgv = argv;
00438 #endif
00439
00440 _tprintf(TEXT("Debugging %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
00441
00442 SetConsoleCtrlHandler( ControlHandler, TRUE );
00443
00444 ServiceStart( dwArgc, lpszArgv );
00445 }
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 BOOL WINAPI ControlHandler ( DWORD dwCtrlType )
00463 {
00464 switch( dwCtrlType )
00465 {
00466 case CTRL_BREAK_EVENT:
00467 case CTRL_C_EVENT:
00468 _tprintf(TEXT("Stopping %s.\n"), TEXT(SZSERVICEDISPLAYNAME));
00469 ServiceStop();
00470 return TRUE;
00471 break;
00472
00473 }
00474 return FALSE;
00475 }
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize )
00492 {
00493 DWORD dwRet;
00494 LPTSTR lpszTemp = NULL;
00495
00496 dwRet = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
00497 NULL,
00498 GetLastError(),
00499 LANG_NEUTRAL,
00500 (LPTSTR)&lpszTemp,
00501 0,
00502 NULL );
00503
00504
00505 if ( !dwRet || ( (long)dwSize < (long)dwRet+14 ) )
00506 lpszBuf[0] = TEXT('\0');
00507 else
00508 {
00509 lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0');
00510 _stprintf( lpszBuf, TEXT("%s (0x%x)"), lpszTemp, GetLastError() );
00511 }
00512
00513 if ( lpszTemp )
00514 LocalFree((HLOCAL) lpszTemp );
00515
00516 return lpszBuf;
00517 }
00518 #else
00519 #include <stdio.h>
00520 static dummy(){
00521 printf("hello\n");
00522 }
00523 #endif