📄 smbfile.java
字号:
* clauses are ncessary to prevent exceptions
*/
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;
}
}
void send( ServerMessageBlock request,
ServerMessageBlock response ) throws SmbException {
for( ;; ) {
resolveDfs(request);
try {
tree.send( request, response );
break;
} catch( DfsReferral dre ) {
if( dre.resolveHashes ) {
throw dre;
}
request.reset();
}
}
}
static String queryLookup( String query, 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;
}
UniAddress[] addresses;
int addressIndex;
UniAddress getAddress() throws UnknownHostException {
if (addressIndex == 0)
return getFirstAddress();
return addresses[addressIndex - 1];
}
UniAddress getFirstAddress() throws UnknownHostException {
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();
}
}
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();
}
UniAddress getNextAddress() {
UniAddress addr = null;
if (addressIndex < addresses.length)
addr = addresses[addressIndex++];
return addr;
}
boolean hasNextAddress() {
return addressIndex < addresses.length;
}
void connect0() throws SmbException {
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 );
}
}
void doConnect() throws IOException {
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.treeConnected = true;
}
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.treeConnected = true;
}
tree.treeConnect(null, null);
} else {
if (log.level >= 1 && hasNextAddress())
sae.printStackTrace(log);
throw sae;
}
}
}
/**
* It is not necessary to call this method directly. This is the
* <tt>URLConnection</tt> implementation of <tt>connect()</tt>.
*/
public void connect() throws IOException {
SmbTransport trans;
SmbSession ssn;
UniAddress addr;
if( isConnected() ) {
return;
}
getUncPath0();
getFirstAddress();
for ( ;; ) {
try {
doConnect();
return;
} catch(SmbException se) {
if (getNextAddress() == null)
throw se;
if (log.level >= 3)
se.printStackTrace(log);
}
}
}
boolean isConnected() {
return tree != null && tree.treeConnected;
}
int open0( int flags, int access, int attrs, int options ) throws SmbException {
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;
}
void open( int flags, int access, int attrs, int options ) throws SmbException {
if( isOpen() ) {
return;
}
fid = open0( flags, access, attrs, options );
opened = true;
tree_num = tree.tree_num;
}
boolean isOpen() {
boolean ans = opened && isConnected() && tree_num == tree.tree_num;
return ans;
}
void close( int f, long lastWriteTime ) throws SmbException {
if( log.level >= 3 )
log.println( "close: " + f );
/*
* Close Request / Response
*/
send( new SmbComClose( f, lastWriteTime ), blank_resp() );
}
void close( long lastWriteTime ) throws SmbException {
if( isOpen() == false ) {
return;
}
close( fid, lastWriteTime );
opened = false;
}
void close() throws SmbException {
close( 0L );
}
/**
* Returns the <tt>NtlmPasswordAuthentication</tt> object used as
* credentials with this file or pipe. This can be used to retrieve the
* username for example:
* <tt>
* String username = f.getPrincipal().getName();
* </tt>
* The <tt>Principal</tt> object returned will never be <tt>null</tt>
* however the username can be <tt>null</tt> indication anonymous
* credentials were used (e.g. some IPC$ services).
*/
public Principal getPrincipal() {
return auth;
}
/**
* Returns the last component of the target URL. This will
* effectively be the name of the file or directory represented by this
* <code>SmbFile</code> 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 <code>smb://</code> is also <code>smb://</code>. If this
* <tt>SmbFile</tt> refers to a workgroup, server, share, or directory,
* the name will include a trailing slash '/' so that composing new
* <tt>SmbFile</tt>s will maintain the trailing slash requirement.
*
* @return The last component of the URL associated with this SMB
* resource or <code>smb://</code> if the resource is <code>smb://</code>
* itself.
*/
public String getName() {
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://";
}
}
/**
* Everything but the last component of the URL representing this SMB
* resource is effectivly it's parent. The root URL <code>smb://</code>
* does not have a parent. In this case <code>smb://</code> is returned.
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -