13 Stimmen

Öffnen eines Handles für ein Gerät in Python unter Windows

Ich versuche, den giveio.sys-Treiber zu verwenden, bei dem eine "Datei" geöffnet werden muss, bevor man auf geschützten Speicher zugreifen kann. Ich schaue mir ein C-Beispiel von WinAVR/AVRdude an, das diese Syntax verwendet:

 #define DRIVERNAME      "\\\\.\\giveio"
 HANDLE h = CreateFile(DRIVERNAME,
            GENERIC_READ,
            0,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL);

aber das scheint in Python nicht zu funktionieren - ich erhalte nur die Fehlermeldung "Der angegebene Pfad ist ungültig", sowohl für

f = os.open("\\\\.\\giveio", os.O_RDONLY)

y

f = os.open("//./giveio", os.O_RDONLY)

Warum tut dies nicht dasselbe?

Bearbeitet um hoffentlich die Verwirrung der Ideen zu verringern (danke Will). Ich habe überprüft, dass der Gerätetreiber über die Batch-Dateien läuft, die mit AVRdude kommen.

Weiter bearbeitet zur Klärung von SamB's Bounty.

6voto

apaulsen Punkte 191

Lösung: In Python müssen Sie win32file.CreateFile() anstelle von open() verwenden. Vielen Dank an alle, die mir gesagt haben, was ich zu tun versuchte, es hat mir geholfen, die Antwort zu finden!

3voto

Will Dean Punkte 38365

Ich weiß nichts über Python, aber ich weiß ein wenig über Treiber. Sie versuchen gar nicht, eine Datei im Kernelbereich zu öffnen - Sie versuchen nur, ein Handle auf ein Gerät zu öffnen, das zufällig so aussieht, als würde man eine Datei öffnen.

CreateFile ist eine Funktion im Benutzermodus, und alles, was Sie hier tun, ist im Benutzermodus und nicht im Kernelmodus.

Wie xenon sagt, kann Ihr Aufruf fehlschlagen, weil Sie den Treiber noch nicht geladen haben, oder weil der Python-Aufruf, den Sie für CreateFile verwenden, die Schreibparameter nicht übergibt.

Ich habe giveio.sys selbst noch nie benutzt, aber ich persönlich würde mich vergewissern, dass es korrekt geladen wurde, indem ich C oder C++ (oder eine vorgefertigte Anwendung) benutze, bevor ich versuche, es mit Python zum Laufen zu bringen.

2voto

Ihre Frage ist, gelinde gesagt, sehr verwirrend.

1> Der Code, den Sie eingefügt haben, verwendet einen Trick, um mit dem Treiber über seinen 'DOSNAME' zu kommunizieren, d.h.

\\.\DRIVERNAME

2> Haben Sie den "giveio"-Treiber erstellt und geladen?

Der Grund, warum der Treiber diese Anrufe bearbeitet, ist folgender

http://msdn.microsoft.com/en-us/library/ms806162.aspx

2voto

willurd Punkte 11009

Ich bin nicht sicher, ob das möglich ist. Als Alternative könnten Sie ein C/C++-Programm schreiben, das die gesamte Arbeit im Kernelspace für Sie erledigt, und die Schnittstelle zu diesem Programm in Python über das Unterprozessmodul o Python C/C++ Bindungen (y weiterer Link dafür).

2voto

Warren P Punkte 61510

Es hört sich für mich so an, als würden Sie fragen, warum os.open nicht auf magische Weise gleichbedeutend ist mit dem Aufruf von CreateFile mit einem ganz bestimmten Satz von Parametern. Kostyas Antwort ist insofern praktisch, als sie Ihnen sagt, dass Sie die Win32-Python-Bindungen verwenden können, um CreateFile, eine Win32-API, direkt aufzurufen.

Alles andere als direktes CreateFile/readFile/writeFile IO führt eine weitere Schicht ein (die Python-Dateiobjekte und ihr Verhalten), die Sie auf die Parameter beschränkt, die os.open unterstützt. os.open erzeugt ein Python-Dateiobjekt, das nicht genau dasselbe ist und nicht alle Optionen von Win32 CreateFile bieten soll.

Das bedeutet zum Beispiel, dass keine exakten Entsprechungen von GENERIC_READ, OPEN_EXISTING oder FILE_ATTRIBUTE_NORMAL garantiert sind.

Meine Vermutung ist, dass os.open nicht dazu gedacht ist, direkte Aufrufe von CreateFile zu ersetzen, für so merkwürdige Zwecke wie den, für den Sie es verwenden.

Wenn Sie C lesen können, warum öffnen Sie nicht die Quellen von Python und lesen die Implementierung von os.open. Wenn Sie os.open wirklich durchgehen müssen, werden Sie herausfinden, welche Parameter Sie übergeben müssen, damit die Implementierung von os.open (in C) am Ende CreateFile in der Win32-API mit den richtigen Parametern aufruft. All das scheint mehr Arbeit zu sein, als wenn man einfach Kostyas Vorschlag verwendet.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X