예제 #1
0
  /**
   * 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 static final 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);
  }
예제 #2
0
  /**
   * 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 static final 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);
  }
예제 #3
0
  /**
   * Pack the full file/directory id 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 static final void packInfoDirectoryBothId(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]
    //      USHORT Reserved
    //      LARGE_INTEGER FileId
    //		STRING FileName

    //	Pack the file id

    int startPos = buf.getPosition();
    buf.putZeros(4);
    buf.putZeros(4);

    //  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, should always be 4 ?.

    //	buf.putInt(4);
    buf.putInt(0);

    //	Pack the short file name length (8.3 name)

    pack8Dot3Name(buf, info.getFileName(), uni);

    // Pack reserved field

    buf.putShort(0);

    // Pack the file id

    buf.putLong(info.getFileIdLong());

    //	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);
  }
예제 #4
0
  /**
   * 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 static final 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);
  }
예제 #5
0
  /**
   * 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 static final 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 4.

    if (EAflag)
      //    	buf.putInt(4);
      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);
    }
  }
예제 #6
0
  /**
   * 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 static final 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;

        //   Full directory information with file id

      case InfoFullDirectoryId:
        len = InfoFullDirectoryIdLen + nameLen;
        break;

        //  Full directory information with file id, and short file name

      case InfoDirectoryBothId:
        len = InfoFullDirectoryIdLen + nameLen + 26;
        break;
    }

    //  Add extra space for the resume key, if enabled

    if (resKey) len += 4;

    //  Return the buffer length required.

    return len;
  }
예제 #7
0
  /**
   * Pack the full file/directory information with file id
   *
   * @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
   * @param shortName true if the 8.3 name should be packed
   */
  protected static final void packInfoFullDirectoryId(
      FileInfo info, DataBuffer buf, boolean uni, boolean shortName) {

    //  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]   ]
    //    ULONG Unknown
    //    LARGE_INTEGER FileId
    //    STRING FileName

    //  Leave space for the offset to the next file entry

    int startPos = buf.getPosition();
    buf.putZeros(8);

    //  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.putInt(0);

    //  Reserved/unknown value

    buf.putInt(0);

    //  Pack the file id

    buf.putInt(EnableFileIdPacking ? info.getFileId() : 0);
    buf.putInt(0);

    //  Pack the short file name length (8.3 name)

    if (shortName == true) 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);
  }
예제 #8
0
  /**
   * Process a transact2 query file information (via handle) request.
   *
   * @param sess SMBSrvSession
   * @param vc VirtualCircuit
   * @param tbuf Transaction request details
   * @param smbPkt SMBSrvPacket
   * @exception IOException
   * @exception SMBSrvException
   */
  protected static final void procTrans2QueryFile(
      SMBSrvSession sess, VirtualCircuit vc, SrvTransactBuffer tbuf, SMBSrvPacket smbPkt)
      throws IOException, SMBSrvException {

    // Get the tree connection details

    int treeId = tbuf.getTreeId();
    TreeConnection conn = vc.findConnection(treeId);

    if (conn == null) {
      sess.sendErrorResponseSMB(
          smbPkt, SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos);
      return;
    }

    // Check if the user has the required access permission

    if (conn.hasReadAccess() == false) {

      // User does not have the required access rights

      sess.sendErrorResponseSMB(
          smbPkt, SMBStatus.NTAccessDenied, SMBStatus.DOSAccessDenied, SMBStatus.ErrDos);
      return;
    }

    // Get the file id and query path information level

    DataBuffer paramBuf = tbuf.getParameterBuffer();

    int fid = paramBuf.getShort();
    int infoLevl = paramBuf.getShort();

    // Get the file details via the file id

    NetworkFile netFile = conn.findFile(fid);

    if (netFile == null) {
      sess.sendErrorResponseSMB(smbPkt, SMBStatus.DOSInvalidHandle, SMBStatus.ErrDos);
      return;
    }

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln(
          "IPC$ Query File - level=0x"
              + Integer.toHexString(infoLevl)
              + ", fid="
              + fid
              + ", name="
              + netFile.getFullName());

    // Access the shared device disk interface

    try {

      // Set the return parameter count, so that the data area position can be calculated.

      smbPkt.setParameterCount(10);

      // Pack the file information into the data area of the transaction reply

      byte[] buf = smbPkt.getBuffer();
      int prmPos = DataPacker.longwordAlign(smbPkt.getByteOffset());
      int dataPos = prmPos + 4;

      // Pack the return parametes, EA error offset

      smbPkt.setPosition(prmPos);
      smbPkt.packWord(0);

      // Create a data buffer using the SMB packet. The response should always fit into a
      // single reply packet.

      DataBuffer replyBuf = new DataBuffer(buf, dataPos, buf.length - dataPos);

      // Build the file information from the network file details

      FileInfo fileInfo =
          new FileInfo(netFile.getName(), netFile.getFileSize(), netFile.getFileAttributes());

      fileInfo.setAccessDateTime(netFile.getAccessDate());
      fileInfo.setCreationDateTime(netFile.getCreationDate());
      fileInfo.setModifyDateTime(netFile.getModifyDate());
      fileInfo.setChangeDateTime(netFile.getModifyDate());

      fileInfo.setFileId(netFile.getFileId());

      // Set the file allocation size, looks like it is used as the pipe buffer size

      fileInfo.setAllocationSize(4096L);

      // Pack the file information into the return data packet

      int dataLen = QueryInfoPacker.packInfo(fileInfo, replyBuf, infoLevl, true);

      // Check if any data was packed, if not then the information level is not supported

      if (dataLen == 0) {
        sess.sendErrorResponseSMB(
            smbPkt, SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
        return;
      }

      SMBSrvTransPacket.initTransactReply(smbPkt, 2, prmPos, dataLen, dataPos);
      smbPkt.setByteCount(replyBuf.getPosition() - smbPkt.getByteOffset());

      // Send the transact reply

      sess.sendResponseSMB(smbPkt);
    } catch (FileNotFoundException ex) {

      // Requested file does not exist

      sess.sendErrorResponseSMB(
          smbPkt, SMBStatus.NTObjectNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos);
      return;
    } catch (PathNotFoundException ex) {

      // Requested path does not exist

      sess.sendErrorResponseSMB(
          smbPkt, SMBStatus.NTObjectPathNotFound, SMBStatus.DOSFileNotFound, SMBStatus.ErrDos);
      return;
    } catch (UnsupportedInfoLevelException ex) {

      // Requested information level is not supported

      sess.sendErrorResponseSMB(
          smbPkt, SMBStatus.NTInvalidParameter, SMBStatus.SRVNonSpecificError, SMBStatus.ErrSrv);
      return;
    } catch (DiskOfflineException ex) {

      // Filesystem is offline

      sess.sendErrorResponseSMB(
          smbPkt, SMBStatus.NTObjectPathNotFound, SMBStatus.HRDDriveNotReady, SMBStatus.ErrHrd);
    }
  }