partlist.c

来自「一个类似windows」· C语言 代码 · 共 2,354 行 · 第 1/5 页

C
2,354
字号
    }
  else
    {
      FillConsoleOutputCharacter (0xC4, // '-',
			          List->Right - List->Left - 5,
			          coPos,
			          &Written);
      coPos.X = List->Right - 5;
      WriteConsoleOutputCharacters ("(\x18)", // "(up)"
			            3,
			            coPos);
      coPos.X = List->Right - 2;
      FillConsoleOutputCharacter (0xC4, // '-',
			          2,
			          coPos,
			          &Written);
    }

  /* draw upper right corner */
  coPos.X = List->Right;
  coPos.Y = List->Top;
  FillConsoleOutputCharacter (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;
      FillConsoleOutputCharacter (0xB3, // '|',
				  1,
				  coPos,
				  &Written);

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

  /* draw lower left corner */
  coPos.X = List->Left;
  coPos.Y = List->Bottom;
  FillConsoleOutputCharacter (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)
    {
      FillConsoleOutputCharacter (0xC4, // '-',
			          List->Right - List->Left - 1,
			          coPos,
			          &Written);
    }
  else
    {
      FillConsoleOutputCharacter (0xC4, // '-',
			          List->Right - List->Left - 5,
			          coPos,
			          &Written);
      coPos.X = List->Right - 5;
      WriteConsoleOutputCharacters ("(\x19)", // "(down)"
			            3,
			            coPos);
      coPos.X = List->Right - 2;
      FillConsoleOutputCharacter (0xC4, // '-',
			          2,
			          coPos,
			          &Written);
    }

  /* draw lower right corner */
  coPos.X = List->Right;
  coPos.Y = List->Bottom;
  FillConsoleOutputCharacter (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 =
	    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;
	    }

	  if ((PartEntry->PartInfo[1].StartingOffset.QuadPart +
	       PartEntry->PartInfo[1].PartitionLength.QuadPart) <
	       (1024LL * 255LL * 63LL * 512LL))
	    {
	      PrevPartEntry->PartInfo[1].PartitionType = PARTITION_EXTENDED;
	    }
	  else
	    {
	      PrevPartEntry->PartInfo[1].PartitionType = PARTITION_XINT13_EXTENDED;
	    }

	  PrevPartEntry->PartInfo[1].BootIndicator = FALSE;
	  PrevPartEntry->PartInfo[1].RewritePartition = TRUE;
	}

      PartEntry->AutoCreate = AutoCreate;
      PartEntry->New = TRUE;
      PartEntry->Unpartitioned = FALSE;
      PartEntry->UnpartitionedOffset = 0ULL;
      PartEntry->UnpartitionedLength = 0ULL;

⌨️ 快捷键说明

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