mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-05-27 02:56:54 +01:00
update sharpcifs
This commit is contained in:
@@ -19,242 +19,232 @@ using SharpCifs.Util.Sharpen;
|
||||
|
||||
namespace SharpCifs.Smb
|
||||
{
|
||||
class SmbTree
|
||||
{
|
||||
private static int _treeConnCounter;
|
||||
class SmbTree
|
||||
{
|
||||
private static int _treeConnCounter;
|
||||
|
||||
internal int ConnectionState;
|
||||
internal int ConnectionState;
|
||||
|
||||
internal int Tid;
|
||||
internal int Tid;
|
||||
|
||||
internal string Share;
|
||||
internal string Share;
|
||||
|
||||
internal string Service = "?????";
|
||||
internal string Service = "?????";
|
||||
|
||||
internal string Service0;
|
||||
internal string Service0;
|
||||
|
||||
internal SmbSession Session;
|
||||
internal SmbSession Session;
|
||||
|
||||
internal bool InDfs;
|
||||
internal bool InDfs;
|
||||
|
||||
internal bool InDomainDfs;
|
||||
internal bool InDomainDfs;
|
||||
|
||||
internal int TreeNum;
|
||||
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 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));
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
/// <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;
|
||||
}
|
||||
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");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw new SmbException(
|
||||
"Invalid operation for " + Service + " service" + request);
|
||||
}
|
||||
}
|
||||
}
|
||||
request.Tid = Tid;
|
||||
if (InDfs
|
||||
&& !Service.Equals("IPC")
|
||||
&& !string.IsNullOrEmpty(request.Path))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <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);
|
||||
}
|
||||
}
|
||||
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 + "]";
|
||||
}
|
||||
}
|
||||
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