EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
cliprdr.js
Go to the documentation of this file.
1const type = require('../../core').type;
2const EventEmitter = require('events').EventEmitter;
3const caps = require('./caps');
4const log = require('../../core').log;
5const data = require('./data');
6
7
8
9/**
10 * Cliprdr channel for all clipboard
11 * capabilities exchange
12 */
13class Cliprdr extends EventEmitter {
14
15 constructor(transport) {
16 super();
17 this.transport = transport;
18 // must be init via connect event
19 this.userId = 0;
20 this.serverCapabilities = [];
21 this.clientCapabilities = [];
22 }
23
24}
25
26
27/**
28 * Client side of Cliprdr channel automata
29 * @param transport
30 */
31class Client extends Cliprdr {
32
33 constructor(transport, fastPathTransport) {
34
35 super(transport, fastPathTransport);
36
37 this.transport.once('connect', (gccCore, userId, channelId) => {
38 this.connect(gccCore, userId, channelId);
39 }).on('close', function () {
40 //this.emit('close');
41 }).on('error', function (err) {
42 //this.emit('error', err);
43 });
44
45 this.content = '';
46
47 }
48
49 /**
50 * connect function
51 * @param gccCore {type.Component(clientCoreData)}
52 */
53 connect(gccCore, userId, channelId) {
54 this.gccCore = gccCore;
55 this.userId = userId;
56 this.channelId = channelId;
57 this.transport.once('cliprdr', (s) => {
58 this.recv(s);
59 });
60 }
61
62
63 send(message) {
64 this.transport.send('cliprdr', new type.Component([
65 // Channel PDU Header
66 new type.UInt32Le(message.size()),
67 // CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST | CHANNEL_FLAG_SHOW_PROTOCOL
68 new type.UInt32Le(0x13),
69 message
70 ]));
71 };
72
73 recv(s) {
74 s.offset = 18;
75 const pdu = data.clipPDU().read(s), type = data.ClipPDUMsgType;
76
77 switch (pdu.obj.header.obj.msgType.value) {
78 case type.CB_MONITOR_READY:
79 this.recvMonitorReadyPDU(s);
80 break;
81 case type.CB_FORMAT_LIST:
82 this.recvFormatListPDU(s);
83 break;
84 case type.CB_FORMAT_LIST_RESPONSE:
85 this.recvFormatListResponsePDU(s);
86 break;
87 case type.CB_FORMAT_DATA_REQUEST:
88 this.recvFormatDataRequestPDU(s);
89 break;
90 case type.CB_FORMAT_DATA_RESPONSE:
91 this.recvFormatDataResponsePDU(s);
92 break;
93 case type.CB_TEMP_DIRECTORY:
94 break;
95 case type.CB_CLIP_CAPS:
96 this.recvClipboardCapsPDU(s);
97 break;
98 case type.CB_FILECONTENTS_REQUEST:
99 }
100
101 this.transport.once('cliprdr', (s) => {
102 this.recv(s);
103 });
104 }
105
106 /**
107 * Receive capabilities from server
108 * @param s {type.Stream}
109 */
110 recvClipboardCapsPDU(s) {
111 // Start at 18
112 s.offset = 18;
113 // const pdu = data.clipPDU().read(s);
114 // console.log('recvClipboardCapsPDU', s);
115 }
116
117
118 /**
119 * Receive monitor ready from server
120 * @param s {type.Stream}
121 */
122 recvMonitorReadyPDU(s) {
123 s.offset = 18;
124 // const pdu = data.clipPDU().read(s);
125 // console.log('recvMonitorReadyPDU', s);
126
127 this.sendClipboardCapsPDU();
128 // this.sendClientTemporaryDirectoryPDU();
129 this.sendFormatListPDU();
130 }
131
132
133 /**
134 * Send clipboard capabilities PDU
135 */
136 sendClipboardCapsPDU() {
137 this.send(new type.Component({
138 msgType: new type.UInt16Le(data.ClipPDUMsgType.CB_CLIP_CAPS),
139 msgFlags: new type.UInt16Le(0x00),
140 dataLen: new type.UInt32Le(0x10),
141 cCapabilitiesSets: new type.UInt16Le(0x01),
142 pad1: new type.UInt16Le(0x00),
143 capabilitySetType: new type.UInt16Le(0x01),
144 lengthCapability: new type.UInt16Le(0x0c),
145 version: new type.UInt32Le(0x02),
146 capabilityFlags: new type.UInt32Le(0x02)
147 }));
148 }
149
150
151 /**
152 * Send client temporary directory PDU
153 */
154 sendClientTemporaryDirectoryPDU(path = '') {
155 // TODO
156 this.send(new type.Component({
157 msgType: new type.UInt16Le(data.ClipPDUMsgType.CB_TEMP_DIRECTORY),
158 msgFlags: new type.UInt16Le(0x00),
159 dataLen: new type.UInt32Le(0x0208),
160 wszTempDir: new type.BinaryString(Buffer.from('D:\\Vectors' + Array(251).join('\x00'), 'ucs2'), { readLength: new type.CallableValue(520) })
161 }));
162 }
163
164
165 /**
166 * Send format list PDU
167 */
168 sendFormatListPDU() {
169 this.send(new type.Component({
170 msgType: new type.UInt16Le(data.ClipPDUMsgType.CB_FORMAT_LIST),
171 msgFlags: new type.UInt16Le(0x00),
172
173 dataLen: new type.UInt32Le(0x24),
174
175 formatId6: new type.UInt32Le(0xc004),
176 formatName6: new type.BinaryString(Buffer.from('Native\x00', 'ucs2'), { readLength: new type.CallableValue(14) }),
177
178 formatId8: new type.UInt32Le(0x0d),
179 formatName8: new type.UInt16Le(0x00),
180
181 formatId9: new type.UInt32Le(0x10),
182 formatName9: new type.UInt16Le(0x00),
183
184 formatId0: new type.UInt32Le(0x01),
185 formatName0: new type.UInt16Le(0x00),
186
187 // dataLen: new type.UInt32Le(0xe0),
188
189 // formatId1: new type.UInt32Le(0xc08a),
190 // formatName1: new type.BinaryString(Buffer.from('Rich Text Format\x00' , 'ucs2'), { readLength : new type.CallableValue(34)}),
191
192 // formatId2: new type.UInt32Le(0xc145),
193 // formatName2: new type.BinaryString(Buffer.from('Rich Text Format Without Objects\x00' , 'ucs2'), { readLength : new type.CallableValue(66)}),
194
195 // formatId3: new type.UInt32Le(0xc143),
196 // formatName3: new type.BinaryString(Buffer.from('RTF As Text\x00' , 'ucs2'), { readLength : new type.CallableValue(24)}),
197
198 // formatId4: new type.UInt32Le(0x01),
199 // formatName4: new type.BinaryString(0x00),
200
201 formatId5: new type.UInt32Le(0x07),
202 formatName5: new type.UInt16Le(0x00),
203
204 // formatId6: new type.UInt32Le(0xc004),
205 // formatName6: new type.BinaryString(Buffer.from('Native\x00' , 'ucs2'), { readLength : new type.CallableValue(14)}),
206
207 // formatId7: new type.UInt32Le(0xc00e),
208 // formatName7: new type.BinaryString(Buffer.from('Object Descriptor\x00' , 'ucs2'), { readLength : new type.CallableValue(36)}),
209
210 // formatId8: new type.UInt32Le(0x03),
211 // formatName8: new type.UInt16Le(0x00),
212
213 // formatId9: new type.UInt32Le(0x10),
214 // formatName9: new type.UInt16Le(0x00),
215
216 // formatId0: new type.UInt32Le(0x07),
217 // formatName0: new type.UInt16Le(0x00),
218 }));
219
220 }
221
222 /**
223 * Recvie format list PDU from server
224 * @param {type.Stream} s
225 */
226 recvFormatListPDU(s) {
227 s.offset = 18;
228 // const pdu = data.clipPDU().read(s);
229 // console.log('recvFormatListPDU', s);
230 this.sendFormatListResponsePDU();
231 }
232
233
234 /**
235 * Send format list reesponse
236 */
237 sendFormatListResponsePDU() {
238 this.send(new type.Component({
239 msgType: new type.UInt16Le(data.ClipPDUMsgType.CB_FORMAT_LIST_RESPONSE),
240 msgFlags: new type.UInt16Le(0x01),
241 dataLen: new type.UInt32Le(0x00),
242 }));
243
244 this.sendFormatDataRequestPDU();
245 }
246
247
248 /**
249 * Receive format list response from server
250 * @param s {type.Stream}
251 */
252 recvFormatListResponsePDU(s) {
253 s.offset = 18;
254 // const pdu = data.clipPDU().read(s);
255 // console.log('recvFormatListResponsePDU', s);
256 // this.sendFormatDataRequestPDU();
257 }
258
259
260 /**
261 * Send format data request PDU
262 */
263 sendFormatDataRequestPDU(formartId = 0x0d) {
264 this.send(new type.Component({
265 msgType: new type.UInt16Le(data.ClipPDUMsgType.CB_FORMAT_DATA_REQUEST),
266 msgFlags: new type.UInt16Le(0x00),
267 dataLen: new type.UInt32Le(0x04),
268 requestedFormatId: new type.UInt32Le(formartId),
269 }));
270 }
271
272
273 /**
274 * Receive format data request PDU from server
275 * @param s {type.Stream}
276 */
277 recvFormatDataRequestPDU(s) {
278 s.offset = 18;
279 // const pdu = data.clipPDU().read(s);
280 // console.log('recvFormatDataRequestPDU', s);
281 this.sendFormatDataResponsePDU();
282 }
283
284
285 /**
286 * Send format data reesponse PDU
287 */
288 sendFormatDataResponsePDU() {
289
290 const bufs = Buffer.from(this.content + '\x00', 'ucs2');
291
292 this.send(new type.Component({
293 msgType: new type.UInt16Le(data.ClipPDUMsgType.CB_FORMAT_DATA_RESPONSE),
294 msgFlags: new type.UInt16Le(0x01),
295 dataLen: new type.UInt32Le(bufs.length),
296 requestedFormatData: new type.BinaryString(bufs, { readLength: new type.CallableValue(bufs.length) })
297 }));
298
299 }
300
301
302 /**
303 * Receive format data response PDU from server
304 * @param s {type.Stream}
305 */
306 recvFormatDataResponsePDU(s) {
307 s.offset = 18;
308 // const pdu = data.clipPDU().read(s);
309 const str = s.buffer.toString('ucs2', 26, s.buffer.length - 2);
310 // console.log('recvFormatDataResponsePDU', str);
311 this.content = str;
312 this.emit('clipboard', str)
313 }
314
315
316 // =====================================================================================
317 setClipboardData(content) {
318 this.content = content;
319 this.sendFormatListPDU();
320 }
321
322}
323
324
325module.exports = {
326 Client
327}