| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 | // 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.IO;using SharpCifs.Util.Sharpen;namespace SharpCifs.Smb{	/// <summary>This <code>OutputStream</code> can write bytes to a file on an SMB file server.	/// 	</summary>	/// <remarks>This <code>OutputStream</code> can write bytes to a file on an SMB file server.	/// 	</remarks>	public class SmbFileOutputStream : OutputStream	{		private SmbFile _file;		private bool _append;		private bool _useNtSmbs;		private int _openFlags;		private int _access;		private int _writeSize;		private long _fp;		private byte[] _tmp = new byte[1];		private SmbComWriteAndX _reqx;		private SmbComWriteAndXResponse _rspx;		private SmbComWrite _req;		private SmbComWriteResponse _rsp;		/// <summary>		/// Creates an		/// <see cref="System.IO.OutputStream">System.IO.OutputStream</see>		/// for writing to a file		/// on an SMB server addressed by the URL parameter. See		/// <see cref="SmbFile">SmbFile</see>		/// for a detailed description and examples of		/// the smb URL syntax.		/// </summary>		/// <param name="url">An smb URL string representing the file to write to</param>		/// <exception cref="SharpCifs.Smb.SmbException"></exception>		/// <exception cref="System.UriFormatException"></exception>		/// <exception cref="UnknownHostException"></exception>		public SmbFileOutputStream(string url) : this(url, false)		{		}		/// <summary>		/// Creates an		/// <see cref="System.IO.OutputStream">System.IO.OutputStream</see>		/// for writing bytes to a file on		/// an SMB server represented by the		/// <see cref="SmbFile">SmbFile</see>		/// parameter. See		/// <see cref="SmbFile">SmbFile</see>		/// for a detailed description and examples of		/// the smb URL syntax.		/// </summary>		/// <param name="file">An <code>SmbFile</code> specifying the file to write to</param>		/// <exception cref="SharpCifs.Smb.SmbException"></exception>		/// <exception cref="System.UriFormatException"></exception>		/// <exception cref="UnknownHostException"></exception>		public SmbFileOutputStream(SmbFile file) : this(file, false)		{		}		/// <summary>		/// Creates an		/// <see cref="System.IO.OutputStream">System.IO.OutputStream</see>		/// for writing bytes to a file on an		/// SMB server addressed by the URL parameter. See		/// <see cref="SmbFile">SmbFile</see>		/// for a detailed description and examples of the smb URL syntax. If the		/// second argument is <code>true</code>, then bytes will be written to the		/// end of the file rather than the beginning.		/// </summary>		/// <param name="url">An smb URL string representing the file to write to</param>		/// <param name="append">Append to the end of file</param>		/// <exception cref="SharpCifs.Smb.SmbException"></exception>		/// <exception cref="System.UriFormatException"></exception>		/// <exception cref="UnknownHostException"></exception>		public SmbFileOutputStream(string url, bool append) : this(new SmbFile(url), append			)		{		}		/// <summary>		/// Creates an		/// <see cref="System.IO.OutputStream">System.IO.OutputStream</see>		/// for writing bytes to a file		/// on an SMB server addressed by the <code>SmbFile</code> parameter. See		/// <see cref="SmbFile">SmbFile</see>		/// for a detailed description and examples of		/// the smb URL syntax. If the second argument is <code>true</code>, then		/// bytes will be written to the end of the file rather than the beginning.		/// </summary>		/// <param name="file">An <code>SmbFile</code> representing the file to write to</param>		/// <param name="append">Append to the end of file</param>		/// <exception cref="SharpCifs.Smb.SmbException"></exception>		/// <exception cref="System.UriFormatException"></exception>		/// <exception cref="UnknownHostException"></exception>		public SmbFileOutputStream(SmbFile file, bool append) : this(file, append, append			 ? SmbFile.OCreat | SmbFile.OWronly | SmbFile.OAppend : SmbFile.OCreat | SmbFile			.OWronly | SmbFile.OTrunc)		{		}		/// <summary>		/// Creates an		/// <see cref="System.IO.OutputStream">System.IO.OutputStream</see>		/// for writing bytes to a file		/// on an SMB server addressed by the <code>SmbFile</code> parameter. See		/// <see cref="SmbFile">SmbFile</see>		/// for a detailed description and examples of		/// the smb URL syntax.		/// <p>		/// The second parameter specifies how the file should be shared. If		/// <code>SmbFile.FILE_NO_SHARE</code> is specified the client will		/// have exclusive access to the file. An additional open command		/// from jCIFS or another application will fail with the "file is being		/// accessed by another process" error. The <code>FILE_SHARE_READ</code>,		/// <code>FILE_SHARE_WRITE</code>, and <code>FILE_SHARE_DELETE</code> may be		/// combined with the bitwise OR '|' to specify that other peocesses may read,		/// write, and/or delete the file while the jCIFS user has the file open.		/// </summary>		/// <param name="url">An smb URL representing the file to write to</param>		/// <param name="shareAccess">File sharing flag: <code>SmbFile.FILE_NOSHARE</code> or any combination of <code>SmbFile.FILE_READ</code>, <code>SmbFile.FILE_WRITE</code>, and <code>SmbFile.FILE_DELETE</code>		/// 	</param>		/// <exception cref="Jcifs.Smb.SmbException"></exception>		/// <exception cref="System.UriFormatException"></exception>		/// <exception cref="UnknownHostException"></exception>		public SmbFileOutputStream(string url, int shareAccess) : this(new SmbFile(url, string.Empty			, null, shareAccess), false)		{		}		/// <exception cref="SharpCifs.Smb.SmbException"></exception>		/// <exception cref="System.UriFormatException"></exception>		/// <exception cref="UnknownHostException"></exception>		internal SmbFileOutputStream(SmbFile file, bool append, int openFlags)		{			this._file = file;			this._append = append;			this._openFlags = openFlags;			_access = ((int)(((uint)openFlags) >> 16)) & 0xFFFF;			if (append)			{				try				{					_fp = file.Length();				}				catch (SmbAuthException sae)				{					throw;				}				catch (SmbException)				{					_fp = 0L;				}			}			if (file is SmbNamedPipe && file.Unc.StartsWith("\\pipe\\"))			{				file.Unc = Runtime.Substring(file.Unc, 5);				file.Send(new TransWaitNamedPipe("\\pipe" + file.Unc), new TransWaitNamedPipeResponse					());			}			file.Open(openFlags, _access | SmbConstants.FileWriteData, SmbFile.AttrNormal, 				0);			this._openFlags &= ~(SmbFile.OCreat | SmbFile.OTrunc);			_writeSize = file.Tree.Session.transport.SndBufSize - 70;			_useNtSmbs = file.Tree.Session.transport.HasCapability(SmbConstants.CapNtSmbs				);			if (_useNtSmbs)			{				_reqx = new SmbComWriteAndX();				_rspx = new SmbComWriteAndXResponse();			}			else			{				_req = new SmbComWrite();				_rsp = new SmbComWriteResponse();			}		}		/// <summary>		/// Closes this output stream and releases any system resources associated		/// with it.		/// </summary>		/// <remarks>		/// Closes this output stream and releases any system resources associated		/// with it.		/// </remarks>		/// <exception cref="System.IO.IOException">if a network error occurs</exception>		public override void Close()		{			_file.Close();			_tmp = null;		}		/// <summary>Writes the specified byte to this file output stream.</summary>		/// <remarks>Writes the specified byte to this file output stream.</remarks>		/// <exception cref="System.IO.IOException">if a network error occurs</exception>		public override void Write(int b)		{			_tmp[0] = unchecked((byte)b);			Write(_tmp, 0, 1);		}		/// <summary>		/// Writes b.length bytes from the specified byte array to this		/// file output stream.		/// </summary>		/// <remarks>		/// Writes b.length bytes from the specified byte array to this		/// file output stream.		/// </remarks>		/// <exception cref="System.IO.IOException">if a network error occurs</exception>		public override void Write(byte[] b)		{			Write(b, 0, b.Length);		}		public virtual bool IsOpen()		{			return _file.IsOpen();		}		/// <exception cref="System.IO.IOException"></exception>		internal virtual void EnsureOpen()		{			// ensure file is open			if (_file.IsOpen() == false)			{				_file.Open(_openFlags, _access | SmbConstants.FileWriteData, SmbFile.AttrNormal, 					0);				if (_append)				{					_fp = _file.Length();				}			}		}		/// <summary>		/// Writes len bytes from the specified byte array starting at		/// offset off to this file output stream.		/// </summary>		/// <remarks>		/// Writes len bytes from the specified byte array starting at		/// offset off to this file output stream.		/// </remarks>		/// <param name="b">The array</param>		/// <exception cref="System.IO.IOException">if a network error occurs</exception>		public override void Write(byte[] b, int off, int len)		{			if (_file.IsOpen() == false && _file is SmbNamedPipe)			{				_file.Send(new TransWaitNamedPipe("\\pipe" + _file.Unc), new TransWaitNamedPipeResponse					());			}			WriteDirect(b, off, len, 0);		}		/// <summary>Just bypasses TransWaitNamedPipe - used by DCERPC bind.</summary>		/// <remarks>Just bypasses TransWaitNamedPipe - used by DCERPC bind.</remarks>		/// <exception cref="System.IO.IOException"></exception>		public virtual void WriteDirect(byte[] b, int off, int len, int flags)		{			if (len <= 0)			{				return;			}			if (_tmp == null)			{				throw new IOException("Bad file descriptor");			}			EnsureOpen();			/*if (file.log.level >= 4)			{				file.log.WriteLine("write: fid=" + file.fid + ",off=" + off + ",len=" + len);			}*/			int w;			do			{				w = len > _writeSize ? _writeSize : len;				if (_useNtSmbs)				{					_reqx.SetParam(_file.Fid, _fp, len - w, b, off, w);					if ((flags & 1) != 0)					{						_reqx.SetParam(_file.Fid, _fp, len, b, off, w);						_reqx.WriteMode = 0x8;					}					else					{						_reqx.WriteMode = 0;					}					_file.Send(_reqx, _rspx);					_fp += _rspx.Count;					len -= (int)_rspx.Count;					off += (int)_rspx.Count;				}				else				{					_req.SetParam(_file.Fid, _fp, len - w, b, off, w);					_fp += _rsp.Count;					len -= (int)_rsp.Count;					off += (int)_rsp.Count;					_file.Send(_req, _rsp);				}			}			while (len > 0);		}	}}
 |