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

📄 serial.c

📁 usb to rs232 虚拟RS232串口驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
SerialDoExternalNaming(IN PDEVICE_EXTENSION PDevExt,
                       IN PDRIVER_OBJECT PDrvObj)

/*++

Routine Description:

    This routine will be used to create a symbolic link
    to the driver name in the given object directory.

    It will also create an entry in the device map for
    this device - IF we could create the symbolic link.

Arguments:

    Extension - Pointer to the device extension.

Return Value:

    None.

--*/

{
   NTSTATUS status = STATUS_SUCCESS;
   HANDLE keyHandle;
   PWCHAR pRegName = NULL;
   ULONG bufLen;


   PAGED_CODE();

   status = IoOpenDeviceRegistryKey(PDevExt->PhysicalDeviceObject, PLUGPLAY_REGKEY_DEVICE,
                                    STANDARD_RIGHTS_READ, &keyHandle);

   //
   // Check to see if we are allowed to do external naming; if not,
   // then we just return success
   //


   if (status != STATUS_SUCCESS) {
      return status;
   }


   SerialGetRegistryKeyValue(keyHandle, L"SerialSkipExternalNaming",
                             sizeof(L"SerialSkipExternalNaming"),
                             &PDevExt->SkipNaming, sizeof(ULONG));

   if (PDevExt->SkipNaming) {
      ZwClose(keyHandle);
      return STATUS_SUCCESS;
   }

   status = SerialReadSymName(PDevExt, keyHandle, &PDevExt->SymbolicLinkName,
                              &pRegName);

   ZwClose (keyHandle);

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

   bufLen = wcslen(pRegName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);

   PDevExt->DosName.Buffer = USB2COM_ExAllocatePool(NonPagedPool, 64 + sizeof(WCHAR));

   if (!PDevExt->DosName.Buffer) {
      SerialDbgPrintEx(SERERRORS, "Couldn't allocate memory for Dos name\n");

      status =  STATUS_INSUFFICIENT_RESOURCES;
      goto SerialDoExternalNamingError;
   }


   PDevExt->DosName.MaximumLength = 64 + sizeof(WCHAR);

   //
   // Zero fill it.
   //

   PDevExt->DosName.Length = 0;

   RtlZeroMemory(PDevExt->DosName.Buffer,
                 PDevExt->DosName.MaximumLength);

   RtlAppendUnicodeToString(&PDevExt->DosName, pRegName);
   RtlZeroMemory(((PUCHAR)(&PDevExt->DosName.Buffer[0]))
                 + PDevExt->DosName.Length, sizeof(WCHAR));

   SerialDbgPrintEx(SERDIAG1, "DosName is %wZ\n", &PDevExt->DosName);

   status = IoCreateSymbolicLink (&PDevExt->SymbolicLinkName,
                                  &PDevExt->DeviceName);

   if (!NT_SUCCESS(status)) {

      //
      // Oh well, couldn't create the symbolic link.  No point
      // in trying to create the device map entry.
      //

      SerialDbgPrintEx(SERERRORS, "Couldn't create the symbolic link\n"
                       "for port %wZ\n", &PDevExt->DeviceName);

      goto SerialDoExternalNamingError;

   }

   PDevExt->CreatedSymbolicLink = TRUE;

   status = RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP, L"SERIALCOMM",
                                   PDevExt->DeviceName.Buffer, REG_SZ,
                                   PDevExt->DosName.Buffer,
                                   PDevExt->DosName.Length + sizeof(WCHAR));

   if (!NT_SUCCESS(status)) {

      SerialDbgPrintEx(SERERRORS, "Couldn't create the device map entry\n"
                       "------- for port %wZ\n", &PDevExt->DeviceName);

      goto SerialDoExternalNamingError;
   }

   PDevExt->CreatedSerialCommEntry = TRUE;

   //
   // Make the device visible via a device association as well.
   // The reference string is the eight digit device index
   //

   status = IoRegisterDeviceInterface(PDevExt->PhysicalDeviceObject, (LPGUID)&GUID_CLASS_COMPORT,
                                      NULL, &PDevExt->DeviceClassSymbolicName);

   if (!NT_SUCCESS(status)) {
      SerialDbgPrintEx(SERERRORS, "Couldn't register class association\n"
                       "for port %wZ\n", &PDevExt->DeviceName);

      PDevExt->DeviceClassSymbolicName.Buffer = NULL;
      goto SerialDoExternalNamingError;
   }


   //
   // Now set the symbolic link for the association
   //

   status = IoSetDeviceInterfaceState(&PDevExt->DeviceClassSymbolicName,
                                         TRUE);

   if (!NT_SUCCESS(status)) {
      SerialDbgPrintEx(SERERRORS, "Couldn't set class association\n"
                       " for port %wZ\n", &PDevExt->DeviceName);
   }

   SerialDoExternalNamingError:;

   //
   // Clean up error conditions
   //

   if (!NT_SUCCESS(status)) {
      if (PDevExt->DosName.Buffer != NULL) {
         USB2COM_ExFreePool(PDevExt->DosName.Buffer);
         PDevExt->DosName.Buffer = NULL;
      }

      if (PDevExt->CreatedSymbolicLink ==  TRUE) {
         IoDeleteSymbolicLink(&PDevExt->SymbolicLinkName);
         PDevExt->CreatedSymbolicLink = FALSE;
      }

      if (PDevExt->SymbolicLinkName.Buffer != NULL) {
         ExFreePool(PDevExt->SymbolicLinkName.Buffer);
         PDevExt->SymbolicLinkName.Buffer = NULL;
      }

      if (PDevExt->DeviceName.Buffer != NULL) {
         RtlDeleteRegistryValue(RTL_REGISTRY_DEVICEMAP, L"SERIALCOMM",
                                PDevExt->DeviceName.Buffer);
      }

      if (PDevExt->DeviceClassSymbolicName.Buffer) {
         IoSetDeviceInterfaceState(&PDevExt->DeviceClassSymbolicName, FALSE);
         USB2COM_ExFreePool(PDevExt->DeviceClassSymbolicName.Buffer);
         PDevExt->DeviceClassSymbolicName.Buffer = NULL;
      }

   }

   //
   // Always clean up our temp buffers.
   //

   if (pRegName != NULL) {
      USB2COM_ExFreePool(pRegName);
   }

   return status;
}





