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

📄 pnp.c

📁 串口Windows驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
                     pResDesc->ShareDisposition = CmResourceShareDriverExclusive;
                     SerialDbgPrintEx(SERPNPPOWER, "Sharing I/O port for "
                                      "device %x\n", pLowerDevObj);
                  }
                  break;

               case CmResourceTypeInterrupt:
                  if (!gotInt) {
                     gotInt = 1;
                     if (pResDesc->ShareDisposition != CmResourceShareShared) {
                        pResDesc->ShareDisposition = CmResourceShareDriverExclusive;
                        SerialDbgPrintEx(SERPNPPOWER, "Sharing interrupt "
                                         "for device %x\n", pLowerDevObj);
                     } else {
                        pDevExt->InterruptShareable = TRUE;
                        SerialDbgPrintEx(SERPNPPOWER, "Globally sharing"
                                         " interrupt for device %x\n",
                                         pLowerDevObj);
                     }
                  }
                  break;

               default:
                  break;
               }

               //
               // If we found what we need, we can break out of the loop
               //

               if ((isMulti && gotInt && gotISR) || (!isMulti && gotInt)) {
                  break;
               }
            }

            pResList = (PIO_RESOURCE_LIST)((PUCHAR)pResList
                                           + sizeof(IO_RESOURCE_LIST)
                                           + sizeof(IO_RESOURCE_DESCRIPTOR)
                                           * (pResList->Count - 1));
         }



         PIrp->IoStatus.Status = STATUS_SUCCESS;
         SerialCompleteRequest(pDevExt, PIrp, IO_NO_INCREMENT);
         return STATUS_SUCCESS;
      }

   case IRP_MN_QUERY_PNP_DEVICE_STATE:
      {
         if (pDevExt->Flags & SERIAL_FLAGS_BROKENHW) {
            (PNP_DEVICE_STATE)PIrp->IoStatus.Information |= PNP_DEVICE_FAILED;

            PIrp->IoStatus.Status = STATUS_SUCCESS;
         }

         IoCopyCurrentIrpStackLocationToNext(PIrp);
         return SerialIoCallDriver(pDevExt, pLowerDevObj, PIrp);
      }

   case IRP_MN_STOP_DEVICE:
      {
         ULONG pendingIRPs;
         KIRQL oldIrql;

         SerialDbgPrintEx(SERPNPPOWER, "Got IRP_MN_STOP_DEVICE Irp\n");
         SerialDbgPrintEx(SERPNPPOWER, "for device %x\n", pLowerDevObj);



         ASSERT(!pDevExt->PortOnAMultiportCard);


         SerialSetFlags(pDevExt, SERIAL_FLAGS_STOPPED);
         SerialSetAccept(pDevExt,SERIAL_PNPACCEPT_STOPPED);
         SerialClearAccept(pDevExt, SERIAL_PNPACCEPT_STOPPING);

         pDevExt->PNPState = SERIAL_PNP_STOPPING;

         //
         // From this point on all non-PNP IRP's will be queued
         //

         //
         // Decrement for entry here
         //

         InterlockedDecrement(&pDevExt->PendingIRPCnt);

         //
         // Decrement for stopping
         //

         pendingIRPs = InterlockedDecrement(&pDevExt->PendingIRPCnt);

         if (pendingIRPs) {
            KeWaitForSingleObject(&pDevExt->PendingIRPEvent, Executive,
                                  KernelMode, FALSE, NULL);
         }

         //
         // Re-increment the count for later
         //

         InterlockedIncrement(&pDevExt->PendingIRPCnt);

         //
         // We need to free resources...basically this is a remove
         // without the detach from the stack.
         //

         if (pDevExt->Flags & SERIAL_FLAGS_STARTED) {
            SerialReleaseResources(pDevExt);
         }

         //
         // Pass the irp down
         //

         PIrp->IoStatus.Status = STATUS_SUCCESS;
         IoSkipCurrentIrpStackLocation(PIrp);

         return IoCallDriver(pLowerDevObj, PIrp);
      }

   case IRP_MN_QUERY_STOP_DEVICE:
      {
         KIRQL oldIrql;

         SerialDbgPrintEx(SERPNPPOWER, "Got IRP_MN_QUERY_STOP_DEVICE Irp\n");
         SerialDbgPrintEx(SERPNPPOWER, "for device %x\n", pLowerDevObj);

         //
         // See if we should succeed a stop query
         //


         if (pDevExt->PortOnAMultiportCard) {
            PIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
            SerialDbgPrintEx(SERPNPPOWER, "------- failing; multiport node\n");
            SerialCompleteRequest(pDevExt, PIrp, IO_NO_INCREMENT);
            return STATUS_NOT_SUPPORTED;
         }

         //
         // If the device hasn't started yet, we ignore this request
         // and just pass it down.
         //

         if (pDevExt->PNPState != SERIAL_PNP_STARTED) {
            IoSkipCurrentIrpStackLocation(PIrp);
            return SerialIoCallDriver(pDevExt, pLowerDevObj, PIrp);
         }

         //
         // Lock around the open status
         //

         ExAcquireFastMutex(&pDevExt->OpenMutex);

         if (pDevExt->DeviceIsOpened) {
            ExReleaseFastMutex(&pDevExt->OpenMutex);
            PIrp->IoStatus.Status = STATUS_DEVICE_BUSY;
            SerialDbgPrintEx(SERPNPPOWER, "failing; device open\n");
            SerialCompleteRequest(pDevExt, PIrp, IO_NO_INCREMENT);
            return STATUS_DEVICE_BUSY;
         }

         pDevExt->PNPState = SERIAL_PNP_QSTOP;

         SerialSetAccept(pDevExt, SERIAL_PNPACCEPT_STOPPING);
         //
         // Unlock around the open status
         //

         ExReleaseFastMutex(&pDevExt->OpenMutex);

         PIrp->IoStatus.Status = STATUS_SUCCESS;
         IoCopyCurrentIrpStackLocationToNext(PIrp);
         return SerialIoCallDriver(pDevExt, pLowerDevObj, PIrp);
      }

   case IRP_MN_CANCEL_STOP_DEVICE:
      SerialDbgPrintEx(SERPNPPOWER, "Got IRP_MN_CANCEL_STOP_DEVICE Irp\n");
      SerialDbgPrintEx(SERPNPPOWER, "for device %x\n", pLowerDevObj);

      if (pDevExt->PNPState == SERIAL_PNP_QSTOP) {
         //
         // Restore the device state
         //

         pDevExt->PNPState = SERIAL_PNP_STARTED;
         SerialClearAccept(pDevExt, SERIAL_PNPACCEPT_STOPPING);
      }

      PIrp->IoStatus.Status = STATUS_SUCCESS;
      IoCopyCurrentIrpStackLocationToNext(PIrp);
      return SerialIoCallDriver(pDevExt, pLowerDevObj, PIrp);

   case IRP_MN_CANCEL_REMOVE_DEVICE:

      SerialDbgPrintEx(SERPNPPOWER, "Got IRP_MN_CANCEL_REMOVE_DEVICE Irp\n");
      SerialDbgPrintEx(SERPNPPOWER, "for device %x\n", pLowerDevObj);

      //
      // Restore the device state
      //

      pDevExt->PNPState = SERIAL_PNP_STARTED;
      SerialClearAccept(pDevExt, SERIAL_PNPACCEPT_REMOVING);

      PIrp->IoStatus.Status = STATUS_SUCCESS;
      IoCopyCurrentIrpStackLocationToNext(PIrp);
      return SerialIoCallDriver(pDevExt, pLowerDevObj, PIrp);

   case IRP_MN_QUERY_REMOVE_DEVICE:
      {
         KIRQL oldIrql;
         SerialDbgPrintEx(SERPNPPOWER, "Got IRP_MN_QUERY_REMOVE_DEVICE Irp\n");
         SerialDbgPrintEx(SERPNPPOWER, "for device %x\n", pLowerDevObj);

         ExAcquireFastMutex(&pDevExt->OpenMutex);

         //
         // See if we should succeed a remove query
         //

         if (pDevExt->DeviceIsOpened) {
            ExReleaseFastMutex(&pDevExt->OpenMutex);
            PIrp->IoStatus.Status = STATUS_DEVICE_BUSY;
            SerialDbgPrintEx(SERPNPPOWER, "failing; device open\n");
            SerialCompleteRequest(pDevExt, PIrp, IO_NO_INCREMENT);
            return STATUS_DEVICE_BUSY;
         }

         pDevExt->PNPState = SERIAL_PNP_QREMOVE;
         SerialSetAccept(pDevExt, SERIAL_PNPACCEPT_REMOVING);
         ExReleaseFastMutex(&pDevExt->OpenMutex);

         PIrp->IoStatus.Status = STATUS_SUCCESS;
         IoCopyCurrentIrpStackLocationToNext(PIrp);
         return SerialIoCallDriver(pDevExt, pLowerDevObj, PIrp);
      }

   case IRP_MN_SURPRISE_REMOVAL:
      {
         ULONG pendingIRPs;
         KIRQL oldIrql;

         SerialDbgPrintEx(SERPNPPOWER, "Got IRP_MN_SURPRISE_REMOVAL Irp\n");
         SerialDbgPrintEx(SERPNPPOWER, "for device %x\n", pLowerDevObj);

         //
         // Prevent any new I/O to the device
         //

         SerialSetAccept(pDevExt, SERIAL_PNPACCEPT_SURPRISE_REMOVING);

         //
         // Dismiss all pending requests
         //

         SerialKillPendingIrps(PDevObj);

         //
         // Wait for any pending requests we raced on.
         //

         //
         // Decrement once for ourselves
         //

         InterlockedDecrement(&pDevExt->PendingIRPCnt);

         //
         // Decrement for the remove
         //

         pendingIRPs = InterlockedDecrement(&pDevExt->PendingIRPCnt);

         if (pendingIRPs) {
            KeWaitForSingleObject(&pDevExt->PendingIRPEvent, Executive,
                                  KernelMode, FALSE, NULL);
         }

         //
         // Reset for subsequent remove
         //

         InterlockedIncrement(&pDevExt->PendingIRPCnt);

         //
         // Remove any external interfaces and release resources
         //

         SerialDisableInterfacesResources(PDevObj, FALSE);

         PIrp->IoStatus.Status = STATUS_SUCCESS;
         IoSkipCurrentIrpStackLocation(PIrp);

         return SerialIoCallDriver(pDevExt, pLowerDevObj, PIrp);
      }

   case IRP_MN_REMOVE_DEVICE:

      {
         ULONG pendingIRPs;
         KIRQL oldIrql;

         SerialDbgPrintEx(SERPNPPOWER, "Got IRP_MN_REMOVE_DEVICE Irp\n");
         SerialDbgPrintEx(SERPNPPOWER, "for device %x\n", pLowerDevObj);

         //
         // If we get this, we have to remove
         //

         //
         // Mark as not accepting requests
         //

         SerialSetAccept(pDevExt, SERIAL_PNPACCEPT_REMOVING);

         //
         // Complete all pending requests
         //

         SerialKillPendingIrps(PDevObj);

         //
         // Decrement for this Irp itself
         //

         InterlockedDecrement(&pDevExt->PendingIRPCnt);

         //
         // Wait for any pending requests we raced on -- this decrement
         // is for our "placeholder".
         //

         pendingIRPs = InterlockedDecrement(&pDevExt->PendingIRPCnt);

         if (pendingIRPs) {
            KeWaitForSingleObject(&pDevExt->PendingIRPEvent, Executive,
                                  KernelMode, FALSE, NULL);
         }

         //
         // Remove us
         //

         SerialRemoveDevObj(PDevObj);


         //
         // Pass the irp down
         //

         PIrp->IoStatus.Status = STATUS_SUCCESS;

         IoCopyCurrentIrpStackLocationToNext(PIrp);

         //
         // We do decrement here because we incremented on entry here.
         //

         return IoCallDriver(pLowerDevObj, PIrp);
      }

   default:
      break;



   }   // switch (pIrpStack->MinorFunction)

   //
   // Pass to driver beneath us
   //

   IoSkipCurrentIrpStackLocation(PIrp);
   status = SerialIoCallDriver(pDevExt, pLowerDevObj, PIrp);
   return status;
}



