ReactOS 0.4.15-dev-6675-gcbc63d8
partlist.h File Reference
#include <pshpack1.h>
#include <poppack.h>
Include dependency graph for partlist.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _PARTENTRY
 
struct  _DISKENTRY
 
struct  _BIOSDISKENTRY
 
struct  _PARTLIST
 
struct  _PARTITION
 
struct  _PARTITION_SECTOR
 
struct  BIOS_DISK
 

Macros

#define PARTITION_EISA   0x12
 
#define PARTITION_HIBERNATION   0x84
 
#define PARTITION_DIAGNOSTIC   0xA0
 
#define PARTITION_DELL   0xDE
 
#define PARTITION_IBM   0xFE
 
#define IsOEMPartition(PartitionType)
 
#define PARTITION_TBL_SIZE   4
 
#define PARTITION_MAGIC   0xAA55
 
#define EFI_PMBR_OSTYPE_EFI   0xEE
 

Typedefs

typedef enum _FORMATSTATE FORMATSTATE
 
typedef enum _FORMATSTATEPFORMATSTATE
 
typedef struct _PARTENTRY PARTENTRY
 
typedef struct _PARTENTRYPPARTENTRY
 
typedef struct _DISKENTRY DISKENTRY
 
typedef struct _DISKENTRYPDISKENTRY
 
typedef struct _BIOSDISKENTRY BIOSDISKENTRY
 
typedef struct _BIOSDISKENTRYPBIOSDISKENTRY
 
typedef struct _PARTLIST PARTLIST
 
typedef struct _PARTLISTPPARTLIST
 
typedef struct _PARTITION PARTITION
 
typedef struct _PARTITIONPPARTITION
 
typedef struct _PARTITION_SECTOR PARTITION_SECTOR
 
typedef struct _PARTITION_SECTORPPARTITION_SECTOR
 
typedef struct BIOS_DISKPBIOS_DISK
 

Enumerations

enum  _FORMATSTATE {
  Unformatted , UnformattedOrDamaged , UnknownFormat , Preformatted ,
  Formatted , Unformatted , UnformattedOrDamaged , UnknownFormat ,
  Preformatted , Formatted
}
 

Functions

ULONGLONG AlignDown (IN ULONGLONG Value, IN ULONG Alignment)
 
ULONGLONG AlignUp (IN ULONGLONG Value, IN ULONG Alignment)
 
ULONGLONG RoundingDivide (IN ULONGLONG Dividend, IN ULONGLONG Divisor)
 
BOOLEAN IsSuperFloppy (IN PDISKENTRY DiskEntry)
 
BOOLEAN IsPartitionActive (IN PPARTENTRY PartEntry)
 
PPARTLIST CreatePartitionList (VOID)
 
VOID DestroyPartitionList (IN PPARTLIST List)
 
PDISKENTRY GetDiskByBiosNumber (IN PPARTLIST List, IN ULONG HwDiskNumber)
 
PDISKENTRY GetDiskByNumber (IN PPARTLIST List, IN ULONG DiskNumber)
 
PDISKENTRY GetDiskBySCSI (IN PPARTLIST List, IN USHORT Port, IN USHORT Bus, IN USHORT Id)
 
PDISKENTRY GetDiskBySignature (IN PPARTLIST List, IN ULONG Signature)
 
PPARTENTRY GetPartition (IN PDISKENTRY DiskEntry, IN ULONG PartitionNumber)
 
BOOLEAN GetDiskOrPartition (IN PPARTLIST List, IN ULONG DiskNumber, IN ULONG PartitionNumber OPTIONAL, OUT PDISKENTRY *pDiskEntry, OUT PPARTENTRY *pPartEntry OPTIONAL)
 
PPARTENTRY SelectPartition (IN PPARTLIST List, IN ULONG DiskNumber, IN ULONG PartitionNumber)
 
PPARTENTRY GetNextPartition (IN PPARTLIST List, IN PPARTENTRY CurrentPart OPTIONAL)
 
PPARTENTRY GetPrevPartition (IN PPARTLIST List, IN PPARTENTRY CurrentPart OPTIONAL)
 
