⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tlp3nt.c

📁 SmardCard Windows驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
            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.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -