; 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 - маска событий по умолчанию ; 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