?? tlp3nt.c
字號:
NULL
);
ASSERT (STATUS_SUCCESS == status);
status = Irp->IoStatus.Status;
}
return status;
}
NTSTATUS
TLP3PnP(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
--*/
{
PUCHAR requestBuffer;
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
PREADER_EXTENSION readerExtension = smartcardExtension->ReaderExtension;
PDEVICE_OBJECT AttachedDeviceObject;
PIO_STACK_LOCATION irpStack;
IO_STATUS_BLOCK ioStatusBlock;
BOOLEAN deviceRemoved = FALSE, irpSkipped = FALSE;
KIRQL irql;
SmartcardDebug(
DEBUG_TRACE,
( "%s!TLP3PnPDeviceControl: Enter\n",
DRIVER_NAME)
);
status = SmartcardAcquireRemoveLockWithTag(smartcardExtension, ' PnP');
ASSERT(status == STATUS_SUCCESS);
if (status != STATUS_SUCCESS) {
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
AttachedDeviceObject = ATTACHED_DEVICE_OBJECT;
irpStack = IoGetCurrentIrpStackLocation(Irp);
// Now look what the PnP manager wants...
switch(irpStack->MinorFunction)
{
case IRP_MN_START_DEVICE:
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3PnPDeviceControl: IRP_MN_START_DEVICE\n",
DRIVER_NAME)
);
// We have to call the underlying driver first
status = TLP3CallSerialDriver(AttachedDeviceObject, Irp);
ASSERT(NT_SUCCESS(status));
if (NT_SUCCESS(status)) {
status = TLP3StartDevice(DeviceObject);
}
break;
case IRP_MN_QUERY_STOP_DEVICE:
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3PnPDeviceControl: IRP_MN_QUERY_STOP_DEVICE\n",
DRIVER_NAME)
);
KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
if (deviceExtension->IoCount > 0) {
// we refuse to stop if we have pending io
KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
status = STATUS_DEVICE_BUSY;
} else {
// stop processing requests
KeClearEvent(&deviceExtension->ReaderStarted);
KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
status = TLP3CallSerialDriver(AttachedDeviceObject, Irp);
}
break;
case IRP_MN_CANCEL_STOP_DEVICE:
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3PnPDeviceControl: IRP_MN_CANCEL_STOP_DEVICE\n",
DRIVER_NAME)
);
status = TLP3CallSerialDriver(AttachedDeviceObject, Irp);
if (status == STATUS_SUCCESS) {
// we can continue to process requests
KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
}
break;
case IRP_MN_STOP_DEVICE:
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3PnPDeviceControl: IRP_MN_STOP_DEVICE\n",
DRIVER_NAME)
);
TLP3StopDevice(DeviceObject);
//
// we don't do anything since a stop is only used
// to reconfigure hw-resources like interrupts and io-ports
//
status = TLP3CallSerialDriver(AttachedDeviceObject, Irp);
break;
case IRP_MN_QUERY_REMOVE_DEVICE:
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3PnPDeviceControl: IRP_MN_QUERY_REMOVE_DEVICE\n",
DRIVER_NAME)
);
// disable the interface (and ignore possible errors)
IoSetDeviceInterfaceState(
&deviceExtension->PnPDeviceName,
FALSE
);
// now look if someone is currently connected to us
if (deviceExtension->ReaderOpen) {
//
// someone is connected, fail the call
// we will enable the device interface in
// IRP_MN_CANCEL_REMOVE_DEVICE again
//
status = STATUS_UNSUCCESSFUL;
break;
}
// pass the call to the next driver in the stack
status = TLP3CallSerialDriver(AttachedDeviceObject, Irp);
break;
case IRP_MN_CANCEL_REMOVE_DEVICE:
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3PnPDeviceControl: IRP_MN_CANCEL_REMOVE_DEVICE\n",
DRIVER_NAME)
);
status = TLP3CallSerialDriver(AttachedDeviceObject, Irp);
//
// reenable the interface only in case that the reader is
// still connected. This covers the following case:
// hibernate machine, disconnect reader, wake up, stop device
// (from task bar) and stop fails since an app. holds the device open
//
if (status == STATUS_SUCCESS &&
READER_EXTENSION_L(SerialConfigData.SerialWaitMask) != 0) {
status = IoSetDeviceInterfaceState(
&deviceExtension->PnPDeviceName,
TRUE
);
ASSERT(status == STATUS_SUCCESS);
}
break;
case IRP_MN_REMOVE_DEVICE:
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3PnPDeviceControl: IRP_MN_REMOVE_DEVICE\n",
DRIVER_NAME)
);
TLP3RemoveDevice(DeviceObject);
status = TLP3CallSerialDriver(AttachedDeviceObject, Irp);
deviceRemoved = TRUE;
break;
default:
// This is an Irp that is only useful for underlying drivers
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3PnPDeviceControl: IRP_MN_...%lx\n",
DRIVER_NAME,
irpStack->MinorFunction)
);
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(AttachedDeviceObject, Irp);
irpSkipped = TRUE;
break;
}
if (irpSkipped == FALSE) {
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
if (deviceRemoved == FALSE) {
SmartcardReleaseRemoveLockWithTag(smartcardExtension, ' PnP');
}
SmartcardDebug(
DEBUG_TRACE,
( "%s!TLP3PnPDeviceControl: Exit %lx\n",
DRIVER_NAME,
status)
);
return status;
}
VOID
TLP3SystemPowerCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN UCHAR MinorFunction,
IN POWER_STATE PowerState,
IN PKEVENT Event,
IN PIO_STATUS_BLOCK IoStatus
)
/*++
Routine Description:
This function is called when the underlying stacks
completed the power transition.
--*/
{
UNREFERENCED_PARAMETER (DeviceObject);
UNREFERENCED_PARAMETER (MinorFunction);
UNREFERENCED_PARAMETER (PowerState);
UNREFERENCED_PARAMETER (IoStatus);
KeSetEvent(Event, 0, FALSE);
}
NTSTATUS
TLP3DevicePowerCompletion (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PSMARTCARD_EXTENSION SmartcardExtension
)
/*++
Routine Description:
This routine is called after the underlying stack powered
UP the serial port, so it can be used again.
--*/
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
LARGE_INTEGER delayPeriod;
//
// Allow the reader enough time to power itself up
//
delayPeriod.HighPart = -1;
delayPeriod.LowPart = 100000 * (-10);
KeDelayExecutionThread(
KernelMode,
FALSE,
&delayPeriod
);
//
// We issue a power request in order to figure out
// what the actual card status is
//
SmartcardExtension->MinorIoControlCode = SCARD_COLD_RESET;
TLP3ReaderPower(SmartcardExtension);
//
// If a card was present before power down or now there is
// a card in the reader, we complete any pending card monitor
// request, since we do not really know what card is now in the
// reader.
//
if(SmartcardExtension->ReaderExtension->CardPresent ||
SmartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT) {
TLP3CompleteCardTracking(SmartcardExtension);
}
// save the current power state of the reader
SmartcardExtension->ReaderExtension->ReaderPowerState =
PowerReaderWorking;
SmartcardReleaseRemoveLockWithTag(SmartcardExtension, 'rwoP');
// inform the power manager of our state.
PoSetPowerState (
DeviceObject,
DevicePowerState,
irpStack->Parameters.Power.State
);
PoStartNextPowerIrp(Irp);
// signal that we can process ioctls again
KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
return STATUS_SUCCESS;
}
typedef enum _ACTION {
Undefined = 0,
SkipRequest,
WaitForCompletion,
CompleteRequest,
MarkPending
} ACTION;
NTSTATUS
TLP3Power (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
The power dispatch routine.
This driver is the power policy owner of the device stack,
because this driver knows about the connected reader.
Therefor this driver will translate system power states
to device power states.
Arguments:
DeviceObject - pointer to a device object.
Irp - pointer to an I/O Request Packet.
Return Value:
NT status code
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
PDEVICE_OBJECT AttachedDeviceObject;
POWER_STATE powerState;
ACTION action = SkipRequest;
KEVENT event;
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3Power: Enter\n",
DRIVER_NAME)
);
status = SmartcardAcquireRemoveLockWithTag(smartcardExtension, 'rwoP');
ASSERT(status == STATUS_SUCCESS);
if (!NT_SUCCESS(status)) {
PoStartNextPowerIrp(Irp);
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
AttachedDeviceObject = ATTACHED_DEVICE_OBJECT;
switch (irpStack->Parameters.Power.Type) {
case DevicePowerState:
if (irpStack->MinorFunction == IRP_MN_SET_POWER) {
switch (irpStack->Parameters.Power.State.DeviceState) {
case PowerDeviceD0:
// Turn on the reader
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3Power: PowerDevice D0\n",
DRIVER_NAME)
);
//
// First, we send down the request to the bus, in order
// to power on the port. When the request completes,
// we turn on the reader
//
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine (
Irp,
TLP3DevicePowerCompletion,
smartcardExtension,
TRUE,
TRUE,
TRUE
);
action = WaitForCompletion;
break;
case PowerDeviceD3:
// Turn off the reader
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3Power: PowerDevice D3\n",
DRIVER_NAME)
);
PoSetPowerState (
DeviceObject,
DevicePowerState,
irpStack->Parameters.Power.State
);
// save the current card state
smartcardExtension->ReaderExtension->CardPresent =
smartcardExtension->ReaderCapabilities.CurrentState > SCARD_ABSENT;
if (smartcardExtension->ReaderExtension->CardPresent) {
smartcardExtension->MinorIoControlCode = SCARD_POWER_DOWN;
status = TLP3ReaderPower(smartcardExtension);
ASSERT(status == STATUS_SUCCESS);
}
//
// If there is a pending card tracking request, setting
// this flag will prevent completion of the request
// when the system will be waked up again.
//
smartcardExtension->ReaderExtension->PowerRequest = TRUE;
// save the current power state of the reader
smartcardExtension->ReaderExtension->ReaderPowerState =
PowerReaderOff;
action = SkipRequest;
break;
default:
ASSERT(FALSE);
action = SkipRequest;
break;
}
}
break;
case SystemPowerState: {
//
// The system wants to change the power state.
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -