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