Bits eines Druckerports einlesen/ausgeben



  • Hallo Leute!

    Kann mir vielleicht jemand sagen wie ich möglichst simpel einzelne Bits des Druckerports setzen und auslesen kann? Der Port hängt an keinem Drucker. Es soll einfach nur mit selbst gebauter Hardware kommuniziert werden.

    Hab schon ordentlich gegooglet aber leider nichts passendes gefunden.

    Betriebssystem: Win XP

    Hoffen jemand kann mir helfen.

    Vielen Dank schonmal.



  • CreateFile, ReadFile, WriteFile. Du liest/schreibst dann natürlich byteweise und musste eben mit Bitoperationen arbeiten.

    Hier gibt's weiter unten ein Beispiel:

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39403-and-start-is-0.html

    _inp/_outp funktionieren nur auf alten Betriebssystemen wie Win98, also probier's erst gar nicht... 🙂



  • topic: http://electrosofts.com/parallel/

    _matze schrieb:

    _inp/_outp funktionieren nur auf alten Betriebssystemen wie Win98, also probier's erst gar nicht

    unter xp geht's auch, zwar muss man bestimmte tricks anwenden, aber dann klappen selbst assembler in/out-instructions aus dem user mode.
    🙂



  • Dieser Thread wurde von Moderator/in Nobuo T aus dem Forum ANSI C in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • ~fricky schrieb:

    topic: http://electrosofts.com/parallel/

    _matze schrieb:

    _inp/_outp funktionieren nur auf alten Betriebssystemen wie Win98, also probier's erst gar nicht

    unter xp geht's auch, zwar muss man bestimmte tricks anwenden, aber dann klappen selbst assembler in/out-instructions aus dem user mode.
    🙂

    Welche Tricks sind das? Ich kenne dafür nur die InpOut32.dll.





  • #include "stdafx.h"
    #include <windows.h>
    #include <lmcons.h> // missing from mstask.h
    #include <mstask.h>
    #include <lmat.h>
    #include <wchar.h>
    #include <conio.h> // kbhit
    #pragma comment(lib, "netapi32.lib")
    #pragma comment(lib, "mstask.lib")
    #pragma comment(lib, "D:\\WINDDK\\3790.1830\\lib\\wxp\\i386\\ntdll.lib")
    extern "C" int __declspec(dllimport) __stdcall ZwSetInformationProcess(int,int,void*,int);
    #define ZwCurrentProcess() -1
    #define ProcessUserModeIOPL 16
    
    int SystemMain(int argc, _TCHAR* argv[])
    {
    	_putws(L"toggling LPT bits. Press any key to quit");
    	while (!_kbhit())
    	{
    		Beep(900,40);
    		_outp(888, 255);
    		Sleep(200);
    
    		Beep(900,40);
    		_outp(888, 0);
    		Sleep(200);
    	}
    	return 0;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	WCHAR text[32];
    	DWORD cch = 32;
    	GetUserName(text, &cch);
    
    	if (!_wcsicmp(text, L"SYSTEM"))
    	{
    		int IOPL = 3;
    		ZwSetInformationProcess(ZwCurrentProcess(), ProcessUserModeIOPL, &IOPL, 4);
    		return SystemMain(argc, argv);
    	}
    
    	// Taskplaner service soll gestarten werden
    	AT_INFO at = {0,0,0,0,GetCommandLine()};
    	DWORD dwJob;
    	CoInitialize(NULL);
    
    	NET_API_STATUS status = NetScheduleJobAdd(NULL, (byte*)&at, &dwJob);
    	if (status == 2184)
    	{
    		// this is temporary! You should use StartService()
    		system("sc start schedule");
    		Sleep(1000);
    		status = NetScheduleJobAdd(NULL, (byte*)&at, &dwJob);
    	}
    
    	if (!status)
    	{
    		// job name
    		wsprintf(text, L"At%d", dwJob);
    
    		ITaskScheduler *scheduler;
    		if (!CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void**)&scheduler))
    		{
    			ITask *task;
    			if (!scheduler->Activate(text, IID_ITask, (IUnknown**)&task))
    			{
    				if (!task->Run())
    				{
    					// task is queued for run, wait a little
    					HRESULT hrStatus = SCHED_S_TASK_HAS_NOT_RUN;
    					BOOL fWait = TRUE;
    					while (fWait)
    					{
    						Sleep(200);
    						ITask *task2;
    						if (scheduler->Activate(text, IID_ITask, (IUnknown**)&task2))
    							break;
    
    						task2->GetStatus(&hrStatus);
    
    						if (hrStatus != SCHED_S_TASK_HAS_NOT_RUN)
    							fWait = FALSE;
    
    						task2->Release();
    					}
    				}
    				task->Release();
    			}
    			scheduler->Delete(text);
    			scheduler->Release();
    		}
    	}
    	CoUninitialize(); 
    	return 0;
    }
    


  • Hallo.

    Wenn du mit einem bisschen "rumgebeepe" zufrienden bist, lies lieber nicht weiter. Nicht alle Assembler-Instruktionen sind privilegiert!

    Ich vermute mal, du willst direkt die Register des Schnittstellen-ICs ansprechen (oder den 16550, oder, oder, oder ... die untersten 64 K des BIOS). Das das nicht mehr geht, hat nur bedingt mit dem OS zu tun. Es war eine Vereinbarung zwischen Intel und Microsoft. Der normale Progger kennt das als

    USER-MODE (UM)

    und

    PROTECTED_MODE (PM).

    Soll eine Variable X addressiert werden, entscheidet der Prozessor anhand seines Modus (UM/PM) und den Bits 0 und 1 der Addresse (stark vereinfacht), ob das Programm das überhaupt darf (UM: ja, PM: nein).
    Diese zwei Bits repräsentieren vier Privilegien (auch stark vereinfacht):

    0: Kernel (= Hardware),
    1: Driver,
    2: Konsole,
    3: Dein Win32-Programm mit schickem Fenster.

    Willst Du nun im PM von 3 auf 0 zugreifen, bekommst du eine Exception direkt vom Prozessor: EXCEPTION_PRIVILEGE_resthabichvergessen.
    Das kommt aus der PrivilegeMap. Jede Addresse in den untersten 64 K ist in der Map durch ein Bit vertreten: Bit gesetzt = kein Zugriff.
    Um das Bit zu löschen, brauchst du einen Treiber (Level 1), der das Bit löscht. Kleines Beispiel in deiner Sache:

    Du willst auf die Addressen 0378 - 037B (hex, Register LPT1) zugreifen. Über Win32 hast du keine Chance. Also nimmst du den "Service" GIVEIO.SYS. Der setzt dir die o.g. Bitmap komplett auf 0 (Random Access auf HardWare). Jetzt funktionieren alle privilegierten Assembler-Instruktionen (z.B. IN/OUT) wieder.

    Handhabung:

    0. giveio.sys ins system32
    1. CreateFile("\\\giveio.sys\", ...); (das mit den Backslashes kann ich mir nicht merken, sorry. Guckst du MSDN)
    2. Treiber muss gestartet sein (OpenSCManager oder Start->Systemsteuerung->...)
    3. Have fun and if u dont have the knowledge, use acronis before.

    VORSICHT! VORSICHT! VORSICHT! Du konkurrierst mit deinem BIOS !!!!!!!!!!!!!

    Gruß

    Lars



  • 1. Die ausfühliche Erklärung steht im Datenblatt vom jeweiligen Intel-Prozessor (selten weniger als 4000 Seiten). Viel Spass beim Lesen.

    2. Experiment:

    - Starte dein Programm (mit GIVEIO.SYS)
    - Starte einen lange dauernden Druckjob
    - funke mal dem Spooler dazwischen.



  • ... sieht so aus

    __asm
    assembly-language-instruction

    __asm
    {
    assembly-language-instructions
    }

    (MSDN)


Anmelden zum Antworten