/* Kopfdatei für USB2LPT.SYS sowie für CoInstaller / Einstellprogramme sowie Sonderfunktionen (bspw. Firmware-Download) */ #ifdef DRIVER # define _X86_ 1 # include # include # include // (enthält störende USB-Hub-GUID-Definition) # ifdef INIT_MY_GUID # include // Erst ab jetzt GUIDs im Speicher ablegen! # endif # ifndef IoInitializeRemoveLock // im 98DDK nicht definiert # include "w2k.h" // Fehlendes "nachreichen" # endif #endif //typedef unsigned char BYTE,*PBYTE; //typedef unsigned short WORD,*PWORD; #define elemof(x) (sizeof(x)/sizeof((x)[0])) #define T(x) TEXT(x) // {DA6B195A-AC68-4c67-B236-C1455804B1A8} DEFINE_GUID(Vlpt_GUID,0xda6b195aL,0xac68,0x4c67,0xb2,0x36,0xc1,0x45,0x58,0x4,0xb1,0xa8); typedef struct{ // Zähler für die Statistik ULONG out; // OUT-Zugriffe ULONG in; // IN-Zugriffe ULONG fail; // bspw: Nicht unterstützte Opcodes (REP INSB u.ä.) ULONG steal; // Gestohlene Debugregister (XP-Problem) ULONG wpu; // WRITE_PORT_UCHAR-Aufrufe ULONG rpu; // READ_PORT_UCHAR-Aufrufe ULONG wdw; // Neu: Word- und DWord-Zugriffe UCHAR debregs; // Zugewiesene Debugregister für SPP(0), EPP(1), ECP(2) UCHAR rsv[3]; }TAccessCnt, *PAccessCnt; typedef struct{ // Einstellbare Eigenschaften des USB2LPT-Gerätes USHORT LptBase; // Abgefangene Basisadresse USHORT TimeOut; // Zeit zum Aufsammeln von OUT-Befehlen in ms (wenn WriteCache) UCHAR flags; #define UCB_Debugreg 0 // Verwendung von (freien) Debugregistern #define UCB_Function 1 // Anzapfung der Kernel-Zugriffsfunktion #define UCB_WriteCache 2 // Verwendung von TimeOut #define UCB_ReadCache0 3 // Lokales Vorhalten von Basisadresse+0 #define UCB_ReadCache2 4 // Lokales Vorhalten von Basisadresse+2 #define UCB_ReadCacheN 5 // Lokales Vorhalten übriger Register (ungenutzt) #define UCB_ForceRes 6 // LptBase-Ressource erzwingen (am PnP vorbei) #define UCB_ForceDebReg 7 // Debugregister-Benutzung erzwingen #define UC_Debugreg 0x01 // Verwendung von Debugregistern #define UC_Function 0x02 // Anzapfung der Kernel-Zugriffsfunktion #define UC_WriteCache 0x04 // Verwendung von TimeOut #define UC_ReadCache0 0x08 // Lokales Vorhalten von Basisadresse+0 #define UC_ReadCache2 0x10 // Lokales Vorhalten von Basisadresse+2 #define UC_ReadCacheN 0x20 // Lokales Vorhalten übriger Register #define UC_ForceRes 0x40 // LptBase-Ressource erzwingen (am PnP vorbei) #define UC_ForceDebReg 0x80 // Debugregister, auch wenn bereits belegt (98-Problem) UCHAR Mode; // enum SPP,EPP,ECP,EPP+ECP }TUserCfg,*PUserCfg; // etwas 16-bit-lastig für Win9x-Eigenschaftsseite // Der Inline-Assembler hat schwere Probleme mit Bitfeldern, // was mich 6 Stunden Debuggen gekostet hat! #define Vlpt_CTL(a,b) CTL_CODE(FILE_DEVICE_UNKNOWN,0x0800+(a),(b),FILE_ANY_ACCESS) /* Konfigurieren (OutBytes==sizeof(TUserCfg)) bzw. Abfrage der Konfiguration (InBytes==sizeof(TUserCfg)) Für den Eigenschaftsseiten-Lieferanten! */ #define IOCTL_VLPT_UserCfg Vlpt_CTL(2,METHOD_BUFFERED) /* Setzen (OutBytes==sizeof(TAccessCnt)) bzw. Abfrage der Zugriffe (InBytes==sizeof(TAccessCnt)) Für den Eigenschaftsseiten-Lieferanten! */ #define IOCTL_VLPT_AccessCnt Vlpt_CTL(3,METHOD_BUFFERED) /* Schreiben und (optional) anschließendes Lesen von Daten über die beiden Pipes zum USB2LPT-Konverter. Asynchron-fähig! ShortTransferOK, dh. USB-Gerät darf auch einen kürzeren Datenblock zurücksenden. ACHTUNG: InBuffer sind (Bulk)OUT-Daten, OutBuffer (Bulk)IN-Daten! */ #define IOCTL_VLPT_OutIn Vlpt_CTL(4,METHOD_BUFFERED) //(DWORD)InputBuffer: 0=OUT-Pipe, 1=IN-Pipe, OutputBuffer ungenutzt #define IOCTL_VLPT_AbortPipe Vlpt_CTL(15,METHOD_BUFFERED) #define IOCTL_VLPT_GetLastError Vlpt_CTL(23,METHOD_BUFFERED) /* (Lesen und) Schreiben des internen Mikrocontroller-RAMs lpInBuffer: WORD offset, nInBufferSize: 2 lpOutBuffer: Download-Daten (gehen ZUM Treiber) nOutputBufferSize: Länge der Download-Daten */ #define IOCTL_VLPT_AnchorDownload Vlpt_CTL(0xA0,METHOD_IN_DIRECT) #define IOCTL_VLPT_EepromRead Vlpt_CTL(0xA2,METHOD_OUT_DIRECT) #define IOCTL_VLPT_EepromWrite Vlpt_CTL(0xA2,METHOD_IN_DIRECT) #define IOCTL_VLPT_XramRead Vlpt_CTL(0xA3,METHOD_OUT_DIRECT) #define IOCTL_VLPT_XramWrite Vlpt_CTL(0xA3,METHOD_IN_DIRECT) #ifdef DRIVER // Ab hier treiber-interne Daten #if DBG # undef ASSERT # define ASSERT(e) if(!(e)){DbgPrint("Verletzung einer Annahme in " \ __FILE__", Zeile %d: " #e "\n", __LINE__); \ _asm int 3} # define Vlpt_KdPrint(_x_) { DbgPrint("usb2lpt.sys: "); DbgPrint _x_; } # ifdef VERBOSE # define Vlpt_KdPrint2(_x_) { DbgPrint("usb2lpt.sys: "); DbgPrint _x_; } # else # define Vlpt_KdPrint2(_x_) # endif # define TRAP() _asm int 3 #else # define Vlpt_KdPrint(_x_) # define Vlpt_KdPrint2(_x_) # define TRAP() #endif typedef enum {false,true} bool; typedef struct{ // Zeitgeber + zugehöriges DPC KTIMER tmr; // Zeitgeber KDPC dpc; // Rückruf (im Dispatch-Level) }MYTIMER,*PMYTIMER; typedef struct { // Frei nach W. Oney: PDEVICE_OBJECT fdo; // Rückwärts-Zeiger zu unserem Gerät PDEVICE_OBJECT pdo; // Physikalisches Gerät (Bustreiber) PDEVICE_OBJECT ldo; // "Tieferliegendes" Gerät, wohin URBs/IRPs gehen /* DEVSTATE devstate; // Gerätezustand DEVSTATE prevstate; POWERSTATE powerstate; // Eigener Geräte-Stromversorgungs-Zustand DEVICE_POWER_STATE devpower; // System-definierte Gerätestromversorgung SYSTEM_POWER_STATE syspower; // Systemstromversorgung DEVICE_CAPABILITIES devcaps; // zum Thema Stromversorgung */ int instance; // Zähler für Gerätenamen "LPTx" UCHAR f; // Zustands-Flags #define Stopped 1 // Indicates that we have recieved a STOP message // Indicates that we are enumerated and configured. Used to hold // of requests until we are ready for them #define Started 2 // Indicates the device needs to be cleaned up (ie., some configuration // has occurred and needs to be torn down). // BOOLEAN NeedCleanup:1; // TRUE if we're trying to remove this device #define removing 4 #define surprise 8 //#define trapping 16 // Trap-ISR gerade in Bearbeitung //#define BiosRamPatch 0x40 #define No_Function 0x80 USHORT oldlpt; // Gerettete LPTx-Adresse aus BIOS-Bereich USHORT oldsys; // Gerettetes BIOS-Ausstattungsbyte (410h) char debugreg[3]; // 0: 378-37B, 1: 37C-37F (EPP) 2: 778-77B (ECP) UCHAR mirror[4]; // 0: Gültigkeits-Bits, 1: 378, 2: 37A UCHAR bfill; // Füllstand des OUT-Puffers UCHAR buffer[63]; // Zum Puffern der OUT-Bytes + 1 IN-Byte TAccessCnt ac; TUserCfg uc; KMUTEX bmutex; // Puffer-Mutex // configuration handle for the configuration the // device is currently in // USBD_CONFIGURATION_HANDLE ConfigurationHandle; PUSB_DEVICE_DESCRIPTOR DeviceDescriptor; // USB-Gerätebeschreiber PUSBD_INTERFACE_INFORMATION Interface; // USB-Interface (nur eins) // ULONG OpenHandles; USBD_STATUS LastFailedUrbStatus; // Letzter USB-Fehler MYTIMER wrcache; // Schreibcache-Zeitgeber (nichtperiodisch) KEVENT ev; // ROT solange asynchroner URB verarbeitet wird // NTSTATUS st; // wird für Komplettierung gebraucht...??? // PURB u; // zur Freigabe bei Komplettierung // ULONG len; // Länge der letzten Übertragung // UNICODE_STRING ucDeviceLink; UNICODE_STRING ifname; // Interface-Name für GUID-basierten Zugriff IO_REMOVE_LOCK rlock; // zur Synchronisation beim Löschen des Gerätes }DEVICE_EXTENSION, *PDEVICE_EXTENSION; // Öffentliche Funktionen von usb2lpt.c //(Diese unterstützen nun auch Word- und Dword-Zugriffe) extern bool _stdcall HandleOut(PDEVICE_EXTENSION,USHORT, ULONG,UCHAR); extern bool _stdcall HandleIn (PDEVICE_EXTENSION,USHORT,PULONG,UCHAR); // Öffentliche Funktionen von vlpt.c extern ULONG CurThreadPtr; int _stdcall AllocDR(USHORT,PDEVICE_EXTENSION); int _stdcall FreeDRN(int); void PrepareDR(void); // Debugregister-Trap vorbereiten (kein Unprepare) void HookSyscalls(void); // READ|WRITE_PORT_UCHAR-Anzapfung setzen void UnhookSyscalls(void); // READ|WRITE_PORT_UCHAR-Anzapfung rückgängig #endif // Ende treiber-interne Daten