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 + -
显示快捷键?