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

📄 tlp3nt.c

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