More code towards getting servman to stop services again, etc...

(clearly not a message for the changelog)

svn path=/trunk/; revision=44949
This commit is contained in:
Ged Murphy 2010-01-05 17:14:08 +00:00
parent 887a166980
commit bbf8c31b35
6 changed files with 366 additions and 259 deletions

View file

@ -1,153 +0,0 @@
/*
* PROJECT: ReactOS Services
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/mscutils/servman/dependencies.c
* PURPOSE: Helper functions for service dependents
* COPYRIGHT: Copyright 2006-2009 Ged Murphy <gedmurphy@reactos.org>
*
*/
#include "precomp.h"
//FIXME: reimplement this
static BOOL
DoInitDependsDialog(PSTOP_INFO pStopInfo,
HWND hDlg)
{
//LPENUM_SERVICE_STATUS lpDependencies;
//DWORD dwCount;
LPTSTR lpPartialStr, lpStr;
DWORD fullLen;
HICON hIcon = NULL;
BOOL bRet = FALSE;
if (pStopInfo)
{
SetWindowLongPtr(hDlg,
GWLP_USERDATA,
(LONG_PTR)pStopInfo);
hIcon = (HICON)LoadImage(hInstance,
MAKEINTRESOURCE(IDI_SM_ICON),
IMAGE_ICON,
16,
16,
0);
if (hIcon)
{
SendMessage(hDlg,
WM_SETICON,
ICON_SMALL,
(LPARAM)hIcon);
DestroyIcon(hIcon);
}
/* Add the label */
if (AllocAndLoadString(&lpPartialStr,
hInstance,
IDS_STOP_DEPENDS))
{
fullLen = _tcslen(lpPartialStr) + _tcslen(pStopInfo->pInfo->pCurrentService->lpDisplayName) + 1;
lpStr = HeapAlloc(ProcessHeap,
0,
fullLen * sizeof(TCHAR));
if (lpStr)
{
_sntprintf(lpStr, fullLen, lpPartialStr, pStopInfo->pInfo->pCurrentService->lpDisplayName);
SendDlgItemMessage(hDlg,
IDC_STOP_DEPENDS,
WM_SETTEXT,
0,
(LPARAM)lpStr);
bRet = TRUE;
HeapFree(ProcessHeap,
0,
lpStr);
}
HeapFree(ProcessHeap,
0,
lpPartialStr);
}
/* Get the list of dependencies
GetServiceDependents(pStopInfo->hMainService, &dwCount);
if (lpDependencies)
{
LPENUM_SERVICE_STATUS lpEnumServiceStatus;
DWORD i;
for (i = 0; i < dwCount; i++)
{
lpEnumServiceStatus = &lpDependencies[i];
Add the service to the listbox
SendDlgItemMessage(hDlg,
IDC_STOP_DEPENDS_LB,
LB_ADDSTRING,
0,
(LPARAM)lpEnumServiceStatus->lpDisplayName);
}
HeapFree(ProcessHeap,
0,
lpDependencies);
}*/
}
return bRet;
}
INT_PTR CALLBACK
StopDependsDialogProc(HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
PSTOP_INFO pStopInfo = NULL;
/* Get the window context */
pStopInfo = (PSTOP_INFO)GetWindowLongPtr(hDlg,
GWLP_USERDATA);
if (pStopInfo == NULL && message != WM_INITDIALOG)
{
return FALSE;
}
switch (message)
{
case WM_INITDIALOG:
{
BOOL bRet = FALSE;
pStopInfo = (PSTOP_INFO)lParam;
if (pStopInfo != NULL)
{
bRet = DoInitDependsDialog(pStopInfo, hDlg);
}
return bRet;
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDOK:
case IDCANCEL:
{
EndDialog(hDlg,
LOWORD(wParam));
return TRUE;
}
}
}
}
return FALSE;
}

View file

