예제 #1
0
static int header_check_dir(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 msdos_dir_entry *de=(const struct msdos_dir_entry*)buffer;
  if(!is_fat_directory(buffer))
    return 0;
  reset_file_recovery(file_recovery_new);
  file_recovery_new->extension=file_hint_dir.extension;
  file_recovery_new->data_check=&data_check_fatdir;
  file_recovery_new->file_check=&file_check_size;
  file_recovery_new->file_rename=&file_rename_fatdir;
  file_recovery_new->time=date_dos2unix(le16(de->time),le16(de->date));
  return 1;
}
예제 #2
0
int fileinfo_to_ino(char *databuf, struct inode *ino, int level, unsigned short datalen, struct sffsi32 *psffsi)
{
    int rc;
    pCommonFileInfo pCommon;
    unsigned short time;
    unsigned short date;

    rc = NO_ERROR;

    /*
     * Only FIL_STANDARD is significant. FIL_QUERYEASIZE is not because one can't SET EAS in an ext2
     * file system.
     */
    if (level == FIL_STANDARD)
    {
        if (datalen >= sizeof(pCommonFileInfo))
        {
            pCommon = (pCommonFileInfo) databuf;


            /*
             * Creation date
             */
            date_unix2dos(ino->i_ctime, __StackToFlat(&time), __StackToFlat(&date));
            if (pCommon->timeCreate)
                time = pCommon->timeCreate;
            if (pCommon->dateCreate)
                date = pCommon->dateCreate;
            ino->i_ctime = date_dos2unix(time, date);
            if (psffsi)
            {
                psffsi->sfi_cdate = date;
                psffsi->sfi_ctime = time;
                if ((pCommon->timeCreate) || (pCommon->dateCreate))
                {
                    /*
                     * Clears the stamp creation date bit if we've just modified the creation date.
                     */
                    psffsi->sfi_tstamp &= ~ST_SCREAT;   // disable kernel time stamp

                    psffsi->sfi_tstamp |= ST_PCREAT;    // propagate new value to other sft

                }
            }

            /*
             * Last write date
             */
            date_unix2dos(ino->i_mtime, __StackToFlat(&time), __StackToFlat(&date));
            if (pCommon->timeWrite)
                time = pCommon->timeWrite;
            if (pCommon->dateWrite)
                date = pCommon->dateWrite;
            ino->i_mtime = date_dos2unix(time, date);
            if (psffsi)
            {
                psffsi->sfi_mdate = date;
                psffsi->sfi_mtime = time;
                if ((pCommon->timeWrite) || (pCommon->dateWrite))
                {
                    /*
                     * Clears the stamp last write date bit if we've just modified the last write date.
                     */
                    psffsi->sfi_tstamp &= ~ST_SWRITE;   // disable kernel time stamp

                    psffsi->sfi_tstamp |= ST_PWRITE;    // propagate new value to other sft

                }
            }

            /*
             * Last access date
             */
            date_unix2dos(ino->i_atime, __StackToFlat(&time), __StackToFlat(&date));
            if (pCommon->timeAccess)
                time = pCommon->timeAccess;
            if (pCommon->dateAccess)
                date = pCommon->dateAccess;
            ino->i_atime = date_dos2unix(time, date);
            if (psffsi)
            {
                psffsi->sfi_adate = date;
                psffsi->sfi_atime = time;
                if ((pCommon->timeAccess) || (pCommon->dateAccess))
                {
                    /*
                     * Clears the stamp last access date bit if we've just modified the last access date.
                     */
                    psffsi->sfi_tstamp &= ~ST_SREAD;    // disable kernel time stamp

                    psffsi->sfi_tstamp |= ST_PREAD;     // propagate new value to other sft

                }
            }

            /*
             * File size - neither the IFS document nor the Control Program Reference
             *             are clear about if we must change the file size when DosSetPathInfo
             *             or DosSetFIleInfo is called. HPFS does NOT change it .... so we don't
             *             change it also.
             */

            /*
             * File attributes
             */
            DOS_To_Linux_Attrs(ino, pCommon->attr);

            /*
             * Marks the inode as dirty
             */
            ino->i_dirt = 1;

        }
        else
        {
            rc = ERROR_BUFFER_OVERFLOW;
        }
    }
    return rc;
}
예제 #3
0
static int zip_parse_file_entry(file_recovery_t *fr, const char **ext, const unsigned int file_nbr)
{
  zip_file_entry_t  file;
  zip64_extra_entry_t extra;
  uint64_t          len;
  if (fread(&file, sizeof(file), 1, fr->handle) != 1)
  {
#ifdef DEBUG_ZIP
    log_trace("zip: Unexpected EOF reading header of file_entry\n");
#endif
    return -1;
  }
  fr->file_size += sizeof(file);
#ifdef DEBUG_ZIP
  log_info("%u Comp=%u %u CRC32=0x%08X ",
      le32(file.compressed_size),
      le16(file.compression),
      le32(file.uncompressed_size),
      le32(file.crc32));
#endif
  {
    /* Use the more recent file to set the time/date of the recovered archive */
    const time_t tmp=date_dos2unix(le16(file.last_mod_time), le16(file.last_mod_date));
    if(fr->time < tmp)
      fr->time=tmp;
  }
  len = le16(file.filename_length);
  if (len)
  {
    char *filename=(char *)MALLOC(len+1);
    if (fread(filename, len, 1, fr->handle) != 1)
    {
#ifdef DEBUG_ZIP
      log_trace("zip: Unexpected EOF in file_entry header: %lu bytes expected\n", len);
#endif
      free(filename);
      return -1;
    }
    fr->file_size += len;
    filename[len]='\0';
    if(first_filename[0]=='\0')
    {
      const unsigned int len_tmp=(len<255?len:255);
      strncpy(first_filename, filename, len_tmp);
      first_filename[len_tmp]='\0';
    }
#ifdef DEBUG_ZIP
    log_info("%s\n", filename);
#endif
    if(*ext==NULL)
    {
      static int msoffice=0;
      static int sh3d=0;
      if(file_nbr==0)
      {
	msoffice=0;
	sh3d=0;
	if(len==8 && memcmp(filename, "mimetype", 8)==0 &&
	    le16(file.extra_length)==0 &&
	    le32(file.compressed_size)==le32(file.uncompressed_size) &&
	    le32(file.compressed_size)<=128)
	{
	  const int compressed_size=le32(file.uncompressed_size);
	  unsigned char buffer[128];
	  if( fread(buffer, compressed_size, 1, fr->handle)!=1)
	  {
#ifdef DEBUG_ZIP
	    log_trace("zip: Unexpected EOF in file_entry data: %u bytes expected\n",
	    compressed_size);
#endif
	    return -1;
	  }
	  if (fseek(fr->handle, -compressed_size, SEEK_CUR) < 0)
	  {
	    log_info("fseek failed CGR\n");
	    return -1;
	  }
	  if(compressed_size==28 && memcmp(buffer,"application/vnd.sun.xml.calc",28)==0)
	    *ext="sxc";
	  else if(compressed_size==28 && memcmp(buffer,"application/vnd.sun.xml.draw",28)==0)
	    *ext="sxd";
	  else if(compressed_size==31 && memcmp(buffer,"application/vnd.sun.xml.impress",31)==0)
	    *ext="sxi";
	  else if(compressed_size==30 && memcmp(buffer,"application/vnd.sun.xml.writer",30)==0)
	    *ext="sxw";
	  else if(compressed_size==39 && memcmp(buffer,"application/vnd.oasis.opendocument.text",39)==0)
	    *ext="odt";
	  else if(compressed_size==43 && memcmp(buffer,"application/vnd.oasis.opendocument.graphics",43)==0)
	    *ext="odg";
	  else if(compressed_size==46 && memcmp(buffer,"application/vnd.oasis.opendocument.spreadsheet",46)==0)
	    *ext="ods";
	  else if(compressed_size==47 && memcmp(buffer,"application/vnd.oasis.opendocument.presentation",47)==0)
	    *ext="odp";
	  else
	  { /* default to writer */
	    *ext="sxw";
	  }
	}
	else if(len==19 && memcmp(filename, "[Content_Types].xml", 19)==0)
	  msoffice=1;
	/* Zipped Keyhole Markup Language (KML) used by Google Earth */
	else if(len==7 && memcmp(filename, "doc.kml", 7)==0)
	  *ext="kmz";
	else if(len==4 && memcmp(filename, "Home", 4)==0)
	  sh3d=1;
      }
      else if(file_nbr==1 && sh3d==1)
      {
	if(len==1 && filename[0]=='0')
	  *ext="sh3d";
      }
      else if(file_nbr==2 && msoffice!=0)
      {
	if(strncmp(filename, "word/", 5)==0)
	  *ext="docx";
	else if(strncmp(filename, "xl/", 3)==0)
	  *ext="xlsx";
	else if(strncmp(filename, "ppt/", 4)==0)
	  *ext="pptx";
	else
	  *ext="docx";
      }
    }
    if(*ext==NULL)
    {
	/* iWork */
      if(len==23 && memcmp(filename, "QuickLook/Thumbnail.jpg", 23)==0)
	*ext="pages";
      else if(len==20 && strcasecmp(filename, "META-INF/MANIFEST.MF")==0)
	*ext="jar";
      else if(len==15 && strcasecmp(filename, "chrome.manifest")==0)
	*ext="xpi";
      else if(len==30 && memcmp(filename, "xsd/MindManagerApplication.xsd", 30)==0)
	*ext="mmap";
    }
    free(filename);
  }
#ifdef DEBUG_ZIP
  log_info("\n");
#endif
  len = le16(file.extra_length);
  memset(&extra, 0, sizeof(extra));
  if (len>0)
  {
    if (fread(&extra, sizeof(extra), 1, fr->handle) != 1)
    {
#ifdef DEBUG_ZIP
      log_trace("zip: Unexpected EOF in file_entry header: %lu bytes expected\n", len);
#endif
    }
    if (fseek(fr->handle, fr->file_size, SEEK_SET) == -1 ||
	fseek(fr->handle, len, SEEK_CUR) == -1)
    {
#ifdef DEBUG_ZIP
      log_trace("zip: Unexpected EOF in file_entry header: %lu bytes expected\n", len);
#endif
      return -1;
    }
    fr->file_size += len;
  }
  len = le32(file.compressed_size);
  if(len==0xffffffff && le16(extra.tag)==1)
  {
    len = le64(extra.compressed_size);
  }
  if (len>0)
  {
    if (fseek(fr->handle, len, SEEK_CUR) == -1)
    {
#ifdef DEBUG_ZIP
      log_trace("zip: Unexpected EOF in file_entry data: %lu bytes expected\n", len);
#endif
      return -1;
    }
#ifdef DEBUG_ZIP
    log_trace("zip: Data of length %lu\n", len);
#endif
    fr->file_size += len;
  }

  expected_compressed_size=0;
  if (file.has_descriptor && (le16(file.compression)==8 || le16(file.compression)==9))
  {
    /* The fields crc-32, compressed size and uncompressed size
       are set to zero in the local header.  The correct values
       are put in the data descriptor immediately following the
       compressed data.
       Typically used in OOO documents
       Search ZIP_DATA_DESCRIPTOR */
    static const unsigned char zip_data_desc_header[4]= {0x50, 0x4B, 0x07, 0x08};
    const int64_t pos = file_get_pos(fr->handle, zip_data_desc_header, 4);
#ifdef DEBUG_ZIP
    log_trace("Searched footer, got length %lli\n", (long long int)pos);
#endif
    if (pos < 0)
      return -1;
    if (pos > 0)
    {
      fr->file_size += pos;
      expected_compressed_size=pos;
    }
  }
  return 0;
}
예제 #4
0
static int dir_exfat_aux(const unsigned char*buffer, const unsigned int size, const dir_data_t *dir_data, file_info_t *dir_list)
{
  const struct exfat_dir_struct *ls=(const struct exfat_dir_struct*)dir_data->private_dir_data;
  /*
   * 0x83 Volume label
   * 0x81 Allocation bitmap
   * 0x82 Upcase tabel
   * 0x85 File			-> 0x05
   * 0xC0 Stream extension	-> 0x40
   * 0xC1 File name extension	-> 0x41
   * 0xA0 Volume GUID
   * 0xA1 TexFAT padding
   * 0xE2 Windows CE ACL
   *
   */
  file_info_t *current_file=NULL;
  unsigned int offset=0;
  unsigned int sec_count=0;
  for(offset=0; offset<size; offset+=0x20)
  {
    if((buffer[offset]&0x80)==0 &&
	(dir_data->param & FLAG_LIST_DELETED)!=FLAG_LIST_DELETED)
      continue;
    if((buffer[offset]&0x7f)==0x05)
    { /* File directory entry */
      const struct exfat_file_entry *entry=(const struct exfat_file_entry *)&buffer[offset];
      file_info_t *new_file=(file_info_t *)MALLOC(sizeof(*new_file));
      sec_count=entry->sec_count;
      new_file->name=(char *)MALLOC(512);
      new_file->name[0]=0;
      new_file->st_ino=0;
      new_file->st_mode = EXFAT_MKMODE(entry->attr,(LINUX_S_IRWXUGO & ~(LINUX_S_IWGRP|LINUX_S_IWOTH)));
      new_file->st_uid=0;
      new_file->st_gid=0;
      new_file->st_size=0;
      new_file->td_atime=date_dos2unix(le16(entry->atime),le16(entry->adate));
      new_file->td_ctime=date_dos2unix(le16(entry->ctime),le16(entry->cdate));
      new_file->td_mtime=date_dos2unix(le16(entry->mtime),le16(entry->mdate));
      new_file->status=((entry->type&0x80)==0x80?0:FILE_STATUS_DELETED);
      current_file=new_file;
      td_list_add_tail(&new_file->list, &dir_list->list);
    }
    else if(sec_count>0 && current_file!=NULL)
    {
      if((buffer[offset]&0x7f)==0x40)
      {
	/* Stream extension */
	const struct exfat_stream_ext_entry *entry=(const struct exfat_stream_ext_entry*)&buffer[offset];
	current_file->st_size=le64(entry->data_length);
	current_file->st_ino=le32(entry->first_cluster);
#if 0
	if((entry->first_cluster&2)!=0)
	  current_file->st_size=0;
#endif
      }
      else if((buffer[offset]&0x7f)==0x41)
      {
#ifdef HAVE_ICONV
	char *outs;
#endif
	unsigned int i,j;
	for(j=0; j<255 && current_file->name[j]!='\0'; j++);
#ifdef HAVE_ICONV
	for(i=2; i<32 && (buffer[offset+i]!=0 || buffer[offset+i+1]!=0); i+=2);
	i-=2;
	outs=&current_file->name[j];
	if(exfat_ucstoutf8(ls->cd, &buffer[offset+2], i, &outs, 512-j) < 0)
#endif
	{
	  for(i=2; i<32; i+=2)
	    current_file->name[j++]=buffer[offset+i];
	  current_file->name[j]='\0';
	}
      }
      sec_count--;
    }
  }
  return 0;
}