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