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

📄 partlist.c

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

  /* draw upper left corner */
  coPos.X = List->Left;
  coPos.Y = List->Top;
  FillConsoleOutputCharacterA (StdOutput,
			      0xDA, // '+',
			      1,
			      coPos,
			      &Written);

  /* draw upper edge */
  coPos.X = List->Left + 1;
  coPos.Y = List->Top;
  if (List->Offset == 0)
    {
      FillConsoleOutputCharacterA (StdOutput,
			          0xC4, // '-',
			          List->Right - List->Left - 1,
			          coPos,
			          &Written);
    }
  else
    {
      FillConsoleOutputCharacterA (StdOutput,
			          0xC4, // '-',
			          List->Right - List->Left - 5,
			          coPos,
			          &Written);
      coPos.X = List->Right - 5;
      WriteConsoleOutputCharacterA (StdOutput,
			            "(\x18)", // "(up)"
			            3,
			            coPos,
			            &Written);
      coPos.X = List->Right - 2;
      FillConsoleOutputCharacterA (StdOutput,
			          0xC4, // '-',
			          2,
			          coPos,
			          &Written);
    }

  /* draw upper right corner */
  coPos.X = List->Right;
  coPos.Y = List->Top;
  FillConsoleOutputCharacterA (StdOutput,
			      0xBF, // '+',
			      1,
			      coPos,
			      &Written);

  /* draw left and right edge */
  for (i = List->Top + 1; i < List->Bottom; i++)
    {
      coPos.X = List->Left;
      coPos.Y = i;
      FillConsoleOutputCharacterA (StdOutput,
				  0xB3, // '|',
				  1,
				  coPos,
				  &Written);

      coPos.X = List->Right;
      FillConsoleOutputCharacterA (StdOutput,
				  0xB3, //'|',
				  1,
				  coPos,
				  &Written);
    }

  /* draw lower left corner */
  coPos.X = List->Left;
  coPos.Y = List->Bottom;
  FillConsoleOutputCharacterA (StdOutput,
			      0xC0, // '+',
			      1,
			      coPos,
			      &Written);

  /* draw lower edge */
  coPos.X = List->Left + 1;
  coPos.Y = List->Bottom;
  if (LastLine - List->Offset <= List->Bottom - List->Top - 2)
    {
      FillConsoleOutputCharacterA (StdOutput,
			          0xC4, // '-',
			          List->Right - List->Left - 1,
			          coPos,
			          &Written);
    }
  else
    {
      FillConsoleOutputCharacterA (StdOutput,
			          0xC4, // '-',
			          List->Right - List->Left - 5,
			          coPos,
			          &Written);
      coPos.X = List->Right - 5;
      WriteConsoleOutputCharacterA (StdOutput,
			            "(\x19)", // "(down)"
			            3,
			            coPos,
			            &Written);
      coPos.X = List->Right - 2;
      FillConsoleOutputCharacterA (StdOutput,
			          0xC4, // '-',
			          2,
			          coPos,
			          &Written);
    }

  /* draw lower right corner */
  coPos.X = List->Right;
  coPos.Y = List->Bottom;
  FillConsoleOutputCharacterA (StdOutput,
			      0xD9, // '+',
			      1,
			      coPos,
			      &Written);

  /* print list entries */
  List->Line = - List->Offset;

  LIST_FOR_EACH(DiskEntry, &List->DiskListHead, DISKENTRY, ListEntry)
    {
      /* Print disk entry */
      PrintDiskData (List,
		     DiskEntry);
    }
}


VOID
SelectPartition(PPARTLIST List, ULONG DiskNumber, ULONG PartitionNumber)
{
  PDISKENTRY DiskEntry;
  PPARTENTRY PartEntry;
  PLIST_ENTRY Entry1;
  PLIST_ENTRY Entry2;
  ULONG i;

  /* Check for empty disks */
  if (IsListEmpty (&List->DiskListHead))
    return;

  /* Check for first usable entry on next disk */
  Entry1 = List->CurrentDisk->ListEntry.Flink;
  while (Entry1 != &List->DiskListHead)
    {
      DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry);

      if (DiskEntry->DiskNumber == DiskNumber)
        {
          Entry2 = DiskEntry->PartListHead.Flink;
          while (Entry2 != &DiskEntry->PartListHead)
            {
              PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);

              for (i = 0; i < 4; i++)
                {
                  if (PartEntry->PartInfo[i].PartitionNumber == PartitionNumber)
	            {
	              List->CurrentDisk = DiskEntry;
	              List->CurrentPartition = PartEntry;
                      DrawPartitionList (List);
	              return;
	            }
                }
              Entry2 = Entry2->Flink;
            }
          return;
        }
      Entry1 = Entry1->Flink;
    }
}


