/src/mdbtools/src/libmdb/catalog.c
Line | Count | Source |
1 | | /* MDB Tools - A library for reading MS Access database file |
2 | | * Copyright (C) 2000 Brian Bruns |
3 | | * |
4 | | * This library is free software; you can redistribute it and/or |
5 | | * modify it under the terms of the GNU Library General Public |
6 | | * License as published by the Free Software Foundation; either |
7 | | * version 2 of the License, or (at your option) any later version. |
8 | | * |
9 | | * This library is distributed in the hope that it will be useful, |
10 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | | * Library General Public License for more details. |
13 | | * |
14 | | * You should have received a copy of the GNU Library General Public |
15 | | * License along with this library; if not, write to the Free Software |
16 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | | */ |
18 | | |
19 | | #include "mdbtools.h" |
20 | | |
21 | | const char * |
22 | | mdb_get_objtype_string(int obj_type) |
23 | 0 | { |
24 | 0 | static const char *type_name[] = {"Form", |
25 | 0 | "Table", |
26 | 0 | "Macro", |
27 | 0 | "System Table", |
28 | 0 | "Report", |
29 | 0 | "Query", |
30 | 0 | "Linked Table", |
31 | 0 | "Module", |
32 | 0 | "Relationship", |
33 | 0 | "Unknown 0x09", |
34 | 0 | "User Info", |
35 | 0 | "Database" |
36 | 0 | }; |
37 | |
|
38 | 0 | if (obj_type >= (int)(sizeof(type_name)/sizeof(type_name[0]))) { |
39 | 0 | return NULL; |
40 | 0 | } else { |
41 | 0 | return type_name[obj_type]; |
42 | 0 | } |
43 | 0 | } |
44 | | |
45 | | void mdb_free_catalog(MdbHandle *mdb) |
46 | 39 | { |
47 | 39 | guint i, j; |
48 | 39 | MdbCatalogEntry *entry; |
49 | | |
50 | 39 | if ((!mdb) || (!mdb->catalog)) return; |
51 | 2.77k | for (i=0; i<mdb->catalog->len; i++) { |
52 | 2.73k | entry = (MdbCatalogEntry *)g_ptr_array_index(mdb->catalog, i); |
53 | 2.73k | if (entry) { |
54 | 2.73k | if (entry->props) { |
55 | 117 | for (j=0; j<entry->props->len; j++) |
56 | 0 | mdb_free_props(g_ptr_array_index(entry->props, j)); |
57 | 117 | g_ptr_array_free(entry->props, TRUE); |
58 | 117 | } |
59 | 2.73k | g_free(entry); |
60 | 2.73k | } |
61 | 2.73k | } |
62 | 39 | g_ptr_array_free(mdb->catalog, TRUE); |
63 | 39 | mdb->catalog = NULL; |
64 | 39 | } |
65 | | |
66 | | GPtrArray *mdb_read_catalog (MdbHandle *mdb, int objtype) |
67 | 39 | { |
68 | 39 | MdbCatalogEntry *entry, msysobj; |
69 | 39 | MdbTableDef *table; |
70 | 39 | char *obj_id = NULL; |
71 | 39 | char *obj_name = NULL; |
72 | 39 | char *obj_type = NULL; |
73 | 39 | char *obj_flags = NULL; |
74 | 39 | char *obj_props = NULL; |
75 | 39 | int type; |
76 | 39 | int i; |
77 | 39 | MdbColumn *col_props; |
78 | 39 | int kkd_size_ole; |
79 | | |
80 | 39 | if (!mdb) return NULL; |
81 | 39 | if (mdb->catalog) mdb_free_catalog(mdb); |
82 | 39 | mdb->catalog = g_ptr_array_new(); |
83 | 39 | mdb->num_catalog = 0; |
84 | | |
85 | 39 | obj_id = malloc(mdb->bind_size); |
86 | 39 | obj_name = malloc(mdb->bind_size); |
87 | 39 | obj_type = malloc(mdb->bind_size); |
88 | 39 | obj_flags = malloc(mdb->bind_size); |
89 | 39 | obj_props = malloc(mdb->bind_size); |
90 | | |
91 | | /* dummy up a catalog entry so we may read the table def */ |
92 | 39 | memset(&msysobj, 0, sizeof(MdbCatalogEntry)); |
93 | 39 | msysobj.mdb = mdb; |
94 | 39 | msysobj.object_type = MDB_TABLE; |
95 | 39 | msysobj.table_pg = 2; |
96 | 39 | snprintf(msysobj.object_name, sizeof(msysobj.object_name), "%s", "MSysObjects"); |
97 | | |
98 | | /* mdb_table_dump(&msysobj); */ |
99 | | |
100 | 39 | table = mdb_read_table(&msysobj); |
101 | 39 | if (!table) { |
102 | 0 | fprintf(stderr, "Unable to read table %s\n", msysobj.object_name); |
103 | 0 | mdb_free_catalog(mdb); |
104 | 0 | goto cleanup; |
105 | 0 | } |
106 | | |
107 | 39 | if (!mdb_read_columns(table)) { |
108 | 0 | fprintf(stderr, "Unable to read columns of table %s\n", msysobj.object_name); |
109 | 0 | mdb_free_catalog(mdb); |
110 | 0 | goto cleanup; |
111 | 0 | } |
112 | | |
113 | 39 | if (mdb_bind_column_by_name(table, "Id", obj_id, NULL) == -1 || |
114 | 39 | mdb_bind_column_by_name(table, "Name", obj_name, NULL) == -1 || |
115 | 39 | mdb_bind_column_by_name(table, "Type", obj_type, NULL) == -1 || |
116 | 39 | mdb_bind_column_by_name(table, "Flags", obj_flags, NULL) == -1) { |
117 | 0 | fprintf(stderr, "Unable to bind columns from table %s (%d columns found)\n", |
118 | 0 | msysobj.object_name, table->num_cols); |
119 | 0 | mdb_free_catalog(mdb); |
120 | 0 | goto cleanup; |
121 | 0 | } |
122 | 39 | if ((i = mdb_bind_column_by_name(table, "LvProp", obj_props, &kkd_size_ole)) == -1) { |
123 | 0 | fprintf(stderr, "Unable to bind column %s from table %s\n", "LvProp", msysobj.object_name); |
124 | 0 | mdb_free_catalog(mdb); |
125 | 0 | goto cleanup; |
126 | 0 | } |
127 | 39 | col_props = g_ptr_array_index(table->columns, i-1); |
128 | | |
129 | 39 | mdb_rewind_table(table); |
130 | | |
131 | 7.62k | while (mdb_fetch_row(table)) { |
132 | 7.58k | type = atoi(obj_type); |
133 | 7.58k | if (objtype==MDB_ANY || type == objtype) { |
134 | | //fprintf(stderr, "obj_id: %10ld objtype: %-3d (0x%04x) obj_name: %s\n", |
135 | | // (atol(obj_id) & 0x00FFFFFF), type, type, obj_name); |
136 | 2.73k | entry = g_malloc0(sizeof(MdbCatalogEntry)); |
137 | 2.73k | entry->mdb = mdb; |
138 | 2.73k | snprintf(entry->object_name, sizeof(entry->object_name), "%s", obj_name); |
139 | 2.73k | entry->object_type = (type & 0x7F); |
140 | 2.73k | entry->table_pg = atol(obj_id) & 0x00FFFFFF; |
141 | 2.73k | entry->flags = atol(obj_flags); |
142 | 2.73k | mdb->num_catalog++; |
143 | 2.73k | g_ptr_array_add(mdb->catalog, entry); |
144 | 2.73k | if (kkd_size_ole) { |
145 | 1.97k | size_t kkd_len; |
146 | 1.97k | void *kkd = mdb_ole_read_full(mdb, col_props, &kkd_len); |
147 | | //mdb_buffer_dump(kkd, 0, kkd_len); |
148 | 1.97k | if (kkd) { |
149 | 1.97k | entry->props = mdb_kkd_to_props(mdb, kkd, kkd_len); |
150 | 1.97k | free(kkd); |
151 | 1.97k | } |
152 | 1.97k | } |
153 | 2.73k | } |
154 | 7.58k | } |
155 | | //mdb_dump_catalog(mdb, MDB_TABLE); |
156 | | |
157 | 39 | cleanup: |
158 | 39 | if (table) |
159 | 39 | mdb_free_tabledef(table); |
160 | | |
161 | 39 | free(obj_id); |
162 | 39 | free(obj_name); |
163 | 39 | free(obj_type); |
164 | 39 | free(obj_flags); |
165 | 39 | free(obj_props); |
166 | | |
167 | 39 | return mdb->catalog; |
168 | 39 | } |
169 | | |
170 | | |
171 | | MdbCatalogEntry * |
172 | | mdb_get_catalogentry_by_name(MdbHandle *mdb, const gchar* name) |
173 | 0 | { |
174 | 0 | unsigned int i; |
175 | 0 | MdbCatalogEntry *entry; |
176 | |
|
177 | 0 | for (i=0; i<mdb->num_catalog; i++) { |
178 | 0 | entry = g_ptr_array_index(mdb->catalog, i); |
179 | 0 | if (!g_ascii_strcasecmp(entry->object_name, name)) |
180 | 0 | return entry; |
181 | 0 | } |
182 | 0 | return NULL; |
183 | 0 | } |
184 | | |
185 | | void |
186 | | mdb_dump_catalog(MdbHandle *mdb, int obj_type) |
187 | 0 | { |
188 | 0 | unsigned int i; |
189 | 0 | MdbCatalogEntry *entry; |
190 | |
|
191 | 0 | mdb_read_catalog(mdb, obj_type); |
192 | 0 | for (i=0;i<mdb->num_catalog;i++) { |
193 | 0 | entry = g_ptr_array_index(mdb->catalog,i); |
194 | 0 | if (obj_type==MDB_ANY || entry->object_type==obj_type) { |
195 | 0 | printf("Type: %-12s Name: %-48s Page: %06lx\n", |
196 | 0 | mdb_get_objtype_string(entry->object_type) ?: "Unknown", |
197 | 0 | entry->object_name, |
198 | 0 | entry->table_pg); |
199 | 0 | } |
200 | 0 | } |
201 | 0 | return; |
202 | 0 | } |
203 | | |