forked from tomatome/grdp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
channel.go
300 lines (264 loc) · 9.8 KB
/
channel.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
package plugin
import "C"
import (
"bytes"
"fmt"
"unsafe"
"github.com/huyenlovemath/grdp/glog"
"github.com/huyenlovemath/grdp/core"
"github.com/huyenlovemath/grdp/emission"
)
const (
CHANNEL_RC_OK = 0
CHANNEL_RC_ALREADY_INITIALIZED = 1
CHANNEL_RC_NOT_INITIALIZED = 2
CHANNEL_RC_ALREADY_CONNECTED = 3
CHANNEL_RC_NOT_CONNECTED = 4
CHANNEL_RC_TOO_MANY_CHANNELS = 5
CHANNEL_RC_BAD_CHANNEL = 6
CHANNEL_RC_BAD_CHANNEL_HANDLE = 7
CHANNEL_RC_NO_BUFFER = 8
CHANNEL_RC_BAD_INIT_HANDLE = 9
CHANNEL_RC_NOT_OPEN = 10
CHANNEL_RC_BAD_PROC = 11
CHANNEL_RC_NO_MEMORY = 12
CHANNEL_RC_UNKNOWN_CHANNEL_NAME = 13
CHANNEL_RC_ALREADY_OPEN = 14
CHANNEL_RC_NOT_IN_VIRTUALCHANNELENTRY = 15
CHANNEL_RC_NULL_DATA = 16
CHANNEL_RC_ZERO_LENGTH = 17
CHANNEL_RC_INVALID_INSTANCE = 18
CHANNEL_RC_UNSUPPORTED_VERSION = 19
CHANNEL_RC_INITIALIZATION_ERROR = 20
)
const (
VIRTUAL_CHANNEL_VERSION_WIN2000 = 1
)
const (
CHANNEL_EVENT_INITIALIZED = 0
CHANNEL_EVENT_CONNECTED = 1
CHANNEL_EVENT_V1_CONNECTED = 2
CHANNEL_EVENT_DISCONNECTED = 3
CHANNEL_EVENT_TERMINATED = 4
CHANNEL_EVENT_REMOTE_CONTROL_START = 5
CHANNEL_EVENT_REMOTE_CONTROL_STOP = 6
CHANNEL_EVENT_ATTACHED = 7
CHANNEL_EVENT_DETACHED = 8
CHANNEL_EVENT_DATA_RECEIVED = 10
CHANNEL_EVENT_WRITE_COMPLETE = 11
CHANNEL_EVENT_WRITE_CANCELLED = 12
)
const (
CHANNEL_OPTION_INITIALIZED = 0x80000000
CHANNEL_OPTION_ENCRYPT_RDP = 0x40000000
CHANNEL_OPTION_ENCRYPT_SC = 0x20000000
CHANNEL_OPTION_ENCRYPT_CS = 0x10000000
CHANNEL_OPTION_PRI_HIGH = 0x08000000
CHANNEL_OPTION_PRI_MED = 0x04000000
CHANNEL_OPTION_PRI_LOW = 0x02000000
CHANNEL_OPTION_COMPRESS_RDP = 0x00800000
CHANNEL_OPTION_COMPRESS = 0x00400000
CHANNEL_OPTION_SHOW_PROTOCOL = 0x00200000
CHANNEL_OPTION_REMOTE_CONTROL_PERSISTENT = 0x00100000
)
type ChannelDef struct {
Name string
Options uint32
}
type CHANNEL_INIT_EVENT_EX_FN func(lpUserParam interface{},
pInitHandle interface{}, event uint, pData uintptr, dataLength uint)
type VIRTUALCHANNELINITEX func(lpUserParam interface{}, clientContext interface{},
pInitHandle interface{}, pChannel []ChannelDef,
channelCount int, versionRequested uint32,
pChannelInitEventProcEx CHANNEL_INIT_EVENT_EX_FN) uint
type CHANNEL_OPEN_EVENT_EX_FN func(lpUserParam uintptr,
openHandle uint32, event uint,
pData uintptr, dataLength uint32, totalLength uint32, dataFlags uint32)
type VIRTUALCHANNELOPENEX func(pInitHandle interface{}, pOpenHandle *uint32,
pChannelName string,
pChannelOpenEventProcEx *CHANNEL_OPEN_EVENT_EX_FN) uint
type VIRTUALCHANNELCLOSEEX func(pInitHandle interface{}, openHandle uint32) uint
type VIRTUALCHANNELWRITEEX func(pInitHandle interface{}, openHandle uint32, pData interface{},
dataLength uint32, pUserData interface{}) uint
type ChannelEntryPointsEx struct {
CbSize uint32
ProtocolVersion uint32
PVirtualChannelInitEx VIRTUALCHANNELINITEX
PVirtualChannelOpenEx VIRTUALCHANNELOPENEX
PVirtualChannelCloseEx VIRTUALCHANNELCLOSEEX
PVirtualChannelWriteEx VIRTUALCHANNELWRITEEX
}
func NewChannelEntryPointsEx() *ChannelEntryPointsEx {
e := &ChannelEntryPointsEx{}
e.CbSize = uint32(unsafe.Sizeof(e))
e.ProtocolVersion = VIRTUAL_CHANNEL_VERSION_WIN2000
return e
}
type VIRTUALCHANNELENTRYEX func(pEntryPointsEx *ChannelEntryPointsEx,
pInitHandle interface{}) error
/*
type ChannelEntryPoints struct {
CbSize uint32
ProtocolVersion uint32
PVirtualChannelInit PVIRTUALCHANNELINIT
PVirtualChannelOpen PVIRTUALCHANNELOPEN
PVirtualChannelClose PVIRTUALCHANNELCLOSE
PVirtualChannelWrite PVIRTUALCHANNELWRITE
}
typedef VOID VCAPITYPE CHANNEL_INIT_EVENT_FN(LPVOID pInitHandle,
UINT event, LPVOID pData, UINT dataLength);
typedef CHANNEL_INIT_EVENT_FN* PCHANNEL_INIT_EVENT_FN;
typedef VOID VCAPITYPE CHANNEL_OPEN_EVENT_FN(DWORD openHandle, UINT event,
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags);
typedef CHANNEL_OPEN_EVENT_FN* PCHANNEL_OPEN_EVENT_FN;
typedef UINT VCAPITYPE VIRTUALCHANNELINIT(LPVOID* ppInitHandle, PCHANNEL_DEF pChannel,
INT channelCount, ULONG versionRequested,
PCHANNEL_INIT_EVENT_FN pChannelInitEventProc);
typedef VIRTUALCHANNELINIT* PVIRTUALCHANNELINIT;
typedef UINT VCAPITYPE VIRTUALCHANNELOPEN(LPVOID pInitHandle, LPDWORD pOpenHandle,
PCHAR pChannelName,
PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc);
typedef VIRTUALCHANNELOPEN* PVIRTUALCHANNELOPEN;
typedef UINT VCAPITYPE VIRTUALCHANNELCLOSE(DWORD openHandle);
typedef VIRTUALCHANNELCLOSE* PVIRTUALCHANNELCLOSE;
typedef UINT VCAPITYPE VIRTUALCHANNELWRITE(DWORD openHandle, LPVOID pData, ULONG dataLength,
LPVOID pUserData);
typedef VIRTUALCHANNELWRITE* PVIRTUALCHANNELWRITE;
typedef UINT VCAPITYPE VIRTUALCHANNELINITEX(LPVOID lpUserParam, LPVOID clientContext,
LPVOID pInitHandle, PCHANNEL_DEF pChannel,
INT channelCount, ULONG versionRequested,
PCHANNEL_INIT_EVENT_EX_FN pChannelInitEventProcEx);
typedef VIRTUALCHANNELINITEX* PVIRTUALCHANNELINITEX;
typedef UINT VCAPITYPE VIRTUALCHANNELOPENEX(LPVOID pInitHandle, LPDWORD pOpenHandle,
PCHAR pChannelName,
PCHANNEL_OPEN_EVENT_EX_FN pChannelOpenEventProcEx);
typedef VIRTUALCHANNELOPENEX* PVIRTUALCHANNELOPENEX;
typedef UINT VCAPITYPE VIRTUALCHANNELCLOSEEX(LPVOID pInitHandle, DWORD openHandle);
typedef VIRTUALCHANNELCLOSEEX* PVIRTUALCHANNELCLOSEEX;
typedef UINT VCAPITYPE VIRTUALCHANNELWRITEEX(LPVOID pInitHandle, DWORD openHandle, LPVOID pData,
ULONG dataLength, LPVOID pUserData);
typedef VIRTUALCHANNELWRITEEX* PVIRTUALCHANNELWRITEEX;
*/
//static channel name
const (
CLIPRDR_SVC_CHANNEL_NAME = "cliprdr" //剪切板
RDPDR_SVC_CHANNEL_NAME = "rdpdr" //设备重定向(打印机,磁盘,端口,智能卡等)
RDPSND_SVC_CHANNEL_NAME = "rdpsnd" //音频输出
RAIL_SVC_CHANNEL_NAME = "rail" //远程应用
ENCOMSP_SVC_CHANNEL_NAME = "encomsp" //多方虚拟通道
REMDESK_SVC_CHANNEL_NAME = "remdesk" //远程协助
)
var StaticVirtualChannels = map[string]int{
CLIPRDR_SVC_CHANNEL_NAME: CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL,
RDPDR_SVC_CHANNEL_NAME: CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP | CHANNEL_OPTION_COMPRESS_RDP,
RDPSND_SVC_CHANNEL_NAME: CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL,
RAIL_SVC_CHANNEL_NAME: CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL,
}
const (
CHANNEL_CHUNK_LENGTH = 1600
CHANNEL_FLAG_FIRST = 0x01
CHANNEL_FLAG_LAST = 0x02
CHANNEL_FLAG_SHOW_PROTOCOL = 0x10
)
type ChannelTransport interface {
GetType() (string, uint32)
Sender(core.ChannelSender)
Process(s []byte)
}
type ChannelClient struct {
ChannelDef
t ChannelTransport
}
type Channels struct {
emission.Emitter
channels map[string]ChannelClient
transport core.Transport
buff *bytes.Buffer
channelSender core.ChannelSender
}
func NewChannels(t core.Transport) *Channels {
c := &Channels{
Emitter: *emission.NewEmitter(),
channels: make(map[string]ChannelClient, 20),
transport: t,
buff: &bytes.Buffer{},
}
t.On("channel", c.process)
return c
}
func (c *Channels) SetChannelSender(f core.ChannelSender) {
c.channelSender = f
}
func (c *Channels) Register(t ChannelTransport) {
name, option := t.GetType()
_, ok := c.channels[name]
if ok {
glog.Warn("Already register channel:", name)
return
}
t.Sender(c)
c.channels[name] = ChannelClient{ChannelDef{name, option}, t}
}
func (c *Channels) SendToChannel(channel string, s []byte) (int, error) {
cli, ok := c.channels[channel]
if !ok {
glog.Warn("No register channel:", channel)
return 0, fmt.Errorf("No register channel: %s", channel)
}
idx := 0
ln := len(s)
b := &bytes.Buffer{}
for ln > 0 {
var flag uint32 = 0
if cli.Options&CHANNEL_OPTION_SHOW_PROTOCOL != 0 {
flag |= CHANNEL_FLAG_SHOW_PROTOCOL
}
if idx == 0 {
flag |= CHANNEL_FLAG_FIRST
}
var ss []byte
if ln > CHANNEL_CHUNK_LENGTH {
ss = s[idx : idx+CHANNEL_CHUNK_LENGTH]
idx += CHANNEL_CHUNK_LENGTH
} else {
flag |= CHANNEL_FLAG_LAST
ss = s[idx : idx+ln]
}
glog.Debug("len:", len(ss), "flag:", flag)
ln -= len(ss)
b.Reset()
core.WriteUInt32LE(uint32(len(s)), b)
core.WriteUInt32LE(flag, b)
b.Write(ss)
c.channelSender.SendToChannel(channel, b.Bytes())
}
return ln, nil
}
func (c *Channels) process(channel string, s []byte) {
cli, ok := c.channels[channel]
if !ok {
glog.Warn("No found channel:", channel)
return
}
r := bytes.NewReader(s)
ln, _ := core.ReadUInt32LE(r)
flags, _ := core.ReadUInt32LE(r)
glog.Debugf("channel:%s length: %d, flags: %d", channel, ln, flags)
if flags&CHANNEL_FLAG_FIRST == 0 || flags&CHANNEL_FLAG_LAST == 0 {
if flags&CHANNEL_FLAG_FIRST != 0 {
c.buff.Reset()
}
b, _ := core.ReadBytes(r.Len(), r)
c.buff.Write(b)
if flags&CHANNEL_FLAG_LAST == 0 {
return
}
s = c.buff.Bytes()
} else {
s, _ = core.ReadBytes(r.Len(), r)
}
cli.t.Process(s)
}