Exemple #1
0
int ntfs_strappend(char **dest, const char *append)
{
	char *p;
	size_t size_append, size_dest = 0;
	
	if (!dest)
		return -1;
	if (!append)
		return 0;

	size_append = strlen(append);
	if (*dest)
		size_dest = strlen(*dest);
	
	if (strappend_is_large(size_dest) || strappend_is_large(size_append)) {
		errno = EOVERFLOW;
		ntfs_log_perror("%s: Too large input buffer", EXEC_NAME);
		return -1;
	}
	
	p = (char*)realloc(*dest, size_dest + size_append + 1);
    	if (!p) {
		ntfs_log_perror("%s: Memory realloction failed", EXEC_NAME);
		return -1;
	}
	
	*dest = p;
	strcpy(*dest + size_dest, append);
	
	return 0;
}
/**
 * ntfs_device_unix_io_close - Close the device, releasing the lock
 * @dev:
 *
 * Description...
 *
 * Returns:
 */
static int ntfs_device_unix_io_close(struct ntfs_device *dev)
{
	struct flock flk;

	if (!NDevOpen(dev)) {
		errno = EBADF;
		ntfs_log_perror("Device %s is not open", dev->d_name);
		return -1;
	}
	if (NDevDirty(dev))
		if (fsync(DEV_FD(dev))) {
			ntfs_log_perror("Failed to fsync device %s", dev->d_name);
			return -1;
		}

	memset(&flk, 0, sizeof(flk));
	flk.l_type = F_UNLCK;
	flk.l_whence = SEEK_SET;
	flk.l_start = flk.l_len = 0LL;
	if (fcntl(DEV_FD(dev), F_SETLK, &flk))
		ntfs_log_perror("Could not unlock %s", dev->d_name);
	if (close(DEV_FD(dev))) {
		ntfs_log_perror("Failed to close device %s", dev->d_name);
		return -1;
	}
	NDevClearOpen(dev);
	free(dev->d_private);
	dev->d_private = NULL;
	return 0;
}
Exemple #3
0
static INDEX_ROOT *ntfs_ir_lookup(ntfs_inode *ni, ntfschar *name,
				  u32 name_len, ntfs_attr_search_ctx **ctx)
{
	ATTR_RECORD *a;
	INDEX_ROOT *ir = NULL;

	ntfs_log_trace("Entering\n");

	*ctx = ntfs_attr_get_search_ctx(ni, NULL);
	if (!*ctx)
		return NULL;

	if (ntfs_attr_lookup(AT_INDEX_ROOT, name, name_len, CASE_SENSITIVE,
			     0, NULL, 0, *ctx)) {
		ntfs_log_perror("Failed to lookup $INDEX_ROOT");
		goto err_out;
	}

	a = (*ctx)->attr;
	if (a->non_resident) {
		errno = EINVAL;
		ntfs_log_perror("Non-resident $INDEX_ROOT detected");
		goto err_out;
	}

	ir = (INDEX_ROOT *)((char *)a + le16_to_cpu(a->value_offset));
err_out:
	if (!ir) {
		ntfs_attr_put_search_ctx(*ctx);
		*ctx = NULL;
	}
	return ir;
}
Exemple #4
0
/**
 * ntfs_ir_truncate - Truncate index root attribute
 *
 * Returns STATUS_OK, STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT or STATUS_ERROR.
 */
static int ntfs_ir_truncate(ntfs_index_context *icx, int data_size)
{
	ntfs_attr *na;
	int ret;

	ntfs_log_trace("Entering\n");

	na = ntfs_attr_open(icx->ni, AT_INDEX_ROOT, icx->name, icx->name_len);
	if (!na) {
		ntfs_log_perror("Failed to open INDEX_ROOT");
		return STATUS_ERROR;
	}
	/*
	 *  INDEX_ROOT must be resident and its entries can be moved to
	 *  INDEX_BLOCK, so ENOSPC isn't a real error.
	 */
	ret = ntfs_attr_truncate(na, data_size + offsetof(INDEX_ROOT, index));
	if (ret == STATUS_OK) {

		icx->ir = ntfs_ir_lookup2(icx->ni, icx->name, icx->name_len);
		if (!icx->ir)
			return STATUS_ERROR;

		icx->ir->index.allocated_size = cpu_to_le32(data_size);

	} else if (ret == STATUS_ERROR)
		ntfs_log_perror("Failed to truncate INDEX_ROOT");

	ntfs_attr_close(na);
	return ret;
}
Exemple #5
0
/**
 * ntfs_cluster_write - write ntfs clusters
 * @vol:	volume to write to
 * @lcn:	starting logical cluster number
 * @count:	number of clusters to write
 * @b:		data buffer to write to disk
 *
 * Write @count ntfs clusters starting at logical cluster number @lcn from
 * buffer @b to volume @vol. Return the number of clusters written or -1 on
 * error, with errno set to the error code.
 */
