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
Standartmässig ist die Adress für LPT1 normal 378. Also braucht man diese nicht auszulesen. Soweit meine Erfahrung ;-)
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.
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
Setupapi http://www.codeproject.com/csharp/DivingSysProg3.asp Musste noch von C_Schweinegatter in die Programmiersprache deiner Wahl übersetzen.
>@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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.