From faa0acd03016c9df3b9d1fc895bae5aaa2a2b209 Mon Sep 17 00:00:00 2001 From: Clement Rouault Date: Fri, 18 Mar 2016 11:24:02 +0100 Subject: [PATCH] Add services and volumes files --- windows/service.py | 76 ++++++++++++++++++++++++++++++++++++++++++++++ windows/volumes.py | 52 +++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 windows/service.py create mode 100644 windows/volumes.py diff --git a/windows/service.py b/windows/service.py new file mode 100644 index 0000000..7fadb24 --- /dev/null +++ b/windows/service.py @@ -0,0 +1,76 @@ +import ctypes +import windows + +from collections import namedtuple + +from windows import utils +from windows.generated_def import * + + +SERVICE_TYPE = {x:x for x in [SERVICE_KERNEL_DRIVER, SERVICE_FILE_SYSTEM_DRIVER, SERVICE_WIN32_OWN_PROCESS, SERVICE_WIN32_SHARE_PROCESS, SERVICE_INTERACTIVE_PROCESS]} +SERVICE_STATE = {x:x for x in [SERVICE_STOPPED, SERVICE_START_PENDING, SERVICE_STOP_PENDING, SERVICE_RUNNING, SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING, SERVICE_PAUSED]} +SERVICE_CONTROLE_ACCEPTED = {x:x for x in []} +SERVICE_FLAGS = {x:x for x in [SERVICE_RUNS_IN_SYSTEM_PROCESS]} + + +service_status = namedtuple("ServiceStatus", ["type", "state", "control_accepted", "flags"]) + +class Service(object): + def __repr__(self): + return '<{0} "{1}">'.format(type(self).__name__, self.name) + + @utils.fixedpropety + def name(self): + return self.lpServiceName + + @utils.fixedpropety + def description(self): + return self.lpDisplayName + + @utils.fixedpropety + def status(self): + status = self.ServiceStatusProcess + stype = SERVICE_TYPE.get(status.dwServiceType, status.dwServiceType) + sstate = SERVICE_STATE.get(status.dwCurrentState, status.dwCurrentState) + scontrol = status.dwControlsAccepted + sflags = SERVICE_FLAGS.get(status.dwServiceFlags, status.dwServiceFlags) + return service_status(stype, sstate, scontrol, sflags) + + @utils.fixedpropety + def process(self): + pid = self.ServiceStatusProcess.dwProcessId + if not pid: + return None + l = [p for p in windows.system.processes if p.pid == pid] + if not l: + return None # Other thing ? + return l[0] + + +class ServiceA(Service, ENUM_SERVICE_STATUS_PROCESSA): + pass + +def enumerate_services(): + scmanager = windows.winproxy.OpenSCManagerA(dwDesiredAccess=SC_MANAGER_ENUMERATE_SERVICE) + + size_needed = DWORD() + nb_services = DWORD() + counter = DWORD() + try: + windows.winproxy.EnumServicesStatusExA(scmanager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL, SERVICE_ACTIVE, None, 0, ctypes.byref(size_needed), ctypes.byref(nb_services), byref(counter), None) + except WindowsError: + pass + + while True: + size = size_needed.value + buffer = (ctypes.c_byte * size)() + + print("SERVICE size = {0}".format(size)) + + try: + windows.winproxy.EnumServicesStatusExA(scmanager, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL, SERVICE_ACTIVE, buffer, size, ctypes.byref(size_needed), ctypes.byref(nb_services), byref(counter), None) + except WindowsError as e: + continue + + return_type = (ServiceA * nb_services.value) + return list(return_type.from_buffer(buffer)) \ No newline at end of file diff --git a/windows/volumes.py b/windows/volumes.py new file mode 100644 index 0000000..3012321 --- /dev/null +++ b/windows/volumes.py @@ -0,0 +1,52 @@ +import ctypes + +import windows +from windows import winproxy +from windows.generated_def.winstructs import * + + + + +class LogicalDrive(object): + DRIVE_TYPE = {x:x for x in [DRIVE_UNKNOWN, DRIVE_NO_ROOT_DIR, DRIVE_REMOVABLE, + DRIVE_FIXED, DRIVE_REMOTE, DRIVE_CDROM, DRIVE_RAMDISK]} + + def __init__(self, name): + self.name = name + + @property + def type(self): + t = windows.winproxy.GetDriveTypeA(self.name) + return self.DRIVE_TYPE.get(t,t) + + @property + def path(self): + return query_dos_device(self.name.strip("\\")) + + def __repr__(self): + return """<{0} "{1}" ({2})>""".format(type(self).__name__, self.name, self.type.name) + + + +def enum_logical_drive(): + return [LogicalDrive(name) for name in get_logical_drive_names()] + +def get_logical_drive_names(): + size = 0x100 + buffer = ctypes.c_buffer(size) + rsize = winproxy.GetLogicalDriveStringsA(0x1000, buffer) + return buffer[:rsize].rstrip("\x00").split("\x00") + +def get_info(drivename): + size = 0x1000 + volume_name = ctypes.c_buffer(size) + fs_name = ctypes.c_buffer(size) + flags = DWORD() + winproxy.GetVolumeInformationA(drivename, volume_name, size, None, None, ctypes.byref(flags), fs_name, size) + raise NotImplementedError("get_info") + +def query_dos_device(name): + size = 0x1000 + buffer = ctypes.c_buffer(size) + rsize = windows.winproxy.QueryDosDeviceA(name, buffer, size) + return buffer[:rsize].rstrip("\x00").split("\x00") \ No newline at end of file