From ac28d0fed6de93138e83f162854b859271e8cc56 Mon Sep 17 00:00:00 2001 From: hidnplayr Date: Sat, 14 Apr 2012 18:22:38 +0000 Subject: [PATCH] Added old VNC client, converted to work with net branch. git-svn-id: svn://kolibrios.org@2613 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../branches/net/applications/vncc/logon.inc | 257 ++++++++++++++++ kernel/branches/net/applications/vncc/raw.inc | 153 ++++++++++ .../net/applications/vncc/structs.inc | 22 ++ .../branches/net/applications/vncc/thread.inc | 239 +++++++++++++++ .../branches/net/applications/vncc/vncc.asm | 283 ++++++++++++++++++ 5 files changed, 954 insertions(+) create mode 100644 kernel/branches/net/applications/vncc/logon.inc create mode 100644 kernel/branches/net/applications/vncc/raw.inc create mode 100644 kernel/branches/net/applications/vncc/structs.inc create mode 100644 kernel/branches/net/applications/vncc/thread.inc create mode 100644 kernel/branches/net/applications/vncc/vncc.asm diff --git a/kernel/branches/net/applications/vncc/logon.inc b/kernel/branches/net/applications/vncc/logon.inc new file mode 100644 index 0000000000..4e9c049cd7 --- /dev/null +++ b/kernel/branches/net/applications/vncc/logon.inc @@ -0,0 +1,257 @@ +red_logon: + call draw_window_logon ; at first, draw the window + +still_logon: ; main cycle of application begins here + mov eax,10 ; wait here for event + mcall + +checkevent_logon: ; Check what event was called _logon: this will be used to return from textbox focus + + dec eax ; redraw request ? + jz red_logon + dec eax ; key in buffer ? + jz key_logon + dec eax ; button in buffer ? + jz button_logon + + jmp still_logon + + key_logon: ; key event handler + mov al,2 ; eax was zero so will now be 2 + mcall ; just read it and ignore + + cmp ah,13 + jne still_logon ; return to main loop + + ret ; enter key was pressed => return to logon + + button_logon: ; eax was zero so will now be 17 + mov al,17 ; get id + mcall + + cmp ah,1 ; close ? + jz close_logon + cmp ah,2 ; logon ? + je connect_logon + cmp ah,5 ; first ? + jz dstbtn_logon + + srcbtn_logon: + mov dword[addr],first + jmp rk_logon + + dstbtn_logon: + mov dword[addr],second + + rk_logon: + mov edi,[addr] ; load the address of the string + xor al,al ; mov al,0 ; the symbol we will search for + mov ecx,STRLEN+1 ; length of the string (+1) + cld ; search forward + repne scasb ; do search now + inc ecx ; we've found a zero or ecx became 0 + mov eax,STRLEN+1 + sub eax,ecx ; eax = address of <0> character + mov [temp],eax ; position + + cmp dword[addr],dword second + jne @f + mov dword [passlen],eax + @@: + + call print_text_logon + + mov edi,[addr] ; address of string + add edi,[temp] ; cursor position + + .waitev_logon: + mov eax,10 ; wait for event + mcall + cmp eax,2 ; button presed ? + jne checkevent_logon ; a key is pressed or redraw is nessesary, goto checkevent + mcall ; eax = 2, read button + shr eax,8 + cmp eax,8 + jnz .nobs_logon ; BACKSPACE + cmp edi,[addr] + jz .waitev_logon + dec edi + mov byte[edi],0 + + cmp dword[addr],second + jne @f + dec [passlen] + @@: + + call print_text_logon + jmp .waitev_logon + .nobs_logon: + cmp eax,13 ; ENTER + je still_logon + cmp eax,192 + jne .noclear_logon + xor al,al + mov edi,[addr] + mov ecx,STRLEN + rep stosb + mov edi,[addr] + call print_text_logon + jmp .waitev_logon + + .noclear_logon: + mov [edi],al + + cmp dword[addr],second + jne @f + inc [passlen] + @@: + + call print_text_logon + + inc edi + mov esi,[addr] + add esi,STRLEN + cmp esi,edi + jnz .waitev_logon + + jmp still_logon + + +; print strings (source & destination) +print_text_logon: +pusha + + mov eax, 8 + mov ebx, 105*65536+200 + mov ecx, 31*65536+13 + mov edx, 4 + mov esi, 0xEBEBEB + mcall + + cmp byte[mode],0 + je @f + + mov ecx, 49*65536+12 + inc edx + mcall + + @@: + mov eax, 4 ; function 4 _logon: write text to window + mov ebx, 107*65536+34 ; [x start] *65536 + [y start] + xor ecx, ecx ; color of text RRGGBB + mov edx, first ; pointer to text beginning + mov esi, STRLEN ; text length + mcall + + cmp byte[mode],0 + je dont_draw_pass + + add ebx,16 + mov edi,[passlen] + + @@: + cmp edi,0 + jle dont_draw_pass + + dec edi + mov edx, passchar + mov esi, 1 + mcall + add ebx,6*65536 + jmp @r + + dont_draw_pass: + +popa + ret + +close_logon: + or eax,-1 + mcall + +connect_logon: + ret + +draw_window_logon: + + mcall 12, 1 ; start window draw + pusha + ; DRAW WINDOW + xor eax, eax ; function 0 _logon: define and draw window + mov ebx, 160*65536+330 ; [x start] *65536 + [x size] + mov ecx, 160*65536+100 ; [y start] *65536 + [y size] + mov edx, 0x13DDDDDD ; color of work area RRGGBB + mov edi, title ; WINDOW LABEL + mcall + + mov eax, 8 ; LOGON BUTTON + mov ebx, 220*65536+85 + mov ecx, 63*65536+16 + mov edx, 2 + mov esi, 0xCCCCCC + mcall + + + call print_text_logon + + cmp byte[mode], 0 + je servermode_ + + mov eax, 4 ; function 4 write text to window + mov ebx, 25*65536+33 ; [x start] *65536 + [y start] + xor ecx, ecx + mov edx, userstr ; pointer to text beginning + mov esi, passstr-userstr ; text length + mcall + + add bl,19 + mov edx, passstr ; pointer to text beginning + mov esi, connectstr-passstr ; text length + mcall + + jmp drawtherest_ + + servermode_: + + mov eax, 4 ; function 4 write text to window + mov ebx, 25*65536+33 ; [x start] *65536 + [y start] + xor ecx, ecx + mov edx, serverstr ; pointer to text beginning + mov esi, userstr-serverstr ; text length + mcall + + drawtherest_: + + mov ebx, 240*65536+67 ; [x start] *65536 + [y start] + mov edx, connectstr ; pointer to text beginning + mov esi, connect_e-connectstr ; text length + mcall + + popa + inc ebx + mcall + + ret + + +; DATA AREA +title db 'Kolibrios VNC client by HIDNPLAYR',0 + +first: db '192.168.1.5' + rb STRLEN +second: rb STRLEN + +passchar db '*' +passlen dd 0 + +addr dd 0 +temp dd 0 +mode db 0 ; 0 = connection details, 1 = authentication + +serverstr: db 'server:' +userstr: db 'username:' +passstr: db 'password:' +connectstr: db 'connect !' +connect_e: + +I_END_logon: diff --git a/kernel/branches/net/applications/vncc/raw.inc b/kernel/branches/net/applications/vncc/raw.inc new file mode 100644 index 0000000000..9ba6d6e0a8 --- /dev/null +++ b/kernel/branches/net/applications/vncc/raw.inc @@ -0,0 +1,153 @@ + encoding_raw: + DEBUGF 1,'RAW\n' + + mov ax,[frame.y] ; + mov bx,[screen.width] ; + mul bx ; + shl edx,16 ; + 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 ; [frame.width]*3 + + 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] ; + mul bx ; + shl edx,16 ; + mov dx,ax ; + mov ecx,edx ; + pop edx ; + add ecx,edx ; mov ecx,edx+([frame.height]-1)*[screen.width]*3 + pop ebx + + .pixelloop32: + cmp ebx,ecx + jge next_rectangle + +; 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 ; + ; + mov al,[esi] ; + shr al,2 ; + and al,3 ; + mul cl ; + mov [ebx],al ; + inc ebx ; + ; + mov al,[esi] ; + and al,3 ; + mul cl ; + mov byte[ebx],al ; + inc ebx ; + inc esi ; + pop ecx ; + + + cmp ebx,edx + jl .pixelloop32 + + push edx + push ebx + mov ax,[screen.width] + mov bx,3 + mul bx + shl edx,16 + mov dx,ax + mov eax,edx + pop ebx + pop edx + + add ebx,eax ; eax = [screen.width]*3 + add edx,eax + + push edx + push ebx + mov ax,[frame.width] + mov bx,3 + mul bx + shl edx,16 + mov dx,ax + mov eax,edx + pop ebx + pop edx + + sub ebx,eax ; eax = [frame.width]*3 + + jmp .pixelloop32 + + + diff --git a/kernel/branches/net/applications/vncc/structs.inc b/kernel/branches/net/applications/vncc/structs.inc new file mode 100644 index 0000000000..507bf6ca93 --- /dev/null +++ b/kernel/branches/net/applications/vncc/structs.inc @@ -0,0 +1,22 @@ + +struct pixel_format + 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 +ends + +struct framebuffer + width dw ? + height dw ? + pixelformat pixel_format + name_length dd ? + name rb 256 +ends \ No newline at end of file diff --git a/kernel/branches/net/applications/vncc/thread.inc b/kernel/branches/net/applications/vncc/thread.inc new file mode 100644 index 0000000000..7bb7e3d8c5 --- /dev/null +++ b/kernel/branches/net/applications/vncc/thread.inc @@ -0,0 +1,239 @@ + +thread_start: + + DEBUGF 1, 'I am the thread!\n' + + mcall 40, 1 shl 7 + +; resolve name + push esp ; reserve stack place + invoke getaddrinfo, first, 0, 0, esp + pop esi +; test for error + test eax, eax + jnz exit + + mov eax, [esi+addrinfo.ai_addr] + mov eax, [eax+sockaddr_in.sin_addr] + mov [sockaddr1.ip], eax + +; DEBUGF 1, 'Connecting to %u.%u.%u.%u:%u\n', \ +; [server_ip]:1, [server_ip+1]:1, \ +; [server_ip+2]:1, [server_ip+3]:1, \ +; [server_port]:2 + + mcall socket, AF_INET4, SOCK_STREAM, 0 + mov [socketnum], eax + mcall connect, [socketnum], sockaddr1, 18 + + call wait_for_data + + cmp dword [receive_buffer], 'RFB ' + jne no_rfb + DEBUGF 1, 'received: %s\n', receive_buffer + mcall send, [socketnum], handshake, 12, 0 + DEBUGF 1, 'Sending handshake: protocol version\n' + + call wait_for_data + + cmp dword [receive_buffer], 0x00000000 + je invalid_security + + cmp dword [receive_buffer], 0x01000000 + je no_security + + cmp dword [receive_buffer], 0x02000000 + je vnc_security + + jmp exit + +vnc_security: + mov byte[mode], 1 + call red_logon + +no_security: + mcall send, [socketnum], shared, 1, 0 + DEBUGF 1, 'Sending handshake: shared session?\n' + + mcall 23, 100*TIMEOUT + + call wait_for_data ; now the server should send init message + + DEBUGF 1, 'Serverinit: bpp: %u depth: %u bigendian: %u truecolor: %u\n', \ + [receive_buffer+framebuffer.pixelformat.bpp]:1, \ + [receive_buffer+framebuffer.pixelformat.depth]:1, \ + [receive_buffer+framebuffer.pixelformat.big_endian]:1, \ + [receive_buffer+framebuffer.pixelformat.true_color]:1 + + mov eax, dword [receive_buffer] + mov dword [fbur.width], eax + bswap eax + mov dword [screen], eax + + mcall send, [socketnum], pixel_format8, 20, 0 + 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 byte [thread_ready], 1 + +request_rfb: + mov [fbur.inc], 2 + mcall send, [socketnum], fbur, 10, 0 + +thread_loop: + mcall 23, 100 + + call read_data ; Read the data into the buffer + +; cmp eax, 2 +; jb 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 + +align 4 +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:',\ + [frame.width]:2, [frame.height]:2, [frame.x]:2, [frame.y]:2, 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 sent SetColourMapEntries message\n' + + jmp thread_loop + + +bell: + mcall 55, 55, , , beep + + jmp thread_loop + + +servercuttext: + + DEBUGF 1, 'Server cut text\n' + + jmp thread_loop + + +read_data: + + mov [datapointer], receive_buffer + .loop: + mcall 23, 100*TIMEOUT + mcall recv, [socketnum], [datapointer], 4096, 0 + cmp eax, -1 + je .done + + add [datapointer], eax + + cmp eax, 4096 + je .loop + + .done: + mov eax, [datapointer] + sub eax, receive_buffer + ret + + + +wait_for_data: + + mcall 23, 500 + mcall recv, [socketnum], receive_buffer, 4096, 0 + cmp eax, -1 + je wait_for_data + test eax, eax + jz wait_for_data + + ret + diff --git a/kernel/branches/net/applications/vncc/vncc.asm b/kernel/branches/net/applications/vncc/vncc.asm new file mode 100644 index 0000000000..f284df1c8e --- /dev/null +++ b/kernel/branches/net/applications/vncc/vncc.asm @@ -0,0 +1,283 @@ +; +; +; VNC Client for kolibrios by hidnplayr +; +; hidnplayr@gmail.com +; + +format binary as "" + +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_Path + +__DEBUG__ equ 1 +__DEBUG_LEVEL__ equ 1 + +STRLEN = 64 ; password and server max length +xpos = 4 ; coordinates of image +ypos = 22 ; + +TIMEOUT = 5 ; timeout in seconds + +include '../macros.inc' +include '../debug-fdo.inc' +include '../proc32.inc' +include '../dll.inc' +include '../struct.inc' +include '../network.inc' + +include 'structs.inc' +include 'logon.inc' +include 'raw.inc' +include 'thread.inc' + +START: + + mcall 68, 11 ; init heap + +; load libraries + stdcall dll.Load, @IMPORT + test eax, eax + jnz exit + + call red_logon + + mcall 40, 0 ; no events + mcall 67, 0, 0, 0, 0 ; resize the window (hide it) + mcall 51, 1, thread_start, thread_stack + + DEBUGF 1,'Thread created: %u\n', eax + + @@: + mcall 5, 10 + cmp byte [thread_ready], 0 + je @r + + mcall 40, 100111b ; mouse, button, key, redraw + + + mov edx, dword [screen] + movzx esi, dx + shr edx, 16 + add edx, 2*xpos + add esi, ypos+xpos + mcall 67, 10, 10 ; resize the window + +mainloop: + mcall 23, 50 ; wait for event, 0,5s timeout + + dec eax + jz redraw + + dec eax + jz key + + dec eax + jz button + + sub eax, 3 + jz mouse + + jmp mainloop + +key: + + DEBUGF 1,'Sending key event\n' + + mcall 2 + mov byte [keyevent.key+3], ah + + mcall send, [socketnum], keyevent, 8, 0 + jmp mainloop + +mouse: + + DEBUGF 1,'Sending mouse event\n' + + mcall 37, 1 ; get mouse pos + sub eax, xpos shl 16 + ypos + bswap eax + mov [pointerevent.x], ax + shr eax, 16 + mov [pointerevent.y], ax + + mcall 37, 2 ; get mouse buttons + 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 [pointerevent.mask],al + + mcall send, [socketnum], pointerevent, 6, 0 + jmp mainloop + +redraw: + + DEBUGF 1,'Drawing window\n' + + mcall 12, 1 + + mov ebx, dword[screen] + movzx ecx, bx + shr ebx, 16 + mov edx, 0x74ffffff + mov edi, name + mcall 0 ; draw window + + call drawbuffer + + mcall 12, 2 + + jmp mainloop + +drawbuffer: + + mcall 7, framebuffer_data, dword[screen], 0 + ret + + +button: + mcall 17 ; get id + +exit: + DEBUGF 1, 'Closing time!\n' + mcall close, [socketnum] + mcall -1 + +no_rfb: + DEBUGF 1, 'This is no vnc server!\n' + jmp exit + +invalid_security: + DEBUGF 1, 'Security error: %s\n', receive_buffer+5 + jmp exit + + +; DATA AREA + +include_debug_strings ; ALWAYS present in data section + +handshake db 'RFB 003.003', 10 +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 + + +sockaddr1: + dw AF_INET4 +.port dw 5900 +.ip dd 0 + rb 10 + +thread_ready db 0 +; import +align 4 +@IMPORT: + +library network, 'network.obj' +import network, \ + getaddrinfo, 'getaddrinfo', \ + freeaddrinfo, 'freeaddrinfo', \ + inet_ntoa, 'inet_ntoa' + +name db 'VNC client', 0 + +I_END: + +socketnum dd ? +datapointer dd ? + +frame: +.width dw ? +.height dw ? +.x dw ? +.y dw ? + +screen: +.height dw ? +.width dw ? + +receive_buffer rb 5*1024*1024 ; 5 mb buffer for received data (incoming frbupdate etc) +framebuffer_data rb 1024*768*3 ; framebuffer + + + rb 0x1000 +thread_stack: + + rb 0x1000 +IM_END: + +