C# | InpOut32 and InpOutx64 Implement

Windows DLL and Driver to give direct access to hardware ports

Kombayar
10 min readFeb 29, 2024

將使用 Visual Studio 的 WPF 應用程式模板,開發可以對硬體做 R/W 的測試小程式。

使用 DLL 如以下網址,裡面有附許多範例,也都寫得蠻清楚!

https://www.highrez.co.uk/Downloads/InpOut32/default.htm

開始實作小程式

  1. 建立 WPF 應用程式(.NET Framework) 空白專案如下

\MainWindow.xaml

<Window x:Class="WpfApp2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp2"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>

</Grid>
</Window>

\MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp2
{
/// <summary>
/// MainWindow.xaml 的互動邏輯
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}

2. Import DLL 套件

\MainWindow.xaml.cs

// inpout32.dll
[DllImport("inpout32.dll")]
private static extern UInt32 IsInpOutDriverOpen();
[DllImport("inpout32.dll")]
private static extern void Out32(short PortAddress, short Data);
[DllImport("inpout32.dll")]
private static extern char Inp32(short PortAddress);

[DllImport("inpout32.dll")]
private static extern void DlPortWritePortUshort(short PortAddress, ushort Data);
[DllImport("inpout32.dll")]
private static extern ushort DlPortReadPortUshort(short PortAddress);

[DllImport("inpout32.dll")]
private static extern void DlPortWritePortUlong(int PortAddress, uint Data);
[DllImport("inpout32.dll")]
private static extern uint DlPortReadPortUlong(int PortAddress);

[DllImport("inpoutx64.dll")]
private static extern bool GetPhysLong(ref int PortAddress, ref uint Data);
[DllImport("inpoutx64.dll")]
private static extern bool SetPhysLong(ref int PortAddress, ref uint Data);

// inpoutx64.dll
[DllImport("inpoutx64.dll", EntryPoint="IsInpOutDriverOpen")]
private static extern UInt32 IsInpOutDriverOpen_x64();
[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);

[DllImport("inpoutx64.dll", EntryPoint = "DlPortWritePortUshort")]
private static extern void DlPortWritePortUshort_x64(short PortAddress, ushort Data);
[DllImport("inpoutx64.dll", EntryPoint = "DlPortReadPortUshort")]
private static extern ushort DlPortReadPortUshort_x64(short PortAddress);

[DllImport("inpoutx64.dll", EntryPoint = "DlPortWritePortUlong")]
private static extern void DlPortWritePortUlong_x64(int PortAddress, uint Data);
[DllImport("inpoutx64.dll", EntryPoint = "DlPortReadPortUlong")]
private static extern uint DlPortReadPortUlong_x64(int PortAddress);

[DllImport("inpoutx64.dll", EntryPoint = "GetPhysLong")]
private static extern bool GetPhysLong_x64(ref int PortAddress, ref uint Data);
[DllImport("inpoutx64.dll", EntryPoint = "SetPhysLong")]
private static extern bool SetPhysLong_x64(ref int PortAddress, ref uint Data);

Reference:

3. 確認該使用 32 / x64 DLL。

public MainWindow()
{
InitializeComponent();
try
{
uint nResult = 0;
try
{
nResult = IsInpOutDriverOpen();
}
catch (BadImageFormatException)
{
nResult = IsInpOutDriverOpen_x64();
if (nResult != 0)
m_bX64 = true;
}
}
catch (DllNotFoundException ex)
{
MessageBox.Show("Unable to find InpOut32.dll or InpOutx64.dll\n", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}

4. 開始對硬體做 R/W,要做哪些動作就根據各自需求去 R/W。

private void AccessSIOGpio()
{
short EFIR = 0x2E;
short EFDR = 0x2F;
if (m_bX64)
{
Out32_x64(EFIR, 0x87);
Out32_x64(EFIR, 0x87);
//Set Multi-function of GP31-37 & GP46
Out32_x64(EFIR, 0x1A);
Out32_x64(EFDR, 0x00);
//Select logical device 7
//Enable group 3 & 4
Out32_x64(EFIR, 0x07);
Out32_x64(EFDR, 0x07);
Out32_x64(EFIR, 0x30);
Out32_x64(EFDR, 0x18);
//Set GP31 GP32 GP33 GP34 to input
//Set GP35 GP36 GP37 to output
Out32_x64(EFIR, 0xEC);
Out32_x64(EFDR, 0x1E);
}
else
{
Out32(EFIR, 0x87);
Out32(EFIR, 0x87);
//Set Multi-function of GP31-37 & GP46
Out32(EFIR, 0x1A);
Out32(EFDR, 0x00);
//Select logical device 7
//Enable group 3 & 4
Out32(EFIR, 0x07);
Out32(EFDR, 0x07);
Out32(EFIR, 0x30);
Out32(EFDR, 0x18);
//Set GP31 GP32 GP33 GP34 to input
//Set GP35 GP36 GP37 to output
Out32(EFIR, 0xEC);
Out32(EFDR, 0x1E);
}
}

5. 可以搭配 GUI 物件針對不痛硬體去做 R/W。

Finish! : )

通常會根據 spec 去讀寫相關 IO,此範例為對 6162D super IO 做讀寫,相關讀寫資訊也需要翻閱 spec 去做設定。

有相關建議與疑問都歡迎留言,謝謝!

--

--

Kombayar
Kombayar

Written by Kombayar

I’m a graduate student. Self-teaching coding on Internet, wanted to write some articles to make myself remember the code.

No responses yet