BOOLEAN CreatePrimaryPartition (IN PPARTLIST List, IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
 
BOOLEAN CreateExtendedPartition (IN PPARTLIST List, IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount)
 
BOOLEAN CreateLogicalPartition (IN PPARTLIST List, IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
 
NTSTATUS DismountVolume (IN PPARTENTRY PartEntry)
 
BOOLEAN DeletePartition (IN PPARTLIST List, IN PPARTENTRY PartEntry, OUT PPARTENTRY *FreeRegion OPTIONAL)
 
PPARTENTRY FindSupportedSystemPartition (IN PPARTLIST List, IN BOOLEAN ForceSelect, IN PDISKENTRY AlternativeDisk OPTIONAL, IN PPARTENTRY AlternativePart OPTIONAL)
 
BOOLEAN SetActivePartition (IN PPARTLIST List, IN PPARTENTRY PartEntry, IN PPARTENTRY OldActivePart OPTIONAL)
 
NTSTATUS WritePartitions (IN PDISKENTRY DiskEntry)
 
BOOLEAN WritePartitionsToDisk (IN PPARTLIST List)
 
BOOLEAN SetMountedDeviceValue (IN WCHAR Letter, IN ULONG Signature, IN LARGE_INTEGER StartingOffset)
 
BOOLEAN SetMountedDeviceValues (IN PPARTLIST List)
 
VOID SetMBRPartitionType (IN PPARTENTRY PartEntry, IN UCHAR PartitionType)
 
ERROR_NUMBER PrimaryPartitionCreationChecks (IN PPARTENTRY PartEntry)
 
ERROR_NUMBER ExtendedPartitionCreationChecks (IN PPARTENTRY PartEntry)
 
ERROR_NUMBER LogicalPartitionCreationChecks (IN PPARTENTRY PartEntry)
 
BOOLEAN GetNextUnformattedPartition (IN PPARTLIST List, OUT PDISKENTRY *pDiskEntry OPTIONAL, OUT PPARTENTRY *pPartEntry)
 
BOOLEAN GetNextUncheckedPartition (IN PPARTLIST List, OUT PDISKENTRY *pDiskEntry OPTIONAL, OUT PPARTENTRY *pPartEntry)
 

Macro Definition Documentation

◆ EFI_PMBR_OSTYPE_EFI

#define EFI_PMBR_OSTYPE_EFI   0xEE

Definition at line 175 of file partlist.h.

◆ IsOEMPartition

#define IsOEMPartition (   PartitionType)
Value:
#define PARTITION_DELL
Definition: partlist.h:19
#define PARTITION_EISA
Definition: partlist.h:16
#define PARTITION_IBM
Definition: partlist.h:20
#define PARTITION_DIAGNOSTIC
Definition: partlist.h:18
#define PARTITION_HIBERNATION
Definition: partlist.h:17
CHAR PartitionType
Definition: part_xbox.c:32

Definition at line 22 of file partlist.h.

◆ PARTITION_DELL

#define PARTITION_DELL   0xDE

Definition at line 19 of file partlist.h.

◆ PARTITION_DIAGNOSTIC

#define PARTITION_DIAGNOSTIC   0xA0

Definition at line 18 of file partlist.h.

◆ PARTITION_EISA

#define PARTITION_EISA   0x12

Definition at line 16 of file partlist.h.

◆ PARTITION_HIBERNATION

#define PARTITION_HIBERNATION   0x84

Definition at line 17 of file partlist.h.

◆ PARTITION_IBM

#define PARTITION_IBM   0xFE

Definition at line 20 of file partlist.h.

◆ PARTITION_MAGIC

#define PARTITION_MAGIC   0xAA55

Definition at line 172 of file partlist.h.

◆ PARTITION_TBL_SIZE

#define PARTITION_TBL_SIZE   4

Definition at line 170 of file partlist.h.

Typedef Documentation

◆ BIOSDISKENTRY

◆ DISKENTRY

◆ FORMATSTATE

◆ PARTENTRY

◆ PARTITION

◆ PARTITION_SECTOR

◆ PARTLIST

◆ PBIOS_DISK

◆ PBIOSDISKENTRY

◆ PDISKENTRY

◆ PFORMATSTATE

◆ PPARTENTRY

◆ PPARTITION

◆ PPARTITION_SECTOR

◆ PPARTLIST

Enumeration Type Documentation

◆ _FORMATSTATE

Enumerator
Unformatted 
UnformattedOrDamaged 
UnknownFormat 
Preformatted 
Formatted 
Unformatted 
UnformattedOrDamaged 
UnknownFormat 
Preformatted 
Formatted 

Definition at line 32 of file partlist.h.

33{
enum _FORMATSTATE FORMATSTATE
enum _FORMATSTATE * PFORMATSTATE
@ UnknownFormat
Definition: partlist.h:36
@ Preformatted
Definition: partlist.h:37
@ Formatted
Definition: partlist.h:38
@ Unformatted
Definition: partlist.h:34
@ UnformattedOrDamaged
Definition: partlist.h:35

Function Documentation

◆ AlignDown()

ULONGLONG AlignDown ( IN ULONGLONG  Value,
IN ULONG  Alignment 
)

Definition at line 67 of file partlist.c.

70{
71 ULONGLONG Temp;
72
73 Temp = Value / Alignment;
74
75 return Temp * Alignment;
76}
union Alignment_ Alignment
uint64_t ULONGLONG
Definition: typedefs.h:67
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by InitializePartitionEntry(), and ScanForUnpartitionedDiskSpace().

◆ AlignUp()

ULONGLONG AlignUp ( IN ULONGLONG  Value,
IN ULONG  Alignment 
)

Definition at line 79 of file partlist.c.

82{
83 ULONGLONG Temp, Result;
84
85 Temp = Value / Alignment;
86
87 Result = Temp * Alignment;
88 if (Value % Alignment)
90
91 return Result;
92}
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by PeFmtCreateSection().

◆ CreateExtendedPartition()

BOOLEAN CreateExtendedPartition ( IN PPARTLIST  List,
IN OUT PPARTENTRY  PartEntry,
IN ULONGLONG  SectorCount 
)

Definition at line 2850 of file partlist.c.

2854{
2856
2857 DPRINT1("CreateExtendedPartition(%I64u)\n", SectorCount);
2858
2859 if (List == NULL || PartEntry == NULL ||
2860 PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
2861 {
2862 return FALSE;
2863 }
2864
2866 if (Error != NOT_AN_ERROR)
2867 {
2868 DPRINT1("ExtendedPartitionCreationChecks() failed with error %lu\n", Error);
2869 return FALSE;
2870 }
2871
2872 /* Initialize the partition entry, inserting a new blank region if needed */
2873 if (!InitializePartitionEntry(PartEntry, SectorCount, FALSE))
2874 return FALSE;
2875
2876 ASSERT(PartEntry->LogicalPartition == FALSE);
2877
2878 if (PartEntry->StartSector.QuadPart < 1450560)
2879 {
2880 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2881 PartEntry->PartitionType = PARTITION_EXTENDED;
2882 }
2883 else
2884 {
2885 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2886 PartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
2887 }
2888
2889 // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
2890 PartEntry->New = FALSE;
2891 PartEntry->FormatState = Formatted;
2892
2893 PartEntry->DiskEntry->ExtendedPartition = PartEntry;
2894
2895 AddLogicalDiskSpace(PartEntry->DiskEntry);
2896
2897 UpdateDiskLayout(PartEntry->DiskEntry);
2899
2900 return TRUE;
2901}
#define DPRINT1
Definition: precomp.h:8
BOOL Error
Definition: chkdsk.c:66
#define PARTITION_EXTENDED
Definition: disk.h:91
#define PARTITION_XINT13_EXTENDED
Definition: disk.h:98
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
enum _ERROR_NUMBER ERROR_NUMBER
@ NOT_AN_ERROR
Definition: errorcode.h:17
#define ASSERT(a)
Definition: mode.c:44
ULONG SectorCount
Definition: part_xbox.c:31
static BOOLEAN InitializePartitionEntry(IN OUT PPARTENTRY PartEntry, IN ULONGLONG SectorCount, IN BOOLEAN AutoCreate)
Definition: partlist.c:678
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2534
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:138
static VOID AddLogicalDiskSpace(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2823
ERROR_NUMBER ExtendedPartitionCreationChecks(IN PPARTENTRY PartEntry)
Definition: partlist.c:3981
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550

Referenced by CreateExtendedPartitionPage().

◆ CreateLogicalPartition()

BOOLEAN CreateLogicalPartition ( IN PPARTLIST  List,
IN OUT PPARTENTRY  PartEntry,
IN ULONGLONG  SectorCount,
IN BOOLEAN  AutoCreate 
)

Definition at line 2904 of file partlist.c.

2909{
2911
2912 DPRINT1("CreateLogicalPartition(%I64u)\n", SectorCount);
2913
2914 if (List == NULL || PartEntry == NULL ||
2915 PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
2916 {
2917 return FALSE;
2918 }
2919
2921 if (Error != NOT_AN_ERROR)
2922 {
2923 DPRINT1("LogicalPartitionCreationChecks() failed with error %lu\n", Error);
2924 return FALSE;
2925 }
2926
2927 /* Initialize the partition entry, inserting a new blank region if needed */
2928 if (!InitializePartitionEntry(PartEntry, SectorCount, AutoCreate))
2929 return FALSE;
2930
2931 ASSERT(PartEntry->LogicalPartition == TRUE);
2932
2933 UpdateDiskLayout(PartEntry->DiskEntry);
2935
2936 return TRUE;
2937}
ERROR_NUMBER LogicalPartitionCreationChecks(IN PPARTENTRY PartEntry)
Definition: partlist.c:4012

Referenced by CreateLogicalPartitionPage(), and SelectPartitionPage().

◆ CreatePartitionList()

PPARTLIST CreatePartitionList ( VOID  )

Definition at line 1847 of file partlist.c.

1848{
1850 PDISKENTRY SystemDisk;
1854 ULONG ReturnSize;
1856 ULONG DiskNumber;
1860
1862 0,
1863 sizeof(PARTLIST));
1864 if (List == NULL)
1865 return NULL;
1866
1867 List->SystemPartition = NULL;
1868
1869 InitializeListHead(&List->DiskListHead);
1870 InitializeListHead(&List->BiosDiskListHead);
1871
1872 /*
1873 * Enumerate the disks seen by the BIOS; this will be used later
1874 * to map drives seen by NTOS with their corresponding BIOS names.
1875 */
1877
1878 /* Enumerate disks seen by NTOS */
1880 &Sdi,
1881 sizeof(Sdi),
1882 &ReturnSize);
1883 if (!NT_SUCCESS(Status))
1884 {
1885 DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx", Status);
1887 return NULL;
1888 }
1889
1890 for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
1891 {
1893 L"\\Device\\Harddisk%lu\\Partition0",
1894 DiskNumber);
1896
1898 &Name,
1900 NULL,
1901 NULL);
1902
1906 &Iosb,
1909 if (NT_SUCCESS(Status))
1910 {
1911 AddDiskToList(FileHandle, DiskNumber, List);
1913 }
1914 }
1915
1919
1920 /*
1921 * Retrieve the system partition: the active partition on the system
1922 * disk (the one that will be booted by default by the hardware).
1923 */
1924 SystemDisk = GetSystemDisk(List);
1925 List->SystemPartition = (SystemDisk ? GetActiveDiskPartition(SystemDisk) : NULL);
1926
1927 return List;
1928}
struct NameRec_ * Name
Definition: cdprocs.h:460
LONG NTSTATUS
Definition: precomp.h:26
HANDLE ProcessHeap
Definition: servman.c:15
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define MAX_PATH
Definition: compat.h:34
#define FILE_SHARE_READ
Definition: compat.h:136
return Iosb
Definition: create.c:4402
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ SystemDeviceInformation
Definition: ntddk_ex.h:18
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
Status
Definition: gdiplustypes.h:25
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
struct _PARTLIST * PPARTLIST
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
#define L(x)
Definition: ntvdm.h:50
static PDISKENTRY GetSystemDisk(IN PPARTLIST List)
Definition: partlist.c:1718
static VOID AddDiskToList(IN HANDLE FileHandle, IN ULONG DiskNumber, IN PPARTLIST List)
Definition: partlist.c:1306
static VOID UpdateDiskSignatures(IN PPARTLIST List)
Definition: partlist.c:1215
static VOID EnumerateBiosDiskEntries(IN PPARTLIST PartList)
Definition: partlist.c:337
static PPARTENTRY GetActiveDiskPartition(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1791
static VOID UpdateHwDiskNumbers(IN PPARTLIST List)
Definition: partlist.c:1245
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
uint32_t ULONG
Definition: typedefs.h:59
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ CreatePrimaryPartition()

BOOLEAN CreatePrimaryPartition ( IN PPARTLIST  List,
IN OUT PPARTENTRY  PartEntry,
IN ULONGLONG  SectorCount,
IN BOOLEAN  AutoCreate 
)

Definition at line 2786 of file partlist.c.

2791{
2793
2794 DPRINT1("CreatePrimaryPartition(%I64u)\n", SectorCount);
2795
2796 if (List == NULL || PartEntry == NULL ||
2797 PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
2798 {
2799 return FALSE;
2800 }
2801
2803 if (Error != NOT_AN_ERROR)
2804 {
2805 DPRINT1("PrimaryPartitionCreationChecks() failed with error %lu\n", Error);
2806 return FALSE;
2807 }
2808
2809 /* Initialize the partition entry, inserting a new blank region if needed */
2810 if (!InitializePartitionEntry(PartEntry, SectorCount, AutoCreate))
2811 return FALSE;
2812
2813 ASSERT(PartEntry->LogicalPartition == FALSE);
2814
2815 UpdateDiskLayout(PartEntry->DiskEntry);
2817
2818 return TRUE;
2819}
ERROR_NUMBER PrimaryPartitionCreationChecks(IN PPARTENTRY PartEntry)
Definition: partlist.c:3954

Referenced by CreatePrimaryPartitionPage(), SelectFileSystemPage(), and SelectPartitionPage().

◆ DeletePartition()

BOOLEAN DeletePartition ( IN PPARTLIST  List,
IN PPARTENTRY  PartEntry,
OUT PPARTENTRY *FreeRegion  OPTIONAL 
)

Definition at line 3047 of file partlist.c.

3051{
3052 PDISKENTRY DiskEntry;
3053 PPARTENTRY PrevPartEntry;
3054 PPARTENTRY NextPartEntry;
3055 PPARTENTRY LogicalPartEntry;
3057
3058 if (List == NULL || PartEntry == NULL ||
3059 PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned == FALSE)
3060 {
3061 return FALSE;
3062 }
3063
3064 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
3065
3066 /* Clear the system partition if it is being deleted */
3067 if (List->SystemPartition == PartEntry)
3068 {
3069 ASSERT(List->SystemPartition);
3070 List->SystemPartition = NULL;
3071 }
3072
3073 DiskEntry = PartEntry->DiskEntry;
3074
3075 /* Check which type of partition (primary/logical or extended) is being deleted */
3076 if (DiskEntry->ExtendedPartition == PartEntry)
3077 {
3078 /* An extended partition is being deleted: delete all logical partition entries */
3079 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
3080 {
3082 LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
3083
3084 /* Dismount the logical partition */
3085 DismountVolume(LogicalPartEntry);
3086
3087 /* Delete it */
3088 RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry);
3089 }
3090
3091 DiskEntry->ExtendedPartition = NULL;
3092 }
3093 else
3094 {
3095 /* A primary partition is being deleted: dismount it */
3096 DismountVolume(PartEntry);
3097 }
3098
3099 /* Adjust the unpartitioned disk space entries */
3100
3101 /* Get pointer to previous and next unpartitioned entries */
3102 PrevPartEntry = GetPrevUnpartitionedEntry(PartEntry);
3103 NextPartEntry = GetNextUnpartitionedEntry(PartEntry);
3104
3105 if (PrevPartEntry != NULL && NextPartEntry != NULL)
3106 {
3107 /* Merge the previous, current and next unpartitioned entries */
3108
3109 /* Adjust the previous entry length */
3110 PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
3111
3112 /* Remove the current and next entries */
3113 RemoveEntryList(&PartEntry->ListEntry);
3114 RtlFreeHeap(ProcessHeap, 0, PartEntry);
3115 RemoveEntryList(&NextPartEntry->ListEntry);
3116 RtlFreeHeap(ProcessHeap, 0, NextPartEntry);
3117
3118 /* Optionally return the freed region */
3119 if (FreeRegion)
3120 *FreeRegion = PrevPartEntry;
3121 }
3122 else if (PrevPartEntry != NULL && NextPartEntry == NULL)
3123 {
3124 /* Merge the current and the previous unpartitioned entries */
3125
3126 /* Adjust the previous entry length */
3127 PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3128
3129 /* Remove the current entry */
3130 RemoveEntryList(&PartEntry->ListEntry);
3131 RtlFreeHeap(ProcessHeap, 0, PartEntry);
3132
3133 /* Optionally return the freed region */
3134 if (FreeRegion)
3135 *FreeRegion = PrevPartEntry;
3136 }
3137 else if (PrevPartEntry == NULL && NextPartEntry != NULL)
3138 {
3139 /* Merge the current and the next unpartitioned entries */
3140
3141 /* Adjust the next entry offset and length */
3142 NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
3143 NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3144
3145 /* Remove the current entry */
3146 RemoveEntryList(&PartEntry->ListEntry);
3147 RtlFreeHeap(ProcessHeap, 0, PartEntry);
3148
3149 /* Optionally return the freed region */
3150 if (FreeRegion)
3151 *FreeRegion = NextPartEntry;
3152 }
3153 else
3154 {
3155 /* Nothing to merge but change the current entry */
3156 PartEntry->IsPartitioned = FALSE;
3157 PartEntry->OnDiskPartitionNumber = 0;
3158 PartEntry->PartitionNumber = 0;
3159 // PartEntry->PartitionIndex = 0;
3160 PartEntry->BootIndicator = FALSE;
3161 PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
3162 PartEntry->FormatState = Unformatted;
3163 PartEntry->FileSystem[0] = L'\0';
3164 PartEntry->DriveLetter = 0;
3165 RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
3166
3167 /* Optionally return the freed region */
3168 if (FreeRegion)
3169 *FreeRegion = PartEntry;
3170 }
3171
3172 UpdateDiskLayout(DiskEntry);
3174
3175 return TRUE;
3176}
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
static PPARTENTRY GetPrevUnpartitionedEntry(IN PPARTENTRY PartEntry)
Definition: partlist.c:2717
static PPARTENTRY GetNextUnpartitionedEntry(IN PPARTENTRY PartEntry)
Definition: partlist.c:2752
NTSTATUS DismountVolume(IN PPARTENTRY PartEntry)
Definition: partlist.c:2940
base of all file and directory entries
Definition: entries.h:83
PPARTENTRY ExtendedPartition
Definition: partlist.h:135
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:132
Definition: typedefs.h:120
BOOLEAN IsPartitioned
Definition: partlist.h:66
ULARGE_INTEGER SectorCount
Definition: partlist.h:50
LIST_ENTRY ListEntry
Definition: partlist.h:43
ULARGE_INTEGER StartSector
Definition: partlist.h:49
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by DeletePartitionPage().

◆ DestroyPartitionList()

VOID DestroyPartitionList ( IN PPARTLIST  List)

Definition at line 1931 of file partlist.c.

1933{
1934 PDISKENTRY DiskEntry;
1935 PBIOSDISKENTRY BiosDiskEntry;
1936 PPARTENTRY PartEntry;
1938
1939 /* Release disk and partition info */
1940 while (!IsListEmpty(&List->DiskListHead))
1941 {
1942 Entry = RemoveHeadList(&List->DiskListHead);
1943 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
1944
1945 /* Release driver name */
1946 RtlFreeUnicodeString(&DiskEntry->DriverName);
1947
1948 /* Release primary partition list */
1949 while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
1950 {
1952 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1953
1954 RtlFreeHeap(ProcessHeap, 0, PartEntry);
1955 }
1956
1957 /* Release logical partition list */
1958 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
1959 {
1961 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1962
1963 RtlFreeHeap(ProcessHeap, 0, PartEntry);
1964 }
1965
1966 /* Release layout buffer */
1967 if (DiskEntry->LayoutBuffer != NULL)
1968 RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
1969
1970 /* Release disk entry */
1971 RtlFreeHeap(ProcessHeap, 0, DiskEntry);
1972 }
1973
1974 /* Release the bios disk info */
1975 while (!IsListEmpty(&List->BiosDiskListHead))
1976 {
1977 Entry = RemoveHeadList(&List->BiosDiskListHead);
1978 BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
1979
1980 RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
1981 }
1982
1983 /* Release list head */
1985}
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
UNICODE_STRING DriverName
Definition: partlist.h:123
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:131
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:125

Referenced by QuitPage(), rescan_main(), SelectPartitionPage(), and wmain().

◆ DismountVolume()

NTSTATUS DismountVolume ( IN PPARTENTRY  PartEntry)

Definition at line 2940 of file partlist.c.

2942{
2944 NTSTATUS LockStatus;
2948 HANDLE PartitionHandle;
2950
2951 /* Check whether the partition is valid and was mounted by the system */
2952 if (!PartEntry->IsPartitioned ||
2953 IsContainerPartition(PartEntry->PartitionType) ||
2954 !IsRecognizedPartition(PartEntry->PartitionType) ||
2955 PartEntry->FormatState == UnknownFormat ||
2956 // NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
2957 // it has been usually mounted with RawFS and thus needs to be dismounted.
2958 !*PartEntry->FileSystem ||
2959 PartEntry->PartitionNumber == 0)
2960 {
2961 /* The partition is not mounted, so just return success */
2962 return STATUS_SUCCESS;
2963 }
2964
2965 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
2966
2967 /* Open the volume */
2969 L"\\Device\\Harddisk%lu\\Partition%lu",
2970 PartEntry->DiskEntry->DiskNumber,
2971 PartEntry->PartitionNumber);
2973
2975 &Name,
2977 NULL,
2978 NULL);
2979
2980 Status = NtOpenFile(&PartitionHandle,
2986 if (!NT_SUCCESS(Status))
2987 {
2988 DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
2989 return Status;
2990 }
2991
2992 /* Lock the volume */
2993 LockStatus = NtFsControlFile(PartitionHandle,
2994 NULL,
2995 NULL,
2996 NULL,
2999 NULL,
3000 0,
3001 NULL,
3002 0);
3003 if (!NT_SUCCESS(LockStatus))
3004 {
3005 DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
3006 }
3007
3008 /* Dismount the volume */
3009 Status = NtFsControlFile(PartitionHandle,
3010 NULL,
3011 NULL,
3012 NULL,
3015 NULL,
3016 0,
3017 NULL,
3018 0);
3019 if (!NT_SUCCESS(Status))
3020 {
3021 DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
3022 }
3023
3024 /* Unlock the volume */
3025 LockStatus = NtFsControlFile(PartitionHandle,
3026 NULL,
3027 NULL,
3028 NULL,
3031 NULL,
3032 0,
3033 NULL,
3034 0);
3035 if (!NT_SUCCESS(LockStatus))
3036 {
3037 DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
3038 }
3039
3040 /* Close the volume */
3041 NtClose(PartitionHandle);
3042
3043 return Status;
3044}
#define GENERIC_READ
Definition: compat.h:135
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
#define GENERIC_WRITE
Definition: nt_native.h:90
NTSYSAPI NTSTATUS NTAPI NtFsControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by AddPartitionToDisk(), clean_main(), and DeletePartition().

◆ ExtendedPartitionCreationChecks()

ERROR_NUMBER ExtendedPartitionCreationChecks ( IN PPARTENTRY  PartEntry)

Definition at line 3981 of file partlist.c.

3983{
3984 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
3985
3986 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3987 {
3988 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3989 return ERROR_WARN_PARTITION;
3990 }
3991
3992 /* Fail if the partition is already in use */
3993 if (PartEntry->IsPartitioned)
3994 return ERROR_NEW_PARTITION;
3995
3996 /* Only one primary partition is allowed on super-floppy */
3997 if (IsSuperFloppy(DiskEntry))
3999
4000 /* Fail if there are already 4 primary partitions in the list */
4001 if (GetPrimaryPartitionCount(DiskEntry) >= 4)
4003
4004 /* Fail if there is another extended partition in the list */
4005 if (DiskEntry->ExtendedPartition != NULL)
4007
4008 return ERROR_SUCCESS;
4009}
#define ERROR_SUCCESS
Definition: deptool.c:10
@ ERROR_WARN_PARTITION
Definition: errorcode.h:33
@ ERROR_NEW_PARTITION
Definition: errorcode.h:34
@ ERROR_ONLY_ONE_EXTENDED
Definition: errorcode.h:60
@ ERROR_PARTITION_TABLE_FULL
Definition: errorcode.h:59
@ PARTITION_STYLE_GPT
Definition: imports.h:202
static ULONG GetPrimaryPartitionCount(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2428
BOOLEAN IsSuperFloppy(IN PDISKENTRY DiskEntry)
Definition: partlist.c:501
PARTITION_STYLE DiskStyle
Definition: partlist.h:121

Referenced by CreateExtendedPartition(), and SelectPartitionPage().

◆ FindSupportedSystemPartition()

PPARTENTRY FindSupportedSystemPartition ( IN PPARTLIST  List,
IN BOOLEAN  ForceSelect,
IN PDISKENTRY AlternativeDisk  OPTIONAL,
IN PPARTENTRY AlternativePart  OPTIONAL 
)

Definition at line 3260 of file partlist.c.

3265{
3266 PLIST_ENTRY ListEntry;
3267 PDISKENTRY DiskEntry;
3268 PPARTENTRY PartEntry;
3269 PPARTENTRY ActivePartition;
3270 PPARTENTRY CandidatePartition = NULL;
3271
3272 /* Check for empty disk list */
3273 if (IsListEmpty(&List->DiskListHead))
3274 {
3275 /* No system partition! */
3276 ASSERT(List->SystemPartition == NULL);
3277 goto NoSystemPartition;
3278 }
3279
3280 /* Adjust the optional alternative disk if needed */
3281 if (!AlternativeDisk && AlternativePart)
3282 AlternativeDisk = AlternativePart->DiskEntry;
3283
3284 /* Ensure that the alternative partition is on the alternative disk */
3285 if (AlternativePart)
3286 ASSERT(AlternativeDisk && (AlternativePart->DiskEntry == AlternativeDisk));
3287
3288 /* Ensure that the alternative disk is in the list */
3289 if (AlternativeDisk)
3290 ASSERT(AlternativeDisk->PartList == List);
3291
3292 /* Start fresh */
3293 CandidatePartition = NULL;
3294
3295//
3296// Step 1 : Check the system disk.
3297//
3298
3299 /*
3300 * First, check whether the system disk, i.e. the one that will be booted
3301 * by default by the hardware, contains an active partition. If so this
3302 * should be our system partition.
3303 */
3304 DiskEntry = GetSystemDisk(List);
3305
3306 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3307 {
3308 DPRINT1("System disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
3309 goto UseAlternativeDisk;
3310 }
3311
3312 /* If we have a system partition (in the system disk), validate it */
3313 ActivePartition = List->SystemPartition;
3314 if (ActivePartition && IsSupportedActivePartition(ActivePartition))
3315 {
3316 CandidatePartition = ActivePartition;
3317
3318 DPRINT1("Use the current system partition %lu in disk %lu, drive letter %C\n",
3319 CandidatePartition->PartitionNumber,
3320 CandidatePartition->DiskEntry->DiskNumber,
3321 (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3322
3323 /* Return the candidate system partition */
3324 return CandidatePartition;
3325 }
3326
3327 /* If the system disk is not the optional alternative disk, perform the minimal checks */
3328 if (DiskEntry != AlternativeDisk)
3329 {
3330 /*
3331 * No active partition has been recognized. Enumerate all the (primary)
3332 * partitions in the system disk, excluding the possible current active
3333 * partition, to find a new candidate.
3334 */
3335 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3336 ListEntry != &DiskEntry->PrimaryPartListHead;
3337 ListEntry = ListEntry->Flink)
3338 {
3339 /* Retrieve the partition */
3340 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3341
3342 /* Skip the current active partition */
3343 if (PartEntry == ActivePartition)
3344 continue;
3345
3346 /* Check if the partition is partitioned and used */
3347 if (PartEntry->IsPartitioned &&
3349 {
3351
3352 /* If we get a candidate active partition in the disk, validate it */
3353 if (IsSupportedActivePartition(PartEntry))
3354 {
3355 CandidatePartition = PartEntry;
3356 goto UseAlternativePartition;
3357 }
3358 }
3359
3360#if 0
3361 /* Check if the partition is partitioned and used */
3362 if (!PartEntry->IsPartitioned)
3363 {
3365
3366 // TODO: Check for minimal size!!
3367 CandidatePartition = PartEntry;
3368 goto UseAlternativePartition;
3369 }
3370#endif
3371 }
3372
3373 /*
3374 * Still nothing, look whether there is some free space that we can use
3375 * for the new system partition. We must be sure that the total number
3376 * of partition is less than the maximum allowed, and that the minimal
3377 * size is fine.
3378 */
3379//
3380// TODO: Fix the handling of system partition being created in unpartitioned space!!
3381// --> When to partition it? etc...
3382//
3383 if (GetPrimaryPartitionCount(DiskEntry) < 4)
3384 {
3385 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3386 ListEntry != &DiskEntry->PrimaryPartListHead;
3387 ListEntry = ListEntry->Flink)
3388 {
3389 /* Retrieve the partition */
3390 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3391
3392 /* Skip the current active partition */
3393 if (PartEntry == ActivePartition)
3394 continue;
3395
3396 /* Check for unpartitioned space */
3397 if (!PartEntry->IsPartitioned)
3398 {
3400
3401 // TODO: Check for minimal size!!
3402 CandidatePartition = PartEntry;
3403 goto UseAlternativePartition;
3404 }
3405 }
3406 }
3407 }
3408
3409
3410//
3411// Step 2 : No active partition found: Check the alternative disk if specified.
3412//
3413
3414UseAlternativeDisk:
3415 if (!AlternativeDisk || (!ForceSelect && (DiskEntry != AlternativeDisk)))
3416 goto NoSystemPartition;
3417
3418 if (AlternativeDisk->DiskStyle == PARTITION_STYLE_GPT)
3419 {
3420 DPRINT1("Alternative disk -- GPT-partitioned disk detected, not currently supported by SETUP!\n");
3421 goto NoSystemPartition;
3422 }
3423
3424 if (DiskEntry != AlternativeDisk)
3425 {
3426 /* Choose the alternative disk */
3427 DiskEntry = AlternativeDisk;
3428
3429 /* If we get a candidate active partition, validate it */
3430 ActivePartition = GetActiveDiskPartition(DiskEntry);
3431 if (ActivePartition && IsSupportedActivePartition(ActivePartition))
3432 {
3433 CandidatePartition = ActivePartition;
3434 goto UseAlternativePartition;
3435 }
3436 }
3437
3438 /* We now may have an unsupported active partition, or none */
3439
3440/***
3441 *** TODO: Improve the selection:
3442 *** - If we want a really separate system partition from the partition where
3443 *** we install, do something similar to what's done below in the code.
3444 *** - Otherwise if we allow for the system partition to be also the partition
3445 *** where we install, just directly fall down to using AlternativePart.
3446 ***/
3447
3448 /* Retrieve the first partition of the disk */
3449 PartEntry = CONTAINING_RECORD(DiskEntry->PrimaryPartListHead.Flink,
3450 PARTENTRY, ListEntry);
3451 ASSERT(DiskEntry == PartEntry->DiskEntry);
3452
3453 CandidatePartition = PartEntry;
3454
3455 //
3456 // See: https://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/usetup/partlist.c?r1=63355&r2=63354&pathrev=63355#l2318
3457 //
3458
3459 /* Check if the disk is new and if so, use its first partition as the active system partition */
3460 if (DiskEntry->NewDisk)
3461 {
3462 // !IsContainerPartition(PartEntry->PartitionType);
3463 if (!CandidatePartition->IsPartitioned || !CandidatePartition->BootIndicator) /* CandidatePartition != ActivePartition */
3464 {
3465 ASSERT(DiskEntry == CandidatePartition->DiskEntry);
3466
3467 DPRINT1("Use new first active system partition %lu in disk %lu, drive letter %C\n",
3468 CandidatePartition->PartitionNumber,
3469 CandidatePartition->DiskEntry->DiskNumber,
3470 (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3471
3472 /* Return the candidate system partition */
3473 return CandidatePartition;
3474 }
3475
3476 // FIXME: What to do??
3477 DPRINT1("NewDisk TRUE but first partition is used?\n");
3478 }
3479
3480 /*
3481 * The disk is not new, check if any partition is initialized;
3482 * if not, the first one becomes the system partition.
3483 */
3484 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3485 ListEntry != &DiskEntry->PrimaryPartListHead;
3486 ListEntry = ListEntry->Flink)
3487 {
3488 /* Retrieve the partition */
3489 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3490
3491 /* Check if the partition is partitioned and is used */
3492 // !IsContainerPartition(PartEntry->PartitionType);
3493 if (/* PartEntry->IsPartitioned && */
3494 PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator)
3495 {
3496 break;
3497 }
3498 }
3499 if (ListEntry == &DiskEntry->PrimaryPartListHead)
3500 {
3501 /*
3502 * OK we haven't encountered any used and active partition,
3503 * so use the first one as the system partition.
3504 */
3505 ASSERT(DiskEntry == CandidatePartition->DiskEntry);
3506
3507 DPRINT1("Use first active system partition %lu in disk %lu, drive letter %C\n",
3508 CandidatePartition->PartitionNumber,
3509 CandidatePartition->DiskEntry->DiskNumber,
3510 (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3511
3512 /* Return the candidate system partition */
3513 return CandidatePartition;
3514 }
3515
3516 /*
3517 * The disk is not new, we did not find any actual active partition,
3518 * or the one we found was not supported, or any possible other candidate
3519 * is not supported. We then use the alternative partition if specified.
3520 */
3521 if (AlternativePart)
3522 {
3523 DPRINT1("No valid or supported system partition has been found, use the alternative partition!\n");
3524 CandidatePartition = AlternativePart;
3525 goto UseAlternativePartition;
3526 }
3527 else
3528 {
3529NoSystemPartition:
3530 DPRINT1("No valid or supported system partition has been found on this system!\n");
3531 return NULL;
3532 }
3533
3534UseAlternativePartition:
3535 /*
3536 * We are here because we did not find any (active) candidate system
3537 * partition that we know how to support. What we are going to do is
3538 * to change the existing system partition and use the alternative partition
3539 * (e.g. on which we install ReactOS) as the new system partition.
3540 * Then we will need to add in FreeLdr's boot menu an entry for booting
3541 * from the original system partition.
3542 */
3543 ASSERT(CandidatePartition);
3544
3545 DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %C\n",
3546 CandidatePartition->PartitionNumber,
3547 CandidatePartition->DiskEntry->DiskNumber,
3548 (CandidatePartition->DriveLetter == 0) ? L'-' : CandidatePartition->DriveLetter);
3549
3550 /* Return the candidate system partition */
3551 return CandidatePartition;
3552}
static BOOLEAN IsSupportedActivePartition(IN PPARTENTRY PartEntry)
Definition: partlist.c:3180
BOOLEAN NewDisk
Definition: partlist.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
UCHAR PartitionType
Definition: partlist.h:53
BOOLEAN BootIndicator
Definition: partlist.h:52
struct _DISKENTRY * DiskEntry
Definition: partlist.h:46
WCHAR DriveLetter
Definition: partlist.h:58
ULONG PartitionNumber
Definition: partlist.h:55

Referenced by SelectFileSystemPage().

◆ GetDiskByBiosNumber()

PDISKENTRY GetDiskByBiosNumber ( IN PPARTLIST  List,
IN ULONG  HwDiskNumber 
)

Definition at line 1988 of file partlist.c.

1991{
1992 PDISKENTRY DiskEntry;
1994
1995 /* Loop over the disks and find the correct one */
1996 for (Entry = List->DiskListHead.Flink;
1997 Entry != &List->DiskListHead;
1998 Entry = Entry->Flink)
1999 {
2000 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2001
2002 if (DiskEntry->HwDiskNumber == HwDiskNumber)
2003 {
2004 /* Disk found */
2005 return DiskEntry;
2006 }
2007 }
2008
2009 /* Disk not found, stop there */
2010 return NULL;
2011}
ULONG HwDiskNumber
Definition: partlist.h:105

◆ GetDiskByNumber()

PDISKENTRY GetDiskByNumber ( IN PPARTLIST  List,
IN ULONG  DiskNumber 
)

Definition at line 2014 of file partlist.c.

2017{
2018 PDISKENTRY DiskEntry;
2020
2021 /* Loop over the disks and find the correct one */
2022 for (Entry = List->DiskListHead.Flink;
2023 Entry != &List->DiskListHead;
2024 Entry = Entry->Flink)
2025 {
2026 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2027
2028 if (DiskEntry->DiskNumber == DiskNumber)
2029 {
2030 /* Disk found */
2031 return DiskEntry;
2032 }
2033 }
2034
2035 /* Disk not found, stop there */
2036 return NULL;
2037}
ULONG DiskNumber
Definition: partlist.h:111

Referenced by GetDiskOrPartition(), and SelectPartition().

◆ GetDiskBySCSI()

PDISKENTRY GetDiskBySCSI ( IN PPARTLIST  List,
IN USHORT  Port,
IN USHORT  Bus,
IN USHORT  Id 
)

Definition at line 2040 of file partlist.c.

2045{
2046 PDISKENTRY DiskEntry;
2048
2049 /* Loop over the disks and find the correct one */
2050 for (Entry = List->DiskListHead.Flink;
2051 Entry != &List->DiskListHead;
2052 Entry = Entry->Flink)
2053 {
2054 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2055
2056 if (DiskEntry->Port == Port &&
2057 DiskEntry->Bus == Bus &&
2058 DiskEntry->Id == Id)
2059 {
2060 /* Disk found */
2061 return DiskEntry;
2062 }
2063 }
2064
2065 /* Disk not found, stop there */
2066 return NULL;
2067}
DWORD Id
CPPORT Port[4]
Definition: headless.c:35
USHORT Bus
Definition: partlist.h:114
USHORT Id
Definition: partlist.h:115
USHORT Port
Definition: partlist.h:113

Referenced by ResolveArcNameManually().

◆ GetDiskBySignature()

PDISKENTRY GetDiskBySignature ( IN PPARTLIST  List,
IN ULONG  Signature 
)

Definition at line 2070 of file partlist.c.

2073{
2074 PDISKENTRY DiskEntry;
2076
2077 /* Loop over the disks and find the correct one */
2078 for (Entry = List->DiskListHead.Flink;
2079 Entry != &List->DiskListHead;
2080 Entry = Entry->Flink)
2081 {
2082 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2083
2084 if (DiskEntry->LayoutBuffer->Signature == Signature)
2085 {
2086 /* Disk found */
2087 return DiskEntry;
2088 }
2089 }
2090
2091 /* Disk not found, stop there */
2092 return NULL;
2093}
static const WCHAR Signature[]
Definition: parser.c:141

Referenced by ResolveArcNameManually().

◆ GetDiskOrPartition()

BOOLEAN GetDiskOrPartition ( IN PPARTLIST  List,
IN ULONG  DiskNumber,
IN ULONG PartitionNumber  OPTIONAL,
OUT PDISKENTRY pDiskEntry,
OUT PPARTENTRY *pPartEntry  OPTIONAL 
)

Definition at line 2143 of file partlist.c.

2149{
2150 PDISKENTRY DiskEntry;
2151 PPARTENTRY PartEntry = NULL;
2152
2153 /* Find the disk */
2154 DiskEntry = GetDiskByNumber(List, DiskNumber);
2155 if (!DiskEntry)
2156 return FALSE;
2157
2158 /* If we have a partition (PartitionNumber != 0), find it */
2159 if (PartitionNumber != 0)
2160 {
2161 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2162 {
2163 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2164 return FALSE;
2165 }
2166
2167 PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
2168 if (!PartEntry)
2169 return FALSE;
2170 ASSERT(PartEntry->DiskEntry == DiskEntry);
2171 }
2172
2173 /* Return the disk (and optionally the partition) */
2174 *pDiskEntry = DiskEntry;
2175 if (pPartEntry) *pPartEntry = PartEntry;
2176 return TRUE;
2177}
PPARTENTRY GetPartition(IN PDISKENTRY DiskEntry, IN ULONG PartitionNumber)
Definition: partlist.c:2096
PDISKENTRY GetDiskByNumber(IN PPARTLIST List, IN ULONG DiskNumber)
Definition: partlist.c:2014
#define DPRINT
Definition: sndvol32.h:71
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2061

Referenced by EnumerateInstallations().

◆ GetNextPartition()

PPARTENTRY GetNextPartition ( IN PPARTLIST  List,
IN PPARTENTRY CurrentPart  OPTIONAL 
)

Definition at line 2207 of file partlist.c.

2210{
2211 PLIST_ENTRY DiskListEntry;
2212 PLIST_ENTRY PartListEntry;
2214
2215 /* Fail if no disks are available */
2216 if (IsListEmpty(&List->DiskListHead))
2217 return NULL;
2218
2219 /* Check for the next usable entry on the current partition's disk */
2220 if (CurrentPart != NULL)
2221 {
2222 CurrentDisk = CurrentPart->DiskEntry;
2223
2224 if (CurrentPart->LogicalPartition)
2225 {
2226 /* Logical partition */
2227
2228 PartListEntry = CurrentPart->ListEntry.Flink;
2229 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2230 {
2231 /* Next logical partition */
2232 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2233 return CurrentPart;
2234 }
2235 else
2236 {
2237 PartListEntry = CurrentDisk->ExtendedPartition->ListEntry.Flink;
2238 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2239 {
2240 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2241 return CurrentPart;
2242 }
2243 }
2244 }
2245 else
2246 {
2247 /* Primary or extended partition */
2248
2249 if (CurrentPart->IsPartitioned &&
2250 IsContainerPartition(CurrentPart->PartitionType))
2251 {
2252 /* First logical partition */
2253 PartListEntry = CurrentDisk->LogicalPartListHead.Flink;
2254 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2255 {
2256 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2257 return CurrentPart;
2258 }
2259 }
2260 else
2261 {
2262 /* Next primary partition */
2263 PartListEntry = CurrentPart->ListEntry.Flink;
2264 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2265 {
2266 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2267 return CurrentPart;
2268 }
2269 }
2270 }
2271 }
2272
2273 /* Search for the first partition entry on the next disk */
2274 for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Flink
2275 : List->DiskListHead.Flink);
2276 DiskListEntry != &List->DiskListHead;
2277 DiskListEntry = DiskListEntry->Flink)
2278 {
2279 CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2280
2282 {
2283 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2284 continue;
2285 }
2286
2287 PartListEntry = CurrentDisk->PrimaryPartListHead.Flink;
2288 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2289 {
2290 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2291 return CurrentPart;
2292 }
2293 }
2294
2295 return NULL;
2296}
PDISKENTRY CurrentDisk
Definition: partlist.c:74
LIST_ENTRY ListEntry
Definition: partlist.h:83

Referenced by ScrollDownPartitionList().

◆ GetNextUncheckedPartition()

BOOLEAN GetNextUncheckedPartition ( IN PPARTLIST  List,
OUT PDISKENTRY *pDiskEntry  OPTIONAL,
OUT PPARTENTRY pPartEntry 
)

Definition at line 4094 of file partlist.c.

4098{
4099 PLIST_ENTRY Entry1, Entry2;
4100 PDISKENTRY DiskEntry;
4101 PPARTENTRY PartEntry;
4102
4103 for (Entry1 = List->DiskListHead.Flink;
4104 Entry1 != &List->DiskListHead;
4105 Entry1 = Entry1->Flink)
4106 {
4107 DiskEntry = CONTAINING_RECORD(Entry1,
4108 DISKENTRY,
4109 ListEntry);
4110
4111 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
4112 {
4113 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
4114 continue;
4115 }
4116
4117 for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
4118 Entry2 != &DiskEntry->PrimaryPartListHead;
4119 Entry2 = Entry2->Flink)
4120 {
4121 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4122 if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
4123 {
4124 ASSERT(DiskEntry == PartEntry->DiskEntry);
4125 if (pDiskEntry) *pDiskEntry = DiskEntry;
4126 *pPartEntry = PartEntry;
4127 return TRUE;
4128 }
4129 }
4130
4131 for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
4132 Entry2 != &DiskEntry->LogicalPartListHead;
4133 Entry2 = Entry2->Flink)
4134 {
4135 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4136 if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
4137 {
4138 ASSERT(DiskEntry == PartEntry->DiskEntry);
4139 if (pDiskEntry) *pDiskEntry = DiskEntry;
4140 *pPartEntry = PartEntry;
4141 return TRUE;
4142 }
4143 }
4144 }
4145
4146 if (pDiskEntry) *pDiskEntry = NULL;
4147 *pPartEntry = NULL;
4148
4149 return FALSE;
4150}
BOOLEAN NeedsCheck
Definition: partlist.h:77

Referenced by CheckFileSystemPage().

◆ GetNextUnformattedPartition()

BOOLEAN GetNextUnformattedPartition ( IN PPARTLIST  List,
OUT PDISKENTRY *pDiskEntry  OPTIONAL,
OUT PPARTENTRY pPartEntry 
)

Definition at line 4035 of file partlist.c.

4039{
4040 PLIST_ENTRY Entry1, Entry2;
4041 PDISKENTRY DiskEntry;
4042 PPARTENTRY PartEntry;
4043
4044 for (Entry1 = List->DiskListHead.Flink;
4045 Entry1 != &List->DiskListHead;
4046 Entry1 = Entry1->Flink)
4047 {
4048 DiskEntry = CONTAINING_RECORD(Entry1,
4049 DISKENTRY,
4050 ListEntry);
4051
4052 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
4053 {
4054 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
4055 continue;
4056 }
4057
4058 for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
4059 Entry2 != &DiskEntry->PrimaryPartListHead;
4060 Entry2 = Entry2->Flink)
4061 {
4062 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4063 if (PartEntry->IsPartitioned && PartEntry->New)
4064 {
4065 ASSERT(DiskEntry == PartEntry->DiskEntry);
4066 if (pDiskEntry) *pDiskEntry = DiskEntry;
4067 *pPartEntry = PartEntry;
4068 return TRUE;
4069 }
4070 }
4071
4072 for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
4073 Entry2 != &DiskEntry->LogicalPartListHead;
4074 Entry2 = Entry2->Flink)
4075 {
4076 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4077 if (PartEntry->IsPartitioned && PartEntry->New)
4078 {
4079 ASSERT(DiskEntry == PartEntry->DiskEntry);
4080 if (pDiskEntry) *pDiskEntry = DiskEntry;
4081 *pPartEntry = PartEntry;
4082 return TRUE;
4083 }
4084 }
4085 }
4086
4087 if (pDiskEntry) *pDiskEntry = NULL;
4088 *pPartEntry = NULL;
4089
4090 return FALSE;
4091}
BOOLEAN New
Definition: partlist.h:71

Referenced by SelectFileSystemPage().

◆ GetPartition()

PPARTENTRY GetPartition ( IN PDISKENTRY  DiskEntry,
IN ULONG  PartitionNumber 
)

Definition at line 2096 of file partlist.c.

2100{
2101 PPARTENTRY PartEntry;
2103
2104 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2105 {
2106 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2107 return NULL;
2108 }
2109
2110 /* Disk found, loop over the primary partitions first... */
2111 for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2112 Entry != &DiskEntry->PrimaryPartListHead;
2113 Entry = Entry->Flink)
2114 {
2115 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2116
2117 if (PartEntry->PartitionNumber == PartitionNumber)
2118 {
2119 /* Partition found */
2120 return PartEntry;
2121 }
2122 }
2123
2124 /* ... then over the logical partitions if needed */
2125 for (Entry = DiskEntry->LogicalPartListHead.Flink;
2126 Entry != &DiskEntry->LogicalPartListHead;
2127 Entry = Entry->Flink)
2128 {
2129 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2130
2131 if (PartEntry->PartitionNumber == PartitionNumber)
2132 {
2133 /* Partition found */
2134 return PartEntry;
2135 }
2136 }
2137
2138 /* The partition was not found on the disk, stop there */
2139 return NULL;
2140}

