Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
260 | hidnplayr | 1 | ; |
2 | ; |
||
3 | ; VNC Client for kolibrios by hidnplayr |
||
4 | ; |
||
5 | ; |
||
6 | ; WORK IN PROGRESS... |
||
7 | ; |
||
8 | ; FEEL FREE TO CONTRIBUTE ! |
||
9 | ; |
||
10 | ; hidnplayr@gmail.com |
||
11 | ; |
||
12 | |||
13 | use32 |
||
14 | |||
15 | org 0x0 |
||
16 | |||
17 | db 'MENUET00' ; 8 byte id |
||
18 | dd 38 ; required os |
||
19 | dd START ; program start |
||
20 | dd I_END ; program image size |
||
21 | dd IM_END ; required amount of memory |
||
22 | dd 0 ; reserved=no extended header |
||
23 | |||
24 | __DEBUG__ equ 1 |
||
25 | __DEBUG_LEVEL__ equ 1 |
||
26 | STRLEN = 64 |
||
27 | xpos = 4 |
||
28 | ypos = 22 |
||
29 | |||
30 | TIMEOUT = 60 ; timeout in seconds |
||
31 | BUFFER = 512 ; Buffer size for DNS |
||
32 | |||
33 | include 'fdo.inc' |
||
34 | include 'ETH.INC' |
||
35 | include 'logon.inc' |
||
36 | include 'raw.inc' |
||
37 | include 'copyrect.inc' |
||
38 | |||
39 | |||
40 | START: ; start of execution |
||
41 | call red_logon |
||
42 | |||
43 | mov eax,40 ; Report events |
||
44 | mov ebx,10000000b ; Only Stack |
||
45 | int 0x40 |
||
46 | |||
47 | mov eax,67 ; resize the window (hide it) |
||
48 | xor ebx,ebx |
||
49 | mov ecx,ebx |
||
50 | mov edx,ebx |
||
51 | mov esi,ebx |
||
52 | int 0x40 |
||
53 | |||
54 | resolve first,[server_ip] ; the input window putted the server @ 'first', resolve it into a real ip |
||
55 | mov [server_port],5900 ; no port input for now, only standard port 5900 |
||
56 | |||
57 | DEBUGF 1,'connecting to %u.%u.%u.%u:%u\n',1[server_ip],1[server_ip+1],1[server_ip+2],1[server_ip+3],4[server_port] |
||
58 | eth.search_port 1000,edx ; Find a free port starting from 1001 and store in edx |
||
59 | eth.open_tcp edx,[server_port],[server_ip],1,[socket] ; open socket |
||
60 | DEBUGF 1,'Socket opened: %u (port %u)\n',[socket],ecx |
||
61 | |||
62 | call read_data |
||
63 | cmp dword[receive_buffer+1],'RFB ' |
||
64 | jne no_rfb |
||
65 | eth.write_tcp [socket],12,handshake |
||
66 | DEBUGF 1,'Sending handshake: protocol version\n' |
||
67 | |||
68 | call read_data |
||
69 | mov eax,receive_buffer+1 |
||
70 | mov eax,[eax] |
||
71 | bswap eax |
||
72 | cmp eax,0 |
||
73 | je invalid_security |
||
74 | cmp eax,1 |
||
75 | je no_security |
||
76 | cmp eax,2 |
||
77 | je vnc_security |
||
78 | |||
79 | jmp close |
||
80 | |||
81 | vnc_security: |
||
82 | mov byte[mode],1 |
||
83 | call red_logon |
||
84 | |||
85 | no_security: |
||
86 | eth.write_tcp [socket],1,shared |
||
87 | DEBUGF 1,'Sending handshake: shared session?\n' |
||
88 | |||
89 | eth.wait_for_data [socket],TIMEOUT*10,close |
||
90 | eth.read_data [socket],framebuffer,[datapointer],IM_END-receive_buffer ; now the server should send init message |
||
91 | DEBUGF 1,'Serverinit: bpp:%u depth:%u bigendian:%u truecolor:%u\n',1[pixelformat.bpp],1[pixelformat.depth],1[pixelformat.big_endian],1[pixelformat.true_color] |
||
92 | mov eax,dword[framebuffer] |
||
93 | bswap eax |
||
94 | mov dword[screen],eax |
||
95 | |||
96 | eth.write_tcp [socket],20,pixel_format32 |
||
97 | DEBUGF 1,'Sending pixel format\n' |
||
98 | call read_data |
||
99 | |||
100 | ; eth.write_tcp [socket],8,encodings |
||
101 | ; DEBUGF 1,'Sending encoding info\n' |
||
102 | ; call read_data |
||
103 | |||
104 | mov eax,dword[framebuffer.width] |
||
105 | mov dword[fbur.width],eax |
||
106 | |||
107 | mov eax,40 ; report events |
||
108 | mov ebx,10100111b ; stack, mouse, button, key, redraw |
||
109 | int 0x40 |
||
110 | |||
111 | mov eax,67 ; resize the window |
||
112 | mov ebx,10 |
||
113 | mov ecx,10 |
||
114 | mov edx,dword[framebuffer] |
||
115 | bswap edx |
||
116 | movzx esi,dx |
||
117 | shr edx,16 |
||
118 | add edx,2*xpos |
||
119 | add esi,ypos+xpos |
||
120 | int 0x40 |
||
121 | |||
122 | ; mov byte[fbur.inc],0 ; request a framebufferupdate |
||
123 | ; eth.write_tcp [socket],10,fbur |
||
124 | |||
125 | mainloop: |
||
126 | eth.socket_status [socket],eax |
||
127 | cmp al,TCB_CLOSE_WAIT |
||
128 | je close |
||
129 | |||
130 | mov eax,23 ; wait for event with timeout |
||
131 | mov ebx,50 ; 0,5 s |
||
132 | int 0x40 |
||
133 | |||
134 | cmp eax,1 ; redraw |
||
135 | je redraw |
||
136 | cmp eax,2 ; key |
||
137 | je key |
||
138 | cmp eax,3 ; button |
||
139 | je button |
||
140 | cmp eax,6 ; mouse |
||
141 | je mouse |
||
142 | cmp eax,8 |
||
143 | je network |
||
144 | |||
145 | ; request an FRB update |
||
146 | jmp mainloop |
||
147 | |||
148 | |||
149 | network: |
||
150 | call read_data ; Read the data into the buffer |
||
151 | |||
152 | mov eax,[datapointer] ; at least 2 bytes should be received |
||
153 | sub eax,receive_buffer |
||
154 | cmp eax,1 |
||
155 | jle mainloop |
||
156 | |||
157 | DEBUGF 1,'Data received, %u bytes\n',eax |
||
158 | |||
159 | cmp byte[receive_buffer],0 |
||
160 | je framebufferupdate |
||
161 | |||
162 | cmp byte[receive_buffer],1 |
||
163 | je setcolourmapentries |
||
164 | |||
165 | cmp byte[receive_buffer],2 |
||
166 | je bell |
||
167 | |||
168 | cmp byte[receive_buffer],3 |
||
169 | je servercuttext |
||
170 | |||
171 | jmp mainloop |
||
172 | |||
173 | |||
174 | framebufferupdate: |
||
175 | DEBUGF 1,'Framebufferupdate!\n' |
||
176 | mov di,word[receive_buffer+2] |
||
177 | bswap edi |
||
178 | shr edi,16 |
||
179 | mov esi,receive_buffer+4 |
||
180 | |||
181 | rectangle_loop: |
||
182 | mov edx,[esi] |
||
183 | bswap edx |
||
184 | mov ebx,edx |
||
185 | shr edx,16 |
||
186 | mov [frame.x],dx |
||
187 | mov [frame.y],bx |
||
188 | add esi,4 |
||
189 | mov ecx,[esi] |
||
190 | bswap ecx |
||
191 | mov eax,ecx |
||
192 | shr ecx,16 |
||
193 | mov [frame.width],cx |
||
194 | mov [frame.height],ax |
||
195 | add esi,4 |
||
196 | mov eax,[esi] |
||
197 | add esi,4 |
||
198 | |||
199 | DEBUGF 1,'screen: width=%u height=%u\nframe: width=%u height=%u x=%u y=%u\n',2[screen.width],2[screen.height],2[frame.width],2[frame.height],2[frame.x],2[frame.y] |
||
200 | |||
201 | cmp eax,0 |
||
202 | je encoding_raw |
||
203 | |||
204 | cmp eax,1 |
||
205 | je encoding_copyrect |
||
206 | |||
207 | cmp eax,2 |
||
208 | je encoding_RRE |
||
209 | |||
210 | cmp eax,5 |
||
211 | je encoding_hextile |
||
212 | |||
213 | cmp eax,16 |
||
214 | je encoding_ZRLE |
||
215 | |||
216 | DEBUGF 1,'FRAME: unknown encoding\n' |
||
217 | jmp mainloop |
||
218 | |||
219 | next_rectangle: |
||
220 | dec di |
||
221 | pusha |
||
222 | call drawbuffer |
||
223 | popa |
||
224 | cmp di,0 |
||
225 | jg rectangle_loop |
||
226 | jmp mainloop |
||
227 | |||
228 | encoding_RRE: |
||
229 | DEBUGF 1,'FRAME: RRE\n' |
||
230 | |||
231 | jmp next_rectangle |
||
232 | |||
233 | encoding_hextile: |
||
234 | DEBUGF 1,'FRAME: hextile\n' |
||
235 | |||
236 | jmp next_rectangle |
||
237 | |||
238 | encoding_ZRLE: |
||
239 | DEBUGF 1,'FRAME: ZRLE\n' |
||
240 | |||
241 | jmp next_rectangle |
||
242 | |||
243 | |||
244 | setcolourmapentries: |
||
245 | |||
246 | DEBUGF 1,'Server sended an SetColourMapEntries message\n' |
||
247 | |||
248 | jmp mainloop |
||
249 | |||
250 | |||
251 | bell: |
||
252 | mov eax,55 |
||
253 | mov ebx,eax |
||
254 | mov esi,beep |
||
255 | int 0x40 |
||
256 | |||
257 | jmp mainloop |
||
258 | |||
259 | |||
260 | servercuttext: |
||
261 | |||
262 | jmp mainloop |
||
263 | |||
264 | |||
265 | key: |
||
266 | DEBUGF 1,'Sending key event\n' |
||
267 | |||
268 | mov eax,2 |
||
269 | int 0x40 |
||
270 | mov byte[keyevent.key+3],ah |
||
271 | |||
272 | ; eth.write_tcp [socket],8,keyevent |
||
273 | |||
274 | cmp ah,13 |
||
275 | jne @f |
||
276 | |||
277 | mov byte[fbur.inc],1 |
||
278 | eth.write_tcp [socket],10,fbur |
||
279 | jmp mainloop |
||
280 | @@: |
||
281 | |||
282 | cmp ah,30 |
||
283 | jne @f |
||
284 | |||
285 | mov byte[fbur.inc],12 |
||
286 | eth.write_tcp [socket],10,fbur |
||
287 | jmp mainloop |
||
288 | @@: |
||
289 | |||
290 | mov byte[fbur.inc],0 |
||
291 | eth.write_tcp [socket],10,fbur |
||
292 | |||
293 | jmp mainloop |
||
294 | |||
295 | mouse: |
||
296 | DEBUGF 1,'Sending mouse event\n' |
||
297 | |||
298 | mov eax,37 |
||
299 | mov ebx,1 |
||
300 | int 0x40 |
||
301 | |||
302 | sub eax,xpos*65536+ypos |
||
303 | bswap eax |
||
304 | mov word[pointerevent.x],ax |
||
305 | shr eax,16 |
||
306 | mov word[pointerevent.y],ax |
||
307 | |||
308 | mov eax,37 |
||
309 | mov ebx,2 |
||
310 | int 0x40 |
||
311 | |||
312 | cmp al,2 |
||
313 | jne @f ; in kolibri right click is 2 (decimal), in RFB protocol it is bit 2 (counting from 0) |
||
314 | mov al,100b |
||
315 | @@: |
||
316 | |||
317 | mov byte[pointerevent.mask],al |
||
318 | |||
319 | eth.write_tcp [socket],6,pointerevent |
||
320 | |||
321 | jmp mainloop |
||
322 | |||
323 | redraw: |
||
324 | |||
325 | DEBUGF 1,'Drawing window\n' |
||
326 | |||
327 | mov eax,12 |
||
328 | mov ebx,1 |
||
329 | int 0x40 |
||
330 | |||
331 | mov eax,0 ; draw window |
||
332 | mov ebx,dword[framebuffer] |
||
333 | bswap ebx |
||
334 | movzx ecx,bx |
||
335 | shr ebx,16 |
||
336 | add ebx,2*xpos |
||
337 | add ecx,ypos+xpos |
||
338 | mov edx,0x03ffffff |
||
339 | mov esi,0x80555599 |
||
340 | mov edi,0x00ffffff |
||
341 | int 0x40 |
||
342 | |||
343 | mov eax,4 ; label |
||
344 | mov ebx,9*65536+8 |
||
345 | mov ecx,0x10ffffff |
||
346 | mov edx,name |
||
347 | mov esi,[name_length] |
||
348 | bswap esi |
||
349 | int 0x40 |
||
350 | |||
351 | call drawbuffer |
||
352 | |||
353 | mov eax,12 |
||
354 | mov ebx,2 |
||
355 | int 0x40 |
||
356 | |||
357 | jmp mainloop |
||
358 | |||
359 | drawbuffer: |
||
360 | |||
361 | mov eax,7 |
||
362 | mov ebx,framebuffer_data |
||
363 | mov ecx,dword[screen] |
||
364 | mov edx,xpos*65536+ypos |
||
365 | int 0x40 |
||
366 | |||
367 | ret |
||
368 | |||
369 | |||
370 | button: ; button |
||
371 | mov eax,17 ; get id |
||
372 | int 0x40 |
||
373 | |||
374 | close: |
||
375 | call read_data |
||
376 | ; eth.close_tcp [socket] ; We're done, close the socket ;;; BUG WHEN CLOSING SCOKET !! |
||
377 | DEBUGF 1,'Socket closed\n' |
||
378 | |||
379 | mov eax,-1 |
||
380 | int 0x40 |
||
381 | |||
382 | no_rfb: |
||
383 | DEBUGF 1,'This is no vnc server!\n' |
||
384 | jmp close |
||
385 | |||
386 | invalid_security: |
||
387 | DEBUGF 1,'Security error: %s\n',receive_buffer+5 |
||
388 | jmp close |
||
389 | |||
390 | read_data: |
||
391 | eth.read_data [socket],receive_buffer,[datapointer],IM_END-receive_buffer |
||
392 | ret |
||
393 | |||
394 | ; DATA AREA |
||
395 | |||
396 | include_debug_strings ; ALWAYS present in data section |
||
397 | |||
398 | handshake db 'RFB 003.003',0x0a |
||
399 | shared db 0 |
||
400 | beep db 0x85,0x25,0x85,0x40,0 |
||
401 | |||
402 | pixel_format32 db 0 ; setPixelformat |
||
403 | rb 3 ; padding |
||
404 | .bpp db 32 ; bits per pixel |
||
405 | .depth db 32 ; depth |
||
406 | .big_endian db 0 ; big-endian flag |
||
407 | .true_color db 1 ; true-colour flag |
||
408 | .red_max db 0,255 ; red-max |
||
409 | .green_max db 0,255 ; green-max |
||
410 | .blue_max db 0,255 ; blue-max |
||
411 | .red_shif db 0 ; red-shift |
||
412 | .green_shift db 8 ; green-shift |
||
413 | .blue_shift db 16 ; blue-shift |
||
414 | rb 3 ; padding |
||
415 | |||
416 | pixel_format16 db 0 ; setPixelformat |
||
417 | rb 3 ; padding |
||
418 | .bpp db 16 ; bits per pixel |
||
419 | .depth db 16 ; depth |
||
420 | .big_endian db 0 ; big-endian flag |
||
421 | .true_color db 1 ; true-colour flag |
||
422 | .red_max db 0,32 ; red-max |
||
423 | .green_max db 0,32 ; green-max |
||
424 | .blue_max db 0,64 ; blue-max |
||
425 | .red_shif db 0 ; red-shift |
||
426 | .green_shift db 5 ; green-shift |
||
427 | .blue_shift db 10 ; blue-shift |
||
428 | rb 3 ; padding |
||
429 | |||
430 | pixel_format8 db 0 ; setPixelformat |
||
431 | rb 3 ; padding |
||
432 | .bpp db 8 ; bits per pixel |
||
433 | .depth db 8 ; depth |
||
434 | .big_endian db 0 ; big-endian flag |
||
435 | .true_color db 1 ; true-colour flag |
||
436 | .red_max db 0,7 ; red-max |
||
437 | .green_max db 0,7 ; green-max |
||
438 | .blue_max db 0,3 ; blue-max |
||
439 | .red_shif db 0 ; red-shift |
||
440 | .green_shift db 3 ; green-shift |
||
441 | .blue_shift db 6 ; blue-shift |
||
442 | rb 3 ; padding |
||
443 | |||
444 | encodings db 2 ; setEncodings |
||
445 | rb 1 ; padding |
||
446 | db 1,0 ; number of encodings |
||
447 | db 0,0,0,0 ; raw encoding (DWORD, Big endian order) |
||
448 | db 1,0,0,0 ; Copyrect encoding |
||
449 | |||
450 | fbur db 3 ; frame buffer update request |
||
451 | .inc db 0 ; incremental |
||
452 | .x dw 0 |
||
453 | .y dw 0 |
||
454 | .width dw 0 |
||
455 | .height dw 0 |
||
456 | |||
457 | keyevent db 4 ; keyevent |
||
458 | .down db 0 ; down-flag |
||
459 | dw 0 ; padding |
||
460 | .key dd 0 ; key |
||
461 | |||
462 | pointerevent db 5 ; pointerevent |
||
463 | .mask db 0 ; button-mask |
||
464 | .x dw 0 ; x-position |
||
465 | .y dw 0 ; y-position |
||
466 | |||
467 | I_END: |
||
468 | |||
469 | framebuffer: |
||
470 | .width dw ? |
||
471 | .height dw ? |
||
472 | pixelformat: |
||
473 | .bpp db ? |
||
474 | .depth db ? |
||
475 | .big_endian db ? |
||
476 | .true_color db ? |
||
477 | .red_max dw ? |
||
478 | .green_max dw ? |
||
479 | .blue_max dw ? |
||
480 | .red_shift db ? |
||
481 | .green_shift db ? |
||
482 | .blue_shift db ? |
||
483 | .padding rb 3 |
||
484 | name_length dd ? |
||
485 | name rb 256 |
||
486 | |||
487 | server_ip dd 0 |
||
488 | server_port dd 0 |
||
489 | socket dd 0 |
||
490 | datapointer dd 0 |
||
491 | |||
492 | frame: |
||
493 | .width dw 0 |
||
494 | .height dw 0 |
||
495 | .x dw 0 |
||
496 | .y dw 0 |
||
497 | |||
498 | screen: |
||
499 | .height dw 0 |
||
500 | .width dw 0 |
||
501 | |||
502 | dnsMsg: |
||
503 | receive_buffer rb 5*1024*1024 ; 5 mb buffer for received data (incoming frbupdate etc) |
||
504 | framebuffer_data rb 1024*768*3 ; framebuffer |
||
505 | |||
506 | IM_END: |
||
507 |