Пример #1
0
static GPtrArray *
mdb_read_props_list(MdbHandle *mdb, gchar *kkd, int len)
{
	guint32 record_len;
	int pos = 0;
	gchar *name;
	GPtrArray *names = NULL;
	int i=0;

	names = g_ptr_array_new();
#if MDB_DEBUG
	mdb_buffer_dump(kkd, 0, len);
#endif
	pos = 0;
	while (pos < len) {
		record_len = mdb_get_int16(kkd, pos);
		pos += 2;
		if (mdb_get_option(MDB_DEBUG_PROPS)) {
			fprintf(stderr, "%02d ",i++);
			mdb_buffer_dump(kkd, pos - 2, record_len + 2);
		}
		name = g_malloc(3*record_len + 1); /* worst case scenario is 3 bytes out per byte in */
		mdb_unicode2ascii(mdb, &kkd[pos], record_len, name, 3*record_len);

		pos += record_len;
		g_ptr_array_add(names, name);
#if MDB_DEBUG
		printf("new len = %d\n", names->len);
#endif
	}
	return names;
}
Пример #2
0
static MdbProperties *
mdb_read_props(MdbHandle *mdb, GPtrArray *names, gchar *kkd, int len)
{
	guint32 record_len, name_len;
	int pos = 0;
	int elem, dtype, dsize;
	gchar *name, *value;
	MdbProperties *props;
	int i=0;

#if MDB_DEBUG
	mdb_buffer_dump(kkd, 0, len);
#endif
	pos = 0;

	record_len = mdb_get_int16(kkd, pos);
	pos += 4;
	name_len = mdb_get_int16(kkd, pos);
	pos += 2;
	props = mdb_alloc_props();
	if (name_len) {
		props->name = g_malloc(3*name_len + 1);
		mdb_unicode2ascii(mdb, kkd+pos, name_len, props->name, 3*name_len);
		mdb_debug(MDB_DEBUG_PROPS,"prop block named: %s", props->name);
	}
	pos += name_len;

	props->hash = g_hash_table_new(g_str_hash, g_str_equal);

	while (pos < len) {
		record_len = mdb_get_int16(kkd, pos);
		dtype = kkd[pos + 3];
		elem = mdb_get_int16(kkd, pos + 4);
		dsize = mdb_get_int16(kkd, pos + 6);
		value = g_malloc(dsize + 1);
		strncpy(value, &kkd[pos + 8], dsize);
		value[dsize] = '\0';
		name = g_ptr_array_index(names,elem);
		if (mdb_get_option(MDB_DEBUG_PROPS)) {
			fprintf(stderr, "%02d ",i++);
			mdb_debug(MDB_DEBUG_PROPS,"elem %d (%s) dsize %d dtype %d", elem, name, dsize, dtype);
			mdb_buffer_dump(value, 0, dsize);
		}
		if (dtype == MDB_MEMO) dtype = MDB_TEXT;
		if (dtype == MDB_BOOL) {
			g_hash_table_insert(props->hash, g_strdup(name),
				g_strdup(kkd[pos + 8] ? "yes" : "no"));
		} else {
			g_hash_table_insert(props->hash, g_strdup(name),
			  mdb_col_to_string(mdb, kkd, pos + 8, dtype, dsize));
		}
		g_free(value);
		pos += record_len;
	}
	return props;
	
}
Пример #3
0
/*
 * That function takes a raw KKD/MR2 binary buffer,
 * typically read from LvProp in table MSysbjects
 * and returns a GPtrArray of MdbProps*
 */
