Rewrite, the last method of getting service dependants and dependent services was flawed/buggy.

svn path=/trunk/; revision=40802
This commit is contained in:
Ged Murphy 2009-05-05 22:04:19 +00:00
parent 80ce1c6708
commit 95370b97d2
4 changed files with 208 additions and 129 deletions

View file

@ -9,8 +9,78 @@
#include "precomp.h"
/*
* Services which depend on the given service.
* The return components depend on this service
*/
LPTSTR
GetDependentServices(SC_HANDLE hService)
{
LPQUERY_SERVICE_CONFIG lpServiceConfig;
LPTSTR lpStr = NULL;
DWORD bytesNeeded;
DWORD bytes;
if (!QueryServiceConfig(hService,
NULL,
0,
&bytesNeeded) &&
GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
lpServiceConfig = HeapAlloc(ProcessHeap,
0,
bytesNeeded);
if (lpServiceConfig)
{
if (QueryServiceConfig(hService,
lpServiceConfig,
bytesNeeded,
&bytesNeeded))
{
if (lpServiceConfig)
{
lpStr = lpServiceConfig->lpDependencies;
bytes = 0;
while (TRUE)
{
bytes++;
if (!*lpStr && !*(lpStr + 1))
{
bytes++;
break;
}
lpStr++;
}
bytes *= sizeof(TCHAR);
lpStr = HeapAlloc(ProcessHeap,
0,
bytes);
if (lpStr)
{
CopyMemory(lpStr,
lpServiceConfig->lpDependencies,
bytes);
}
}
}
}
}
return lpStr;
}
/*
* Services which the given service depends on (1st treeview)
* The service depends on the return components
*/
LPENUM_SERVICE_STATUS
GetDependentServices(SC_HANDLE hService,
GetServiceDependents(SC_HANDLE hService,
LPDWORD lpdwCount)
{
LPENUM_SERVICE_STATUS lpDependencies;
@ -150,7 +220,7 @@ DoInitDependsDialog(PSTOP_INFO pStopInfo,
}
/* Get the list of dependencies */
lpDependencies = GetDependentServices(pStopInfo->hMainService, &dwCount);
lpDependencies = GetServiceDependents(pStopInfo->hMainService, &dwCount);
if (lpDependencies)
{
LPENUM_SERVICE_STATUS lpEnumServiceStatus;

View file

@ -106,9 +106,10 @@ BOOL UpdateServiceStatus(ENUM_SERVICE_STATUS_PROCESS* pService);
BOOL GetServiceList(PMAIN_WND_INFO Info, DWORD *NumServices);
/* dependencies */
LPENUM_SERVICE_STATUS GetDependentServices(SC_HANDLE hService, LPDWORD lpdwCount);
LPENUM_SERVICE_STATUS GetServiceDependents(SC_HANDLE hService, LPDWORD lpdwCount);
BOOL HasDependentServices(SC_HANDLE hService);
INT_PTR CALLBACK StopDependsDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
LPTSTR GetDependentServices(SC_HANDLE hService);
/* propsheet.c */
typedef struct _SERVICEPROPSHEET

View file

@ -61,7 +61,6 @@ AddServiceDependency(PSERVICEPROPSHEET dlgInfo,
LPQUERY_SERVICE_CONFIG lpServiceConfig;
SC_HANDLE hService;
HTREEITEM hChild;
DWORD bytesNeeded;
LPTSTR lpStr;
LPTSTR lpNoDepends;
@ -71,132 +70,40 @@ AddServiceDependency(PSERVICEPROPSHEET dlgInfo,
if (hService)
{
if (!QueryServiceConfig(hService,
NULL,
0,
&bytesNeeded) &&
GetLastError() == ERROR_INSUFFICIENT_BUFFER)
lpStr = GetDependentServices(hService);
if (lpStr)
{
lpServiceConfig = HeapAlloc(ProcessHeap,
0,
bytesNeeded);
if (lpServiceConfig)
{
if (QueryServiceConfig(hService,
lpServiceConfig,
bytesNeeded,
&bytesNeeded))
{
if (lpServiceConfig)
{
lpStr = lpServiceConfig->lpDependencies;
if (*lpStr)
{
while (*lpStr)
{
hChild = AddItemToTreeView(hTreeView,
hParent,
lpServiceConfig->lpDisplayName,
lpServiceConfig->dwServiceType);
AddServiceDependency(dlgInfo,
hTreeView,
hSCManager,
lpStr,
hChild,
hwndDlg);
while (*lpStr++)
;
}
}
else
{
if (TreeView_GetCount(hTreeView) == 0)
{
if (AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS))
{
lpStr = lpNoDepends;
}
AddItemToTreeView(hTreeView,
hParent,
lpStr,
0);
HeapFree(ProcessHeap,
0,
lpNoDepends);
EnableWindow(hTreeView, FALSE);
}
}
}
}
HeapFree(ProcessHeap,
0,
lpServiceConfig);
}
}
CloseServiceHandle(hService);
}
}
static VOID
AddServiceDependent(PSERVICEPROPSHEET dlgInfo,
HWND hTreeView,
SC_HANDLE hSCManager,
LPTSTR lpServiceName,
HTREEITEM hParent,
HWND hwndDlg)
{
LPENUM_SERVICE_STATUS lpServiceStatus;
SC_HANDLE hService;
HTREEITEM hChild;
LPTSTR lpNoDepends;
DWORD count;
INT i;
hService = OpenService(hSCManager,
lpServiceName,
SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
if (hService)
{
lpServiceStatus = GetDependentServices(hService, &count);
if (lpServiceStatus)
{
for (i = 0; i < count; i++)
while (*lpStr)
{
hChild = AddItemToTreeView(hTreeView,
hParent,
lpServiceStatus[i].lpDisplayName,
SERVICE_WIN32);
lpServiceConfig->lpDisplayName,
lpServiceConfig->dwServiceType);
AddServiceDependent(dlgInfo,
hTreeView,
hSCManager,
lpServiceStatus[i].lpServiceName,
hChild,
hwndDlg);
AddServiceDependency(dlgInfo,
hTreeView,
hSCManager,
lpStr,
hChild,
hwndDlg);
while (*lpStr++)
;
}
HeapFree(ProcessHeap,
0,
lpServiceStatus);
}
else
{
if (TreeView_GetCount(hTreeView) == 0)
{
AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS);
if (AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS))
{
lpStr = lpNoDepends;
}
AddItemToTreeView(hTreeView,
hParent,
lpNoDepends,
lpStr,
0);
HeapFree(ProcessHeap,
@ -206,9 +113,107 @@ AddServiceDependent(PSERVICEPROPSHEET dlgInfo,
EnableWindow(hTreeView, FALSE);
}
}
HeapFree(ProcessHeap,
0,
lpStr);
CloseServiceHandle(hService);
}
}
static VOID
AddServiceDependent(HWND hTreeView,
HTREEITEM hParent,
SC_HANDLE hSCManager,
LPTSTR lpServiceName,
LPTSTR lpDisplayName,
DWORD dwServiceType)
{
LPENUM_SERVICE_STATUS lpServiceStatus;
SC_HANDLE hChildService;
HTREEITEM hChildNode;
DWORD count;
INT i;
hChildNode = AddItemToTreeView(hTreeView,
hParent,
lpDisplayName,
dwServiceType);
hChildService = OpenService(hSCManager,
lpServiceName,
SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
if (hChildService)
{
lpServiceStatus = GetServiceDependents(hChildService, &count);
if (lpServiceStatus)
{
for (i = 0; i < count; i++)
{
AddServiceDependent(hTreeView,
hChildNode,
hSCManager,
lpServiceStatus[i].lpServiceName,
lpServiceStatus[i].lpDisplayName,
lpServiceStatus[i].ServiceStatus.dwServiceType);
}
HeapFree(ProcessHeap,
0,
lpServiceStatus);
}
CloseServiceHandle(hChildService);
}
}
static VOID
SetServiceDependents(HWND hTreeView,
SC_HANDLE hSCManager,
SC_HANDLE hService)
{
LPENUM_SERVICE_STATUS lpServiceStatus;
LPTSTR lpNoDepends;
DWORD count, i;
lpServiceStatus = GetServiceDependents(hService, &count);
if (lpServiceStatus)
{
for (i = 0; i < count; i++)
{
AddServiceDependent(hTreeView,
NULL,
hSCManager,
lpServiceStatus[i].lpServiceName,
lpServiceStatus[i].lpDisplayName,
lpServiceStatus[i].ServiceStatus.dwServiceType);
}
}
else
{
AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS);
AddItemToTreeView(hTreeView,
NULL,
lpNoDepends,
0);
HeapFree(ProcessHeap,
0,
lpNoDepends);
EnableWindow(hTreeView, FALSE);
}
}
static VOID
SetDependentServices(SC_HANDLE hService)
{
}
static VOID
InitDependPage(PSERVICEPROPSHEET dlgInfo,
@ -216,6 +221,7 @@ InitDependPage(PSERVICEPROPSHEET dlgInfo,
{
HWND hTreeView1, hTreeView2;
SC_HANDLE hSCManager;
SC_HANDLE hService;
dlgInfo->hDependsImageList = InitImageList(IDI_NODEPENDS,
IDI_DRIVER,
@ -245,19 +251,21 @@ InitDependPage(PSERVICEPROPSHEET dlgInfo,
SC_MANAGER_ALL_ACCESS);
if (hSCManager)
{
AddServiceDependency(dlgInfo,
hTreeView1,
hSCManager,
dlgInfo->pService->lpServiceName,
NULL,
hwndDlg);
hService = OpenService(hSCManager,
dlgInfo->pService->lpServiceName,
SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_QUERY_CONFIG);
if (hService)
{
/* Set the first tree view */
SetServiceDependents(hTreeView1,
hSCManager,
hService);
AddServiceDependent(dlgInfo,
hTreeView2,
hSCManager,
dlgInfo->pService->lpServiceName,
NULL,
hwndDlg);
/* Set the second tree view */
SetDependentServices(hService);
CloseServiceHandle(hService);
}
CloseServiceHandle(hSCManager);
}

View file

@ -76,7 +76,7 @@ StopDependentServices(PSTOP_INFO pStopInfo,
DWORD dwCount;
BOOL bRet = FALSE;
lpDependencies = GetDependentServices(hService, &dwCount);
lpDependencies = GetServiceDependents(hService, &dwCount);
if (lpDependencies)
{
LPENUM_SERVICE_STATUS lpEnumServiceStatus;