From 8d399869943414e56fcffff81fc352c6346c2358 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Mon, 11 Aug 2008 11:04:23 +0000 Subject: [PATCH] - Start of an implementation of a named pipe wrapper needed for hooking RosDbg up to vmware. - Due to p/invoke, this is a Win32 only implementation. Linux users will need to use mono with Wine. svn path=/trunk/tools/reactosdbg/; revision=780 --- Pipe/Pipe.csproj | 1 + Pipe/namedpipe.cs | 221 ++++++++++++++++++++++++++++++++++ RosDBG/MainWindow.Designer.cs | 52 ++++---- RosDBG/MainWindow.cs | 10 +- RosDBG/RosDBG.csproj | 12 +- 5 files changed, 268 insertions(+), 28 deletions(-) create mode 100644 Pipe/namedpipe.cs diff --git a/Pipe/Pipe.csproj b/Pipe/Pipe.csproj index c87dacd..6261223 100644 --- a/Pipe/Pipe.csproj +++ b/Pipe/Pipe.csproj @@ -45,6 +45,7 @@ + diff --git a/Pipe/namedpipe.cs b/Pipe/namedpipe.cs new file mode 100644 index 0000000..8a1cd78 --- /dev/null +++ b/Pipe/namedpipe.cs @@ -0,0 +1,221 @@ +using System; +using System.IO; +using System.ComponentModel; +using System.Runtime.InteropServices; + + +namespace AbstractPipe +{ + class Kernel32 + { + [DllImport("kernel32.dll", SetLastError = true)] + public static extern IntPtr CreateNamedPipe( + String lpName, + OpenMode dwOpenMode, + uint dwPipeMode, + uint nMaxInstances, + uint nOutBufferSize, + uint nInBufferSize, + DefaultTimeout nDefaultTimeOut, + IntPtr pipeSecurityDescriptor + ); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool ConnectNamedPipe( + IntPtr hHandle, + Overlapped lpOverlapped + ); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool ReadFile( + IntPtr hHandle, + byte[] lpBuffer, + uint nNumberOfBytesToRead, + ref uint lpNumberOfBytesRead, + IntPtr lpOverlapped + ); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool WriteFile( + IntPtr hHandle, + byte[] lpBuffer, + uint nNumberOfBytesToWrite, + ref uint lpNumberOfBytesWritten, + IntPtr lpOverlapped + ); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool CloseHandle( + IntPtr hHandle); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern uint GetLastError(); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool DisconnectNamedPipe( + IntPtr hHandle); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool FlushFileBuffers(IntPtr handle); + } + + [StructLayout(LayoutKind.Sequential)] + public class Overlapped + { + } + + public enum OpenMode : uint + { + PIPE_ACCESS_INBOUND = 0x00000001, + PIPE_ACCESS_OUTBOUND = 0x00000002, + PIPE_ACCESS_DUPLEX = 0x00000003, + FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000, + FILE_FLAG_OVERLAPPED = 0x40000000, + FILE_FLAG_WRITE_THROUGH = 0x80000000 + } + + public enum DefaultTimeout : uint + { + NMPWAIT_USE_DEFAULT_WAIT = 0x00000000, + NMPWAIT_NOWAIT = 0x00000001, + NMPWAIT_WAIT_FOREVER = 0xffffffff + } + + [StructLayout(LayoutKind.Sequential)] + public struct SECURITY_ATTRIBUTES + { + public int nLength; + public IntPtr lpSecurityDescriptor; + public int bInheritHandle; + } + + public class NamedPipe// : Pipe + { + private const string pipeName = @"\\.\Pipe\RosDbg"; + private const Int32 INVALID_HANDLE_VALUE = -1; + + IntPtr handle; + //FileAccess mode; + + protected NamedPipe() + { + handle = IntPtr.Zero; + } + + public IntPtr Create() + { + return Create(pipeName); + } + + public IntPtr Create(string name) + { + IntPtr handle; + + handle = Kernel32.CreateNamedPipe(name, + OpenMode.PIPE_ACCESS_DUPLEX | OpenMode.FILE_FLAG_OVERLAPPED, + 0, + 1, + 100, + 100, + DefaultTimeout.NMPWAIT_WAIT_FOREVER, + IntPtr.Zero); + if (handle.ToInt32() == INVALID_HANDLE_VALUE) + { + throw new Win32Exception("Error creating named pipe " + name + " . Internal error: " + Marshal.GetLastWin32Error().ToString()); + } + + return handle; + } + + public void Disconnect() + { + Kernel32.DisconnectNamedPipe(handle); + } + + public void Close() + { + Kernel32.CloseHandle(handle); + handle = IntPtr.Zero; + } + + public void Flush() + { + if (handle == IntPtr.Zero) + throw new ObjectDisposedException("NamedPipeStream", "The stream has already been closed"); + Kernel32.FlushFileBuffers(handle); + } + + public int Read(byte[] buffer, int offset, int count) + { + if (buffer == null) + throw new ArgumentNullException("buffer", "The buffer to read into cannot be null"); + if (buffer.Length < (offset + count)) + throw new ArgumentException("Buffer is not large enough to hold requested data", "buffer"); + if (offset < 0) + throw new ArgumentOutOfRangeException("offset", offset, "Offset cannot be negative"); + if (count < 0) + throw new ArgumentOutOfRangeException("count", count, "Count cannot be negative"); + if (handle == IntPtr.Zero) + throw new ObjectDisposedException("NamedPipeStream", "The stream has already been closed"); + + // first read the data into an internal buffer since ReadFile cannot read into a buf at + // a specified offset + uint read = 0; + + byte[] buf = buffer; + if (offset != 0) + { + buf = new byte[count]; + } + bool f = Kernel32.ReadFile(handle, buf, (uint)count, ref read, IntPtr.Zero); + if (!f) + { + throw new Win32Exception(Marshal.GetLastWin32Error(), "ReadFile failed"); + } + if (offset != 0) + { + for (int x = 0; x < read; x++) + { + buffer[offset + x] = buf[x]; + } + + } + return (int)read; + } + + public void Write(byte[] buffer, int offset, int count) + { + if (buffer == null) + throw new ArgumentNullException("buffer", "The buffer to write into cannot be null"); + if (buffer.Length < (offset + count)) + throw new ArgumentException("Buffer does not contain amount of requested data", "buffer"); + if (offset < 0) + throw new ArgumentOutOfRangeException("offset", offset, "Offset cannot be negative"); + if (count < 0) + throw new ArgumentOutOfRangeException("count", count, "Count cannot be negative"); + if (handle == IntPtr.Zero) + throw new ObjectDisposedException("NamedPipeStream", "The stream has already been closed"); + + // copy data to internal buffer to allow writing from a specified offset + if (offset != 0) + { + byte[] buf = new Byte[count]; + for (int x = 0; x < count; x++) + { + buf[x] = buffer[offset + x]; + } + buffer = buf; + } + uint written = 0; + bool result = Kernel32.WriteFile(handle, buffer, (uint)count, ref written, IntPtr.Zero); + + if (!result) + { + int err = (int)Marshal.GetLastWin32Error(); + throw new Win32Exception(err, "Writing to the stream failed"); + } + if (written < count) + throw new IOException("Unable to write entire buffer to stream"); + } + } +} diff --git a/RosDBG/MainWindow.Designer.cs b/RosDBG/MainWindow.Designer.cs index 98a6717..3860cf3 100644 --- a/RosDBG/MainWindow.Designer.cs +++ b/RosDBG/MainWindow.Designer.cs @@ -57,15 +57,15 @@ this.NewWindowItem = new System.Windows.Forms.ToolStripMenuItem(); this.detachCurrentTabToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.closeCurrentTabToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); + this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.infoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.splitContainer2 = new System.Windows.Forms.SplitContainer(); this.WorkTabs = new System.Windows.Forms.TabControl(); this.statusStrip1 = new System.Windows.Forms.StatusStrip(); this.RunStatus = new System.Windows.Forms.ToolStripStatusLabel(); this.contextMenuTabStrip = new System.Windows.Forms.ContextMenuStrip(this.components); this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); - this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.infoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); this.splitContainer1.SuspendLayout(); @@ -148,10 +148,10 @@ // // connectPipeToolStripMenuItem // - this.connectPipeToolStripMenuItem.Enabled = false; this.connectPipeToolStripMenuItem.Name = "connectPipeToolStripMenuItem"; this.connectPipeToolStripMenuItem.Size = new System.Drawing.Size(175, 22); this.connectPipeToolStripMenuItem.Text = "Connect Pipe ..."; + this.connectPipeToolStripMenuItem.Click += new System.EventHandler(this.connectPipeToolStripMenuItem_Click); // // connectTCPIPToolStripMenuItem // @@ -308,6 +308,28 @@ this.closeCurrentTabToolStripMenuItem.Text = "Close Current Tab"; this.closeCurrentTabToolStripMenuItem.Click += new System.EventHandler(this.closeCurrentTabToolStripMenuItem_Click); // + // toolStripMenuItem2 + // + this.toolStripMenuItem2.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.helpToolStripMenuItem, + this.infoToolStripMenuItem}); + this.toolStripMenuItem2.Name = "toolStripMenuItem2"; + this.toolStripMenuItem2.Size = new System.Drawing.Size(24, 20); + this.toolStripMenuItem2.Text = "&?"; + // + // helpToolStripMenuItem + // + this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; + this.helpToolStripMenuItem.Size = new System.Drawing.Size(107, 22); + this.helpToolStripMenuItem.Text = "&Help"; + this.helpToolStripMenuItem.Click += new System.EventHandler(this.helpToolStripMenuItem_Click); + // + // infoToolStripMenuItem + // + this.infoToolStripMenuItem.Name = "infoToolStripMenuItem"; + this.infoToolStripMenuItem.Size = new System.Drawing.Size(107, 22); + this.infoToolStripMenuItem.Text = "&About"; + // // splitContainer2 // this.splitContainer2.Dock = System.Windows.Forms.DockStyle.Fill; @@ -367,28 +389,6 @@ this.closeToolStripMenuItem.Text = "&Close"; this.closeToolStripMenuItem.Click += new System.EventHandler(this.closeToolStripMenuItem_Click); // - // toolStripMenuItem2 - // - this.toolStripMenuItem2.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.helpToolStripMenuItem, - this.infoToolStripMenuItem}); - this.toolStripMenuItem2.Name = "toolStripMenuItem2"; - this.toolStripMenuItem2.Size = new System.Drawing.Size(24, 20); - this.toolStripMenuItem2.Text = "&?"; - // - // helpToolStripMenuItem - // - this.helpToolStripMenuItem.Name = "helpToolStripMenuItem"; - this.helpToolStripMenuItem.Size = new System.Drawing.Size(152, 22); - this.helpToolStripMenuItem.Text = "&Help"; - this.helpToolStripMenuItem.Click += new System.EventHandler(this.helpToolStripMenuItem_Click); - // - // infoToolStripMenuItem - // - this.infoToolStripMenuItem.Name = "infoToolStripMenuItem"; - this.infoToolStripMenuItem.Size = new System.Drawing.Size(152, 22); - this.infoToolStripMenuItem.Text = "&About"; - // // MainWindow // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); diff --git a/RosDBG/MainWindow.cs b/RosDBG/MainWindow.cs index 2ca80a1..cd62264 100644 --- a/RosDBG/MainWindow.cs +++ b/RosDBG/MainWindow.cs @@ -321,7 +321,15 @@ namespace RosDBG AddTab(Help); WorkTabs.SelectTab(WorkTabs.TabCount - 1); } - + + private void connectPipeToolStripMenuItem_Click(object sender, EventArgs e) + { + PipeTargetSelect targetSelect = new PipeTargetSelect(); + if (targetSelect.ShowDialog() == DialogResult.OK) + { + + } + } } public class InteractiveInputEventArgs : EventArgs diff --git a/RosDBG/RosDBG.csproj b/RosDBG/RosDBG.csproj index 2cf40f7..28979ca 100644 --- a/RosDBG/RosDBG.csproj +++ b/RosDBG/RosDBG.csproj @@ -115,6 +115,12 @@ Modules.cs + + Form + + + PipeTargetSelect.cs + @@ -145,6 +151,10 @@ Modules.cs Designer + + PipeTargetSelect.cs + Designer + ResXFileCodeGenerator Resources.Designer.cs @@ -282,4 +292,4 @@ copy $(SolutionDir)dbghelptest\dbghelp.dll $(TargetDir) - + \ No newline at end of file