[TRANSLATION]
[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 BOOL
13 TV2_HasDependantServices(LPWSTR lpServiceName)
14 {
15 HANDLE hSCManager;
16 HANDLE hService;
17 DWORD dwBytesNeeded, dwCount;
18 BOOL bRet = FALSE;
19
20 hSCManager = OpenSCManager(NULL,
21 NULL,
22 SC_MANAGER_ALL_ACCESS);
23 if (hSCManager)
24 {
25 hService = OpenService(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
46 CloseServiceHandle(hSCManager);
47 }
48
49 return bRet;
50 }
51
52 LPENUM_SERVICE_STATUS
53 TV2_GetDependants(LPWSTR lpServiceName,
54 LPDWORD lpdwCount)
55 {
56 SC_HANDLE hSCManager;
57 SC_HANDLE hService;
58 LPENUM_SERVICE_STATUSW lpDependencies = NULL;
59 DWORD dwBytesNeeded;
60 DWORD dwCount;
61
62 /* Set the first items in each tree view */
63 hSCManager = OpenSCManagerW(NULL,
64 NULL,
65 SC_MANAGER_ALL_ACCESS);
66 if (hSCManager)
67 {
68 hService = OpenServiceW(hSCManager,
69 lpServiceName,
70 SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_QUERY_CONFIG);
71 if (hService)
72 {
73 /* Does this have any dependencies? */
74 if (!EnumDependentServicesW(hService,
75 SERVICE_STATE_ALL,
76 NULL,
77 0,
78 &dwBytesNeeded,
79 &dwCount) &&
80 GetLastError() == ERROR_MORE_DATA)
81 {
82 lpDependencies = (LPENUM_SERVICE_STATUSW)HeapAlloc(GetProcessHeap(),
83 0,
84 dwBytesNeeded);
85 if (lpDependencies)
86 {
87 /* Get the list of dependents */
88 if (EnumDependentServicesW(hService,
89 SERVICE_STATE_ALL,
90 lpDependencies,
91 dwBytesNeeded,
92 &dwBytesNeeded,
93 &dwCount))
94 {
95 /* Set the count */
96 *lpdwCount = dwCount;
97 }
98 else
99 {
100 HeapFree(ProcessHeap,
101 0,
102 lpDependencies);
103
104 lpDependencies = NULL;
105 }
106 }
107 }
108
109 CloseServiceHandle(hService);
110 }
111
112 CloseServiceHandle(hSCManager);
113 }
114
115 return lpDependencies;
116 }
117
118 VOID
119 TV2_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo,
120 HTREEITEM hParent,
121 LPTSTR lpServiceName)
122 {
123
124 LPENUM_SERVICE_STATUSW lpServiceStatus;
125 LPTSTR lpNoDepends;
126 DWORD count, i;
127 BOOL bHasChildren;
128
129 /* Get a list of service dependents */
130 lpServiceStatus = TV2_GetDependants(lpServiceName, &count);
131 if (lpServiceStatus)
132 {
133 for (i = 0; i < count; i++)
134 {
135 /* Does this item need a +/- box? */
136 bHasChildren = TV2_HasDependantServices(lpServiceStatus[i].lpServiceName);
137
138 /* Add it */
139 AddItemToTreeView(pDlgInfo->hDependsTreeView2,
140 hParent,
141 lpServiceStatus[i].lpDisplayName,
142 lpServiceStatus[i].lpServiceName,
143 lpServiceStatus[i].ServiceStatus.dwServiceType,
144 bHasChildren);
145 }
146
147 HeapFree(GetProcessHeap(),
148 0,
149 lpServiceStatus);
150 }
151 else
152 {
153 /* If there is no parent, set the tree to 'no dependencies' */
154 if (!hParent)
155 {
156 /* Load the 'No dependencies' string */
157 AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS);
158
159 AddItemToTreeView(pDlgInfo->hDependsTreeView2,
160 NULL,
161 lpNoDepends,
162 NULL,
163 0,
164 FALSE);
165
166 HeapFree(ProcessHeap,
167 0,
168 lpNoDepends);
169
170 /* Disable the window */
171 EnableWindow(pDlgInfo->hDependsTreeView2, FALSE);
172 }
173 }
174 }
175
176 BOOL
177 TV2_Initialize(PSERVICEPROPSHEET pDlgInfo,
178 LPTSTR lpServiceName)
179 {
180 BOOL bRet = FALSE;
181
182 /* Accociate the imagelist with TV2 */
183 pDlgInfo->hDependsTreeView2 = GetDlgItem(pDlgInfo->hDependsWnd, IDC_DEPEND_TREE2);
184 if (!pDlgInfo->hDependsTreeView2)
185 {
186 ImageList_Destroy(pDlgInfo->hDependsImageList);
187 pDlgInfo->hDependsImageList = NULL;
188 return FALSE;
189 }
190 (void)TreeView_SetImageList(pDlgInfo->hDependsTreeView2,
191 pDlgInfo->hDependsImageList,
192 TVSIL_NORMAL);
193
194 /* Set the first items in the control */
195 TV2_AddDependantsToTree(pDlgInfo, NULL, lpServiceName);
196
197 return bRet;
198 }