- 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
This commit is contained in:
Ged Murphy 2008-08-11 11:04:23 +00:00
parent 18d233b7bb
commit 8d39986994
5 changed files with 268 additions and 28 deletions

View File

@ -45,6 +45,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="namedpipe.cs" />
<Compile Include="serialpipe.cs" />
<Compile Include="pipe.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />

221
Pipe/namedpipe.cs Normal file
View File

@ -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");
}
}
}

View File

@ -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);

View File

@ -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

View File

@ -115,6 +115,12 @@
<Compile Include="Modules.Designer.cs">
<DependentUpon>Modules.cs</DependentUpon>
</Compile>
<Compile Include="PipeTargetSelect.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="PipeTargetSelect.Designer.cs">
<DependentUpon>PipeTargetSelect.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="BackTrace.resx">
@ -145,6 +151,10 @@
<DependentUpon>Modules.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="PipeTargetSelect.resx">
<DependentUpon>PipeTargetSelect.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
@ -282,4 +292,4 @@
<PropertyGroup>
<PostBuildEvent>copy $(SolutionDir)dbghelptest\dbghelp.dll $(TargetDir)</PostBuildEvent>
</PropertyGroup>
</Project>
</Project>