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