Esempio n. 1
0
		public static utf_query_result query_utf_key(Stream infile, long offset, int index, string name) {
			utf_query query = new utf_query();
			query.index = index;
			query.name = name;

			return query_utf_nofail(infile, offset, query);
		}
Esempio n. 2
0
		public static utf_query_result query_utf_nofail(Stream infile, long offset, utf_query query) {
			utf_query_result result = query_utf(infile, offset, query);

			ErrorStuff.CHECK_ERROR(result.valid == 0, "didn't find valid @UTF table where one was expected");
			ErrorStuff.CHECK_ERROR(query != null && result.found == 0, "key not found");

			return result;
		}
Esempio n. 3
0
		public static utf_query_result analyze_utf(Stream infile, long offset, int indent, int print, utf_query query) {
			byte[] buf = new byte[4];
			long table_info_table_offset;
			uint table_info_table_size;
			uint table_info_schema_offset;
			uint table_info_rows_offset;
			uint table_info_string_table_offset;
			uint table_info_data_offset;
			uint table_info_table_name; // references index in string_table
			ushort table_info_columns;
			ushort table_info_row_width;
			uint table_info_rows;
			byte[] string_table = null;
			utf_column_info[] schema = null;
			utf_query_result result = new utf_query_result();

			result.valid = 0;

			if (print != 0) {
				Util.printf_indent(indent);
				Console.WriteLine("{");
			}

			indent += INDENT_LEVEL;

			table_info_table_offset = offset;

			// check header
			byte[] UTF_signature = Encoding.ASCII.GetBytes("@UTF");
			Util.get_bytes_seek(offset, infile, buf, 4);
			if (!Util.memcmp(buf, UTF_signature)) {
				if (print != 0) {
					Util.printf_indent(indent);
					Console.WriteLine("not a @UTF table at {0:X8}", offset);
				}

				indent -= INDENT_LEVEL;
				if (print != 0) {
					Util.printf_indent(indent);
					Console.WriteLine("}");
				}

				string_table = null;
				schema = null;

				return result;
			}

			// get table size
			table_info_table_size = Util.get_32_be(infile);

			table_info_schema_offset = 0x20;
			table_info_rows_offset = Util.get_32_be(infile);
			table_info_string_table_offset = Util.get_32_be(infile);
			table_info_data_offset = Util.get_32_be(infile);
			uint table_name_string = Util.get_32_be(infile);
			table_info_columns = Util.get_16_be(infile);
			table_info_row_width = Util.get_16_be(infile);
			table_info_rows = Util.get_32_be(infile);

			// allocate for string table
			long string_table_size =
				table_info_data_offset - table_info_string_table_offset;
			string_table = new byte[string_table_size + 1];

			// load schema
			schema = new utf_column_info[table_info_columns];
			for (int i = 0; i < schema.Length; ++i) {
				schema[i] = new utf_column_info();
			}
			{
				int i;
				for (i = 0; i < table_info_columns; i++) {
					schema[i].type = Util.get_byte(infile);
					schema[i].column_name = Util.get_32_be(infile);

					if ((schema[i].type & COLUMN_STORAGE_MASK) == COLUMN_STORAGE_CONSTANT) {
						schema[i].constant_offset = infile.Position;
						switch (schema[i].type & COLUMN_TYPE_MASK) {
							case COLUMN_TYPE_STRING:
								Util.get_32_be(infile);
								break;
							case COLUMN_TYPE_8BYTE:
							case COLUMN_TYPE_DATA:
								Util.get_32_be(infile);
								Util.get_32_be(infile);
								break;
							case COLUMN_TYPE_FLOAT:
							case COLUMN_TYPE_4BYTE2:
							case COLUMN_TYPE_4BYTE:
								Util.get_32_be(infile);
								break;
							case COLUMN_TYPE_2BYTE2:
							case COLUMN_TYPE_2BYTE:
								Util.get_16_be(infile);
								break;
							case COLUMN_TYPE_1BYTE2:
							case COLUMN_TYPE_1BYTE:
								Util.get_byte(infile);
								break;
							default:
								ErrorStuff.CHECK_ERROR(true, "unknown type for constant");
								break;
						}
					}
				}
			}

			// read string table
			Util.get_bytes_seek(table_info_string_table_offset + 8 + offset,
					infile, string_table, string_table_size);
			table_info_table_name = table_name_string;

			// fill in the default stuff
			result.valid = 1;
			result.found = 0;
			result.rows = table_info_rows;
			result.name_offset = table_name_string;
			result.string_table_offset = table_info_string_table_offset;
			result.data_offset = table_info_data_offset;

			// explore the values
			if (query != null || print != 0) {
				int i, j;

				for (i = 0; i < table_info_rows; i++) {
					if (print == 0 && query != null && i != query.index) continue;

					long row_offset =
						table_info_table_offset + 8 + table_info_rows_offset +
						i * table_info_row_width;
					long row_start_offset = row_offset;

					if (print != 0) {
						Util.printf_indent(indent);
						Console.WriteLine("{0}[{1}] = {{", ReadString(string_table, table_info_table_name), i);
					}
					indent += INDENT_LEVEL;
					for (j = 0; j < table_info_columns; j++) {
						byte type = schema[j].type;
						long constant_offset = schema[j].constant_offset;
						int constant = 0;

						int qthis = (query != null && i == query.index && ReadString(string_table, schema[j].column_name) == query.name) ? 1 : 0;

						if (print != 0) {
							Util.printf_indent(indent);
							Console.Write("{0:x8} {1:x2} {2} = ", row_offset - row_start_offset, type, ReadString(string_table, schema[j].column_name));
						}

						if (qthis != 0) {
							result.found = 1;
							result.type = schema[j].type & COLUMN_TYPE_MASK;
						}

						switch (schema[j].type & COLUMN_STORAGE_MASK) {
							case COLUMN_STORAGE_PERROW:
								break;
							case COLUMN_STORAGE_CONSTANT:
								constant = 1;
								break;
							case COLUMN_STORAGE_ZERO:
								if (print != 0) {
									Console.WriteLine("UNDEFINED");
								}
								if (qthis != 0) {
									result.value_u64 = 0;
								}
								continue;
							default:
								ErrorStuff.CHECK_ERROR(true, "unknown storage class");
								break;
						}

						if (true) {
							long data_offset;
							int bytes_read = 0;

							if (constant != 0) {
								data_offset = constant_offset;
								if (print != 0) {
									Console.Write("constant ");
								}
							} else {
								data_offset = row_offset;
							}

							if (qthis != 0) {
								result.data_position = data_offset;
							}

							switch (type & COLUMN_TYPE_MASK) {
								case COLUMN_TYPE_STRING: {
									uint string_offset;
									string_offset = Util.get_32_be_seek(data_offset, infile);
									bytes_read = 4;
									if (print != 0) {
										Console.WriteLine("\"{0}\"", ReadString(string_table, string_offset));
									}
									if (qthis != 0) {
										result.value_string = string_offset;
									}
								}
								break;
								case COLUMN_TYPE_DATA: {
									uint vardata_offset, vardata_size;

									vardata_offset = Util.get_32_be_seek(data_offset, infile);
									vardata_size = Util.get_32_be(infile);
									bytes_read = 8;
									if (print != 0) {
										Console.Write("[0x{0:x8}]", vardata_offset);
										Console.WriteLine(" (size 0x{0:x8})", vardata_size);
									}
									if (qthis != 0) {
										result.value_data = new offset_size_pair() { offset = vardata_offset, size = vardata_size };
									}

									if (vardata_size != 0 && print != 0) {
										// assume that the data is another table
										analyze_utf(infile,
												table_info_table_offset + 8 +
												table_info_data_offset +
												vardata_offset,
												indent,
												print,
												null
												);
									}
								}
								break;

								case COLUMN_TYPE_8BYTE: {
									ulong value =
										Util.get_64_be_seek(data_offset, infile);
									if (print != 0) {
										Console.WriteLine("0x{0:x}", value);
									}
									if (qthis != 0) {
										result.value_u64 = value;
									}
									bytes_read = 8;
									break;
								}
								case COLUMN_TYPE_4BYTE2:
								case COLUMN_TYPE_4BYTE:
									if ((type & COLUMN_TYPE_MASK) == COLUMN_TYPE_4BYTE2 && print != 0) {
										Console.Write("type 2 ");
									} {
										uint value =
											Util.get_32_be_seek(data_offset, infile);
										if (print != 0) {
											Console.WriteLine("{0}", value);
										}
										if (qthis != 0) {
											result.value_u32 = value;
										}
										bytes_read = 4;
									}
									break;
								case COLUMN_TYPE_2BYTE2:
								case COLUMN_TYPE_2BYTE:
									if ((type & COLUMN_TYPE_MASK) == COLUMN_TYPE_2BYTE2 && print != 0) {
										Console.Write("type 2 ");
									} {
										ushort value =
											Util.get_16_be_seek(data_offset, infile);
										if (print != 0) {
											Console.WriteLine("{0}", value);
										}
										if (qthis != 0) {
											result.value_u16 = value;
										}
										bytes_read = 2;
									}
									break;
								case COLUMN_TYPE_FLOAT:
									if (true) {
										uint int_float;
										int_float = Util.get_32_be_seek(data_offset, infile);
										if (print != 0) {
											Console.WriteLine("{0}", Util.reinterpret_to_float(int_float));
										}
										if (qthis != 0) {
											result.value_u32 = int_float;
										}
									}
									bytes_read = 4;
									break;
								case COLUMN_TYPE_1BYTE2:
								case COLUMN_TYPE_1BYTE:
									if ((type & COLUMN_TYPE_MASK) == COLUMN_TYPE_1BYTE2 && print != 0) {
										Console.Write("type 2 ");
									} {
										byte value =
											Util.get_byte_seek(data_offset, infile);
										if (print != 0) {
											Console.WriteLine("{0}", value);
										}
										if (qthis != 0) {
											result.value_u8 = value;
										}
										bytes_read = 1;
									}
									break;
								default:
									ErrorStuff.CHECK_ERROR(true, "unknown normal type");
									break;
							}

							if (constant == 0) {
								row_offset += bytes_read;
							}
						} // useless if end
					} // column for loop end
					indent -= INDENT_LEVEL;
					if (print != 0) {
						Util.printf_indent(indent);
						Console.WriteLine("}");
					}

					ErrorStuff.CHECK_ERROR(row_offset - row_start_offset != table_info_row_width,
							"column widths do now add up to row width");

					if (query != null && print == 0 && i >= query.index) break;
				} // row for loop end
			} // explore values block end

			indent -= INDENT_LEVEL;
			if (print != 0) {
				Util.printf_indent(indent);
				Console.WriteLine("}");
			}

			string_table = null;
			schema = null;

			return result;
		}
Esempio n. 4
0
		public static utf_query_result query_utf(Stream infile, long offset, utf_query query) {
			return analyze_utf(infile, offset, 0, 0, query);
		}