Referenced by GetDiskOrPartition(), ResolveArcNameManually(), and SelectPartition().

◆ GetPrevPartition()

PPARTENTRY GetPrevPartition ( IN PPARTLIST  List,
IN PPARTENTRY CurrentPart  OPTIONAL 
)

Definition at line 2299 of file partlist.c.

2302{
2303 PLIST_ENTRY DiskListEntry;
2304 PLIST_ENTRY PartListEntry;
2306
2307 /* Fail if no disks are available */
2308 if (IsListEmpty(&List->DiskListHead))
2309 return NULL;
2310
2311 /* Check for the previous usable entry on the current partition's disk */
2312 if (CurrentPart != NULL)
2313 {
2314 CurrentDisk = CurrentPart->DiskEntry;
2315
2316 if (CurrentPart->LogicalPartition)
2317 {
2318 /* Logical partition */
2319
2320 PartListEntry = CurrentPart->ListEntry.Blink;
2321 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2322 {
2323 /* Previous logical partition */
2324 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2325 }
2326 else
2327 {
2328 /* Extended partition */
2329 CurrentPart = CurrentDisk->ExtendedPartition;
2330 }
2331 return CurrentPart;
2332 }
2333 else
2334 {
2335 /* Primary or extended partition */
2336
2337 PartListEntry = CurrentPart->ListEntry.Blink;
2338 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2339 {
2340 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2341
2342 if (CurrentPart->IsPartitioned &&
2343 IsContainerPartition(CurrentPart->PartitionType))
2344 {
2345 PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2346 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2347 }
2348
2349 return CurrentPart;
2350 }
2351 }
2352 }
2353
2354 /* Search for the last partition entry on the previous disk */
2355 for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink
2356 : List->DiskListHead.Blink);
2357 DiskListEntry != &List->DiskListHead;
2358 DiskListEntry = DiskListEntry->Blink)
2359 {
2360 CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2361
2363 {
2364 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2365 continue;
2366 }
2367
2368 PartListEntry = CurrentDisk->PrimaryPartListHead.Blink;
2369 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2370 {
2371 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2372
2373 if (CurrentPart->IsPartitioned &&
2374 IsContainerPartition(CurrentPart->PartitionType))
2375 {
2376 PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2377 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2378 {
2379 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2380 return CurrentPart;
2381 }
2382 }
2383 else
2384 {
2385 return CurrentPart;
2386 }
2387 }
2388 }
2389
2390 return NULL;
2391}
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122

