Beispiel #1
0
/**
 * cat
 */
static int cat(ntfs_volume *vol, ntfs_inode *inode, ATTR_TYPES type,
		ntfschar *name, int namelen)
{
	const int bufsize = 4096;
	char *buffer;
	ntfs_attr *attr;
	s64 bytes_read, written;
	s64 offset;
	u32 block_size;

	buffer = malloc(bufsize);
	if (!buffer)
		return 1;

	attr = ntfs_attr_open(inode, type, name, namelen);
	if (!attr) {
		ntfs_log_error("Cannot find attribute type 0x%x.\n",
				le32_to_cpu(type));
		free(buffer);
		return 1;
	}

	if ((inode->mft_no < 2) && (attr->type == AT_DATA))
		block_size = vol->mft_record_size;
	else if (attr->type == AT_INDEX_ALLOCATION)
		block_size = index_get_size(inode);
	else
		block_size = 0;

	offset = 0;
	for (;;) {
		if (!opts.raw && block_size > 0) {
			// These types have fixup
			bytes_read = ntfs_attr_mst_pread(attr, offset, 1, block_size, buffer);
			if (bytes_read > 0)
				bytes_read *= block_size;
		} else {
			bytes_read = ntfs_attr_pread(attr, offset, bufsize, buffer);
		}
		//ntfs_log_info("read %lld bytes\n", bytes_read);
		if (bytes_read == -1) {
			ntfs_log_perror("ERROR: Couldn't read file");
			break;
		}
		if (!bytes_read)
			break;

		written = fwrite(buffer, 1, bytes_read, stdout);
		if (written != bytes_read) {
			ntfs_log_perror("ERROR: Couldn't output all data!");
			break;
		}
		offset += bytes_read;
	}

	ntfs_attr_close(attr);
	free(buffer);
	return 0;
}
Beispiel #2
0
static int ntfs_ib_read(ntfs_index_context *icx, VCN vcn, INDEX_BLOCK *dst)
{
	s64 pos, ret;

	ntfs_log_trace("vcn: %lld\n", (long long)vcn);
	
	pos = ntfs_ib_vcn_to_pos(icx, vcn);

	ret = ntfs_attr_mst_pread(icx->ia_na, pos, 1, icx->block_size, (u8 *)dst);
	if (ret != 1) {
		if (ret == -1)
			ntfs_log_perror("Failed to read index block");
		else 
			ntfs_log_error("Failed to read full index block at "
				       "%lld\n", (long long)pos);
		return -1;
	}
	
	if (ntfs_ia_check(icx, dst, vcn))
		return -1;
	
	return 0;
}
Beispiel #3
0
static int ntfs_copy(disk_t *disk_car, const partition_t *partition, dir_data_t *dir_data, const file_info_t *file)
{
  const unsigned long int first_inode=file->st_ino;
  ntfs_inode *inode;
  struct ntfs_dir_struct *ls=(struct ntfs_dir_struct*)dir_data->private_dir_data;
  inode = ntfs_inode_open (ls->vol, first_inode);
  if (!inode) {
    log_error("ntfs_copy: ntfs_inode_open failed for %s\n", dir_data->current_directory);
    return -1;
  }
  {
    char *buffer;
    char *new_file;
    ntfs_attr *attr=NULL;
    FILE *f_out;
    char *stream_name;
    s64 offset;
    u32 block_size;
    buffer = (char *)MALLOC(bufsize);
    if (!buffer)
    {
      ntfs_inode_close(inode);
      return -2;
    }
    stream_name=strrchr(dir_data->current_directory, ':');
    if(stream_name)
      stream_name++;
    if(stream_name != NULL)
    {
      ntfschar *stream_name_ucs=NULL;
#ifdef NTFS_MBSTOUCS_HAVE_TWO_ARGUMENTS
      const int len=ntfs_mbstoucs(stream_name, &stream_name_ucs);
#else
      const int len=ntfs_mbstoucs(stream_name, &stream_name_ucs, 0);
#endif
      if(len < 0)
	log_error("ntfs_mbstoucs failed\n");
      else
	attr = ntfs_attr_open(inode, AT_DATA, stream_name_ucs, len);
    }
    else
      attr = ntfs_attr_open(inode, AT_DATA, NULL, 0);
    if (!attr)
    {
      log_error("Cannot find attribute type 0x%lx.\n", (long) AT_DATA);
      free(buffer);
      ntfs_inode_close(inode);
      return -3;
    }
    if ((inode->mft_no < 2) && (attr->type == AT_DATA))
      block_size = ls->vol->mft_record_size;
    else if (attr->type == AT_INDEX_ALLOCATION)
      block_size = index_get_size(inode);
    else
      block_size = 0;
#if defined(__CYGWIN__) || defined(__MINGW32__)
    if(stream_name)
    {
      /* fopen() create normal files instead of ADS with ':' replaced by an UTF char
       * replace ':' by '_' instead */
      stream_name--;
      *stream_name='_';
      f_out=fopen_local(&new_file, dir_data->local_dir, dir_data->current_directory);
    }
    else
      f_out=fopen_local(&new_file, dir_data->local_dir, dir_data->current_directory);
#else
    f_out=fopen_local(&new_file, dir_data->local_dir, dir_data->current_directory);
#endif
    if(!f_out)
    {
      log_critical("Can't create file %s: %s\n",new_file, strerror(errno));
      free(new_file);
      ntfs_attr_close(attr);
      free(buffer);
      ntfs_inode_close(inode);
      return -4;
    }
    offset = 0;
    for (;;)
    {
      s64 bytes_read, written;
      if (block_size > 0) {
	// These types have fixup
	bytes_read = ntfs_attr_mst_pread(attr, offset, 1, block_size, buffer);
	bytes_read *= block_size;
      } else {
	bytes_read = ntfs_attr_pread(attr, offset, bufsize, buffer);
      }
      //ntfs_log_info("read %lld bytes\n", bytes_read);
      if (bytes_read < 0) {
	log_error("ERROR: Couldn't read file");
	break;
      }
      if (!bytes_read)
	break;

      written = fwrite(buffer, 1, bytes_read, f_out);
      if (written != bytes_read)
      {
	log_error("ERROR: Couldn't output all data!");
	break;
      }
      offset += bytes_read;
    }
    fclose(f_out);
    set_date(new_file, file->td_atime, file->td_mtime);
    free(new_file);
    ntfs_attr_close(attr);
    free(buffer);
  }
  /* Finished with the inode; release it. */
  ntfs_inode_close(inode);
  return 0;
}
Beispiel #4
0
static int ntfsrec_emit_file(struct ntfsrec_copy *state, ntfs_inode *inode, const char *name) {
    ntfs_attr *data_attribute;
    char *old_path_end;
    
    
    if (ntfsrec_append_filename(state, name, &old_path_end) == NR_FALSE) {
        printf("Error: path %s and filename %s are too long.\n", state->path, name);
        return NR_FALSE;
    }
    
    data_attribute = ntfs_attr_open(inode, AT_DATA, NULL, 0);

    if (data_attribute != NULL) {
        int output_fd;
        unsigned int block_size = 0, retries = 0;
        s64 offset = 0;
        
        output_fd = open(state->path, O_WRONLY | O_CREAT);
        
        if (output_fd != -1) {
            if (inode->mft_no < 2) {
                block_size = state->volume->mft_record_size;
            }
            
            for(;;) {
                s64 bytes_read = 0;
                
                if (block_size > 0) {
                    bytes_read = ntfs_attr_mst_pread(data_attribute, offset, 1, block_size, state->file_buffer);
                    bytes_read *= block_size;
                } else {
                    bytes_read = ntfs_attr_pread(data_attribute, offset, NR_FILE_BUFFER_SIZE, state->file_buffer);
                }
                
                if (bytes_read == -1) {
                    unsigned int actual_size = block_size > 0 ? block_size : NR_FILE_BUFFER_SIZE;
                    
                    if (retries++ < state->opt.retries) {
                        state->stats.retries++;
                        continue;
                    }
                    
                    state->stats.errors++;
                    printf("Error: failed %u times to read %s, skipping %d bytes\n", retries, name, actual_size);
                    
                    lseek(output_fd, actual_size, SEEK_CUR);
                    
                    offset += actual_size;
                    continue;
                }
                
                if (bytes_read == 0) {
                    break;
                }
                
                if (write(output_fd, state->file_buffer, bytes_read) < 0) {
                    printf("Error: unable to write to output file %s\n", state->path);
                    
                    if (retries++ < state->opt.retries) {
                        state->stats.retries++;
                        continue;
                    }
                    
                    break;
                }
                
                retries = 0;
                offset += bytes_read;
            }
            
            close(output_fd);
        }
        
        state->stats.files++;
        ntfs_attr_close(data_attribute);
    } else {
        printf("Error: can't access the data for %s\n", name);
    }

    *old_path_end = '\0';
    state->current_path_end = old_path_end;
    return NR_TRUE;
}