Forum: PC-Programmierung LPTn Basisadressen unter XP


von Michael (Gast)


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

von Manuel B. (Gast)


Lesenswert?

(entfernt)

von Michael (Gast)


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

von Schoaschi (Gast)


Lesenswert?

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

Soweit meine Erfahrung ;-)

von Wolfram (Gast)


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.

von GAST (Gast)


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;

von Michael (Gast)


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

von Christoph Kessler (Gast)


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

von H-A-L-9000 (Gast)


Lesenswert?

Setupapi

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

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

von Wolfram (Gast)


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.

von nimnix (Gast)


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.

von Holger (Gast)


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.

von Blackbird (Gast)


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

von Blackbird (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.