Referenced by ScrollUpPartitionList().

◆ IsPartitionActive()

BOOLEAN IsPartitionActive ( IN PPARTENTRY  PartEntry)

Definition at line 1768 of file partlist.c.

1770{
1771 // TODO: Support for GPT disks!
1772
1773 if (IsContainerPartition(PartEntry->PartitionType))
1774 return FALSE;
1775
1776 /* Check if the partition is partitioned, used and active */
1777 if (PartEntry->IsPartitioned &&
1778 // !IsContainerPartition(PartEntry->PartitionType) &&
1779 PartEntry->BootIndicator)
1780 {
1781 /* Yes it is */
1782 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
1783 return TRUE;
1784 }
1785
1786 return FALSE;
1787}

Referenced by GetActiveDiskPartition(), SelectPartitionPage(), and SetActivePartition().

◆ IsSuperFloppy()

BOOLEAN IsSuperFloppy ( IN PDISKENTRY  DiskEntry)

Definition at line 501 of file partlist.c.

503{
505 ULONGLONG PartitionLengthEstimate;
506
507 /* No layout buffer: we cannot say anything yet */
508 if (DiskEntry->LayoutBuffer == NULL)
509 return FALSE;
510
511 /* We must have only one partition */
512 if (DiskEntry->LayoutBuffer->PartitionCount != 1)
513 return FALSE;
514
515 /* Get the single partition entry */
516 PartitionInfo = DiskEntry->LayoutBuffer->PartitionEntry;
517
518 /* The single partition must start at the beginning of the disk */
519 if (!(PartitionInfo->StartingOffset.QuadPart == 0 &&
520 PartitionInfo->HiddenSectors == 0))
521 {
522 return FALSE;
523 }
524
525 /* The disk signature is usually set to one; warn in case it's not */
526 if (DiskEntry->LayoutBuffer->Signature != 1)
527 {
528 DPRINT1("Super-Floppy disk %lu signature %08x != 1!\n",
529 DiskEntry->DiskNumber, DiskEntry->LayoutBuffer->Signature);
530 }
531
532 /*
533 * The partition number must be zero or one, be recognized,
534 * have FAT16 type and report as non-bootable.
535 */
536 if ((PartitionInfo->PartitionNumber != 0 &&
537 PartitionInfo->PartitionNumber != 1) ||
538 PartitionInfo->RecognizedPartition != TRUE ||
539 PartitionInfo->PartitionType != PARTITION_FAT_16 ||
540 PartitionInfo->BootIndicator != FALSE)
541 {
542 DPRINT1("Super-Floppy disk %lu does not return default settings!\n"
543 " PartitionNumber = %lu, expected 0\n"
544 " RecognizedPartition = %s, expected TRUE\n"
545 " PartitionType = 0x%02x, expected 0x04 (PARTITION_FAT_16)\n"
546 " BootIndicator = %s, expected FALSE\n",
547 DiskEntry->DiskNumber,
548 PartitionInfo->PartitionNumber,
549 PartitionInfo->RecognizedPartition ? "TRUE" : "FALSE",
550 PartitionInfo->PartitionType,
551 PartitionInfo->BootIndicator ? "TRUE" : "FALSE");
552 }
553
554 /* The partition lengths should agree */
555 PartitionLengthEstimate = DiskEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
556 if (PartitionInfo->PartitionLength.QuadPart != PartitionLengthEstimate)
557 {
558 DPRINT1("PartitionLength = %I64u is different from PartitionLengthEstimate = %I64u\n",
559 PartitionInfo->PartitionLength.QuadPart, PartitionLengthEstimate);
560 }
561
562 return TRUE;
563}
#define PARTITION_FAT_16
Definition: disk.h:90
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105

