413 lines
7.8 KiB
NASM
413 lines
7.8 KiB
NASM
|
; <--- description --->
|
|||
|
; compiler: FASM
|
|||
|
; name: Clipboard server/daemon
|
|||
|
; version: 0.2
|
|||
|
; author: barsuk
|
|||
|
|
|||
|
; <--- include all MeOS stuff --->
|
|||
|
include "lang.inc"
|
|||
|
include "..\..\..\MACROS.INC"
|
|||
|
|
|||
|
; <--- start of MenuetOS application --->
|
|||
|
MEOS_APP_START
|
|||
|
|
|||
|
;define DEBUG TRUE
|
|||
|
define DEBUG FALSE
|
|||
|
include "bdebug.inc"
|
|||
|
|
|||
|
DEFAULT_SIZE = 0x10010 ; 64K + size of headers
|
|||
|
MAX_SIZE = 0x01000000 ; 16 M
|
|||
|
MAX_FORMAT = 16
|
|||
|
DELAY = 10 ; 1/10 sec between sending attempts
|
|||
|
ATTEMPT = 5 ; number of sending attempts
|
|||
|
|
|||
|
|
|||
|
; <--- start of code --->
|
|||
|
CODE
|
|||
|
|
|||
|
; <20><>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> 㡨<><E3A1A8> <20><><EFBFBD> @clip, <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:
|
|||
|
; <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ⮫쪮 <20><><EFBFBD><EFBFBD>!
|
|||
|
; <20> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ᠬ<><E1A0AC> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
|
|||
|
|
|||
|
mov ecx, 2 ; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <><E1ABAE> <20><><EFBFBD> <20><EFBFBD>ન
|
|||
|
mov ebp, info
|
|||
|
mov ebx, ebp
|
|||
|
mov edx, 18
|
|||
|
.next_process:
|
|||
|
mov eax, 9
|
|||
|
int 0x40
|
|||
|
cmp dword [ebx + 10], '@CLI'
|
|||
|
jnz .differ
|
|||
|
cmp byte [ebx + 14], 'P'
|
|||
|
jnz .differ
|
|||
|
.similar:
|
|||
|
xchg eax, edx
|
|||
|
mov ebx, 2
|
|||
|
int 0x40
|
|||
|
mov ebx, ebp
|
|||
|
xchg eax, edx
|
|||
|
.differ:
|
|||
|
inc ecx
|
|||
|
cmp ecx, eax
|
|||
|
jae .done ; process not found
|
|||
|
jmp .next_process
|
|||
|
|
|||
|
.done:
|
|||
|
mov eax, 68 ; init heap
|
|||
|
mov ebx, 11
|
|||
|
int 0x40
|
|||
|
|
|||
|
mov eax, 66 ; set hotkey: Ctrl-Alt-V
|
|||
|
mov ebx, 4
|
|||
|
mov ecx, 47
|
|||
|
mov edx, 0x110 ; 0x110
|
|||
|
int 0x40
|
|||
|
print "set hot key (1 bad)"
|
|||
|
pregs
|
|||
|
|
|||
|
mov ebp, DEFAULT_SIZE
|
|||
|
|
|||
|
mov eax, 68 ; get memory for buffer
|
|||
|
mov ebx, 12
|
|||
|
mov ecx, ebp
|
|||
|
int 0x40
|
|||
|
mov esi, IPC_buffer
|
|||
|
mov [esi], eax
|
|||
|
|
|||
|
mov eax, 60 ; define buffer for IPC
|
|||
|
mov ebx, 1
|
|||
|
mov ecx, [esi]
|
|||
|
mov edx, ebp
|
|||
|
int 0x40
|
|||
|
|
|||
|
mov eax, 40
|
|||
|
mov ebx, 01000010b ;
|
|||
|
int 0x40
|
|||
|
|
|||
|
wait_event: ; main cycle
|
|||
|
mov eax, [IPC_buffer]
|
|||
|
mov dword [eax], 0 ; unlock buffer
|
|||
|
mov dword [eax + 4], 8
|
|||
|
|
|||
|
mov eax, 10 ; wait
|
|||
|
int 0x40
|
|||
|
print "event"
|
|||
|
pregs
|
|||
|
|
|||
|
;dec eax
|
|||
|
;dec eax
|
|||
|
cmp eax, 2
|
|||
|
jnz ipc_event
|
|||
|
|
|||
|
print "hotkey"
|
|||
|
|
|||
|
mov eax, 2
|
|||
|
int 0x40
|
|||
|
pregs
|
|||
|
cmp ah, 47 ; "v" up
|
|||
|
jnz wait_event
|
|||
|
|
|||
|
print "hotkey v up"
|
|||
|
; it is hotkey
|
|||
|
mov eax, 1
|
|||
|
mov ebx, eax
|
|||
|
call find_format
|
|||
|
pregs
|
|||
|
cmp eax, -1
|
|||
|
jz wait_event
|
|||
|
mov esi, [data_buffer + eax * 4]
|
|||
|
mov edi, [data_size + eax * 4]
|
|||
|
mov ecx, 2
|
|||
|
print "ping"
|
|||
|
.next:
|
|||
|
mov eax, 72
|
|||
|
movzx edx, byte [esi]
|
|||
|
int 0x40 ; here we should pause if eax = 1
|
|||
|
pregs
|
|||
|
|
|||
|
inc esi
|
|||
|
dec edi
|
|||
|
jnz .next
|
|||
|
jmp wait_event
|
|||
|
|
|||
|
ipc_event:
|
|||
|
|
|||
|
; we get an IPC message
|
|||
|
|
|||
|
print "recv. "
|
|||
|
|
|||
|
mov eax, [IPC_buffer]
|
|||
|
mov dword [eax], 1 ; lock buffer
|
|||
|
mov dword [eax + 4], 8
|
|||
|
|
|||
|
dph1 dword [eax] ; lock
|
|||
|
dph1 dword [eax + 4] ; current used size
|
|||
|
dph1 dword [eax + 8] ; pid
|
|||
|
dph1 dword [eax + 12] ; len
|
|||
|
print ""
|
|||
|
dph1 dword [eax + 16] ; cmd << 16 | fmt
|
|||
|
dph1 dword [eax + 20]
|
|||
|
dph1 dword [eax + 24]
|
|||
|
|
|||
|
mov ebx, [eax + 8 + 4]
|
|||
|
cmp ebx, 8
|
|||
|
jb wait_event ; all my messages have 8-byte header
|
|||
|
; so ignore this one
|
|||
|
|
|||
|
movzx ecx, word [eax + 8 + 8] ; command
|
|||
|
cmp ecx, 1
|
|||
|
jz command_setsize
|
|||
|
cmp ecx, 2
|
|||
|
jz command_set
|
|||
|
cmp ecx, 3
|
|||
|
jz command_getsize
|
|||
|
cmp ecx, 4
|
|||
|
jz command_get
|
|||
|
cmp ecx, 5
|
|||
|
jz command_delete
|
|||
|
jmp wait_event ; unrecognised command
|
|||
|
|
|||
|
command_setsize:
|
|||
|
|
|||
|
; the only thing we really need to do here is to grow IPC buffer
|
|||
|
; no changes are done to real buffer of chosen format
|
|||
|
|
|||
|
; the bad thing is that IPC buffer grows and never becomes less.
|
|||
|
; i want to fix this in the next version.
|
|||
|
|
|||
|
print "set size"
|
|||
|
|
|||
|
mov esi, [IPC_buffer_size]
|
|||
|
mov ecx, [eax + 24] ; size
|
|||
|
add ecx, 0x18 ; for headers
|
|||
|
;pregs
|
|||
|
cmp esi, ecx
|
|||
|
jae wait_event
|
|||
|
print "ipc buffer resize from esi to ecx"
|
|||
|
pregs
|
|||
|
|
|||
|
mov ebp, MAX_SIZE ; sort of protection. forbid transfer of more
|
|||
|
cmp ecx, ebp ; than 16,7 Mb of data through buffer
|
|||
|
jbe not_much
|
|||
|
mov ecx, ebp
|
|||
|
|
|||
|
not_much:
|
|||
|
xchg eax, edi ; edx := [IPC_buffer]
|
|||
|
add ecx, 0x18 ; for headers
|
|||
|
|
|||
|
mov [IPC_buffer_size], ecx
|
|||
|
mov eax, 68
|
|||
|
mov ebx, 12
|
|||
|
int 0x40 ; get memory
|
|||
|
print "get mem for new buf, eax"
|
|||
|
pregs
|
|||
|
mov [IPC_buffer], eax
|
|||
|
|
|||
|
mov dword [eax + 4], 8
|
|||
|
mov edx, ecx
|
|||
|
mov ecx, eax
|
|||
|
mov eax, 60
|
|||
|
mov ebx, 1
|
|||
|
int 0x40 ; make it IPC buffer
|
|||
|
|
|||
|
mov ecx, edi
|
|||
|
mov eax, 68
|
|||
|
mov ebx, 13
|
|||
|
int 0x40 ; free old IPC buffer
|
|||
|
|
|||
|
jmp wait_event
|
|||
|
|
|||
|
command_set:
|
|||
|
print "set"
|
|||
|
|
|||
|
; here we put the data transfered to us to one of internal buffers
|
|||
|
|
|||
|
;;;outs eax + 0x18
|
|||
|
|
|||
|
movzx eax, word [eax + 18] ; format id
|
|||
|
call find_format
|
|||
|
cmp eax, -1
|
|||
|
jz new_format
|
|||
|
mov edx, eax
|
|||
|
|
|||
|
; free old buffer of this format
|
|||
|
|
|||
|
mov ecx, [data_buffer + edx * 4]
|
|||
|
mov eax, 68
|
|||
|
mov ebx, 13
|
|||
|
int 0x40
|
|||
|
jmp set_buffer
|
|||
|
|
|||
|
new_format:
|
|||
|
mov eax, data_count ; allocate a buffer
|
|||
|
mov edx, [eax]
|
|||
|
inc dword [eax] ; no protection, no checks. very bad :(
|
|||
|
set_buffer:
|
|||
|
mov eax, [IPC_buffer]
|
|||
|
mov ecx, dword [eax + 12]
|
|||
|
sub ecx, 8 ; get length of data itself
|
|||
|
; subtract size of my headers
|
|||
|
;pregs
|
|||
|
mov [data_size + edx * 4], ecx ; save length of data
|
|||
|
|
|||
|
mov eax, 68
|
|||
|
mov ebx, 12
|
|||
|
int 0x40
|
|||
|
mov [data_buffer + edx * 4], eax
|
|||
|
|
|||
|
; copy data from IPC to new buffer
|
|||
|
mov esi, [IPC_buffer]
|
|||
|
mov ebp, esi
|
|||
|
add esi, 24 ; start of data
|
|||
|
mov edi, eax
|
|||
|
rep movsb ; oh, me knows that it's bad
|
|||
|
|
|||
|
mov eax, ebp
|
|||
|
movzx ecx, word [eax + 18] ; format id
|
|||
|
mov [data_format + edx * 4], ecx
|
|||
|
|
|||
|
; debug
|
|||
|
; print "set debug"
|
|||
|
; mov eax, [data_buffer + edx * 4]
|
|||
|
; mov ebx, [data_size + edx * 4]
|
|||
|
; mov ecx, [data_format + edx * 4]
|
|||
|
; pregs
|
|||
|
|
|||
|
jmp wait_event
|
|||
|
|
|||
|
command_delete:
|
|||
|
movzx eax, word [eax + 18] ; format id
|
|||
|
cmp eax, -1
|
|||
|
jz command_clear
|
|||
|
call find_format
|
|||
|
cmp eax, -1
|
|||
|
jz wait_event
|
|||
|
mov ecx, [data_buffer + eax * 4]
|
|||
|
mov [data_format + eax * 4], 0
|
|||
|
mov eax, 68
|
|||
|
mov ebx, 13
|
|||
|
int 0x40
|
|||
|
jmp wait_event
|
|||
|
|
|||
|
command_clear:
|
|||
|
mov eax, 68
|
|||
|
mov ebx, 13
|
|||
|
mov edx, data_buffer
|
|||
|
.next:
|
|||
|
mov ecx, [edx]
|
|||
|
jecxz .nofree
|
|||
|
int 0x40
|
|||
|
.nofree:
|
|||
|
mov [edx + data_size - data_buffer], 0
|
|||
|
add edx, 4
|
|||
|
cmp edx, data_format
|
|||
|
jnae .next
|
|||
|
jmp wait_event
|
|||
|
|
|||
|
command_getsize:
|
|||
|
|
|||
|
print "get size"
|
|||
|
|
|||
|
; we should send reply, containing size of data with chosen format id
|
|||
|
movzx eax, word [eax + 18] ; format id
|
|||
|
mov esi, 4
|
|||
|
call find_format
|
|||
|
;pregs
|
|||
|
cmp eax, -1
|
|||
|
jz zero_size
|
|||
|
|
|||
|
lea edx, [data_size + eax * 4]
|
|||
|
mov eax, [edx]
|
|||
|
jmp send_getsize
|
|||
|
zero_size:
|
|||
|
mov edx, dw_zero ; send 0 to indicate that the buffer is empty
|
|||
|
send_getsize:
|
|||
|
jmp send_msg
|
|||
|
|
|||
|
command_get:
|
|||
|
print "get"
|
|||
|
|
|||
|
; we need to send the data
|
|||
|
|
|||
|
; [:||||:]
|
|||
|
|
|||
|
movzx eax, word [eax + 18] ; format id
|
|||
|
call find_format
|
|||
|
cmp eax, -1
|
|||
|
jz wait_event
|
|||
|
mov edi, eax ; <20> <20><>䨣
|
|||
|
|
|||
|
mov edx, [data_buffer + edi * 4]
|
|||
|
mov esi, [data_size + edi * 4]
|
|||
|
;jmp send_msg
|
|||
|
|
|||
|
send_msg:
|
|||
|
|
|||
|
; for debugging
|
|||
|
; mov eax, 5
|
|||
|
; mov ebx, DELAY*5
|
|||
|
; int 0x40
|
|||
|
|
|||
|
mov ebp, ATTEMPT ; number of attempts to send
|
|||
|
mov eax, [IPC_buffer]
|
|||
|
mov ecx, [eax + 8] ; sender PID
|
|||
|
mov eax, 60
|
|||
|
mov ebx, 2
|
|||
|
int 0x40
|
|||
|
print "send data result eax"
|
|||
|
pregs
|
|||
|
cmp eax, 2
|
|||
|
jz .wait
|
|||
|
cmp eax, 3 ; it is strange..
|
|||
|
jz .wait ; maybe he needs time to resize his buf
|
|||
|
jmp wait_event
|
|||
|
.wait:
|
|||
|
dec ebp
|
|||
|
jz wait_event
|
|||
|
mov eax, 5 ; sleep a bit
|
|||
|
mov ebx, DELAY
|
|||
|
int 0x40
|
|||
|
jmp send_msg
|
|||
|
|
|||
|
|
|||
|
find_format: ; small function returning number of format
|
|||
|
|
|||
|
;print "find format"
|
|||
|
push ebx
|
|||
|
mov ebx, eax ; format id
|
|||
|
and ebx, 0xffff ; it is word
|
|||
|
xor eax, eax
|
|||
|
next:
|
|||
|
cmp [data_format + eax * 4], ebx
|
|||
|
jz found
|
|||
|
inc eax
|
|||
|
cmp eax, MAX_FORMAT
|
|||
|
jb next
|
|||
|
not_found:
|
|||
|
or eax, -1
|
|||
|
found:
|
|||
|
;pregs
|
|||
|
pop ebx
|
|||
|
ret
|
|||
|
|
|||
|
; <--- initialised data --->
|
|||
|
DATA
|
|||
|
IPC_buffer dd 0
|
|||
|
IPC_buffer_size dd DEFAULT_SIZE ; initially 64K
|
|||
|
|
|||
|
info db 1024 dup(0) ; for process info
|
|||
|
|
|||
|
data_buffer dd MAX_FORMAT dup(0) ; buffer for some format
|
|||
|
; (256 formats max)
|
|||
|
data_format dd MAX_FORMAT dup(0) ; format id
|
|||
|
data_size dd MAX_FORMAT dup(0) ; size of buffer
|
|||
|
data_count dd 0 ; number of formats used
|
|||
|
dw_zero dd 0 ; used to tell that
|
|||
|
; we don't have a format
|
|||
|
|
|||
|
; <--- uninitialised data --->
|
|||
|
UDATA
|
|||
|
|
|||
|
|
|||
|
MEOS_APP_END
|
|||
|
; <--- end of MenuetOS application --->
|