def __init__(self, domain, init_flags=INIT_DOMAINNAME, init_data=ffi.NULL, config_mode=VMIConfig.GLOBAL_FILE_ENTRY, config=ffi.NULL, mode=None, partial=False): self.vmi = ffi.NULL self.opaque_vmi = ffi.new("vmi_instance_t *") init_error = ffi.new("vmi_init_error_t *") # avoid GC to free ghashtable inserted values ghash_ref = dict() ghash = None if partial: # vmi_init if not mode: # calling vmi_get_access_mode to auto determine vmi_mode mode = self.get_access_mode(domain, init_flags, init_data) if not isinstance(mode, VMIMode): raise RuntimeError("mode is not an instance of VMIMode") if not init_flags & INIT_DOMAINNAME and not init_flags & INIT_DOMAINID: raise RuntimeError( "Partial init, init_flags must be either INIT_DOMAINAME or INIT_DOMAINID" ) domain = domain.encode() status = lib.vmi_init(self.opaque_vmi, mode.value, domain, init_flags, init_data, init_error) else: # vmi_init_complete # if INIT_DOMAINNAME, we need to encode the string from str to bytes if init_flags & INIT_DOMAINNAME or init_flags & INIT_DOMAINID: domain = domain.encode() # same for VMI_CONFIG_STRING if config_mode == VMIConfig.STRING: config = config.encode() elif config_mode == VMIConfig.DICT: # need to convert config to a GHashTable g_str_hash_addr = ffi.addressof(glib, "g_str_hash") g_str_equal_addr = ffi.addressof(glib, "g_str_equal") ghash = glib.g_hash_table_new(g_str_hash_addr, g_str_equal_addr) for k, v in list(config.items()): key = k.encode() if isinstance(v, str): value = v.encode() elif isinstance(v, int): value = ffi.new("int*", v) else: raise RuntimeError( "Invalid value {} in config hash".format(v)) glib.g_hash_table_insert(ghash, key, value) # keep a reference to avoid GC ghash_ref[key] = value config = ghash # init libvmi status = lib.vmi_init_complete(self.opaque_vmi, domain, init_flags, init_data, config_mode.value, config, init_error) error_msg = LibvmiInitError(init_error[0]).name check(status, error_msg) # store handle to real vmi_instance_t self.vmi = self.opaque_vmi[0] # destroy ghashtable if necessary if ghash is not None: glib.g_hash_table_destroy(ghash)
def __init__(self, domain, init_flags=INIT_DOMAINNAME, init_data=None, config_mode=VMIConfig.GLOBAL_FILE_ENTRY, config=ffi.NULL, mode=None, partial=False): self.vmi = ffi.NULL self.opaque_vmi = ffi.new("vmi_instance_t *") init_error = ffi.new("vmi_init_error_t *") # avoid GC to free ghashtable inserted values ghash_ref = dict() ghash = None # keep references on ffi buffers, avoid issues with GC ffi_refs = {'init_data': []} init_data_ffi = ffi.NULL if init_data: init_data_ffi = ffi.new("vmi_init_data_t *", {"entry": len(init_data)}) init_data_ffi.count = len(init_data) for i, (e_type, e_value) in enumerate(init_data.items()): init_data_ffi.entry[i].type = e_type.value if not isinstance(e_value, str): raise RuntimeError( "Passing anything else than a string as init_data value is not implemented" ) ref = e_value.encode() init_data_ffi.entry[i].data = ffi.from_buffer(ref) # keep a ref ! ffi_refs['init_data'].append(ref) if partial: # vmi_init if not mode: # calling vmi_get_access_mode to auto determine vmi_mode mode = self.get_access_mode(domain, init_flags, init_data_ffi) if not isinstance(mode, VMIMode): raise RuntimeError("mode is not an instance of VMIMode") if (not init_flags & INIT_DOMAINNAME and not init_flags & INIT_DOMAINID): raise RuntimeError("Partial init, init_flags must be either" "INIT_DOMAINAME or INIT_DOMAINID") domain = domain.encode() status = lib.vmi_init(self.opaque_vmi, mode.value, domain, init_flags, init_data_ffi, init_error) else: # vmi_init_complete # if INIT_DOMAINNAME, we need to encode the string # from str to bytes if init_flags & INIT_DOMAINNAME or init_flags & INIT_DOMAINID: domain = domain.encode() # same for VMI_CONFIG_STRING if config_mode == VMIConfig.STRING: config = config.encode() elif config_mode == VMIConfig.DICT: # need to convert config to a GHashTable g_str_hash_addr = ffi.addressof(lib, "g_str_hash") g_str_equal_addr = ffi.addressof(lib, "g_str_equal") ghash = lib.g_hash_table_new(g_str_hash_addr, g_str_equal_addr) for k, v in list(config.items()): key = k.encode() if isinstance(v, str): value = v.encode() elif isinstance(v, int): value = ffi.new("int*", v) else: raise RuntimeError( "Invalid value {} in config".format(v)) lib.g_hash_table_insert(ghash, key, value) # keep a reference to avoid GC ghash_ref[key] = value config = ghash # init libvmi status = lib.vmi_init_complete(self.opaque_vmi, domain, init_flags, init_data_ffi, config_mode.value, config, init_error) error_msg = LibvmiInitError(init_error[0]).name check(status, error_msg) # store handle to real vmi_instance_t self.vmi = self.opaque_vmi[0] # destroy ghashtable if necessary if ghash is not None: lib.g_hash_table_destroy(ghash)