diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/analysis/Makefile.am | 2 | ||||
-rw-r--r-- | src/analysis/binary.c | 327 | ||||
-rw-r--r-- | src/analysis/binary.h | 35 | ||||
-rw-r--r-- | src/analysis/loaded-int.h | 79 | ||||
-rw-r--r-- | src/analysis/loaded.c | 362 | ||||
-rw-r--r-- | src/analysis/loaded.h | 92 | ||||
-rw-r--r-- | src/analysis/project.c | 491 | ||||
-rw-r--r-- | src/analysis/project.h | 34 | ||||
-rw-r--r-- | src/glibext/gloadedpanel-int.h | 9 | ||||
-rw-r--r-- | src/glibext/gloadedpanel.c | 52 | ||||
-rw-r--r-- | src/glibext/gloadedpanel.h | 21 | ||||
-rw-r--r-- | src/gtkext/graph/cluster.c | 7 | ||||
-rw-r--r-- | src/gtkext/gtkblockdisplay.c | 32 | ||||
-rw-r--r-- | src/gtkext/gtkblockdisplay.h | 3 | ||||
-rw-r--r-- | src/gtkext/gtkbufferdisplay.c | 10 | ||||
-rw-r--r-- | src/gtkext/gtkdisplaypanel-int.h | 4 | ||||
-rw-r--r-- | src/gtkext/gtkdisplaypanel.c | 175 | ||||
-rw-r--r-- | src/gtkext/gtkdisplaypanel.h | 6 | ||||
-rw-r--r-- | src/gui/editor.c | 90 | ||||
-rw-r--r-- | src/gui/menus/project.c | 41 | ||||
-rw-r--r-- | src/gui/menus/view.c | 66 |
21 files changed, 1270 insertions, 668 deletions
diff --git a/src/analysis/Makefile.am b/src/analysis/Makefile.am index 9e84753..c5f8c82 100755 --- a/src/analysis/Makefile.am +++ b/src/analysis/Makefile.am @@ -7,6 +7,8 @@ libanalysis_la_SOURCES = \ block.h block.c \ content-int.h \ content.h content.c \ + loaded-int.h \ + loaded.h loaded.c \ loading.h loading.c \ project.h project.c \ roptions.h roptions.c \ diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 7b0e528..5b2caf0 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -35,6 +35,7 @@ #include <i18n.h> +#include "loaded-int.h" #include "routine.h" #include "db/client.h" //#include "decomp/decompiler.h" @@ -47,7 +48,11 @@ #include "../core/global.h" #include "../core/params.h" #include "../core/processors.h" -#include "../glibext/chrysamarshal.h" +//#include "../glibext/chrysamarshal.h" +#include "../gtkext/easygtk.h" +#include "../gtkext/gtkblockdisplay.h" +#include "../gtkext/gtkdisplaypanel.h" +#include "../gtkext/gtkgraphdisplay.h" #include "../gui/panels/log.h" @@ -98,7 +103,6 @@ struct _GLoadedBinaryClass /* Signaux */ void (* disassembly_done) (GLoadedBinary *); - void (* display_changed) (GLoadedBinary *, BinaryView, BufferLineColumn); }; @@ -109,6 +113,9 @@ static void g_loaded_binary_class_init(GLoadedBinaryClass *); /* Initialise une description de fichier binaire. */ static void g_loaded_binary_init(GLoadedBinary *); +/* Procède à l'initialisation de l'interface de contenu chargé. */ +static void g_loaded_binary_interface_init(GLoadedContentInterface *); + /* Supprime toutes les références externes. */ static void g_loaded_binary_dispose(GLoadedBinary *); @@ -145,6 +152,28 @@ static bool g_loaded_binary_connect_remote(GLoadedBinary *); static void _g_loaded_binary_analyse(GLoadedBinary *, disassembly_ack_fc); +/* ---------------------- GESTION SOUS FORME DE CONTENU CHARGE ---------------------- */ + + +/* Fournit le désignation associée à l'élément chargé. */ +static const char *g_loaded_binary_describe(const GLoadedBinary *, bool); + +/* Détermine le nombre de vues disponibles pour un contenu. */ +static unsigned int g_loaded_binary_count_views(const GLoadedBinary *); + +/* Met en place la vue demandée pour un contenu binaire. */ +static GtkWidget *g_loaded_binary_build_view(GLoadedBinary *, unsigned int); + +/* Retrouve l'indice correspondant à la vue donnée d'un contenu. */ +static unsigned int g_loaded_binary_get_view_index(GLoadedBinary *, GtkWidget *); + +/* Fournit toutes les options d'affichage pour un contenu. */ +bool * const g_loaded_binary_get_all_display_options(const GLoadedBinary *, unsigned int); + +/* Définit une option d'affichage pour un contenu chargé. */ +static bool g_loaded_binary_set_display_option(GLoadedBinary *, unsigned int, unsigned int, bool); + + /* ---------------------------------------------------------------------------------- */ /* ENCADREMENTS D'UN BINAIRE CHARGE */ @@ -152,7 +181,8 @@ static void _g_loaded_binary_analyse(GLoadedBinary *, disassembly_ack_fc); /* Indique le type défini pour une description de fichier binaire. */ -G_DEFINE_TYPE(GLoadedBinary, g_loaded_binary, G_TYPE_OBJECT); +G_DEFINE_TYPE_WITH_CODE(GLoadedBinary, g_loaded_binary, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_LOADED_CONTENT, g_loaded_binary_interface_init)); /****************************************************************************** @@ -184,14 +214,6 @@ static void g_loaded_binary_class_init(GLoadedBinaryClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - g_signal_new("display-changed", - G_TYPE_LOADED_BINARY, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GLoadedBinaryClass, display_changed), - NULL, NULL, - g_cclosure_user_marshal_VOID__ENUM_ENUM, - G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); - } @@ -237,6 +259,32 @@ static void g_loaded_binary_init(GLoadedBinary *binary) /****************************************************************************** * * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de contenu chargé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_loaded_binary_interface_init(GLoadedContentInterface *iface) +{ + iface->describe = (describe_loaded_fc)g_loaded_binary_describe; + + iface->count_views = (count_loaded_views_fc)g_loaded_binary_count_views; + iface->build_view = (build_loaded_view_fc)g_loaded_binary_build_view; + iface->get_view_index = (get_loaded_view_index_fc)g_loaded_binary_get_view_index; + + iface->get_all_options = (get_all_loaded_options_fc)g_loaded_binary_get_all_display_options; + iface->set_option = (set_loaded_option_fc)g_loaded_binary_set_display_option; + +} + + +/****************************************************************************** +* * * Paramètres : binary = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * @@ -499,6 +547,7 @@ GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const ch * xdoc = structure XML en cours d'édition. * * context = contexte à utiliser pour les recherches. * * path = chemin d'accès réservé au binaire. * +* base = référence au lieu d'enregistrement du projet. * * * * Description : Ecrit une sauvegarde du binaire dans un fichier XML. * * * @@ -508,13 +557,12 @@ GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const ch * * ******************************************************************************/ -bool g_loaded_binary_save(const GLoadedBinary *binary, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path) +bool g_loaded_binary_save(const GLoadedBinary *binary, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path, const char *base) { bool result; /* Bilan à faire remonter */ char *content_path; /* Partie "Contenus" */ char *access; /* Chemin d'accès à un élément */ GBinContent *content; /* Contenu à référencer */ - const gchar *hash; /* Empreinte à mémoriser */ size_t debugs_count; /* Quantité de formats liés */ size_t i; /* Boucle de parcours */ GDbgFormat *debug; /* Informations de débogage */ @@ -524,33 +572,28 @@ bool g_loaded_binary_save(const GLoadedBinary *binary, xmlDocPtr xdoc, xmlXPathC content_path = strdup(path); content_path = stradd(content_path, "/Contents"); - access = strdup(content_path); - access = stradd(access, "/Main"); + asprintf(&access, "%s/Main", content_path); content = g_binary_format_get_content(G_BIN_FORMAT(binary->format)); - hash = g_binary_content_get_checksum(content); + result = g_binary_content_save(content, xdoc, context, access, base); g_object_unref(G_OBJECT(content)); - result = add_content_to_node(xdoc, context, access, hash); - free(access); debugs_count = g_exe_format_count_debug_info(binary->format); - for (i = 0; i < debugs_count; i++) + for (i = 0; i < debugs_count && result; i++) { asprintf(&access, "%s/DebugInfo[position()=%zu]", content_path, i); debug = g_exe_format_get_debug_info(binary->format, i); content = g_binary_format_get_content(G_BIN_FORMAT(debug)); - hash = g_binary_content_get_checksum(content); + result = g_binary_content_save(content, xdoc, context, access, base); g_object_unref(G_OBJECT(content)); g_object_unref(G_OBJECT(debug)); - result &= add_content_to_node(xdoc, context, access, hash); - free(access); } @@ -1625,56 +1668,6 @@ GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *binary, /****************************************************************************** * * -* Paramètres : binary = élément binaire à mettre à jour. * -* view = type de représentation visée. * -* col = indice de colonne dont l'affichage est à modifier. * -* state = nouvel état de l'affichage. * -* * -* Description : Définit si une colonne donnée doit apparaître dans le rendu. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_loaded_binary_set_column_display(GLoadedBinary *binary, BinaryView view, BufferLineColumn col, bool state) -{ - bool old; /* Ancien état à remplacer */ - - old = binary->col_display[view][col]; - - if (state != old) - { - binary->col_display[view][col] = state; - g_signal_emit_by_name(binary, "display-changed", view, col); - } - -} - - -/****************************************************************************** -* * -* Paramètres : binary = élément binaire à consulter. * -* view = type de représentation visée. * -* * -* Description : Indique quelles colonnes doivent apparaître dans le rendu. * -* * -* Retour : Consigne d'affichage. [OUT] * -* * -* Remarques : - * -* * -******************************************************************************/ - -const bool *g_loaded_binary_get_column_display(GLoadedBinary *binary, BinaryView view) -{ - return binary->col_display[view]; - -} - - -/****************************************************************************** -* * * Paramètres : binary = élément binaire à consulter. * * * * Description : Indique si les lignes doivent apparaître dans le rendu. * @@ -1760,3 +1753,193 @@ void ack_completed_disassembly(GDelayedDisassembly *disass, GLoadedBinary *binar g_signal_emit_by_name(binary, "disassembly-done"); } + + + +/* ---------------------------------------------------------------------------------- */ +/* GESTION SOUS FORME DE CONTENU CHARGE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : binary = élément chargé à consulter. * +* long = précise s'il s'agit d'une version longue ou non. * +* * +* Description : Fournit le désignation associée à l'élément chargé. * +* * +* Retour : Description courante. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *g_loaded_binary_describe(const GLoadedBinary *binary, bool full) +{ + const char *result; /* Description à retourner */ + GBinContent *content; /* Contenu binaire mannipulé */ + + content = g_binary_format_get_content(G_BIN_FORMAT(binary->format)); + + result = g_binary_content_describe(content, full); + + g_object_unref(G_OBJECT(content)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : binary = contenu chargé à consulter. * +* * +* Description : Détermine le nombre de vues disponibles pour un contenu. * +* * +* Retour : Quantité strictement positive. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static unsigned int g_loaded_binary_count_views(const GLoadedBinary *binary) +{ + return BVW_COUNT; + +} + + +/****************************************************************************** +* * +* Paramètres : binary = contenu chargé à consulter. * +* index = indice de la vue ciblée. * +* * +* Description : Met en place la vue demandée pour un contenu binaire. * +* * +* Retour : Composant graphique nouveau. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GtkWidget *g_loaded_binary_build_view(GLoadedBinary *binary, unsigned int index) +{ + GtkWidget *result; /* Support à retourner */ + GtkWidget *display; /* Composant d'affichage */ + + assert(index < g_loaded_binary_count_views(binary)); + + switch (index) + { + case BVW_BLOCK: + display = gtk_block_display_new(); + break; + + case BVW_GRAPH: + display = gtk_graph_display_new(); + break; + + default: + assert(false); + break; + } + + gtk_widget_show(display); + + g_loaded_panel_set_content(G_LOADED_PANEL(display), G_LOADED_CONTENT(binary)); + + result = qck_create_scrolled_window(NULL, NULL); + gtk_container_add(GTK_CONTAINER(result), display); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : binary = contenu chargé à consulter. * +* index = composant graphique en place. * +* * +* Description : Retrouve l'indice correspondant à la vue donnée d'un contenu.* +* * +* Retour : Indice de la vue représentée, ou -1 en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static unsigned int g_loaded_binary_get_view_index(GLoadedBinary *binary, GtkWidget *view) +{ + unsigned int result; /* Indice à retourner */ + + if (GTK_IS_BLOCK_DISPLAY(view)) + result = BVW_BLOCK; + + else if (GTK_IS_GRAPH_DISPLAY(view)) + result = BVW_GRAPH; + + else + { + assert(false); + result = -1; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : binary = contenu chargé à consulter. * +* index = composant graphique à cibler. * +* * +* Description : Fournit toutes les options d'affichage pour un contenu. * +* * +* Retour : Tableau de paramètres en accès libre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool * const g_loaded_binary_get_all_display_options(const GLoadedBinary *binary, unsigned int index) +{ + return binary->col_display[index]; + +} + + +/****************************************************************************** +* * +* Paramètres : binary = contenu chargé à consulter. * +* index = composant graphique à cibler. * +* option = type de paramètre à manipuler. * +* state = valeur dudit paramètre. * +* * +* Description : Définit une option d'affichage pour un contenu chargé. * +* * +* Retour : true si un changement a été effectué, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_loaded_binary_set_display_option(GLoadedBinary *binary, unsigned int index, unsigned int option, bool state) +{ + bool result; /* Variation à faire remonter */ + bool old; /* Ancien état à remplacer */ + + old = binary->col_display[index][option]; + + if (state != old) + { + binary->col_display[index][option] = state; + result = true; + } + + else result = false; + + return result; + +} diff --git a/src/analysis/binary.h b/src/analysis/binary.h index 2df42aa..73b5a71 100644 --- a/src/analysis/binary.h +++ b/src/analysis/binary.h @@ -74,16 +74,6 @@ typedef enum _BinaryPartModel } BinaryPartModel; -/* Type de représentations */ -typedef enum _BinaryView -{ - BVW_BLOCK, /* Version basique */ - BVW_GRAPH, /* Affichage en graphique */ - - BVW_COUNT - -} BinaryView; - /* Indique le type défini pour une description de fichier binaire. */ GType g_loaded_binary_get_type(void); @@ -95,7 +85,7 @@ GLoadedBinary *g_loaded_binary_new(GBinContent *); GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr, const char *, GStudyProject *); /* Ecrit une sauvegarde du binaire dans un fichier XML. */ -bool g_loaded_binary_save(const GLoadedBinary *, xmlDocPtr, xmlXPathContextPtr, const char *); +bool g_loaded_binary_save(const GLoadedBinary *, xmlDocPtr, xmlXPathContextPtr, const char *, const char *); /* Fournit le nom associé à l'élément binaire. */ const char *g_loaded_binary_get_name(const GLoadedBinary *, bool); @@ -191,15 +181,26 @@ GBufferCache *g_loaded_binary_get_disassembled_cache(const GLoadedBinary *); /* Fournit le tampon associé au contenu d'un fichier source. */ //GCodeBuffer *g_loaded_binary_get_decompiled_buffer(const GLoadedBinary *, size_t); -/* Définit si une colonne donnée doit apparaître dans le rendu. */ -void g_loaded_binary_set_column_display(GLoadedBinary *, BinaryView, BufferLineColumn, bool); - -/* Indique quelles colonnes doivent apparaître dans le rendu. */ -const bool *g_loaded_binary_get_column_display(GLoadedBinary *, BinaryView); - /* Indique si les lignes doivent apparaître dans le rendu. */ bool *g_loaded_binary_display_decomp_lines(GLoadedBinary *); + + +/* ---------------------- GESTION SOUS FORME DE CONTENU CHARGE ---------------------- */ + + +/* Type de représentations */ +typedef enum _BinaryView +{ + BVW_BLOCK, /* Version basique */ + BVW_GRAPH, /* Affichage en graphique */ + + BVW_COUNT + +} BinaryView; + + + #endif /* _ANALYSIS_BINARY_H */ diff --git a/src/analysis/loaded-int.h b/src/analysis/loaded-int.h new file mode 100644 index 0000000..a574d27 --- /dev/null +++ b/src/analysis/loaded-int.h @@ -0,0 +1,79 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * loaded-int.h - définitions internes propres aux contenus chargés + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_LOADED_INT_H +#define _ANALYSIS_LOADED_INT_H + + +#include "loaded.h" + + + +/* Fournit le désignation associée à l'élément chargé. */ +typedef const char * (* describe_loaded_fc) (const GLoadedContent *, bool); + +/* Détermine le nombre de vues disponibles pour un contenu. */ +typedef unsigned int (* count_loaded_views_fc) (const GLoadedContent *); + +/* Met en place la vue demandée pour un contenu chargé. */ +typedef GtkWidget * (* build_loaded_view_fc) (GLoadedContent *, unsigned int); + +/* Retrouve l'indice correspondant à la vue donnée d'un contenu. */ +typedef unsigned int (* get_loaded_view_index_fc) (GLoadedContent *, GtkWidget *); + +/* Fournit toutes les options d'affichage pour un contenu. */ +typedef bool * const (* get_all_loaded_options_fc) (const GLoadedContent *, unsigned int); + +/* Définit une option d'affichage pour un contenu. */ +typedef bool ( * set_loaded_option_fc) (GLoadedContent *, unsigned int, unsigned int, bool); + + +/* Accès à un contenu binaire quelconque (interface) */ +struct _GLoadedContentIface +{ + GTypeInterface base_iface; /* A laisser en premier */ + + /* Méthodes virtuelles */ + + describe_loaded_fc describe; /* Description de contenu */ + + count_loaded_views_fc count_views; /* Compteur de vues */ + build_loaded_view_fc build_view; /* Mise en place de vues */ + get_loaded_view_index_fc get_view_index;/* Récupération d'indice de vue*/ + + get_all_loaded_options_fc get_all_options; /* Obtention de liste brute*/ + set_loaded_option_fc set_option; /* Définition d'affichage */ + + /* Signaux */ + + void (* display_changed) (GLoadedContent *, unsigned int, unsigned int); + +}; + + +/* Redéfinition */ +typedef GLoadedContentIface GLoadedContentInterface; + + + +#endif /* _ANALYSIS_LOADED_INT_H */ diff --git a/src/analysis/loaded.c b/src/analysis/loaded.c new file mode 100644 index 0000000..5ce16c1 --- /dev/null +++ b/src/analysis/loaded.c @@ -0,0 +1,362 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * loaded.c - intégration des contenus chargés + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "loaded.h" + + +#include <assert.h> + + +#include "loaded-int.h" +#include "../glibext/chrysamarshal.h" +#include "../glibext/gloadedpanel.h" + + + +/* ---------------------- GESTION SOUS FORME DE CONTENU CHARGE ---------------------- */ + + +/* Procède à l'initialisation de l'interface de contenu chargé. */ +static void g_loaded_content_default_init(GLoadedContentInterface *); + + + +/* ---------------------------------------------------------------------------------- */ +/* GESTION SOUS FORME DE CONTENU CHARGE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type d'une interface pour l'intégration de contenu chargé. */ +G_DEFINE_INTERFACE(GLoadedContent, g_loaded_content, G_TYPE_OBJECT) + + +/****************************************************************************** +* * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de contenu chargé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_loaded_content_default_init(GLoadedContentInterface *iface) +{ + g_signal_new("display-changed", + G_TYPE_LOADED_CONTENT, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GLoadedContentIface, display_changed), + NULL, NULL, + g_cclosure_user_marshal_VOID__ENUM_ENUM, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); + +} + + +/****************************************************************************** +* * +* Paramètres : content = élément chargé à consulter. * +* long = précise s'il s'agit d'une version longue ou non. * +* * +* Description : Fournit le désignation associée à l'élément chargé. * +* * +* Retour : Description courante. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_loaded_content_describe(const GLoadedContent *content, bool full) +{ + GLoadedContentIface *iface; /* Interface utilisée */ + + iface = G_LOADED_CONTENT_GET_IFACE(content); + + return iface->describe(content, full); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu chargé à consulter. * +* * +* Description : Détermine le nombre de vues disponibles pour un contenu. * +* * +* Retour : Quantité strictement positive. * +* * +* Remarques : - * +* * +******************************************************************************/ + +unsigned int g_loaded_content_count_views(const GLoadedContent *content) +{ + GLoadedContentIface *iface; /* Interface utilisée */ + + iface = G_LOADED_CONTENT_GET_IFACE(content); + + return iface->count_views(content); + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu chargé à consulter. * +* index = indice de la vue ciblée. * +* * +* Description : Met en place la vue demandée pour un contenu chargé. * +* * +* Retour : Composant graphique nouveau. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *g_loaded_content_build_view(GLoadedContent *content, unsigned int index) +{ + GtkWidget *result; /* Support à retourner */ + GLoadedContentIface *iface; /* Interface utilisée */ + + iface = G_LOADED_CONTENT_GET_IFACE(content); + + assert(index <= g_loaded_content_count_views(content)); + + result = iface->build_view(content, index); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu chargé à consulter. * +* index = composant graphique en place. * +* * +* Description : Retrouve l'indice correspondant à la vue donnée d'un contenu.* +* * +* Retour : Indice de la vue représentée, ou -1 en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +unsigned int g_loaded_content_get_view_index(GLoadedContent *content, GtkWidget *view) +{ + unsigned int result; /* Indice à retourner */ + GLoadedContentIface *iface; /* Interface utilisée */ + + iface = G_LOADED_CONTENT_GET_IFACE(content); + + result = iface->get_view_index(content, view); + + assert(result == -1 || result <= g_loaded_content_count_views(content)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu chargé à consulter. * +* index = composant graphique à cibler. * +* * +* Description : Fournit toutes les options d'affichage pour un contenu. * +* * +* Retour : Tableau de paramètres en accès libre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool * const g_loaded_content_get_all_display_options(const GLoadedContent *content, unsigned int index) +{ + bool const *result; /* Accès aux options à renvoyer*/ + GLoadedContentIface *iface; /* Interface utilisée */ + + assert(index <= g_loaded_content_count_views(content)); + + iface = G_LOADED_CONTENT_GET_IFACE(content); + + result = iface->get_all_options(content, index); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu chargé à consulter. * +* index = composant graphique à cibler. * +* option = type de paramètre à manipuler. * +* state = valeur dudit paramètre. * +* * +* Description : Définit une option d'affichage pour un contenu chargé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_loaded_content_set_display_option(GLoadedContent *content, unsigned int index, unsigned int option, bool state) +{ + GLoadedContentIface *iface; /* Interface utilisée */ + bool changed; /* Note un changement */ + + assert(index <= g_loaded_content_count_views(content)); + + iface = G_LOADED_CONTENT_GET_IFACE(content); + + changed = iface->set_option(content, index, option, state); + + if (changed) + g_signal_emit_by_name(content, "display-changed", index, option); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* VUES ET BASCULEMENT ENTRE LES VUES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : panel = panneau affichant un contenu binaire. * +* * +* Description : Fournit la station d'accueil d'un panneau d'affichage. * +* * +* Retour : Composant GTK fourni sans transfert de propriété. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkDockStation *get_dock_station_for_view_panel(GtkWidget *panel) +{ + GtkWidget *result; /* Support trouvé à retourner */ + + /** + * La hiérarchie des composants empilés est la suivante : + * + * - GtkBlockView / GtkGraphView / GtkSourceView (avec GtkViewport intégré) + * - GtkScrolledWindow + * - GtkDockStation + * + */ + + result = gtk_widget_get_parent(panel); /* ScrolledWindow */ + result = gtk_widget_get_parent(result); /* DockStation */ + + return GTK_DOCK_STATION(result); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = panneau affichant un contenu binaire. * +* * +* Description : Fournit le support défilant d'un panneau d'affichage. * +* * +* Retour : Composant GTK fourni sans transfert de propriété. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *get_scroll_window_for_view_panel(GtkWidget *panel) +{ + GtkWidget *result; /* Support trouvé à retourner */ + + /** + * La hiérarchie des composants empilés est la suivante : + * + * - GtkBlockView / GtkGraphView / GtkSourceView (avec GtkViewport intégré) + * - GtkScrolledWindow + * - GtkDockStation + * + */ + + result = gtk_widget_get_parent(panel); /* ScrolledWindow */ + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : view = composant retourné par un contenu chargé. * +* * +* Description : Fournit le panneau chargé inclus dans un affichage. * +* * +* Retour : Composant GTK fourni sans transfert de propriété. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkWidget *get_loaded_panel_from_built_view(GtkWidget *view) +{ + GtkWidget *result; /* Support trouvé à retourner */ + + if (G_IS_LOADED_PANEL(view)) + result = view; + + else + { + assert(GTK_IS_CONTAINER(view)); + + result = NULL; + + void track_loaded_panel(GtkWidget *widget, GtkWidget **found) + { + if (*found == NULL) + { + if (G_IS_LOADED_PANEL(widget)) + *found = widget; + + else if (GTK_IS_CONTAINER(widget)) + gtk_container_foreach(GTK_CONTAINER(widget), (GtkCallback)track_loaded_panel, found); + + } + + } + + gtk_container_foreach(GTK_CONTAINER(view), (GtkCallback)track_loaded_panel, &result); + + assert(result != NULL); + + } + + return result; + +} diff --git a/src/analysis/loaded.h b/src/analysis/loaded.h new file mode 100644 index 0000000..d1d9102 --- /dev/null +++ b/src/analysis/loaded.h @@ -0,0 +1,92 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * loaded.h - prototypes pour l'intégration des contenus chargés + * + * Copyright (C) 2017 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_LOADED_H +#define _ANALYSIS_LOADED_H + + +#include <glib-object.h> +#include <stdbool.h> +#include <gtk/gtk.h> + + +#include "../gtkext/gtkdockstation.h" + + + +/* ---------------------- GESTION SOUS FORME DE CONTENU CHARGE ---------------------- */ + + +#define G_TYPE_LOADED_CONTENT (g_loaded_content_get_type()) +#define G_LOADED_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LOADED_CONTENT, GLoadedContent)) +#define G_LOADED_CONTENT_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_LOADED_CONTENT, GLoadedContentIface)) +#define G_IS_LOADED_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LOADED_CONTENT)) +#define G_IS_LOADED_CONTENT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_LOADED_CONTENT)) +#define G_LOADED_CONTENT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_LOADED_CONTENT, GLoadedContentIface)) + + +/* Accès à un contenu binaire quelconque (coquille vide) */ +typedef struct _GLoadedContent GLoadedContent; + +/* Accès à un contenu binaire quelconque (interface) */ +typedef struct _GLoadedContentIface GLoadedContentIface; + + +/* Détermine le type d'une interface pour l'intégration de contenu chargé. */ +GType g_loaded_content_get_type(void) G_GNUC_CONST; + +/* Fournit le désignation associée à l'élément chargé. */ +const char *g_loaded_content_describe(const GLoadedContent *, bool); + +/* Détermine le nombre de vues disponibles pour un contenu. */ +unsigned int g_loaded_content_count_views(const GLoadedContent *); + +/* Met en place la vue demandée pour un contenu chargé. */ +GtkWidget *g_loaded_content_build_view(GLoadedContent *, unsigned int); + +/* Retrouve l'indice correspondant à la vue donnée d'un contenu. */ +unsigned int g_loaded_content_get_view_index(GLoadedContent *, GtkWidget *); + +/* Fournit toutes les options d'affichage pour un contenu. */ +bool * const g_loaded_content_get_all_display_options(const GLoadedContent *, unsigned int); + +/* Définit une option d'affichage pour un contenu chargé. */ +void g_loaded_content_set_display_option(GLoadedContent *, unsigned int, unsigned int, bool); + + + +/* ----------------------- VUES ET BASCULEMENT ENTRE LES VUES ----------------------- */ + + +/* Fournit la station d'accueil d'un panneau d'affichage. */ +GtkDockStation *get_dock_station_for_view_panel(GtkWidget *); + +/* Fournit le support défilant d'un panneau d'affichage. */ +GtkWidget *get_scroll_window_for_view_panel(GtkWidget *); + +/* Fournit le panneau chargé inclus dans un affichage. */ +GtkWidget *get_loaded_panel_from_built_view(GtkWidget *); + + + +#endif /* _ANALYSIS_LOADED_H */ diff --git a/src/analysis/project.c b/src/analysis/project.c index cb1c70a..a5b59ab 100644 --- a/src/analysis/project.c +++ b/src/analysis/project.c @@ -33,15 +33,13 @@ #include <i18n.h> +#include "loaded.h" #include "loading.h" #include "../common/xml.h" #include "../core/global.h" #include "../core/params.h" -#include "../glibext/signal.h" -#include "../gtkext/easygtk.h" #include "../glibext/delayed-int.h" -#include "../gtkext/gtkblockdisplay.h" -#include "../gtkext/gtkgraphdisplay.h" +#include "../glibext/signal.h" #include "../gui/core/panels.h" #include "../gui/panels/log.h" #include "../gui/panels/panel.h" @@ -78,13 +76,9 @@ struct _GStudyProject char *filename; /* Lieu d'enregistrement */ - loaded_content *contents; /* Contenus binaires chargés */ - size_t contents_count; /* Nombre de ces contenus */ - GMutex cnt_mutex; /* Modification de la liste */ - - loaded_binary **binaries; /* Fichiers binaires associés */ - size_t binaries_count; /* Nombre de ces fichiers */ - GMutex bin_mutex; /* Modification de la liste */ + GLoadedContent **contents; /* Contenus chargés et intégrés*/ + size_t count; /* Quantité de ces contenus */ + GMutex mutex; /* Encadrement des accès */ }; @@ -94,6 +88,11 @@ struct _GStudyProjectClass { GObjectClass parent; /* A laisser en premier */ + /* Signaux */ + + void (* content_added) (GStudyProject *, GLoadedContent *); + void (* content_removed) (GStudyProject *, GLoadedContent *); + }; @@ -103,17 +102,6 @@ static void g_study_project_class_init(GStudyProjectClass *); /*Initialise une instance de projet d'étude. */ static void g_study_project_init(GStudyProject *); -/* Assure un positionnement initial idéal. */ -static gboolean scroll_for_the_first_time(GtkWidget *, GdkEvent *, GLoadedBinary *); - - - -/* ----------------------- VUES ET BASCULEMENT ENTRE LES VUES ----------------------- */ - - -/* Met en place un ensemble de vues pour un binaire. */ -GPanelItem *_setup_new_panel_item_for_binary(GStudyProject *, GLoadedBinary *, BinaryView, GtkDisplayPanel **); - /* ---------------------------------------------------------------------------------- */ @@ -139,6 +127,21 @@ G_DEFINE_TYPE(GStudyProject, g_study_project, G_TYPE_OBJECT); static void g_study_project_class_init(GStudyProjectClass *klass) { + g_signal_new("content-added", + G_TYPE_STUDY_PROJECT, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GStudyProjectClass, content_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + g_signal_new("content-removed", + G_TYPE_STUDY_PROJECT, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GStudyProjectClass, content_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); } @@ -157,9 +160,7 @@ static void g_study_project_class_init(GStudyProjectClass *klass) static void g_study_project_init(GStudyProject *project) { - g_mutex_init(&project->cnt_mutex); - - g_mutex_init(&project->bin_mutex); + g_mutex_init(&project->mutex); } @@ -201,6 +202,10 @@ GStudyProject *g_study_project_new(void) GStudyProject *g_study_project_open(const char *filename) { + return NULL; + +#if 0 + GStudyProject *result; /* Adresse à retourner */ xmlDocPtr xdoc; /* Structure XML chargée */ xmlXPathContextPtr context; /* Contexte pour les XPath */ @@ -318,6 +323,8 @@ GStudyProject *g_study_project_open(const char *filename) return result; +#endif + } @@ -336,50 +343,31 @@ GStudyProject *g_study_project_open(const char *filename) bool g_study_project_save(GStudyProject *project, const char *filename) { + return false; + +#if 0 + bool result; /* Bilan à retourner */ xmlDocPtr xdoc; /* Document XML à créer */ xmlXPathContextPtr context; /* Contexte pour les recherches*/ const char *final; /* Lieu d'enregistrement final */ size_t i; /* Boucle de parcours */ - size_t access_len; /* Taille d'un chemin interne */ char *access; /* Chemin pour une sous-config.*/ result = create_new_xml_file(&xdoc, &context); - result &= (ensure_node_exist(xdoc, context, "/ChrysalideProject") != NULL); + if (result) + result = (ensure_node_exist(xdoc, context, "/ChrysalideProject") != NULL); final = filename != NULL ? filename : project->filename; - /* Enregistrement des contenus binaires attachés */ - - for (i = 0; i < project->contents_count && result; i++) - { - if (project->contents[i].state == PCS_INTERNAL) continue; - - access_len = strlen("/ChrysalideProject/Contents/Content[position()=") + SIZE_T_MAXLEN + strlen("]") + 1; - - access = calloc(access_len, sizeof(char)); - snprintf(access, access_len, "/ChrysalideProject/Contents/Content[position()=%zu]", i + 1); - - result = g_binary_content_save(project->contents[i].content, xdoc, context, access, final); - - if (result) - result = add_long_attribute_to_node(xdoc, context, access, "state", project->contents[i].state); - - free(access); - - } - /* Enregistrement des binaires analysés */ for (i = 0; i < project->binaries_count && result; i++) { - access_len = strlen("/ChrysalideProject/Binaries/Binary[position()=") + SIZE_T_MAXLEN + strlen("]") + 1; - - access = calloc(access_len, sizeof(char)); - snprintf(access, access_len, "/ChrysalideProject/Binaries/Binary[position()=%zu]", i + 1); + asprintf(&access, "/ChrysalideProject/Binaries/Binary[position()=%zu]", i + 1); - result = g_loaded_binary_save(project->binaries[i]->binary, xdoc, context, access); + result = g_loaded_binary_save(project->binaries[i]->binary, xdoc, context, access, final); free(access); @@ -400,6 +388,8 @@ bool g_study_project_save(GStudyProject *project, const char *filename) return result; +#endif + } @@ -438,6 +428,8 @@ const char *g_study_project_get_filename(const GStudyProject *project) void g_study_project_add_binary_content(GStudyProject *project, GBinContent *content, ProjectContentState state) { +#if 0 + loaded_content *new; /* Nouveau contenu à définir */ g_mutex_lock(&project->cnt_mutex); @@ -454,6 +446,7 @@ void g_study_project_add_binary_content(GStudyProject *project, GBinContent *con g_mutex_unlock(&project->cnt_mutex); +#endif } @@ -473,6 +466,10 @@ void g_study_project_add_binary_content(GStudyProject *project, GBinContent *con GBinContent *g_study_project_find_binary_content_by_hash(GStudyProject *project, const char *hash) { + return NULL; + +#if 0 + GBinContent *result; /* Trouvaille à retourner */ size_t i; /* Boucle de parcours */ GBinContent *iter; /* Contenu binaire analysé */ @@ -499,6 +496,8 @@ GBinContent *g_study_project_find_binary_content_by_hash(GStudyProject *project, return result; +#endif + } @@ -524,7 +523,7 @@ void ack_loaded_binary(GBinaryLoader *loader, GStudyProject *project) if (binary != NULL) { g_signal_connect_to_main_swapped(binary, "disassembly-done", - G_CALLBACK(g_study_project_attach_binary), project, + G_CALLBACK(g_study_project_attach_content), project, g_cclosure_marshal_VOID__VOID); g_loaded_binary_analyse(binary); @@ -536,43 +535,10 @@ void ack_loaded_binary(GBinaryLoader *loader, GStudyProject *project) /****************************************************************************** * * -* Paramètres : widget = composant d'affichage nouvellement porté à l'écran. * -* event = informations liées à l'événement. * -* binary = fichier binaire à associer au projet actuel. * -* * -* Description : Assure un positionnement initial idéal. * -* * -* Retour : FALSE. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static gboolean scroll_for_the_first_time(GtkWidget *widget, GdkEvent *event, GLoadedBinary *binary) -{ - GExeFormat *format; /* Format associé au binaire */ - vmpa2t target; /* Position initiale à viser */ - - g_signal_handlers_disconnect_by_func(widget, G_CALLBACK(scroll_for_the_first_time), binary); - - format = g_loaded_binary_get_format(binary); - - if (g_exe_format_get_main_address(format, &target)) - gtk_display_panel_request_move(GTK_DISPLAY_PANEL(widget), &target); - - g_object_unref(G_OBJECT(format)); - - return FALSE; - -} - - -/****************************************************************************** -* * -* Paramètres : project = project à effacer de la mémoire. * -* binary = fichier binaire à associer au projet actuel. * +* Paramètres : project = project à manipuler. * +* content = contenu chargé à associer au projet actuel. * * * -* Description : Attache un fichier donné à un projet donné. * +* Description : Attache un contenu donné à un projet donné. * * * * Retour : - * * * @@ -580,48 +546,28 @@ static gboolean scroll_for_the_first_time(GtkWidget *widget, GdkEvent *event, GL * * ******************************************************************************/ -void g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *binary) +void g_study_project_attach_content(GStudyProject *project, GLoadedContent *content) { - loaded_binary *new; /* Nouveau binaire à présenter */ - GtkDisplayPanel *display; /* Composant d'affichage */ - GPanelItem *panel; /* Nouveau panneau associé */ - - /* Mise en place */ - - new = (loaded_binary *)calloc(1, sizeof(loaded_binary)); - - new->binary = binary; - - /* Enregistrement dans le projet */ + g_mutex_lock(&project->mutex); - g_mutex_lock(&project->bin_mutex); + project->contents = (GLoadedContent **)realloc(project->contents, + ++project->count * sizeof(GLoadedContent *)); - project->binaries = (loaded_binary **)realloc(project->binaries, - ++project->binaries_count * sizeof(loaded_binary *)); + project->contents[project->count - 1] = content; - project->binaries[project->binaries_count - 1] = new; + g_mutex_unlock(&project->mutex); - /* Premier affichage */ - - panel = _setup_new_panel_item_for_binary(project, binary, BVW_BLOCK, &display); - - g_mutex_unlock(&project->bin_mutex); - - g_signal_connect(display, "size-allocate", G_CALLBACK(scroll_for_the_first_time), binary); - - g_panel_item_dock(panel); - - update_project_area(project); + g_signal_emit_by_name(project, "content-added", content); } /****************************************************************************** * * -* Paramètres : project = project à effacer de la mémoire. * -* binary = fichier binaire à dissocier au projet actuel. * +* Paramètres : project = project à manipuler. * +* content = contenu chargé à dissocier du projet actuel. * * * -* Description : Détache un fichier donné à un projet donné. * +* Description : Détache un contenu donné d'un projet donné. * * * * Retour : - * * * @@ -629,29 +575,27 @@ void g_study_project_attach_binary(GStudyProject *project, GLoadedBinary *binary * * ******************************************************************************/ -void g_study_project_detach_binary(GStudyProject *project, GLoadedBinary *binary) +void g_study_project_detach_content(GStudyProject *project, GLoadedContent *content) { - //GtkDockPanel *dpanel; /* Support de panneaux */ - //GDockItem *ditem; /* Support d'affichage utilisé */ size_t i; /* Boucle de parcours */ - //dpanel = GTK_DOCK_PANEL(g_object_get_data(project->ref, "binpanel")); - //ditem = gtk_dock_panel_get_item_from_binary(project, binary); FIXME !! - - //gtk_dock_panel_remove_item(dpanel, ditem); + g_mutex_lock(&project->mutex); + for (i = 0; i < project->count; i++) + if (project->contents[i] == content) break; + if ((i + 1) < project->count) + memmove(&project->contents[i], &project->contents[i + 1], + (project->count - i - 1) * sizeof(GLoadedContent *)); - for (i = 0; i < project->binaries_count; i++) - if (project->binaries[i]->binary == binary) break; + project->contents = (GLoadedContent **)realloc(project->contents, + --project->count * sizeof(GLoadedContent *)); - if ((i + 1) < project->binaries_count) - memmove(&project->binaries[i], &project->binaries[i + 1], (project->binaries_count - i - 1) * sizeof(loaded_binary *)); + g_mutex_unlock(&project->mutex); - project->binaries = (loaded_binary **)realloc(project->binaries, - --project->binaries_count * sizeof(loaded_binary *)); + g_signal_emit_by_name(project, "content-removed", content); - update_project_area(project); + g_object_unref(G_OBJECT(content)); } @@ -670,6 +614,7 @@ void g_study_project_detach_binary(GStudyProject *project, GLoadedBinary *binary void g_study_project_display(const GStudyProject *project) { +#if 0 size_t i; /* Boucle de parcours #1 */ loaded_binary *handled; /* Binaire prise en compte */ size_t j; /* Boucle de parcours #2 */ @@ -682,7 +627,7 @@ void g_study_project_display(const GStudyProject *project) g_panel_item_dock(handled->items[j]); } - +#endif } @@ -700,6 +645,7 @@ void g_study_project_display(const GStudyProject *project) void g_study_project_hide(const GStudyProject *project) { +#if 0 size_t i; /* Boucle de parcours #1 */ loaded_binary *handled; /* Binaire prise en compte */ size_t j; /* Boucle de parcours #2 */ @@ -712,16 +658,16 @@ void g_study_project_hide(const GStudyProject *project) g_panel_item_undock(handled->items[j]); } - +#endif } /****************************************************************************** * * * Paramètres : project = projet dont le contenu est à afficher. * -* count = nombre de binaires pris en compte. [OUT] * +* count = nombre de contenus pris en compte. [OUT] * * * -* Description : Fournit l'ensemble des binaires associés à un projet. * +* Description : Fournit l'ensemble des contenus associés à un projet. * * * * Retour : Liste à libérer de la mémoire. * * * @@ -729,278 +675,23 @@ void g_study_project_hide(const GStudyProject *project) * * ******************************************************************************/ -GLoadedBinary **g_study_project_get_binaries(const GStudyProject *project, size_t *count) +GLoadedContent **g_study_project_get_contents(GStudyProject *project, size_t *count) { - GLoadedBinary **result; /* Tableau à retourner */ + GLoadedContent **result; /* Tableau à retourner */ size_t i; /* Boucle de parcours */ - *count = project->binaries_count; - result = (GLoadedBinary **)calloc(*count, sizeof(GLoadedBinary *)); + g_mutex_lock(&project->mutex); + + *count = project->count; + result = (GLoadedContent **)calloc(*count, sizeof(GLoadedContent *)); for (i = 0; i < *count; i++) { - result[i] = project->binaries[i]->binary; + result[i] = project->contents[i]; g_object_ref(G_OBJECT(result[i])); } - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* VUES ET BASCULEMENT ENTRE LES VUES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : project = zone d'inscription du nouveau panneau. * -* binary = fichier binaire dont les vues sont à créer. * -* wanted = interface de visualisation demandée. * -* panel = interface de visualisation principale. [OUT] * -* * -* Description : Met en place un ensemble de vues pour un binaire. * -* * -* Retour : Panneau mis en place et prêt à être inséré. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GPanelItem *_setup_new_panel_item_for_binary(GStudyProject *project, GLoadedBinary *binary, BinaryView wanted, GtkDisplayPanel **panel) -{ - GPanelItem *result; /* Nouveau panneau à renvoyer */ - size_t k; /* Boucle de parcours #3 */ - loaded_binary *handled; /* Dossier de suivi à compléter*/ - GtkDisplayPanel *displays[BVW_COUNT]; /* Composants pour l'affichage */ - BinaryView i; /* Boucle de parcours #1 */ - GtkWidget *display; /* Affichage du binaire */ - GtkWidget *scroll; /* Surface d'exposition */ - GtkWidget *selected; /* Interface de prédilection */ - const char *name; /* Titre associé au binaire */ - const char *lname; /* Description du binaire */ - BinaryView j; /* Boucle de parcours #2 */ - - /* Recherche du dossier correspondant */ - - for (k = 0; k < project->binaries_count; k++) - if (project->binaries[k]->binary == binary) - break; - - assert(k < project->binaries_count); - - handled = project->binaries[k]; - - /* Créations */ - - for (i = 0; i < BVW_COUNT; i++) - { - /* Préparation du support visuel */ - - switch (i) - { - case BVW_BLOCK: - display = gtk_block_display_new(); - break; - case BVW_GRAPH: - display = gtk_graph_display_new(); - break; - default: /* GCC ! */ - break; - } - - gtk_widget_show(display); - - displays[i] = GTK_DISPLAY_PANEL(display); - - gtk_display_panel_attach_binary(displays[i], binary, i); - - /* Intégration finale dans un support défilant */ - - scroll = qck_create_scrolled_window(NULL, NULL); - gtk_container_add(GTK_CONTAINER(scroll), display); - - if (i == wanted) - { - selected = scroll; - *panel = GTK_DISPLAY_PANEL(display); - } - - } - - /* Support graphique final */ - - name = g_loaded_binary_get_name(binary, false); - lname = g_loaded_binary_get_name(binary, true); - - result = g_panel_item_new(PIP_BINARY_VIEW, name, lname, selected, true, "N"); - register_panel_item(result, get_main_configuration()); - - handled->items = (GPanelItem **)realloc(handled->items, ++handled->count * sizeof(GPanelItem *)); - handled->items[handled->count - 1] = result; - - /* Etablissement des liens */ - - for (i = 0; i < BVW_COUNT; i++) - for (j = 0; j < BVW_COUNT; j++) - { - if (j == i) - continue; - - switch (j) - { - case BVW_BLOCK: - g_object_set_data(G_OBJECT(displays[i]), "block_alt_view", displays[j]); - break; - case BVW_GRAPH: - g_object_set_data(G_OBJECT(displays[i]), "graph_alt_view", displays[j]); - break; - default: /* GCC ! */ - break; - } - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : project = zone d'inscription du nouveau panneau. * -* binary = fichier binaire dont les vues sont à créer. * -* wanted = interface de visualisation demandée. * -* panel = interface de visualisation principale. [OUT] * -* * -* Description : Met en place un ensemble de vues pour un binaire. * -* * -* Retour : Panneau mis en place et prêt à être inséré. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GPanelItem *setup_new_panel_item_for_binary(GStudyProject *project, GLoadedBinary *binary, BinaryView wanted, GtkDisplayPanel **panel) -{ - GPanelItem *result; /* Nouveau panneau à renvoyer */ - - /** - * La liste des binaires pris en charge ne doit pas évoluer en cours - * de traitement. On place donc le verrou adapté... - */ - - g_mutex_lock(&project->bin_mutex); - - result = _setup_new_panel_item_for_binary(project, binary, wanted, panel); - - g_mutex_unlock(&project->bin_mutex); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : panel = panneau affichant un contenu binaire. * -* * -* Description : Fournit la station d'accueil d'un panneau d'affichage. * -* * -* Retour : Composant GTK fourni sans transfert de propriété. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkDockStation *get_dock_station_for_view_panel(GtkDisplayPanel *panel) -{ - GtkWidget *result; /* Support trouvé à retourner */ - - /** - * La hiérarchie des composants empilés est la suivante : - * - * - GtkBlockView / GtkGraphView / GtkSourceView (avec GtkViewport intégré) - * - GtkScrolledWindow - * - GtkDockStation - * - */ - - result = gtk_widget_get_parent(GTK_WIDGET(panel)); /* ScrolledWindow */ - result = gtk_widget_get_parent(result); /* DockStation */ - - return GTK_DOCK_STATION(result); - -} - - -/****************************************************************************** -* * -* Paramètres : panel = panneau affichant un contenu binaire. * -* * -* Description : Fournit le support défilant d'un panneau d'affichage. * -* * -* Retour : Composant GTK fourni sans transfert de propriété. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkWidget *get_scroll_window_for_view_panel(GtkDisplayPanel *panel) -{ - GtkWidget *result; /* Support trouvé à retourner */ - - /** - * La hiérarchie des composants empilés est la suivante : - * - * - GtkBlockView / GtkGraphView / GtkSourceView (avec GtkViewport intégré) - * - GtkScrolledWindow - * - GtkDockStation - * - */ - - result = gtk_widget_get_parent(GTK_WIDGET(panel)); /* ScrolledWindow */ - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : panel = panneau affichant un contenu binaire. * -* view = autre vision recherchée. * -* * -* Description : Fournit une vision alternative d'un panneau d'affichage. * -* * -* Retour : Composant GTK fourni sans transfert de propriété. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GtkDisplayPanel *get_alt_view_for_view_panel(GtkDisplayPanel *panel, BinaryView view) -{ - GtkDisplayPanel *result; /* Panneau visé à renvoyer */ - - switch (view) - { - case BVW_BLOCK: - result = GTK_DISPLAY_PANEL(g_object_get_data(G_OBJECT(panel), "block_alt_view")); - break; - case BVW_GRAPH: - result = GTK_DISPLAY_PANEL(g_object_get_data(G_OBJECT(panel), "graph_alt_view")); - break; - default: - assert(false); - result = NULL; - break; - } - - if (result != NULL) - g_object_ref(G_OBJECT(result)); + g_mutex_unlock(&project->mutex); return result; diff --git a/src/analysis/project.h b/src/analysis/project.h index 8288384..9e777ee 100644 --- a/src/analysis/project.h +++ b/src/analysis/project.h @@ -29,15 +29,14 @@ #include "binary.h" -#include "../gtkext/gtkdockstation.h" -#include "../gtkext/gtkdisplaypanel.h" +#include "loaded.h" /** * Comme "gui/panels/panel.h" inclut "gui/editem.h", qui inclut lui même * ce fichier pour la mise à jour de la zone de projet, on redéfinit... */ -typedef struct _GPanelItem GPanelItem; +//typedef struct _GPanelItem GPanelItem; /** * Autre boucle sans fin similaire... @@ -99,11 +98,11 @@ GBinContent *g_study_project_find_binary_content_by_hash(GStudyProject *, const /* Acquitte la fin d'un chargement différé et complet. */ void ack_loaded_binary(GBinaryLoader *, GStudyProject *); -/* Attache un fichier donné à un projet donné. */ -void g_study_project_attach_binary(GStudyProject *, GLoadedBinary *); +/* Attache un contenu donné à un projet donné. */ +void g_study_project_attach_content(GStudyProject *, GLoadedContent *); -/* Détache un fichier donné à un projet donné. */ -void g_study_project_detach_binary(GStudyProject *, GLoadedBinary *); +/* Détache un contenu donné d'un projet donné. */ +void g_study_project_detach_content(GStudyProject *, GLoadedContent *); /* Met en place un projet à l'écran. */ void g_study_project_display(const GStudyProject *); @@ -111,25 +110,8 @@ void g_study_project_display(const GStudyProject *); /* Supprime de l'écran un projet en place. */ void g_study_project_hide(const GStudyProject *); -/* Fournit l'ensemble des binaires associés à un projet. */ -GLoadedBinary **g_study_project_get_binaries(const GStudyProject *, size_t *); - - - -/* ----------------------- VUES ET BASCULEMENT ENTRE LES VUES ----------------------- */ - - -/* Met en place un ensemble de vues pour un binaire. */ -GPanelItem *setup_new_panel_item_for_binary(GStudyProject *, GLoadedBinary *, BinaryView, GtkDisplayPanel **); - -/* Fournit la station d'accueil d'un panneau d'affichage. */ -GtkDockStation *get_dock_station_for_view_panel(GtkDisplayPanel *); - -/* Fournit le support défilant d'un panneau d'affichage. */ -GtkWidget *get_scroll_window_for_view_panel(GtkDisplayPanel *); - -/* Fournit une vision alternative d'un panneau d'affichage. */ -GtkDisplayPanel *get_alt_view_for_view_panel(GtkDisplayPanel *, BinaryView); +/* Fournit l'ensemble des contenus associés à un projet. */ +GLoadedContent **g_study_project_get_contents(GStudyProject *, size_t *); diff --git a/src/glibext/gloadedpanel-int.h b/src/glibext/gloadedpanel-int.h index 8686d1b..904041d 100644 --- a/src/glibext/gloadedpanel-int.h +++ b/src/glibext/gloadedpanel-int.h @@ -29,6 +29,12 @@ +/* Définit le contenu associé à un panneau de chargement. */ +typedef void (* set_loaded_panel_content_fc) (GLoadedPanel *, GLoadedContent *); + +/* Fournit le contenu associé à un panneau de chargement. */ +typedef GLoadedContent * (* get_loaded_panel_content_fc) (const GLoadedPanel *); + /* Place en cache un rendu destiné à l'aperçu graphique rapide. */ typedef void (* cache_loaded_glance_fc) (GLoadedPanel *, cairo_t *, const GtkAllocation *, double); @@ -38,6 +44,9 @@ struct _GLoadedPanelIface { GTypeInterface base_iface; /* A laisser en premier */ + set_loaded_panel_content_fc set_content;/* Définition du contenu */ + get_loaded_panel_content_fc get_content;/* Récupération du contenu */ + cache_loaded_glance_fc cache_glance; /* Cache de la mignature */ }; diff --git a/src/glibext/gloadedpanel.c b/src/glibext/gloadedpanel.c index fa12ec7..4d5a1e1 100644 --- a/src/glibext/gloadedpanel.c +++ b/src/glibext/gloadedpanel.c @@ -57,6 +57,58 @@ static void g_loaded_panel_default_init(GLoadedPanelInterface *iface) /****************************************************************************** * * +* Paramètres : panel = composant GTK à compléter. * +* content = contenu quelconque chargé en mémoire. * +* * +* Description : Définit le contenu associé à un panneau de chargement. * +* * +* Retour : * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_loaded_panel_set_content(GLoadedPanel *panel, GLoadedContent *content) +{ + GLoadedPanelIface *iface; /* Interface utilisée */ + + g_object_ref(G_OBJECT(content)); + + iface = G_LOADED_PANEL_GET_IFACE(panel); + + iface->set_content(panel, content); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à consulter. * +* * +* Description : Fournit le contenu associé à un panneau de chargement. * +* * +* Retour : Contenu quelconque chargé en mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GLoadedContent *g_loaded_panel_get_content(const GLoadedPanel *panel) +{ + GLoadedContent *result; /* Contenu à retourner */ + GLoadedPanelIface *iface; /* Interface utilisée */ + + iface = G_LOADED_PANEL_GET_IFACE(panel); + + result = iface->get_content(panel); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : panel = composant GTK à manipuler. * * cairo = assistant pour la création de rendus. * * area = taille de la surface réduite à disposition. * diff --git a/src/glibext/gloadedpanel.h b/src/glibext/gloadedpanel.h index 51f4f36..c2c9e85 100644 --- a/src/glibext/gloadedpanel.h +++ b/src/glibext/gloadedpanel.h @@ -29,13 +29,16 @@ #include <gtk/gtk.h> +#include "../analysis/loaded.h" -#define G_TYPE_LOADED_PANEL (g_loaded_panel_get_type()) -#define G_LOADED_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LOADED_PANEL, GLoadedPanel)) -#define G_LOADED_PANEL_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_LOADED_PANEL, GLoadedPanelIface)) -#define GTK_IS_LOADED_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LOADED_PANEL)) -#define GTK_IS_LOADED_PANEL_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_LOADED_PANEL)) -#define G_LOADED_PANEL_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_LOADED_PANEL, GLoadedPanelIface)) + + +#define G_TYPE_LOADED_PANEL (g_loaded_panel_get_type()) +#define G_LOADED_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LOADED_PANEL, GLoadedPanel)) +#define G_LOADED_PANEL_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_LOADED_PANEL, GLoadedPanelIface)) +#define G_IS_LOADED_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LOADED_PANEL)) +#define G_IS_LOADED_PANEL_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_LOADED_PANEL)) +#define G_LOADED_PANEL_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_LOADED_PANEL, GLoadedPanelIface)) /* Composant d'affichage basique (coquille vide) */ @@ -48,6 +51,12 @@ typedef struct _GLoadedPanelIface GLoadedPanelIface; /* Détermine le type d'une interface pour la mise en place de lignes. */ GType g_loaded_panel_get_type(void) G_GNUC_CONST; +/* Définit le contenu associé à un panneau de chargement. */ +void g_loaded_panel_set_content(GLoadedPanel *, GLoadedContent *); + +/* Fournit le contenu associé à un panneau de chargement. */ +GLoadedContent *g_loaded_panel_get_content(const GLoadedPanel *); + /* Place en cache un rendu destiné à l'aperçu graphique rapide. */ void g_loaded_panel_cache_glance(GLoadedPanel *, cairo_t *, const GtkAllocation *, double); diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c index 413af86..b8cba94 100644 --- a/src/gtkext/graph/cluster.c +++ b/src/gtkext/graph/cluster.c @@ -34,6 +34,7 @@ #include "../gtkbufferdisplay.h" #include "../gtkdisplaypanel.h" #include "../../common/sort.h" +#include "../../glibext/gloadedpanel.h" @@ -313,9 +314,11 @@ GGraphCluster *g_graph_cluster_new(GLoadedBinary *binary, const GBlockList *list g_object_ref(G_OBJECT(result->block)); result->display = gtk_block_display_new(); - gtk_widget_show(result->display); - gtk_display_panel_attach_binary(GTK_DISPLAY_PANEL(result->display), binary, BVW_GRAPH); + + g_loaded_panel_set_content(G_LOADED_PANEL(result->display), G_LOADED_CONTENT(binary)); + + gtk_block_display_override_view_index(GTK_BLOCK_DISPLAY(result->display), BVW_GRAPH); gtk_display_panel_show_border(GTK_DISPLAY_PANEL(result->display), true); diff --git a/src/gtkext/gtkblockdisplay.c b/src/gtkext/gtkblockdisplay.c index b39b561..e4d9d48 100644 --- a/src/gtkext/gtkblockdisplay.c +++ b/src/gtkext/gtkblockdisplay.c @@ -26,6 +26,7 @@ #include "gtkbufferdisplay-int.h" #include "../arch/operand.h" +#include "../analysis/loaded.h" @@ -249,7 +250,7 @@ static gboolean gtk_block_display_button_press(GtkWidget *widget, GdkEventButton view = gtk_buffer_display_get_view(GTK_BUFFER_DISPLAY(display)); - changed = g_buffer_view_highlight_segments(view, real_x, real_y, GTK_DISPLAY_PANEL(display)->display); + changed = g_buffer_view_highlight_segments(view, real_x, real_y, GTK_DISPLAY_PANEL(display)->display_options); g_object_unref(G_OBJECT(view)); @@ -300,7 +301,7 @@ static gboolean gtk_block_display_query_tooltip(GtkWidget *widget, gint x, gint real_y = y; gtk_display_panel_compute_real_coord(panel, &real_x, &real_y); - creator = g_buffer_view_find_creator(GTK_BUFFER_DISPLAY(display)->view, real_x, real_y, panel->display); + creator = g_buffer_view_find_creator(GTK_BUFFER_DISPLAY(display)->view, real_x, real_y, panel->display_options); if (creator != NULL) { @@ -400,7 +401,7 @@ static bool gtk_block_display_notify_caret_relocation(GtkBlockDisplay *display, view = gtk_buffer_display_get_view(GTK_BUFFER_DISPLAY(display)); - result = g_buffer_view_highlight_segments(view, area->x, area->y, GTK_DISPLAY_PANEL(display)->display); + result = g_buffer_view_highlight_segments(view, area->x, area->y, GTK_DISPLAY_PANEL(display)->display_options); g_object_unref(G_OBJECT(view)); @@ -410,3 +411,28 @@ static bool gtk_block_display_notify_caret_relocation(GtkBlockDisplay *display, return result; } + + +/****************************************************************************** +* * +* Paramètres : display = composant GTK d'affichage. * +* index = indice de type de vue effectif. * +* * +* Description : Force un type de vue pour les options de rendu. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_block_display_override_view_index(GtkBlockDisplay *display, unsigned int index) +{ + GtkDisplayPanel *panel; /* Version de plus haut niveau */ + + panel = GTK_DISPLAY_PANEL(display); + + panel->view_index = index; + panel->display_options = g_loaded_content_get_all_display_options(G_LOADED_CONTENT(panel->binary), index); + +} diff --git a/src/gtkext/gtkblockdisplay.h b/src/gtkext/gtkblockdisplay.h index 1455690..b394a01 100644 --- a/src/gtkext/gtkblockdisplay.h +++ b/src/gtkext/gtkblockdisplay.h @@ -51,6 +51,9 @@ GType gtk_block_display_get_type(void); /* Crée un nouveau composant pour l'affichage de bloc en ASM. */ GtkWidget *gtk_block_display_new(void); +/* Force un type de vue pour les options de rendu. */ +void gtk_block_display_override_view_index(GtkBlockDisplay *, unsigned int); + #endif /* _GTKEXT_GTKBLOCKDISPLAY_H */ diff --git a/src/gtkext/gtkbufferdisplay.c b/src/gtkext/gtkbufferdisplay.c index ff70032..c1311c5 100644 --- a/src/gtkext/gtkbufferdisplay.c +++ b/src/gtkext/gtkbufferdisplay.c @@ -488,7 +488,7 @@ static gboolean gtk_buffer_display_draw(GtkWidget *widget, cairo_t *cr) area.x -= virt_x; virt_y += area.y; - g_buffer_view_draw(display->view, cr, virt_y, &area, parent->display, selected); + g_buffer_view_draw(display->view, cr, virt_y, &area, parent->display_options, selected); } @@ -571,7 +571,7 @@ static gboolean gtk_buffer_display_key_press(GtkWidget *widget, GdkEventKey *eve ctrl = (event->state & GDK_CONTROL_MASK); area = display->caret; - status = g_buffer_view_move_caret(display->view, ctrl, dir, panel->display, &area, &addr); + status = g_buffer_view_move_caret(display->view, ctrl, dir, panel->display_options, &area, &addr); if (status) { @@ -607,7 +607,7 @@ static void gtk_buffer_display_compute_requested_size(GtkBufferDisplay *display, if (width != NULL) { if (display->view != NULL) - *width = g_buffer_view_get_width(display->view, GTK_DISPLAY_PANEL(display)->display); + *width = g_buffer_view_get_width(display->view, GTK_DISPLAY_PANEL(display)->display_options); else *width = 0; } @@ -737,7 +737,7 @@ static bool gtk_buffer_display_get_address_coordinates(const GtkBufferDisplay *d if (result) { - *x += g_buffer_view_get_margin(display->view, GTK_DISPLAY_PANEL(display)->display); + *x += g_buffer_view_get_margin(display->view, GTK_DISPLAY_PANEL(display)->display_options); height = gtk_widget_get_allocated_height(GTK_WIDGET(display)); @@ -874,7 +874,7 @@ static bool _gtk_buffer_display_move_caret_to(GtkBufferDisplay *display, gint x, panel = GTK_DISPLAY_PANEL(display); - result = g_buffer_view_compute_caret_full(display->view, x, y, panel->display, &new, &addr); + result = g_buffer_view_compute_caret_full(display->view, x, y, panel->display_options, &new, &addr); if (result) gtk_buffer_display_relocate_caret(display, &new, &addr); diff --git a/src/gtkext/gtkdisplaypanel-int.h b/src/gtkext/gtkdisplaypanel-int.h index a2170e7..4425427 100644 --- a/src/gtkext/gtkdisplaypanel-int.h +++ b/src/gtkext/gtkdisplaypanel-int.h @@ -76,8 +76,8 @@ struct _GtkDisplayPanel GtkScrollablePolicy vscroll_policy; /* Politique verticale */ bool show_border; /* Affichage d'une bordure ? */ - BinaryView content; /* Type de contenu */ - const bool *display; /* Affichage des colonnes ? */ + unsigned int view_index; /* Indice du type de contenu */ + bool *display_options; /* Affichage des colonnes ? */ GLoadedBinary *binary; /* Binaire à visualiser */ diff --git a/src/gtkext/gtkdisplaypanel.c b/src/gtkext/gtkdisplaypanel.c index 003ac5f..620a1b1 100644 --- a/src/gtkext/gtkdisplaypanel.c +++ b/src/gtkext/gtkdisplaypanel.c @@ -87,6 +87,17 @@ static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *, GtkDispl /* Réagit à un changement des règles d'affichage. */ static void on_view_panel_binary_display_change(GLoadedBinary *, BinaryView, BufferLineColumn, GtkDisplayPanel *); + + +/* ----------------------- INTERFACE DE PANNEAU DE CHARGEMENT ----------------------- */ + + +/* Associe à un panneau d'affichage un binaire chargé. */ +static void gtk_display_panel_set_content(GtkDisplayPanel *, GLoadedContent *); + +/* Fournit le contenu associé à un panneau de chargement. */ +static GLoadedContent *gtk_display_panel_get_content(const GtkDisplayPanel *); + /* Place en cache un rendu destiné à l'aperçu graphique rapide. */ static void gtk_display_panel_cache_glance(GtkDisplayPanel *, cairo_t *, const GtkAllocation *, double); @@ -190,6 +201,9 @@ static void gtk_display_panel_init(GtkDisplayPanel *panel) static void gtk_display_panel_loaded_interface_init(GLoadedPanelInterface *iface) { + iface->set_content = (set_loaded_panel_content_fc)gtk_display_panel_set_content; + iface->get_content = (get_loaded_panel_content_fc)gtk_display_panel_get_content; + iface->cache_glance = (cache_loaded_glance_fc)gtk_display_panel_cache_glance; } @@ -677,25 +691,6 @@ static void gtk_display_panel_adjustment_value_changed(GtkAdjustment *adj, GtkDi /****************************************************************************** * * -* Paramètres : panel = composant GTK à consulter. * -* * -* Description : Indique le type de contenu représenté par le composant. * -* * -* Retour : Identifiant d'un type de représentation de contenu. * -* * -* Remarques : - * -* * -******************************************************************************/ - -BinaryView gtk_display_panel_describe_content(const GtkDisplayPanel *panel) -{ - return panel->content; - -} - - -/****************************************************************************** -* * * Paramètres : panel = composant GTK à mettre à jour. * * show = état de l'affichage auquel parvenir. * * * @@ -814,36 +809,6 @@ void gtk_display_panel_draw_border(GtkDisplayPanel *panel, cairo_t *cr) /****************************************************************************** * * -* Paramètres : panel = composant GTK à mettre à jour. * -* binary = binaire associé à intégrer. * -* view = aspect du binaire à présenter. * -* * -* Description : Associe à un panneau d'affichage un binaire chargé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void gtk_display_panel_attach_binary(GtkDisplayPanel *panel, GLoadedBinary *binary, BinaryView view) -{ - g_object_ref(G_OBJECT(binary)); - panel->binary = binary; - - panel->content = view; - panel->display = g_loaded_binary_get_column_display(binary, view); - - if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->attach != NULL) /* REMME */ - GTK_DISPLAY_PANEL_GET_CLASS(panel)->attach(panel, binary); - - g_signal_connect(binary, "display-changed", G_CALLBACK(on_view_panel_binary_display_change), panel); - -} - - -/****************************************************************************** -* * * Paramètres : binary = bianire dont les consignes d'affichage ont évolué. * * view = type d'affichage à considérer. * * col = colonne dont le statut a changé. * @@ -859,7 +824,7 @@ void gtk_display_panel_attach_binary(GtkDisplayPanel *panel, GLoadedBinary *bina static void on_view_panel_binary_display_change(GLoadedBinary *binary, BinaryView view, BufferLineColumn col, GtkDisplayPanel *panel) { - if (panel->content == view) + if (panel->view_index == view) { gtk_widget_queue_resize(gtk_widget_get_parent(GTK_WIDGET(panel))); gtk_widget_queue_resize(GTK_WIDGET(panel)); @@ -1067,35 +1032,6 @@ bool gtk_display_panel_get_position(const GtkDisplayPanel *panel, GBufferLine ** /****************************************************************************** * * -* Paramètres : panel = composant GTK à manipuler. * -* cairo = assistant pour la création de rendus. * -* area = taille de la surface réduite à disposition. * -* scale = échelle vis à vis de la taille réelle. * -* * -* Description : Place en cache un rendu destiné à l'aperçu graphique rapide. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void gtk_display_panel_cache_glance(GtkDisplayPanel *panel, cairo_t *cairo, const GtkAllocation *area, double scale) -{ - if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->cache_glance != NULL) - GTK_DISPLAY_PANEL_GET_CLASS(panel)->cache_glance(panel, cairo, area, scale); - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* CONVERSIONS DE COORDONNEES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * * Paramètres : panel = composant GTK à consulter. * * event = informations liées à l'événement. * * * @@ -1165,3 +1101,84 @@ void gtk_display_panel_compute_relative_coords(GtkDisplayPanel *panel, gint *x, *y -= gtk_adjustment_get_value(panel->vadjustment); } + + + +/* ---------------------------------------------------------------------------------- */ +/* INTERFACE DE PANNEAU DE CHARGEMENT */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à mettre à jour. * +* content = binaire associé à intégrer. * +* * +* Description : Associe à un panneau d'affichage un binaire chargé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_set_content(GtkDisplayPanel *panel, GLoadedContent *content) +{ + panel->view_index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); + + panel->display_options = g_loaded_content_get_all_display_options(content, panel->view_index); + + panel->binary = G_LOADED_BINARY(content); + + if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->attach != NULL) /* REMME */ + GTK_DISPLAY_PANEL_GET_CLASS(panel)->attach(panel, panel->binary); + + g_signal_connect(content, "display-changed", G_CALLBACK(on_view_panel_binary_display_change), panel); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à consulter. * +* * +* Description : Fournit le contenu associé à un panneau de chargement. * +* * +* Retour : Contenu quelconque chargé en mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GLoadedContent *gtk_display_panel_get_content(const GtkDisplayPanel *panel) +{ + GLoadedContent *result; /* Contenu à retourner */ + + result = G_LOADED_CONTENT(panel->binary); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = composant GTK à manipuler. * +* cairo = assistant pour la création de rendus. * +* area = taille de la surface réduite à disposition. * +* scale = échelle vis à vis de la taille réelle. * +* * +* Description : Place en cache un rendu destiné à l'aperçu graphique rapide. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void gtk_display_panel_cache_glance(GtkDisplayPanel *panel, cairo_t *cairo, const GtkAllocation *area, double scale) +{ + if (GTK_DISPLAY_PANEL_GET_CLASS(panel)->cache_glance != NULL) + GTK_DISPLAY_PANEL_GET_CLASS(panel)->cache_glance(panel, cairo, area, scale); + +} diff --git a/src/gtkext/gtkdisplaypanel.h b/src/gtkext/gtkdisplaypanel.h index 3ea967a..7d4c824 100644 --- a/src/gtkext/gtkdisplaypanel.h +++ b/src/gtkext/gtkdisplaypanel.h @@ -50,15 +50,9 @@ typedef struct _GtkDisplayPanelClass GtkDisplayPanelClass; /* Détermine le type du composant d'affichage générique. */ GType gtk_display_panel_get_type(void); -/* Indique le type de contenu représenté par le composant. */ -BinaryView gtk_display_panel_describe_content(const GtkDisplayPanel *); - /* Définit si une bordure est à afficher. */ void gtk_display_panel_show_border(GtkDisplayPanel *, bool); -/* Associe à un panneau d'affichage un binaire chargé. */ -void gtk_display_panel_attach_binary(GtkDisplayPanel *, GLoadedBinary *, BinaryView); - /* Définit si les adresses doivent apparaître dans le rendu. */ void gtk_display_panel_set_addresses_display(GtkDisplayPanel *, bool); diff --git a/src/gui/editor.c b/src/gui/editor.c index 6785753..d1f90d5 100644 --- a/src/gui/editor.c +++ b/src/gui/editor.c @@ -47,6 +47,7 @@ #include "../core/global.h" #include "../core/params.h" #include "../gtkext/easygtk.h" +#include "../gtkext/gtkdisplaypanel.h" #include "../gtkext/gtkdockable.h" #include "../gtkext/gtkdockstation.h" #include "../gtkext/support.h" @@ -214,6 +215,11 @@ static void notify_paned_handle_position_change(GObject *, GParamSpec *, gpointe /* Réagit à un changement du projet principal. */ static void notify_editor_project_change(GStudyProject *, bool); +/* Assure un positionnement initial idéal. */ +static gboolean scroll_for_the_first_time(GtkWidget *, GdkEvent *, GLoadedContent *); + +/* Affiche le contenu qui vient de rejoindre un projet donné. */ +void on_editor_loaded_content_added(GStudyProject *, GLoadedContent *, void *); @@ -1612,7 +1618,12 @@ static void notify_editor_project_change(GStudyProject *project, bool new) if (new) { - /* ... */ + + g_signal_connect(project, "content-added", G_CALLBACK(on_editor_loaded_content_added), NULL); + + + + /* TODO : show_all()... */ } @@ -1623,9 +1634,86 @@ static void notify_editor_project_change(GStudyProject *project, bool new) g_study_project_hide(project); + g_signal_handlers_disconnect_by_func(project, G_CALLBACK(on_editor_loaded_content_added), NULL); + } } + + +/****************************************************************************** +* * +* Paramètres : project = project impliqué dans l'opération. * +* content = nouveau contenu à présenter dans l'éditeur. * +* unused = adresse non utilisée ici. * +* * +* Description : Affiche le contenu qui vient de rejoindre un projet donné. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void on_editor_loaded_content_added(GStudyProject *project, GLoadedContent *content, void *unused) +{ + GtkWidget *selected; /* Interface de prédilection */ + const char *name; /* Titre associé au binaire */ + const char *lname; /* Description du binaire */ + GPanelItem *panel; /* Nouveau panneau à integrer */ + + selected = g_loaded_content_build_view(content, 0); + + name = g_loaded_content_describe(content, false); + lname = g_loaded_content_describe(content, true); + + panel = g_panel_item_new(PIP_BINARY_VIEW, name, lname, selected, true, "N"); + register_panel_item(panel, get_main_configuration()); + + g_signal_connect(selected, "size-allocate", G_CALLBACK(scroll_for_the_first_time), content); + + g_panel_item_dock(panel); + + update_project_area(project); + +} + + +/****************************************************************************** +* * +* Paramètres : widget = composant d'affichage nouvellement porté à l'écran.* +* event = informations liées à l'événement. * +* content = contenu chargé associé au composant d'affichage. * +* * +* Description : Assure un positionnement initial idéal. * +* * +* Retour : FALSE. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean scroll_for_the_first_time(GtkWidget *widget, GdkEvent *event, GLoadedContent *content) +{ + GExeFormat *format; /* Format associé au binaire */ + vmpa2t target; /* Position initiale à viser */ + + g_signal_handlers_disconnect_by_func(widget, G_CALLBACK(scroll_for_the_first_time), content); + + if (G_IS_LOADED_BINARY(content)) + { + format = g_loaded_binary_get_format(G_LOADED_BINARY(content)); + + if (g_exe_format_get_main_address(format, &target)) + gtk_display_panel_request_move(GTK_DISPLAY_PANEL(widget), &target); + + g_object_unref(G_OBJECT(format)); + + } + + return FALSE; + +} diff --git a/src/gui/menus/project.c b/src/gui/menus/project.c index c46c017..5d027a0 100644 --- a/src/gui/menus/project.c +++ b/src/gui/menus/project.c @@ -46,8 +46,8 @@ static void mcb_project_add_shellcode(GtkMenuItem *, GMenuBar *); /* Affiche la boîte d'ajout d'un binaire au projet courant. */ static void mcb_project_add_binary_file(GtkMenuItem *, GMenuBar *); -/* Retire un binaire du projet indiqué. */ -static void mcb_project_remove_binary(GtkMenuItem *, GStudyProject *); +/* Retire un contenu du projet indiqué. */ +static void mcb_project_remove_content(GtkMenuItem *, GStudyProject *); @@ -122,8 +122,8 @@ void update_menu_project_for_project(GtkWidget *widget, GStudyProject *project, GtkWidget *menubar; /* Support pour éléments */ GList *list; /* Liste des éléments en place */ GList *iter; /* Boucle de parcours #1 */ - size_t count; /* Nombre de binaires attachés */ - GLoadedBinary **binaries; /* Liste de ces binaires */ + size_t count; /* Nombre de contenus attachés */ + GLoadedContent **contents; /* Liste de ces contenus */ size_t i; /* Boucle de parcours #2 */ const char *desc; /* Description à afficher */ GtkWidget *submenuitem; /* Sous-menu à ajouter */ @@ -142,23 +142,26 @@ void update_menu_project_for_project(GtkWidget *widget, GStudyProject *project, /* Ajout des entrées */ - binaries = g_study_project_get_binaries(project, &count); + contents = g_study_project_get_contents(project, &count); for (i = 0; i < count; i++) { - desc = g_loaded_binary_get_name(binaries[i], true); + desc = g_loaded_content_describe(contents[i], true); submenuitem = qck_create_menu_item(NULL, NULL, desc, - G_CALLBACK(mcb_project_remove_binary), project); - g_object_set_data(G_OBJECT(submenuitem), "binary", binaries[i]); + G_CALLBACK(mcb_project_remove_content), project); + g_object_set_data_full(G_OBJECT(submenuitem), "content", contents[i], g_object_unref); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); - g_object_unref(G_OBJECT(binaries[i])); + /** + * Note : l'appel à g_object_unref() est réalisé lorsque la référence + * est retirée du menu. + */ } - if (binaries != NULL) - free(binaries); + if (contents != NULL) + free(contents); gtk_widget_set_sensitive(menuitem, count > 0); @@ -304,7 +307,7 @@ static void mcb_project_add_binary_file(GtkMenuItem *menuitem, GMenuBar *bar) * Paramètres : menuitem = élément de menu sélectionné. * * project = projet d'appartenance du binaire à traiter. * * * -* Description : Retire un binaire du projet indiqué. * +* Description : Retire un contenu du projet indiqué. * * * * Retour : - * * * @@ -312,13 +315,17 @@ static void mcb_project_add_binary_file(GtkMenuItem *menuitem, GMenuBar *bar) * * ******************************************************************************/ -static void mcb_project_remove_binary(GtkMenuItem *menuitem, GStudyProject *project) +static void mcb_project_remove_content(GtkMenuItem *menuitem, GStudyProject *project) { - GLoadedBinary *binary; /* Binaire à retirer */ + GObject *ref; /* Espace de référencement */ + GLoadedContent *content; /* Contenu à retirer */ - binary = G_LOADED_BINARY(g_object_get_data(G_OBJECT(menuitem), "binary")); + ref = G_OBJECT(menuitem); - g_study_project_detach_binary(project, binary); - g_object_unref(G_OBJECT(binary)); + content = G_LOADED_CONTENT(g_object_get_data(ref, "content")); + + g_study_project_detach_content(project, content); + + g_object_set_data(ref, "content", NULL); } diff --git a/src/gui/menus/view.c b/src/gui/menus/view.c index 4298805..81b06d6 100644 --- a/src/gui/menus/view.c +++ b/src/gui/menus/view.c @@ -35,7 +35,7 @@ #include "../core/global.h" #include "../core/items.h" #include "../core/panels.h" -#include "../../analysis/project.h" +#include "../../analysis/loaded.h" #include "../../gtkext/easygtk.h" #include "../../gtkext/gtkblockdisplay.h" #include "../../gtkext/gtkgraphdisplay.h" @@ -125,17 +125,17 @@ GtkWidget *build_menu_view(GObject *ref, GtkAccelGroup *accgroup, GMenuBar *bar) submenuitem = qck_create_check_menu_item(ref, "mnu_view_display_off", _("Physical offset"), G_CALLBACK(mcb_view_display_column), NULL); - g_object_set_data(G_OBJECT(submenuitem), "kind_of_col", GUINT_TO_POINTER(BLC_PHYSICAL)); + g_object_set_data(G_OBJECT(submenuitem), "kind_of_opt", GUINT_TO_POINTER(BLC_PHYSICAL)); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_check_menu_item(ref, "mnu_view_display_addr", _("Virtual address"), G_CALLBACK(mcb_view_display_column), NULL); - g_object_set_data(G_OBJECT(submenuitem), "kind_of_col", GUINT_TO_POINTER(BLC_VIRTUAL)); + g_object_set_data(G_OBJECT(submenuitem), "kind_of_opt", GUINT_TO_POINTER(BLC_VIRTUAL)); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); submenuitem = qck_create_check_menu_item(ref, "mnu_view_display_code", _("Binary code"), G_CALLBACK(mcb_view_display_column), NULL); - g_object_set_data(G_OBJECT(submenuitem), "kind_of_col", GUINT_TO_POINTER(BLC_BINARY)); + g_object_set_data(G_OBJECT(submenuitem), "kind_of_opt", GUINT_TO_POINTER(BLC_BINARY)); gtk_container_add(GTK_CONTAINER(menubar), submenuitem); /* - */ @@ -175,8 +175,8 @@ void update_menu_view_for_view(GtkWidget *widget, GtkDisplayPanel *panel, GMenuB GtkRadioMenuItem *item; /* Elément de menu arbitraire */ GSList *radios; /* Liste des menus d'affichage */ GSList *found; /* Elément de menu à activer */ - BinaryView content; /* Type de vue active */ - GLoadedBinary *binary; /* Binaire courant */ + GLoadedContent *content; /* Contenu global représenté */ + unsigned int view_index; /* Indice de représentation */ const bool *display; /* Règles d'affichage courantes*/ GtkWidget *submenuitem; /* Sous-élément de menu */ bool status; /* Consigne d'affichage */ @@ -226,13 +226,13 @@ void update_menu_view_for_view(GtkWidget *widget, GtkDisplayPanel *panel, GMenuB /* - */ - content = gtk_display_panel_describe_content(panel); + content = g_loaded_panel_get_content(G_LOADED_PANEL(panel)); - binary = get_current_binary(); + view_index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); - display = g_loaded_binary_get_column_display(binary, content); + display = g_loaded_content_get_all_display_options(content, view_index); - g_object_unref(G_OBJECT(binary)); + g_object_unref(G_OBJECT(content)); /* Positions physiques */ @@ -465,11 +465,12 @@ static void mcb_view_change_support(GtkRadioMenuItem *menuitem, gpointer unused) { GSList *group; /* Liste de menus radio */ GSList *iter; /* Boucle de parcours */ - BinaryView wanted; /* Nouvelle vue à présenter */ - GtkDisplayPanel *panel; /* Afficheur effectif de code */ + unsigned int wanted; /* Nouvelle vue à présenter */ + GLoadedPanel *panel; /* Afficheur effectif de code */ GtkDockStation *station; /* Base du remplacement */ - GtkWidget *scroll; /* Nouveau support à utiliser */ - GtkDisplayPanel *new; /* Nouvel afficheur de code */ + GLoadedContent *content; /* Contenu représenté */ + GtkWidget *support; /* Nouvel afficheur généraliste*/ + GtkWidget *new; /* Panneau encapsulé */ /* On ne traite qu'une seule fois ! */ if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem))) return; @@ -483,16 +484,17 @@ static void mcb_view_change_support(GtkRadioMenuItem *menuitem, gpointer unused) wanted = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(iter->data), "kind_of_view")); panel = get_current_view(); - station = get_dock_station_for_view_panel(panel); + station = get_dock_station_for_view_panel(GTK_WIDGET(panel)); - /* En vue du retrait de la station d'accueil... */ - scroll = get_scroll_window_for_view_panel(panel); - g_object_ref(G_OBJECT(scroll)); + content = g_loaded_panel_get_content(panel); - new = get_alt_view_for_view_panel(panel, wanted); - scroll = get_scroll_window_for_view_panel(new); + support = g_loaded_content_build_view(content, wanted); - gtk_dock_panel_change_active_widget(station, scroll); + g_object_unref(G_OBJECT(content)); + + gtk_dock_panel_change_active_widget(station, support); + + new = get_loaded_panel_from_built_view(support); change_editor_items_current_view(G_LOADED_PANEL(new)); @@ -518,25 +520,25 @@ static void mcb_view_change_support(GtkRadioMenuItem *menuitem, gpointer unused) static void mcb_view_display_column(GtkCheckMenuItem *menuitem, gpointer unused) { - BufferLineColumn col; /* Colonne à traiter */ - GLoadedBinary *binary; /* Binaire courant */ - GtkDisplayPanel *panel; /* Affichage courant */ - BinaryView view; /* Type de vue représentée */ + unsigned int option; /* Paramètre à traiter */ gboolean active; /* Etat de sélection du menu */ + GLoadedPanel *panel; /* Afficheur effectif de code */ + GLoadedContent *content; /* Contenu représenté */ + unsigned int index; /* Indice de la vue courante */ - col = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(menuitem), "kind_of_col")); + option = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(menuitem), "kind_of_opt")); - binary = get_current_binary(); + active = gtk_check_menu_item_get_active(menuitem); panel = get_current_view(); - view = gtk_display_panel_describe_content(panel); - g_object_unref(G_OBJECT(panel)); + content = g_loaded_panel_get_content(panel); - active = gtk_check_menu_item_get_active(menuitem); + index = g_loaded_content_get_view_index(content, GTK_WIDGET(panel)); - g_loaded_binary_set_column_display(binary, view, col, active); + g_loaded_content_set_display_option(content, index, option, active); - g_object_unref(G_OBJECT(binary)); + g_object_unref(G_OBJECT(content)); + g_object_unref(G_OBJECT(panel)); } |