Как найти адрес lpt порта

Добро пожаловать!

Как узнать адрес LPT

        LPT (параллельный порт) предназначен для связи компьютера с внешними (перефирийными) устройствами и имеет базовый адрес &H378 (LPT1), &H278 (LPT2), &H3BC (LPT3), что в десятичной системе соответствует адресам: 888 (LPT1), 632 (LPT2) и 956 (LPT3).

        Эти три адреса являются базовыми и при загрузке операционной системы происходит опрос именно этих трех адресов. По этим адресам посылается байт после чего происходит считывание этого байта. Если считанный байт равен записанному, то по данному адресу обнаруживается активный LPT-порт. На этом принципе и основан алгоритм программы

LPT Port Scaner, о которой пойдет речь ниже.

        Современные компьютеры всё реже стали оснащать LPT — портами, что уж говорить о ноутбуках, на которых они и вовсе исчезли, почем не заслуженно. Существует множество программаторов, работающих через LPT — порт. Что же делать пользователям этих устройств? Рынок наводнили разного рода адаптерами, работающими через интерфейс USB, PCMCIA (произносится пи-си-эм-си-ай-эй), ExpressCard (ранее NEWCARD) и др. и теперь нам есть из чего выбрать. Но даже сделав правильный выбор мы не всегда можем прийти к желаемому результату, как это было со мной. Купив PCMCIA to LPT карту я надеялся оснастить свой ноутбук полноценным LPT — портом, но тут меня ожидало разочарование: мои программы никак не могли найти порт, как и программы сторонних производителей. Оказалось, что адрес, выделяемый устройством не всегда находится в стандартном диапазоне. Это и стало причиной, сподвигшей меня к написанию программы

LPT Port Scaner.

Рисунок 1. USB to LPT

PCMCIA (произносится пи-си-эм-си-ай-эй)

Рисунок 2. PCMCIA to LPT
Expresscard

Рисунок 3. Expresscard to LPT

Рисунок 4. PCI to LPT

        Если Вы не можете обойтись без LPT — порта в силу сложившихся обстоятельств или еще чего-нибудь, то Вы можете преобрести одно из вышеуказанных устройств. Однако, при использовании таких адаптеров зачастую возникают проблемы с адресами портов, т. к., они бывают расположены не в стандартном для LPT — порта адресном пространстве, а в пространстве, присвоенном устройству во время обнаружения, что особенно касается Plug and Play устройств.

        Существует множество программ для программаторов, работающих через LPT и поддерживающих ручную настройку адресации. Такие программы не найдя LPT — потра по стандартному адресу обычно вместо адреса выводят надпись «Hex». Зная адрес порта можно ввести его вручную, если того позволяет ПО, с которым Вы работаете.

        Попробуем разобраться в этом на примере адаптера PCMCIA to LPT. После установки устройства и драйвера к ниму в диспетчере устройств появится устройство с именем LPT Port1 или что-то в роде того (На Рис. 5 PCI Parallel Port (LPT3)). Кликаем на Устройстве, после чего переходим на вкладку «Ресурсы» (Рис.6.), где отчетливо видим все доступные ресурсы этого устройства и диапазоны ввода/вывода. Адрес LPT — Порта будет находится в диапазоне ввода/вывода ресурса устройства, который отображается в шестьнадцатиричной системе счисления (0 1 2 3 4 5 6 7 8 9 A B C D E F) в столбце «Параметры».

        Теперь, для того, чтобы найти адрес LPT — Порта, Вам понадобится программа

LPT Port Scaner.Диспетчер устройств

Рисунок 5. Диспетчер устройств.

Ресурсы

Рисунок 6. Свойства LPT — Порта.

LPT Port Scaner

Рисунок 7. Интерфейс программы LPT Port Scaner

