00001
00002
00003
00004
00005
00006
00007 #ifdef WIN32
00008
00009 #include <windows.h>
00010 #include <tchar.h>
00011
00012 #include <stdio.h>
00013 #include <process.h>
00014
00015 #include <net-snmp/library/winservice.h>
00016
00017 #ifdef mingw32
00018
00019 #define TRY if(1)
00020 #define LEAVE goto labelFIN
00021 #define FINALLY do { \
00022 labelFIN: \
00023 ; \
00024 } while(0); if(1)
00025
00026 #else
00027
00028 #define TRY __try
00029 #define LEAVE __leave
00030 #define FINALLY __finally
00031
00032 #endif
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 extern LPTSTR app_name_long;
00044
00045
00046
00047
00048
00049
00050
00051
00052 BOOL g_fRunningAsService = FALSE;
00053
00054
00055
00056
00057 static SERVICE_STATUS ServiceStatus;
00058
00059
00060
00061
00062 static SERVICE_STATUS_HANDLE hServiceStatus = 0L;
00063
00064
00065
00066
00067 SERVICE_TABLE_ENTRY ServiceTableEntry[] = {
00068 {NULL, ServiceMain},
00069 {NULL, NULL}
00070 };
00071
00072
00073
00074
00075 static HANDLE hServiceThread = NULL;
00076
00077
00078
00079
00080
00081 static INT (*ServiceEntryPoint) (INT Argc, LPTSTR Argv[]) = 0L;
00082
00083
00084
00085
00086
00087 static VOID (*StopFunction) (VOID) = 0L;
00088
00089 VOID
00090 ProcessError (WORD eventLogType, LPCTSTR pszMessage, int useGetLastError, int quiet);
00091
00092
00093
00094
00095
00096
00097 int
00098 RegisterService (LPCTSTR lpszServiceName, LPCTSTR lpszServiceDisplayName,
00099 LPCTSTR lpszServiceDescription,
00100 InputParams * StartUpArg, int quiet)
00101 {
00102 TCHAR szServicePath[MAX_PATH];
00103 TCHAR MsgErrorString[MAX_STR_SIZE];
00104 TCHAR szServiceCommand[MAX_PATH + 9];
00105 SC_HANDLE hSCManager = NULL;
00106 SC_HANDLE hService = NULL;
00107 TCHAR szRegAppLogKey[] =
00108 "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
00109 TCHAR szRegKey[512];
00110 HKEY hKey = NULL;
00111 HKEY hParamKey = NULL;
00112 DWORD dwData;
00113 DWORD i, j;
00114 int exitStatus = 0;
00115 GetModuleFileName (NULL, szServicePath, MAX_PATH);
00116 TRY
00117 {
00118
00119
00120
00121
00122 hSCManager = OpenSCManager (NULL, NULL, SC_MANAGER_CREATE_SERVICE);
00123 if (hSCManager == NULL)
00124 {
00125 ProcessError (EVENTLOG_ERROR_TYPE, _T ("Can't open SCM (Service Control Manager)"), 1, quiet);
00126 exitStatus = SERVICE_ERROR_SCM_OPEN;
00127 LEAVE;
00128 }
00129
00130
00131
00132
00133 _snprintf (szServiceCommand, sizeof(szServiceCommand), "%s %s", szServicePath, _T ("-service"));
00134
00135
00136
00137
00138 hService = CreateService (hSCManager, lpszServiceName, lpszServiceDisplayName,
00139 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
00140 SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, szServiceCommand,
00141 NULL,
00142 NULL,
00143 NULL,
00144 NULL,
00145 NULL);
00146 if (hService == NULL)
00147 {
00148 _snprintf (MsgErrorString, sizeof(MsgErrorString), "%s %s",
00149 _T ("Can't create service"), lpszServiceDisplayName);
00150 ProcessError (EVENTLOG_ERROR_TYPE, MsgErrorString, 1, quiet);
00151
00152 exitStatus = SERVICE_ERROR_CREATE_SERVICE;
00153 LEAVE;
00154 }
00155
00156
00157
00158
00159
00160
00161
00162 _tcscpy (szRegKey, szRegAppLogKey);
00163 _tcscat (szRegKey, lpszServiceName);
00164
00165
00166
00167
00168 if (RegCreateKey (HKEY_LOCAL_MACHINE, szRegKey, &hKey) != ERROR_SUCCESS)
00169 {
00170 _snprintf (MsgErrorString, sizeof(MsgErrorString), "%s %s",
00171 _T ("is unable to create registry entries"), lpszServiceDisplayName);
00172 ProcessError (EVENTLOG_ERROR_TYPE, MsgErrorString, 1, quiet);
00173 exitStatus = SERVICE_ERROR_CREATE_REGISTRY_ENTRIES;
00174 LEAVE;
00175 }
00176
00177
00178
00179
00180 RegSetValueEx (hKey, "EventMessageFile", 0, REG_EXPAND_SZ,
00181 (CONST BYTE *) szServicePath,
00182 _tcslen (szServicePath) + sizeof (TCHAR));
00183
00184
00185
00186
00187 dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
00188 RegSetValueEx (hKey, "TypesSupported", 0, REG_DWORD,
00189 (CONST BYTE *) & dwData, sizeof (DWORD));
00190
00191
00192
00193
00194 RegCloseKey (hKey);
00195
00196
00197
00198
00199 if (lpszServiceDescription != NULL || StartUpArg->Argc > 2)
00200 {
00201
00202
00203
00204 _tcscpy (szRegKey, _T ("SYSTEM\\CurrentControlSet\\Services\\"));
00205 _tcscat (szRegKey, app_name_long);
00206 hKey = NULL;
00207
00208
00209
00210
00211 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_WRITE,
00212 &hKey) != ERROR_SUCCESS)
00213 {
00214 _snprintf (MsgErrorString, sizeof(MsgErrorString), "%s %s",
00215 _T ("is unable to create registry entries"),
00216 lpszServiceDisplayName);
00217 ProcessError (EVENTLOG_ERROR_TYPE, MsgErrorString, 1, quiet);
00218 exitStatus = SERVICE_ERROR_CREATE_REGISTRY_ENTRIES;
00219 LEAVE;
00220 }
00221
00222
00223
00224
00225 if (lpszServiceDescription != NULL)
00226 {
00227 if (RegSetValueEx (hKey, "Description", 0, REG_SZ,
00228 (CONST BYTE *) lpszServiceDescription,
00229 _tcslen (lpszServiceDescription) +
00230 sizeof (TCHAR)) != ERROR_SUCCESS)
00231 {
00232 _snprintf (MsgErrorString, sizeof(MsgErrorString), "%s %s",
00233 _T ("is unable to create registry entries"),
00234 lpszServiceDisplayName);
00235 ProcessError (EVENTLOG_ERROR_TYPE, MsgErrorString, 1, quiet);
00236 exitStatus = SERVICE_ERROR_CREATE_REGISTRY_ENTRIES;
00237 LEAVE;
00238 };
00239 }
00240
00241
00242
00243
00244 if (StartUpArg->Argc > 2)
00245 {
00246
00247
00248
00249 if (RegCreateKeyEx
00250 (hKey, "Parameters", 0, NULL,
00251 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
00252 &hParamKey, NULL) != ERROR_SUCCESS)
00253 {
00254 _snprintf (MsgErrorString, sizeof(MsgErrorString), "%s %s",
00255 _T ("is unable to create registry entries"),
00256 lpszServiceDisplayName);
00257 ProcessError (EVENTLOG_ERROR_TYPE, MsgErrorString, 1, quiet);
00258 exitStatus = SERVICE_ERROR_CREATE_REGISTRY_ENTRIES;
00259 LEAVE;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269 if (quiet)
00270 i = 3;
00271 else
00272 i = 2;
00273
00274 for (j = 1; i < StartUpArg->Argc; i++, j++)
00275 {
00276 _snprintf (szRegKey, sizeof(szRegKey), "%s%d", _T ("Param"), j);
00277
00278
00279
00280
00281 if (RegSetValueEx
00282 (hParamKey, szRegKey, 0, REG_SZ,
00283 (CONST BYTE *) StartUpArg->Argv[i],
00284 _tcslen (StartUpArg->Argv[i]) +
00285 sizeof (TCHAR)) != ERROR_SUCCESS)
00286 {
00287 _snprintf (MsgErrorString, sizeof(MsgErrorString), "%s %s",
00288 _T ("is unable to create registry entries"),
00289 lpszServiceDisplayName);
00290 ProcessError (EVENTLOG_ERROR_TYPE, MsgErrorString, 1, quiet);
00291 exitStatus = SERVICE_ERROR_CREATE_REGISTRY_ENTRIES;
00292 LEAVE;
00293 };
00294 }
00295 }
00296
00297
00298
00299
00300 RegCloseKey (hParamKey);
00301 RegCloseKey (hKey);
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311 _snprintf (MsgErrorString, sizeof(MsgErrorString), "%s %s", lpszServiceName,
00312 _T ("successfully registered as a service"));
00313
00314
00315
00316
00317 ProcessError (EVENTLOG_INFORMATION_TYPE, MsgErrorString, 0, quiet);
00318 }
00319
00320 FINALLY
00321 {
00322 if (hSCManager)
00323 CloseServiceHandle (hSCManager);
00324 if (hService)
00325 CloseServiceHandle (hService);
00326 if (hKey)
00327 RegCloseKey (hKey);
00328 if (hParamKey)
00329 RegCloseKey (hParamKey);
00330 }
00331 return (exitStatus);
00332 }
00333
00334
00335
00336
00337
00338 int
00339 UnregisterService (LPCSTR lpszServiceName, int quiet)
00340 {
00341 TCHAR MsgErrorString[MAX_STR_SIZE];
00342 SC_HANDLE hSCManager = NULL;
00343 SC_HANDLE hService = NULL;
00344 SERVICE_STATUS sStatus;
00345 TCHAR szRegAppLogKey[] =
00346 "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
00347 TCHAR szRegKey[512];
00348 int exitStatus = 0;
00349
00350 TRY
00351 {
00352
00353
00354
00355 hSCManager = OpenSCManager (NULL, NULL, SC_MANAGER_CREATE_SERVICE);
00356 if (hSCManager == NULL)
00357 {
00358 ProcessError (EVENTLOG_ERROR_TYPE, _T ("Can't open SCM (Service Control Manager)"), 1, quiet);
00359 exitStatus = SERVICE_ERROR_SCM_OPEN;
00360 LEAVE;
00361 }
00362
00363
00364
00365
00366 hService = OpenService (hSCManager, lpszServiceName, SERVICE_ALL_ACCESS);
00367 if (hService == NULL)
00368 {
00369 _snprintf (MsgErrorString, sizeof(MsgErrorString), "%s %s", _T ("Can't open service"),
00370 lpszServiceName);
00371 ProcessError (EVENTLOG_ERROR_TYPE, MsgErrorString, 1, quiet);
00372 exitStatus = SERVICE_ERROR_OPEN_SERVICE;
00373 LEAVE;
00374 }
00375
00376
00377
00378
00379
00380 if (QueryServiceStatus (hService, &sStatus))
00381 {
00382 if (sStatus.dwCurrentState == SERVICE_RUNNING
00383 || sStatus.dwCurrentState == SERVICE_PAUSED)
00384 {
00385 ControlService (hService, SERVICE_CONTROL_STOP, &sStatus);
00386 }
00387 };
00388
00389
00390
00391
00392 if (DeleteService (hService) == FALSE)
00393 {
00394 _snprintf (MsgErrorString, sizeof(MsgErrorString), "%s %s", _T ("Can't delete service"),
00395 lpszServiceName);
00396
00397
00398
00399
00400 ProcessError (EVENTLOG_ERROR_TYPE, MsgErrorString, 0, quiet);
00401 LEAVE;
00402 }
00403
00404
00405
00406
00407 _snprintf (MsgErrorString, sizeof(MsgErrorString), "%s %s", lpszServiceName, _T ("service deleted"));
00408 ProcessError (EVENTLOG_INFORMATION_TYPE, MsgErrorString, 0, quiet);
00409
00410
00411
00412
00413 _tcscpy (szRegKey, szRegAppLogKey);
00414 _tcscat (szRegKey, lpszServiceName);
00415 RegDeleteKey (HKEY_LOCAL_MACHINE, szRegKey);
00416 }
00417
00418
00419
00420
00421 FINALLY
00422 {
00423 if (hService)
00424 CloseServiceHandle (hService);
00425 if (hSCManager)
00426 CloseServiceHandle (hSCManager);
00427 }
00428 return (exitStatus);
00429 }
00430
00431
00432
00433
00434
00435 VOID
00436 WriteToEventLog (WORD wType, LPCTSTR pszFormat, ...)
00437 {
00438 TCHAR szMessage[512];
00439 LPTSTR LogStr[1];
00440 va_list ArgList;
00441 HANDLE hEventSource = NULL;
00442 va_start (ArgList, pszFormat);
00443 _vsnprintf (szMessage, sizeof(szMessage), pszFormat, ArgList);
00444 va_end (ArgList);
00445 LogStr[0] = szMessage;
00446 hEventSource = RegisterEventSource (NULL, app_name_long);
00447 if (hEventSource == NULL)
00448 return;
00449 ReportEvent (hEventSource, wType, 0,
00450 DISPLAY_MSG,
00451 NULL, 1, 0, LogStr, NULL);
00452 DeregisterEventSource (hEventSource);
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 INT
00466 ParseCmdLineForServiceOption (int argc, TCHAR * argv[], int *quiet)
00467 {
00468 int nReturn = RUN_AS_CONSOLE;
00469
00470 if (argc >= 2)
00471 {
00472
00473
00474
00475
00476 if (lstrcmpi (_T ("-register"), argv[1]) == 0)
00477 {
00478 nReturn = REGISTER_SERVICE;
00479 }
00480
00481 else if (lstrcmpi (_T ("-unregister"), argv[1]) == 0)
00482 {
00483 nReturn = UN_REGISTER_SERVICE;
00484 }
00485
00486 else if (lstrcmpi (_T ("-service"), argv[1]) == 0)
00487 {
00488 nReturn = RUN_AS_SERVICE;
00489 }
00490 }
00491
00492 if (argc >= 3)
00493 {
00494
00495
00496
00497 if (lstrcmpi (_T ("-quiet"), argv[2]) == 0)
00498 {
00499 *quiet = 1;
00500 }
00501 }
00502
00503 return nReturn;
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 VOID
00520 ProcessError (WORD eventLogType, LPCTSTR pszMessage, int useGetLastError, int quiet)
00521 {
00522 LPTSTR pErrorMsgTemp = NULL;
00523 HANDLE hEventSource = NULL;
00524 TCHAR pszMessageFull[MAX_STR_SIZE];
00525
00526
00527
00528
00529
00530 if (useGetLastError) {
00531 FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
00532 FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError (),
00533 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
00534 (LPTSTR) & pErrorMsgTemp, 0, NULL);
00535
00536 _snprintf (pszMessageFull, sizeof(pszMessageFull), "%s: %s", pszMessage, pErrorMsgTemp);
00537 if (pErrorMsgTemp) {
00538 LocalFree (pErrorMsgTemp);
00539 pErrorMsgTemp = NULL;
00540 }
00541 }
00542 else {
00543 _snprintf (pszMessageFull, sizeof(pszMessageFull), "%s", pszMessage);
00544 }
00545
00546 hEventSource = RegisterEventSource (NULL, app_name_long);
00547 if (hEventSource != NULL) {
00548 pErrorMsgTemp = pszMessageFull;
00549
00550 if (ReportEvent (hEventSource,
00551 eventLogType,
00552 0,
00553 DISPLAY_MSG,
00554 NULL,
00555 1,
00556 0,
00557 &pErrorMsgTemp,
00558 NULL)) {
00559 }
00560 else {
00561 FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
00562 FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError (),
00563 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
00564 (LPTSTR) & pErrorMsgTemp, 0, NULL);
00565
00566 fprintf(stderr,"Could NOT lot to Event Log. Error returned from ReportEvent(): %s\n",pErrorMsgTemp);
00567 if (pErrorMsgTemp) {
00568 LocalFree (pErrorMsgTemp);
00569 pErrorMsgTemp = NULL;
00570 }
00571 }
00572 DeregisterEventSource (hEventSource);
00573 }
00574
00575 if (quiet) {
00576 fprintf(stderr,"%s\n",pszMessageFull);
00577 }
00578 else {
00579 switch (eventLogType) {
00580 case EVENTLOG_INFORMATION_TYPE:
00581 MessageBox (NULL, pszMessageFull, app_name_long, MB_ICONASTERISK);
00582 break;
00583 case EVENTLOG_WARNING_TYPE:
00584 MessageBox (NULL, pszMessageFull, app_name_long, MB_ICONEXCLAMATION);
00585 break;
00586 case EVENTLOG_ERROR_TYPE:
00587 MessageBox (NULL, pszMessageFull, app_name_long, MB_ICONSTOP);
00588 break;
00589 default:
00590 MessageBox (NULL, pszMessageFull, app_name_long, EVENTLOG_WARNING_TYPE);
00591 break;
00592 }
00593 }
00594
00595 LocalFree (pErrorMsgTemp);
00596 }
00597
00598
00599
00600
00601
00602
00603 static BOOL
00604 UpdateServiceStatus (DWORD dwStatus, DWORD dwErrorCode, DWORD dwWaitHint)
00605 {
00606 DWORD static dwCheckpoint = 1;
00607 DWORD dwControls = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
00608 if (g_fRunningAsService == FALSE)
00609 return FALSE;
00610 ZeroMemory (&ServiceStatus, sizeof (ServiceStatus));
00611 ServiceStatus.dwServiceType = SERVICE_WIN32;
00612 ServiceStatus.dwCurrentState = dwStatus;
00613 ServiceStatus.dwWaitHint = dwWaitHint;
00614 if (dwErrorCode)
00615 {
00616 ServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
00617 ServiceStatus.dwServiceSpecificExitCode = dwErrorCode;
00618 }
00619
00620
00621
00622
00623 switch (dwStatus)
00624 {
00625 case SERVICE_START_PENDING:
00626 dwControls = 0;
00627 break;
00628 case SERVICE_RUNNING:
00629 case SERVICE_STOPPED:
00630 dwCheckpoint = 0;
00631 break;
00632 }
00633 ServiceStatus.dwCheckPoint = dwCheckpoint++;
00634 ServiceStatus.dwControlsAccepted = dwControls;
00635 return ReportCurrentServiceStatus ();
00636 }
00637
00638
00639
00640
00641 static BOOL
00642 ReportCurrentServiceStatus ()
00643 {
00644 return SetServiceStatus (hServiceStatus, &ServiceStatus);
00645 }
00646
00647
00648
00649
00650 VOID WINAPI
00651 ServiceMain (DWORD argc, LPTSTR argv[])
00652 {
00653 SECURITY_ATTRIBUTES SecurityAttributes;
00654 DWORD dwThreadId;
00655
00656
00657
00658
00659 DWORD ArgCount = 0;
00660 LPTSTR *ArgArray = NULL;
00661 TCHAR szRegKey[512];
00662 TCHAR szValue[128];
00663 DWORD nSize;
00664 HKEY hParamKey = NULL;
00665 DWORD TotalParams = 0;
00666 DWORD i;
00667 InputParams ThreadInputParams;
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 ArgCount = 1;
00682
00683
00684
00685
00686 _snprintf (szRegKey, sizeof(szRegKey), "%s%s\\%s",
00687 _T ("SYSTEM\\CurrentControlSet\\Services\\"), app_name_long,
00688 "Parameters");
00689 if (RegOpenKeyEx
00690 (HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_ALL_ACCESS, &hParamKey) == ERROR_SUCCESS)
00691 {
00692
00693
00694
00695
00696
00697
00698
00699 if (RegQueryInfoKey (hParamKey, NULL, NULL, 0,
00700 NULL, NULL, NULL, &TotalParams,
00701 NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
00702 {
00703 if (TotalParams != 0)
00704 {
00705 ArgCount += TotalParams;
00706
00707
00708
00709
00710 ArgArray = (LPTSTR *) malloc (sizeof (LPTSTR) * ArgCount);
00711 if (ArgArray == 0)
00712 {
00713 WriteToEventLog (EVENTLOG_ERROR_TYPE,
00714 _T ("Resource failure"));
00715 return;
00716 }
00717
00718
00719
00720
00721 ArgArray[0] = _tcsdup (argv[0]);
00722 for (i = 1; i <= TotalParams; i++)
00723 {
00724
00725
00726
00727
00728 _snprintf (szRegKey, sizeof(szRegKey), "%s%d", "Param", i);
00729
00730
00731
00732
00733 nSize = 128;
00734 RegQueryValueEx (hParamKey, szRegKey, 0, NULL,
00735 (LPBYTE) & szValue, &nSize);
00736 ArgArray[i] = _tcsdup (szValue);
00737 }
00738 }
00739 }
00740 RegCloseKey (hParamKey);
00741 }
00742 if (ArgCount == 1)
00743 {
00744
00745
00746
00747
00748 ThreadInputParams.Argc = argc;
00749 ThreadInputParams.Argv = argv;
00750 }
00751
00752 else
00753 {
00754 ThreadInputParams.Argc = ArgCount;
00755 ThreadInputParams.Argv = ArgArray;
00756 }
00757
00758
00759
00760
00761 hServiceStatus = RegisterServiceCtrlHandler (app_name_long, ControlHandler);
00762 if (hServiceStatus == 0)
00763 {
00764 WriteToEventLog (EVENTLOG_ERROR_TYPE,
00765 _T ("RegisterServiceCtrlHandler failed"));
00766 return;
00767 }
00768
00769
00770
00771
00772 UpdateServiceStatus (SERVICE_START_PENDING, NO_ERROR, SCM_WAIT_INTERVAL);
00773
00774
00775
00776
00777 TRY
00778 {
00779 if (SetSimpleSecurityAttributes (&SecurityAttributes) == FALSE)
00780 {
00781 WriteToEventLog (EVENTLOG_ERROR_TYPE,
00782 _T ("Couldn't init security attributes"));
00783 LEAVE;
00784 }
00785 hServiceThread =
00786 (void *) _beginthreadex (&SecurityAttributes, 0,
00787 ThreadFunction,
00788 (void *) &ThreadInputParams, 0, &dwThreadId);
00789 if (hServiceThread == NULL)
00790 {
00791 WriteToEventLog (EVENTLOG_ERROR_TYPE, _T ("Couldn't start worker thread"));
00792 LEAVE;
00793 }
00794
00795
00796
00797
00798 UpdateServiceStatus (SERVICE_RUNNING, NO_ERROR, SCM_WAIT_INTERVAL);
00799
00800
00801
00802
00803
00804 WaitForSingleObject (hServiceThread, INFINITE);
00805 }
00806 FINALLY
00807 {
00808
00809
00810
00811 UpdateServiceStatus (SERVICE_STOPPED, NO_ERROR, SCM_WAIT_INTERVAL);
00812 if (hServiceThread)
00813 CloseHandle (hServiceThread);
00814 FreeSecurityAttributes (&SecurityAttributes);
00815
00816
00817
00818
00819 if (ArgCount > 1 && ArgArray != NULL)
00820 {
00821
00822
00823
00824 for (i = 0; i < ArgCount; i++)
00825 {
00826 free (ArgArray[i]);
00827 }
00828 free (ArgArray);
00829 }
00830 }
00831 }
00832
00833
00834
00835
00836
00837
00838 BOOL
00839 RunAsService (INT (*ServiceFunction) (INT, LPTSTR *))
00840 {
00841
00842
00843
00844
00845 ServiceEntryPoint = ServiceFunction;
00846
00847
00848
00849
00850 g_fRunningAsService = TRUE;
00851
00852
00853
00854
00855 ServiceTableEntry[0].lpServiceName = app_name_long;
00856
00857
00858
00859
00860
00861 if (StartServiceCtrlDispatcher (ServiceTableEntry) == FALSE)
00862 {
00863 g_fRunningAsService = FALSE;
00864
00865
00866
00867
00868 WriteToEventLog (EVENTLOG_ERROR_TYPE,
00869 _T ("Couldn't start service - %s"), app_name_long);
00870 }
00871 return g_fRunningAsService;
00872 }
00873
00874
00875
00876
00877
00878
00879
00880 VOID WINAPI
00881 ControlHandler (DWORD dwControl)
00882 {
00883 switch (dwControl)
00884 {
00885 case SERVICE_CONTROL_INTERROGATE:
00886 ProcessServiceInterrogate ();
00887 break;
00888
00889 case SERVICE_CONTROL_PAUSE:
00890 ProcessServicePause ();
00891 break;
00892
00893 case SERVICE_CONTROL_CONTINUE:
00894 ProcessServiceContinue ();
00895 break;
00896
00897 case SERVICE_CONTROL_STOP:
00898 ProcessServiceStop ();
00899 break;
00900 }
00901 }
00902
00903
00904
00905
00906
00907
00908
00909
00910 VOID
00911 ProcessServiceStop (VOID)
00912 {
00913 UpdateServiceStatus (SERVICE_STOP_PENDING, NO_ERROR, SCM_WAIT_INTERVAL);
00914
00915 if (StopFunction != NULL)
00916 {
00917 (*StopFunction) ();
00918 }
00919
00920 else
00921 {
00922 TerminateThread (hServiceThread, 0);
00923 }
00924 }
00925
00926
00927
00928
00929 VOID
00930 ProcessServiceInterrogate (VOID)
00931 {
00932 ReportCurrentServiceStatus ();
00933 }
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943 BOOL
00944 SetSimpleSecurityAttributes (SECURITY_ATTRIBUTES * pSecurityAttr)
00945 {
00946 BOOL fReturn = FALSE;
00947 SECURITY_DESCRIPTOR *pSecurityDesc = NULL;
00948
00949
00950
00951
00952
00953 if (!pSecurityAttr)
00954 return FALSE;
00955 pSecurityDesc =
00956 (SECURITY_DESCRIPTOR *) LocalAlloc (LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
00957 if (!pSecurityDesc)
00958 return FALSE;
00959 fReturn =
00960 InitializeSecurityDescriptor (pSecurityDesc, SECURITY_DESCRIPTOR_REVISION);
00961 if (fReturn != FALSE)
00962 {
00963 fReturn = SetSecurityDescriptorDacl (pSecurityDesc, TRUE, NULL, FALSE);
00964 }
00965 if (fReturn != FALSE)
00966 {
00967 pSecurityAttr->nLength = sizeof (SECURITY_ATTRIBUTES);
00968 pSecurityAttr->lpSecurityDescriptor = pSecurityDesc;
00969 pSecurityAttr->bInheritHandle = TRUE;
00970 }
00971
00972 else
00973 {
00974
00975
00976
00977 LocalFree (pSecurityDesc);
00978 }
00979 return fReturn;
00980 }
00981
00982
00983
00984
00985 VOID
00986 FreeSecurityAttributes (SECURITY_ATTRIBUTES * pSecurityAttr)
00987 {
00988 if (pSecurityAttr && pSecurityAttr->lpSecurityDescriptor)
00989 LocalFree (pSecurityAttr->lpSecurityDescriptor);
00990 }
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001 DWORD WINAPI
01002 ThreadFunction (LPVOID lpParam)
01003 {
01004 InputParams * pInputArg = (InputParams *) lpParam;
01005 return (*ServiceEntryPoint) (pInputArg->Argc, pInputArg->Argv);
01006 }
01007
01008
01009
01010
01011
01012 VOID
01013 RegisterStopFunction (VOID (*StopFunc) (VOID))
01014 {
01015 StopFunction = StopFunc;
01016 }
01017
01018
01019
01020
01021
01022
01023 VOID
01024 ProcessServicePause (VOID)
01025 {
01026 if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
01027 {
01028 UpdateServiceStatus (SERVICE_PAUSE_PENDING, NO_ERROR, SCM_WAIT_INTERVAL);
01029
01030 if (SuspendThread (hServiceThread) != -1)
01031 {
01032 UpdateServiceStatus (SERVICE_PAUSED, NO_ERROR, SCM_WAIT_INTERVAL);
01033 }
01034 }
01035 }
01036
01037
01038
01039
01040
01041
01042 VOID
01043 ProcessServiceContinue (VOID)
01044 {
01045 if (ServiceStatus.dwCurrentState == SERVICE_PAUSED)
01046 {
01047 UpdateServiceStatus (SERVICE_CONTINUE_PENDING, NO_ERROR, SCM_WAIT_INTERVAL);
01048
01049 if (ResumeThread (hServiceThread) != -1)
01050 {
01051 UpdateServiceStatus (SERVICE_RUNNING, NO_ERROR, SCM_WAIT_INTERVAL);
01052 }
01053 }
01054 }
01055
01056 #endif
01057
01058