customize start script

This commit is contained in:
speyrefitte
2014-06-18 18:14:36 +02:00
parent b2b2d36dba
commit 03e0425f7b
10 changed files with 197 additions and 78 deletions

View File

@@ -3,19 +3,21 @@
''' '''
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
from rdpy.protocol.rfb.rfb import RfbObserver from rdpy.protocol.rfb.rfb import RfbObserver
from rdpy.protocol.rdp.rdp import RDPObserver
class QAdaptor(object): class QAdaptor(object):
''' '''
adaptor model with link beetween protocol adaptor model with link beetween protocol
and qt widget and qt widget
''' '''
def __init__(self): def __init__(self, qRemoteDesktop):
''' '''
constructor constructor
must set qRemoteDesktop attribute must set qRemoteDesktop attribute
''' '''
#qwidget use for render #qwidget use for render
self._qRemoteDesktop = None self._qRemoteDesktop = qRemoteDesktop
self._qRemoteDesktop._adaptor = self
def sendMouseEvent(self, e): def sendMouseEvent(self, e):
''' '''
@@ -39,14 +41,21 @@ class RfbAdaptor(RfbObserver, QAdaptor):
QAdaptor for specific RFB protocol stack QAdaptor for specific RFB protocol stack
is to an RFB observer is to an RFB observer
''' '''
def __init__(self, rfb): def __init__(self, qRemoteDesktop):
''' '''
ctor ctor
@param rfb: RFB protocol stack @param qRemoteDesktop: widget use for render
'''
QAdaptor.__init__(self, qRemoteDesktop)
self._rfb = None
def setProtocol(self, rfb):
'''
inherit from RfbObserver
init protocol settings
''' '''
self._rfb = rfb
#set RFB observer to #set RFB observer to
self._rfb.addObserver(self) self._rfb = rfb
def notifyFramebufferUpdate(self, width, height, x, y, pixelFormat, encoding, data): def notifyFramebufferUpdate(self, width, height, x, y, pixelFormat, encoding, data):
''' '''
@@ -93,22 +102,59 @@ class RfbAdaptor(RfbObserver, QAdaptor):
''' '''
self._rfb.sendKeyEvent(True, e.nativeVirtualKey()) self._rfb.sendKeyEvent(True, e.nativeVirtualKey())
class RDPAdaptor(RDPObserver, QAdaptor):
'''
Adaptor for RDP client
'''
def __init__(self, qRemoteDesktop):
'''
constructor
@param qRemoteDesktop: widget use for render
'''
QAdaptor.__init__(self, qRemoteDesktop)
def notifyBitmapUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data):
'''
notify bitmap update
@param destLeft: xmin position
@param destTop: ymin position
@param destRight: xmax position because RDP can send bitmap with padding
@param destBottom: ymax position because RDP can send bitmap with padding
@param width: width of bitmap
@param height: height of bitmap
@param bitsPerPixel: number of bit per pixel
@param isCompress: use RLE compression
@param data: bitmap data
'''
#TODO
if isCompress:
return
imageFormat = None
if bitsPerPixel == 16:
imageFormat = QtGui.QImage.Format_RGB16
elif bitsPerPixel == 24:
imageFormat = QtGui.QImage.Format_RGB888
elif bitsPerPixel == 32:
imageFormat = QtGui.QImage.Format_RGB32
else:
print "Receive image in bad format"
return
image = QtGui.QImage(data, width, height, imageFormat)
self._qRemoteDesktop.notifyImage(destLeft, destTop, image)
class QRemoteDesktop(QtGui.QWidget): class QRemoteDesktop(QtGui.QWidget):
''' '''
qt display widget qt display widget
''' '''
def __init__(self, adaptor): def __init__(self):
''' '''
constructor constructor
@param adaptor: any object which inherit
from QAdaptor (RfbAdaptor | RdpAdaptor)
''' '''
super(QRemoteDesktop, self).__init__() super(QRemoteDesktop, self).__init__()
#set adaptor #set by adaptor
self._adaptor = adaptor self._adaptor = None
#set widget attribute of adaptor
self._adaptor._qRemoteDesktop = self
#refresh stack of image #refresh stack of image
#because we can update image only in paint #because we can update image only in paint
#event function. When protocol receive image #event function. When protocol receive image
@@ -153,6 +199,8 @@ class QRemoteDesktop(QtGui.QWidget):
call when mouse move call when mouse move
@param event: qMouseEvent @param event: qMouseEvent
''' '''
if self._adaptor is None:
print "No adaptor to send mouse move event"
self._adaptor.sendMouseEvent(event) self._adaptor.sendMouseEvent(event)
def mousePressEvent(self, event): def mousePressEvent(self, event):
@@ -160,6 +208,8 @@ class QRemoteDesktop(QtGui.QWidget):
call when button mouse is pressed call when button mouse is pressed
@param event: qMouseEvent @param event: qMouseEvent
''' '''
if self._adaptor is None:
print "No adaptor to send mouse press event"
self._adaptor.sendMouseEvent(event) self._adaptor.sendMouseEvent(event)
def keyPressEvent(self, event): def keyPressEvent(self, event):
@@ -167,4 +217,6 @@ class QRemoteDesktop(QtGui.QWidget):
call when button key is pressed call when button key is pressed
@param event: qKeyEvent @param event: qKeyEvent
''' '''
if self._adaptor is None:
print "No adaptor to send key press event"
self._adaptor.sendKeyEvent(event) self._adaptor.sendKeyEvent(event)

