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

📄 hardware.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
  FullResourceDescriptor->PartialResourceList.Revision = 1;
  FullResourceDescriptor->PartialResourceList.Count = 1;
  FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type =
    CmResourceTypeDeviceSpecific;
//  FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
//  FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
  FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize =
    sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);

  /* Get pointer to geometry data */
  DiskGeometry = (PVOID)(((ULONG_PTR)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR));

  /* Get the disk geometry */
  ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
  if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
    {
      DiskGeometry->BytesPerSector = ExtGeometry.BytesPerSector;
      DiskGeometry->NumberOfCylinders = ExtGeometry.Cylinders;
      DiskGeometry->SectorsPerTrack = ExtGeometry.SectorsPerTrack;
      DiskGeometry->NumberOfHeads = ExtGeometry.Heads;
    }
  else if(MachDiskGetDriveGeometry(DriveNumber, &Geometry))
    {
      DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
      DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
      DiskGeometry->SectorsPerTrack = Geometry.Sectors;
      DiskGeometry->NumberOfHeads = Geometry.Heads;
    }
  else
    {
      DbgPrint((DPRINT_HWDETECT, "Reading disk geometry failed\n"));
      MmFreeMemory(FullResourceDescriptor);
      return;
    }
  DbgPrint((DPRINT_HWDETECT,
	   "Disk %x: %u Cylinders  %u Heads  %u Sectors  %u Bytes\n",
	   DriveNumber,
	   DiskGeometry->NumberOfCylinders,
	   DiskGeometry->NumberOfHeads,
	   DiskGeometry->SectorsPerTrack,
	   DiskGeometry->BytesPerSector));

  Error = RegSetValue(DiskKey,
		      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));
    }
}


static VOID
SetHarddiskIdentifier(FRLDRHKEY DiskKey,
		      ULONG DriveNumber)
{
  PMASTER_BOOT_RECORD Mbr;
  ULONG *Buffer;
  ULONG i;
  ULONG Checksum;
  ULONG Signature;
  WCHAR Identifier[20];
  CHAR ArcName[256];
  LONG Error;

  /* Read the MBR */
  if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
    {
      DbgPrint((DPRINT_HWDETECT, "Reading MBR failed\n"));
      return;
    }

  Buffer = (ULONG*)DISKREADBUFFER;
  Mbr = (PMASTER_BOOT_RECORD)DISKREADBUFFER;

  Signature =  Mbr->Signature;
  DbgPrint((DPRINT_HWDETECT, "Signature: %x\n", Signature));

  /* Calculate the MBR checksum */
  Checksum = 0;
  for (i = 0; i < 128; i++)
    {
      Checksum += Buffer[i];
    }
  Checksum = ~Checksum + 1;
  DbgPrint((DPRINT_HWDETECT, "Checksum: %x\n", Checksum));

  /* Fill out the ARC disk block */
  reactos_arc_disk_info[reactos_disk_count].Signature = Signature;
  reactos_arc_disk_info[reactos_disk_count].CheckSum = Checksum;
  sprintf(ArcName, "multi(0)disk(0)rdisk(%lu)", reactos_disk_count);
  strcpy(reactos_arc_strings[reactos_disk_count], ArcName);
  reactos_arc_disk_info[reactos_disk_count].ArcName =
      reactos_arc_strings[reactos_disk_count];
  reactos_disk_count++;

  /* Convert checksum and signature to identifier string */
  Identifier[0] = Hex[(Checksum >> 28) & 0x0F];
  Identifier[1] = Hex[(Checksum >> 24) & 0x0F];
  Identifier[2] = Hex[(Checksum >> 20) & 0x0F];
  Identifier[3] = Hex[(Checksum >> 16) & 0x0F];
  Identifier[4] = Hex[(Checksum >> 12) & 0x0F];
  Identifier[5] = Hex[(Checksum >> 8) & 0x0F];
  Identifier[6] = Hex[(Checksum >> 4) & 0x0F];
  Identifier[7] = Hex[Checksum & 0x0F];
  Identifier[8] = L'-';
  Identifier[9] = Hex[(Signature >> 28) & 0x0F];
  Identifier[10] = Hex[(Signature >> 24) & 0x0F];
  Identifier[11] = Hex[(Signature >> 20) & 0x0F];
  Identifier[12] = Hex[(Signature >> 16) & 0x0F];
  Identifier[13] = Hex[(Signature >> 12) & 0x0F];
  Identifier[14] = Hex[(Signature >> 8) & 0x0F];
  Identifier[15] = Hex[(Signature >> 4) & 0x0F];
  Identifier[16] = Hex[Signature & 0x0F];
  Identifier[17] = L'-';
  Identifier[18] = L'A';
  Identifier[19] = 0;
  DbgPrint((DPRINT_HWDETECT, "Identifier: %S\n", Identifier));

  /* Set identifier */
  Error = RegSetValue(DiskKey,
		      L"Identifier",
		      REG_SZ,
		      (PCHAR)Identifier,
		      sizeof(Identifier));
  if (Error != ERROR_SUCCESS)
    {
      DbgPrint((DPRINT_HWDETECT,
		"RegSetValue(Identifier) failed (Error %u)\n",
		(int)Error));
    }
}


