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

📄 hardware.c

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

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

  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;
    }
  memset(FullResourceDescriptor, 0, Size);

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

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

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

  /* Set DMA channel */
  PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[2];
  PartialDescriptor->Type = CmResourceTypeDma;
  PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
  PartialDescriptor->Flags = 0;
  PartialDescriptor->u.Dma.Channel = 2;
  PartialDescriptor->u.Dma.Port = 0;

  /* 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;
    }

  DetectBiosFloppyPeripheral(ControllerKey);
}


static VOID
InitializeSerialPort(ULONG Port,
		     ULONG LineControl)
{
  WRITE_PORT_UCHAR((PUCHAR)Port + 3, 0x80);  /* set DLAB on   */
  WRITE_PORT_UCHAR((PUCHAR)Port,     0x60);  /* speed LO byte */
  WRITE_PORT_UCHAR((PUCHAR)Port + 1, 0);     /* speed HI byte */
  WRITE_PORT_UCHAR((PUCHAR)Port + 3, LineControl);
  WRITE_PORT_UCHAR((PUCHAR)Port + 1, 0);     /* set comm and DLAB to 0 */
  WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x09);  /* DR int enable */
  READ_PORT_UCHAR((PUCHAR)Port + 5);  /* clear error bits */
}


static ULONG
DetectSerialMouse(ULONG Port)
{
  CHAR Buffer[4];
  ULONG i;
  ULONG TimeOut;
  UCHAR LineControl;

  /* Shutdown mouse or something like that */
  LineControl = READ_PORT_UCHAR((PUCHAR)Port + 4);
  WRITE_PORT_UCHAR((PUCHAR)Port + 4, (LineControl & ~0x02) | 0x01);
  StallExecutionProcessor(100000);

  /*
   * Clear buffer
   * Maybe there is no serial port although BIOS reported one (this
   * is the case on Apple hardware), or the serial port is misbehaving,
   * therefore we must give up after some time.
   */
  TimeOut = 200;
  while (READ_PORT_UCHAR((PUCHAR)Port + 5) & 0x01)
    {
      if (--TimeOut == 0)
        return MOUSE_TYPE_NONE;
      READ_PORT_UCHAR((PUCHAR)Port);
    }

  /*
   * Send modem control with 'Data Terminal Ready', 'Request To Send' and
   * 'Output Line 2' message. This enables mouse to identify.
   */
  WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x0b);

  /* Wait 10 milliseconds for the mouse getting ready */
  StallExecutionProcessor(10000);

  /* Read first four bytes, which contains Microsoft Mouse signs */
  TimeOut = 200;
  for (i = 0; i < 4; i++)
    {
      while (((READ_PORT_UCHAR((PUCHAR)Port + 5) & 1) == 0) && (TimeOut > 0))
	{
	  StallExecutionProcessor(1000);
	  --TimeOut;
	  if (TimeOut == 0)
	    return MOUSE_TYPE_NONE;
	}
      Buffer[i] = READ_PORT_UCHAR((PUCHAR)Port);
    }

  DbgPrint((DPRINT_HWDETECT,
	    "Mouse data: %x %x %x %x\n",
	    Buffer[0],Buffer[1],Buffer[2],Buffer[3]));

  /* Check that four bytes for signs */
  for (i = 0; i < 4; ++i)
    {
      if (Buffer[i] == 'B')
	{
	  /* Sign for Microsoft Ballpoint */
//	  DbgPrint("Microsoft Ballpoint device detected\n");
//	  DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET\n");
	  return MOUSE_TYPE_NONE;
	}
      else if (Buffer[i] == 'M')
	{
	  /* Sign for Microsoft Mouse protocol followed by button specifier */
	  if (i == 3)
	    {
	      /* Overflow Error */
	      return MOUSE_TYPE_NONE;
	    }

	  switch (Buffer[i + 1])
	    {
	      case '3':
		DbgPrint((DPRINT_HWDETECT,
			  "Microsoft Mouse with 3-buttons detected\n"));
		return MOUSE_TYPE_LOGITECH;

	      case 'Z':
		DbgPrint((DPRINT_HWDETECT,
			  "Microsoft Wheel Mouse detected\n"));
		return MOUSE_TYPE_WHEELZ;

	      /* case '2': */
	      default:
		DbgPrint((DPRINT_HWDETECT,
			  "Microsoft Mouse with 2-buttons detected\n"));
		return MOUSE_TYPE_MICROSOFT;
	    }
	}
    }

  return MOUSE_TYPE_NONE;
}