View File

36
rdpy/examples/client.py Normal file
View File

@@ -0,0 +1,36 @@
'''
@author: citronneur
'''
import sys
import os
# Change path so we find rdpy
sys.path.insert(1, os.path.join(sys.path[0], '../..'))
from PyQt4 import QtGui
from rdpy.display.qt import RDPAdaptor, RfbAdaptor, QRemoteDesktop
from rdpy.protocol.rdp import rdp
from rdpy.protocol.rfb import rfb
if __name__ == '__main__':
#create application
app = QtGui.QApplication(sys.argv)
#add qt4 reactor
import qt4reactor
qt4reactor.install()
#create widget
w = QRemoteDesktop()
w.resize(1024, 800)
w.setWindowTitle('rdpyclient')
w.show()
if sys.argv[3] == 'rdp':
factory = rdp.Factory(RDPAdaptor(w))
else:
factory = rfb.ClientFactory(RfbAdaptor(w))
from twisted.internet import reactor
reactor.connectTCP(sys.argv[1], int(sys.argv[2]), factory)
reactor.run()
sys.exit(app.exec_())

View File

@@ -4,7 +4,7 @@
import sys, os import sys, os
# Change path so we find rdpy # Change path so we find rdpy
sys.path.insert(1, os.path.join(sys.path[0], '..')) sys.path.insert(1, os.path.join(sys.path[0], '../..'))
from rdpy.protocol.rdp import rdp from rdpy.protocol.rdp import rdp
from rdpy.network.layer import LayerMode from rdpy.network.layer import LayerMode

View File

