update sharpcifs

This commit is contained in:
Luke Pulverenti
2017-07-08 03:25:24 -04:00
parent a7187180bf
commit 71eb9f143f
220 changed files with 23703 additions and 25613 deletions

View File

@@ -21,277 +21,276 @@ using SharpCifs.Util.Transport;
namespace SharpCifs.Smb
{
/// <summary>This InputStream can read bytes from a file on an SMB file server.</summary>
/// <remarks>This InputStream can read bytes from a file on an SMB file server. Offsets are 64 bits.
/// </remarks>
public class SmbFileInputStream : InputStream
{
private long _fp;
/// <summary>This InputStream can read bytes from a file on an SMB file server.</summary>
/// <remarks>This InputStream can read bytes from a file on an SMB file server. Offsets are 64 bits.
/// </remarks>
public class SmbFileInputStream : InputStream
{
private long _fp;
private int _readSize;
private int _readSize;
private int _openFlags;
private int _openFlags;
private int _access;
private int _access;
private byte[] _tmp = new byte[1];
private byte[] _tmp = new byte[1];
internal SmbFile File;
internal SmbFile File;
/// <summary>
/// Creates an
/// <see cref="System.IO.InputStream">System.IO.InputStream</see>
/// for reading bytes from a file on
/// an SMB server addressed by the <code>url</code> 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 read from</param>
/// <exception cref="SharpCifs.Smb.SmbException"></exception>
/// <exception cref="System.UriFormatException"></exception>
/// <exception cref="UnknownHostException"></exception>
public SmbFileInputStream(string url) : this(new SmbFile(url))
{
}
/// <summary>
/// Creates an
/// <see cref="System.IO.InputStream">System.IO.InputStream</see>
/// for reading bytes from a file on
/// an SMB server addressed by the <code>url</code> 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 read from</param>
/// <exception cref="SharpCifs.Smb.SmbException"></exception>
/// <exception cref="System.UriFormatException"></exception>
/// <exception cref="UnknownHostException"></exception>
public SmbFileInputStream(string url) : this(new SmbFile(url))
{
}
/// <summary>
/// Creates an
/// <see cref="System.IO.InputStream">System.IO.InputStream</see>
/// for reading bytes from 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 read from</param>
/// <exception cref="SharpCifs.Smb.SmbException"></exception>
/// <exception cref="System.UriFormatException"></exception>
/// <exception cref="UnknownHostException"></exception>
public SmbFileInputStream(SmbFile file) : this(file, SmbFile.ORdonly)
{
}
/// <summary>
/// Creates an
/// <see cref="System.IO.InputStream">System.IO.InputStream</see>
/// for reading bytes from 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 read from</param>
/// <exception cref="SharpCifs.Smb.SmbException"></exception>
/// <exception cref="System.UriFormatException"></exception>
/// <exception cref="UnknownHostException"></exception>
public SmbFileInputStream(SmbFile file) : this(file, SmbFile.ORdonly)
{
}
/// <exception cref="SharpCifs.Smb.SmbException"></exception>
/// <exception cref="System.UriFormatException"></exception>
/// <exception cref="UnknownHostException"></exception>
internal SmbFileInputStream(SmbFile file, int openFlags)
{
this.File = file;
this._openFlags = openFlags & 0xFFFF;
_access = ((int)(((uint)openFlags) >> 16)) & 0xFFFF;
if (file.Type != SmbFile.TypeNamedPipe)
{
file.Open(openFlags, _access, SmbFile.AttrNormal, 0);
this._openFlags &= ~(SmbFile.OCreat | SmbFile.OTrunc);
}
else
{
file.Connect0();
}
_readSize = Math.Min(file.Tree.Session.transport.RcvBufSize - 70,
file.Tree.Session.transport.Server.MaxBufferSize - 70);
}
/// <exception cref="SharpCifs.Smb.SmbException"></exception>
/// <exception cref="System.UriFormatException"></exception>
/// <exception cref="UnknownHostException"></exception>
internal SmbFileInputStream(SmbFile file, int openFlags)
{
this.File = file;
this._openFlags = openFlags & 0xFFFF;
_access = ((int)(((uint)openFlags) >> 16)) & 0xFFFF;
if (file.Type != SmbFile.TypeNamedPipe)
{
file.Open(openFlags, _access, SmbFile.AttrNormal, 0);
this._openFlags &= ~(SmbFile.OCreat | SmbFile.OTrunc);
}
else
{
file.Connect0();
}
_readSize = Math.Min(file.Tree.Session.transport.RcvBufSize - 70, file.Tree.Session
.transport.Server.MaxBufferSize - 70);
}
protected internal virtual IOException SeToIoe(SmbException se)
{
IOException ioe = se;
Exception root = se.GetRootCause();
if (root is TransportException)
{
ioe = (TransportException)root;
root = ((TransportException)ioe).GetRootCause();
}
if (root is Exception)
{
ioe = new IOException(root.Message);
ioe.InitCause(root);
}
return ioe;
}
protected internal virtual IOException SeToIoe(SmbException se)
{
IOException ioe = se;
Exception root = se.GetRootCause();
if (root is TransportException)
{
ioe = (TransportException)root;
root = ((TransportException)ioe).GetRootCause();
}
if (root is Exception)
{
ioe = new IOException(root.Message);
ioe.InitCause(root);
}
return ioe;
}
/// <summary>Closes this input stream and releases any system resources associated with the stream.
/// </summary>
/// <remarks>Closes this input stream and releases any system resources associated with the stream.
/// </remarks>
/// <exception cref="System.IO.IOException">if a network error occurs</exception>
public override void Close()
{
try
{
File.Close();
_tmp = null;
}
catch (SmbException se)
{
throw SeToIoe(se);
}
}
/// <summary>Closes this input stream and releases any system resources associated with the stream.
/// </summary>
/// <remarks>Closes this input stream and releases any system resources associated with the stream.
/// </remarks>
/// <exception cref="System.IO.IOException">if a network error occurs</exception>
public override void Close()
{
try
{
File.Close();
_tmp = null;
}
catch (SmbException se)
{
throw SeToIoe(se);
}
}
/// <summary>Reads a byte of data from this input stream.</summary>
/// <remarks>Reads a byte of data from this input stream.</remarks>
/// <exception cref="System.IO.IOException">if a network error occurs</exception>
public override int Read()
{
// need oplocks to cache otherwise use BufferedInputStream
if (Read(_tmp, 0, 1) == -1)
{
return -1;
}
return _tmp[0] & unchecked(0xFF);
}
/// <summary>Reads a byte of data from this input stream.</summary>
/// <remarks>Reads a byte of data from this input stream.</remarks>
/// <exception cref="System.IO.IOException">if a network error occurs</exception>
public override int Read()
{
// need oplocks to cache otherwise use BufferedInputStream
if (Read(_tmp, 0, 1) == -1)
{
return -1;
}
return _tmp[0] & unchecked(0xFF);
}
/// <summary>Reads up to b.length bytes of data from this input stream into an array of bytes.
/// </summary>
/// <remarks>Reads up to b.length bytes of data from this input stream into an array of bytes.
/// </remarks>
/// <exception cref="System.IO.IOException">if a network error occurs</exception>
public override int Read(byte[] b)
{
return Read(b, 0, b.Length);
}
/// <summary>Reads up to b.length bytes of data from this input stream into an array of bytes.
/// </summary>
/// <remarks>Reads up to b.length bytes of data from this input stream into an array of bytes.
/// </remarks>
/// <exception cref="System.IO.IOException">if a network error occurs</exception>
public override int Read(byte[] b)
{
return Read(b, 0, b.Length);
}
/// <summary>Reads up to len bytes of data from this input stream into an array of bytes.
/// </summary>
/// <remarks>Reads up to len bytes of data from this input stream into an array of bytes.
/// </remarks>
/// <exception cref="System.IO.IOException">if a network error occurs</exception>
public override int Read(byte[] b, int off, int len)
{
return ReadDirect(b, off, len);
}
/// <summary>Reads up to len bytes of data from this input stream into an array of bytes.
/// </summary>
/// <remarks>Reads up to len bytes of data from this input stream into an array of bytes.
/// </remarks>
/// <exception cref="System.IO.IOException">if a network error occurs</exception>
public override int Read(byte[] b, int off, int len)
{
return ReadDirect(b, off, len);
}
/// <exception cref="System.IO.IOException"></exception>
public virtual int ReadDirect(byte[] b, int off, int len)
{
if (len <= 0)
{
return 0;
}
/// <exception cref="System.IO.IOException"></exception>
public virtual int ReadDirect(byte[] b, int off, int len)
{
if (len <= 0)
{
return 0;
}
long start = _fp;
if (_tmp == null)
{
throw new IOException("Bad file descriptor");
}
long start = _fp;
if (_tmp == null)
{
throw new IOException("Bad file descriptor");
}
// ensure file is open
File.Open(_openFlags, _access, SmbFile.AttrNormal, 0);
if (File.Log.Level >= 4)
{
File.Log.WriteLine("read: fid=" + File.Fid + ",off=" + off + ",len=" + len);
}
// ensure file is open
File.Open(_openFlags, _access, SmbFile.AttrNormal, 0);
if (File.Log.Level >= 4)
{
File.Log.WriteLine("read: fid=" + File.Fid + ",off=" + off + ",len=" + len);
}
SmbComReadAndXResponse response = new SmbComReadAndXResponse(b, off);
if (File.Type == SmbFile.TypeNamedPipe)
{
response.ResponseTimeout = 0;
}
SmbComReadAndXResponse response = new SmbComReadAndXResponse(b, off);
if (File.Type == SmbFile.TypeNamedPipe)
{
response.ResponseTimeout = 0;
}
int r;
int n;
do
{
r = len > _readSize
? _readSize
: len;
if (File.Log.Level >= 4)
{
File.Log.WriteLine("read: len=" + len + ",r=" + r + ",fp=" + _fp);
}
int r;
int n;
do
{
r = len > _readSize ? _readSize : len;
if (File.Log.Level >= 4)
{
File.Log.WriteLine("read: len=" + len + ",r=" + r + ",fp=" + _fp);
}
try
{
SmbComReadAndX request = new SmbComReadAndX(File.Fid, _fp, r, null);
if (File.Type == SmbFile.TypeNamedPipe)
{
request.MinCount = request.MaxCount = request.Remaining = 1024;
}
//ここで読み込んでいるらしい。
File.Send(request, response);
}
catch (SmbException se)
{
if (File.Type == SmbFile.TypeNamedPipe
&& se.GetNtStatus() == NtStatus.NtStatusPipeBroken)
{
return -1;
}
throw SeToIoe(se);
}
try
{
SmbComReadAndX request = new SmbComReadAndX(File.Fid, _fp, r, null);
if (File.Type == SmbFile.TypeNamedPipe)
{
request.MinCount = request.MaxCount = request.Remaining = 1024;
}
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>œǂݍ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ł<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
File.Send(request, response);
}
catch (SmbException se)
{
if (File.Type == SmbFile.TypeNamedPipe && se.GetNtStatus() == NtStatus.NtStatusPipeBroken)
{
return -1;
}
throw SeToIoe(se);
}
if ((n = response.DataLength) <= 0)
{
return (int)((_fp - start) > 0L ? _fp - start : -1);
}
if ((n = response.DataLength) <= 0)
{
return (int)((_fp - start) > 0L ? _fp - start : -1);
}
_fp += n;
len -= n;
response.Off += n;
}
while (len > 0 && n == r);
_fp += n;
len -= n;
response.Off += n;
}
while (len > 0 && n == r);
return (int)(_fp - start);
}
/// <summary>This stream class is unbuffered.</summary>
/// <remarks>
/// This stream class is unbuffered. Therefore this method will always
/// return 0 for streams connected to regular files. However, a
/// stream created from a Named Pipe this method will query the server using a
/// "peek named pipe" operation and return the number of available bytes
/// on the server.
/// </remarks>
/// <exception cref="System.IO.IOException"></exception>
public override int Available()
{
SmbNamedPipe pipe;
TransPeekNamedPipe req;
TransPeekNamedPipeResponse resp;
if (File.Type != SmbFile.TypeNamedPipe)
{
return 0;
}
try
{
pipe = (SmbNamedPipe)File;
File.Open(SmbFile.OExcl, pipe.PipeType & 0xFF0000, SmbFile.AttrNormal, 0);
req = new TransPeekNamedPipe(File.Unc, File.Fid);
resp = new TransPeekNamedPipeResponse(pipe);
pipe.Send(req, resp);
if (resp.status == TransPeekNamedPipeResponse.StatusDisconnected
|| resp.status == TransPeekNamedPipeResponse.StatusServerEndClosed)
{
File.Opened = false;
return 0;
}
return resp.Available;
}
catch (SmbException se)
{
throw SeToIoe(se);
}
}
return (int)(_fp - start);
}
/// <summary>Skip n bytes of data on this stream.</summary>
/// <remarks>
/// Skip n bytes of data on this stream. This operation will not result
/// in any IO with the server. Unlink <tt>InputStream</tt> value less than
/// the one provided will not be returned if it exceeds the end of the file
/// (if this is a problem let us know).
/// </remarks>
/// <exception cref="System.IO.IOException"></exception>
public override long Skip(long n)
{
if (n > 0)
{
_fp += n;
return n;
}
return 0;
}
/// <summary>This stream class is unbuffered.</summary>
/// <remarks>
/// This stream class is unbuffered. Therefore this method will always
/// return 0 for streams connected to regular files. However, a
/// stream created from a Named Pipe this method will query the server using a
/// "peek named pipe" operation and return the number of available bytes
/// on the server.
/// </remarks>
/// <exception cref="System.IO.IOException"></exception>
public override int Available()
{
SmbNamedPipe pipe;
TransPeekNamedPipe req;
TransPeekNamedPipeResponse resp;
if (File.Type != SmbFile.TypeNamedPipe)
{
return 0;
}
try
{
pipe = (SmbNamedPipe)File;
File.Open(SmbFile.OExcl, pipe.PipeType & 0xFF0000, SmbFile.AttrNormal
, 0);
req = new TransPeekNamedPipe(File.Unc, File.Fid);
resp = new TransPeekNamedPipeResponse(pipe);
pipe.Send(req, resp);
if (resp.status == TransPeekNamedPipeResponse.StatusDisconnected || resp.status
== TransPeekNamedPipeResponse.StatusServerEndClosed)
{
File.Opened = false;
return 0;
}
return resp.Available;
}
catch (SmbException se)
{
throw SeToIoe(se);
}
}
/// <summary>Skip n bytes of data on this stream.</summary>
/// <remarks>
/// Skip n bytes of data on this stream. This operation will not result
/// in any IO with the server. Unlink <tt>InputStream</tt> value less than
/// the one provided will not be returned if it exceeds the end of the file
/// (if this is a problem let us know).
/// </remarks>
/// <exception cref="System.IO.IOException"></exception>
public override long Skip(long n)
{
if (n > 0)
{
_fp += n;
return n;
}
return 0;
}
/// <summary>
@@ -301,20 +300,19 @@ namespace SharpCifs.Smb
/// Add by dobes
/// mod interface to WrappedSystemStream readable, for random access.
/// </remarks>
internal override long Position
{
get { return this._fp; }
set
{
var tmpPos = value;
var length = File.Length();
if (tmpPos < 0)
tmpPos = 0;
internal override long Position {
get { return this._fp; }
set
{
var tmpPos = value;
var length = File.Length();
if (tmpPos < 0)
tmpPos = 0;
else if (length < tmpPos)
tmpPos = length;
this._fp = tmpPos;
}
}
tmpPos = length;
this._fp = tmpPos;
}
}
/// <summary>
///
@@ -325,17 +323,17 @@ namespace SharpCifs.Smb
/// mod interface to WrappedSystemStream readable, for random access.
/// </remarks>
internal override bool CanSeek()
{
return (File.Length() >= 0);
}
{
return (File.Length() >= 0);
}
/// <summary>
/// Get file length
/// </summary>
public override long Length
{
get { return File.Length(); }
}
}
{
get { return File.Length(); }
}
}
}