Exemplo n.º 1
0
/*
 * Get service description.
 */
PyObject *
psutil_winservice_query_descr(PyObject *self, PyObject *args) {
    ENUM_SERVICE_STATUS_PROCESS *lpService = NULL;
    BOOL ok;
    DWORD bytesNeeded = 0;
    DWORD resumeHandle = 0;
    DWORD dwBytes = 0;
    SC_HANDLE hService = NULL;
    SERVICE_DESCRIPTION *scd = NULL;
    char *service_name;
    PyObject *py_retstr = NULL;

    if (!PyArg_ParseTuple(args, "s", &service_name))
        return NULL;
    hService = psutil_get_service_handler(
        service_name, SC_MANAGER_ENUMERATE_SERVICE, SERVICE_QUERY_CONFIG);
    if (hService == NULL)
        goto error;

    // This first call to QueryServiceConfig2() is necessary in order
    // to get the right size.
    bytesNeeded = 0;
    QueryServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, NULL, 0,
                        &bytesNeeded);
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        PyErr_SetFromWindowsErr(0);
        goto error;
    }

    scd = (SERVICE_DESCRIPTION *)malloc(bytesNeeded);
    ok = QueryServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION,
                             (LPBYTE)scd, bytesNeeded, &bytesNeeded);
    if (ok == 0) {
        PyErr_SetFromWindowsErr(0);
        goto error;
    }

    if (scd->lpDescription == NULL) {
        py_retstr = Py_BuildValue("s", "");
    }
    else {
        py_retstr = PyUnicode_Decode(
            scd->lpDescription,
            _tcslen(scd->lpDescription),
            Py_FileSystemDefaultEncoding,
            "replace");
    }
    if (!py_retstr)
        goto error;

    free(scd);
    return py_retstr;