@@ -701,7 +701,7 @@ class PDU(LayerAutomata):
Global channel for mcs that handle session Global channel for mcs that handle session
identification user, licensing management, and capabilities exchange identification user, licensing management, and capabilities exchange
''' '''
def __init__(self, mode): def __init__(self, mode, dispatcher):
''' '''
Constructor Constructor
''' '''
@@ -742,6 +742,9 @@ class PDU(LayerAutomata):
#share id between client and server #share id between client and server
self._shareId = UInt32Le() self._shareId = UInt32Le()
#rdp observer
self._dispatcher = dispatcher
def connect(self): def connect(self):
''' '''
connect event in client mode send logon info connect event in client mode send logon info
@@ -793,9 +796,9 @@ class PDU(LayerAutomata):
if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_SET_ERROR_INFO_PDU: if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_SET_ERROR_INFO_PDU:
return dataPDU return dataPDU
message = "Unknown code %s"%hex(dataPDU.pduData.errorInfo.value) message = "Unknown code %s"%hex(dataPDU.pduData._value.errorInfo.value)
if ErrorInfo._MESSAGES_.has_key(dataPDU.pduData.errorInfo): if ErrorInfo._MESSAGES_.has_key(dataPDU.pduData._value.errorInfo):
message = ErrorInfo._MESSAGES_[dataPDU.pduData.errorInfo] message = ErrorInfo._MESSAGES_[dataPDU.pduData._value.errorInfo]
raise ErrorReportedFromPeer("Receive PDU Error info : %s"%message) raise ErrorReportedFromPeer("Receive PDU Error info : %s"%message)
@@ -867,6 +870,9 @@ class PDU(LayerAutomata):
@param data: Stream from transport layer @param data: Stream from transport layer
''' '''
dataPDU = self.readDataPDU(data) dataPDU = self.readDataPDU(data)
if dataPDU.shareDataHeader.pduType2 == PDUType2.PDUTYPE2_UPDATE and dataPDU.pduData._value.updateType == UpdateType.UPDATETYPE_BITMAP:
self._dispatcher.recvBitmapUpdateDataPDU(dataPDU.pduData._value.updateData._value)
def sendConfirmActivePDU(self): def sendConfirmActivePDU(self):
''' '''

View File

@@ -3,15 +3,51 @@
''' '''
from twisted.internet import protocol from twisted.internet import protocol
import tpkt, tpdu, mcs, pdu import tpkt, tpdu, mcs, pdu
from rdpy.network.layer import LayerMode
class RDP(object):
'''
use to decode and dispatch to observer PDU message and orders
'''
def __init__(self):
'''
ctor
'''
#list of observer
self._observers = []
def addObserver(self, observer):
'''
add observer to rdp protocol
@param observer: new observer to add
'''
self._observers.append(observer)
def recvBitmapUpdateDataPDU(self, bitmapUpdateData):
'''
call when a bitmap data is received from update pdu
@param bitmapData: pdu.BitmapData struct
'''
for observer in self._observers:
#for each rectangle in update PDU
for rectangle in bitmapUpdateData.rectangles._array:
observer.notifyBitmapUpdate(rectangle.destLeft.value, rectangle.destTop.value, rectangle.destRight.value, rectangle.destBottom.value, rectangle.width.value, rectangle.height.value, rectangle.bitsPerPixel.value, rectangle.flags | pdu.BitmapFlag.BITMAP_COMPRESSION, rectangle.bitmapDataStream.value)
class Factory(protocol.Factory): class Factory(protocol.Factory):
''' '''
Factory of RDP protocol Factory of Client RDP protocol
''' '''
def __init__(self, mode): def __init__(self, observer):
self._mode = mode '''
ctor
@param observer: observer use by rdp protocol to handle events
'''
self._observer = observer
def buildProtocol(self, addr): def buildProtocol(self, addr):
return tpkt.TPKT(tpdu.TPDU(mcs.MCS(pdu.PDU(self._mode)))); rdp = RDP()
rdp.addObserver(self._observer)
return tpkt.TPKT(tpdu.TPDU(mcs.MCS(pdu.PDU(LayerMode.CLIENT, rdp))));
def startedConnecting(self, connector): def startedConnecting(self, connector):
print 'Started to connect.' print 'Started to connect.'
@@ -21,3 +57,22 @@ class Factory(protocol.Factory):
def clientConnectionFailed(self, connector, reason): def clientConnectionFailed(self, connector, reason):
print 'Connection failed. Reason:', reason print 'Connection failed. Reason:', reason
class RDPObserver(object):
'''
class use to inform all rdp event handle by RDPY
'''
def notifyBitmapUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data):
'''
notify bitmap update
@param destLeft: xmin position
@param destTop: ymin position
@param destRight: xmax position because RDP can send bitmap with padding
@param destBottom: ymax position because RDP can send bitmap with padding
@param width: width of bitmap
@param height: height of bitmap
@param bitsPerPixel: number of bit per pixel
@param isCompress: use RLE compression
@param data: bitmap data
'''
pass

View File

