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

📄 enum.c

📁 enumerates Plug-n-Play RS-232 devices that are compliant with the current revision of Plug and Play
💻 C
📖 第 1 页 / 共 4 页
字号:

      Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE, ("Setting DTR...\n"));

      status = Serenum_IoSyncIoctl(IOCTL_SERIAL_SET_DTR, FALSE,
                                   FdoData->TopOfStack, &event, &IoStatusBlock);

      if (!NT_SUCCESS(status)) {
         goto EnumerationDone;
      }

      //
      // First iteration is for modems
      // Therefore wait for 200 ms as per protocol for getting PNP string out
      //

      if (!i) {
         status = Serenum_Wait(&timer, defaultTime);
         if (!NT_SUCCESS(status)) {
            Serenum_KdPrint (FdoData, SER_DBG_SS_ERROR,
                             ("Timer failed with status %x\n", status ));
            goto EnumerationDone;
         }
      }

      //
      // set RTS
      //

      Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE, ("Setting RTS...\n"));

      status = Serenum_IoSyncIoctl(IOCTL_SERIAL_SET_RTS, FALSE,
                                   FdoData->TopOfStack, &event, &IoStatusBlock);

      if (!NT_SUCCESS(status)) {
         goto EnumerationDone;
      }

      //
      // Read from the serial port
      //
      Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
                      ("Reading the serial port...\n"));

      Serenum_KdPrint(FdoData, SER_DBG_SS_INFO, ("Address: %x\n", ReadBuffer));

      nActual = 0;

#if DBG
      RtlFillMemory(ReadBuffer, MAX_DEVNODE_NAME, 0xff);
#endif

      //
      // Flush the input buffer
      //

      status = Serenum_ReadSerialPort(ReadBuffer, MAX_DEVNODE_NAME,
                                      defaultSerialTime, &nActual,
                                      &IoStatusBlock, FdoData);

      switch (status) {
      case STATUS_TIMEOUT:
         if (nActual == 0) {
            Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
                      ("Timeout with no bytes read; continuing\n"));
            continue;
         }
         break;

      case STATUS_SUCCESS:
         Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
                         ("Read succeeded\n"));
         goto EnumerationDone;
         break;

      default:
         Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
                         ("Read failed with 0x%x\n", status));
         goto EnumerationDone;
         break;
      }

      //
      // If anything was read from the serial port, we're done!
      //

      if (nActual) {
         break;
      }
   }

   //
   // If DSR wasn't set, then a jump will be made here, and any existing
   // pdos will be eliminated
   //

EnumerationDone:;

   if (basicSettingsDone) {
      Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
                      ("Restoring basic settings\n"));

      Serenum_IoSyncIoctlEx(IOCTL_SERIAL_INTERNAL_RESTORE_SETTINGS, TRUE,
                            FdoData->TopOfStack, &event, &IoStatusBlock,
                            &basicSettings, sizeof(basicSettings), NULL, 0);
   } else {
      Serenum_IoSyncIoctlEx(IOCTL_SERIAL_SET_TIMEOUTS, FALSE,
                            FdoData->TopOfStack, &event, &IoStatusBlock,
                            &timeouts, sizeof(timeouts), NULL, 0);
   }

   //
   // Cleanup and then Close
   //
   Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
                   ("Cleanup on the serial port...\n"));

   status = Serenum_IoSyncReqWithIrp(Irp, IRP_MJ_CLEANUP, &event,
                                     FdoData->TopOfStack);

#if DBG
   if (!NT_SUCCESS(status)) {
      Serenum_KdPrint(FdoData, SER_DBG_SS_ERROR,
                      ("Failed to cleanup the serial port...\n"));
      // don't return because we want to attempt to close!
   }
