/programs/network/VNCclient/ETH.INC |
---|
0,0 → 1,671 |
; |
; ETH.INC |
; |
; made by hidnplayr (hidnplayr@gmail.com) for KolibriOS |
; |
; The given code before every macro is only a simple example |
; |
; |
; HISTORY |
; |
; v1.0: 18 august 2006 original release |
; v1.1: december 2006 bugfixes and improvements |
; |
macro mov arg1,arg2 { |
if arg1 eq arg2 |
else |
mov arg1,arg2 |
end if |
} |
TCB_LISTEN = 1 |
TCB_SYN_SENT = 2 |
TCB_SYN_RECEIVED = 3 |
TCB_ESTABLISHED = 4 |
TCB_FIN_WAIT_1 = 5 |
TCB_FIN_WAIT_2 = 6 |
TCB_CLOSE_WAIT = 7 |
TCB_CLOSING = 8 |
TCB_LAST_ASK = 9 |
TCB_TIME_WAIT = 10 |
TCB_CLOSED = 11 |
PASSIVE = 0 |
ACTIVE = 1 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
; eth.get_IP eax |
; |
; gets the current IP that is defined in Stack (return in eax in this example) |
macro eth.get_IP IP { |
mov ebx,1 |
mov eax,52 |
int 0x40 |
mov IP ,eax |
} |
; eth.get_GATEWAY eax |
; |
; gets the current GATEWAY that is defined in Stack (return in eax in this example) |
macro eth.get_GATEWAY GATEWAY { |
mov ebx,9 |
mov eax,52 |
int 0x40 |
move GATEWAY ,eax |
} |
; eth.get_SUBNET eax |
; |
; gets the current SUBNET that is defined in Stack (return in eax in this example) |
macro eth.get_SUBNET SUBNET { |
mov ebx,10 |
mov eax,52 |
int 0x40 |
mov SUBNET ,eax |
} |
; eth.get_DNS eax |
; |
; gets the current DNS that is defined in Stack (return in eax in this example) |
macro eth.get_DNS DNS { |
mov ebx,13 |
mov eax,52 |
int 0x40 |
mov DNS ,eax |
} |
; eth.set_IP eax |
; |
; set a new IP in stack (input in eax in this example) |
macro eth.set_IP IP { |
mov ecx,IP |
mov ebx,3 |
mov eax,52 |
int 0x40 |
} |
; eth.set_GATEWAY eax |
; |
; set a new GATEWAY in stack (input in eax in this example) |
macro eth.set_GATEWAY GATEWAY { |
mov ecx,GATEWAY |
mov ebx,11 |
mov eax,52 |
int 0x40 |
} |
; eth.set_SUBNET eax |
; |
; set a new SUBNET in stack (input in eax in this example) |
macro eth.set_SUBNET SUBNET { |
mov ecx,SUBNET |
mov ebx,12 |
mov eax,52 |
int 0x40 |
} |
; eth.set_DNS eax |
; |
; set a new DNS in stack (input in eax in this example) |
macro eth.set_DNS DNS { |
mov ecx,DNS |
mov ebx,14 |
mov eax,52 |
int 0x40 |
} |
; eth.open eax,80,ebx,[socket] |
; |
; open a socket on local port in eax to port 80 on server on ebx |
; the socketnumber will be returned in [socket] (dword) |
macro eth.open_udp local,remote,ip,socket { |
mov ecx, local |
mov edx, remote |
mov esi, ip |
mov ebx, 0 |
mov eax, 53 |
int 0x40 |
mov socket,eax |
} |
; eth.close [socket] |
; |
; closes socket on socketnumber [socket] |
macro eth.close_udp socket { |
mov ecx, socket |
mov ebx, 1 |
mov eax, 53 |
int 0x40 |
} |
; eth.poll [socket],eax |
; |
; polls [socket] for data |
; eax = 0 when there is data |
macro eth.poll socket { |
mov ecx, socket |
mov ebx, 2 |
mov eax, 53 |
int 0x40 |
} |
; eth.read_byte [socket], bl |
; |
; reads a byte from the socket and returns in bl |
macro eth.read_byte socket, result { |
mov ecx, socket |
mov ebx, 3 |
mov eax, 53 |
int 0x40 |
mov result,bl |
} |
; eth.read_byte [socket], bl |
; |
; reads a byte from the socket and returns in bl |
macro eth.read_packet socket, result { |
mov edx, result |
mov ecx, socket |
mov ebx, 10 |
mov eax, 53 |
int 0x40 |
} |
; eth.write [socket],12,msg |
; msg db 'hello world!' |
; |
; send message msg to socket |
macro eth.write_udp socket,length,msg,verify { |
mov ecx, socket |
mov edx, length |
mov esi, msg |
mov ebx, 4 |
mov eax, 53 |
int 0x40 |
if verify eq 1 |
call verifysend |
end if |
} |
verifysend: |
test eax,eax |
jnz @f |
ret |
@@: |
pusha |
mov eax,5 |
mov ebx,100 |
int 0x40 |
popa |
int 0x40 |
ret |
; eth.open_tcp 80,80,eax,0,[socket] |
; |
; opens a tcp socket on port 80 to port 80 on IP eax with passive open |
; returns socket number in eax |
macro eth.open_tcp local,remote,ip,passive,socket { |
mov ecx, local |
mov edx, remote |
mov esi, ip |
mov edi, passive ; 0 = PASSIVE open |
mov ebx, 5 |
mov eax, 53 |
int 0x40 |
mov socket,eax |
} |
; eth.socket_status [socket],eax |
; |
; returns socket status in eax |
macro eth.socket_status socket,result { |
mov ecx, socket |
mov ebx, 6 |
mov eax, 53 |
int 0x40 |
mov result,eax |
} |
; eth.write_tcp [socket],12,msg |
; |
; msg db 'hello world!' |
; |
; send message to TCP socket |
macro eth.write_tcp socket,length,msg,verify { |
mov ecx, socket |
mov edx, length |
mov esi, msg |
mov ebx, 7 |
mov eax, 53 |
int 0x40 |
if verify eq 1 |
call verifysend |
end if |
} |
; eth.close_tcp [socket] |
; |
; closes tcp socket [socket] |
macro eth.close_tcp socket { |
mov ecx, socket |
mov ebx, 8 |
mov eax, 53 |
int 0x40 |
} |
; eth.check_port 165,eax |
; |
; checks if port 165 is used |
; return is 0 when port is free |
macro eth.check_port port,result { |
mov ecx, port |
mov ebx, 9 |
mov eax, 53 |
int 0x40 |
mov result,eax |
} |
; eth.status eax |
; |
; returns socket status in eax |
macro eth.status status { |
mov ebx, 255 |
mov ecx, 6 |
mov eax, 53 |
int 0x40 |
mov status,eax |
} |
; eth.search 165,edx |
; |
; searches a free local port starting from 166 (165 + 1 !) |
; returns in edx |
macro eth.search_port port,result { |
mov edx,port |
@@: |
inc edx |
eth.check_port edx,eax |
cmp eax,0 |
je @r |
mov result,edx |
} |
; eth.read_data [socket],buffer,512 |
; buffer rb 512 |
; socket dd ? |
; |
; reads data from socket into a buffer, stops when there is no more data or buffer is full. |
macro eth.read_data socket,dest,endptr,bufferl { |
local .getdata,.loop,.end |
mov eax, dest |
mov endptr, eax |
; we have data - this will be the response |
.getdata: |
mov eax,endptr |
cmp eax,bufferl |
jg .end |
eth.read_byte socket,bl |
; Store the data in the response buffer |
mov eax, endptr |
mov [eax], bl |
inc dword endptr |
eth.poll socket |
cmp eax,0 |
jne .getdata ; yes, so get it |
; now we are going to wait 30 times 10 ms (300ms) |
mov edx,0 |
.loop: |
mov eax,5 |
mov ebx,1 |
int 0x40 |
eth.poll socket |
cmp eax, 0 |
jne .getdata ; yes, so get it |
inc edx |
cmp edx,100 |
jl .loop |
.end: |
} |
; eth.wait_for_data [socket],60,abort |
; eth.read_data .... |
; abort: |
; |
; Waits for data with timeout |
macro eth.wait_for_data socket,TIMEOUT,abort { |
mov edx,TIMEOUT |
@@: |
eth.poll socket |
cmp eax,0 |
jne @f |
dec edx |
jz abort |
mov eax,5 ; wait here for event |
mov ebx,10 |
int 0x40 |
jmp @r |
@@: |
} |
; The function 'resolve' resolves the address in edx and puts the resulting IP in eax. |
; When the input is an IP-adress, the function will output this IP in eax. |
; If something goes wrong, the result in eax should be 0 |
; |
; example: |
; |
; resolve query1,IP,PORT |
; resolve '192.168.0.1',IP,PORT |
; resolve query2,IP,PORT |
; |
; query1 db 'www.google.com',0 |
; query2 db '49.78.84.45',0 |
; IP dd ? |
; PORT dd ? |
macro resolve query,result { |
if query eqtype 0 |
mov edx,query |
else |
local ..string, ..label |
jmp ..label |
..string db query,0 |
..label: |
mov edx,..string |
end if |
call __resolve |
mov result,eax |
} |
if used __resolve |
__resolve: |
if __DEBUG__ eq 1 |
DEBUGF 1,'Resolving started\n' |
end if |
; This code validates if the query is an IP containing 4 numbers and 3 dots |
push edx ; push edx (query address) onto stack |
xor al, al ; make al (dot count) zero |
@@: |
cmp byte[edx],'0' ; check if this byte is a number, if not jump to no_IP |
jl no_IP ; |
cmp byte[edx],'9' ; |
jg no_IP ; |
inc edx ; the byte was a number, so lets check the next byte |
cmp byte[edx],0 ; is this byte zero? (have we reached end of query?) |
jz @f ; jump to next @@ then |
cmp byte[edx],':' |
jz @f |
cmp byte[edx],'.' ; is this byte a dot? |
jne @r ; if not, jump to previous @@ |
inc al ; the byte was a dot so increment al(dot count) |
inc edx ; next byte |
jmp @r ; lets check for numbers again (jump to previous @@) |
@@: ; we reach this when end of query reached |
cmp al,3 ; check if there where 3 dots |
jnz no_IP ; if not, jump to no_IP (this is where the DNS will take over) |
; The following code will convert this IP into a dword and output it in eax |
; If there is also a port number specified, this will be returned in ebx, otherwise ebx is -1 |
pop esi ; edx (query address) was pushed onto stack and is now popped in esi |
xor edx, edx ; result |
xor eax, eax ; current character |
xor ebx, ebx ; current byte |
.outer_loop: |
shl edx, 8 |
add edx, ebx |
xor ebx, ebx |
.inner_loop: |
lodsb |
test eax, eax |
jz .finish |
cmp al, '.' |
jz .outer_loop |
sub eax, '0' |
imul ebx, 10 |
add ebx, eax |
jmp .inner_loop |
.finish: |
shl edx, 8 |
add edx, ebx |
bswap edx ; we want little endian order |
mov eax, edx |
ret |
no_IP: |
pop edx |
; The query is not an IP address, we will send the query to a DNS server and hope for answer ;) |
if __DEBUG__ eq 1 |
DEBUGF 1,'The query is no ip, Building request string from:%u\n',edx |
end if |
; Build the request string |
mov eax, 0x00010100 |
mov [dnsMsg], eax |
mov eax, 0x00000100 |
mov [dnsMsg+4], eax |
mov eax, 0x00000000 |
mov [dnsMsg+8], eax |
; domain name goes in at dnsMsg+12 |
mov esi, dnsMsg + 12 ; location of label length |
mov edi, dnsMsg + 13 ; label start |
mov ecx, 12 ; total string length so far |
td002: |
mov [esi], byte 0 |
inc ecx |
td0021: |
mov al, [edx] |
cmp al, 0 |
je td001 ; we have finished the string translation |
cmp al, '.' |
je td004 ; we have finished the label |
inc byte [esi] |
inc ecx |
mov [edi], al |
inc edi |
inc edx |
jmp td0021 |
td004: |
mov esi, edi |
inc edi |
inc edx |
jmp td002 |
; write label len + label text |
td001: |
mov [edi], byte 0 |
inc ecx |
inc edi |
mov [edi], dword 0x01000100 |
add ecx, 4 |
mov [dnsMsgLen], ecx ; We'll need the length of the message when we send it |
; Now, lets send this and wait for an answer |
eth.search_port 1024,edx ; Find a free port starting from 1025 and store in edx |
eth.get_DNS esi ; Read DNS IP from stack into esi |
eth.open_udp edx,53,esi,[socketNum] ; First, open socket |
if __DEBUG__ eq 1 |
DEBUGF 1,'Socket opened: %u (port %u)\n',[socketNum],ecx |
end if |
eth.write_udp [socketNum],[dnsMsgLen],dnsMsg ; Write to socket ( request DNS lookup ) |
if __DEBUG__ eq 1 |
DEBUGF 1,'Data written, length:%u offset:%u\n',[dnsMsgLen],dnsMsg |
DEBUGF 1,'Waiting for data: (timeout is %us)\n',TIMEOUT |
end if |
eth.wait_for_data [socketNum],TIMEOUT,abort ; Now, we wait for data from remote |
eth.read_data [socketNum],dnsMsg,[dnsMsgLen],dnsMsg+BUFFER ; Read the data into the buffer |
if __DEBUG__ eq 1 |
DEBUGF 1,'Data received, offset:%u buffer size:%u length:%u\n',dnsMsg,BUFFER,esi-dnsMsg |
end if |
eth.close_udp [socketNum] ; We're done, close the socket |
if __DEBUG__ eq 1 |
DEBUGF 1,'Closed Socket\n' |
end if |
; Now parse the message to get the host IP. Man, this is complicated. It's described in RFC 1035 |
; 1) Validate that we have an answer with > 0 responses |
; 2) Find the answer record with TYPE 0001 ( host IP ) |
; 3) Finally, copy the IP address to the display |
; Note: The response is in dnsMsg, the end of the buffer is pointed to by [dnsMsgLen] |
mov esi, dnsMsg |
mov al, [esi+2] ; Is this a response to my question? |
and al, 0x80 |
cmp al, 0x80 |
jne abort |
if __DEBUG__ eq 1 |
DEBUGF 1,'It was a response to my question\n' |
end if |
mov al, [esi+3] ; Were there any errors? |
and al, 0x0F |
cmp al, 0x00 |
jne abort |
if __DEBUG__ eq 1 |
DEBUGF 1,'There were no errors\n' |
end if |
mov ax, [esi+6] ; Is there ( at least 1 ) answer? |
cmp ax, 0x00 |
je abort |
; Header validated. Scan through and get my answer |
add esi, 12 ; Skip to the question field |
call skipName ; Skip through the question field |
add esi, 4 ; skip past the questions qtype, qclass |
ctr002z: |
; Now at the answer. There may be several answers, find the right one ( TYPE = 0x0001 ) |
call skipName |
mov ax, [esi] |
cmp ax, 0x0100 ; Is this the IP address answer? |
jne ctr002c |
add esi, 10 ; Yes! Point eax to the first byte of the IP address |
mov eax,[esi] |
ret |
ctr002c: ; Skip through the answer, move to the next |
add esi, 8 |
movzx eax, byte [esi+1] |
mov ah, [esi] |
add esi, eax |
add esi, 2 |
cmp esi, [dnsMsgLen] ; Have we reached the end of the msg? This is an error condition, should not happen |
jl ctr002z ; Check next answer |
abort: |
if __DEBUG__ eq 1 |
DEBUGF 1,'Something went wrong, aborting\n' |
end if |
xor eax,eax |
ret |
skipName: |
; Increment esi to the first byte past the name field |
; Names may use compressed labels. Normally do. |
; RFC 1035 page 30 gives details |
mov al, [esi] |
cmp al, 0 |
je sn_exit |
and al, 0xc0 |
cmp al, 0xc0 |
je sn001 |
movzx eax, byte [esi] |
inc eax |
add esi, eax |
jmp skipName |
sn001: |
add esi, 2 ; A pointer is always at the end |
ret |
sn_exit: |
inc esi |
ret |
dnsMsgLen: dd 0 |
socketNum: dd 0xFFFF |
if ~defined dnsMsg |
dnsMsg: rb BUFFER |
end if |
end if |
/programs/network/VNCclient/copyrect.inc |
---|
0,0 → 1,5 |
encoding_copyrect: |
DEBUGF 1,'FRAME: copyrect\n' |
jmp next_rectangle |
/programs/network/VNCclient/fdo.inc |
---|
0,0 → 1,343 |
; |
; Formatted Debug Output (FDO) |
; Copyright (c) 2005-2006, mike.dld |
; Created: 2005-01-29, Changed: 2006-07-20 |
; |
; For questions and bug reports, mail to mike.dld@gmail.com |
; |
; Available format specifiers are: %s, %d, %u, %x (with partial width support) |
; |
; to be defined: |
; __DEBUG__ equ 1 |
; __DEBUG_LEVEL__ equ 5 |
macro debug_func name { |
if used name |
name@of@func equ name |
} |
macro debug_beginf { |
align 4 |
name@of@func: |
} |
debug_endf fix end if |
macro DEBUGS _sign,[_str] { |
common |
pushf |
pushad |
local ..str,..label,is_str |
is_str = 0 |
forward |
if _str eqtype '' |
is_str = 1 |
end if |
common |
if is_str = 1 |
jmp ..label |
..str db _str,0 |
..label: |
add esp,4*8+4 |
mov edx,..str |
sub esp,4*8+4 |
call fdo_debug_outstr |
else |
mov edx,_str |
call fdo_debug_outstr |
end if |
popad |
popf |
} |
macro DEBUGD _sign,_dec { |
pushf |
pushad |
if _dec eqtype eax |
if _dec in <ebx,ecx,edx,esi,edi,ebp,esp> |
mov eax,_dec |
else if ~_dec eq eax |
if _sign = 1 |
movsx eax,_dec |
else |
movzx eax,_dec |
end if |
end if |
else if _dec eqtype 0 |
mov eax,_dec |
else |
add esp,4*8+4 |
local tp |
tp equ 0 |
match _num[_arg],_dec \{ |
if _num = 1 |
if _sign = 1 |
movsx eax,byte[_arg] |
else |
movzx eax,byte[_arg] |
end if |
else if _num = 2 |
if _sign = 1 |
movsx eax,word[_arg] |
else |
movzx eax,word[_arg] |
end if |
else |
mov eax,dword[_arg] |
end if |
tp equ 1 |
\} |
match =0 [_arg],tp _dec \{ |
mov eax,dword[_arg] |
\} |
sub esp,4*8+4 |
end if |
mov cl,_sign |
call fdo_debug_outdec |
popad |
popf |
} |
macro DEBUGH _sign,_hex { |
pushf |
pushad |
if _hex eqtype eax |
if _hex in <eax,ebx,ecx,edx,esi,edi,ebp,esp> |
if ~_hex eq eax |
mov eax,_hex |
end if |
mov edx,8 |
else if _hex in <ax,bx,cx,dx,si,di,bp,sp> |
if ~_hex eq ax |
movzx eax,_hex |
end if |
shl eax,16 |
mov edx,4 |
else if _hex in <al,ah,bl,bh,cl,ch,dl,dh> |
if ~_hex eq al |
movzx eax,_hex |
end if |
shl eax,24 |
mov edx,2 |
end if |
else if _hex eqtype 0 |
mov eax,_hex |
mov edx,8 |
else |
add esp,4*8+4 |
local tp |
tp equ 0 |
match _num[_arg],_hex \{ |
mov eax,dword[_arg] |
mov edx,_num |
tp equ 1 |
\} |
match =0 [_arg],tp _hex \{ |
mov eax,dword[_arg] |
mov edx,8 |
\} |
sub esp,4*8+4 |
end if |
call fdo_debug_outhex |
popad |
popf |
} |
;----------------------------------------------------------------------------- |
debug_func fdo_debug_outchar |
debug_beginf |
pushad |
mov cl,al |
mov ebx,1 |
mov eax,63 |
int 0x40 |
popad |
ret |
debug_endf |
debug_func fdo_debug_outstr |
debug_beginf |
mov eax,63 |
mov ebx,1 |
.l1: mov cl,[edx] |
or cl,cl |
jz .l2 |
int 0x40 |
inc edx |
jmp .l1 |
.l2: ret |
debug_endf |
debug_func fdo_debug_outdec |
debug_beginf |
or cl,cl |
jz @f |
or eax,eax |
jns @f |
neg eax |
push eax |
mov al,'-' |
call fdo_debug_outchar |
pop eax |
@@: push 10 |
pop ecx |
push -'0' |
.l1: xor edx,edx |
div ecx |
push edx |
test eax,eax |
jnz .l1 |
.l2: pop eax |
add al,'0' |
jz .l3 |
call fdo_debug_outchar |
jmp .l2 |
.l3: ret |
debug_endf |
debug_func fdo_debug_outhex |
__fdo_hexdigits db '0123456789ABCDEF' |
debug_beginf |
mov cl,dl |
neg cl |
add cl,8 |
shl cl,2 |
rol eax,cl |
.l1: rol eax,4 |
push eax |
and eax,0x0000000F |
mov al,[__fdo_hexdigits+eax] |
call fdo_debug_outchar |
pop eax |
dec edx |
jnz .l1 |
ret |
debug_endf |
;----------------------------------------------------------------------------- |
macro DEBUGF _level,_format,[_arg] { |
common |
if __DEBUG__ = 1 & _level >= __DEBUG_LEVEL__ |
local ..f1,f2,a1,a2,c1,c2,c3,..lbl |
_debug_str_ equ __debug_str_ # a1 |
a1 = 0 |
c2 = 0 |
c3 = 0 |
f2 = 0 |
repeat ..lbl-..f1 |
virtual at 0 |
db _format,0,0 |
load c1 word from %-1 |
end virtual |
if c1 = '%s' |
virtual at 0 |
db _format,0,0 |
store word 0 at %-1 |
load c1 from f2-c2 |
end virtual |
if c1 <> 0 |
DEBUGS 0,_debug_str_+f2-c2 |
end if |
c2 = c2 + 1 |
f2 = %+1 |
DEBUGF_HELPER S,a1,0,_arg |
else if c1 = '%x' |
virtual at 0 |
db _format,0,0 |
store word 0 at %-1 |
load c1 from f2-c2 |
end virtual |
if c1 <> 0 |
DEBUGS 0,_debug_str_+f2-c2 |
end if |
c2 = c2 + 1 |
f2 = %+1 |
DEBUGF_HELPER H,a1,0,_arg |
else if c1 = '%d' | c1 = '%u' |
local c4 |
if c1 = '%d' |
c4 = 1 |
else |
c4 = 0 |
end if |
virtual at 0 |
db _format,0,0 |
store word 0 at %-1 |
load c1 from f2-c2 |
end virtual |
if c1 <> 0 |
DEBUGS 0,_debug_str_+f2-c2 |
end if |
c2 = c2 + 1 |
f2 = %+1 |
DEBUGF_HELPER D,a1,c4,_arg |
else if c1 = '\n' |
c3 = c3 + 1 |
end if |
end repeat |
virtual at 0 |
db _format,0,0 |
load c1 from f2-c2 |
end virtual |
if (c1<>0)&(f2<>..lbl-..f1-1) |
DEBUGS 0,_debug_str_+f2-c2 |
end if |
virtual at 0 |
..f1 db _format,0 |
..lbl: |
__debug_strings equ __debug_strings,_debug_str_,<_format>,..lbl-..f1-1-c2-c3 |
end virtual |
end if |
} |
macro __include_debug_strings dummy,[_id,_fmt,_len] { |
common |
local c1,a1,a2 |
forward |
if defined _len & ~_len eq |
_id: |
a1 = 0 |
a2 = 0 |
repeat _len |
virtual at 0 |
db _fmt,0,0 |
load c1 word from %+a2-1 |
end virtual |
if (c1='%s')|(c1='%x')|(c1='%d')|(c1='%u') |
db 0 |
a2 = a2 + 1 |
else if (c1='\n') |
dw $0A0D |
a1 = a1 + 1 |
a2 = a2 + 1 |
else |
db c1 and 0x0FF |
end if |
end repeat |
db 0 |
end if |
} |
macro DEBUGF_HELPER _letter,_num,_sign,[_arg] { |
common |
local num |
num = 0 |
forward |
if num = _num |
DEBUG#_letter _sign,_arg |
end if |
num = num+1 |
common |
_num = _num+1 |
} |
macro include_debug_strings { |
if __DEBUG__ = 1 |
match dbg_str,__debug_strings \{ |
__include_debug_strings dbg_str |
\} |
end if |
} |
/programs/network/VNCclient/logon.inc |
---|
0,0 → 1,263 |
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 |
int 0x40 |
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 |
int 0x40 ; 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 |
int 0x40 |
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 |
int 0x40 |
cmp eax,2 ; button presed ? |
jne checkevent_logon ; a key is pressed or redraw is nessesary, goto checkevent |
int 0x40 ; 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, 33*65536+12 |
mov edx, 4 |
mov esi, 0xEBEBEB |
int 0x40 |
cmp byte[mode],0 |
je @f |
mov ecx, 49*65536+12 |
inc edx |
int 0x40 |
@@: |
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 |
int 0x40 |
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 |
int 0x40 |
add ebx,6*65536 |
jmp @r |
dont_draw_pass: |
popa |
ret |
close_logon: |
mov eax,-1 |
int 0x40 |
connect_logon: |
ret |
draw_window_logon: |
mov eax, 12 ; function 12_logon:tell os about windowdraw |
mov ebx, 1 ; 1, start of draw |
int 0x40 |
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, 0x03DDDDDD ; color of work area RRGGBB |
int 0x40 |
mov eax, 8 ; LOGON BUTTON |
mov ebx, 220*65536+85 |
mov ecx, 63*65536+16 |
mov edx, 2 |
mov esi, 0xCCCCCC |
int 0x40 |
call print_text_logon |
; WINDOW LABEL |
mov eax, 4 ; function 4 _logon: write text to window |
mov ebx, 8*65536+8 ; [x start] *65536 + [y start] |
mov ecx, 0x10ffffff ; color of text RRGGBB |
mov edx, labelt ; pointer to text beginning |
mov esi, labellen-labelt ; text length |
int 0x40 |
cmp byte[mode],0 |
je servermode_ |
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 |
int 0x40 |
add bl,16 |
mov edx, passstr ; pointer to text beginning |
mov esi, connect-passstr ; text length |
int 0x40 |
jmp drawtherest_ |
servermode_: |
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 |
int 0x40 |
drawtherest_: |
mov ebx, 240*65536+67 ; [x start] *65536 + [y start] |
mov edx, connect ; pointer to text beginning |
mov esi, connect_e-connect ; text length |
int 0x40 |
popa |
inc ebx |
int 0x40 |
ret |
; DATA AREA |
labelt: db 'Kolibrios VNC client by HIDNPLAYR' |
labellen: |
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:' |
connect: db 'connect !' |
connect_e: |
I_END_logon: |
/programs/network/VNCclient/raw.inc |
---|
0,0 → 1,145 |
encoding_raw: |
DEBUGF 1,'FRAME: RAW\n' |
mov ax,[screen.width] ; |
mov bx,[frame.y] ; |
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 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 |
push ebx |
push edx ; |
mov ax,[frame.height] ; |
mov bx,3 ; |
mul bx ; |
mov bx,[screen.width] ; |
mul bx ; |
shl edx,16 ; |
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 |
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 |
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 ; |
; 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 |
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 |
/programs/network/VNCclient/vnc.asm |
---|
0,0 → 1,508 |
; |
; |
; VNC Client for kolibrios by hidnplayr |
; |
; |
; WORK IN PROGRESS... |
; |
; FEEL FREE TO CONTRIBUTE ! |
; |
; hidnplayr@gmail.com |
; |
use32 |
org 0x0 |
db 'MENUET00' ; 8 byte id |
dd 38 ; required os |
dd START ; program start |
dd I_END ; program image size |
dd IM_END ; required amount of memory |
dd 0 ; reserved=no extended header |
__DEBUG__ equ 1 |
__DEBUG_LEVEL__ equ 1 |
STRLEN = 64 |
xpos = 4 |
ypos = 22 |
TIMEOUT = 60 ; timeout in seconds |
BUFFER = 512 ; Buffer size for DNS |
include 'fdo.inc' |
include 'ETH.INC' |
include 'logon.inc' |
include 'raw.inc' |
include 'copyrect.inc' |
START: ; start of execution |
call red_logon |
mov eax,40 ; Report events |
mov ebx,10000000b ; 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 |
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_format32 |
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 eax,40 ; report events |
mov ebx,10100111b ; stack, 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 |
; mov byte[fbur.inc],0 ; request a framebufferupdate |
; eth.write_tcp [socket],10,fbur |
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 ; redraw |
je redraw |
cmp eax,2 ; key |
je key |
cmp eax,3 ; button |
je button |
cmp eax,6 ; mouse |
je mouse |
cmp eax,8 |
je network |
; request an FRB update |
jmp mainloop |
network: |
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 mainloop |
framebufferupdate: |
DEBUGF 1,'Framebufferupdate!\n' |
mov di,word[receive_buffer+2] |
bswap edi |
shr edi,16 |
mov esi,receive_buffer+4 |
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 |
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] |
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 |
DEBUGF 1,'FRAME: unknown encoding\n' |
jmp mainloop |
next_rectangle: |
dec di |
pusha |
call drawbuffer |
popa |
cmp di,0 |
jg rectangle_loop |
jmp mainloop |
encoding_RRE: |
DEBUGF 1,'FRAME: RRE\n' |
jmp next_rectangle |
encoding_hextile: |
DEBUGF 1,'FRAME: hextile\n' |
jmp next_rectangle |
encoding_ZRLE: |
DEBUGF 1,'FRAME: ZRLE\n' |
jmp next_rectangle |
setcolourmapentries: |
DEBUGF 1,'Server sended an SetColourMapEntries message\n' |
jmp mainloop |
bell: |
mov eax,55 |
mov ebx,eax |
mov esi,beep |
int 0x40 |
jmp mainloop |
servercuttext: |
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 |
cmp ah,13 |
jne @f |
mov byte[fbur.inc],1 |
eth.write_tcp [socket],10,fbur |
jmp mainloop |
@@: |
cmp ah,30 |
jne @f |
mov byte[fbur.inc],12 |
eth.write_tcp [socket],10,fbur |
jmp mainloop |
@@: |
mov byte[fbur.inc],0 |
eth.write_tcp [socket],10,fbur |
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 |
cmp al,2 |
jne @f ; in kolibri right click is 2 (decimal), in RFB protocol it is bit 2 (counting from 0) |
mov al,100b |
@@: |
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 SCOKET !! |
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 |
read_data: |
eth.read_data [socket],receive_buffer,[datapointer],IM_END-receive_buffer |
ret |
; 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 16 ; depth |
.big_endian db 0 ; big-endian flag |
.true_color db 1 ; true-colour flag |
.red_max db 0,32 ; red-max |
.green_max db 0,32 ; green-max |
.blue_max db 0,64 ; 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 8 ; depth |
.big_endian db 0 ; big-endian flag |
.true_color db 1 ; true-colour flag |
.red_max db 0,7 ; red-max |
.green_max db 0,7 ; green-max |
.blue_max db 0,3 ; blue-max |
.red_shif db 0 ; red-shift |
.green_shift db 3 ; green-shift |
.blue_shift db 6 ; 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 |
dnsMsg: |
receive_buffer rb 5*1024*1024 ; 5 mb buffer for received data (incoming frbupdate etc) |
framebuffer_data rb 1024*768*3 ; framebuffer |
IM_END: |