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