184 lines
4.2 KiB
HTML
184 lines
4.2 KiB
HTML
; =============================================================================
|
|
; Модуль : IOCTL интерфейс драйвера VBoxGuest
|
|
; Назначение : Обработка команд от приложений (service_proc, ioctl_get_services)
|
|
; Файл : sys/ioctl.inc
|
|
; =============================================================================
|
|
|
|
; IOCTL ABI v1
|
|
API_VERSION equ 1
|
|
|
|
; General
|
|
VBOX_IOCTL_GET_VERSION equ 0
|
|
VBOX_IOCTL_GET_SERVICES equ 1
|
|
VBOX_IOCTL_SVC_ENABLE equ 2
|
|
VBOX_IOCTL_SVC_DISABLE equ 3
|
|
|
|
; Clipboard
|
|
VBOX_IOCTL_CLIP_STATUS equ 10
|
|
VBOX_IOCTL_CLIP_READ equ 11
|
|
VBOX_IOCTL_CLIP_WRITE equ 12
|
|
|
|
; SERVICE_INFO size for GET_SERVICES (dd id + rb name[16] + dd enabled = 24)
|
|
SVC_INFO_SIZE equ 24
|
|
SVC_INFO_NAME_LEN equ 16
|
|
|
|
; =============================================================================
|
|
; Service Procedure — IOCTL dispatch
|
|
; =============================================================================
|
|
proc service_proc stdcall, ioctl:dword
|
|
mov ebx, [ioctl]
|
|
mov eax, [ebx + IOCTL.io_code]
|
|
|
|
cmp eax, VBOX_IOCTL_GET_VERSION
|
|
je .get_version
|
|
cmp eax, VBOX_IOCTL_GET_SERVICES
|
|
je .get_services
|
|
cmp eax, VBOX_IOCTL_SVC_ENABLE
|
|
je .svc_enable
|
|
cmp eax, VBOX_IOCTL_SVC_DISABLE
|
|
je .svc_disable
|
|
cmp eax, VBOX_IOCTL_CLIP_STATUS
|
|
je .clip_status
|
|
cmp eax, VBOX_IOCTL_CLIP_READ
|
|
je .clip_read
|
|
cmp eax, VBOX_IOCTL_CLIP_WRITE
|
|
je .clip_write
|
|
|
|
jmp .fail
|
|
|
|
; --- GET_VERSION (0) ---
|
|
.get_version:
|
|
cmp [ebx + IOCTL.out_size], 4
|
|
jb .fail
|
|
mov eax, [ebx + IOCTL.output]
|
|
mov dword [eax], API_VERSION
|
|
xor eax, eax
|
|
ret
|
|
|
|
; --- GET_SERVICES (1) ---
|
|
.get_services:
|
|
stdcall ioctl_get_services, ebx
|
|
ret
|
|
|
|
; --- SVC_ENABLE (2) ---
|
|
.svc_enable:
|
|
cmp [ebx + IOCTL.inp_size], 4
|
|
jb .fail
|
|
mov eax, [ebx + IOCTL.input]
|
|
mov eax, [eax]
|
|
stdcall dispatcher_enable_by_id, eax
|
|
push eax
|
|
call dispatcher_get_active_events
|
|
call vmmdev_update_event_filter
|
|
call dispatcher_get_active_caps
|
|
call vmmdev_update_capabilities
|
|
pop eax
|
|
ret
|
|
|
|
; --- SVC_DISABLE (3) ---
|
|
.svc_disable:
|
|
cmp [ebx + IOCTL.inp_size], 4
|
|
jb .fail
|
|
mov eax, [ebx + IOCTL.input]
|
|
mov eax, [eax]
|
|
stdcall dispatcher_disable_by_id, eax
|
|
push eax
|
|
call dispatcher_get_active_events
|
|
call vmmdev_update_event_filter
|
|
call dispatcher_get_active_caps
|
|
call vmmdev_update_capabilities
|
|
pop eax
|
|
ret
|
|
|
|
; --- CLIP_STATUS (10) ---
|
|
.clip_status:
|
|
stdcall clip_ioctl_status, ebx
|
|
ret
|
|
|
|
; --- CLIP_READ (11) ---
|
|
.clip_read:
|
|
stdcall clip_ioctl_read, ebx
|
|
ret
|
|
|
|
; --- CLIP_WRITE (12) ---
|
|
.clip_write:
|
|
stdcall clip_ioctl_write, ebx
|
|
ret
|
|
|
|
.fail:
|
|
or eax, -1
|
|
ret
|
|
endp
|
|
|
|
; =============================================================================
|
|
; ioctl_get_services — Заполнить список сервисов
|
|
; =============================================================================
|
|
proc ioctl_get_services stdcall uses ebx ecx edx esi edi, ioctl_ptr:dword
|
|
mov ebx, [ioctl_ptr]
|
|
cmp [ebx + IOCTL.out_size], 4
|
|
jb .fail
|
|
|
|
mov edi, [ebx + IOCTL.output]
|
|
mov ecx, [services_count]
|
|
mov [edi], ecx ; dd count
|
|
add edi, 4
|
|
|
|
test ecx, ecx
|
|
jz .done
|
|
|
|
; Доступное место = out_size - 4
|
|
mov edx, [ebx + IOCTL.out_size]
|
|
sub edx, 4
|
|
|
|
mov esi, services_table
|
|
|
|
.loop:
|
|
cmp edx, SVC_INFO_SIZE
|
|
jb .done
|
|
|
|
; dd id
|
|
mov eax, [esi + SERVICE_ENTRY.id]
|
|
mov [edi], eax
|
|
add edi, 4
|
|
|
|
; rb name[16] — null-padded
|
|
push ecx esi edi
|
|
mov ecx, SVC_INFO_NAME_LEN
|
|
; Заполнить нулями
|
|
push edi
|
|
xor al, al
|
|
rep stosb
|
|
pop edi
|
|
; Скопировать имя
|
|
mov esi, [esi + SERVICE_ENTRY.name_ptr]
|
|
mov ecx, SVC_INFO_NAME_LEN - 1
|
|
.copy_name:
|
|
lodsb
|
|
test al, al
|
|
jz .name_done
|
|
stosb
|
|
dec ecx
|
|
jnz .copy_name
|
|
.name_done:
|
|
pop edi esi ecx
|
|
add edi, SVC_INFO_NAME_LEN
|
|
|
|
; dd enabled
|
|
mov eax, [esi + SERVICE_ENTRY.enabled]
|
|
mov [edi], eax
|
|
add edi, 4
|
|
|
|
sub edx, SVC_INFO_SIZE
|
|
add esi, sizeof.SERVICE_ENTRY
|
|
dec ecx
|
|
jnz .loop
|
|
|
|
.done:
|
|
xor eax, eax
|
|
ret
|
|
|
|
.fail:
|
|
or eax, -1
|
|
ret
|
|
endp
|