是否可以使用 Inpout32.dll 寻址高端口?
Is it possible to address high Ports with Inpout32.dll?
我想寻址端口 0xE020(十六进制 -> 十进制 = 57.376),但它暂时超出了范围。现在,我需要这个来测试 PCI-E 扩展并行端口。
感谢这个问题的回答 () 我在 32 位环境中使用以下工作代码:
using System;
using System.Runtime.InteropServices;
namespace LPTx86
{
public class LPT
{
//inpout.dll
[DllImport("inpout32.dll")]
private static extern void Out32(short PortAddress, short Data);
[DllImport("inpout32.dll")]
private static extern char Inp32(short PortAddress);
private short _PortAddress;
public LPT(short PortAddress)
{
_PortAddress = PortAddress;
}
public void Write(short Data)
{
Out32(_PortAddress, Data);
}
public byte Read()
{
return (byte)Inp32(_PortAddress);
}
}
}
对于 64 位环境:
using System;
using System.Runtime.InteropServices;
namespace LPTx64
{
class LPT
{
[DllImport("inpoutx64.dll", EntryPoint = "Out32")]
private static extern void Out32_x64(short PortAddress, short Data);
[DllImport("inpoutx64.dll", EntryPoint = "Inp32")]
private static extern char Inp32_x64(short PortAddress);
private short _PortAddress;
public LPT64(short PortAddress)
{
_PortAddress = PortAddress;
}
public void Write(short Data)
{
Out32_x64(_PortAddress, Data);
}
public byte Read()
{
return (byte)Inp32_x64(_PortAddress);
}
}
}
(是的,我删除了所有安全和完整性检查,我的第二个名字是“Danger”;))
是否可能以及如何解决不适合短路的端口?
有可能:
我尝试将端口变量的类型从 short 更改为 int,我测试了它,它似乎可以工作:
编辑:重构代码以将 data/control/status 个端口组合成一个包
using System;
using System.Runtime.InteropServices;
namespace LPTtestdrive
{
class LPT_X
{
//inpout.dll
[DllImport("inpout32.dll")]
private static extern UInt32 IsInpOutDriverOpen();
[DllImport("inpout32.dll")]
private static extern void Out32(int PortAddress, short Data);
[DllImport("inpout32.dll")]
private static extern char Inp32(int PortAddress);
//inpoutx64.dll
[DllImport("inpoutx64.dll", EntryPoint = "IsInpOutDriverOpen")]
private static extern UInt32 IsInpOutDriverOpen_x64();
[DllImport("inpoutx64.dll", EntryPoint = "Out32")]
private static extern void Out32_x64(int PortAddress, short Data);
[DllImport("inpoutx64.dll", EntryPoint = "Inp32")]
private static extern char Inp32_x64(int PortAddress);
private bool _X64;
private int DataAddress;
private int StatusAddress;
private int ControlAddress;
public LPT_X(int PortAddress)
{
DataAddress = PortAddress;
StatusAddress = (int)(DataAddress + 1);
ControlAddress = (int)(DataAddress + 2);
//now the code tries to determine if it should use inpout32.dll or inpoutx64.dll
uint nResult = 0;
try
{
Console.WriteLine("trying 32 bits");
nResult = IsInpOutDriverOpen();
if (nResult != 0)
{
Console.WriteLine("using 32 bits");
return;
}
}
catch (BadImageFormatException)
{
Console.WriteLine("32 bits failed");
}
catch (DllNotFoundException)
{
throw new ArgumentException("Unable to find InpOut32.dll");
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
try
{
Console.WriteLine("trying 64 bits");
nResult = IsInpOutDriverOpen_x64();
if (nResult != 0)
{
Console.WriteLine("using 64 bits");
_X64 = true;
return;
}
}
catch (BadImageFormatException)
{
Console.WriteLine("64 bits failed");
}
catch (DllNotFoundException)
{
throw new ArgumentException("Unable to find InpOutx64.dll");
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
throw new ArgumentException("Unable to open either inpout32 and inpoutx64");
}
public void WriteData(short Data)
{
if (_X64)
{
Out32_x64(DataAddress, Data);
}
else
{
Out32(DataAddress, Data);
}
}
public void WriteControl(short Data)
{
if (_X64)
{
Out32_x64(ControlAddress, Data);
}
else
{
Out32(ControlAddress, Data);
}
}
public byte ReadData()
{
if (_X64)
{
return (byte)Inp32_x64(DataAddress);
}
else
{
return (byte)Inp32(DataAddress);
}
}
public byte ReadControl()
{
if (_X64)
{
return (byte)Inp32_x64(ControlAddress);
}
else
{
return (byte)Inp32(ControlAddress);
}
}
public byte ReadStatus()
{
if (_X64)
{
return (byte)Inp32_x64(StatusAddress);
}
else
{
return (byte)Inp32(StatusAddress);
}
}
}
}
这样使用:
LPT_X LPT;
int read;
int Adress = 0xE020;
try
{
LPT = new LPT_X(Address);
LPT.WriteData(251);
LPT.WriteControl(0);
read = LPT.ReadStatus();
...
}
我的header看起来像这样
void _stdcall Out32(short PortAddress, short data);
short _stdcall Inp32(short PortAddress);
接受的答案有效,但我认为使用更长地址的更惯用的方法是保持签名一致并在 unchecked
上下文
中转换为 short
[DllImport("inpout32.dll")]
private static extern void Out32(short PortAddress, short data);
[DllImport("inpout32.dll")]
private static extern short Inp32(short PortAddress);
public void Write(int address, short data) {
short portAddress;
unchecked {
portAddress = (short)address;
}
Out32(portAddress, data);
}
public short Read(int address) {
short portAddress;
unchecked {
portAddress = (short)address;
}
return Inp32(portAddress);
}
我想寻址端口 0xE020(十六进制 -> 十进制 = 57.376),但它暂时超出了范围。现在,我需要这个来测试 PCI-E 扩展并行端口。
感谢这个问题的回答 () 我在 32 位环境中使用以下工作代码:
using System;
using System.Runtime.InteropServices;
namespace LPTx86
{
public class LPT
{
//inpout.dll
[DllImport("inpout32.dll")]
private static extern void Out32(short PortAddress, short Data);
[DllImport("inpout32.dll")]
private static extern char Inp32(short PortAddress);
private short _PortAddress;
public LPT(short PortAddress)
{
_PortAddress = PortAddress;
}
public void Write(short Data)
{
Out32(_PortAddress, Data);
}
public byte Read()
{
return (byte)Inp32(_PortAddress);
}
}
}
对于 64 位环境:
using System;
using System.Runtime.InteropServices;
namespace LPTx64
{
class LPT
{
[DllImport("inpoutx64.dll", EntryPoint = "Out32")]
private static extern void Out32_x64(short PortAddress, short Data);
[DllImport("inpoutx64.dll", EntryPoint = "Inp32")]
private static extern char Inp32_x64(short PortAddress);
private short _PortAddress;
public LPT64(short PortAddress)
{
_PortAddress = PortAddress;
}
public void Write(short Data)
{
Out32_x64(_PortAddress, Data);
}
public byte Read()
{
return (byte)Inp32_x64(_PortAddress);
}
}
}
(是的,我删除了所有安全和完整性检查,我的第二个名字是“Danger”;))
是否可能以及如何解决不适合短路的端口?
有可能:
我尝试将端口变量的类型从 short 更改为 int,我测试了它,它似乎可以工作:
编辑:重构代码以将 data/control/status 个端口组合成一个包
using System;
using System.Runtime.InteropServices;
namespace LPTtestdrive
{
class LPT_X
{
//inpout.dll
[DllImport("inpout32.dll")]
private static extern UInt32 IsInpOutDriverOpen();
[DllImport("inpout32.dll")]
private static extern void Out32(int PortAddress, short Data);
[DllImport("inpout32.dll")]
private static extern char Inp32(int PortAddress);
//inpoutx64.dll
[DllImport("inpoutx64.dll", EntryPoint = "IsInpOutDriverOpen")]
private static extern UInt32 IsInpOutDriverOpen_x64();
[DllImport("inpoutx64.dll", EntryPoint = "Out32")]
private static extern void Out32_x64(int PortAddress, short Data);
[DllImport("inpoutx64.dll", EntryPoint = "Inp32")]
private static extern char Inp32_x64(int PortAddress);
private bool _X64;
private int DataAddress;
private int StatusAddress;
private int ControlAddress;
public LPT_X(int PortAddress)
{
DataAddress = PortAddress;
StatusAddress = (int)(DataAddress + 1);
ControlAddress = (int)(DataAddress + 2);
//now the code tries to determine if it should use inpout32.dll or inpoutx64.dll
uint nResult = 0;
try
{
Console.WriteLine("trying 32 bits");
nResult = IsInpOutDriverOpen();
if (nResult != 0)
{
Console.WriteLine("using 32 bits");
return;
}
}
catch (BadImageFormatException)
{
Console.WriteLine("32 bits failed");
}
catch (DllNotFoundException)
{
throw new ArgumentException("Unable to find InpOut32.dll");
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
try
{
Console.WriteLine("trying 64 bits");
nResult = IsInpOutDriverOpen_x64();
if (nResult != 0)
{
Console.WriteLine("using 64 bits");
_X64 = true;
return;
}
}
catch (BadImageFormatException)
{
Console.WriteLine("64 bits failed");
}
catch (DllNotFoundException)
{
throw new ArgumentException("Unable to find InpOutx64.dll");
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
}
throw new ArgumentException("Unable to open either inpout32 and inpoutx64");
}
public void WriteData(short Data)
{
if (_X64)
{
Out32_x64(DataAddress, Data);
}
else
{
Out32(DataAddress, Data);
}
}
public void WriteControl(short Data)
{
if (_X64)
{
Out32_x64(ControlAddress, Data);
}
else
{
Out32(ControlAddress, Data);
}
}
public byte ReadData()
{
if (_X64)
{
return (byte)Inp32_x64(DataAddress);
}
else
{
return (byte)Inp32(DataAddress);
}
}
public byte ReadControl()
{
if (_X64)
{
return (byte)Inp32_x64(ControlAddress);
}
else
{
return (byte)Inp32(ControlAddress);
}
}
public byte ReadStatus()
{
if (_X64)
{
return (byte)Inp32_x64(StatusAddress);
}
else
{
return (byte)Inp32(StatusAddress);
}
}
}
}
这样使用:
LPT_X LPT;
int read;
int Adress = 0xE020;
try
{
LPT = new LPT_X(Address);
LPT.WriteData(251);
LPT.WriteControl(0);
read = LPT.ReadStatus();
...
}
我的header看起来像这样
void _stdcall Out32(short PortAddress, short data);
short _stdcall Inp32(short PortAddress);
接受的答案有效,但我认为使用更长地址的更惯用的方法是保持签名一致并在 unchecked
上下文
short
[DllImport("inpout32.dll")]
private static extern void Out32(short PortAddress, short data);
[DllImport("inpout32.dll")]
private static extern short Inp32(short PortAddress);
public void Write(int address, short data) {
short portAddress;
unchecked {
portAddress = (short)address;
}
Out32(portAddress, data);
}
public short Read(int address) {
short portAddress;
unchecked {
portAddress = (short)address;
}
return Inp32(portAddress);
}