mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Moving to root below branch label
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2005 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
945
source/java/org/alfresco/filesys/smb/server/FindInfoPacker.java
Normal file
945
source/java/org/alfresco/filesys/smb/server/FindInfoPacker.java
Normal file
@@ -0,0 +1,945 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.filesys.smb.server;
|
||||
|
||||
import org.alfresco.filesys.server.filesys.FileInfo;
|
||||
import org.alfresco.filesys.server.filesys.UnsupportedInfoLevelException;
|
||||
import org.alfresco.filesys.smb.NTTime;
|
||||
import org.alfresco.filesys.smb.SMBDate;
|
||||
import org.alfresco.filesys.util.DataBuffer;
|
||||
|
||||
/**
|
||||
* Find Information Packer Class
|
||||
* <p>
|
||||
* Pack file information for a find first/find next information level.
|
||||
*/
|
||||
class FindInfoPacker
|
||||
{
|
||||
|
||||
// Enable 8.3 name generation (required for Mac OS9)
|
||||
|
||||
private static final boolean Enable8Dot3Names = false;
|
||||
|
||||
// Enable packing of file id
|
||||
|
||||
private static final boolean EnableFileIdPacking = false;
|
||||
|
||||
// File information levels
|
||||
|
||||
public static final int InfoStandard = 1;
|
||||
public static final int InfoQueryEASize = 2;
|
||||
public static final int InfoQueryEAFromList = 3;
|
||||
public static final int InfoDirectory = 0x101;
|
||||
public static final int InfoFullDirectory = 0x102;
|
||||
public static final int InfoNames = 0x103;
|
||||
public static final int InfoDirectoryBoth = 0x104;
|
||||
public static final int InfoMacHfsInfo = 0x302;
|
||||
|
||||
// File information fixed lengths, includes nulls on strings.
|
||||
|
||||
public static final int InfoStandardLen = 24;
|
||||
public static final int InfoQueryEASizeLen = 28;
|
||||
public static final int InfoDirectoryLen = 64;
|
||||
public static final int InfoFullDirectoryLen = 68;
|
||||
public static final int InfoNamesLen = 12;
|
||||
public static final int InfoDirectoryBothLen = 94;
|
||||
public static final int InfoMacHfsLen = 120;
|
||||
|
||||
/**
|
||||
* Pack a file information object into the specified buffer, using information level 1 format.
|
||||
*
|
||||
* @param info File information to be packed.
|
||||
* @param buf Data buffer to pack the file information into
|
||||
* @param infoLevel File information level.
|
||||
* @param uni Pack Unicode strings if true, else pack ASCII strings
|
||||
* @return Length of data packed
|
||||
*/
|
||||
public final static int packInfo(FileInfo info, DataBuffer buf, int infoLevel, boolean uni)
|
||||
throws UnsupportedInfoLevelException
|
||||
{
|
||||
|
||||
// Determine the information level
|
||||
|
||||
int curPos = buf.getPosition();
|
||||
|
||||
switch (infoLevel)
|
||||
{
|
||||
|
||||
// Standard information
|
||||
|
||||
case InfoStandard:
|
||||
packInfoStandard(info, buf, false, uni);
|
||||
break;
|
||||
|
||||
// Standard information + EA list size
|
||||
|
||||
case InfoQueryEASize:
|
||||
packInfoStandard(info, buf, true, uni);
|
||||
break;
|
||||
|
||||
// File name information
|
||||
|
||||
case InfoNames:
|
||||
packInfoFileName(info, buf, uni);
|
||||
break;
|
||||
|
||||
// File/directory information
|
||||
|
||||
case InfoDirectory:
|
||||
packInfoDirectory(info, buf, uni);
|
||||
break;
|
||||
|
||||
// Full file/directory information
|
||||
|
||||
case InfoFullDirectory:
|
||||
packInfoDirectoryFull(info, buf, uni);
|
||||
break;
|
||||
|
||||
// Full file/directory information with short name
|
||||
|
||||
case InfoDirectoryBoth:
|
||||
packInfoDirectoryBoth(info, buf, uni);
|
||||
break;
|
||||
|
||||
// Pack Macintosh format file information
|
||||
|
||||
case InfoMacHfsInfo:
|
||||
packInfoMacHfs(info, buf, uni);
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if we packed any data
|
||||
|
||||
if (curPos == buf.getPosition())
|
||||
throw new UnsupportedInfoLevelException();
|
||||
|
||||
// Return the length of the packed data
|
||||
|
||||
return buf.getPosition() - curPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the file name offset for the specified information level.
|
||||
*
|
||||
* @param infoLev int
|
||||
* @param offset int
|
||||
* @return int
|
||||
*/
|
||||
public final static int calcFileNameOffset(int infoLev, int offset)
|
||||
{
|
||||
|
||||
// Determine the information level
|
||||
|
||||
int pos = offset;
|
||||
|
||||
switch (infoLev)
|
||||
{
|
||||
|
||||
// Standard information level
|
||||
|
||||
case InfoStandard:
|
||||
pos += InfoStandard;
|
||||
break;
|
||||
|
||||
// Standard + EA size
|
||||
|
||||
case InfoQueryEASize:
|
||||
pos += InfoQueryEASizeLen;
|
||||
break;
|
||||
|
||||
// File name information
|
||||
|
||||
case InfoNames:
|
||||
pos += InfoNamesLen;
|
||||
break;
|
||||
|
||||
// File/directory information
|
||||
|
||||
case InfoDirectory:
|
||||
pos += InfoDirectoryLen;
|
||||
break;
|
||||
|
||||
// File/directory information full
|
||||
|
||||
case InfoFullDirectory:
|
||||
pos += InfoFullDirectoryLen;
|
||||
break;
|
||||
|
||||
// Full file/directory information full plus short name
|
||||
|
||||
case InfoDirectoryBoth:
|
||||
pos += InfoDirectoryBothLen;
|
||||
break;
|
||||
}
|
||||
|
||||
// Return the file name offset
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the required buffer space for the file information at the specified file
|
||||
* information level.
|
||||
*
|
||||
* @param info File information
|
||||
* @param infoLev File information level requested.
|
||||
* @param resKey true if resume keys are being returned, else false.
|
||||
* @param uni true if Unicode strings are being used, or false for ASCII strings
|
||||
* @return int Buffer space required, or -1 if unknown information level.
|
||||
*/
|
||||
public final static int calcInfoSize(FileInfo info, int infoLev, boolean resKey, boolean uni)
|
||||
{
|
||||
|
||||
// Determine the information level requested
|
||||
|
||||
int len = -1;
|
||||
int nameLen = info.getFileName().length() + 1;
|
||||
if (uni)
|
||||
nameLen *= 2;
|
||||
|
||||
switch (infoLev)
|
||||
{
|
||||
|
||||
// Standard information level
|
||||
|
||||
case InfoStandard:
|
||||
len = InfoStandardLen + nameLen;
|
||||
break;
|
||||
|
||||
// Standard + EA size
|
||||
|
||||
case InfoQueryEASize:
|
||||
len = InfoQueryEASizeLen + nameLen;
|
||||
break;
|
||||
|
||||
// File name information
|
||||
|
||||
case InfoNames:
|
||||
len += InfoNamesLen + nameLen;
|
||||
break;
|
||||
|
||||
// File/directory information
|
||||
|
||||
case InfoDirectory:
|
||||
len = InfoDirectoryLen + nameLen;
|
||||
break;
|
||||
|
||||
// File/directory information full
|
||||
|
||||
case InfoFullDirectory:
|
||||
len += InfoFullDirectoryLen + nameLen;
|
||||
break;
|
||||
|
||||
// Full file/directory information plus short name
|
||||
|
||||
case InfoDirectoryBoth:
|
||||
len = InfoDirectoryBothLen + nameLen;
|
||||
break;
|
||||
|
||||
// Maacintosh information level
|
||||
|
||||
case InfoMacHfsInfo:
|
||||
len = InfoMacHfsLen + nameLen;
|
||||
break;
|
||||
}
|
||||
|
||||
// Add extra space for the resume key, if enabled
|
||||
|
||||
if (resKey)
|
||||
len += 4;
|
||||
|
||||
// Return the buffer length required.
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the next structure offset
|
||||
*
|
||||
* @param dataBuf DataBuffer
|
||||
* @param level int
|
||||
* @param offset int
|
||||
*/
|
||||
public static final void clearNextOffset(DataBuffer buf, int level, int offset)
|
||||
{
|
||||
|
||||
// Standard information level does not have a next entry offset
|
||||
|
||||
if (level == InfoStandard)
|
||||
return;
|
||||
|
||||
// Clear the next entry offset
|
||||
|
||||
int curPos = buf.getPosition();
|
||||
buf.setPosition(offset);
|
||||
buf.putInt(0);
|
||||
buf.setPosition(curPos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack a file information object into the specified buffer. Use the standard information level
|
||||
* if the EA size flag is false, else add the EA size field.
|
||||
*
|
||||
* @param info File information to be packed.
|
||||
* @param buf Buffer to pack the data into.
|
||||
* @param EAflag Add EA size field if true.
|
||||
* @param uni Pack Unicode strings if true, else pack ASCII strings
|
||||
*/
|
||||
protected final 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 ]
|
||||
// UCHAR File name length
|
||||
// STRING File name, null terminated
|
||||
|
||||
// Pack the creation date/time
|
||||
|
||||
SMBDate date = new SMBDate(0);
|
||||
|
||||
if (info.hasCreationDateTime())
|
||||
{
|
||||
date.setTime(info.getCreationDateTime());
|
||||
buf.putShort(date.asSMBDate());
|
||||
buf.putShort(date.asSMBTime());
|
||||
}
|
||||
else
|
||||
buf.putZeros(4);
|
||||
|
||||
// Pack the last access date/time
|
||||
|
||||
if (info.hasAccessDateTime())
|
||||
{
|
||||
date.setTime(info.getAccessDateTime());
|
||||
buf.putShort(date.asSMBDate());
|
||||
buf.putShort(date.asSMBTime());
|
||||
}
|
||||
else
|
||||
buf.putZeros(4);
|
||||
|
||||
// Pack the last write date/time
|
||||
|
||||
if (info.hasModifyDateTime())
|
||||
{
|
||||
date.setTime(info.getModifyDateTime());
|
||||
buf.putShort(date.asSMBDate());
|
||||
buf.putShort(date.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 zero
|
||||
|
||||
if (EAflag)
|
||||
buf.putInt(0);
|
||||
|
||||
// Pack the file name
|
||||
|
||||
if (uni == true)
|
||||
{
|
||||
|
||||
// Pack the number of bytes followed by the Unicode name word aligned
|
||||
|
||||
buf.putByte(info.getFileName().length() * 2);
|
||||
buf.wordAlign();
|
||||
buf.putString(info.getFileName(), uni, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Pack the number of bytes followed by the ASCII name
|
||||
|
||||
buf.putByte(info.getFileName().length());
|
||||
buf.putString(info.getFileName(), uni, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack the file name information
|
||||
*
|
||||
* @param info File information to be packed.
|
||||
* @param buf Buffer to pack the data into.
|
||||
* @param uni Pack Unicode strings if true, else pack ASCII strings
|
||||
*/
|
||||
protected final static void packInfoFileName(FileInfo info, DataBuffer buf, boolean uni)
|
||||
{
|
||||
|
||||
// Information format :-
|
||||
// ULONG NextEntryOffset
|
||||
// ULONG FileIndex
|
||||
// ULONG FileNameLength
|
||||
// STRING FileName
|
||||
|
||||
// Pack the file id
|
||||
|
||||
int startPos = buf.getPosition();
|
||||
buf.putZeros(4);
|
||||
buf.putInt(EnableFileIdPacking ? info.getFileId() : 0);
|
||||
|
||||
// Pack the file name length
|
||||
|
||||
int nameLen = info.getFileName().length();
|
||||
if (uni)
|
||||
nameLen *= 2;
|
||||
|
||||
buf.putInt(nameLen);
|
||||
|
||||
// Pack the long file name string
|
||||
|
||||
buf.putString(info.getFileName(), uni, false);
|
||||
|
||||
// Align the buffer pointer and set the offset to the next file information entry
|
||||
|
||||
buf.longwordAlign();
|
||||
|
||||
int curPos = buf.getPosition();
|
||||
buf.setPosition(startPos);
|
||||
buf.putInt(curPos - startPos);
|
||||
buf.setPosition(curPos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack the file/directory information
|
||||
*
|
||||
* @param info File information to be packed.
|
||||
* @param buf Buffer to pack the data into.
|
||||
* @param uni Pack Unicode strings if true, else pack ASCII strings
|
||||
*/
|
||||
protected final static void packInfoDirectory(FileInfo info, DataBuffer buf, boolean uni)
|
||||
{
|
||||
|
||||
// Information format :-
|
||||
// ULONG NextEntryOffset
|
||||
// ULONG FileIndex
|
||||
// LARGE_INTEGER CreationTime
|
||||
// LARGE_INTEGER LastAccessTime
|
||||
// LARGE_INTEGER LastWriteTime
|
||||
// LARGE_INTEGER ChangeTime
|
||||
// LARGE_INTEGER EndOfFile
|
||||
// LARGE_INTEGER AllocationSize
|
||||
// ULONG FileAttributes
|
||||
// ULONG FileNameLength
|
||||
// STRING FileName
|
||||
|
||||
// Pack the file id
|
||||
|
||||
int startPos = buf.getPosition();
|
||||
buf.putZeros(4);
|
||||
buf.putInt(EnableFileIdPacking ? info.getFileId() : 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 date/time and change time
|
||||
|
||||
if (info.hasModifyDateTime())
|
||||
{
|
||||
buf.putLong(NTTime.toNTTime(info.getModifyDateTime()));
|
||||
buf.putLong(NTTime.toNTTime(info.getModifyDateTime()));
|
||||
}
|
||||
else
|
||||
buf.putZeros(16);
|
||||
|
||||
// Pack the file size and allocation size
|
||||
|
||||
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());
|
||||
|
||||
// Pack the file name length
|
||||
|
||||
int nameLen = info.getFileName().length();
|
||||
if (uni)
|
||||
nameLen *= 2;
|
||||
|
||||
buf.putInt(nameLen);
|
||||
|
||||
// Pack the long file name string
|
||||
|
||||
buf.putString(info.getFileName(), uni, false);
|
||||
|
||||
// Align the buffer pointer and set the offset to the next file information entry
|
||||
|
||||
buf.longwordAlign();
|
||||
|
||||
int curPos = buf.getPosition();
|
||||
buf.setPosition(startPos);
|
||||
buf.putInt(curPos - startPos);
|
||||
buf.setPosition(curPos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack the full file/directory information
|
||||
*
|
||||
* @param info File information to be packed.
|
||||
* @param buf Buffer to pack the data into.
|
||||
* @param uni Pack Unicode strings if true, else pack ASCII strings
|
||||
*/
|
||||
protected final static void packInfoDirectoryFull(FileInfo info, DataBuffer buf, boolean uni)
|
||||
{
|
||||
|
||||
// Information format :-
|
||||
// ULONG NextEntryOffset
|
||||
// ULONG FileIndex
|
||||
// LARGE_INTEGER CreationTime
|
||||
// LARGE_INTEGER LastAccessTime
|
||||
// LARGE_INTEGER LastWriteTime
|
||||
// LARGE_INTEGER ChangeTime
|
||||
// LARGE_INTEGER EndOfFile
|
||||
// LARGE_INTEGER AllocationSize
|
||||
// ULONG FileAttributes
|
||||
// ULONG FileNameLength
|
||||
// ULONG EaSize
|
||||
// STRING FileName
|
||||
|
||||
// Pack the file id
|
||||
|
||||
int startPos = buf.getPosition();
|
||||
buf.putZeros(4);
|
||||
buf.putInt(EnableFileIdPacking ? info.getFileId() : 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 date/time
|
||||
|
||||
if (info.hasModifyDateTime())
|
||||
{
|
||||
buf.putLong(NTTime.toNTTime(info.getModifyDateTime()));
|
||||
buf.putLong(NTTime.toNTTime(info.getModifyDateTime()));
|
||||
}
|
||||
else
|
||||
buf.putZeros(16);
|
||||
|
||||
// Pack the file size and allocation size
|
||||
|
||||
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());
|
||||
|
||||
// Pack the file name length
|
||||
|
||||
int nameLen = info.getFileName().length();
|
||||
if (uni)
|
||||
nameLen *= 2;
|
||||
|
||||
buf.putInt(nameLen);
|
||||
|
||||
// Pack the EA size
|
||||
|
||||
buf.putZeros(4);
|
||||
|
||||
// Pack the long file name string
|
||||
|
||||
buf.putString(info.getFileName(), uni, false);
|
||||
|
||||
// Align the buffer pointer and set the offset to the next file information entry
|
||||
|
||||
buf.longwordAlign();
|
||||
|
||||
int curPos = buf.getPosition();
|
||||
buf.setPosition(startPos);
|
||||
buf.putInt(curPos - startPos);
|
||||
buf.setPosition(curPos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack the full file/directory information
|
||||
*
|
||||
* @param info File information to be packed.
|
||||
* @param buf Buffer to pack the data into.
|
||||
* @param uni Pack Unicode strings if true, else pack ASCII strings
|
||||
*/
|
||||
protected final static void packInfoDirectoryBoth(FileInfo info, DataBuffer buf, boolean uni)
|
||||
{
|
||||
|
||||
// Information format :-
|
||||
// ULONG NextEntryOffset
|
||||
// ULONG FileIndex
|
||||
// LARGE_INTEGER CreationTime
|
||||
// LARGE_INTEGER LastAccessTime
|
||||
// LARGE_INTEGER LastWriteTime
|
||||
// LARGE_INTEGER ChangeTime
|
||||
// LARGE_INTEGER EndOfFile
|
||||
// LARGE_INTEGER AllocationSize
|
||||
// ULONG FileAttributes
|
||||
// ULONG FileNameLength
|
||||
// ULONG EaSize
|
||||
// UCHAR ShortNameLength
|
||||
// WCHAR ShortName[12]
|
||||
// STRING FileName
|
||||
|
||||
// Pack the file id
|
||||
|
||||
int startPos = buf.getPosition();
|
||||
buf.putZeros(4);
|
||||
buf.putInt(EnableFileIdPacking ? info.getFileId() : 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 date/time and change time
|
||||
|
||||
if (info.hasModifyDateTime())
|
||||
{
|
||||
buf.putLong(NTTime.toNTTime(info.getModifyDateTime()));
|
||||
buf.putLong(NTTime.toNTTime(info.getModifyDateTime()));
|
||||
}
|
||||
else
|
||||
buf.putZeros(16);
|
||||
|
||||
// Pack the file size and allocation size
|
||||
|
||||
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());
|
||||
|
||||
// Pack the file name length
|
||||
|
||||
int nameLen = info.getFileName().length();
|
||||
if (uni)
|
||||
nameLen *= 2;
|
||||
|
||||
buf.putInt(nameLen);
|
||||
|
||||
// Pack the EA size
|
||||
|
||||
buf.putZeros(4);
|
||||
|
||||
// Pack the short file name length (8.3 name)
|
||||
|
||||
pack8Dot3Name(buf, info.getFileName(), uni);
|
||||
|
||||
// Pack the long file name string
|
||||
|
||||
buf.putString(info.getFileName(), uni, false);
|
||||
|
||||
// Align the buffer pointer and set the offset to the next file information entry
|
||||
|
||||
buf.longwordAlign();
|
||||
|
||||
int curPos = buf.getPosition();
|
||||
buf.setPosition(startPos);
|
||||
buf.putInt(curPos - startPos);
|
||||
buf.setPosition(curPos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack the Macintosh format file/directory information
|
||||
*
|
||||
* @param info File information to be packed.
|
||||
* @param buf Buffer to pack the data into.
|
||||
* @param uni Pack Unicode strings if true, else pack ASCII strings
|
||||
*/
|
||||
protected final static void packInfoMacHfs(FileInfo info, DataBuffer buf, boolean uni)
|
||||
{
|
||||
|
||||
// Information format :-
|
||||
// ULONG NextEntryOffset
|
||||
// ULONG FileIndex
|
||||
// LARGE_INTEGER CreationTime
|
||||
// LARGE_INTEGER LastWriteTime
|
||||
// LARGE_INTEGER ChangeTime
|
||||
// LARGE_INTEGER Data stream length
|
||||
// LARGE_INTEGER Resource stream length
|
||||
// LARGE_INTEGER Data stream allocation size
|
||||
// LARGE_INTEGER Resource stream allocation size
|
||||
// ULONG ExtFileAttributes
|
||||
// UCHAR FLAttrib Macintosh SetFLock, 1 = file locked
|
||||
// UCHAR Pad
|
||||
// UWORD DrNmFls Number of items in a directory, zero for files
|
||||
// ULONG AccessControl
|
||||
// UCHAR FinderInfo[32]
|
||||
// ULONG FileNameLength
|
||||
// UCHAR ShortNameLength
|
||||
// UCHAR Pad
|
||||
// WCHAR ShortName[12]
|
||||
// STRING FileName
|
||||
// LONG UniqueId
|
||||
|
||||
// Pack the file id
|
||||
|
||||
int startPos = buf.getPosition();
|
||||
buf.putZeros(4);
|
||||
buf.putInt(EnableFileIdPacking ? info.getFileId() : 0);
|
||||
|
||||
// Pack the creation date/time
|
||||
|
||||
if (info.hasCreationDateTime())
|
||||
{
|
||||
buf.putLong(NTTime.toNTTime(info.getCreationDateTime()));
|
||||
}
|
||||
else
|
||||
buf.putZeros(8);
|
||||
|
||||
// Pack the last write date/time and change time
|
||||
|
||||
if (info.hasModifyDateTime())
|
||||
{
|
||||
buf.putLong(NTTime.toNTTime(info.getModifyDateTime()));
|
||||
buf.putLong(NTTime.toNTTime(info.getModifyDateTime()));
|
||||
}
|
||||
else
|
||||
buf.putZeros(16);
|
||||
|
||||
// Pack the data stream size and resource stream size (always zero)
|
||||
|
||||
buf.putLong(info.getSize());
|
||||
buf.putZeros(8);
|
||||
|
||||
// Pack the data stream allocation size and resource stream allocation size (always zero)
|
||||
|
||||
if (info.getAllocationSize() < info.getSize())
|
||||
buf.putLong(info.getSize());
|
||||
else
|
||||
buf.putLong(info.getAllocationSize());
|
||||
buf.putZeros(8);
|
||||
|
||||
// Pack the file attributes
|
||||
|
||||
buf.putInt(info.getFileAttributes());
|
||||
|
||||
// Pack the file lock and padding byte
|
||||
|
||||
buf.putZeros(2);
|
||||
|
||||
// Pack the number of items in a directory, always zero for now
|
||||
|
||||
buf.putShort(0);
|
||||
|
||||
// Pack the access control
|
||||
|
||||
buf.putInt(0);
|
||||
|
||||
// Pack the finder information
|
||||
|
||||
buf.putZeros(32);
|
||||
|
||||
// Pack the file name length
|
||||
|
||||
int nameLen = info.getFileName().length();
|
||||
if (uni)
|
||||
nameLen *= 2;
|
||||
|
||||
buf.putInt(nameLen);
|
||||
|
||||
// Pack the short file name length (8.3 name) and name
|
||||
|
||||
pack8Dot3Name(buf, info.getFileName(), uni);
|
||||
|
||||
// Pack the long file name string
|
||||
|
||||
buf.putString(info.getFileName(), uni, false);
|
||||
|
||||
// Pack the unique id
|
||||
|
||||
buf.putInt(0);
|
||||
|
||||
// Align the buffer pointer and set the offset to the next file information entry
|
||||
|
||||
buf.longwordAlign();
|
||||
|
||||
int curPos = buf.getPosition();
|
||||
buf.setPosition(startPos);
|
||||
buf.putInt(curPos - startPos);
|
||||
buf.setPosition(curPos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pack a file name as a short 8.3 DOS style name. Packs the short name length byte, reserved
|
||||
* byte and 8.3 file name string.
|
||||
*
|
||||
* @param buf DataBuffer
|
||||
* @param fileName String
|
||||
* @param uni boolean
|
||||
*/
|
||||
private static final void pack8Dot3Name(DataBuffer buf, String fileName, boolean uni)
|
||||
{
|
||||
|
||||
if (Enable8Dot3Names == false)
|
||||
{
|
||||
|
||||
// Pack an emty 8.3 name structure
|
||||
|
||||
buf.putZeros(26);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Split the file name string into name and extension
|
||||
|
||||
int pos = fileName.lastIndexOf('.');
|
||||
|
||||
String namePart = null;
|
||||
String extPart = null;
|
||||
|
||||
if (pos != -1)
|
||||
{
|
||||
|
||||
// Split the file name string
|
||||
|
||||
namePart = fileName.substring(0, pos);
|
||||
extPart = fileName.substring(pos + 1);
|
||||
}
|
||||
else
|
||||
namePart = fileName;
|
||||
|
||||
// If the name already fits into an 8.3 name we do not need to pack the short name
|
||||
|
||||
if (namePart.length() <= 8 && (extPart == null || extPart.length() <= 3))
|
||||
{
|
||||
|
||||
// Pack an emty 8.3 name structure
|
||||
|
||||
buf.putZeros(26);
|
||||
return;
|
||||
}
|
||||
|
||||
// Truncate the name and extension parts down to 8.3 sizes
|
||||
|
||||
if (namePart.length() > 8)
|
||||
namePart = namePart.substring(0, 6) + "~1";
|
||||
|
||||
if (extPart != null && extPart.length() > 3)
|
||||
extPart = extPart.substring(0, 3);
|
||||
|
||||
// Build the 8.3 format string
|
||||
|
||||
StringBuffer str = new StringBuffer(16);
|
||||
|
||||
str.append(namePart);
|
||||
while (str.length() < 8)
|
||||
str.append(" ");
|
||||
|
||||
if (extPart != null)
|
||||
{
|
||||
str.append(".");
|
||||
str.append(extPart);
|
||||
}
|
||||
else
|
||||
str.append(" ");
|
||||
|
||||
// Space pad the string to 12 characters
|
||||
|
||||
while (str.length() < 12)
|
||||
str.append(" ");
|
||||
|
||||
// Calculate the used length
|
||||
|
||||
int len = namePart.length();
|
||||
if (extPart != null)
|
||||
len = extPart.length() + 9;
|
||||
|
||||
len *= 2;
|
||||
|
||||
// Pack the 8.3 file name structure, always packed as Unicode
|
||||
|
||||
buf.putByte(len);
|
||||
buf.putByte(0);
|
||||
|
||||
buf.putString(str.toString(), true, false);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user