From 65996b036a4a99f1fcd82e97652e4c8a8c3c10d0 Mon Sep 17 00:00:00 2001 From: szaka Date: Sun, 3 Feb 2008 16:35:25 +0000 Subject: [PATCH] add 'remove_hiberfile' mount option to be able rw mount hibernated volumes --- include/ntfs-3g/volume.h | 5 ++++- libntfs-3g/volume.c | 15 +++++++++------ src/ntfs-3g.c | 22 ++++++++++++++++++++-- src/utils.c | 11 ++++++++--- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/include/ntfs-3g/volume.h b/include/ntfs-3g/volume.h index c00e5d56..fc2973aa 100644 --- a/include/ntfs-3g/volume.h +++ b/include/ntfs-3g/volume.h @@ -4,7 +4,7 @@ * Copyright (c) 2000-2004 Anton Altaparmakov * Copyright (c) 2004-2005 Richard Russon * Copyright (c) 2005-2006 Yura Pakhuchiy - * Copyright (c) 2005-2006 Szabolcs Szakacsits + * Copyright (c) 2005-2008 Szabolcs Szakacsits * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published @@ -56,6 +56,8 @@ #define MS_FORCE 0x10000000 #endif +#define MS_IGNORE_HIBERFILE 0x20000000 + /* Forward declaration */ typedef struct _ntfs_volume ntfs_volume; @@ -233,6 +235,7 @@ extern ntfs_volume *ntfs_mount(const char *name, unsigned long flags); extern int ntfs_umount(ntfs_volume *vol, const BOOL force); extern int ntfs_version_is_supported(ntfs_volume *vol); +extern int ntfs_volume_check_hiberfile(ntfs_volume *vol, int verbose); extern int ntfs_logfile_reset(ntfs_volume *vol); extern int ntfs_volume_write_flags(ntfs_volume *vol, const u16 flags); diff --git a/libntfs-3g/volume.c b/libntfs-3g/volume.c index b90a48e6..d159494e 100644 --- a/libntfs-3g/volume.c +++ b/libntfs-3g/volume.c @@ -2,7 +2,7 @@ * volume.c - NTFS volume handling code. Originated from the Linux-NTFS project. * * Copyright (c) 2000-2006 Anton Altaparmakov - * Copyright (c) 2002-2006 Szabolcs Szakacsits + * Copyright (c) 2002-2008 Szabolcs Szakacsits * Copyright (c) 2004-2005 Richard Russon * * This program/include file is free software; you can redistribute it and/or @@ -675,7 +675,7 @@ out: * Return: 0 if Windows isn't hibernated for sure * -1 otherwise and errno is set to the appropriate value */ -static int ntfs_volume_check_hiberfile(ntfs_volume *vol) +int ntfs_volume_check_hiberfile(ntfs_volume *vol, int verbose) { ntfs_inode *ni; ntfs_attr *na = NULL; @@ -705,13 +705,15 @@ static int ntfs_volume_check_hiberfile(ntfs_volume *vol) goto out; } if (bytes_read < NTFS_HIBERFILE_HEADER_SIZE) { - ntfs_log_error("Hibernated non-system partition, refused to " - "mount.\n"); + if (verbose) + ntfs_log_error("Hibernated non-system partition, " + "refused to mount.\n"); errno = EPERM; goto out; } if (memcmp(buf, "hibr", 4) == 0) { - ntfs_log_error("Windows is hibernated, refused to mount.\n"); + if (verbose) + ntfs_log_error("Windows is hibernated, refused to mount.\n"); errno = EPERM; goto out; } @@ -1098,7 +1100,8 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags) * We care only about read-write mounts. */ if (!(flags & MS_RDONLY)) { - if (ntfs_volume_check_hiberfile(vol) < 0) + if (!(flags & MS_IGNORE_HIBERFILE) && + ntfs_volume_check_hiberfile(vol, 1) < 0) goto error_exit; if (ntfs_volume_check_logfile(vol) < 0) { if (!(flags & MS_FORCE)) diff --git a/src/ntfs-3g.c b/src/ntfs-3g.c index f932773c..d40a22ca 100644 --- a/src/ntfs-3g.c +++ b/src/ntfs-3g.c @@ -127,6 +127,7 @@ typedef struct { BOOL show_sys_files; BOOL silent; BOOL force; + BOOL hiberfile; BOOL debug; BOOL no_detach; BOOL blkdev; @@ -159,8 +160,9 @@ static const char *usage_msg = "\n" "Usage: %s [-o option[,...]]\n" "\n" -"Options: ro, force, locale=, uid=, gid=, umask=, fmask=, dmask=,\n" -" streams_interface=. Please see details in the manual.\n" +"Options: ro (read-only mount), force, remove_hiberfile, locale=,\n" +" uid=, gid=, umask=, fmask=, dmask=, streams_interface=.\n" +" Please see the details in the manual.\n" "\n" "Example: ntfs-3g /dev/sda1 /mnt/win -o force\n" "\n" @@ -1633,6 +1635,8 @@ static int ntfs_open(const char *device) flags |= MS_RDONLY; if (ctx->force) flags |= MS_FORCE; + if (ctx->hiberfile) + flags |= MS_IGNORE_HIBERFILE; ctx->vol = ntfs_mount(device, flags); if (!ctx->vol) { @@ -1652,6 +1656,13 @@ static int ntfs_open(const char *device) goto err_out; } + if (ctx->hiberfile && ntfs_volume_check_hiberfile(ctx->vol, 0)) { + if (errno != EPERM) + goto err_out; + if (ntfs_fuse_rm("/hiberfil.sys")) + goto err_out; + } + errno = 0; err_out: return ntfs_volume_error(errno); @@ -1809,6 +1820,13 @@ static char *parse_mount_options(const char *orig_opts) goto err_exit; } ctx->force = TRUE; + } else if (!strcmp(opt, "remove_hiberfile")) { + if (val) { + ntfs_log_error("'remove_hiberfile' option " + "should not have value.\n"); + goto err_exit; + } + ctx->hiberfile = TRUE; } else if (!strcmp(opt, "locale")) { if (!val) { ntfs_log_error("'locale' option should have " diff --git a/src/utils.c b/src/utils.c index 2627d83f..734d952c 100644 --- a/src/utils.c +++ b/src/utils.c @@ -4,7 +4,7 @@ * Copyright (c) 2002-2005 Richard Russon * Copyright (c) 2003-2006 Anton Altaparmakov * Copyright (c) 2003 Lode Leroy - * Copyright (c) 2005-2007 Szabolcs Szakacsits + * Copyright (c) 2005-2008 Szabolcs Szakacsits * * A set of shared functions for ntfs utilities * @@ -62,7 +62,12 @@ static const char *corrupt_volume_msg = static const char *hibernated_volume_msg = "The NTFS partition is hibernated. Please resume and shutdown Windows\n" -"properly, so mounting could be done safely.\n"; +"properly, or mount the volume read-only with the 'ro' mount option, or\n" +"mount the volume read-write with the 'remove_hiberfile' mount option.\n" +"For example type on the command line:\n" +"\n" +" mount -t ntfs-3g %s %s -o remove_hiberfile\n" +"\n"; static const char *unclean_journal_msg = "Mount is denied because NTFS is marked to be in use. Choose one action:\n" @@ -124,7 +129,7 @@ void utils_mount_error(const char *volume, const char *mntpoint, int err) ntfs_log_error("%s", corrupt_volume_msg); break; case NTFS_VOLUME_HIBERNATED: - ntfs_log_error("%s", hibernated_volume_msg); + ntfs_log_error(hibernated_volume_msg, volume, mntpoint); break; case NTFS_VOLUME_UNCLEAN_UNMOUNT: ntfs_log_error(unclean_journal_msg);