Рисунок 8. Распиновка LPT — Порта.

        Сразу должен предупредить, что программа LPT Port Scaner использует библиотеку inpout32.dll, которая находится в архиве с программой и всегда должна находиться в папке с ней, иначе возникнет ошибка. Так же, в архиве находится картинка с распиновкой LPT — порта.

        И так, как было сказано выше, адрес порта находится в диапазоне ввода/вывода ресурса устройства в столбце «Параметры». По-этому, после того, как вы скачали программу и запустили её (рисунок 7) имеет смысл узнать в каком диапазоне находится адрес порта на Вашем компьютере (как это сделать сказано выше.). Определив минимальное значение ресурса, вводим его в поле рядом с надписью «С адреса:» (на рисунке 6 минимальное значение = FDE0). Следом определяем максимальное значение (на рисунке 6 оно равно FDEF), вводим его в поле рядом с надписью «по адрес:» и нажимаем кнопку «Задать», после чего в полях справа должен определиться диапазон в десятичной (Dec) системе счисления. Ну а теперь можно нажать кнопочку «Scan» и в текстовом окне справа выведется результат опроса портов в заданном диапазоне.
В столбце «Dec» выводится адрес в десятичной системе счисления
В столбце «Hex» — в шестьнадцатиричной.
В столбце «Запись» выводится число, посылаемое в порт и оно зависит от параметров, выставленных в разделе «Вывод данных» (по умолчанию флажки установлены так, чтоб число, посылаемое в порт было равно 0).
В столбце «Чтение» выводится считанное из порта число. Если оно равно записанному, то, возможно, по данному адресу находится искомый LPT.

        А самым простым способом, по моему мнению, является поиск в столбце «Чтение» числа 120 (Рисунок 7). Это регистр состояния (status) и если не одна из цепей не заземлена (разьем отключен), то считываемое число будет именно 120. Строкой выше будет находиться регистр данных (Data) с цепями D0-D7, а строкой ниже — регистр управления (Control) с цепями C0-C3 (рисунок 8).
Таким образом мы получили адреса FDE8, FDE9 и FDEA, которые в нашем случае соответствуют стандартному LPT — Порту с адресами 378, 379 и 37A.

        Чтобы убедиться в том, что мы нашли именно нужный нам порт, можно вставить светодиод прямо в разъем порта анодом в любую цепь с D0 по D7 (c 2-го по 9-й пин см. рисунок 8), катодом в любую цепь с 18-го по 25-й пин (это общая земля), после чего необходимо выставить верхний диапазон равный нижнему (например: с адреса FDE8, по адрес FDE8), и поставить соответствующую галку в разделе «Вывод данных». После чего при каждом нажатии кнопки «Scan» цепи регистров будут включаться в соответствии с конфигурацией галок в разделе «Вывод данных».
Если вы захотите подключить светодиод к регистру управления Control (1-й, 14-й, 16-й и 17-й пин(C0-C3)), то учтите, что три из четырех цепей инвертированы. В программе учтена эта особенность, и по умолчанию на всех цепях регистров будет логический ноль.

Скачать с Deposit Files Скачать программу для сканирования LPT — Портов LPT Port Scaner v1.0.0


Лет 10-15 назад параллельный порт был довольно востребованным интерфейсом для связи между устройствами. Сегодня производители различных устройств отдают предпочтение последовательным интерфейсам. Тем не менее, и сегодня LPT порт всё ещё можно встретить. А некоторые разработчики ещё пишут под него программы (или поддерживают написанные во времена расцвета параллельных интерфейсов). Но в компьютерах сейчас LPT порт – достаточно большая редкость. Существуют, конечно, платы расширения для компьютера, которые реализуют интерфейс LPT. Они в основном представляют собой платы на шине PCI. К сожалению, далеко не весь софт, который был написан для интегрированных в материнскую плату LPT портов, будет работать с LPT-PCI-платами.

Предлагается решение этой проблемы: программный класс, написанный под .NET, и динамическую библиотеку, которая работает с LPT. Данная реализация проверена на 32- и 64-разрядных Windows XP, Windows 7, 8 и 10 как со встроенными LPT портами, так и реализованными в виде плат расширения на шине PCI или PCI-Express. Скачать драйвер для LPT порта можно по ссылке внизу после статьи.

1Установка драйвера для работы с LPT портом

