Create this branch to work on loading of different Kernel-Debugger DLL providers...
[reactos.git] / base / applications / msconfig / srvpage.c
1 /*
2 * PROJECT: ReactOS Applications
3 * LICENSE: LGPL - See COPYING in the top level directory
4 * FILE: base/applications/srvpage.c
5 * PURPOSE: Services page message handler
6 * COPYRIGHT: Copyright 2005-2006 Christoph von Wittich <Christoph@ApiViewer.de>
7 *
8 */
9
10 #include "precomp.h"
11
12 HWND hServicesPage;
13 HWND hServicesListCtrl;
14 HWND hServicesDialog;
15
16 void GetServices ( void );
17
18 INT_PTR CALLBACK
19 ServicesPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
20 {
21 LV_COLUMN column;
22 TCHAR szTemp[256];
23 DWORD dwStyle;
24
25 UNREFERENCED_PARAMETER(lParam);
26 UNREFERENCED_PARAMETER(wParam);
27
28 switch (message) {
29 case WM_INITDIALOG:
30
31 hServicesListCtrl = GetDlgItem(hDlg, IDC_SERVICES_LIST);
32 hServicesDialog = hDlg;
33
34 dwStyle = (DWORD) SendMessage(hServicesListCtrl, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);
35 dwStyle = dwStyle | LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES;
36 SendMessage(hServicesListCtrl, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, dwStyle);
37
38 SetWindowPos(hDlg, NULL, 10, 32, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
39
40 // Initialize the application page's controls
41 column.mask = LVCF_TEXT | LVCF_WIDTH;
42
43 LoadString(hInst, IDS_SERVICES_COLUMN_SERVICE, szTemp, 256);
44 column.pszText = szTemp;
45 column.cx = 200;
46 (void)ListView_InsertColumn(hServicesListCtrl, 0, &column);
47
48 column.mask = LVCF_TEXT | LVCF_WIDTH;
49 LoadString(hInst, IDS_SERVICES_COLUMN_REQ, szTemp, 256);
50 column.pszText = szTemp;
51 column.cx = 70;
52 (void)ListView_InsertColumn(hServicesListCtrl, 1, &column);
53
54 column.mask = LVCF_TEXT | LVCF_WIDTH;
55 LoadString(hInst, IDS_SERVICES_COLUMN_VENDOR, szTemp, 256);
56 column.pszText = szTemp;
57 column.cx = 200;
58 (void)ListView_InsertColumn(hServicesListCtrl, 2, &column);
59
60 column.mask = LVCF_TEXT | LVCF_WIDTH;
61 LoadString(hInst, IDS_SERVICES_COLUMN_STATUS, szTemp, 256);
62 column.pszText = szTemp;
63 column.cx = 70;
64 (void)ListView_InsertColumn(hServicesListCtrl, 3, &column);
65
66 GetServices();
67 return TRUE;
68 }
69
70 return 0;
71 }
72
73 void
74 GetServices ( void )
75 {
76 LV_ITEM item;
77 WORD wCodePage;
78 WORD wLangID;
79 SC_HANDLE ScHandle;
80 SC_HANDLE hService;
81 DWORD BytesNeeded = 0;
82 DWORD ResumeHandle = 0;
83 DWORD NumServices = 0;
84 DWORD dwHandle, dwLen;
85 size_t Index;
86 UINT BufLen;
87 TCHAR szStatus[128];
88 TCHAR* lpData;
89 TCHAR* lpBuffer;
90 TCHAR szStrFileInfo[80];
91 TCHAR FileName[MAX_PATH];
92 LPVOID pvData;
93
94 LPSERVICE_FAILURE_ACTIONS pServiceFailureActions = NULL;
95 LPQUERY_SERVICE_CONFIG pServiceConfig = NULL;
96 ENUM_SERVICE_STATUS_PROCESS *pServiceStatus = NULL;
97
98 ScHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
99 if (ScHandle != INVALID_HANDLE_VALUE)
100 {
101 if (EnumServicesStatusEx(ScHandle, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, (LPBYTE)pServiceStatus, 0, &BytesNeeded, &NumServices, &ResumeHandle, 0) == 0)
102 {
103 /* Call function again if required size was returned */
104 if (GetLastError() == ERROR_MORE_DATA)
105 {
106 /* reserve memory for service info array */
107 pServiceStatus = (ENUM_SERVICE_STATUS_PROCESS *) HeapAlloc(GetProcessHeap(), 0, BytesNeeded);
108 if (!pServiceStatus)
109 return;
110
111 /* fill array with service info */
112 if (EnumServicesStatusEx(ScHandle, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL, (LPBYTE)pServiceStatus, BytesNeeded, &BytesNeeded, &NumServices, &ResumeHandle, 0) == 0)
113 {
114 HeapFree(GetProcessHeap(), 0, pServiceStatus);
115 return;
116 }
117 }
118 else /* exit on failure */
119 {
120 return;
121 }
122 }
123
124 if (NumServices)
125 {
126 if (!pServiceStatus)
127 return;
128 for (Index = 0; Index < NumServices; Index++)
129 {
130 memset(&item, 0, sizeof(LV_ITEM));
131 item.mask = LVIF_TEXT;
132 item.iImage = 0;
133 item.pszText = pServiceStatus[Index].lpDisplayName;
134 item.iItem = ListView_GetItemCount(hServicesListCtrl);
135 item.lParam = 0;
136 item.iItem = ListView_InsertItem(hServicesListCtrl, &item);
137
138 if (pServiceStatus[Index].ServiceStatusProcess.dwCurrentState == SERVICE_RUNNING)
139 {
140 ListView_SetCheckState(hServicesListCtrl, item.iItem, TRUE);
141 }
142
143 BytesNeeded = 0;
144 hService = OpenService(ScHandle, pServiceStatus[Index].lpServiceName, SC_MANAGER_CONNECT);
145 if (hService != INVALID_HANDLE_VALUE)
146 {
147 /* check if service is required by the system*/
148 if (!QueryServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, (LPBYTE)NULL, 0, &BytesNeeded))
149 {
150 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
151 {
152 pServiceFailureActions = (LPSERVICE_FAILURE_ACTIONS) HeapAlloc(GetProcessHeap(), 0, BytesNeeded);
153 if (pServiceFailureActions == NULL)
154 return;
155
156 if (!QueryServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, (LPBYTE)pServiceFailureActions, BytesNeeded, &BytesNeeded))
157 {
158 HeapFree(GetProcessHeap(), 0, pServiceFailureActions);
159 HeapFree(GetProcessHeap(), 0, pServiceStatus);
160 CloseServiceHandle(hService);
161 CloseServiceHandle(ScHandle);
162 return;
163 }
164 }
165 else /* exit on failure */
166 {
167 HeapFree(GetProcessHeap(), 0, pServiceStatus);
168 CloseServiceHandle(hService);
169 CloseServiceHandle(ScHandle);
170 return;
171 }
172 }
173 if (pServiceFailureActions->cActions)
174 {
175 if (pServiceFailureActions->lpsaActions[0].Type == SC_ACTION_REBOOT)
176 {
177 LoadString(hInst, IDS_SERVICES_YES, szStatus, 128);
178 item.pszText = szStatus;
179 item.iSubItem = 1;
180 SendMessage(hServicesListCtrl, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
181 }
182 }
183
184 if (pServiceFailureActions != NULL)
185 {
186 HeapFree(GetProcessHeap(), 0, pServiceFailureActions);
187 pServiceFailureActions = NULL;
188 }
189
190 /* get vendor of service binary */
191 BytesNeeded = 0;
192 if (!QueryServiceConfig(hService, NULL, 0, &BytesNeeded))
193 {
194 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
195 {
196 pServiceConfig = (LPQUERY_SERVICE_CONFIG) HeapAlloc(GetProcessHeap(), 0, BytesNeeded);
197 if (pServiceConfig == NULL)
198 {
199 HeapFree(GetProcessHeap(), 0, pServiceStatus);
200 CloseServiceHandle(hService);
201 CloseServiceHandle(ScHandle);
202 return;
203 }
204 if (!QueryServiceConfig(hService, pServiceConfig, BytesNeeded, &BytesNeeded))
205 {
206 HeapFree(GetProcessHeap(), 0, pServiceConfig);
207 HeapFree(GetProcessHeap(), 0, pServiceStatus);
208 CloseServiceHandle(hService);
209 CloseServiceHandle(ScHandle);
210 return;
211 }
212 }
213 else /* exit on failure */
214 {
215 HeapFree(GetProcessHeap(), 0, pServiceStatus);
216 CloseServiceHandle(hService);
217 CloseServiceHandle(ScHandle);
218 return;
219 }
220 }
221
222 memset(&FileName, 0, MAX_PATH);
223 if (_tcscspn(pServiceConfig->lpBinaryPathName, _T("\"")))
224 {
225 _tcsncpy(FileName, pServiceConfig->lpBinaryPathName, _tcscspn(pServiceConfig->lpBinaryPathName, _T(" ")) );
226 }
227 else
228 {
229 _tcscpy(FileName, pServiceConfig->lpBinaryPathName);
230 }
231
232 HeapFree(GetProcessHeap(), 0, pServiceConfig);
233 pServiceConfig = NULL;
234
235 dwLen = GetFileVersionInfoSize(FileName, &dwHandle);
236 if (dwLen)
237 {
238 lpData = (TCHAR*) HeapAlloc(GetProcessHeap(), 0, dwLen);
239 if (lpData == NULL)
240 {
241 HeapFree(GetProcessHeap(), 0, pServiceStatus);
242 CloseServiceHandle(hService);
243 CloseServiceHandle(ScHandle);
244 return;
245 }
246 if (!GetFileVersionInfo (FileName, dwHandle, dwLen, lpData))
247 {
248 HeapFree(GetProcessHeap(), 0, lpData);
249 HeapFree(GetProcessHeap(), 0, pServiceStatus);
250 CloseServiceHandle(hService);
251 CloseServiceHandle(ScHandle);
252 return;
253 }
254
255 if (VerQueryValue(lpData, _T("\\VarFileInfo\\Translation"), &pvData, (PUINT) &BufLen))
256 {
257 wCodePage = LOWORD(*(DWORD*) pvData);
258 wLangID = HIWORD(*(DWORD*) pvData);
259 wsprintf(szStrFileInfo, _T("StringFileInfo\\%04X%04X\\CompanyName"), wCodePage, wLangID);
260 }
261
262 if (VerQueryValue (lpData, szStrFileInfo, (void**) &lpBuffer, (PUINT) &BufLen))
263 {
264 item.pszText = lpBuffer;
265 item.iSubItem = 2;
266 SendMessage(hServicesListCtrl, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
267 }
268 HeapFree(GetProcessHeap(), 0, lpData);
269 }
270 else
271 {
272 LoadString(hInst, IDS_SERVICES_UNKNOWN, szStatus, 128);
273 item.pszText = szStatus;
274 item.iSubItem = 2;
275 SendMessage(hServicesListCtrl, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
276 }
277 CloseServiceHandle(hService);
278 }
279
280 LoadString(hInst, ((pServiceStatus[Index].ServiceStatusProcess.dwCurrentState == SERVICE_STOPPED) ? IDS_SERVICES_STATUS_STOPPED : IDS_SERVICES_STATUS_RUNNING), szStatus, 128);
281 item.pszText = szStatus;
282 item.iSubItem = 3;
283 SendMessage(hServicesListCtrl, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
284
285 }
286 }
287
288 HeapFree(GetProcessHeap(), 0, pServiceStatus);
289 CloseServiceHandle(ScHandle);
290 }
291
292 }