Files
VBoxGuest/sys/ioctl.inc
2026-03-04 22:03:47 +03:00

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