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

📄 partlist.c

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

      InitializeObjectAttributes (&ObjectAttributes,
				  &Name,
				  0,
				  NULL,
				  NULL);

      Status = NtOpenFile (&FileHandle,
			   FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
			   &ObjectAttributes,
			   &Iosb,
			   FILE_SHARE_READ,
			   FILE_SYNCHRONOUS_IO_NONALERT);
	  if (NT_SUCCESS(Status))
	{
	  AddDiskToList (FileHandle,
			 DiskNumber,
			 List);

	  NtClose(FileHandle);
	}
    }

  AssignDriverLetters (List);

  List->TopDisk = 0;
  List->TopPartition = 0;

  /* Search for first usable disk and partition */
  if (IsListEmpty (&List->DiskListHead))
    {
      List->CurrentDisk = NULL;
      List->CurrentPartition = NULL;
    }
  else
    {
      List->CurrentDisk =
	CONTAINING_RECORD (List->DiskListHead.Flink,
			   DISKENTRY,
			   ListEntry);

      if (IsListEmpty (&List->CurrentDisk->PartListHead))
	{
	  List->CurrentPartition = 0;
	}
      else
	{
	  List->CurrentPartition =
	    CONTAINING_RECORD (List->CurrentDisk->PartListHead.Flink,
			       PARTENTRY,
			       ListEntry);
	}
    }

  return List;
}


VOID
DestroyPartitionList (PPARTLIST List)
{
  PDISKENTRY DiskEntry;
  PBIOSDISKENTRY BiosDiskEntry;
  PPARTENTRY PartEntry;
  PLIST_ENTRY Entry;

  /* Release disk and partition info */
  while (!IsListEmpty (&List->DiskListHead))
    {
      Entry = RemoveHeadList (&List->DiskListHead);
      DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry);

      /* Release driver name */
      RtlFreeUnicodeString(&DiskEntry->DriverName);

      /* Release partition array */
      while (!IsListEmpty (&DiskEntry->PartListHead))
	{
	  Entry = RemoveHeadList (&DiskEntry->PartListHead);
	  PartEntry = CONTAINING_RECORD (Entry, PARTENTRY, ListEntry);

	  RtlFreeHeap (ProcessHeap,
		       0,
		       PartEntry);
	}

      /* Release disk entry */
      RtlFreeHeap (ProcessHeap, 0, DiskEntry);
    }

  /* release the bios disk info */
  while(!IsListEmpty(&List->BiosDiskListHead))
    {
      Entry = RemoveHeadList(&List->BiosDiskListHead);
      BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);

      RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
    }

  /* Release list head */
  RtlFreeHeap (ProcessHeap, 0, List);
}


static VOID
PrintEmptyLine (PPARTLIST List)
{
  COORD coPos;
  DWORD Written;
  USHORT Width;
  USHORT Height;

  Width = List->Right - List->Left - 1;
  Height = List->Bottom - List->Top - 2;


  coPos.X = List->Left + 1;
  coPos.Y = List->Top + 1 + List->Line;

  if (List->Line >= 0 && List->Line <= Height)
    {
      FillConsoleOutputAttribute (StdOutput,
			          FOREGROUND_WHITE | BACKGROUND_BLUE,
			          Width,
			          coPos,
			          &Written);

      FillConsoleOutputCharacterA (StdOutput,
			          ' ',
			          Width,
			          coPos,
			          &Written);
    }
  List->Line++;
}


static VOID
PrintPartitionData (PPARTLIST List,
		    PDISKENTRY DiskEntry,
		    PPARTENTRY PartEntry)
{
  CHAR LineBuffer[128];
  COORD coPos;
  DWORD Written;
  USHORT Width;
  USHORT Height;

  LARGE_INTEGER PartSize;
  PCHAR Unit;
  UCHAR Attribute;
  PCHAR PartType;

  Width = List->Right - List->Left - 1;
  Height = List->Bottom - List->Top - 2;


  coPos.X = List->Left + 1;
  coPos.Y = List->Top + 1 + List->Line;

  if (PartEntry->Unpartitioned == TRUE)
    {
#if 0
      if (PartEntry->UnpartitionledLength >= 0x280000000ULL) /* 10 GB */
	{
	  PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 29)) >> 30;
	  Unit = "GB";
	}
      else
