Beispiel #1
0
static int header_check_reg_nt(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new)
{
  const struct regf_file_header *header=(const struct regf_file_header*)buffer;
  if(le32(header->file_type) > 1)
    return 0;
  reset_file_recovery(file_recovery_new);
  file_recovery_new->min_filesize=0x1000;
  file_recovery_new->extension=file_hint_reg.extension;
  file_recovery_new->time=td_ntfs2utc(le64(header->modification_time));
  return 1;
}
Beispiel #2
0
/**
 * ntfs_td_list_entry
 * FIXME: Should we print errors as we go along? (AIA)
 */
static int ntfs_td_list_entry(  struct ntfs_dir_struct *ls, const ntfschar *name, 
		const int name_len, const int name_type, const s64 pos,
		const MFT_REF mref, const unsigned dt_type)
{
  int result = 0;
  char *filename;
  ntfs_inode *ni;
  ntfs_attr_search_ctx *ctx_si = NULL;
  file_info_t *new_file=NULL;
  /* Keep FILE_NAME_WIN32 and FILE_NAME_POSIX */
  if ((name_type & FILE_NAME_WIN32_AND_DOS) == FILE_NAME_DOS)
    return 0;

  filename = (char *)calloc (1, MAX_PATH);
  if (!filename)
  {
    log_critical("ntfs_td_list_entry calloc failed\n");
    return -1;
  }

#ifdef HAVE_ICONV
  if (ntfs_ucstoutf8(ls->cd, name, name_len, &filename, MAX_PATH) < 0 &&
      ntfs_ucstombs (name, name_len, &filename, MAX_PATH) < 0) {
    log_error("Cannot represent filename in current locale.\n");
    goto freefn;
  }
#else
  if (ntfs_ucstombs (name, name_len, &filename, MAX_PATH) < 0) {
    log_error("Cannot represent filename in current locale.\n");
    goto freefn;
  }
#endif

  result = 0;					/* These are successful */
  if ((ls->dir_data->param & FLAG_LIST_SYSTEM)!=FLAG_LIST_SYSTEM &&
      MREF(mref) < FILE_first_user && filename[0] == '$')	/* Hide system file */
      goto freefn;
  result = -1;				/* Everything else is bad */

  ni = ntfs_inode_open(ls->vol, mref);
  if (!ni)
    goto freefn;
  new_file=(file_info_t*)MALLOC(sizeof(*new_file));
  new_file->status=0;
  new_file->st_ino=MREF(mref);
  new_file->st_uid=0;
  new_file->st_gid=0;

  ctx_si = ntfs_attr_get_search_ctx(ni, ni->mrec);
  if (ctx_si)
  {
    if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED, 0, CASE_SENSITIVE, 0, NULL, 0, ctx_si)==0)
    {
      const ATTR_RECORD *attr = ctx_si->attr;
      const STANDARD_INFORMATION *si = (const STANDARD_INFORMATION*)((const char*)attr +
	  le16_to_cpu(attr->value_offset));
      if(si)
      {
	new_file->td_atime=td_ntfs2utc(sle64_to_cpu(si->last_access_time));
	new_file->td_mtime=td_ntfs2utc(sle64_to_cpu(si->last_data_change_time));
	new_file->td_ctime=td_ntfs2utc(sle64_to_cpu(si->creation_time));
      }
    }
    ntfs_attr_put_search_ctx(ctx_si);
  }
  {
    ATTR_RECORD *rec;
    int first=1;
    ntfs_attr_search_ctx *ctx = NULL;
    if (dt_type == NTFS_DT_DIR)
    {
      new_file->name=strdup(filename);
      new_file->st_mode = LINUX_S_IFDIR| LINUX_S_IRUGO | LINUX_S_IXUGO;
      new_file->st_size=0;
      td_list_add_tail(&new_file->list, &ls->dir_list->list);
      first=0;
    }
    ctx = ntfs_attr_get_search_ctx(ni, ni->mrec);
    /* A file has always an unnamed date stream and
     * may have named alternate data streams (ADS) */
    while((rec = find_attribute(AT_DATA, ctx)))
    {
      const s64 filesize = ntfs_get_attribute_value_length(ctx->attr);
      if(rec->name_length &&
	  (ls->dir_data->param & FLAG_LIST_ADS)!=FLAG_LIST_ADS)
	continue;
      if(first==0)
      {
	const file_info_t *old_file=new_file;
	new_file=(file_info_t *)MALLOC(sizeof(*new_file));
	memcpy(new_file, old_file, sizeof(*new_file));
      }
      new_file->st_mode = LINUX_S_IFREG | LINUX_S_IRUGO;
      new_file->st_size=filesize;
      if (rec->name_length)
      {
	char *stream_name=NULL;
	new_file->status=FILE_STATUS_ADS;
	new_file->name = (char *)MALLOC(MAX_PATH);
	if (ntfs_ucstombs((ntfschar *) ((char *) rec + le16_to_cpu(rec->name_offset)),
	      rec->name_length, &stream_name, 0) < 0)
	{
	  log_error("ERROR: Cannot translate name into current locale.\n");
	  snprintf(new_file->name, MAX_PATH, "%s:???", filename);
	}
	else
	{
	  snprintf(new_file->name, MAX_PATH, "%s:%s", filename, stream_name);
	}
	free(stream_name);
      }
      else
      {
	new_file->name=strdup(filename);
      }
      td_list_add_tail(&new_file->list, &ls->dir_list->list);
      first=0;
    }
    ntfs_attr_put_search_ctx(ctx);
    if(first)
    {
      free(new_file);
    }
  }

  result = 0;
  /* close the inode. */
  ntfs_inode_close(ni);