UINT32
SerialReportMaxBaudRate(ULONG Bauds)
/*++

Routine Description:

    This routine returns the max baud rate given a selection of rates

Arguments:

   Bauds  -  Bit-encoded list of supported bauds


  Return Value:

   The max baud rate listed in Bauds

--*/
{
   PAGED_CODE();

   if (Bauds & SERIAL_BAUD_128K) {
      return (128U * 1024U);
   }

   if (Bauds & SERIAL_BAUD_115200) {
      return 115200U;
   }

   if (Bauds & SERIAL_BAUD_56K) {
      return (56U * 1024U);
   }

   if (Bauds & SERIAL_BAUD_57600) {
      return 57600U;
   }

   if (Bauds & SERIAL_BAUD_38400) {
      return 38400U;
   }

   if (Bauds & SERIAL_BAUD_19200) {
      return 19200U;
   }

   if (Bauds & SERIAL_BAUD_14400) {
      return 14400U;
   }

   if (Bauds & SERIAL_BAUD_9600) {
      return 9600U;
   }

   if (Bauds & SERIAL_BAUD_7200) {
      return 7200U;
   }

   if (Bauds & SERIAL_BAUD_4800) {
      return 4800U;
   }

   if (Bauds & SERIAL_BAUD_2400) {
      return 2400U;
   }

   if (Bauds & SERIAL_BAUD_1800) {
      return 1800U;
   }

   if (Bauds & SERIAL_BAUD_1200) {

⌨️ 快捷键说明

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