1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132 |
- #include "spsvc.h"
- #include <aclapi.h>
- #define ANOTHER_USERNAME "ClientUser"
- SERVICE_STATUS g_srv_status = {0};
- SERVICE_STATUS_HANDLE g_srv_status_handle = NULL;
- HANDLE g_srv_stop_event = INVALID_HANDLE_VALUE;
- HANDLE g_file_map = NULL;
- void WINAPI service_ctrl_handle(DWORD);
- bool __stdcall StopDependentServices(SC_HANDLE sch_mnr, SC_HANDLE sch_srv)
- {
- DWORD i;
- DWORD dwBytesNeeded;
- DWORD dwCount;
- LPENUM_SERVICE_STATUS lpDependencies = NULL;
- ENUM_SERVICE_STATUS ess;
- SC_HANDLE hDepService;
- SERVICE_STATUS_PROCESS ssp;
- DWORD dwStartTime = GetTickCount();
- DWORD dwTimeout = 30000; // 30-second time-out
- // Pass a zero-length buffer to get the required buffer size.
- if ( EnumDependentServices( sch_srv, SERVICE_ACTIVE,
- lpDependencies, 0, &dwBytesNeeded, &dwCount ) )
- {
- // If the Enum call succeeds, then there are no dependent
- // services, so do nothing.
- return true;
- }
- else
- {
- if ( GetLastError() != ERROR_MORE_DATA )
- return false; // Unexpected error
- // Allocate a buffer for the dependencies.
- lpDependencies = (LPENUM_SERVICE_STATUS) HeapAlloc(
- GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded );
- if ( !lpDependencies )
- return false;
- __try {
- // Enumerate the dependencies.
- if ( !EnumDependentServices( sch_srv, SERVICE_ACTIVE,
- lpDependencies, dwBytesNeeded, &dwBytesNeeded,
- &dwCount ) )
- return false;
- for ( i = 0; i < dwCount; i++ )
- {
- ess = *(lpDependencies + i);
- // Open the service.
- hDepService = OpenService( sch_mnr,
- ess.lpServiceName,
- SERVICE_STOP | SERVICE_QUERY_STATUS );
- if ( !hDepService )
- return false;
- __try {
- // Send a stop code.
- if ( !ControlService( hDepService,
- SERVICE_CONTROL_STOP,
- (LPSERVICE_STATUS) &ssp ) )
- return false;
- // Wait for the service to stop.
- while ( ssp.dwCurrentState != SERVICE_STOPPED )
- {
- Sleep( ssp.dwWaitHint );
- if ( !QueryServiceStatusEx(
- hDepService,
- SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ssp,
- sizeof(SERVICE_STATUS_PROCESS),
- &dwBytesNeeded ) )
- return false;
- if ( ssp.dwCurrentState == SERVICE_STOPPED )
- break;
- if ( GetTickCount() - dwStartTime > dwTimeout )
- return false;
- }
- }
- __finally
- {
- // Always release the service handle.
- CloseServiceHandle( hDepService );
- }
- }
- }
- __finally
- {
- // Always free the enumeration buffer.
- HeapFree( GetProcessHeap(), 0, lpDependencies );
- }
- }
- return true;
- }
- bool ChangeServiceStatus(DWORD status, DWORD exitcode, DWORD wait)
- {
- static DWORD dwCheckPoint = 1;
- g_srv_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
- //g_srv_status.dwControlsAccepted = ac;
- g_srv_status.dwCurrentState = status;
- g_srv_status.dwWin32ExitCode = exitcode;
- g_srv_status.dwServiceSpecificExitCode = 0;
- //g_srv_status.dwCheckPoint = progress;
- g_srv_status.dwWaitHint = wait;
- if (status == SERVICE_START_PENDING) {
- g_srv_status.dwControlsAccepted = 0;
- }
- else {
- g_srv_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
- }
- if ( (status == SERVICE_RUNNING) || (status == SERVICE_STOPPED) ) {
- g_srv_status.dwCheckPoint = 0;
- }
- else {
- g_srv_status.dwCheckPoint = dwCheckPoint++;
- }
- return !!SetServiceStatus(g_srv_status_handle, &g_srv_status);
- }
- bool IsDirExist(LPCSTR lpDirPath)
- {
- DWORD dwRet = GetFileAttributesA(lpDirPath);
- return (dwRet != INVALID_FILE_ATTRIBUTES) && (dwRet & FILE_ATTRIBUTE_DIRECTORY);
- }
- void InitLogConfig()
- {
- if(IsDirExist("D:\\rvc\\dbg")) {
- GET_LOGGER()->SetFileWriteMode(Day_Seperated_Mode, "D:\\rvc\\dbg\\wFreeWrapSvc");
- } else if(IsDirExist("C:\\rvc\\dbg")) {
- GET_LOGGER()->SetFileWriteMode(Day_Seperated_Mode, "C:\\rvc\\dbg\\wFreeWrapSvc");
- } else {
- GET_LOGGER()->DisableRecord();
- }
- }
- bool GetCurrentUserToken(HANDLE& token, DWORD& sessionID, LPCTSTR lpcszUserName)
- {
- sessionID = -1;
- HANDLE cur_token = NULL;
- HANDLE primary_token = NULL;
- DWORD error = ERROR_SUCCESS;
- PWTS_SESSION_INFO session_info_ptr = NULL;
- DWORD count = 0;
- WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &session_info_ptr, &count);
- int size = sizeof(WTS_SESSION_INFO);
- DWORD active_session_id = (DWORD)-1;
- for(DWORD i=0; i<count; ++i) {
- WTS_SESSION_INFO item = session_info_ptr[i];
- OP_PRINTF("State: %d", item.State);
- if(WTSActive == item.State || WTSConnected == item.State) {
- LPTSTR pbuf = NULL;
- DWORD dwLen = 0;
- if(!WTSQuerySessionInformation(WTS_CURRENT_SERVER_NAME,
- item.SessionId, WTSUserName,
- &pbuf, &dwLen)) {
- error = GetLastError();
- OP_PRINTF("WTSUserName failed, GLE=%u", error);
- } else {
- OP_PRINTF("UserName: %s", pbuf);
- }
- if(lpcszUserName != NULL && strlen(lpcszUserName) > 0
- && strcmp(pbuf, lpcszUserName) == 0) {
- active_session_id = item.SessionId;
- OP_PRINTF("Retrieve specified session id: %d", active_session_id);
- break;
- }
- if(pbuf) {
- WTSFreeMemory(pbuf);
- pbuf = NULL;
- }
- }
- }
- WTSFreeMemory(session_info_ptr);
- if(active_session_id == DWORD(-1)) {
- error = ERROR_NO_SUCH_LOGON_SESSION;
- OP_PRINTF("Cannot find specified session id from username: %s", lpcszUserName);
- SetLastError(error);
- return false;
- }
- sessionID = active_session_id;
-
- BOOL ret = WTSQueryUserToken(active_session_id, &cur_token);
- if(!ret) {
- error = GetLastError();
- OP_PRINTF("Query active user token failed, GLE=%u.", error);
- SetLastError(error);
- token = INVALID_HANDLE_VALUE;
- return true;
- }
- ret = DuplicateTokenEx(cur_token, TOKEN_ASSIGN_PRIMARY|TOKEN_ALL_ACCESS, NULL,
- SecurityImpersonation, TokenPrimary, &primary_token);
- if(!ret) {
- error = GetLastError();
- OP_PRINTF("DuplicateTokenEx failed, GLE=%u.", error);
- SetLastError(error);
- primary_token = INVALID_HANDLE_VALUE;
- }
- CloseHandle(cur_token);
- token = primary_token;
- return true;
- }
- bool LaunchApplication(PSP_CREATE_PROCESS_INFO NewProcInfo)
- {
- LOG_FUNCTION();
- DWORD cur_session_id = WTSGetActiveConsoleSessionId();
- DWORD dmp_session_id = cur_session_id;
- if(cur_session_id == (DWORD)-1) {
- OP_PRINTF("There are no session attached to the physical console.");
- NewProcInfo->dwLastError = ERROR_CTX_SESSION_IN_USE;
- return false;
- }
- //Sleep(3000);
- OP_PRINTF("WTSGetActiveConsoleSessionId returned %d", cur_session_id);
- HANDLE token = INVALID_HANDLE_VALUE;
- if(!GetCurrentUserToken(token, cur_session_id, NewProcInfo->szUserName)) {
- NewProcInfo->dwLastError = GetLastError();
- OP_PRINTF("Get current user token failed (%d).", NewProcInfo->dwLastError);
- cur_session_id = dmp_session_id;
- return false;
- }
- //SetTokenInformation(token, TokenSessionId, &cur_session_id, sizeof(DWORD));
- //if(token != NULL && token != INVALID_HANDLE_VALUE) {
- // CloseHandle(token);
- //}
- //PROCESSENTRY32 proce_entry;
- //HANDLE h_snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- //if(h_snap == INVALID_HANDLE_VALUE) {
- // NewProcInfo->dwLastError = GetLastError();
- // OP_PRINTF("CreateToolhelp32Snapshot failed, GLE=%u", NewProcInfo->dwLastError);
- // return false;
- //}
- //proce_entry.dwSize = sizeof(PROCESSENTRY32);
- //if(!Process32First(h_snap, &proce_entry)) {
- // NewProcInfo->dwLastError = GetLastError();
- // OP_PRINTF("Process32First failed, GLE=%u", NewProcInfo->dwLastError);
- // CloseHandle(h_snap);
- // return false;
- //}
- //DWORD dw_winlogon_pid = -1;
- //Retrieves the Remote Desktop Services session associated with a specified process.
- //do
- //{
- // if(!_stricmp(proce_entry.szExeFile, "winlogon.exe")) {
- // DWORD winlogon_session_id = 0;
- // if(ProcessIdToSessionId(proce_entry.th32ProcessID, &winlogon_session_id)
- // && winlogon_session_id == cur_session_id) {
- // dw_winlogon_pid = proce_entry.th32ProcessID;
- // break;
- // }
- // }
- //} while (Process32Next(h_snap, &proce_entry));
- //CloseHandle(h_snap);
- //if(dw_winlogon_pid == -1) {
- // OP_PRINTF("Find the specified \"winlogon.exe\" failed.");
- // NewProcInfo->dwLastError = ERROR_NO_LOGON_SERVERS;
- // return false;
- //}
- DWORD dw_flag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
- PROCESS_INFORMATION pi;
- STARTUPINFO si;
- memset(&pi, 0, sizeof(PROCESS_INFORMATION));
- memset(&si, 0, sizeof(STARTUPINFO));
- si.cb = sizeof(STARTUPINFO);
- //Window station and desktop
- si.lpDesktop = "WinSta0\\Default";
- //HANDLE h_wl_token = NULL;
- //HANDLE h_wl_proc = OpenProcess(MAXIMUM_ALLOWED, FALSE, dw_winlogon_pid);
- //if(!::OpenProcessToken(h_wl_proc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
- // | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID
- // | TOKEN_READ | TOKEN_WRITE, &h_wl_token)) {
- // NewProcInfo->dwLastError = GetLastError();
- // OP_PRINTF("OpenProcessToken from winlogon failed, GLE=%u", NewProcInfo->dwLastError);
- // return false;
- //}
- //TOKEN_PRIVILEGES tp;
- //LUID luid;
- //if(!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
- // NewProcInfo->dwLastError = GetLastError();
- // OP_PRINTF("LookupPrivilegeValue from winlogon failed, GLE=%u", NewProcInfo->dwLastError);
- // CloseHandle(h_wl_token);
- // CloseHandle(h_wl_proc);
- // return false;
- //}
- //tp.PrivilegeCount = 1;
- //tp.Privileges[0].Luid = luid;
- //tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- //HANDLE h_user_token = INVALID_HANDLE_VALUE;
- //if(!WTSQueryUserToken(cur_session_id, &h_user_token)) {
- // OP_PRINTF("WTSQueryUserToken failed, GLE=%u.", GetLastError());
- //}
- //HANDLE h_user_token_duplicated = NULL;
- //DuplicateTokenEx(h_wl_token, MAXIMUM_ALLOWED, NULL,
- // SecurityIdentification, TokenPrimary, &h_user_token_duplicated);
- //if(!SetTokenInformation(h_user_token_duplicated, TokenSessionId,
- // (void*)&cur_session_id, sizeof(DWORD))) {
- // NewProcInfo->dwLastError = GetLastError();
- // OP_PRINTF("SetTokenInformation failed, GLE=%u", NewProcInfo->dwLastError);
- // CloseHandle(h_wl_proc);
- // CloseHandle(h_user_token_duplicated);
- // CloseHandle(h_wl_token);
- // return false;
- //}
- //if(!AdjustTokenPrivileges(h_user_token_duplicated, FALSE,
- // &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, NULL)) {
- // NewProcInfo->dwLastError = GetLastError();
- // OP_PRINTF("AdjustTokenPrivileges from winlogon failed, GLE=%u", NewProcInfo->dwLastError);
- // //CloseHandle(h_user_token);
- // CloseHandle(h_wl_proc);
- // CloseHandle(h_user_token_duplicated);
- // CloseHandle(h_wl_token);
- // return false;
- //}
- //if(GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
- // NewProcInfo->dwLastError = ERROR_NOT_ALL_ASSIGNED;
- // OP_PRINTF("Have not such privilege.");
- // //CloseHandle(h_user_token);
- // CloseHandle(h_wl_proc);
- // CloseHandle(h_user_token_duplicated);
- // CloseHandle(h_wl_token);
- // return false;
- //}
- LPVOID env = NULL;
- if(CreateEnvironmentBlock(&env, token, TRUE)) {
- dw_flag |= CREATE_UNICODE_ENVIRONMENT;
- }else {
- env = NULL;
- }
- char szExeLine[MAX_PATH*2] = {0};
- strcpy_s(szExeLine, NewProcInfo->szCmdline);
- OP_PRINTF("ExePath: (%s)[0X%X] 0X%X", szExeLine, token, env);
- BOOL res = CreateProcessAsUserA(token, NULL, szExeLine,
- NULL, NULL, FALSE, dw_flag, env, NULL, &si, &pi);
- if(!res) {
- NewProcInfo->dwLastError = GetLastError();
- OP_PRINTF("CreateProcessAsUser failed, GLE=%u", NewProcInfo->dwLastError);
- } else {
- OP_PRINTF("CreateProcessAsUser succ.");
- NewProcInfo->usValiSize = sizeof(PROCESS_INFORMATION);
- memcpy(&(NewProcInfo->pi), &pi, sizeof(PROCESS_INFORMATION));
- }
- if(!env) {
- DestroyEnvironmentBlock(env);
- }
- //RevertToSelf();
- //CloseHandle(h_wl_proc);
- //CloseHandle(h_user_token_duplicated);
- //CloseHandle(h_wl_token);
- CloseHandle(token);
- return !!res;
- }
- unsigned int WINAPI thread_procedure(void *param)
- {
- OP_PRINTF("thread_procdure routine enter.");
- while (WaitForSingleObject(g_srv_stop_event, 0) != WAIT_OBJECT_0) {
- Sleep(3000);
- }
- OP_PRINTF("thread_procdure routine exit.");
- return 0;
- }
- void WINAPI service_main(DWORD argc, LPTSTR *argv)
- {
- OP_PRINTF("service_main enter.");
- g_srv_status_handle = RegisterServiceCtrlHandler(SERVICE_SPECIFICED_NAME, service_ctrl_handle);
- if(!g_srv_status_handle) {
- OP_PRINTF("RegisterServiceCtrlHandler failed (%d).", GetLastError());
- goto pt_quit;
- }
- //not accept any controls while it is performing its initialization.
- memset(&g_srv_status, 0, sizeof(SERVICE_STATUS));
- if(!ChangeServiceStatus(SERVICE_START_PENDING, 0, 3000)) {
- OP_PRINTF("SetServiceStatus failed");
- goto pt_quit;
- }
- g_srv_stop_event = CreateEvent(NULL, TRUE, FALSE, NULL);
- if(!g_srv_stop_event) {
- OP_PRINTF("Create event failed");
- if(!ChangeServiceStatus(SERVICE_STOP, GetLastError(), 0)) {
- OP_PRINTF("SetServiceStatus as stop failed");
- }
- goto pt_quit;
- }
- HANDLE h_handle = (HANDLE)_beginthreadex(NULL, 0, thread_procedure, NULL, 0, NULL);
- if(h_handle == NULL || h_handle == INVALID_HANDLE_VALUE) {
- OP_PRINTF("Create thread of procedure failed (%d).", GetLastError());
- if(!ChangeServiceStatus(SERVICE_STOP, GetLastError(), 0)) {
- OP_PRINTF("SetServiceStatus as stop failed");
- }
- goto pt_quit;
- }
- //ready to accept controls.
- if(!ChangeServiceStatus(SERVICE_RUNNING, NO_ERROR, 0)) {
- OP_PRINTF("SetServiceStatus as running failed");
- goto pt_quit;
- }
- OP_PRINTF("Waiting for worker thread to complete.");
- WaitForSingleObject(h_handle, INFINITE);
- OP_PRINTF("Work thread event signaled !");
- if(!ChangeServiceStatus(SERVICE_STOPPED, NO_ERROR, 0)) {
- OP_PRINTF("SetServiceStatus as stopped failed");
- }
- pt_quit:
- OP_PRINTF("service_main exit.");
- return;
- }
- void WINAPI service_ctrl_handle(DWORD ctl_code)
- {
- OP_PRINTF("service_ctrl_handle routine enter.");
- switch(ctl_code)
- {
- case SERVICE_CONTROL_STOP:
- OP_PRINTF("SERVICE_CONTROL_STOP - command received.");
- if(g_srv_status.dwCurrentState != SERVICE_RUNNING) {
- break;
- }
- if(!ChangeServiceStatus(SERVICE_STOP_PENDING, 0, 0)) {
- OP_PRINTF("SetServiceStatus with stopp cmd failed");
- }
- SetEvent(g_srv_stop_event);
- break;
- case SERVICE_CONTROL_CREATEPROCESS:
- OP_PRINTF("SERVICE_CONTROL_CREATEPROCESS received.");
- {
- int szInfor = sizeof(SP_CREATE_PROCESS_INFO);
- HANDLE hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, szName);
- if (hMapFile == NULL) {
- OP_PRINTF("Could not open file mapping object, GLE=%u", GetLastError());
- break;
- }
- PSP_CREATE_PROCESS_INFO pBuf = (PSP_CREATE_PROCESS_INFO)
- MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, szInfor);
- if(pBuf == NULL) {
- OP_PRINTF("MapViewOfFile failed, GLE=%u.", GetLastError());
- CloseHandle(hMapFile);
- break;
- }
- OP_PRINTF("%s, %s", pBuf->szCmdline, pBuf->szUserName);
- LaunchApplication(pBuf);
- //UnmapViewOfFile(pBuf);
- CloseHandle(hMapFile);
- }
- break;
- default:
- break;
- }
- OP_PRINTF("service_ctrl_handle routine exit.");
- }
- //////////////////////////////////////////////////////////////////////////
- bool InstallService()
- {
- bool ret = true;
- char szPath[MAX_PATH];
- if( !GetModuleFileName(NULL, szPath, MAX_PATH ))
- {
- OP_PRINTF("GetModuleFileName failed (%d)", GetLastError());
- return false;
- }
- OP_PRINTF("Service path: %s", szPath);
- SC_HANDLE sch_mnr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if(!sch_mnr) {
- OP_PRINTF("OpenSCManager failed (%d).", GetLastError());
- return false;
- }
- // Change start-type as auto-run [4/13/2018 14:22 @Gifur]
- SC_HANDLE sch_srv = CreateService(sch_mnr, SERVICE_SPECIFICED_NAME, "Rvc2wFreeWrap Service",
- SERVICE_ALL_ACCESS, SERVICE_WIN32_SHARE_PROCESS, SERVICE_AUTO_START/*SERVICE_DEMAND_START*/,
- SERVICE_ERROR_NORMAL,
- szPath, NULL, NULL, NULL, NULL, NULL);
- if(!sch_srv) {
- OP_PRINTF("CreateService failed (%d).", GetLastError());
- CloseServiceHandle(sch_mnr);
- return false;
- }
- CloseServiceHandle(sch_mnr);
- CloseServiceHandle(sch_srv);
- return true;
- }
- bool UnstallService()
- {
- bool ret = true;
- SC_HANDLE sch_mnr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if(!sch_mnr) {
- OP_PRINTF("OpenSCManager failed (%d).", GetLastError());
- return false;
- }
- SC_HANDLE sch_srv = OpenService(sch_mnr, SERVICE_SPECIFICED_NAME, SERVICE_ALL_ACCESS);
- if(!sch_srv) {
- CloseServiceHandle(sch_mnr);
- OP_PRINTF("Open service failed (%d).", GetLastError());
- return false;
- }
- if(!DeleteService(sch_srv)) {
- CloseServiceHandle(sch_mnr);
- OP_PRINTF("Delete service failed (%d).", GetLastError());
- return false;
- }
- CloseServiceHandle(sch_srv);
- CloseServiceHandle(sch_mnr);
- OP_PRINTF("Delete service succ.");
- return true;
- }
- bool StopService()
- {
- bool ret = false;
- SERVICE_STATUS_PROCESS ssp;
- DWORD dwStartTime = GetTickCount();
- DWORD dwBytesNeeded;
- DWORD dwTimeout = 30000; // 30-second time-out
- DWORD dwWaitTime;
- SC_HANDLE sch_mnr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if(!sch_mnr) {
- OP_PRINTF("OpenSCManager failed (%d).", GetLastError());
- return false;
- }
- SC_HANDLE sch_srv = OpenService(sch_mnr, SERVICE_SPECIFICED_NAME,
- SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
- if(!sch_srv) {
- CloseServiceHandle(sch_mnr);
- OP_PRINTF("Open service failed (%d).", GetLastError());
- return false;
- }
- // Make sure the service is not already stopped.
- if ( !QueryServiceStatusEx(
- sch_srv,
- SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ssp,
- sizeof(SERVICE_STATUS_PROCESS),
- &dwBytesNeeded ) )
- {
- OP_PRINTF("QueryServiceStatusEx failed (%d)", GetLastError());
- goto stop_cleanup;
- }
- if ( ssp.dwCurrentState == SERVICE_STOPPED )
- {
- OP_PRINTF("Service is already stopped.");
- ret = true;
- goto stop_cleanup;
- }
- // If a stop is pending, wait for it.
- while ( ssp.dwCurrentState == SERVICE_STOP_PENDING )
- {
- OP_PRINTF("Service stop pending...");
- // Do not wait longer than the wait hint. A good interval is
- // one-tenth of the wait hint but not less than 1 second
- // and not more than 10 seconds.
- dwWaitTime = ssp.dwWaitHint / 10;
- if( dwWaitTime < 1000 )
- dwWaitTime = 1000;
- else if ( dwWaitTime > 10000 )
- dwWaitTime = 10000;
- Sleep( dwWaitTime );
- if ( !QueryServiceStatusEx(
- sch_srv,
- SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ssp,
- sizeof(SERVICE_STATUS_PROCESS),
- &dwBytesNeeded ) )
- {
- OP_PRINTF("QueryServiceStatusEx failed (%d)", GetLastError());
- goto stop_cleanup;
- }
- if ( ssp.dwCurrentState == SERVICE_STOPPED )
- {
- OP_PRINTF("Service stopped succ.");
- ret = true;
- goto stop_cleanup;
- }
- if ( GetTickCount() - dwStartTime > dwTimeout )
- {
- OP_PRINTF("Service stop timed out.");
- goto stop_cleanup;
- }
- }
- // If the service is running, dependencies must be stopped first.
- StopDependentServices(sch_mnr, sch_srv);
- // Send a stop code to the service.
- if ( !ControlService(
- sch_srv,
- SERVICE_CONTROL_STOP,
- (LPSERVICE_STATUS) &ssp ) )
- {
- OP_PRINTF( "ControlService failed (%d)", GetLastError() );
- goto stop_cleanup;
- }
- // Wait for the service to stop.
- while ( ssp.dwCurrentState != SERVICE_STOPPED )
- {
- Sleep( ssp.dwWaitHint );
- if ( !QueryServiceStatusEx(
- sch_srv,
- SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ssp,
- sizeof(SERVICE_STATUS_PROCESS),
- &dwBytesNeeded ) )
- {
- OP_PRINTF( "QueryServiceStatusEx failed (%d)", GetLastError() );
- goto stop_cleanup;
- }
- if ( ssp.dwCurrentState == SERVICE_STOPPED ) {
- ret = true;
- break;
- }
- if ( GetTickCount() - dwStartTime > dwTimeout )
- {
- OP_PRINTF( "Wait timed out" );
- goto stop_cleanup;
- }
- }
- stop_cleanup:
- CloseServiceHandle(sch_srv);
- CloseServiceHandle(sch_mnr);
- if(ret) {
- OP_PRINTF("Service stopped succ.");
- }
- return ret;
- }
- bool StartExService()
- {
- bool ret = false;
- SERVICE_STATUS_PROCESS ssStatus;
- DWORD dwOldCheckPoint;
- DWORD dwStartTickCount;
- DWORD dwWaitTime;
- DWORD dwBytesNeeded;
- SC_HANDLE sch_mnr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if(!sch_mnr) {
- OP_PRINTF("OpenSCManager failed (%d).", GetLastError());
- return false;
- }
- SC_HANDLE sch_srv = OpenService(sch_mnr, SERVICE_SPECIFICED_NAME, SERVICE_ALL_ACCESS);
- if(!sch_srv) {
- CloseServiceHandle(sch_mnr);
- OP_PRINTF("Open service failed (%d).", GetLastError());
- return false;
- }
- // Check the status in case the service is not stopped.
- if (!QueryServiceStatusEx(
- sch_srv, // handle to service
- SC_STATUS_PROCESS_INFO, // information level
- (LPBYTE) &ssStatus, // address of structure
- sizeof(SERVICE_STATUS_PROCESS), // size of structure
- &dwBytesNeeded ) ) // size needed if buffer is too small
- {
- OP_PRINTF("QueryServiceStatusEx failed (%d)", GetLastError());
- CloseServiceHandle(sch_srv);
- CloseServiceHandle(sch_mnr);
- return false;
- }
- // Check if the service is already running. It would be possible
- // to stop the service here, but for simplicity this example just returns.
- if(ssStatus.dwCurrentState != SERVICE_STOPPED && ssStatus.dwCurrentState != SERVICE_STOP_PENDING)
- {
- OP_PRINTF("Cannot start the service because it is already running");
- CloseServiceHandle(sch_srv);
- CloseServiceHandle(sch_mnr);
- return true;
- }
- // Save the tick count and initial checkpoint.
- dwStartTickCount = GetTickCount();
- dwOldCheckPoint = ssStatus.dwCheckPoint;
- // Wait for the service to stop before attempting to start it.
- while (ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
- {
- // Do not wait longer than the wait hint. A good interval is
- // one-tenth of the wait hint but not less than 1 second
- // and not more than 10 seconds.
- dwWaitTime = ssStatus.dwWaitHint / 10;
- if( dwWaitTime < 1000 )
- dwWaitTime = 1000;
- else if ( dwWaitTime > 10000 )
- dwWaitTime = 10000;
- Sleep( dwWaitTime );
- // Check the status until the service is no longer stop pending.
- if (!QueryServiceStatusEx(
- sch_srv, // handle to service
- SC_STATUS_PROCESS_INFO, // information level
- (LPBYTE) &ssStatus, // address of structure
- sizeof(SERVICE_STATUS_PROCESS), // size of structure
- &dwBytesNeeded ) ) // size needed if buffer is too small
- {
- OP_PRINTF("QueryServiceStatusEx failed (%d)", GetLastError());
- CloseServiceHandle(sch_srv);
- CloseServiceHandle(sch_mnr);
- return false;
- }
- if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
- {
- // Continue to wait and check.
- dwStartTickCount = GetTickCount();
- dwOldCheckPoint = ssStatus.dwCheckPoint;
- }
- else
- {
- if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
- {
- OP_PRINTF("Timeout waiting for service to stop");
- CloseServiceHandle(sch_srv);
- CloseServiceHandle(sch_mnr);
- return false;
- }
- }
- }
- // Attempt to start the service.
- if (!StartService(
- sch_srv, // handle to service
- 0, // number of arguments
- NULL) ) // no arguments
- {
- OP_PRINTF("StartService failed (%d)", GetLastError());
- CloseServiceHandle(sch_srv);
- CloseServiceHandle(sch_mnr);
- return false;
- }
- else {
- OP_PRINTF("Service start pending...");
- }
- // Check the status until the service is no longer start pending.
- if (!QueryServiceStatusEx(
- sch_srv, // handle to service
- SC_STATUS_PROCESS_INFO, // info level
- (LPBYTE) &ssStatus, // address of structure
- sizeof(SERVICE_STATUS_PROCESS), // size of structure
- &dwBytesNeeded ) ) // if buffer too small
- {
- OP_PRINTF("QueryServiceStatusEx failed (%d)", GetLastError());
- CloseServiceHandle(sch_srv);
- CloseServiceHandle(sch_mnr);
- return false;
- }
- // Save the tick count and initial checkpoint.
- dwStartTickCount = GetTickCount();
- dwOldCheckPoint = ssStatus.dwCheckPoint;
- while (ssStatus.dwCurrentState == SERVICE_START_PENDING)
- {
- // Do not wait longer than the wait hint. A good interval is
- // one-tenth the wait hint, but no less than 1 second and no
- // more than 10 seconds.
- dwWaitTime = ssStatus.dwWaitHint / 10;
- if( dwWaitTime < 1000 )
- dwWaitTime = 1000;
- else if ( dwWaitTime > 10000 )
- dwWaitTime = 10000;
- Sleep( dwWaitTime );
- // Check the status again.
- if (!QueryServiceStatusEx(
- sch_srv, // handle to service
- SC_STATUS_PROCESS_INFO, // info level
- (LPBYTE) &ssStatus, // address of structure
- sizeof(SERVICE_STATUS_PROCESS), // size of structure
- &dwBytesNeeded ) ) // if buffer too small
- {
- OP_PRINTF("QueryServiceStatusEx failed (%d)", GetLastError());
- break;
- }
- if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
- {
- // Continue to wait and check.
- dwStartTickCount = GetTickCount();
- dwOldCheckPoint = ssStatus.dwCheckPoint;
- }
- else
- {
- if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
- {
- // No progress made within the wait hint.
- break;
- }
- }
- }
- // Determine whether the service is running.
- if (ssStatus.dwCurrentState == SERVICE_RUNNING)
- {
- OP_PRINTF("Service started succ.");
- ret = true;
- }
- else
- {
- OP_PRINTF("Service not started.");
- OP_PRINTF(" Current State: %d", ssStatus.dwCurrentState);
- OP_PRINTF(" Exit Code: %d", ssStatus.dwWin32ExitCode);
- OP_PRINTF(" Check Point: %d", ssStatus.dwCheckPoint);
- OP_PRINTF(" Wait Hint: %d", ssStatus.dwWaitHint);
- }
- CloseServiceHandle(sch_srv);
- CloseServiceHandle(sch_mnr);
- return ret;
- }
- // Updates the service DACL to grant start, stop, delete, and read control access to the ClientUser account.
- bool __stdcall UpdateServiceDacl()
- {
- bool ret = false;
- EXPLICIT_ACCESS ea;
- SECURITY_DESCRIPTOR sd;
- PSECURITY_DESCRIPTOR psd = NULL;
- PACL pacl = NULL;
- PACL pNewAcl = NULL;
- BOOL bDaclPresent = FALSE;
- BOOL bDaclDefaulted = FALSE;
- DWORD dwError = 0;
- DWORD dwSize = 0;
- DWORD dwBytesNeeded = 0;
- SC_HANDLE sch_mnr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- if(!sch_mnr) {
- OP_PRINTF("OpenSCManager failed (%d).", GetLastError());
- return false;
- }
- SC_HANDLE sch_srv = OpenService(sch_mnr, SERVICE_SPECIFICED_NAME,
- READ_CONTROL | WRITE_DAC);
- if(!sch_srv) {
- CloseServiceHandle(sch_mnr);
- OP_PRINTF("Open service failed (%d).", GetLastError());
- return false;
- }
- // Get the current security descriptor.
- if (!QueryServiceObjectSecurity(sch_srv,
- DACL_SECURITY_INFORMATION,
- &psd, // using NULL does not work on all versions
- 0,
- &dwBytesNeeded))
- {
- if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
- {
- dwSize = dwBytesNeeded;
- psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(),
- HEAP_ZERO_MEMORY, dwSize);
- if (psd == NULL)
- {
- // Note: HeapAlloc does not support GetLastError.
- OP_PRINTF("HeapAlloc failed");
- goto dacl_cleanup;
- }
- if (!QueryServiceObjectSecurity(sch_srv,
- DACL_SECURITY_INFORMATION, psd, dwSize, &dwBytesNeeded))
- {
- OP_PRINTF("QueryServiceObjectSecurity failed (%d)", GetLastError());
- goto dacl_cleanup;
- }
- }
- else
- {
- OP_PRINTF("QueryServiceObjectSecurity failed (%d)", GetLastError());
- goto dacl_cleanup;
- }
- }
- // Get the DACL.
- if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl,
- &bDaclDefaulted))
- {
- OP_PRINTF("GetSecurityDescriptorDacl failed(%d)", GetLastError());
- goto dacl_cleanup;
- }
- // Build the ACE.
- BuildExplicitAccessWithName(&ea, TEXT(ANOTHER_USERNAME),
- SERVICE_START | SERVICE_STOP | READ_CONTROL | DELETE,
- SET_ACCESS, NO_INHERITANCE);
- dwError = SetEntriesInAcl(1, &ea, pacl, &pNewAcl);
- if (dwError != ERROR_SUCCESS)
- {
- OP_PRINTF("SetEntriesInAcl failed(%d)", dwError);
- goto dacl_cleanup;
- }
- // Initialize a new security descriptor.
- if (!InitializeSecurityDescriptor(&sd,
- SECURITY_DESCRIPTOR_REVISION))
- {
- OP_PRINTF("InitializeSecurityDescriptor failed(%d)", GetLastError());
- goto dacl_cleanup;
- }
- // Set the new DACL in the security descriptor.
- if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE))
- {
- OP_PRINTF("SetSecurityDescriptorDacl failed(%d)", GetLastError());
- goto dacl_cleanup;
- }
- // Set the new DACL for the service object.
- if (!SetServiceObjectSecurity(sch_srv,
- DACL_SECURITY_INFORMATION, &sd))
- {
- OP_PRINTF("SetServiceObjectSecurity failed(%d)", GetLastError());
- goto dacl_cleanup;
- }
- else {
- OP_PRINTF("Service DACL updated succ.");
- ret = true;
- }
- dacl_cleanup:
- CloseServiceHandle(sch_srv);
- CloseServiceHandle(sch_mnr);
- if(NULL != pNewAcl)
- LocalFree((HLOCAL)pNewAcl);
- if(NULL != psd)
- HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
- return ret;
- }
- int _tmain(int argc, char* argv[])
- {
- int ret = 0;
- InitLogConfig();
- OP_PRINTF("main routine enter.");
- if(argc > 1) {
- if(strcmp(argv[1], "-i") == 0) {
- if(InstallService()) {
- OP_PRINTF("Install service cmd succ.");
- } else {
- ret = 1;
- OP_PRINTF("Error occurs when installing service.");
- }
- } else if(strcmp(argv[1], "-u") == 0) {
- if(!StopService()) {
- ret = 1;
- OP_PRINTF("Error occurs when stoping service.");
- }else {
- if(UnstallService()) {
- OP_PRINTF("Unstall service cmd succ.");
- } else {
- ret = 1;
- OP_PRINTF("Error occurs when unstalling service.");
- }
- }
- } else if(strcmp(argv[1], "-s") == 0) {
- if(StopService()) {
- OP_PRINTF("Stop service cmd succ.");
- } else {
- ret = 1;
- OP_PRINTF("Error occurs when stoping service.");
- }
- } else if(strcmp(argv[1], "-t") == 0) {
- if(StartExService()) {
- OP_PRINTF("Start service cmd succ.");
- UpdateServiceDacl();
- } else {
- ret = 1;
- OP_PRINTF("Error occurs when starting service.");
- }
- } else if(strcmp(argv[1], "-d") == 0) {
- if(UpdateServiceDacl()) {
- OP_PRINTF("Dacl service cmd succ.");
- } else {
- ret = 1;
- OP_PRINTF("Error occurs when dacling service.");
- }
- }else {
- OP_PRINTF("illegal paramters.");
- ret = 2;
- }
- }
- else {
- SERVICE_TABLE_ENTRY srv_table[] = {
- {SERVICE_SPECIFICED_NAME, (LPSERVICE_MAIN_FUNCTION)service_main},
- {NULL, NULL}
- };
- if(!StartServiceCtrlDispatcher(srv_table)) {
- DWORD dwError = GetLastError();
- OP_PRINTF("StartServiceCtrlDispatcher failed. GLE=%u", dwError);
- if(dwError == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
- OP_PRINTF("ERROR_FAILED_SERVICE_CONTROLLER_CONNECT");
- else if (dwError == ERROR_INVALID_DATA)
- OP_PRINTF("ERROR_INVALID_DATA");
- else if (dwError == ERROR_SERVICE_ALREADY_RUNNING)
- OP_PRINTF("ERROR_SERVICE_ALREADY_RUNNING");
- return 3;
- }
- }
- OP_PRINTF("main routine exit.");
- return ret;
- }
|