status_tvmi_register_event( vmi_instance_t vmi, vmi_event_t* event){ status_t rc = VMI_FAILURE;#ifdef ENABLE_SAFETY_CHECKS if (!vmi) { dbprint(VMI_DEBUG_EVENTS, "LibVMI wasn't initialized!\n"); return VMI_FAILURE; } if (!(vmi->init_flags & (VMI_INIT_EVENTS | VMI_INIT_DOMAINWATCH))) { dbprint(VMI_DEBUG_EVENTS, "LibVMI wasn't initialized with events!\n"); return VMI_FAILURE; } if (!event) { dbprint(VMI_DEBUG_EVENTS, "No event given!\n"); return VMI_FAILURE; } if (event->version > VMI_EVENTS_VERSION) { dbprint(VMI_DEBUG_EVENTS, "The caller requires a newer version of LibVMI!\n"); return VMI_FAILURE; } if (event->version < VMI_EVENTS_VERSION) { /* * Note: backwards-compatibility can be implemented by defining an internal * header for the older ABI and handling the calls according to the version * that was requested. * This is left as a TODO for when it becomes necessary. */ dbprint(VMI_DEBUG_EVENTS, "The caller requires an older version of LibVMI!\n"); return VMI_FAILURE; } if (!event->callback) { dbprint(VMI_DEBUG_EVENTS, "No event callback function specified!\n"); return VMI_FAILURE; }#endif switch (event->type) { case VMI_EVENT_REGISTER: rc = register_reg_event(vmi, event); break; case VMI_EVENT_MEMORY: rc = register_mem_event(vmi, event); break; case VMI_EVENT_SINGLESTEP: rc = register_singlestep_event(vmi, event); break; case VMI_EVENT_INTERRUPT: rc = register_interrupt_event(vmi, event); break; case VMI_EVENT_GUEST_REQUEST: rc = register_guest_requested_event(vmi, event); break; case VMI_EVENT_CPUID: rc = register_cpuid_event(vmi, event); break; case VMI_EVENT_DEBUG_EXCEPTION: rc = register_debug_event(vmi, event); break; case VMI_EVENT_PRIVILEGED_CALL: rc = register_privcall_event(vmi, event); break; case VMI_EVENT_DESCRIPTOR_ACCESS: rc = register_desc_access_event(vmi, event); break; case VMI_EVENT_FAILED_EMULATION: rc = register_failed_emulation_event(vmi, event); break; case VMI_EVENT_DOMAIN_WATCH: rc = register_watch_domain_event(vmi, event); break; default: dbprint(VMI_DEBUG_EVENTS, "Unknown event type: %d\n", event->type); break; } return rc;}