📄 pdoioctl.c
字号:
None.
--*/
{
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
ULONG IdLength;
NTSTATUS NtStatus;
UCHAR Status;
UCHAR Control;
ULONG ioControlCode;
Irp = Pdx->CurrentOpIrp;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
ioControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
switch( ioControlCode ) {
case IOCTL_PAR_SET_INFORMATION :
{
Status = ParInitializeDevice(Pdx);
if (!PAR_OK(Status)) {
ParNotInitError(Pdx, Status); // Set the IoStatus.Status of the CurrentOpIrp appropriately
} else {
Irp->IoStatus.Status = STATUS_SUCCESS;
}
}
break;
case IOCTL_PAR_QUERY_INFORMATION :
{
PPAR_QUERY_INFORMATION IrpBuffer = Irp->AssociatedIrp.SystemBuffer;
Irp->IoStatus.Status = STATUS_SUCCESS;
Status = GetStatus(Pdx->Controller);
Control = GetControl(Pdx->Controller);
// Interpretating Status & Control
IrpBuffer->Status = 0x0;
if (PAR_POWERED_OFF(Status) || PAR_NO_CABLE(Status)) {
IrpBuffer->Status = (UCHAR)(IrpBuffer->Status | PARALLEL_POWER_OFF);
} else if (PAR_PAPER_EMPTY(Status)) {
IrpBuffer->Status = (UCHAR)(IrpBuffer->Status | PARALLEL_PAPER_EMPTY);
} else if (PAR_OFF_LINE(Status)) {
IrpBuffer->Status = (UCHAR)(IrpBuffer->Status | PARALLEL_OFF_LINE);
} else if (PAR_NOT_CONNECTED(Status)) {
IrpBuffer->Status = (UCHAR)(IrpBuffer->Status | PARALLEL_NOT_CONNECTED);
}
if (PAR_BUSY(Status)) {
IrpBuffer->Status = (UCHAR)(IrpBuffer->Status | PARALLEL_BUSY);
}
if (PAR_SELECTED(Status)) {
IrpBuffer->Status = (UCHAR)(IrpBuffer->Status | PARALLEL_SELECTED);
}
Irp->IoStatus.Information = sizeof( PAR_QUERY_INFORMATION );
}
break;
case IOCTL_PAR_QUERY_RAW_DEVICE_ID :
// We always read the Device Id in Nibble Mode.
NtStatus = SppQueryDeviceId(Pdx,
Irp->AssociatedIrp.SystemBuffer,
IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
&IdLength, TRUE);
Irp->IoStatus.Status = NtStatus;
if (NT_SUCCESS(NtStatus)) {
Irp->IoStatus.Information = IdLength;
} else {
Irp->IoStatus.Information = 0;
}
break;
case IOCTL_PAR_QUERY_DEVICE_ID :
// We always read the Device Id in Nibble Mode.
NtStatus = SppQueryDeviceId(Pdx,
Irp->AssociatedIrp.SystemBuffer,
IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
&IdLength, FALSE);
Irp->IoStatus.Status = NtStatus;
if( NT_SUCCESS( NtStatus ) ) {
DD((PCE)Pdx,DDT,"IOCTL_PAR_QUERY_ID - SUCCESS - size = %d\n", IdLength);
// Include terminating NULL in the string to copy back to user buffer
Irp->IoStatus.Information = IdLength + sizeof(CHAR);
} else if( NtStatus == STATUS_BUFFER_TOO_SMALL) {
DD((PCE)Pdx,DDT,"IOCTL_PAR_QUERY_ID - FAIL - BUFFER_TOO_SMALL - supplied= %d, required=%d\n",
IrpSp->Parameters.DeviceIoControl.OutputBufferLength, IdLength);
Irp->IoStatus.Information = 0;
} else {
DD((PCE)Pdx,DDT,"IOCTL_PAR_QUERY_ID - FAIL - QUERY ID FAILED\n");
Irp->IoStatus.Information = 0;
}
break;
case IOCTL_PAR_QUERY_DEVICE_ID_SIZE :
//
// Read the first two bytes of the Nibble Id, add room for the terminating NULL and
// return this to the caller.
//
NtStatus = SppQueryDeviceId(Pdx, NULL, 0, &IdLength, FALSE);
if (NtStatus == STATUS_BUFFER_TOO_SMALL) {
DD((PCE)Pdx,DDT,"IOCTL_PAR_QUERY_DEVICE_ID_SIZE - size required = %d\n", IdLength);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information =
sizeof(PAR_DEVICE_ID_SIZE_INFORMATION);
// include space for terminating NULL
((PPAR_DEVICE_ID_SIZE_INFORMATION)
Irp->AssociatedIrp.SystemBuffer)->DeviceIdSize = IdLength + sizeof(CHAR);
} else {
Irp->IoStatus.Status = NtStatus;
Irp->IoStatus.Information = 0;
}
break;
case IOCTL_PAR_PING :
// We need to do a quick terminate and negotiate of the current modes
NtStatus = ParPing(Pdx);
DD((PCE)Pdx,DDT,"ParDeviceIo:IOCTL_PAR_PING\n");
Irp->IoStatus.Status = NtStatus;
Irp->IoStatus.Information = 0;
break;
case IOCTL_INTERNAL_DISCONNECT_IDLE :
if ((Pdx->Connected) &&
(afpForward[Pdx->IdxForwardProtocol].fnDisconnect)) {
DD((PCE)Pdx,DDT,"ParDeviceIo:IOCTL_INTERNAL_DISCONNECT_IDLE: Calling afpForward.fnDisconnect\n");
afpForward[Pdx->IdxForwardProtocol].fnDisconnect (Pdx);
}
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
break;
case IOCTL_IEEE1284_NEGOTIATE:
{
PPARCLASS_NEGOTIATION_MASK ppnmMask = (PPARCLASS_NEGOTIATION_MASK)Irp->AssociatedIrp.SystemBuffer;
ParTerminate(Pdx);
Irp->IoStatus.Status = IeeeNegotiateMode(Pdx, ppnmMask->usReadMask, ppnmMask->usWriteMask);
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(PARCLASS_NEGOTIATION_MASK)) {
DD((PCE)Pdx,DDT, "ParDeviceIo: IOCTL_IEEE1284_NEGOTIATE Passed.\n");
ppnmMask->usReadMask = arpReverse[Pdx->IdxReverseProtocol].Protocol;
ppnmMask->usWriteMask = afpForward[Pdx->IdxForwardProtocol].Protocol;
Irp->IoStatus.Information = sizeof (PARCLASS_NEGOTIATION_MASK);
} else {
DD((PCE)Pdx,DDT, "ParDeviceIo: IOCTL_IEEE1284_NEGOTIATE failed.\n");
Irp->IoStatus.Information = 0;
}
}
break;
case IOCTL_PAR_GET_DEVICE_CAPS :
Pdx->BadProtocolModes = *((USHORT *) Irp->AssociatedIrp.SystemBuffer);
IeeeDetermineSupportedProtocols(Pdx);
*((USHORT *) Irp->AssociatedIrp.SystemBuffer) = Pdx->ProtocolModesSupported;
Irp->IoStatus.Information = sizeof(Pdx->ProtocolModesSupported);
Irp->IoStatus.Status = STATUS_SUCCESS;
break;
case IOCTL_PAR_SET_READ_ADDRESS:
{
PUCHAR pAddress = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
if (Pdx->ReverseInterfaceAddress != *pAddress) {
Pdx->ReverseInterfaceAddress = *pAddress;
Pdx->SetReverseAddress = TRUE;
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
}
break;
case IOCTL_PAR_SET_WRITE_ADDRESS :
{
PUCHAR pAddress = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
NtStatus = STATUS_SUCCESS;
if (Pdx->ForwardInterfaceAddress != *pAddress) {
Pdx->ForwardInterfaceAddress = *pAddress;
if (Pdx->Connected) {
if (afpForward[Pdx->IdxForwardProtocol].fnSetInterfaceAddress) {
if (Pdx->CurrentPhase != PHASE_FORWARD_IDLE &&
Pdx->CurrentPhase != PHASE_FORWARD_XFER) {
NtStatus = ParReverseToForward(Pdx);
}
if (NT_SUCCESS(NtStatus)) {
NtStatus = afpForward[Pdx->IdxForwardProtocol].fnSetInterfaceAddress(
Pdx,
Pdx->ForwardInterfaceAddress
);
}
if (NT_SUCCESS(NtStatus)) {
Pdx->SetForwardAddress = FALSE;
Pdx->SetReverseAddress = FALSE;
Pdx->ReverseInterfaceAddress = *pAddress;
} else {
Pdx->SetForwardAddress = TRUE;
DD((PCE)Pdx,DDE,"ParDeviceIo: IOCTL_PAR_SET_WRITE_ADDRESS Failed\n");
}
} else {
DD((PCE)Pdx,DDE, "ParDeviceIo: Someone called IOCTL_PAR_SET_WRITE_ADDRESS.\n");
DD((PCE)Pdx,DDE, "ParDeviceIo: You don't have a fnSetInterfaceAddress.\n");
DD((PCE)Pdx,DDE, "ParDeviceIo: Either IEEE1284.c has wrong info or your caller is in error!\n");
NtStatus = STATUS_UNSUCCESSFUL;
}
} else {
Pdx->SetForwardAddress = TRUE;
}
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = NtStatus;
}
break;
case IOCTL_INTERNAL_LOCK_PORT :
ParpIoctlThreadLockPort(Pdx);
break;
case IOCTL_INTERNAL_UNLOCK_PORT :
ParpIoctlThreadUnlockPort(Pdx);
break;
case IOCTL_INTERNAL_LOCK_PORT_NO_SELECT:
DD((PCE)Pdx,DDT, "ParDeviceIo - IOCTL_INTERNAL_LOCK_PORT_NO_SELECT\n");
Pdx->AllocatedByLockPort = TRUE;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
break;
case IOCTL_INTERNAL_UNLOCK_PORT_NO_DESELECT:
DD((PCE)Pdx,DDT, "ParDeviceIo - IOCTL_INTERNAL_UNLOCK_PORT_NO_DESELECT\n");
Pdx->AllocatedByLockPort = FALSE;
PptAssert(!Pdx->Connected && !Pdx->AllocatedByLockPort);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
break;
case IOCTL_SERIAL_SET_TIMEOUTS:
{
PSERIAL_TIMEOUTS ptoNew = Irp->AssociatedIrp.SystemBuffer;
//
// The only other thing let through is setting
// the timer start.
//
Pdx->TimerStart = ptoNew->WriteTotalTimeoutConstant / 1000;
Irp->IoStatus.Status = STATUS_SUCCESS;
}
break;
case IOCTL_INTERNAL_PARDOT3_CONNECT:
DD((PCE)Pdx,DDT,"IOCTL_INTERNAL_PARDOT3_CONNECT - Dispatch\n");
Irp->IoStatus.Status = ParDot3Connect(Pdx);
Irp->IoStatus.Information = 0;
break;
case IOCTL_INTERNAL_PARDOT3_DISCONNECT:
DD((PCE)Pdx,DDT,"IOCTL_INTERNAL_PARDOT3_DISCONNECT - Dispatch\n");
Irp->IoStatus.Status = ParDot3Disconnect(Pdx);
Irp->IoStatus.Information = 0;
break;
case IOCTL_INTERNAL_PARDOT3_SIGNAL:
if( Pdx->IdxReverseProtocol != NIBBLE_MODE ) {
PKEVENT Event;// = (PKEVENT)Irp->AssociatedIrp.SystemBuffer;
RtlCopyMemory(&Event, Irp->AssociatedIrp.SystemBuffer, sizeof(PKEVENT));
ASSERT_EVENT(Event);
DD((PCE)Pdx,DDT,"IOCTL_INTERNAL_PARDOT3_SIGNAL - Dispatch. Event [%x]\n", Event);
Pdx->P12843DL.Event = Event;
Pdx->P12843DL.bEventActive = TRUE;
Irp->IoStatus.Status = STATUS_SUCCESS;
} else {
// don't use signalling in NIBBLE mode - rely on dot4 polling
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
}
Irp->IoStatus.Information = 0;
break;
case IOCTL_INTERNAL_PARDOT3_RESET:
DD((PCE)Pdx,DDT,"IOCTL_INTERNAL_PARDOT3_RESET - Dispatch\n");
if (Pdx->P12843DL.fnReset)
Irp->IoStatus.Status = ((PDOT3_RESET_ROUTINE) (Pdx->P12843DL.fnReset))(Pdx);
else
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
break;
default:
//
// unrecognized IOCTL? - we should never get here because the
// dispatch routines should have filtered this out
//
// probably harmless, but we want to know if this happens
// so we can fix the problem elsewhere
ASSERTMSG("Unrecognized IOCTL in ParDeviceIo()\n",FALSE);
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -