ntfsfilerecord.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 299 行

JAVA
299
字号
/*
 * $Id: NTFSFileRecord.java,v 1.9 2004/01/25 00:28:36 gbin Exp $
 */
package org.jnode.fs.ntfs;

import java.io.IOException;

import org.jnode.fs.ntfs.attributes.*;
import org.jnode.fs.ntfs.attributes.NTFSAttribute;
import org.jnode.fs.ntfs.attributes.NTFSResidentAttribute;

/**
 * @author Chira
 *
 * To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
public class NTFSFileRecord
{
	private byte[] buffer = null;
	public static int $FILE_NAME = 0x30 ;
	public static int $INDEX_ROOT = 0x90 ;
	public static int $INDEX_ALLOCATION = 0xA0 ;
	public static int $DATA = 0x80 ;
	public static int $ATTRIBUTE_LIST = 0x20 ;
	
	public static long EndMarker = 0xFFFFFFFF; 
	public static int NTFS_FILEMAGIC = 0x454C4946;
	
	
	private NTFSVolume volume;

	
	
	public NTFSFileRecord(NTFSVolume volume, byte[] buffer)
	{
		super();
		
		this.buffer = buffer;
		this.volume = volume;
		//  check for the magic numberb to see if we have a filerecord
		if(!NTFSFileRecord.hasMagicNumber(buffer))
		{	
			System.out.println(new String(buffer,0,200));
			throw new RuntimeException("ERROR:_File record does not start with MAGIC number ('FILE')");
		}
		fixUp();
	}
	private void fixUp() 
	{
		int usn = NTFSUTIL.LE_READ_U16_INT(
				buffer[this.getUpdateSequenceOffset()],
				buffer[this.getUpdateSequenceOffset() + 1]
		);
		
		int bytespersector = this.getVolume().getBootRecord().getBytesPerSector();
		
		// check each sector if the last 2 bytes are equal with the USN from header
		if(this.getVolume().getBootRecord().getBytesPerFileRecord() > bytespersector)
		{	
			for(int i = 1;i <= (this.getVolume().getBootRecord().getBytesPerFileRecord() / bytespersector);i++)
			{
				int sectusn = NTFSUTIL.LE_READ_U16_INT(
						buffer[(i * bytespersector)-2],
						buffer[(i * bytespersector)-1]
				);
				if(sectusn == usn)
					//copy the USN buffer to the end
					buffer[(i * bytespersector)-2] = buffer[this.getUpdateSequenceOffset() + (i * 2)]; 
				buffer[(i * bytespersector)-1] = buffer[this.getUpdateSequenceOffset() + (i * 2) + 1]; 
			}
		}
	}
	public static boolean hasMagicNumber(byte[] buff)
	{
		if(NTFSUTIL.LE_READ_U32_INT(buff,0) == NTFS_FILEMAGIC)
			return true;
		else 
			return false;
	}
	/**
	 * @return Returns the alocatedSize.
	 */
	public int getAlocatedSize()
	{
		return NTFSUTIL.LE_READ_U32_INT( buffer, 0x1C);	
	}
	/**
	 * @return Returns the realSize.
	 */
	public int getRealSize()
	{
		return NTFSUTIL.LE_READ_U32_INT( buffer, 0x18);
	}
	public boolean isDirectory()
	{
		if((this.getFlags() & 0x02) != 0)
			return true;
		else
			return false;
	}
	/**
	 * @return Returns the hardLinkCount.
	 */
	public int getHardLinkCount()
	{
		return NTFSUTIL.LE_READ_U16_INT(buffer[0x12],buffer[0x13]);
	}

	/**
	 * @return Returns the firtAttributeOffset.
	 */
	public int getFirtAttributeOffset()
	{
		return NTFSUTIL.LE_READ_U16_INT(buffer[0x14],buffer[0x15]);
	}
	/**
	 * @return Returns the flags.
	 */
	public int getFlags()
	{
		return NTFSUTIL.LE_READ_U16_INT(buffer[0x16],buffer[0x17]);
	}
	/**
	 * @return Returns the nextAttributeID.
	 */
	public int getNextAttributeID()
	{
		return NTFSUTIL.LE_READ_U16_INT(buffer[0x28],buffer[0x29]);
	}
	/**
	 * @return Returns the sequenceNumber.
	 */
	public int getSequenceNumber()
	{
		return NTFSUTIL.LE_READ_U16_INT(buffer[0x10],buffer[0x11]);
	}

	/**
	 * @return Returns the updateSequenceOffset.
	 */
	public int getUpdateSequenceOffset()
	{
		return NTFSUTIL.LE_READ_U16_INT(buffer[0x4],buffer[0x5]);
	}
	
	public String getFileName()
	{
		return new String(this.getFileNameAsCharArray());
	}
	
	public boolean isCompressed()
	{
		NTFSResidentAttribute fileNameAttribute = (NTFSResidentAttribute) this.getAttribute($FILE_NAME);
		System.out.println(
				NTFSUTIL.LE_READ_32_INT(fileNameAttribute.getBuffer(),fileNameAttribute.getAttributeOffset() + 0x38)
		);		
		return (NTFSUTIL.LE_READ_32_INT(fileNameAttribute.getBuffer(),fileNameAttribute.getAttributeOffset() + 0x38) & 0x0800 ) != 0;
		
	}
	public char[] getFileNameAsCharArray()
	{
		NTFSResidentAttribute fileNameAttribute = (NTFSResidentAttribute) this.getAttribute($FILE_NAME);
		
		int fileNameLength = fileNameAttribute.getBuffer()[fileNameAttribute.getAttributeOffset() + 0x40];
		
		char[] name = new char[fileNameLength];
		for(int i = 0;i < fileNameLength;i++)
		{
			name[i] = NTFSUTIL.READ16_CHAR(
										fileNameAttribute.getBuffer()[fileNameAttribute.getAttributeOffset() + 0x42 + (i*2)],
										fileNameAttribute.getBuffer()[fileNameAttribute.getAttributeOffset() + 0x42 + (i*2) + 1]
								);
		}
		return name;
	}
	/**
	 * @return Returns the volume.
	 */
	public NTFSVolume getVolume() {
		return this.volume;
	}

	/**
	 * @param volume The volume to set.
	 */
	public void setVolume(NTFSVolume volume) {
		this.volume = volume;
	}

	/**
	 * @return Returns the updateSequenceSize.
	 */
	public int getUpdateSequenceSize() {
		return NTFSUTIL.LE_READ_U16_INT(buffer[0x6],buffer[0x7]);
	}

	public NTFSAttribute getAttribute(int attrTypeID)
	{
		int offset = this.getFirtAttributeOffset();
		
		/*
		 * check the fixup
		 */
		
		// calculate the Update sequence number
		//System.out.println("----------------------------------");
		
		while(NTFSUTIL.LE_READ_U32_INT( buffer, offset) != 0xFFFFFFFF)
		{
			int attrLength = NTFSUTIL.LE_READ_U32_INT( buffer, offset + 0x04);
			
			// check if the attribute is of the type that we want
			if(NTFSUTIL.LE_READ_U32_INT( buffer, offset) != attrTypeID)
			{	
				if(NTFSUTIL.LE_READ_U32_INT( buffer, offset) > 0)
					offset += attrLength; 
				continue;
			}
			
			// return the attribute
			return NTFSAttribute.getAttribute(
								this,
								NTFSUTIL.extractSubBuffer(
													buffer,offset,attrLength
													)
								);
		}
		
		if(this.getAttribute($ATTRIBUTE_LIST) != null)
			System.out.println("Has $ATTRIBUTE_LIST attribute");
		
		return null;
	}
	/**
	 * @return Returns the buffer.
	 */
	public byte[] getBuffer() {
		return this.buffer;
	}

	/**
	 * @param buffer The buffer to set.
	 */
	public void setBuffer(byte[] buffer) {
		this.buffer = buffer;
	}
	
	public void readData(long fileOffset, byte[] dest, int off, int len) throws IOException 
	{
		NTFSAttribute data = this.getAttribute($DATA);
		if(data.isResident())
		{
			if(((NTFSResidentAttribute)data).getAttributeLength() < len)
				throw new RuntimeException("Fila data(" + ((NTFSResidentAttribute)data).getAttributeLength() + "b) is not latge enaugh to read:" + len + "b");
			System.arraycopy(
					data.getBuffer(),
					((NTFSResidentAttribute)data).getAttributeOffset() + (int)fileOffset,
					dest,
					off,
					len
			);
			return;
		}
			
		// caclulate start and end cluster
		
		long startCluster = (fileOffset / this.getVolume().getClusterSize());
		int howMany = (int) 
			(
					(	
							len 
							+ 
							(
									fileOffset 
									% 
									getVolume().getClusterSize()
							)
					) 
					/ 
					getVolume().getClusterSize()
			) 
			+ 1;
		
		buffer = ((NTFSNonResidentAttribute)data).readVCN(
										startCluster,
										howMany);
		System.arraycopy(
				buffer,
				(int)fileOffset % getVolume().getClusterSize(),
				dest,
				off,
				len
				);
		
	}
		
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?