forked from KolibriOS/kolibrios
360 lines
5.5 KiB
PHP
360 lines
5.5 KiB
PHP
|
|
|||
|
; clipboard client module by barsuk.
|
|||
|
; version 0.2
|
|||
|
; see readme.txt
|
|||
|
|
|||
|
macro CLIP_BUFFER buf_name, buf_size
|
|||
|
{
|
|||
|
#buf_name:
|
|||
|
.size dd buf_size
|
|||
|
.sys1 dd ?
|
|||
|
.sys2 dd ?
|
|||
|
.data db buf_size dup(?)
|
|||
|
}
|
|||
|
|
|||
|
_ipc_send:
|
|||
|
; internally used routine
|
|||
|
; esi->buffer, edx = byte count
|
|||
|
|
|||
|
push ebx
|
|||
|
push ecx
|
|||
|
push ebp
|
|||
|
|
|||
|
mov ebp, ATTEMPT ; number of attempts to send
|
|||
|
xchg edx, esi
|
|||
|
.send_again:
|
|||
|
mov eax, 5
|
|||
|
mov ebx, SEND_DELAY
|
|||
|
int 0x40
|
|||
|
|
|||
|
mov eax, 60
|
|||
|
mov ebx, 2
|
|||
|
mov ecx, [clipboard_init.clipserv_pid]
|
|||
|
int 0x40
|
|||
|
print "send result eax"
|
|||
|
pregs
|
|||
|
|
|||
|
or eax, eax
|
|||
|
jz .ok
|
|||
|
cmp eax, 2
|
|||
|
jz .wait
|
|||
|
jmp .err
|
|||
|
.wait:
|
|||
|
dec ebp
|
|||
|
jz .err
|
|||
|
jmp .send_again
|
|||
|
.ok:
|
|||
|
mov eax, 1
|
|||
|
jmp .exit
|
|||
|
.err:
|
|||
|
xor eax, eax
|
|||
|
.exit:
|
|||
|
pop ebp
|
|||
|
pop ecx
|
|||
|
pop ebx
|
|||
|
xchg edx, esi
|
|||
|
ret
|
|||
|
|
|||
|
_ipc_recv:
|
|||
|
; used internally.
|
|||
|
; edx = default event mask of thread(!!!)
|
|||
|
; esi -> CLIP_buffer
|
|||
|
; result: eax == 1 - suc, 0 - err
|
|||
|
|
|||
|
push ebx
|
|||
|
push ecx
|
|||
|
|
|||
|
mov dword [esi + 4], 0 ; unlock buffer
|
|||
|
mov dword [esi + 8], 0 ;
|
|||
|
|
|||
|
push edx
|
|||
|
mov eax, 60 ; register buffer
|
|||
|
mov ebx, 1
|
|||
|
lea ecx, [esi + 4]
|
|||
|
mov edx, [esi]
|
|||
|
add edx, 8
|
|||
|
;print "register buffer"
|
|||
|
;pregs
|
|||
|
int 0x40
|
|||
|
pop edx
|
|||
|
|
|||
|
.wait:
|
|||
|
mov eax, 40 ; listen for IPC
|
|||
|
mov ebx, 01000000b
|
|||
|
int 0x40
|
|||
|
|
|||
|
mov eax, 23 ; wait for IPC event
|
|||
|
mov ebx, RECV_DELAY ; not too long
|
|||
|
int 0x40
|
|||
|
cmp eax, 7
|
|||
|
jnz .err
|
|||
|
|
|||
|
mov eax, [clipboard_init.clipserv_pid] ; not message from
|
|||
|
cmp eax, [esi + 4] ; daemon, so ignore
|
|||
|
jnz .wait
|
|||
|
|
|||
|
mov dword [esi + 4], 1 ; lock so it will not be spoiled
|
|||
|
|
|||
|
print "cli recv"
|
|||
|
dph1 [esi]
|
|||
|
dph1 [esi+4]
|
|||
|
dph1 [esi+8]
|
|||
|
dph1 [esi+12]
|
|||
|
dph1 [esi+16]
|
|||
|
dph1 [esi+20]
|
|||
|
print ""
|
|||
|
|
|||
|
mov eax, 40 ; restore event mask
|
|||
|
mov ebx, edx
|
|||
|
int 0x40
|
|||
|
mov eax, 1
|
|||
|
jmp .exit
|
|||
|
.err:
|
|||
|
xor eax, eax
|
|||
|
.exit:
|
|||
|
pop ecx
|
|||
|
pop ebx
|
|||
|
ret
|
|||
|
|
|||
|
|
|||
|
clipboard_init:
|
|||
|
; action: define IPC buffer and find clipserv process
|
|||
|
; output: eax == 0 - error, eax == 1 - success
|
|||
|
|
|||
|
push ebx
|
|||
|
push ecx
|
|||
|
push edx
|
|||
|
|
|||
|
; mov eax, 60 ; define buffer for IPC
|
|||
|
; mov ebx, 1
|
|||
|
; mov ecx, .IPC_real_buffer
|
|||
|
; mov edx, IPC_buffer_size
|
|||
|
; int 0x40
|
|||
|
|
|||
|
;print "buffer defined"
|
|||
|
|
|||
|
; mov [.IPC_buffer], ecx
|
|||
|
|
|||
|
push ebp
|
|||
|
mov ebp, 1
|
|||
|
.next_process:
|
|||
|
mov eax, 9
|
|||
|
mov ebx, .process_info
|
|||
|
mov ecx, ebp
|
|||
|
int 0x40
|
|||
|
mov ecx, eax
|
|||
|
mov ebx, .process_info + 10
|
|||
|
mov eax, [ebx]
|
|||
|
cmp eax, '@CLI'
|
|||
|
jnz .differ
|
|||
|
mov al, [ebx + 4]
|
|||
|
cmp al, 'P'
|
|||
|
jnz .differ
|
|||
|
jmp .similar
|
|||
|
|
|||
|
; mov edx, .clipserv_name
|
|||
|
;.compare:
|
|||
|
; mov al, [edx]
|
|||
|
; cmp al, 0
|
|||
|
; jz .similar
|
|||
|
; cmp al, [ebx]
|
|||
|
; jnz .differ
|
|||
|
; inc edx
|
|||
|
; inc ebx
|
|||
|
; jmp .compare
|
|||
|
.differ:
|
|||
|
inc ebp
|
|||
|
cmp ebp, ecx
|
|||
|
jae .err ; process not found
|
|||
|
jmp .next_process
|
|||
|
.similar:
|
|||
|
;print "found server"
|
|||
|
mov eax, dword [.process_info + 30]
|
|||
|
mov [.clipserv_pid], eax
|
|||
|
|
|||
|
mov eax, 1
|
|||
|
jmp .exit
|
|||
|
.err:
|
|||
|
;print "no server"
|
|||
|
xor eax, eax
|
|||
|
.exit:
|
|||
|
pop ebp
|
|||
|
pop edx
|
|||
|
pop ecx
|
|||
|
pop ebx
|
|||
|
ret
|
|||
|
.clipserv_pid dd 0
|
|||
|
.process_info db 1024 dup(0)
|
|||
|
;;.clipserv_name db '@clip',0
|
|||
|
;.IPC_buffer dd .IPC_real_buffer ; sorry
|
|||
|
;.IPC_real_buffer db IPC_buffer_size dup(0)
|
|||
|
|
|||
|
clipboard_write:
|
|||
|
; action: put to clipboard data in format (ax) from buffer
|
|||
|
; input: esi -> CLIP_buffer, ax = format id
|
|||
|
; output: eax == 0 - error, eax == 1 - success
|
|||
|
|
|||
|
push ecx
|
|||
|
push edx
|
|||
|
push edi
|
|||
|
|
|||
|
mov edx, [esi] ; CLIP_buffer.size
|
|||
|
|
|||
|
push edx
|
|||
|
push esi
|
|||
|
mov [.msg_set_size + 2], ax
|
|||
|
mov word [esi + 4 + 2], ax ; format id to low word of sys1
|
|||
|
mov dword [.msg_set_size + 8], edx
|
|||
|
mov esi, .msg_set_size
|
|||
|
mov edx, 12
|
|||
|
call _ipc_send
|
|||
|
pop esi
|
|||
|
pop edx
|
|||
|
or eax, eax
|
|||
|
jz .err
|
|||
|
|
|||
|
mov word [esi + 4], 2 ; COMMAND_SET to high word of sys1
|
|||
|
add esi, 4 ; esi->buffer.sys1
|
|||
|
add edx, 8
|
|||
|
call _ipc_send
|
|||
|
sub esi, 4
|
|||
|
or eax, eax
|
|||
|
jz .err
|
|||
|
|
|||
|
mov eax, 1
|
|||
|
print "write success"
|
|||
|
jmp .exit
|
|||
|
.err:
|
|||
|
print "write failed"
|
|||
|
xor eax, eax
|
|||
|
.exit:
|
|||
|
pop edi
|
|||
|
pop edx
|
|||
|
pop ecx
|
|||
|
ret
|
|||
|
|
|||
|
.msg_set_size dw 1
|
|||
|
dw 1
|
|||
|
dd 0
|
|||
|
dd 0
|
|||
|
|
|||
|
clipboard_read:
|
|||
|
; esi -> CLIP_buffer, ax = format id
|
|||
|
; edx - <EFBFBD><EFBFBD>᪠ ᮡ<EFBFBD>⨩ <EFBFBD><EFBFBD> 㬮<EFBFBD>砭<EFBFBD><EFBFBD>
|
|||
|
; result: eax = 1 - success, 0 - general failure,
|
|||
|
; -1 - buffer too small
|
|||
|
; edx = size of data
|
|||
|
|
|||
|
push ebx
|
|||
|
push ecx
|
|||
|
push ebp
|
|||
|
push esi
|
|||
|
push edi
|
|||
|
|
|||
|
mov ebp, edx
|
|||
|
|
|||
|
; get size
|
|||
|
|
|||
|
mov edi, esi
|
|||
|
mov esi, .msg_get_size
|
|||
|
mov word [esi], 3
|
|||
|
mov [esi + 2], ax
|
|||
|
mov [.msg_get_buf + 2], ax
|
|||
|
mov edx, 8
|
|||
|
call _ipc_send
|
|||
|
or eax, eax
|
|||
|
jz .err
|
|||
|
|
|||
|
;;mov edx, DEFAULT_MASK
|
|||
|
mov edx, ebp
|
|||
|
mov esi, .buf_for_size
|
|||
|
mov dword [esi], 4
|
|||
|
call _ipc_recv
|
|||
|
or eax, eax
|
|||
|
jz .err
|
|||
|
|
|||
|
mov eax, [esi + 12] ; space we need
|
|||
|
mov edx, [edi] ; space we have
|
|||
|
print "read size eax"
|
|||
|
pregs
|
|||
|
mov ecx, eax
|
|||
|
cmp eax, edx
|
|||
|
ja .size
|
|||
|
or eax, eax
|
|||
|
jz .err
|
|||
|
mov ebx, eax
|
|||
|
|
|||
|
mov esi, .msg_get_buf
|
|||
|
mov word [esi], 4
|
|||
|
mov edx, 8
|
|||
|
call _ipc_send
|
|||
|
or eax, eax
|
|||
|
jz .err
|
|||
|
|
|||
|
;print "send fuck"
|
|||
|
|
|||
|
mov edx, ebp
|
|||
|
mov esi, edi
|
|||
|
call _ipc_recv
|
|||
|
or eax, eax
|
|||
|
jz .err
|
|||
|
|
|||
|
print "read get data"
|
|||
|
|
|||
|
mov edx, ebx
|
|||
|
mov eax, 1
|
|||
|
print "read ok"
|
|||
|
jmp .exit ; i'm an idiot. Never will I code at night again
|
|||
|
; i put jz instead of jmp.
|
|||
|
|
|||
|
.size:
|
|||
|
print "buffer small"
|
|||
|
mov edx, eax
|
|||
|
or eax, -1
|
|||
|
jmp .exit
|
|||
|
.err:
|
|||
|
print "read error"
|
|||
|
xor eax, eax
|
|||
|
.exit:
|
|||
|
pop edi
|
|||
|
pop esi
|
|||
|
pop ebp
|
|||
|
pop ecx
|
|||
|
pop ebx
|
|||
|
ret
|
|||
|
|
|||
|
.msg_get_size dw 0
|
|||
|
dw 1
|
|||
|
dd 0
|
|||
|
.msg_get_buf dw 0
|
|||
|
dw 1
|
|||
|
dd 0
|
|||
|
.buf_for_size dd 0
|
|||
|
dd 0
|
|||
|
dd 0
|
|||
|
dd 0
|
|||
|
|
|||
|
|
|||
|
clipboard_delete:
|
|||
|
; ax = format id to delete
|
|||
|
; result: eax = 0 error, = 1 ok
|
|||
|
|
|||
|
push edx
|
|||
|
push esi
|
|||
|
|
|||
|
mov esi, .msg_del
|
|||
|
mov word [esi], 5
|
|||
|
mov [esi + 2], ax
|
|||
|
mov edx, 8
|
|||
|
|
|||
|
call _ipc_send
|
|||
|
|
|||
|
pop esi
|
|||
|
pop edx
|
|||
|
|
|||
|
ret
|
|||
|
.msg_del dw 0
|
|||
|
dw 1
|
|||
|
dd 0
|
|||
|
|