В приложенном архиве находятся две папки – для 32-разрядной и для 64-разрядной версий Windows. В одной из папок лежит файл InstallDriver.exe. Сначала запустите этот файл, он установит динамические библиотеки в систему. После этого компьютер следует перезагрузить.

Чтобы использовать предлагаемый драйвер, файлы inpout32.dll и inpoutx64.dll должны располагаться в одной директории с исполняемым файлом вашей программы.

2Программный класс использования библиотек работы с LPT портом

Мной был написан класс для .NET, который использует динамические библиотеки inpout32.dll и inpoutx64.dll и позволяет считывать из параллельного порта и записывать в его регистры данные.

Упомянутые библиотеки написаны не мной. Я предлагаю удобный класс-оболочку, упрощающий работу с данными библиотеками. Кроме того, автор библиотек в файле readme.txt сообщает, что его драйвер не поддерживает PCI устройства. Мне удалось его запустить для работы как с интегрированным параллельным портом, так и LPT портом, реализованном в виде платы расширения на шине PCI-Express. Причём порт отлично работает и на современной Windows10 x64, и на более старых системах.

Вот код класса LPT на языке VB.NET:

Код класса LPT на языке VB.NET (разворачивается)

Imports System.Runtime.InteropServices

''' <summary>
''' Работа с LPT портом. При создании определяет наличие драйвера и выбирает подходящую библиотеку.
''' </summary>
Public NotInheritable Class LPT

#Region "CONST"

    Public Const DLL32 As String = "c:tempinpout32.dll"
    Public Const DLL64 As String = "c:tempinpoutx64.dll"
    Public Const DLL32DRV As String = "c:tempinpoutx32drv.dll"

    ''' <summary>
    ''' Регистры параллельного порта.
    ''' </summary>
    Public Enum Register As Integer
        ''' <summary>
        ''' Регистр данных SPP/EPP.
        ''' </summary>
        DATA = 0
        ''' <summary>
        ''' Регистр состояния SPP/EPP.
        ''' </summary>
        STATUS = DATA + 1
        ''' <summary>
        ''' Регистр управления SPP/EPP.
        ''' </summary>
        CONTROL = DATA + 2
        ''' <summary>
        ''' Регистр адреса EPP. Чтение или запись в него генерирует свзяанный цикл чтения или записи адреса EPP.
        ''' </summary>
        EPP_ADDRESS = DATA + 3
        ''' <summary>
        ''' Регистр данных EPP. Чтение (запись) генерирует связанный цикл чтения (записи) данных EPP.
        ''' </summary>
        EPP_DATA = DATA + 4
        ''' <summary>
        ''' Регистр активации режима EPP.
        ''' </summary>
        ''' <remarks>
        ''' Если только смешанный "ECP+EPP" или "Extended" - скорее всего потребуется еще выполнить запись в порт ECR байта 0x80 
        ''' (ECR - это регистр ECP-режима, ECR=BASE_ADDR+0x402, BASE_ADDR - базовый адрес LPT-порта
        ''' </remarks>
        ECR = DATA + &H402 
    End Enum

#End Region '/CONST

#Region "DllImport"

    <DllImport(DLL32, CharSet:=CharSet.Auto, EntryPoint:="IsInpOutDriverOpen")>
    Private Shared Function IsInpOutDriverOpen() As Byte
    End Function

    <DllImport(DLL64, CharSet:=CharSet.Auto, EntryPoint:="IsInpOutDriverOpen")>
    Private Shared Function IsInpOutDriverOpen_x64() As UInt64
    End Function

    <DllImport(DLL32, CharSet:=CharSet.Auto, EntryPoint:="Inp32")>
    Private Shared Function Inp32(PortAddress As UInt32) As Byte
    End Function

    <DllImport(DLL32, CharSet:=CharSet.Auto, EntryPoint:="Out32")>
    Private Shared Sub Out32(portAddress As UInt32, data As UInt32)
    End Sub

    <DllImport(DLL64, CharSet:=CharSet.Auto, EntryPoint:="Inp32")>
    Private Shared Function Inp64(PortAddress As UInt64) As Byte
    End Function

    <DllImport(DLL64, CharSet:=CharSet.Auto, EntryPoint:="Out32")>
    Private Shared Sub Out64(PortAddress As UInt64, Data As UInt64)
    End Sub