error:
    if (hService != NULL)
        CloseServiceHandle(hService);
    if (lpService != NULL)
        free(lpService);
    return NULL;
}
Exemplo n.º 2
0
VOID PhpUpdateServiceItemConfig(
    _In_ SC_HANDLE ScManagerHandle,
    _In_ PPH_SERVICE_ITEM ServiceItem
    )
{
    SC_HANDLE serviceHandle;

    serviceHandle = OpenService(ScManagerHandle, ServiceItem->Name->Buffer, SERVICE_QUERY_CONFIG);

    if (serviceHandle)
    {
        LPQUERY_SERVICE_CONFIG config;
        SERVICE_DELAYED_AUTO_START_INFO delayedAutoStartInfo;
        ULONG returnLength;
        PSERVICE_TRIGGER_INFO triggerInfo;

        config = PhGetServiceConfig(serviceHandle);

        if (config)
        {
            ServiceItem->StartType = config->dwStartType;
            ServiceItem->ErrorControl = config->dwErrorControl;

            PhFree(config);
        }

        if (QueryServiceConfig2(
            serviceHandle,
            SERVICE_CONFIG_DELAYED_AUTO_START_INFO,
            (BYTE *)&delayedAutoStartInfo,
            sizeof(SERVICE_DELAYED_AUTO_START_INFO),
            &returnLength
            ))
        {
            ServiceItem->DelayedStart = delayedAutoStartInfo.fDelayedAutostart;
        }
        else
        {
            ServiceItem->DelayedStart = FALSE;
        }

        if (triggerInfo = PhQueryServiceVariableSize(serviceHandle, SERVICE_CONFIG_TRIGGER_INFO))
        {
            ServiceItem->HasTriggers = triggerInfo->cTriggers != 0;
            PhFree(triggerInfo);
        }
        else
        {
            ServiceItem->HasTriggers = FALSE;
        }

        CloseServiceHandle(serviceHandle);
    }
}
Exemplo n.º 3
0
static int	check_delayed_start(SC_HANDLE h_srv)
{
	SERVICE_DELAYED_AUTO_START_INFO	*sds = NULL;
	DWORD				sz = 0;
	int 				ret = FAIL;

	QueryServiceConfig2(h_srv, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, NULL, 0, &sz);

	if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
	{
		sds = (SERVICE_DELAYED_AUTO_START_INFO *)zbx_malloc(sds, sz);

		if (0 != QueryServiceConfig2(h_srv, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, (LPBYTE)sds, sz, &sz) &&
				TRUE == sds->fDelayedAutostart)
		{
			ret = SUCCEED;
		}

		zbx_free(sds);
	}

	return ret;
}
Exemplo n.º 4
0
PVOID PhQueryServiceVariableSize(
    _In_ SC_HANDLE ServiceHandle,
    _In_ ULONG InfoLevel
    )
{
    PVOID buffer;
    ULONG bufferSize = 0x100;

    buffer = PhAllocate(bufferSize);

    if (!QueryServiceConfig2(
        ServiceHandle,
        InfoLevel,
        (BYTE *)buffer,
        bufferSize,
        &bufferSize
        ))
    {
        PhFree(buffer);
        buffer = PhAllocate(bufferSize);

        if (!QueryServiceConfig2(
            ServiceHandle,
            InfoLevel,
            (BYTE *)buffer,
            bufferSize,
            &bufferSize
            ))
        {
            PhFree(buffer);
            return NULL;
        }
    }

    return buffer;
}
Exemplo n.º 5
0
BOOLEAN PhGetServiceDelayedAutoStart(
    _In_ SC_HANDLE ServiceHandle,
    _Out_ PBOOLEAN DelayedAutoStart
    )
{
    SERVICE_DELAYED_AUTO_START_INFO delayedAutoStartInfo;
    ULONG returnLength;

    if (QueryServiceConfig2(
        ServiceHandle,
        SERVICE_CONFIG_DELAYED_AUTO_START_INFO,
        (BYTE *)&delayedAutoStartInfo,
        sizeof(SERVICE_DELAYED_AUTO_START_INFO),
        &returnLength
        ))
    {
        *DelayedAutoStart = !!delayedAutoStartInfo.fDelayedAutostart;
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
Exemplo n.º 6
0
int	SERVICE_INFO(AGENT_REQUEST *request, AGENT_RESULT *result)
{
	QUERY_SERVICE_CONFIG	*qsc = NULL;
	SERVICE_DESCRIPTION	*scd = NULL;
	SERVICE_STATUS		status;
	SC_HANDLE		h_mgr, h_srv;
	DWORD			sz = 0;
	int			param_type, i;
	char			*name, *param;
	wchar_t			*wname, service_name[MAX_STRING_LEN];
	DWORD			max_len_name = MAX_STRING_LEN;

	if (2 < request->nparam)
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
		return SYSINFO_RET_FAIL;
	}

	name = get_rparam(request, 0);
	param = get_rparam(request, 1);

	if (NULL == name || '\0' == *name)
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
		return SYSINFO_RET_FAIL;
	}

	if (NULL == param || '\0' == *param || 0 == strcmp(param, "state"))	/* default second parameter */
		param_type = ZBX_SRV_PARAM_STATE;
	else if (0 == strcmp(param, "displayname"))
		param_type = ZBX_SRV_PARAM_DISPLAYNAME;
	else if (0 == strcmp(param, "path"))
		param_type = ZBX_SRV_PARAM_PATH;
	else if (0 == strcmp(param, "user"))
		param_type = ZBX_SRV_PARAM_USER;
	else if (0 == strcmp(param, "startup"))
		param_type = ZBX_SRV_PARAM_STARTUP;
	else if (0 == strcmp(param, "description"))
		param_type = ZBX_SRV_PARAM_DESCRIPTION;
	else
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid second parameter."));
		return SYSINFO_RET_FAIL;
	}

	if (NULL == (h_mgr = OpenSCManager(NULL, NULL, GENERIC_READ)))
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain system information."));
		return SYSINFO_RET_FAIL;
	}

	wname = zbx_utf8_to_unicode(name);

	h_srv = OpenService(h_mgr, wname, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG);
	if (NULL == h_srv && 0 != GetServiceKeyName(h_mgr, wname, service_name, &max_len_name))
		h_srv = OpenService(h_mgr, service_name, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG);

	zbx_free(wname);

	if (NULL == h_srv)
	{
		int	ret;

		if (ZBX_SRV_PARAM_STATE == param_type)
		{
			SET_UI64_RESULT(result, 255);
			ret = SYSINFO_RET_OK;
		}
		else
		{
			SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot find the specified service."));
			ret = SYSINFO_RET_FAIL;
		}

		CloseServiceHandle(h_mgr);
		return ret;
	}

	if (ZBX_SRV_PARAM_STATE == param_type)
	{
		if (0 != QueryServiceStatus(h_srv, &status))
		{
			for (i = 0; i < ARRSIZE(service_states) && status.dwCurrentState != service_states[i]; i++)
				;

			SET_UI64_RESULT(result, i);
		}
		else
			SET_UI64_RESULT(result, 7);
	}
	else if (ZBX_SRV_PARAM_DESCRIPTION == param_type)
	{
		QueryServiceConfig2(h_srv, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &sz);

		if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
		{
			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service description: %s",
					strerror_from_system(GetLastError())));
			CloseServiceHandle(h_srv);
			CloseServiceHandle(h_mgr);
			return SYSINFO_RET_FAIL;
		}

		scd = (SERVICE_DESCRIPTION *)zbx_malloc(scd, sz);

		if (0 == QueryServiceConfig2(h_srv, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)scd, sz, &sz))
		{
			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service description: %s",
					strerror_from_system(GetLastError())));
			zbx_free(scd);
			CloseServiceHandle(h_srv);
			CloseServiceHandle(h_mgr);
			return SYSINFO_RET_FAIL;
		}

		if (NULL == scd->lpDescription)
			SET_TEXT_RESULT(result, zbx_strdup(NULL, ""));
		else
			SET_TEXT_RESULT(result, zbx_unicode_to_utf8(scd->lpDescription));

		zbx_free(scd);
	}
	else
	{
		QueryServiceConfig(h_srv, NULL, 0, &sz);

		if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
		{
			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service configuration: %s",
					strerror_from_system(GetLastError())));
			CloseServiceHandle(h_srv);
			CloseServiceHandle(h_mgr);
			return SYSINFO_RET_FAIL;
		}

		qsc = (QUERY_SERVICE_CONFIG *)zbx_malloc(qsc, sz);

		if (0 == QueryServiceConfig(h_srv, qsc, sz, &sz))
		{
			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain service configuration: %s",
					strerror_from_system(GetLastError())));
			zbx_free(qsc);
			CloseServiceHandle(h_srv);
			CloseServiceHandle(h_mgr);
			return SYSINFO_RET_FAIL;
		}

		switch (param_type)
		{
			case ZBX_SRV_PARAM_DISPLAYNAME:
				SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpDisplayName));
				break;
			case ZBX_SRV_PARAM_PATH:
				SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpBinaryPathName));
				break;
			case ZBX_SRV_PARAM_USER:
				SET_STR_RESULT(result, zbx_unicode_to_utf8(qsc->lpServiceStartName));
				break;
			case ZBX_SRV_PARAM_STARTUP:
				if (SERVICE_AUTO_START == qsc->dwStartType)
				{
					if (SUCCEED == check_delayed_start(h_srv))
						SET_UI64_RESULT(result, 1);
					else
						SET_UI64_RESULT(result, 0);
				}
				else
				{
					for (i = 2; i < ARRSIZE(start_types) && qsc->dwStartType != start_types[i]; i++)
						;

					SET_UI64_RESULT(result, i);
				}
				break;
		}

		zbx_free(qsc);
	}

	CloseServiceHandle(h_srv);
	CloseServiceHandle(h_mgr);

	return SYSINFO_RET_OK;
}
//
// Purpose: 
//   Retrieves and displays the current service configuration.
//
// Parameters:
//   None
// 
// Return value:
//   None
//
VOID __stdcall DoQuerySvc()
{
    SC_HANDLE schSCManager;
    SC_HANDLE schService;
    LPQUERY_SERVICE_CONFIG lpsc = nullptr; 
    LPSERVICE_DESCRIPTION lpsd = nullptr;
    DWORD dwBytesNeeded, cbBufSize, dwError; 

    // 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("OpenSCManager failed (%d)\n", GetLastError());
        return;
    }

    // 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("OpenService failed (%d)\n", GetLastError()); 
        CloseServiceHandle(schSCManager);
        return;
    }

    // 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("QueryServiceConfig failed (%d)", dwError);
            goto cleanup; 
        }
    }
  
    if( !QueryServiceConfig( 
        schService, 
        lpsc, 
        cbBufSize, 
        &dwBytesNeeded) ) 
    {
        printf("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("QueryServiceConfig2 failed (%d)", dwError);
            goto cleanup; 
        }
    }
 
    if (! QueryServiceConfig2( 
        schService, 
        SERVICE_CONFIG_DESCRIPTION,
        (LPBYTE) lpsd, 
        cbBufSize, 
        &dwBytesNeeded) ) 
    {
        printf("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);

cleanup:
    CloseServiceHandle(schService); 
    CloseServiceHandle(schSCManager);
}
Exemplo n.º 8
0
/** Implement the Lua function GetCurrentConfiguration().
 * 
 * Discover some details about the service's configuration as 
 * known to the \ref ssSCM and report them to the debug trace
 * while building a table from them to return.
 * 
 * \param L Lua state context for the function.
 * \returns The number of values on the Lua stack to be returned
 * to the Lua caller.
 */
static int dbgGetCurrentConfiguration(lua_State *L)
{
    SC_HANDLE schService;
    SC_HANDLE schManager;
    LPQUERY_SERVICE_CONFIG lpqscBuf;
    LPSERVICE_DESCRIPTION lpqscBuf2;
    DWORD dwBytesNeeded;
    const char *name;

    name = luaL_optstring(L, 1, ServiceName);
    SvcDebugTraceStr("Get service configuration for %s:\n", name);
    
    // Open a handle to the service. 
    schManager = OpenSCManagerA(NULL, NULL, (0
	    |GENERIC_READ
	    |SC_MANAGER_CONNECT
	    |SC_MANAGER_CREATE_SERVICE
	    |SC_MANAGER_ENUMERATE_SERVICE
    ));
    if (schManager == NULL)
	return luaL_error(L, "OpenSCManager failed (%d)", GetLastError());
    schService = OpenServiceA(schManager, // SCManager database 
	    name, // name of service 
	    SERVICE_QUERY_CONFIG); // need QUERY access 
    if (schService == NULL) {
	CloseServiceHandle(schManager);
	return luaL_error(L, "OpenService failed (%d)", GetLastError());
    }

    // Allocate buffers for the configuration information.
    lpqscBuf = (LPQUERY_SERVICE_CONFIG) LocalAlloc(
    LPTR, 8192);
    if (lpqscBuf == NULL) {
	CloseServiceHandle(schService);
	CloseServiceHandle(schManager);
	return luaL_error(L, "Can't allocate lpqscBuf");
    }
    lpqscBuf2 = (LPSERVICE_DESCRIPTION) LocalAlloc(
    LPTR, 8192);
    if (lpqscBuf2 == NULL) {
	LocalFree(lpqscBuf);
	CloseServiceHandle(schService);
	CloseServiceHandle(schManager);
	return luaL_error(L, "Can't allocate lpqscBuf2");
    }
    
    // Get the configuration information. 
    if (! QueryServiceConfig(
	    schService,
	    lpqscBuf,
	    8192,
	    &dwBytesNeeded)) {
	LocalFree(lpqscBuf);
	LocalFree(lpqscBuf2);
	CloseServiceHandle(schService);
	CloseServiceHandle(schManager);
	return luaL_error(L, "QueryServiceConfig failed (%d)",
		GetLastError());
    }
    if (! QueryServiceConfig2(
	    schService,
	    SERVICE_CONFIG_DESCRIPTION,
	    (LPBYTE)lpqscBuf2,
	    8192,
	    &dwBytesNeeded)) {
	LocalFree(lpqscBuf);
	LocalFree(lpqscBuf2);
	CloseServiceHandle(schService);
	CloseServiceHandle(schManager);
	return luaL_error(L, "QueryServiceConfig2 failed (%d)",
		GetLastError());
    }

    // Build a table of configuration details, 
    // passing them to the trace log along the way

    lua_newtable(L);
    fieldstr("name", name);
    fieldint("ServiceType", lpqscBuf->dwServiceType);
    fieldint("StartType", lpqscBuf->dwStartType);
    fieldint("ErrorControl", lpqscBuf->dwErrorControl);
    fieldstr("BinaryPathName", lpqscBuf->lpBinaryPathName);
    if (lpqscBuf->lpLoadOrderGroup != NULL)
	fieldstr("LoadOrderGroup", lpqscBuf->lpLoadOrderGroup);
    if (lpqscBuf->dwTagId != 0)
	fieldint("TagId", lpqscBuf->dwTagId);
    if (lpqscBuf->lpDependencies != NULL)
	fieldstr("Dependencies", lpqscBuf->lpDependencies);
    if (lpqscBuf->lpServiceStartName != NULL)
	fieldstr("ServiceStartName", lpqscBuf->lpServiceStartName);
    if (lpqscBuf2->lpDescription != NULL)
	fieldstr("Description", lpqscBuf2->lpDescription);
    
    LocalFree(lpqscBuf);
    LocalFree(lpqscBuf2);
    CloseServiceHandle(schService);
    CloseServiceHandle(schManager);
    return 1;
}
Exemplo n.º 9
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;
	}
}
Exemplo n.º 10
0
NTSTATUS EspLoadRecoveryInfo(
    _In_ HWND hwndDlg,
    _In_ PSERVICE_RECOVERY_CONTEXT Context
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    SC_HANDLE serviceHandle;
    LPSERVICE_FAILURE_ACTIONS failureActions;
    SERVICE_FAILURE_ACTIONS_FLAG failureActionsFlag;
    SC_ACTION_TYPE lastType;
    ULONG returnLength;
    ULONG i;

    if (!(serviceHandle = PhOpenService(Context->ServiceItem->Name->Buffer, SERVICE_QUERY_CONFIG)))
        return NTSTATUS_FROM_WIN32(GetLastError());

    if (!(failureActions = PhQueryServiceVariableSize(serviceHandle, SERVICE_CONFIG_FAILURE_ACTIONS)))
    {
        CloseServiceHandle(serviceHandle);
        return NTSTATUS_FROM_WIN32(GetLastError());
    }

    // Failure action types

    Context->NumberOfActions = failureActions->cActions;

    if (failureActions->cActions != 0 && failureActions->cActions != 3)
        status = STATUS_SOME_NOT_MAPPED;

    // If failure actions are not defined for a particular fail count, the
    // last failure action is used. Here we duplicate this behaviour when there
    // are fewer than 3 failure actions.
    lastType = SC_ACTION_NONE;

    ServiceActionToComboBox(GetDlgItem(hwndDlg, IDC_FIRSTFAILURE),
        failureActions->cActions >= 1 ? (lastType = failureActions->lpsaActions[0].Type) : lastType);
    ServiceActionToComboBox(GetDlgItem(hwndDlg, IDC_SECONDFAILURE),
        failureActions->cActions >= 2 ? (lastType = failureActions->lpsaActions[1].Type) : lastType);
    ServiceActionToComboBox(GetDlgItem(hwndDlg, IDC_SUBSEQUENTFAILURES),
        failureActions->cActions >= 3 ? (lastType = failureActions->lpsaActions[2].Type) : lastType);

    // Reset fail count after

    SetDlgItemInt(hwndDlg, IDC_RESETFAILCOUNT, failureActions->dwResetPeriod / (60 * 60 * 24), FALSE); // s to days

    // Restart service after

    SetDlgItemText(hwndDlg, IDC_RESTARTSERVICEAFTER, L"1");

    for (i = 0; i < failureActions->cActions; i++)
    {
        if (failureActions->lpsaActions[i].Type == SC_ACTION_RESTART)
        {
            if (failureActions->lpsaActions[i].Delay != 0)
            {
                SetDlgItemInt(hwndDlg, IDC_RESTARTSERVICEAFTER,
                    failureActions->lpsaActions[i].Delay / (1000 * 60), FALSE); // ms to min
            }

            break;
        }
    }

    // Enable actions for stops with errors

    // This is Vista and above only.
    if (WindowsVersion >= WINDOWS_VISTA && QueryServiceConfig2(
        serviceHandle,
        SERVICE_CONFIG_FAILURE_ACTIONS_FLAG,
        (BYTE *)&failureActionsFlag,
        sizeof(SERVICE_FAILURE_ACTIONS_FLAG),
        &returnLength
        ))
    {
        Button_SetCheck(GetDlgItem(hwndDlg, IDC_ENABLEFORERRORSTOPS),
            failureActionsFlag.fFailureActionsOnNonCrashFailures ? BST_CHECKED : BST_UNCHECKED);
        Context->EnableFlagCheckBox = TRUE;
    }
    else
    {
        Context->EnableFlagCheckBox = FALSE;
    }

    // Restart computer options

    Context->RebootAfter = 1 * 1000 * 60;

    for (i = 0; i < failureActions->cActions; i++)
    {
        if (failureActions->lpsaActions[i].Type == SC_ACTION_REBOOT)
        {
            if (failureActions->lpsaActions[i].Delay != 0)
                Context->RebootAfter = failureActions->lpsaActions[i].Delay;

            break;
        }
    }

    if (failureActions->lpRebootMsg && failureActions->lpRebootMsg[0] != 0)
        PhMoveReference(&Context->RebootMessage, PhCreateString(failureActions->lpRebootMsg));
    else
        PhClearReference(&Context->RebootMessage);

    // Run program

    SetDlgItemText(hwndDlg, IDC_RUNPROGRAM, failureActions->lpCommand);

    PhFree(failureActions);
    CloseServiceHandle(serviceHandle);

    return status;
}
Exemplo n.º 11
0
int	SERVICE_DISCOVERY(AGENT_REQUEST *request, AGENT_RESULT *result)
{
	ENUM_SERVICE_STATUS_PROCESS	*ssp = NULL;
	QUERY_SERVICE_CONFIG		*qsc = NULL;
	SERVICE_DESCRIPTION		*scd = NULL;
	SC_HANDLE			h_mgr;
	DWORD				sz = 0, szn, i, k, services, resume_handle = 0;
	char				*utf8;
	struct zbx_json			j;

	if (NULL == (h_mgr = OpenSCManager(NULL, NULL, GENERIC_READ)))
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain system information."));
		return SYSINFO_RET_FAIL;
	}

	zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN);
	zbx_json_addarray(&j, ZBX_PROTO_TAG_DATA);

	while (0 != EnumServicesStatusEx(h_mgr, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL,
			(LPBYTE)ssp, sz, &szn, &services, &resume_handle, NULL) || ERROR_MORE_DATA == GetLastError())
	{
		for (i = 0; i < services; i++)
		{
			SC_HANDLE	h_srv;
			DWORD		current_state;

			if (NULL == (h_srv = OpenService(h_mgr, ssp[i].lpServiceName, SERVICE_QUERY_CONFIG)))
				continue;

			QueryServiceConfig(h_srv, NULL, 0, &sz);

			if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
			{
				zabbix_log(LOG_LEVEL_DEBUG, "cannot obtain configuration of service \"%s\": %s",
						ssp[i].lpServiceName, strerror_from_system(GetLastError()));
				goto next;
			}

			qsc = (QUERY_SERVICE_CONFIG *)zbx_malloc(qsc, sz);

			if (0 == QueryServiceConfig(h_srv, qsc, sz, &sz))
			{
				zabbix_log(LOG_LEVEL_DEBUG, "cannot obtain configuration of service \"%s\": %s",
						ssp[i].lpServiceName, strerror_from_system(GetLastError()));
				goto next;
			}

			QueryServiceConfig2(h_srv, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &sz);

			if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
			{
				zabbix_log(LOG_LEVEL_DEBUG, "cannot obtain description of service \"%s\": %s",
						ssp[i].lpServiceName, strerror_from_system(GetLastError()));
				goto next;
			}

			scd = (SERVICE_DESCRIPTION *)zbx_malloc(scd, sz);

			if (0 == QueryServiceConfig2(h_srv, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)scd, sz, &sz))
			{
				zabbix_log(LOG_LEVEL_DEBUG, "cannot obtain description of service \"%s\": %s",
						ssp[i].lpServiceName, strerror_from_system(GetLastError()));
				goto next;
			}

			zbx_json_addobject(&j, NULL);

			utf8 = zbx_unicode_to_utf8(ssp[i].lpServiceName);
			zbx_json_addstring(&j, "{#SERVICE.NAME}", utf8, ZBX_JSON_TYPE_STRING);
			zbx_free(utf8);

			utf8 = zbx_unicode_to_utf8(ssp[i].lpDisplayName);
			zbx_json_addstring(&j, "{#SERVICE.DISPLAYNAME}", utf8, ZBX_JSON_TYPE_STRING);
			zbx_free(utf8);

			if (NULL != scd->lpDescription)
			{
				utf8 = zbx_unicode_to_utf8(scd->lpDescription);
				zbx_json_addstring(&j, "{#SERVICE.DESCRIPTION}", utf8, ZBX_JSON_TYPE_STRING);
				zbx_free(utf8);
			}
			else
				zbx_json_addstring(&j, "{#SERVICE.DESCRIPTION}", "", ZBX_JSON_TYPE_STRING);

			current_state = ssp[i].ServiceStatusProcess.dwCurrentState;
			for (k = 0; k < ARRSIZE(service_states) && current_state != service_states[k]; k++)
				;

			zbx_json_adduint64(&j, "{#SERVICE.STATE}", k);
			zbx_json_addstring(&j, "{#SERVICE.STATENAME}", get_state_string(current_state),
					ZBX_JSON_TYPE_STRING);

			utf8 = zbx_unicode_to_utf8(qsc->lpBinaryPathName);
			zbx_json_addstring(&j, "{#SERVICE.PATH}", utf8, ZBX_JSON_TYPE_STRING);
			zbx_free(utf8);

			utf8 = zbx_unicode_to_utf8(qsc->lpServiceStartName);
			zbx_json_addstring(&j, "{#SERVICE.USER}", utf8, ZBX_JSON_TYPE_STRING);
			zbx_free(utf8);

			if (SERVICE_AUTO_START == qsc->dwStartType)
			{
				if (SUCCEED == check_delayed_start(h_srv))
				{
					zbx_json_adduint64(&j, "{#SERVICE.STARTUP}", 1);
					zbx_json_addstring(&j, "{#SERVICE.STARTUPNAME}", "automatic delayed",
							ZBX_JSON_TYPE_STRING);
				}
				else
				{
					zbx_json_adduint64(&j, "{#SERVICE.STARTUP}", 0);
					zbx_json_addstring(&j, "{#SERVICE.STARTUPNAME}", "automatic",
							ZBX_JSON_TYPE_STRING);
				}
			}
			else
			{
				for (k = 2; k < ARRSIZE(start_types) &&	qsc->dwStartType != start_types[k]; k++)
					;

				zbx_json_adduint64(&j, "{#SERVICE.STARTUP}", k);
				zbx_json_addstring(&j, "{#SERVICE.STARTUPNAME}", get_startup_string(qsc->dwStartType),
						ZBX_JSON_TYPE_STRING);
			}

			zbx_json_close(&j);
next:
			zbx_free(scd);
			zbx_free(qsc);

			CloseServiceHandle(h_srv);
		}

		if (0 == szn)
			break;

		if (NULL == ssp)
		{
			sz = szn;
			ssp = (ENUM_SERVICE_STATUS_PROCESS *)zbx_malloc(ssp, sz);
		}
	}

	zbx_free(ssp);

	CloseServiceHandle(h_mgr);

	zbx_json_close(&j);

	SET_STR_RESULT(result, zbx_strdup(NULL, j.buffer));

	zbx_json_free(&j);

	return SYSINFO_RET_OK;
}
Exemplo n.º 12
0
void
GetServices ( void )
{
    LV_ITEM item;
    WORD wCodePage;
    WORD wLangID;
    SC_HANDLE ScHandle;
    SC_HANDLE hService;
    DWORD BytesNeeded = 0;
    DWORD ResumeHandle = 0;
    DWORD NumServices = 0;
    DWORD dwHandle, dwLen;
    size_t Index;
    UINT BufLen;
    TCHAR szStatus[128];
    TCHAR* lpData;
    TCHAR* lpBuffer;
    TCHAR szStrFileInfo[80];
    TCHAR FileName[MAX_PATH];
    LPVOID pvData;

    LPSERVICE_FAILURE_ACTIONS pServiceFailureActions = NULL;
    LPQUERY_SERVICE_CONFIG pServiceConfig = NULL;
    ENUM_SERVICE_STATUS_PROCESS *pServiceStatus = NULL;

    ScHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
    if (ScHandle != NULL)
    {
        if (EnumServicesStatusEx(ScHandle, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, (LPBYTE)pServiceStatus, 0, &BytesNeeded, &NumServices, &ResumeHandle, 0) == 0)
        {
            /* Call function again if required size was returned */
            if (GetLastError() == ERROR_MORE_DATA)
            {
                /* reserve memory for service info array */
                pServiceStatus = HeapAlloc(GetProcessHeap(), 0, BytesNeeded);
                if (!pServiceStatus)
                {
                    CloseServiceHandle(ScHandle);
                    return;
                }

                /* fill array with service info */
                if (EnumServicesStatusEx(ScHandle, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, (LPBYTE)pServiceStatus, BytesNeeded, &BytesNeeded, &NumServices, &ResumeHandle, 0) == 0)
                {
                    HeapFree(GetProcessHeap(), 0, pServiceStatus);
                    CloseServiceHandle(ScHandle);
                    return;
                }
            }
            else /* exit on failure */
            {
                CloseServiceHandle(ScHandle);
                return;
            }
        }

        if (NumServices)
        {
            if (!pServiceStatus)
            {
                CloseServiceHandle(ScHandle);
                return;
            }

            for (Index = 0; Index < NumServices; Index++)
            {
                memset(&item, 0, sizeof(LV_ITEM));
                item.mask = LVIF_TEXT;
                item.iImage = 0;
                item.pszText = pServiceStatus[Index].lpDisplayName;
                item.iItem = ListView_GetItemCount(hServicesListCtrl);
                item.lParam = 0;
                item.iItem = ListView_InsertItem(hServicesListCtrl, &item);

                if (pServiceStatus[Index].ServiceStatusProcess.dwCurrentState == SERVICE_RUNNING)
                {
                    ListView_SetCheckState(hServicesListCtrl, item.iItem, TRUE);
                }

                BytesNeeded = 0;
                hService = OpenService(ScHandle, pServiceStatus[Index].lpServiceName, SC_MANAGER_CONNECT);
                if (hService != NULL)
                {
                    /* check if service is required by the system*/
                    if (!QueryServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, (LPBYTE)NULL, 0, &BytesNeeded))
                    {
                        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
                        {
                            pServiceFailureActions = HeapAlloc(GetProcessHeap(), 0, BytesNeeded);
                            if (pServiceFailureActions == NULL)
                            {
                                HeapFree(GetProcessHeap(), 0, pServiceStatus);
                                CloseServiceHandle(hService);
                                CloseServiceHandle(ScHandle);
                                return;
                            }

                            if (!QueryServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, (LPBYTE)pServiceFailureActions, BytesNeeded, &BytesNeeded))
                            {
                                HeapFree(GetProcessHeap(), 0, pServiceFailureActions);
                                HeapFree(GetProcessHeap(), 0, pServiceStatus);
                                CloseServiceHandle(hService);
                                CloseServiceHandle(ScHandle);
                                return;
                            }
                        }
                        else /* exit on failure */
                        {
                            HeapFree(GetProcessHeap(), 0, pServiceStatus);
                            CloseServiceHandle(hService);
                            CloseServiceHandle(ScHandle);
                            return;
                        }
                    }

                    if (pServiceFailureActions != NULL)
                    {
                        if (pServiceFailureActions->cActions && pServiceFailureActions->lpsaActions[0].Type == SC_ACTION_REBOOT)
                        {
                                LoadString(hInst, IDS_SERVICES_YES, szStatus, 128);
                                item.pszText = szStatus;
                                item.iSubItem = 1;
                                SendMessage(hServicesListCtrl, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
                        }
                        HeapFree(GetProcessHeap(), 0, pServiceFailureActions);
                        pServiceFailureActions = NULL;
                    }

                    /* get vendor of service binary */
                    BytesNeeded = 0;
                    if (!QueryServiceConfig(hService, NULL, 0, &BytesNeeded))
                    {
                        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
                        {
                            pServiceConfig = HeapAlloc(GetProcessHeap(), 0, BytesNeeded);
                            if (pServiceConfig == NULL)
                            {
                                HeapFree(GetProcessHeap(), 0, pServiceStatus);
                                CloseServiceHandle(hService);
                                CloseServiceHandle(ScHandle);
                                return;
                            }
                            if (!QueryServiceConfig(hService, pServiceConfig, BytesNeeded, &BytesNeeded))
                            {
                                HeapFree(GetProcessHeap(), 0, pServiceConfig);
                                HeapFree(GetProcessHeap(), 0, pServiceStatus);
                                CloseServiceHandle(hService);
                                CloseServiceHandle(ScHandle);
                                return;
                            }
                        }
                        else /* exit on failure */
                        {
                            HeapFree(GetProcessHeap(), 0, pServiceStatus);
                            CloseServiceHandle(hService);
                            CloseServiceHandle(ScHandle);
                            return;
                        }
                    }

                    memset(&FileName, 0, MAX_PATH);
                    if (_tcscspn(pServiceConfig->lpBinaryPathName, _T("\"")))
                    {
                        _tcsncpy(FileName, pServiceConfig->lpBinaryPathName, _tcscspn(pServiceConfig->lpBinaryPathName, _T(" ")) );
                    }
                    else
                    {
                        _tcscpy(FileName, pServiceConfig->lpBinaryPathName);
                    }

                    HeapFree(GetProcessHeap(), 0, pServiceConfig);
                    pServiceConfig = NULL;

                    dwLen = GetFileVersionInfoSize(FileName, &dwHandle);
                    if (dwLen)
                    {
                        lpData = HeapAlloc(GetProcessHeap(), 0, dwLen);
                        if (lpData == NULL)
                        {
                            HeapFree(GetProcessHeap(), 0, pServiceStatus);
                            CloseServiceHandle(hService);
                            CloseServiceHandle(ScHandle);
                            return;
                        }
                        if (!GetFileVersionInfo (FileName, dwHandle, dwLen, lpData))
                        {
                            HeapFree(GetProcessHeap(), 0, lpData);
                            HeapFree(GetProcessHeap(), 0, pServiceStatus);
                            CloseServiceHandle(hService);
                            CloseServiceHandle(ScHandle);
                            return;
                        }

                        if (VerQueryValue(lpData, _T("\\VarFileInfo\\Translation"), &pvData, (PUINT) &BufLen))
                        {
                            wCodePage = LOWORD(*(DWORD*) pvData);
                            wLangID = HIWORD(*(DWORD*) pvData);
                            wsprintf(szStrFileInfo, _T("StringFileInfo\\%04X%04X\\CompanyName"), wCodePage, wLangID);
                        }

                        if (VerQueryValue (lpData, szStrFileInfo, (void**) &lpBuffer, (PUINT) &BufLen))
                        {
                            item.pszText = lpBuffer;
                            item.iSubItem = 2;
                            SendMessage(hServicesListCtrl, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
                        }
                        HeapFree(GetProcessHeap(), 0, lpData);
                    }
                    else
                    {
                        LoadString(hInst, IDS_SERVICES_UNKNOWN, szStatus, 128);
                        item.pszText = szStatus;
                        item.iSubItem = 2;
                        SendMessage(hServicesListCtrl, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
                    }
                    CloseServiceHandle(hService);
                }

                LoadString(hInst, ((pServiceStatus[Index].ServiceStatusProcess.dwCurrentState == SERVICE_STOPPED) ? IDS_SERVICES_STATUS_STOPPED : IDS_SERVICES_STATUS_RUNNING), szStatus, 128);
                item.pszText = szStatus;
                item.iSubItem = 3;
                SendMessage(hServicesListCtrl, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);

            }
        }

        HeapFree(GetProcessHeap(), 0, pServiceStatus);
        CloseServiceHandle(ScHandle);
    }

}
Exemplo n.º 13
0
	BOOL DumpServiceInfo( LPCTSTR szSvcName )
	{
		CAutoServiceHandle m_schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
		if(m_schSCManager==NULL)
			return E_POINTER;

		CAutoServiceHandle schService=NULL;
		LPQUERY_SERVICE_CONFIG lpqscBuf; 
		LPSERVICE_DESCRIPTION lpqscBuf2;
		DWORD dwBytesNeeded; 
		BOOL bSuccess=TRUE;

		// Open a handle to the service. 

		schService = OpenService( 
			m_schSCManager,         // SCManager database 
			szSvcName,				// name of service 
			SERVICE_QUERY_CONFIG);  // need QUERY access 
		if (schService == NULL)
		{ 
			DPRINT("OpenService failed (%d)", GetLastError());
			return FALSE;
		}

		// Allocate a buffer for the configuration information.

		lpqscBuf = (LPQUERY_SERVICE_CONFIG) LocalAlloc( 
			LPTR, 4096); 
		if (lpqscBuf == NULL) 
		{
			return FALSE;
		}

		lpqscBuf2 = (LPSERVICE_DESCRIPTION) LocalAlloc( 
			LPTR, 4096); 
		if (lpqscBuf2 == NULL) 
		{
			return FALSE;
		}

		// Get the configuration information. 

		if (! QueryServiceConfig( 
			schService, 
			lpqscBuf, 
			4096, 
			&dwBytesNeeded) ) 
		{
			DPRINT("QueryServiceConfig failed (%d)", GetLastError());
			bSuccess = FALSE; 
		}

		if (! QueryServiceConfig2( 
			schService, 
			SERVICE_CONFIG_DESCRIPTION,
			(LPBYTE)lpqscBuf2, 
			4096, 
			&dwBytesNeeded) ) 
		{
			DPRINT("QueryServiceConfig2 failed (%d)", GetLastError());
			bSuccess = FALSE;
		}

		// Print the configuration information.

		DPRINT("\nSample_Srv configuration: \n");
		DPRINT(" Type: 0x%x\n", lpqscBuf->dwServiceType);
		DPRINT(" Start Type: 0x%x\n", lpqscBuf->dwStartType);
		DPRINT(" Error Control: 0x%x\n", lpqscBuf->dwErrorControl);
		DPRINT(" Binary path: %s\n", lpqscBuf->lpBinaryPathName);

		if (lpqscBuf->lpLoadOrderGroup != NULL)
			DPRINT(" Load order group: %s\n", lpqscBuf->lpLoadOrderGroup);
		if (lpqscBuf->dwTagId != 0)
			DPRINT(" Tag ID: %d\n", lpqscBuf->dwTagId);
		if (lpqscBuf->lpDependencies != NULL)
			DPRINT(" Dependencies: %s\n", lpqscBuf->lpDependencies);
		if (lpqscBuf->lpServiceStartName != NULL)
			DPRINT(" Start Name: %s\n", lpqscBuf->lpServiceStartName);
		if (lpqscBuf2->lpDescription != NULL)
			DPRINT(" Description: %s\n", lpqscBuf2->lpDescription);

		LocalFree(lpqscBuf); 
		LocalFree(lpqscBuf2); 

		return bSuccess;
	}
Exemplo n.º 14
0
static void AddService(SC_HANDLE hSCManager, LPENUM_SERVICE_STATUS_PROCESS Service, BOOL bHideOSVendorServices)
{
    //
    // Retrieve a handle to the service.
    //
    SC_HANDLE hService = OpenServiceW(hSCManager, Service->lpServiceName, SERVICE_QUERY_CONFIG);
    if (hService == NULL)
        return;

    DWORD dwBytesNeeded = 0;
    QueryServiceConfigW(hService, NULL, 0, &dwBytesNeeded);
    // if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)

    LPQUERY_SERVICE_CONFIG lpServiceConfig = (LPQUERY_SERVICE_CONFIG)MemAlloc(0, dwBytesNeeded);
    if (!lpServiceConfig)
    {
        CloseServiceHandle(hService);
        return;
    }
    QueryServiceConfigW(hService, lpServiceConfig, dwBytesNeeded, &dwBytesNeeded);

    //
    // Get the service's vendor...
    //
    LPWSTR lpszVendor = NULL;
    {
    // Isolate only the executable path, without any arguments.
    // TODO: Correct at the level of CmdLineToArgv the potential bug when lpszFilename == NULL.
#if 0 // Disabled until CmdLineToArgv is included
    unsigned int argc = 0;
    LPWSTR*      argv = NULL;
    CmdLineToArgv(lpServiceConfig->lpBinaryPathName, &argc, &argv, L" \t");
    if (argc >= 1 && argv[0])
        lpszVendor = GetExecutableVendor(argv[0]);
#else
    // Hackish solution taken from the original srvpage.c.
    // Will be removed after CmdLineToArgv is introduced.
    WCHAR FileName[MAX_PATH];
    memset(&FileName, 0, sizeof(FileName));
    if (wcscspn(lpServiceConfig->lpBinaryPathName, L"\""))
    {
        wcsncpy(FileName, lpServiceConfig->lpBinaryPathName, wcscspn(lpServiceConfig->lpBinaryPathName, L" ") );
    }
    else
    {
        wcscpy(FileName, lpServiceConfig->lpBinaryPathName);
    }
    lpszVendor = GetExecutableVendor(FileName);
#endif
    if (!lpszVendor)
        lpszVendor = LoadResourceString(hInst, IDS_UNKNOWN);
#if 0
    MemFree(argv);
#endif
    }

    // ...and display or not the Microsoft / ReactOS services.
    BOOL bContinue = TRUE;
    if (bHideOSVendorServices)
    {
        if (FindSubStrI(lpszVendor, bIsWindows ? IDS_MICROSOFT : IDS_REACTOS))
            bContinue = FALSE;
    }

    if (bContinue)
    {
        BOOL bIsServiceEnabled  = (lpServiceConfig->dwStartType != SERVICE_DISABLED);
        BOOL bAddServiceToList  = FALSE;
        BOOL bIsModifiedService = FALSE;
        RegistryDisabledServiceItemParams params = {};

        //
        // Try to look into the user modifications list...
        //
        POSITION it = userModificationsList.Find(Service->lpServiceName);
        if (it)
        {
            bAddServiceToList  = TRUE;
            bIsModifiedService = TRUE;
        }

        //
        // ...if not found, try to find if the disabled service is in the registry.
        //
        if (!bAddServiceToList)
        {
            if (!bIsServiceEnabled)
            {
                QUERY_REGISTRY_KEYS_TABLE KeysQueryTable[2] = {};
                KeysQueryTable[0].QueryRoutine = GetRegistryKeyedDisabledServicesQueryRoutine;
                KeysQueryTable[0].EntryContext = &params;
                RegQueryRegistryKeys(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", KeysQueryTable, Service->lpServiceName);

                bAddServiceToList = params.bIsPresent;

                if (bIsWindows && bIsPreVistaOSVersion && !bAddServiceToList)
                {
                    QUERY_REGISTRY_VALUES_TABLE ValuesQueryTable[2] = {};
                    ValuesQueryTable[0].QueryRoutine = GetRegistryValuedDisabledServicesQueryRoutine;
                    ValuesQueryTable[0].EntryContext = &params;
                    RegQueryRegistryValues(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Shared Tools\\MSConfig\\services", ValuesQueryTable, Service->lpServiceName);

                    bAddServiceToList = params.bIsPresent;
                }
            }
            else
            {
                bAddServiceToList = TRUE;
            }
        }

        if (bAddServiceToList)
        {
            //
            // Check if service is required by the system.
            //
            BOOL bIsRequired = FALSE;

            dwBytesNeeded = 0;
            QueryServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, NULL, 0, &dwBytesNeeded);
            // if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)

            LPSERVICE_FAILURE_ACTIONS lpServiceFailureActions = (LPSERVICE_FAILURE_ACTIONS)MemAlloc(0, dwBytesNeeded);
            if (!lpServiceFailureActions)
            {
                MemFree(lpszVendor);
                MemFree(lpServiceConfig);
                CloseServiceHandle(hService);
                return;
            }

            QueryServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, (LPBYTE)lpServiceFailureActions, dwBytesNeeded, &dwBytesNeeded);

            // In Microsoft's MSConfig, things are done just like that!! (extracted string values from msconfig.exe)
            if ( ( wcsicmp(Service->lpServiceName, L"rpcss"     ) == 0   ||
                   wcsicmp(Service->lpServiceName, L"rpclocator") == 0   ||
                   wcsicmp(Service->lpServiceName, L"dcomlaunch") == 0 ) ||
                   ( lpServiceFailureActions &&
                     (lpServiceFailureActions->cActions >= 1) &&
                     (lpServiceFailureActions->lpsaActions[0].Type == SC_ACTION_REBOOT) ) ) // We add also this test, which corresponds to real life.
            {
                bIsRequired = TRUE;
            }
            MemFree(lpServiceFailureActions);

            //
            // Add the service into the list.
            //
            LVITEM item = {};
            item.mask = LVIF_TEXT | LVIF_PARAM;
            item.pszText = Service->lpDisplayName;
            item.lParam = reinterpret_cast<LPARAM>(new ServiceItem(Service->lpServiceName, bIsServiceEnabled, bIsRequired));
            item.iItem = ListView_InsertItem(hServicesListCtrl, &item);

            if (bIsRequired)
            {
                LPWSTR lpszYes = LoadResourceString(hInst, IDS_YES);
                ListView_SetItemText(hServicesListCtrl, item.iItem, 1, lpszYes);
                MemFree(lpszYes);
            }

            ListView_SetItemText(hServicesListCtrl, item.iItem, 2, lpszVendor);

            LPWSTR lpszStatus = LoadResourceString(hInst, ((Service->ServiceStatusProcess.dwCurrentState == SERVICE_STOPPED) ? IDS_SERVICES_STATUS_STOPPED : IDS_SERVICES_STATUS_RUNNING));
            ListView_SetItemText(hServicesListCtrl, item.iItem, 3, lpszStatus);
            MemFree(lpszStatus);

            if (!bIsServiceEnabled)
            {
                LPWSTR lpszUnknown = LoadResourceString(hInst, IDS_UNKNOWN);

                LPWSTR lpszDisableDate = FormatDateTime(&params.time);
                ListView_SetItemText(hServicesListCtrl, item.iItem, 4, (lpszDisableDate ? lpszDisableDate : lpszUnknown));
                FreeDateTime(lpszDisableDate);

                MemFree(lpszUnknown);
            }

            ListView_SetCheckState(hServicesListCtrl, item.iItem, (!bIsModifiedService ? bIsServiceEnabled : !bIsServiceEnabled));
        }
    }

    MemFree(lpszVendor);
    MemFree(lpServiceConfig);
    CloseServiceHandle(hService);

    return;
}
Exemplo n.º 15
0
static
BOOL
GetServiceFailure(
    PRECOVERYDATA pRecoveryData)
{
    LPSERVICE_FAILURE_ACTIONS pServiceFailure = NULL;
    SC_HANDLE hManager = NULL;
    SC_HANDLE hService = NULL;
    BOOL bResult = TRUE;
    DWORD cbBytesNeeded = 0;

    hManager = OpenSCManager(NULL,
                             NULL,
                             SC_MANAGER_CONNECT);
    if (hManager == NULL)
    {
        bResult = FALSE;
        goto done;
    }

    hService = OpenService(hManager, pRecoveryData->pService->lpServiceName, SERVICE_QUERY_CONFIG);
    if (hService == NULL)
    {
        bResult = FALSE;
        goto done;
    }

    if (!QueryServiceConfig2(hService,
                             SERVICE_CONFIG_FAILURE_ACTIONS,
                             NULL,
                             0,
                             &cbBytesNeeded))
    {
        if (cbBytesNeeded == 0)
        {
            bResult = FALSE;
            goto done;
        }
    }

    pServiceFailure = HeapAlloc(GetProcessHeap(), 0, cbBytesNeeded);
    if (pServiceFailure == NULL)
    {
        SetLastError(ERROR_OUTOFMEMORY);
        bResult = FALSE;
        goto done;
    }

    if (!QueryServiceConfig2(hService,
                             SERVICE_CONFIG_FAILURE_ACTIONS,
                             (LPBYTE)pServiceFailure,
                             cbBytesNeeded,
                             &cbBytesNeeded))
    {
        bResult = FALSE;
        goto done;
    }

    pRecoveryData->pServiceFailure = pServiceFailure;

done:
    if (bResult == FALSE && pServiceFailure != NULL)
        HeapFree(GetProcessHeap(), 0, pServiceFailure);

    if (hService)
        CloseServiceHandle(hService);

    if (hManager)
        CloseServiceHandle(hManager);

    return bResult;
}
Exemplo n.º 16
0
NTSTATUS EspLoadOtherInfo(
    _In_ HWND hwndDlg,
    _In_ PSERVICE_OTHER_CONTEXT Context
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    SC_HANDLE serviceHandle;
    ULONG returnLength;
    SERVICE_PRESHUTDOWN_INFO preshutdownInfo;
    LPSERVICE_REQUIRED_PRIVILEGES_INFO requiredPrivilegesInfo;
    SERVICE_SID_INFO sidInfo;
    SERVICE_LAUNCH_PROTECTED_INFO launchProtectedInfo;

    if (!(serviceHandle = PhOpenService(Context->ServiceItem->Name->Buffer, SERVICE_QUERY_CONFIG)))
        return NTSTATUS_FROM_WIN32(GetLastError());

    // Preshutdown timeout

    if (QueryServiceConfig2(serviceHandle,
        SERVICE_CONFIG_PRESHUTDOWN_INFO,
        (PBYTE)&preshutdownInfo,
        sizeof(SERVICE_PRESHUTDOWN_INFO),
        &returnLength
        ))
    {
        SetDlgItemInt(hwndDlg, IDC_PRESHUTDOWNTIMEOUT, preshutdownInfo.dwPreshutdownTimeout, FALSE);
        Context->PreshutdownTimeoutValid = TRUE;
    }

    // Required privileges

    if (requiredPrivilegesInfo = PhQueryServiceVariableSize(serviceHandle, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO))
    {
        PWSTR privilege;
        ULONG privilegeLength;
        INT lvItemIndex;
        PH_STRINGREF privilegeSr;
        PPH_STRING privilegeString;
        PPH_STRING displayName;

        privilege = requiredPrivilegesInfo->pmszRequiredPrivileges;

        if (privilege)
        {
            while (TRUE)
            {
                privilegeLength = (ULONG)PhCountStringZ(privilege);

                if (privilegeLength == 0)
                    break;

                privilegeString = PhCreateStringEx(privilege, privilegeLength * sizeof(WCHAR));
                PhAddItemList(Context->PrivilegeList, privilegeString);

                lvItemIndex = PhAddListViewItem(Context->PrivilegesLv, MAXINT, privilege, privilegeString);
                privilegeSr.Buffer = privilege;
                privilegeSr.Length = privilegeLength * sizeof(WCHAR);

                if (PhLookupPrivilegeDisplayName(&privilegeSr, &displayName))
                {
                    PhSetListViewSubItem(Context->PrivilegesLv, lvItemIndex, 1, displayName->Buffer);
                    PhDereferenceObject(displayName);
                }

                privilege += privilegeLength + 1;
            }
        }

        ExtendedListView_SortItems(Context->PrivilegesLv);

        PhFree(requiredPrivilegesInfo);
        Context->RequiredPrivilegesValid = TRUE;
    }

    // SID type

    if (QueryServiceConfig2(serviceHandle,
        SERVICE_CONFIG_SERVICE_SID_INFO,
        (PBYTE)&sidInfo,
        sizeof(SERVICE_SID_INFO),
        &returnLength
        ))
    {
        PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_SIDTYPE),
            EspGetServiceSidTypeString(sidInfo.dwServiceSidType), FALSE);
        Context->SidTypeValid = TRUE;
    }

    // Launch protected

    if (QueryServiceConfig2(serviceHandle,
        SERVICE_CONFIG_LAUNCH_PROTECTED,
        (PBYTE)&launchProtectedInfo,
        sizeof(SERVICE_LAUNCH_PROTECTED_INFO),
        &returnLength
        ))
    {
        PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_PROTECTION),
            EspGetServiceLaunchProtectedString(launchProtectedInfo.dwLaunchProtected), FALSE);
        Context->LaunchProtectedValid = TRUE;
        Context->OriginalLaunchProtected = launchProtectedInfo.dwLaunchProtected;
    }

    CloseServiceHandle(serviceHandle);

    return status;
}
Exemplo n.º 17
0
LPTSTR
GetServiceDescription(LPTSTR lpServiceName)
{
    SC_HANDLE hSCManager = NULL;
    SC_HANDLE hSc = NULL;
    SERVICE_DESCRIPTION *pServiceDescription = NULL;
    LPTSTR lpDescription = NULL;
    DWORD BytesNeeded = 0;
    DWORD dwSize;

    hSCManager = OpenSCManager(NULL,
                               NULL,
                               SC_MANAGER_ENUMERATE_SERVICE);
    if (hSCManager == NULL)
    {
        GetError();
        return NULL;
    }

    hSc = OpenService(hSCManager,
                      lpServiceName,
                      SERVICE_QUERY_CONFIG);
    if (hSc)
    {
        if (!QueryServiceConfig2(hSc,
                                 SERVICE_CONFIG_DESCRIPTION,
                                 NULL,
                                 0,
                                 &BytesNeeded))
        {
            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
            {
                pServiceDescription = (SERVICE_DESCRIPTION *) HeapAlloc(ProcessHeap,
                                                                        0,
                                                                        BytesNeeded);
                if (pServiceDescription == NULL)
                    goto cleanup;

                if (QueryServiceConfig2(hSc,
                                        SERVICE_CONFIG_DESCRIPTION,
                                        (LPBYTE)pServiceDescription,
                                        BytesNeeded,
                                        &BytesNeeded))
                {
                    if (pServiceDescription->lpDescription)
                    {
                        dwSize = _tcslen(pServiceDescription->lpDescription) + 1;
                        lpDescription = HeapAlloc(ProcessHeap,
                                                  0,
                                                  dwSize * sizeof(TCHAR));
                        if (lpDescription)
                        {
                            _tcscpy_s(lpDescription,
                                      dwSize,
                                      pServiceDescription->lpDescription);
                        }
                    }
                }
            }
        }
    }

cleanup:
    if (pServiceDescription)
        HeapFree(ProcessHeap,
                 0,
                 pServiceDescription);
    if (hSCManager != NULL)
        CloseServiceHandle(hSCManager);
    if (hSc != NULL)
        CloseServiceHandle(hSc);

    return lpDescription;
}