@Override
  public void closeFile(SrvSession sess, TreeConnection tree, NetworkFile param)
      throws IOException {
    ContentContext tctx = (ContentContext) tree.getContext();

    try {
      diskInterface.closeFile(sess, tree, param);

      if (tctx.hasStateCache()) {
        FileStateCache cache = tctx.getStateCache();
        FileState fstate = cache.findFileState(param.getFullName(), true);

        if (fstate != null && param.getAccessToken() != null) {
          FileAccessToken token = param.getAccessToken();
          if (logger.isDebugEnabled() && token != null) {
            logger.debug("close file release lock token:" + token);
          }
          cache.releaseFileAccess(fstate, token);
        }
      }
    } catch (IOException ie) {
      if (logger.isDebugEnabled()) {
        logger.debug("close file exception caught", ie);
      }
      throw ie;
    }
  }
  /**
   * Process a filesystem I/O control request
   *
   * @param sess Server session
   * @param tree Tree connection.
   * @param ctrlCode I/O control code
   * @param fid File id
   * @param dataBuf I/O control specific input data
   * @param isFSCtrl true if this is a filesystem control, or false for a device control
   * @param filter if bit0 is set indicates that the control applies to the share root handle
   * @return DataBuffer
   * @exception IOControlNotImplementedException
   * @exception SMBException
   */
  public DataBuffer processIOControl(
      SrvSession sess,
      TreeConnection tree,
      int ctrlCode,
      int fid,
      DataBuffer dataBuf,
      boolean isFSCtrl,
      int filter)
      throws IOControlNotImplementedException, SMBException {
    // Validate the file id

    NetworkFile netFile = tree.findFile(fid);
    if (netFile == null || netFile.isDirectory() == false)
      throw new SMBException(SMBStatus.NTErr, SMBStatus.NTInvalidParameter);

    // Check if the I/O control handler is enabled

    if (tree.getContext() instanceof ContentContext) {
      ContentContext ctx = (ContentContext) tree.getContext();

      if (ioControlHandler != null) {
        return ioControlHandler.processIOControl(
            sess, tree, ctrlCode, fid, dataBuf, isFSCtrl, filter, this, ctx);
      } else {
        throw new IOControlNotImplementedException();
      }
    }
    return null;
  }
  @Override
  public void closeFile(SrvSession sess, TreeConnection tree, NetworkFile param)
      throws IOException {
    if (logger.isDebugEnabled()) {
      logger.debug("closeFile:" + param.getFullName());
    }

    ContentContext tctx = (ContentContext) tree.getContext();
    NodeRef rootNode = tctx.getRootNode();

    DriverState driverState = getDriverState(sess);

    String[] paths = FileName.splitPath(param.getFullName());
    String folder = paths[0];
    String file = paths[1];

    try {
      EvaluatorContext ctx = getEvaluatorContext(driverState, folder);

      Operation o =
          new CloseFileOperation(
              file,
              param,
              rootNode,
              param.getFullName(),
              param.hasDeleteOnClose(),
              param.isForce());
      Command c = ruleEvaluator.evaluate(ctx, o);

      commandExecutor.execute(sess, tree, c);

      releaseEvaluatorContextIfEmpty(driverState, ctx, folder);
    } catch (org.alfresco.repo.security.permissions.AccessDeniedException ade) {
      throw new AccessDeniedException("Unable to close file " + param.getFullName(), ade);
    }
  }
  @Override
  public NetworkFile createFile(SrvSession sess, TreeConnection tree, FileOpenParams params)
      throws IOException {
    ContentContext tctx = (ContentContext) tree.getContext();

    FileAccessToken token = null;

    if (tctx.hasStateCache()) {
      FileStateCache cache = tctx.getStateCache();
      FileState fstate = tctx.getStateCache().findFileState(params.getPath(), true);
      token = cache.grantFileAccess(params, fstate, FileStatus.NotExist);
      if (logger.isDebugEnabled()) {
        logger.debug("create file created lock token:" + token);
      }
    }

    try {
      NetworkFile newFile = diskInterface.createFile(sess, tree, params);

      if (tctx.hasStateCache()) {
        FileState fstate = tctx.getStateCache().findFileState(params.getPath(), true);
        fstate.setProcessId(params.getProcessId());
        fstate.setSharedAccess(params.getSharedAccess());

        // Indicate that the file is open
        fstate.setFileStatus(
            newFile.isDirectory() ? FileStatus.DirectoryExists : FileStatus.FileExists);
        fstate.setAllocationSize(params.getAllocationSize());

        if (newFile instanceof NodeRefNetworkFile) {
          NodeRefNetworkFile x = (NodeRefNetworkFile) newFile;
          x.setFileState(fstate);
        }

        if (newFile instanceof TempNetworkFile) {
          TempNetworkFile x = (TempNetworkFile) newFile;
          x.setFileState(fstate);
        }
      }

      if (newFile instanceof NodeRefNetworkFile) {
        NodeRefNetworkFile x = (NodeRefNetworkFile) newFile;
        x.setProcessId(params.getProcessId());
        x.setAccessToken(token);
      }

      if (newFile instanceof TempNetworkFile) {
        TempNetworkFile x = (TempNetworkFile) newFile;
        x.setAccessToken(token);
      }

      return newFile;

    } catch (IOException ie) {
      if (logger.isDebugEnabled()) {
        logger.debug("create file exception caught", ie);
      }
      if (tctx.hasStateCache() && token != null) {
        FileStateCache cache = tctx.getStateCache();
        FileState fstate = tctx.getStateCache().findFileState(params.getPath(), false);
        if (fstate != null && token != null) {
          if (logger.isDebugEnabled()) {
            logger.debug("create file release lock token:" + token);
          }
          cache.releaseFileAccess(fstate, token);
        }
      }
      throw ie;
    }
  }
  /**
   * Close the network file
   *
   * @param sess SrvSession
   * @param netFile NetworkFile
   * @exception IOException
   */
  public void closeFile(SrvSession sess, NetworkFile netFile) throws IOException {

    // Close the cached network file

    if (netFile instanceof CachedNetworkFile) {

      // Get the cached network file

      CachedNetworkFile cacheFile = (CachedNetworkFile) netFile;
      cacheFile.closeFile();

      // Get the file segment details

      FileSegment fileSeg = cacheFile.getFileSegment();

      // Check if the file data has been updated, if so then queue a file save

      if (fileSeg.isUpdated() && netFile.hasDeleteOnClose() == false) {

        // Set the modified date/time and file size for the file

        File tempFile = new File(fileSeg.getTemporaryFile());

        netFile.setModifyDate(tempFile.lastModified());
        netFile.setFileSize(tempFile.length());

        // Queue a file save request to save the data back to the repository, if not already queued

        if (fileSeg.isSaveQueued() == false) {

          // Create a file save request for the updated file segment

          SingleFileRequest fileReq =
              new SingleFileRequest(
                  FileRequest.SAVE,
                  cacheFile.getFileId(),
                  cacheFile.getStreamId(),
                  fileSeg.getInfo(),
                  netFile.getFullName(),
                  cacheFile.getFileState());

          // Check if there are any attributes to be added to the file request

          if (hasRequiredAttributes() && sess != null) {

            // Check if the user name is required

            if (m_reqAttributes.containsString(FileRequest.AttrUserName)) {

              // Add the user name attribute

              ClientInfo cInfo = sess.getClientInformation();
              String userName = "";

              if (cInfo != null && cInfo.getUserName() != null) userName = cInfo.getUserName();

              fileReq.addAttribute(new NameValue(FileRequest.AttrUserName, userName));
            }

            // Check if the protocol type is required

            if (m_reqAttributes.containsString(FileRequest.AttrProtocol)) {

              // Add the protocol type attribute

              fileReq.addAttribute(new NameValue(FileRequest.AttrProtocol, sess.getProtocolName()));
            }
          }

          // Set the file segment status

          fileSeg.setStatus(FileSegmentInfo.SaveWait, true);

          // Queue the file save request

          queueFileRequest(fileReq);
        } else if (Debug.EnableInfo && hasDebug()) {

          // DEBUG

          Debug.println("## FileLoader Save already queued for " + fileSeg);
        }
      }

      // Update the cache timeout for the temporary file if there are no references to the file. If
      // the file was
      // opened for sequential access only it will be expired quicker.

      else if (cacheFile.getFileState().getOpenCount() == 0) {

        // If the file was opened for sequential access only then we can delete it from the
        // temporary area
        // sooner

        long tmo = System.currentTimeMillis();

        if (cacheFile.isSequentialOnly()) tmo += SequentialFileExpire;
        else tmo += m_stateCache.getFileStateExpireInterval();

        // Set the file state expiry, the local file data will be deleted when the file state
        // expires (if there
        // are still no references to the file).

        cacheFile.getFileState().setExpiryTime(tmo);
      }

      // If the database is not online and the file is marked for delete then queue a delete file
      // request to do
      // the
      // delete when the database is back online

      if (m_dbCtx.isAvailable() == false && netFile.hasDeleteOnClose()) {

        // Queue an offline delete request for the file

        DeleteFileRequest deleteReq =
            new DeleteFileRequest(
                cacheFile.getFileId(),
                cacheFile.getStreamId(),
                fileSeg.getTemporaryFile(),
                cacheFile.getFullNameStream(),
                cacheFile.getFileState());
        m_dbCtx.addOfflineFileDelete(deleteReq);

        // DEBUG

        if (Debug.EnableInfo && hasDebug())
          Debug.println("## FileLoader queued offline delete, " + deleteReq);
      }
    }
  }
Exemple #6
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);
    }
  }