170 lines
7.8 KiB
HTML
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
|