#include "glpntdrv.h"
#pragma intrinsic(memset)
/*
void KrnlInterfaceHdw::Disable() {
if (!DisableCallCount++) KeRaiseIrql(HIGH_LEVEL,&OldIrql);
}
void KrnlInterfaceHdw::Enable() {
if (!--DisableCallCount) KeLowerIrql(OldIrql);
}
*/
long GALEP::FreePort(long) {
if (PortAllocFlag) {
freefunc(context);
PortAllocFlag=false;
}
return 0;
}
NTSTATUS GALEP::FindAndAllocParallelPort(ULONG addr) {
FreePort(0);
PCONFIGURATION_INFORMATION ci=IoGetConfigurationInformation();
int numPar=ci->ParallelCount;
WCHAR space[32];
UNICODE_STRING strSpace={0,sizeof space,space};
WCHAR numBuf[10];
UNICODE_STRING strNumber={0,sizeof numBuf,numBuf};
UNICODE_STRING strDevPar;
RtlInitUnicodeString(&strDevPar,L"\\Device\\ParallelPort"); // 20 Zeichen
RtlCopyUnicodeString(&strSpace,&strDevPar);
for (int idx=0; idx<numPar; idx++) {
RtlCopyUnicodeString(&strSpace,&strDevPar);
NTSTATUS ret=RtlIntegerToUnicodeString(idx,10,&strNumber);
if (!NT_SUCCESS(ret)) return ret;
ret=RtlAppendUnicodeStringToString(&strSpace,&strNumber);
if (!NT_SUCCESS(ret)) return ret;
PFILE_OBJECT fileObj;
PDEVICE_OBJECT parObj;
ret=IoGetDeviceObjectPointer(&strSpace,FILE_READ_ATTRIBUTES,&fileObj,&parObj);
if (!NT_SUCCESS(ret)) return ret;
ObDereferenceObject(fileObj);
pDevObj->StackSize=parObj->StackSize+1; // Huh! Was ist denn das??
KEVENT event;
KeInitializeEvent(&event,NotificationEvent,false);
PARALLEL_PORT_INFORMATION ppi;
IO_STATUS_BLOCK ioStatus;
IRP *irp=IoBuildDeviceIoControlRequest(
IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO,parObj, // 0x160030
NULL,0,
&ppi,sizeof ppi,
true, // internal IOCTL
&event,&ioStatus);
if (!irp) return STATUS_INSUFFICIENT_RESOURCES;
ret=IoCallDriver(parObj,irp);
if (!NT_SUCCESS(ret)) return ret;
ret=KeWaitForSingleObject(&event,Executive,KernelMode,false,NULL);
if (!NT_SUCCESS(ret)) return ret;
KeClearEvent(&event);
allocfunc=ppi.TryAllocatePort;
freefunc=ppi.FreePort;
context=ppi.Context;
if (ppi.OriginalController.LowPart==addr) {
if (allocfunc(context)) {
PortAllocFlag=true;
PortExternBusy=false;
break;
}else{
PortExternBusy=true;
return STATUS_ADAPTER_HARDWARE_ERROR;
}
}
}
return STATUS_SUCCESS;
}
long GALEP::SetLPTAddress(long addr) {
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)) {
pCmdBuf->errorcode=1002;
return 0;
}
lptport=got_address.LowPart;
#else
lptport=addr;
#endif
if (NT_SUCCESS(FindAndAllocParallelPort(addr))
&& PortExternBusy) pCmdBuf->errorcode=1000;
}
return 0;
}
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;
GALEP*p=(GALEP*)irpStack->FileObject->FsContext;
p->doio(devObj,(CMDBUF*)irpStack->Parameters.DeviceIoControl.Type3InputBuffer);
I->IoStatus.Information=sizeof(CMDBUF);
return STATUS_SUCCESS;
}
static NTSTATUS DispatchCreate(DEVICE_OBJECT*, IRP*I) {
GALEP*p=(GALEP*)ExAllocatePool(PagedPool,sizeof(GALEP));
if (!p) return STATUS_NO_MEMORY;
IoGetCurrentIrpStackLocation(I)->FileObject->FsContext=p;
return STATUS_SUCCESS;
}
static NTSTATUS DispatchClose(DEVICE_OBJECT*, IRP*I) {
GALEP*p=(GALEP*)IoGetCurrentIrpStackLocation(I)->FileObject->FsContext;
p->FreePort(0);
ExFreePool(p);
return STATUS_SUCCESS;
}
static NTSTATUS DispatchDeviceControl(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;
PDEVICE_OBJECT devObj;
RtlInitUnicodeString(&ntName,L"\\Device\\glpntdrv");
NTSTATUS ret=IoCreateDevice(drvObj,0,&ntName,FILE_DEVICE_UNKNOWN,0,FALSE,&devObj);
if (!ret) {
devObj->Flags|=DO_DIRECT_IO;
UNICODE_STRING dosName;
RtlInitUnicodeString(&dosName,L"\\DosDevices\\glpntdrv");
ret=IoCreateSymbolicLink(&dosName,&ntName);
if (ret) IoDeleteDevice(devObj);
}
return ret;
}
static void DriverUnload(IN PDRIVER_OBJECT drvObj) {
UNICODE_STRING dosName;
RtlInitUnicodeString(&dosName,L"\\DosDevices\\glpntdrv");
IoDeleteSymbolicLink(&dosName);
IoDeleteDevice(drvObj->DeviceObject);
}
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT drvObj, IN PUNICODE_STRING /*regPath*/) {
drvObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
drvObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
drvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
drvObj->DriverUnload = DriverUnload;
return CreateDevice(drvObj);
}
Detected encoding: ASCII (7 bit) | 2
|