/programs/network/VNCclient/vnc.asm |
---|
File deleted |
/programs/network/VNCclient/VNCclient.asm |
---|
0,0 → 1,336 |
; |
; |
; VNC Client for kolibrios by hidnplayr |
; |
; |
; WORK IN PROGRESS... |
; |
; FEEL FREE TO CONTRIBUTE ! |
; |
; hidnplayr@gmail.com |
; |
use32 |
org 0x0 |
db 'MENUET01' ; 8 byte id |
dd 0x01 ; header version |
dd START ; start of code |
dd I_END ; size of image |
dd IM_END ; memory for app |
dd IM_END ; esp |
dd 0x0 , 0x0 ; I_Param , I_Icon |
__DEBUG__ equ 1 |
__DEBUG_LEVEL__ equ 1 |
STRLEN = 64 ; password and server max length |
xpos = 4 ; coordinates of image |
ypos = 22 ; |
TIMEOUT = 60 ; timeout in seconds |
BUFFER = 1500 ; Buffer size for DNS |
include 'fdo.inc' |
include 'ETH.INC' |
include 'logon.inc' |
include 'raw.inc' |
include 'copyrect.inc' |
include 'thread.inc' |
START: ; start of execution |
call red_logon |
mov eax,40 ; Report events |
mov ebx,00000000b ; Only Stack |
int 0x40 |
mov eax,67 ; resize the window (hide it) |
xor ebx,ebx |
mov ecx,ebx |
mov edx,ebx |
mov esi,ebx |
int 0x40 |
mov eax,51 |
mov ebx,1 |
mov ecx,thread_start |
mov edx,thread_stack |
int 0x40 |
DEBUGF 1,'Thread created: %u\n',eax |
@@: |
mov eax,5 |
mov ebx,10 |
int 0x40 |
cmp byte[thread_ready],0 |
je @r |
mov eax,40 ; report events |
mov ebx,100111b ; mouse, button, key, redraw |
int 0x40 |
mov eax,67 ; resize the window |
mov ebx,10 |
mov ecx,10 |
mov edx,dword[framebuffer] |
bswap edx |
movzx esi,dx |
shr edx,16 |
add edx,2*xpos |
add esi,ypos+xpos |
int 0x40 |
mainloop: |
eth.socket_status [socket],eax |
cmp al,TCB_CLOSE_WAIT |
je close |
mov eax,23 ; wait for event with timeout |
mov ebx,50 ; 0,5 s |
int 0x40 |
cmp eax,1 |
je redraw |
cmp eax,2 ; key |
je key |
cmp eax,3 ; button |
je button |
cmp eax,6 ; mouse |
je mouse |
call drawbuffer |
jmp mainloop |
key: |
DEBUGF 1,'Sending key event\n' |
mov eax,2 |
int 0x40 |
mov byte[keyevent.key+3],ah |
eth.write_tcp [socket],8,keyevent |
jmp mainloop |
mouse: |
DEBUGF 1,'Sending mouse event\n' |
mov eax,37 |
mov ebx,1 |
int 0x40 |
sub eax,xpos*65536+ypos |
bswap eax |
mov word[pointerevent.x],ax |
shr eax,16 |
mov word[pointerevent.y],ax |
mov eax,37 |
mov ebx,2 |
int 0x40 |
test al,00000010b ; test if right button was pressed (bit 1 in kolibri) |
jz @f |
add al,00000010b ; in RFB protocol it is bit 2, so if we add bit 2 again, we'll get bit 3 and bit 1 will remain the same |
@@: |
mov byte[pointerevent.mask],al |
eth.write_tcp [socket],6,pointerevent |
jmp mainloop |
redraw: |
DEBUGF 1,'Drawing window\n' |
mov eax,12 |
mov ebx,1 |
int 0x40 |
mov eax,0 ; draw window |
mov ebx,dword[framebuffer] |
bswap ebx |
movzx ecx,bx |
shr ebx,16 |
add ebx,2*xpos |
add ecx,ypos+xpos |
mov edx,0x03ffffff |
mov esi,0x80555599 |
mov edi,0x00ffffff |
int 0x40 |
mov eax,4 ; label |
mov ebx,9*65536+8 |
mov ecx,0x10ffffff |
mov edx,name |
mov esi,[name_length] |
bswap esi |
int 0x40 |
call drawbuffer |
mov eax,12 |
mov ebx,2 |
int 0x40 |
jmp mainloop |
drawbuffer: |
mov eax,7 |
mov ebx,framebuffer_data |
mov ecx,dword[screen] |
mov edx,xpos*65536+ypos |
int 0x40 |
ret |
button: ; button |
mov eax,17 ; get id |
int 0x40 |
close: |
call read_data |
; eth.close_tcp [socket] ; We're done, close the socket ;;; BUG WHEN CLOSING SOCKET !! |
DEBUGF 1,'Socket closed\n' |
mov eax,-1 |
int 0x40 |
no_rfb: |
DEBUGF 1,'This is no vnc server!\n' |
jmp close |
invalid_security: |
DEBUGF 1,'Security error: %s\n',receive_buffer+5 |
jmp close |
; DATA AREA |
include_debug_strings ; ALWAYS present in data section |
handshake db 'RFB 003.003',0x0a |
shared db 0 |
beep db 0x85,0x25,0x85,0x40,0 |
pixel_format32 db 0 ; setPixelformat |
rb 3 ; padding |
.bpp db 32 ; bits per pixel |
.depth db 32 ; depth |
.big_endian db 0 ; big-endian flag |
.true_color db 1 ; true-colour flag |
.red_max db 0,255 ; red-max |
.green_max db 0,255 ; green-max |
.blue_max db 0,255 ; blue-max |
.red_shif db 0 ; red-shift |
.green_shift db 8 ; green-shift |
.blue_shift db 16 ; blue-shift |
rb 3 ; padding |
pixel_format16 db 0 ; setPixelformat |
rb 3 ; padding |
.bpp db 16 ; bits per pixel |
.depth db 15 ; depth |
.big_endian db 0 ; big-endian flag |
.true_color db 1 ; true-colour flag |
.red_max db 0,31 ; red-max |
.green_max db 0,31 ; green-max |
.blue_max db 0,31 ; blue-max |
.red_shif db 0 ; red-shift |
.green_shift db 5 ; green-shift |
.blue_shift db 10 ; blue-shift |
rb 3 ; padding |
pixel_format8 db 0 ; setPixelformat |
rb 3 ; padding |
.bpp db 8 ; bits per pixel |
.depth db 6 ; depth |
.big_endian db 0 ; big-endian flag |
.true_color db 1 ; true-colour flag |
.red_max db 0,3 ; red-max |
.green_max db 0,3 ; green-max |
.blue_max db 0,3 ; blue-max |
.red_shif db 0 ; red-shift |
.green_shift db 2 ; green-shift |
.blue_shift db 4 ; blue-shift |
rb 3 ; padding |
encodings db 2 ; setEncodings |
rb 1 ; padding |
db 1,0 ; number of encodings |
db 0,0,0,0 ; raw encoding (DWORD, Big endian order) |
db 1,0,0,0 ; Copyrect encoding |
fbur db 3 ; frame buffer update request |
.inc db 0 ; incremental |
.x dw 0 |
.y dw 0 |
.width dw 0 |
.height dw 0 |
keyevent db 4 ; keyevent |
.down db 0 ; down-flag |
dw 0 ; padding |
.key dd 0 ; key |
pointerevent db 5 ; pointerevent |
.mask db 0 ; button-mask |
.x dw 0 ; x-position |
.y dw 0 ; y-position |
I_END: |
framebuffer: |
.width dw ? |
.height dw ? |
pixelformat: |
.bpp db ? |
.depth db ? |
.big_endian db ? |
.true_color db ? |
.red_max dw ? |
.green_max dw ? |
.blue_max dw ? |
.red_shift db ? |
.green_shift db ? |
.blue_shift db ? |
.padding rb 3 |
name_length dd ? |
name rb 256 |
server_ip dd 0 |
server_port dd 0 |
socket dd 0 |
datapointer dd 0 |
frame: |
.width dw 0 |
.height dw 0 |
.x dw 0 |
.y dw 0 |
screen: |
.height dw 0 |
.width dw 0 |
thread_ready db 0 |
dnsMsg: |
receive_buffer rb 5*1024*1024 ; 5 mb buffer for received data (incoming frbupdate etc) |
framebuffer_data rb 1024*768*3 ; framebuffer |
thread_stack rb 0x1000 |
IM_END: |
/programs/network/VNCclient/raw.inc |
---|
1,40 → 1,33 |
encoding_raw: |
DEBUGF 1,'FRAME: RAW\n' |
DEBUGF 1,'RAW\n' |
mov ax,[screen.width] ; |
mov bx,[frame.y] ; |
mov ax,[frame.y] ; |
mov bx,[screen.width] ; |
mul bx ; |
DEBUGF 1,'screen.width*frame.y=%u\n',ax |
mov bx,3 ; |
mul bx ; |
shl edx,16 ; |
mov dx,ax ; |
mov ebx,edx ; mov ebx,[screen.width]*[frame.y]*3 |
push ebx |
DEBUGF 1,'screen.width*frame.y*3=%u\n',edx |
mov ax,[frame.x] ; |
mov bx,3 ; |
mul bx ; |
shl edx,16 ; |
mov dx,ax ; |
pop ebx |
add ebx,edx ; add ebx,[frame.x]*3 |
add ebx,framebuffer_data ; add ebx,framebuffer_data |
push ebx |
DEBUGF 1,'frame.x*3=%u\n',edx |
mov dx,ax ; [screen.width]*[frame.y] |
movzx eax,[frame.x] |
add edx,eax ; [screen.width]*[frame.y]+[frame.x] |
mov eax,3 ; |
mul edx ; ([screen.width]*[frame.y]+[frame.x])*3 |
add eax,framebuffer_data ; |
push eax ; framebuffer_data+([screen.width]*[frame.y]+[frame.x])*3 |
mov ax,[frame.width] ; |
mov bx,3 ; |
mul bx ; |
shl edx,16 ; |
mov dx,ax ; |
DEBUGF 1,'frame.width*3=%u\n',edx |
pop ebx |
add edx,ebx ; mov edx,ebx+[frame.width]*3 |
mov dx,ax ; [frame.width]*3 |
push ebx |
pop eax ; |
add edx,eax ; framebuffer_data+([screen.width]*[frame.y]+[frame.x])*3+[frame.width]*3 |
push eax ; |
push edx ; |
mov ax,[frame.height] ; |
dec ax ; |
mov bx,3 ; |
mul bx ; |
mov bx,[screen.width] ; |
43,72 → 36,87 |
mov dx,ax ; |
mov ecx,edx ; |
pop edx ; |
DEBUGF 1,'frame.height*screen.width*3=%u\n',ecx |
add ecx,edx ; mov ecx,edx+[frame.height]*[screen.width]*3 |
add ecx,edx ; mov ecx,edx+([frame.height]-1)*[screen.width]*3 |
pop ebx |
DEBUGF 1,'FRAME: framebuffer:%u ebx:%u ecx:%u edx:%u\n',framebuffer_data,ebx,ecx,edx |
.pixelloop32: |
cmp ebx,ecx |
jge next_rectangle |
add esi,2 ; 32 bit code RAW |
; add esi,2 ; 32 bit code RAW - OK |
; mov al,[esi] ; |
; mov [ebx],al ; |
; inc ebx ; |
; dec esi ; |
; ; |
; mov al,[esi] ; |
; mov [ebx],al ; |
; inc ebx ; |
; dec esi ; |
; ; |
; mov al,[esi] ; |
; mov [ebx],al ; |
; inc ebx ; |
; add esi,4 ; |
; push ecx ; 16 bit code RAW |
; mov cl,51 |
; |
; mov ax,[esi] ; |
; xchg al,ah |
; and al,00011111b ; |
; xchg al,ah |
; mul cl |
; mov [ebx],al ; |
; inc ebx ; |
; |
; mov ax,[esi] ; |
; xchg al,ah |
; shr ax,5 ; |
; xchg al,ah |
; and al,00011111b ; |
; mul cl |
; mov [ebx],al ; |
; inc ebx ; |
; |
; mov ax,[esi] ; |
; xchg al,ah |
; shr ax,10 ; |
; and al,00011111b ; |
; mul cl |
; mov [ebx],al ; |
; inc ebx ; |
; |
; inc esi ; |
; inc esi ; |
; pop ecx |
push ecx ; 8 bit code RAW - OK |
mov cl,85 ; |
; |
mov al,[esi] ; |
shr al,4 ; |
and al,3 ; |
mul cl ; |
mov [ebx],al ; |
inc ebx ; |
dec esi ; |
; |
mov al,[esi] ; |
shr al,2 ; |
and al,3 ; |
mul cl ; |
mov [ebx],al ; |
inc ebx ; |
dec esi ; |
; |
mov al,[esi] ; |
mov [ebx],al ; |
and al,3 ; |
mul cl ; |
mov byte[ebx],al ; |
inc ebx ; |
add esi,4 ; |
inc esi ; |
pop ecx ; |
; mov ax,[esi] ; 16 bit code RAW |
; and ax,32 |
; mov [ebx],al |
; inc ebx |
; |
; mov ax,[esi] |
; shr ax,5 |
; and ax,32 |
; mov [ebx],al |
; inc ebx |
; |
; mov ax,[esi] |
; shr ax,10 |
; and ax,64 |
; mov [ebx],al |
; inc ebx |
; inc esi |
; inc esi |
; mov al,[esi] ; 8 bit code RAW |
; and al,7 ; |
; mov byte[ebx],0xff;al ; |
; inc ebx ; |
; ; |
; mov al,[esi] ; |
; shr al,3 ; |
; and al,7 ; |
; mov [ebx],al ; |
; inc ebx ; |
; ; |
; mov al,[esi] ; |
; shr al,6 ; |
; and al,3 ; |
; mov [ebx],al ; |
; inc ebx ; |
; ; |
; inc esi ; |
cmp ebx,edx |
jl .pixelloop32 |
/programs/network/VNCclient/thread.inc |
---|
0,0 → 1,188 |
thread_start: |
DEBUGF 1,'I am the thread!\n' |
mov eax,40 ; Report events |
mov ebx,10000000b ; Only Stack |
int 0x40 |
resolve first,[server_ip] ; the input window putted the server @ 'first', resolve it into a real ip |
mov [server_port],5900 ; no port input for now, only standard port 5900 |
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] |
eth.search_port 1000,edx ; Find a free port starting from 1001 and store in edx |
eth.open_tcp edx,[server_port],[server_ip],1,[socket] ; open socket |
DEBUGF 1,'Socket opened: %u (port %u)\n',[socket],ecx |
call read_data |
cmp dword[receive_buffer+1],'RFB ' |
jne no_rfb |
eth.write_tcp [socket],12,handshake |
DEBUGF 1,'Sending handshake: protocol version\n' |
call read_data |
mov eax,receive_buffer+1 |
mov eax,[eax] |
bswap eax |
cmp eax,0 |
je invalid_security |
cmp eax,1 |
je no_security |
cmp eax,2 |
je vnc_security |
jmp close |
vnc_security: |
mov byte[mode],1 |
call red_logon |
no_security: |
eth.write_tcp [socket],1,shared |
DEBUGF 1,'Sending handshake: shared session?\n' |
eth.wait_for_data [socket],TIMEOUT*10,close |
eth.read_data [socket],framebuffer,[datapointer],IM_END-receive_buffer ; now the server should send init message |
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] |
mov eax,dword[framebuffer] |
bswap eax |
mov dword[screen],eax |
eth.write_tcp [socket],20,pixel_format8 |
DEBUGF 1,'Sending pixel format\n' |
call read_data |
; eth.write_tcp [socket],8,encodings |
; DEBUGF 1,'Sending encoding info\n' |
; call read_data |
mov eax,dword[framebuffer.width] |
mov dword[fbur.width],eax |
mov byte[thread_ready],1 |
request_rfb: |
mov byte[fbur.inc],2 ;;;;;;;; |
eth.write_tcp [socket],10,fbur ;;;;;;;;; |
thread_loop: |
eth.wait_for_data [socket],1000,thread_loop |
call read_data ; Read the data into the buffer |
mov eax,[datapointer] ; at least 2 bytes should be received |
sub eax,receive_buffer |
cmp eax,1 |
jle mainloop |
DEBUGF 1,'Data received, %u bytes\n',eax |
cmp byte[receive_buffer],0 |
je framebufferupdate |
cmp byte[receive_buffer],1 |
je setcolourmapentries |
cmp byte[receive_buffer],2 |
je bell |
cmp byte[receive_buffer],3 |
je servercuttext |
jmp thread_loop |
framebufferupdate: |
mov ax,word[receive_buffer+2] |
xchg al,ah |
mov di,ax |
DEBUGF 1,'Framebufferupdate: %u frames\n',di |
mov esi,receive_buffer+4 |
jmp rectangle_loop |
next_rectangle: |
call drawbuffer |
dec di |
test di,di |
jz request_rfb |
rectangle_loop: |
mov edx,[esi] |
bswap edx |
mov ebx,edx |
shr edx,16 |
mov [frame.x],dx |
mov [frame.y],bx |
add esi,4 |
mov ecx,[esi] |
bswap ecx |
mov eax,ecx |
shr ecx,16 |
mov [frame.width],cx |
mov [frame.height],ax |
add esi,4 |
mov eax,[esi] |
add esi,4 |
mov ebx,esi |
sub ebx,receive_buffer+12 |
DEBUGF 1,'frame: width=%u height=%u x=%u y=%u offset:%u encoding:',2[frame.width],2[frame.height],2[frame.x],2[frame.y],ebx |
cmp eax,0 |
je encoding_raw |
cmp eax,1 |
je encoding_copyrect |
cmp eax,2 |
je encoding_RRE |
cmp eax,5 |
je encoding_hextile |
cmp eax,16 |
je encoding_ZRLE |
mov ebx,esi |
sub ebx,receive_buffer+8 |
DEBUGF 1,'\nunknown encoding: %u (offset %u)\n',eax,ebx |
jmp bell |
jmp thread_loop |
encoding_RRE: |
DEBUGF 1,'RRE\n' |
jmp next_rectangle |
encoding_hextile: |
DEBUGF 1,'hextile\n' |
jmp next_rectangle |
encoding_ZRLE: |
DEBUGF 1,'ZRLE\n' |
jmp next_rectangle |
setcolourmapentries: |
DEBUGF 1,'Server sended SetColourMapEntries message\n' |
jmp thread_loop |
bell: |
mov eax,55 |
mov ebx,eax |
mov esi,beep |
int 0x40 |
jmp thread_loop |
servercuttext: |
DEBUGF 1,'Server cut text\n' |
jmp thread_loop |
read_data: |
eth.read_data [socket],receive_buffer,[datapointer],IM_END-receive_buffer |
ret |