#endif
      if (PartEntry->UnpartitionedLength >= 0xA00000ULL) /* 10 MB */
	{
	  PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20;
	  Unit = "MB";
	}
      else
	{
	  PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 9)) >> 10;
	  Unit = "KB";
	}

      sprintf (LineBuffer,
	       "    Unpartitioned space              %6lu %s",
	       PartSize.u.LowPart,
	       Unit);
    }
  else
    {
      /* Determine partition type */
      PartType = NULL;
      if (PartEntry->New == TRUE)
	{
	  PartType = "New (Unformatted)";
	}
      else if (PartEntry->Unpartitioned == FALSE)
	{
	  if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_12) ||
	      (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_16) ||
	      (PartEntry->PartInfo[0].PartitionType == PARTITION_HUGE) ||
	      (PartEntry->PartInfo[0].PartitionType == PARTITION_XINT13))
	    {
	      PartType = "FAT";
	    }
	  else if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32) ||
		   (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13))
	    {
	      PartType = "FAT32";
	    }
	  else if (PartEntry->PartInfo[0].PartitionType == PARTITION_IFS)
	    {
	      PartType = "NTFS"; /* FIXME: Not quite correct! */
	    }
	}

#if 0
      if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */
	{
	  PartSize.QuadPart = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 29)) >> 30;
	  Unit = "GB";
	}
      else
#endif
      if (PartEntry->PartInfo[0].PartitionLength.QuadPart >= 0xA00000LL) /* 10 MB */
	{
	  PartSize.QuadPart = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 19)) >> 20;
	  Unit = "MB";
	}
      else
	{
	  PartSize.QuadPart = (PartEntry->PartInfo[0].PartitionLength.QuadPart + (1 << 9)) >> 10;
	  Unit = "KB";
	}

      if (PartType == NULL)
	{
	  sprintf (LineBuffer,
		   "%c%c  Type %-3u                         %6lu %s",
		   (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
		   (PartEntry->DriveLetter == 0) ? '-' : ':',
		   PartEntry->PartInfo[0].PartitionType,
		   PartSize.u.LowPart,
		   Unit);
	}
      else
	{
	  sprintf (LineBuffer,
		   "%c%c  %-24s         %6lu %s",
		   (PartEntry->DriveLetter == 0) ? '-' : PartEntry->DriveLetter,
		   (PartEntry->DriveLetter == 0) ? '-' : ':',
		   PartType,
		   PartSize.u.LowPart,
		   Unit);
	}
    }

  Attribute = (List->CurrentDisk == DiskEntry &&
	       List->CurrentPartition == PartEntry) ?
	           FOREGROUND_BLUE | BACKGROUND_WHITE :
	           FOREGROUND_WHITE | BACKGROUND_BLUE;

  if (List->Line >= 0 && List->Line <= Height)
    {
      FillConsoleOutputCharacterA (StdOutput,
			          ' ',
			          Width,
			          coPos,
			          &Written);
    }
  coPos.X += 4;
  Width -= 8;
  if (List->Line >= 0 && List->Line <= Height)
    {
      FillConsoleOutputAttribute (StdOutput,
			          Attribute,
			          Width,
			          coPos,
			          &Written);
    }
  coPos.X++;
  Width -= 2;
  if (List->Line >= 0 && List->Line <= Height)
    {
      WriteConsoleOutputCharacterA (StdOutput,
				    LineBuffer,
				    min (strlen (LineBuffer), Width),
				    coPos,
				    &Written);
    }
  List->Line++;
}