s64 ntfs_cluster_write(const ntfs_volume *vol, const s64 lcn,
		const s64 count, const void *b)
{
	s64 bw;

	if (!vol || lcn < 0 || count < 0) {
		errno = EINVAL;
		return -1;
	}
	if (vol->nr_clusters < lcn + count) {
		errno = ESPIPE;
		ntfs_log_perror("Trying to write outside of volume "
				"(%lld < %lld)", (long long)vol->nr_clusters,
			        (long long)lcn + count);
		return -1;
	}
	if (!NVolReadOnly(vol))
		bw = ntfs_pwrite(vol->dev, lcn << vol->cluster_size_bits,
				count << vol->cluster_size_bits, b);
	else
		bw = count << vol->cluster_size_bits;
	if (bw < 0) {
		ntfs_log_perror("Error writing cluster(s)");
		return bw;
	}
	return bw >> vol->cluster_size_bits;
}
Exemple #6
0
/**
 * ntfs_pkcs12_load_pfxfile
 */
static int ntfs_pkcs12_load_pfxfile(const char *keyfile, u8 **pfx,
		unsigned *pfx_size)
{
	int f, to_read, total, attempts, br;
	struct stat key_stat;

	if (!keyfile || !pfx || !pfx_size) {
		ntfs_log_error("You have to specify the key file, a pointer "
				"to hold the key file contents, and a pointer "
				"to hold the size of the key file contents.\n");
		return -1;
	}
	f = open(keyfile, O_RDONLY);
	if (f == -1) {
		ntfs_log_perror("Failed to open key file");
		return -1;
	}
	if (fstat(f, &key_stat) == -1) {
		ntfs_log_perror("Failed to stat key file");
		goto file_out;
	}
	if (!S_ISREG(key_stat.st_mode)) {
		ntfs_log_error("Key file is not a regular file, cannot read "
				"it.\n");
		goto file_out;
	}
	if (!key_stat.st_size) {
		ntfs_log_error("Key file has zero size.\n");
		goto file_out;
	}
	*pfx = malloc(key_stat.st_size + 1);
	if (!*pfx) {
		ntfs_log_perror("Failed to allocate buffer for key file "
			"contents");
		goto file_out;
	}
	to_read = key_stat.st_size;
	total = attempts = 0;
	do {
		br = read(f, *pfx + total, to_read);
		if (br == -1) {
			ntfs_log_perror("Failed to read from key file");
			goto free_out;
		}
		if (!br)
			attempts++;
		to_read -= br;
		total += br;
	} while (to_read > 0 && attempts < 3);
	close(f);
	/* Make sure it is zero terminated. */
	(*pfx)[key_stat.st_size] = 0;
	*pfx_size = key_stat.st_size;
	return 0;
free_out:
	free(*pfx);
file_out:
	close(f);
	return -1;
}
Exemple #7
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;
}
Exemple #8
0
/**
 * ntfs_device_unix_io_open - Open a device and lock it exclusively
 * @dev:
 * @flags:
 *
 * Description...
 *
 * Returns:
 */
static int ntfs_device_unix_io_open(struct ntfs_device *dev, int flags)
{
	struct flock flk;
	struct stat sbuf;
	int err;

	if (NDevOpen(dev)) {
		errno = EBUSY;
		return -1;
	}
	if (stat(dev->d_name, &sbuf)) {
		ntfs_log_perror("Failed to access '%s'", dev->d_name);
		return -1;
	}
	if (S_ISBLK(sbuf.st_mode))
		NDevSetBlock(dev);
	
	dev->d_private = ntfs_malloc(sizeof(int));
	if (!dev->d_private)
		return -1;
	/*
	 * Open file for exclusive access if mounting r/w.
	 * Fuseblk takes care about block devices.
	 */ 
	if (!NDevBlock(dev) && (flags & O_RDWR) == O_RDWR)
		flags |= O_EXCL;
	*(int*)dev->d_private = open(dev->d_name, flags);
	if (*(int*)dev->d_private == -1) {
		err = errno;
		goto err_out;
	}
	
	if ((flags & O_RDWR) != O_RDWR)
		NDevSetReadOnly(dev);
	
	memset(&flk, 0, sizeof(flk));
	if (NDevReadOnly(dev))
		flk.l_type = F_RDLCK;
	else
		flk.l_type = F_WRLCK;
	flk.l_whence = SEEK_SET;
	flk.l_start = flk.l_len = 0LL;
	if (fcntl(DEV_FD(dev), F_SETLK, &flk)) {
		err = errno;
		ntfs_log_perror("Failed to %s lock '%s'", NDevReadOnly(dev) ? 
				"read" : "write", dev->d_name);
		if (close(DEV_FD(dev)))
			ntfs_log_perror("Failed to close '%s'", dev->d_name);
		goto err_out;
	}
	
	NDevSetOpen(dev);
	return 0;
err_out:
	free(dev->d_private);
	dev->d_private = NULL;
	errno = err;
	return -1;
}
/**
 * ntfs_device_unix_io_pread - Perform a positioned read from the device
 * @dev:
 * @buf:
 * @count:
 * @offset:
 *
 * Description...
 *
 * Returns:
 */
