All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jcifs.smb.SmbWatchHandleImpl Maven / Gradle / Ivy

/*
 * © 2017 AgNO3 Gmbh & Co. KG
 * 
 * This library 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 2.1 of the License, or (at your option) any later version.
 * 
 * This library 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 this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package jcifs.smb;


import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jcifs.CIFSException;
import jcifs.FileNotifyInformation;
import jcifs.SmbConstants;
import jcifs.SmbWatchHandle;
import jcifs.internal.CommonServerMessageBlockRequest;
import jcifs.internal.NotifyResponse;
import jcifs.internal.smb1.trans.nt.NtTransNotifyChange;
import jcifs.internal.smb1.trans.nt.NtTransNotifyChangeResponse;
import jcifs.internal.smb2.notify.Smb2ChangeNotifyRequest;


/**
 * @author mbechler
 *
 */
class SmbWatchHandleImpl implements SmbWatchHandle {

    private static final Logger log = LoggerFactory.getLogger(SmbWatchHandleImpl.class);

    private final SmbFileHandleImpl handle;
    private final int filter;
    private final boolean recursive;


    /**
     * @param fh
     * @param filter
     * @param recursive
     * 
     */
    public SmbWatchHandleImpl ( SmbFileHandleImpl fh, int filter, boolean recursive ) {
        this.handle = fh;
        this.filter = filter;
        this.recursive = recursive;
    }


    /**
     * {@inheritDoc}
     *
     * @see jcifs.SmbWatchHandle#watch()
     */
    @Override
    public List watch () throws CIFSException {
        if ( !this.handle.isValid() ) {
            throw new SmbException("Watch was broken by tree disconnect");
        }
        try ( SmbTreeHandleImpl th = this.handle.getTree() ) {

            CommonServerMessageBlockRequest req;
            NotifyResponse resp = null;
            if ( th.isSMB2() ) {
                Smb2ChangeNotifyRequest r = new Smb2ChangeNotifyRequest(th.getConfig(), this.handle.getFileId());
                r.setCompletionFilter(this.filter);
                r.setNotifyFlags(this.recursive ? Smb2ChangeNotifyRequest.SMB2_WATCH_TREE : 0);
                req = r;
            }
            else {
                if ( !th.hasCapability(SmbConstants.CAP_NT_SMBS) ) {
                    throw new SmbUnsupportedOperationException("Not supported without CAP_NT_SMBS");
                }

                /*
                 * NtTrans Notify Change Request / Response
                 */
                req = new NtTransNotifyChange(th.getConfig(), this.handle.getFid(), this.filter, this.recursive);
                resp = new NtTransNotifyChangeResponse(th.getConfig());
            }

            if ( log.isTraceEnabled() ) {
                log.trace("Sending NtTransNotifyChange for " + this.handle);
            }
            try {
                resp = th.send(req, resp, RequestParam.NO_TIMEOUT, RequestParam.NO_RETRY);
            }
            catch ( SmbException e ) {
                if ( e.getNtStatus() == 0xC0000120 ) {
                    // cancelled
                    log.debug("Request was cancelled", e);
                    return null;
                }
                throw e;
            }
            if ( log.isTraceEnabled() ) {
                log.trace("Returned from NtTransNotifyChange " + resp.getErrorCode());
            }

            if ( !resp.isReceived() ) {
                throw new CIFSException("Did not receive response");
            }

            if ( resp.getErrorCode() == 0x10B ) {
                this.handle.markClosed();
            }
            if ( resp.getErrorCode() == 0x10C ) {
                resp.getNotifyInformation().clear();
            }
            return resp.getNotifyInformation();
        }
    }


    /**
     * {@inheritDoc}
     *
     * @see jcifs.SmbWatchHandle#call()
     */
    @Override
    public List call () throws CIFSException {
        return watch();
    }


    /**
     * {@inheritDoc}
     *
     * @see jcifs.SmbWatchHandle#close()
     */
    @Override
    public void close () throws CIFSException {
        if ( this.handle.isValid() ) {
            this.handle.close(0L);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy