From 11d66a48188e49bb442cfc50a67c3c2f29b717d9 Mon Sep 17 00:00:00 2001 From: speyrefitte Date: Tue, 19 May 2015 17:53:15 +0200 Subject: [PATCH] add onSessionReady event -> user session is ready --- README.md | 5 +++++ bin/rdpy-rdpmitm.py | 7 +++++++ bin/rdpy-rdpscreenshot.py | 7 +++++++ rdpy/protocol/rdp/pdu/data.py | 16 ++++++++++++++-- rdpy/protocol/rdp/pdu/layer.py | 10 ++++++++++ rdpy/protocol/rdp/rdp.py | 15 +++++++++++++++ rdpy/ui/qt4.py | 27 ++++++++++++--------------- 7 files changed, 70 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 10599be..f8ecdb4 100644 --- a/README.md +++ b/README.md @@ -181,6 +181,11 @@ class MyRDPFactory(rdp.ClientFactory): @param isCompress: use RLE compression @param data: bitmap data """ + + def onSessionReady(self): + """ + @summary: Windows session is ready + """ def onClose(self): """ diff --git a/bin/rdpy-rdpmitm.py b/bin/rdpy-rdpmitm.py index 3601179..b568b7f 100755 --- a/bin/rdpy-rdpmitm.py +++ b/bin/rdpy-rdpmitm.py @@ -179,6 +179,13 @@ class ProxyClient(rdp.RDPClientObserver): #maybe color depth change self._server._controller.setColorDepth(self._controller.getColorDepth()) + def onSessionReady(self): + """ + @summary: Windows session is ready + @see: rdp.RDPClientObserver.onSessionReady + """ + pass + def onClose(self): """ @summary: Event inform that stack is close diff --git a/bin/rdpy-rdpscreenshot.py b/bin/rdpy-rdpscreenshot.py index 7ca58a7..4b87755 100755 --- a/bin/rdpy-rdpscreenshot.py +++ b/bin/rdpy-rdpscreenshot.py @@ -136,6 +136,13 @@ class RDPScreenShotFactory(rdp.ClientFactory): """ log.info("connected %s"%addr) + def onSessionReady(self): + """ + @summary: Windows session is ready + @see: rdp.RDPClientObserver.onSessionReady + """ + pass + def onClose(self): """ @summary: callback use when RDP stack is closed diff --git a/rdpy/protocol/rdp/pdu/data.py b/rdpy/protocol/rdp/pdu/data.py index f527c0a..84a19b8 100644 --- a/rdpy/protocol/rdp/pdu/data.py +++ b/rdpy/protocol/rdp/pdu/data.py @@ -542,7 +542,7 @@ class DataPDU(CompositeType): """ @summary: Create object in accordance self.shareDataHeader.pduType2 value """ - for c in [UpdateDataPDU, SynchronizeDataPDU, ControlDataPDU, ErrorInfoDataPDU, FontListDataPDU, FontMapDataPDU, PersistentListPDU, ClientInputEventPDU, ShutdownDeniedPDU, ShutdownRequestPDU, SupressOutputDataPDU]: + for c in [UpdateDataPDU, SynchronizeDataPDU, ControlDataPDU, ErrorInfoDataPDU, FontListDataPDU, FontMapDataPDU, PersistentListPDU, ClientInputEventPDU, ShutdownDeniedPDU, ShutdownRequestPDU, SupressOutputDataPDU, SaveSessionInfoPDU]: if self.shareDataHeader.pduType2.value == c._PDUTYPE2_: return c() log.debug("unknown PDU data type : %s"%hex(self.shareDataHeader.pduType2.value)) @@ -771,7 +771,19 @@ class UpdateDataPDU(CompositeType): raise InvalidExpectedDataException("Try to send an invalid data update PDU") self.updateData = updateData - + +class SaveSessionInfoPDU(CompositeType): + """ + @see: https://msdn.microsoft.com/en-us/library/cc240636.aspx + """ + _PDUTYPE2_ = PDUType2.PDUTYPE2_SAVE_SESSION_INFO + + def __init__(self, readLen = None): + CompositeType.__init__(self, readLen = readLen) + self.infoType = UInt32Le() + #TODO parse info data + self.infoData = String() + class FastPathUpdatePDU(CompositeType): """ @summary: Fast path update PDU packet diff --git a/rdpy/protocol/rdp/pdu/layer.py b/rdpy/protocol/rdp/pdu/layer.py index 271a7d3..f326701 100644 --- a/rdpy/protocol/rdp/pdu/layer.py +++ b/rdpy/protocol/rdp/pdu/layer.py @@ -39,6 +39,13 @@ class PDUClientListener(object): """ raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onReady", "PDUClientListener")) + def onSessionReady(self): + """ + @summary: Event call when Windows session is ready + """ + raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onSessionReady", "PDUClientListener")) + + def onUpdate(self, rectangles): """ @summary: call when a bitmap data is received from update PDU @@ -298,6 +305,9 @@ class Client(PDULayer): elif dataPDU.shareDataHeader.pduType2.value == data.PDUType2.PDUTYPE2_SHUTDOWN_DENIED: #may be an event to ask to user self._transport.close() + elif dataPDU.shareDataHeader.pduType2.value == data.PDUType2.PDUTYPE2_SAVE_SESSION_INFO: + #handle session event + self._listener.onSessionReady() elif dataPDU.shareDataHeader.pduType2.value == data.PDUType2.PDUTYPE2_UPDATE: self.readUpdateDataPDU(dataPDU.pduData) diff --git a/rdpy/protocol/rdp/rdp.py b/rdpy/protocol/rdp/rdp.py index 5ac6fc5..4f38fd6 100644 --- a/rdpy/protocol/rdp/rdp.py +++ b/rdpy/protocol/rdp/rdp.py @@ -199,6 +199,15 @@ class RDPClientController(pdu.layer.PDUClientListener): for observer in self._clientObserver: observer.onReady() + def onSessionReady(self): + """ + @summary: Call when Windows session is ready (connected) + """ + self._isReady = True + #signal all listener + for observer in self._clientObserver: + observer.onSessionReady() + def onClose(self): """ @summary: Event call when RDP stack is closed @@ -616,6 +625,12 @@ class RDPClientObserver(object): """ raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onReady", "RDPClientObserver")) + def onSessionReady(self): + """ + @summary: Windows session is ready + """ + raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onSessionReady", "RDPClientObserver")) + def onClose(self): """ @summary: Stack is closes diff --git a/rdpy/ui/qt4.py b/rdpy/ui/qt4.py index 59723a6..5f17155 100644 --- a/rdpy/ui/qt4.py +++ b/rdpy/ui/qt4.py @@ -311,12 +311,21 @@ class RDPClientQt(RDPClientObserver, QAdaptor): def onReady(self): """ @summary: Call when stack is ready + @see: rdp.RDPClientObserver.onReady """ #do something maybe a loader + + def onSessionReady(self): + """ + @summary: Windows session is ready + @see: rdp.RDPClientObserver.onSessionReady + """ + pass def onClose(self): """ @summary: Call when stack is close + @see: rdp.RDPClientObserver.onClose """ #do something maybe a message @@ -336,12 +345,6 @@ class QRemoteDesktop(QtGui.QWidget): self._adaptor = adaptor #set correct size self.resize(width, height) - #refresh stack of image - #because we can update image only in paint - #event function. When protocol receive image - #we will stock into refresh list - #and in paint event paint list of all refresh images - self._refresh = [] #bind mouse event self.setMouseTracking(True) #buffer image @@ -354,8 +357,9 @@ class QRemoteDesktop(QtGui.QWidget): @param y: y position of new image @param qimage: new QImage """ - #save in refresh list (order is important) - self._refresh.append((x, y, qimage, width, height)) + #fill buffer image + with QtGui.QPainter(self._buffer) as qp: + qp.drawImage(x, y, qimage, 0, 0, width, height) #force update self.update() @@ -373,16 +377,9 @@ class QRemoteDesktop(QtGui.QWidget): @summary: Call when Qt renderer engine estimate that is needed @param e: QEvent """ - #fill buffer image - with QtGui.QPainter(self._buffer) as qp: - #draw image - for (x, y, image, width, height) in self._refresh: - qp.drawImage(x, y, image, 0, 0, width, height) #draw in widget with QtGui.QPainter(self) as qp: qp.drawImage(0, 0, self._buffer) - - self._refresh = [] def mouseMoveEvent(self, event): """