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

📄 hardware.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* Set 'ComponentInformation' value */
  SetComponentInformation(ControllerKey,
			  0x28,
			  0,
			  0xFFFFFFFF);

  /* Set 'Configuration Data' value */
  Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
	  2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
  FullResourceDescriptor = MmAllocateMemory(Size);
  if (FullResourceDescriptor == NULL)
    {
      DbgPrint((DPRINT_HWDETECT,
		"Failed to allocate resource descriptor\n"));
      return;
    }

  /* Initialize resource descriptor */
  memset(FullResourceDescriptor, 0, Size);
  FullResourceDescriptor->InterfaceType = Isa;
  FullResourceDescriptor->BusNumber = 0;
  FullResourceDescriptor->PartialResourceList.Version = 1;
  FullResourceDescriptor->PartialResourceList.Revision = 1;
  FullResourceDescriptor->PartialResourceList.Count = 3;

  /* Set Interrupt */
  PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0];
  PartialDescriptor->Type = CmResourceTypeInterrupt;
  PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
  PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
  PartialDescriptor->u.Interrupt.Level = 1;
  PartialDescriptor->u.Interrupt.Vector = 0;
  PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;

  /* Set IO Port 0x60 */
  PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[1];
  PartialDescriptor->Type = CmResourceTypePort;
  PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
  PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
  PartialDescriptor->u.Port.Start.LowPart = 0x60;
  PartialDescriptor->u.Port.Start.HighPart = 0x0;
  PartialDescriptor->u.Port.Length = 1;

  /* Set IO Port 0x64 */
  PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[2];
  PartialDescriptor->Type = CmResourceTypePort;
  PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
  PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
  PartialDescriptor->u.Port.Start.LowPart = 0x64;
  PartialDescriptor->u.Port.Start.HighPart = 0x0;
  PartialDescriptor->u.Port.Length = 1;

  /* Set 'Configuration Data' value */
  Error = RegSetValue(ControllerKey,
		      L"Configuration Data",
		      REG_FULL_RESOURCE_DESCRIPTOR,
		      (PCHAR)FullResourceDescriptor,
		      Size);
  MmFreeMemory(FullResourceDescriptor);
  if (Error != ERROR_SUCCESS)
    {
      DbgPrint((DPRINT_HWDETECT,
		"RegSetValue(Configuration Data) failed (Error %u)\n",
		(int)Error));
      return;
    }

  DetectKeyboardPeripheral(ControllerKey);
}


static VOID
PS2ControllerWait(VOID)
{
  ULONG Timeout;
  UCHAR Status;

  for (Timeout = 0; Timeout < CONTROLLER_TIMEOUT; Timeout++)
    {
      Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
      if ((Status & CONTROLLER_STATUS_INPUT_BUFFER_FULL) == 0)
	return;

      /* Sleep for one millisecond */
      StallExecutionProcessor(1000);
    }
}


static BOOLEAN
DetectPS2AuxPort(VOID)
{
#if 1
  /* Current detection is too unreliable. Just do as if
   * the PS/2 aux port is always present
   */
   return TRUE;
#else
  ULONG Loops;
  UCHAR Status;

  /* Put the value 0x5A in the output buffer using the
   * "WriteAuxiliary Device Output Buffer" command (0xD3).
   * Poll the Status Register for a while to see if the value really turns up
   * in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
   * to 1 in the Status Register, we assume this controller has an
   *  Auxiliary Port (a.k.a. Mouse Port).
   */
  PS2ControllerWait();
  WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
		   CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER);
  PS2ControllerWait();

  /* 0x5A is a random dummy value */
  WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA,
		   0x5A);

  for (Loops = 0; Loops < 10; Loops++)
    {
      StallExecutionProcessor(10000);
      Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
      if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
        break;
    }

  READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);

  return (Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL);
#endif
}


static BOOLEAN
DetectPS2AuxDevice(VOID)
{
  UCHAR Scancode;
  UCHAR Status;
  ULONG Loops;
  BOOLEAN Result = TRUE;

  PS2ControllerWait();
  WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
		   CONTROLLER_COMMAND_WRITE_MOUSE);
  PS2ControllerWait();

  /* Identify device */
  WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA,
		   0xF2);

  /* Wait for reply */
  for (Loops = 0; Loops < 100; Loops++)
    {
      StallExecutionProcessor(10000);
      Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
      if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
        break;
    }

  Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
  if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
    Result = FALSE;

  Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
  if (Scancode != 0xFA)
    Result = FALSE;

  StallExecutionProcessor(10000);

  Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
  if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
    Result = FALSE;

  Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
  if (Scancode != 0x00)
    Result = FALSE;

  return Result;
}


