Changes by: mattjf
Update of /cvsroot/linux-ntfs/linux-ntfs/ntfstools
In directory usw-pr-cvs1:/tmp/cvs-serv21473/ntfstools
Modified Files:
ntfslabel.c
Log Message:
Changes to change_label()
Index: ntfslabel.c
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/ntfstools/ntfslabel.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -U2 -r1.3 -r1.4
--- ntfslabel.c 16 Apr 2002 20:56:01 -0000 1.3
+++ ntfslabel.c 21 Apr 2002 09:55:18 -0000 1.4
@@ -40,4 +40,7 @@
#include "volume.h"
#include "debug.h"
+#include "mft.h"
+#include "attrib.h"
+
#define NTFS_MF_MOUNTED 1
@@ -92,9 +95,57 @@
void change_label(const char *dev, const char *label)
{
- printf("now changing label - FIXME: Not implemented yet!\n");
+ MFT_RECORD *mrec;
+ MFT_REF *mref;
+ ATTR_RECORD *a;
+ ntfs_attr_search_ctx *ctx = NULL;
+ int err;
+
+ printf("now changing label - FIXME: Not implemented yet!\n");
/*First we need to make sure the device is not mounted*/
- check_mount(dev);
+ check_mount(dev); /* check_mount() will handle exiting */
+
+ vol = ntfs_mount(dev,MS_RDONLY);
+ if (!vol)
+ printf("ntfs_mount() failed!\n");
+
+ if (strlen(vol->vol_name) != strlen(label) ){
+
+ mref = (MFT_REF)FILE_Volume;
+
+ if (err=ntfs_read_file_record(vol,mref,&mrec,NULL)){
+ printf("Error reading file record\n");
+ exit(1);
+ }
+
+ ctx = ntfs_get_attr_search_ctx(NULL,mref);
+
+ if (!ctx) {
+ printf("Failed to allocate attribute search context!\n");
+ exit(1);
+ }
+
+ if (ntfs_lookup_attr(AT_VOLUME_NAME, NULL, 0, 0, 0, NULL, 0, ctx)) {
+ printf("$VOLUME_NAME attribute not found?!?\n");
+ exit(1);
+ }
+
+ a = ctx->attr;
+ if (a->non_resident){
+ printf("Error: Attribute $VOLUME_NAME must be resident!\n");
+ exit(1);
+ }
+
+ resize_resident_attribute_value(mref,a,strlen(label));
+
+
+
+
+ }
+
}
+
+
+
/* Only check if the mount is readonly when it's the root filesystem. */
int check_mntent(const char *file)
@@ -136,2 +187,32 @@
}
+
+
+/* Return 0 on success and -errno on error. */
+int resize_resident_attribute_value(MFT_RECORD *m, ATTR_RECORD *a,
+ const __u32 new_vsize)
+{
+ int new_alen, new_muse;
+
+ /* New attribute length and mft record bytes used. */
+ new_alen = (le32_to_cpu(a->length) - le32_to_cpu(a->value_length) +
+ new_vsize + 7) & ~7;
+ new_muse = le32_to_cpu(m->bytes_in_use) - le32_to_cpu(a->length) +
+ new_alen;
+ /* Check for sufficient space. */
+ if (new_muse > le32_to_cpu(m->bytes_allocated) ) {
+ // Aarrgghh! Need to make space. Probably want generic function
+ // for this as we need to call it from other places, too.
+ return -ENOTSUP;
+ }
+ /* Move attributes behind @a to their new location. */
+ memmove((char*)a + new_alen, (char*)a + le32_to_cpu(a->length),
+ le32_to_cpu(m->bytes_in_use) - ((char*)a - (char*)m) -
+ le32_to_cpu(a->length));
+ /* Adjust @m to reflect change in used space. */
+ m->bytes_in_use = cpu_to_le32(new_muse);
+ /* Adjust @a to reflect new value size. */
+ a->length = cpu_to_le32(new_alen);
+ a->value_length = cpu_to_le32(new_vsize);
+ return 0;
+}
|