Files
VBoxGuest/vmmdev/packets.inc
2026-03-04 22:03:47 +03:00

170 lines
7.8 KiB
HTML

; =============================================================================
; Модуль : VMMDev Packets
; Назначение : Выделение и инициализация пакетов VMMDev (одна страница 4KB)
; Файл : vmmdev/packets.inc
; =============================================================================
VMMDEV_PKT_OFS_HOST_VERSION = 0 ; sizeof.VMMDEV_GET_HOST_VERSION
VMMDEV_PKT_OFS_GUEST_INFO = 64 ; sizeof.VMMDEV_REPORT_GUEST_INFO
VMMDEV_PKT_OFS_GUEST_INFO2 = 128 ; sizeof.VMMDEV_REPORT_GUEST_INFO2 (~168)
VMMDEV_PKT_OFS_CAPS = 320 ; sizeof.VMMDEV_SET_GUEST_CAPABILITIES2
VMMDEV_PKT_OFS_FILTER = 384 ; sizeof.VMMDEV_CTL_GUEST_FILTER_MASK
VMMDEV_PKT_OFS_ACK_EVENTS = 448 ; sizeof.VMMDEV_ACKNOWLEDGE_EVENTS
; Строка версии (read-only, для копирования в пакет)
vmmdev_version_string db '1.0.0_KolibriOS', 0
VMMDEV_VERSION_STRING_LEN = $ - vmmdev_version_string
; =============================================================================
; vmmdev_init_packets — Выделить страницу и инициализировать все VMMDev пакеты
; =============================================================================
proc vmmdev_init_packets uses ebx ecx edx esi edi
DEBUGF 2, "[VBoxGuest] [VMMDev] Init packets (dynamic)\n"
; --- Выделить страницу ---
invoke KernelAlloc, 4096
test eax, eax
jz .alloc_fail
mov [vbox_device.vmmdev_packets_page], eax
; Обнулить страницу
mov edi, eax
xor eax, eax
mov ecx, 4096 / 4
rep stosd
mov ebx, [vbox_device.vmmdev_packets_page]
; =================================================================
; 1) HOST_VERSION (offset 0)
; =================================================================
lea edi, [ebx + VMMDEV_PKT_OFS_HOST_VERSION]
mov dword [edi + VMMDEV_HEADER.size], sizeof.VMMDEV_GET_HOST_VERSION
mov dword [edi + VMMDEV_HEADER.version], VMMDEV_REQUEST_HEADER_VERSION
mov dword [edi + VMMDEV_HEADER.request_type], VMMDEV_REQ_GET_HOST_VERSION
mov [vbox_device.host_version_virt], edi
mov eax, edi
invoke GetPhysAddr
mov [vbox_device.host_version_phys], eax
DEBUGF 2, "[VBoxGuest] [VMMDev] HostVersion packet: virt=0x%x, phys=0x%x\n", \
[vbox_device.host_version_virt], eax
; =================================================================
; 2) REPORT_GUEST_INFO (offset 64)
; =================================================================
lea edi, [ebx + VMMDEV_PKT_OFS_GUEST_INFO]
mov dword [edi + VMMDEV_HEADER.size], sizeof.VMMDEV_REPORT_GUEST_INFO
mov dword [edi + VMMDEV_HEADER.version], VMMDEV_REQUEST_HEADER_VERSION
mov dword [edi + VMMDEV_HEADER.request_type], VMMDEV_REQ_REPORT_GUEST_INFO
mov dword [edi + VMMDEV_REPORT_GUEST_INFO.interface_version], VMMDEV_VERSION
mov dword [edi + VMMDEV_REPORT_GUEST_INFO.os_type], VBOXOSTYPE_KOLIBRIOS
mov [vbox_device.guestinfo_virt], edi
mov eax, edi
invoke GetPhysAddr
mov [vbox_device.guestinfo_phys], eax
DEBUGF 2, "[VBoxGuest] [VMMDev] GuestInfo packet : virt=0x%x, phys=0x%x\n", \
[vbox_device.guestinfo_virt], eax
; =================================================================
; 3) REPORT_GUEST_INFO2 (offset 128)
; =================================================================
lea edi, [ebx + VMMDEV_PKT_OFS_GUEST_INFO2]
mov dword [edi + VMMDEV_HEADER.size], sizeof.VMMDEV_REPORT_GUEST_INFO2
mov dword [edi + VMMDEV_HEADER.version], VMMDEV_REQUEST_HEADER_VERSION
mov dword [edi + VMMDEV_HEADER.request_type], VMMDEV_REQ_REPORT_GUEST_INFO2
; rc, reserved1, f_requestor уже 0 (обнулено)
; payload: версия заполняется из host_version в guest_info_2_report()
mov dword [edi + VMMDEV_REPORT_GUEST_INFO2.guest_info + VMMDEV_GUEST_INFO2.additions_features], VBOXGSTINFO2_F_REQUESTOR_INFO
; szName[128] — копируем строку версии
push edi ecx
lea edi, [edi + VMMDEV_REPORT_GUEST_INFO2.guest_info + VMMDEV_GUEST_INFO2.szName]
mov esi, vmmdev_version_string
mov ecx, VMMDEV_VERSION_STRING_LEN
rep movsb
pop ecx edi
lea eax, [ebx + VMMDEV_PKT_OFS_GUEST_INFO2]
mov [vbox_device.guestinfo2_virt], eax
invoke GetPhysAddr
mov [vbox_device.guestinfo2_phys], eax
DEBUGF 2, "[VBoxGuest] [VMMDev] GuestInfo2 packet : virt=0x%x, phys=0x%x\n", \
[vbox_device.guestinfo2_virt], eax
; =================================================================
; 4) SET_GUEST_CAPABILITIES2 (offset 320)
; =================================================================
lea edi, [ebx + VMMDEV_PKT_OFS_CAPS]
mov dword [edi + VMMDEV_HEADER.size], sizeof.VMMDEV_SET_GUEST_CAPABILITIES2
mov dword [edi + VMMDEV_HEADER.version], VMMDEV_REQUEST_HEADER_VERSION
mov dword [edi + VMMDEV_HEADER.request_type], VMMDEV_SET_GUEST_CAPS
mov dword [edi + VMMDEV_SET_GUEST_CAPABILITIES2.or_mask], VBOXGUEST_GUEST_CAPS_OR_MASK
mov dword [edi + VMMDEV_SET_GUEST_CAPABILITIES2.not_mask], VBOXGUEST_GUEST_CAPS_NOT_MASK
mov [vbox_device.caps_virt], edi
mov eax, edi
invoke GetPhysAddr
mov [vbox_device.caps_phys], eax
DEBUGF 2, "[VBoxGuest] [VMMDev] Caps packet : virt=0x%x, phys=0x%x\n", \
[vbox_device.caps_virt], eax
; =================================================================
; 5) CTL_GUEST_FILTER_MASK (offset 384)
; =================================================================
lea edi, [ebx + VMMDEV_PKT_OFS_FILTER]
mov dword [edi + VMMDEV_HEADER.size], sizeof.VMMDEV_CTL_GUEST_FILTER_MASK
mov dword [edi + VMMDEV_HEADER.version], VMMDEV_REQUEST_HEADER_VERSION
mov dword [edi + VMMDEV_HEADER.request_type], VMMDEV_REQ_CTL_GUEST_FILTER_MASK
mov dword [edi + VMMDEV_CTL_GUEST_FILTER_MASK.or_mask], VBOXGUEST_EVENTS_OR_MASK
mov dword [edi + VMMDEV_CTL_GUEST_FILTER_MASK.not_mask], VBOXGUEST_EVENTS_NOT_MASK
mov [vbox_device.filter_virt], edi
mov eax, edi
invoke GetPhysAddr
mov [vbox_device.filter_phys], eax
DEBUGF 2, "[VBoxGuest] [VMMDev] Filter packet : virt=0x%x, phys=0x%x\n", \
[vbox_device.filter_virt], eax
DEBUGF 2, "[VBoxGuest] [VMMDev] Filter: OR=0x%x, NOT=0x%x\n", \
[edi + VMMDEV_CTL_GUEST_FILTER_MASK.or_mask], \
[edi + VMMDEV_CTL_GUEST_FILTER_MASK.not_mask]
; =================================================================
; 6) ACKNOWLEDGE_EVENTS (offset 448)
; =================================================================
lea edi, [ebx + VMMDEV_PKT_OFS_ACK_EVENTS]
mov dword [edi + VMMDEV_HEADER.size], sizeof.VMMDEV_ACKNOWLEDGE_EVENTS
mov dword [edi + VMMDEV_HEADER.version], VMMDEV_REQUEST_HEADER_VERSION
mov dword [edi + VMMDEV_HEADER.request_type], VMMDEV_REQ_ACKNOWLEDGE_EVENTS
mov [vbox_device.events_virt], edi
mov eax, edi
invoke GetPhysAddr
mov [vbox_device.events_phys], eax
DEBUGF 2, "[VBoxGuest] [VMMDev] ACK packet : virt=0x%x, phys=0x%x\n", \
[vbox_device.events_virt], eax
DEBUGF 2, "[VBoxGuest] [VMMDev] Init packets success\n"
xor eax, eax
ret
.alloc_fail:
DEBUGF 2, "[VBoxGuest] [VMMDev] ERROR: KernelAlloc failed for VMMDev packets\n"
mov eax, VERR_NO_MEMORY
ret
endp
; =============================================================================
; vmmdev_free_packets — Освободить страницу VMMDev пакетов
; =============================================================================
proc vmmdev_free_packets
cmp dword [vbox_device.vmmdev_packets_page], 0
je @f
invoke KernelFree, [vbox_device.vmmdev_packets_page]
mov dword [vbox_device.vmmdev_packets_page], 0
@@:
ret
endp