static VOID
DetectPS2Mouse(FRLDRHKEY BusKey)
{
  CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
  FRLDRHKEY ControllerKey;
  FRLDRHKEY PeripheralKey;
  LONG Error;

  if (DetectPS2AuxPort())
    {
      DbgPrint((DPRINT_HWDETECT, "Detected PS2 port\n"));

      /* Create controller key */
      Error = RegCreateKey(BusKey,
			   L"PointerController\\0",
			   &ControllerKey);
      if (Error != ERROR_SUCCESS)
	{
	  DbgPrint((DPRINT_HWDETECT, "Failed to create controller key\n"));
	  return;
	}
      DbgPrint((DPRINT_HWDETECT, "Created key: PointerController\\0\n"));

      /* Set 'ComponentInformation' value */
      SetComponentInformation(ControllerKey,
			      0x20,
			      0,
			      0xFFFFFFFF);

      memset(&FullResourceDescriptor, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR));

      /* Initialize resource descriptor */
      FullResourceDescriptor.InterfaceType = Isa;
      FullResourceDescriptor.BusNumber = 0;
      FullResourceDescriptor.PartialResourceList.Version = 1;
      FullResourceDescriptor.PartialResourceList.Revision = 1;
      FullResourceDescriptor.PartialResourceList.Count = 1;

      /* Set Interrupt */
      FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeInterrupt;
      FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareUndetermined;
      FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].Flags = CM_RESOURCE_INTERRUPT_LATCHED;
      FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Level = 12;
      FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Vector = 0;
      FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Affinity = 0xFFFFFFFF;

      /* Set 'Configuration Data' value */
      Error = RegSetValue(ControllerKey,
			  L"Configuration Data",
			  REG_FULL_RESOURCE_DESCRIPTOR,
			  (PCHAR)&FullResourceDescriptor,
			  sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
      if (Error != ERROR_SUCCESS)
	{
	  DbgPrint((DPRINT_HWDETECT,
		    "RegSetValue(Configuration Data) failed (Error %u)\n",
		    (int)Error));
	  return;
	}


      if (DetectPS2AuxDevice())
	{
	  DbgPrint((DPRINT_HWDETECT, "Detected PS2 mouse\n"));

	  /* Create peripheral key */
	  Error = RegCreateKey(ControllerKey,
			       L"PointerPeripheral\\0",
			       &PeripheralKey);
	  if (Error != ERROR_SUCCESS)
	    {
	      DbgPrint((DPRINT_HWDETECT, "Failed to create peripheral key\n"));
	      return;
	    }
	  DbgPrint((DPRINT_HWDETECT, "Created key: PointerPeripheral\\0\n"));

	  /* Set 'ComponentInformation' value */
	  SetComponentInformation(PeripheralKey,
				  0x20,
				  0,
				  0xFFFFFFFF);

	  /* Initialize resource descriptor */
	  memset(&FullResourceDescriptor, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
	  FullResourceDescriptor.InterfaceType = Isa;
	  FullResourceDescriptor.BusNumber = 0;
	  FullResourceDescriptor.PartialResourceList.Version = 1;
	  FullResourceDescriptor.PartialResourceList.Revision = 1;
	  FullResourceDescriptor.PartialResourceList.Count = 0;

	  /* Set 'Configuration Data' value */
	  Error = RegSetValue(PeripheralKey,
			      L"Configuration Data",
			      REG_FULL_RESOURCE_DESCRIPTOR,
			      (PCHAR)&FullResourceDescriptor,
			      sizeof(CM_FULL_RESOURCE_DESCRIPTOR) -
			      sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
	  if (Error != ERROR_SUCCESS)
	    {
	      DbgPrint((DPRINT_HWDETECT,
			"RegSetValue(Configuration Data) failed (Error %u)\n",
			(int)Error));
	      return;
	    }

	  /* Set 'Identifier' value */
	  Error = RegSetValue(PeripheralKey,
			      L"Identifier",
			      REG_SZ,
			      (PCHAR)L"MICROSOFT PS2 MOUSE",
			      20 * sizeof(WCHAR));
	  if (Error != ERROR_SUCCESS)
	    {
	      DbgPrint((DPRINT_HWDETECT,
			"RegSetValue() failed (Error %u)\n",
			(int)Error));
	      return;
	    }
	}
    }
}


static VOID
DetectDisplayController(FRLDRHKEY BusKey)
{
  WCHAR Buffer[80];
  FRLDRHKEY ControllerKey;
  USHORT VesaVersion;
  LONG Error;

  Error = RegCreateKey(BusKey,
		       L"DisplayController\\0",
		       &ControllerKey);
  if (Error != ERROR_SUCCESS)
    {
      DbgPrint((DPRINT_HWDETECT, "Failed to create controller key\n"));
      return;
    }
  DbgPrint((DPRINT_HWDETECT, "Created key: DisplayController\\0\n"));

  /* Set 'ComponentInformation' value */
  SetComponentInformation(ControllerKey,
			  0x00,
			  0,
			  0xFFFFFFFF);

  /* FIXME: Set 'ComponentInformation' value */

  VesaVersion = BiosIsVesaSupported();
  if (VesaVersion != 0)
    {
      DbgPrint((DPRINT_HWDETECT,
		"VESA version %c.%c\n",
		(VesaVersion >> 8) + '0',
		(VesaVersion & 0xFF) + '0'));
    }
  else
    {
      DbgPrint((DPRINT_HWDETECT,
		"VESA not supported\n"));
    }

  if (VesaVersion >= 0x0200)
    {
      wcscpy(Buffer,
             L"VBE Display");
    }
  else
    {
      wcscpy(Buffer,
             L"VGA Display");
    }

  /* Set 'Identifier' value */
  Error = RegSetValue(ControllerKey,
		      L"Identifier",
		      REG_SZ,
		      (PCHAR)Buffer,
		      (wcslen(Buffer) + 1) * sizeof(WCHAR));
  if (Error != ERROR_SUCCESS)
    {
      DbgPrint((DPRINT_HWDETECT,
		"RegSetValue() failed (Error %u)\n",
		(int)Error));
      return;
    }

  /* FIXME: Add display peripheral (monitor) data */
}


static VOID
DetectIsaBios(FRLDRHKEY SystemKey, ULONG *BusNumber)
{
  PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
  WCHAR Buffer[80];
  FRLDRHKEY BusKey;
  ULONG Size;
  LONG Error;

  /* Create new bus key */
  swprintf(Buffer,
	  L"MultifunctionAdapter\\%u", *BusNumber);
  Error = RegCreateKey(SystemKey,
		       Buffer,
		       &BusKey);
  if (Error != ERROR_SUCCESS)
    {
      DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
      return;
    }

  /* Set 'Component Information' value similar to my NT4 box */
  SetComponentInformation(BusKey,
                          0x0,
                          0x0,
                          0xFFFFFFFF);

  /* Increment bus number */
  (*BusNumber)++;

  /* Set 'Identifier' value */
  Error = RegSetValue(BusKey,
		      L"Identifier",
		      REG_SZ,
		      (PCHAR)L"ISA",
		      4 * sizeof(WCHAR));
  if (Error != ERROR_SUCCESS)
    {
      DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
      return;
    }

  /* Set 'Configuration Data' value */
  Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) -
	 sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
  FullResourceDescriptor = MmAllocateMemory(Size);
  if (FullResourceDescriptor == NULL)
    {
      DbgPrint((DPRINT_HWDETECT,
		"Failed to allocate resource descriptor\n"));
      return;
    }

  /* Initialize resource descriptor */
  memset(FullResourceDescriptor, 0, Size);
  FullResourceDescriptor->InterfaceType = Isa;
  FullResourceDescriptor->BusNumber = 0;
  FullResourceDescriptor->PartialResourceList.Version = 1;
  FullResourceDescriptor->PartialResourceList.Revision = 1;
  FullResourceDescriptor->PartialResourceList.Count = 0;

  /* Set 'Configuration Data' value */
  Error = RegSetValue(BusKey,
		      L"Configuration Data",
		      REG_FULL_RESOURCE_DESCRIPTOR,
		      (PCHAR) FullResourceDescriptor,
		      Size);
  MmFreeMemory(FullResourceDescriptor);
  if (Error != ERROR_SUCCESS)
    {
      DbgPrint((DPRINT_HWDETECT,
		"RegSetValue(Configuration Data) failed (Error %u)\n",
		(int)Error));
      return;
    }

  /* Detect ISA/BIOS devices */
  DetectBiosDisks(S

⌨️ 快捷键说明

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