@ -51,55 +51,67 @@ TV2_HasDependantServices(LPWSTR lpServiceName)
}
static LPENUM_SERVICE_STATUS
TV2_GetDependants(SC_HANDLE hService,
LPENUM_SERVICE_STATUS
TV2_GetDependants(LPWSTR lpServiceName,
LPDWORD lpdwCount)
{
LPENUM_SERVICE_STATUS lpDependencies;
SC_HANDLE hSCManager;
SC_HANDLE hService;
LPENUM_SERVICE_STATUSW lpDependencies = NULL;
DWORD dwBytesNeeded;
DWORD dwCount;
/* Does this have any dependencies? */
if (EnumDependentServices(hService,
SERVICE_STATE_ALL,
NULL,
0,
&dwBytesNeeded,
&dwCount))
/* Set the first items in each tree view */
hSCManager = OpenSCManagerW(NULL,
NULL,
SC_MANAGER_ALL_ACCESS);
if (hSCManager)
{
/* There are no dependent services */
return NULL;
}
else
{
if (GetLastError() != ERROR_MORE_DATA)
return NULL; /* Unexpected error */
lpDependencies = (LPENUM_SERVICE_STATUS)HeapAlloc(GetProcessHeap(),
0,
dwBytesNeeded);
if (lpDependencies)
hService = OpenServiceW(hSCManager,
lpServiceName,
SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_QUERY_CONFIG);
if (hService)
{
/* Get the list of dependents */
if (EnumDependentServices(hService,
SERVICE_STATE_ALL,
lpDependencies,
dwBytesNeeded,
&dwBytesNeeded,
&dwCount))
/* Does this have any dependencies? */
if (!EnumDependentServicesW(hService,
SERVICE_STATE_ALL,
NULL,
0,
&dwBytesNeeded,
&dwCount) &&
GetLastError() == ERROR_MORE_DATA)
{
/* Set the count */
*lpdwCount = dwCount;
}
else
{
HeapFree(ProcessHeap,
0,
lpDependencies);
lpDependencies = (LPENUM_SERVICE_STATUSW)HeapAlloc(GetProcessHeap(),
0,
dwBytesNeeded);
if (lpDependencies)
{
/* Get the list of dependents */
if (EnumDependentServicesW(hService,
SERVICE_STATE_ALL,
lpDependencies,
dwBytesNeeded,
&dwBytesNeeded,
&dwCount))
{
/* Set the count */
*lpdwCount = dwCount;
}
else
{
HeapFree(ProcessHeap,
0,
lpDependencies);
lpDependencies = NULL;
lpDependencies = NULL;
}
}
}
CloseServiceHandle(hService);
}
CloseServiceHandle(hSCManager);
}
return lpDependencies;
@ -111,70 +123,56 @@ TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo,
HTREEITEM hParent,
LPTSTR lpServiceName)
{
SC_HANDLE hSCManager;
SC_HANDLE hService;
LPENUM_SERVICE_STATUS lpServiceStatus;
LPENUM_SERVICE_STATUSW lpServiceStatus;
LPTSTR lpNoDepends;
DWORD count, i;
BOOL bHasChildren;
/* Set the first items in each tree view */
hSCManager = OpenSCManager(NULL,
NULL,
SC_MANAGER_ALL_ACCESS);
if (hSCManager)
/* Get a list of service dependents */
lpServiceStatus = TV2_GetDependants(lpServiceName, &count);
if (lpServiceStatus)
{
hService = OpenService(hSCManager,
lpServiceName,
SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_QUERY_CONFIG);
if (hService)
for (i = 0; i < count; i++)
{
/* Get a list of service dependents */
lpServiceStatus = TV2_GetDependants(hService, &count);
if (lpServiceStatus)
{
for (i = 0; i < count; i++)
{
/* Does this item need a +/- box? */
bHasChildren = TV2_HasDependantServices(lpServiceStatus[i].lpServiceName);
/* Does this item need a +/- box? */
bHasChildren = TV2_HasDependantServices(lpServiceStatus[i].lpServiceName);
/* Add it */
AddItemToTreeView(pDlgInfo->hDependsTreeView2,
hParent,
lpServiceStatus[i].lpDisplayName,
lpServiceStatus[i].lpServiceName,
lpServiceStatus[i].ServiceStatus.dwServiceType,
bHasChildren);
}
}
else
{
/* If there is no parent, set the tree to 'no dependencies' */
if (!hParent)
{
/* Load the 'No dependencies' string */
AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS);
AddItemToTreeView(pDlgInfo->hDependsTreeView2,
NULL,
lpNoDepends,
NULL,
0,
FALSE);
HeapFree(ProcessHeap,
0,
lpNoDepends);
/* Disable the window */
EnableWindow(pDlgInfo->hDependsTreeView2, FALSE);
}
}
CloseServiceHandle(hService);
/* Add it */
AddItemToTreeView(pDlgInfo->hDependsTreeView2,
hParent,
lpServiceStatus[i].lpDisplayName,
lpServiceStatus[i].lpServiceName,
lpServiceStatus[i].ServiceStatus.dwServiceType,
bHasChildren);
}
CloseServiceHandle(hSCManager);
HeapFree(GetProcessHeap(),
0,
lpServiceStatus);
}
else
{
/* If there is no parent, set the tree to 'no dependencies' */
if (!hParent)
{
/* Load the 'No dependencies' string */
AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS);
AddItemToTreeView(pDlgInfo->hDependsTreeView2,
NULL,
lpNoDepends,
NULL,
0,
FALSE);
HeapFree(ProcessHeap,
0,
lpNoDepends);
/* Disable the window */
EnableWindow(pDlgInfo->hDependsTreeView2, FALSE);
}
}
}

