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 } 293