@@ -357,6 +357,7 @@ class Rfb(RawLayer):
''' '''
for observer in self._observer: for observer in self._observer:
observer.notifyFramebufferUpdate(self._currentRect.width.value, self._currentRect.height.value, self._currentRect.x.value, self._currentRect.y.value, self._pixelFormat, self._currentRect.encoding, data.getvalue()) observer.notifyFramebufferUpdate(self._currentRect.width.value, self._currentRect.height.value, self._currentRect.x.value, self._currentRect.y.value, self._pixelFormat, self._currentRect.encoding, data.getvalue())
self._nbRect = self._nbRect - 1 self._nbRect = self._nbRect - 1
#if there is another rect to read #if there is another rect to read
if self._nbRect == 0: if self._nbRect == 0:
@@ -410,15 +411,26 @@ class Rfb(RawLayer):
''' '''
self.send((ClientToServerMessages.CUT_TEXT, ClientCutText(text))) self.send((ClientToServerMessages.CUT_TEXT, ClientCutText(text)))
class Factory(protocol.Factory): class ClientFactory(protocol.Factory):
''' '''
Factory of RFB protocol Factory of RFB protocol
''' '''
def __init__(self, mode): def __init__(self, observer):
self._protocol = Rfb(mode) '''
save mode and adapter
@param adapter: graphic client adapter
'''
self._observer = observer
def buildProtocol(self, addr): def buildProtocol(self, addr):
return self._protocol; '''
function call by twisted on connection
@param addr: adresse where client try to connect
'''
protocol = Rfb(LayerMode.CLIENT)
protocol.addObserver(self._observer)
self._observer.setProtocol(protocol)
return protocol
def startedConnecting(self, connector): def startedConnecting(self, connector):
print 'Started to connect.' print 'Started to connect.'
@@ -445,3 +457,10 @@ class RfbObserver(object):
@param data : in respect of dataFormat and pixelFormat @param data : in respect of dataFormat and pixelFormat
''' '''
pass pass
def setProtocol(self, rfbLayer):
'''
call when observer is added to an rfb layer
@param: rfbLayer layer inform the observer
'''
pass

View File

@@ -1,17 +0,0 @@
'''
Created on 4 sept. 2013
@author: sylvain
'''
import sys, os
# Change path so we find rdpy
sys.path.insert(1, os.path.join(sys.path[0], '..'))
from rdpy.protocol.rdp import rdp
from rdpy.network.layer import LayerMode
if __name__ == '__main__':
from twisted.internet import reactor
reactor.connectTCP("192.168.135.59", 3389, rdp.Factory(LayerMode.CLIENT))
reactor.run()

View File

@@ -3,7 +3,7 @@
''' '''
import sys, os import sys, os
# Change path so we find rdpy # Change path so we find rdpy
sys.path.insert(1, os.path.join(sys.path[0], '..')) sys.path.insert(1, os.path.join(sys.path[0], '../..'))
import unittest, rdpy.tests.network.type, rdpy.tests.network.const, rdpy.tests.network.layer import unittest, rdpy.tests.network.type, rdpy.tests.network.const, rdpy.tests.network.layer
def headerTest(name): def headerTest(name):

View File

@@ -1,32 +0,0 @@
'''
@author: sylvain
'''
import sys
import os
# Change path so we find rdpy
sys.path.insert(1, os.path.join(sys.path[0], '..'))
from PyQt4 import QtGui
from rdpy.display.qt import RfbAdaptor, QRemoteDesktop
from rdpy.protocol.rfb import rfb
from rdpy.network.layer import LayerMode
if __name__ == '__main__':
#create application
app = QtGui.QApplication(sys.argv)
#add qt4 reactor
import qt4reactor
qt4reactor.install()
#create rfb protocol
factory = rfb.Factory(LayerMode.CLIENT)
w = QRemoteDesktop(RfbAdaptor(factory._protocol))
w.resize(1000, 700)
w.setWindowTitle('vncclient')
w.show()
from twisted.internet import reactor
reactor.connectTCP("127.0.0.1", 5903, factory)
reactor.run()
sys.exit(app.exec_())