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

📄 partlist.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
	    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;
    }
  else
    {
      /* Insert an initialize a new partition entry */
      NewPartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap,
						  0,
						  sizeof(PARTENTRY));
      if (NewPartEntry == NULL)
	return;

      RtlZeroMemory (NewPartEntry,
		     sizeof(PARTENTRY));

      /* Insert the new entry into the list */
      InsertTailList (&PartEntry->ListEntry,
		      &NewPartEntry->ListEntry);

      NewPartEntry->New = TRUE;

      NewPartEntry->FormatState = Unformatted;
      NewPartEntry->PartInfo[0].StartingOffset.QuadPart =
	PartEntry->UnpartitionedOffset + DiskEntry->TrackSize;
      NewPartEntry->PartInfo[0].PartitionLength.QuadPart =
	PartitionSize - DiskEntry->TrackSize;
      NewPartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED;
      NewPartEntry->PartInfo[0].BootIndicator = FALSE; /* FIXME */
      NewPartEntry->PartInfo[0].RewritePartition = TRUE;
      NewPartEntry->PartInfo[1].RewritePartition = TRUE;
      NewPartEntry->PartInfo[2].RewritePartition = TRUE;
      NewPartEntry->PartInfo[3].RewritePartition = TRUE;

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

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

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

	  /* Update previous container partition data */

	  PrevPartEntry->PartInfo[1].StartingOffset.QuadPart =
	    NewPartEntry->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 =
		NewPartEntry->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 =
	    NewPartEntry->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 =
		NewPartEntry->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;
	}

      /* Update offset and size of the remaining unpartitioned disk space */
      PartEntry->UnpartitionedOffset += PartitionSize;
      PartEntry->UnpartitionedLength -= PartitionSize;
    }

  DiskEntry->Modified = TRUE;

  UpdatePartitionNumbers (DiskEntry);

  AssignDriverLetters (List);
}


VOID
DeleteCurrentPartition (PPARTLIST List)
{
  PDISKENTRY DiskEntry;
  PPARTENTRY PartEntry;
  PPARTENTRY PrevPartEntry;
  PPARTENTRY NextPartEntry;

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

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

  /* Adjust container partition entries */

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

      /*
       * The first extended partition can not be deleted
       * as long as other extended partitions are present.
       */
      if (PrevPartEntry->ListEntry.Blink == &DiskEntry->PartListHead)
	return;

      /* Copy previous container partition data to current entry */
      RtlCopyMemory (&PrevPartEntry->PartInfo[1],
		     &PartEntry->PartInfo[1],
		     sizeof(PARTITION_INFORMATION));
      PrevPartEntry->PartInfo[1].RewritePartition = TRUE;
    }
  else if (PrevPartEntry == NULL && NextPartEntry != NULL)
    {
      /*
       * A primary partition can not be deleted as long as
       * extended partitions are present.
       */
      return;
    }
  else if (PrevPartEntry != NULL && NextPartEntry == NULL)
    {
      /* Current entry is the last entry */
      RtlZeroMemory (&PrevPartEntry->PartInfo[1],
		     sizeof(PARTITION_INFORMATION));
      PrevPartEntry->PartInfo[1].RewritePartition = TRUE;
    }


  /* Adjust unpartitioned disk space entries */

  /* Get pointer to previous and next unpartitioned entries */
  PrevPartEntry = GetPrevUnpartitionedEntry (DiskEntry,
					     PartEntry);

  NextPartEntry = GetNextUnpartitionedEntry (DiskEntry,
					     PartEntry);

  if (PrevPartEntry != NULL && NextPartEntry != NULL)
    {
      /* Merge previous, current and next unpartitioned entry */

      /* Adjust the previous entries length */
      PrevPartEntry->UnpartitionedLength +=
	(PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize +
	 NextPartEntry->UnpartitionedLength);

      /* Remove the current entry */
      RemoveEntryList (&PartEntry->ListEntry);
      RtlFreeHeap (ProcessHeap,
		   0,
		   PartEntry);

      /* Remove the next entry */
      RemoveEntryList (&NextPartEntry->ListEntry);
      RtlFreeHeap (ProcessHeap,
		   0,
		   NextPartEntry);

      /* Update current partition */
      List->CurrentPartition = PrevPartEntry;
    }
  else if (PrevPartEntry != NULL && NextPartEntry == NULL)
    {
      /* Merge current and previous unpartitioned entry */

      /* Adjust the previous entries length */
      PrevPartEntry->UnpartitionedLength +=
	(PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize);

      /* Remove the current entry */
      RemoveEntryList (&PartEntry->ListEntry);
      RtlFreeHeap (ProcessHeap,
		   0,
		   PartEntry);

      /* Update current partition */
      List->CurrentPartition = PrevPartEntry;
    }
  else if (PrevPartEntry == NULL && NextPartEntry != NULL)
    {
      /* Merge current and next unpartitioned entry */

      /* Adjust the next entries offset and length */
      NextPartEntry->UnpartitionedOffset =
	PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
      NextPartEntry->UnpartitionedLength +=
	(PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize);

      /* Remove the current entry */
      RemoveEntryList (&PartEntry->ListEntry);
      RtlFreeHeap (ProcessHeap,
		   0,
		   PartEntry);

      /* Update current partition */
      List->CurrentPartition = NextPartEntry;
    }
  else
    {
      /* Nothing to merge but change current entry */
      PartEntry->New = FALSE;
      PartEntry->Unpartitioned = TRUE;
      PartEntry->UnpartitionedOffset =
	PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize;
      PartEntry->UnpartitionedLength =
	PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize;

      /* Wipe the partition table */
      RtlZeroMemory (&PartEntry->PartInfo,
		     sizeof(PartEntry->PartInfo));
    }

  DiskEntry->Modified = TRUE;

  UpdatePartitionNumbers (DiskEntry);

  AssignDriverLetters (List);
}


