mirror of
https://github.com/mdbtools/mdbtools.git
synced 2026-03-10 00:20:54 +08:00
add -M option to mdb-ver
make gmdb2 version match mainline code new dissector for jet4 tdef pages in gmdb2 gmdb2 right mouse click behaviour bugfix pre-compute index page bitmap in mdb_index_unpack_page() in preparation for index writes.
This commit is contained in:
@@ -2,4 +2,4 @@ Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
.libs
|
||||
mdb-dump
|
||||
mdb-hexdump
|
||||
|
||||
@@ -650,7 +650,47 @@ GtkTreeIter *container;
|
||||
}
|
||||
}
|
||||
void
|
||||
gmdb_debug_dissect_tabledef_pg(GtkTreeStore *store, char *fbuf, int offset, int len)
|
||||
gmdb_debug_dissect_tabledef_pg4(GtkTreeStore *store, char *fbuf, int offset, int len)
|
||||
{
|
||||
gchar str[100];
|
||||
guint32 i, num_idx, num_cols, idx_entries;
|
||||
int newbase;
|
||||
GtkTreeIter *node, *container;
|
||||
|
||||
snprintf(str, 100, "Next TDEF Page: 0x%06x (%lu)",
|
||||
get_uint32(&fbuf[offset+4]), get_uint32(&fbuf[offset+4]));
|
||||
gmdb_debug_add_item(store, NULL, str, offset+4, offset+7);
|
||||
snprintf(str, 100, "Length of Data: %lu", get_uint32(&fbuf[offset+8]));
|
||||
gmdb_debug_add_item(store, NULL, str, offset+8, offset+11);
|
||||
snprintf(str, 100, "# of Records: %lu", get_uint32(&fbuf[offset+16]));
|
||||
gmdb_debug_add_item(store, NULL, str, offset+16, offset+19);
|
||||
snprintf(str, 100, "Autonumber Value: %lu", get_uint32(&fbuf[offset+20]));
|
||||
gmdb_debug_add_item(store, NULL, str, offset+20, offset+23);
|
||||
snprintf(str, 100, "Table Type: 0x%02x (%s)", fbuf[offset+40],
|
||||
gmdb_val_to_str(table_types, fbuf[offset+40]));
|
||||
gmdb_debug_add_item(store, NULL, str, offset+40, offset+40);
|
||||
num_cols = get_uint16(&fbuf[offset+41]);
|
||||
snprintf(str, 100, "Max # of Columns: %u", num_cols);
|
||||
gmdb_debug_add_item(store, NULL, str, offset+41, offset+42);
|
||||
snprintf(str, 100, "# of VarCols: %u",
|
||||
get_uint16(&fbuf[offset+43]));
|
||||
gmdb_debug_add_item(store, NULL, str, offset+43, offset+44);
|
||||
snprintf(str, 100, "# of Columns: %u",
|
||||
get_uint16(&fbuf[offset+45]));
|
||||
gmdb_debug_add_item(store, NULL, str, offset+45, offset+46);
|
||||
idx_entries = get_uint32(&fbuf[offset+47]);
|
||||
snprintf(str, 100, "# of Index Entries: %lu", idx_entries);
|
||||
gmdb_debug_add_item(store, NULL, str, offset+47, offset+50);
|
||||
|
||||
num_idx = get_uint32(&fbuf[offset+51]);
|
||||
snprintf(str, 100, "# of Real Indices: %lu", num_idx);
|
||||
gmdb_debug_add_item(store, NULL, str, offset+51, offset+54);
|
||||
|
||||
gmdb_debug_add_page_ptr(store, NULL, fbuf, "Used Pages Pointer", offset+55);
|
||||
gmdb_debug_add_page_ptr(store, NULL, fbuf, "Pages Freespace Pointer", offset+59);
|
||||
}
|
||||
void
|
||||
gmdb_debug_dissect_tabledef_pg3(GtkTreeStore *store, char *fbuf, int offset, int len)
|
||||
{
|
||||
gchar str[100];
|
||||
guint32 i, num_idx, num_cols, idx_entries;
|
||||
@@ -670,7 +710,7 @@ GtkTreeIter *node, *container;
|
||||
gmdb_val_to_str(table_types, fbuf[offset+20]));
|
||||
gmdb_debug_add_item(store, NULL, str, offset+20, offset+20);
|
||||
num_cols = get_uint16(&fbuf[offset+21]);
|
||||
snprintf(str, 100, "# of Columns: %u", num_cols);
|
||||
snprintf(str, 100, "Max # of Columns: %u", num_cols);
|
||||
gmdb_debug_add_item(store, NULL, str, offset+21, offset+22);
|
||||
snprintf(str, 100, "# of VarCols: %u",
|
||||
get_uint16(&fbuf[offset+23]));
|
||||
@@ -687,6 +727,7 @@ GtkTreeIter *node, *container;
|
||||
|
||||
gmdb_debug_add_item(store, NULL, str, offset+31, offset+34);
|
||||
gmdb_debug_add_page_ptr(store, NULL, fbuf, "Used Pages Pointer", offset+35);
|
||||
gmdb_debug_add_page_ptr(store, NULL, fbuf, "Pages Freespace Pointer", offset+39);
|
||||
|
||||
container = gmdb_debug_add_item(store, NULL, "Index Entries", -1, -1);
|
||||
for (i=0;i<num_idx;i++) {
|
||||
@@ -748,6 +789,14 @@ GtkTreeIter *node, *container;
|
||||
}
|
||||
}
|
||||
void
|
||||
gmdb_debug_dissect_tabledef_pg(GtkTreeStore *store, char *fbuf, int offset, int len)
|
||||
{
|
||||
if (IS_JET3(mdb))
|
||||
gmdb_debug_dissect_tabledef_pg3(store, fbuf, offset, len);
|
||||
else
|
||||
gmdb_debug_dissect_tabledef_pg4(store, fbuf, offset, len);
|
||||
}
|
||||
void
|
||||
gmdb_debug_dissect(GtkTreeStore *store, char *fbuf, int offset, int len)
|
||||
{
|
||||
gchar str[100];
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="default_width">600</property>
|
||||
<property name="default_height">200</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="enable_layout_config">True</property>
|
||||
|
||||
@@ -24,6 +24,18 @@
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="help_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-help</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="response_id">-11</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="cancel_button">
|
||||
<property name="visible">True</property>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* MDB Tools - A library for reading MS Access database file
|
||||
* Copyright (C) 2000 Brian Bruns
|
||||
* Copyright (C) 2000-2004 Brian Bruns
|
||||
*
|
||||
* 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
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <libgnome/gnome-help.h>
|
||||
#include <glade/glade.h>
|
||||
#include <mdbtools.h>
|
||||
#include <mdbver.h>
|
||||
#include <mdbsql.h>
|
||||
#include "gmdb.h"
|
||||
|
||||
@@ -52,8 +53,8 @@ GdkPixbuf *pixbuf;
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_file (GMDB_ICONDIR "logo.xpm", NULL);
|
||||
|
||||
gtk_widget_show (gnome_about_new ("Gnome MDB Viewer", "0.2",
|
||||
"Copyright 2002-2003 Brian Bruns",
|
||||
gtk_widget_show (gnome_about_new ("Gnome MDB Viewer", MDB_VERSION_NO,
|
||||
"Copyright 2002-2004 Brian Bruns",
|
||||
_("The Gnome-MDB Viewer is the grapical interface to "
|
||||
"MDB Tools. It lets you view and export data and schema"
|
||||
"from MDB files produced by MS Access 97/2000/XP."),
|
||||
|
||||
@@ -362,20 +362,29 @@ gmdb_sql_select_hist_cb(GtkList *list, GladeXML *xml)
|
||||
void
|
||||
gmdb_sql_execute_cb(GtkWidget *w, GladeXML *xml)
|
||||
{
|
||||
guint len;
|
||||
gchar *buf;
|
||||
gchar *bound_data[256];
|
||||
int i;
|
||||
MdbSQLColumn *sqlcol;
|
||||
gchar *titles[256];
|
||||
GtkTextBuffer *txtbuffer;
|
||||
GtkTextIter start, end;
|
||||
GtkWidget *textview, *combo, *treeview, *store;
|
||||
GList *history;
|
||||
GType *gtypes;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeViewColumn *column;
|
||||
long row, maxrow;
|
||||
guint len;
|
||||
gchar *buf;
|
||||
gchar *bound_data[256];
|
||||
int i;
|
||||
MdbSQLColumn *sqlcol;
|
||||
gchar *titles[256];
|
||||
GtkTextBuffer *txtbuffer;
|
||||
GtkTextIter start, end;
|
||||
GtkWidget *textview, *combo, *treeview, *store;
|
||||
GtkWidget *window;
|
||||
GList *history;
|
||||
GType *gtypes;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeViewColumn *column;
|
||||
long row, maxrow;
|
||||
/* GdkCursor *watch, *pointer; */
|
||||
|
||||
/* need to figure out how to clock during the treeview recalc/redraw
|
||||
window = glade_xml_get_widget(xml, "sql_window");
|
||||
watch = gdk_cursor_new(GDK_WATCH);
|
||||
gdk_window_set_cursor(GTK_WIDGET(window)->window, watch);
|
||||
gdk_cursor_unref(watch);
|
||||
*/
|
||||
|
||||
/* stuff this query on the history */
|
||||
textview = glade_xml_get_widget(xml, "sql_textview");
|
||||
@@ -455,6 +464,13 @@ long row, maxrow;
|
||||
|
||||
mdb_sql_reset(sql);
|
||||
g_free(buf);
|
||||
|
||||
/*
|
||||
pointer = gdk_cursor_new(GDK_LEFT_PTR);
|
||||
gdk_window_set_cursor(GTK_WIDGET(window)->window, pointer);
|
||||
gdk_cursor_unref(pointer);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -41,7 +41,7 @@ MdbCatalogEntry *entry;
|
||||
}
|
||||
|
||||
entry = g_ptr_array_index(mdb->catalog,selected_table);
|
||||
gmdb_debug_new_cb(w, &entry->table_pg);
|
||||
gmdb_debug_new_cb(w, (gpointer *) &entry->table_pg);
|
||||
}
|
||||
void
|
||||
gmdb_table_def_cb(GtkList *list, GtkWidget *w, gpointer data)
|
||||
@@ -94,9 +94,9 @@ gmdb_table_unselect_cb(GnomeIconList *gil, int num, GdkEvent *ev, gpointer data)
|
||||
void
|
||||
gmdb_table_select_cb(GnomeIconList *gil, int num, GdkEvent *ev, gpointer data)
|
||||
{
|
||||
int i;
|
||||
MdbCatalogEntry *entry;
|
||||
gchar *text;
|
||||
int i;
|
||||
MdbCatalogEntry *entry;
|
||||
gchar *text;
|
||||
|
||||
text = (gchar *) gnome_icon_list_get_icon_data(gil, num);
|
||||
|
||||
@@ -116,13 +116,25 @@ gchar *text;
|
||||
}
|
||||
|
||||
}
|
||||
gboolean
|
||||
gmdb_table_popup_cb(GtkWidget *menu, GdkEvent *event)
|
||||
{
|
||||
GdkEventButton *event_button;
|
||||
//GtkWidget *menu;
|
||||
GdkEventButton *event_button;
|
||||
GnomeIconList *gil;
|
||||
gdouble x,y;
|
||||
int num;
|
||||
|
||||
gil = (GnomeIconList *) glade_xml_get_widget (mainwin_xml, "table_iconlist");
|
||||
|
||||
if (selected_table == -1) return FALSE;
|
||||
if (event->type == GDK_BUTTON_PRESS) {
|
||||
event_button = (GdkEventButton *) event;
|
||||
x = event_button->x;
|
||||
y = event_button->y;
|
||||
num = gnome_icon_list_get_icon_at(gil, x, y);
|
||||
if (num != -1) {
|
||||
gnome_icon_list_select_icon(gil, num);
|
||||
}
|
||||
if (event_button->button == 3) {
|
||||
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
|
||||
event_button->button, event_button->time);
|
||||
|
||||
@@ -312,6 +312,42 @@ mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, unsigned char *buf, int len)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* unpack the pages bitmap
|
||||
*/
|
||||
int
|
||||
mdb_index_unpack_page(MdbHandle *mdb, MdbIndexPage *ipg)
|
||||
{
|
||||
int mask_bit = 0;
|
||||
int mask_pos = 0x16;
|
||||
int mask_byte;
|
||||
int start = 0xf8;
|
||||
int elem = 0;
|
||||
int len = 0;
|
||||
|
||||
ipg->idx_starts[elem++]=start;
|
||||
|
||||
//fprintf(stdout, "Unpacking index page %lu\n", ipg->pg);
|
||||
do {
|
||||
len = 0;
|
||||
do {
|
||||
mask_bit++;
|
||||
if (mask_bit==8) {
|
||||
mask_bit=0;
|
||||
mask_pos++;
|
||||
}
|
||||
mask_byte = mdb->pg_buf[mask_pos];
|
||||
len++;
|
||||
} while (mask_pos <= 0xf8 && !((1 << mask_bit) & mask_byte));
|
||||
//fprintf(stdout, "%d %d %d %d\n", mask_pos, mask_bit, mask_byte, len);
|
||||
|
||||
start += len;
|
||||
if (mask_pos < 0xf8) ipg->idx_starts[elem++]=start;
|
||||
|
||||
} while (mask_pos < 0xf8);
|
||||
|
||||
return elem;
|
||||
}
|
||||
/*
|
||||
* find the next entry on a page (either index or leaf). Uses state information
|
||||
* stored in the MdbIndexPage across calls.
|
||||
@@ -319,6 +355,22 @@ mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, unsigned char *buf, int len)
|
||||
int
|
||||
mdb_index_find_next_on_page(MdbHandle *mdb, MdbIndexPage *ipg)
|
||||
{
|
||||
int offset, len;
|
||||
int ret = 0;
|
||||
|
||||
if (!ipg->pg) return 0;
|
||||
|
||||
/* if this page has not been unpacked to it */
|
||||
if (!ipg->idx_starts[0])
|
||||
mdb_index_unpack_page(mdb, ipg);
|
||||
|
||||
|
||||
if (ipg->idx_starts[ipg->start_pos + 1]==0) return 0;
|
||||
ipg->len = ipg->idx_starts[ipg->start_pos+1] - ipg->idx_starts[ipg->start_pos];
|
||||
ipg->start_pos++;
|
||||
|
||||
|
||||
/*
|
||||
do {
|
||||
//fprintf(stdout, "%d %d\n", ipg->mask_bit, ipg->mask_byte);
|
||||
ipg->mask_bit++;
|
||||
@@ -333,7 +385,7 @@ mdb_index_find_next_on_page(MdbHandle *mdb, MdbIndexPage *ipg)
|
||||
|
||||
if (ipg->mask_pos>=0xf8)
|
||||
return 0;
|
||||
|
||||
*/
|
||||
return ipg->len;
|
||||
}
|
||||
void mdb_index_page_reset(MdbIndexPage *ipg)
|
||||
@@ -341,6 +393,7 @@ void mdb_index_page_reset(MdbIndexPage *ipg)
|
||||
ipg->offset = 0xf8; /* start byte of the index entries */
|
||||
ipg->mask_pos = 0x16;
|
||||
ipg->mask_bit=0;
|
||||
ipg->start_pos=0;
|
||||
ipg->len = 0;
|
||||
}
|
||||
void mdb_index_page_init(MdbIndexPage *ipg)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* MDB Tools - A library for reading MS Access database file
|
||||
* Copyright (C) 2000 Brian Bruns
|
||||
* Copyright (C) 2000-2004 Brian Bruns
|
||||
*
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -18,6 +18,7 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include "mdbtools.h"
|
||||
#include "mdbver.h"
|
||||
#include "mdbprivate.h"
|
||||
#include <locale.h>
|
||||
|
||||
@@ -28,24 +29,41 @@
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
MdbHandle *mdb;
|
||||
/* doesn't handle tables > 256 columns. Can that happen? */
|
||||
MdbHandle *mdb;
|
||||
int print_mdbver = 0;
|
||||
int opt;
|
||||
|
||||
/* setlocale (LC_ALL, ""); */
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
while ((opt=getopt(argc, argv, "M"))!=-1) {
|
||||
switch (opt) {
|
||||
case 'M':
|
||||
print_mdbver = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (print_mdbver) {
|
||||
fprintf(stdout,"%s\n", MDB_FULL_VERSION);
|
||||
if (argc-optind < 1) exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
** optind is now the position of the first non-option arg,
|
||||
** see getopt(3)
|
||||
*/
|
||||
if (argc < 2) {
|
||||
fprintf(stderr,_("Usage: %s <file>\n"),argv[0]);
|
||||
if (argc-optind < 1) {
|
||||
fprintf(stderr,_("Usage: %s [-M] <file>\n"),argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mdb_init();
|
||||
|
||||
if (!(mdb = mdb_open(argv[optind]))) {
|
||||
fprintf(stderr,_("Error: unable to open file %s\n"),argv[optind]);
|
||||
exit(1);
|
||||
}
|
||||
if (IS_JET3(mdb)) {
|
||||
|
||||
Reference in New Issue
Block a user