- Merge from trunk up to r45543
[reactos.git] / base / applications / mscutils / servman / dependencies_tv2.c
1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/mscutils/servman/tv2_dependencies.c
5 * PURPOSE: Helper functions for service dependents
6 * COPYRIGHT: Copyright 2009 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9
10 #include "precomp.h"
11
12
13 BOOL
14 TV2_HasDependantServices(LPWSTR lpServiceName)
15 {
16 HANDLE hSCManager;
17 HANDLE hService;
18 DWORD dwBytesNeeded, dwCount;
19 BOOL bRet = FALSE;
20
21 hSCManager = OpenSCManager(NULL,
22 NULL,
23 SC_MANAGER_ALL_ACCESS);
24 if (hSCManager)
25 {
26 hService = OpenService(hSCManager,
27 lpServiceName,
28 SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
29 if (hService)
30 {
31 /* Does this have any dependencies? */
32 if (!EnumDependentServices(hService,
33 SERVICE_STATE_ALL,
34 NULL,
35 0,
36 &dwBytesNeeded,
37 &dwCount))
38 {
39 if (GetLastError() == ERROR_MORE_DATA)
40 {
41 /* It does, return TRUE */
42 bRet = TRUE;
43 }
44 }
45 }
46
47 CloseServiceHandle(hSCManager);
48 }
49
50 return bRet;
51 }
52
53
54 LPENUM_SERVICE_STATUS
55 TV2_GetDependants(LPWSTR lpServiceName,
56 LPDWORD lpdwCount)
57 {
58 SC_HANDLE hSCManager;
59 SC_HANDLE hService;
60 LPENUM_SERVICE_STATUSW lpDependencies = NULL;
61 DWORD dwBytesNeeded;
62 DWORD dwCount;
63
64 /* Set the first items in each tree view */
65 hSCManager = OpenSCManagerW(NULL,
66 NULL,
67 SC_MANAGER_ALL_ACCESS);
68 if (hSCManager)
69 {
70 hService = OpenServiceW(hSCManager,
71 lpServiceName,
72 SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_QUERY_CONFIG);
73 if (hService)
74 {
75 /* Does this have any dependencies? */
76 if (!EnumDependentServicesW(hService,
77 SERVICE_STATE_ALL,
78 NULL,
79 0,
80 &dwBytesNeeded,
81 &dwCount) &&
82 GetLastError() == ERROR_MORE_DATA)
83 {
84 lpDependencies = (LPENUM_SERVICE_STATUSW)HeapAlloc(GetProcessHeap(),
85 0,
86 dwBytesNeeded);
87 if (lpDependencies)
88 {
89 /* Get the list of dependents */
90 if (EnumDependentServicesW(hService,
91 SERVICE_STATE_ALL,
92 lpDependencies,
93 dwBytesNeeded,
94 &dwBytesNeeded,
95 &dwCount))
96 {
97 /* Set the count */
98 *lpdwCount = dwCount;
99 }
100 else
101 {
102 HeapFree(ProcessHeap,
103 0,
104 lpDependencies);
105
106 lpDependencies = NULL;
107 }
108 }
109 }
110
111 CloseServiceHandle(hService);
112 }
113
114 CloseServiceHandle(hSCManager);
115 }
116
117 return lpDependencies;
118 }
119
120
121 VOID
122 TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo,
123 HTREEITEM hParent,
124 LPTSTR lpServiceName)
125 {
126
127 LPENUM_SERVICE_STATUSW lpServiceStatus;
128 LPTSTR lpNoDepends;
129 DWORD count, i;
130 BOOL bHasChildren;
131
132 /* Get a list of service dependents */
133 lpServiceStatus = TV2_GetDependants(lpServiceName, &count);
134 if (lpServiceStatus)
135 {
136 for (i = 0; i < count; i++)
137 {
138 /* Does this item need a +/- box? */
139 bHasChildren = TV2_HasDependantServices(lpServiceStatus[i].lpServiceName);
140
141 /* Add it */
142 AddItemToTreeView(pDlgInfo->hDependsTreeView2,
143 hParent,
144 lpServiceStatus[i].lpDisplayName,
145 lpServiceStatus[i].lpServiceName,
146 lpServiceStatus[i].ServiceStatus.dwServiceType,
147 bHasChildren);
148 }
149
150 HeapFree(GetProcessHeap(),
151 0,
152 lpServiceStatus);
153 }
154 else
155 {
156 /* If there is no parent, set the tree to 'no dependencies' */
157 if (!hParent)
158 {
159 /* Load the 'No dependencies' string */
160 AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS);
161
162 AddItemToTreeView(pDlgInfo->hDependsTreeView2,
163 NULL,
164 lpNoDepends,
165 NULL,
166 0,
167 FALSE);
168
169 HeapFree(ProcessHeap,
170 0,
171 lpNoDepends);
172
173 /* Disable the window */
174 EnableWindow(pDlgInfo->hDependsTreeView2, FALSE);
175 }
176 }
177 }
178
179 BOOL
180 TV2_Initialize(PSERVICEPROPSHEET pDlgInfo,
181 LPTSTR lpServiceName)
182 {
183 BOOL bRet = FALSE;
184
185 /* Accociate the imagelist with TV2 */
186 pDlgInfo->hDependsTreeView2 = GetDlgItem(pDlgInfo->hDependsWnd, IDC_DEPEND_TREE2);
187 if (!pDlgInfo->hDependsTreeView2)
188 {
189 ImageList_Destroy(pDlgInfo->hDependsImageList);
190 pDlgInfo->hDependsImageList = NULL;
191 return FALSE;
192 }
193 (void)TreeView_SetImageList(pDlgInfo->hDependsTreeView2,
194 pDlgInfo->hDependsImageList,
195 TVSIL_NORMAL);
196
197 /* Set the first items in the control */
198 TV2_AddDependantsToTree(pDlgInfo, NULL, lpServiceName);
199
200 return bRet;
201 }