static s64 ntfs_device_unix_io_pread(struct ntfs_device *dev, void *buf,
		s64 count, s64 offset)
{
    s64 ret;
    if (lseek64(DEV_FD(dev), offset, SEEK_SET) != offset) {
		ntfs_log_perror("seek for pread fail");
    }
	
	ret = read(DEV_FD(dev), buf, count);
	if (!ret) {
		ntfs_log_perror("read device fail, errno: %d", errno);
	}
	return ret;
}
Exemple #10
0
/**
 * ntfs_inode_badclus_bad - check for $Badclus:$Bad data attribute
 * @mft_no:		mft record number where @attr is present
 * @attr:		attribute record used to check for the $Bad attribute
 *
 * Check if the mft record given by @mft_no and @attr contains the bad sector
 * list. Please note that mft record numbers describing $Badclus extent inodes
 * will not match the current $Badclus:$Bad check.
 *
 * On success return 1 if the file is $Badclus:$Bad, otherwise return 0.
 * On error return -1 with errno set to the error code.
 */
int ntfs_inode_badclus_bad(u64 mft_no, ATTR_RECORD *attr)
{
	int len, ret = 0;
	ntfschar *ustr;

	if (!attr) {
		ntfs_log_error("Invalid argument.\n");
		errno = EINVAL;
		return -1;
	}

	if (mft_no != FILE_BadClus)
	       	return 0;

	if (attr->type != AT_DATA)
	       	return 0;

	if ((ustr = ntfs_str2ucs("$Bad", &len)) == NULL) {
		ntfs_log_perror("Couldn't convert '$Bad' to Unicode");
		return -1;
	}

	if (ustr && ntfs_names_are_equal(ustr, len,
			(ntfschar *)((u8 *)attr + le16_to_cpu(attr->name_offset)),
			attr->name_length, 0, NULL, 0))
		ret = 1;

	ntfs_ucsfree(ustr);

	return ret;
}
Exemple #11
0
/**
 * ntfs_pread - positioned read from disk
 * @dev:	device to read from
 * @pos:	position in device to read from
 * @count:	number of bytes to read
 * @b:		output data buffer
 *
 * This function will read @count bytes from device @dev at position @pos into
 * the data buffer @b.
 *
 * On success, return the number of successfully read bytes. If this number is
 * lower than @count this means that we have either reached end of file or
 * encountered an error during the read so that the read is partial. 0 means
 * end of file or nothing to read (@count is 0).
 *
 * On error and nothing has been read, return -1 with errno set appropriately
 * to the return code of either seek, read, or set to EINVAL in case of
 * invalid arguments.
 */
s64 ntfs_pread(struct ntfs_device *dev, const s64 pos, s64 count, void *b)
{
	s64 br, total;
	struct ntfs_device_operations *dops;

	ntfs_log_trace("Entering for pos 0x%llx, count 0x%llx.\n", pos, count);
	if (!b || count < 0 || pos < 0) {
		errno = EINVAL;
		return -1;
	}
	if (!count)
		return 0;
	dops = dev->d_ops;
	/* Locate to position. */
	if (dops->seek(dev, pos, SEEK_SET) == (off_t)-1) {
		ntfs_log_perror("ntfs_pread: device seek to 0x%llx returned error",
				pos);
		return -1;
	}
	/* Read the data. */
	for (total = 0; count; count -= br, total += br) {
		br = dops->read(dev, (char*)b + total, count);
		/* If everything ok, continue. */
		if (br > 0)
			continue;
		/* If EOF or error return number of bytes read. */
		if (!br || total)
			return total;
		/* Nothing read and error, return error status. */
		return br;
	}
	/* Finally, return the number of bytes read. */
	return total;
}
Exemple #12
0
/**
 * ntfs_device_unix_io_close - Close the device, releasing the lock
 * @dev:
 *
 * Description...
 *
 * Returns:
 */