static ULONG
GetSerialMousePnpId(ULONG Port, char *Buffer)
{
  ULONG TimeOut;
  ULONG i = 0;
  char c;
  char x;

  WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x09);

  /* Wait 10 milliseconds for the mouse getting ready */
  StallExecutionProcessor(10000);

  WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x0b);

  StallExecutionProcessor(10000);

  for (;;)
    {
      TimeOut = 200;
      while (((READ_PORT_UCHAR((PUCHAR)Port + 5) & 1) == 0) && (TimeOut > 0))
	{
	  StallExecutionProcessor(1000);
	  --TimeOut;
	  if (TimeOut == 0)
	    {
	      return 0;
	    }
	}

      c = READ_PORT_UCHAR((PUCHAR)Port);
      if (c == 0x08 || c == 0x28)
	break;
    }

  Buffer[i++] = c;
  x = c + 1;

  for (;;)
    {
      TimeOut = 200;
      while (((READ_PORT_UCHAR((PUCHAR)Port + 5) & 1) == 0) && (TimeOut > 0))
	{
	  StallExecutionProcessor(1000);
	  --TimeOut;
	  if (TimeOut == 0)
	    return 0;
	}
      c = READ_PORT_UCHAR((PUCHAR)Port);
      Buffer[i++] = c;
      if (c == x)
	break;
      if (i >= 256)
	break;
    }

  return i;
}


static VOID
DetectSerialPointerPeripheral(FRLDRHKEY ControllerKey,
			      ULONG Base)
{
  CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
  char Buffer[256];
  WCHAR Identifier[256];
  FRLDRHKEY PeripheralKey;
  ULONG MouseType;
  ULONG Length;
  ULONG i;
  ULONG j;
  ULONG k;
  LONG Error;

  DbgPrint((DPRINT_HWDETECT,
	    "DetectSerialPointerPeripheral()\n"));

  Identifier[0] = 0;

  InitializeSerialPort(Base, 2);
  MouseType = DetectSerialMouse(Base);

  if (MouseType != MOUSE_TYPE_NONE)
    {
      Length = GetSerialMousePnpId(Base, Buffer);
      DbgPrint((DPRINT_HWDETECT,
		"PnP ID length: %u\n",
		Length));

      if (Length != 0)
	{
	  /* Convert PnP sting to ASCII */
	  if (Buffer[0] == 0x08)
	    {
	      for (i = 0; i < Length; i++)
		Buffer[i] += 0x20;
	    }
	  Buffer[Length] = 0;

	  DbgPrint((DPRINT_HWDETECT,
		    "PnP ID string: %s\n",
		    Buffer));

	  /* Copy PnpId string */
          for (i = 0; i < 7; i++)
            {
              Identifier[i] = Buffer[3+i];
            }
          memcpy(&Identifier[7],
		 L" - ",
		 3 * sizeof(WCHAR));

	  /* Skip device serial number */
	  i = 10;
	  if (Buffer[i] == '\\')
	    {
	      for (j = ++i; i < Length; ++i)
		{
		  if (Buffer[i] == '\\')
		    break;
		}
	      if (i >= Length)
		i -= 3;
	    }

	  /* Skip PnP class */
	  if (Buffer[i] == '\\')
	    {
	      for (j = ++i; i < Length; ++i)
		{
		  if (Buffer[i] == '\\')
		    break;
		}

	      if (i >= Length)
	        i -= 3;
	    }

	  /* Skip compatible PnP Id */
	  if (Buffer[i] == '\\')
	    {
	      for (j = ++i; i < Length; ++i)
		{
		  if (Buffer[i] == '\\')
		    break;
		}
	      if (Buffer[j] == '*')
		++j;
	      if (i >= Length)
		i -= 3;
	    }

	  /* Get product description */
	  if (Buffer[i] == '\\')
	    {
	      for (j = ++i; i < Length; ++i)
		{
		  if (Buffer[i] == ';')
		    break;
		}
	      if (i >= Length)
		i -= 3;
	      if (i > j + 1)
		{
                  for (k = 0; k < i - j; k++)
                    {
                      Identifier[k + 10] = Buffer[k + j];
                    }
		  Identifier[10 + (i-j)] = 0;
		}
	    }

	  DbgPrint((DPRINT_HWDETECT,
		    "Identifier string: %S\n",
		    Identifier));
	}

      if (Length == 0 || wcslen(Identifier) < 11)
	{
	  switch (MouseType)
	    {
	      case MOUSE_TYPE_LOGITECH:
		wcscpy (Identifier,
			L"LOGITECH SERIAL MOUSE");
		break;

	      case MOUSE_TYPE_WHEELZ:
		wcscpy (Identifier,
			L"MICROSOFT SERIAL MOUSE WITH WHEEL");
		break;

	      case MOUSE_TYPE_MICROSOFT:
	      default:
		wcscpy (Identifier,
			L"MICROSOFT SERIAL MOUSE");
		break;
	    }
	}

      /* Create 'PointerPeripheral' 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);

      /* Set 'Configuration Data' value */
      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;

      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));
	}

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


static VOID
DetectSerialPorts(FRLDRHKEY BusKey)
{
  PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
  PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
  PCM_SERIAL_DEVICE_DATA SerialDeviceData;
  ULONG Irq[4] = {4, 3, 4, 3};
  ULONG Base;
  WCHAR Buffer[80];
  PUSHORT BasePtr;
  ULONG ControllerNumber = 0;
  FRLDRHKEY ControllerKey;

⌨️ 快捷键说明

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