1 /* 2 * PROJECT: ReactOS Services 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: base/applications/mscutils/servman/query.c 5 * PURPOSE: Query service information 6 * COPYRIGHT: Copyright 2006-2007 Ged Murphy <gedmurphy@reactos.org> 7 * 8 */ 9 10 #include "precomp.h" 11 12 ENUM_SERVICE_STATUS_PROCESS* 13 GetSelectedService(PMAIN_WND_INFO Info) 14 { 15 LVITEM lvItem; 16 17 lvItem.mask = LVIF_PARAM; 18 lvItem.iItem = Info->SelectedItem; 19 SendMessage(Info->hListView, 20 LVM_GETITEM, 21 0, 22 (LPARAM)&lvItem); 23 24 /* return pointer to selected service */ 25 return (ENUM_SERVICE_STATUS_PROCESS *)lvItem.lParam; 26 } 27 28 LPQUERY_SERVICE_CONFIG 29 GetServiceConfig(LPWSTR lpServiceName) 30 { 31 LPQUERY_SERVICE_CONFIGW lpServiceConfig = NULL; 32 SC_HANDLE hSCManager; 33 SC_HANDLE hService; 34 DWORD dwBytesNeeded; 35 36 hSCManager = OpenSCManagerW(NULL, 37 NULL, 38 SC_MANAGER_CONNECT); 39 if (hSCManager) 40 { 41 hService = OpenServiceW(hSCManager, 42 lpServiceName, 43 SERVICE_QUERY_CONFIG); 44 if (hService) 45 { 46 if (!QueryServiceConfigW(hService, 47 NULL, 48 0, 49 &dwBytesNeeded)) 50 { 51 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 52 { 53 lpServiceConfig = (LPQUERY_SERVICE_CONFIG)HeapAlloc(GetProcessHeap(), 54 0, 55 dwBytesNeeded); 56 if (lpServiceConfig) 57 { 58 if (!QueryServiceConfigW(hService, 59 lpServiceConfig, 60 dwBytesNeeded, 61 &dwBytesNeeded)) 62 { 63 HeapFree(GetProcessHeap(), 64 0, 65 lpServiceConfig); 66 lpServiceConfig = NULL; 67 } 68 } 69 } 70 } 71 72 CloseServiceHandle(hService); 73 } 74 75 CloseServiceHandle(hSCManager); 76 } 77 78 return lpServiceConfig; 79 } 80 81 BOOL 82 SetServiceConfig(LPQUERY_SERVICE_CONFIG pServiceConfig, 83 LPWSTR lpServiceName, 84 LPWSTR lpPassword) 85 { 86 SC_HANDLE hSCManager; 87 SC_HANDLE hSc; 88 SC_LOCK scLock; 89 BOOL bRet = FALSE; 90 91 hSCManager = OpenSCManagerW(NULL, 92 NULL, 93 SC_MANAGER_LOCK); 94 if (hSCManager) 95 { 96 scLock = LockServiceDatabase(hSCManager); 97 if (scLock) 98 { 99 hSc = OpenServiceW(hSCManager, 100 lpServiceName, 101 SERVICE_CHANGE_CONFIG); 102 if (hSc) 103 { 104 if (ChangeServiceConfigW(hSc, 105 pServiceConfig->dwServiceType, 106 pServiceConfig->dwStartType, 107 pServiceConfig->dwErrorControl, 108 pServiceConfig->lpBinaryPathName, 109 pServiceConfig->lpLoadOrderGroup, 110 pServiceConfig->dwTagId ? &pServiceConfig->dwTagId : NULL, 111 pServiceConfig->lpDependencies, 112 pServiceConfig->lpServiceStartName, 113 lpPassword, 114 pServiceConfig->lpDisplayName)) 115 { 116 bRet = TRUE; 117 } 118 119 CloseServiceHandle(hSc); 120 } 121 122 UnlockServiceDatabase(scLock); 123 } 124 125 CloseServiceHandle(hSCManager); 126 } 127 128 if (!bRet) 129 GetError(); 130 131 return bRet; 132 } 133 134 LPWSTR 135 GetServiceDescription(LPWSTR lpServiceName) 136 { 137 SC_HANDLE hSCManager = NULL; 138 SC_HANDLE hSc = NULL; 139 SERVICE_DESCRIPTIONW *pServiceDescription = NULL; 140 LPWSTR lpDescription = NULL; 141 DWORD BytesNeeded = 0; 142 DWORD dwSize; 143 144 hSCManager = OpenSCManagerW(NULL, 145 NULL, 146 SC_MANAGER_ENUMERATE_SERVICE); 147 if (hSCManager == NULL) 148 { 149 GetError(); 150 return NULL; 151 } 152 153 hSc = OpenServiceW(hSCManager, 154 lpServiceName, 155 SERVICE_QUERY_CONFIG); 156 if (hSc) 157 { 158 if (!QueryServiceConfig2W(hSc, 159 SERVICE_CONFIG_DESCRIPTION, 160 NULL, 161 0, 162 &BytesNeeded)) 163 { 164 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 165 { 166 pServiceDescription = (SERVICE_DESCRIPTION *) HeapAlloc(ProcessHeap, 167 0, 168 BytesNeeded); 169 if (pServiceDescription == NULL) 170 goto cleanup; 171 172 if (QueryServiceConfig2W(hSc, 173 SERVICE_CONFIG_DESCRIPTION, 174 (LPBYTE)pServiceDescription, 175 BytesNeeded, 176 &BytesNeeded)) 177 { 178 if (pServiceDescription->lpDescription) 179 { 180 dwSize = wcslen(pServiceDescription->lpDescription) + 1; 181 lpDescription = HeapAlloc(ProcessHeap, 182 0, 183 dwSize * sizeof(WCHAR)); 184 if (lpDescription) 185 { 186 StringCchCopyW(lpDescription, 187 dwSize, 188 pServiceDescription->lpDescription); 189 } 190 } 191 } 192 } 193 } 194 } 195 196 cleanup: 197 if (pServiceDescription) 198 HeapFree(ProcessHeap, 199 0, 200 pServiceDescription); 201 if (hSCManager != NULL) 202 CloseServiceHandle(hSCManager); 203 if (hSc != NULL) 204 CloseServiceHandle(hSc); 205 206 return lpDescription; 207 } 208 209 BOOL 210 SetServiceDescription(LPWSTR lpServiceName, 211 LPWSTR lpDescription) 212 { 213 SC_HANDLE hSCManager; 214 SC_HANDLE hSc; 215 SC_LOCK scLock; 216 SERVICE_DESCRIPTION ServiceDescription; 217 BOOL bRet = FALSE; 218 219 hSCManager = OpenSCManagerW(NULL, 220 NULL, 221 SC_MANAGER_LOCK); 222 if (hSCManager) 223 { 224 scLock = LockServiceDatabase(hSCManager); 225 if (scLock) 226 { 227 hSc = OpenServiceW(hSCManager, 228 lpServiceName, 229 SERVICE_CHANGE_CONFIG); 230 if (hSc) 231 { 232 ServiceDescription.lpDescription = lpDescription; 233 234 if (ChangeServiceConfig2W(hSc, 235 SERVICE_CONFIG_DESCRIPTION, 236 &ServiceDescription)) 237 { 238 bRet = TRUE; 239 } 240 241 CloseServiceHandle(hSc); 242 } 243 244 UnlockServiceDatabase(scLock); 245 } 246 247 CloseServiceHandle(hSCManager); 248 } 249 250 if (!bRet) 251 GetError(); 252 253 return bRet; 254 } 255 256 VOID 257 FreeServiceList(PMAIN_WND_INFO Info) 258 { 259 DWORD i; 260 261 if (Info->pAllServices != NULL) 262 { 263 for (i = 0; i < Info->NumServices; i++) 264 { 265 if (Info->pAllServices[i].lpServiceName) 266 HeapFree(ProcessHeap, 0, Info->pAllServices[i].lpServiceName); 267 268 if (Info->pAllServices[i].lpDisplayName) 269 HeapFree(ProcessHeap, 0, Info->pAllServices[i].lpDisplayName); 270 } 271 272 HeapFree(ProcessHeap, 0, Info->pAllServices); 273 Info->pAllServices = NULL; 274 Info->NumServices = 0; 275 } 276 } 277 278 BOOL 279 GetServiceList(PMAIN_WND_INFO Info) 280 { 281 ENUM_SERVICE_STATUS_PROCESS *pServices = NULL; 282 SC_HANDLE ScHandle; 283 BOOL bRet = FALSE; 284 285 DWORD BytesNeeded = 0; 286 DWORD ResumeHandle = 0; 287 DWORD NumServices = 0; 288 DWORD i; 289 290 FreeServiceList(Info); 291 292 ScHandle = OpenSCManagerW(NULL, 293 NULL, 294 SC_MANAGER_ENUMERATE_SERVICE); 295 if (ScHandle != NULL) 296 { 297 if (!EnumServicesStatusEx(ScHandle, 298 SC_ENUM_PROCESS_INFO, 299 SERVICE_WIN32, 300 SERVICE_STATE_ALL, 301 NULL, 302 0, 303 &BytesNeeded, 304 &NumServices, 305 &ResumeHandle, 306 0)) 307 { 308 /* Call function again if required size was returned */ 309 if (GetLastError() == ERROR_MORE_DATA) 310 { 311 /* reserve memory for service info array */ 312 pServices = (ENUM_SERVICE_STATUS_PROCESS *)HeapAlloc(ProcessHeap, 313 0, 314 BytesNeeded); 315 if (pServices) 316 { 317 /* fill array with service info */ 318 if (EnumServicesStatusEx(ScHandle, 319 SC_ENUM_PROCESS_INFO, 320 SERVICE_WIN32, 321 SERVICE_STATE_ALL, 322 (LPBYTE)pServices, 323 BytesNeeded, 324 &BytesNeeded, 325 &NumServices, 326 &ResumeHandle, 327 0)) 328 { 329 bRet = TRUE; 330 } 331 } 332 } 333 } 334 } 335 336 if (ScHandle) 337 CloseServiceHandle(ScHandle); 338 339 Info->pAllServices = (ENUM_SERVICE_STATUS_PROCESS *)HeapAlloc(ProcessHeap, 340 HEAP_ZERO_MEMORY, 341 NumServices * sizeof(ENUM_SERVICE_STATUS_PROCESS)); 342 if (Info->pAllServices != NULL) 343 { 344 Info->NumServices = NumServices; 345 346 for (i = 0; i < NumServices; i++) 347 { 348 Info->pAllServices[i].lpServiceName = HeapAlloc(ProcessHeap, 349 HEAP_ZERO_MEMORY, 350 (wcslen(pServices[i].lpServiceName) + 1) * sizeof(WCHAR)); 351 if (Info->pAllServices[i].lpServiceName) 352 wcscpy(Info->pAllServices[i].lpServiceName, pServices[i].lpServiceName); 353 354 Info->pAllServices[i].lpDisplayName = HeapAlloc(ProcessHeap, 355 HEAP_ZERO_MEMORY, 356 (wcslen(pServices[i].lpDisplayName) + 1) * sizeof(WCHAR)); 357 if (Info->pAllServices[i].lpDisplayName) 358 wcscpy(Info->pAllServices[i].lpDisplayName, pServices[i].lpDisplayName); 359 360 CopyMemory(&Info->pAllServices[i].ServiceStatusProcess, 361 &pServices[i].ServiceStatusProcess, 362 sizeof(SERVICE_STATUS_PROCESS)); 363 } 364 } 365 366 if (pServices) 367 HeapFree(ProcessHeap, 0, pServices); 368 369 return bRet; 370 } 371 372 BOOL 373 UpdateServiceStatus(ENUM_SERVICE_STATUS_PROCESS* pService) 374 { 375 SC_HANDLE hScm; 376 BOOL bRet = FALSE; 377 378 hScm = OpenSCManagerW(NULL, 379 NULL, 380 SC_MANAGER_ENUMERATE_SERVICE); 381 if (hScm != NULL) 382 { 383 SC_HANDLE hService; 384 385 hService = OpenServiceW(hScm, 386 pService->lpServiceName, 387 SERVICE_QUERY_STATUS); 388 if (hService) 389 { 390 DWORD size; 391 392 QueryServiceStatusEx(hService, 393 SC_STATUS_PROCESS_INFO, 394 (LPBYTE)&pService->ServiceStatusProcess, 395 sizeof(SERVICE_STATUS_PROCESS), 396 &size); 397 398 CloseServiceHandle(hService); 399 bRet = TRUE; 400 } 401 402 CloseServiceHandle(hScm); 403 } 404 405 return bRet; 406 } 407