static int ntfs_device_unix_io_close(struct ntfs_device *dev)
{
	struct flock flk;

	if (!NDevOpen(dev)) {
		errno = EBADF;
		return -1;
	}
	if (NDevDirty(dev))
		fsync(DEV_FD(dev));
	/* Release exclusive (mandatory) lock on the whole device. */
	memset(&flk, 0, sizeof(flk));
	flk.l_type = F_UNLCK;
	flk.l_whence = SEEK_SET;
	flk.l_start = flk.l_len = 0LL;
	if (fcntl(DEV_FD(dev), F_SETLK, &flk))
		ntfs_log_perror("ntfs_device_unix_io_close: Warning: Could not "
				"unlock %s", dev->d_name);
	/* Close the file descriptor and clear our open flag. */
	if (close(DEV_FD(dev)))
		return -1;
	NDevClearOpen(dev);
	free(dev->d_private);
	dev->d_private = NULL;
	return 0;
}
Exemple #13
0
/**
 * change_label - change the current label on a device
 * @dev:	device to change the label on
 * @mnt_flags:	mount flags of the device or 0 if not mounted
 * @mnt_point:	mount point of the device or NULL
 * @label:	the new label
 *
 * Change the label on the device @dev to @label.
 */
static int change_label(ntfs_volume *vol, char *label)
{
	ntfschar *new_label = NULL;
	int label_len;
	int result = 0;

	label_len = ntfs_mbstoucs(label, &new_label);
	if (label_len == -1) {
		ntfs_log_perror("Unable to convert label string to Unicode");
		return 1;
	}
	else if (label_len*sizeof(ntfschar) > 0x100) {
		ntfs_log_warning("New label is too long. Maximum %u characters "
				"allowed. Truncating %u excess characters.\n",
				(unsigned)(0x100 / sizeof(ntfschar)),
				(unsigned)(label_len -
				(0x100 / sizeof(ntfschar))));
		label_len = 0x100 / sizeof(ntfschar);
		label[label_len] = const_cpu_to_le16(0);
	}

	if(!opts.noaction)
		result = ntfs_volume_rename(vol, new_label, label_len) ? 1 : 0;

	free(new_label);
	return result;
}
Exemple #14
0
static int ntfs_ibm_modify(ntfs_index_context *icx, VCN vcn, int set)
{
	u8 byte;
	s64 pos = ntfs_ibm_vcn_to_pos(icx, vcn);
	u32 bpos = pos / 8;
	u32 bit = 1 << (pos % 8);
	ntfs_attr *na;
	int ret = STATUS_ERROR;

	ntfs_log_trace("%s vcn: %lld\n", set ? "set" : "clear", (long long)vcn);
	
	na = ntfs_attr_open(icx->ni, AT_BITMAP,  icx->name, icx->name_len);
	if (!na) {
		ntfs_log_perror("Failed to open $BITMAP attribute");
		return -1;
	}

	if (set) {
		if (na->data_size < bpos + 1) {
			if (ntfs_attr_truncate(na, (na->data_size + 8) & ~7)) {
				ntfs_log_perror("Failed to truncate AT_BITMAP");
				goto err_na;
			}
		}
	}
	
	if (ntfs_attr_pread(na, bpos, 1, &byte) != 1) {
		ntfs_log_perror("Failed to read $BITMAP");
		goto err_na;
	}

	if (set) 
		byte |= bit;
	else
		byte &= ~bit;
		
	if (ntfs_attr_pwrite(na, bpos, 1, &byte) != 1) {
		ntfs_log_perror("Failed to write $Bitmap");
		goto err_na;
	}

	ret = STATUS_OK;
err_na:
	ntfs_attr_close(na);
	return ret;
}
Exemple #15
0
static int ntfs_icx_parent_dec(ntfs_index_context *icx)
{
	icx->pindex--;
	if (icx->pindex < 0) {
		errno = EINVAL;
		ntfs_log_perror("Corrupt index pointer (%d)", icx->pindex);
		return STATUS_ERROR;
	}
	return STATUS_OK;
}
Exemple #16
0
static int ntfs_icx_parent_inc(ntfs_index_context *icx)
{
	icx->pindex++;
	if (icx->pindex >= MAX_PARENT_VCN) {
		errno = EOPNOTSUPP;
		ntfs_log_perror("Index is over %d level deep", MAX_PARENT_VCN);
		return STATUS_ERROR;
	}
	return STATUS_OK;
}
Exemple #17
0
/**
 * main - Begin here
 *
 * Start from here.
 *
 * Return:  0  Success, the program worked
 *	    1  Error, something went wrong
 */
