www.mikrocontroller.net

Forum: PC-Programmierung LPTn Basisadressen unter XP


Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Unter DOS konnte man die Basis-Adressen z.B. der LPTn Anschlüsse
wie folgt abfragen, egal wie diese 'gejumpert' waren:

int far *dummy;
  dummy = MK_FP(0x40,8+(port-1)*2); // port 1-3

Ich suche nun nach einer Möglichkeit dies unter XP zu machen. Hat
jemand einen Tipp ?

Gruß Michael

Autor: Manuel B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
(entfernt)

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Manuell,

mir geht es um die Alternative. Ich möchte, daß ein Programm
selbsttätig erkennt, welche LPT-Adressen verwendet werden, damit es
direkt auf den Port zugreifen kann. Die Zugriffe unter XP klappen, nur
sollte eine logische Nummer den entsprechenden LPT-Port anwählen ohne
daß der Anwender die Adresse (378, 278 oder 3BC) kennen muß.

Gruß Michael

Autor: Schoaschi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Standartmässig ist die Adress für LPT1 normal 378. Also braucht man
diese nicht auszulesen.

Soweit meine Erfahrung ;-)

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Probiere sie doch einfach erstmal mit einem CreateFile zu öffnen,
dann weißt du ob sie vorhanden sind und ob ein anderes Programm sie
evt. benutzt.

