//
// Purpose: 
//   Stops the service.
//
// Parameters:
//   None
// 
// Return value:
//   None
//
void MainFrame::DoStopSvc(LPCTSTR szSvcName)
{
	SERVICE_STATUS_PROCESS ssp;
	DWORD dwStartTime = GetTickCount();
	DWORD dwBytesNeeded;
	DWORD dwTimeout = 30000; // 30-second time-out
	DWORD dwWaitTime;

	// Get a handle to the SCM database. 

	SC_HANDLE schSCManager = OpenSCManager( 
		NULL,                    // local computer
		NULL,                    // ServicesActive database 
		SC_MANAGER_ALL_ACCESS);  // full access rights 

	if (NULL == schSCManager) 
	{
		return;
	}

	// Get a handle to the service.

	SC_HANDLE schService = OpenService( 
		schSCManager,			// SCM database 
		szSvcName,				// name of service 
		SERVICE_STOP | 
		SERVICE_QUERY_STATUS | 
		SERVICE_ENUMERATE_DEPENDENTS);  

	if (schService == NULL)
	{ 
		//printf("OpenService failed (%d)\n", GetLastError()); 
		CloseServiceHandle(schSCManager);
		return;
	}    

	// Make sure the service is not already stopped.
	if ( !QueryServiceStatusEx( 
		schService, 
		SC_STATUS_PROCESS_INFO,
		(LPBYTE)&ssp, 
		sizeof(SERVICE_STATUS_PROCESS),
		&dwBytesNeeded ) )
	{
		//printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); 
		goto stop_cleanup;
	}

	if ( ssp.dwCurrentState == SERVICE_STOPPED )
	{
		//printf("Service is already stopped.\n");
		goto stop_cleanup;
	}

	// If a stop is pending, wait for it.
	while ( ssp.dwCurrentState == SERVICE_STOP_PENDING ) 
	{
		//printf("Service stop pending...\n");

		// 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( 
			schService, 
			SC_STATUS_PROCESS_INFO,
			(LPBYTE)&ssp, 
			sizeof(SERVICE_STATUS_PROCESS),
			&dwBytesNeeded ) )
		{
			//printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); 
			goto stop_cleanup;
		}

		if ( ssp.dwCurrentState == SERVICE_STOPPED )
		{
			//printf("Service stopped successfully.\n");
			goto stop_cleanup;
		}

		if ( GetTickCount() - dwStartTime > dwTimeout )
		{
			//printf("Service stop timed out.\n");
			goto stop_cleanup;
		}
	}

	// If the service is running, dependencies must be stopped first.
	StopDependentServices(schSCManager, schService);

	// Send a stop code to the service.
	if (!ControlService(
		schService, 
		SERVICE_CONTROL_STOP, 
		(LPSERVICE_STATUS) &ssp))
	{
		//printf( "ControlService failed (%d)\n", GetLastError() );
		goto stop_cleanup;
	}

	// Wait for the service to stop.
	while ( ssp.dwCurrentState != SERVICE_STOPPED ) 
	{
		Sleep( ssp.dwWaitHint );
		if ( !QueryServiceStatusEx( 
			schService, 
			SC_STATUS_PROCESS_INFO,
			(LPBYTE)&ssp, 
			sizeof(SERVICE_STATUS_PROCESS),
			&dwBytesNeeded ) )
		{
			//printf( "QueryServiceStatusEx failed (%d)\n", GetLastError() );
			goto stop_cleanup;
		}

		if ( ssp.dwCurrentState == SERVICE_STOPPED )
			break;

		if ( GetTickCount() - dwStartTime > dwTimeout )
		{
			//printf( "Wait timed out\n" );
			goto stop_cleanup;
		}
	}
	//printf("Service stopped successfully\n");

stop_cleanup:
	CloseServiceHandle(schService); 
	CloseServiceHandle(schSCManager);
}
BOOL StopServiceEx(HWND hWnd, SC_HANDLE schSCManager, char *szSvcName)
{
    SC_HANDLE schService;
    SERVICE_STATUS_PROCESS ssp;
    DWORD dwStartTime = GetTickCount();
    DWORD dwBytesNeeded;
    DWORD dwTimeout = 30000; // 30 секундна пауза
    DWORD dwWaitTime;

    schService = OpenService(schSCManager, szSvcName,
                             SERVICE_STOP | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
    if (schService == NULL) {
        MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR);
        return FALSE;
    }

    // Проверява дали сервиса не е вече спрян.
    if (!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
                              sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded))
    {
        MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR);
        CloseServiceHandle(schService);
        return FALSE;
    }

    if (ssp.dwCurrentState == SERVICE_STOPPED) {
        MessageBox(hWnd, "Сервисът е бил спрен", "FileHide", MB_ICONERROR);
        CloseServiceHandle(schService);
        return FALSE;
    }

    // Ако стопирането е в очакване, изчакай го.
    while (ssp.dwCurrentState == SERVICE_STOP_PENDING) {
        dwWaitTime = ssp.dwWaitHint / 10;
        if(dwWaitTime < 1000)
            dwWaitTime = 1000;
        else if (dwWaitTime > 10000)
            dwWaitTime = 10000;

        Sleep(dwWaitTime);

        if ( !QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
                                   sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded))
        {
            MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR);
            CloseServiceHandle(schService);
            return FALSE;
        }

        if (ssp.dwCurrentState == SERVICE_STOPPED) {
            MessageBox(hWnd, "Сервисът е спрян", "FileHide", MB_ICONEXCLAMATION);
            CloseServiceHandle(schService);
            return TRUE;
        }

        if (GetTickCount() - dwStartTime > dwTimeout) {
            MessageBox(hWnd, "Времето за спиране на сервиса изтече", "FileHide", MB_ICONERROR);
            CloseServiceHandle(schService);
            return FALSE;
        }
    }

    // Ако сервиса работи, зависимите сервиси първо се спират.
    StopDependentServices(schSCManager, schService);

    // Изпраща стоп код към сервиса.
    if (!ControlService(schService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ssp)) {
        MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR);
        CloseServiceHandle(schService);
        return FALSE;
    }

    // Изчака сервиса да спре.
    while (ssp.dwCurrentState != SERVICE_STOPPED) {
        Sleep(ssp.dwWaitHint);

        if (!QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
                                  sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded))
        {
            MessageBox(hWnd, GetErrorText(GetLastError()), "FileHide", MB_ICONERROR);
            CloseServiceHandle(schService);
            return FALSE;
        }

        if (ssp.dwCurrentState == SERVICE_STOPPED)
            break;

        if (GetTickCount() - dwStartTime > dwTimeout) {
            MessageBox(hWnd, "Времето за спиране на сервиса изтече", "FileHide", MB_ICONERROR);
            CloseServiceHandle(schService);
            return FALSE;
        }
    }

    MessageBox(hWnd, "Сервисът е спрян", "FileHide", MB_ICONEXCLAMATION);
    CloseServiceHandle(schService);
    return TRUE;
}