FileDocCategorySizeDatePackage
SmbFile.javaAPI DocJCIFS 1.3.17 API111649Tue Oct 18 15:26:24 BST 2011jcifs.smb

SmbFile

public class SmbFile extends URLConnection implements SmbConstants
This class represents a resource on an SMB network. Mainly these resources are files and directories however an SmbFile may also refer to servers and workgroups. If the resource is a file or directory the methods of SmbFile follow the behavior of the well known {@link java.io.File} class. One fundamental difference is the usage of a URL scheme [1] to specify the target file or directory. SmbFile URLs have the following syntax:
smb://[[[domain;]username[:password]@]server[:port]/[[share/[dir/]file]]][?[param=value[param2=value2[...]]]
This example:
smb://storage15/public/foo.txt
would reference the file foo.txt in the share public on the server storage15. In addition to referencing files and directories, jCIFS can also address servers, and workgroups.

Important: all SMB URLs that represent workgroups, servers, shares, or directories require a trailing slash '/'.

When using the java.net.URL class with 'smb://' URLs it is necessary to first call the static jcifs.Config.registerSmbURLHandler(); method. This is required to register the SMB protocol handler.

The userinfo component of the SMB URL (domain;user:pass) must be URL encoded if it contains reserved characters. According to RFC 2396 these characters are non US-ASCII characters and most meta characters however jCIFS will work correctly with anything but '@' which is used to delimit the userinfo component from the server and '%' which is the URL escape character itself.

The server component may a traditional NetBIOS name, a DNS name, or IP address. These name resolution mechanisms and their resolution order can be changed (See Setting Name Resolution Properties). The servername and path components are not case sensitive but the domain, username, and password components are. It is also likely that properties must be specified for jcifs to function (See Setting JCIFS Properties). Here are some examples of SMB URLs with brief descriptions of what they do:

[1] This URL scheme is based largely on the SMB Filesharing URL Scheme IETF draft.

SMB URL Examples
URLDescription
smb://users-nyc;miallen:mypass@angus/tmp/ This URL references a share called tmp on the server angus as user miallen who's password is mypass.
smb://Administrator:P%40ss@msmith1/c/WINDOWS/Desktop/foo.txt A relativly sophisticated example that references a file msmith1's desktop as user Administrator. Notice the '@' is URL encoded with the '%40' hexcode escape.
smb://angus/ This references only a server. The behavior of some methods is different in this context(e.g. you cannot delete a server) however as you might expect the list method will list the available shares on this server.
smb://myworkgroup/ This syntactically is identical to the above example. However if myworkgroup happends to be a workgroup(which is indeed suggested by the name) the list method will return a list of servers that have registered themselves as members of myworkgroup.
smb:// Just as smb://server/ lists shares and smb://workgroup/ lists servers, the smb:// URL lists all available workgroups on a netbios LAN. Again, in this context many methods are not valid and return default values(e.g. isHidden will always return false).
smb://angus.foo.net/d/jcifs/pipes.doc The server name may also be a DNS name as it is in this example. See Setting Name Resolution Properties for details.
smb://192.168.1.15/ADMIN$/ The server name may also be an IP address. See Setting Name Resolution Properties for details.
smb://domain;username:password@server/share/path/to/file.txt A prototypical example that uses all the fields.
smb://myworkgroup/angus/ <-- ILLEGAL Despite the hierarchial relationship between workgroups, servers, and filesystems this example is not valid.
smb://server/share/path/to/dir <-- ILLEGAL URLs that represent workgroups, servers, shares, or directories require a trailing slash '/'.
smb://MYGROUP/?SERVER=192.168.10.15 SMB URLs support some query string parameters. In this example the SERVER parameter is used to override the server name service lookup to contact the server 192.168.10.15 (presumably known to be a master browser) for the server list in workgroup MYGROUP.

A second constructor argument may be specified to augment the URL for better programmatic control when processing many files under a common base. This is slightly different from the corresponding java.io.File usage; a '/' at the beginning of the second parameter will still use the server component of the first parameter. The examples below illustrate the resulting URLs when this second contructor argument is used.

Examples Of SMB URLs When Augmented With A Second Constructor Parameter
First ParameterSecond ParameterResult
smb://host/share/a/b/ c/d/ smb://host/share/a/b/c/d/
smb://host/share/foo/bar/ /share2/zig/zag smb://host/share2/zig/zag
smb://host/share/foo/bar/ ../zip/ smb://host/share/foo/zip/
smb://host/share/zig/zag smb://foo/bar/ smb://foo/bar/
smb://host/share/foo/ ../.././.././../foo/ smb://host/foo/
smb://host/share/zig/zag / smb://host/
smb://server/ ../ smb://server/
smb:// myworkgroup/ smb://myworkgroup/
smb://myworkgroup/ angus/ smb://myworkgroup/angus/ <-- ILLEGAL
(But if you first create an SmbFile with 'smb://workgroup/' and use and use it as the first parameter to a constructor that accepts it with a second String parameter jCIFS will factor out the 'workgroup'.)

Instances of the SmbFile class are immutable; that is, once created, the abstract pathname represented by an SmbFile object will never change.

see
java.io.File