#endif

   //
   // Close the Serial port after everything is done
   //

   Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
                   ("Closing the serial port...\n"));

   status = Serenum_IoSyncReqWithIrp(Irp, IRP_MJ_CLOSE, &event,
                                     FdoData->TopOfStack);

   if (!NT_SUCCESS(status)) {
      Serenum_KdPrint(FdoData, SER_DBG_SS_ERROR,
                      ("Failed to close the serial port...\n"));
      Irp->AssociatedIrp.SystemBuffer = stack->Parameters.Others.Argument1;
      return status;
   }

   //
   // Check if anything was read, and if not, we're done
   //

   if (nActual == 0) {
      if (ReadBuffer != NULL) {
         ExFreePool(ReadBuffer);
      }

      if (pdo != NULL) {
         //
         // Something was there.  The device must have been unplugged.
         // Remove the PDO.
         //

         Serenum_PDO_EnumMarkMissing(FdoData, pdo->DeviceExtension);
         pdo = NULL;
      }

      goto ExitReenumerate;
   }

   Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
                   ("Something was read from the serial port...\n"));



#if DBG
   if (FdoData->DebugLevel & SER_DBG_PNP_DUMP_PACKET) {
      ULONG dmpi;
      ULONG col;

      DbgPrint("SERENUM: Raw Data Packet on probe\n");


      for (dmpi = 0; dmpi < ((ULONG)nActual / 20); dmpi++) {
         DbgPrint("-------: ");
         for (col = 0; col < 20; col++) {
            DbgPrint("%02x ", (unsigned char)ReadBuffer[dmpi * 20 + col]);
         }

         DbgPrint(" ");
         for (col = 0; col < 20; col++) {
            if (__isascii(ReadBuffer[dmpi * 20 + col])
                && (ReadBuffer[dmpi * 20 + col] > ' ')) {
               DbgPrint("%c", ReadBuffer[dmpi * 20 + col]);
            } else {
               DbgPrint(".");
            }
         }

         DbgPrint("\n");
      }

      if (nActual % 20) {

         DbgPrint("-------: ");

         for (col = 0; col < ((ULONG)nActual % 20); col++) {
            DbgPrint("%02x ", (unsigned char)ReadBuffer[dmpi * 20 + col]);
         }

         for (col = 0; col < (20 - ((ULONG)nActual % 20)); col++) {
            DbgPrint("   ");
         }

         for (col = 0; col < ((ULONG)nActual % 20); col++) {
            if (__isascii(ReadBuffer[dmpi * 20 + col])
                && (ReadBuffer[dmpi * 20 + col] > ' ')) {
               DbgPrint("%c", ReadBuffer[dmpi * 20 + col]);
            } else {
               DbgPrint(".");
            }

         }

         DbgPrint("\n");
      }


   }
