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
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
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;
@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
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
>@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.
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.
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.