From a40bd103fc2870fc25a9ba3da09927826eba055e Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 12 Jan 2026 15:29:54 +0100 Subject: [PATCH] [DISKPART] Prevent deletion of boot and system partitions --- base/system/diskpart/delete.c | 6 +++ base/system/diskpart/diskpart.h | 5 +- base/system/diskpart/lang/de-DE.rc | 3 +- base/system/diskpart/lang/en-US.rc | 1 + base/system/diskpart/lang/it-IT.rc | 1 + base/system/diskpart/lang/pl-PL.rc | 1 + base/system/diskpart/lang/pt-PT.rc | 1 + base/system/diskpart/lang/ro-RO.rc | 1 + base/system/diskpart/lang/ru-RU.rc | 1 + base/system/diskpart/lang/sq-AL.rc | 1 + base/system/diskpart/lang/tr-TR.rc | 1 + base/system/diskpart/lang/zh-CN.rc | 1 + base/system/diskpart/lang/zh-TW.rc | 1 + base/system/diskpart/partlist.c | 78 +++++++++++++++++++++++++++++- base/system/diskpart/resource.h | 1 + 15 files changed, 99 insertions(+), 4 deletions(-) diff --git a/base/system/diskpart/delete.c b/base/system/diskpart/delete.c index ab099c92673..3cd779a70da 100644 --- a/base/system/diskpart/delete.c +++ b/base/system/diskpart/delete.c @@ -324,6 +324,12 @@ DeletePartition( } } + if (CurrentPartition->IsBoot || CurrentPartition->IsSystem) + { + ConResPuts(StdOut, IDS_DELETE_PARTITION_SYSTEM); + return EXIT_SUCCESS; + } + if (CurrentDisk->PartitionStyle == PARTITION_STYLE_MBR) { DeleteMbrPartition(bOverride); diff --git a/base/system/diskpart/diskpart.h b/base/system/diskpart/diskpart.h index b15e359a046..1ef27d761c4 100644 --- a/base/system/diskpart/diskpart.h +++ b/base/system/diskpart/diskpart.h @@ -109,7 +109,6 @@ typedef enum _FORMATSTATE typedef enum _VOLUME_TYPE { VOLUME_TYPE_CDROM, -// VOLUME_TYPE_DVD, VOLUME_TYPE_PARTITION, VOLUME_TYPE_REMOVABLE, VOLUME_TYPE_UNKNOWN @@ -167,6 +166,10 @@ typedef struct _PARTENTRY BOOLEAN NeedsCheck; struct _FILE_SYSTEM_ITEM *FileSystem; + + BOOL IsSystem; + BOOL IsBoot; + } PARTENTRY, *PPARTENTRY; diff --git a/base/system/diskpart/lang/de-DE.rc b/base/system/diskpart/lang/de-DE.rc index 0182c5219c8..cfab204eb02 100644 --- a/base/system/diskpart/lang/de-DE.rc +++ b/base/system/diskpart/lang/de-DE.rc @@ -69,7 +69,8 @@ END STRINGTABLE BEGIN IDS_DELETE_PARTITION_FAIL "\nDie gewählte Partition konnte nicht gelöscht werden.\nVergewissern Sie sich, dass die Partition wirklich gelöscht werden kann.\n" - IDS_DELETE_PARTITION_SUCCESS "\nDer gewählte Partition wurde erfolgreich gelöscht.\n" + IDS_DELETE_PARTITION_SUCCESS "\nDie gewählte Partition wurde erfolgreich gelöscht.\n" + IDS_DELETE_PARTITION_SYSTEM "\nDie gewählte Partition ist möglicherweise für den Betrieb des Computers erforderlich und kann nicht gelöscht werden.\n" END /* Disk Information Labels */ diff --git a/base/system/diskpart/lang/en-US.rc b/base/system/diskpart/lang/en-US.rc index 5ee708c65af..f1b43695364 100644 --- a/base/system/diskpart/lang/en-US.rc +++ b/base/system/diskpart/lang/en-US.rc @@ -70,6 +70,7 @@ STRINGTABLE BEGIN IDS_DELETE_PARTITION_FAIL "\nDiskPart failed to delete the selected partition.\nPlease make sure the selected partition is valid to delete.\n" IDS_DELETE_PARTITION_SUCCESS "\nDiskPart successfully deleted the selected partition.\n" + IDS_DELETE_PARTITION_SYSTEM "\nThe selected partition may be neccessary to the operation of your computer, and may not be deleted.\n" END /* Disk Information Labels */ diff --git a/base/system/diskpart/lang/it-IT.rc b/base/system/diskpart/lang/it-IT.rc index 69036f2a3d0..349b41e40ae 100644 --- a/base/system/diskpart/lang/it-IT.rc +++ b/base/system/diskpart/lang/it-IT.rc @@ -77,6 +77,7 @@ STRINGTABLE BEGIN IDS_DELETE_PARTITION_FAIL "\nDiskPart ha fallito ad eliminare la partizione selezionata.\nAssicurarsi che la partizione selezionata sia valida.\n" IDS_DELETE_PARTITION_SUCCESS "\nDiskPart ha eliminato con successo la partizione selezionata.\n" + IDS_DELETE_PARTITION_SYSTEM "\nThe selected partition may be neccessary to the operation of your computer, and may not be deleted.\n" END /* Disk Information Labels */ diff --git a/base/system/diskpart/lang/pl-PL.rc b/base/system/diskpart/lang/pl-PL.rc index 6b4046fb137..55f9fa25d17 100644 --- a/base/system/diskpart/lang/pl-PL.rc +++ b/base/system/diskpart/lang/pl-PL.rc @@ -70,6 +70,7 @@ STRINGTABLE BEGIN IDS_DELETE_PARTITION_FAIL "\nDiskPart nie może usunąć wybranej partycji.\nUpewnij się, że wybrana partycja nadaje się do usunięcia.\n" IDS_DELETE_PARTITION_SUCCESS "\nDiskPart pomyślnie usunął wybraną partycję.\n" + IDS_DELETE_PARTITION_SYSTEM "\nThe selected partition may be neccessary to the operation of your computer, and may not be deleted.\n" END /* Disk Information Labels */ diff --git a/base/system/diskpart/lang/pt-PT.rc b/base/system/diskpart/lang/pt-PT.rc index c4d8113bcc9..e7c44bf95d5 100644 --- a/base/system/diskpart/lang/pt-PT.rc +++ b/base/system/diskpart/lang/pt-PT.rc @@ -72,6 +72,7 @@ STRINGTABLE BEGIN IDS_DELETE_PARTITION_FAIL "\nDiskPart failed to delete the selected partition.\nPlease make sure the selected partition is valid to delete.\n" IDS_DELETE_PARTITION_SUCCESS "\nDiskPart successfully deleted the selected partition.\n" + IDS_DELETE_PARTITION_SYSTEM "\nThe selected partition may be neccessary to the operation of your computer, and may not be deleted.\n" END /* Disk Information Labels */ diff --git a/base/system/diskpart/lang/ro-RO.rc b/base/system/diskpart/lang/ro-RO.rc index 4b5144c388a..22a99fb88f1 100644 --- a/base/system/diskpart/lang/ro-RO.rc +++ b/base/system/diskpart/lang/ro-RO.rc @@ -78,6 +78,7 @@ STRINGTABLE BEGIN IDS_DELETE_PARTITION_FAIL "\nDiskPart nu a reușit să șteargă partiția selectată.\nAsigurați-vă că partiția selectată este validă pentru ștergere.\n" IDS_DELETE_PARTITION_SUCCESS "\nDiskPart a șters cu succes partiția selectată.\n" + IDS_DELETE_PARTITION_SYSTEM "\nThe selected partition may be neccessary to the operation of your computer, and may not be deleted.\n" END /* Disk Information Labels */ diff --git a/base/system/diskpart/lang/ru-RU.rc b/base/system/diskpart/lang/ru-RU.rc index ecb2cd036ad..706d2606385 100644 --- a/base/system/diskpart/lang/ru-RU.rc +++ b/base/system/diskpart/lang/ru-RU.rc @@ -72,6 +72,7 @@ STRINGTABLE BEGIN IDS_DELETE_PARTITION_FAIL "\nDiskPart failed to delete the selected partition.\nPlease make sure the selected partition is valid to delete.\n" IDS_DELETE_PARTITION_SUCCESS "\nDiskPart successfully deleted the selected partition.\n" + IDS_DELETE_PARTITION_SYSTEM "\nThe selected partition may be neccessary to the operation of your computer, and may not be deleted.\n" END /* Disk Information Labels */ diff --git a/base/system/diskpart/lang/sq-AL.rc b/base/system/diskpart/lang/sq-AL.rc index a624e2625b2..1310385dd46 100644 --- a/base/system/diskpart/lang/sq-AL.rc +++ b/base/system/diskpart/lang/sq-AL.rc @@ -74,6 +74,7 @@ STRINGTABLE BEGIN IDS_DELETE_PARTITION_FAIL "\nDiskPart failed to delete the selected partition.\nPlease make sure the selected partition is valid to delete.\n" IDS_DELETE_PARTITION_SUCCESS "\nDiskPart successfully deleted the selected partition.\n" + IDS_DELETE_PARTITION_SYSTEM "\nThe selected partition may be neccessary to the operation of your computer, and may not be deleted.\n" END /* Disk Information Labels */ diff --git a/base/system/diskpart/lang/tr-TR.rc b/base/system/diskpart/lang/tr-TR.rc index d45c347177e..643ba63a8a9 100644 --- a/base/system/diskpart/lang/tr-TR.rc +++ b/base/system/diskpart/lang/tr-TR.rc @@ -80,6 +80,7 @@ STRINGTABLE BEGIN IDS_DELETE_PARTITION_FAIL "\nDiskPart, seçilen bölümü silemedi.\nLütfen seçilen bölümün silmek için geçerli olduğundan emin olun.\n" IDS_DELETE_PARTITION_SUCCESS "\nDiskPart seçilen bölümü başarıyla sildi.\n" + IDS_DELETE_PARTITION_SYSTEM "\nThe selected partition may be neccessary to the operation of your computer, and may not be deleted.\n" END /* Disk Information Labels */ diff --git a/base/system/diskpart/lang/zh-CN.rc b/base/system/diskpart/lang/zh-CN.rc index 07f542d85ec..45b7c14e167 100644 --- a/base/system/diskpart/lang/zh-CN.rc +++ b/base/system/diskpart/lang/zh-CN.rc @@ -79,6 +79,7 @@ STRINGTABLE BEGIN IDS_DELETE_PARTITION_FAIL "\nDiskPart failed to delete the selected partition.\nPlease make sure the selected partition is valid to delete.\n" IDS_DELETE_PARTITION_SUCCESS "\nDiskPart successfully deleted the selected partition.\n" + IDS_DELETE_PARTITION_SYSTEM "\nThe selected partition may be neccessary to the operation of your computer, and may not be deleted.\n" END /* Disk Information Labels */ diff --git a/base/system/diskpart/lang/zh-TW.rc b/base/system/diskpart/lang/zh-TW.rc index 5e1c2a55f0a..26d404dfa2b 100644 --- a/base/system/diskpart/lang/zh-TW.rc +++ b/base/system/diskpart/lang/zh-TW.rc @@ -79,6 +79,7 @@ STRINGTABLE BEGIN IDS_DELETE_PARTITION_FAIL "\nDiskPart 無法刪除指定的磁碟分割。\n請確認已選擇的磁碟分割能夠正確地刪除。\n" IDS_DELETE_PARTITION_SUCCESS "\nDiskPart 成功刪除指定的磁碟分割。\n" + IDS_DELETE_PARTITION_SYSTEM "\nThe selected partition may be neccessary to the operation of your computer, and may not be deleted.\n" END /* Disk Information Labels */ diff --git a/base/system/diskpart/partlist.c b/base/system/diskpart/partlist.c index e77fac048d1..cce4e857a28 100644 --- a/base/system/diskpart/partlist.c +++ b/base/system/diskpart/partlist.c @@ -1865,12 +1865,75 @@ GetDiskForVolume( } +static +PPARTENTRY +GetPartitionForVolume( + _In_ PVOLENTRY VolumeEntry) +{ + PLIST_ENTRY Entry1, Entry2; + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + INT i; + + DPRINT("GetPartitionFromVolume(%p)\n", VolumeEntry); + + DPRINT("Extents: %p\n", VolumeEntry->pExtents); + if (VolumeEntry->pExtents == NULL) + return NULL; + + DPRINT("Extents: %lu\n", VolumeEntry->pExtents->NumberOfDiskExtents); + + Entry1 = DiskListHead.Flink; + while (Entry1 != &DiskListHead) + { + DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry); + + for (i = 0; i < VolumeEntry->pExtents->NumberOfDiskExtents; i++) + { + DPRINT("DiskNumber: %lu -- %lu\n", VolumeEntry->pExtents->Extents[i].DiskNumber, DiskEntry->DiskNumber); + if (VolumeEntry->pExtents->Extents[i].DiskNumber == DiskEntry->DiskNumber) + { + + Entry2 = DiskEntry->PrimaryPartListHead.Flink; + while (Entry2 != &DiskEntry->PrimaryPartListHead) + { + PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); + + if ((VolumeEntry->pExtents->Extents[i].StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * PartEntry->DiskEntry->BytesPerSector) && + (VolumeEntry->pExtents->Extents[i].ExtentLength.QuadPart == PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector)) + return PartEntry; + + Entry2 = Entry2->Flink; + } + + Entry2 = DiskEntry->LogicalPartListHead.Flink; + while (Entry2 != &DiskEntry->LogicalPartListHead) + { + PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); + + if ((VolumeEntry->pExtents->Extents[i].StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * PartEntry->DiskEntry->BytesPerSector) && + (VolumeEntry->pExtents->Extents[i].ExtentLength.QuadPart == PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector)) + return PartEntry; + + Entry2 = Entry2->Flink; + } + } + } + + Entry1 = Entry1->Flink; + } + + return NULL; +} + + static VOID IsVolumeSystem( _In_ PVOLENTRY VolumeEntry) { WCHAR szSystemPartition[MAX_PATH]; + PPARTENTRY PartEntry; HKEY hKey; DWORD dwError, dwLength; @@ -1904,11 +1967,17 @@ IsVolumeSystem( return; } - DPRINT1("SystemPartition: %S\n", szSystemPartition); - DPRINT1("DeviceName: %S\n", VolumeEntry->DeviceName); + DPRINT("SystemPartition: %S\n", szSystemPartition); + DPRINT("DeviceName: %S\n", VolumeEntry->DeviceName); if (_wcsnicmp(szSystemPartition, VolumeEntry->DeviceName, wcslen(szSystemPartition)) == 0) + { VolumeEntry->IsSystem = TRUE; + + PartEntry = GetPartitionForVolume(VolumeEntry); + if (PartEntry) + PartEntry->IsSystem = TRUE; + } } @@ -1919,6 +1988,7 @@ IsVolumeBoot( { WCHAR szSystemDir[MAX_PATH]; PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; DPRINT("IsVolumeBoot()\n"); @@ -1937,6 +2007,10 @@ IsVolumeBoot( { VolumeEntry->IsBoot = TRUE; + PartEntry = GetPartitionForVolume(VolumeEntry); + if (PartEntry) + PartEntry->IsBoot = TRUE; + DiskEntry = GetDiskForVolume(VolumeEntry); if (DiskEntry) DiskEntry->IsBoot = TRUE; diff --git a/base/system/diskpart/resource.h b/base/system/diskpart/resource.h index 9bc532e0288..edfdc0c6eb8 100644 --- a/base/system/diskpart/resource.h +++ b/base/system/diskpart/resource.h @@ -50,6 +50,7 @@ #define IDS_DELETE_PARTITION_FAIL 1070 #define IDS_DELETE_PARTITION_SUCCESS 1071 +#define IDS_DELETE_PARTITION_SYSTEM 1072 #define IDS_DETAIL_DISK_DESCRIPTION 1106 #define IDS_DETAIL_DISK_ID 1107