Referenced by AddDiskToList(), BootLoaderInstallationPage(), ExtendedPartitionCreationChecks(), LogicalPartitionCreationChecks(), PrimaryPartitionCreationChecks(), and xHalIoWritePartitionTable().

◆ LogicalPartitionCreationChecks()

ERROR_NUMBER LogicalPartitionCreationChecks ( IN PPARTENTRY  PartEntry)

Definition at line 4012 of file partlist.c.

4014{
4015 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
4016
4017 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
4018 {
4019 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
4020 return ERROR_WARN_PARTITION;
4021 }
4022
4023 /* Fail if the partition is already in use */
4024 if (PartEntry->IsPartitioned)
4025 return ERROR_NEW_PARTITION;
4026
4027 /* Only one primary partition is allowed on super-floppy */
4028 if (IsSuperFloppy(DiskEntry))
4030
4031 return ERROR_SUCCESS;
4032}

Referenced by CreateLogicalPartition(), and SelectPartitionPage().

◆ PrimaryPartitionCreationChecks()

ERROR_NUMBER PrimaryPartitionCreationChecks ( IN PPARTENTRY  PartEntry)

Definition at line 3954 of file partlist.c.

3956{
3957 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
3958
3959 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3960 {
3961 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3962 return ERROR_WARN_PARTITION;
3963 }
3964
3965 /* Fail if the partition is already in use */
3966 if (PartEntry->IsPartitioned)
3967 return ERROR_NEW_PARTITION;
3968
3969 /* Only one primary partition is allowed on super-floppy */
3970 if (IsSuperFloppy(DiskEntry))
3972
3973 /* Fail if there are already 4 primary partitions in the list */
3974 if (GetPrimaryPartitionCount(DiskEntry) >= 4)
3976
3977 return ERROR_SUCCESS;
3978}

Referenced by CreatePrimaryPartition(), and SelectPartitionPage().

◆ RoundingDivide()

ULONGLONG RoundingDivide ( IN ULONGLONG  Dividend,
IN ULONGLONG  Divisor 
)

Definition at line 95 of file partlist.c.

98{
99 return (Dividend + Divisor / 2) / Divisor;
100}
_In_ LARGE_INTEGER Divisor
Definition: rtlfuncs.h:3044

Referenced by ListPartition(), PrettifySize1(), PrettifySize2(), PrintDisk(), PrintDiskData(), PrintPartitionData(), and PrintVolume().

◆ SelectPartition()

PPARTENTRY SelectPartition ( IN PPARTLIST  List,
IN ULONG  DiskNumber,
IN ULONG  PartitionNumber 
)

Definition at line 2183 of file partlist.c.

2187{
2188 PDISKENTRY DiskEntry;
2189 PPARTENTRY PartEntry;
2190
2191 DiskEntry = GetDiskByNumber(List, DiskNumber);
2192 if (!DiskEntry)
2193 return NULL;
2194
2195 PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
2196 if (!PartEntry)
2197 return NULL;
2198
2199 ASSERT(PartEntry->DiskEntry == DiskEntry);
2200 ASSERT(DiskEntry->DiskNumber == DiskNumber);
2201 ASSERT(PartEntry->PartitionNumber == PartitionNumber);
2202
2203 return PartEntry;
2204}

