📄 tlp3nt.c
字号:
// We need to translate the system power state to
// a corresponding device power state.
//
POWER_STATE_TYPE powerType = DevicePowerState;
ASSERT(smartcardExtension->ReaderExtension->ReaderPowerState !=
PowerReaderUnspecified);
switch (irpStack->MinorFunction) {
KIRQL irql;
case IRP_MN_QUERY_POWER:
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3Power: Query Power\n",
DRIVER_NAME)
);
switch (irpStack->Parameters.Power.State.SystemState) {
case PowerSystemMaximum:
case PowerSystemWorking:
case PowerSystemSleeping1:
case PowerSystemSleeping2:
action = SkipRequest;
break;
case PowerSystemSleeping3:
case PowerSystemHibernate:
case PowerSystemShutdown:
KeAcquireSpinLock(&deviceExtension->SpinLock, &irql);
if (deviceExtension->IoCount == 0) {
// Block any further ioctls
KeClearEvent(&deviceExtension->ReaderStarted);
action = SkipRequest;
} else {
// can't go to sleep mode since the reader is busy.
status = STATUS_DEVICE_BUSY;
action = CompleteRequest;
}
KeReleaseSpinLock(&deviceExtension->SpinLock, irql);
break;
}
break;
case IRP_MN_SET_POWER:
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3Power: PowerSystem S%d\n",
DRIVER_NAME,
irpStack->Parameters.Power.State.SystemState - 1)
);
switch (irpStack->Parameters.Power.State.SystemState) {
case PowerSystemMaximum:
case PowerSystemWorking:
case PowerSystemSleeping1:
case PowerSystemSleeping2:
if (smartcardExtension->ReaderExtension->ReaderPowerState ==
PowerReaderWorking) {
// We're already in the right state
KeSetEvent(&deviceExtension->ReaderStarted, 0, FALSE);
action = SkipRequest;
break;
}
// wake up the underlying stack...
powerState.DeviceState = PowerDeviceD0;
action = MarkPending;
break;
case PowerSystemSleeping3:
case PowerSystemHibernate:
case PowerSystemShutdown:
if (smartcardExtension->ReaderExtension->ReaderPowerState ==
PowerReaderOff) {
// We're already in the right state
action = SkipRequest;
break;
}
powerState.DeviceState = PowerDeviceD3;
// first, inform the power manager of our new state.
PoSetPowerState (
DeviceObject,
SystemPowerState,
powerState
);
action = MarkPending;
break;
default:
ASSERT(FALSE);
action = SkipRequest;
break;
}
break;
}
}
break;
default:
ASSERT(FALSE);
action = SkipRequest;
break;
}
switch (action) {
case CompleteRequest:
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
SmartcardReleaseRemoveLockWithTag(smartcardExtension, 'rwoP');
PoStartNextPowerIrp(Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
case MarkPending:
// initialize the event we need in the completion function
KeInitializeEvent(
&event,
NotificationEvent,
FALSE
);
// request the device power irp
status = PoRequestPowerIrp (
DeviceObject,
IRP_MN_SET_POWER,
powerState,
TLP3SystemPowerCompletion,
&event,
NULL
);
ASSERT(status == STATUS_PENDING);
if (status == STATUS_PENDING) {
// wait until the device power irp completed
status = KeWaitForSingleObject(
&event,
Executive,
KernelMode,
FALSE,
NULL
);
SmartcardReleaseRemoveLockWithTag(smartcardExtension, 'rwoP');
if (powerState.SystemState == PowerSystemWorking) {
PoSetPowerState (
DeviceObject,
SystemPowerState,
powerState
);
}
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
status = PoCallDriver(AttachedDeviceObject, Irp);
} else {
SmartcardReleaseRemoveLockWithTag(smartcardExtension, 'rwoP');
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
break;
case SkipRequest:
SmartcardReleaseRemoveLockWithTag(smartcardExtension, 'rwoP');
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
status = PoCallDriver(AttachedDeviceObject, Irp);
break;
case WaitForCompletion:
status = PoCallDriver(AttachedDeviceObject, Irp);
break;
default:
ASSERT(FALSE);
break;
}
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3Power: Exit %lx\n",
DRIVER_NAME,
status)
);
return status;
}
NTSTATUS
TLP3CreateClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is called by the I/O system when the device is opened or closed.
Arguments:
DeviceObject - Pointer to device object for this miniport
Irp - IRP involved.
Return Value:
STATUS_SUCCESS.
--*/
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS;
__try {
if (irpStack->MajorFunction == IRP_MJ_CREATE) {
status = SmartcardAcquireRemoveLockWithTag(
&deviceExtension->SmartcardExtension,
'lCrC'
);
if (status != STATUS_SUCCESS) {
status = STATUS_DEVICE_REMOVED;
__leave;
}
// test if the device has been opened already
if (InterlockedCompareExchange(
&deviceExtension->ReaderOpen,
TRUE,
FALSE) == FALSE) {
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3CreateClose: Open\n",
DRIVER_NAME)
);
} else {
// the device is already in use
status = STATUS_UNSUCCESSFUL;
// release the lock
SmartcardReleaseRemoveLockWithTag(
&deviceExtension->SmartcardExtension,
'lCrC'
);
}
} else {
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3CreateClose: Close\n",
DRIVER_NAME)
);
SmartcardReleaseRemoveLockWithTag(
&deviceExtension->SmartcardExtension,
'lCrC'
);
deviceExtension->ReaderOpen = FALSE;
}
}
__finally {
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
return status;
}
NTSTATUS
TLP3Cancel(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is called by the I/O system
when the irp should be cancelled
Arguments:
DeviceObject - Pointer to device object for this miniport
Irp - IRP involved.
Return Value:
STATUS_CANCELLED
--*/
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
SmartcardDebug(
DEBUG_TRACE,
("%s!TLP3Cancel: Enter\n",
DRIVER_NAME)
);
ASSERT(Irp == smartcardExtension->OsData->NotificationIrp);
IoReleaseCancelSpinLock(
Irp->CancelIrql
);
TLP3CompleteCardTracking(smartcardExtension);
SmartcardDebug(
DEBUG_TRACE,
("%s!TLP3Cancel: Exit\n",
DRIVER_NAME)
);
return STATUS_CANCELLED;
}
NTSTATUS
TLP3Cleanup(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is called when the calling application terminates.
We can actually only have the notification irp that we have to cancel.
--*/
{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PSMARTCARD_EXTENSION smartcardExtension = &deviceExtension->SmartcardExtension;
NTSTATUS status = STATUS_SUCCESS;
SmartcardDebug(
DEBUG_TRACE,
("%s!TLP3Cleanup: Enter\n",
DRIVER_NAME)
);
ASSERT(Irp != smartcardExtension->OsData->NotificationIrp);
// We need to complete the notification irp
TLP3CompleteCardTracking(smartcardExtension);
SmartcardDebug(
DEBUG_DRIVER,
("%s!TLP3Cleanup: Completing IRP %lx\n",
DRIVER_NAME,
Irp)
);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(
Irp,
IO_NO_INCREMENT
);
SmartcardDebug(
DEBUG_TRACE,
("%s!TLP3Cleanup: Exit\n",
DRIVER_NAME)
);
return STATUS_SUCCESS;
}
VOID
TLP3RemoveDevice(
PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
Remove the device from the system.
--*/
{
PDEVICE_EXTENSION deviceExtension;
PSMARTCARD_EXTENSION smartcardExtension;
NTSTATUS status;
PAGED_CODE();
if (DeviceObject == NULL) {
return;
}
deviceExtension = DeviceObject->DeviceExtension;
smartcardExtension = &deviceExtension->SmartcardExtension;
SmartcardDebug(
DEBUG_TRACE,
( "%s!TLP3RemoveDevice: Enter\n",
DRIVER_NAME)
);
if (smartcardExtension->OsData) {
// complete pending card tracking requests (if any)
TLP3CompleteCardTracking(smartcardExtension);
ASSERT(smartcardExtension->OsData->NotificationIrp == NULL);
// Wait until we can safely unload the device
SmartcardReleaseRemoveLockAndWait(smartcardExtension);
}
TLP3StopDevice(DeviceObject);
if (deviceExtension->SmartcardExtension.ReaderExtension &&
deviceExtension->SmartcardExtension.ReaderExtension->AttachedDeviceObject) {
IoDetachDevice(
deviceExtension->SmartcardExtension.ReaderExtension->AttachedDeviceObject
);
}
if(deviceExtension->PnPDeviceName.Buffer != NULL) {
RtlFreeUnicodeString(&deviceExtension->PnPDeviceName);
}
if(smartcardExtension->OsData != NULL) {
SmartcardExit(smartcardExtension);
}
if (smartcardExtension->ReaderExtension != NULL) {
ExFreePool(smartcardExtension->ReaderExtension);
}
if (deviceExtension->CloseSerial != NULL) {
IoFreeWorkItem(deviceExtension->CloseSerial);
}
IoDeleteDevice(DeviceObject);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -