Программное определение доступных LPT портов и их адресов

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Rojohn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 439
Зарегистрирован: 22.06.2005 (Ср) 11:00
Откуда: Moscow city

Программное определение доступных LPT портов и их адресов

Сообщение Rojohn » 22.07.2007 (Вс) 0:22

Уважаемые эксперты!
Подскажите, как программно вывести, например в комбо, список всех доступных на ПК LPT портов и их адресов, например LPT1 (&H378) и т.д.
Спасибо!
Делитесь опытом и Вам воздастся! Кто разместит полезный код - тому воздастся вдвойне! :)

Rojohn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 439
Зарегистрирован: 22.06.2005 (Ср) 11:00
Откуда: Moscow city

?

Сообщение Rojohn » 22.07.2007 (Вс) 20:50

Неужели все юзают только COM и USB? По ним примеров много, а вот по LPT найти трудно... :roll:
Делитесь опытом и Вам воздастся! Кто разместит полезный код - тому воздастся вдвойне! :)

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 23.07.2007 (Пн) 12:02

WMI кое-что тебе покажет, примеры я уже выкладывал сюда, да и не только я

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 23.07.2007 (Пн) 15:14

Получить список портов можно через EnumPorts:

Код: Выделить всё
#Include "WIN32API.INC"
Function PBMain
   Dim Ports(255) As PORT_INFO_1
   EnumPorts ByVal %NULL, 1, VarPtr(Ports(0)), SizeOf(Ports(0)) * UBound(Ports(1)), pcbNeeded&, pcReturned&
   For x& = 0 To pcReturned& - 1
       MsgBox Ports(x&).@pName
   Next x&
End Function


Адреса портов, в NT - только через драйвера, в 95/98 можно было так:

Код: Выделить всё
FUNCTION WinMain (BYVAL hCurInstance AS INTEGER, _
                  BYVAL hPrevInstance AS INTEGER, _
                  lpCmdLine AS ASCIIZ, _
                  BYVAL nCmdShow AS INTEGER) AS INTEGER

  DIM lpCaption AS ASCIIZ * 255   
  DIM lpText    AS ASCIIZ * 255   
  DIM CrLf      AS STRING
  DIM PortInfo  AS PortInfoType PTR
  DIM Address   AS DWORD
  CrLf      = CHR$(13,10)
  lpCaption = "BIOS Port Addresses"
  Address   = (pbv0000h * 65536) + &H0400
  PortInfo  = Address
  lpText    = "COM1: " + HEX$(@PortInfo.Com1) + CrLf _
            + "COM2: " + HEX$(@PortInfo.Com2) + CrLf _
            + "COM3: " + HEX$(@PortInfo.Com3) + CrLf _
            + "COM4: " + HEX$(@PortInfo.Com4) + CrLf _
            + "LPT1: " + HEX$(@PortInfo.Lpt1) + CrLf _
            + "LPT2: " + HEX$(@PortInfo.Lpt2) + CrLf _
            + "LPT3: " + HEX$(@PortInfo.Lpt3) + CrLf _
            + "LPT4: " + HEX$(@PortInfo.Lpt4)
  MessageBox 0, lpText, lpCaption, 0
END FUNCTION


Естественно код нужно переложить на VB синтаксис

Rojohn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 439
Зарегистрирован: 22.06.2005 (Ср) 11:00
Откуда: Moscow city

Сообщение Rojohn » 23.07.2007 (Пн) 19:23

WMI кое-что тебе покажет...


Что такое WMI? Поиск чтоли? :) По поиску я что-то не нашел.
Или Windows Management Instrumentation? (Если честно мельком про это слышал).

Естественно код нужно переложить на VB синтаксис


А на чём эти примеры? На VB-NET чтоли? Если так, то я в нём пока не силен... :oops:
Последний раз редактировалось Rojohn 23.07.2007 (Пн) 19:34, всего редактировалось 1 раз.
Делитесь опытом и Вам воздастся! Кто разместит полезный код - тому воздастся вдвойне! :)

dr.MIG
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1441
Зарегистрирован: 18.12.2004 (Сб) 9:53
Откуда: г.Ярославль

Сообщение dr.MIG » 23.07.2007 (Пн) 19:30

Rojohn писал(а):Что такое WMI? Поиск чтоли? :) По поиску я что-то не нашел.


Обманывать нехорошо :)

http://bbs.vbstreets.ru/viewtopic.php?t=31376
http://bbs.vbstreets.ru/viewtopic.php?t=31351

И т.д.
Salus populi suprema lex

Rojohn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 439
Зарегистрирован: 22.06.2005 (Ср) 11:00
Откуда: Moscow city

?

Сообщение Rojohn » 23.07.2007 (Пн) 19:57

Я не WMI в поиске не нашел, а про то, как порт вывести...

Посмотрел эти ссылки про WMI и ужаснулся:) Вроде говорят, что всё просто, но надо очень разбираться. Пряма какой-то второй API :)

А проще никак нельзя?

Адреса портов, в NT - только через драйвера