Referenced by SelectPartitionPage().

◆ SetActivePartition()

BOOLEAN SetActivePartition ( IN PPARTLIST  List,
IN PPARTENTRY  PartEntry,
IN PPARTENTRY OldActivePart  OPTIONAL 
)

Definition at line 3555 of file partlist.c.

3559{
3560 /* Check for empty disk list */
3561 if (IsListEmpty(&List->DiskListHead))
3562 return FALSE;
3563
3564 /* Validate the partition entry */
3565 if (!PartEntry)
3566 return FALSE;
3567
3568 /*
3569 * If the partition entry is already the system partition, or if it is
3570 * the same as the old active partition hint the user provided (and if
3571 * it is already active), just return success.
3572 */
3573 if ((PartEntry == List->SystemPartition) ||
3574 ((PartEntry == OldActivePart) && IsPartitionActive(OldActivePart)))
3575 {
3576 return TRUE;
3577 }
3578
3579 ASSERT(PartEntry->DiskEntry);
3580
3581 /* Ensure that the partition's disk is in the list */
3582 ASSERT(PartEntry->DiskEntry->PartList == List);
3583
3584 /*
3585 * If the user provided an old active partition hint, verify that it is
3586 * indeeed active and belongs to the same disk where the new partition
3587 * belongs. Otherwise determine the current active partition on the disk
3588 * where the new partition belongs.
3589 */
3590 if (!(OldActivePart && IsPartitionActive(OldActivePart) && (OldActivePart->DiskEntry == PartEntry->DiskEntry)))
3591 {
3592 /* It's not, determine the current active partition for the disk */
3593 OldActivePart = GetActiveDiskPartition(PartEntry->DiskEntry);
3594 }
3595
3596 /* Unset the old active partition if it exists */
3597 if (OldActivePart)
3598 {
3599 OldActivePart->BootIndicator = FALSE;
3600 OldActivePart->DiskEntry->LayoutBuffer->PartitionEntry[OldActivePart->PartitionIndex].BootIndicator = FALSE;
3601 OldActivePart->DiskEntry->LayoutBuffer->PartitionEntry[OldActivePart->PartitionIndex].RewritePartition = TRUE;
3602 OldActivePart->DiskEntry->Dirty = TRUE;
3603 }
3604
3605 /* Modify the system partition if the new partition is on the system disk */
3606 if (PartEntry->DiskEntry == GetSystemDisk(List))
3607 List->SystemPartition = PartEntry;
3608
3609 /* Set the new active partition */
3610 PartEntry->BootIndicator = TRUE;
3611 PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].BootIndicator = TRUE;
3612 PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
3613 PartEntry->DiskEntry->Dirty = TRUE;
3614
3615 return TRUE;
3616}
BOOLEAN IsPartitionActive(IN PPARTENTRY PartEntry)
Definition: partlist.c:1768

Referenced by SelectFileSystemPage().

◆ SetMBRPartitionType()

VOID SetMBRPartitionType ( IN PPARTENTRY  PartEntry,
IN UCHAR  PartitionType 
)

Definition at line 3937 of file partlist.c.

3940{
3941 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
3942
3943 ASSERT(DiskEntry->DiskStyle == PARTITION_STYLE_MBR);
3944
3945 PartEntry->PartitionType = PartitionType;
3946
3947 DiskEntry->Dirty = TRUE;
3948 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartitionType;
3949 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RecognizedPartition = IsRecognizedPartition(PartitionType);
3950 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
3951}
@ PARTITION_STYLE_MBR
Definition: imports.h:201
BOOLEAN Dirty
Definition: partlist.h:118
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:426
BOOLEAN RecognizedPartition
Definition: ntdddisk.h:419
BOOLEAN RewritePartition
Definition: ntdddisk.h:420

Referenced by FormatPartition().

◆ SetMountedDeviceValue()

