mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-12 21:32:08 +01:00
merge common implementations and server implementations
This commit is contained in:
250
Emby.Server.Implementations/IO/SharpCifs/Smb/SmbTree.cs
Normal file
250
Emby.Server.Implementations/IO/SharpCifs/Smb/SmbTree.cs
Normal file
@@ -0,0 +1,250 @@
|
||||
// This code is derived from jcifs smb client library <jcifs at samba dot org>
|
||||
// Ported by J. Arturo <webmaster at komodosoft dot net>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
using System;
|
||||
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))
|
||||
{
|
||||
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
|
||||
+ "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user