// "C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat" // "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" // g++ -O2 -std=c++11 lock.cpp // cl.exe /O2 /std:c++11 lock.cpp // cl.exe /O2 /std:c++14 stream.cpp #include <iostream> // iostream istream ostream | wxxx #include <fstream> // fstream ifstream ofstream | wxxx #include <sstream> // stringstream istringstream ostringstream | wxxx #include <string> #include <ctime> // #include <cstddef> // #include <cstring> #include <windows.h> #include <tchar.h> using namespace std; #pragma comment(lib, "advapi32.lib") #define SVCNAME TEXT("aboycando") #define szSvcName TEXT("aboycando") SERVICE_STATUS gSvcStatus; SERVICE_STATUS_HANDLE gSvcStatusHandle; HANDLE ghSvcStopEvent = NULL; VOID SvcInstall(); BOOL DoQuerySvc(); BOOL DoCheckSvc(); VOID DoDeleteSvc(); VOID WINAPI SvcMain(DWORD, LPTSTR *); bool logFile(string fileName, string fileText, int mode) { //fstream oftextStream(fileName.c_str(), mode); // ofstream::out ofstream::app fstream oftextStream(fileName.c_str(), (ios_base::openmode)mode); if (oftextStream){ // char mbstr[64] = {'\0'}; time_t timer = time(NULL); // ctime(&timer);// unsafe and endeith newline // std::strftime(mbstr, sizeof(mbstr), " %F %a %T", std::localtime(&timer)); string strstext = ctime(&timer); strstext.assign(strstext, 0, strstext.size() - 1); strstext = strstext + " " + fileName + " " + fileText + "\n"; oftextStream << strstext; // oftextStream << mbstr << " " << fileText.c_str() << endl; oftextStream.close(); } return true; } int main(int argc, char *argv[]){ logFile("aboycando.txt", "main call", fstream::out); while(argc--) logFile("aboycando.txt", "main argv=" + string(argv[argc]), fstream::app); if( (argv[0][0] == '.') && DoQuerySvc() ) { // DoCheckSvc() service exist difexe || if run stop logFile("aboycando.txt", "main DoDeleteSvc", fstream::app); DoDeleteSvc(); return 1; } if(!DoQuerySvc()) { // service not exist logFile("aboycando.txt", "main SvcInstall", fstream::app); SvcInstall(); } else { // service exist right logFile("aboycando.txt", "main DoStartSvc", fstream::app); SERVICE_TABLE_ENTRY DispatchTable[] = { { SVCNAME, (LPSERVICE_MAIN_FUNCTION) SvcMain }, { NULL, NULL } }; if (FALSE == StartServiceCtrlDispatcher( DispatchTable )) { logFile("aboycando.txt", "main StartServiceCtrlDispatcher FALSE", fstream::app); } } logFile("aboycando.txt", "main exit", fstream::app); return 0; } VOID SvcInstall() { SC_HANDLE schSCManager; SC_HANDLE schService; TCHAR szPath[MAX_PATH]; printf("SvcInstall exit\n"); if (!GetModuleFileName(NULL, szPath, MAX_PATH)) { printf("SvcInstall Cannot install service (%d)\n", GetLastError()); return; } // Get a handle to the SCM database. schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) { printf("SvcInstall OpenSCManager failed (%d)\n", GetLastError()); return; } // Create the service schService = CreateService( schSCManager, // SCM database SVCNAME, // name of service SVCNAME, // service name to display SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type // SERVICE_AUTO_START SERVICE_DEMAND_START SERVICE_ERROR_NORMAL, // error control type szPath, // path to service's binary NULL, // no load ordering group NULL, // no tag identifier NULL, // no dependencies NULL, // LocalSystem account NULL); // no password SERVICE_DESCRIPTION sdBuf; sdBuf.lpDescription = _T("SERVICE_CONFIG_DESCRIPTION"); ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &sdBuf); if (schService == NULL) { printf("SvcInstall CreateService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return; } else printf("SvcInstall Service installed successfully\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); printf("SvcInstall SvcInstall exit\n"); } BOOL DoQuerySvc() { SC_HANDLE schSCManager; SC_HANDLE schService; LPQUERY_SERVICE_CONFIG lpsc; LPSERVICE_DESCRIPTION lpsd; DWORD dwBytesNeeded, cbBufSize, dwError; BOOL reCode = FALSE; printf("DoQuerySvc DoQuerySvc init\n"); // Get a handle to the SCM database. schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) { printf("DoQuerySvc OpenSCManager failed (%d)\n", GetLastError()); return reCode; } // Get a handle to the service. schService = OpenService( schSCManager, // SCM database szSvcName, // name of service SERVICE_QUERY_CONFIG); // need query config access if (schService == NULL) { printf("DoQuerySvc OpenService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return reCode; } // Get the configuration information. if (!QueryServiceConfig( schService, NULL, 0, &dwBytesNeeded)) { dwError = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == dwError) { cbBufSize = dwBytesNeeded; lpsc = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LMEM_FIXED, cbBufSize); } else { printf("DoQuerySvc QueryServiceConfig failed (%d)", dwError); goto cleanup; } } if (!QueryServiceConfig( schService, lpsc, cbBufSize, &dwBytesNeeded)) { printf("DoQuerySvc QueryServiceConfig failed (%d)", GetLastError()); goto cleanup; } if (!QueryServiceConfig2( schService, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &dwBytesNeeded)) { dwError = GetLastError(); if (ERROR_INSUFFICIENT_BUFFER == dwError) { cbBufSize = dwBytesNeeded; lpsd = (LPSERVICE_DESCRIPTION)LocalAlloc(LMEM_FIXED, cbBufSize); } else { printf("DoQuerySvc QueryServiceConfig2 failed (%d)", dwError); goto cleanup; } } if (!QueryServiceConfig2( schService, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)lpsd, cbBufSize, &dwBytesNeeded)) { printf("DoQuerySvc QueryServiceConfig2 failed (%d)", GetLastError()); goto cleanup; } // Print the configuration information. _tprintf(TEXT("%s configuration: \n"), szSvcName); _tprintf(TEXT(" Type: 0x%x\n"), lpsc->dwServiceType); _tprintf(TEXT(" Start Type: 0x%x\n"), lpsc->dwStartType); _tprintf(TEXT(" Error Control: 0x%x\n"), lpsc->dwErrorControl); _tprintf(TEXT(" Binary path: %s\n"), lpsc->lpBinaryPathName); _tprintf(TEXT(" Account: %s\n"), lpsc->lpServiceStartName); if (lpsd->lpDescription != NULL && lstrcmp(lpsd->lpDescription, TEXT("")) != 0) _tprintf(TEXT(" Description: %s\n"), lpsd->lpDescription); if (lpsc->lpLoadOrderGroup != NULL && lstrcmp(lpsc->lpLoadOrderGroup, TEXT("")) != 0) _tprintf(TEXT(" Load order group: %s\n"), lpsc->lpLoadOrderGroup); if (lpsc->dwTagId != 0) _tprintf(TEXT(" Tag ID: %d\n"), lpsc->dwTagId); if (lpsc->lpDependencies != NULL && lstrcmp(lpsc->lpDependencies, TEXT("")) != 0) _tprintf(TEXT(" Dependencies: %s\n"), lpsc->lpDependencies); LocalFree(lpsc); LocalFree(lpsd); reCode = TRUE; cleanup: CloseServiceHandle(schService); CloseServiceHandle(schSCManager); printf("DoQuerySvc DoQuerySvc exit\n"); return reCode; } VOID DoDeleteSvc() { SC_HANDLE schSCManager; SC_HANDLE schService; SERVICE_STATUS ssStatus; printf("DoDeleteSvc init\n"); // Get a handle to the SCM database. schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) { printf("DoDeleteSvc OpenSCManager failed (%d)\n", GetLastError()); return; } // Get a handle to the service. schService = OpenService( schSCManager, // SCM database szSvcName, // name of service DELETE); // need delete access if (schService == NULL) { printf("DoDeleteSvc OpenService failed (%d)\n", GetLastError()); CloseServiceHandle(schSCManager); return; } // Delete the service. if (!DeleteService(schService)) { printf("DoDeleteSvc DeleteService failed (%d)\n", GetLastError()); } else printf("DoDeleteSvc Service deleted successfully\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); printf("DoDeleteSvc exit\n"); } VOID ReportSvcStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) { static DWORD dwCheckPoint = 1; // Fill in the SERVICE_STATUS structure. gSvcStatus.dwCurrentState = dwCurrentState; gSvcStatus.dwWin32ExitCode = dwWin32ExitCode; gSvcStatus.dwWaitHint = dwWaitHint; if (dwCurrentState == SERVICE_START_PENDING) gSvcStatus.dwControlsAccepted = 0; else gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; if ((dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED)) gSvcStatus.dwCheckPoint = 0; else gSvcStatus.dwCheckPoint = dwCheckPoint++; // Report the status of the service to the SCM. SetServiceStatus(gSvcStatusHandle, &gSvcStatus); } VOID WINAPI SvcCtrlHandler(DWORD dwCtrl){ // Handle the requested control code. switch (dwCtrl) { case SERVICE_CONTROL_STOP: ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); // Signal the service to stop. SetEvent(ghSvcStopEvent); ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0); return; case SERVICE_CONTROL_INTERROGATE: break; default: break; } } int sysnap(int a){ return a; } VOID WINAPI SvcMain( DWORD dwArgc, LPTSTR *lpszArgv ) { // Register the handler function for the service logFile("aboycando.txt", "SvcMain call", fstream::app); gSvcStatusHandle = RegisterServiceCtrlHandler( SVCNAME, SvcCtrlHandler); if( !gSvcStatusHandle ) { logFile("aboycando.txt", "main gSvcStatusHandle FALSE", fstream::app); return; } // These SERVICE_STATUS members remain as set here gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; gSvcStatus.dwServiceSpecificExitCode = 0; // Report initial status to the SCM ReportSvcStatus( SERVICE_START_PENDING, NO_ERROR, 3000 ); // Perform service-specific initialization and work. // SvcInit( dwArgc, lpszArgv ); ghSvcStopEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); if ( ghSvcStopEvent == NULL) { ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 ); return; } ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0 ); DWORD id = 0; HANDLE hServiceThread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)sysnap,0,0,&id); // DWORD id; while(1) { logFile("aboycando.txt", "SvcMain while", fstream::app); WaitForSingleObject(ghSvcStopEvent, INFINITE); // stop service run ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 ); return; } }