org.filesys.smb.server.QueryInfoPacker Maven / Gradle / Ivy
Show all versions of jfileserver Show documentation
/*
* Copyright (C) 2006-2010 Alfresco Software Limited.
* Copyright (C) 2018 GK Spencer
*
* This file is part of Alfresco
*
* Alfresco 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 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Alfresco. If not, see .
*/
package org.filesys.smb.server;
import org.filesys.server.filesys.AccessMode;
import org.filesys.server.filesys.FileInfo;
import org.filesys.server.filesys.FileName;
import org.filesys.server.filesys.UnsupportedInfoLevelException;
import org.filesys.smb.*;
import org.filesys.smb.server.ntfs.StreamInfo;
import org.filesys.smb.server.ntfs.StreamInfoList;
import org.filesys.util.DataBuffer;
import org.filesys.util.MemorySize;
/**
* Query File Information Packer Class
*
*
* Packs file/directory information for the specified information level.
*
* @author gkspencer
*/
public class QueryInfoPacker {
// Information level fixed length parts
private static final int PathStandardLen = 36;
private static final int PathQueryEASizeLen = 36;
private static final int PathAllEAsLen = 4;
private static final int PathFileBasicLen = 40;
private static final int PathFileStandardLen = 24;
private static final int PathFileEAInfoLen = 4;
private static final int PathFileNameLen = 4;
private static final int PathFileAllLen = 100;
private static final int PathFileStreamLen = 38;
private static final int PathFileCompressionLen = 12;
private static final int NTFileInternalLen = 8;
private static final int NTFilePositionLen = 8;
private static final int NTAttributeTagLen = 16;
private static final int NTNetworkOpenLen = 56;
private static final int NTBothDirectoryLen = 90;
private static final int NTIdBothDirectoryLen = 98;
// Default access modes for files/folders
private static final int AccessFileReadOnly = AccessMode.NTRead + AccessMode.NTReadEA + AccessMode.NTReadAttrib + AccessMode.NTReadControl +
AccessMode.NTExecute + AccessMode.NTSynchronize;
private static final int AccessFileReadWrite = AccessMode.NTRead + AccessMode.NTWrite + AccessMode.NTAppend + AccessMode.NTReadEA + AccessMode.NTWriteEA +
AccessMode.NTReadAttrib + AccessMode.NTWriteAttrib + AccessMode.NTDelete + AccessMode.NTReadControl + AccessMode.NTWriteDAC + AccessMode.NTWriteOwner +
AccessMode.NTExecute + AccessMode.NTDeleteChild + AccessMode.NTSynchronize;
private static final int AccessFolderReadOnly = AccessMode.NTRead + AccessMode.NTReadEA + AccessMode.NTReadAttrib + AccessMode.NTReadControl +
AccessMode.NTTraverse + AccessMode.NTSynchronize;
private static final int AccessFolderReadWrite = AccessMode.NTRead + AccessMode.NTWrite + AccessMode.NTAddSubDir + AccessMode.NTReadEA + AccessMode.NTWriteEA +
AccessMode.NTReadAttrib + AccessMode.NTWriteAttrib + AccessMode.NTDelete + AccessMode.NTReadControl + AccessMode.NTWriteDAC + AccessMode.NTWriteOwner +
AccessMode.NTDeleteChild + AccessMode.NTTraverse + AccessMode.NTDeleteChild + AccessMode.NTSynchronize;
/**
* Pack a file information object into the specified buffer, using the specified information
* level.
*
* @param info File information to be packed.
* @param buf Buffer to pack the data into.
* @param infoLevel File information level.
* @param uni Pack Unicode strings if true, else pack ASCII strings
* @return int Length of data packed
* @exception UnsupportedInfoLevelException Unsupported information level
*/
public final static int packInfo(FileInfo info, DataBuffer buf, int infoLevel, boolean uni)
throws UnsupportedInfoLevelException {
// Determine the information level
int startPos = buf.getPosition();
switch (infoLevel) {
// Standard information
case FileInfoLevel.PathStandard:
packInfoStandard(info, buf, false, uni);
break;
// Standard information plus EA size
case FileInfoLevel.PathQueryEASize:
packInfoStandard(info, buf, true, uni);
break;
// Extended attributes list
case FileInfoLevel.PathQueryEAsFromList:
break;
// All extended attributes
case FileInfoLevel.PathAllEAs:
packAllEAsInfo(info, buf);
break;
// Validate a file name
case FileInfoLevel.PathIsNameValid:
break;
// Basic file information
case FileInfoLevel.PathFileBasicInfo:
case FileInfoLevel.NTFileBasicInfo:
packBasicFileInfo(info, buf);
break;
// Standard file information
case FileInfoLevel.PathFileStandardInfo:
case FileInfoLevel.NTFileStandardInfo:
packStandardFileInfo(info, buf);
break;
// Extended attribute information
case FileInfoLevel.PathFileEAInfo:
case FileInfoLevel.NTFileEAInfo:
packEAFileInfo(info, buf);
break;
// File name information
case FileInfoLevel.PathFileNameInfo:
case FileInfoLevel.NTFileNameInfo:
// case FileInfoLevel.NTFileNormalizedName:
packNameFileInfo(info, buf, uni);
break;
// All information
case FileInfoLevel.PathFileAllInfo:
case FileInfoLevel.NTFileAllInfo:
packAllFileInfo(info, buf, uni);
break;
// Alternate name information
case FileInfoLevel.PathFileAltNameInfo:
case FileInfoLevel.NTFileAltNameInfo:
packAlternateNameFileInfo(info, buf);
break;
// Stream information
case FileInfoLevel.PathFileStreamInfo:
case FileInfoLevel.NTFileStreamInfo:
packStreamFileInfo(info, buf, uni);
break;
// Compression information
case FileInfoLevel.PathFileCompressionInfo:
case FileInfoLevel.NTFileCompressionInfo:
packCompressionFileInfo(info, buf);
break;
// File internal information
case FileInfoLevel.NTFileInternalInfo:
packFileInternalInfo(info, buf);
break;
// File position information
case FileInfoLevel.NTFilePositionInfo:
packFilePositionInfo(info, buf);
break;
// Attribute tag information
case FileInfoLevel.NTAttributeTagInfo:
packFileAttributeTagInfo(info, buf);
break;
// Network open information
case FileInfoLevel.NTNetworkOpenInfo:
packFileNetworkOpenInfo(info, buf);
break;
// Both directory information
case FileInfoLevel.NTFileBothDirectoryInfo:
packBothDirectoryInfo(info, buf, uni);
break;
// Id both directory information
case FileInfoLevel.NTIdBothDirectoryInfo:
packIdBothDirectoryInfo(info, buf, uni);
break;
// File alignment
case FileInfoLevel.NTFileAlignmentInfo:
packFileAlignmentInfo(buf);
break;
// File access
case FileInfoLevel.NTFileAccessInfo:
packFileAccessInfo(info, buf);
break;
// Mode
case FileInfoLevel.NTFileModeInfo:
packModeInfo( info, buf);
break;
// Quota
case FileInfoLevel.NTFileQuotaInfo:
packQuotaInfo( info, buf);
break;
// Unsupported information level
default:
throw new UnsupportedInfoLevelException("" + infoLevel);
}
// Return the length of the data that was packed
return buf.getPosition() - startPos;
}
/**
* Pack the standard file information
*
* @param info File information
* @param buf Buffer to pack data into
* @param eaFlag Return EA size
* @param uni Pack unicode strings
*/
private static void packInfoStandard(FileInfo info, DataBuffer buf, boolean eaFlag, boolean uni) {
// Information format :-
// SMB_DATE CreationDate
// SMB_TIME CreationTime
// SMB_DATE LastAccessDate
// SMB_TIME LastAccessTime
// SMB_DATE LastWriteDate
// SMB_TIME LastWriteTime
// ULONG File size
// ULONG Allocation size
// USHORT File attributes
// [ ULONG EA size ]
// Pack the creation date/time
SMBDate dateTime = new SMBDate(0);
if (info.hasCreationDateTime()) {
dateTime.setTime(info.getCreationDateTime());
buf.putShort(dateTime.asSMBDate());
buf.putShort(dateTime.asSMBTime());
}
else
buf.putZeros(4);
// Pack the last access date/time
if (info.hasAccessDateTime()) {
dateTime.setTime(info.getAccessDateTime());
buf.putShort(dateTime.asSMBDate());
buf.putShort(dateTime.asSMBTime());
}
else
buf.putZeros(4);
// Pack the last write date/time
if (info.hasModifyDateTime()) {
dateTime.setTime(info.getModifyDateTime());
buf.putShort(dateTime.asSMBDate());
buf.putShort(dateTime.asSMBTime());
}
else
buf.putZeros(4);
// Pack the file size and allocation size
buf.putInt(info.getSizeInt());
if (info.getAllocationSize() < info.getSize())
buf.putInt(info.getSizeInt());
else
buf.putInt(info.getAllocationSizeInt());
// Pack the file attributes
buf.putShort(info.getFileAttributes());
// Pack the EA size, always 4.
if (eaFlag == true)
buf.putInt(0);
}
/**
* Pack the basic file information (level 0x101)
*
* @param info File information
* @param buf Buffer to pack data into
*/
private static void packBasicFileInfo(FileInfo info, DataBuffer buf) {
// Information format :-
// LARGE_INTEGER Creation date/time
// LARGE_INTEGER Access date/time
// LARGE_INTEGER Write date/time
// LARGE_INTEGER Change date/time
// UINT Attributes
// UINT Reserved
// Pack the creation date/time
if (info.hasCreationDateTime()) {
buf.putLong(NTTime.toNTTime(info.getCreationDateTime()));
}
else
buf.putZeros(8);
// Pack the last access date/time
if (info.hasAccessDateTime()) {
buf.putLong(NTTime.toNTTime(info.getAccessDateTime()));
}
else if (info.hasModifyDateTime())
buf.putLong(NTTime.toNTTime(info.getModifyDateTime()));
else
buf.putZeros(8);
// Pack the last write and change date/time
if (info.hasModifyDateTime()) {
long ntTime = NTTime.toNTTime(info.getModifyDateTime());
buf.putLong(ntTime);
buf.putLong(ntTime);
}
else
buf.putZeros(16);
// Pack the file attributes
buf.putInt(info.getFileAttributes());
// Pack reserved value
buf.putZeros(4);
}
/**
* Pack the standard file information (level 0x102)
*
* @param info File information
* @param buf Buffer to pack data into
*/
private static void packStandardFileInfo(FileInfo info, DataBuffer buf) {
// Information format :-
// LARGE_INTEGER AllocationSize
// LARGE_INTEGER EndOfFile
// UINT NumberOfLinks
// BOOLEAN DeletePending
// BOOLEAN Directory
// SHORT Unknown
// Pack the allocation and file sizes
if (info.getAllocationSize() < info.getSize())
buf.putLong(info.getSize());
else
buf.putLong(info.getAllocationSize());
buf.putLong(info.getSize());
// Pack the number of links, always one for now
buf.putInt(1);
// Pack the delete pending and directory flags
buf.putByte(info.hasDeleteOnClose() ? 1 : 0);
buf.putByte(info.isDirectory() ? 1 : 0);
// Pack the reserved field
buf.putZeros( 2);
}
/**
* Pack the extended attribute information (level 0x103)
*
* @param info File information
* @param buf Buffer to pack data into
*/
private static void packEAFileInfo(FileInfo info, DataBuffer buf) {
// Information format :-
// ULONG EASize
// Pack the extended attribute size
buf.putInt(0);
}
/**
* Pack the file name information (level 0x104)
*
* @param info File information
* @param buf Buffer to pack data into
* @param uni Pack unicode strings
*/
private static void packNameFileInfo(FileInfo info, DataBuffer buf, boolean uni) {
// Information format :-
// UINT FileNameLength
// WCHAR FileName[]
// Pack the file name length and name string as Unicode
int nameLen = info.getFileNameLength();
if (uni)
nameLen *= 2;
buf.putInt(nameLen);
if ( nameLen > 0)
buf.putString(info.getFileName(), uni, false);
}
/**
* Pack the all file information (level 0x107)
*
* @param info File information
* @param buf Buffer to pack data into
* @param uni Pack unicode strings
*/
private static void packAllFileInfo(FileInfo info, DataBuffer buf, boolean uni) {
// Information format :-
// LARGE_INTEGER Creation date/time
// LARGE_INTEGER Access date/time
// LARGE_INTEGER Write date/time
// LARGE_INTEGER Change date/time
// UINT Attributes
// UINT Reserved
// LARGE_INTEGER Allocation
// LARGE_INTEGER Size
// UINT NumberOfLinks
// BYTE Delete pending
// BYTE Directory flag
// 2 byte longword alignment
// LARGE_INTEGER FileId
// UINT EA Size
// UINT Access mask
// LARGE_INTEGER FilePosition
// UINT Mode
// UINT Alignment
// UINT File name length
// WCHAR FileName[]
// Pack the creation date/time
if (info.hasCreationDateTime()) {
buf.putLong(NTTime.toNTTime(info.getCreationDateTime()));
}
else
buf.putZeros(8);
// Pack the last access date/time
if (info.hasAccessDateTime()) {
buf.putLong(NTTime.toNTTime(info.getAccessDateTime()));
}
else
buf.putZeros(8);
// Pack the last write and change date/time
if (info.hasModifyDateTime()) {
long ntTime = NTTime.toNTTime(info.getModifyDateTime());
buf.putLong(ntTime);
buf.putLong(ntTime);
}
else
buf.putZeros(16);
// Pack the file attributes
buf.putInt(info.getFileAttributes());
// Reserved
buf.putInt(0);
// Pack the allocation and used file sizes
if (info.getAllocationSize() < info.getSize())
buf.putLong(info.getSize());
else
buf.putLong(info.getAllocationSize());
buf.putLong(info.getSize());
// Number of links
buf.putInt(1);
// Pack the delete pending and directory flags
buf.putByte(info.hasDeleteOnClose() ? 1 : 0);
buf.putByte(info.isDirectory() ? 1 : 0);
buf.putShort(0); // Alignment
// Internal id
buf.putLong( info.getFileIdLong());
// EA list size
buf.putInt(0);
// Access mask
buf.putInt(AccessMode.NTFileGenericAll);
// Current file position
buf.putLong( 0);
// Mode
if (info.hasDeleteOnClose())
buf.putInt(Mode.DeleteOnClose);
else
buf.putInt( 0);
// Alignment information
buf.putInt( 0); // byte alignment
// File name length in bytes and file name, Unicode
int nameLen = info.getFileNameLength();
if (uni)
nameLen *= 2;
buf.putInt(nameLen);
if ( nameLen > 0)
buf.putString(info.getFileName(), uni, false);
}
/**
* Pack the alternate name information (level 0x108), 8.3 format name
*
* @param info File information
* @param buf Buffer to pack data into
*/
private static void packAlternateNameFileInfo(FileInfo info, DataBuffer buf) {
// Information format :-
// UINT FileNameLength
// WCHAR FileName[]
// Pack the file name length and name string as Unicode
// Pack a zero length, 8.3 names not supported
buf.putInt( 0);
}
/**
* Pack the stream information (level 0x109)
*
* @param info File information
* @param buf Buffer to pack data into
* @param uni Pack unicode strings
*/
private static void packStreamFileInfo(FileInfo info, DataBuffer buf, boolean uni) {
// Information format :-
// ULONG OffsetToNextStreamInfo
// ULONG NameLength (in bytes)
// LARGE_INTEGER StreamSize
// LARGE_INTEGER StreamAlloc
// WCHAR StreamName[]
// Pack a dummy data stream for now
String streamName = "::$DATA";
buf.putInt(0); // offset to next info (no more info)
int nameLen = streamName.length();
if (uni)
nameLen *= 2;
buf.putInt(nameLen);
// Stream size
buf.putLong(info.getSize());
// Allocation size
if (info.getAllocationSize() < info.getSize())
buf.putLong(info.getSize());
else
buf.putLong(info.getAllocationSize());
buf.putString(streamName, uni, false);
}
/**
* Pack the stream information (level 0x109)
*
* @param streams List of streams
* @param buf Buffer to pack data into
* @param uni Pack unicode strings
* @return int
*/
public static int packStreamFileInfo(StreamInfoList streams, DataBuffer buf, boolean uni) {
// Information format :-
// ULONG OffsetToNextStreamInfo
// ULONG NameLength (in bytes)
// LARGE_INTEGER StreamSize
// LARGE_INTEGER StreamAlloc
// WCHAR StreamName[]
// Loop through the available streams
int curPos = buf.getPosition();
int startPos = curPos;
int pos = 0;
for (int i = 0; i < streams.numberOfStreams(); i++) {
// Get the current stream information
StreamInfo sinfo = streams.getStreamAt(i);
// Skip the offset to the next stream information structure
buf.putInt(0);
// Get the stream name
String sName = sinfo.getName();
if (sName.endsWith(FileName.DataStreamName) == false)
sName = sName + FileName.DataStreamName;
// Set the stream name length
int nameLen = sName.length();
if (uni)
nameLen *= 2;
buf.putInt(nameLen);
// Stream size
buf.putLong(sinfo.getSize());
// Allocation size
//
// First entry in the list should be the $$DATA entry for the main file stream, use a sector
// rounded value for the allocation size. For other streams use the stream size for the allocation
// size
if ( i == 0) {
if (sinfo.getAllocationSize() <= sinfo.getSize())
buf.putLong(MemorySize.roundupLongSize(sinfo.getSize()));
else
buf.putLong(MemorySize.roundupLongSize(sinfo.getAllocationSize()));
}
else
buf.putLong(sinfo.getSize());
buf.putString(sName, uni, false);
// Fill in the offset to the next stream information, if this is not the last stream
if (i < (streams.numberOfStreams() - 1)) {
// Word align the buffer, do not align the last buffer
buf.longwordAlign();
// Fill in the offset from the current stream information structure to the next
pos = buf.getPosition();
buf.setPosition(startPos);
buf.putInt(pos - startPos);
buf.setPosition(pos);
startPos = pos;
}
}
// Return the data length
return buf.getPosition() - curPos;
}
/**
* Pack the compression information (level 0x10B)
*
* @param info File information
* @param buf Buffer to pack data into
*/
private static void packCompressionFileInfo(FileInfo info, DataBuffer buf) {
// Information format :-
// LARGE_INTEGER CompressedSize
// ULONG CompressionFormat (sess WinNT class)
buf.putLong(info.getSize());
buf.putInt(Compression.None.ordinal());
}
/**
* Pack the file internal information (level 1006)
*
* @param info File information
* @param buf Buffer to pack data into
*/
private static void packFileInternalInfo(FileInfo info, DataBuffer buf) {
// Information format :-
// ULONG Unknown1
// ULONG Unknown2
buf.putInt(0);
buf.putInt(0);
}
/**
* Pack the file position information (level 1014)
*
* @param info File information
* @param buf Buffer to pack data into
*/
private static void packFilePositionInfo(FileInfo info, DataBuffer buf) {
// Information format :-
// ULONG Unknown1
// ULONG Unknown2
buf.putInt(0);
buf.putInt(0);
}
/**
* Pack the network open information (level 1034)
*
* @param info File information
* @param buf Buffer to pack data into
*/
private static void packFileNetworkOpenInfo(FileInfo info, DataBuffer buf) {
// Information format :-
// LARGE_INTEGER Creation date/time
// LARGE_INTEGER Access date/time
// LARGE_INTEGER Write date/time
// LARGE_INTEGER Change date/time
// LARGE_INTEGER Allocation
// LARGE_INTEGER Size
// UINT Attributes
// UINT Reserved
// Pack the creation date/time
if (info.hasCreationDateTime()) {
buf.putLong(NTTime.toNTTime(info.getCreationDateTime()));
}
else
buf.putZeros(8);
// Pack the last access date/time
if (info.hasAccessDateTime()) {
buf.putLong(NTTime.toNTTime(info.getAccessDateTime()));
}
else if ( info.hasModifyDateTime()) {
buf.putLong(NTTime.toNTTime(info.getModifyDateTime()));
}
else
buf.putZeros(8);
// Pack the last write and change date/time
if (info.hasModifyDateTime()) {
long ntTime = NTTime.toNTTime(info.getModifyDateTime());
buf.putLong(ntTime);
buf.putLong(ntTime);
}
else
buf.putZeros(16);
// Pack the allocation and used file sizes
if (info.getAllocationSize() < info.getSize())
buf.putLong(info.getSize());
else
buf.putLong(info.getAllocationSize());
buf.putLong(info.getSize());
// Pack the file attributes
buf.putInt(info.getFileAttributes());
// Pack the reserved value
buf.putInt(0);
}
/**
* Pack the attribute tag information (level 1035)
*
* @param info File information
* @param buf Buffer to pack data into
*/
private static void packFileAttributeTagInfo(FileInfo info, DataBuffer buf) {
// Information format :-
// UINT FileAttributes
// UINT ReparseTag
buf.putInt(info.getFileAttributes());
buf.putInt(0);
}
/**
* Pack the extended attributes (level 1035)
*
* @param info File information
* @param buf Buffer to pack data into
*/
private static void packAllEAsInfo(FileInfo info, DataBuffer buf) {
// Information format :-
// UINT EA list length
buf.putInt(4);
}
/**
* Pack the both directory information (level 1003)
*
* @param info File information
* @param buf Buffer to pack data into
* @param uni Pack unicode strings
*/
private static void packBothDirectoryInfo(FileInfo info, DataBuffer buf, boolean uni) {
// Information format :-
// UINT FileIndex
// LARGE_INTEGER Creation date/time
// LARGE_INTEGER Access date/time
// LARGE_INTEGER Write date/time
// LARGE_INTEGER Change date/time
// LARGE_INTEGER Size
// LARGE_INTEGER Allocation
// UINT FileAttributes
// UINT FileNameLength
// UINT EASize
// BYTE ShortNameLength
// BYTE Reserved
// BYTE[24] ShortName
// WCHAR FileName[]
// Pack the file index
buf.putInt(0);
// Pack the creation date/time
if (info.hasCreationDateTime()) {
buf.putLong(NTTime.toNTTime(info.getCreationDateTime()));
}
else
buf.putZeros(8);
// Pack the last access date/time
if (info.hasAccessDateTime()) {
buf.putLong(NTTime.toNTTime(info.getAccessDateTime()));
}
else
buf.putZeros(8);
// Pack the last write and change date/time
if (info.hasModifyDateTime()) {
long ntTime = NTTime.toNTTime(info.getModifyDateTime());
buf.putLong(ntTime);
buf.putLong(ntTime);
}
else
buf.putZeros(16);
// Pack the used and allocation file sizes
buf.putLong(info.getSize());
if (info.getAllocationSize() < info.getSize())
buf.putLong(info.getSize());
else
buf.putLong(info.getAllocationSize());
// Pack the file attributes
buf.putInt(info.getFileAttributes());
// File name length in bytes and file name, Unicode
int nameLen = info.getFileNameLength();
if (uni)
nameLen *= 2;
buf.putInt(nameLen);
// Pack the extended attributes size
buf.putInt( 0);
// Pack the short name length and bytes (not used)
buf.putZeros( 26);
// Pack the file name
if ( nameLen > 0)
buf.putString(info.getFileName(), uni, false);
}
/**
* Pack the id both directory information (level 1003)
*
* @param info File information
* @param buf Buffer to pack data into
* @param uni Pack unicode strings
*/
private static void packIdBothDirectoryInfo(FileInfo info, DataBuffer buf, boolean uni) {
// Information format :-
// UINT FileIndex
// LARGE_INTEGER Creation date/time
// LARGE_INTEGER Access date/time
// LARGE_INTEGER Write date/time
// LARGE_INTEGER Change date/time
// LARGE_INTEGER Size
// LARGE_INTEGER Allocation
// UINT FileAttributes
// UINT FileNameLength
// UINT EASize
// BYTE ShortNameLength
// BYTE Reserved
// BYTE[24] ShortName
// LARGE_INTEGER FileId
// WCHAR FileName[]
// Pack the file index
buf.putInt(0);
// Pack the creation date/time
if (info.hasCreationDateTime()) {
buf.putLong(NTTime.toNTTime(info.getCreationDateTime()));
}
else
buf.putZeros(8);
// Pack the last access date/time
if (info.hasAccessDateTime()) {
buf.putLong(NTTime.toNTTime(info.getAccessDateTime()));
}
else
buf.putZeros(8);
// Pack the last write and change date/time
if (info.hasModifyDateTime()) {
long ntTime = NTTime.toNTTime(info.getModifyDateTime());
buf.putLong(ntTime);
buf.putLong(ntTime);
}
else
buf.putZeros(16);
// Pack the used and allocation file sizes
buf.putLong(info.getSize());
if (info.getAllocationSize() < info.getSize())
buf.putLong(info.getSize());
else
buf.putLong(info.getAllocationSize());
// Pack the file attributes
buf.putInt(info.getFileAttributes());
// File name length in bytes and file name, Unicode
int nameLen = info.getFileNameLength();
if (uni)
nameLen *= 2;
buf.putInt(nameLen);
// Pack the extended attributes size
buf.putInt( 0);
// Pack the short name length and bytes (not used)
buf.putZeros( 26);
// Internal id
buf.putLong( info.getFileIdLong());
// Pack the file name
if ( nameLen > 0)
buf.putString(info.getFileName(), uni, false);
}
/**
* Pack the file alignment information (level 1017)
*
* @param buf Buffer to pack data into
*/
private static void packFileAlignmentInfo(DataBuffer buf) {
// Information format :-
// UINT FileAlignment
buf.putInt( FileAlignment.Long.intValue());
}
/**
* Pack the file access information (level 1008)
*
* @param info File information
* @param buf Buffer to pack data into
*/
private static void packFileAccessInfo(FileInfo info, DataBuffer buf) {
// Information format :-
// UINT AccessFlags
if ( info.isDirectory()) {
// Directory access masks
if (info.isReadOnly())
buf.putInt( AccessFolderReadOnly);
else
buf.putInt( AccessFolderReadWrite);
}
else {
// File access masks
if (info.isReadOnly())
buf.putInt( AccessFileReadOnly);
else
buf.putInt( AccessFileReadWrite);
}
}
/**
* Pack the mode information (level 1016)
*
* @param info File information
* @param buf Buffer to pack data into
*/
private static void packModeInfo(FileInfo info, DataBuffer buf) {
// Information format :-
// UINT Mode
buf.putInt( 0);
}
/**
* Pack the quota information (level 1032)
*
* @param info File information
* @param buf Buffer to pack data into
*/
private static void packQuotaInfo(FileInfo info, DataBuffer buf) {
// Information format :-
// UINT NextEntryOffset
// UINT SIDLength
// LARGE_INTEGER ChangeTime
// LARGE_INTEGER QuotaUsed
// LARGE_INTEGER QuotaThreshold
// LARGE_INTEGER QuotaLimit
// BYTE[] SID
buf.putInt( 0);
}
/**
* Calculate the buffer space required for the specified file information and information level. Return zero length if
* the information level is unsupported.
*
* @param info File information
* @param infoLevel File information level
* @param uni Using Unicode strings
* @return int
*/
public static final int calculateInformationSize( FileInfo info, int infoLevel, boolean uni) {
// Determine the information level
int infoLen = 0;
switch (infoLevel) {
// Standard information
case FileInfoLevel.PathStandard:
infoLen = PathStandardLen;
break;
// Standard information plus EA size
case FileInfoLevel.PathQueryEASize:
infoLen = PathQueryEASizeLen;
break;
// Extended attributes list
case FileInfoLevel.PathQueryEAsFromList:
break;
// All extended attributes
case FileInfoLevel.PathAllEAs:
infoLen = PathAllEAsLen;
break;
// Validate a file name
case FileInfoLevel.PathIsNameValid:
break;
// Basic file information
case FileInfoLevel.PathFileBasicInfo:
case FileInfoLevel.NTFileBasicInfo:
infoLen = PathFileBasicLen;
break;
// Standard file information
case FileInfoLevel.PathFileStandardInfo:
case FileInfoLevel.NTFileStandardInfo:
infoLen = PathFileStandardLen;
break;
// Extended attribute information
case FileInfoLevel.PathFileEAInfo:
case FileInfoLevel.NTFileEAInfo:
infoLen = PathFileEAInfoLen;
break;
// File name information
case FileInfoLevel.PathFileNameInfo:
case FileInfoLevel.NTFileNameInfo:
case FileInfoLevel.NTFileNormalizedName:
infoLen = PathFileNameLen;
// Add the file name length
infoLen += (info.getFileNameLength() + 1) * (uni ? 2 : 1);
break;
// All information
case FileInfoLevel.PathFileAllInfo:
case FileInfoLevel.NTFileAllInfo:
infoLen = PathFileAllLen;
// Add the file name length
infoLen += (info.getFileNameLength() + 1) * (uni ? 2 : 1);
break;
// Alternate name information
case FileInfoLevel.PathFileAltNameInfo:
case FileInfoLevel.NTFileAltNameInfo:
break;
// Stream information *
case FileInfoLevel.PathFileStreamInfo:
case FileInfoLevel.NTFileStreamInfo:
infoLen = PathFileStreamLen;
break;
// Compression information
case FileInfoLevel.PathFileCompressionInfo:
case FileInfoLevel.NTFileCompressionInfo:
infoLen = PathFileCompressionLen;
break;
// File internal information
case FileInfoLevel.NTFileInternalInfo:
infoLen = NTFileInternalLen;
break;
// File position information
case FileInfoLevel.NTFilePositionInfo:
infoLen = NTFilePositionLen;
break;
// Attribute tag information
case FileInfoLevel.NTAttributeTagInfo:
infoLen = NTAttributeTagLen;
break;
// Network open information
case FileInfoLevel.NTNetworkOpenInfo:
infoLen = NTNetworkOpenLen;
break;
// Both directory information
case FileInfoLevel.NTFileBothDirectoryInfo:
infoLen = NTBothDirectoryLen;
// Add the file name length
infoLen += (info.getFileNameLength() + 1) * (uni ? 2 : 1);
break;
// Id both directory information
case FileInfoLevel.NTIdBothDirectoryInfo:
infoLen = NTIdBothDirectoryLen;
// Add the file name length
infoLen += (info.getFileNameLength() + 1) * (uni ? 2 : 1);
break;
// Unsupported information level
default:
}
// Return the length of the data
return infoLen;
}
}