Example #1
0
void ntfsDeinitVolume (ntfs_vd *vd)
{
    // Sanity check
    if (!vd) {
        errno = ENODEV;
        return;
    }

    // Lock
    ntfsLock(vd);

    // Close any directories which are still open (lazy programmers!)
    ntfs_dir_state *nextDir = vd->firstOpenDir;
    while (nextDir) {
        ntfs_log_warning("Cleaning up orphaned directory @ %p\n", nextDir);
        ntfsCloseDir(nextDir);
        nextDir = nextDir->nextOpenDir;
    }

    // Close any files which are still open (lazy programmers!)
    ntfs_file_state *nextFile = vd->firstOpenFile;
    while (nextFile) {
        ntfs_log_warning("Cleaning up orphaned file @ %p\n", nextFile);
        ntfsCloseFile(nextFile);
        nextFile = nextFile->nextOpenFile;
    }

    // Reset open directory and file stats
    vd->openDirCount = 0;
    vd->openFileCount = 0;
    vd->firstOpenDir = NULL;
    vd->firstOpenFile = NULL;

    // Close the volumes current directory (if any)
    //if (vd->cwd_ni) {
        //ntfsCloseEntry(vd, vd->cwd_ni);
        //vd->cwd_ni = NULL;
    //}

    // Force the underlying device to sync
    ntfs_device_sync(vd->dev);

    // Unlock
    ntfsUnlock(vd);
#ifndef LIBXENON
    // Deinitialise the volume lock
    LWP_MutexDestroy(vd->lock);
#endif
    return;
}
Example #2
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;
}
Example #3
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, unsigned long mnt_flags, char *label, BOOL force)
{
	ntfschar *new_label = NULL;
	int label_len;
	int result = 0;

	//XXX significant?
	if (mnt_flags & NTFS_MF_MOUNTED) {
		/* If not the root fs or mounted read/write, refuse change. */
		if (!(mnt_flags & NTFS_MF_ISROOT) ||
				!(mnt_flags & NTFS_MF_READONLY)) {
			if (!force) {
				ntfs_log_error("Refusing to change label on "
						"read-%s mounted device %s.\n",
						mnt_flags & NTFS_MF_READONLY ?
						"only" : "write", opts.device);
				return 1;
			}
		}
	}

	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;
}
Example #4
0
int ntfsFindPartitions (const DISC_INTERFACE *interface, sec_t **partitions)
{
    MASTER_BOOT_RECORD mbr;
    PARTITION_RECORD *partition = NULL;
    sec_t partition_starts[NTFS_MAX_PARTITIONS] = {0};
    int partition_count = 0;
    sec_t part_lba = 0;
    int i;

    union {
        u8 buffer[BYTES_PER_SECTOR];
        MASTER_BOOT_RECORD mbr;
        EXTENDED_BOOT_RECORD ebr;
        NTFS_BOOT_SECTOR boot;
    } sector;

    // Sanity check
    if (!interface) {
        errno = EINVAL;
        return -1;
    }
    if (!partitions)
        return 0;

    // Initialise ntfs-3g
    ntfsInit();

    // Start the device and check that it is inserted
    if (!interface->startup()) {
        errno = EIO;
        return -1;
    }
    if (!interface->isInserted()) {
        return 0;
    }

    // Read the first sector on the device
    if (!interface->readSectors(0, 1, &sector.buffer)) {
        errno = EIO;
        return -1;
    }

    // If this is the devices master boot record
    if (sector.mbr.signature == MBR_SIGNATURE) {
        memcpy(&mbr, &sector, sizeof(MASTER_BOOT_RECORD));
        ntfs_log_debug("Valid Master Boot Record found\n");

        // Search the partition table for all NTFS partitions (max. 4 primary partitions)
        for (i = 0; i < 4; i++) {
            partition = &mbr.partitions[i];
            part_lba = le32_to_cpu(mbr.partitions[i].lba_start);

            ntfs_log_debug("Partition %i: %s, sector %d, type 0x%x\n", i + 1,
                           partition->status == PARTITION_STATUS_BOOTABLE ? "bootable (active)" : "non-bootable",
                           part_lba, partition->type);

            // Figure out what type of partition this is
            switch (partition->type) {

            // Ignore empty partitions
            case PARTITION_TYPE_EMPTY:
                continue;

            // NTFS partition
            case PARTITION_TYPE_NTFS: {
                ntfs_log_debug("Partition %i: Claims to be NTFS\n", i + 1);

                // Read and validate the NTFS partition
                if (interface->readSectors(part_lba, 1, &sector)) {
                    if (sector.boot.oem_id == NTFS_OEM_ID) {
                        ntfs_log_debug("Partition %i: Valid NTFS boot sector found\n", i + 1);
                        if (partition_count < NTFS_MAX_PARTITIONS) {
                            partition_starts[partition_count] = part_lba;
                            partition_count++;
                        }
                    } else {
                        ntfs_log_debug("Partition %i: Invalid NTFS boot sector, not actually NTFS\n", i + 1);
                    }
                }

                break;

            }

            // DOS 3.3+ or Windows 95 extended partition
            case PARTITION_TYPE_DOS33_EXTENDED:
            case PARTITION_TYPE_WIN95_EXTENDED: {
                ntfs_log_debug("Partition %i: Claims to be Extended\n", i + 1);

                // Walk the extended partition chain, finding all NTFS partitions within it
                sec_t ebr_lba = part_lba;
                sec_t next_erb_lba = 0;
                do {

                    // Read and validate the extended boot record
                    if (interface->readSectors(ebr_lba + next_erb_lba, 1, &sector)) {
                        if (sector.ebr.signature == EBR_SIGNATURE) {
                            ntfs_log_debug("Logical Partition @ %d: type 0x%x\n", ebr_lba + next_erb_lba,
                                           sector.ebr.partition.status == PARTITION_STATUS_BOOTABLE ? "bootable (active)" : "non-bootable",
                                           sector.ebr.partition.type);

                            // Get the start sector of the current partition
                            // and the next extended boot record in the chain
                            part_lba = ebr_lba + next_erb_lba + le32_to_cpu(sector.ebr.partition.lba_start);
                            next_erb_lba = le32_to_cpu(sector.ebr.next_ebr.lba_start);

                            // Check if this partition has a valid NTFS boot record
                            if (interface->readSectors(part_lba, 1, &sector)) {
                                if (sector.boot.oem_id == NTFS_OEM_ID) {
                                    ntfs_log_debug("Logical Partition @ %d: Valid NTFS boot sector found\n", part_lba);
                                    if(sector.ebr.partition.type != PARTITION_TYPE_NTFS) {
                                        ntfs_log_warning("Logical Partition @ %d: Is NTFS but type is 0x%x; 0x%x was expected\n", part_lba, sector.ebr.partition.type, PARTITION_TYPE_NTFS);
                                    }
                                    if (partition_count < NTFS_MAX_PARTITIONS) {
                                        partition_starts[partition_count] = part_lba;
                                        partition_count++;
                                    }
                                }
                            }

                        } else {
                            next_erb_lba = 0;
                        }
                    }

                } while (next_erb_lba);

                break;

            }

            // Unknown or unsupported partition type
            default: {

                // Check if this partition has a valid NTFS boot record anyway,
                // it might be misrepresented due to a lazy partition editor
                if (interface->readSectors(part_lba, 1, &sector)) {
                    if (sector.boot.oem_id == NTFS_OEM_ID) {
                        ntfs_log_debug("Partition %i: Valid NTFS boot sector found\n", i + 1);
                        if(partition->type != PARTITION_TYPE_NTFS) {
                            ntfs_log_warning("Partition %i: Is NTFS but type is 0x%x; 0x%x was expected\n", i + 1, partition->type, PARTITION_TYPE_NTFS);
                        }
                        if (partition_count < NTFS_MAX_PARTITIONS) {
                            partition_starts[partition_count] = part_lba;
                            partition_count++;
                        }
                    }
                }

                break;

            }

            }

        }

        // Else it is assumed this device has no master boot record
    } else {
        ntfs_log_debug("No Master Boot Record was found!\n");

        // As a last-ditched effort, search the first 64 sectors of the device for stray NTFS partitions
        for (i = 0; i < 64; i++) {
            if (interface->readSectors(i, 1, &sector)) {
                if (sector.boot.oem_id == NTFS_OEM_ID) {
                    ntfs_log_debug("Valid NTFS boot sector found at sector %d!\n", i);
                    if (partition_count < NTFS_MAX_PARTITIONS) {
                        partition_starts[partition_count] = i;
                        partition_count++;
                    }
                }
            }
        }

    }

    // Shutdown the device
    /*interface->shutdown();*/

    // Return the found partitions (if any)
    if (partition_count > 0) {
        *partitions = (sec_t*)ntfs_alloc(sizeof(sec_t) * partition_count);
        if (*partitions) {
            memcpy(*partitions, &partition_starts, sizeof(sec_t) * partition_count);
            return partition_count;
        }
    }

    return 0;
}