int main(int argc, char *argv[])
{
	ntfs_volume *vol;
	ntfs_inode *inode;
	ATTR_TYPES attr;
	int result = 1;

	ntfs_log_set_handler(ntfs_log_handler_stderr);

	if (!parse_options(argc, argv))
		return 1;

	utils_set_locale();

	vol = utils_mount_volume(opts.device, MS_RDONLY |
			(opts.force ? MS_RECOVER : 0));
	if (!vol) {
		ntfs_log_perror("ERROR: couldn't mount volume");
		return 1;
	}

	if (opts.inode != -1)
		inode = ntfs_inode_open(vol, opts.inode);
	else
		inode = ntfs_pathname_to_inode(vol, NULL, opts.file);

	if (!inode) {
		ntfs_log_perror("ERROR: Couldn't open inode");
		return 1;
	}

	attr = AT_DATA;
	if (opts.attr != cpu_to_le32(-1))
		attr = opts.attr;

	result = cat(vol, inode, attr, opts.attr_name, opts.attr_name_len);

	ntfs_inode_close(inode);
	ntfs_umount(vol, FALSE);

	return result;
}
Exemple #18
0
int ntfs_strinsert(char **dest, const char *append)
{
	char *p, *q;
	size_t size_append, size_dest = 0;
	
	if (!dest)
		return -1;
	if (!append)
		return 0;

	size_append = strlen(append);
	if (*dest)
		size_dest = strlen(*dest);
	
	if (strappend_is_large(size_dest) || strappend_is_large(size_append)) {
		errno = EOVERFLOW;
		ntfs_log_perror("%s: Too large input buffer", EXEC_NAME);
		return -1;
	}
	
	p = (char*)malloc(size_dest + size_append + 1);
	if (!p) {
		ntfs_log_perror("%s: Memory reallocation failed", EXEC_NAME);
		return -1;
	}
	strcpy(p, *dest);
	q = strstr(p, ",fsname=");
	if (q) {
		strcpy(q, append);
		q = strstr(*dest, ",fsname=");
		if (q)
			strcat(p, q);
		free(*dest);
		*dest = p;
	} else {
		free(*dest);
		*dest = p;
		strcpy(*dest + size_dest, append);
	}
	return 0;
}
Exemple #19
0
static int ntfs_device_uefi_io_close(struct ntfs_device *dev)
{
	struct _uefi_fd *fd = DEV_FD(dev);
    ntfs_log_trace("dev %p\n", dev);

	//AsciiPrint("ntfs_device_uefi_io_close\n\r");
    // Get the device driver descriptor
    
    if (!fd) {
        errno = EBADF;
        return -1;
    }

    // Check that the device is actually open
    if (!NDevOpen(dev)) {
        ntfs_log_perror("device is not open\n");
        errno = EIO;
        return -1;
    }

    // Mark the device as closed
    NDevClearOpen(dev);
    NDevClearBlock(dev);

    // Flush the device (if dirty and not read-only)
    if (NDevDirty(dev) && !NDevReadOnly(dev)) {
        ntfs_log_debug("device is dirty, will now sync\n");

        // ...?

        // Mark the device as clean
        NDevClearDirty(dev);

    }

    // Flush and destroy the cache (if required)
    if (fd->cache) {
        //_NTFS_cache_flush(fd->cache);
        //_NTFS_cache_destructor(fd->cache);
    }

    // Shutdown the device interface
    /*const DISC_INTERFACE* interface = fd->interface;
    if (interface) {
        interface->shutdown();
    }*/

    // Free the device driver private data
    ntfs_free(dev->d_private);
    dev->d_private = NULL;

    return 0;
}
Exemple #20
0
/**
 * ntfs_device_unix_io_sync - Flush any buffered changes to the device
 * @dev:
 *
 * Description...
 *
 * Returns:
 */
