[NTDLL]
[reactos.git] / base / applications / mscutils / servman / dependencies_tv1.c
1 /*
2 * PROJECT: ReactOS Services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/mscutils/servman/tv1_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 LPTSTR
14 TV1_GetDependants(PSERVICEPROPSHEET pDlgInfo,
15 SC_HANDLE hService)
16 {
17 LPQUERY_SERVICE_CONFIG lpServiceConfig;
18 LPTSTR lpStr = NULL;
19 DWORD bytesNeeded;
20 DWORD bytes;
21
22 /* Get the info for this service */
23 if (!QueryServiceConfig(hService,
24 NULL,
25 0,
26 &bytesNeeded) &&
27 GetLastError() == ERROR_INSUFFICIENT_BUFFER)
28 {
29 lpServiceConfig = HeapAlloc(ProcessHeap,
30 0,
31 bytesNeeded);
32 if (lpServiceConfig)
33 {
34 if (QueryServiceConfig(hService,
35 lpServiceConfig,
36 bytesNeeded,
37 &bytesNeeded))
38 {
39 /* Does this service have any dependencies? */
40 if (lpServiceConfig->lpDependencies &&
41 *lpServiceConfig->lpDependencies != '\0')
42 {
43 lpStr = lpServiceConfig->lpDependencies;
44 bytes = 0;
45
46 /* Work out how many bytes we need to hold the list */
47 while (TRUE)
48 {
49 bytes++;
50
51 if (!*lpStr && !*(lpStr + 1))
52 {
53 bytes++;
54 break;
55 }
56
57 lpStr++;
58 }
59
60 /* Allocate and copy the list */
61 bytes *= sizeof(TCHAR);
62 lpStr = HeapAlloc(ProcessHeap,
63 0,
64 bytes);
65 if (lpStr)
66 {
67 CopyMemory(lpStr,
68 lpServiceConfig->lpDependencies,
69 bytes);
70 }
71 }
72 }
73
74 HeapFree(GetProcessHeap(),
75 0,
76 lpServiceConfig);
77 }
78 }
79
80 return lpStr;
81 }
82
83 VOID
84 TV1_AddDependantsToTree(PSERVICEPROPSHEET pDlgInfo,
85 HTREEITEM hParent,
86 LPTSTR lpServiceName)
87 {
88 SC_HANDLE hSCManager;
89 SC_HANDLE hService;
90 LPQUERY_SERVICE_CONFIG lpServiceConfig;
91 LPTSTR lpDependants;
92 LPTSTR lpStr;
93 LPTSTR lpNoDepends;
94 BOOL bHasChildren;
95
96 hSCManager = OpenSCManager(NULL,
97 NULL,
98 SC_MANAGER_ALL_ACCESS);
99 if (hSCManager)
100 {
101 hService = OpenService(hSCManager,
102 lpServiceName,
103 SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_QUERY_CONFIG);
104 if (hService)
105 {
106 /* Get a list of service dependents */
107 lpDependants = TV1_GetDependants(pDlgInfo, hService);
108 if (lpDependants)
109 {
110 lpStr = lpDependants;
111
112 /* Make sure this isn't the end of the list */
113 while (*lpStr)
114 {
115 /* Get the info for this service */
116 lpServiceConfig = GetServiceConfig(lpStr);
117 if (lpServiceConfig)
118 {
119 /* Does this item need a +/- box? */
120 if (lpServiceConfig->lpDependencies &&
121 *lpServiceConfig->lpDependencies != '\0')
122 {
123 bHasChildren = TRUE;
124 }
125 else
126 {
127 bHasChildren = FALSE;
128 }
129
130 /* Add it */
131 AddItemToTreeView(pDlgInfo->hDependsTreeView1,
132 hParent,
133 lpServiceConfig->lpDisplayName,
134 lpStr,
135 lpServiceConfig->dwServiceType,
136 bHasChildren);
137
138 HeapFree(GetProcessHeap(),
139 0,
140 lpServiceConfig);
141 }
142
143 /* Move to the end of the string */
144 while (*lpStr++)
145 ;
146 }
147
148 HeapFree(GetProcessHeap(),
149 0,
150 lpDependants);
151 }
152 else
153 {
154 /* If there is no parent, set the tree to 'no dependencies' */
155 if (!hParent)
156 {
157 /* Load the 'No dependencies' string */
158 AllocAndLoadString(&lpNoDepends, hInstance, IDS_NO_DEPENDS);
159
160 AddItemToTreeView(pDlgInfo->hDependsTreeView1,
161 NULL,
162 lpNoDepends,
163 NULL,
164 0,
165 FALSE);
166
167 HeapFree(ProcessHeap,
168 0,
169 lpNoDepends);
170
171 /* Disable the window */
172 EnableWindow(pDlgInfo->hDependsTreeView1, FALSE);
173 }
174 }
175
176 CloseServiceHandle(hService);
177 }
178
179 CloseServiceHandle(hSCManager);
180 }
181 }
182
183
184 BOOL
185 TV1_Initialize(PSERVICEPROPSHEET pDlgInfo,
186 LPTSTR lpServiceName)
187 {
188 BOOL bRet = FALSE;
189
190 /* Accociate the imagelist with TV1 */
191 pDlgInfo->hDependsTreeView1 = GetDlgItem(pDlgInfo->hDependsWnd, IDC_DEPEND_TREE1);
192 if (!pDlgInfo->hDependsTreeView1)
193 {
194 ImageList_Destroy(pDlgInfo->hDependsImageList);
195 pDlgInfo->hDependsImageList = NULL;
196 return FALSE;
197 }
198 (void)TreeView_SetImageList(pDlgInfo->hDependsTreeView1,
199 pDlgInfo->hDependsImageList,
200 TVSIL_NORMAL);
201
202 /* Set the first items in the control */
203 TV1_AddDependantsToTree(pDlgInfo, NULL, lpServiceName);
204
205 return bRet;
206 }