freefn:
  free (filename);
  return result;
}
Beispiel #3
0
static int header_check_asf(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new)
{
  const struct asf_header_obj_s *hdr=(const struct asf_header_obj_s*)buffer;
  unsigned int i;
  const struct asf_file_prop_s *prop=(const struct asf_file_prop_s*)(hdr+1);
  uint64_t size=0;
  time_t time=0;
  const char *extension=file_hint_asf.extension;
  /* Header + File Properties + Stream Properties + Header Extension */
  if(le64(hdr->object_size)<30 ||
      le64(hdr->object_size)>buffer_size ||
      le32(hdr->nbr_header_obj)<4)
    return 0;
  for(i=0;
      i<le32(hdr->nbr_header_obj) &&
      (const unsigned char *)prop+0x28 < buffer + buffer_size;
      i++, prop=(const struct asf_file_prop_s *)((const char *)prop + le64(prop->object_size)))
  {
    // ASF_File_Properties_Object   // 8CABDCA1-A947-11CF-8EE4-00C00C205365
    // ASF_Stream_Properties_Object // B7DC0791-A9B7-11CF-8EE6-00C00C205365
    static const unsigned char asf_file_prop_id[16]= {
      0xa1, 0xdc, 0xab, 0x8c, 0x47, 0xa9, 0xcf, 0x11, 
      0x8e, 0xe4, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65
    };
    static const unsigned char asf_stream_prop_s[16]= {
      0x91, 0x07, 0xdc, 0xb7, 0xb7, 0xa9, 0xcf, 0x11,
      0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65
    };
    if(le64(prop->object_size) < 0x18)
    {
      log_info("header_check_asf object_size too small %llu\n", (long long unsigned)le64(prop->object_size));
      return 0;
    }
    if(memcmp(prop->object_id, asf_file_prop_id, sizeof(asf_file_prop_id))==0)
    {
      if(le64(prop->object_size) < 0x28)
	return 0;
      if(le64(prop->file_size) < sizeof(struct asf_header_obj_s) + sizeof(struct asf_file_prop_s))
	return 0;
      size=le64(prop->file_size);
      time=td_ntfs2utc(le64(prop->file_date));
    }
    else if(memcmp(prop->object_id, asf_stream_prop_s, sizeof(asf_stream_prop_s))==0)
    {
      const struct asf_stream_prop_s *stream=(const struct asf_stream_prop_s *)prop;
      const char wma[16]={
	0x40, 0x9e, 0x69, 0xf8, 0x4d, 0x5b, 0xcf, 0x11, 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b
      };
      const char wmv[16]={
	0xc0, 0xef, 0x19, 0xbc, 0x4d, 0x5b, 0xcf, 0x11, 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b
      };
      if(le64(prop->object_size) < 0x28)
	return 0;
      if(memcmp(stream->stream_type, wma, sizeof(wma))==0)
	extension="wma";
      else if(memcmp(stream->stream_type, wmv, sizeof(wmv))==0)
	extension="wmv";
    }
    if(le64(prop->object_size) > buffer_size)
      break;
  }
  reset_file_recovery(file_recovery_new);
  file_recovery_new->extension=extension;
  if(size > 0)
  {
    file_recovery_new->calculated_file_size=le64(size);
    file_recovery_new->data_check=&data_check_size;
    file_recovery_new->file_check=&file_check_size;
  }
  file_recovery_new->time=time;
  return 1;
}