1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/mscutils/servman/dependencies_tv2.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 BOOL
TV2_HasDependantServices(LPWSTR lpServiceName)13 TV2_HasDependantServices(LPWSTR lpServiceName)
14 {
15 HANDLE hSCManager;
16 HANDLE hService;
17 DWORD dwBytesNeeded, dwCount;
18 BOOL bRet = FALSE;
19
20 hSCManager = OpenSCManagerW(NULL,
21 NULL,
22 SC_MANAGER_ALL_ACCESS);
23 if (hSCManager)
24 {
25 hService = OpenServiceW(hSCManager,
26 lpServiceName,
27 SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
28 if (hService)
29 {
30 /* Does this have any dependencies? */
31 if (!EnumDependentServices(hService,
32 SERVICE_STATE_ALL,
33 NULL,
34 0,
35 &dwBytesNeeded,
36 &dwCount))
37 {
38 if (GetLastError() == ERROR_MORE_DATA)
39 {
40 /* It does, return TRUE */
41 bRet = TRUE;
42 }
43 }
44
45 CloseServiceHandle(hService);
46 }
47
48 CloseServiceHandle(hSCManager);
49 }
50
51 return bRet;
52 }
53
54 LPENUM_SERVICE_STATUS
TV2_GetDependants(LPWSTR lpServiceName,LPDWORD lpdwCount)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 VOID
TV2_AddDependantsToTree(PDEPENDDATA pDependData,HTREEITEM hParent,LPWSTR lpServiceName)121 TV2_AddDependantsToTree(PDEPENDDATA pDependData,
122 HTREEITEM hParent,
123 LPWSTR lpServiceName)
124 {
125
126 LPENUM_SERVICE_STATUSW lpServiceStatus;
127 LPWSTR lpNoDepends;
128 DWORD count, i;
129 BOOL bHasChildren;
130
131 /* Get a list of service dependents */
132 lpServiceStatus = TV2_GetDependants(lpServiceName, &count);
133 if (lpServiceStatus)
134 {
135 for (i = 0; i < count; i++)
136 {
137 /* Does this item need a +/- box? */
138 bHasChildren = TV2_HasDependantServices(lpServiceStatus[i].lpServiceName);
139
140 /* Add it */
141 AddItemToTreeView(pDependData->hDependsTreeView2,
142 hParent,
143 lpServiceStatus[i].lpDisplayName,
144 lpServiceStatus[i].lpServiceName,
145 lpServiceStatus[i].ServiceStatus.dwServiceType,
146 bHasChildren);
147 }
148
149 HeapFree(GetProcessHeap(),
150 0,
151 lpServiceStatus);
152 }
153 else
154 {
155 /* If there is no parent, set the tree to 'no dependencies' */
156 if (!hParent)
157 {
158 /* Load the 'No dependencies' string */
159 AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS);
160
161 AddItemToTreeView(pDependData->hDependsTreeView2,
162 NULL,
163 lpNoDepends,
164 NULL,
165 0,
166 FALSE);
167
168 LocalFree(lpNoDepends);
169
170 /* Disable the window */
171 EnableWindow(pDependData->hDependsTreeView2, FALSE);
172 }
173 }
174 }
175
176 BOOL
TV2_Initialize(PDEPENDDATA pDependData,LPWSTR lpServiceName)177 TV2_Initialize(PDEPENDDATA pDependData,
178 LPWSTR lpServiceName)
179 {
180 BOOL bRet = FALSE;
181
182 /* Associate the imagelist with TV2 */
183 pDependData->hDependsTreeView2 = GetDlgItem(pDependData->hDependsWnd, IDC_DEPEND_TREE2);
184 if (!pDependData->hDependsTreeView2)
185 {
186 ImageList_Destroy(pDependData->hDependsImageList);
187 pDependData->hDependsImageList = NULL;
188 return FALSE;
189 }
190 (void)TreeView_SetImageList(pDependData->hDependsTreeView2,
191 pDependData->hDependsImageList,
192 TVSIL_NORMAL);
193
194 /* Set the first items in the control */
195 TV2_AddDependantsToTree(pDependData, NULL, lpServiceName);
196
197 return bRet;
198 }
199