static VOID
DetectBiosDisks(FRLDRHKEY SystemKey,
		FRLDRHKEY BusKey)
{
  PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
  PCM_INT13_DRIVE_PARAMETER Int13Drives;
  GEOMETRY Geometry;
  WCHAR Buffer[80];
  FRLDRHKEY DiskKey;
  ULONG DiskCount;
  ULONG Size;
  ULONG i;
  LONG Error;
  BOOLEAN Changed;

  /* Count the number of visible drives */
  DiskReportError(FALSE);
  DiskCount = 0;

  /* There are some really broken BIOSes out there. There are even BIOSes
   * that happily report success when you ask them to read from non-existent
   * harddisks. So, we set the buffer to known contents first, then try to
   * read. If the BIOS reports success but the buffer contents haven't
   * changed then we fail anyway */
  memset((PVOID) DISKREADBUFFER, 0xcd, 512);
  while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, (PVOID)DISKREADBUFFER))
    {
      Changed = FALSE;
      for (i = 0; ! Changed && i < 512; i++)
        {
          Changed = ((PUCHAR)DISKREADBUFFER)[i] != 0xcd;
        }
      if (! Changed)
        {
          DbgPrint((DPRINT_HWDETECT, "BIOS reports success for disk %d but data didn't change\n",
                    (int)DiskCount));
          break;
        }
      DiskCount++;
      memset((PVOID) DISKREADBUFFER, 0xcd, 512);
    }
  DiskReportError(TRUE);
  DbgPrint((DPRINT_HWDETECT, "BIOS reports %d harddisk%s\n",
	    (int)DiskCount, (DiskCount == 1) ? "": "s"));

  /* Allocate resource descriptor */
  Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
	 sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
  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 = InterfaceTypeUndefined;
  FullResourceDescriptor->BusNumber = -1;
  FullResourceDescriptor->PartialResourceList.Version = 1;
  FullResourceDescriptor->PartialResourceList.Revision = 1;
  FullResourceDescriptor->PartialResourceList.Count = 1;
  FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type =
    CmResourceTypeDeviceSpecific;
