210 lines
5.1 KiB
NASM
210 lines
5.1 KiB
NASM
; =============================================================================
|
|
; Программа : VirtualBox Guest Driver для KolibriOS
|
|
; Модуль : Main driver entry
|
|
; Назначение : Full-featured driver with Clipboard support and dual-level error handling
|
|
; Файл : vboxguest.asm
|
|
;
|
|
; cp /usbhd0/1/vboxguest/vboxguest /sys/Drivers/vboxguest.sys
|
|
; loaddrv vboxguest
|
|
;
|
|
; =============================================================================
|
|
|
|
format PE DLL native 0.05
|
|
entry START
|
|
|
|
__DEBUG__ = 1
|
|
__DEBUG_LEVEL__ = 1
|
|
|
|
API_VERSION equ 0
|
|
SRV_GETVERSION equ 0
|
|
|
|
section '.flat' code readable writable executable
|
|
|
|
; KolibriOS includes
|
|
include '/usbhd0/1/ksrc_n/DRIVERS/proc32.inc'
|
|
include '/usbhd0/1/ksrc_n/DRIVERS/struct.inc'
|
|
include '/usbhd0/1/ksrc_n/DRIVERS/macros.inc'
|
|
include '/usbhd0/1/ksrc_n/DRIVERS/peimport.inc'
|
|
include '/usbhd0/1/ksrc_n/DRIVERS/fdo.inc'
|
|
include '/usbhd0/1/ksrc_n/DRIVERS/pci.inc'
|
|
|
|
; VBoxGuest driver modules
|
|
include 'common/log.inc'
|
|
include 'common/constants.inc'
|
|
include 'common/structs.inc'
|
|
include 'common/macros.inc'
|
|
include 'common/errors.inc'
|
|
include 'core/vmmdev.inc'
|
|
include 'core/hgcm.inc'
|
|
include 'core/irq.inc'
|
|
include 'services/display.inc'
|
|
include 'services/clipboard.inc'
|
|
include 'services/shared_folder.inc'
|
|
|
|
; =============================================================================
|
|
; Driver Entry Point
|
|
; =============================================================================
|
|
|
|
proc START c, state:dword, cmdline:dword
|
|
push ebx esi edi
|
|
cmp [state], DRV_ENTRY
|
|
jne .exit
|
|
|
|
.entry:
|
|
DEBUGF 1, "[VBoxGuest] ========================================\n"
|
|
DEBUGF 1, "[VBoxGuest] VBoxGuest Driver v1.3\n"
|
|
DEBUGF 1, "[VBoxGuest] Clipboard + Display + Dual-level Errors\n"
|
|
DEBUGF 1, "[VBoxGuest] ========================================\n"
|
|
|
|
; 1. Find PCI device
|
|
stdcall detect
|
|
test eax, eax
|
|
jz .fail
|
|
|
|
; 2. Initialize device (BAR, IRQ, MMIO)
|
|
stdcall vmmdev_init, ebx
|
|
test eax, eax
|
|
jnz .fail
|
|
|
|
stdcall vbox_service_init
|
|
|
|
; 3. Send guest info
|
|
call vmmdev_send_guest_info
|
|
test eax, eax
|
|
jnz .fail
|
|
|
|
; 4. Set capabilities
|
|
call vmmdev_set_guest_caps
|
|
test eax, eax
|
|
jnz .fail
|
|
|
|
; 7. Enable interrupts
|
|
call vmmdev_enable_interrupts
|
|
|
|
|
|
; 5. Initialize prepared packets
|
|
call init_packets
|
|
|
|
; 6. Initialize clipboard
|
|
call clipboard_init
|
|
test eax, eax
|
|
jnz .clipboard_failed
|
|
DEBUGF 2, "[VBoxGuest] Clipboard initialized successfully\n"
|
|
jmp .clipboard_ok
|
|
.clipboard_failed:
|
|
DEBUGF 1, "[VBoxGuest] Clipboard initialization failed (non-fatal)\n"
|
|
.clipboard_ok:
|
|
|
|
call sf_init
|
|
|
|
; 8. Set initial display
|
|
call display_change
|
|
|
|
; 9. Register service
|
|
invoke RegService, service_name, service_proc
|
|
|
|
DEBUGF 1, "[VBoxGuest] ========================================\n"
|
|
DEBUGF 1, "[VBoxGuest] Initialization complete!\n"
|
|
DEBUGF 1, "[VBoxGuest] ========================================\n"
|
|
|
|
pop edi esi ebx
|
|
ret
|
|
|
|
.fail:
|
|
DEBUGF 1, "[VBoxGuest] Initialization FAILED\n"
|
|
|
|
.exit:
|
|
pop edi esi ebx
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
; =============================================================================
|
|
; Service Procedure
|
|
; =============================================================================
|
|
|
|
proc service_proc stdcall, ioctl:dword
|
|
mov ebx, [ioctl]
|
|
mov eax, [ebx + IOCTL.io_code]
|
|
cmp eax, SRV_GETVERSION
|
|
jne .fail
|
|
|
|
mov eax, [ebx + IOCTL.output]
|
|
cmp [ebx + IOCTL.out_size], 4
|
|
jne .fail
|
|
|
|
mov dword [eax], API_VERSION
|
|
xor eax, eax
|
|
ret
|
|
|
|
.fail:
|
|
or eax, -1
|
|
ret
|
|
endp
|
|
|
|
; =============================================================================
|
|
; Detect VirtualBox PCI Device
|
|
; =============================================================================
|
|
|
|
proc detect stdcall
|
|
invoke GetPCIList
|
|
mov ebx, eax
|
|
|
|
.next_dev:
|
|
mov eax, [eax + PCIDEV.fd]
|
|
cmp eax, ebx
|
|
jz .not_found
|
|
|
|
mov edx, [eax + PCIDEV.vendor_device_id]
|
|
cmp edx, (VBOX_DEVICE_ID shl 16) + VBOX_VENDOR_ID
|
|
jne .next_dev
|
|
|
|
.found:
|
|
DEBUGF 2, "[VBoxGuest] VirtualBox device found\n"
|
|
mov ebx, eax
|
|
mov eax, 1
|
|
ret
|
|
|
|
.not_found:
|
|
DEBUGF 1, "[VBoxGuest] VirtualBox device NOT found\n"
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
; =============================================================================
|
|
; Initialize Prepared Packets
|
|
; =============================================================================
|
|
|
|
proc init_packets
|
|
; ACK events packet
|
|
mov eax, vmmdev_ack
|
|
mov [vbox_device.ack_virt], eax
|
|
invoke GetPhysAddr
|
|
mov [vbox_device.ack_phys], eax
|
|
|
|
; Display change packet
|
|
mov eax, vmmdev_display
|
|
mov [vbox_device.display_virt], eax
|
|
invoke GetPhysAddr
|
|
mov [vbox_device.display_phys], eax
|
|
|
|
DEBUGF 2, "[VBoxGuest] Packets initialized\n"
|
|
ret
|
|
endp
|
|
|
|
; =============================================================================
|
|
; Data Section
|
|
; =============================================================================
|
|
align 4
|
|
service_name db 'VBOXGUEST', 0
|
|
|
|
align 4
|
|
; VBox device structure
|
|
vbox_device VBOX_DEVICE
|
|
|
|
include_debug_strings
|
|
|
|
align 4
|
|
data fixups
|
|
end data
|