#End Region '/DllImport

#Region "CTOR"

    ''' <summary>
    ''' Проверяет возможность использования x86 или x64 драйвера. В случае невозможности выбрасывает исключение "драйвер не установлен".
    ''' </summary>
    Shared Sub New()
        Dim x86 As Boolean = CheckIsDriverX86()
        Dim x64 As Boolean = CheckIsDriverX64()
        If x64 Then
            _IsX64DriverUsed = True
        ElseIf x86 Then
            _IsX64DriverUsed = False
        Else
            Throw New SystemException("Драйвер для LPT порта не установлен.")
        End If
    End Sub

    ''' <summary>
    ''' Инициализация порта - выставление XXXX0100'b в регистре контроля.
    ''' </summary>
    Private Shared Sub InitLpt(port As ULong)
        Write(port, Register.ECR, &H80)
        Write(port, Register.CONTROL, &H4)
    End Sub

#End Region '/CTOR

#Region "PROPS"

    ''' <summary>
    ''' Используется ли 64-разрядная версия драйвера.
    ''' Если драйвер не установлен, возвращается NULL.
    ''' </summary>
    Public Shared ReadOnly Property IsX64DriverUsed As Boolean?
        Get
            Return _IsX64DriverUsed
        End Get
    End Property
    Private Shared ReadOnly _IsX64DriverUsed As Boolean? = Nothing

#End Region '/PROPS

#Region "METHODS"

    ''' <summary>
    ''' Определяет, является ли драйвер 32-разрядным.
    ''' </summary>
    Private Shared Function CheckIsDriverX86() As Boolean
        Try
            Dim res As Byte = IsInpOutDriverOpen()
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    ''' <summary>
    ''' Определяет, является ли драйвер 64-разрядным.
    ''' </summary>
    Private Shared Function CheckIsDriverX64() As Boolean
        Try
            Dim nResult As ULong = IsInpOutDriverOpen_x64()
            Return (nResult <> 0)
        Catch ex As Exception
            Return False
        End Try
    End Function

#End Region '/METHODS