static int ntfs_device_unix_io_sync(struct ntfs_device *dev)
{
	int res = 0;
	
	if (!NDevReadOnly(dev)) {
		res = ntfs_fsync(DEV_FD(dev));
		if (res)
			ntfs_log_perror("Failed to sync device %s", dev->d_name);
		else
			NDevClearDirty(dev);
	}
	return res;
}
Exemple #21
0
static ntfs_attr *ntfs_ia_open(ntfs_index_context *icx, ntfs_inode *ni)
{
	ntfs_attr *na;
	
	na = ntfs_attr_open(ni, AT_INDEX_ALLOCATION, icx->name, icx->name_len);
	if (!na) {
		ntfs_log_perror("Failed to open index allocation of inode "
				"%llu", (unsigned long long)ni->mft_no);
		return NULL;
	}
	
	return na;
}
Exemple #22
0
static bool ntfs_device_uefi_io_writesectors(struct ntfs_device *dev, sec_t sector, sec_t numSectors, const void* buffer)
{
    // Get the device driver descriptor
    struct _uefi_fd *fd = DEV_FD(dev);
	UINT64	_sectorStart;
	UINT64	_bufferSize;

	EFI_DISK_IO_PROTOCOL *DiskIo = fd->interface->DiskIo;

	ntfs_log_trace("ntfs_device_uefi_io_writesectors\n\r");

    if (!fd) {
        errno = EBADF;
        return false;
    }

    // Write the sectors to disc (or cache, if enabled)
	if (fd->cache) {
        //return _NTFS_cache_writeSectors(fd->cache, sector, numSectors, buffer);
		ntfs_log_perror("ntfs_device_uefi_io_writesectors cache enabled?!?!");
	}
    else
	{
		while(numSectors > 0)
		{
			//AsciiPrint("DiskIo.ReadDisk sectors %x\n\r", (UINTN) numSectors );
			_sectorStart = sector * fd->sectorSize;
			_bufferSize = fd->sectorSize;

			if (DiskIo->WriteDisk(DiskIo, fd->interface->MediaId, _sectorStart, _bufferSize, buffer) != EFI_SUCCESS)
			{
				//AsciiPrint("DiskIo %x\n\r", DiskIo);
				//AsciiPrint("MediaId %x\n\r", fd->interface->MediaId);
				//AsciiPrint("sector %x%x\n\r", (UINTN) sector * fd->sectorSize);
				//AsciiPrint("numSectors %x%x\n\r", (UINTN)  fd->sectorSize);
				//AsciiPrint("buffer %x\n\r", buffer);
				//AsciiPrint("ntfs_device_uefi_io_writesectors [DISKIO!WRITEDISK] FAILED!!!\n\r");
				return false;
			}

			numSectors--;	// decrease sector count
			sector++;		// increase sector start
			buffer = CALC_OFFSET(void *, buffer, fd->sectorSize);	// move ptr!
		}
	}

        //return fd->interface->writeSectors(sector, numSectors, buffer);

    return true;
}
/**
 * ntfs_device_unix_io_pwrite - Perform a positioned write to the device
 * @dev:
 * @buf:
 * @count:
 * @offset:
 *
 * Description...
 *
 * Returns:
 */
static s64 ntfs_device_unix_io_pwrite(struct ntfs_device *dev, const void *buf,
		s64 count, s64 offset)
{
	if (NDevReadOnly(dev)) {
		errno = EROFS;
		return -1;
	}
	NDevSetDirty(dev);
	
	if (lseek64(DEV_FD(dev), offset, SEEK_SET) != offset) {
		ntfs_log_perror("seek for pwrite fail");
    }
	return write(DEV_FD(dev), buf, count);
}
Exemple #24
0
/**
 * ntfs_device_unix_io_open - Open a device and lock it exclusively
 * @dev:
 * @flags:
 *
 * Description...
 *
 * Returns:
 */
