| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 | // 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  USAusing 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				 + "]";		}	}}
 |