diff options
Diffstat (limited to 'Emby.Common.Implementations/IO/SharpCifs/Smb/SmbTree.cs')
| -rw-r--r-- | Emby.Common.Implementations/IO/SharpCifs/Smb/SmbTree.cs | 464 |
1 files changed, 237 insertions, 227 deletions
diff --git a/Emby.Common.Implementations/IO/SharpCifs/Smb/SmbTree.cs b/Emby.Common.Implementations/IO/SharpCifs/Smb/SmbTree.cs index 8dc068c4c..880a6682f 100644 --- a/Emby.Common.Implementations/IO/SharpCifs/Smb/SmbTree.cs +++ b/Emby.Common.Implementations/IO/SharpCifs/Smb/SmbTree.cs @@ -19,232 +19,242 @@ using SharpCifs.Util.Sharpen; namespace SharpCifs.Smb { - class SmbTree - { - private static int _treeConnCounter; - - internal int ConnectionState; - - internal int Tid; - - internal string Share; - - internal string Service = "?????"; - - internal string Service0; - - internal SmbSession Session; - - internal bool InDfs; - - internal bool InDomainDfs; - - internal int TreeNum; - - internal SmbTree(SmbSession session, string share, string service) - { - // used by SmbFile.isOpen - this.Session = session; - this.Share = share.ToUpper(); - if (service != null && service.StartsWith("??") == false) - { - this.Service = service; - } - Service0 = this.Service; - ConnectionState = 0; - } - - internal virtual bool Matches(string share, string service) - { - return Runtime.EqualsIgnoreCase(this.Share, share) && (service == null || - service.StartsWith("??") || Runtime.EqualsIgnoreCase(this.Service, service - )); - } - - public override bool Equals(object obj) - { - if (obj is SmbTree) - { - SmbTree tree = (SmbTree)obj; - return Matches(tree.Share, tree.Service); - } - return false; - } - - /// <exception cref="SharpCifs.Smb.SmbException"></exception> - internal virtual void Send(ServerMessageBlock request, ServerMessageBlock response - ) - { - lock (Session.Transport()) - { - if (response != null) - { - response.Received = false; - } - TreeConnect(request, response); - if (request == null || (response != null && response.Received)) - { - return; - } - if (Service.Equals("A:") == false) - { - switch (request.Command) - { - case ServerMessageBlock.SmbComOpenAndx: - case ServerMessageBlock.SmbComNtCreateAndx: - case ServerMessageBlock.SmbComReadAndx: - case ServerMessageBlock.SmbComWriteAndx: - case ServerMessageBlock.SmbComClose: - case ServerMessageBlock.SmbComTreeDisconnect: - { - break; - } - - case ServerMessageBlock.SmbComTransaction: - case ServerMessageBlock.SmbComTransaction2: - { - switch (((SmbComTransaction)request).SubCommand & unchecked(0xFF)) - { - case SmbComTransaction.NetShareEnum: - case SmbComTransaction.NetServerEnum2: - case SmbComTransaction.NetServerEnum3: - case SmbComTransaction.TransPeekNamedPipe: - case SmbComTransaction.TransWaitNamedPipe: - case SmbComTransaction.TransCallNamedPipe: - case SmbComTransaction.TransTransactNamedPipe: - case SmbComTransaction.Trans2GetDfsReferral: - { - break; - } - - default: - { - throw new SmbException("Invalid operation for " + Service + " service"); - } - } - break; - } - - default: - { - throw new SmbException("Invalid operation for " + Service + " service" + request); - } - } - } - request.Tid = Tid; - if (InDfs && !Service.Equals("IPC") && !string.IsNullOrEmpty(request.Path)) - { + class SmbTree + { + private static int _treeConnCounter; + + internal int ConnectionState; + + internal int Tid; + + internal string Share; + + internal string Service = "?????"; + + internal string Service0; + + internal SmbSession Session; + + internal bool InDfs; + + internal bool InDomainDfs; + + internal int TreeNum; + + internal SmbTree(SmbSession session, string share, string service) + { + // used by SmbFile.isOpen + this.Session = session; + this.Share = share.ToUpper(); + if (service != null && service.StartsWith("??") == false) + { + this.Service = service; + } + Service0 = this.Service; + ConnectionState = 0; + } + + internal virtual bool Matches(string share, string service) + { + return Runtime.EqualsIgnoreCase(this.Share, share) + && (service == null + || service.StartsWith("??") + || Runtime.EqualsIgnoreCase(this.Service, service)); + } + + public override bool Equals(object obj) + { + if (obj is SmbTree) + { + SmbTree tree = (SmbTree)obj; + return Matches(tree.Share, tree.Service); + } + return false; + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void Send(ServerMessageBlock request, ServerMessageBlock response) + { + lock (Session.Transport()) + { + if (response != null) + { + response.Received = false; + } + TreeConnect(request, response); + if (request == null || (response != null && response.Received)) + { + return; + } + if (Service.Equals("A:") == false) + { + switch (request.Command) + { + case ServerMessageBlock.SmbComOpenAndx: + case ServerMessageBlock.SmbComNtCreateAndx: + case ServerMessageBlock.SmbComReadAndx: + case ServerMessageBlock.SmbComWriteAndx: + case ServerMessageBlock.SmbComClose: + case ServerMessageBlock.SmbComTreeDisconnect: + { + break; + } + + case ServerMessageBlock.SmbComTransaction: + case ServerMessageBlock.SmbComTransaction2: + { + switch (((SmbComTransaction)request).SubCommand + & unchecked(0xFF)) + { + case SmbComTransaction.NetShareEnum: + case SmbComTransaction.NetServerEnum2: + case SmbComTransaction.NetServerEnum3: + case SmbComTransaction.TransPeekNamedPipe: + case SmbComTransaction.TransWaitNamedPipe: + case SmbComTransaction.TransCallNamedPipe: + case SmbComTransaction.TransTransactNamedPipe: + case SmbComTransaction.Trans2GetDfsReferral: + { + break; + } + + default: + { + throw new SmbException( + "Invalid operation for " + Service + " service"); + } + } + break; + } + + default: + { + throw new SmbException( + "Invalid operation for " + Service + " service" + request); + } + } + } + request.Tid = Tid; + if (InDfs + && !Service.Equals("IPC") + && !string.IsNullOrEmpty(request.Path)) + { request.Flags2 = SmbConstants.Flags2ResolvePathsInDfs; - request.Path = '\\' + Session.Transport().TconHostName + '\\' + Share + request.Path; - } - try - { - Session.Send(request, response); - } - catch (SmbException se) - { - if (se.GetNtStatus() == NtStatus.NtStatusNetworkNameDeleted) - { - TreeDisconnect(true); - } - throw; - } - } - } - - /// <exception cref="SharpCifs.Smb.SmbException"></exception> - internal virtual void TreeConnect(ServerMessageBlock andx, ServerMessageBlock andxResponse - ) - { - lock (Session.Transport()) - { - string unc; - while (ConnectionState != 0) - { - if (ConnectionState == 2 || ConnectionState == 3) - { - // connected or disconnecting - return; - } - try - { - Runtime.Wait(Session.transport); - } - catch (Exception ie) - { - throw new SmbException(ie.Message, ie); - } - } - ConnectionState = 1; - // trying ... - try - { - Session.transport.Connect(); - unc = "\\\\" + Session.transport.TconHostName + '\\' + Share; - Service = Service0; - if (Session.transport.Log.Level >= 4) - { - Session.transport.Log.WriteLine("treeConnect: unc=" + unc + ",service=" + Service - ); - } - SmbComTreeConnectAndXResponse response = new SmbComTreeConnectAndXResponse(andxResponse - ); - SmbComTreeConnectAndX request = new SmbComTreeConnectAndX(Session, unc, Service, - andx); - Session.Send(request, response); - Tid = response.Tid; - Service = response.Service; - InDfs = response.ShareIsInDfs; - TreeNum = _treeConnCounter++; - ConnectionState = 2; - } - catch (SmbException se) - { - // connected - TreeDisconnect(true); - ConnectionState = 0; - throw; - } - } - } - - internal virtual void TreeDisconnect(bool inError) - { - lock (Session.Transport()) - { - if (ConnectionState != 2) - { - // not-connected - return; - } - ConnectionState = 3; - // disconnecting - if (!inError && Tid != 0) - { - try - { - Send(new SmbComTreeDisconnect(), null); - } - catch (SmbException se) - { - if (Session.transport.Log.Level > 1) - { - Runtime.PrintStackTrace(se, Session.transport.Log); - } - } - } - InDfs = false; - InDomainDfs = false; - ConnectionState = 0; - Runtime.NotifyAll(Session.transport); - } - } - - public override string ToString() - { - return "SmbTree[share=" + Share + ",service=" + Service + ",tid=" + Tid + ",inDfs=" - + InDfs + ",inDomainDfs=" + InDomainDfs + ",connectionState=" + ConnectionState - + "]"; - } - } + request.Path = '\\' + Session.Transport().TconHostName + + '\\' + Share + request.Path; + } + try + { + Session.Send(request, response); + } + catch (SmbException se) + { + if (se.GetNtStatus() == NtStatus.NtStatusNetworkNameDeleted) + { + TreeDisconnect(true); + } + throw; + } + } + } + + /// <exception cref="SharpCifs.Smb.SmbException"></exception> + internal virtual void TreeConnect(ServerMessageBlock andx, + ServerMessageBlock andxResponse) + { + lock (Session.Transport()) + { + string unc; + while (ConnectionState != 0) + { + if (ConnectionState == 2 || ConnectionState == 3) + { + // connected or disconnecting + return; + } + try + { + Runtime.Wait(Session.transport); + } + catch (Exception ie) + { + throw new SmbException(ie.Message, ie); + } + } + ConnectionState = 1; + // trying ... + try + { + Session.transport.Connect(); + unc = "\\\\" + Session.transport.TconHostName + '\\' + Share; + Service = Service0; + if (Session.transport.Log.Level >= 4) + { + Session.transport.Log.WriteLine( + "treeConnect: unc=" + unc + + ",service=" + Service); + } + SmbComTreeConnectAndXResponse response + = new SmbComTreeConnectAndXResponse(andxResponse); + SmbComTreeConnectAndX request + = new SmbComTreeConnectAndX(Session, unc, Service, andx); + Session.Send(request, response); + Tid = response.Tid; + Service = response.Service; + InDfs = response.ShareIsInDfs; + TreeNum = _treeConnCounter++; + ConnectionState = 2; + } + catch (SmbException se) + { + // connected + TreeDisconnect(true); + ConnectionState = 0; + throw; + } + } + } + + internal virtual void TreeDisconnect(bool inError) + { + lock (Session.Transport()) + { + if (ConnectionState != 2) + { + // not-connected + return; + } + ConnectionState = 3; + // disconnecting + if (!inError && Tid != 0) + { + try + { + Send(new SmbComTreeDisconnect(), null); + } + catch (SmbException se) + { + if (Session.transport.Log.Level > 1) + { + Runtime.PrintStackTrace(se, Session.transport.Log); + } + } + } + InDfs = false; + InDomainDfs = false; + ConnectionState = 0; + Runtime.NotifyAll(Session.transport); + } + } + + public override string ToString() + { + return "SmbTree[share=" + Share + + ",service=" + Service + + ",tid=" + Tid + + ",inDfs=" + InDfs + + ",inDomainDfs=" + InDomainDfs + + ",connectionState=" + ConnectionState + "]"; + } + } } |