static int ntfs_device_unix_io_open(struct ntfs_device *dev, int flags)
{
	struct flock flk;
	struct stat sbuf;
	int err;

	if (NDevOpen(dev)) {
		errno = EBUSY;
		return -1;
	}
	if (!(dev->d_private = ntfs_malloc(sizeof(int))))
		return -1;
	*(int*)dev->d_private = open(dev->d_name, flags);
	if (*(int*)dev->d_private == -1) {
		err = errno;
		goto err_out;
	}
	/* Setup our read-only flag. */
	if ((flags & O_RDWR) != O_RDWR)
		NDevSetReadOnly(dev);
	/* Acquire exclusive (mandatory) lock on the whole device. */
	memset(&flk, 0, sizeof(flk));
	if (NDevReadOnly(dev))
		flk.l_type = F_RDLCK;
	else
		flk.l_type = F_WRLCK;
	flk.l_whence = SEEK_SET;
	flk.l_start = flk.l_len = 0LL;
	if (fcntl(DEV_FD(dev), F_SETLK, &flk)) {
		err = errno;
		ntfs_log_debug("ntfs_device_unix_io_open: Could not lock %s "
				"for %s\n", dev->d_name, NDevReadOnly(dev) ?
				"reading" : "writing");
		if (close(DEV_FD(dev)))
			ntfs_log_perror("ntfs_device_unix_io_open: Warning: "
					"Could not close %s", dev->d_name);
		goto err_out;
	}
	/* Determine if device is a block device or not, ignoring errors. */
	if (!fstat(DEV_FD(dev), &sbuf) && S_ISBLK(sbuf.st_mode))
		NDevSetBlock(dev);
	/* Set our open flag. */
	NDevSetOpen(dev);
	return 0;
err_out:
	free(dev->d_private);
	dev->d_private = NULL;
	errno = err;
	return -1;
}
Exemple #25
0
/**
 * ntfs_pread - positioned read from disk
 * @dev:	device to read from
 * @pos:	position in device to read from
 * @count:	number of bytes to read
 * @b:		output data buffer
 *
 * This function will read @count bytes from device @dev at position @pos into
 * the data buffer @b.
 *
 * On success, return the number of successfully read bytes. If this number is
 * lower than @count this means that we have either reached end of file or
 * encountered an error during the read so that the read is partial. 0 means
 * end of file or nothing to read (@count is 0).
 *
 * On error and nothing has been read, return -1 with errno set appropriately
 * to the return code of either seek, read, or set to EINVAL in case of
 * invalid arguments.
 */
s64 ntfs_pread(struct ntfs_device *dev, const s64 pos, s64 count, void *b)
{
	s64 br, total;
	struct ntfs_device_operations *dops;
	s64 (*_pread)(struct ntfs_device *, void *, s64, s64);

	ntfs_log_trace("Entering for pos 0x%llx, count 0x%llx.\n", pos, count);
	if (!b || count < 0 || pos < 0) {
		errno = EINVAL;
		return -1;
	}
	if (!count)
		return 0;
	dops = dev->d_ops;
	_pread = dops->pread;
	if (!_pread)
		_pread = fake_pread;
seek:
	/* Locate to position if pread is to be emulated by seek() + read(). */
	if (_pread == fake_pread &&
			dops->seek(dev, pos, SEEK_SET) == (off_t)-1) {
		ntfs_log_perror("ntfs_pread: device seek to 0x%llx returned "
				"error", pos);
		return -1;
	}
	/* Read the data. */
	for (total = 0; count; count -= br, total += br) {
		br = _pread(dev, (char*)b + total, count, pos + total);
		/* If everything ok, continue. */
		if (br > 0)
			continue;
		/* If EOF or error return number of bytes read. */
		if (!br || total)
			return total;
		/*
		 * If pread is not supported by the OS, fall back to emulating
		 * it by seek() + read() and set the device pread() pointer to
		 * NULL so we automatically use seek() + read() from now on.
		 */
		if (errno == ENOSYS && _pread != fake_pread) {
			_pread = fake_pread;
			dops->pread = NULL;
			goto seek;
		}
		/* Nothing read and error, return error status. */
		return br;
	}
	/* Finally, return the number of bytes read. */
	return total;
}
Exemple #26
0
/**
 * ntfs_cluster_read - read ntfs clusters
 * @vol:	volume to read from
 * @lcn:	starting logical cluster number
 * @count:	number of clusters to read
 * @b:		output data buffer
 *
 * Read @count ntfs clusters starting at logical cluster number @lcn from
 * volume @vol into buffer @b. Return number of clusters read or -1 on error,
 * with errno set to the error code.
 */
s64 ntfs_cluster_read(const ntfs_volume *vol, const s64 lcn, const s64 count,
		void *b)
{
	s64 br;

	if (!vol || lcn < 0 || count < 0) {
		errno = EINVAL;
		return -1;
	}
	if (vol->nr_clusters < lcn + count) {
		errno = ESPIPE;
		ntfs_log_perror("Trying to read outside of volume "
				"(%lld < %lld)", (long long)vol->nr_clusters,
			        (long long)lcn + count);
		return -1;
	}
	br = ntfs_pread(vol->dev, lcn << vol->cluster_size_bits,
			count << vol->cluster_size_bits, b);
	if (br < 0) {
		ntfs_log_perror("Error reading cluster(s)");
		return br;
	}
	return br >> vol->cluster_size_bits;
}
Exemple #27
0
static int ntfs_ib_write(ntfs_index_context *icx, INDEX_BLOCK *ib)
{
	s64 ret, vcn = sle64_to_cpu(ib->index_block_vcn);
	
	ntfs_log_trace("vcn: %lld\n", (long long)vcn);
	
	ret = ntfs_attr_mst_pwrite(icx->ia_na, ntfs_ib_vcn_to_pos(icx, vcn),
				   1, icx->block_size, ib);
	if (ret != 1) {
		ntfs_log_perror("Failed to write index block %lld, inode %llu",
			(long long)vcn, (unsigned long long)icx->ni->mft_no);
		return STATUS_ERROR;
	}
	
	return STATUS_OK;
}
Exemple #28
0
/**
 * ntfs_inode_sync_standard_information - update standard information attribute
 * @ni:		ntfs inode to update standard information
 *
 * Return 0 on success or -1 on error with errno set to the error code.
 */