Autor: GAST (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
moin moin,

die LPT Adressen kann man aus der Registry auslesen.
Mit Delphi geht das z.B. so,


var
  FLPTAddress : array[0..7] of Word;

procedure DetectPortsNT5;     //W2000,WinXP
const
  sLevel0 : String = 'SYSTEM\CurrentControlSet\Enum';
var
  KeysInKey0,KeysInKey1,KeysInKey2,KeysInKey3,KeysInKey4,
  SubKeys0,  SubKeys1,  SubKeys2,  SubKeys3,  SubKeys4,
  Level0,    Level1,    Level2                           : Integer;
  Key0, Key1, Key2, Key3, Key4                           : HKEY;
  P                                                      : Word;
  sLevel1,sLevel2,sLevel3 ,FN                            : String;
  achKey, Buffer                                         :
array[0..1023] of Char;
  PortAllocation                                         : array[0..63]
of Word;
begin
  {$ifDef Debug}WR(sLevel0);{$EndIf}
  OpenSubKey(HKLM,sLevel0,Key0,SubKeys0,KeysInKey0);
  if SubKeys0 > 0 then for Level0:=0 to SubKeys0-1  do begin
    RegEnumKey(Key0,Level0,achKey,1024);
    sLevel1:=sLevel0+'\'+StrPas(achKey);
    {$ifDef Debug}WR(sLevel1);{$EndIf}
    OpenSubKey(HKLM,sLevel1,Key1,SubKeys1,KeysInKey1);
    if SubKeys1 > 0 then for Level1:=0 to SubKeys1-1 do begin
      RegEnumKey(Key1,Level1,achKey,1024);
      sLevel2:=sLevel1+'\'+StrPas(achKey);
      {$ifDef Debug}WR(sLevel2);{$EndIf}
      OpenSubKey(HKLM,sLevel2,Key2,SubKeys2,KeysInKey2);
      if SubKeys2 > 0 then for Level2:=0 to SubKeys2-1 do begin
        RegEnumKey(Key2,Level2,achKey,1024);
        sLevel3:=sLevel2+'\'+StrPas(achKey);
        {$ifDef Debug}WR(sLevel3);{$EndIf}
        OpenSubKey(HKLM,sLevel3,Key3,SubKeys3,KeysInKey3);
        SearchKeyValue(Key3,KeysInKey3,
'Class',SizeOf(Buffer),Buffer);
        if UpperCase(StrPas(Buffer))= 'PORTS' then Begin
          SearchKeyValue(Key3,KeysInKey3, 'FriendlyName',
SizeOf(Buffer),Buffer);
          FN:= UpperCase(StrPas(Buffer));
          {$ifDef Debug}WR( 'FriendlyName:'+FN);{$EndIf}
          if POS('LPT',FN) <> 0 then Begin
            OpenSubKey(HKLM,
sLevel3+'\Control',Key4,SubKeys4,KeysInKey4);
            {$ifDef
Debug}WR('Read:'+sLevel3+'\Control\AllocConfig');{$EndIf}
            if SearchKeyValue(Key4,KeysInKey4, 'AllocConfig'
,SizeOf(PortAllocation),PortAllocation)
            then Begin { PortAllocation[12] , PortAllocation[20] }
              {$ifDef Debug}WR('Value of AllocConfig'); WRP(
PortAllocation);{$EndIf}
              if      PortAllocation[11] >= 5 then P :=
PortAllocation[12]
              else if PortAllocation[19] >= 5 then P :=
PortAllocation[20]
              else                                 P := 0;
              FLPTAddress[StrToInt(FN[ POS('LPT',FN)+3])] := P;
             {$ifDef Debug}WR('Port :
'+IntToHex(P,4)+^M^J'-----------------------------');{$EndIf}
              End
            end;
          End;
        RegCloseKey(Key3);
        end;
      RegCloseKey(Key2);
      end;
    RegCloseKey(Key1);
    end;
  RegCloseKey(Key0);
end;

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Manuel
Natürlich kann ich mir die Adressen im Geräte-Manager ansehen. Aber ich
möchte gerne, daß das Anwendungsprogramm das selber macht. Wenn Du
schreibst '.. auch per Software auslesen lassen.' , so ist dieses
Auslesen genau mein Problem, wofür ich eine Lösung suche.

@Wolfram
Ich finde keine Funktion, mit 'CreateFile' und dem erzeugten
'handle' die physikalische Adresse abzufragen. Wie ich es sehe,
sollen die Systemfunktionen dies ja auch garnicht machen, sondern dem
Anwender die Hardware vorenthalten egal, ob z.B. ein realer Port oder
ein USB->LPT-Adapter vorhanden ist.

@Gast
Herrn Delphi kenne ich nicht, ich kenne nur Delphine :-)
Daran liegt es wohl, daß ich vor lauter Bäumen den Wald nicht sehe. Mit
'regedit' habe ich mal nach 378 bzw. 888 gesucht oder auch nach LPT1.
Leider ohne verwertbaren Erfolg. Offensichtlich ist es doch nicht so
einfach, wie früher unter DOS.

Danke, Michael

Autor: Christoph Kessler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab mal gehört, moderne plug-and-play BIOSse verteilen die
Interrupt-Adressen jedesmal beim Booten neu, auch Linux hatte damit
Probleme. Man kann die Funktion aber abstellen

Autor: H-A-L-9000 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Setupapi

http://www.codeproject.com/csharp/DivingSysProg3.asp

Musste noch von C_Schweinegatter in die Programmiersprache deiner Wahl
übersetzen.

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>@Wolfram
>Ich finde keine Funktion, mit 'CreateFile' und dem erzeugten
>'handle' die physikalische Adresse abzufragen. Wie ich es sehe,
>sollen die Systemfunktionen dies ja auch garnicht machen, sondern dem
>Anwender die Hardware vorenthalten egal, ob z.B. ein realer Port oder
>ein USB->LPT-Adapter vorhanden ist.

Die wirst du auch nicht finden. Es ist aber wesentlich sauberer sich
davon zu überzeugen, dass kein anderes Programm/Druckertreiber gerade
auf diesem Port arbeitet.

Autor: nimnix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schon mal was von HAL gehört?
Der wird dir ganz böse auf die Finger hauhen wenn Du aus dem User-Mode
mit einem inp oder outp daherkommst. Ich fürchte, du musst da
dein Wissen etwas updaten bzgl. Hardware Abstraction Layer, Protected
Mode, IO-Exceptions usw.

Es gibt da einen generischen LPT-Driver. Vielleicht wäre das was
für dich.

Autor: Holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PORTTALK habe ich für die LPT unter XP am laufen.
Ich kan mich nur an ein Driver Tool erinnern wo man in den
Memory per C Programm reinsehen konnte. Den das ist das was die alte
DOS Anwendung konnte.

Autor: Blackbird (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So was vielleicht?


#include <windows.h>
#include <stdio.h>

#define MAXPORTNUM 3

int main (void)
{
  HANDLE hLpt;
  TCHAR szLptPort[10];

  for (int iPortNum = 1; iPortNum <= MAXPORTNUM; ++iPortNum)
  {
    wsprintf (szLptPort, "LPT%d", iPortNum);
    printf ("%s ...", szLptPort);

    hLpt= CreateFile (szLptPort, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
0, NULL);

    if (hLpt == NULL || hLpt == INVALID_HANDLE_VALUE)
    {
      LPVOID lpMsgBuf;
      FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, GetLastError (), MAKELANGID (LANG_NEUTRAL, 
SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf, 0, NULL);
      printf ("%s", (LPCTSTR)lpMsgBuf);
      LocalFree (lpMsgBuf);
    }
    else
      printf ("OK\n", szLptPort);

    CloseHandle (hLpt);
  }

  return (0);
}


Blackbird

Autor: Blackbird (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder etwas universeller?


#include <windows.h>
#include <stdio.h>

#define MAXPORTNUM 4
#define LPT_PORT TEXT("LPT%d")
#define COM_PORT TEXT("COM%d")

int main (void)
{
  HANDLE hPort;
  TCHAR szPort[12];
  TCHAR szTyp[2][14] = {LPT_PORT, COM_PORT};

  for (int i = 0; i < 2; ++i)
  {
    for (int iPortNum = 1; iPortNum <= MAXPORTNUM; ++iPortNum)
    {
      wsprintf (szPort, szTyp[i], iPortNum);
      printf ("%s ...", szPort);

      hPort = CreateFile (szPort, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
0, NULL);

      if (hPort == NULL || hPort == INVALID_HANDLE_VALUE)
      {
        LPVOID lpMsgBuf;
        FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
          FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
          NULL, GetLastError (), MAKELANGID (LANG_NEUTRAL,
SUBLANG_DEFAULT),
          (LPTSTR) &lpMsgBuf, 0, NULL);
        printf ("%s", (LPCTSTR)lpMsgBuf);
        LocalFree (lpMsgBuf);
      }
      else
        printf ("OK\n", szPort);

      CloseHandle (hPort);
    }
  }

  return (0);
}


Blackbird

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.