From 3dc843b3f7991dcd738a30821ff56c7fe13f1094 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Wed, 18 Sep 2019 00:06:54 +0200 Subject: Kept tracks of current active DB items. --- plugins/pychrysalide/analysis/db/constants.c | 1 + plugins/pychrysalide/analysis/db/constants.h | 2 + src/analysis/db/cdb.c | 9 ++- src/analysis/db/client.c | 2 +- src/analysis/db/collection-int.h | 3 +- src/analysis/db/collection.c | 57 +++++++++++++++--- src/analysis/db/item-int.h | 9 +++ src/analysis/db/item.c | 53 +++++++++++++++++ src/analysis/db/item.h | 11 +++- src/analysis/db/items/bookmark.c | 87 +++++++++++++++++++++++++--- src/arch/vmpa.c | 27 +++++++++ src/arch/vmpa.h | 3 + src/gui/panels/bookmarks.c | 4 +- src/gui/panels/history.c | 4 +- 14 files changed, 243 insertions(+), 29 deletions(-) diff --git a/plugins/pychrysalide/analysis/db/constants.c b/plugins/pychrysalide/analysis/db/constants.c index 9c628f9..46d0876 100644 --- a/plugins/pychrysalide/analysis/db/constants.c +++ b/plugins/pychrysalide/analysis/db/constants.c @@ -93,6 +93,7 @@ bool define_db_item_constants(PyTypeObject *type) result = add_const_to_group(values, "NONE", DIF_NONE); if (result) result = add_const_to_group(values, "ERASER", DIF_ERASER); + if (result) result = add_const_to_group(values, "UPDATED", DIF_UPDATED); if (result) result = add_const_to_group(values, "VOLATILE", DIF_VOLATILE); if (result) result = add_const_to_group(values, "BROKEN", DIF_BROKEN); diff --git a/plugins/pychrysalide/analysis/db/constants.h b/plugins/pychrysalide/analysis/db/constants.h index cb7edf4..5f0afeb 100644 --- a/plugins/pychrysalide/analysis/db/constants.h +++ b/plugins/pychrysalide/analysis/db/constants.h @@ -30,6 +30,8 @@ #include +/* Définit les constantes relatives au protocole. */ +bool define_db_protocol_constants(PyTypeObject *); /* Définit les constantes pour les éléments de base de données. */ bool define_db_item_constants(PyTypeObject *); diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c index 597242f..a787a19 100644 --- a/src/analysis/db/cdb.c +++ b/src/analysis/db/cdb.c @@ -146,7 +146,7 @@ static bool g_cdb_archive_create_db(const GCdbArchive *); static bool g_cdb_archive_load_collections(GCdbArchive *); /* Réagit à une modification au sein d'une collection donnée. */ -static void on_collection_changed(GDbCollection *, DBAction, GDbItem *, GCdbArchive *); +static void on_collection_extended(GDbCollection *, GDbItem *, GCdbArchive *); /* Assure le traitement des requêtes de clients. */ static void *g_cdb_archive_process(GCdbArchive *); @@ -742,7 +742,7 @@ static bool g_cdb_archive_load_collections(GCdbArchive *archive) iter = g_list_next(iter)) { collec = G_DB_COLLECTION(iter->data); - g_signal_connect(collec, "content-changed", G_CALLBACK(on_collection_changed), archive); + g_signal_connect(collec, "content-extended", G_CALLBACK(on_collection_extended), archive); if (!g_db_collection_load_all_items(collec, archive->db)) return false; @@ -757,7 +757,6 @@ static bool g_cdb_archive_load_collections(GCdbArchive *archive) /****************************************************************************** * * * Paramètres : collec = collection dont le contenu a évolué. * -* action = type d'évolution rencontrée. * * item = élément ajouté, modifié ou supprimé. * * archive = centralisation de tous les savoirs. * * * @@ -769,7 +768,7 @@ static bool g_cdb_archive_load_collections(GCdbArchive *archive) * * ******************************************************************************/ -static void on_collection_changed(GDbCollection *collec, DBAction action, GDbItem *item, GCdbArchive *archive) +static void on_collection_extended(GDbCollection *collec, GDbItem *item, GCdbArchive *archive) { packed_buffer pbuf; /* Tampon d'émission */ size_t i; /* Boucle de parcours */ @@ -777,7 +776,7 @@ static void on_collection_changed(GDbCollection *collec, DBAction action, GDbIte init_packed_buffer(&pbuf); - status = g_db_collection_pack(collec, &pbuf, action, item); + status = g_db_collection_pack(collec, &pbuf, DBA_ADD_ITEM, item); g_mutex_lock(&archive->clients_access); diff --git a/src/analysis/db/client.c b/src/analysis/db/client.c index 3197a8c..744fa57 100644 --- a/src/analysis/db/client.c +++ b/src/analysis/db/client.c @@ -789,7 +789,7 @@ static void *g_hub_client_update(GHubClient *client) status = extract_packed_buffer(&in_pbuf, &tmp8, sizeof(uint8_t), true); if (!status) goto gdcu_bad_exchange; - client->can_get_updates = (tmp8 == 0x1); + client->can_get_updates = (tmp8 == 0x0); break; } diff --git a/src/analysis/db/collection-int.h b/src/analysis/db/collection-int.h index c2d1282..b3b83bb 100644 --- a/src/analysis/db/collection-int.h +++ b/src/analysis/db/collection-int.h @@ -60,6 +60,7 @@ struct _GDbCollection GList *items; /* Eléments rassemblés */ GList *sorted; /* Eléments triés */ + GHashTable *last_items; /* Statuts courants d'éléments */ GRWLock params_access; /* Verrou de protection */ }; @@ -76,7 +77,7 @@ struct _GDbCollectionClass /* Signaux */ - void (* content_changed) (GDbCollection *, DBAction, GDbItem *); + void (* content_extended) (GDbCollection *, GDbItem *); }; diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c index 33145a6..f728718 100644 --- a/src/analysis/db/collection.c +++ b/src/analysis/db/collection.c @@ -106,13 +106,13 @@ static void g_db_collection_class_init(GDbCollectionClass *klass) klass->setup_load = (collec_setup_load_fc)_g_db_collection_setup_load; - g_signal_new("content-changed", + g_signal_new("content-extended", G_TYPE_DB_COLLECTION, G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GDbCollectionClass, content_changed), + G_STRUCT_OFFSET(GDbCollectionClass, content_extended), NULL, NULL, - g_cclosure_user_marshal_VOID__ENUM_OBJECT, - G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_OBJECT); + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); } @@ -133,6 +133,11 @@ static void g_db_collection_init(GDbCollection *collec) { collec->binary = NULL; + collec->last_items = g_hash_table_new_full((GHashFunc)g_db_item_hash_key, + (GEqualFunc)g_db_item_cmp_key, + (GDestroyNotify)g_object_unref, + (GDestroyNotify)g_object_unref); + g_rw_lock_init(&collec->params_access); } @@ -654,6 +659,7 @@ bool g_db_collection_has_item(GDbCollection *collec, GDbItem *item) bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock) { bool result; /* Bilan à faire remonter */ + GDbItem *prev; /* Elément similaire précédent */ result = true; @@ -666,7 +672,40 @@ bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock) g_object_ref(G_OBJECT(item)); collec->sorted = g_list_insert_sorted(collec->sorted, item, (GCompareFunc)g_db_item_compare_with_timestamp); - g_signal_emit_by_name(collec, "content-changed", DBA_ADD_ITEM, item); + prev = g_hash_table_lookup(collec->last_items, item); + + if (prev != NULL) + { + g_object_ref(G_OBJECT(prev)); + + if (g_db_item_get_flags(item) & DIF_ERASER) + g_hash_table_remove(collec->last_items, prev); + + else + { + g_db_item_add_flag(item, DIF_UPDATED); + + g_object_ref(G_OBJECT(item)); + g_object_ref(G_OBJECT(item)); + + g_hash_table_replace(collec->last_items, item, item); + + } + + g_object_unref(G_OBJECT(prev)); + + } + + else + { + g_object_ref(G_OBJECT(item)); + g_object_ref(G_OBJECT(item)); + + g_hash_table_add(collec->last_items, item); + + } + + g_signal_emit_by_name(collec, "content-extended", item); if (lock) g_db_collection_wunlock(collec); @@ -718,7 +757,7 @@ bool _g_db_collection_remove_item(GDbCollection *collec, GDbItem *item, bool loc collec->items = g_list_delete_link(collec->items, found); if (signal) - g_signal_emit_by_name(collec, "content-changed", DBA_REM_ITEM, internal); + ;//g_signal_emit_by_name(collec, "content-changed", DBA_REM_ITEM, internal); g_object_unref(G_OBJECT(internal)); g_object_unref(G_OBJECT(internal)); @@ -816,7 +855,7 @@ bool _g_db_collection_update_item_activity(GDbCollection *collec, GDbItem *item, result = g_db_item_set_activity(internal, collec->binary, timestamp); - g_signal_emit_by_name(collec, "content-changed", DBA_CHANGE_STATE, internal); + //g_signal_emit_by_name(collec, "content-changed", DBA_CHANGE_STATE, internal); } @@ -863,7 +902,7 @@ GList *g_db_collection_set_last_active(GDbCollection *collec, timestamp_t timest { /* ... */g_db_item_set_activity(item, collec->binary, NULL); /* ... */g_db_collection_store_updated_item(collec, item, db); - g_signal_emit_by_name(collec, "content-changed", DBA_CHANGE_STATE, item); + //g_signal_emit_by_name(collec, "content-changed", DBA_CHANGE_STATE, item); } } @@ -911,7 +950,7 @@ bool g_db_collection_set_inactive(GDbCollection *collec, GDbItem *item, timestam result = g_db_item_set_activity(item, collec->binary, timestamp); - g_signal_emit_by_name(collec, "content-changed", DBA_CHANGE_STATE, item); + //g_signal_emit_by_name(collec, "content-changed", DBA_CHANGE_STATE, item); return result; diff --git a/src/analysis/db/item-int.h b/src/analysis/db/item-int.h index a6398f9..8bba8a3 100644 --- a/src/analysis/db/item-int.h +++ b/src/analysis/db/item-int.h @@ -36,6 +36,12 @@ +/* Calcule le condensat associé à l'élément vu comme clef. */ +typedef guint (* hash_db_item_key_fc) (const GDbItem *); + +/* Compare deux éléments en tant que clefs. */ +typedef gboolean (* cmp_db_item_key_fc) (const GDbItem *, const GDbItem *); + /* Effectue la comparaison entre deux éléments de collection. */ typedef gint (* cmp_db_item_fc) (GDbItem *, GDbItem *, bool); @@ -84,6 +90,9 @@ struct _GDbItemClass DBFeatures feature; /* Fonctionnalité représentée */ + hash_db_item_key_fc hash_key; /* Condensat de l'élément */ + cmp_db_item_key_fc cmp_key; /* Comparaison en tant que clef*/ + cmp_db_item_fc cmp; /* Comparaison entre éléments */ unpack_db_item_fc unpack; /* Réception depuis le réseau */ diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c index 2eb31b1..efa2cdf 100644 --- a/src/analysis/db/item.c +++ b/src/analysis/db/item.c @@ -205,6 +205,59 @@ void g_db_item_set_server_side(GDbItem *item) /****************************************************************************** * * +* Paramètres : item = élément de collection à consulter. * +* * +* Description : Calcule le condensat associé à l'élément vu comme clef. * +* * +* Retour : Condensat associé à l'élément. * +* * +* Remarques : - * +* * +******************************************************************************/ + +guint g_db_item_hash_key(const GDbItem *item) +{ + guint result; /* Valeur "unique" à renvoyer */ + GDbItemClass *class; /* Classe liée à l'instance */ + + class = G_DB_ITEM_GET_CLASS(item); + + result = class->hash_key(item); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : a = premier élément de collection à consulter. * +* b = second élément de collection à consulter. * +* * +* Description : Compare deux éléments en tant que clefs. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gboolean g_db_item_cmp_key(const GDbItem *a, const GDbItem *b) +{ + gboolean result; /* Bilan à retourner */ + GDbItemClass *class; /* Classe liée à l'instance */ + + class = G_DB_ITEM_GET_CLASS(a); + + result = class->cmp_key(a, b); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : a = premier élément à analyser. * * b = second élément à analyser. * * with = précise les horodatages à prendre en compte. * diff --git a/src/analysis/db/item.h b/src/analysis/db/item.h index dfc97fd..395a56f 100644 --- a/src/analysis/db/item.h +++ b/src/analysis/db/item.h @@ -45,8 +45,9 @@ typedef enum _DbItemFlags { DIF_NONE = (0 << 0), /* Propriétés par défaut */ DIF_ERASER = (1 << 0), /* Suppression de l'effet */ - DIF_VOLATILE = (1 << 1), /* Abscence de sauvegarde */ - DIF_BROKEN = (1 << 2), /* Application impossible */ + DIF_UPDATED = (1 << 1), /* Mise à jour de l'élément */ + DIF_VOLATILE = (1 << 2), /* Abscence de sauvegarde */ + DIF_BROKEN = (1 << 3), /* Application impossible */ } DbItemFlags; @@ -75,6 +76,12 @@ DBFeatures g_db_item_get_feature(const GDbItem *); /* Indique à l'élément qu'il se trouve du côté serveur. */ void g_db_item_set_server_side(GDbItem *); +/* Calcule le condensat associé à l'élément vu comme clef. */ +guint g_db_item_hash_key(const GDbItem *); + +/* Compare deux éléments en tant que clefs. */ +gboolean g_db_item_cmp_key(const GDbItem *, const GDbItem *); + /* Effectue la comparaison entre deux éléments de collection. */ gint g_db_item_cmp(GDbItem *, GDbItem *, bool); diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c index 20f98ea..3d66f6b 100644 --- a/src/analysis/db/items/bookmark.c +++ b/src/analysis/db/items/bookmark.c @@ -73,6 +73,12 @@ static void g_db_bookmark_dispose(GDbBookmark *); /* Procède à la libération totale de la mémoire. */ static void g_db_bookmark_finalize(GDbBookmark *); +/* Calcule le condensat associé à l'élément vu comme clef. */ +static guint g_db_bookmark_hash_key(const GDbBookmark *); + +/* Compare deux éléments en tant que clefs. */ +static gboolean g_db_bookmark_cmp_key(const GDbBookmark *, const GDbBookmark *); + /* Effectue la comparaison entre deux signets de collection. */ static gint g_db_bookmark_cmp(GDbBookmark *, GDbBookmark *, bool); @@ -178,6 +184,9 @@ static void g_db_bookmark_class_init(GDbBookmarkClass *klass) item->feature = DBF_BOOKMARKS; + item->hash_key = (hash_db_item_key_fc)g_db_bookmark_hash_key; + item->cmp_key = (cmp_db_item_key_fc)g_db_bookmark_cmp_key; + item->cmp = (cmp_db_item_fc)g_db_bookmark_cmp; item->unpack = (unpack_db_item_fc)g_db_bookmark_unpack; @@ -319,6 +328,56 @@ bool g_db_bookmark_fill(GDbBookmark *bookmark, const vmpa2t *addr, const char *c /****************************************************************************** * * +* Paramètres : bookmark = élément de collection à consulter. * +* * +* Description : Calcule le condensat associé à l'élément vu comme clef. * +* * +* Retour : Condensat associé à l'élément. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static guint g_db_bookmark_hash_key(const GDbBookmark *bookmark) +{ + guint result; /* Valeur "unique" à renvoyer */ + + result = hash_vmpa(&bookmark->addr); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : a = premier élément de collection à consulter. * +* b = second élément de collection à consulter. * +* * +* Description : Compare deux éléments en tant que clefs. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean g_db_bookmark_cmp_key(const GDbBookmark *a, const GDbBookmark *b) +{ + gboolean result; /* Bilan à retourner */ + int ret; /* Bilan intermédiaire */ + + ret = cmp_vmpa(&a->addr, &b->addr); + + result = (ret == 0); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : a = premier élément à analyser. * * b = second élément à analyser. * * with = précise les horodatages à prendre en compte. * @@ -424,22 +483,36 @@ static char *g_db_bookmark_build_label(GDbBookmark *bookmark) { char *result; /* Description à retourner */ DbItemFlags flags; /* Propriétés de l'élément */ - const char *prefix; /* Préfixe à ajouter */ const char *text; /* Commentaire associé */ + const char *prefix; /* Préfixe à ajouter */ flags = g_db_item_get_flags(G_DB_ITEM(bookmark)); if (flags & DIF_ERASER) - prefix = _("Removed"); + asprintf(&result, _("Removed bookmark")); + + else if (flags & DIF_UPDATED) + { + text = get_rle_string(&bookmark->comment); + + if (text != NULL) + asprintf(&result, _("Updated bookmark: \"%s\""), text); + else + asprintf(&result, _("Reset bookmark")); + } + else + { prefix = _("Created"); - text = get_rle_string(&bookmark->comment); + text = get_rle_string(&bookmark->comment); - if (text != NULL) - asprintf(&result, _("%s bookmark \"%s\""), prefix, text); - else - asprintf(&result, _("%s empty bookmark"), prefix); + if (text != NULL) + asprintf(&result, _("%s bookmark \"%s\""), prefix, text); + else + asprintf(&result, _("%s empty bookmark"), prefix); + + } return result; diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index 70ea52b..bf97a37 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -172,6 +172,33 @@ void copy_vmpa(vmpa2t *dest, const vmpa2t *src) /****************************************************************************** * * +* Paramètres : addr = position à consulter. * +* * +* Description : Calcule une empreinte de localisation dans l'espace mémoire. * +* * +* Retour : Condensat déterminé pour la localisation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t hash_vmpa(const vmpa2t *addr) +{ + uint32_t result; /* Empreinte à retourner */ + + result = addr->physical; + result ^= (addr->physical >> 32); + + result ^= addr->virtual; + result ^= (addr->virtual >> 32); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : a = première définition à analyser. * * b = seconde définition à analyser. * * * diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index 8dfc646..66f8769 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -90,6 +90,9 @@ void delete_vmpa(vmpa2t *); /* Copie la définition d'un adressage dans un autre. */ void copy_vmpa(vmpa2t *, const vmpa2t *); +/* Calcule une empreinte de localisation dans l'espace mémoire. */ +uint32_t hash_vmpa(const vmpa2t *); + /* Compare entre elles deux adresses physiques. */ int cmp_vmpa_by_phy(const vmpa2t *, const vmpa2t *); diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c index 5fbc2fc..f32f9f5 100644 --- a/src/gui/panels/bookmarks.c +++ b/src/gui/panels/bookmarks.c @@ -450,8 +450,8 @@ static void reload_bookmarks_into_treeview(GBookmarksPanel *panel, GLoadedBinary g_object_ref(G_OBJECT(binary)); collec = g_loaded_binary_find_collection(binary, DBF_BOOKMARKS); - g_signal_connect_to_main(collec, "content-changed", G_CALLBACK(on_collection_content_changed), panel, - g_cclosure_user_marshal_VOID__ENUM_OBJECT); + //g_signal_connect_to_main(collec, "content-changed", G_CALLBACK(on_collection_content_changed), panel, + // g_cclosure_user_marshal_VOID__ENUM_OBJECT); } diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c index 3bdf77e..57e6a14 100644 --- a/src/gui/panels/history.c +++ b/src/gui/panels/history.c @@ -350,8 +350,8 @@ static void change_history_panel_current_content(GHistoryPanel *panel, GLoadedCo } - g_signal_connect_to_main(collections[k], "content-changed", G_CALLBACK(on_history_changed), panel, - g_cclosure_user_marshal_VOID__ENUM_OBJECT); + //g_signal_connect_to_main(collections[k], "content-changed", G_CALLBACK(on_history_changed), panel, + // g_cclosure_user_marshal_VOID__ENUM_OBJECT); g_object_unref(G_OBJECT(collections[k])); -- cgit v0.11.2-87-g4458