LPTn Basisadressen unter XP

Gast #384893
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
Gast #384895
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
Gast #384898
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;
Gast #384899
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
Gast #384902
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.
Gast #384903
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.
Gast #384904
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.
Gast #384905
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
Gast #384906
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren