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" #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 LPENUM_SERVICE_STATUS
GetDependentServices(SC_HANDLE hService, GetServiceDependents(SC_HANDLE hService,
LPDWORD lpdwCount) LPDWORD lpdwCount)
{ {
LPENUM_SERVICE_STATUS lpDependencies; LPENUM_SERVICE_STATUS lpDependencies;
@ -150,7 +220,7 @@ DoInitDependsDialog(PSTOP_INFO pStopInfo,
} }
/* Get the list of dependencies */ /* Get the list of dependencies */
lpDependencies = GetDependentServices(pStopInfo->hMainService, &dwCount); lpDependencies = GetServiceDependents(pStopInfo->hMainService, &dwCount);
if (lpDependencies) if (lpDependencies)
{ {
LPENUM_SERVICE_STATUS lpEnumServiceStatus; 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); BOOL GetServiceList(PMAIN_WND_INFO Info, DWORD *NumServices);
/* dependencies */ /* dependencies */
LPENUM_SERVICE_STATUS GetDependentServices(SC_HANDLE hService, LPDWORD lpdwCount); LPENUM_SERVICE_STATUS GetServiceDependents(SC_HANDLE hService, LPDWORD lpdwCount);
BOOL HasDependentServices(SC_HANDLE hService); BOOL HasDependentServices(SC_HANDLE hService);
INT_PTR CALLBACK StopDependsDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); INT_PTR CALLBACK StopDependsDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
LPTSTR GetDependentServices(SC_HANDLE hService);
/* propsheet.c */ /* propsheet.c */
typedef struct _SERVICEPROPSHEET typedef struct _SERVICEPROPSHEET

View file

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

View file

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