ntfsnonresidentattribute.java

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

JAVA
284
字号
/*
 * $Id: NTFSNonResidentAttribute.java,v 1.3 2004/01/19 21:20:55 vchira_2000 Exp $
 */
package org.jnode.fs.ntfs.attributes;

import java.io.*;
import java.util.*;

import org.jnode.fs.ntfs.*;

/**
 * @author Chira
 *
 * To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
public class NTFSNonResidentAttribute extends NTFSAttribute
{
	private int numberOfVCNs = 0;
	
	private List dataRuns = new ArrayList();
	
	/**
	 * @param fileRecord
	 * @param buffer
	 */
	public NTFSNonResidentAttribute(NTFSFileRecord fileRecord, byte[] buffer)
	{
		super(fileRecord, buffer);
		/*
		 * process the dataruns...all non resident attributes have their
		 * data outside. can find where using data runs
		 */
		if(this.getFlags() > 0 )
			System.out.println(this.getFlags() & 0x0001);
		
		if(getDataRunsOffset() > 0)
			processDataRuns(
					buffer,
					getDataRunsOffset());
	}

	/* (non-Javadoc)
	 * @see org.jnode.fs.ntfs.attributes.NTFSAttribute#processAttributeData(byte[])
	 */
	public void processAttributeData(byte[] buffer)
	{
		// TODO Auto-generated method stub
		
	}
	/**
	 * @return Returns the startVCN.
	 */
	public long getStartVCN() {
		return NTFSUTIL.LE_READ_U32_INT( buffer, 0x10);
	}
	public long getLastVCN() {
		return NTFSUTIL.LE_READ_U32_INT( buffer, 0x18);
	}
	/**
	 * @return Returns the dataRunsOffset.
	 */
	public int getDataRunsOffset() {
		return NTFSUTIL.LE_READ_U16_INT( buffer[0x20],buffer[0x21]);
	}
	/**
	 * @return Returns the attributeAlocatedSize.
	 */
	public long getAttributeAlocatedSize() {
		return NTFSUTIL.LE_READ_U32_INT( buffer, 0x28);
	}
	// it is called only for non resident attributes
	public void processDataRuns(byte[] buffer, int parentoffset)
	{
		int offset = parentoffset;
		
		long previosLCN = 0;
		
		while(buffer[offset] != 0x0)
		{
			DataRun dataRun = new DataRun(buffer,offset,previosLCN);
			// map VCN-> datarun
			this.getDataRuns().add(dataRun);
			this.numberOfVCNs += dataRun.getLength();
			offset+= dataRun.getSize();
			previosLCN = dataRun.getCluster(); 
		}
		// check the dataruns
		if(this.numberOfVCNs != this.getAttributeAlocatedSize() / this.getFileRecord().getVolume().getClusterSize())
		{	
			System.out.println("ERROR: The number of VCNs from the data runs is different than the allocated size!: - " + this.numberOfVCNs );
			System.out.println("Alocatedsize = " + getAttributeAlocatedSize() / this.getFileRecord().getVolume().getClusterSize() );
			System.out.println("number of data runs = " + dataRuns.size() );
		}
	}
	/**
	 * @return Returns the dataRuns.
	 */
	public List getDataRuns() {
		return this.dataRuns;
	}
	
	public byte[] readVCN(long vcn, int howMany) throws IOException
	{
		byte[] buf = new byte[howMany * this.getFileRecord().getVolume().getClusterSize()];
		
		int currentOffset = 0;
		int allreadyRead = 0;
		
		for(Iterator it = this.getDataRuns().iterator();it.hasNext();)
		{
			DataRun dataRun = (DataRun) it.next();
			
			if(allreadyRead > 0)
			{
				// Iam still here so it means Iwas unable to read all
				if((howMany - allreadyRead) <= dataRun.getLength() )
				{	
					// ok all the rest is in here so read it.and return
					byte[] partialBuffer = this.getFileRecord().getVolume().readClusters(
							dataRun.getCluster(),
							howMany - allreadyRead);
					//add it to the end
					System.arraycopy(partialBuffer,0,buf,allreadyRead * this.getFileRecord().getVolume().getClusterSize(),partialBuffer.length);
					return buf;
				}
				else if((howMany - allreadyRead) > dataRun.getLength()) 
				{
					//read all this datarun
					byte[] partialBuffer = this.getFileRecord().getVolume().readClusters(
							dataRun.getCluster(),
							dataRun.getLength());
					//add it to the end
					System.arraycopy(partialBuffer,0,buf,allreadyRead * this.getFileRecord().getVolume().getClusterSize(),partialBuffer.length);
				}
			}
			// if offset from parameter is not bigger than the data must be inside this offset
			else
				if(vcn < (currentOffset + dataRun.getLength()))
				{	
					allreadyRead = (int) ((currentOffset + dataRun.getLength()) - vcn); 
					if(allreadyRead >= howMany)
						// read all
						return this.getFileRecord().getVolume().readClusters(
								dataRun.getCluster() + (vcn - currentOffset) ,
								howMany);
					else
					{	
						// read huw much I can for the first time
						byte[] partialBuffer = this.getFileRecord().getVolume().readClusters(
								dataRun.getCluster() + (vcn - currentOffset) ,
								allreadyRead);
						// copy the partial result inside the buffer
						System.arraycopy(partialBuffer,0,buf,0,partialBuffer.length);
					}
				}
		}
		
		return buf;
	}
	
	/**
	 * @return Returns the numberOfVNCs.
	 */
	public int getNumberOfVCNs()
	{
		return numberOfVCNs;
	}
	/**
	 * @param numberOfVNCs The numberOfVNCs to set.
	 */
	public void setNumberOfVCNs(int numberOfVNCs)
	{
		this.numberOfVCNs = numberOfVNCs;
	}
	
	public class DataRun
	{
		private byte type=0;
		private long cluster=0;
		private int length = 0;
		private int size = 0;
		
		public DataRun(byte[] buffer, int bufferOffset, long previosLCN)
		{
			// read first byte in type attribute
			this.type = buffer[bufferOffset];
			
			int lenlen = type & 0xF;
			
			int clusterlen = type >>> 4;
			
			this.size = lenlen + clusterlen + 1;
			
			switch(lenlen)
			{
				case 0x01: 
					length = buffer[bufferOffset+1];
					break;
				case 0x02: 
					length = NTFSUTIL.LE_READ_U16_INT(
							buffer[bufferOffset +1],
							buffer[bufferOffset +2]
					);
					break;
				case 0x03: 
					length = NTFSUTIL.LE_READ_U24_INT(
							buffer,
							bufferOffset + 1
					);
					break;
				case 0x04: 
					length = NTFSUTIL.LE_READ_U32_INT(
							buffer,
							bufferOffset + 1
					);
					break;
			}
			switch(clusterlen)
			{
				case 0x01: 
					cluster = buffer[bufferOffset+1 + lenlen];
					break;
				case 0x02: 
					cluster = NTFSUTIL.LE_READ_16_INT(
							buffer[bufferOffset +1 + lenlen],
							buffer[bufferOffset +2 + lenlen]
					);
					break;
				case 0x03: 
					cluster = NTFSUTIL.LE_READ_24_INT(
							buffer,
							bufferOffset + 1 + lenlen
					);
					break;
				case 0x04: 
					cluster = NTFSUTIL.LE_READ_U32_INT(
							buffer,
							bufferOffset + 1 + lenlen
					);
					break;
			}
			cluster+= previosLCN;
		}
		/**
		 * @return Returns the cluster.
		 */
		public long getCluster() {
			return this.cluster;
		}

		/**
		 * @return Returns the size.
		 */
		public int getSize() {
			return this.size;
		}

		/**
		 * @param size The size to set.
		 */
		public void setSize(int size) {
			this.size = size;
		}

		/**
		 * @param length The length to set.
		 */
		public void setLength(int length)
		{
			this.length = length;
		}
		/**
		 * @return Returns the length.
		 */
		public int getLength()
		{
			return length;
		}
	}
	
	
}

⌨️ 快捷键说明

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