internal Service(ENUM_SERVICE_STATUS_PROCESS status) { Name = status.lpServiceName; DisplayName = status.lpDisplayName; ProcessId = status.serviceStatusProcess.dwProcessId; State = (ServiceState)status.serviceStatusProcess.dwCurrentState; }
/// <summary> /// Get the Win32 services for the SCM. /// </summary> /// <param name="service_state">The state of the services to return.</param> /// <param name="service_types">The types of services to return.</param> /// <param name="throw_on_error">True throw on error.</param> /// <returns>The list of services.</returns> /// <remarks>SCM must have been opened with EnumerateService access.</remarks> public NtResult <IEnumerable <Win32Service> > GetServices(ServiceState service_state, ServiceType service_types, bool throw_on_error) { SERVICE_STATE state; switch (service_state) { case ServiceState.All: state = SERVICE_STATE.SERVICE_STATE_ALL; break; case ServiceState.Active: state = SERVICE_STATE.SERVICE_ACTIVE; break; case ServiceState.InActive: state = SERVICE_STATE.SERVICE_INACTIVE; break; default: throw new ArgumentException("Invalid service state", nameof(service_state)); } List <Win32Service> ret_services = new List <Win32Service>(); const int Length = 32 * 1024; using (var buffer = new SafeHGlobalBuffer(Length)) { int resume_handle = 0; while (true) { bool ret = Win32NativeMethods.EnumServicesStatusEx(_handle, SC_ENUM_TYPE.SC_ENUM_PROCESS_INFO, service_types, state, buffer, buffer.Length, out int bytes_needed, out int services_returned, ref resume_handle, null); Win32Error error = Win32Utils.GetLastWin32Error(); if (!ret && error != Win32Error.ERROR_MORE_DATA) { return(error.CreateResultFromDosError <IEnumerable <Win32Service> >(throw_on_error)); } ENUM_SERVICE_STATUS_PROCESS[] services = new ENUM_SERVICE_STATUS_PROCESS[services_returned]; buffer.ReadArray(0, services, 0, services_returned); ret_services.AddRange(services.Select(s => new Win32Service(_machine_name, s))); if (ret) { break; } } } return(ret_services.CreateResult().Cast <IEnumerable <Win32Service> >()); }
public static string[] GetAllServices(int pid) { IntPtr hServiceManager = OpenSCManager(null, null, (uint)(SCM_ACCESS.SC_MANAGER_CONNECT | SCM_ACCESS.SC_MANAGER_ENUMERATE_SERVICE)); if (hServiceManager == IntPtr.Zero) { LogHelper.Warning("Unable to open SCManager."); return(null); } try { uint dwBufSize = 0; uint dwBufNeed = 0; uint ServicesReturned = 0; uint ResumeHandle = 0; var resp = EnumServicesStatusEx(hServiceManager, (int)SC_ENUM_TYPE.SC_ENUM_PROCESS_INFO, (int)SERVICE_TYPES.SERVICE_WIN32, (int)SERVICE_STATE.SERVICE_ACTIVE, IntPtr.Zero, dwBufSize, out dwBufNeed, out ServicesReturned, ref ResumeHandle, null); if (resp != 0) { LogHelper.Warning("Unexpected result from call to EnumServicesStatusEx."); return(null); } if (Marshal.GetLastWin32Error() != ERROR_MORE_DATA) { LogHelper.Warning("Unable to retrieve data from SCManager."); return(null); } List <string> result = new List <string>(); bool IsThereMore = true; while (IsThereMore) { IsThereMore = false; dwBufSize = dwBufNeed; dwBufNeed = 0; IntPtr buffer = Marshal.AllocHGlobal((int)dwBufSize); try { resp = EnumServicesStatusEx(hServiceManager, (int)SC_ENUM_TYPE.SC_ENUM_PROCESS_INFO, (int)SERVICE_TYPES.SERVICE_WIN32, (int)SERVICE_STATE.SERVICE_ACTIVE, buffer, dwBufSize, out dwBufNeed, out ServicesReturned, ref ResumeHandle, null); if (resp == 0) { uint resp2 = (uint)Marshal.GetLastWin32Error(); if (resp2 == ERROR_MORE_DATA) { IsThereMore = true; } else { LogHelper.Error("Unable to retrieve data from SCManager.", new Win32Exception((int)resp2)); return(null); } } for (uint i = 0; i < ServicesReturned; i++) { IntPtr buffer2; if (Environment.Is64BitProcess) { //8 byte packing on 64 bit OSes. buffer2 = IntPtr.Add(buffer, (int)i * (ENUM_SERVICE_STATUS_PROCESS.SizeOf + 4)); } else { buffer2 = IntPtr.Add(buffer, (int)i * ENUM_SERVICE_STATUS_PROCESS.SizeOf); } ENUM_SERVICE_STATUS_PROCESS service = (ENUM_SERVICE_STATUS_PROCESS)Marshal.PtrToStructure(buffer2, typeof(ENUM_SERVICE_STATUS_PROCESS)); if (pid == service.ServiceStatus.dwProcessId) { //We have found one of the services we're looking for! result.Add(service.lpServiceName); } } } finally { Marshal.FreeHGlobal(buffer); } } return(result.ToArray()); } finally { CloseServiceHandle(hServiceManager); } }
private static ServiceController [] GetServices(string machineName, SERVICE_TYPE serviceType, string group) { IntPtr scHandle = IntPtr.Zero; IntPtr buffer = IntPtr.Zero; try { #if NET_2_0 scHandle = OpenServiceControlManager(machineName, SERVICE_MANAGER_RIGHTS.SC_MANAGER_ENUMERATE_SERVICE); #else scHandle = OpenServiceControlManager(machineName, SERVICE_MANAGER_RIGHTS.SC_MANAGER_ENUMERATE_SERVICE, true); #endif uint bufferSize = 0; uint bytesNeeded = 0; uint servicesReturned = 0; uint resumeHandle = 0; ServiceController [] services; while (true) { if (!EnumServicesStatusEx(scHandle, SC_ENUM_PROCESS_INFO, serviceType, SERVICE_STATE_REQUEST.SERVICE_STATE_ALL, buffer, bufferSize, out bytesNeeded, out servicesReturned, ref resumeHandle, group)) { int err = Marshal.GetLastWin32Error(); if (err == ERROR_MORE_DATA) { buffer = Marshal.AllocHGlobal((int)bytesNeeded); bufferSize = bytesNeeded; } else { throw new Win32Exception(err); } } else { int iPtr = buffer.ToInt32(); services = new ServiceController [servicesReturned]; for (int i = 0; i < servicesReturned; i++) { ENUM_SERVICE_STATUS_PROCESS serviceStatus = (ENUM_SERVICE_STATUS_PROCESS)Marshal.PtrToStructure( new IntPtr(iPtr), typeof(ENUM_SERVICE_STATUS_PROCESS)); // TODO: use internal ctor that takes displayname too services [i] = new ServiceController(serviceStatus.pServiceName, machineName); // move on to the next services iPtr += ENUM_SERVICE_STATUS_PROCESS.SizeOf; } // we're done, so exit the loop break; } } return(services); } finally { if (scHandle != IntPtr.Zero) { CloseServiceHandle(scHandle); } if (buffer != IntPtr.Zero) { Marshal.FreeHGlobal(buffer); } } }
internal static List <Services> GetServices() { var serviceList = new List <Services>(); List <ENUM_SERVICE_STATUS_PROCESS> result = new List <ENUM_SERVICE_STATUS_PROCESS>(); IntPtr handle = IntPtr.Zero; IntPtr buf = IntPtr.Zero; try { handle = OpenSCManager(null, null, (int)ServiceControlManagerType.SC_MANAGER_ALL_ACCESS); if (handle != IntPtr.Zero) { uint iBytesNeeded = 0; uint iServicesReturned = 0; uint iResumeHandle = 0; // ENUM_SERVICE_STATUS_PROCESS infoLevel = new ENUM_SERVICE_STATUS_PROCESS(); if (!EnumServicesStatusEx(handle, SC_ENUM_PROCESS_INFO, (int)ServiceType.SERVICE_WIN32, (int)ServiceStateRequest.SERVICE_STATE_ALL, IntPtr.Zero, 0, out iBytesNeeded, out iServicesReturned, ref iResumeHandle, null)) { // allocate our memory to receive the data for all the services (including the names) buf = Marshal.AllocHGlobal((int)iBytesNeeded); if (!EnumServicesStatusEx(handle, SC_ENUM_PROCESS_INFO, (int)ServiceType.SERVICE_WIN32, (int)ServiceStateRequest.SERVICE_STATE_ALL, buf, iBytesNeeded, out iBytesNeeded, out iServicesReturned, ref iResumeHandle, null)) { return(null); } ENUM_SERVICE_STATUS_PROCESS serviceStatus; // check if 64 bit system which has different pack sizes if (IntPtr.Size == 8) { long pointer = buf.ToInt64(); for (int i = 0; i < (int)iServicesReturned; i++) { serviceStatus = (ENUM_SERVICE_STATUS_PROCESS)Marshal.PtrToStructure(new IntPtr(pointer), typeof(ENUM_SERVICE_STATUS_PROCESS)); result.Add(serviceStatus); // incremement by sizeof(ENUM_SERVICE_STATUS_PROCESS) allow Packing of 8 pointer += ENUM_SERVICE_STATUS_PROCESS.SizePack8; } } else { int pointer = buf.ToInt32(); for (int i = 0; i < (int)iServicesReturned; i++) { serviceStatus = (ENUM_SERVICE_STATUS_PROCESS)Marshal.PtrToStructure(new IntPtr(pointer), typeof(ENUM_SERVICE_STATUS_PROCESS)); result.Add(serviceStatus); // incremement by sizeof(ENUM_SERVICE_STATUS_PROCESS) allow Packing of 4 pointer += ENUM_SERVICE_STATUS_PROCESS.SizePack4; } } } for (int i = 0; i < result.Count; i++) { ENUM_SERVICE_STATUS_PROCESS service = result[i]; Services srv = new Services(); if (srv != null) { srv.ServiceName = service.pServiceName; srv.FullName = service.pDisplayName; int sstatus = service.ServiceStatus.currentState; int stype = service.ServiceStatus.serviceType; srv.PID = service.ServiceStatus.processId; switch (sstatus) { case 0x2: case 0x4: case 0x5: case 0x6: case 0x7: srv.Status = "SERVICE_ACTIVE"; break; case 0x01: srv.Status = "SERVICE_INACTIVE"; break; default: //case 0x3: srv.Status = "UNKNOWN"; break; } switch (stype) { case 0x01: srv.Type = "SERVICE_KERNEL_DRIVER"; break; case 0x02: srv.Type = "SERVICE_FILE_SYSTEM_DRIVER"; break; case 0x10: srv.Type = "SERVICE_WIN32_OWN_PROCESS"; break; case 0x20: srv.Type = "SERVICE_WIN32_SHARED_PROCESS"; break; case 0x100: srv.Type = "SERVICE_INTERACTIVE_PROCESS"; break; default: srv.Type = "UNKNOWN"; break; } try { IntPtr serviceHandle = OpenService(handle, service.pServiceName, 0x1); QUERY_SERVICE_CONFIG qUERY_SERVICE_CONFIG = new QUERY_SERVICE_CONFIG(); IntPtr ptr = Marshal.AllocHGlobal(0); int bytesNeeded = 0; bool success = QueryServiceConfig(serviceHandle, ptr, 0, out bytesNeeded); if (bytesNeeded != 0) { ptr = Marshal.AllocHGlobal(bytesNeeded); success = QueryServiceConfig(serviceHandle, ptr, bytesNeeded, out bytesNeeded); Marshal.PtrToStructure(ptr, qUERY_SERVICE_CONFIG); Marshal.FreeHGlobal(ptr); } srv.Path = qUERY_SERVICE_CONFIG.lpBinaryPathName; srv.StartMode = ((ServiceStartMode)qUERY_SERVICE_CONFIG.dwStartType).ToString(); srv.Description = GetServiceDescription(serviceHandle); srv.StartedAs = qUERY_SERVICE_CONFIG.lpServiceStartName; } catch (Exception) { } serviceList.Add(srv); } } } } catch (Exception) { } finally { if (handle != IntPtr.Zero) { CloseServiceHandle(handle); } if (buf != IntPtr.Zero) { Marshal.FreeHGlobal(buf); } } return(serviceList); }