VOID
ScrollDownPartitionList (PPARTLIST List)
{
  PDISKENTRY DiskEntry;
  PPARTENTRY PartEntry;
  PLIST_ENTRY Entry1;
  PLIST_ENTRY Entry2;

  /* Check for empty disks */
  if (IsListEmpty (&List->DiskListHead))
    return;

  /* Check for next usable entry on current disk */
  if (List->CurrentPartition != NULL)
    {
      Entry2 = List->CurrentPartition->ListEntry.Flink;
      while (Entry2 != &List->CurrentDisk->PartListHead)
	{
	  PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);

//	  if (PartEntry->HidePartEntry == FALSE)
	    {
	      List->CurrentPartition = PartEntry;
	      DrawPartitionList (List);
	      return;
	    }
	  Entry2 = Entry2->Flink;
	}
    }

  /* Check for first usable entry on next disk */
  if (List->CurrentDisk != NULL)
    {
      Entry1 = List->CurrentDisk->ListEntry.Flink;
      while (Entry1 != &List->DiskListHead)
	{
	  DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry);

	  Entry2 = DiskEntry->PartListHead.Flink;
	  while (Entry2 != &DiskEntry->PartListHead)
	    {
	      PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);

//	      if (PartEntry->HidePartEntry == FALSE)
		{
		  List->CurrentDisk = DiskEntry;
		  List->CurrentPartition = PartEntry;
		  DrawPartitionList (List);
		  return;
		}

	      Entry2 = Entry2->Flink;
	    }

	  Entry1 = Entry1->Flink;
	}
    }
}


VOID
ScrollUpPartitionList (PPARTLIST List)
{
  PDISKENTRY DiskEntry;
  PPARTENTRY PartEntry;
  PLIST_ENTRY Entry1;
  PLIST_ENTRY Entry2;

  /* Check for empty disks */
  if (IsListEmpty (&List->DiskListHead))
    return;

  /* check for previous usable entry on current disk */
  if (List->CurrentPartition != NULL)
    {
      Entry2 = List->CurrentPartition->ListEntry.Blink;
      while (Entry2 != &List->CurrentDisk->PartListHead)
	{
	  PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);

//	  if (PartEntry->HidePartEntry == FALSE)
	    {
	      List->CurrentPartition = PartEntry;
	      DrawPartitionList (List);
	      return;
	    }
	  Entry2 = Entry2->Blink;
	}
    }


  /* check for last usable entry on previous disk */
  if (List->CurrentDisk != NULL)
    {
      Entry1 = List->CurrentDisk->ListEntry.Blink;
      while (Entry1 != &List->DiskListHead)
	{
	  DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry);

	  Entry2 = DiskEntry->PartListHead.Blink;
	  while (Entry2 != &DiskEntry->PartListHead)
	    {
	      PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry);

//	      if (PartEntry->HidePartEntry == FALSE)
		{
		  List->CurrentDisk = DiskEntry;
		  List->CurrentPartition = PartEntry;
		  DrawPartitionList (List);
		  return;
		}

	      Entry2 = Entry2->Blink;
	    }

	  Entry1 = Entry1->Blink;
	}
    }
}


static PPARTENTRY
GetPrevPartitionedEntry (PDISKENTRY DiskEntry,
			 PPARTENTRY CurrentEntry)
{
  PPARTENTRY PrevEntry;
  PLIST_ENTRY Entry;

  if (CurrentEntry->ListEntry.Blink == &DiskEntry->PartListHead)
    return NULL;

  Entry = CurrentEntry->ListEntry.Blink;
  while (Entry != &DiskEntry->PartListHead)
    {
      PrevEntry = CONTAINING_RECORD (Entry,
				     PARTENTRY,
				     ListEntry);
      if (PrevEntry->Unpartitioned == FALSE)
	return PrevEntry;

      Entry = Entry->Blink;
    }

  return NULL;
}


static PPARTENTRY
GetNextPartitionedEntry (PDISKENTRY DiskEntry,
			 PPARTENTRY CurrentEntry)
{
  PPARTENTRY NextEntry;
  PLIST_ENTRY Entry;

  if (CurrentEntry->ListEntry.Flink == &DiskEntry->PartListHead)
    return NULL;

  Entry = CurrentEntry->ListEntry.Flink;
  while (Entry != &DiskEntry->PartListHead)
    {
      NextEntry = CONTAINING_RECORD (Entry,
				     PARTENTRY,
				     ListEntry);
      if (NextEntry->Unpartitioned == FALSE)
	return NextEntry;

      Entry = Entry->Flink;
    }

  return NULL;
}