GArray*
mdb_kkd_to_props(MdbHandle *mdb, void *buffer, size_t len) {
	guint32 record_len;
	guint16 record_type;
	size_t pos;
	GPtrArray *names = NULL;
	MdbProperties *props;
	GArray *result;

#if MDB_DEBUG
	mdb_buffer_dump(buffer, 0, len);
#endif
	mdb_debug(MDB_DEBUG_PROPS,"starting prop parsing of type %s", buffer);

	if (strcmp("KKD", buffer) && strcmp("MR2", buffer)) {
		fprintf(stderr, "Unrecognized format.\n");
		mdb_buffer_dump(buffer, 0, len);
		return NULL;
	}

	result = g_array_new(0, 0, sizeof(MdbProperties*));

	pos = 4;
	while (pos < len) {
		record_len = mdb_get_int32(buffer, pos);
		record_type = mdb_get_int16(buffer, pos + 4);
		mdb_debug(MDB_DEBUG_PROPS,"prop chunk type:0x%04x len:%d", record_type, record_len);
		//mdb_buffer_dump(buffer, pos+4, record_len);
		switch (record_type) {
			case 0x80:
				if (names) free_names(names);
				names = mdb_read_props_list(mdb, buffer+pos+6, record_len - 6);
				break;
			case 0x00:
			case 0x01:
				if (!names) {
					fprintf(stderr,"sequence error!\n");
					break;
				}
				props = mdb_read_props(mdb, names, buffer+pos+6, record_len - 6);
				g_array_append_val(result, props);
				//mdb_dump_props(props, stderr, 1);
				break;
			default:
				fprintf(stderr,"Unknown record type %d\n", record_type);
				break;
		}
		pos += record_len;
	}
	if (names) free_names(names);
	return result;
}
Пример #4
0
void dump_ole(MdbTableDef *table, char *colname, char *sargname)
{
char ole_data[200000];
int len;
MdbSarg sarg;
char *sargcol, *sargop, *sargval;

	mdb_bind_column_by_name(table, colname, ole_data, &len);

	if (sargname) {
		sargcol = strtok(sargname," ");
		sargop = strtok(NULL," ");
		sargval = strtok(NULL," ");
		printf("col %s op %s val %s\n",sargcol,sargop,sargval);
        	sarg.op = MDB_EQUAL; /* only support = for now, sorry */
		strcpy(sarg.value.s, sargval);
		mdb_add_sarg_by_name(table, sargcol, &sarg);
	}

        mdb_rewind_table(table);
	while (mdb_fetch_row(table)) {
		mdb_buffer_dump(ole_data, 0, len);
		printf("---\n");
	}

}
Пример #5
0
int mdb_read_row(MdbTableDef *table, unsigned int row)
{
	MdbHandle *mdb = table->entry->mdb;
	MdbColumn *col;
	unsigned int i;
	int row_start;
	size_t row_size;
	int delflag, lookupflag;
	MdbField fields[256];
	int num_fields;

	if (table->num_rows == 0) 
		return 0;

	if (mdb_find_row(mdb, row, &row_start, &row_size)) {
		fprintf(stderr, "warning: mdb_find_row failed.");
		return 0;
	}

	delflag = lookupflag = 0;
	if (row_start & 0x8000) lookupflag++;
	if (row_start & 0x4000) delflag++;
	row_start &= OFFSET_MASK; /* remove flags */
#if MDB_DEBUG
	fprintf(stdout,"Row %d bytes %d to %d %s %s\n", 
		row, row_start, row_start + row_size - 1,
		lookupflag ? "[lookup]" : "",
		delflag ? "[delflag]" : "");
#endif	

	if (!table->noskip_del && delflag) {
		return 0;
	}

	num_fields = mdb_crack_row(table, row_start, row_start + row_size - 1,
		fields);
	if (!mdb_test_sargs(table, fields, num_fields)) return 0;
	
#if MDB_DEBUG
	fprintf(stdout,"sarg test passed row %d \n", row);
#endif 

#if MDB_DEBUG
	mdb_buffer_dump(mdb->pg_buf, row_start, row_size);
#endif

	/* take advantage of mdb_crack_row() to clean up binding */
	/* use num_cols instead of num_fields -- bsb 03/04/02 */
	for (i = 0; i < table->num_cols; i++) {
		col = g_ptr_array_index(table->columns,fields[i].colnum);
		_mdb_attempt_bind(mdb, col, fields[i].is_null,
			fields[i].start, fields[i].siz);
	}

	return 1;
}
Пример #6
0
MdbTableDef *mdb_read_table(MdbCatalogEntry *entry)
{
	MdbTableDef *table;
	MdbHandle *mdb = entry->mdb;
	MdbFormatConstants *fmt = mdb->fmt;
	int row_start, pg_row;
	void *buf, *pg_buf = mdb->pg_buf;
	guint i;

	mdb_read_pg(mdb, entry->table_pg);
	if (mdb_get_byte(pg_buf, 0) != 0x02)  /* not a valid table def page */
		return NULL;
	table = mdb_alloc_tabledef(entry);

	mdb_get_int16(pg_buf, 8); /* len */

	table->num_rows = mdb_get_int32(pg_buf, fmt->tab_num_rows_offset);
	table->num_var_cols = mdb_get_int16(pg_buf, fmt->tab_num_cols_offset-2);
	table->num_cols = mdb_get_int16(pg_buf, fmt->tab_num_cols_offset);
	table->num_idxs = mdb_get_int32(pg_buf, fmt->tab_num_idxs_offset);
	table->num_real_idxs = mdb_get_int32(pg_buf, fmt->tab_num_ridxs_offset);

	/* grab a copy of the usage map */
	pg_row = mdb_get_int32(pg_buf, fmt->tab_usage_map_offset);
	mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &(table->map_sz));
	table->usage_map = g_memdup(buf + row_start, table->map_sz);
	if (mdb_get_option(MDB_DEBUG_USAGE)) 
		mdb_buffer_dump(buf, row_start, table->map_sz);
	mdb_debug(MDB_DEBUG_USAGE,"usage map found on page %ld row %d start %d len %d",
		pg_row >> 8, pg_row & 0xff, row_start, table->map_sz);

	/* grab a copy of the free space page map */
	pg_row = mdb_get_int32(pg_buf, fmt->tab_free_map_offset);
	mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &(table->freemap_sz));
	table->free_usage_map = g_memdup(buf + row_start, table->freemap_sz);
	mdb_debug(MDB_DEBUG_USAGE,"free map found on page %ld row %d start %d len %d\n",
		pg_row >> 8, pg_row & 0xff, row_start, table->freemap_sz);

	table->first_data_pg = mdb_get_int16(pg_buf, fmt->tab_first_dpg_offset);

	if (entry->props)
		for (i=0; i<entry->props->len; ++i) {
			MdbProperties *props = g_array_index(entry->props, MdbProperties*, i);
			if (!props->name)
				table->props = props;
		}

	return table;
}
Пример #7
0
size_t 
mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int chunk_size)
{
	guint32 ole_len;
	void *buf;
	int row_start;
	size_t len;

	ole_len = mdb_get_int32(ole_ptr, 0);
	mdb_debug(MDB_DEBUG_OLE,"ole len = %d ole flags = %02x",
		ole_len & 0x00ffffff, ole_len >> 24);

	col->chunk_size = chunk_size;

	if (ole_len & 0x80000000) {
		/* inline ole field, if we can satisfy it, then do it */
		len = col->cur_value_len - MDB_MEMO_OVERHEAD;
		if (chunk_size >= len) {
			if (col->bind_ptr) 
				memcpy(col->bind_ptr, 
					&mdb->pg_buf[col->cur_value_start + 
						MDB_MEMO_OVERHEAD],
					len);
			return len;
		} else {
			return 0;
		}
	} else if (ole_len & 0x40000000) {
		col->cur_blob_pg_row = mdb_get_int32(ole_ptr, 4);
		mdb_debug(MDB_DEBUG_OLE,"ole row = %d ole pg = %ld",
			col->cur_blob_pg_row & 0xff,
			col->cur_blob_pg_row >> 8);

		if (mdb_find_pg_row(mdb, col->cur_blob_pg_row,
			&buf, &row_start, &len)) {
			return 0;
		}
		mdb_debug(MDB_DEBUG_OLE,"start %d len %d", row_start, len);

		if (col->bind_ptr) {
			memcpy(col->bind_ptr, buf + row_start, len);
			if (mdb_get_option(MDB_DEBUG_OLE))
				mdb_buffer_dump(col->bind_ptr, 0, 16);
		}
		return len;
	} else if ((ole_len & 0xff000000) == 0) {