BOOLEAN SetMountedDeviceValue ( IN WCHAR  Letter,
IN ULONG  Signature,
IN LARGE_INTEGER  StartingOffset 
)

Definition at line 3800 of file partlist.c.

3804{
3807 UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"SYSTEM\\MountedDevices");
3809 WCHAR ValueNameBuffer[16];
3811 REG_DISK_MOUNT_INFO MountInfo;
3812
3813 RtlStringCchPrintfW(ValueNameBuffer, ARRAYSIZE(ValueNameBuffer),
3814 L"\\DosDevices\\%c:", Letter);
3815 RtlInitUnicodeString(&ValueName, ValueNameBuffer);
3816
3818 &KeyName,
3821 NULL);
3822
3826 if (!NT_SUCCESS(Status))
3827 {
3831 0,
3832 NULL,
3834 NULL);
3835 }
3836 if (!NT_SUCCESS(Status))
3837 {
3838 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
3839 return FALSE;
3840 }
3841
3842 MountInfo.Signature = Signature;
3843 MountInfo.StartingOffset = StartingOffset;
3845 &ValueName,
3846 0,
3847 REG_BINARY,
3848 (PVOID)&MountInfo,
3849 sizeof(MountInfo));
3851 if (!NT_SUCCESS(Status))
3852 {
3853 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
3854 return FALSE;
3855 }
3856
3857 return TRUE;
3858}
WCHAR Letter
HANDLE GetRootKeyByPredefKey(IN HANDLE KeyHandle, OUT PCWSTR *RootKeyMountPoint OPTIONAL)
Definition: registry.c:90
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:291
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
NTSTATUS NTAPI NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: ntapi.c:240
LARGE_INTEGER StartingOffset
Definition: partlist.c:26
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by SetMountedDeviceValues().

◆ SetMountedDeviceValues()

BOOLEAN SetMountedDeviceValues ( IN PPARTLIST  List)

Definition at line 3861 of file partlist.c.

3863{
3864 PLIST_ENTRY Entry1, Entry2;
3865 PDISKENTRY DiskEntry;
3866 PPARTENTRY PartEntry;
3868
3869 if (List == NULL)
3870 return FALSE;
3871
3872 for (Entry1 = List->DiskListHead.Flink;
3873 Entry1 != &List->DiskListHead;
3874 Entry1 = Entry1->Flink)
3875 {
3876 DiskEntry = CONTAINING_RECORD(Entry1,
3877 DISKENTRY,
3878 ListEntry);
3879
3880 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3881 {
3882 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3883 continue;
3884 }
3885
3886 for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
3887 Entry2 != &DiskEntry->PrimaryPartListHead;
3888 Entry2 = Entry2->Flink)
3889 {
3890 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
3891 if (PartEntry->IsPartitioned) // && !IsContainerPartition(PartEntry->PartitionType)
3892 {
3894
3895 /* Assign a "\DosDevices\#:" mount point to this partition */
3896 if (PartEntry->DriveLetter)
3897 {
3898 StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
3899 if (!SetMountedDeviceValue(PartEntry->DriveLetter,
3900 DiskEntry->LayoutBuffer->Signature,
3902 {
3903 return FALSE;
3904 }
3905 }
3906 }
3907 }
3908
3909 for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
3910 Entry2 != &DiskEntry->LogicalPartListHead;
3911 Entry2 = Entry2->Flink)
3912 {
3913 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
3914 if (PartEntry->IsPartitioned) // && !IsContainerPartition(PartEntry->PartitionType)
3915 {
3917
3918 /* Assign a "\DosDevices\#:" mount point to this partition */
3919 if (PartEntry->DriveLetter)
3920 {
3921 StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
3922 if (!SetMountedDeviceValue(PartEntry->DriveLetter,
3923 DiskEntry->LayoutBuffer->Signature,
3925 {
3926 return FALSE;
3927 }
3928 }
3929 }
3930 }
3931 }
3932
3933 return TRUE;
3934}
BOOLEAN SetMountedDeviceValue(IN WCHAR Letter, IN ULONG Signature, IN LARGE_INTEGER StartingOffset)
Definition: partlist.c:3800
ULONG BytesPerSector
Definition: partlist.h:95

Referenced by UpdateRegistry().

◆ WritePartitions()

NTSTATUS WritePartitions ( IN PDISKENTRY  DiskEntry)

Definition at line 3619 of file partlist.c.

3621{
3629 ULONG PartitionCount;
3630 PLIST_ENTRY ListEntry;
3631 PPARTENTRY PartEntry;
3633
3634 DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
3635
3636 /* If the disk is not dirty, there is nothing to do */
3637 if (!DiskEntry->Dirty)
3638 return STATUS_SUCCESS;
3639
3641 L"\\Device\\Harddisk%lu\\Partition0",
3642 DiskEntry->DiskNumber);
3644
3646 &Name,
3648 NULL,
3649 NULL);
3650
3654 &Iosb,
3655 0,
3657 if (!NT_SUCCESS(Status))
3658 {
3659 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
3660 return Status;
3661 }
3662
3663#ifdef DUMP_PARTITION_TABLE
3664 DumpPartitionTable(DiskEntry);
3665#endif
3666
3667 //
3668 // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
3669 // the disk in MBR or GPT format in case the disk was not initialized!!
3670 // For this we must ask the user which format to use.
3671 //
3672
3673 /* Save the original partition count to be restored later (see comment below) */
3674 PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
3675
3676 /* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
3678 ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
3680 NULL,
3681 NULL,
3682 NULL,
3683 &Iosb,
3685 DiskEntry->LayoutBuffer,
3686 BufferSize,
3687 DiskEntry->LayoutBuffer,
3688 BufferSize);
3690
3691 /*
3692 * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
3693 * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
3694 * where such a table is expected to enumerate up to 4 partitions:
3695 * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
3696 * Due to this we need to restore the original PartitionCount number.
3697 */
3698 DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
3699
3700 /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
3701 if (!NT_SUCCESS(Status))
3702 {
3703 DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
3704 return Status;
3705 }
3706
3707#ifdef DUMP_PARTITION_TABLE
3708 DumpPartitionTable(DiskEntry);
3709#endif
3710
3711 /* Update the partition numbers */
3712
3713 /* Update the primary partition table */
3714 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3715 ListEntry != &DiskEntry->PrimaryPartListHead;
3716 ListEntry = ListEntry->Flink)
3717 {
3718 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3719
3720 if (PartEntry->IsPartitioned)
3721 {
3723 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
3724 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
3725 }
3726 }
3727
3728 /* Update the logical partition table */
3729 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
3730 ListEntry != &DiskEntry->LogicalPartListHead;
3731 ListEntry = ListEntry->Flink)
3732 {
3733 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3734
3735 if (PartEntry->IsPartitioned)
3736 {
3738 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
3739 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
3740 }
3741 }
3742
3743 //
3744 // NOTE: Originally (see r40437), we used to install here also a new MBR
3745 // for this disk (by calling InstallMbrBootCodeToDisk), only if:
3746 // DiskEntry->NewDisk == TRUE and DiskEntry->HwDiskNumber == 0.
3747 // Then after that, both DiskEntry->NewDisk and DiskEntry->NoMbr were set
3748 // to FALSE. In the other place (in usetup.c) where InstallMbrBootCodeToDisk
3749 // was called too, the installation test was modified by checking whether
3750 // DiskEntry->NoMbr was TRUE (instead of NewDisk).
3751 //
3752
3753 // HACK: Parts of FIXMEs described above: (Re)set the PartitionStyle to MBR.
3754 DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
3755
3756 /* The layout has been successfully updated, the disk is not dirty anymore */
3757 DiskEntry->Dirty = FALSE;
3758
3759 return Status;
3760}
#define BufferSize
Definition: mmc.h:75
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
#define IOCTL_DISK_SET_DRIVE_LAYOUT
Definition: ntdddisk.h:205
struct _PARTITION_INFORMATION PARTITION_INFORMATION
struct _DRIVE_LAYOUT_INFORMATION DRIVE_LAYOUT_INFORMATION
IN HANDLE DstPath
Definition: fsutil.h:76
ULONG PartitionIndex
Definition: partlist.h:56
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

Referenced by active_main(), CreateExtendedPartition(), CreateLogicalPartition(), CreatePrimaryPartition(), DeletePartition(), FormatPartition(), inactive_main(), setid_main(), UniqueIdDisk(), and WritePartitionsToDisk().

◆ WritePartitionsToDisk()

BOOLEAN WritePartitionsToDisk ( IN PPARTLIST  List)

Definition at line 3763 of file partlist.c.

3765{
3768 PDISKENTRY DiskEntry;
3769
3770 if (List == NULL)
3771 return TRUE;
3772
3773 for (Entry = List->DiskListHead.Flink;
3774 Entry != &List->DiskListHead;
3775 Entry = Entry->Flink)
3776 {
3777 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
3778
3779 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3780 {
3781 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3782 continue;
3783 }
3784
3785 if (DiskEntry->Dirty != FALSE)
3786 {
3787 Status = WritePartitions(DiskEntry);
3788 if (!NT_SUCCESS(Status))
3789 {
3790 DPRINT1("WritePartitionsToDisk() failed to update disk %lu, Status 0x%08lx\n",
3791 DiskEntry->DiskNumber, Status);
3792 }
3793 }
3794 }
3795
3796 return TRUE;
3797}
NTSTATUS WritePartitions(IN PDISKENTRY DiskEntry)
Definition: partlist.c:3619

Referenced by SelectFileSystemPage().