static int ntfs_inode_sync_standard_information(ntfs_inode *ni)
{
	ntfs_attr_search_ctx *ctx;
	STANDARD_INFORMATION *std_info;
	u32 lth;
	le32 lthle;

	ntfs_log_trace("Entering for inode %lld\n", (long long)ni->mft_no);

	ctx = ntfs_attr_get_search_ctx(ni, NULL);
	if (!ctx)
		return -1;
	if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED,
			     0, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
		ntfs_log_perror("Failed to sync standard info (inode %lld)",
				(long long)ni->mft_no);
		ntfs_attr_put_search_ctx(ctx);
		return -1;
	}
	std_info = (STANDARD_INFORMATION *)((u8 *)ctx->attr +
			le16_to_cpu(ctx->attr->value_offset));
	std_info->file_attributes = ni->flags;
	if (test_nino_flag(ni, TimesDirty)) {
		std_info->creation_time = utc2ntfs(ni->creation_time);
		std_info->last_data_change_time = utc2ntfs(ni->last_data_change_time);
		std_info->last_mft_change_time = utc2ntfs(ni->last_mft_change_time);
		std_info->last_access_time = utc2ntfs(ni->last_access_time);
	}

		/* JPA update v3.x extensions, ensuring consistency */

	lthle = ctx->attr->length;
	lth = le32_to_cpu(lthle);
	if (test_nino_flag(ni, v3_Extensions)
	    && (lth <= sizeof(STANDARD_INFORMATION)))
		ntfs_log_error("bad sync of standard information\n");

	if (lth > sizeof(STANDARD_INFORMATION)) {
		std_info->owner_id = ni->owner_id;
		std_info->security_id = ni->security_id;
		std_info->quota_charged = ni->quota_charged;
		std_info->usn = ni->usn;
	}
	ntfs_inode_mark_dirty(ctx->ntfs_ino);
	ntfs_attr_put_search_ctx(ctx);
	return 0;
}
Exemple #29
0
/**
 * ntfs_ir_make_space - Make more space for the index root attribute
 * 
 * On success return STATUS_OK or STATUS_KEEP_SEARCHING.
 * On error return STATUS_ERROR.
 */
static int ntfs_ir_make_space(ntfs_index_context *icx, int data_size)
{			  
	int ret;

	ntfs_log_trace("Entering\n");

	ret = ntfs_ir_truncate(icx, data_size);
	if (ret == STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT) {
	
		ret = ntfs_ir_reparent(icx);
		if (ret == STATUS_OK)
			ret = STATUS_KEEP_SEARCHING;
		else
			ntfs_log_perror("Failed to nodify INDEX_ROOT");
	}

	return ret;
}
Exemple #30
0
int ntfs_inode_get_times(ntfs_inode *ni, char *value, size_t size)
{
	ntfs_attr_search_ctx *ctx;
	STANDARD_INFORMATION *std_info;
	u64 *times;
	int ret;

	ret = 0;
	ctx = ntfs_attr_get_search_ctx(ni, NULL);
	if (ctx) {
		if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED,
				     0, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
			ntfs_log_perror("Failed to get standard info (inode %lld)",
					(long long)ni->mft_no);
		} else {
			std_info = (STANDARD_INFORMATION *)((u8 *)ctx->attr +
					le16_to_cpu(ctx->attr->value_offset));
			if (value && (size >= 8)) {
				times = (u64*)value;
				times[0] = le64_to_cpu(std_info->creation_time);
				ret = 8;
				if (size >= 16) {
					times[1] = le64_to_cpu(std_info->last_data_change_time);
					ret = 16;
				}
				if (size >= 24) {
					times[2] = le64_to_cpu(std_info->last_access_time);
					ret = 24;
				}
				if (size >= 32) {
					times[3] = le64_to_cpu(std_info->last_mft_change_time);
					ret = 32;
				}
			} else
				if (!size)
					ret = 32;
				else
					ret = -ERANGE;
			}
		ntfs_attr_put_search_ctx(ctx);
	}
	return (ret ? ret : -errno);
}