BOOL CNTScmService::EnumDependents(DWORD dwServiceState, void* pUserData, ENUM_SERVICES_PROC lpEnumServicesFunc) const
{
  //Validate our parameters
  ATLASSUME(m_hService != NULL);

  DWORD dwBytesNeeded;
  DWORD dwServices;
  BOOL bSuccess = EnumDependentServices(m_hService, dwServiceState, NULL, 0, &dwBytesNeeded, &dwServices);
  DWORD dwLastError = GetLastError();
  if (!bSuccess && (dwLastError == ERROR_MORE_DATA) || (dwLastError == ERROR_INSUFFICIENT_BUFFER)) //Note we use ERROR_INSUFFICIENT_BUFFER here even though it is not documented as a legal return value from EnumDependentServices here
  {
    //Allocate some memory for the API
    ATL::CHeapPtr<ENUM_SERVICE_STATUS> lpServices;
    if (!lpServices.AllocateBytes(dwBytesNeeded))
    {
      SetLastError(ERROR_OUTOFMEMORY);
      return FALSE;
    }

    DWORD dwSize;
    bSuccess = EnumDependentServices(m_hService, dwServiceState, lpServices.m_pData, dwBytesNeeded, &dwSize, &dwServices);
    if (bSuccess)
    {
      BOOL bContinue = TRUE;
      for (DWORD i=0; i<dwServices && bContinue; i++)
        bContinue = lpEnumServicesFunc(pUserData, lpServices[i]);
    }
  }
  return bSuccess;
}
Esempio n. 2
0
LPENUM_SERVICE_STATUS EsEnumDependentServices(
    __in SC_HANDLE ServiceHandle,
    __in_opt ULONG State,
    __out PULONG Count
    )
{
    LOGICAL result;
    PVOID buffer;
    ULONG bufferSize;
    ULONG returnLength;
    ULONG servicesReturned;

    if (!State)
        State = SERVICE_STATE_ALL;

    bufferSize = 0x800;
    buffer = PhAllocate(bufferSize);

    if (!(result = EnumDependentServices(
        ServiceHandle,
        State,
        buffer,
        bufferSize,
        &returnLength,
        &servicesReturned
        )))
    {
        if (GetLastError() == ERROR_MORE_DATA)
        {
            PhFree(buffer);
            bufferSize = returnLength;
            buffer = PhAllocate(bufferSize);

            result = EnumDependentServices(
                ServiceHandle,
                State,
                buffer,
                bufferSize,
                &returnLength,
                &servicesReturned
                );
        }

        if (!result)
        {
            PhFree(buffer);
            return NULL;
        }
    }

    *Count = servicesReturned;

    return buffer;
}
Esempio n. 3
0
void
CUtils::DealWithDependentServices(const char *szServiceName, const unsigned int iRequest)
{
	DWORD dwBytes = 0;
	DWORD dwNumServices = 0;
	DWORD dwResumeHandle = 0;
	ENUM_SERVICE_STATUS status[100];

	// service may have dependent services so stop them first
	SC_HANDLE hService = OpenService(hSCM, szServiceName, SERVICE_ENUMERATE_DEPENDENTS);
	if (hService) 
	{
		if (EnumDependentServices(hService, 
								SERVICE_ACTIVE,
								(ENUM_SERVICE_STATUS *)status,		// returned info
								100 * sizeof(ENUM_SERVICE_STATUS),	// length of buffer
								&dwBytes,							// returned length
								&dwNumServices))					// number services returned
		{
			for (DWORD i=0;i<dwNumServices;i++)
			{
				// recurse until we stop the last dependant
				ServiceRequest(status[i].lpServiceName, iRequest);
			}
		}

		CloseServiceHandle(hService);

		// if there were dependents, allow some time register service stops
		if (dwNumServices)
			Sleep(2000);
	}
	else
		_GetWindowsError();
}
Esempio n. 4
0
BOOL
TV2_HasDependantServices(LPWSTR lpServiceName)
{
    HANDLE hSCManager;
    HANDLE hService;
    DWORD dwBytesNeeded, dwCount;
    BOOL bRet = FALSE;

    hSCManager = OpenSCManagerW(NULL,
                                NULL,
                                SC_MANAGER_ALL_ACCESS);
    if (hSCManager)
    {
        hService = OpenServiceW(hSCManager,
                                lpServiceName,
                                SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
        if (hService)
        {
            /* Does this have any dependencies? */
            if (!EnumDependentServices(hService,
                                       SERVICE_STATE_ALL,
                                       NULL,
                                       0,
                                       &dwBytesNeeded,
                                       &dwCount))
            {
                 if (GetLastError() == ERROR_MORE_DATA)
                 {
                     /* It does, return TRUE */
                     bRet = TRUE;
                 }
            }

            CloseServiceHandle(hService);
        }

        CloseServiceHandle(hSCManager);
    }

    return bRet;
}
Esempio n. 5
0
int MAIN( int argc, WINCHAR *argv[] )
{
	SC_HANDLE hSCM, hService;
	DWORD needed, returned;
	LPENUM_SERVICE_STATUS pServices = NULL;
	DWORD i;

	if ( argc != 3 ) {
		printf(TEXT("Usage: %s <server> <service>\n"), argv[0]);
		exit( 1 );
	}

	printf(TEXT("Opening the Service Control Manager on %s..."), (LPTSTR)argv[1]);
	if ( !(hSCM = OpenSCManager( (LPTSTR)argv[1], NULL, SC_MANAGER_ALL_ACCESS )) ) {
		printf(TEXT("failed.\n"));
		PrintLastError();
		exit(1);
	}
	printf(TEXT("ok\n"));

	printf(TEXT("Opening service \"%s\"..."), (LPTSTR)argv[2]);
	if ( !(hService = OpenService( hSCM, (LPTSTR)argv[2], SERVICE_ALL_ACCESS )) ) {
		printf(TEXT("failed.\n"));
		PrintLastError();
		CloseServiceHandle( hSCM );
		exit(1);
	}
	printf(TEXT("ok\n"));

	printf(TEXT("Enumerating dependent services...."));
	needed = returned = 0;
	if ( !EnumDependentServices( hService, SERVICE_ACTIVE, NULL, 0, &needed, &returned ) ) 
	{
		DWORD status;
		DWORD bufsize;

		status = GetLastError();
		if ( status != ERROR_MORE_DATA ) 
		{
			printf(TEXT("failed.\n"));
			printf(TEXT("error == %d\n"), status);
			CloseServiceHandle( hSCM );
			exit(1);
		}

		pServices = (LPENUM_SERVICE_STATUS)malloc(needed);
		bufsize = needed;
		if ( !EnumDependentServices( hService, SERVICE_ACTIVE, pServices, bufsize, &needed, &returned ) ) 
		{
			PrintLastError();
			CloseServiceHandle( hSCM );
			exit(1);
		}
	}
	printf(TEXT("ok\n"));

	if ( returned == 0 )	
		printf(TEXT("**no dependent services**\n"));

	for (i=0; i<returned; i++) {
		printf(TEXT("%s (%s)\n"), pServices[i].lpDisplayName, pServices[i].lpServiceName );
		printf(TEXT("\ttype              = 0x%x\n"), pServices[i].ServiceStatus.dwServiceType );
		printf(TEXT("\tstate             = 0x%x\n"), pServices[i].ServiceStatus.dwCurrentState );
		printf(TEXT("\tcontrols accepted = 0x%x\n"), pServices[i].ServiceStatus.dwControlsAccepted );
		printf(TEXT("\twin32 exit code   = 0x%x\n"), pServices[i].ServiceStatus.dwWin32ExitCode );
		printf(TEXT("\tsvc exit code     = 0x%x\n"), pServices[i].ServiceStatus.dwServiceSpecificExitCode );
		printf(TEXT("\tcheck point       = 0x%x\n"), pServices[i].ServiceStatus.dwCheckPoint );
		printf(TEXT("\twait hont         = 0x%x\n"), pServices[i].ServiceStatus.dwWaitHint );
	}

	free( pServices );

	printf(TEXT("Closing Service handles..."));
	CloseServiceHandle( hSCM );
	CloseServiceHandle( hService );
	printf(TEXT("ok\n"));

	exit(0);

}
Esempio n. 6
0
/*
* DriverSetInfo
*
* Purpose:
*
* Sets registry info for selected driver object
*
*/
VOID DriverSetInfo(
	PROP_OBJECT_INFO *Context,
	HWND hwndDlg
	)
{
	BOOL					cond = FALSE, bResult, fGroup, bRet;
	INT						nEndOfList, nEnd, nStart;
	DWORD					i, bytesNeeded, dwServices, dwGroups;
	LPWSTR					lpType;
	SC_HANDLE				SchSCManager;
	SC_HANDLE				schService;
	LPENUM_SERVICE_STATUS   lpDependencies = NULL;
	LPQUERY_SERVICE_CONFIG	psci;
	LPSERVICE_DESCRIPTION	psd;
	SERVICE_STATUS_PROCESS 	ssp;
	ENUM_SERVICE_STATUS     ess;
	WCHAR					szBuffer[MAX_PATH + 1];
	
	if (Context == NULL) {
		ShowWindow(GetDlgItem(hwndDlg, IDC_QUERYFAIL), TRUE);
		return;
	}

	__try {

		ShowWindow(GetDlgItem(hwndDlg, IDC_QUERYFAIL), FALSE);

		psci = NULL;
		SchSCManager = NULL;
		bResult = FALSE;

		do {
			SchSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
			if (SchSCManager == NULL) {
				break;
			}

			schService = OpenService(SchSCManager, Context->lpObjectName,
				SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
			if (schService == NULL) {
				break;
			}

			bytesNeeded = 0;
			bResult = QueryServiceConfig(schService, NULL, 0, &bytesNeeded);
			if ((bResult == FALSE) && (bytesNeeded == 0)) {
				break;
			}

			psci = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded);
			if (psci == NULL) {
				break;
			}

			//disable comboboxes
			EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES), FALSE);
			EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE), FALSE);
			EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDSONGROUP), FALSE);

			bResult = QueryServiceConfig(schService, psci, bytesNeeded, &bytesNeeded);
			if (bResult) {
				//set key name (identical to object name)
				SetDlgItemText(hwndDlg, IDC_SERVICE_KEYNAME, Context->lpObjectName);
				//set image path info
				SetDlgItemText(hwndDlg, IDC_SERVICE_IMAGEPATH, psci->lpBinaryPathName);
				//set display name
				SetDlgItemText(hwndDlg, IDC_SERVICE_DISPLAYNAME, psci->lpDisplayName);
				//set load order group
				SetDlgItemText(hwndDlg, IDC_SERVICE_LOADORDERGROUP, psci->lpLoadOrderGroup);

				//Service Type
				lpType = T_UnknownType;
				switch (psci->dwServiceType) {
				case SERVICE_KERNEL_DRIVER:
					lpType = L"Kernel-Mode Driver";
					break;
				case SERVICE_FILE_SYSTEM_DRIVER:
					lpType = L"File System Driver";
					break;
				case SERVICE_ADAPTER:
					lpType = L"Adapter";
					break;
				case SERVICE_RECOGNIZER_DRIVER:
					lpType = L"File System Recognizer";
					break;
				case SERVICE_WIN32_OWN_PROCESS:
					lpType = L"Own Process";
					break;
				case SERVICE_WIN32_SHARE_PROCESS:
					lpType = L"Share Process";
					break;
				case (SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS):
					lpType = L"Own Process (Interactive)";
					SetDlgItemText(hwndDlg, ID_SERVICE_NAME, psci->lpServiceStartName);
					break;
				case (SERVICE_WIN32_SHARE_PROCESS | SERVICE_INTERACTIVE_PROCESS):
					lpType = L"Share Process (Interactive)";
					SetDlgItemText(hwndDlg, ID_SERVICE_NAME, psci->lpServiceStartName);
					break;
				}
				SetDlgItemText(hwndDlg, ID_SERVICE_TYPE, lpType);

				//Start Type
				lpType = T_UnknownType;
				switch (psci->dwStartType) {
				case SERVICE_AUTO_START:
					lpType = L"Auto";
					break;
				case SERVICE_BOOT_START:
					lpType = L"Boot";
					break;
				case SERVICE_DEMAND_START:
					lpType = L"On Demand";
					break;
				case SERVICE_DISABLED:
					lpType = L"Disabled";
					break;
				case SERVICE_SYSTEM_START:
					lpType = L"System";
					break;
				}
				SetDlgItemText(hwndDlg, ID_SERVICE_START, lpType);

				//Error Control
				lpType = T_Unknown;
				switch (psci->dwErrorControl) {
				case SERVICE_ERROR_CRITICAL:
					lpType = L"Critical";
					break;
				case SERVICE_ERROR_IGNORE:
					lpType = L"Ignore";
					break;
				case SERVICE_ERROR_NORMAL:
					lpType = L"Normal";
					break;
				case SERVICE_ERROR_SEVERE:
					lpType = L"Severe";
					break;
				}
				SetDlgItemText(hwndDlg, ID_SERVICE_ERROR, lpType);

				//dwTagId
				if (psci->dwTagId) {
					RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
					ultostr(psci->dwTagId, szBuffer);
					SetDlgItemText(hwndDlg, ID_SERVICE_TAG, szBuffer);
				}
				else {
					//not assigned tag
					SetDlgItemText(hwndDlg, ID_SERVICE_TAG, L"");
				}

				//State
				RtlSecureZeroMemory(&ssp, sizeof(ssp));
				if (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, 
					(LPBYTE)&ssp, sizeof(ssp), &bytesNeeded)) 
				{
					lpType = T_Unknown;
					switch (ssp.dwCurrentState) {
					case SERVICE_STOPPED:
						lpType = L"Stopped";
						break;
					case SERVICE_START_PENDING:
						lpType = L"Start Pending";
						break;
					case SERVICE_STOP_PENDING:
						lpType = L"Stop Pending";
						break;
					case SERVICE_RUNNING:
						lpType = L"Running";
						break;
					case SERVICE_CONTINUE_PENDING:
						lpType = L"Continue Pending";
						break;
					case SERVICE_PAUSE_PENDING:
						lpType = L"Pause Pending";
						break;
					case SERVICE_PAUSED:
						lpType = L"Paused";
						break;
					}
					SetDlgItemText(hwndDlg, ID_SERVICE_CURRENT, lpType);
				}
				else {
					SetDlgItemText(hwndDlg, ID_SERVICE_CURRENT, T_CannotQuery);
				}

				//Service Description
				bRet = FALSE;
				SetDlgItemText(hwndDlg, ID_SERVICE_DESCRIPTION, L"");
				bytesNeeded = 0x1000;
				psd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded);
				if (psd) {				

					bRet = QueryServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, 
						(LPBYTE)psd, bytesNeeded, &bytesNeeded);

					if ((bRet == FALSE) && (bytesNeeded != 0)) {
						HeapFree(GetProcessHeap(), 0, psd);
						psd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded);
					}
					if (psd) {
						//set description or hide window
						bRet = QueryServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, 
							(LPBYTE)psd, bytesNeeded, &bytesNeeded);

						if (bRet) {
							SetDlgItemText(hwndDlg, IDC_SERVICE_DESCRIPTION, psd->lpDescription);
						}
						HeapFree(GetProcessHeap(), 0, psd);
					}
				}
				if (bRet == FALSE) {
					//not enough memory, hide description window
					ShowWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DESCRIPTION), SW_HIDE);
				}


				//Service Dependencies
				if (psci->lpDependencies) {

					//first list DependsOnService, DependsOnGroup

					nEndOfList = 0;
					nEnd = 0;
					nStart = 0;
					dwGroups = 0;
					dwServices = 0;

					//calc total number of symbols
					while ((psci->lpDependencies[nEndOfList] != L'\0') || (psci->lpDependencies[nEndOfList + 1] != L'\0'))
						nEndOfList++;

					if (nEndOfList > 0) {

						SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONGROUP, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0);
						SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0);

						//iterate through MULTI_SZ string
						do {
							while (psci->lpDependencies[nEnd] != L'\0') {
								nEnd++;
							}

							RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer));
							//maximum bytes that can be copied is sizeof(szBuffer)
							_strncpy(szBuffer, sizeof(szBuffer), &psci->lpDependencies[nStart], nEnd);

							//check if dependency is a group (has "+" before name)
							fGroup = (szBuffer[0] == SC_GROUP_IDENTIFIER);
							if (fGroup) {
								SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONGROUP, CB_ADDSTRING, 
									(WPARAM)0, (LPARAM)&szBuffer[1]);
								dwGroups++;
							}
							else {
								SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE, CB_ADDSTRING, 
									(WPARAM)0, (LPARAM)&szBuffer);
								dwServices++;
							}
							nEnd++;
							nStart = nEnd;
						} while (nEnd < nEndOfList);

						//group present, enable combobox
						if (dwGroups > 0) {
							EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDSONGROUP), TRUE);
							SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONGROUP, CB_SETCURSEL, 
								(WPARAM)0, (LPARAM)0);
						}
						//service present, enable combobox
						if (dwServices > 0) {
							EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE), TRUE);
							SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDSONSERVICE, CB_SETCURSEL, 
								(WPARAM)0, (LPARAM)0);
						}
					} //if (nEndOfList > 0)

					//second list services that depends on this service
					SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES, CB_RESETCONTENT, 
						(WPARAM)0, (LPARAM)0);

					dwServices = 0;
					bytesNeeded = 1024;
					bRet = FALSE;

					//avoid SCM unexpected behaviour by using preallocated buffer
					lpDependencies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded);
					if (lpDependencies) {
						bRet = EnumDependentServices(schService, SERVICE_STATE_ALL, lpDependencies, 
							bytesNeeded, &bytesNeeded, &dwServices);

						if (bRet && (GetLastError() == ERROR_MORE_DATA)) {
							//more memory needed for enum
							HeapFree(GetProcessHeap(), 0, lpDependencies);
							dwServices = 0;
							lpDependencies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytesNeeded);
							if (lpDependencies) {
								bRet = EnumDependentServices(schService, SERVICE_STATE_ALL,
									lpDependencies, bytesNeeded, &bytesNeeded,
									&dwServices);
							}
						}
						//list dependents
						if (bRet && dwServices) {
							for (i = 0; i < dwServices; i++) {
								ess = *(lpDependencies + i);
								SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES, CB_ADDSTRING, 
									(WPARAM)0, (LPARAM)ess.lpServiceName);
							}
							//enable combobox and set current selection to the first item
							EnableWindow(GetDlgItem(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES), TRUE);
							SendDlgItemMessage(hwndDlg, IDC_SERVICE_DEPENDENTSERVICES, CB_SETCURSEL, 
								(WPARAM)0, (LPARAM)0);
						}
						HeapFree(GetProcessHeap(), 0, lpDependencies);
					}
				} //if (psi->lpDependencies)
			} //bResult != FALSE

			CloseServiceHandle(schService);
		} while (cond);

		if (psci != NULL) {
			HeapFree(GetProcessHeap(), 0, psci);
		}

		if (SchSCManager) {
			CloseServiceHandle(SchSCManager);
		}

		if (bResult == FALSE) {
			EnumChildWindows(hwndDlg, DriverShowChildWindows, SW_HIDE);
			ShowWindow(GetDlgItem(hwndDlg, IDC_QUERYFAIL), SW_SHOW);
		}
		else {
			SetFocus(GetDlgItem(hwndDlg, ID_SERVICE_JUMPTOKEY));
		}

	}
	__except (exceptFilter(GetExceptionCode(), GetExceptionInformation())) {
		EnumChildWindows(hwndDlg, DriverShowChildWindows, SW_HIDE);
		ShowWindow(GetDlgItem(hwndDlg, IDC_QUERYFAIL), SW_SHOW);
		return;
	}
}
Esempio n. 7
0
BOOL EnumDepend(LPCTSTR ServiceName)
{
    SC_HANDLE hManager = NULL;
    SC_HANDLE hService = NULL;
    BOOL bResult = TRUE;
    DWORD BufferSize = 0;
    DWORD EntriesRead = 0;
    LPENUM_SERVICE_STATUS pBuffer = NULL;
    DWORD i;

    hManager = OpenSCManager(NULL,
                             NULL,
                             SC_MANAGER_CONNECT);
    if (hManager == NULL)
    {
        _tprintf(_T("[SC] OpenSCManager FAILED %lu:\n\n"), GetLastError());
        bResult = FALSE;
        goto done;
    }

    hService = OpenService(hManager, ServiceName, SERVICE_ENUMERATE_DEPENDENTS);
    if (hService == NULL)
    {
        _tprintf(_T("[SC] OpenService FAILED %lu:\n\n"), GetLastError());
        bResult = FALSE;
        goto done;
    }

    if (!EnumDependentServices(hService,
                               SERVICE_STATE_ALL,
                               NULL,
                               0,
                               &BufferSize,
                               &EntriesRead))
    {
        if (BufferSize == 0)
        {
            _tprintf(_T("[SC] EnumDependentServices FAILED %lu:\n\n"), GetLastError());
            bResult = FALSE;
            goto done;
        }
    }

    pBuffer = HeapAlloc(GetProcessHeap(), 0, BufferSize);
    if (pBuffer == NULL)
    {
        SetLastError(ERROR_OUTOFMEMORY);
        _tprintf(_T("[SC] HeapAlloc FAILED %lu:\n\n"), GetLastError());
        bResult = FALSE;
        goto done;
    }

    if (!EnumDependentServices(hService,
                               SERVICE_STATE_ALL,
                               pBuffer,
                               BufferSize,
                               &BufferSize,
                               &EntriesRead))
    {
        _tprintf(_T("[SC] EnumDependentServices FAILED %lu:\n\n"), GetLastError());
        bResult = FALSE;
        goto done;
    }

    _tprintf(_T("Enum: entriesRead = %lu\n"), EntriesRead);

    for (i = 0; i < EntriesRead; i++)
    {
        _tprintf(_T("\n"));
        _tprintf(_T("SERVICE_NAME: %s\n"), pBuffer[i].lpServiceName);
        _tprintf(_T("DISPLAY_NAME: %s\n"), pBuffer[i].lpDisplayName);
        PrintServiceStatus(&pBuffer[i].ServiceStatus);
    }

done:
    if (bResult == FALSE)
        ReportLastError();

    if (pBuffer != NULL)
        HeapFree(GetProcessHeap(), 0, pBuffer);

    if (hService)
        CloseServiceHandle(hService);

    if (hManager)
        CloseServiceHandle(hManager);

    return bResult;
}
BOOL MainFrame::StopDependentServices(SC_HANDLE schSCManager, SC_HANDLE schService)
{
	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( schService, 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( schService, SERVICE_ACTIVE, 
				lpDependencies, dwBytesNeeded, &dwBytesNeeded,
				&dwCount ) )
				return FALSE;

			for ( i = 0; i < dwCount; i++ ) 
			{
				ess = *(lpDependencies + i);
				// Open the service.
				hDepService = OpenService( schSCManager, 
					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;
}
Esempio n. 9
0
BOOL StopDependentServices(SC_HANDLE hSCManager, SC_HANDLE hService)
{
    LPENUM_SERVICE_STATUS   lpDependencies = NULL;
    ENUM_SERVICE_STATUS     ess;
    SC_HANDLE               hDepService;
    SERVICE_STATUS_PROCESS  ssp;
    DWORD i, dwBytesNeeded, dwCount;

    DWORD dwStartTime = GetTickCount();
    DWORD dwTimeout = 30000; // 30 секундна пауза

    // Пускане на буфер с нулева дължина, за да се получи желания размер на буфера.
    if (EnumDependentServices(hService, SERVICE_ACTIVE, lpDependencies, 0, &dwBytesNeeded, &dwCount))
        // Ако извикването на Enum-а е успешно, тогава няма зависими
        // сервиси, така че не се прави нищо.
        return TRUE;

    if (GetLastError() != ERROR_MORE_DATA)
        return FALSE; // Неочаквана грешка

    // Алокиране на буфер за зависимостите.
    lpDependencies = (LPENUM_SERVICE_STATUS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded);
    if (!lpDependencies)
        return FALSE;

    __try {
        // Избройват се зависимостите.
        if (!EnumDependentServices(hService, SERVICE_ACTIVE, lpDependencies,
                                   dwBytesNeeded, &dwBytesNeeded, &dwCount))
            return FALSE;

        for (i=0; i<dwCount; i++) {
            ess = *(lpDependencies + i);
            // Отваря се сервиса
            hDepService = OpenService(hSCManager, ess.lpServiceName, SERVICE_STOP|SERVICE_QUERY_STATUS);
            if (!hDepService)
                return FALSE;

            __try {
                // Изпраща се стоп код.
                if (!ControlService(hDepService, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ssp))
                    return FALSE;

                // Изчаква се сервиса да спре.
                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 {
                // Винаги се изпуска дръжката на сервиса.
                CloseServiceHandle(hDepService);
            }
        }
    } __finally {
        // Винаги се освобождава изброения буфер.
        HeapFree(GetProcessHeap(), 0, lpDependencies);
    }
    return TRUE;
}
Esempio n. 10
0
/*
This function attempts to stop a service. It allows the caller to
specify whether dependent services should also be stopped. It also
accepts a timeout value, to prevent a scenario in which a service
shutdown hangs, then the application stopping the service hangs

Parameters:
pszServiceName - service name string
fStopDependencies - Indicates whether to stop dependent services.
dwTimeout - maximum time (in milliseconds) to wait

If the operation is successful, returns true. Otherwise, returns false.
*/
bool ServiceManager_t::StopService(_TCHAR * pszServiceName, bool fStopDependencies,
								   DWORD dwTimeout)
{
	SC_HANDLE schService;
	SERVICE_STATUS_PROCESS ssp;
	SERVICE_STATUS ssDummy;
	DWORD dwStartTime = GetTickCount();
	DWORD dwBytesNeeded;

	if (!_QueryServiceStatusEx)
	{
		g_Log.Write(_T("Dynamic function QueryServiceStatusEx not initialized."));
		return false;
	}

	schService = OpenService(schSCManager, pszServiceName, SERVICE_ALL_ACCESS);

	if (schService == NULL)
	{
		g_Log.Write(_T("Could not open service '%s'."), pszServiceName);
		return false;
	}

	// Make sure the service is not already stopped:
	if (!_QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
		sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded))
	{
		g_Log.Write(_T("Could not tell if service '%s' already stopped - error %d."),
			pszServiceName, GetLastError());
		return false;
	}

	if (ssp.dwCurrentState == SERVICE_STOPPED)
		return true;

	// If a stop is pending, just wait for it:
	while (ssp.dwCurrentState == SERVICE_STOP_PENDING)
	{
		Sleep(ssp.dwWaitHint);
		if (!_QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
			sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded))
		{
			g_Log.Write(_T("Could not tell if service '%s' already stopped - error %d."),
				pszServiceName, GetLastError());
			return false;
		}

		if (ssp.dwCurrentState == SERVICE_STOPPED)
			return true;

		if (GetTickCount() - dwStartTime > dwTimeout)
		{
			g_Log.Write(_T("Timed out waiting for service '%s' to stop."),
				pszServiceName);
			return false;
		}
	}

	// If the service is running, dependencies must be stopped first:
	if (fStopDependencies)
	{
		DWORD i;
		DWORD dwBytesNeeded;
		DWORD dwCount;

		LPENUM_SERVICE_STATUS lpDependencies = NULL;
		ENUM_SERVICE_STATUS ess;
		SC_HANDLE hDepService;

		// Pass a zero-length buffer to get the required buffer size:
		if (EnumDependentServices(schService, SERVICE_ACTIVE, lpDependencies, 0, &dwBytesNeeded,
			&dwCount))
		{
			// If the Enum call succeeds, then there are no dependent services so do nothing
		}
		else
		{
			if (GetLastError() != ERROR_MORE_DATA)
			{
				g_Log.Write(_T("Unexpected error %d while trying to obtain buffer size needed to enumerate dependent services of '%s'."),
					GetLastError(), pszServiceName);
				return false; // Unexpected error.
			}

			// Allocate a buffer for the dependencies:
			lpDependencies = (LPENUM_SERVICE_STATUS)HeapAlloc(GetProcessHeap(),
				HEAP_ZERO_MEMORY, dwBytesNeeded);

			if (!lpDependencies)
			{
				g_Log.Write(_T("Unexpected error while trying to create buffer needed to enumerate dependent services of '%s'."),
					GetLastError(), pszServiceName);
				return false; // Unexpected error.
			}

			__try
			{
				// Enumerate the dependencies:
				if (!EnumDependentServices(schService, SERVICE_ACTIVE, lpDependencies,
					dwBytesNeeded, &dwBytesNeeded, &dwCount))
				{
					g_Log.Write(_T("Unexpected error %d while trying to enumerate dependent services of '%s'."),
						GetLastError(), pszServiceName);
					return false; // Unexpected error.
				}

				for (i = 0; i < dwCount; i++)
				{
					ess = *(lpDependencies + i);

					// Open the service:
					hDepService = OpenService(schSCManager, ess.lpServiceName,
						SERVICE_STOP | SERVICE_QUERY_STATUS);
					if (!hDepService)
					{
						g_Log.Write(_T("Unexpected error %d while trying to open dependent service '%s' of '%s'."),
							GetLastError(), ess.lpServiceName, pszServiceName);
						return false; // Unexpected error.
					}

					__try
					{
						// Send a stop code:
						if (!ControlService(hDepService, SERVICE_CONTROL_STOP, &ssDummy))
						{
							g_Log.Write(_T("Unexpected error %d while trying to stop dependent service '%s' of '%s'."),
								GetLastError(), ess.lpServiceName, pszServiceName);
							return false; // Unexpected error.
						}

						// Wait for the service to stop:
						do
						{
							if (!_QueryServiceStatusEx(hDepService, SC_STATUS_PROCESS_INFO,
								(LPBYTE)&ssp, sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded))
							{
								g_Log.Write(_T("Unexpected error %d while trying to get status of dependent service '%s' of '%s'."),
									GetLastError(), ess.lpServiceName, pszServiceName);
								return false; // Unexpected error.
							}

							if (ssp.dwCurrentState == SERVICE_STOPPED)
								break;

							if (GetTickCount() - dwStartTime > dwTimeout)
							{
								g_Log.Write(_T("Timed out while trying to stop dependent service '%s' of '%s'."),
									ess.lpServiceName, pszServiceName);
								return false;
							}

							Sleep(ssp.dwWaitHint);

						} while (ssp.dwCurrentState != SERVICE_STOPPED);
					}
					__finally
					{
						// Always release the service handle:
						CloseServiceHandle(hDepService);
					}
				} // Next dependent service
			}
			__finally
			{
				// Always free the enumeration buffer:
				HeapFree(GetProcessHeap(), 0, lpDependencies);
			}
		}
	}

	// Send a stop code to the main service:
	if (!ControlService(schService, SERVICE_CONTROL_STOP, &ssDummy))
	{
		g_Log.Write(_T("Unexpected error %d while trying to stop service '%s'."),
			GetLastError(), pszServiceName);
		return false; // Unexpected error.
	}

	// Wait for the service to stop:
	do
	{
		if (!_QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
			sizeof(SERVICE_STATUS_PROCESS), &dwBytesNeeded))
		{
			g_Log.Write(_T("Unexpected error %d while trying to get status of service '%s'."),
				GetLastError(), pszServiceName);
			return false; // Unexpected error.
		}

		if (ssp.dwCurrentState == SERVICE_STOPPED)
			break;

		if (GetTickCount() - dwStartTime > dwTimeout)
		{
			g_Log.Write(_T("Timed out while trying to stop service '%s'."), pszServiceName);
			return false;
		}
		
		Sleep(ssp.dwWaitHint);

	} while (ssp.dwCurrentState != SERVICE_STOPPED);

	// Return success:
	return true;
}