rendered paste body/* * Synce Registry Editor * Copyright (C) 2007 Mihai Draghicioiu <mihai.draghicioiu@gmail.com> * * This program 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 2 * of the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */#include <string.h>#include <gtk/gtk.h>#include <rapi.h>static void dump_reg(char *filename){ printf("dump_reg(\"%s\");\n", filename);}static void export_reg(){ GtkWidget *dialog = gtk_file_chooser_dialog_new("Export registry", NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); if(gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { char *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (dialog)); dump_reg(filename); g_free (filename); } gtk_widget_destroy (dialog);}static void import_reg(){}static GtkItemFactoryEntry menu_items[] = {{ "/_Registry", NULL, NULL, 0, "<Branch>" },{ "/Registry/_Export", "<control>E", export_reg, 0, "<StockItem>", GTK_STOCK_SAVE },{ "/Registry/_Import", "<control>I", import_reg, 0, "<StockItem>", GTK_STOCK_OPEN },{ "/Registry/sep", NULL, NULL, 0, "<Separator>" },{ "/Registry/_Quit", "<CTRL>Q", gtk_main_quit, 0, "<StockItem>", GTK_STOCK_QUIT },{ "/_Tools", NULL, NULL, 0, "<Branch>" },{ "/Tools/tear", NULL, NULL, 0, "<Tearoff>" },{ "/Tools/Search", NULL, NULL, 0, "<StockItem>", GTK_STOCK_FIND },{ "/_Help", NULL, NULL, 0, "<LastBranch>" },{ "/_Help/About", NULL, NULL, 0, "<StockItem>", GTK_STOCK_ABOUT },};static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);static GtkItemFactoryEntry val_menu_items[] = {{ "/_Edit", NULL, NULL, 0, "<Item>" },{ "/_New value", NULL, NULL, 0, "<Branch>" },{ "/New value/_String", NULL, NULL, 0, "<Item>" },{ "/New value/_DWORD", NULL, NULL, 0, "<Item>" },{ "/New value/_Multi String", NULL, NULL, 0, "<Item>" },{ "/New value/_Hex", NULL, NULL, 0, "<Item>" },{ "/_Delete", NULL, NULL, 0, "<Item>" },{ "/_Copy value name", NULL, NULL, 0, "<Item>" },{ "/Copy value d_ata", NULL, NULL, 0, "<Item>" },};static gint nval_menu_items = sizeof (val_menu_items) / sizeof (val_menu_items[0]);enum{ VALUE_NAME = 0, VALUE_TYPE, VALUE_DATA};static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data){ return FALSE;}static void destroy(GtkWidget *widget, gpointer data){ gtk_main_quit();}HKEY get_subkey(GtkTreeStore *store, GtkTreePath *path){ gint *indices = gtk_tree_path_get_indices(path); gint depth = gtk_tree_path_get_depth(path); HKEY rootkey; switch(indices[0]) { case 0: rootkey = HKEY_CLASSES_ROOT; break; case 1: rootkey = HKEY_CURRENT_USER; break; case 2: rootkey = HKEY_LOCAL_MACHINE; break; case 3: rootkey = HKEY_USERS; break; default: printf("invalid root key %d\n", indices[0]); return 0; } if(depth == 1) return rootkey; int i; char buf[MAX_PATH]; buf[0] = 0; GtkTreeIter iter, iter2; gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, indices[0]); for(i = 1; i < depth; i++) { gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter2, &iter, indices[i]); char *childstr; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter2, 0, &childstr, -1); if(i > 1) strcat(buf, "\\"); strcat(buf, childstr); iter = iter2; } //g_print("get subkey childstr %s\n", buf); HKEY key; LONG l = CeRegOpenKeyEx(rootkey, wstr_from_utf8(buf), 0, 0, &key); if(l != 0) { printf("Could not find key: %s\n", synce_strerror(l)); return 0; } //printf("get_subkey returning %d\n", key); return key;}void load_subkeys(GtkTreeView *treeview, GtkTreeStore *store, GtkTreeIter *iter, GtkTreePath *path){ HKEY key; key = get_subkey(store, path); LONG l; DWORD i = 0; WCHAR subk_name[MAX_PATH]; DWORD subk_name_len = sizeof(subk_name); for(i = 0; ; i++) { l = CeRegEnumKeyEx(key, i, subk_name, &subk_name_len, NULL, NULL, NULL, NULL); if(ERROR_NO_MORE_ITEMS == l) break; else if(ERROR_SUCCESS != l) { fprintf(stderr,"Failed to list subkey #%d: %s\n", i, synce_strerror(l)); return ; }// g_print("i %d subk_name %s subk_name_len %d\n", i, wstr_to_ascii(subk_name), subk_name_len); subk_name_len = 512; GtkTreeIter iter2; gtk_tree_store_append(store, &iter2, iter); gtk_tree_store_set(store, &iter2, 0, wstr_to_utf8(subk_name), -1); HKEY subk; CeRegOpenKeyEx(key, subk_name, 0, 0, &subk); DWORD nsubk = 0;// WCHAR cl[512];// DWORD ncl = 512; DWORD d1; CeRegQueryInfoKey(subk, NULL, NULL, NULL, &nsubk, &d1, NULL, NULL, NULL, NULL, NULL, NULL); CeRegCloseKey(subk); if(nsubk > 0) { GtkTreeIter iter3; gtk_tree_store_append(store, &iter3, &iter2); gtk_tree_store_set(store, &iter3, 0, NULL, -1); } } if(gtk_tree_path_get_depth(path) > 1) CeRegCloseKey(key);}void row_expanded(GtkTreeView *treeview, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data){ GtkTreeStore *store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview)); char *name; gtk_tree_model_get(GTK_TREE_MODEL(store), iter, 0, &name, -1); GtkTreeIter iter2; gboolean er = gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter2, iter, 0); if(er == TRUE) { char *childname; gtk_tree_model_get(GTK_TREE_MODEL(store), &iter2, 0, &childname, -1); if(!childname) { load_subkeys(treeview, store, iter, path); gtk_tree_store_remove(store, &iter2); } }}void sel_changed(GtkTreeSelection *sel, GtkListStore *lstore){ gtk_list_store_clear(lstore); GtkTreeIter iter; GtkTreeModel *store; gboolean er = gtk_tree_selection_get_selected(sel, &store, &iter); if(!er) return; GtkTreePath *path = gtk_tree_model_get_path(store, &iter); HKEY key = get_subkey(store, path); gtk_tree_path_free(path); int i; for(i = 0; ; i++) { WCHAR wide_name[MAX_PATH], data[2048]; DWORD name_size = sizeof(wide_name), data_size = 2048; DWORD type = -1; LONG l; l = CeRegEnumValue(key, i, wide_name, &name_size, NULL, &type, data, &data_size); if(ERROR_NO_MORE_ITEMS == l) break; else if(ERROR_SUCCESS != l) { fprintf(stderr,"Failed to list subkey #%d: %s\n", i, synce_strerror(l)); //return 1; } l = CeRegQueryValueEx(key, wide_name, NULL, &type, data, &data_size); if(l != 0) { fprintf(stderr, "Failed to query value #%d: %s\n", i, synce_strerror(1)); } char *typestr; char buf[256]; char *datastr = ""; switch(type) { case REG_BINARY: typestr = "REG_BINARY"; break; case REG_DWORD: typestr = "REG_DWORD"; sprintf(buf, "0x%08X", ((DWORD *)data)[0]); datastr = buf; break; case REG_EXPAND_SZ: typestr = "REG_EXPAND_SZ"; datastr = wstr_to_utf8(data); break; case REG_LINK: typestr = "REG_LINK"; break; case REG_MULTI_SZ: typestr = "REG_MULTI_SZ"; break; case REG_NONE: typestr = "REG_NONE"; break; case REG_SZ: typestr = "REG_SZ"; datastr = wstr_to_utf8(data); break; default: sprintf(buf, "Unknown 0x%08X", type); typestr = buf;; } //g_print("name \"%s\" (%d)\n", wstr_to_utf8(wide_name), name_size); gtk_list_store_append(lstore, &iter); gtk_list_store_set(lstore, &iter, 0, wstr_to_utf8(wide_name), 1, typestr, 2, datastr, -1); }}GtkWidget *init_treeview(GtkListStore *lstore){ GtkWidget *treeview = gtk_tree_view_new(); GtkTreeStore *store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_UINT); GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), -1, "Keys", renderer, "text", 0, NULL); GtkTreeIter iter, iter2; gtk_tree_store_append(store, &iter, NULL); gtk_tree_store_set(store, &iter, 0, "HKEY_CLASSES_ROOT", -1); gtk_tree_store_append(store, &iter2, &iter); gtk_tree_store_set(store, &iter2, 0, NULL, -1); gtk_tree_store_append(store, &iter, NULL); gtk_tree_store_set(store, &iter, 0, "HKEY_CURRENT_USER", -1); gtk_tree_store_append(store, &iter2, &iter); gtk_tree_store_set(store, &iter2, 0, NULL, -1); gtk_tree_store_append(store, &iter, NULL); gtk_tree_store_set(store, &iter, 0, "HKEY_LOCAL_MACHINE", -1); gtk_tree_store_append(store, &iter2, &iter); gtk_tree_store_set(store, &iter2, 0, NULL, -1); gtk_tree_store_append(store, &iter, NULL); gtk_tree_store_set(store, &iter, 0, "HKEY_USERS", -1); gtk_tree_store_append(store, &iter2, &iter); gtk_tree_store_set(store, &iter2, 0, NULL, -1); gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(store)); g_object_unref(G_OBJECT(store)); g_signal_connect(G_OBJECT(treeview), "row-expanded", G_CALLBACK(row_expanded), NULL);// g_signal_connect(G_OBJECT(treeview), "cursor_changed", G_CALLBACK(cursor_changed), lstore); GtkTreeSelection *sel = gtk_tree_view_get_selection(treeview); g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(sel_changed), lstore); return treeview;}static void list_item_edit(GtkMenuItem *item, GtkTreeIter *iter){}static void list_item_delete(GtkMenuItem *item, GtkTreeIter *iter){}static gboolean list_event(GtkWidget *widget, GdkEventButton *event, GtkListStore *lstore){ if(event->button == 3 && event->type == GDK_BUTTON_PRESS) { GtkWidget *menu = gtk_menu_new (); g_signal_connect(menu, "deactivate", G_CALLBACK(gtk_widget_destroy), NULL); GtkTreeIter iter; GtkMenuItem *menu_item = gtk_menu_item_new_with_label("Edit"); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(list_item_edit), &iter); gtk_widget_show(menu_item); menu_item = gtk_menu_item_new_with_label("Delete"); gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); g_signal_connect(G_OBJECT(menu_item), "activate", G_CALLBACK(list_item_delete), &iter); gtk_widget_show(menu_item); int button, event_time; if(event) { button = event->button; event_time = event->time; } else { button = 0; event_time = gtk_get_current_event_time (); } gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, button, event_time); return TRUE; } return FALSE;}int main(int argc, char **argv){ gtk_init(&argc, &argv); RapiConnection* connection = NULL; char *devpath = NULL; HRESULT hr; if((connection = rapi_connection_from_path(devpath)) == NULL) { fprintf(stderr, "%s: Could not find configuration at path '%s'\n", argv[0], devpath?devpath:"(Default)"); goto exit; } rapi_connection_select(connection); if (S_OK != (hr = CeRapiInit())) { fprintf(stderr, "%s: Unable to initialize RAPI: %s\n", argv[0], synce_strerror(hr)); goto exit; } /* Main window */ GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Synce Registry Editor"); gtk_window_set_default_size(GTK_WINDOW(window), 500, 300); g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL); /* Main VBox */ GtkWidget *vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(window), vbox); /* Menu bar */ GtkAccelGroup *accel_group = gtk_accel_group_new (); GtkItemFactory *item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group); gtk_item_factory_create_items(item_factory, nmenu_items, menu_items, NULL); gtk_window_add_accel_group(GTK_WINDOW(window), accel_group); GtkWidget *menubar = gtk_item_factory_get_widget (item_factory, "<main>"); gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, TRUE, 0); /* HPaned */ GtkWidget *hpaned = gtk_hpaned_new(); gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0); /* List view */ GtkWidget *listview = gtk_tree_view_new(); GtkListStore *lstore = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", VALUE_NAME, NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_insert_column(GTK_TREE_VIEW(listview), column, -1); column = gtk_tree_view_column_new_with_attributes("Type", renderer, "text", VALUE_TYPE, NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_insert_column(GTK_TREE_VIEW(listview), column, -1); column = gtk_tree_view_column_new_with_attributes("Data", renderer, "text", VALUE_DATA, NULL); gtk_tree_view_column_set_resizable(column, TRUE); gtk_tree_view_insert_column(GTK_TREE_VIEW(listview), column, -1); gtk_tree_view_set_model(GTK_TREE_VIEW(listview), GTK_TREE_MODEL(lstore)); g_object_unref(G_OBJECT(lstore)); g_signal_connect(G_OBJECT(listview), "event", G_CALLBACK(list_event), lstore); /* List view scrolled window */ GtkWidget *scrolledwindow1 = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow1), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(scrolledwindow1), listview); gtk_paned_add2(GTK_PANED(hpaned), scrolledwindow1); /* Tree view */ GtkWidget *treeview = init_treeview(lstore); /* Tree view scrolled window */ GtkWidget *scrolledwindow2 = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow2), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow2), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(scrolledwindow2), treeview); GtkRequisition req; gtk_widget_size_request(treeview, &req); gtk_widget_set_size_request(scrolledwindow2, req.width + 10, -1); gtk_paned_add1(GTK_PANED(hpaned), scrolledwindow2); /* Status bar */ GtkWidget *statusbar = gtk_statusbar_new(); gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, TRUE, 0); gtk_widget_show(statusbar); gtk_widget_show(treeview); gtk_widget_show(scrolledwindow1); gtk_widget_show(listview); gtk_widget_show(scrolledwindow2); gtk_widget_show(hpaned); gtk_widget_show(menubar); gtk_widget_show(vbox); gtk_widget_show(window); gtk_main();exit: CeRapiUninit(); return 0;}