Это как?
Делитесь опытом и Вам воздастся! Кто разместит полезный код - тому воздастся вдвойне! :)

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 23.07.2007 (Пн) 20:04

Rojohn писал(а):
А на чём эти примеры? На VB-NET чтоли? Если так, то я в нём пока не силен... :oops:


Нет, это PowerBASIC, но это не важно. Ключевое слово этого примера EnumPorts, набираешь его в поисковике и сразу находишь пример на VB

Код: Выделить всё
Private Declare Function EnumPorts Lib "winspool.drv" Alias "EnumPortsA" _
                                   (ByVal pName As String, ByVal nLevel As Long, _
                                    lpbPorts As Any, ByVal cbBuf As Long, _
                                    pcbNeeded As Long, pcReturned As Long) As Long

Private Declare Function lstrlenA Lib "kernel32" (lpString As Any) As Long
Private Declare Function lstrcpyA Lib "kernel32" (lpString1 As Any, lpString2 As Any) As Long

Private Const SIZEOFPORT_INFO_2 = 20

Private Type PORT_INFO_2
    pPortName    As Long
    pMonitorName As Long
    pDescription As Long
    fPortType    As Long
    Reserved     As Long
End Type

Private Enum PortTypes
    PORT_TYPE_WRITE = &H1
    PORT_TYPE_READ = &H2
    PORT_TYPE_REDIRECTED = &H4
    PORT_TYPE_NET_ATTACHED = &H8
End Enum

Private Function GetStrFromPtrA(lpszA As Long) As String
    GetStrFromPtrA = String$(lstrlenA(ByVal lpszA), 0)
    Call lstrcpyA(ByVal GetStrFromPtrA, ByVal lpszA)
End Function

Public Function GetPorts() As String

    Dim pcbNeeded As Long, pcReturned  As Long, Boucle As Integer
    Dim PortI2() As PORT_INFO_2
    Dim StrPortType As String, ret As String
   
    EnumPorts vbNullString, 2, 0, 0, pcbNeeded, pcReturned
    If pcbNeeded Then
        ReDim PortI2((pcbNeeded / SIZEOFPORT_INFO_2))
        If EnumPorts(vbNullString, 2, PortI2(0), pcbNeeded, pcbNeeded, pcReturned) Then
            For Boucle = 0 To (pcReturned - 1)
                With PortI2(Boucle)
                    StrPortType = ""
                    If (.fPortType And PORT_TYPE_WRITE) Then StrPortType = "write "
                    If (.fPortType And PORT_TYPE_READ) Then StrPortType = StrPortType & "read "
                    If (.fPortType And PORT_TYPE_REDIRECTED) Then StrPortType = StrPortType & "redirected "
                    If (.fPortType And PORT_TYPE_NET_ATTACHED) Then StrPortType = StrPortType & "network"
                    ret = ret & GetStrFromPtrA(.pPortName) & " (" & StrPortType & ")" & "|"
                End With
            Next
        End If
    End If
   
    If Len(ret) > 0 Then ret = Left(ret, Len(ret) - 1)
    GetPorts = ret
   
End Function

Rojohn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 439
Зарегистрирован: 22.06.2005 (Ср) 11:00
Откуда: Moscow city

!

Сообщение Rojohn » 23.07.2007 (Пн) 20:10

А вот за это спасибо! С виду должно работать под VB и 2000/XP и т.д. Буду пробовать!
Делитесь опытом и Вам воздастся! Кто разместит полезный код - тому воздастся вдвойне! :)

Rojohn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 439
Зарегистрирован: 22.06.2005 (Ср) 11:00
Откуда: Moscow city

!

Сообщение Rojohn » 23.07.2007 (Пн) 20:24

Вроде работает, но выдает только встроенные порты, а LPT2, установленный на мультипортовой плате на PCI не видит. К тому же адреса вроде не выдаются, а только название порта и тип. Как выдать адрес порта?
Делитесь опытом и Вам воздастся! Кто разместит полезный код - тому воздастся вдвойне! :)

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: !

Сообщение jangle » 23.07.2007 (Пн) 21:01

Вроде работает, но выдает только встроенные порты, а LPT2, установленный на мультипортовой плате на PCI не видит.


Обращайся к драйверу мультипортовой платы, скорее всего для этого нужен соответствующий SDK от производителя "железа"

К тому же адреса вроде не выдаются, а только название порта и тип. Как выдать адрес порта?


Чтобы узнать адреса, нужно обращатся к драйверу через обертку DLL, например поищи в гугле библу WinIo.DLL

Rojohn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 439
Зарегистрирован: 22.06.2005 (Ср) 11:00
Откуда: Moscow city

...

Сообщение Rojohn » 23.07.2007 (Пн) 21:07

Обращайся к драйверу мультипортовой платы, скорее всего для этого нужен соответствующий SDK от производителя "железа"


Это не подходит: мне нужно выводить порты на машине с неизвестной заранее конфигурацией. Дай бог, чтоб на ней были только стандартные порты, а если вдруг плата расширения?

Чтобы узнать адреса, нужно обращатся к драйверу через обертку DLL, например поищи в гугле библу WinIo.DLL