View file

@ -124,8 +124,9 @@ typedef struct _SERVICEPROPSHEET
HTREEITEM AddItemToTreeView(HWND hTreeView, HTREEITEM hRoot, LPTSTR lpDisplayName, LPTSTR lpServiceName, ULONG serviceType, BOOL bHasChildren);
/* dependencies */
/* stop_dependencies */
INT_PTR CALLBACK StopDependsDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
LPWSTR GetListOfServicesToStop(LPWSTR lpServiceName);
/* tv1_dependencies */
BOOL TV1_Initialize(PSERVICEPROPSHEET pDlgInfo, LPTSTR lpServiceName);
@ -135,6 +136,7 @@ VOID TV1_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPTS
BOOL TV2_Initialize(PSERVICEPROPSHEET pDlgInfo, LPTSTR lpServiceName);
VOID TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo, HTREEITEM hParent, LPTSTR lpServiceName);
BOOL TV2_HasDependantServices(LPWSTR lpServiceName);
LPENUM_SERVICE_STATUS TV2_GetDependants(LPWSTR lpServiceName, LPDWORD lpdwCount);
LONG APIENTRY OpenPropSheet(PMAIN_WND_INFO Info);

View file

@ -14,7 +14,6 @@
<file>control.c</file>
<file>create.c</file>
<file>delete.c</file>
<file>dependencies.c</file>
<file>dependencies_tv1.c</file>
<file>dependencies_tv2.c</file>
<file>export.c</file>
@ -29,6 +28,7 @@
<file>servman.c</file>
<file>start.c</file>
<file>stop.c</file>
<file>stop_dependencies.c</file>
</compilationunit>
<file>servman.rc</file>
<pch>precomp.h</pch>

View file

@ -3,7 +3,7 @@
* LICENSE: GPL - See COPYING in the top level directory
* FILE: base/applications/mscutils/servman/stop.c
* PURPOSE: Stops running a service
* COPYRIGHT: Copyright 2006-2009 Ged Murphy <gedmurphy@reactos.org>
* COPYRIGHT: Copyright 2006-2010 Ged Murphy <gedmurphy@reactos.org>
*
*/
@ -118,6 +118,7 @@ StopDependantServices(PMAIN_WND_INFO pInfo,
BOOL
DoStop(PMAIN_WND_INFO pInfo)
{
LPWSTR lpServiceList;
BOOL bRet = FALSE;
if (pInfo)
@ -125,18 +126,23 @@ DoStop(PMAIN_WND_INFO pInfo)
/* Does this service have anything which depends on it? */
if (TV2_HasDependantServices(pInfo->pCurrentService->lpServiceName))
{
/* It does, list them and ask the user if they want to stop them as well */
if (DialogBoxParam(hInstance,
MAKEINTRESOURCE(IDD_DLG_DEPEND_STOP),
pInfo->hMainWnd,
StopDependsDialogProc,
(LPARAM)&pInfo) == IDOK)
/* It does, get a list of all the services which need stopping */
lpServiceList = GetListOfServicesToStop(pInfo->pCurrentService->lpServiceName);
if (lpServiceList)
{
/* Stop all the dependany services */
if (StopDependantServices(pInfo, pInfo->pCurrentService->lpServiceName))
/* List them and ask the user if they want to stop them */
if (DialogBoxParamW(hInstance,
MAKEINTRESOURCEW(IDD_DLG_DEPEND_STOP),
pInfo->hMainWnd,
StopDependsDialogProc,
(LPARAM)lpServiceList) == IDOK)
{
/* Finally stop the requested service */
bRet = StopService(pInfo, pInfo->pCurrentService->lpServiceName);
/* Stop all the dependant services */
if (StopDependantServices(pInfo, pInfo->pCurrentService->lpServiceName))
{
/* Finally stop the requested service */
bRet = StopService(pInfo, pInfo->pCurrentService->lpServiceName);
}
}
}
}

View file

@ -0,0 +1,254 @@
/*
* 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 (*ptr != L'\0' || *(ptr + 1) != L'\0')
{
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 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);
}
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 BOOL
DoInitDependsDialog(PMAIN_WND_INFO pInfo,
HWND hDlg)
{
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);
}
/* FIXME: Load the list of services which need stopping */
}
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;
}