VOID
SerialUndoExternalNaming(IN PDEVICE_EXTENSION Extension)

/*++

Routine Description:

    This routine will be used to delete a symbolic link
    to the driver name in the given object directory.

    It will also delete an entry in the device map for
    this device if the symbolic link had been created.

Arguments:

    Extension - Pointer to the device extension.

Return Value:

    None.

--*/

{

   NTSTATUS status;
   HANDLE keyHandle;

   PAGED_CODE();

   SerialDbgPrintEx(SERDIAG3, "In SerialUndoExternalNaming for\n"
                    "extension: %x of port %wZ\n",
                    Extension,&Extension->DeviceName);

   //
   // Maybe there is nothing for us to do
   //

   if (Extension->SkipNaming) {
      return;
   }

   //
   // We're cleaning up here.  One reason we're cleaning up
   // is that we couldn't allocate space for the directory
   // name or the symbolic link.
   //

   if (Extension->SymbolicLinkName.Buffer && Extension->CreatedSymbolicLink) {

      if (Extension->DeviceClassSymbolicName.Buffer) {
         status = IoSetDeviceInterfaceState(&Extension->DeviceClassSymbolicName,
                                            FALSE);

         //
         // IoRegisterDeviceClassInterface() allocated this string for us,
         // and we no longer need it.
         //

         USB2COM_ExFreePool(Extension->DeviceClassSymbolicName.Buffer);
         Extension->DeviceClassSymbolicName.Buffer = NULL;
	 ExFreePool(Extension->SymbolicLinkName.Buffer);
	 Extension->SymbolicLinkName.Buffer = NULL;
      }

      //
      // Before we delete the symlink, re-read the PortName
      // from the registry in case we were renamed in user mode.
      //

      status = IoOpenDeviceRegistryKey(Extension->PhysicalDeviceObject, PLUGPLAY_REGKEY_DEVICE,
                                       STANDARD_RIGHTS_READ, &keyHandle);

      if (status == STATUS_SUCCESS) {
         UNICODE_STRING symLinkName;
         PWCHAR pRegName;

         RtlInitUnicodeString(&symLinkName, NULL);

         status = SerialReadSymName(Extension, keyHandle, &symLinkName,
                                    &pRegName);

         if (status == STATUS_SUCCESS) {

            SerialDbgPrintEx(SERDIAG1, "Deleting Link %wZ\n", &symLinkName);
            IoDeleteSymbolicLink(&symLinkName);

            USB2COM_ExFreePool(symLinkName.Buffer);
            USB2COM_ExFreePool(pRegName);
         }

         ZwClose(keyHandle);
      }
   }

   //
   // We're cleaning up here.  One reason we're cleaning up
   // is that we couldn't allocate space for the NtNameOfPort.
   //

   if ((Extension->DeviceName.Buffer != NULL)
        && Extension->CreatedSerialCommEntry) {

      status = RtlDeleteRegistryValue(RTL_REGISTRY_DEVICEMAP, L"SERIALCOMM",
                                     Extension->DeviceName.Buffer);

      if (!NT_SUCCESS(status)) {

         SerialDbgPrintEx(SERERRORS, "Couldn't delete value entry %wZ\n",
                          &Extension->DeviceName);

      }
      USB2COM_ExFreePool(Extension->DeviceName.Buffer);
      Extension->DeviceName.Buffer = NULL;
   }
   if (Extension->DosName.Buffer != NULL) {
         USB2COM_ExFreePool(Extension->DosName.Buffer);
         Extension->DosName.Buffer = NULL;
   }
}

⌨️ 快捷键说明

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