static VOID
PrintDiskData (PPARTLIST List,
	       PDISKENTRY DiskEntry)
{
  PPARTENTRY PartEntry;
  CHAR LineBuffer[128];
  COORD coPos;
  DWORD Written;
  USHORT Width;
  USHORT Height;
  ULARGE_INTEGER DiskSize;
  PCHAR Unit;

  Width = List->Right - List->Left - 1;
  Height = List->Bottom - List->Top - 2;


  coPos.X = List->Left + 1;
  coPos.Y = List->Top + 1 + List->Line;

#if 0
  if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */
    {
      DiskSize.QuadPart = (DiskEntry->DiskSize + (1 << 29)) >> 30;
      Unit = "GB";
    }
  else
#endif
    {
      DiskSize.QuadPart = (DiskEntry->DiskSize + (1 << 19)) >> 20;
      if (DiskSize.QuadPart == 0)
	DiskSize.QuadPart = 1;
      Unit = "MB";
    }

  if (DiskEntry->DriverName.Length > 0)
    {
      sprintf (LineBuffer,
	       "%6lu %s  Harddisk %lu  (Port=%hu, Bus=%hu, Id=%hu) on %S",
	       DiskSize.u.LowPart,
	       Unit,
	       DiskEntry->DiskNumber,
	       DiskEntry->Port,
	       DiskEntry->Bus,
	       DiskEntry->Id,
	       DiskEntry->DriverName.Buffer);
    }
  else
    {
      sprintf (LineBuffer,
	       "%6lu %s  Harddisk %lu  (Port=%hu, Bus=%hu, Id=%hu)",
	       DiskSize.u.LowPart,
	       Unit,
	       DiskEntry->DiskNumber,
	       DiskEntry->Port,
	       DiskEntry->Bus,
	       DiskEntry->Id);
    }
  if (List->Line >= 0 && List->Line <= Height)
    {
      FillConsoleOutputAttribute (StdOutput,
			          FOREGROUND_WHITE | BACKGROUND_BLUE,
			          Width,
			          coPos,
			          &Written);

      FillConsoleOutputCharacterA (StdOutput,
			          ' ',
			          Width,
			          coPos,
			          &Written);
    }

  coPos.X++;
  if (List->Line >= 0 && List->Line <= Height)
    {
      WriteConsoleOutputCharacterA (StdOutput,
				    LineBuffer,
				    min ((USHORT)strlen (LineBuffer), Width - 2),
				    coPos,
				    &Written);
    }
  List->Line++;

  /* Print separator line */
  PrintEmptyLine (List);

  /* Print partition lines*/
  LIST_FOR_EACH(PartEntry, &DiskEntry->PartListHead, PARTENTRY, ListEntry)
    {
      /* Print disk entry */
      PrintPartitionData (List,
			  DiskEntry,
			  PartEntry);
    }

  /* Print separator line */
  PrintEmptyLine (List);
}


VOID
DrawPartitionList (PPARTLIST List)
{
  PLIST_ENTRY Entry, Entry2;
  PDISKENTRY DiskEntry;
  PPARTENTRY PartEntry = NULL;
  COORD coPos;
  DWORD Written;
  SHORT i;
  SHORT CurrentDiskLine;
  SHORT CurrentPartLine;
  SHORT LastLine;
  BOOL CurrentPartLineFound = FALSE;
  BOOL CurrentDiskLineFound = FALSE;

  /* Calculate the line of the current disk and partition */
  CurrentDiskLine = 0;
  CurrentPartLine = 0;
  LastLine = 0;
  Entry = List->DiskListHead.Flink;
  while (Entry != &List->DiskListHead)
    {
      DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry);
      LastLine += 2;
      if (CurrentPartLineFound == FALSE)
        {
          CurrentPartLine += 2;
	}
      Entry2 = DiskEntry->PartListHead.Flink;
      while (Entry2 != &DiskEntry->PartListHead)
	{
	  PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);
	  if (PartEntry == List->CurrentPartition)
	    {
	      CurrentPartLineFound = TRUE;
	    }
          Entry2 = Entry2->Flink;
	  if (CurrentPartLineFound == FALSE)
	    {
	      CurrentPartLine++;
	    }
	  LastLine++;
	}
      if (DiskEntry == List->CurrentDisk)
        {
	  CurrentDiskLineFound = TRUE;
	}
      Entry = Entry->Flink;
      if (Entry != &List->DiskListHead)
        {
	  if (CurrentDiskLineFound == FALSE)
	    {
	      CurrentPartLine ++;
	      CurrentDiskLine = CurrentPartLine;
	    }
	  LastLine++;
	}
      else
        {
	  LastLine--;
	}
    }

  /* If it possible, make the disk name visible */
  if (CurrentPartLine < List->Offset)
    {
      List->Offset = CurrentPartLine;
    }
  else if (CurrentPartLine - List->Offset > List->Bottom - List->Top - 2)
    {
      List->Offset = CurrentPartLine - (List->Bottom - List->Top - 2);
    }
  if (CurrentDiskLine < List->Offset && CurrentPartLine - CurrentDiskLine < List->Bottom - List->Top - 2)
    {
      List->Offset = CurrentDiskLine;
    }

⌨️ 快捷键说明

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