static void WINAPI ServiceMain(DWORD dwArgc, LPTSTR lpszArgv[]) { if ((sshStatusHandle = RegisterServiceCtrlHandler(szServiceName, ServiceCtrl)) != NULL) { ZeroData(ssStatus); ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ssStatus.dwServiceSpecificExitCode = 0; if (ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, SERVER_START_WAIT)) { ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0); /* Run server */ int iSvrResult = SvrMain((int) dwArgc, lpszArgv); if (iSvrResult < 0) { AddToMessageLog(ErrGetErrorString(iSvrResult)); } } ReportStatusToSCMgr(SERVICE_STOPPED, dwErr, 0); } else AddToMessageLog(_T("RegisterServiceCtrlHandler")); }
VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv) { pthread_t lprobeThread; TCHAR szAppParameters[8192]; // Let the service control manager know that the service is // initializing. if (!ReportStatus(SERVICE_START_PENDING, NO_ERROR, 3000)) //goto cleanup; return; // Create a Stop Event hServerStopEvent = CreateEvent( NULL, TRUE, FALSE, NULL); if ( hServerStopEvent == NULL) goto cleanup; if(dwArgc > 0) _dwArgc = dwArgc, _lpszArgv = lpszArgv; else { char *progName = SZSERVICENAME; _dwArgc = 1, _lpszArgv = &progName; } if (!ReportStatus(SERVICE_RUNNING,NO_ERROR,0)){ goto cleanup; } // createThread(&lprobeThread, invokelprobe, NULL); // J. R. Duarte: Create an argument string from the argument list convertArgListToArgString((LPTSTR)szAppParameters,0, dwArgc, lpszArgv); if(NULL == szAppParameters){ _tprintf(TEXT("Could not create AppParameters string.\n")); } AddToMessageLog(TEXT("About to start lprobe")); pthread_create(&lprobeThread, NULL, invokelprobe, (void*)strdup(szAppParameters)); AddToMessageLog(TEXT("lprobe started")); // Wait for the stop event to be signalled. WaitForSingleObject(hServerStopEvent,INFINITE); AddToMessageLog(TEXT("lprobe terminated")); cleanup: if (hServerStopEvent) CloseHandle(hServerStopEvent); }
// // FUNCTION: main // // PURPOSE: entrypoint for service // // PARAMETERS: // argc - number of command line arguments // argv - array of command line arguments // // RETURN VALUE: // none // // COMMENTS: // main() either performs the command line task, or // call StartServiceCtrlDispatcher to register the // main service thread. When the this call returns, // the service has stopped, so exit. // void _CRTAPI1 main(int argc, char **argv) { SERVICE_TABLE_ENTRY dispatchTable[] = { { NULL, (LPSERVICE_MAIN_FUNCTION)service_main }, { NULL, NULL } }; if (!InitPrologService()) { AddToMessageLog(TEXT("Prolog Service Initilization failed.")); exit(0); } dispatchTable[0].lpServiceName = szServiceName; if ( (argc > 1) && ((*argv[1] == '-') || (*argv[1] == '/')) ) { if ( _stricmp( "install", argv[1]+1 ) == 0 ) { CmdInstallService(); } else if ( _stricmp( "remove", argv[1]+1 ) == 0 ) { CmdRemoveService(); } else if ( _stricmp( "debug", argv[1]+1 ) == 0 ) { bDebug = TRUE; CmdDebugService(argc, argv); } else { goto dispatch; } exit(0); } // if it doesn't match any of the above parameters // the service control manager may be starting the service // so we must call StartServiceCtrlDispatcher dispatch: // this is just to be friendly printf( "%s -install to install the service\n", szAppName ); printf( "%s -remove to remove the service\n", szAppName ); printf( "%s -debug <params> to run as a console app for debugging\n", szAppName ); printf( "\nStartServiceCtrlDispatcher being called.\n" ); printf( "This may take several seconds. Please wait.\n" ); if (!StartServiceCtrlDispatcher(dispatchTable)) AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed.")); }
VOID QueueHashDecrementCounter(Queue *pHashQueue, PSID pSID) { Counter *pCounter; ASSERT(pHashQueue != NULL); if (pHashQueue->lpCriticalSection != NULL) EnterCriticalSection(pHashQueue->lpCriticalSection); #ifdef DEBUG2 DbgMsgRecord(TEXT("-> QueueHashDecrementCounter\n")); #endif // Put the counter onto the appropriate queue. // Lookup the counter for the user's sid. pCounter = (Counter *) QueueHashLookup(pHashQueue, pSID, FALSE); // If the counter does not exist, create it. if (pCounter == NULL) { if ((pCounter = CounterCreate(MaxUserReqs)) == NULL) { AddToMessageLog(TEXT("QueueHashIncrementCounter: CounterCreate failed")); if (pHashQueue->lpCriticalSection != NULL) LeaveCriticalSection(pHashQueue->lpCriticalSection); return; } QueueHashAdd(pHashQueue, pSID, pCounter, FALSE); } // Decrement the counter. CounterDecrement(pCounter); #ifdef DEBUG2 DbgMsgRecord(TEXT("<- QueueHashDecrementCounter\n")); #endif if (pHashQueue->lpCriticalSection != NULL) LeaveCriticalSection(pHashQueue->lpCriticalSection); }
// // FUNCTION: ReportStatusToSCMgr() // // PURPOSE: Sets the current status of the service and // reports it to the Service Control Manager // // PARAMETERS: // dwCurrentState - the state of the service // dwWin32ExitCode - error code to report // dwWaitHint - worst case estimate to next checkpoint // // RETURN VALUE: // TRUE - success // FALSE - failure // // COMMENTS: // BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) { static DWORD dwCheckPoint = 1; BOOL fResult = TRUE; if ( !bDebug ) // when debugging we don't report to the SCM { if (dwCurrentState == SERVICE_START_PENDING) ssStatus.dwControlsAccepted = 0; else ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; ssStatus.dwCurrentState = dwCurrentState; ssStatus.dwWin32ExitCode = dwWin32ExitCode; ssStatus.dwWaitHint = dwWaitHint; if ( ( dwCurrentState == SERVICE_RUNNING ) || ( dwCurrentState == SERVICE_STOPPED ) ) ssStatus.dwCheckPoint = 0; else ssStatus.dwCheckPoint = dwCheckPoint++; // Report the status of the service to the service control manager. // if (!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus))) { AddToMessageLog(TEXT("SetServiceStatus")); } } return fResult; }
// // FUNCTION: main // // PURPOSE: entrypoint for service // // PARAMETERS: // argc - number of command line arguments // argv - array of command line arguments // // RETURN VALUE: // none // // COMMENTS: // main() either performs the command line task, or // call StartServiceCtrlDispatcher to register the // main service thread. When the this call returns, // the service has stopped, so exit. // void main(int argc, char **argv) { char *Account; char *Password; SERVICE_TABLE_ENTRY dispatchTable[] = { { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main }, { NULL, NULL } }; if ( (argc > 1) && ((*argv[1] == '-') || (*argv[1] == '/')) ) { if ( _stricmp( "install", argv[1]+1 ) == 0 ) { /*check the account*/ /*WCG. Install it with domain or without domain*/ if(argc<3) Account=NULL; else Account=argv[2]; /*check the account*/ if(argc<4) Password=NULL; else Password=argv[3]; CmdInstallService(Account,Password); } else if ( _stricmp( "remove", argv[1]+1 ) == 0 ) { CmdRemoveService(); } else if ( _stricmp( "debug", argv[1]+1 ) == 0 ) { bDebug = TRUE; CmdDebugService(argc, argv); } else { goto dispatch; } exit(0); } // if it doesn't match any of the above parameters // the service control manager may be starting the service // so we must call StartServiceCtrlDispatcher dispatch: // this is just to be friendly printf( "%s -install administrator_account password to install the service\n", SZAPPNAME ); printf( "%s -remove to remove the service\n", SZAPPNAME ); printf( "%s -debug <params> to run as a console app for debugging\n", SZAPPNAME ); printf( "\nStartServiceCtrlDispatcher being called.\n" ); printf( "This may take several seconds. Please wait.\n" ); if (!StartServiceCtrlDispatcher(dispatchTable)) AddToMessageLog(NULL,0,EVENTLOG_ERROR_TYPE,SC_SYSTEM, EVLG_STD_STARTSERVICECTRLDISPATCHER_FAILED); }
VOID QueueHashAddToSubqueue(Queue *pHashQueue, PSID pSID, VOID * pData) { ASSERT(pHashQueue != NULL); if (pHashQueue->lpCriticalSection != NULL) EnterCriticalSection(pHashQueue->lpCriticalSection); #ifdef DEBUG2 DbgMsgRecord(TEXT("-> QueueHashAddToSubqueue\n")); #endif // Put the request onto the appropriate queue. // Lookup the subqueue for the user's sid. Queue * pQueue = (Queue *) QueueHashLookup(pHashQueue, pSID, FALSE); // If the subqueue does not exist, create it. if (pQueue == NULL) { if ((pQueue = QueueCreate(TRUE)) == NULL) { AddToMessageLog(TEXT("QueueHashAddToSubqueue: QueueCreate failed")); if (pHashQueue->lpCriticalSection != NULL) LeaveCriticalSection(pHashQueue->lpCriticalSection); return; } QueueHashAdd(pHashQueue, pSID, pQueue, FALSE); } // Add the request to the subqueue QueueAdd(pQueue, pData, FALSE); #ifdef DEBUG2 DbgMsgRecord(TEXT("<- QueueHashAddToSubqueue\n")); #endif if (pHashQueue->lpCriticalSection != NULL) LeaveCriticalSection(pHashQueue->lpCriticalSection); }
BOOL ReportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) { static DWORD dwCheckPoint = 1; BOOL bResult = TRUE; if ( !bConsole ) { if (dwCurrentState == SERVICE_START_PENDING) ssStatus.dwControlsAccepted = 0; else ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; ssStatus.dwCurrentState = dwCurrentState; ssStatus.dwWin32ExitCode = dwWin32ExitCode; ssStatus.dwWaitHint = dwWaitHint; if ( ( dwCurrentState == SERVICE_RUNNING ) || ( dwCurrentState == SERVICE_STOPPED ) ) ssStatus.dwCheckPoint = 0; else ssStatus.dwCheckPoint = dwCheckPoint++; if (!(bResult = SetServiceStatus( sshStatusHandle, &ssStatus))) { AddToMessageLog(TEXT("SetServiceStatus")); } } return bResult; }
Queue * QueueCreate(BOOL NoCritSec) { Queue * pQueue; #ifdef DEBUG2 DbgMsgRecord(TEXT("-> QueueCreate\n")); #endif pQueue = (Queue *)AutoHeapAlloc(sizeof(Queue)); if (pQueue == NULL) { AddToMessageLog(TEXT("QueueCreate: AutoHeapAlloc failed")); return NULL; } pQueue->pFirst = NULL; pQueue->pLast = NULL; if (NoCritSec) { pQueue->lpCriticalSection = NULL; } else { pQueue->lpCriticalSection = (LPCRITICAL_SECTION) AutoHeapAlloc(sizeof(CRITICAL_SECTION)); if (InitializeCriticalSectionAndSpinCount(pQueue->lpCriticalSection, 100) == 0) { AddToMessageLogProcFailure(TEXT("QueueCreate: InitializeCriticalSectionAndSpinCount"), GetLastError()); QueueDelete(pQueue); return NULL; } } #ifdef DEBUG2 DbgMsgRecord(TEXT("<- QueueCreate\n")); #endif return pQueue; }
// // FUNCTION: main // // PURPOSE: entrypoint for service // // PARAMETERS: // argc - number of command line arguments // argv - array of command line arguments // // RETURN VALUE: // none // // COMMENTS: // main() either performs the command line task, or // call StartServiceCtrlDispatcher to register the // main service thread. When the this call returns, // the service has stopped, so exit. // int __cdecl main(int argc, char **argv) { SERVICE_TABLE_ENTRY dispatchTable[] = { { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main}, { NULL, NULL} }; if ( (argc > 1) && ((*argv[1] == '-') || (*argv[1] == '/')) ) { if ( _stricmp( "install", argv[1]+1 ) == 0 ) { return CmdInstallService(); } else if ( _stricmp( "remove", argv[1]+1 ) == 0 ) { return CmdRemoveService(); } else if ( _stricmp( "start", argv[1]+1 ) == 0) { return CmdStartService(); } else if ( _stricmp( "stop", argv[1]+1 ) == 0) { return CmdStopService(); } else if ( _stricmp( "debug", argv[1]+1 ) == 0 ) { bDebug = TRUE; CmdDebugService(argc, argv); } else { goto dispatch; } return 0; } // if it doesn't match any of the above parameters // the service control manager may be starting the service // so we must call StartServiceCtrlDispatcher dispatch: // this is just to be friendly printf( "%s -install to install the service\n", SZAPPNAME ); printf( "%s -start to start the service\n", SZAPPNAME ); printf( "%s -stop to start the service\n", SZAPPNAME ); printf( "%s -remove to remove the service\n", SZAPPNAME ); printf( "%s -debug <params> to run as a console app for debugging\n", SZAPPNAME ); printf( "\nStartServiceCtrlDispatcher being called.\n" ); printf( "This may take several seconds. Please wait.\n" ); if (!StartServiceCtrlDispatcher(dispatchTable)) AddToMessageLog(MSG_FLAGS_ERROR, TEXT("StartServiceCtrlDispatcher failed.")); return 0; }
static int MnSetupStdHandles(void) { HANDLE hInFile = CreateFile(NULFILE, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hInFile == INVALID_HANDLE_VALUE) { AddToMessageLog(_T("CreateFile")); return -1; } HANDLE hOutFile = CreateFile(NULFILE, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hOutFile == INVALID_HANDLE_VALUE) { AddToMessageLog(_T("CreateFile")); CloseHandle(hInFile); return -1; } HANDLE hErrFile = CreateFile(NULFILE, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hErrFile == INVALID_HANDLE_VALUE) { AddToMessageLog(_T("CreateFile")); CloseHandle(hOutFile); CloseHandle(hInFile); return -1; } if (!SetStdHandle(STD_INPUT_HANDLE, hInFile) || !SetStdHandle(STD_OUTPUT_HANDLE, hOutFile) || !SetStdHandle(STD_ERROR_HANDLE, hErrFile)) { AddToMessageLog(_T("SetStdHandle")); CloseHandle(hErrFile); CloseHandle(hOutFile); CloseHandle(hInFile); return -1; } return 0; }
int _tmain(int argc, TCHAR * argv[]) { if (GetModuleFileName(NULL, szServicePath, CountOf(szServicePath)) == 0) { _tprintf(_T("Unable to get module name - %s\n"), GetLastErrorText(szErr, CountOf(szErr))); return 1; } GetServiceNameFromModule(szServicePath, szServiceName, CountOf(szServiceName)); _stprintf(szServiceDispName, _T("%s Server"), szServiceName); SERVICE_TABLE_ENTRY DispTable[] = { { szServiceName, (LPSERVICE_MAIN_FUNCTION) ServiceMain }, { NULL, NULL } }; if (argc > 1) { if (_tcsicmp(_T("--install"), argv[1]) == 0) { CmdInstallService(SERVICE_DEMAND_START); return 0; } if (_tcsicmp(_T("--install-auto"), argv[1]) == 0) { CmdInstallService(SERVICE_AUTO_START); return 0; } else if (_tcsicmp(_T("--remove"), argv[1]) == 0) { CmdRemoveService(); return 0; } else if (_tcsicmp(_T("--debug"), argv[1]) == 0) { bDebug = TRUE; CmdDebugService(argc, argv); return 0; } } _tprintf(_T("%s --install = Install the service\n"), argv[0]); _tprintf(_T("%s --remove = Remove the service\n"), argv[0]); _tprintf(_T("%s --debug [params] = Run as a console app for debugging\n"), argv[0]); _tprintf(_T("\nStartServiceCtrlDispatcher being called.\n")); _tprintf(_T("This may take several seconds. Please wait.\n")); /* Setup std handles */ if (MnSetupStdHandles() < 0) return 1; /* Service loop */ if (!StartServiceCtrlDispatcher(DispTable)) AddToMessageLog(_T("StartServiceCtrlDispatcher")); return 0; }
/* * FUNCTION: GetStatusFromPartnerStatus * * CATEGORY: Local function. * * PURPOSE: Return the CommServer status according with partner status * * PARAMETERS: * DWORD TimeSyncCurrentStatus - TimeSync Current status. * DWORD LastKnownStatus - Last local state known by the partner. * DWORD PartnerStatus - Partner status. * * RETURN VALUE: * NewTimeSyncStatus - The new TimeSync status. * * COMMENTS: */ DWORD GetStatusFromPartnerStatus(DWORD TimeSyncCurrentStatus,DWORD LastKnownStatus,DWORD PartnerStatus) { DWORD NewTimeSyncStatus; char MsgText[200]; char *pStringSub[2]; char ComputerName[80]; DWORD ComputerNameSize; /*Check the Current status with the partner status*/ switch(TimeSyncCurrentStatus) { case PROCESS_STATE_UNKNOWN: case PROCESS_STATE_NORUNNING: case PROCESS_STATE_FAILED: NewTimeSyncStatus=PROCESS_STATE_UNKNOWN; break; case PROCESS_STATE_ACTIVE: case PROCESS_STATE_STANDBY: NewTimeSyncStatus=TimeSyncCurrentStatus; break; default: /*unknown case*/ NewTimeSyncStatus=PROCESS_STATE_UNKNOWN; } /*store the statuses in the registry*/ SetParameterRegistry(TIMESYNC_PARTNER_STATE,(unsigned char *)&PartnerStatus); SetParameterRegistry(TIMESYNC_STATE,(unsigned char *)&NewTimeSyncStatus); /*show the status message*/ if(NewTimeSyncStatus !=LastKnownStatus ) { /*get the computer name*/ ComputerNameSize=sizeof(ComputerName); GetComputerName( ComputerName,&ComputerNameSize); sprintf(MsgText,"TIMESYNC in computer %s become %s" ,ComputerName ,TIMESYNC_STATE_STRING[NewTimeSyncStatus].State); LogWrite( LoggerRouteId, SourceRouteId, MsgText, 1); /*put the event in the event viewer*/ pStringSub[0] = MsgText; AddToMessageLog(pStringSub,1,EVENTLOG_WARNING_TYPE,SC_SYSTEM, EVLG_TIMESYNC_REDUNDANCY); } return NewTimeSyncStatus; }
void runService(int argc, char ** argv) { DWORD dwArgc; LPTSTR *lpszArgv; #ifdef UNICODE lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) ); #else dwArgc = (DWORD) argc; lpszArgv = argv; #endif AddToMessageLog("Starting ntopg"); _tprintf(TEXT("Running %s.\n"), TEXT(SZSERVICEDISPLAYNAME)); ServiceStart( dwArgc, lpszArgv); }
VOID QueueHashAdd(Queue *pQueue, PSID Sid, VOID *pValue, BOOL EnterCritSec) { QueueHashNode *pQueueHashNode; DWORD SidLength; ASSERT(pQueue != NULL); if (pQueue->lpCriticalSection != NULL && EnterCritSec) EnterCriticalSection(pQueue->lpCriticalSection); #ifdef DEBUG2 DbgMsgRecord(TEXT("-> QueueHashAdd\n")); #endif pQueueHashNode = (QueueHashNode *) AutoHeapAlloc(sizeof(QueueHashNode)); SidLength = GetLengthSid(Sid); // We need to copy the key so that if the original // copy gets deallocated we still have one. if ((pQueueHashNode->pKey = AutoHeapAlloc(SidLength)) == NULL) { AddToMessageLog(TEXT("QueueHashAdd: AutoHeapAlloc failed")); if (pQueue->lpCriticalSection != NULL && EnterCritSec) LeaveCriticalSection(pQueue->lpCriticalSection); return; } if (CopySid(SidLength, pQueueHashNode->pKey, Sid) == 0) { AddToMessageLogProcFailure(TEXT("QueueHashAdd: CopySid"), GetLastError()); if (pQueue->lpCriticalSection != NULL && EnterCritSec) LeaveCriticalSection(pQueue->lpCriticalSection); return; } pQueueHashNode->pValue = pValue; QueueAdd(pQueue, (VOID *) pQueueHashNode, FALSE); #ifdef DEBUG2 DbgMsgRecord(TEXT("<- QueueHashAdd\n")); #endif if (pQueue->lpCriticalSection != NULL && EnterCritSec) LeaveCriticalSection(pQueue->lpCriticalSection); }
// // FUNCTION: main // // PURPOSE: entrypoint for service // // PARAMETERS: // argc - number of command line arguments // argv - array of command line arguments // // RETURN VALUE: // none // // COMMENTS: // main() either performs the command line task, or // call StartServiceCtrlDispatcher to register the // main service thread. When the this call returns, // the service has stopped, so exit. // void _CRTAPI1 main(int argc, char **argv) { SERVICE_TABLE_ENTRY dispatchTable[] = { { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)service_main }, { NULL, NULL } }; if ( (argc > 1) && ((*argv[1] == '-') || (*argv[1] == '/')) ) { if ( _stricmp( "install", argv[1]+1 ) == 0 ) { CmdInstallService(); } else if ( _stricmp( "remove", argv[1]+1 ) == 0 ) { CmdRemoveService(); } else { goto dispatch; } exit(0); } // if it doesn't match any of the above parameters // the service control manager may be starting the service // so we must call StartServiceCtrlDispatcher dispatch: // this is just to be friendly printf( "%s -install to install the service\n", SZAPPNAME ); printf( "%s -remove to remove the service\n", SZAPPNAME ); printf( "\nStartServiceCtrlDispatcher being called.\n" ); printf( "This may take several seconds. Please wait.\n" ); if (!StartServiceCtrlDispatcher(dispatchTable)) AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed.")); }
VOID QueueAdd(Queue *pQueue, VOID *pData, BOOL EnterCritSec) { ASSERT(pQueue != NULL); #ifdef DEBUG2 DbgMsgRecord(TEXT("-> QueueAdd\n")); #endif QueueNode * pNode = (QueueNode *) AutoHeapAlloc(sizeof(QueueNode)); if (pNode == NULL) { AddToMessageLog(TEXT("QueueAdd: AutoHeapAlloc failed")); return; } pNode->pNext = NULL; pNode->pData = pData; if (pQueue->lpCriticalSection != NULL && EnterCritSec) EnterCriticalSection(pQueue->lpCriticalSection); if (pQueue->pFirst == NULL) { //ASSERT(pQueue->pLast == NULL); pQueue->pFirst = pNode; pQueue->pLast = pNode; } else { ASSERT(pQueue->pLast->pNext == NULL); pQueue->pLast->pNext = pNode; pQueue->pLast = pNode; } #ifdef DEBUG2 DbgMsgRecord(TEXT("<- QueueAdd\n")); #endif if (pQueue->lpCriticalSection != NULL && EnterCritSec) LeaveCriticalSection(pQueue->lpCriticalSection); }
void main(int argc, char **argv) { // The StartServiceCtrlDispatcher requires this table to specify // the ServiceMain function to run in the calling process. The first // member in this example is actually ignored, since we will install // our service as a SERVICE_WIN32_OWN_PROCESS service type. The NULL // members of the last entry are necessary to indicate the end of // the table; SERVICE_TABLE_ENTRY serviceTable[] = { { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)serviceMain }, { NULL, NULL } }; TCHAR szAppParameters[8192]; if(!isWinNT()) { convertArgListToArgString((LPTSTR) szAppParameters,0, argc, argv); if(NULL == szAppParameters){ _tprintf(TEXT("Could not create AppParameters string.\n")); } invokeNtop(szAppParameters); return; } isNtopAservice = 0; // This app may be started with one of three arguments, /i, /r, and // /c, or /?, followed by actual program arguments. These arguments // indicate if the program is to be installed, removed, run as a // console application, or to display a usage message. if(argc > 1){ if(!stricmp(argv[1],"/i")){ installService(argc,argv); printf("NOTE: the default password for the 'admin' user has been set to 'admin'."); } else if(!stricmp(argv[1],"/r")){ removeService(); } else if(!stricmp(argv[1],"/c")){ bConsole = TRUE; runService(argc, argv); } else { printf("\nUnrecognized option: %s\n", argv[1]); printf("Available options:\n"); printf("/i [ntopng options] - Install ntopng as service\n"); printf("/c - Run ntopng on a console\n"); printf("/r - Deinstall the service\n"); printf("/h - Prints this help\n\n"); usage(); } exit(0); } // If main is called without any arguments, it will probably be by the // service control manager, in which case StartServiceCtrlDispatcher // must be called here. A message will be printed just in case this // happens from the console. printf("\nNOTE:\nUnder your version of Windows, ntopng is started as a service.\n"); printf("Please open the services control panel to start/stop ntop,\n"); printf("or type ntop /h to see all the available options.\n"); isNtopAservice = 1; if(!StartServiceCtrlDispatcher(serviceTable)) { printf("\n%s\n", SZFAILURE); AddToMessageLog(TEXT(SZFAILURE)); } }
void main(int argc, char **argv) { // The StartServiceCtrlDispatcher requires this table to specify // the ServiceMain function to run in the calling process. The first // member in this example is actually ignored, since we will install // our service as a SERVICE_WIN32_OWN_PROCESS service type. The NULL // members of the last entry are necessary to indicate the end of // the table; SERVICE_TABLE_ENTRY serviceTable[] = { { TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)serviceMain }, { NULL, NULL } }; TCHAR szAppParameters[8192]; // pthread_win32_process_attach_np(); if(!isWinNT()) { convertArgListToArgString((LPTSTR) szAppParameters,0, argc, argv); if(NULL == szAppParameters){ _tprintf(TEXT("Could not create AppParameters string.\n")); } invokelprobe(szAppParameters); return; } thisIsAservice = 0; // This app may be started with one of three arguments, /i, /r, and // /c, or /?, followed by actual program arguments. These arguments // indicate if the program is to be installed, removed, run as a // console application, or to display a usage message. if(argc > 1){ char *service_name = "lprobe for Win32"; if(!stricmp(argv[1],"/i")){ if(argc >2) installService(argv[2], argc, argv); else _tprintf(TEXT("/i requires the service name as parameter\n")); } else if(!stricmp(argv[1],"/r")){ if(argc >1) removeService(argv[2]); else _tprintf(TEXT("/r requires the service name as parameter\n")); } else if(!stricmp(argv[1],"/c")){ bConsole = TRUE; runService(argc,argv); } else{ if(stricmp(argv[1],"/h")) printf("\nUnrecognized option: %s\n", argv[1]); printf("Available options:\n"); printf("/i <service name> [lprobe options] - Install lprobe as service\n"); printf("/c [lprobe options] - Run lprobe on a console\n"); printf("/r <service name> - Deinstall the service\n\n"); printf("Example:\n" "Install lprobe as a service: 'lprobe /i my_lprobe -i 0 -n 192.168.0.1:2055'\n" "Remove the lprobe service: 'lprobe /r my_lprobe'\n\n"); printf("Notes:\n" "1. Type 'lprobe /c -h' to see all options\n" "1. In order to reinstall a service with new options\n" " it is necessary to first remove the service, then add it\n" " again with the new options.\n" "2. Services are started/stopped using the Services\n" " control panel item.\n" "3. You can install the lprobe service multiple times\n" " as long as you use different service names.\n\n"); } exit(0); } thisIsAservice = 1; // If main is called without any arguments, it will probably be by the // service control manager, in which case StartServiceCtrlDispatcher // must be called here. A message will be printed just in case this // happens from the console. printf("\nNOTE:\nUnder your version of Windows, lprobe is started as a service.\n"); printf("Please open the services control panel to start/stop lprobe,\n"); printf("or type lprobe /h to see all the available options.\n"); if(!StartServiceCtrlDispatcher(serviceTable)) { printf("\n%s\n", SZFAILURE); AddToMessageLog(TEXT(SZFAILURE)); } }
//int WINAPI WinMain (HINSTANCE hInstance, // HINSTANCE hPrevInstance, // LPSTR lpCmdLine, // int nShowCmd) VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv) { char ConnectionName[15]; /*------------------------------------------------------------*/ /* Modification: Migration from single thread to multithread */ /* Create thread calls are changed to _beginthread */ /* XID on 7-DEC-1998 */ /*------------------------------------------------------------*/ // DWORD CreateThreadId; char StrAux[128]; int CommServerNumber; int LoggerRouteId, CommServerRouteId; char *pStringSub[2]; BYTE CommServerRedundant; BYTE DBServiceDepending; BYTE CommServerPreferred; // report the status to the service control manager. // if (!ReportStatusToSCMgr (SERVICE_START_PENDING, // service state NO_ERROR, // exit code 3000)) // wait hint return; /* Create the event to stop the service */ hStopEvent = CreateEvent (NULL, TRUE, FALSE, NULL); /*-----------------*/ /* Init. procedure */ /*-----------------*/ /* Sets process priority (Normal class) */ SetPriorityClass (GetCurrentProcess (), NORMAL_PRIORITY_CLASS); /* Modification: Process parameters are got from system registry */ /* XID on 16-JUL-1998 */ /* Get the CommServer Number CommServer.Ini */ //CommServerNumber = GetPrivateProfileInt ("GENERAL", "CommServerId", 0,"CommServer.ini"); if (!GetParameterRegistry (COMM_NUM_COMMSERVER, (unsigned char *) &CommServerNumber)) { CommServerNumber = 0; } /* endif */ /* Get the redundant configuration from the system registry */ if (!GetParameterRegistry (COMM_REDUNDANT_CONFIGURATION, (unsigned char *) &CommServerRedundant)) { CommServerRedundant = FALSE; } /* endif */ /* Get the redundant configuration from the system registry */ if (!GetParameterRegistry (COMM_DBSERVICE_DEPENDING, (unsigned char *) &DBServiceDepending)) { DBServiceDepending = TRUE; } /* endif */ if (!GetParameterRegistry (COMM_COMMSERVER_PREFERRED, (unsigned char *) &CommServerPreferred)) { CommServerPreferred = TRUE; } /* endif */ /*-------------------------------*/ /* Basic Network init. procedure */ /*-------------------------------*/ /* Initialize interproccess communication */ if (!RouterInit ()) { /* Error */ AddToMessageLog (NULL, 0, EVENTLOG_ERROR_TYPE, SC_SYSTEM, EVLG_STD_ROUTER_FAILED); return; } /* endif */ /* Detailed Logging initialization */ (void) Log_SetProcessName("CommS"); (void) Log_SetThreadName("SrvcMain"); /* Get connection to send logger messages */ sprintf (ConnectionName, "LOGGER%03u", 0); if (!GetConnection (ConnectionName, &LoggerRouteId)) { /* Error */ pStringSub[0] = ConnectionName; AddToMessageLog (pStringSub, 1, EVENTLOG_ERROR_TYPE, SC_SYSTEM, EVLG_STD_GET_CONECTION_ERROR); return; } /* endif */ /* Create connection to receive online messages from DBService */ sprintf (ConnectionName, "COMSERV%03u", CommServerNumber); if (!CreateConnection (ConnectionName, &CommServerRouteId)) { /* Error */ pStringSub[0] = ConnectionName; AddToMessageLog (pStringSub, 1, EVENTLOG_ERROR_TYPE, SC_SYSTEM, EVLG_STD_CREATE_CONECTION_ERROR); sprintf (StrAux, CS_LOG_MSG_00035); LogWrite (LoggerRouteId, -1, StrAux, 1); return; } /* endif */ /* Start & version message */ LogWrite (LoggerRouteId, CommServerRouteId, "", 1); sprintf (StrAux, CS_LOG_MSG_00036, COMM_SERVER_BUILD_NUMBER, COMM_SERVER_VERSION_DATE); LogWrite (LoggerRouteId, CommServerRouteId, StrAux, 1); sprintf (StrAux, CS_LOG_MSG_00109); LogWrite (LoggerRouteId, CommServerRouteId, StrAux, 1); sprintf (StrAux, CS_LOG_MSG_00037); LogWrite (LoggerRouteId, CommServerRouteId, StrAux, 1); #if defined (HASP_KEY) sprintf (StrAux, COMM_SERVER_HASP_ON_STR); #else sprintf (StrAux, COMM_SERVER_HASP_OFF_STR); #endif LogWrite (LoggerRouteId, CommServerRouteId, StrAux, 1); #if defined (PROT_CONV_LAYER) sprintf (StrAux, COMM_SERVER_CONV_ON_STR); #else sprintf (StrAux, COMM_SERVER_CONV_OFF_STR); #endif LogWrite (LoggerRouteId, CommServerRouteId, StrAux, 1); #if defined (PROT_ENCRYPTION) sprintf (StrAux, COMM_SERVER_ENC_ON_STR); #else sprintf (StrAux, COMM_SERVER_ENC_OFF_STR); #endif LogWrite (LoggerRouteId, CommServerRouteId, StrAux, 1); #if defined (PROT_COMPRESSION) sprintf (StrAux, COMM_SERVER_COMP_ON_STR); #else sprintf (StrAux, COMM_SERVER_COMP_OFF_STR); #endif LogWrite (LoggerRouteId, CommServerRouteId, StrAux, 1); /* Commserver Id */ sprintf (StrAux, CS_LOG_MSG_00110, CommServerNumber); LogWrite (LoggerRouteId, CommServerRouteId, StrAux, 1); LogWrite (LoggerRouteId, CommServerRouteId, "", 1); /* Redundant configuration */ if (CommServerRedundant) { sprintf (StrAux, CS_LOG_MSG_00125); LogWrite (LoggerRouteId, CommServerRouteId, StrAux, 1); sprintf (StrAux, CS_LOG_MSG_00124 ,CommServerPreferred ,DBServiceDepending); LogWrite (LoggerRouteId, CommServerRouteId, StrAux, 1); LogWrite (LoggerRouteId, CommServerRouteId, "", 1); } /* endif */ /* Set input buffer size for this route. */ /* This input buffer has to be large enough */ /* to receive all the incomming messages */ SetInputBufferSize (CommServerRouteId, COMMSERVER_CONNECTION_INPUT_BUFFER_SIZE); /*---------------------*/ /* DB access semaphore */ /*---------------------*/ if (!InitDBSection ()) { /* Error */ sprintf (StrAux, CS_LOG_MSG_00038); printf ("%s\n", StrAux); LogWrite (LoggerRouteId, CommServerRouteId, StrAux, 1); //AddToMessageLog (NULL, 0, EVENTLOG_ERROR_TYPE, SC_SYSTEM, // EVLG_COMMSERVER_MAP_MEMORY_ERROR); sprintf (StrAux, CS_LOG_MSG_00035); LogWrite (LoggerRouteId, CommServerRouteId, StrAux, 1); return; } /* endif */ /*--------------------*/ /* Map channel memory */ /*--------------------*/ if (InitChannelMapData () != STATUS_OK) { /* Error */ sprintf (StrAux, CS_LOG_MSG_00039); printf ("%s\n", StrAux); LogWrite (LoggerRouteId, CommServerRouteId, StrAux, 1); AddToMessageLog (NULL, 0, EVENTLOG_ERROR_TYPE, SC_SYSTEM, EVLG_COMMSERVER_MAP_MEMORY_ERROR); sprintf (StrAux, CS_LOG_MSG_00035); LogWrite (LoggerRouteId, CommServerRouteId, StrAux, 1); return; } /* endif */ /* Reset CommServer database */ ResetDB (); /* Assign comm. server id. and basic routes */ DB_PROCESS.CommServerNumber = CommServerNumber; DB_PROCESS.LoggerRouteId = LoggerRouteId; DB_PROCESS.CommServerRouteId = CommServerRouteId; /* CommServer redundancy initial state */ DB_PROCESS.CommServerPartnerState = PROCESS_STATE_NORUNNING; DB_PROCESS.CommServerState = PROCESS_STATE_NORUNNING; DB_PROCESS.DBServiceDepending = DBServiceDepending; DB_PROCESS.CommServerPreferred = CommServerPreferred; #if defined (HASP_KEY) /* Default hasp check */ DB_PROCESS.HaspPresent = TRUE; #endif /*-------------*/ /* MGL license */ /*-------------*/ MGL_ReadLicense (); /*------------------------*/ /* Compression algorithms */ /*------------------------*/ Util_SplayTreeCompressInit (NULL); Util_SplayTreeUncompressInit (NULL); /*--------------------------*/ /* Process critical secions */ /*--------------------------*/ InitializeCriticalSection (&DB_PROCESS.CSFreeChannels); InitializeCriticalSection (&DB_PROCESS.CSFreeNetworkThreads); InitializeCriticalSection (&DB_PROCESS.CSModifyCfg); /*---------------------------*/ /* Other Network connections */ /*---------------------------*/ /* Get connection to send message to DBService */ sprintf (ConnectionName, "DBCOMM%03u", 0); if (!GetConnection (ConnectionName, &DB_PROCESS.DBServiceRouteId)) { /* Error */ sprintf (StrAux, CS_LOG_MSG_00041, ConnectionName); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); pStringSub[0] = ConnectionName; AddToMessageLog (pStringSub, 1, EVENTLOG_ERROR_TYPE, SC_SYSTEM, EVLG_STD_GET_CONECTION_ERROR); sprintf (StrAux, CS_LOG_MSG_00035); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); return; } /* endif */ /* Get connection to send confirm messages */ sprintf (ConnectionName, "DBCONF%03u", 0); if (!GetConnection (ConnectionName, &DB_PROCESS.DBConfirmRouteId)) { /* Error */ sprintf (StrAux, CS_LOG_MSG_00041, ConnectionName); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); pStringSub[0] = ConnectionName; AddToMessageLog (pStringSub, 1, EVENTLOG_ERROR_TYPE, SC_SYSTEM, EVLG_STD_GET_CONECTION_ERROR); sprintf (StrAux, CS_LOG_MSG_00035); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); return; } /* endif */ /* Get connection to send confirm messages */ sprintf (ConnectionName, "DBSEQ%03u", 0); if (!GetConnection (ConnectionName, &DB_PROCESS.DBSeqRouteId)) { /* Error */ sprintf (StrAux, CS_LOG_MSG_00041, ConnectionName); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); pStringSub[0] = ConnectionName; AddToMessageLog (pStringSub, 1, EVENTLOG_ERROR_TYPE, SC_SYSTEM, EVLG_STD_GET_CONECTION_ERROR); sprintf (StrAux, CS_LOG_MSG_00035); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); return; } /* endif */ /* Initialize Network layer */ if (!NetworkInit ()) { /* Error */ sprintf (StrAux, CS_LOG_MSG_00042); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); AddToMessageLog (NULL, 0, EVENTLOG_ERROR_TYPE, SC_SYSTEM, EVLG_COMMSERVER_NETWORK_LAYER_INIT_ERROR); sprintf (StrAux, CS_LOG_MSG_00035); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); return; } /* endif */ /*------------------*/ /* Threads creation */ /*------------------*/ /*------------------------------------------------------------*/ /* Modification: Migration from single thread to multithread */ /* Create thread calls are changed to _beginthread */ /* XID on 7-DEC-1998 */ /*------------------------------------------------------------*/ /* Create thread to receive messages from the DbService */ // if (CreateThread (NULL, MAX_STACK, (LPTHREAD_START_ROUTINE) HostToTermThread, // (LPVOID) NULL, 0, &CreateThreadId) == NULL) if (_beginthread (HostToTermThread, MAX_STACK, (LPVOID) NULL) == -1) { /* Error */ sprintf (StrAux, CS_LOG_MSG_00043); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); AddToMessageLog (NULL, 0, EVENTLOG_ERROR_TYPE, SC_SYSTEM, EVLG_STD_CREATE_THREAD_ERROR); sprintf (StrAux, CS_LOG_MSG_00035); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); return; } /* endif */ /* Create thread to check channels integrity */ // if (CreateThread (NULL, MAX_STACK, (LPTHREAD_START_ROUTINE) CheckChannelsThread, // (LPVOID) NULL, 0, &CreateThreadId) == NULL) if (_beginthread (CheckChannelsThread, MAX_STACK, (LPVOID) NULL) == -1) { /* Error */ sprintf (StrAux, CS_LOG_MSG_00045); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); AddToMessageLog (NULL, 0, EVENTLOG_ERROR_TYPE, SC_SYSTEM, EVLG_STD_CREATE_THREAD_ERROR); sprintf (StrAux, CS_LOG_MSG_00035); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); return; } /* endif */ /* If the redundancy is configured create the failover thread */ if (CommServerRedundant) { if (_beginthread (FailOverThread, MAX_STACK, (LPVOID) NULL) == -1) { /* Error */ sprintf (StrAux, CS_LOG_MSG_00045); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); AddToMessageLog (NULL, 0, EVENTLOG_ERROR_TYPE, SC_SYSTEM, EVLG_STD_CREATE_THREAD_ERROR); sprintf (StrAux, CS_LOG_MSG_00035); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); return; } /* endif */ } else { /* In not redundancy case it is always active */ DB_PROCESS.CommServerState = PROCESS_STATE_ACTIVE; } /* endif */ /*--------------------------*/ /* CommServer configuration */ /*--------------------------*/ /* Offline parameters */ if (!ReadOfflineDir ()) { /* Error */ sprintf (StrAux, CS_LOG_MSG_00046); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); AddToMessageLog (NULL, 0, EVENTLOG_ERROR_TYPE, SC_SYSTEM, EVLG_COMMSERVER_OFFLINE_DIR_ERROR); sprintf (StrAux, CS_LOG_MSG_00035); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); return; } /* endif */ /* Configuration message */ sprintf (StrAux, CS_LOG_MSG_00047); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 5); // report the status to the service control manager. // if (!ReportStatusToSCMgr (SERVICE_RUNNING, // service state NO_ERROR, // exit code 3000)) // wait hint { sprintf (StrAux, CS_LOG_MSG_00048); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); sprintf (StrAux, CS_LOG_MSG_00035); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); return; } /* endif */ // XID on 17/OCT/2002 // X25 support X25_Init (); /* Start message */ AddToMessageLog (NULL, 0, EVENTLOG_INFORMATION_TYPE, SC_SYSTEM, EVLG_STD_SERVICE_STARTED); /* Get configuration from DBService */ if (!RemoteConfiguration ()) //if (!ConfigureApp ()) { /* Error */ sprintf (StrAux, CS_LOG_MSG_00049); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); AddToMessageLog (NULL, 0, EVENTLOG_ERROR_TYPE, SC_SYSTEM, EVLG_COMMSERVER_LOAD_CONFIG_ERROR); sprintf (StrAux, CS_LOG_MSG_00035); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 1); /* Write the last status in the system registry */ if (CommServerRedundant) { GetStatusFromPartnerStatus (PROCESS_STATE_NORUNNING, DB_PROCESS.CommServerState, DB_PROCESS.CommServerPartnerState); } /* endif */ return; } /* endif */ /* Sets main thread to idle priority */ SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE); /* Configuration message */ sprintf (StrAux, CS_LOG_MSG_00050); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, StrAux, 5); /*-----------------------------*/ /* Wait for the the stop event */ /*-----------------------------*/ WaitForSingleObject (hStopEvent, INFINITE); LogWrite (DB_PROCESS.LoggerRouteId, DB_PROCESS.CommServerRouteId, CS_LOG_MSG_00051, 1); /* Write the last status in the system registry */ if (CommServerRedundant) { GetStatusFromPartnerStatus (PROCESS_STATE_NORUNNING, DB_PROCESS.CommServerState, DB_PROCESS.CommServerPartnerState); } /* endif */ AddToMessageLog (NULL, 0, EVENTLOG_INFORMATION_TYPE, SC_SYSTEM, EVLG_STD_SERVICE_STOPPED); return; } /* main */
PI_END static BOOL InitPrologService(void) { HMODULE module; TCHAR szPrologAppName[MAX_PATH]; TCHAR *dot; PI_system_setup setup; // Get the application name module = GetModuleHandle(NULL); if (!module) { AddToMessageLog(TEXT("GetModuleHandle failed.")); goto error; } if (GetModuleFileName(module, szAppName, MAX_PATH) == 0) { AddToMessageLog(TEXT("GetModuleFileName failed.")); goto error; } // Initilize ALS Prolog setup.heap_size = 0; setup.stack_size = 0; setup.icbuf_size = 0; setup.alsdir = NULL; setup.saved_state = NULL; setup.load_executable_state = 1; setup.argc = 0; setup.argv = NULL; setup.hInstance = NULL; setup.hPrevInstance = NULL; setup.lpCmdLine = NULL; setup.nCmdShow = 1; if (PI_startup(&setup) != 0) { AddToMessageLog(TEXT("Prolog initilization failed.")); goto error; } PI_INIT; #ifndef PACKAGE_STUB // Calculate the Prolog service name from the App name. strcpy(szPrologAppName, szAppName); dot = strrchr(szPrologAppName, '.'); if (!dot) { AddToMessageLog(TEXT("App name doesn't have extension.")); goto error; } *dot = 0; strcat(szPrologAppName, ".pro"); // Consult the Prolog service code. if (!prolog_consult(szPrologAppName)) { AddToMessageLog(TEXT("Prolog consult failed.")); goto error; } #endif // Get the service name, display name and start predicate. if (!get_win32_service()) { AddToMessageLog(TEXT("win32_service/3 failed.")); goto error; } return TRUE; error: return FALSE; }
// // FUNCTION: ServiceStart // // PURPOSE: Actual code of the service that does the work. // // PARAMETERS: // dwArgc - number of command line arguments // lpszArgv - array of command line arguments // // RETURN VALUE: // none // // COMMENTS: // The default behavior is to open a // named pipe, \\.\pipe\simple, and read // from it. It the modifies the data and // writes it back to the pipe. The service // stops when hServerStopEvent is signalled // VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv) { HANDLE hPipe = INVALID_HANDLE_VALUE; HANDLE hEvents[2] = {NULL, NULL}; OVERLAPPED os; PSECURITY_DESCRIPTOR pSD = NULL; SECURITY_ATTRIBUTES sa; TCHAR szIn[80]; TCHAR szOut[ (sizeof(szIn) / sizeof(TCHAR) ) + 100]; LPTSTR lpszPipeName = TEXT("\\\\.\\pipe\\simple"); BOOL bRet; DWORD cbRead; DWORD cbWritten; DWORD dwWait; UINT ndx; /////////////////////////////////////////////////// // // Service initialization // // report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, // service state NO_ERROR, // exit code 3000)) // wait hint goto cleanup; // create the event object. The control handler function signals // this event when it receives the "stop" control code. // hServerStopEvent = CreateEvent( NULL, // no security attributes TRUE, // manual reset event FALSE, // not-signalled NULL); // no name if ( hServerStopEvent == NULL) goto cleanup; hEvents[0] = hServerStopEvent; // report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, // service state NO_ERROR, // exit code 3000)) // wait hint goto cleanup; // create the event object object use in overlapped i/o // hEvents[1] = CreateEvent( NULL, // no security attributes TRUE, // manual reset event FALSE, // not-signalled NULL); // no name if ( hEvents[1] == NULL) goto cleanup; // report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, // service state NO_ERROR, // exit code 3000)) // wait hint goto cleanup; // create a security descriptor that allows anyone to write to // the pipe... // pSD = (PSECURITY_DESCRIPTOR) malloc( SECURITY_DESCRIPTOR_MIN_LENGTH ); if (pSD == NULL) goto cleanup; if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) goto cleanup; sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = pSD; if(!CreateMyDACL(&sa) ) { // DACL creation FAILED!! return; } // report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_START_PENDING, // service state NO_ERROR, // exit code 3000)) // wait hint goto cleanup; // allow user tp define pipe name for ( ndx = 1; ndx < dwArgc-1; ndx++ ) { if ( ( (*(lpszArgv[ndx]) == TEXT('-')) || (*(lpszArgv[ndx]) == TEXT('/')) ) && (!_tcsicmp( TEXT("pipe"), lpszArgv[ndx]+1 ) && ((ndx + 1) < dwArgc)) ) { lpszPipeName = lpszArgv[++ndx]; } } // open our named pipe... // hPipe = CreateNamedPipe( lpszPipeName , // name of pipe FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX, // pipe open mode PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, // pipe IO type 1, // number of instances 0, // size of outbuf (0 == allocate as necessary) 0, // size of inbuf 1000, // default time-out value &sa); // security attributes if (hPipe == INVALID_HANDLE_VALUE) { AddToMessageLog(TEXT("Unable to create named pipe")); goto cleanup; } // report the status to the service control manager. // if (!ReportStatusToSCMgr( SERVICE_RUNNING, // service state NO_ERROR, // exit code 0)) // wait hint goto cleanup; // // End of initialization // //////////////////////////////////////////////////////// //////////////////////////////////////////////////////// // // Service is now running, perform work until shutdown // for(;;) { // init the overlapped structure // memset( &os, 0, sizeof(OVERLAPPED) ); os.hEvent = hEvents[1]; ResetEvent( hEvents[1] ); // wait for a connection... // ConnectNamedPipe(hPipe, &os); if ( GetLastError() == ERROR_IO_PENDING ) { dwWait = WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE ); if ( dwWait != WAIT_OBJECT_0+1 ) // not overlapped i/o event - error occurred, break; // or server stop signaled } // init the overlapped structure // memset( &os, 0, sizeof(OVERLAPPED) ); os.hEvent = hEvents[1]; ResetEvent( hEvents[1] ); // Set the buffer to all NULLs otherwise we get leftover characters memset(szIn, '\0', sizeof(szIn)); // grab whatever's coming through the pipe... // bRet = ReadFile( hPipe, // file to read from szIn, // address of input buffer sizeof(szIn), // number of bytes to read &cbRead, // number of bytes read &os); // overlapped stuff, not needed if ( !bRet && ( GetLastError() == ERROR_IO_PENDING ) ) { dwWait = WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE ); if ( dwWait != WAIT_OBJECT_0+1 ) // not overlapped i/o event - error occurred, break; // or server stop signaled } // munge the string // StringCchPrintf(szOut, sizeof(szOut),TEXT("Hello! [%s]"), szIn); // init the overlapped structure // memset( &os, 0, sizeof(OVERLAPPED) ); os.hEvent = hEvents[1]; ResetEvent( hEvents[1] ); // send it back out... // bRet = WriteFile( hPipe, // file to write to szOut, // address of output buffer sizeof(szOut), // number of bytes to write &cbWritten, // number of bytes written &os); // overlapped stuff, not needed if ( !bRet && ( GetLastError() == ERROR_IO_PENDING ) ) { dwWait = WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE ); if ( dwWait != WAIT_OBJECT_0+1 ) // not overlapped i/o event - error occurred, break; // or server stop signaled } // drop the connection... // DisconnectNamedPipe(hPipe); } cleanup: if (hPipe != INVALID_HANDLE_VALUE ) CloseHandle(hPipe); if (hServerStopEvent) CloseHandle(hServerStopEvent); if (hEvents[1]) // overlapped i/o event CloseHandle(hEvents[1]); if ( pSD ) free( pSD ); }