mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1125 lines
37 KiB
1125 lines
37 KiB
/*++
|
|
|
|
Copyright (C) Microsoft Corporation, 1998 - 1999
|
|
|
|
File Name:
|
|
|
|
ioctl.c
|
|
|
|
Contained in Module:
|
|
|
|
parallel.sys
|
|
|
|
Abstract:
|
|
|
|
This file contains functions associated with ParClass IOCTL processing.
|
|
|
|
- The three main entry points in this file are:
|
|
|
|
- ParDeviceControl() - Dispatch function for non-internal IOCTLs
|
|
|
|
- ParInternalDeviceControl() - Dispatch function for internal IOCTLs
|
|
|
|
- ParDeviceIo() - Worker thread entry point for handling all
|
|
IOCTLs not completed in a dispatch function
|
|
|
|
- Helper/Utility function naming conventions:
|
|
|
|
- ParpIoctlDispatch...() - private helper function called by dispatch function
|
|
|
|
- ParpIoctlThread...() - private helper function called by worker thread
|
|
|
|
Authors:
|
|
|
|
Anthony V. Ercolano 1-Aug-1992
|
|
Norbert P. Kusters 22-Oct-1993
|
|
Douglas G. Fritz 24-Jul-1998
|
|
|
|
Revision History :
|
|
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
#include "readwrit.h" // require declaration for ParReverseToForward()
|
|
|
|
|
|
VOID
|
|
ParpIoctlThreadLockPort(
|
|
IN PDEVICE_EXTENSION Extension
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PIRP irp = Extension->CurrentOpIrp;
|
|
|
|
ParDump2(PARIOCTL2, ("ParDeviceIo::IOCTL_INTERNAL_LOCK_PORT - attempting to acquire LockPortMutex\n") );
|
|
// ExAcquireFastMutex (&Extension->LockPortMutex);
|
|
ParDump2(PARIOCTL2, ("ParDeviceIo::IOCTL_INTERNAL_LOCK_PORT - LockPortMutex acquired\n") );
|
|
|
|
Extension->AllocatedByLockPort = TRUE;
|
|
|
|
// - begin
|
|
ParDump2(PARIOCTL2, ("ParDeviceIo::IOCTL_INTERNAL_LOCK_PORT - attempting to Select Device\n") );
|
|
|
|
// dvdr if( ParSelectDevice(Extension,FALSE) ) {
|
|
if( ParSelectDevice(Extension,TRUE) ) {
|
|
ParDump2(PARIOCTL2, ("ParDeviceIo::IOCTL_INTERNAL_LOCK_PORT - Select Device - SUCCESS\n") );
|
|
status = STATUS_SUCCESS;
|
|
} else {
|
|
ParDump2(PARIOCTL2, ("ParDeviceIo::IOCTL_INTERNAL_LOCK_PORT - Select Device - FAIL\n") );
|
|
status = STATUS_UNSUCCESSFUL;
|
|
Extension->AllocatedByLockPort = FALSE;
|
|
ParDump2(PARIOCTL2, ("ParDeviceIo::IOCTL_INTERNAL_LOCK_PORT - Releasing LockPortMutex\n") );
|
|
// ExReleaseFastMutex (&Extension->LockPortMutex);
|
|
ParDump2(PARIOCTL2, ("ParDeviceIo::IOCTL_INTERNAL_LOCK_PORT - Released LockPortMutex\n") );
|
|
}
|
|
// - end
|
|
|
|
irp->IoStatus.Status = status;
|
|
}
|
|
|
|
VOID
|
|
ParpIoctlThreadUnlockPort(
|
|
IN PDEVICE_EXTENSION Extension
|
|
)
|
|
{
|
|
PIRP irp = Extension->CurrentOpIrp;
|
|
|
|
ParDump2(PARIOCTL2, ("ParDeviceIo::IOCTL_INTERNAL_UNLOCK_PORT\n") );
|
|
|
|
Extension->AllocatedByLockPort = FALSE;
|
|
|
|
if( ParDeselectDevice(Extension, FALSE) ) {
|
|
ParDump2(PARIOCTL2, ("ParDeviceIo::IOCTL_INTERNAL_UNLOCK_PORT - Device Deselected\n") );
|
|
} else {
|
|
ParDump2(PARIOCTL2, ("ParDeviceIo::IOCTL_INTERNAL_UNLOCK_PORT - Device Deselect FAILED\n") );
|
|
}
|
|
|
|
ParDump2(PARIOCTL2, ("ParDeviceIo::IOCTL_INTERNAL_UNLOCK_PORT - Releasing LockMutex\n") );
|
|
// ExReleaseFastMutex (&Extension->LockPortMutex);
|
|
ParDump2(PARIOCTL2, ("ParDeviceIo::IOCTL_INTERNAL_UNLOCK_PORT - Released LockMutex\n") );
|
|
|
|
irp->IoStatus.Status = STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
IoctlTest(PIRP Irp, PIO_STACK_LOCATION IrpSp, PDEVICE_EXTENSION Extension) {
|
|
|
|
// if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(PAR_SET_INFORMATION)) {}
|
|
// if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PAR_QUERY_INFORMATION)) {}
|
|
// Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
ParDump2(PARIOCTL2, ("IoctlTest - Irp= %x , IrpSp= %x , Extension= %x\n", Irp, IrpSp, Extension) );
|
|
|
|
ParDump2(PARIOCTL2, ("OutputBufferLength= %d, sizeof(PARALLEL_WMI_LOG_INFO)= %d\n",
|
|
IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
|
|
sizeof(PARALLEL_WMI_LOG_INFO) ) );
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(PPARALLEL_WMI_LOG_INFO)) {
|
|
PPARALLEL_WMI_LOG_INFO buffer = (PPARALLEL_WMI_LOG_INFO)Irp->AssociatedIrp.SystemBuffer;
|
|
*buffer = Extension->log;
|
|
Irp->IoStatus.Information = sizeof(PARALLEL_WMI_LOG_INFO);
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
ParCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_SUCCESS;
|
|
} else {
|
|
Irp->IoStatus.Information = 0;
|
|
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
|
|
ParCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_BUFFER_TOO_SMALL;
|
|
}
|
|
}
|
|
|
|
NTSTATUS
|
|
ParDeviceControl(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is the dispatch for device control requests.
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - Supplies the device object.
|
|
|
|
Irp - Supplies the I/O request packet.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - Success.
|
|
STATUS_PENDING - Request pending.
|
|
STATUS_BUFFER_TOO_SMALL - Buffer too small.
|
|
STATUS_INVALID_PARAMETER - Invalid io control request.
|
|
STATUS_DELETE_PENDING - This device object is being deleted
|
|
|
|
--*/
|
|
|
|
{
|
|
PIO_STACK_LOCATION IrpSp;
|
|
PPAR_SET_INFORMATION SetInfo;
|
|
NTSTATUS Status;
|
|
PSERIAL_TIMEOUTS SerialTimeouts;
|
|
PDEVICE_EXTENSION Extension;
|
|
KIRQL OldIrql;
|
|
// PPARCLASS_INFORMATION pParclassInfo;
|
|
|
|
|
|
ParDump2(PARIOCTL2, ("Enter ParDeviceControl(...)\n") );
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
Extension = DeviceObject->DeviceExtension;
|
|
|
|
//
|
|
// bail out if a delete is pending for this device object
|
|
//
|
|
if(Extension->DeviceStateFlags & PAR_DEVICE_DELETE_PENDING) {
|
|
Irp->IoStatus.Status = STATUS_DELETE_PENDING;
|
|
ParCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_DELETE_PENDING;
|
|
}
|
|
|
|
//
|
|
// bail out if a remove is pending for our ParPort device object
|
|
//
|
|
if(Extension->DeviceStateFlags & PAR_DEVICE_PORT_REMOVE_PENDING) {
|
|
Irp->IoStatus.Status = STATUS_DELETE_PENDING;
|
|
ParCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_DELETE_PENDING;
|
|
}
|
|
|
|
//
|
|
// bail out if device has been removed
|
|
//
|
|
if(Extension->DeviceStateFlags & (PAR_DEVICE_REMOVED|PAR_DEVICE_SURPRISE_REMOVAL) ) {
|
|
|
|
Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
|
|
ParCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_DEVICE_REMOVED;
|
|
}
|
|
|
|
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
|
|
|
|
#if 0
|
|
case IOCTL_PAR_TEST:
|
|
|
|
return IoctlTest(Irp, IrpSp, Extension);
|
|
#endif
|
|
|
|
case IOCTL_PAR_SET_INFORMATION:
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL_PAR_SET_INFORMATION\n") );
|
|
|
|
SetInfo = Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
|
|
sizeof(PAR_SET_INFORMATION)) {
|
|
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
} else if (SetInfo->Init != PARALLEL_INIT) {
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
} else {
|
|
|
|
//
|
|
// This is a parallel reset
|
|
//
|
|
Status = STATUS_PENDING;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_PAR_QUERY_INFORMATION :
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL_PAR_QUERY_INFORMATION - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
|
|
sizeof(PAR_QUERY_INFORMATION)) {
|
|
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
} else {
|
|
Status = STATUS_PENDING;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_SERIAL_SET_TIMEOUTS:
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL_SERIAL_SET_TIMEOUTS - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
|
|
SerialTimeouts = Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
|
|
sizeof(SERIAL_TIMEOUTS)) {
|
|
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
} else if (SerialTimeouts->WriteTotalTimeoutConstant < 2000) {
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
} else {
|
|
Status = STATUS_PENDING;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_SERIAL_GET_TIMEOUTS:
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL_SERIAL_GET_TIMEOUTS - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
|
|
SerialTimeouts = Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
|
|
sizeof(SERIAL_TIMEOUTS)) {
|
|
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
} else {
|
|
|
|
//
|
|
// We don't need to synchronize the read.
|
|
//
|
|
|
|
RtlZeroMemory(SerialTimeouts, sizeof(SERIAL_TIMEOUTS));
|
|
SerialTimeouts->WriteTotalTimeoutConstant =
|
|
1000 * Extension->TimerStart;
|
|
|
|
Irp->IoStatus.Information = sizeof(SERIAL_TIMEOUTS);
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_PAR_QUERY_DEVICE_ID:
|
|
case IOCTL_PAR_QUERY_RAW_DEVICE_ID:
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL_PAR_QUERY_DEVICE_ID - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0) {
|
|
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
} else {
|
|
Status = STATUS_PENDING;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_PAR_QUERY_DEVICE_ID_SIZE:
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL_PAR_QUERY_DEVICE_ID_SIZE - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
|
|
sizeof(PAR_DEVICE_ID_SIZE_INFORMATION)) {
|
|
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
} else {
|
|
Status = STATUS_PENDING;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_PAR_IS_PORT_FREE:
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL_PAR_IS_PORT_FREE - %wZ\n", &Extension->SymbolicLinkName));
|
|
|
|
if( IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(BOOLEAN) ) {
|
|
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
} else {
|
|
|
|
if( Extension->bAllocated ) {
|
|
// if we have the port then it is not free
|
|
*((PBOOLEAN)Irp->AssociatedIrp.SystemBuffer) = FALSE;
|
|
} else {
|
|
// determine if the port is free by trying to allocate and free it
|
|
// - our alloc/free will only succeed if no one else has the port
|
|
BOOLEAN tryAllocSuccess = Extension->TryAllocatePort( Extension->PortContext );
|
|
if( tryAllocSuccess ) {
|
|
// we were able to allocate the port, free it and report that the port is free
|
|
Extension->FreePort( Extension->PortContext );
|
|
*((PBOOLEAN)Irp->AssociatedIrp.SystemBuffer) = TRUE;
|
|
} else {
|
|
// we were unable to allocate the port, someone else must be using the port
|
|
*((PBOOLEAN)Irp->AssociatedIrp.SystemBuffer) = FALSE;
|
|
}
|
|
}
|
|
|
|
Irp->IoStatus.Information = sizeof(BOOLEAN);
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
break;
|
|
|
|
case IOCTL_PAR_GET_READ_ADDRESS:
|
|
ParDump2(PARIOCTL2, ("IOCTL_PAR_GET_READ_ADDRESS - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
|
|
sizeof(Extension->ReverseInterfaceAddress))
|
|
{
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
}
|
|
else
|
|
{
|
|
*((PUCHAR) Irp->AssociatedIrp.SystemBuffer) = Extension->ReverseInterfaceAddress;
|
|
Irp->IoStatus.Information = sizeof(Extension->ReverseInterfaceAddress);
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_PAR_GET_WRITE_ADDRESS:
|
|
ParDump2(PARIOCTL2, ("IOCTL_PAR_GET_WRITE_ADDRESS - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
|
|
sizeof(Extension->ForwardInterfaceAddress))
|
|
{
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
}
|
|
else
|
|
{
|
|
*((PUCHAR) Irp->AssociatedIrp.SystemBuffer) = Extension->ForwardInterfaceAddress;
|
|
Irp->IoStatus.Information = sizeof(Extension->ForwardInterfaceAddress);
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_PAR_SET_READ_ADDRESS:
|
|
|
|
ParDump2(PARIOCTL2, (" IOCTL_PAR_SET_READ_ADDRESS - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(Extension->ReverseInterfaceAddress)) {
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
} else {
|
|
|
|
Status = STATUS_PENDING;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_PAR_SET_WRITE_ADDRESS:
|
|
|
|
ParDump2(PARIOCTL2, (" IOCTL_PAR_SET_WRITE_ADDRESS - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(Extension->ForwardInterfaceAddress)) {
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
} else {
|
|
|
|
Status = STATUS_PENDING;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_IEEE1284_GET_MODE:
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL_IEEE1284_GET_MODE - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
|
|
sizeof(PARCLASS_NEGOTIATION_MASK)) {
|
|
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
} else {
|
|
|
|
PPARCLASS_NEGOTIATION_MASK ppnmMask;
|
|
|
|
ppnmMask = (PPARCLASS_NEGOTIATION_MASK)Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
ppnmMask->usReadMask =
|
|
arpReverse[Extension->IdxReverseProtocol].Protocol;
|
|
|
|
ppnmMask->usWriteMask =
|
|
afpForward[Extension->IdxForwardProtocol].Protocol;
|
|
|
|
Irp->IoStatus.Information = sizeof (PARCLASS_NEGOTIATION_MASK);
|
|
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_PAR_GET_DEFAULT_MODES:
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL_IEEE1284_GET_MODE - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
|
|
sizeof(PARCLASS_NEGOTIATION_MASK)) {
|
|
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
} else {
|
|
|
|
PPARCLASS_NEGOTIATION_MASK ppnmMask;
|
|
|
|
ppnmMask = (PPARCLASS_NEGOTIATION_MASK)Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
ppnmMask->usReadMask = NONE;
|
|
ppnmMask->usWriteMask = CENTRONICS;
|
|
|
|
Irp->IoStatus.Information = sizeof (PARCLASS_NEGOTIATION_MASK);
|
|
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_PAR_ECP_HOST_RECOVERY:
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL_PAR_ECP_HOST_RECOVERY - %wZ\n", &Extension->SymbolicLinkName) );
|
|
{
|
|
BOOLEAN *isSupported;
|
|
|
|
if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(BOOLEAN) ) {
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
} else {
|
|
isSupported = (BOOLEAN *)Irp->AssociatedIrp.SystemBuffer;
|
|
Extension->bIsHostRecoverSupported = *isSupported;
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IOCTL_PAR_PING:
|
|
ParDump2(PARIOCTL2, ("IOCTL_PAR_PING - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
// No Parms to check!
|
|
Status = STATUS_PENDING;
|
|
break;
|
|
|
|
case IOCTL_PAR_GET_DEVICE_CAPS:
|
|
ParDump2(PARIOCTL2, ("IOCTL_PAR_GET_DEVICE_CAPS - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
|
|
sizeof(Extension->ProtocolModesSupported)) {
|
|
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
} else {
|
|
Status = STATUS_PENDING;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_IEEE1284_NEGOTIATE:
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL_IEEE1284_NEGOTIATE - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
|
|
if ( IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(PARCLASS_NEGOTIATION_MASK) ||
|
|
IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PARCLASS_NEGOTIATION_MASK) ) {
|
|
ParDump2(PARERRORS, ( "ParDeviceControl: IOCTL_IEEE1284_NEGOTIATE STATUS_INVALID_PARAMETER.\n" ));
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
} else {
|
|
|
|
PPARCLASS_NEGOTIATION_MASK ppnmMask;
|
|
|
|
ppnmMask = (PPARCLASS_NEGOTIATION_MASK)Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
if ((ppnmMask->usReadMask == arpReverse[Extension->IdxReverseProtocol].Protocol) &&
|
|
(ppnmMask->usWriteMask == afpForward[Extension->IdxForwardProtocol].Protocol))
|
|
{
|
|
Irp->IoStatus.Information = sizeof (PARCLASS_NEGOTIATION_MASK);
|
|
ParDump2(PARINFO, ( "ParDeviceControl: IOCTL_IEEE1284_NEGOTIATE Passed.\n" ));
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
Status = STATUS_PENDING;
|
|
}
|
|
break;
|
|
|
|
default :
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL default case\n") );
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
if (Status == STATUS_PENDING) {
|
|
|
|
IoAcquireCancelSpinLock(&OldIrql);
|
|
|
|
if (Irp->Cancel) {
|
|
|
|
IoReleaseCancelSpinLock(OldIrql);
|
|
Status = STATUS_CANCELLED;
|
|
|
|
} else {
|
|
|
|
//
|
|
// This IRP takes more time, so it should be queued.
|
|
//
|
|
BOOLEAN needToSignalSemaphore = IsListEmpty( &Extension->WorkQueue );
|
|
IoMarkIrpPending(Irp);
|
|
IoSetCancelRoutine(Irp, ParCancelRequest);
|
|
InsertTailList(&Extension->WorkQueue, &Irp->Tail.Overlay.ListEntry);
|
|
IoReleaseCancelSpinLock(OldIrql);
|
|
if( needToSignalSemaphore ) {
|
|
KeReleaseSemaphore(&Extension->RequestSemaphore, 0, 1, FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Status != STATUS_PENDING) {
|
|
|
|
Irp->IoStatus.Status = Status;
|
|
ParCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
ParInternalDeviceControl(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is the dispatch for internal device control requests.
|
|
|
|
Arguments:
|
|
|
|
DeviceObject - Supplies the device object.
|
|
|
|
Irp - Supplies the I/O request packet.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS - Success.
|
|
STATUS_PENDING - Request pending.
|
|
STATUS_BUFFER_TOO_SMALL - Buffer too small.
|
|
STATUS_INVALID_PARAMETER - Invalid io control request.
|
|
STATUS_DELETE_PENDING - This device object is being deleted
|
|
|
|
--*/
|
|
|
|
{
|
|
PIO_STACK_LOCATION IrpSp;
|
|
// PPAR_SET_INFORMATION SetInfo;
|
|
NTSTATUS Status;
|
|
// PSERIAL_TIMEOUTS SerialTimeouts;
|
|
PDEVICE_EXTENSION Extension;
|
|
KIRQL OldIrql;
|
|
PPARCLASS_INFORMATION pParclassInfo;
|
|
|
|
ParDump2(PARIOCTL2, ("Enter ParInternalDeviceControl(...)\n") );
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
|
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
Extension = DeviceObject->DeviceExtension;
|
|
|
|
//
|
|
// bail out if a delete is pending for this device object
|
|
//
|
|
if(Extension->DeviceStateFlags & PAR_DEVICE_DELETE_PENDING) {
|
|
Irp->IoStatus.Status = STATUS_DELETE_PENDING;
|
|
ParCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
ParDump2(PARIOCTL2, ("ParInternalDeviceControl(...) - returning DELETE_PENDING\n") );
|
|
return STATUS_DELETE_PENDING;
|
|
}
|
|
|
|
//
|
|
// bail out if a remove is pending for our ParPort device object
|
|
//
|
|
if(Extension->DeviceStateFlags & PAR_DEVICE_PORT_REMOVE_PENDING) {
|
|
Irp->IoStatus.Status = STATUS_DELETE_PENDING;
|
|
ParCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
ParDump2(PARIOCTL2, ("ParInternalDeviceControl(...) - returning DELETE_PENDING\n") );
|
|
return STATUS_DELETE_PENDING;
|
|
}
|
|
|
|
//
|
|
// bail out if device has been removed
|
|
//
|
|
if(Extension->DeviceStateFlags & (PAR_DEVICE_REMOVED|PAR_DEVICE_SURPRISE_REMOVAL) ) {
|
|
|
|
Irp->IoStatus.Status = STATUS_DEVICE_REMOVED;
|
|
ParCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
return STATUS_DEVICE_REMOVED;
|
|
}
|
|
|
|
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
|
|
|
|
case IOCTL_INTERNAL_PARCLASS_CONNECT:
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL_INTERNAL_PARCLASS_CONNECT - Dispatch\n") );
|
|
ParDump2(PARIOCTL2, ("IOCTL_INTERNAL_PARCLASS_CONNECT - %wZ\n",
|
|
&Extension->SymbolicLinkName) );
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength <
|
|
sizeof(PARCLASS_INFORMATION)) {
|
|
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
} else {
|
|
|
|
pParclassInfo = Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
pParclassInfo->Controller = Extension->Controller;
|
|
pParclassInfo->EcrController = Extension->EcrController;
|
|
pParclassInfo->SpanOfController = Extension->SpanOfController;
|
|
pParclassInfo->ParclassContext = Extension;
|
|
pParclassInfo->HardwareCapabilities = Extension->HardwareCapabilities;
|
|
pParclassInfo->FifoDepth = Extension->FifoDepth;
|
|
pParclassInfo->FifoWidth = Extension->FifoWidth;
|
|
pParclassInfo->DetermineIeeeModes = ParExportedDetermineIeeeModes;
|
|
pParclassInfo->TerminateIeeeMode = ParExportedTerminateIeeeMode;
|
|
pParclassInfo->NegotiateIeeeMode = ParExportedNegotiateIeeeMode;
|
|
pParclassInfo->IeeeFwdToRevMode = ParExportedIeeeFwdToRevMode;
|
|
pParclassInfo->IeeeRevToFwdMode = ParExportedIeeeRevToFwdMode;
|
|
pParclassInfo->ParallelRead = ParExportedParallelRead;
|
|
pParclassInfo->ParallelWrite = ParExportedParallelWrite;
|
|
|
|
Irp->IoStatus.Information = sizeof(PARCLASS_INFORMATION);
|
|
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
|
|
break;
|
|
|
|
case IOCTL_INTERNAL_PARCLASS_DISCONNECT:
|
|
|
|
Status = STATUS_SUCCESS;
|
|
break;
|
|
|
|
case IOCTL_INTERNAL_DISCONNECT_IDLE:
|
|
case IOCTL_INTERNAL_LOCK_PORT:
|
|
case IOCTL_INTERNAL_UNLOCK_PORT:
|
|
case IOCTL_INTERNAL_PARDOT3_CONNECT:
|
|
case IOCTL_INTERNAL_PARDOT3_RESET:
|
|
|
|
Status = STATUS_PENDING;
|
|
break;
|
|
|
|
case IOCTL_INTERNAL_PARDOT3_DISCONNECT:
|
|
|
|
// immediately tell worker thread to stop signalling
|
|
Extension->P12843DL.bEventActive = FALSE;
|
|
Status = STATUS_PENDING;
|
|
break;
|
|
|
|
case IOCTL_INTERNAL_PARDOT3_SIGNAL:
|
|
|
|
if( IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(PKEVENT) ) {
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
} else {
|
|
Status = STATUS_PENDING;
|
|
}
|
|
break;
|
|
|
|
default :
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL_INTERNAL... default case - Dispatch\n") );
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
|
|
if (Status == STATUS_PENDING) {
|
|
|
|
//
|
|
// This IRP takes more time, queue it for the worker thread
|
|
//
|
|
|
|
IoAcquireCancelSpinLock(&OldIrql);
|
|
|
|
if (Irp->Cancel) {
|
|
|
|
IoReleaseCancelSpinLock(OldIrql);
|
|
Status = STATUS_CANCELLED;
|
|
|
|
} else {
|
|
|
|
BOOLEAN needToSignalSemaphore = IsListEmpty( &Extension->WorkQueue );
|
|
IoMarkIrpPending(Irp);
|
|
IoSetCancelRoutine(Irp, ParCancelRequest);
|
|
InsertTailList(&Extension->WorkQueue, &Irp->Tail.Overlay.ListEntry);
|
|
IoReleaseCancelSpinLock(OldIrql);
|
|
if( needToSignalSemaphore ) {
|
|
KeReleaseSemaphore(&Extension->RequestSemaphore, 0, 1, FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Status != STATUS_PENDING) {
|
|
|
|
Irp->IoStatus.Status = Status;
|
|
ParCompleteRequest(Irp, IO_NO_INCREMENT);
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
VOID
|
|
ParDeviceIo(
|
|
IN PDEVICE_EXTENSION Extension
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine implements a DEVICE_IOCTL request with the extension's current irp.
|
|
|
|
Arguments:
|
|
|
|
Extension - Supplies the device extension.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
|
|
PIRP Irp;
|
|
PIO_STACK_LOCATION IrpSp;
|
|
ULONG IdLength;
|
|
NTSTATUS NtStatus;
|
|
UCHAR Status;
|
|
UCHAR Control;
|
|
ULONG ioControlCode;
|
|
|
|
// ParDump2(PARIOCTL2,("Enter ParDeviceIo(...)\n") );
|
|
|
|
Irp = Extension->CurrentOpIrp;
|
|
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
|
|
|
ioControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
|
|
|
|
switch( ioControlCode ) {
|
|
|
|
case IOCTL_PAR_SET_INFORMATION :
|
|
{
|
|
|
|
PPAR_SET_INFORMATION IrpBuffer = Extension->CurrentOpIrp->AssociatedIrp.SystemBuffer;
|
|
|
|
Status = ParInitializeDevice(Extension);
|
|
|
|
if (!PAR_OK(Status)) {
|
|
ParNotInitError(Extension, 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(Extension->Controller);
|
|
Control = GetControl(Extension->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(Extension,
|
|
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(Extension,
|
|
Irp->AssociatedIrp.SystemBuffer,
|
|
IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
|
|
&IdLength, FALSE);
|
|
|
|
Irp->IoStatus.Status = NtStatus;
|
|
|
|
if( NT_SUCCESS( NtStatus ) ) {
|
|
ParDump2(PARIOCTL1, ("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) {
|
|
ParDump2(PARIOCTL1, ("IOCTL_PAR_QUERY_ID - FAIL - BUFFER_TOO_SMALL - supplied= %d, required=%d\n",
|
|
IrpSp->Parameters.DeviceIoControl.OutputBufferLength, IdLength) );
|
|
Irp->IoStatus.Information = 0;
|
|
} else {
|
|
ParDump2(PARIOCTL1, ("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(Extension, NULL, 0, &IdLength, FALSE);
|
|
|
|
if (NtStatus == STATUS_BUFFER_TOO_SMALL) {
|
|
|
|
ParDump2(PARIOCTL1, ("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(Extension);
|
|
ParDump2(PARINFO, ("ParDeviceIo:IOCTL_PAR_PING\n"));
|
|
Irp->IoStatus.Status = NtStatus;
|
|
Irp->IoStatus.Information = 0;
|
|
break;
|
|
|
|
case IOCTL_INTERNAL_DISCONNECT_IDLE :
|
|
|
|
if ((Extension->Connected) &&
|
|
(afpForward[Extension->IdxForwardProtocol].fnDisconnect)) {
|
|
|
|
ParDump2(PARINFO, ("ParDeviceIo:IOCTL_INTERNAL_DISCONNECT_IDLE: Calling afpForward.fnDisconnect\n"));
|
|
afpForward[Extension->IdxForwardProtocol].fnDisconnect (Extension);
|
|
}
|
|
|
|
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(Extension);
|
|
Irp->IoStatus.Status = IeeeNegotiateMode(Extension, ppnmMask->usReadMask, ppnmMask->usWriteMask);
|
|
|
|
if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(PARCLASS_NEGOTIATION_MASK)) {
|
|
ParDump2(PARINFO, ( "ParDeviceIo: IOCTL_IEEE1284_NEGOTIATE Passed.\n" ));
|
|
ppnmMask->usReadMask = arpReverse[Extension->IdxReverseProtocol].Protocol;
|
|
ppnmMask->usWriteMask = afpForward[Extension->IdxForwardProtocol].Protocol;
|
|
Irp->IoStatus.Information = sizeof (PARCLASS_NEGOTIATION_MASK);
|
|
} else {
|
|
ParDump2(PARERRORS, ( "ParDeviceIo: IOCTL_IEEE1284_NEGOTIATE failed.\n" ));
|
|
Irp->IoStatus.Information = 0;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case IOCTL_PAR_GET_DEVICE_CAPS :
|
|
|
|
Extension->BadProtocolModes = *((USHORT *) Irp->AssociatedIrp.SystemBuffer);
|
|
IeeeDetermineSupportedProtocols(Extension);
|
|
*((USHORT *) Irp->AssociatedIrp.SystemBuffer) = Extension->ProtocolModesSupported;
|
|
Irp->IoStatus.Information = sizeof(Extension->ProtocolModesSupported);
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
break;
|
|
|
|
case IOCTL_PAR_SET_READ_ADDRESS:
|
|
{
|
|
PUCHAR pAddress = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
if (Extension->ReverseInterfaceAddress != *pAddress) {
|
|
|
|
Extension->ReverseInterfaceAddress = *pAddress;
|
|
Extension->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 (Extension->ForwardInterfaceAddress != *pAddress) {
|
|
|
|
Extension->ForwardInterfaceAddress = *pAddress;
|
|
|
|
if (Extension->Connected) {
|
|
if (afpForward[Extension->IdxForwardProtocol].fnSetInterfaceAddress) {
|
|
|
|
if (Extension->CurrentPhase != PHASE_FORWARD_IDLE &&
|
|
Extension->CurrentPhase != PHASE_FORWARD_XFER) {
|
|
NtStatus = ParReverseToForward(Extension);
|
|
}
|
|
|
|
if (NT_SUCCESS(NtStatus)) {
|
|
NtStatus = afpForward[Extension->IdxForwardProtocol].fnSetInterfaceAddress(
|
|
Extension,
|
|
Extension->ForwardInterfaceAddress
|
|
);
|
|
}
|
|
|
|
if (NT_SUCCESS(NtStatus)) {
|
|
Extension->SetForwardAddress = FALSE;
|
|
Extension->SetReverseAddress = FALSE;
|
|
Extension->ReverseInterfaceAddress = *pAddress;
|
|
} else {
|
|
Extension->SetForwardAddress = TRUE;
|
|
ParDump2(PARERRORS, ( "ParDeviceIo: IOCTL_PAR_SET_WRITE_ADDRESS Failed\n" ));
|
|
}
|
|
} else {
|
|
#if DBG
|
|
ParDump2(PARERRORS, ( "ParDeviceIo: Someone called IOCTL_PAR_SET_WRITE_ADDRESS.\n" ));
|
|
ParDump2(PARERRORS, ( "ParDeviceIo: You don't have a fnSetInterfaceAddress.\n" ));
|
|
ParDump2(PARERRORS, ( "ParDeviceIo: Either IEEE1284.c has wrong info or your caller is in error!\n" ));
|
|
NtStatus = STATUS_UNSUCCESSFUL;
|
|
#endif
|
|
}
|
|
} else {
|
|
Extension->SetForwardAddress = TRUE;
|
|
}
|
|
}
|
|
|
|
Irp->IoStatus.Information = 0;
|
|
Irp->IoStatus.Status = NtStatus;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_INTERNAL_LOCK_PORT :
|
|
|
|
ParpIoctlThreadLockPort(Extension);
|
|
break;
|
|
|
|
case IOCTL_INTERNAL_UNLOCK_PORT :
|
|
|
|
ParpIoctlThreadUnlockPort(Extension);
|
|
break;
|
|
|
|
case IOCTL_SERIAL_SET_TIMEOUTS:
|
|
{
|
|
PSERIAL_TIMEOUTS ptoNew = Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
//
|
|
// The only other thing let through is setting
|
|
// the timer start.
|
|
//
|
|
|
|
Extension->TimerStart = ptoNew->WriteTotalTimeoutConstant / 1000;
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
}
|
|
break;
|
|
|
|
case IOCTL_INTERNAL_PARDOT3_CONNECT:
|
|
ParDump2(PARIOCTL2, ("IOCTL_INTERNAL_PARDOT3_CONNECT - Dispatch\n") );
|
|
Irp->IoStatus.Status = ParDot3Connect(Extension);
|
|
Irp->IoStatus.Information = 0;
|
|
break;
|
|
case IOCTL_INTERNAL_PARDOT3_DISCONNECT:
|
|
ParDump2(PARIOCTL2, ("IOCTL_INTERNAL_PARDOT3_DISCONNECT - Dispatch\n") );
|
|
Irp->IoStatus.Status = ParDot3Disconnect(Extension);
|
|
Irp->IoStatus.Information = 0;
|
|
break;
|
|
case IOCTL_INTERNAL_PARDOT3_SIGNAL:
|
|
{
|
|
PKEVENT Event;// = (PKEVENT)Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
RtlCopyMemory(&Event, Irp->AssociatedIrp.SystemBuffer, sizeof(PKEVENT));
|
|
|
|
ASSERT_EVENT(Event);
|
|
|
|
ParDump2(PARIOCTL2, ("IOCTL_INTERNAL_PARDOT3_SIGNAL - Dispatch. Event [%x]\n", Event) );
|
|
|
|
Extension->P12843DL.Event = Event;
|
|
Extension->P12843DL.bEventActive = TRUE;
|
|
}
|
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
|
Irp->IoStatus.Information = 0;
|
|
break;
|
|
case IOCTL_INTERNAL_PARDOT3_RESET:
|
|
ParDump2(PARIOCTL2, ("IOCTL_INTERNAL_PARDOT3_RESET - Dispatch\n") );
|
|
if (Extension->P12843DL.fnReset)
|
|
Irp->IoStatus.Status = ((PDOT3_RESET_ROUTINE) (Extension->P12843DL.fnReset))(Extension);
|
|
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;
|
|
}
|