#Region "Read / Write LPT Port"

    ''' <summary>
    ''' Читает из заданного регистра LPT порта 1 байт данных.
    ''' </summary>
    ''' <param name="port">Номер порта.</param>
    ''' <param name="reg">Регистр порта.</param>
    Public Shared Function Read(port As ULong, Optional reg As Register = Register.DATA) As Byte
        Dim data As Byte = 0
        If IsX64DriverUsed Then
            data = Inp64(CULng(port + reg))
        Else
            data = Inp32(CUInt(port + reg))
        End If
        Return data
    End Function

    ''' <summary>
    ''' Записывает в заданный регистр LPT порта число.
    ''' </summary>
    ''' <param name="port">Адрес порта.</param>
    ''' <param name="reg">Регистр порта.</param>
    ''' <param name="data">Число для записи. В 32-разрядных системах аргумент должен быть не более, чем максимальное значение для типа UInt32.</param>
    Public Shared Sub Write(port As ULong, reg As Register, data As ULong)
        If IsX64DriverUsed Then
            Out64(port + CULng(reg), data)
        Else
            If (data <= UInteger.MaxValue) Then
                Out32(CUInt(port + reg), CUInt(data))
            Else
                Throw New ArgumentException("В 32-разрядных системах аргумент должен быть 32-разрядным (тип UInt32).", "data")
            End If
        End If
    End Sub

#End Region '/Read / Write LPT Port

    ''' <summary>
    ''' Тестирует наличие LPT порта по заданному адресу.
    ''' </summary>
    ''' <param name="lptAddress">Адрес параллельного порта.</param>
    Public Shared Function CheckPortPresent(lptAddress As ULong) As Boolean
        Dim portPresent As Boolean = False
        Try
            InitLpt(lptAddress)
            Dim data As ULong = Read(lptAddress, Register.DATA) 'сохраняем текущее значение регистра данных

            'Проверим: что записали, то и прочитали?
            Write(lptAddress, Register.DATA, &H0)
            portPresent = portPresent And (&H0 = Read(lptAddress, Register.DATA))

            Write(lptAddress, Register.DATA, &H55)
            portPresent = portPresent And (&H55 = Read(lptAddress, Register.DATA))

            Write(lptAddress, Register.DATA, &HAA)
            portPresent = portPresent And (&HAA = Read(lptAddress, Register.DATA))

            Write(lptAddress, Register.DATA, data) 'восстанавливаем прежнее значение регистра данных

            'Проверим наличие регистров управления и данных, если порт не обнаружен (в случае однонаправленного порта)
            If (Not portPresent) Then
                data = Read(lptAddress, Register.CONTROL)
                portPresent = ((data <> 0) AndAlso (data <> &HFF)) 'Не пустое значение? => Порт присутствует.
                If (Not portPresent) Then
                    data = Read(lptAddress, Register.STATUS)
                    portPresent = ((data <> 0) AndAlso (data <> &HFF))
                End If
            End If
        Catch ex As Exception
            Return False
        End Try
        Return portPresent
    End Function

End Class '/LPT

Код класса LPT на языке C#:

Код класса LPT на языке C# (разворачивается)

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace LPTIO
{
  /// Класс для работы LPT портом. При создании определяет наличие драйвера и его разрядность.
public sealed class LPT
  {
    private const string DLL32 = "inpout32.dll";
    private const string DLL64 = "inpoutx64.dll";
    private static bool _IsX64DriverUsed;

    /// Используется ли 64-разрядная версия драйвера.
    public static bool IsX64DriverUsed
    {
      get
      {
        return LPT._IsX64DriverUsed;
      }
    }

    static LPT()
    {
      if (LPT.getIsDriverX86())
      {
        LPT._IsX64DriverUsed = false;
      }
      else
      {
        if (!LPT.getIsDriverX64())
          throw new SystemException("Драйвер для LPT порта не установлен.");
        LPT._IsX64DriverUsed = true;
      }
    }

    [DebuggerNonUserCode]
    public LPT()
    {
    }

    [DllImport("inpout32.dll", CharSet = CharSet.Auto)]
    private static extern byte IsInpOutDriverOpen();

    [DllImport("inpoutx64.dll", EntryPoint = "IsInpOutDriverOpen", CharSet = CharSet.Auto)]
    private static extern ulong IsInpOutDriverOpen_x64();

    [DllImport("inpout32.dll", CharSet = CharSet.Auto)]
    private static extern byte Inp32(uint PortAddress);

    [DllImport("inpout32.dll", CharSet = CharSet.Auto)]
    private static extern void Out32(uint portAddress, uint data);

    [DllImport("inpoutx64.dll", EntryPoint = "Inp32", CharSet = CharSet.Auto)]
    private static extern byte Inp64(ulong PortAddress);

    [DllImport("inpoutx64.dll", EntryPoint = "Out32", CharSet = CharSet.Auto)]
    private static extern void Out64(ulong PortAddress, ulong Data);

    /// Определяет, является ли драйвер для 32-разрядной версии Windows.
    private static bool getIsDriverX86()
    {
      bool flag;
      try
      {
        LPT.IsInpOutDriverOpen();
        flag = true;
      }
      catch (Exception ex)
      {
        ProjectData.SetProjectError(ex);
        flag = false;
        ProjectData.ClearProjectError();
      }
      return flag;
    }

    /// Определяет, является ли драйвер для 64-разрядной версии Windows.
    private static bool getIsDriverX64()
    {
      bool flag;
      try
      {
        flag = Decimal.Compare(new Decimal(LPT.IsInpOutDriverOpen_x64()), Decimal.Zero) != 0;
      }
      catch (Exception ex)
      {
        ProjectData.SetProjectError(ex);
        flag = false;
        ProjectData.ClearProjectError();
      }
      return flag;
    }

    /// <summary>Читает из LPT порта 1 байт данных.</summary>
    /// <param name="port">Номер порта.</param>
    /// <param name="reg">Регистр порта.</param>
    public static byte Read(ulong port, LPT.Register reg = LPT.Register.DATA)
    {
      return !LPT.IsX64DriverUsed ? LPT.Inp32(Convert.ToUInt32(Decimal.Add(new Decimal(port), new Decimal((int) reg)))) : LPT.Inp64(Convert.ToUInt64(Decimal.Add(new Decimal(port), new Decimal((int) reg))));
    }

    /// <summary>Записывает в LPT порт число.</summary>
    /// <param name="port">Адрес порта.</param>
    /// <param name="reg">Регистр порта.</param>
    /// <param name="data">Число для записи. В 32-разрядных системах аргумент должен быть не более, чем максимальное значение для типа UInt32.</param>
    public static void Write(ulong port, LPT.Register reg, ulong data)
    {
      if (LPT.IsX64DriverUsed)
      {
        LPT.Out64(checked (port + (ulong) (uint) reg), data);
      }
      else
      {
        if (data > (ulong) uint.MaxValue)
          throw new ArgumentException("В 32-разрядных системах аргумент должен быть 32-разрядным (тип UInt32).", "data");
        LPT.Out32(Convert.ToUInt32(Decimal.Add(new Decimal(port), new Decimal((int) reg))), checked ((uint) data));
      }
    }

    /// <summary>Регистры порта LPT.</summary>
    public enum Register
    {
      DATA,
      STATUS,
      CONTROL,
    }
  }
}

3Применение класса .NET для работы с LPT портом

Если мы посмотрим на список экспортируемых функций библиотеки inpout32.dll с помощью замечательного инструмента DLL Export Viewer от NirSoft, то увидим следующую картину:

Список экспортируемых функций библиотеки inpout32.dll

Список экспортируемых функций библиотеки inpout32.dll

Это список функций, которые мы можем использовать. Фактически все они используются в классе LPT, но реализация скрыта, и из публичных методов пользователю доступны только два метода и одно свойство (они рассматриваются чуть далее).

При инстанцировании класс сам определит, библиотеку какой разрядности ему использовать – inpout32.dll или inpoutx64.dll. Поэтому от пользователя не требуется никаких действий по инициализации или определения разрядности используемой dll. Вы можете сразу записывать или читать из LPT порта. Одно «Но»: если драйвер не установлен, обращение к любому из методов динамической библиотеки вызовет исключение, поэтому рекомендую использовать блоки Try…Catch для перехвата и обработки исключений.

Несколько примеров использования класса LPT.

Для определения, используется ли 64-разрядная версия драйвера (inpoutx64.dll при True) или 32-разрядная (inpout32.dll при False) (на самом деле, это знать не обязательно, класс использует именно ту библиотеку, которая нужна, но вдруг вам для чего-то понадобится это узнать из своей программы):

bool is64bitDriver = LPT.IsX64DriverUsed;

Для записи числа «123» в регистр контроля LPT порта вызовите из своего класса:

LPT.Write(currentPort, LPT.Register.CONTROL, 123);

Для чтения одного байта из регистра данных LPT порта и чтения регистра статуса:

byte b = LPT.Read(currentPort, LPT.Register.DATA);
byte s = LPT.Read(currentPort, LPT.Register.STATUS);

Здесь currentPortадрес LPT порта. Причём, если у вас интегрированный LPT порт, то его адрес будет, скорее всего, 378h. А если у вас LPT порт на плате расширения, то адрес будет другой, например, D100h или C100h.

Чтобы узнать адрес LPT порта, зайдите в диспетчер устройств Windows, найдите раздел Порты COM и LPT, выберите используемый параллельный порт, и в окне свойств (щёлкнув по нему правой кнопкой мыши) посмотрите, какие ресурсы использует выбранный порт (необходимо брать первое значение из диапазона).

Ресурсы, используемые LPT портом, в диспетчере устройств Windows

Ресурсы, используемые LPT портом, в диспетчере устройств Windows

Например, в данном случае необходимо использовать номер порта C100.

Проблема такая: я установил дополнительный LPT порт (PCI плата), и не могу найти адрес этого порта ?

Есть тут одна книга под рукой, в ней написано что адреса LPT портов находятся в следующих ячейках памяти: для LPT1 0x0408, для LPT2 0x040A, для LPT3 0x040C, для LPT4 0x040E. Пробовал считывать содержимое этих ячеек, в 0x0408 всё правильно находится базовый адрес 888 (0x378) порта LPT1, в 0x040A находится 0, в 0x040C находится 2680160256 (если перевести в Hex то 9FC00000), в 0x040E находится 1076338624 (если перевести в Hex то 40279FC0), что это за данные находятся в ячейках 0x040C и 0x040E ?

Как узнать базовый адрес LPT порта который я установил?

Ещё проблема с определением количества LPT портов, в книге написано что 0x0411 содержит информацию о количестве установленных LPT портов (информацию несут только биты 6 и 7) считываю содержимое 0x0411 без установки дополнительного LPT порта, бит 6 = 0, а бит 7 = 1 соответствует что установлено 2 LPT порта, устанавливаю дополнительный LPT порт и ничего не меняется. В чём тут проблема?

Author Message

Supreme God

User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия

Reply with quote

Post Как узнать адрес LPT-порта в windows

Как программно узнать адрес LPT-порта в Windows-98, Windows XP, Windows 7?

Подозреваю, что как-то через ключи реестра…

Но обширно погуглив, ответа так и не нашел. :(

Именно базовый адрес адрес LPT-порта, а не принтера по умолчанию.

03 Jan 2014 15:00

Profile

Lavr

Supreme God

User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия

Reply with quote

Post 

Я, честно говоря, знаю, где в реестре прописаны свойства LPT-портов на моей машине,

но с этим есть разночтения…

Вот, к примеру, совет на одном из зарубежных сайтов:

for sample on my PC with W98SE:

Address of ports are:

In LogConfig are (device driver resource list) information of port-address.

Вся засада в том, что на моей машине в этих ключах прописаны вовсе не LPT-порты, а вот как

выяснить — по какому принципу заносятся данные о портах в ключи…

Впрочем, в Windows XP эти ключи вроде как и совсем другие.

03 Jan 2014 17:32

Profile

Lavr

Supreme God

User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия

Reply with quote

Post 

На сайте М$ в ответ на похожий вопрос:»How to find I/O range for given LPT Port programatically?»

разводят очень густой туман… :(

Но WMI class похоже, что работает только начиная с Minimum supported client — Windows XP

03 Jan 2014 17:49

Profile

VituZz

God

User avatar

Joined: 13 Nov 2010 04:06
Posts: 1345

Reply with quote

Post 

В Linux в процессе загрузки действия протоколируются, после загрузки протокол можно посмотреть командой dmesg. Может, что-то наподобие можно сделать и в Windows?

Вот пример с моего компа. grep позволяет выбрать нужные строки по шаблону из вывода команды dmesg:

Image

04 Jan 2014 09:03

Profile

Lavr

Supreme God

User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия

Reply with quote

Post 

В Linux, как я прочитал роясь в поиске, этот вопрос решается более просто и имеет

конкретное решение.

В принципе — вопрос советуют решать корректно примерно так:

Поскольку параллельные порты имеют известные адреса:

3BCh, 378h, 278h

то чтобы убедиться в наличии порта, по этим адресам записывают число, после чего

считывают его и если записанное = считанному, то есть некая уверенность в наличии

порта.

В принципе — не очень хорошо, если на порте висит принтер…

Но дело в том, что в ноутах сейчас этих портов нет. А есть только УСБ.

Поэтому LPT-порты эмулируются вот такими гаджетами:

Image

Если повезёт при покупке, они могут эмулировать LPT-порт прямо на уровне регистров,

но вся неприятность в том, что по включению базовый адрес такого «LPT-порта» вовсе

не ложится в привычные 3BCh, 378h, 278h:( ,

а устанавливается в верхние адреса портов, причем в разные.

Вот эту ситуацию я (и многие в сети, как я увидел) пытаюсь разрешить, поскольку

к новому ноутбуку я такую USB2LPT приблуду приобрел…

04 Jan 2014 09:49

Profile

Lavr

Supreme God

User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия

Reply with quote

Post Re: Как узнать адрес LPT-порта в windows

Похоже, что именно так, а не иначе… решение вроде как нашел:
Как получить адрес LPT порта в Win2k.
Решение довольно громоздкое — сугубо в стиле М$ — сделать простые вещи сложными… :D

Как я понял, для Win2k это работает, т.к. есть по ссылке пример. Осталось проверить

этот рецепт для Windows XP, Windows 7

04 Jan 2014 10:20

Profile

Lavr

Supreme God

User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия

Reply with quote

Post 

Это я так думаю, что «не очень хорошо», вот тут пишут, что Виндавоз XP счтает несколько иначе…

04 Jan 2014 11:53

Profile

VituZz

God

User avatar

Joined: 13 Nov 2010 04:06
Posts: 1345

Reply with quote

Post 

А как насчёт прав на запись в порт? Винда Хрр позволит это простому пользователю? :)

04 Jan 2014 13:15

Profile

Lavr

Supreme God

User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия

Reply with quote

Post 

Насколько я всё это прочитал и по своему опыту работы с портами, тут дело даже не в Виндe Хрр,

право на запись в порт регулируется на уровне процесора.

Но не всё так грустно! :D

Для управления портами из программы для Windows NT/XP используется драйвер inpout32.dll.

Сколь он коварный, что обходит все препоны ОС, можно прочитать здесь: How Inpout32.dll works ?

Image

04 Jan 2014 15:32

Profile

Lavr

Supreme God

User avatar

Joined: 21 Oct 2009 08:08
Posts: 7777
Location: Россия

Reply with quote

Post 

Что-то мне в первый раз нигде не попался довольно простой пример, как искать порты в Венде.

А между тем у меня на жестком диске такой пример даже в двух вариантах имеется.

В обоих вариантах используется функция из библиотеки winspool.drv:

Function EnumPorts Lib «winspool.drv» Alias «EnumPortsA» (ByVal pName As String, ByVal Level As Long, _
ByVal lpbPorts As Long, ByVal cbBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long

Если кто столкнется с такой же проблемой, пример на VB есть вот здесь:

Получить список доступных портов

Под Вендой_98 похожий вариант программы у меня добросовестно «выкатил» все порты:

—————Image

Здесь нет адресов портов, но по их именам теперь можно читать соответствующие ключи

реестра, поскольку теперь точно известно, сколько и каких LPT — портов есть в системе.

Я не проверял пока, как это работает под Вендой 7 — там у меня просто нет LPT и СОМ портов… :wink:

04 Feb 2014 11:29

Profile

Более подробно. К LPT порту подключено устройство (что-то типа исполнительного механизма). Мне нужно определить, к какому LPT порту подключено устроойство и после этого читать биты ACK, BUSY, SEL, ERROR и послать данные на INIT, на STROBE и на D0-D7.
Мне известно, что когда BIOS назначает адреса LPT портов, он сохраняет базовые адреса этих портов по таким адресам:

0000:0408 для LPT1
0000:040A для LPT2
0000:040C для LPT3
0000:040E для LPT4

Действительно, адреса, например, LPT1 обычно 378h — 37Fh, но это не ввсегда так.
Для правильного определения адреса LPT1 нужно посмотреть в 0000:0408.

Отсюда и вовопрос. Как правильно прочитать данные по вышеуказанным адресам и
как послать и прочитать данные?

Заранее благодарен.
С уважением, Дмитрий.

Понравилась статья? Поделить с друзьями:
  • Как исправить работу проводника windows 7 как
  • Как найти автомобиль на штрафстоянках москвы
  • Как найти группу в вк мессенджер
  • Как найти документы об образовании архив
  • Как найти представителя осознания