VOID
CheckActiveBootPartition (PPARTLIST List)
{
  PDISKENTRY DiskEntry;
  PPARTENTRY PartEntry;

  /* Check for empty disk list */
  if (IsListEmpty (&List->DiskListHead))
    {
      List->ActiveBootDisk = NULL;
      List->ActiveBootPartition = NULL;
      return;
    }

#if 0
  if (List->ActiveBootDisk != NULL &&
      List->ActiveBootPartition != NULL)
    {
      /* We already have an active boot partition */
      return;
    }
#endif

  DiskEntry = CONTAINING_RECORD (List->DiskListHead.Flink,
				 DISKENTRY,
				 ListEntry);

  /* Check for empty partition list */
  if (IsListEmpty (&DiskEntry->PartListHead))
    {
      List->ActiveBootDisk = NULL;
      List->ActiveBootPartition = NULL;
      return;
    }

  PartEntry = CONTAINING_RECORD (DiskEntry->PartListHead.Flink,
				 PARTENTRY,
				 ListEntry);

  /* Set active boot partition */
  if ((DiskEntry->NewDisk == TRUE) ||
      (PartEntry->PartInfo[0].BootIndicator == FALSE &&
       PartEntry->PartInfo[1].BootIndicator == FALSE &&
       PartEntry->PartInfo[2].BootIndicator == FALSE &&
       PartEntry->PartInfo[3].BootIndicator == FALSE))
    {
      PartEntry->PartInfo[0].BootIndicator = TRUE;
      PartEntry->PartInfo[0].RewritePartition = TRUE;
      DiskEntry->Modified = TRUE;
    }

  /* FIXME: Might be incorrect if partitions were created by Linux FDISK */
  List->ActiveBootDisk = DiskEntry;
  List->ActiveBootPartition = PartEntry;
}


BOOLEAN
CheckForLinuxFdiskPartitions (PPARTLIST List)
{
  PDISKENTRY DiskEntry;
  PPARTENTRY PartEntry;
  PLIST_ENTRY Entry1;
  PLIST_ENTRY Entry2;
  ULONG PartitionCount;
  ULONG i;

  Entry1 = List->DiskListHead.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->Unpartitioned == FALSE)
	    {
	      PartitionCount = 0;

	      for (i = 0; i < 4; i++)
		{
		  if (!IsContainerPartition (PartEntry->PartInfo[i].PartitionType) &&
		      PartEntry->PartInfo[i].PartitionLength.QuadPart != 0ULL)
		    {
		      PartitionCount++;
		    }
		}

	      if (PartitionCount > 1)
		{
		  return TRUE;
		}
	    }

	  Entry2 = Entry2->Flink;
	}

      Entry1 = Entry1->Flink;
    }

  return FALSE;
}


BOOLEAN
WritePartitionsToDisk (PPARTLIST List)
{
  PDRIVE_LAYOUT_INFORMATION DriveLayout;
  OBJECT_ATTRIBUTES ObjectAttributes;
  IO_STATUS_BLOCK Iosb;
  WCHAR SrcPath[MAX_PATH];
  WCHAR DstPath[MAX_PATH];
  UNICODE_STRING Name;
  HANDLE FileHandle;
  PDISKENTRY DiskEntry1;
  PDISKENTRY DiskEntry2;
  PPARTENTRY PartEntry;
  PLIST_ENTRY Entry1;
  PLIST_ENTRY Entry2;
  ULONG PartitionCount;
  ULONG DriveLayoutSize;
  ULONG Index;
  NTSTATUS Status;

  if (List == NULL)
    {
      return TRUE;
    }

  Entry1 = List->DiskListHead.Flink;
  while (Entry1 != &List->DiskListHead)
    {
      DiskEntry1 = CONTAINING_RECORD (Entry1,
				      DISKENTRY,
				      ListEntry);

      if (DiskEntry1->Modified == TRUE)
	{
	  /* Count partitioned entries */
	  PartitionCount = 0;
	  Entry2 = DiskEntry1->PartListHead.Flink;
	  while (Entry2 != &DiskEntry1->PartListHead)
	    {
	      PartEntry = CONTAINING_RECORD (Entry2,
					     PARTENTRY,
					     ListEntry);
	      if (PartEntry->Unpartitioned == FALSE)
		{
		  PartitionCount += 4;
		}

	      Entry2 = Entry2->Flink;
	    }
          if (PartitionCount == 0)
            {
              DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) +
		((4 - 1) * s

⌨️ 快捷键说明

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