/* * $Id$ * * Copyright (C) 2003-2015 JNode.org * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; If not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.jnode.fs.ntfs; import java.io.UnsupportedEncodingException; import org.jnode.fs.ntfs.attribute.NTFSResidentAttribute; /** * @author Ewout Prangsma (epr@users.sourceforge.net) */ public final class FileNameAttribute extends NTFSResidentAttribute { public static class NameSpace { /** * This is the largest namespace. It is case sensitive and allows all Unicode characters except for: '\0' and * '/'. Beware that in WinNT/2k files which eg have the same name except for their case will not be * distinguished by the standard utilities and thus a "del filename" will delete both "filename" and "fileName" * without warning. */ public static final int POSIX = 0x00; /** * The standard WinNT/2k NTFS long filenames. Case insensitive. All * Unicode chars except: '\0', '"', '*', '/', ':', ' <', '>', '?', '\' * and '|'. Further, names cannot end with a '.' or a space. */ public static final int WIN32 = 0x01; /** * The standard DOS filenames (8.3 format). Uppercase only. All 8-bit * characters greater space, except: '"', '*', '+', ',', '/', ':', ';', ' * <', '=', '>', '?' and '\'. */ public static final int DOS = 0x02; /** * 3 means that both the Win32 and the DOS filenames are identical and hence have been saved in this single * filename record. */ public static final int WIN32_AND_DOS = 0x03; } private final Structure fileNameStructure; /** * @param fileRecord * @param offset */ public FileNameAttribute(FileRecord fileRecord, int offset) { super(fileRecord, offset); fileNameStructure = new Structure(this, getAttributeOffset()); } /** * Gets the filename. * * @return */ public String getFileName() { return fileNameStructure.getFileName(); } /** * Is this a compressed file. * * @return */ public boolean isCompressed() { return fileNameStructure.isCompressed(); } /** * Gets the index of the parent MFT entry. * * @return the index of the parent MFT entry. */ public long getParentMftIndex() { return fileNameStructure.getParentMftIndex(); } /** * Gets the parent sequence number as recorded in the child record. * * @return the parent sequence number. */ public int getParentSequenceNumber() { return fileNameStructure.getParentSequenceNumber(); } /** * Gets the allocated file size. */ public long getAllocatedFileSize() { return fileNameStructure.getAllocatedFileSize(); } /** * Gets the real file size. */ public long getRealSize() { return fileNameStructure.getRealSize(); } /** * Gets the flags. */ public int getFlags() { return fileNameStructure.getFlags(); } /** * Gets the filename namespace. * * @return * @see NameSpace */ public int getNameSpace() { return fileNameStructure.getNameSpace(); } /** * Gets the creation time. * * @return the creation time, as a 64-bit NTFS filetime value. */ public long getCreationTime() { return fileNameStructure.getCreationTime(); } /** * Gets the modification time. * * @return the modification time, as a 64-bit NTFS filetime value. */ public long getModificationTime() { return fileNameStructure.getModificationTime(); } /** * Gets the time when the MFT record last changed. * * @return the MFT change time, as a 64-bit NTFS filetime value. */ public long getMftChangeTime() { return fileNameStructure.getMftChangeTime(); } /** * Gets the access time. * * @return the access time, as a 64-bit NTFS filetime value. */ public long getAccessTime() { return fileNameStructure.getAccessTime(); } /** * The $FILE_NAME attribute structure. Also used in directory index records. */ public static class Structure extends NTFSStructure { private String name; public Structure(NTFSStructure parent, int offset) { super(parent, offset); } /** * Gets the filename. * * @return */ public String getFileName() { if (name == null) { try { //XXX: For Java 6, should use the version that accepts a Charset. name = new String(getFileNameAsByteArray(), "UTF-16LE"); } catch (UnsupportedEncodingException e) { throw new IllegalStateException("UTF-16LE charset missing from JRE", e); } } return name; } /** * Is this a compressed file. * * @return */ public boolean isCompressed() { final int flags = getFlags(); return ((flags & 0x0800) != 0); } /** * Checks whether this file name corresponds to a directory. * * @return {@code true} if a directory. */ public boolean isDirectory() { return (getFlags() & 0x10000000L) != 0; } /** * Gets the index of the parent MFT entry. * * @return the index of the parent MFT entry. */ public long getParentMftIndex() { return getInt48(0); } /** * Gets the parent sequence number as recorded in the child record. * * @return the parent sequence number. */ public int getParentSequenceNumber() { return getUInt16(0x6); } /** * Gets the allocated file size. */ public long getAllocatedFileSize() { return getInt64(0x28); } /** * Gets the real file size. */ public long getRealSize() { return getInt64(0x30); } /** * Gets the flags. */ public int getFlags() { return getUInt32AsInt(0x38); } /** * Gets the filename namespace. * * @return * @see NameSpace */ public int getNameSpace() { return getUInt8(0x41); } /** * Gets the creation time. * * @return the creation time, as a 64-bit NTFS filetime value. */ public long getCreationTime() { return getInt64(0x08); } /** * Gets the modification time. * * @return the modification time, as a 64-bit NTFS filetime value. */ public long getModificationTime() { return getInt64(0x10); } /** * Gets the time when the MFT record last changed. * * @return the MFT change time, as a 64-bit NTFS filetime value. */ public long getMftChangeTime() { return getInt64(0x18); } /** * Gets the access time. * * @return the access time, as a 64-bit NTFS filetime value. */ public long getAccessTime() { return getInt64(0x20); } /** * Gets the name of this file as a byte array. * * @return the file name. */ private byte[] getFileNameAsByteArray() { final int len = getUInt8(0x40); final byte[] bytes = new byte[len * 2]; getData(0x42, bytes, 0, bytes.length); return bytes; } } }