Это вместо EnumPorts? Или дополнительно к ней? Буду искать...
Делитесь опытом и Вам воздастся! Кто разместит полезный код - тому воздастся вдвойне! :)

Rojohn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 439
Зарегистрирован: 22.06.2005 (Ср) 11:00
Откуда: Moscow city

?

Сообщение Rojohn » 23.07.2007 (Пн) 21:18

Кстати, очень обидно, т.к. COM-порты на плате он видит, а LPT - нет. Может он его как FILE: обзывает?
Делитесь опытом и Вам воздастся! Кто разместит полезный код - тому воздастся вдвойне! :)

Rojohn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 439
Зарегистрирован: 22.06.2005 (Ср) 11:00
Откуда: Moscow city

?

Сообщение Rojohn » 24.07.2007 (Вт) 19:03

А можно как-нибудь прочесть текущий LPT порт и его адрес из настроек BIOSа?
Делитесь опытом и Вам воздастся! Кто разместит полезный код - тому воздастся вдвойне! :)

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 24.07.2007 (Вт) 20:18

А что такое "текущий порт"?
Изображение

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 24.07.2007 (Вт) 20:34

А можно как-нибудь прочесть текущий LPT порт и его адрес из настроек BIOSа?


А зачем адрес-то? Все равно, в NT из Ring3 его нельзя использовать.

Rojohn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 439
Зарегистрирован: 22.06.2005 (Ср) 11:00
Откуда: Moscow city

Сообщение Rojohn » 24.07.2007 (Вт) 21:24

А что такое "текущий порт"?


Скорее это текущий адрес, на который настроен LPT (обычно порт один) в BIOS на данный момент. По умолчанию - &H378, но там можно ещё на два варианта поменять.

А зачем адрес-то? Все равно, в NT из Ring3 его нельзя использовать.


Что такое Ring3? Мне адрес нужен, т.к. по нему я шлю данные в порт и читаю с него с помощью DLPortIO. Конечно не лучший способ, но сам написать драйвер общения с LPT я пока не могу :oops:
Делитесь опытом и Вам воздастся! Кто разместит полезный код - тому воздастся вдвойне! :)

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 24.07.2007 (Вт) 21:35

Что такое Ring3? Мне адрес нужен, т.к. по нему я шлю данные в порт и читаю с него с помощью DLPortIO. Конечно не лучший способ, но сам написать драйвер общения с LPT я пока не могу


Это user mode, режим в котором работает прикладной софт.
Кстати, какие функции из DLPortIO используешь для записи/чтения?

Rojohn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 439
Зарегистрирован: 22.06.2005 (Ср) 11:00
Откуда: Moscow city

Сообщение Rojohn » 24.07.2007 (Вт) 21:45

Обычно байтовые:
Код: Выделить всё
Public Declare Function DlPortReadPortUchar Lib "dlportio.dll" (ByVal Port As Long) As Byte
и
Public Declare Sub DlPortWritePortUchar Lib "dlportio.dll" (ByVal Port As Long, ByVal Value As Byte)


Но иногда ещё Integer или Long, чтобы не мучиться:
Код: Выделить всё
Public Declare Function DlPortReadPortUshort Lib "dlportio.dll" (ByVal Port As Long) As Integer
Public Declare Function DlPortReadPortUlong Lib "dlportio.dll" (ByVal Port As Long) As Long
и
Public Declare Sub DlPortWritePortUshort Lib "dlportio.dll" (ByVal Port As Long, ByVal Value As Integer)
Public Declare Sub DlPortWritePortUlong Lib "dlportio.dll" (ByVal Port As Long, ByVal Value As Long)


Там ещё какой-то буфер есть, но я не знаю как его использовать.
Делитесь опытом и Вам воздастся! Кто разместит полезный код - тому воздастся вдвойне! :)

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 24.07.2007 (Вт) 22:25

У LPT есть базовые адреса по умолчанию, &H378 (LPT1), &H278 (LPT2), &H3BC (LPT3). ИМХО самый лучший вариант найти устройство на неизвестном порту, просканировать весь диапазон адресов, записывая туда определенною строку, пытаясь получить ответ от устройства. Этакий самодельный Plug-in-Play. Например есть записать строку "AT" в COM порт, на который повешен модем, он ответит "ok"

Rojohn
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 439
Зарегистрирован: 22.06.2005 (Ср) 11:00
Откуда: Moscow city

?

Сообщение Rojohn » 25.07.2007 (Ср) 0:27

Для этого надо опрашивать не порт, а само устройство к нему подключенное (сам порт врядли ответит что-либо). Может и можно что-либо проследить по состоянию каких-нибудь битов порта, но, лучше бы, как-то считать инфу из BIOSа. А, в идеале, если такое возможно, выставить нужный адрес из выше названных из программы в BIOSе для LPT. А вообще, можно ли из VB обращаться к BIOSу?
Делитесь опытом и Вам воздастся! Кто разместит полезный код - тому воздастся вдвойне! :)


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot, Google-бот, Majestic-12 [Bot], Yandex-бот и гости: 33

    TopList