//  FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
//  FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
  FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize =
    sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;

  /* Get harddisk Int13 geometry data */
  Int13Drives = (PVOID)(((ULONG_PTR)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
  for (i = 0; i < DiskCount; i++)
    {
      if (MachDiskGetDriveGeometry(0x80 + i, &Geometry))
	{
	  Int13Drives[i].DriveSelect = 0x80 + i;
	  Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1;
	  Int13Drives[i].SectorsPerTrack = Geometry.Sectors;
	  Int13Drives[i].MaxHeads = Geometry.Heads - 1;
	  Int13Drives[i].NumberDrives = DiskCount;

	  DbgPrint((DPRINT_HWDETECT,
		    "Disk %x: %u Cylinders  %u Heads  %u Sectors  %u Bytes\n",
		    0x80 + i,
		    Geometry.Cylinders - 1,
		    Geometry.Heads -1,
		    Geometry.Sectors,
		    Geometry.BytesPerSector));
	}
    }

  /* Set 'Configuration Data' value */
  Error = RegSetValue(SystemKey,
		      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;
    }

  /* Create and fill subkey for each harddisk */
  for (i = 0; i < DiskCount; i++)
    {
      /* Create disk key */
      swprintf (Buffer,
	        L"DiskController\\0\\DiskPeripheral\\%u",
	        i);

      Error = RegCreateKey(BusKey,
			   Buffer,
			   &DiskKey);
      if (Error != ERROR_SUCCESS)
	{
	  DbgPrint((DPRINT_HWDETECT, "Failed to create drive key\n"));
	  continue;
	}
      DbgPrint((DPRINT_HWDETECT, "Created key: %S\n", Buffer));

      /* Set disk values */
      SetHarddiskConfigurationData(DiskKey, 0x80 + i);
      SetHarddiskIdentifier(DiskKey, 0x80 + i);
    }
}


static ULONG
GetFloppyCount(VOID)
{
  UCHAR Data;

  WRITE_PORT_UCHAR((PUCHAR)0x70, 0x10);
  Data = READ_PORT_UCHAR((PUCHAR)0x71);

  return ((Data & 0xF0) ? 1 : 0) + ((Data & 0x0F) ? 1 : 0);
}


static UCHAR
GetFloppyType(UCHAR DriveNumber)
{
  UCHAR Data;

  WRITE_PORT_UCHAR((PUCHAR)0x70, 0x10);
  Data = READ_PORT_UCHAR((PUCHAR)0x71);

  if (DriveNumber == 0)
    return Data >> 4;
  else if (DriveNumber == 1)
    return Data & 0x0F;

  return 0;
}


static PVOID
GetInt1eTable(VOID)
{
  PUSHORT SegPtr = (PUSHORT)0x7A;
  PUSHORT OfsPtr = (PUSHORT)0x78;

  return (PVOID)((ULONG_PTR)(((ULONG)(*SegPtr)) << 4) + (ULONG)(*OfsPtr));
}


static VOID
DetectBiosFloppyPeripheral(FRLDRHKEY ControllerKey)
{
  PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
  PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
  PCM_FLOPPY_DEVICE_DATA FloppyData;
  WCHAR KeyName[32];
  WCHAR Identifier[20];
  FRLDRHKEY PeripheralKey;
  ULONG Size;
  LONG Error;
  ULONG FloppyNumber;
  UCHAR FloppyType;
  ULONG MaxDensity[6] = {0, 360, 1200, 720, 1440, 2880};
  PUCHAR Ptr;

  for (FloppyNumber = 0; FloppyNumber < 2; FloppyNumber++)
  {
    FloppyType = GetFloppyType(FloppyNumber);

    if ((FloppyType > 5) || (FloppyType == 0))
      continue;

    DiskResetController(FloppyNumber);

    Ptr = GetInt1eTable();

    swprintf(KeyName, L"FloppyDiskPeripheral\\%u", FloppyNumber);

    Error = RegCreateKey(ControllerKey,
			 KeyName,
			 &PeripheralKey);
    if (Error != ERROR_SUCCESS)
    {
      DbgPrint((DPRINT_HWDETECT, "Failed to create peripheral key\n"));
      return;
    }

    DbgPrint((DPRINT_HWDETECT, "Created key: %S\n", KeyName));

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

    Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
	   sizeof(CM_FLOPPY_DEVICE_DATA);
    FullResourceDescriptor = MmAllocateMemory(Size);
    if (FullResourceDescriptor == NULL)
    {
      DbgPrint((DPRINT_HWDETECT,
		"Failed to allocate resource descriptor\n"));
      return;
    }

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

    PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0];
    PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
    PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
    PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_FLOPPY_DEVICE_DATA);

    FloppyData = (PVOID)(((ULONG_PTR)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
    FloppyData->Version = 2;
    FloppyData->Revision = 0;
    FloppyData->MaxDensity = MaxDensity[FloppyType];
    FloppyData->MountDensity = 0;
    RtlCopyMemory(&FloppyData->StepRateHeadUnloadTime,
                  Ptr,
                  11);
    FloppyData->MaximumTrackValue = (FloppyType == 1) ? 39 : 79;
    FloppyData->DataTransferRate = 0;

    /* Set 'Configuration Data' value */
    Error = RegSetValue(PeripheralKey,
			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;
    }

    /* Set 'Identifier' value */
    swprintf(Identifier, L"FLOPPY%u", FloppyNumber + 1);
    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
DetectBiosFloppyController(FRLDRHKEY SystemKey,
			   FRLDRHKEY BusKey)
{
  PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
  PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
  FRLDRHKEY ControllerKey;
  ULONG Size;
  LONG Error;
  ULONG FloppyCount;

  FloppyCount = GetFloppyCount();
  DbgPrint((DPRINT_HWDETECT,
	    "Floppy count: %u\n",
	    FloppyCount));

  if (FloppyCount == 0)
    return;

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

  DbgPrint((DPRINT_HWDETECT, "Created key: DiskController\\0\n"));

⌨️ 快捷键说明

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