#include "glpntdrv.h"
#include <parallel.h>
#pragma intrinsic(memset)
struct DEVEXT{ // Device Extension
ULONG xxx;
PDEVICE_OBJECT parObj;
ULONG unused[4];
PHYSICAL_ADDRESS OriginalController;
PUCHAR Controller;
ULONG SpanOfController;
PPARALLEL_TRY_ALLOCATE_ROUTINE allocfunc;
PPARALLEL_FREE_ROUTINE freefunc;
PVOID context;
ULONG unused2[3];
};
// Variablen, einige hatten C-, einige C++-Linkage
// Diese gehören eigentlich allesamt nach DEVEXT, sonst kracht's beim Betrieb zweier GALEPs
CMDBUF *pCmdBuf;
NTSTATUS doio_error;
ULONG i;
KrnlInterfaceHdw io;
ULONG IsIrplHigh;
ULONG DisableCallCount;
extern "C"{
static UCHAR OldIrql;
static bool PortExternBusy;
static PDEVICE_OBJECT pDevObj;
static bool PortAllocFlag;
static ULONG lptport;
// Prototypen
static void FreePort(PDEVICE_OBJECT);
static NTSTATUS FindAndAllocParallelPort(ULONG arg);
// Funktionen exakt in der Reihenfolge wie Conitecs glpntdrv.sys
// Auch in den beiden anderen Dateien, entsprechend alphabetisch angeordnet
void WRITE(UCHAR offset, UCHAR data) {
WRITE_PORT_UCHAR(PUCHAR(lptport+offset),data);
}
UCHAR READ(UCHAR offset) {
return READ_PORT_UCHAR(PUCHAR(lptport+offset));
}
void SetIrqlHigh() {
KeRaiseIrql(HIGH_LEVEL,&OldIrql);
}
void ResetIrql() {
KeLowerIrql(OldIrql);
}
void SetLPTAddress(CMDBUF*cmdbuf) {
static ULONG OldAddr;
ULONG addr=cmdbuf->address;
if (PortExternBusy
|| OldAddr!=addr
|| !PortAllocFlag) {
PortExternBusy=false;
#ifdef _M_IX86
OldAddr=addr;
PHYSICAL_ADDRESS got_address;
ULONG addrSpace=1;
LARGE_INTEGER a={addr};
if (!HalTranslateBusAddress(Isa,0,a,&addrSpace,&got_address)) {
doio_error=1002;
return;
}
lptport=got_address.LowPart;
#else
lptport=addr;
#endif
if (!NT_SUCCESS(FindAndAllocParallelPort(addr))
&& PortExternBusy) doio_error=1000;
}
}
void ExternFreePort() {
FreePort(pDevObj);
}
static NTSTATUS FindAndAllocParallelPort(ULONG addr) {
FreePort(pDevObj);
PCONFIGURATION_INFORMATION ci=IoGetConfigurationInformation();
int numPar=ci->ParallelCount;
UNICODE_STRING strSpaces;
static WCHAR spaces[]=L" "; // 39 spaces
RtlInitUnicodeString(&strSpaces,spaces); // (hier NICHT im CONST-Segment!! Problem ab Vista(?))
WCHAR numBuf[10];
UNICODE_STRING strNumber={0,sizeof numBuf,numBuf};
UNICODE_STRING strDevPar;
RtlInitUnicodeString(&strDevPar,L"\\Device\\ParallelPort"); // 20 Zeichen
RtlCopyUnicodeString(&strSpaces,&strDevPar);
if (numPar>0) {
for(int idx=0;idx<numPar;idx++) {
RtlCopyUnicodeString(&strSpaces,&strDevPar); // überschreibt die Leerzeichen
NTSTATUS ret=RtlIntegerToUnicodeString(idx,10,&strNumber);
if (!NT_SUCCESS(ret)) return ret;
ret=RtlAppendUnicodeStringToString(&strSpaces,&strNumber);
if (!NT_SUCCESS(ret)) return ret;
DEVEXT *X=(DEVEXT*)pDevObj->DeviceExtension;
RtlZeroMemory(X,sizeof(DEVEXT));
PFILE_OBJECT fileObj;
ret=IoGetDeviceObjectPointer(&strSpaces,FILE_READ_ATTRIBUTES,&fileObj,&X->parObj);
if (!NT_SUCCESS(ret)) return ret;
ObDereferenceObject(fileObj);
pDevObj->StackSize=X->parObj->StackSize+1; // Huh! Was ist denn das??
KEVENT event;
X->unused[2]=0; // Keine Ahnung!
KeInitializeEvent(&event,NotificationEvent,false);
PARALLEL_PORT_INFORMATION ppi;
IO_STATUS_BLOCK ioStatus;
IRP *irp=IoBuildDeviceIoControlRequest(
IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO,X->parObj, // 0x160030
NULL,0,
&ppi,sizeof ppi,
true, // internal IOCTL
&event,&ioStatus);
if (!irp) return STATUS_INSUFFICIENT_RESOURCES;
ret=IoCallDriver(X->parObj,irp);
if (!NT_SUCCESS(ret)) return ret;
ret=KeWaitForSingleObject(&event,Executive,KernelMode,false,NULL);
if (!NT_SUCCESS(ret)) return ret;
KeClearEvent(&event);
X->OriginalController=ppi.OriginalController;
X->Controller=ppi.Controller; // unbenutzt
X->SpanOfController=ppi.SpanOfController; // unbenutzt
X->allocfunc=ppi.TryAllocatePort;
X->freefunc=ppi.FreePort;
X->context=ppi.Context;
if (X->OriginalController.LowPart==addr) {
if (X->allocfunc(X->context)) {
PortAllocFlag=true;
PortExternBusy=false;
break;
}else{
PortExternBusy=true;
return STATUS_ADAPTER_HARDWARE_ERROR;
}
}
}
}
return STATUS_SUCCESS;
}
static void FreePort(PDEVICE_OBJECT devObj) {
if (PortAllocFlag) {
DEVEXT *X=(DEVEXT*)devObj->DeviceExtension;
X->freefunc(X->context);
PortAllocFlag=false;
}
}
void ExternalDelay(ULONG us) {
KeStallExecutionProcessor(us);
}
static NTSTATUS DoIrpDeviceControl(IN PDEVICE_OBJECT devObj, IN PIRP I, IN PIO_STACK_LOCATION irpStack) {
if (irpStack->Parameters.DeviceIoControl.IoControlCode!=IOCTL_GALEP) return STATUS_NOT_IMPLEMENTED;
doio_error=0;
pDevObj=devObj;
CMDBUF *cmdbuf=(CMDBUF*)irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
if (!doio(cmdbuf)) cmdbuf->errorcode=doio_error;
I->IoStatus.Information=sizeof(CMDBUF);
return STATUS_SUCCESS;
}
static NTSTATUS DoIrpClose(IN PDEVICE_OBJECT, IN PIRP) {
return STATUS_SUCCESS;
}
static NTSTATUS DispatchFunction(IN PDEVICE_OBJECT devObj, IN PIRP I) {
I->IoStatus.Information=0;
PIO_STACK_LOCATION irpStack=IoGetCurrentIrpStackLocation(I);
I->IoStatus.Status=irpStack->MajorFunction==IRP_MJ_DEVICE_CONTROL
?DoIrpDeviceControl(devObj,I,irpStack)
:STATUS_NOT_IMPLEMENTED;
IoCompleteRequest(I,0);
return STATUS_SUCCESS;
}
static NTSTATUS CreateDevice(PDRIVER_OBJECT drvObj) {
UNICODE_STRING ntName,dosName;
PDEVICE_OBJECT devObj;
RtlInitUnicodeString(&ntName,L"\\Device\\glpntdrv");
RtlInitUnicodeString(&dosName,L"\\DosDevices\\glpntdrv");
NTSTATUS ret=IoCreateDevice(drvObj,sizeof(DEVEXT),&ntName,FILE_DEVICE_UNKNOWN,0,TRUE,&devObj);
if (!ret) {
devObj->Flags|=DO_DIRECT_IO;
ret=IoCreateSymbolicLink(&dosName,&ntName);
if (ret) IoDeleteDevice(devObj);
}
return ret;
}
static NTSTATUS DeleteDevice(PDRIVER_OBJECT drvObj) {
IoDeleteDevice(drvObj->DeviceObject);
return STATUS_SUCCESS;
}
static void UnloadDriver(IN PDRIVER_OBJECT drvObj) {
UNICODE_STRING dosName;
RtlInitUnicodeString(&dosName,L"\\DosDevices\\glpntdrv");
IoDeleteSymbolicLink(&dosName);
FreePort(drvObj->DeviceObject);
DeleteDevice(drvObj);
}
static NTSTATUS InitDriver(PDRIVER_OBJECT drvObj) {
return CreateDevice(drvObj);
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT drvObj, IN PUNICODE_STRING /*regPath*/) {
drvObj->MajorFunction[IRP_MJ_CREATE] = DoIrpClose;
drvObj->MajorFunction[IRP_MJ_CLOSE] = DoIrpClose;
drvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchFunction;
drvObj->DriverUnload = UnloadDriver;
return InitDriver(drvObj);
}
}//extern "C"
Detected encoding: ANSI (CP1252) | 4
|
|