; ============================================================================= ; Модуль : 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