// This code is derived from jcifs smb client library // Ported by J. Arturo // // 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 System.IO; using SharpCifs.Smb; using SharpCifs.Util; using SharpCifs.Util.Sharpen; namespace SharpCifs.Dcerpc { public class DcerpcPipeHandle : DcerpcHandle { internal SmbNamedPipe Pipe; internal SmbFileInputStream In; internal SmbFileOutputStream Out; internal bool IsStart = true; /// /// /// public DcerpcPipeHandle(string url, NtlmPasswordAuthentication auth) { Binding = ParseBinding(url); url = "smb://" + Binding.Server + "/IPC$/" + Runtime.Substring(Binding.Endpoint , 6); string @params = string.Empty; string server; string address; server = (string)Binding.GetOption("server"); if (server != null) { @params += "&server=" + server; } address = (string)Binding.GetOption("address"); if (server != null) { @params += "&address=" + address; } if (@params.Length > 0) { url += "?" + Runtime.Substring(@params, 1); } Pipe = new SmbNamedPipe(url, (unchecked(0x2019F) << 16) | SmbNamedPipe.PipeTypeRdwr | SmbNamedPipe.PipeTypeDceTransact, auth); } /// protected internal override void DoSendFragment(byte[] buf, int off, int length, bool isDirect) { if (Out != null && Out.IsOpen() == false) { throw new IOException("DCERPC pipe is no longer open"); } if (In == null) { In = (SmbFileInputStream)Pipe.GetNamedPipeInputStream(); } if (Out == null) { Out = (SmbFileOutputStream)Pipe.GetNamedPipeOutputStream(); } if (isDirect) { Out.WriteDirect(buf, off, length, 1); return; } Out.Write(buf, off, length); } /// protected internal override void DoReceiveFragment(byte[] buf, bool isDirect) { int off; int flags; int length; if (buf.Length < MaxRecv) { throw new ArgumentException("buffer too small"); } if (IsStart && !isDirect) { // start of new frag, do trans off = In.Read(buf, 0, 1024); } else { off = In.ReadDirect(buf, 0, buf.Length); } if (buf[0] != 5 && buf[1] != 0) { throw new IOException("Unexpected DCERPC PDU header"); } flags = buf[3] & unchecked(0xFF); // next read is start of new frag IsStart = (flags & DcerpcConstants.DcerpcLastFrag) == DcerpcConstants.DcerpcLastFrag; length = Encdec.Dec_uint16le(buf, 8); if (length > MaxRecv) { throw new IOException("Unexpected fragment length: " + length); } while (off < length) { off += In.ReadDirect(buf, off, length - off); } } /// public override void Close() { State = 0; if (Out != null) { Out.Close(); } } } }