53 ParPortIoctlInOut(IN PDEVICE_EXTENSION Pdx, IN ULONG Ioctl,
54 IN PVOID InBuffer, IN ULONG InBufferLength,
55 OUT PVOID OutBuffer, IN ULONG OutBufferLength)
57 IO_STATUS_BLOCK ioStatusBlock;
67 DBG_IRQL( == PASSIVE_LEVEL);
68 KeInitializeEvent(&event, NotificationEvent, FALSE);
70 ntStatus = STATUS_SUCCESS;
74 DBG_IRQL( == PASSIVE_LEVEL);
75 irp = IoBuildDeviceIoControlRequest(
89 PIO_STACK_LOCATION irpStack;
93 DBG_IRQL( <= DISPATCH_LEVEL);
94 irpStack = IoGetNextIrpStackLocation(irp);
100 DBG_IRQL( <= DISPATCH_LEVEL);
101 ObReferenceObject(Pdx->ParallelPortFileObject);
106 irpStack->FileObject = Pdx->ParallelPortFileObject;
110 DBG_IRQL( <= DISPATCH_LEVEL);
111 ntStatus = IoCallDriver(Pdx->ParallelPortFdo, irp);
115 DBG_IRQL( <= DISPATCH_LEVEL);
116 ObDereferenceObject(Pdx->ParallelPortFileObject);
118 if (!NT_SUCCESS(ntStatus))
126 DBG_IRQL( <= DISPATCH_LEVEL );
127 ntStatus = KeWaitForSingleObject(
134 if (!NT_SUCCESS(ntStatus))
141 FUNC_LEAVE_NTSTATUS(ntStatus);
164 DBG_ASSERT(Pdx->ParallelPortAllocated == FALSE);
168 ntStatus = ParPortIoctlInOut(Pdx, IOCTL_INTERNAL_PARALLEL_PORT_ALLOCATE,
173 if (NT_SUCCESS(ntStatus))
175 Pdx->ParallelPortAllocated = TRUE;
178 FUNC_LEAVE_NTSTATUS(ntStatus);
197 NTSTATUS ntStatus = STATUS_SUCCESS;
201 DBG_IRQL( == PASSIVE_LEVEL);
205 if (Pdx->ParallelPortAllocated == TRUE)
216 Pdx->PortInfo->FreePort(Pdx->PortInfo->Context);
218 #error THIS IS ONLY AVAILABLE ON WDM! Thus, don't use it! (see comment above)
219 ntStatus = ParPortIoctlInOut(Pdx, IOCTL_INTERNAL_PARALLEL_PORT_FREE,
223 Pdx->ParallelPortAllocated = FALSE;
226 FUNC_LEAVE_NTSTATUS(ntStatus);
253 ParPortInit(PUNICODE_STRING ParallelPortName, PDEVICE_EXTENSION Pdx)
264 DBG_IRQL( == PASSIVE_LEVEL);
265 ntStatus = IoGetDeviceObjectPointer(ParallelPortName,
266 FILE_READ_ATTRIBUTES,
267 &Pdx->ParallelPortFileObject,
268 &Pdx->ParallelPortFdo);
270 if (!NT_SUCCESS(ntStatus))
273 FUNC_LEAVE_NTSTATUS(ntStatus);
278 DBG_IRQL( == PASSIVE_LEVEL);
279 Pdx->PortInfo = (PPARALLEL_PORT_INFORMATION) ExAllocatePoolWithTag(NonPagedPool,
286 ntStatus = ParPortIoctlInOut(Pdx, IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO,
288 Pdx->PortInfo,
sizeof(*Pdx->PortInfo));
292 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
295 if (NT_SUCCESS(ntStatus))
297 Pdx->ParPortPortAddress = Pdx->PortInfo->Controller;
311 if (!NT_SUCCESS(ntStatus) && Pdx->PortInfo)
313 DBG_IRQL( < DISPATCH_LEVEL);
314 ExFreePool(Pdx->PortInfo);
315 Pdx->PortInfo = NULL;
318 FUNC_LEAVE_NTSTATUS(ntStatus);
343 DBG_IRQL( <= DISPATCH_LEVEL);
349 if (Pdx->ParallelPortFileObject)
351 DBG_IRQL( <= DISPATCH_LEVEL);
352 ObDereferenceObject(Pdx->ParallelPortFileObject);
353 Pdx->ParallelPortFileObject = NULL;
360 DBG_IRQL( < DISPATCH_LEVEL);
361 ExFreePool(Pdx->PortInfo);
362 Pdx->PortInfo = NULL;
365 FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
369 #define DBG_PPORT_VERBOSE( _yy, _xxx, _type) \
370 DBG_PPORT((DBG_PREFIX " --- " #_xxx " = " _type, PnpInfo->_xxx))
389 ParPortGetPnpInformation(PDEVICE_EXTENSION Pdx, PPARALLEL_PNP_INFORMATION PnpInfo)
398 ntStatus = ParPortIoctlInOut(Pdx, IOCTL_INTERNAL_GET_PARALLEL_PNP_INFO,
399 NULL, 0, PnpInfo,
sizeof(*PnpInfo));
401 if (!NT_SUCCESS(ntStatus))
418 Pdx->ParPortEcpPortAddress = PnpInfo->EcpController;
446 #undef DBG_PPORT_VERBOSE
463 PARALLEL_PNP_INFORMATION pnpInformation;
470 ntStatus = STATUS_INVALID_PARAMETER;
472 if (ParPortGetPnpInformation(Pdx, &pnpInformation))
477 if (pnpInformation.EcpController != 0)
479 ecr = pnpInformation.EcpController + ECR_OFFSET;
490 if (pnpInformation.TrySetChipMode && pnpInformation.ClearChipMode)
495 if (pnpInformation.HardwareCapabilities & PPT_BYTE_PRESENT)
501 DBG_IRQL( <= DISPATCH_LEVEL);
502 ntStatus = pnpInformation.TrySetChipMode(pnpInformation.Context, ECR_BYTE_MODE);
511 DBG_PPORT((
DBG_PREFIX "****************************** NO BYTE MODE PRESENT, making sure to have SPP mode!!!"));
517 ntStatus = STATUS_SUCCESS;
520 if (pnpInformation.EcpController != 0)
532 FUNC_LEAVE_NTSTATUS(ntStatus);
551 PARALLEL_PNP_INFORMATION pnpInformation;
558 ntStatus = STATUS_SUCCESS;
560 if (ParPortGetPnpInformation(Pdx, &pnpInformation))
565 if (pnpInformation.EcpController != 0)
567 ecr = pnpInformation.EcpController + ECR_OFFSET;
577 if (pnpInformation.ClearChipMode)
581 DBG_IRQL( <= DISPATCH_LEVEL);
582 ntStatus = pnpInformation.ClearChipMode(
583 pnpInformation.Context,
584 (UCHAR) pnpInformation.CurrentMode);
592 if (ntStatus == STATUS_UNSUCCESSFUL)
594 ntStatus = STATUS_SUCCESS;
599 if (pnpInformation.EcpController != 0)
606 FUNC_LEAVE_NTSTATUS(ntStatus);
634 DBG_IRQL( == PASSIVE_LEVEL);
638 DBG_ASSERT(Pdx->ParallelPortAllocatedInterrupt == FALSE);
640 Pdx->Pisr.InterruptServiceRoutine = Isr;
641 Pdx->Pisr.InterruptServiceContext = Pdx;
642 Pdx->Pisr.DeferredPortCheckRoutine = NULL;
643 Pdx->Pisr.DeferredPortCheckContext = NULL;
647 ntStatus = ParPortIoctlInOut(Pdx, IOCTL_INTERNAL_PARALLEL_CONNECT_INTERRUPT,
648 &Pdx->Pisr,
sizeof(Pdx->Pisr),
649 &Pdx->Pii,
sizeof(Pdx->Pii));
653 if (NT_SUCCESS(ntStatus))
655 Pdx->ParallelPortAllocatedInterrupt = TRUE;
663 FUNC_LEAVE_NTSTATUS(ntStatus);
686 DBG_IRQL( == PASSIVE_LEVEL);
692 if (Pdx->ParallelPortAllocatedInterrupt == TRUE)
694 ntStatus = ParPortIoctlInOut(Pdx, IOCTL_INTERNAL_PARALLEL_DISCONNECT_INTERRUPT,
695 &Pdx->Pisr,
sizeof(Pdx->Pisr),
698 Pdx->ParallelPortAllocatedInterrupt = FALSE;
705 ntStatus = STATUS_SUCCESS;
708 FUNC_LEAVE_NTSTATUS(ntStatus);
734 ULONG OldStateEnableConnectInterruptIoctl;
735 ULONG OldStateFilterResourceMethod;
745 if (NT_SUCCESS(ntStatus))
760 &OldStateEnableConnectInterruptIoctl);
764 if (ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
766 OldStateEnableConnectInterruptIoctl = -1;
767 ntStatus = STATUS_SUCCESS;
783 &OldStateFilterResourceMethod);
787 if (ntStatus == STATUS_OBJECT_NAME_NOT_FOUND)
789 OldStateFilterResourceMethod = -1;
790 ntStatus = STATUS_SUCCESS;
796 if (NT_SUCCESS(ntStatus) && OldStateEnableConnectInterruptIoctl != 1)
801 if (NT_SUCCESS(ntStatus) && OldStateFilterResourceMethod != 2)
811 FUNC_LEAVE_NTSTATUS(ntStatus);
NTSTATUS ParPortUnsetModeWdm(PDEVICE_EXTENSION Pdx)
Unset the operational mode of the parallel port, WDM Version.
#define FUNC_LEAVE_BOOLEAN(_xxx)
NTSTATUS ParPortAllocInterrupt(PDEVICE_EXTENSION Pdx, PKSERVICE_ROUTINE Isr)
Allocate an interrupt routine for a parallel port.
NTSTATUS cbm_registry_open_hardwarekey(OUT PHANDLE HandleKey, OUT PDEVICE_OBJECT *Pdo, IN PDEVICE_EXTENSION Pdx)
Open the hardware key for another driver.
NTSTATUS ParPortFreeInterrupt(PDEVICE_EXTENSION Pdx)
Free an interrupt routine for a parallel port after using it.
NTSTATUS ParPortDeinit(PDEVICE_EXTENSION Pdx)
Undoes anything ParPortInit has done.
NTSTATUS cbm_registry_read_ulong(IN HANDLE HandleKey, IN PCWSTR KeyName, OUT PULONG Value)
Read a ULONG value out of a registry key.
NTSTATUS ParPortFree(PDEVICE_EXTENSION Pdx)
Free a parallel port after using it.
NTSTATUS ParPortAllowInterruptIoctl(PDEVICE_EXTENSION Pdx)
Set registry key such that we can get the interrupt of a parallel port.
NTSTATUS ParPortUnsetMode(PDEVICE_EXTENSION Pdx)
Unset the operational mode of the parallel port.
const UCHAR * DebugNtStatus(NTSTATUS Value)
Return the description of an NTSTATUS code.
Definitions for the opencbm driver.
#define LogErrorOnly(_Fdo_, _UniqueErrorValue_)
NTSTATUS cbm_registry_close_hardwarekey(IN HANDLE HandleKey, IN PDEVICE_OBJECT Pdo)
Close a hardware registry key.
NTSTATUS ParPortSetModeWdm(PDEVICE_EXTENSION Pdx)
Set the operational mode of the parallel port, WDM Version.
NTSTATUS ParPortAllocate(PDEVICE_EXTENSION Pdx)
Allocate a parallel port for using it.
#define DBG_PPORT_VERBOSE(_yy, _xxx, _type)
NTSTATUS ParPortInit(PUNICODE_STRING ParallelPortName, PDEVICE_EXTENSION Pdx)
Initialize the knowledge on a parallel port.
NTSTATUS cbm_registry_write_ulong(IN HANDLE HandleKey, IN PCWSTR KeyName, IN ULONG Value)
Write a ULONG value out of a registry key.
#define READ_PORT_UCHAR(_x_)
READ_PORT_UCHAR replacement for debugging.