mirror of
https://github.com/reactos/reactos.git
synced 2024-11-11 01:04:11 +00:00
c424146e2c
svn path=/branches/cmake-bringup/; revision=48236
309 lines
8.2 KiB
C
309 lines
8.2 KiB
C
/*
|
|
* PROJECT: ReactOS Services
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
* FILE: base/applications/mscutils/servman/stop_dependencies.c
|
|
* PURPOSE: Routines related to stopping dependent services
|
|
* COPYRIGHT: Copyright 2006-2010 Ged Murphy <gedmurphy@reactos.org>
|
|
*
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
|
|
static LPWSTR
|
|
AddServiceToList(LPWSTR *lpServiceList,
|
|
LPWSTR lpServiceToAdd)
|
|
{
|
|
LPWSTR lpNewList = NULL;
|
|
LPWSTR ptr;
|
|
DWORD dwToAddSize;
|
|
DWORD dwCurSize;
|
|
|
|
dwToAddSize = wcslen(lpServiceToAdd) + 1;
|
|
|
|
/* Is this is the first in the list? */
|
|
if (!*lpServiceList)
|
|
{
|
|
/* Add another char for double null */
|
|
dwToAddSize++;
|
|
|
|
lpNewList = HeapAlloc(GetProcessHeap(),
|
|
0,
|
|
dwToAddSize * sizeof(WCHAR));
|
|
if (lpNewList)
|
|
{
|
|
/* Copy the service name */
|
|
wcscpy_s(lpNewList,
|
|
dwToAddSize,
|
|
lpServiceToAdd);
|
|
|
|
/* Add the double null char */
|
|
lpNewList[dwToAddSize - 1] = L'\0';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ptr = *lpServiceList;
|
|
dwCurSize = 0;
|
|
|
|
/* Get the list size */
|
|
while (TRUE)
|
|
{
|
|
/* Break when we hit the double null */
|
|
if (*ptr == L'\0' && *(ptr + 1) == L'\0')
|
|
break;
|
|
|
|
ptr++;
|
|
dwCurSize++;
|
|
}
|
|
dwCurSize++;
|
|
|
|
/* Add another char for double null */
|
|
dwCurSize++;
|
|
|
|
/* Extend the list size */
|
|
lpNewList = HeapReAlloc(GetProcessHeap(),
|
|
0,
|
|
*lpServiceList,
|
|
(dwCurSize + dwToAddSize) * sizeof(WCHAR));
|
|
if (lpNewList)
|
|
{
|
|
/* Copy the service name */
|
|
wcscpy_s(&lpNewList[dwCurSize - 1],
|
|
dwToAddSize,
|
|
lpServiceToAdd);
|
|
|
|
/* Add the double null char */
|
|
lpNewList[dwCurSize + dwToAddSize - 1] = L'\0';
|
|
}
|
|
}
|
|
|
|
return lpNewList;
|
|
}
|
|
|
|
static BOOL
|
|
BuildListOfServicesToStop(LPWSTR *lpServiceList,
|
|
LPWSTR lpServiceName)
|
|
{
|
|
LPENUM_SERVICE_STATUS lpServiceStatus;
|
|
DWORD dwCount, i;
|
|
BOOL bRet = FALSE;
|
|
|
|
/* Get a list of service dependents */
|
|
lpServiceStatus = TV2_GetDependants(lpServiceName, &dwCount);
|
|
if (lpServiceStatus)
|
|
{
|
|
for (i = 0; i < dwCount; i++)
|
|
{
|
|
/* Does this service need stopping? */
|
|
if (lpServiceStatus[i].ServiceStatus.dwCurrentState != SERVICE_STOPPED &&
|
|
lpServiceStatus[i].ServiceStatus.dwCurrentState != SERVICE_STOP_PENDING)
|
|
{
|
|
/* Does this service have any dependents? */
|
|
if (TV2_HasDependantServices(lpServiceStatus[i].lpServiceName))
|
|
{
|
|
/* recall this function with the dependent */
|
|
BuildListOfServicesToStop(lpServiceList, lpServiceStatus[i].lpServiceName);
|
|
}
|
|
|
|
/* Add the service to the list */
|
|
*lpServiceList = AddServiceToList(lpServiceList, lpServiceStatus[i].lpServiceName);
|
|
|
|
/* We've got one */
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
|
|
HeapFree(GetProcessHeap(),
|
|
0,
|
|
lpServiceStatus);
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
LPWSTR
|
|
GetListOfServicesToStop(LPWSTR lpServiceName)
|
|
{
|
|
LPWSTR lpServiceList = NULL;
|
|
|
|
/* Call recursive function to get our list */
|
|
if (BuildListOfServicesToStop(&lpServiceList, lpServiceName))
|
|
return lpServiceList;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
|
|
static VOID
|
|
AddServiceNamesToStop(HWND hServiceListBox,
|
|
LPWSTR lpServiceList)
|
|
{
|
|
LPQUERY_SERVICE_CONFIG lpServiceConfig;
|
|
LPWSTR lpStr;
|
|
|
|
lpStr = lpServiceList;
|
|
|
|
/* Loop through all the services in the list */
|
|
while (TRUE)
|
|
{
|
|
/* Break when we hit the double null */
|
|
if (*lpStr == L'\0' && *(lpStr + 1) == L'\0')
|
|
break;
|
|
|
|
/* If this isn't our first time in the loop we'll
|
|
have been left on a null char */
|
|
if (*lpStr == L'\0')
|
|
lpStr++;
|
|
|
|
/* Get the service's display name */
|
|
lpServiceConfig = GetServiceConfig(lpStr);
|
|
if (lpServiceConfig)
|
|
{
|
|
/* Add the service to the listbox */
|
|
SendMessageW(hServiceListBox,
|
|
LB_ADDSTRING,
|
|
0,
|
|
(LPARAM)lpServiceConfig->lpDisplayName);
|
|
}
|
|
|
|
/* Move onto the next string */
|
|
while (*lpStr != L'\0')
|
|
lpStr++;
|
|
}
|
|
}
|
|
|
|
static BOOL
|
|
DoInitDependsDialog(PMAIN_WND_INFO pInfo,
|
|
HWND hDlg)
|
|
{
|
|
HWND hServiceListBox;
|
|
LPWSTR lpPartialStr, lpStr;
|
|
DWORD fullLen;
|
|
HICON hIcon = NULL;
|
|
BOOL bRet = FALSE;
|
|
|
|
if (pInfo)
|
|
{
|
|
/* Tag the info to the window */
|
|
SetWindowLongPtrW(hDlg,
|
|
GWLP_USERDATA,
|
|
(LONG_PTR)pInfo);
|
|
|
|
/* Load the icon for the window */
|
|
hIcon = (HICON)LoadImageW(hInstance,
|
|
MAKEINTRESOURCE(IDI_SM_ICON),
|
|
IMAGE_ICON,
|
|
GetSystemMetrics(SM_CXSMICON),
|
|
GetSystemMetrics(SM_CXSMICON),
|
|
0);
|
|
if (hIcon)
|
|
{
|
|
/* Set it */
|
|
SendMessageW(hDlg,
|
|
WM_SETICON,
|
|
ICON_SMALL,
|
|
(LPARAM)hIcon);
|
|
DestroyIcon(hIcon);
|
|
}
|
|
|
|
/* Load the stop depends note */
|
|
if (AllocAndLoadString(&lpPartialStr,
|
|
hInstance,
|
|
IDS_STOP_DEPENDS))
|
|
{
|
|
/* Get the length required */
|
|
fullLen = wcslen(lpPartialStr) + wcslen(pInfo->pCurrentService->lpDisplayName) + 1;
|
|
|
|
lpStr = HeapAlloc(ProcessHeap,
|
|
0,
|
|
fullLen * sizeof(WCHAR));
|
|
if (lpStr)
|
|
{
|
|
/* Add the service name to the depends note */
|
|
_snwprintf(lpStr,
|
|
fullLen,
|
|
lpPartialStr,
|
|
pInfo->pCurrentService->lpDisplayName);
|
|
|
|
/* Add the string to the dialog */
|
|
SendDlgItemMessageW(hDlg,
|
|
IDC_STOP_DEPENDS,
|
|
WM_SETTEXT,
|
|
0,
|
|
(LPARAM)lpStr);
|
|
|
|
HeapFree(ProcessHeap,
|
|
0,
|
|
lpStr);
|
|
|
|
bRet = TRUE;
|
|
}
|
|
|
|
HeapFree(ProcessHeap,
|
|
0,
|
|
lpPartialStr);
|
|
}
|
|
|
|
/* Display the list of services which need stopping */
|
|
hServiceListBox = GetDlgItem(hDlg,
|
|
IDC_STOP_DEPENDS_LB);
|
|
if (hServiceListBox)
|
|
{
|
|
AddServiceNamesToStop(hServiceListBox,
|
|
(LPWSTR)pInfo->pTag);
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
INT_PTR CALLBACK
|
|
StopDependsDialogProc(HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
PMAIN_WND_INFO pInfo = NULL;
|
|
|
|
/* Get the window context */
|
|
pInfo = (PMAIN_WND_INFO)GetWindowLongPtrW(hDlg,
|
|
GWLP_USERDATA);
|
|
if (pInfo == NULL && message != WM_INITDIALOG)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
switch (message)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
BOOL bRet = FALSE;
|
|
|
|
pInfo = (PMAIN_WND_INFO)lParam;
|
|
if (pInfo != NULL)
|
|
{
|
|
bRet = DoInitDependsDialog(pInfo, hDlg);
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDOK:
|
|
case IDCANCEL:
|
|
{
|
|
EndDialog(hDlg,
|
|
LOWORD(wParam));
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|