static PPARTENTRY
GetPrevUnpartitionedEntry (PDISKENTRY DiskEntry,
			   PPARTENTRY PartEntry)
{
  PPARTENTRY PrevPartEntry;

  if (PartEntry->ListEntry.Blink != &DiskEntry->PartListHead)
    {
      PrevPartEntry = CONTAINING_RECORD (PartEntry->ListEntry.Blink,
					 PARTENTRY,
					 ListEntry);
      if (PrevPartEntry->Unpartitioned == TRUE)
	return PrevPartEntry;
    }

  return NULL;
}


static PPARTENTRY
GetNextUnpartitionedEntry (PDISKENTRY DiskEntry,
			   PPARTENTRY PartEntry)
{
  PPARTENTRY NextPartEntry;

  if (PartEntry->ListEntry.Flink != &DiskEntry->PartListHead)
    {
      NextPartEntry = CONTAINING_RECORD (PartEntry->ListEntry.Flink,
					 PARTENTRY,
					 ListEntry);
      if (NextPartEntry->Unpartitioned == TRUE)
	return NextPartEntry;
    }

  return NULL;
}


VOID
CreateNewPartition (PPARTLIST List,
		    ULONGLONG PartitionSize,
		    BOOLEAN AutoCreate)
{
  PDISKENTRY DiskEntry;
  PPARTENTRY PartEntry;
  PPARTENTRY PrevPartEntry;
  PPARTENTRY NextPartEntry;
  PPARTENTRY NewPartEntry;

  if (List == NULL ||
      List->CurrentDisk == NULL ||
      List->CurrentPartition == NULL ||
      List->CurrentPartition->Unpartitioned == FALSE)
    {
      return;
    }

  DiskEntry = List->CurrentDisk;
  PartEntry = List->CurrentPartition;

  if (AutoCreate == TRUE ||
      PartitionSize == PartEntry->UnpartitionedLength)
    {
      /* Convert current entry to 'new (unformatted)' */
      PartEntry->FormatState = Unformatted;
      PartEntry->PartInfo[0].StartingOffset.QuadPart =
	PartEntry->UnpartitionedOffset + DiskEntry->TrackSize;
      PartEntry->PartInfo[0].PartitionLength.QuadPart =
	PartEntry->UnpartitionedLength - DiskEntry->TrackSize;
      PartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED;
      PartEntry->PartInfo[0].BootIndicator = FALSE; /* FIXME */
      PartEntry->PartInfo[0].RewritePartition = TRUE;
      PartEntry->PartInfo[1].RewritePartition = TRUE;
      PartEntry->PartInfo[2].RewritePartition = TRUE;
      PartEntry->PartInfo[3].RewritePartition = TRUE;

      /* Get previous and next partition entries */
      PrevPartEntry = GetPrevPartitionedEntry (DiskEntry,
					       PartEntry);
      NextPartEntry = GetNextPartitionedEntry (DiskEntry,
					       PartEntry);

      if (PrevPartEntry != NULL && NextPartEntry != NULL)
	{
	  /* Current entry is in the middle of the list */

	  /* Copy previous container partition data to current entry */
	  RtlCopyMemory (&PartEntry->PartInfo[1],
			 &PrevPartEntry->PartInfo[1],
			 sizeof(PARTITION_INFORMATION));
	  PartEntry->PartInfo[1].RewritePartition = TRUE;

	  /* Update previous container partition data */

	  PrevPartEntry->PartInfo[1].StartingOffset.QuadPart =
	    PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;

	  if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry)
	    {
	      /* Special case - previous partition is first partition */
	      PrevPartEntry->PartInfo[1].PartitionLength.QuadPart =
		DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart;
	    }
	  else
	    {
	      PrevPartEntry->PartInfo[1].PartitionLength.QuadPart =
		PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize;
	    }

	  PrevPartEntry->PartInfo[1].RewritePartition = TRUE;
	}
      else if (PrevPartEntry == NULL && NextPartEntry != NULL)
	{
	  /* Current entry is the first entry */
	  return;
	}
      else if (PrevPartEntry != NULL && NextPartEntry == NULL)
	{
	  /* Current entry is the last entry */

	  PrevPartEntry->PartInfo[1].StartingOffset.QuadPart =

⌨️ 快捷键说明

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