reactos/base/applications/msconfig/srvpage.c

315 lines
13 KiB
C

/*
* PROJECT: ReactOS Applications
* LICENSE: LGPL - See COPYING in the top level directory
* FILE: base/applications/msconfig/srvpage.c
* PURPOSE: Services page message handler
* COPYRIGHT: Copyright 2005-2006 Christoph von Wittich <Christoph@ApiViewer.de>
*
*/
#include "precomp.h"
#include <winsvc.h>
#include <winver.h>
HWND hServicesPage;
HWND hServicesListCtrl;
HWND hServicesDialog;
void GetServices ( void );
INT_PTR CALLBACK
ServicesPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
LV_COLUMN column;
TCHAR szTemp[256];
DWORD dwStyle;
UNREFERENCED_PARAMETER(lParam);
UNREFERENCED_PARAMETER(wParam);
switch (message) {
case WM_INITDIALOG:
hServicesListCtrl = GetDlgItem(hDlg, IDC_SERVICES_LIST);
hServicesDialog = hDlg;
dwStyle = (DWORD) SendMessage(hServicesListCtrl, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
dwStyle = dwStyle | LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES;
SendMessage(hServicesListCtrl, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);
SetWindowPos(hDlg, NULL, 10, 32, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
// Initialize the application page's controls
column.mask = LVCF_TEXT | LVCF_WIDTH;
LoadString(hInst, IDS_SERVICES_COLUMN_SERVICE, szTemp, 256);
column.pszText = szTemp;
column.cx = 200;
(void)ListView_InsertColumn(hServicesListCtrl, 0, &column);
column.mask = LVCF_TEXT | LVCF_WIDTH;
LoadString(hInst, IDS_SERVICES_COLUMN_REQ, szTemp, 256);
column.pszText = szTemp;
column.cx = 70;
(void)ListView_InsertColumn(hServicesListCtrl, 1, &column);
column.mask = LVCF_TEXT | LVCF_WIDTH;
LoadString(hInst, IDS_SERVICES_COLUMN_VENDOR, szTemp, 256);
column.pszText = szTemp;
column.cx = 200;
(void)ListView_InsertColumn(hServicesListCtrl, 2, &column);
column.mask = LVCF_TEXT | LVCF_WIDTH;
LoadString(hInst, IDS_SERVICES_COLUMN_STATUS, szTemp, 256);
column.pszText = szTemp;
column.cx = 70;
(void)ListView_InsertColumn(hServicesListCtrl, 3, &column);
GetServices();
return TRUE;
}
return 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;
}
}
if (pServiceConfig->lpBinaryPathName[0] != _T('"'))
{
/* Assume everything before the first space is the binary path */
/* FIXME: This is a reasonable heuristic but some
* services use unquoted paths with spaces */
StringCchCopyN(FileName,
_countof(FileName),
pServiceConfig->lpBinaryPathName,
_tcscspn(pServiceConfig->lpBinaryPathName, _T(" ")));
}
else
{
/* Binary path is inside the quotes */
StringCchCopyN(FileName,
_countof(FileName),
pServiceConfig->lpBinaryPathName + 1,
_tcscspn(pServiceConfig->lpBinaryPathName + 1, _T("\"")));
}
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);
}
}