mirror of
https://github.com/yv1ing/ShotRDP.git
synced 2025-09-16 15:10:57 +08:00
基本适应win7,win10,win server 08,win server 12,win server 16的截图
This commit is contained in:
162
grdp/plugin/drdynvc/dvc.go
Normal file
162
grdp/plugin/drdynvc/dvc.go
Normal file
@@ -0,0 +1,162 @@
|
||||
package drdynvc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
|
||||
"ShotRDP/grdp/core"
|
||||
"ShotRDP/grdp/glog"
|
||||
"ShotRDP/grdp/plugin"
|
||||
)
|
||||
|
||||
const (
|
||||
ChannelName = plugin.DRDYNVC_SVC_CHANNEL_NAME
|
||||
ChannelOption = plugin.CHANNEL_OPTION_INITIALIZED |
|
||||
plugin.CHANNEL_OPTION_ENCRYPT_RDP
|
||||
)
|
||||
|
||||
const (
|
||||
MAX_DVC_CHANNELS = 20
|
||||
)
|
||||
|
||||
const (
|
||||
DYNVC_CREATE_REQ = 0x01
|
||||
DYNVC_DATA_FIRST = 0x02
|
||||
DYNVC_DATA = 0x03
|
||||
DYNVC_CLOSE = 0x04
|
||||
DYNVC_CAPABILITIES = 0x05
|
||||
DYNVC_DATA_FIRST_COMPRESSED = 0x06
|
||||
DYNVC_DATA_COMPRESSED = 0x07
|
||||
DYNVC_SOFT_SYNC_REQUEST = 0x08
|
||||
DYNVC_SOFT_SYNC_RESPONSE = 0x09
|
||||
)
|
||||
|
||||
type ChannelClient struct {
|
||||
name string
|
||||
id uint32
|
||||
channelSender core.ChannelSender
|
||||
}
|
||||
|
||||
type DvcClient struct {
|
||||
w core.ChannelSender
|
||||
channels map[string]ChannelClient
|
||||
}
|
||||
|
||||
func NewDvcClient() *DvcClient {
|
||||
return &DvcClient{
|
||||
channels: make(map[string]ChannelClient, 100),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *DvcClient) LoadAddin(f core.ChannelSender) {
|
||||
|
||||
}
|
||||
|
||||
type DvcHeader struct {
|
||||
cmd uint8
|
||||
sp uint8
|
||||
cbChId uint8
|
||||
}
|
||||
|
||||
func readHeader(r io.Reader) *DvcHeader {
|
||||
value, _ := core.ReadUInt8(r)
|
||||
cmd := (value & 0xf0) >> 4
|
||||
sp := (value & 0x0c) >> 2
|
||||
cbChId := (value & 0x03) >> 0
|
||||
return &DvcHeader{cmd, sp, cbChId}
|
||||
}
|
||||
|
||||
func (h *DvcHeader) serialize(channelId uint32) []byte {
|
||||
b := &bytes.Buffer{}
|
||||
core.WriteUInt8((h.cmd<<4)|(h.sp<<2)|h.cbChId, b)
|
||||
if h.cbChId == 0 {
|
||||
core.WriteUInt8(uint8(channelId), b)
|
||||
} else if h.cbChId == 1 {
|
||||
core.WriteUInt16LE(uint16(channelId), b)
|
||||
} else {
|
||||
core.WriteUInt32LE(channelId, b)
|
||||
}
|
||||
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
func (c *DvcClient) Send(s []byte) (int, error) {
|
||||
glog.Debug("len:", len(s), "data:", hex.EncodeToString(s))
|
||||
name, _ := c.GetType()
|
||||
return c.w.SendToChannel(name, s)
|
||||
}
|
||||
func (c *DvcClient) Sender(f core.ChannelSender) {
|
||||
c.w = f
|
||||
}
|
||||
func (c *DvcClient) GetType() (string, uint32) {
|
||||
return ChannelName, ChannelOption
|
||||
}
|
||||
|
||||
func (c *DvcClient) Process(s []byte) {
|
||||
glog.Debug("recv:", hex.EncodeToString(s))
|
||||
r := bytes.NewReader(s)
|
||||
hdr := readHeader(r)
|
||||
glog.Infof("dvc: Cmd=0x%x, Sp=%d CbChId=%d all=%d", hdr.cmd, hdr.sp, hdr.cbChId, r.Len())
|
||||
|
||||
b, _ := core.ReadBytes(r.Len(), r)
|
||||
|
||||
switch hdr.cmd {
|
||||
case DYNVC_CAPABILITIES:
|
||||
glog.Info("DYNVC_CAPABILITIES")
|
||||
c.processCapsPdu(hdr, b)
|
||||
case DYNVC_CREATE_REQ:
|
||||
glog.Info("DYNVC_CREATE_REQ")
|
||||
c.processCreateReq(hdr, b)
|
||||
case DYNVC_DATA_FIRST:
|
||||
glog.Info("DYNVC_DATA_FIRST")
|
||||
case DYNVC_DATA:
|
||||
glog.Info("DYNVC_DATA")
|
||||
case DYNVC_CLOSE:
|
||||
glog.Info("DYNVC_CLOSE")
|
||||
default:
|
||||
glog.Errorf("type 0x%x not supported", hdr.cmd)
|
||||
}
|
||||
}
|
||||
func (c *DvcClient) processCreateReq(hdr *DvcHeader, s []byte) {
|
||||
r := bytes.NewReader(s)
|
||||
channelId := readDvcId(r, hdr.cbChId)
|
||||
name, _ := core.ReadBytes(r.Len(), r)
|
||||
channelName := string(name)
|
||||
glog.Infof("Server requests channelId=%d, name=%s", channelId, channelName)
|
||||
|
||||
//response
|
||||
b := &bytes.Buffer{}
|
||||
b.Write(hdr.serialize(channelId))
|
||||
core.WriteUInt32LE(0, b)
|
||||
c.Send(b.Bytes())
|
||||
}
|
||||
|
||||
func readDvcId(r io.Reader, cbLen uint8) (id uint32) {
|
||||
switch cbLen {
|
||||
case 0:
|
||||
i, _ := core.ReadUInt8(r)
|
||||
id = uint32(i)
|
||||
case 1:
|
||||
i, _ := core.ReadUint16LE(r)
|
||||
id = uint32(i)
|
||||
default:
|
||||
id, _ = core.ReadUInt32LE(r)
|
||||
}
|
||||
return
|
||||
}
|
||||
func (c *DvcClient) processCapsPdu(hdr *DvcHeader, s []byte) {
|
||||
r := bytes.NewReader(s)
|
||||
core.ReadUInt8(r)
|
||||
ver, _ := core.ReadUint16LE(r)
|
||||
glog.Infof("Server supports dvc=%d", ver)
|
||||
|
||||
hdr.cmd = DYNVC_CAPABILITIES
|
||||
hdr.cbChId = 0
|
||||
hdr.sp = 0
|
||||
|
||||
b := &bytes.Buffer{}
|
||||
core.WriteUInt16LE(0x0050, b)
|
||||
core.WriteUInt16LE(ver, b)
|
||||
c.Send(b.Bytes())
|
||||
}
|
||||
Reference in New Issue
Block a user