#endif

   //
   // Determine from the result whether the current pdo (if we have one),
   // should be deleted.  If it's the same device, then keep it.  If it's a
   // different device or if the device is a legacy device, then create a
   // new pdo.
   //
   if (legacyPotential) {

      PCHAR mouseId = ReadBuffer;
      ULONG charCnt;

      SerenumScanOtherIdForMouse(ReadBuffer, nActual, &mouseId);

      if (mouseId != NULL) {
         //
         // A legacy device is attached to the serial port, since DSR was
         // not set when RTS was set.
         // If we find a mouse from the readbuffer, copy the appropriate
         // strings into the hardwareIDs and CompIDs manually.
         //
         if (*mouseId == 'M') {
            if ((mouseId - ReadBuffer) > 1 && mouseId[1] == '3') {
               Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE, ("*PNP0F08 mouse\n"));
               Serenum_InitMultiString(FdoData, &HardwareIDs, "*PNP0F08",
                                       NULL);
               Serenum_InitMultiString(FdoData, &CompIDs, "SERIAL_MOUSE",
                                       NULL);
               //
               // ADRIAO CIMEXCIMEX 04/28/1999 -
               //     Device ID's should be unique, at least as unique as the
               // hardware ID's. This ID should really be Serenum\\PNP0F08
               //
               Serenum_InitMultiString(FdoData, &DeviceIDs, "Serenum\\Mouse",
                                       NULL);
               legacyFound = TRUE;

               Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
                               ("Buffers at 0x%x 0x%x 0x%x\n",
                                HardwareIDs.Buffer, CompIDs.Buffer,
                                DeviceIDs.Buffer));

            } else {
               Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE, ("*PNP0F01 mouse\n"));
               Serenum_InitMultiString(FdoData, &HardwareIDs, "*PNP0F01", NULL);
               Serenum_InitMultiString(FdoData, &CompIDs, "SERIAL_MOUSE", NULL);
               //
               // ADRIAO CIMEXCIMEX 04/28/1999 -
               //     Device ID's should be unique, at least as unique as the
               // hardware ID's. This ID should really be Serenum\\PNP0F01
               //
               Serenum_InitMultiString(FdoData, &DeviceIDs, "Serenum\\Mouse",
                                       NULL);
               legacyFound = TRUE;

               Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
                               ("Buffers at 0x%x 0x%x 0x%x\n",
                                HardwareIDs.Buffer, CompIDs.Buffer,
                                DeviceIDs.Buffer));
            }
         } else if (*mouseId == 'B') {
            Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE, ("*PNP0F09 mouse\n"));
            Serenum_InitMultiString(FdoData, &HardwareIDs, "*PNP0F09", NULL);
            Serenum_InitMultiString(FdoData, &CompIDs, "*PNP0F0F",
                                    "SERIAL_MOUSE", NULL);
            //
            // ADRIAO CIMEXCIMEX 04/28/1999 -
            //     Device ID's should be unique, at least as unique as the
            // hardware ID's. This ID should really be Serenum\\PNP0F09
            //
            Serenum_InitMultiString(FdoData, &DeviceIDs, "Serenum\\BallPoint",
                                    NULL);
            legacyFound = TRUE;

            Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
                            ("Buffers at 0x%x 0x%x 0x%x\n",
                             HardwareIDs.Buffer, CompIDs.Buffer,
                             DeviceIDs.Buffer));
         }
      }
   }

   if (!legacyFound) {
      //
      // A legacy device wasn't found.  Even if DSR wasn't set, it could
      // just be a broken PNP device, so check here by parsing the
      // PNP COM ID
      //
      if (!NT_SUCCESS(Serenum_ParseData(FdoData, ReadBuffer, nActual,
                                        &HardwareIDs, &CompIDs, &DeviceIDs,
                                        &DevDesc))) {
         Serenum_KdPrint(FdoData, SER_DBG_SS_ERROR,
                         ("Failed to parse the data for the new device\n"));

         //
         // Legacy device.  Remove the current pdo and make a new one
         // so that always pops up message asking for new device driver.
         //

         if (pdo) {
            Serenum_PDO_EnumMarkMissing(FdoData, pdo->DeviceExtension);
            pdo = NULL;
         }

         ExFreePool(ReadBuffer);

         goto ExitReenumerate;
      }
   }

   //
   // We're now finally able to free this read buffer.
   //

   if (ReadBuffer != NULL) {
      ExFreePool(ReadBuffer);
   }

   //
   // Check if the current device is the same as the one that we're
   // enumerating.  If so, we'll just keep the current pdo.
   //
   if (pdo) {
      pdoData = pdo->DeviceExtension;

      //
      // ADRIAO CIMEXCIMEX 04/28/1999 -
      //     We should be comparing device ID's here, but the above mentioned
      // bug must be fixed first. Note that even this code is broken as it
      // doesn't take into account that hardware/compID's are multiSz.
      //

      if (!(RtlEqualUnicodeString(&pdoData->HardwareIDs, &HardwareIDs, FALSE)
            && RtlEqualUnicodeString(&pdoData->CompIDs, &CompIDs, FALSE))) {
         //
         // The ids are not the same, so get rid of this pdo and create a
         // new one so that the PNP system will query the ids and find a
         // new driver
         //
         Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE, ("Different device."
                                                     " Removing PDO %x\n",
                                                     pdo));
         Serenum_PDO_EnumMarkMissing(FdoData, pdoData);
         pdo = NULL;
      } else {
         Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
                         ("Same device. Keeping current Pdo %x\n", pdo));
      }
   }

   //
   // If there isn't a pdo, then create one!
   //
   if (!pdo) {
      //
      // Allocate a pdo
      //
      status = IoCreateDevice(FdoData->Self->DriverObject,

⌨️ 快捷键说明

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