Files
kolibrios/drivers/vboxguest/core/dispatcher/dispatcher.inc
lex ab59015ded
Some checks failed
Build system / Check kernel codestyle (pull_request) Has been cancelled
Build system / Build (pull_request) Has been cancelled
Add VBoxGuest driver code
2026-03-04 21:16:17 +03:00

346 lines
7.6 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
; =============================================================================
; Модуль : Service Dispatcher
; Файл : core/dispatcher.inc
; Назначение : Функции диспетчера сервисов
; =============================================================================
include 'dispatcher_macros.inc'
; =============================================================================
; Данные диспетчера
; =============================================================================
align 4
dispatcher_active_events dd 0 ; OR всех event_mask включенных сервисов
dispatcher_active_caps dd 0 ; OR всех caps_mask включенных сервисов
; dispatcher_find_by_id — Найти сервис по ID
;
; Вход : svc_id — числовой идентификатор сервиса
; Выход: eax = SERVICE_ENTRY* или 0 если не найден
proc dispatcher_find_by_id stdcall uses ecx esi, svc_id:dword
mov ecx, [services_count]
test ecx, ecx
jz .not_found
mov esi, services_table
mov eax, [svc_id]
.loop:
cmp [esi + SERVICE_ENTRY.id], eax
je .found
add esi, sizeof.SERVICE_ENTRY
dec ecx
jnz .loop
.not_found:
xor eax, eax
ret
.found:
mov eax, esi
ret
endp
; Включить сервис по ID
proc dispatcher_enable_by_id stdcall, svc_id:dword
stdcall dispatcher_find_by_id, [svc_id]
test eax, eax
jz .not_found
stdcall dispatcher_enable_entry, eax
ret
.not_found:
mov eax, -1
ret
endp
; Выключить сервис по ID
proc dispatcher_disable_by_id stdcall, svc_id:dword
stdcall dispatcher_find_by_id, [svc_id]
test eax, eax
jz .not_found
stdcall dispatcher_disable_entry, eax
ret
.not_found:
mov eax, -1
ret
endp
; Включить сервис по указателю на SERVICE_ENTRY
proc dispatcher_enable_entry stdcall uses ebx esi, entry_ptr:dword
mov esi, [entry_ptr]
; Уже включен?
cmp dword [esi + SERVICE_ENTRY.enabled], 1
je .already_enabled
; Вызвать fn_enable если есть
mov eax, [esi + SERVICE_ENTRY.fn_enable]
test eax, eax
jz .no_enable_fn
push esi
call eax
pop esi
test eax, eax
jnz .enable_failed
.no_enable_fn:
; Включить
mov dword [esi + SERVICE_ENTRY.enabled], 1
; Добавить маски
mov eax, [esi + SERVICE_ENTRY.event_mask]
or [dispatcher_active_events], eax
mov eax, [esi + SERVICE_ENTRY.caps_mask]
or [dispatcher_active_caps], eax
DEBUGF 2, "[VBoxGuest] [Dispatcher] Enabled service ID=%d\n", [esi + SERVICE_ENTRY.id]
.already_enabled:
xor eax, eax
ret
.enable_failed:
DEBUGF 2, "[VBoxGuest] [Dispatcher] Enable failed: 0x%x\n", eax
ret
endp
; Выключить сервис по указателю
proc dispatcher_disable_entry stdcall uses ebx esi, entry_ptr:dword
mov esi, [entry_ptr]
; Уже выключен?
cmp dword [esi + SERVICE_ENTRY.enabled], 0
je .already_disabled
; Вызвать fn_disable если есть
mov eax, [esi + SERVICE_ENTRY.fn_disable]
test eax, eax
jz .no_disable_fn
push esi
call eax
pop esi
.no_disable_fn:
; Выключить
mov dword [esi + SERVICE_ENTRY.enabled], 0
; Пересчитать активные маски
call dispatcher_recalc_masks
DEBUGF 2, "[VBoxGuest] [Dispatcher] Disabled service ID=%d\n", [esi + SERVICE_ENTRY.id]
.already_disabled:
xor eax, eax
ret
endp
; dispatcher_disable_all — Выключить все сервисы
proc dispatcher_disable_all uses ecx esi
DEBUGF 2, "[VBoxGuest] [Dispatcher] Disabling all services\n"
mov ecx, [services_count]
test ecx, ecx
jz .done
mov esi, services_table
.loop:
stdcall dispatcher_disable_entry, esi
add esi, sizeof.SERVICE_ENTRY
dec ecx
jnz .loop
.done:
ret
endp
; Инициализация всех сервисов
proc dispatcher_init_all uses ebx ecx esi
DEBUGF 2, "[VBoxGuest] [Dispatcher] Initializing %d services...\n", [services_count]
mov ecx, [services_count]
test ecx, ecx
jz .done
mov esi, services_table
.loop:
mov eax, [esi + SERVICE_ENTRY.fn_init]
test eax, eax
jz .next
DEBUGF 2, "[VBoxGuest] [Dispatcher] Init service ID=%d, name=%s\n", [esi + SERVICE_ENTRY.id], [esi + SERVICE_ENTRY.name_ptr]
push ecx esi
call eax
pop esi ecx
test eax, eax
jnz .init_failed
.next:
add esi, sizeof.SERVICE_ENTRY
dec ecx
jnz .loop
.done:
DEBUGF 2, "[VBoxGuest] [Dispatcher] All services initialized\n"
xor eax, eax
ret
.init_failed:
DEBUGF 2, "[VBoxGuest] [Dispatcher] Service ID=%d init failed: 0x%x\n", [esi + SERVICE_ENTRY.id], eax
jmp .next
endp
; Включить сервисы с autostart=1
proc dispatcher_enable_autostart uses ecx esi
DEBUGF 2, "[VBoxGuest] [Dispatcher] Enabling autostart services...\n"
mov ecx, [services_count]
test ecx, ecx
jz .done
mov esi, services_table
.loop:
cmp dword [esi + SERVICE_ENTRY.autostart], 1
jne .next
push ecx esi
stdcall dispatcher_enable_entry, esi
pop esi ecx
.next:
add esi, sizeof.SERVICE_ENTRY
dec ecx
jnz .loop
.done:
DEBUGF 2, "[VBoxGuest] [Dispatcher] Autostart done, events=0x%x, caps=0x%x\n", \
[dispatcher_active_events], [dispatcher_active_caps]
ret
endp
; Пересчитать активные маски
proc dispatcher_recalc_masks uses ebx ecx edx esi
xor edx, edx ; events
xor ebx, ebx ; caps
mov ecx, [services_count]
test ecx, ecx
jz .done
mov esi, services_table
.loop:
cmp dword [esi + SERVICE_ENTRY.enabled], 1
jne .next
or edx, [esi + SERVICE_ENTRY.event_mask]
or ebx, [esi + SERVICE_ENTRY.caps_mask]
.next:
add esi, sizeof.SERVICE_ENTRY
dec ecx
jnz .loop
.done:
mov [dispatcher_active_events], edx
mov [dispatcher_active_caps], ebx
ret
endp
; Разослать события включенным сервисам
proc dispatcher_dispatch stdcall uses ebx ecx edx esi, event_mask:dword
mov edx, [event_mask]
test edx, edx
jz .done
mov ecx, [services_count]
test ecx, ecx
jz .done
mov esi, services_table
.loop:
; Включен?
cmp dword [esi + SERVICE_ENTRY.enabled], 0
je .next
; Есть совпадение событий?
mov eax, [esi + SERVICE_ENTRY.event_mask]
test eax, edx
jz .next
; Есть обработчик?
mov eax, [esi + SERVICE_ENTRY.fn_on_event]
test eax, eax
jz .next
; Вызвать fn_on_event(event_mask)
push ecx edx esi
mov eax, edx
call [esi + SERVICE_ENTRY.fn_on_event]
pop esi edx ecx
.next:
add esi, sizeof.SERVICE_ENTRY
dec ecx
jnz .loop
.done:
ret
endp
; Вызвать fn_on_tick у включенных сервисов
proc dispatcher_tick_all uses eax ecx esi
mov ecx, [services_count]
test ecx, ecx
jz .done
mov esi, services_table
.loop:
cmp dword [esi + SERVICE_ENTRY.enabled], 0
je .next
mov eax, [esi + SERVICE_ENTRY.fn_on_tick]
test eax, eax
jz .next
push ecx esi
call eax
pop esi ecx
.next:
add esi, sizeof.SERVICE_ENTRY
dec ecx
jnz .loop
.done:
ret
endp
; Получить активную маску событий
proc dispatcher_get_active_events
mov eax, [dispatcher_active_events]
ret
endp
; Получить активную маску capabilities
proc dispatcher_get_active_caps
mov eax, [dispatcher_active_caps]
ret
endp