Fields Summary
static final int
O_RDONLY
static final int
O_WRONLY
static final int
O_RDWR
static final int
O_APPEND
static final int
O_CREAT
static final int
O_EXCL
static final int
O_TRUNC
public static final int
FILE_NO_SHARE
When specified as the shareAccess constructor parameter, other SMB clients (including other threads making calls into jCIFS) will not be permitted to access the target file and will receive "The file is being accessed by another process" message.
public static final int
FILE_SHARE_READ
When specified as the shareAccess constructor parameter, other SMB clients will be permitted to read from the target file while this file is open. This constant may be logically OR'd with other share access flags.
public static final int
FILE_SHARE_WRITE
When specified as the shareAccess constructor parameter, other SMB clients will be permitted to write to the target file while this file is open. This constant may be logically OR'd with other share access flags.
public static final int
FILE_SHARE_DELETE
When specified as the shareAccess constructor parameter, other SMB clients will be permitted to delete the target file while this file is open. This constant may be logically OR'd with other share access flags.
public static final int
ATTR_READONLY
A file with this bit on as returned by getAttributes() or set with setAttributes() will be read-only
public static final int
ATTR_HIDDEN
A file with this bit on as returned by getAttributes() or set with setAttributes() will be hidden
public static final int
ATTR_SYSTEM
A file with this bit on as returned by getAttributes() or set with setAttributes() will be a system file
public static final int
ATTR_VOLUME
A file with this bit on as returned by getAttributes() is a volume
public static final int
ATTR_DIRECTORY
A file with this bit on as returned by getAttributes() is a directory
public static final int
ATTR_ARCHIVE
A file with this bit on as returned by getAttributes() or set with setAttributes() is an archived file
static final int
ATTR_COMPRESSED
static final int
ATTR_NORMAL
static final int
ATTR_TEMPORARY
static final int
ATTR_GET_MASK
static final int
ATTR_SET_MASK
static final int
DEFAULT_ATTR_EXPIRATION_PERIOD
static final int
HASH_DOT
static final int
HASH_DOT_DOT
static jcifs.util.LogStream
log
static long
attrExpirationPeriod
static boolean
ignoreCopyToException
public static final int
TYPE_FILESYSTEM
Returned by {@link #getType()} if the resource this SmbFile represents is a regular file or directory.
public static final int
TYPE_WORKGROUP
Returned by {@link #getType()} if the resource this SmbFile represents is a workgroup.
public static final int
TYPE_SERVER
Returned by {@link #getType()} if the resource this SmbFile represents is a server.
public static final int
TYPE_SHARE
Returned by {@link #getType()} if the resource this SmbFile represents is a share.
public static final int
TYPE_NAMED_PIPE
Returned by {@link #getType()} if the resource this SmbFile represents is a named pipe.
public static final int
TYPE_PRINTER
Returned by {@link #getType()} if the resource this SmbFile represents is a printer.
public static final int
TYPE_COMM
Returned by {@link #getType()} if the resource this SmbFile represents is a communications device.
private String
canon
private String
share
private long
createTime
private long
lastModified
private int
attributes
private long
attrExpiration
private long
size
private long
sizeExpiration
private boolean
isExists
private int
shareAccess
private SmbComBlankResponse
blank_resp
private DfsReferral
dfsReferral
protected static Dfs
dfs
NtlmPasswordAuthentication
auth
SmbTree
tree
String
unc
int
fid
int
type
boolean
opened
int
tree_num
jcifs.UniAddress[]
addresses
int
addressIndex
Constructors Summary
public SmbFile(String url)
Constructs an SmbFile representing a resource on an SMB network such as a file or directory. See the description and examples of smb URLs above.

param
url A URL string
throws
MalformedURLException If the parent and child parameters do not follow the prescribed syntax


                                                                   

           
        this( new URL( null, url, Handler.SMB_HANDLER ));
    
public SmbFile(URL url, NtlmPasswordAuthentication auth)
Constructs an SmbFile representing a resource on an SMB network such as a file or directory from a URL object and an NtlmPasswordAuthentication object.

param
url The URL of the target resource
param
auth The credentials the client should use for authentication

        super( url );
        this.auth = auth == null ? new NtlmPasswordAuthentication( url.getUserInfo() ) : auth;

        getUncPath0();
    
SmbFile(SmbFile context, String name, int type, int attributes, long createTime, long lastModified, long size)

        this( context.isWorkgroup0() ?
            new URL( null, "smb://" + name + "/", Handler.SMB_HANDLER ) :
            new URL( context.url, name + (( attributes & ATTR_DIRECTORY ) > 0 ? "/" : "" )));

        /* why was this removed before? DFS? copyTo? Am I going around in circles? */
        auth = context.auth;


        if( context.share != null ) {
            this.tree = context.tree;
            this.dfsReferral = context.dfsReferral;
        }
        int last = name.length() - 1;
        if( name.charAt( last ) == '/" ) {
            name = name.substring( 0, last );
        }
        if( context.share == null ) {
            this.unc = "\\";
        } else if( context.unc.equals( "\\" )) {
            this.unc = '\\" + name;
        } else {
            this.unc = context.unc + '\\" + name;
        }
    /* why? am I going around in circles?
     *  this.type = type == TYPE_WORKGROUP ? 0 : type;
     */
        this.type = type;
        this.attributes = attributes;
        this.createTime = createTime;
        this.lastModified = lastModified;
        this.size = size;
        isExists = true;

        attrExpiration = sizeExpiration =
                System.currentTimeMillis() + attrExpirationPeriod;
    
public SmbFile(SmbFile context, String name)
Constructs an SmbFile representing a resource on an SMB network such as a file or directory. The second parameter is a relative path from the parent SmbFile. See the description above for examples of using the second name parameter.

param
context A base SmbFile
param
name A path string relative to the parent paremeter
throws
MalformedURLException If the parent and child parameters do not follow the prescribed syntax
throws
UnknownHostException If the server or workgroup of the context file cannot be determined

        this( context.isWorkgroup0() ?
            new URL( null, "smb://" + name, Handler.SMB_HANDLER ) :
            new URL( context.url, name, Handler.SMB_HANDLER ), context.auth );
    
public SmbFile(String context, String name)
Constructs an SmbFile representing a resource on an SMB network such as a file or directory. The second parameter is a relative path from the parent. See the description above for examples of using the second chile parameter.

param
context A URL string
param
name A path string relative to the context paremeter
throws
MalformedURLException If the context and name parameters do not follow the prescribed syntax

        this( new URL( new URL( null, context, Handler.SMB_HANDLER ),
                name, Handler.SMB_HANDLER ));
    
public SmbFile(String url, NtlmPasswordAuthentication auth)
Constructs an SmbFile representing a resource on an SMB network such as a file or directory.

param
url A URL string
param
auth The credentials the client should use for authentication
throws
MalformedURLException If the url parameter does not follow the prescribed syntax

        this( new URL( null, url, Handler.SMB_HANDLER ), auth );
    
public SmbFile(String url, NtlmPasswordAuthentication auth, int shareAccess)
Constructs an SmbFile representing a file on an SMB network. The shareAccess parameter controls what permissions other clients have when trying to access the same file while this instance is still open. This value is either FILE_NO_SHARE or any combination of FILE_SHARE_READ, FILE_SHARE_WRITE, and FILE_SHARE_DELETE logically OR'd together.

param
url A URL string
param
auth The credentials the client should use for authentication
param
shareAccess Specifies what access other clients have while this file is open.
throws
MalformedURLException If the url parameter does not follow the prescribed syntax

        this( new URL( null, url, Handler.SMB_HANDLER ), auth );
        if ((shareAccess & ~(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)) != 0) {
            throw new RuntimeException( "Illegal shareAccess parameter" );
        }
        this.shareAccess = shareAccess;
    
public SmbFile(String context, String name, NtlmPasswordAuthentication auth)
Constructs an SmbFile representing a resource on an SMB network such as a file or directory. The second parameter is a relative path from the context. See the description above for examples of using the second name parameter.

param
context A URL string
param
name A path string relative to the context paremeter
param
auth The credentials the client should use for authentication
throws
MalformedURLException If the context and name parameters do not follow the prescribed syntax

        this( new URL( new URL( null, context, Handler.SMB_HANDLER ), name, Handler.SMB_HANDLER ), auth );
    
public SmbFile(String context, String name, NtlmPasswordAuthentication auth, int shareAccess)
Constructs an SmbFile representing a resource on an SMB network such as a file or directory. The second parameter is a relative path from the context. See the description above for examples of using the second name parameter. The shareAccess parameter controls what permissions other clients have when trying to access the same file while this instance is still open. This value is either FILE_NO_SHARE or any combination of FILE_SHARE_READ, FILE_SHARE_WRITE, and FILE_SHARE_DELETE logically OR'd together.

param
context A URL string
param
name A path string relative to the context paremeter
param
auth The credentials the client should use for authentication
param
shareAccess Specifies what access other clients have while this file is open.
throws
MalformedURLException If the context and name parameters do not follow the prescribed syntax

        this( new URL( new URL( null, context, Handler.SMB_HANDLER ), name, Handler.SMB_HANDLER ), auth );
        if ((shareAccess & ~(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)) != 0) {
            throw new RuntimeException( "Illegal shareAccess parameter" );
        }
        this.shareAccess = shareAccess;
    
public SmbFile(SmbFile context, String name, int shareAccess)
Constructs an SmbFile representing a resource on an SMB network such as a file or directory. The second parameter is a relative path from the context. See the description above for examples of using the second name parameter. The shareAccess parameter controls what permissions other clients have when trying to access the same file while this instance is still open. This value is either FILE_NO_SHARE or any combination of FILE_SHARE_READ, FILE_SHARE_WRITE, and FILE_SHARE_DELETE logically OR'd together.

param
context A base SmbFile
param
name A path string relative to the context file path
param
shareAccess Specifies what access other clients have while this file is open.
throws
MalformedURLException If the context and name parameters do not follow the prescribed syntax

        this( context.isWorkgroup0() ?
            new URL( null, "smb://" + name, Handler.SMB_HANDLER ) :
            new URL( context.url, name, Handler.SMB_HANDLER ), context.auth );
        if ((shareAccess & ~(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)) != 0) {
            throw new RuntimeException( "Illegal shareAccess parameter" );
        }
        this.shareAccess = shareAccess;
    
public SmbFile(URL url)
Constructs an SmbFile representing a resource on an SMB network such as a file or directory from a URL object.

param
url The URL of the target resource

        this( url, new NtlmPasswordAuthentication( url.getUserInfo() ));
    
Methods Summary
private SmbComBlankResponseblank_resp()

        if( blank_resp == null ) {
            blank_resp = new SmbComBlankResponse();
        }
        return blank_resp;
    
public booleancanRead()
Tests to see if the file this SmbFile represents can be read. Because any file, directory, or other resource can be read if it exists, this method simply calls the exists method.

return
true if the file is read-only

        if( getType() == TYPE_NAMED_PIPE ) { // try opening the pipe for reading?
            return true;
        }
        return exists(); // try opening and catch sharing violation?
    
public booleancanWrite()
Tests to see if the file this SmbFile represents exists and is not marked read-only. By default, resources are considered to be read-only and therefore for smb://, smb://workgroup/, and smb://server/ resources will be read-only.

return
true if the resource exists is not marked read-only

        if( getType() == TYPE_NAMED_PIPE ) { // try opening the pipe for writing?
            return true;
        }
        return exists() && ( attributes & ATTR_READONLY ) == 0;
    
voidclose(int f, long lastWriteTime)


        if( log.level >= 3 )
            log.println( "close: " + f );

        /*
         * Close Request / Response
         */

        send( new SmbComClose( f, lastWriteTime ), blank_resp() );
    
voidclose(long lastWriteTime)

        if( isOpen() == false ) {
            return;
        }
        close( fid, lastWriteTime );
        opened = false;
    
voidclose()

        close( 0L );
    
public voidconnect()
It is not necessary to call this method directly. This is the URLConnection implementation of connect().

        SmbTransport trans;
        SmbSession ssn;
        UniAddress addr;

        if( isConnected() ) {
            return;
        }

        getUncPath0();
        getFirstAddress();
        for ( ;; ) {
            try {
                doConnect();
                return;
            } catch(SmbAuthException sae) {
                throw sae; // Prevents account lockout on servers with multiple IPs
            } catch(SmbException se) {
                if (getNextAddress() == null) 
                    throw se;
                if (log.level >= 3)
                    se.printStackTrace(log);
            }
        }
    
voidconnect0()

        try {
            connect();
        } catch( UnknownHostException uhe ) {
            throw new SmbException( "Failed to connect to server", uhe );
        } catch( SmbException se ) {
            throw se;
        } catch( IOException ioe ) {
            throw new SmbException( "Failed to connect to server", ioe );
        }
    
public voidcopyTo(jcifs.smb.SmbFile dest)
This method will copy the file or directory represented by this SmbFile and it's sub-contents to the location specified by the dest parameter. This file and the destination file do not need to be on the same host. This operation does not copy extended file attibutes such as ACLs but it does copy regular attributes as well as create and last write times. This method is almost twice as efficient as manually copying as it employs an additional write thread to read and write data concurrently.

It is not possible (nor meaningful) to copy entire workgroups or servers.

param
dest the destination file or directory
throws
SmbException

        SmbComReadAndX req;
        SmbComReadAndXResponse resp;
        WriterThread w;
        int bsize;
        byte[][] b;

        /* Should be able to copy an entire share actually
         */
        if( share == null || dest.share == null) {
            throw new SmbException( "Invalid operation for workgroups or servers" );
        }

        req = new SmbComReadAndX();
        resp = new SmbComReadAndXResponse();

        connect0();
        dest.connect0();

                /* At this point the maxBufferSize values are from the server
                 * exporting the volumes, not the one that we will actually
                 * end up performing IO with. If the server hosting the
                 * actual files has a smaller maxBufSize this could be
                 * incorrect. To handle this properly it is necessary
                 * to redirect the tree to the target server first before
                 * establishing buffer size. These exists() calls facilitate
                 * that.
                 */
        resolveDfs(null);

        /* It is invalid for the source path to be a child of the destination
         * path or visa versa.
         */
        try {
            if (getAddress().equals( dest.getAddress() ) &&
                        canon.regionMatches( true, 0, dest.canon, 0,
                                Math.min( canon.length(), dest.canon.length() ))) {
                throw new SmbException( "Source and destination paths overlap." );
            }
        } catch (UnknownHostException uhe) {
        }

        w = new WriterThread();
        w.setDaemon( true );
        w.start();

        /* Downgrade one transport to the lower of the negotiated buffer sizes
         * so we can just send whatever is received.
         */

        SmbTransport t1 = tree.session.transport;
        SmbTransport t2 = dest.tree.session.transport;

        if( t1.snd_buf_size < t2.snd_buf_size ) {
            t2.snd_buf_size = t1.snd_buf_size;
        } else {
            t1.snd_buf_size = t2.snd_buf_size;
        }

        bsize = Math.min( t1.rcv_buf_size - 70, t1.snd_buf_size - 70 );
        b = new byte[2][bsize];

        try {
            copyTo0( dest, b, bsize, w, req, resp );
        } finally {
            w.write( null, -1, null, 0 );
        }
    
voidcopyTo0(jcifs.smb.SmbFile dest, byte[][] b, int bsize, jcifs.smb.SmbFile$WriterThread w, SmbComReadAndX req, SmbComReadAndXResponse resp)

        int i;

        if( attrExpiration < System.currentTimeMillis() ) {
            attributes = ATTR_READONLY | ATTR_DIRECTORY;
            createTime = 0L;
            lastModified = 0L;
            isExists = false;

            Info info = queryPath( getUncPath0(),
                    Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO );
            attributes = info.getAttributes();
            createTime = info.getCreateTime();
            lastModified = info.getLastWriteTime();

            /* If any of the above fails, isExists will not be set true
             */

            isExists = true;
            attrExpiration = System.currentTimeMillis() + attrExpirationPeriod;
        }

        if( isDirectory() ) {
            SmbFile[] files;
            SmbFile ndest;

            String path = dest.getUncPath0();
            if( path.length() > 1 ) {
                try {
                    dest.mkdir();
                    dest.setPathInformation( attributes, createTime, lastModified );
                } catch( SmbException se ) {
                    if( se.getNtStatus() != NtStatus.NT_STATUS_ACCESS_DENIED &&
                            se.getNtStatus() != NtStatus.NT_STATUS_OBJECT_NAME_COLLISION ) {
                        throw se;
                    }
                }
            }

            files = listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null );
            try {
                for( i = 0; i < files.length; i++ ) {
                    ndest = new SmbFile( dest,
                                    files[i].getName(),
                                    files[i].type,
                                    files[i].attributes,
                                    files[i].createTime,
                                    files[i].lastModified,
                                    files[i].size );
                    files[i].copyTo0( ndest, b, bsize, w, req, resp );
                }
            } catch( UnknownHostException uhe ) {
                throw new SmbException( url.toString(), uhe );
            } catch( MalformedURLException mue ) {
                throw new SmbException( url.toString(), mue );
            }
        } else {
            long off;

            try {
                open( SmbFile.O_RDONLY, 0, ATTR_NORMAL, 0 );
                try {
                    dest.open( SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_TRUNC,
                            FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES,
                            attributes, 0 );
                } catch( SmbAuthException sae ) {
                    if(( dest.attributes & ATTR_READONLY ) != 0 ) {
                                                /* Remove READONLY and try again
                                                 */
                        dest.setPathInformation( dest.attributes & ~ATTR_READONLY, 0L, 0L );
                        dest.open( SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_TRUNC,
                                FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES,
                                attributes, 0 );
                    } else {
                        throw sae;
                    }
                }
    
                i = 0;
                off = 0L;
                for( ;; ) {
                    req.setParam( fid, off, bsize );
                    resp.setParam( b[i], 0 );
                    send( req, resp );
    
                    synchronized( w ) {
                        if( w.e != null ) {
                            throw w.e;
                        }
                        while( !w.ready ) {
                            try {
                                w.wait();
                            } catch( InterruptedException ie ) {
                                throw new SmbException( dest.url.toString(), ie );
                            }
                        }
                        if( w.e != null ) {
                            throw w.e;
                        }
                        if( resp.dataLength <= 0 ) {
                            break;
                        }
                        w.write( b[i], resp.dataLength, dest, off );
                    }
    
                    i = i == 1 ? 0 : 1;
                    off += resp.dataLength;
                }
    
                dest.send( new Trans2SetFileInformation(
                        dest.fid, attributes, createTime, lastModified ),
                        new Trans2SetFileInformationResponse() );
                dest.close( 0L );
            } catch( SmbException se ) {

                if (ignoreCopyToException == false)
                    throw new SmbException("Failed to copy file from [" + this.toString() + "] to [" + dest.toString() + "]", se);

                if( log.level > 1 )
                    se.printStackTrace( log );
            } finally {
                close();
            }
        }
    
public voidcreateNewFile()
Create a new file but fail if it already exists. The check for existance of the file and it's creation are an atomic operation with respect to other filesystem activities.

        if( getUncPath0().length() == 1 ) {
            throw new SmbException( "Invalid operation for workgroups, servers, or shares" );
        }
        close( open0( O_RDWR | O_CREAT | O_EXCL, 0, ATTR_NORMAL, 0 ), 0L );
    
public longcreateTime()
Retrieve the time this SmbFile was created. The value returned is suitable for constructing a {@link java.util.Date} object (i.e. seconds since Epoch 1970). Times should be the same as those reported using the properties dialog of the Windows Explorer program. For Win95/98/Me this is actually the last write time. It is currently not possible to retrieve the create time from files on these systems.

return
The number of milliseconds since the 00:00:00 GMT, January 1, 1970 as a long value

        if( getUncPath0().length() > 1 ) {
            exists();
            return createTime;
        }
        return 0L;
    
public voiddelete()
This method will delete the file or directory specified by this SmbFile. If the target is a directory, the contents of the directory will be deleted as well. If a file within the directory or it's sub-directories is marked read-only, the read-only status will be removed and the file will be deleted.

throws
SmbException

        exists();
        getUncPath0();
        delete( unc );
    
voiddelete(java.lang.String fileName)

        if( getUncPath0().length() == 1 ) {
            throw new SmbException( "Invalid operation for workgroups, servers, or shares" );
        }

        if( System.currentTimeMillis() > attrExpiration ) {
            attributes = ATTR_READONLY | ATTR_DIRECTORY;
            createTime = 0L;
            lastModified = 0L;
            isExists = false;

            Info info = queryPath( getUncPath0(),
                    Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO );
            attributes = info.getAttributes();
            createTime = info.getCreateTime();
            lastModified = info.getLastWriteTime();

            attrExpiration = System.currentTimeMillis() + attrExpirationPeriod;
            isExists = true;
        }

        if(( attributes & ATTR_READONLY ) != 0 ) {
            setReadWrite();
        }

        /*
         * Delete or Delete Directory Request / Response
         */

        if( log.level >= 3 )
            log.println( "delete: " + fileName );

        if(( attributes & ATTR_DIRECTORY ) != 0 ) {

            /* Recursively delete directory contents
             */

            try {
                SmbFile[] l = listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null );
                for( int i = 0; i < l.length; i++ ) {
                    l[i].delete();
                }
            } catch( SmbException se ) {
                /* Oracle FilesOnline version 9.0.4 doesn't send '.' and '..' so
                 * listFiles may generate undesireable "cannot find
                 * the file specified".
                 */
                if( se.getNtStatus() != SmbException.NT_STATUS_NO_SUCH_FILE ) {
                    throw se;
                }
            }

            send( new SmbComDeleteDirectory( fileName ), blank_resp() );
        } else {
            send( new SmbComDelete( fileName ), blank_resp() );
        }

        attrExpiration = sizeExpiration = 0;
    
voiddoConnect()

        SmbTransport trans;
        UniAddress addr;

        addr = getAddress();
        if (tree != null) {
            trans = tree.session.transport;
        } else {
            trans = SmbTransport.getSmbTransport(addr, url.getPort());
            tree = trans.getSmbSession(auth).getSmbTree(share, null);
        }

        String hostName = getServerWithDfs();
        tree.inDomainDfs = dfs.resolve(hostName, tree.share, null, auth) != null;
        if (tree.inDomainDfs) {
            tree.connectionState = 2;
        }

        try {
            if( log.level >= 3 )
                log.println( "doConnect: " + addr );

            tree.treeConnect(null, null);
        } catch (SmbAuthException sae) {
            NtlmPasswordAuthentication a;
            SmbSession ssn;

            if (share == null) { // IPC$ - try "anonymous" credentials
                ssn = trans.getSmbSession(NtlmPasswordAuthentication.NULL);
                tree = ssn.getSmbTree(null, null);
                tree.treeConnect(null, null);
            } else if ((a = NtlmAuthenticator.requestNtlmPasswordAuthentication(
                        url.toString(), sae)) != null) {
                auth = a;
                ssn = trans.getSmbSession(auth);
                tree = ssn.getSmbTree(share, null);
                tree.inDomainDfs = dfs.resolve(hostName, tree.share, null, auth) != null;
                if (tree.inDomainDfs) {
                    tree.connectionState = 2;
                }
                tree.treeConnect(null, null);
            } else {
                if (log.level >= 1 && hasNextAddress())
                    sae.printStackTrace(log);
                throw sae;
            }
        }
    
FileEntry[]doDfsRootEnum()

        MsrpcDfsRootEnum rpc;
        DcerpcHandle handle = null;
        FileEntry[] entries;

        handle = DcerpcHandle.getHandle("ncacn_np:" +
                    getAddress().getHostAddress() +
                    "[\\PIPE\\netdfs]", auth);
        try {
            rpc = new MsrpcDfsRootEnum(getServer());
            handle.sendrecv(rpc);
            if (rpc.retval != 0)
                throw new SmbException(rpc.retval, true);
            return rpc.getEntries();
        } finally {
            try {
                handle.close();
            } catch(IOException ioe) {
                if (log.level >= 4)
                    ioe.printStackTrace(log);
            }
        }
    
voiddoEnum(java.util.ArrayList list, boolean files, java.lang.String wildcard, int searchAttributes, SmbFilenameFilter fnf, SmbFileFilter ff)

        if (ff != null && ff instanceof DosFileFilter) {
            DosFileFilter dff = (DosFileFilter)ff;
            if (dff.wildcard != null)
                wildcard = dff.wildcard;
            searchAttributes = dff.attributes;
        }

        try {
            int hostlen = url.getHost().length();
            if (hostlen == 0 || getType() == TYPE_WORKGROUP) {
                doNetServerEnum(list, files, wildcard, searchAttributes, fnf, ff);
            } else if (share == null) {
                doShareEnum(list, files, wildcard, searchAttributes, fnf, ff);
            } else {
                doFindFirstNext(list, files, wildcard, searchAttributes, fnf, ff);
            }
        } catch (UnknownHostException uhe) {
            throw new SmbException(url.toString(), uhe);
        } catch (MalformedURLException mue) {
            throw new SmbException(url.toString(), mue);
        }
    
voiddoFindFirstNext(java.util.ArrayList list, boolean files, java.lang.String wildcard, int searchAttributes, SmbFilenameFilter fnf, SmbFileFilter ff)

        SmbComTransaction req;
        Trans2FindFirst2Response resp;
        int sid;
        String path = getUncPath0();
        String p = url.getPath();

        if( p.lastIndexOf( '/" ) != ( p.length() - 1 )) {
            throw new SmbException( url.toString() + " directory must end with '/'" );
        }

        req = new Trans2FindFirst2( path, wildcard, searchAttributes );
        resp = new Trans2FindFirst2Response();

        if( log.level >= 3 )
            log.println( "doFindFirstNext: " + req.path );

        send( req, resp );

        sid = resp.sid;
        req = new Trans2FindNext2( sid, resp.resumeKey, resp.lastName );

        /* The only difference between first2 and next2 responses is subCommand
         * so let's recycle the response object.
         */
        resp.subCommand = SmbComTransaction.TRANS2_FIND_NEXT2;

        for( ;; ) {
            for( int i = 0; i < resp.numEntries; i++ ) {
                FileEntry e = resp.results[i];
                String name = e.getName();
                if( name.length() < 3 ) {
                    int h = name.hashCode();
                    if( h == HASH_DOT || h == HASH_DOT_DOT ) {
                        if (name.equals(".") || name.equals(".."))
                            continue;
                    }
                }
                if( fnf != null && fnf.accept( this, name ) == false ) {
                    continue;
                }
                if( name.length() > 0 ) {
                    SmbFile f = new SmbFile( this, name, TYPE_FILESYSTEM,
                            e.getAttributes(), e.createTime(), e.lastModified(), e.length() );
                    if( ff != null && ff.accept( f ) == false ) {
                        continue;
                    }
                    if( files ) {
                        list.add( f );
                    } else {
                        list.add( name );
                    }
                }
            }

            if( resp.isEndOfSearch || resp.numEntries == 0 ) {
                break;
            }

            req.reset( resp.resumeKey, resp.lastName );
            resp.reset();
            send( req, resp );
        }

        try {
            send( new SmbComFindClose2( sid ), blank_resp() );
        } catch (SmbException se) {
            if( log.level >= 4 )
                se.printStackTrace( log );
        }
    
FileEntry[]doMsrpcShareEnum()

        MsrpcShareEnum rpc;
        DcerpcHandle handle;

        rpc = new MsrpcShareEnum(url.getHost());

        /* JCIFS will build a composite list of shares if the target host has
         * multiple IP addresses such as when domain-based DFS is in play. Because
         * of this, to ensure that we query each IP individually without re-resolving
         * the hostname and getting a different IP, we must use the current addresses
         * IP rather than just url.getHost() like we were using prior to 1.2.16.
         */

        handle = DcerpcHandle.getHandle("ncacn_np:" +
                    getAddress().getHostAddress() +
                    "[\\PIPE\\srvsvc]", auth);

        try {
            handle.sendrecv(rpc);
            if (rpc.retval != 0)
                throw new SmbException(rpc.retval, true);
            return rpc.getEntries();
        } finally {
            try {
                handle.close();
            } catch(IOException ioe) {
                if (log.level >= 4)
                    ioe.printStackTrace(log);
            }
        }
    
voiddoNetServerEnum(java.util.ArrayList list, boolean files, java.lang.String wildcard, int searchAttributes, SmbFilenameFilter fnf, SmbFileFilter ff)

        int listType = url.getHost().length() == 0 ? 0 : getType();
        SmbComTransaction req;
        SmbComTransactionResponse resp;

        if (listType == 0) {
            connect0();
            req = new NetServerEnum2(tree.session.transport.server.oemDomainName,
                        NetServerEnum2.SV_TYPE_DOMAIN_ENUM );
            resp = new NetServerEnum2Response();
        } else if (listType == TYPE_WORKGROUP) {
            req = new NetServerEnum2(url.getHost(), NetServerEnum2.SV_TYPE_ALL);
            resp = new NetServerEnum2Response();
        } else {
            throw new SmbException( "The requested list operations is invalid: " + url.toString() );
        }

        boolean more;
        do {
            int n;

            send(req, resp);

            if (resp.status != SmbException.ERROR_SUCCESS &&
                    resp.status != SmbException.ERROR_MORE_DATA) {
                throw new SmbException( resp.status, true );
            }
            more = resp.status == SmbException.ERROR_MORE_DATA;

            n = more ? resp.numEntries - 1 : resp.numEntries;
            for (int i = 0; i < n; i++) {
                FileEntry e = resp.results[i];
                String name = e.getName();
                if (fnf != null && fnf.accept(this, name) == false)
                    continue;
                if (name.length() > 0) {
                    // if !files we don't need to create SmbFiles here
                    SmbFile f = new SmbFile(this, name, e.getType(),
                                ATTR_READONLY | ATTR_DIRECTORY, 0L, 0L, 0L );
                    if (ff != null && ff.accept(f) == false)
                        continue;
                    if (files) {
                        list.add(f);
                    } else {
                        list.add(name);
                    }
                }
            }
            if (getType() != TYPE_WORKGROUP) {
                break;
            }
            req.subCommand = (byte)SmbComTransaction.NET_SERVER_ENUM3;
            req.reset(0, ((NetServerEnum2Response)resp).lastName);
            resp.reset();
        } while(more);
    
FileEntry[]doNetShareEnum()

        SmbComTransaction req = new NetShareEnum();
        SmbComTransactionResponse resp = new NetShareEnumResponse();

        send(req, resp);

        if (resp.status != SmbException.ERROR_SUCCESS)
            throw new SmbException(resp.status, true);

        return resp.results;
    
voiddoShareEnum(java.util.ArrayList list, boolean files, java.lang.String wildcard, int searchAttributes, SmbFilenameFilter fnf, SmbFileFilter ff)

        String p = url.getPath();
        IOException last = null;
        FileEntry[] entries;
        UniAddress addr;
        FileEntry e;
        HashMap map;

        if (p.lastIndexOf('/") != (p.length() - 1))
            throw new SmbException(url.toString() + " directory must end with '/'");
        if (getType() != TYPE_SERVER)
            throw new SmbException("The requested list operations is invalid: " + url.toString());

        map = new HashMap();

        if (dfs.isTrustedDomain(getServer(), auth)) {
            /* The server name is actually the name of a trusted
             * domain. Add DFS roots to the list.
             */
            try {
                entries = doDfsRootEnum();
                for (int ei = 0; ei < entries.length; ei++) {
                    e = entries[ei];
                    if (map.containsKey(e) == false)
                        map.put(e, e);
                }
            } catch (IOException ioe) {
                if (log.level >= 4)
                    ioe.printStackTrace(log);
            }
        }

        addr = getFirstAddress();
        while (addr != null) {
            try {
                doConnect();
                try {
                    entries = doMsrpcShareEnum();
                } catch(IOException ioe) {
                    if (log.level >= 3)
                        ioe.printStackTrace(log);
                    entries = doNetShareEnum();
                }
                for (int ei = 0; ei < entries.length; ei++) {
                    e = entries[ei];
                    if (map.containsKey(e) == false)
                        map.put(e, e);
                }
                break;
            } catch(IOException ioe) {
                if (log.level >= 3)
                    ioe.printStackTrace(log);
                last = ioe;
            }
            addr = getNextAddress();
        }

        if (last != null && map.isEmpty()) {
            if (last instanceof SmbException == false)
                throw new SmbException(url.toString(), last);
            throw (SmbException)last;
        }

        Iterator iter = map.keySet().iterator();
        while (iter.hasNext()) {
            e = (FileEntry)iter.next();
            String name = e.getName();
            if (fnf != null && fnf.accept(this, name) == false)
                continue;
            if (name.length() > 0) {
                // if !files we don't need to create SmbFiles here
                SmbFile f = new SmbFile(this, name, e.getType(),
                            ATTR_READONLY | ATTR_DIRECTORY, 0L, 0L, 0L );
                if (ff != null && ff.accept(f) == false)
                    continue;
                if (files) {
                    list.add(f);
                } else {
                    list.add(name);
                }
            }
        }
    
public booleanequals(java.lang.Object obj)
Tests to see if two SmbFile objects are equal. Two SmbFile objects are equal when they reference the same SMB resource. More specifically, two SmbFile objects are equals if their server IP addresses are equal and the canonicalized representation of their URLs, minus authentication parameters, are case insensitivly and lexographically equal.

For example, assuming the server angus resolves to the 192.168.1.15 IP address, the below URLs would result in SmbFiles that are equal.

smb://192.168.1.15/share/DIR/foo.txt
smb://angus/share/data/../dir/foo.txt

param
obj Another SmbFile object to compare for equality
return
true if the two objects refer to the same SMB resource and false otherwise
throws
SmbException

        if (obj instanceof SmbFile) {
            SmbFile f = (SmbFile)obj;
            boolean ret;

            if (this == f)
                return true;

            /* If uncertain, pathNamesPossiblyEqual returns true.
             * Comparing canonical paths is definitive.
             */
            if (pathNamesPossiblyEqual(url.getPath(), f.url.getPath())) {

                getUncPath0();
                f.getUncPath0();

                if (canon.equalsIgnoreCase(f.canon)) {
                    try {
                        ret = getAddress().equals(f.getAddress());
                    } catch( UnknownHostException uhe ) {
                        ret = getServer().equalsIgnoreCase(f.getServer());
                    }
                    return ret;
                }
            }
        }

        return false;
    
public booleanexists()
Tests to see if the SMB resource exists. If the resource refers only to a server, this method determines if the server exists on the network and is advertising SMB services. If this resource refers to a workgroup, this method determines if the workgroup name is valid on the local SMB network. If this SmbFile refers to the root smb:// resource true is always returned. If this SmbFile is a traditional file or directory, it will be queried for on the specified server as expected.

return
true if the resource exists or is alive or false otherwise


        if( attrExpiration > System.currentTimeMillis() ) {
            return isExists;
        }

        attributes = ATTR_READONLY | ATTR_DIRECTORY;
        createTime = 0L;
        lastModified = 0L;
        isExists = false;

        try {
            if( url.getHost().length() == 0 ) {
            } else if( share == null ) {
                if( getType() == TYPE_WORKGROUP ) {
                    UniAddress.getByName( url.getHost(), true );
                } else {
                    UniAddress.getByName( url.getHost() ).getHostName();
                }
            } else if( getUncPath0().length() == 1 ||
                                        share.equalsIgnoreCase( "IPC$" )) {
                connect0(); // treeConnect is good enough
            } else {
                Info info = queryPath( getUncPath0(),
                    Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO );
                attributes = info.getAttributes();
                createTime = info.getCreateTime();
                lastModified = info.getLastWriteTime();
            }

            /* If any of the above fail, isExists will not be set true
             */

            isExists = true;

        } catch( UnknownHostException uhe ) {
        } catch( SmbException se ) {
            switch (se.getNtStatus()) {
                case NtStatus.NT_STATUS_NO_SUCH_FILE:
                case NtStatus.NT_STATUS_OBJECT_NAME_INVALID:
                case NtStatus.NT_STATUS_OBJECT_NAME_NOT_FOUND:
                case NtStatus.NT_STATUS_OBJECT_PATH_NOT_FOUND:
                    break;
                default:
                    throw se;
            }
        }

        attrExpiration = System.currentTimeMillis() + attrExpirationPeriod;

        return isExists;
    
jcifs.UniAddressgetAddress()

        if (addressIndex == 0)
            return getFirstAddress();
        return addresses[addressIndex - 1];
    
public intgetAttributes()
Return the attributes of this file. Attributes are represented as a bitset that must be masked with ATTR_* constants to determine if they are set or unset. The value returned is suitable for use with the setAttributes() method.

return
the ATTR_* attributes associated with this file
throws
SmbException

        if( getUncPath0().length() == 1 ) {
            return 0;
        }
        exists();
        return attributes & ATTR_GET_MASK;
    
public java.lang.StringgetCanonicalPath()
Returns the full URL of this SMB resource with '.' and '..' components factored out. An SmbFile constructed with the result of this method will result in an SmbFile that is equal to the original.

return
The canonicalized URL of this SMB resource.

        String str = url.getAuthority();
        getUncPath0();
        if( str.length() > 0 ) {
            return "smb://" + url.getAuthority() + canon;
        }
        return "smb://";
    
public intgetContentLength()
This URLConnection method just returns the result of length().

return
the length of this file or 0 if it refers to a directory

        try {
            return (int)(length() & 0xFFFFFFFFL);
        } catch( SmbException se ) {
        }
        return 0;
    
public longgetDate()
This URLConnection method just returns the result of lastModified.

return
the last modified data as milliseconds since Jan 1, 1970

        try {
            return lastModified();
        } catch( SmbException se ) {
        }
        return 0L;
    
public java.lang.StringgetDfsPath()
If the path of this SmbFile falls within a DFS volume, this method will return the referral path to which it maps. Otherwise null is returned.

        resolveDfs(null);
        if( dfsReferral == null ) {
            return null;
        }
        String path = "smb:/" + dfsReferral.server + "/" + dfsReferral.share + unc;
        path = path.replace( '\\", '/" );
        if (isDirectory()) {
            path += '/";
        }
        return path;
    
public longgetDiskFreeSpace()
This method returns the free disk space in bytes of the drive this share represents or the drive on which the directory or file resides. Objects other than TYPE_SHARE or TYPE_FILESYSTEM will result in 0L being returned.

return
the free disk space in bytes of the drive on which this file or directory resides

        if( getType() == TYPE_SHARE || type == TYPE_FILESYSTEM ) {
            int level = Trans2QueryFSInformationResponse.SMB_FS_FULL_SIZE_INFORMATION;
            try {
                return queryFSInformation(level);
            } catch( SmbException ex ) {
                switch (ex.getNtStatus()) {
                    case NtStatus.NT_STATUS_INVALID_INFO_CLASS:
                    case NtStatus.NT_STATUS_UNSUCCESSFUL: // NetApp Filer
                        // SMB_FS_FULL_SIZE_INFORMATION not supported by the server.
                        level = Trans2QueryFSInformationResponse.SMB_INFO_ALLOCATION;
                        return queryFSInformation(level);
                }
                throw ex;
            }
        }
        return 0L;
    
jcifs.UniAddressgetFirstAddress()

        addressIndex = 0;

        String host = url.getHost();
        String path = url.getPath();
        String query = url.getQuery();

        if( query != null ) {
            String server = queryLookup( query, "server" );
            if( server != null && server.length() > 0 ) {
                addresses = new UniAddress[1];
                addresses[0] = UniAddress.getByName( server );
                return getNextAddress();
            }
            String address = queryLookup(query, "address");
            if (address != null && address.length() > 0) {
                byte[] ip = java.net.InetAddress.getByName(address).getAddress();
                addresses = new UniAddress[1];
                addresses[0] = new UniAddress(java.net.InetAddress.getByAddress(host, ip));
                return getNextAddress();
            }
        }

        if (host.length() == 0) {
            try {
                NbtAddress addr = NbtAddress.getByName(
                        NbtAddress.MASTER_BROWSER_NAME, 0x01, null);
                addresses = new UniAddress[1];
                addresses[0] = UniAddress.getByName( addr.getHostAddress() );
            } catch( UnknownHostException uhe ) {
                NtlmPasswordAuthentication.initDefaults();
                if( NtlmPasswordAuthentication.DEFAULT_DOMAIN.equals( "?" )) {
                    throw uhe;
                }
                addresses = UniAddress.getAllByName( NtlmPasswordAuthentication.DEFAULT_DOMAIN, true );
            }
        } else if( path.length() == 0 || path.equals( "/" )) {
            addresses = UniAddress.getAllByName( host, true );
        } else {
            addresses = UniAddress.getAllByName(host, false);
        }

        return getNextAddress();
    
public java.io.InputStreamgetInputStream()
This URLConnection method just returns a new SmbFileInputStream created with this file.

throws
IOException thrown by SmbFileInputStream constructor

        return new SmbFileInputStream( this );
    
public longgetLastModified()
This URLConnection method just returns the result of lastModified.

return
the last modified data as milliseconds since Jan 1, 1970

        try {
            return lastModified();
        } catch( SmbException se ) {
        }
        return 0L;
    
public java.lang.StringgetName()
Returns the last component of the target URL. This will effectively be the name of the file or directory represented by this SmbFile or in the case of URLs that only specify a server or workgroup, the server or workgroup will be returned. The name of the root URL smb:// is also smb://. If this SmbFile refers to a workgroup, server, share, or directory, the name will include a trailing slash '/' so that composing new SmbFiles will maintain the trailing slash requirement.

return
The last component of the URL associated with this SMB resource or smb:// if the resource is smb:// itself.

        getUncPath0();
        if( canon.length() > 1 ) {
            int i = canon.length() - 2;
            while( canon.charAt( i ) != '/" ) {
                i--;
            }
            return canon.substring( i + 1 );
        } else if( share != null ) {
            return share + '/";
        } else if( url.getHost().length() > 0 ) {
            return url.getHost() + '/";
        } else {
            return "smb://";
        }
    
jcifs.UniAddressgetNextAddress()

        UniAddress addr = null;
        if (addressIndex < addresses.length)
            addr = addresses[addressIndex++];
        return addr;
    
public java.io.OutputStreamgetOutputStream()
This URLConnection method just returns a new SmbFileOutputStream created with this file.

throws
IOException thrown by SmbFileOutputStream constructor

        return new SmbFileOutputStream( this );
    
public java.lang.StringgetParent()
Everything but the last component of the URL representing this SMB resource is effectivly it's parent. The root URL smb:// does not have a parent. In this case smb:// is returned.

return
The parent directory of this SMB resource or smb:// if the resource refers to the root of the URL hierarchy which incedentally is also smb://.

        String str = url.getAuthority();

        if( str.length() > 0 ) {
            StringBuffer sb = new StringBuffer( "smb://" );

            sb.append( str );

            getUncPath0();
            if( canon.length() > 1 ) {
                sb.append( canon );
            } else {
                sb.append( '/" );
            }

            str = sb.toString();

            int i = str.length() - 2;
            while( str.charAt( i ) != '/" ) {
                i--;
            }

            return str.substring( 0, i + 1 );
        }

        return "smb://";
    
public java.lang.StringgetPath()
Returns the full uncanonicalized URL of this SMB resource. An SmbFile constructed with the result of this method will result in an SmbFile that is equal to the original.

return
The uncanonicalized full URL of this SMB resource.

        return url.toString();
    
public java.security.PrincipalgetPrincipal()
Returns the NtlmPasswordAuthentication object used as credentials with this file or pipe. This can be used to retrieve the username for example: String username = f.getPrincipal().getName(); The Principal object returned will never be null however the username can be null indication anonymous credentials were used (e.g. some IPC$ services).

        return auth;
    
public ACE[]getSecurity(boolean resolveSids)
Return an array of Access Control Entry (ACE) objects representing the security descriptor associated with this file or directory. If no DACL is present, null is returned. If the DACL is empty, an array with 0 elements is returned.

param
resolveSids Attempt to resolve the SIDs within each ACE form their numeric representation to their corresponding account names.

        int f;
        ACE[] aces;

        f = open0( O_RDONLY, READ_CONTROL, 0, isDirectory() ? 1 : 0 );

        /*
         * NtTrans Query Security Desc Request / Response
         */

        NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc( f, 0x04 );
        NtTransQuerySecurityDescResponse response = new NtTransQuerySecurityDescResponse();

        try {
            send( request, response );
        } finally {
            close( f, 0L );
        }

        aces = response.securityDescriptor.aces;
        if (aces != null)
            processAces(aces, resolveSids);

        return aces;
    
public ACE[]getSecurity()
Return an array of Access Control Entry (ACE) objects representing the security descriptor associated with this file or directory.

Initially, the SIDs within each ACE will not be resolved however when getType(), getDomainName(), getAccountName(), or toString() is called, the names will attempt to be resolved. If the names cannot be resolved (e.g. due to temporary network failure), the said methods will return default values (usually S-X-Y-Z strings of fragments of).

Alternatively getSecurity(true) may be used to resolve all SIDs together and detect network failures.

        return getSecurity(false);
    
public java.lang.StringgetServer()
Retrieve the hostname of the server for this SMB resource. If this SmbFile references a workgroup, the name of the workgroup is returned. If this SmbFile refers to the root of this SMB network hierarchy, null is returned.

return
The server or workgroup name or null if this SmbFile refers to the root smb:// resource.

        String str = url.getHost();
        if( str.length() == 0 ) {
            return null;
        }
        return str;
    
java.lang.StringgetServerWithDfs()

        if (dfsReferral != null) {
            return dfsReferral.server;
        }
        return getServer();
    
public java.lang.StringgetShare()
Retrieves the share associated with this SMB resource. In the case of smb://, smb://workgroup/, and smb://server/ URLs which do not specify a share, null will be returned.

return
The share component or null if there is no share

        return share;
    
public ACE[]getShareSecurity(boolean resolveSids)
Return an array of Access Control Entry (ACE) objects representing the share permissions on the share exporting this file or directory. If no DACL is present, null is returned. If the DACL is empty, an array with 0 elements is returned.

Note that this is different from calling getSecurity on a share. There are actually two different ACLs for shares - the ACL on the share and the ACL on the folder being shared. Go to Computer Management > System Tools > Shared Folders > Shares and look at the Properties for a share. You will see two tabs - one for "Share Permissions" and another for "Security". These correspond to the ACLs returned by getShareSecurity and getSecurity respectively.

param
resolveSids Attempt to resolve the SIDs within each ACE form their numeric representation to their corresponding account names.

        String p = url.getPath();
        MsrpcShareGetInfo rpc;
        DcerpcHandle handle;
        ACE[] aces;

        resolveDfs(null);
        String server = getServerWithDfs();

        rpc = new MsrpcShareGetInfo(server, tree.share);
        handle = DcerpcHandle.getHandle("ncacn_np:" + server + "[\\PIPE\\srvsvc]", auth);

        try {
            handle.sendrecv(rpc);
            if (rpc.retval != 0)
                throw new SmbException(rpc.retval, true);
            aces = rpc.getSecurity();
            if (aces != null)
                processAces(aces, resolveSids);
        } finally {
            try {
                handle.close();
            } catch(IOException ioe) {
                if (log.level >= 1)
                    ioe.printStackTrace(log);
            }
        }

        return aces;
    
public intgetType()
Returns type of of object this SmbFile represents.

return
TYPE_FILESYSTEM, TYPE_WORKGROUP, TYPE_SERVER, TYPE_SHARE, TYPE_PRINTER, TYPE_NAMED_PIPE, or TYPE_COMM.

        if( type == 0 ) {
            if( getUncPath0().length() > 1 ) {
                type = TYPE_FILESYSTEM;
            } else if( share != null ) {
                // treeConnect good enough to test service type
                connect0();
                if( share.equals( "IPC$" )) {
                    type = TYPE_NAMED_PIPE;
                } else if( tree.service.equals( "LPT1:" )) {
                    type = TYPE_PRINTER;
                } else if( tree.service.equals( "COMM" )) {
                    type = TYPE_COMM;
                } else {
                    type = TYPE_SHARE;
                }
            } else if( url.getAuthority() == null || url.getAuthority().length() == 0 ) {
                type = TYPE_WORKGROUP;
            } else {
                UniAddress addr;
                try {
                    addr = getAddress();
                } catch( UnknownHostException uhe ) {
                    throw new SmbException( url.toString(), uhe );
                }
                if( addr.getAddress() instanceof NbtAddress ) {
                    int code = ((NbtAddress)addr.getAddress()).getNameType();
                    if( code == 0x1d || code == 0x1b ) {
                        type = TYPE_WORKGROUP;
                        return type;
                    }
                }
                type = TYPE_SERVER;
            }
        }
        return type;
    
public java.lang.StringgetUncPath()
Retuns the Windows UNC style path with backslashs intead of forward slashes.

return
The UNC path.

        getUncPath0();
        if( share == null ) {
            return "\\\\" + url.getHost();
        }
        return "\\\\" + url.getHost() + canon.replace( '/", '\\" );
    
java.lang.StringgetUncPath0()

        if( unc == null ) {
            char[] in = url.getPath().toCharArray();
            char[] out = new char[in.length];
            int length = in.length, i, o, state, s;

                              /* The canonicalization routine
                               */
            state = 0;
            o = 0;
            for( i = 0; i < length; i++ ) {
                switch( state ) {
                    case 0:
                        if( in[i] != '/" ) {
                            return null;
                        }
                        out[o++] = in[i];
                        state = 1;
                        break;
                    case 1:
                        if( in[i] == '/" ) {
                            break;
                        } else if( in[i] == '." &&
                                    (( i + 1 ) >= length || in[i + 1] == '/" )) {
                            i++;
                            break;
                        } else if(( i + 1 ) < length &&
                                    in[i] == '." &&
                                    in[i + 1] == '." &&
                                    (( i + 2 ) >= length || in[i + 2] == '/" )) {
                            i += 2;
                            if( o == 1 ) break;
                            do {
                                o--;
                            } while( o > 1 && out[o - 1] != '/" );
                            break;
                        }
                        state = 2;
                    case 2:
                        if( in[i] == '/" ) {
                            state = 1;
                        }
                        out[o++] = in[i];
                        break;
                }
            }

            canon = new String( out, 0, o );

            if( o > 1 ) {
                o--;
                i = canon.indexOf( '/", 1 );
                if( i < 0 ) {
                    share = canon.substring( 1 );
                    unc = "\\";
                } else if( i == o ) {
                    share = canon.substring( 1, i );
                    unc = "\\";
                } else {
                    share = canon.substring( 1, i );
                    unc = canon.substring( i, out[o] == '/" ? o : o + 1 );
                    unc = unc.replace( '/", '\\" );
                }
            } else {
                share = null;
                unc = "\\";
            }
        }
        return unc;
    
booleanhasNextAddress()

        return addressIndex < addresses.length;
    
public inthashCode()
Computes a hashCode for this file based on the URL string and IP address if the server. The hashing function uses the hashcode of the server address, the canonical representation of the URL, and does not compare authentication information. In essance, two SmbFile objects that refer to the same file should generate the same hashcode provided it is possible to make such a determination.

return
A hashcode for this abstract file
throws
SmbException

        int hash;
        try {
            hash = getAddress().hashCode();
        } catch( UnknownHostException uhe ) {
            hash = getServer().toUpperCase().hashCode();
        }
        getUncPath0();
        return hash + canon.toUpperCase().hashCode();
    
booleanisConnected()

        return tree != null && tree.connectionState == 2;
    
public booleanisDirectory()
Tests to see if the file this SmbFile represents is a directory.

return
true if this SmbFile is a directory

        if( getUncPath0().length() == 1 ) {
            return true;
        }
        if (!exists()) return false;
        return ( attributes & ATTR_DIRECTORY ) == ATTR_DIRECTORY;
    
public booleanisFile()
Tests to see if the file this SmbFile represents is not a directory.

return
true if this SmbFile is not a directory

        if( getUncPath0().length() == 1 ) {
            return false;
        }
        exists();
        return ( attributes & ATTR_DIRECTORY ) == 0;
    
public booleanisHidden()
Tests to see if the file this SmbFile represents is marked as hidden. This method will also return true for shares with names that end with '$' such as IPC$ or C$.

return
true if the SmbFile is marked as being hidden

        if( share == null ) {
            return false;
        } else if( getUncPath0().length() == 1 ) {
            if( share.endsWith( "$" )) {
                return true;
            }
            return false;
        }
        exists();
        return ( attributes & ATTR_HIDDEN ) == ATTR_HIDDEN;
    
booleanisOpen()

        boolean ans = opened && isConnected() && tree_num == tree.tree_num;
        return ans;
    
booleanisWorkgroup0()

        if( type == TYPE_WORKGROUP || url.getHost().length() == 0 ) {
            type = TYPE_WORKGROUP;
            return true;
        } else {
            getUncPath0();
            if( share == null ) {
                UniAddress addr = getAddress();
                if( addr.getAddress() instanceof NbtAddress ) {
                    int code = ((NbtAddress)addr.getAddress()).getNameType();
                    if( code == 0x1d || code == 0x1b ) {
                        type = TYPE_WORKGROUP;
                        return true;
                    }
                }
                type = TYPE_SERVER;
            }
        }
        return false;
    
public longlastModified()
Retrieve the last time the file represented by this SmbFile was modified. The value returned is suitable for constructing a {@link java.util.Date} object (i.e. seconds since Epoch 1970). Times should be the same as those reported using the properties dialog of the Windows Explorer program.

return
The number of milliseconds since the 00:00:00 GMT, January 1, 1970 as a long value

        if( getUncPath0().length() > 1 ) {
            exists();
            return lastModified;
        }
        return 0L;
    
public longlength()
Returns the length of this SmbFile in bytes. If this object is a TYPE_SHARE the total capacity of the disk shared in bytes is returned. If this object is a directory or a type other than TYPE_SHARE, 0L is returned.

return
The length of the file in bytes or 0 if this SmbFile is not a file.
throws
SmbException

        if( sizeExpiration > System.currentTimeMillis() ) {
            return size;
        }

        if( getType() == TYPE_SHARE ) {
            Trans2QueryFSInformationResponse response;
            int level = Trans2QueryFSInformationResponse.SMB_INFO_ALLOCATION;

            response = new Trans2QueryFSInformationResponse( level );
            send( new Trans2QueryFSInformation( level ), response );

            size = response.info.getCapacity();
        } else if( getUncPath0().length() > 1 && type != TYPE_NAMED_PIPE ) {
            Info info = queryPath( getUncPath0(),
                    Trans2QueryPathInformationResponse.SMB_QUERY_FILE_STANDARD_INFO );
            size = info.getSize();
        } else {
            size = 0L;
        }
        sizeExpiration = System.currentTimeMillis() + attrExpirationPeriod;
        return size;
    
public java.lang.String[]list()
List the contents of this SMB resource. The list returned by this method will be;
  • files and directories contained within this resource if the resource is a normal disk file directory,
  • all available NetBIOS workgroups or domains if this resource is the top level URL smb://,
  • all servers registered as members of a NetBIOS workgroup if this resource refers to a workgroup in a smb://workgroup/ URL,
  • all browseable shares of a server including printers, IPC services, or disk volumes if this resource is a server URL in the form smb://server/,
  • or null if the resource cannot be resolved.

return
A String[] array of files and directories, workgroups, servers, or shares depending on the context of the resource URL

        return list( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null );
    
public java.lang.String[]list(SmbFilenameFilter filter)
List the contents of this SMB resource. The list returned will be identical to the list returned by the parameterless list() method minus filenames filtered by the specified filter.

param
filter a filename filter to exclude filenames from the results
throws
SmbException # @return An array of filenames

        return list( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, filter, null );
    
java.lang.String[]list(java.lang.String wildcard, int searchAttributes, SmbFilenameFilter fnf, SmbFileFilter ff)

        ArrayList list = new ArrayList();
        doEnum(list, false, wildcard, searchAttributes, fnf, ff);
        return (String[])list.toArray(new String[list.size()]);
    
public jcifs.smb.SmbFile[]listFiles()
List the contents of this SMB resource as an array of SmbFile objects. This method is much more efficient than the regular list method when querying attributes of each file in the result set.

The list of SmbFiles returned by this method will be;

  • files and directories contained within this resource if the resource is a normal disk file directory,
  • all available NetBIOS workgroups or domains if this resource is the top level URL smb://,
  • all servers registered as members of a NetBIOS workgroup if this resource refers to a workgroup in a smb://workgroup/ URL,
  • all browseable shares of a server including printers, IPC services, or disk volumes if this resource is a server URL in the form smb://server/,
  • or null if the resource cannot be resolved.

return
An array of SmbFile objects representing file and directories, workgroups, servers, or shares depending on the context of the resource URL

        return listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null );
    
public jcifs.smb.SmbFile[]listFiles(java.lang.String wildcard)
The CIFS protocol provides for DOS "wildcards" to be used as a performance enhancement. The client does not have to filter the names and the server does not have to return all directory entries.

The wildcard expression may consist of two special meta characters in addition to the normal filename characters. The '*' character matches any number of characters in part of a name. If the expression begins with one or more '?'s then exactly that many characters will be matched whereas if it ends with '?'s it will match that many characters or less.

Wildcard expressions will not filter workgroup names or server names.

winnt> ls c?o*
clock.avi -rw-- 82944 Mon Oct 14 1996 1:38 AM
Cookies drw-- 0 Fri Nov 13 1998 9:42 PM
2 items in 5ms

param
wildcard a wildcard expression
throws
SmbException
return
An array of SmbFile objects representing file and directories, workgroups, servers, or shares depending on the context of the resource URL

        return listFiles( wildcard, ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, null );
    
public jcifs.smb.SmbFile[]listFiles(SmbFilenameFilter filter)
List the contents of this SMB resource. The list returned will be identical to the list returned by the parameterless listFiles() method minus files filtered by the specified filename filter.

param
filter a filter to exclude files from the results
return
An array of SmbFile objects
throws
SmbException

        return listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, filter, null );
    
public jcifs.smb.SmbFile[]listFiles(SmbFileFilter filter)
List the contents of this SMB resource. The list returned will be identical to the list returned by the parameterless listFiles() method minus filenames filtered by the specified filter.

param
filter a file filter to exclude files from the results
return
An array of SmbFile objects

        return listFiles( "*", ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM, null, filter );
    
jcifs.smb.SmbFile[]listFiles(java.lang.String wildcard, int searchAttributes, SmbFilenameFilter fnf, SmbFileFilter ff)

        ArrayList list = new ArrayList();
        doEnum(list, true, wildcard, searchAttributes, fnf, ff);
        return (SmbFile[])list.toArray(new SmbFile[list.size()]);
    
public voidmkdir()
Creates a directory with the path specified by this SmbFile. For this method to be successful, the target must not already exist. This method will fail when used with smb://, smb://workgroup/, smb://server/, or smb://server/share/ URLs because workgroups, servers, and shares cannot be dynamically created (although in the future it may be possible to create shares).

throws
SmbException

        String path = getUncPath0();

        if( path.length() == 1 ) {
            throw new SmbException( "Invalid operation for workgroups, servers, or shares" );
        }

        /*
         * Create Directory Request / Response
         */

        if( log.level >= 3 )
            log.println( "mkdir: " + path );

        send( new SmbComCreateDirectory( path ), blank_resp() );

        attrExpiration = sizeExpiration = 0;
    
public voidmkdirs()
Creates a directory with the path specified by this SmbFile and any parent directories that do not exist. This method will fail when used with smb://, smb://workgroup/, smb://server/, or smb://server/share/ URLs because workgroups, servers, and shares cannot be dynamically created (although in the future it may be possible to create shares).

throws
SmbException

        SmbFile parent;

        try {
            parent = new SmbFile( getParent(), auth );
        } catch( IOException ioe ) {
            return;
        }
        if( parent.exists() == false ) {
            parent.mkdirs();
        }
        mkdir();
    
voidopen(int flags, int access, int attrs, int options)

        if( isOpen() ) {
            return;
        }
        fid = open0( flags, access, attrs, options );
        opened = true;
        tree_num = tree.tree_num;
    
intopen0(int flags, int access, int attrs, int options)

        int f;

        connect0();

        if( log.level >= 3 )
            log.println( "open0: " + unc );

        /*
         * NT Create AndX / Open AndX Request / Response
         */

        if( tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS )) {
            SmbComNTCreateAndXResponse response = new SmbComNTCreateAndXResponse();
SmbComNTCreateAndX request = new SmbComNTCreateAndX( unc, flags, access, shareAccess, attrs, options, null );
if (this instanceof SmbNamedPipe) {
    request.flags0 |= 0x16;
    request.desiredAccess |= 0x20000;
    response.isExtended = true;
}
            send( request, response );
            f = response.fid;
            attributes = response.extFileAttributes & ATTR_GET_MASK;
            attrExpiration = System.currentTimeMillis() + attrExpirationPeriod;
            isExists = true;
        } else {
            SmbComOpenAndXResponse response = new SmbComOpenAndXResponse();
            send( new SmbComOpenAndX( unc, access, flags, null ), response );
            f = response.fid;
        }

        return f;
    
protected booleanpathNamesPossiblyEqual(java.lang.String path1, java.lang.String path2)

        int p1, p2, l1, l2;

        // if unsure return this method returns true

        p1 = path1.lastIndexOf('/");
        p2 = path2.lastIndexOf('/");
        l1 = path1.length() - p1;
        l2 = path2.length() - p2;

        // anything with dots voids comparison
        if (l1 > 1 && path1.charAt(p1 + 1) == '.")
            return true;
        if (l2 > 1 && path2.charAt(p2 + 1) == '.")
            return true;

        return l1 == l2 && path1.regionMatches(true, p1, path2, p2, l1);
    
private voidprocessAces(ACE[] aces, boolean resolveSids)

        String server = getServerWithDfs();
        int ai;

        if (resolveSids) {
            SID[] sids = new SID[aces.length];
            String[] names = null;

            for (ai = 0; ai < aces.length; ai++) {
                sids[ai] = aces[ai].sid;
            }

            for (int off = 0; off < sids.length; off += 64) {
                int len = sids.length - off;
                if (len > 64)
                    len = 64;
                SID.resolveSids(server, auth, sids, off, len);
            }
        } else {
            for (ai = 0; ai < aces.length; ai++) {
                aces[ai].sid.origin_server = server;
                aces[ai].sid.origin_auth = auth;
            }
        }
    
private longqueryFSInformation(int level)

        Trans2QueryFSInformationResponse response;

        response = new Trans2QueryFSInformationResponse( level );
        send( new Trans2QueryFSInformation( level ), response );

        if( type == TYPE_SHARE ) {
            size = response.info.getCapacity();
            sizeExpiration = System.currentTimeMillis() + attrExpirationPeriod;
        }

        return response.info.getFree();
    
static java.lang.StringqueryLookup(java.lang.String query, java.lang.String param)

        char in[] = query.toCharArray();
        int i, ch, st, eq;

        st = eq = 0;
        for( i = 0; i < in.length; i++) {
            ch = in[i];
            if( ch == '&" ) {
                if( eq > st ) {
                    String p = new String( in, st, eq - st );
                    if( p.equalsIgnoreCase( param )) {
                        eq++;
                        return new String( in, eq, i - eq );
                    }
                }
                st = i + 1;
            } else if( ch == '=" ) {
                eq = i;
            }
        }
        if( eq > st ) {
            String p = new String( in, st, eq - st );
            if( p.equalsIgnoreCase( param )) {
                eq++;
                return new String( in, eq, in.length - eq );
            }
        }

        return null;
    
InfoqueryPath(java.lang.String path, int infoLevel)

        connect0();

        if (log.level >= 3)
            log.println( "queryPath: " + path );

        /* normally we'd check the negotiatedCapabilities for CAP_NT_SMBS
         * however I can't seem to get a good last modified time from
         * SMB_COM_QUERY_INFORMATION so if NT_SMBs are requested
         * by the server than in this case that's what it will get
         * regardless of what jcifs.smb.client.useNTSmbs is set
         * to(overrides negotiatedCapabilities).
         */

        /* We really should do the referral before this in case
         * the redirected target has different capabilities. But
         * the way we have been doing that is to call exists() which
         * calls this method so another technique will be necessary
         * to support DFS referral _to_ Win95/98/ME.
         */

        if( tree.session.transport.hasCapability( ServerMessageBlock.CAP_NT_SMBS )) {

            /*
             * Trans2 Query Path Information Request / Response
             */

            Trans2QueryPathInformationResponse response =
                    new Trans2QueryPathInformationResponse( infoLevel );
            send( new Trans2QueryPathInformation( path, infoLevel ), response );

            return response.info;
        } else {

            /*
             * Query Information Request / Response
             */

            SmbComQueryInformationResponse response =
                    new SmbComQueryInformationResponse(
                    tree.session.transport.server.serverTimeZone * 1000 * 60L );
            send( new SmbComQueryInformation( path ), response );
            return response;
        }
    
public voidrenameTo(jcifs.smb.SmbFile dest)
Changes the name of the file this SmbFile represents to the name designated by the SmbFile argument.

Remember: SmbFiles are immutible and therefore the path associated with this SmbFile object will not change). To access the renamed file it is necessary to construct a new SmbFile.

param
dest An SmbFile that represents the new pathname
throws
NullPointerException If the dest argument is null

        if( getUncPath0().length() == 1 || dest.getUncPath0().length() == 1 ) {
            throw new SmbException( "Invalid operation for workgroups, servers, or shares" );
        }

        resolveDfs(null);
        dest.resolveDfs(null);

        if (!tree.equals(dest.tree)) {
            throw new SmbException( "Invalid operation for workgroups, servers, or shares" );
        }

        if( log.level >= 3 )
            log.println( "renameTo: " + unc + " -> " + dest.unc );

        attrExpiration = sizeExpiration = 0;
        dest.attrExpiration = 0;

        /*
         * Rename Request / Response
         */

        send( new SmbComRename( unc, dest.unc ), blank_resp() );
    
voidresolveDfs(ServerMessageBlock request)

        if (request instanceof SmbComClose)
            return;

        connect0();

        DfsReferral dr = dfs.resolve(
                    tree.session.transport.tconHostName,
                    tree.share,
                    unc,
                    auth);
        if (dr != null) {
            String service = null;

            if (request != null) {
                switch( request.command ) {
                    case ServerMessageBlock.SMB_COM_TRANSACTION:
                    case ServerMessageBlock.SMB_COM_TRANSACTION2:
                        switch( ((SmbComTransaction)request).subCommand & 0xFF ) {
                            case SmbComTransaction.TRANS2_GET_DFS_REFERRAL:
                                break;
                            default:
                                service = "A:";
                        }
                        break;
                    default:
                        service = "A:";
                }
            }

            DfsReferral start = dr;
            SmbException se = null;

            do {
                try {
                    if (log.level >= 2)
                        log.println("DFS redirect: " + dr);

                    UniAddress addr = UniAddress.getByName(dr.server);
                    SmbTransport trans = SmbTransport.getSmbTransport(addr, url.getPort());
                    /* This is a key point. This is where we set the "tree" of this file which
                     * is like changing the rug out from underneath our feet.
                     */
/* Technically we should also try to authenticate here but that means doing the session setup and tree connect separately. For now a simple connect will at least tell us if the host is alive. That should be sufficient for 99% of the cases. We can revisit this again for 2.0.
 */
                    trans.connect();
                    tree = trans.getSmbSession( auth ).getSmbTree( dr.share, service );

                    if (dr != start && dr.key != null) {
                        dr.map.put(dr.key, dr);
                    }

                    se = null;

                    break;
                } catch (IOException ioe) {
                    if (ioe instanceof SmbException) {
                        se = (SmbException)ioe;
                    } else {
                        se = new SmbException(dr.server, ioe);
                    }
                }

                dr = dr.next;
            } while (dr != start);

            if (se != null)
                throw se;

            if (log.level >= 3)
                log.println( dr );

            dfsReferral = dr;
            if (dr.pathConsumed < 0) {
                dr.pathConsumed = 0;
            } else if (dr.pathConsumed > unc.length()) {
                dr.pathConsumed = unc.length();
            }
            String dunc = unc.substring(dr.pathConsumed);
            if (dunc.equals(""))
                dunc = "\\";
            if (!dr.path.equals(""))
                dunc = "\\" + dr.path + dunc;

            unc = dunc;
            if (request != null &&
                        request.path != null &&
                        request.path.endsWith("\\") &&
                        dunc.endsWith("\\") == false) {
                dunc += "\\";
            }
            if (request != null) {
                request.path = dunc;
                request.flags2 |= ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS;
            }
        } else if (tree.inDomainDfs &&
                        !(request instanceof NtTransQuerySecurityDesc) &&
                        !(request instanceof SmbComClose) &&
                        !(request instanceof SmbComFindClose2)) {
            throw new SmbException(NtStatus.NT_STATUS_NOT_FOUND, false);
        } else {
            if (request != null)
                request.flags2 &= ~ServerMessageBlock.FLAGS2_RESOLVE_PATHS_IN_DFS;
        }
    
voidsend(ServerMessageBlock request, ServerMessageBlock response)

        for( ;; ) {
            resolveDfs(request);
            try {
                tree.send( request, response );
                break;
            } catch( DfsReferral dre ) {
                if( dre.resolveHashes ) {
                    throw dre;
                }
                request.reset();
            }
        }
    
public voidsetAttributes(int attrs)
Set the attributes of this file. Attributes are composed into a bitset by bitwise ORing the ATTR_* constants. Setting the value returned by getAttributes will result in both files having the same attributes.

throws
SmbException

        if( getUncPath0().length() == 1 ) {
            throw new SmbException( "Invalid operation for workgroups, servers, or shares" );
        }
        setPathInformation( attrs & ATTR_SET_MASK, 0L, 0L );
    
public voidsetCreateTime(long time)
Set the create time of the file. The time is specified as milliseconds from Jan 1, 1970 which is the same as that which is returned by the createTime() method.

This method does not apply to workgroups, servers, or shares.

param
time the create time as milliseconds since Jan 1, 1970

        if( getUncPath0().length() == 1 ) {
            throw new SmbException( "Invalid operation for workgroups, servers, or shares" );
        }

        setPathInformation( 0, time, 0L );
    
public voidsetLastModified(long time)
Set the last modified time of the file. The time is specified as milliseconds from Jan 1, 1970 which is the same as that which is returned by the lastModified(), getLastModified(), and getDate() methods.

This method does not apply to workgroups, servers, or shares.

param
time the last modified time as milliseconds since Jan 1, 1970

        if( getUncPath0().length() == 1 ) {
            throw new SmbException( "Invalid operation for workgroups, servers, or shares" );
        }

        setPathInformation( 0, 0L, time );
    
voidsetPathInformation(int attrs, long ctime, long mtime)

        int f, dir;

        exists();
        dir = attributes & ATTR_DIRECTORY;

        f = open0( O_RDONLY, FILE_WRITE_ATTRIBUTES,
                dir, dir != 0 ? 0x0001 : 0x0040 );
        send( new Trans2SetFileInformation( f, attrs | dir, ctime, mtime ),
                new Trans2SetFileInformationResponse() );
        close( f, 0L );

        attrExpiration = 0;
    
public voidsetReadOnly()
Make this file read-only. This is shorthand for setAttributes( getAttributes() | ATTR_READ_ONLY ).

throws
SmbException

        setAttributes( getAttributes() | ATTR_READONLY );
    
public voidsetReadWrite()
Turn off the read-only attribute of this file. This is shorthand for setAttributes( getAttributes() & ~ATTR_READONLY ).

throws
SmbException

        setAttributes( getAttributes() & ~ATTR_READONLY );
    
public java.lang.StringtoString()
Returns the string representation of this SmbFile object. This will be the same as the URL used to construct this SmbFile. This method will return the same value as getPath.

return
The original URL representation of this SMB resource
throws
SmbException

        return url.toString();
    
public java.net.URLtoURL()
Returns a {@link java.net.URL} for this SmbFile. The URL may be used as any other URL might to access an SMB resource. Currently only retrieving data and information is supported (i.e. no doOutput).

deprecated
Use getURL() instead
return
A new {@link java.net.URL} for this SmbFile
throws
MalformedURLException

        return url;