ReactOS 0.4.15-dev-7942-gd23573b
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
 
#define GetPartEntryOffsetInBytes(PartEntry)    ((PartEntry)->StartSector.QuadPart * (PartEntry)->DiskEntry->BytesPerSector)
 
#define GetPartEntrySizeInBytes(PartEntry)    ((PartEntry)->SectorCount.QuadPart * (PartEntry)->DiskEntry->BytesPerSector)
 
#define GetDiskSizeInBytes(DiskEntry)    ((DiskEntry)->SectorCount.QuadPart * (DiskEntry)->BytesPerSector)
 

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)
 
ERROR_NUMBER PartitionCreationChecks (_In_ PPARTENTRY PartEntry)
 
ERROR_NUMBER ExtendedPartitionCreationChecks (_In_ PPARTENTRY PartEntry)
 
BOOLEAN CreatePartition (_In_ PPARTLIST List, _Inout_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes)
 
BOOLEAN CreateExtendedPartition (_In_ PPARTLIST List, _Inout_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes)
 
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)
 
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 172 of file partlist.h.

◆ GetDiskSizeInBytes

#define GetDiskSizeInBytes (   DiskEntry)     ((DiskEntry)->SectorCount.QuadPart * (DiskEntry)->BytesPerSector)

Definition at line 233 of file partlist.h.

◆ GetPartEntryOffsetInBytes

#define GetPartEntryOffsetInBytes (   PartEntry)     ((PartEntry)->StartSector.QuadPart * (PartEntry)->DiskEntry->BytesPerSector)

Definition at line 227 of file partlist.h.

◆ GetPartEntrySizeInBytes

#define GetPartEntrySizeInBytes (   PartEntry)     ((PartEntry)->SectorCount.QuadPart * (PartEntry)->DiskEntry->BytesPerSector)

Definition at line 230 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 169 of file partlist.h.

◆ PARTITION_TBL_SIZE

#define PARTITION_TBL_SIZE   4

Definition at line 167 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,
_Inout_ PPARTENTRY  PartEntry,
_In_opt_ ULONGLONG  SizeBytes 
)

Definition at line 2930 of file partlist.c.

2934{
2936
2937 DPRINT1("CreateExtendedPartition(%I64u bytes)\n", SizeBytes);
2938
2939 if (List == NULL || PartEntry == NULL ||
2940 PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
2941 {
2942 return FALSE;
2943 }
2944
2946 if (Error != NOT_AN_ERROR)
2947 {
2948 DPRINT1("ExtendedPartitionCreationChecks() failed with error %lu\n", Error);
2949 return FALSE;
2950 }
2951
2952 /* Initialize the partition entry, inserting a new blank region if needed */
2953 if (!InitializePartitionEntry(PartEntry, SizeBytes))
2954 return FALSE;
2955
2956 ASSERT(PartEntry->LogicalPartition == FALSE);
2957
2958 if (PartEntry->StartSector.QuadPart < 1450560)
2959 {
2960 /* Partition starts below the 8.4GB boundary ==> CHS partition */
2961 PartEntry->PartitionType = PARTITION_EXTENDED;
2962 }
2963 else
2964 {
2965 /* Partition starts above the 8.4GB boundary ==> LBA partition */
2966 PartEntry->PartitionType = PARTITION_XINT13_EXTENDED;
2967 }
2968
2969 // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
2970 PartEntry->New = FALSE;
2971 PartEntry->FormatState = Formatted;
2972
2973 PartEntry->DiskEntry->ExtendedPartition = PartEntry;
2974
2975 AddLogicalDiskSpace(PartEntry->DiskEntry);
2976
2977 UpdateDiskLayout(PartEntry->DiskEntry);
2979
2980 return TRUE;
2981}
#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
ERROR_NUMBER ExtendedPartitionCreationChecks(_In_ PPARTENTRY PartEntry)
Definition: partlist.c:2838
static BOOLEAN InitializePartitionEntry(_Inout_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes)
Definition: partlist.c:678
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2541
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:138
static VOID AddLogicalDiskSpace(_In_ PDISKENTRY DiskEntry)
Definition: partlist.c:2903
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550

Referenced by CreatePartitionPage().

◆ CreatePartition()

BOOLEAN CreatePartition ( _In_ PPARTLIST  List,
_Inout_ PPARTENTRY  PartEntry,
_In_opt_ ULONGLONG  SizeBytes 
)

Definition at line 2869 of file partlist.c.

2873{
2875
2876 DPRINT1("CreatePartition(%I64u bytes)\n", SizeBytes);
2877
2878 if (List == NULL || PartEntry == NULL ||
2879 PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned)
2880 {
2881 return FALSE;
2882 }
2883
2884 Error = PartitionCreationChecks(PartEntry);
2885 if (Error != NOT_AN_ERROR)
2886 {
2887 DPRINT1("PartitionCreationChecks() failed with error %lu\n", Error);
2888 return FALSE;
2889 }
2890
2891 /* Initialize the partition entry, inserting a new blank region if needed */
2892 if (!InitializePartitionEntry(PartEntry, SizeBytes))
2893 return FALSE;
2894
2895 UpdateDiskLayout(PartEntry->DiskEntry);
2897
2898 return TRUE;
2899}
ERROR_NUMBER PartitionCreationChecks(_In_ PPARTENTRY PartEntry)
Definition: partlist.c:2793

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

◆ CreatePartitionList()

PPARTLIST CreatePartitionList ( VOID  )

Definition at line 1867 of file partlist.c.

1868{
1870 PDISKENTRY SystemDisk;
1874 ULONG ReturnSize;
1876 ULONG DiskNumber;
1880
1882 0,
1883 sizeof(PARTLIST));
1884 if (List == NULL)
1885 return NULL;
1886
1887 List->SystemPartition = NULL;
1888
1889 InitializeListHead(&List->DiskListHead);
1890 InitializeListHead(&List->BiosDiskListHead);
1891
1892 /*
1893 * Enumerate the disks seen by the BIOS; this will be used later
1894 * to map drives seen by NTOS with their corresponding BIOS names.
1895 */
1897
1898 /* Enumerate disks seen by NTOS */
1900 &Sdi,
1901 sizeof(Sdi),
1902 &ReturnSize);
1903 if (!NT_SUCCESS(Status))
1904 {
1905 DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx\n", Status);
1907 return NULL;
1908 }
1909
1910 for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
1911 {
1913 L"\\Device\\Harddisk%lu\\Partition0",
1914 DiskNumber);
1916
1918 &Name,
1920 NULL,
1921 NULL);
1922
1926 &Iosb,
1929 if (NT_SUCCESS(Status))
1930 {
1931 AddDiskToList(FileHandle, DiskNumber, List);
1933 }
1934 }
1935
1939
1940 /*
1941 * Retrieve the system partition: the active partition on the system
1942 * disk (the one that will be booted by default by the hardware).
1943 */
1944 SystemDisk = GetSystemDisk(List);
1945 List->SystemPartition = (SystemDisk ? GetActiveDiskPartition(SystemDisk) : NULL);
1946
1947 return List;
1948}
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:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
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:1738
static VOID AddDiskToList(IN HANDLE FileHandle, IN ULONG DiskNumber, IN PPARTLIST List)
Definition: partlist.c:1326
static VOID UpdateDiskSignatures(IN PPARTLIST List)
Definition: partlist.c:1235
static VOID EnumerateBiosDiskEntries(IN PPARTLIST PartList)
Definition: partlist.c:337
static PPARTENTRY GetActiveDiskPartition(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1811
static VOID UpdateHwDiskNumbers(IN PPARTLIST List)
Definition: partlist.c:1265
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

◆ DeletePartition()

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

Definition at line 3091 of file partlist.c.

3095{
3096 PDISKENTRY DiskEntry;
3097 PPARTENTRY PrevPartEntry;
3098 PPARTENTRY NextPartEntry;
3099 PPARTENTRY LogicalPartEntry;
3101
3102 if (List == NULL || PartEntry == NULL ||
3103 PartEntry->DiskEntry == NULL || PartEntry->IsPartitioned == FALSE)
3104 {
3105 return FALSE;
3106 }
3107
3108 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
3109
3110 /* Clear the system partition if it is being deleted */
3111 if (List->SystemPartition == PartEntry)
3112 {
3113 ASSERT(List->SystemPartition);
3114 List->SystemPartition = NULL;
3115 }
3116
3117 DiskEntry = PartEntry->DiskEntry;
3118
3119 /* Check which type of partition (primary/logical or extended) is being deleted */
3120 if (DiskEntry->ExtendedPartition == PartEntry)
3121 {
3122 /* An extended partition is being deleted: delete all logical partition entries */
3123 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
3124 {
3126 LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
3127
3128 /* Dismount the logical partition */
3129 DismountVolume(LogicalPartEntry);
3130
3131 /* Delete it */
3132 RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry);
3133 }
3134
3135 DiskEntry->ExtendedPartition = NULL;
3136 }
3137 else
3138 {
3139 /* A primary partition is being deleted: dismount it */
3140 DismountVolume(PartEntry);
3141 }
3142
3143 /* Adjust the unpartitioned disk space entries */
3144
3145 /* Get pointer to previous and next unpartitioned entries */
3146 PrevPartEntry = GetPrevUnpartitionedEntry(PartEntry);
3147 NextPartEntry = GetNextUnpartitionedEntry(PartEntry);
3148
3149 if (PrevPartEntry != NULL && NextPartEntry != NULL)
3150 {
3151 /* Merge the previous, current and next unpartitioned entries */
3152
3153 /* Adjust the previous entry length */
3154 PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
3155
3156 /* Remove the current and next entries */
3157 RemoveEntryList(&PartEntry->ListEntry);
3158 RtlFreeHeap(ProcessHeap, 0, PartEntry);
3159 RemoveEntryList(&NextPartEntry->ListEntry);
3160 RtlFreeHeap(ProcessHeap, 0, NextPartEntry);
3161
3162 /* Optionally return the freed region */
3163 if (FreeRegion)
3164 *FreeRegion = PrevPartEntry;
3165 }
3166 else if (PrevPartEntry != NULL && NextPartEntry == NULL)
3167 {
3168 /* Merge the current and the previous unpartitioned entries */
3169
3170 /* Adjust the previous entry length */
3171 PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3172
3173 /* Remove the current entry */
3174 RemoveEntryList(&PartEntry->ListEntry);
3175 RtlFreeHeap(ProcessHeap, 0, PartEntry);
3176
3177 /* Optionally return the freed region */
3178 if (FreeRegion)
3179 *FreeRegion = PrevPartEntry;
3180 }
3181 else if (PrevPartEntry == NULL && NextPartEntry != NULL)
3182 {
3183 /* Merge the current and the next unpartitioned entries */
3184
3185 /* Adjust the next entry offset and length */
3186 NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
3187 NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3188
3189 /* Remove the current entry */
3190 RemoveEntryList(&PartEntry->ListEntry);
3191 RtlFreeHeap(ProcessHeap, 0, PartEntry);
3192
3193 /* Optionally return the freed region */
3194 if (FreeRegion)
3195 *FreeRegion = NextPartEntry;
3196 }
3197 else
3198 {
3199 /* Nothing to merge but change the current entry */
3200 PartEntry->IsPartitioned = FALSE;
3201 PartEntry->OnDiskPartitionNumber = 0;
3202 PartEntry->PartitionNumber = 0;
3203 // PartEntry->PartitionIndex = 0;
3204 PartEntry->BootIndicator = FALSE;
3205 PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
3206 PartEntry->FormatState = Unformatted;
3207 PartEntry->FileSystem[0] = L'\0';
3208 PartEntry->DriveLetter = 0;
3209 RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
3210
3211 /* Optionally return the freed region */
3212 if (FreeRegion)
3213 *FreeRegion = PartEntry;
3214 }
3215
3216 UpdateDiskLayout(DiskEntry);
3218
3219 return TRUE;
3220}
#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:2724
static PPARTENTRY GetNextUnpartitionedEntry(IN PPARTENTRY PartEntry)
Definition: partlist.c:2759
NTSTATUS DismountVolume(IN PPARTENTRY PartEntry)
Definition: partlist.c:2984
base of all file and directory entries
Definition: entries.h:83
PPARTENTRY ExtendedPartition
Definition: partlist.h:132
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:129
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 1951 of file partlist.c.

1953{
1954 PDISKENTRY DiskEntry;
1955 PBIOSDISKENTRY BiosDiskEntry;
1956 PPARTENTRY PartEntry;
1958
1959 /* Release disk and partition info */
1960 while (!IsListEmpty(&List->DiskListHead))
1961 {
1962 Entry = RemoveHeadList(&List->DiskListHead);
1963 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
1964
1965 /* Release driver name */
1966 RtlFreeUnicodeString(&DiskEntry->DriverName);
1967
1968 /* Release primary partition list */
1969 while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
1970 {
1972 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1973
1974 RtlFreeHeap(ProcessHeap, 0, PartEntry);
1975 }
1976
1977 /* Release logical partition list */
1978 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
1979 {
1981 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1982
1983 RtlFreeHeap(ProcessHeap, 0, PartEntry);
1984 }
1985
1986 /* Release layout buffer */
1987 if (DiskEntry->LayoutBuffer != NULL)
1988 RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
1989
1990 /* Release disk entry */
1991 RtlFreeHeap(ProcessHeap, 0, DiskEntry);
1992 }
1993
1994 /* Release the bios disk info */
1995 while (!IsListEmpty(&List->BiosDiskListHead))
1996 {
1997 Entry = RemoveHeadList(&List->BiosDiskListHead);
1998 BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
1999
2000 RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
2001 }
2002
2003 /* Release list head */
2005}
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
UNICODE_STRING DriverName
Definition: partlist.h:120
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:128
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:122

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

◆ DismountVolume()

NTSTATUS DismountVolume ( IN PPARTENTRY  PartEntry)

Definition at line 2984 of file partlist.c.

2986{
2988 NTSTATUS LockStatus;
2992 HANDLE PartitionHandle;
2994
2995 /* Check whether the partition is valid and was mounted by the system */
2996 if (!PartEntry->IsPartitioned ||
2997 IsContainerPartition(PartEntry->PartitionType) ||
2998 !IsRecognizedPartition(PartEntry->PartitionType) ||
2999 PartEntry->FormatState == UnknownFormat ||
3000 // NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
3001 // it has been usually mounted with RawFS and thus needs to be dismounted.
3002 !*PartEntry->FileSystem ||
3003 PartEntry->PartitionNumber == 0)
3004 {
3005 /* The partition is not mounted, so just return success */
3006 return STATUS_SUCCESS;
3007 }
3008
3009 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
3010
3011 /* Open the volume */
3013 L"\\Device\\Harddisk%lu\\Partition%lu",
3014 PartEntry->DiskEntry->DiskNumber,
3015 PartEntry->PartitionNumber);
3017
3019 &Name,
3021 NULL,
3022 NULL);
3023
3024 Status = NtOpenFile(&PartitionHandle,
3030 if (!NT_SUCCESS(Status))
3031 {
3032 DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
3033 return Status;
3034 }
3035
3036 /* Lock the volume */
3037 LockStatus = NtFsControlFile(PartitionHandle,
3038 NULL,
3039 NULL,
3040 NULL,
3043 NULL,
3044 0,
3045 NULL,
3046 0);
3047 if (!NT_SUCCESS(LockStatus))
3048 {
3049 DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
3050 }
3051
3052 /* Dismount the volume */
3053 Status = NtFsControlFile(PartitionHandle,
3054 NULL,
3055 NULL,
3056 NULL,
3059 NULL,
3060 0,
3061 NULL,
3062 0);
3063 if (!NT_SUCCESS(Status))
3064 {
3065 DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
3066 }
3067
3068 /* Unlock the volume */
3069 LockStatus = NtFsControlFile(PartitionHandle,
3070 NULL,
3071 NULL,
3072 NULL,
3075 NULL,
3076 0,
3077 NULL,
3078 0);
3079 if (!NT_SUCCESS(LockStatus))
3080 {
3081 DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
3082 }
3083
3084 /* Close the volume */
3085 NtClose(PartitionHandle);
3086
3087 return Status;
3088}
#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 2838 of file partlist.c.

2840{
2841 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2842
2843 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2844 {
2845 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2846 return ERROR_WARN_PARTITION;
2847 }
2848
2849 /* Fail if the partition is already in use */
2850 if (PartEntry->IsPartitioned)
2851 return ERROR_NEW_PARTITION;
2852
2853 /* Only one primary partition is allowed on super-floppy */
2854 if (IsSuperFloppy(DiskEntry))
2856
2857 /* Fail if there are already 4 primary partitions in the list */
2858 if (GetPrimaryPartitionCount(DiskEntry) >= 4)
2860
2861 /* Fail if there is another extended partition in the list */
2862 if (DiskEntry->ExtendedPartition != NULL)
2864
2865 return ERROR_SUCCESS;
2866}
#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:59
@ ERROR_PARTITION_TABLE_FULL
Definition: errorcode.h:58
@ PARTITION_STYLE_GPT
Definition: imports.h:202
static ULONG GetPrimaryPartitionCount(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2435
BOOLEAN IsSuperFloppy(IN PDISKENTRY DiskEntry)
Definition: partlist.c:501
PARTITION_STYLE DiskStyle
Definition: partlist.h:118

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 3304 of file partlist.c.

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

2011{
2012 PDISKENTRY DiskEntry;
2014
2015 /* Loop over the disks and find the correct one */
2016 for (Entry = List->DiskListHead.Flink;
2017 Entry != &List->DiskListHead;
2018 Entry = Entry->Flink)
2019 {
2020 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2021
2022 if (DiskEntry->HwDiskNumber == HwDiskNumber)
2023 {
2024 /* Disk found */
2025 return DiskEntry;
2026 }
2027 }
2028
2029 /* Disk not found, stop there */
2030 return NULL;
2031}
ULONG HwDiskNumber
Definition: partlist.h:102

◆ GetDiskByNumber()

PDISKENTRY GetDiskByNumber ( IN PPARTLIST  List,
IN ULONG  DiskNumber 
)

Definition at line 2034 of file partlist.c.

2037{
2038 PDISKENTRY DiskEntry;
2040
2041 /* Loop over the disks and find the correct one */
2042 for (Entry = List->DiskListHead.Flink;
2043 Entry != &List->DiskListHead;
2044 Entry = Entry->Flink)
2045 {
2046 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2047
2048 if (DiskEntry->DiskNumber == DiskNumber)
2049 {
2050 /* Disk found */
2051 return DiskEntry;
2052 }
2053 }
2054
2055 /* Disk not found, stop there */
2056 return NULL;
2057}
ULONG DiskNumber
Definition: partlist.h:108

Referenced by GetDiskOrPartition(), and SelectPartition().

◆ GetDiskBySCSI()

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

Definition at line 2060 of file partlist.c.

2065{
2066 PDISKENTRY DiskEntry;
2068
2069 /* Loop over the disks and find the correct one */
2070 for (Entry = List->DiskListHead.Flink;
2071 Entry != &List->DiskListHead;
2072 Entry = Entry->Flink)
2073 {
2074 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2075
2076 if (DiskEntry->Port == Port &&
2077 DiskEntry->Bus == Bus &&
2078 DiskEntry->Id == Id)
2079 {
2080 /* Disk found */
2081 return DiskEntry;
2082 }
2083 }
2084
2085 /* Disk not found, stop there */
2086 return NULL;
2087}
DWORD Id
CPPORT Port[4]
Definition: headless.c:35
USHORT Bus
Definition: partlist.h:111
USHORT Id
Definition: partlist.h:112
USHORT Port
Definition: partlist.h:110

Referenced by ResolveArcNameManually().

◆ GetDiskBySignature()

PDISKENTRY GetDiskBySignature ( IN PPARTLIST  List,
IN ULONG  Signature 
)

Definition at line 2090 of file partlist.c.

2093{
2094 PDISKENTRY DiskEntry;
2096
2097 /* Loop over the disks and find the correct one */
2098 for (Entry = List->DiskListHead.Flink;
2099 Entry != &List->DiskListHead;
2100 Entry = Entry->Flink)
2101 {
2102 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2103
2104 if (DiskEntry->LayoutBuffer->Signature == Signature)
2105 {
2106 /* Disk found */
2107 return DiskEntry;
2108 }
2109 }
2110
2111 /* Disk not found, stop there */
2112 return NULL;
2113}
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 2163 of file partlist.c.

2169{
2170 PDISKENTRY DiskEntry;
2171 PPARTENTRY PartEntry = NULL;
2172
2173 /* Find the disk */
2174 DiskEntry = GetDiskByNumber(List, DiskNumber);
2175 if (!DiskEntry)
2176 return FALSE;
2177
2178 /* If we have a partition (PartitionNumber != 0), find it */
2179 if (PartitionNumber != 0)
2180 {
2181 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2182 {
2183 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2184 return FALSE;
2185 }
2186
2187 PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
2188 if (!PartEntry)
2189 return FALSE;
2190 ASSERT(PartEntry->DiskEntry == DiskEntry);
2191 }
2192
2193 /* Return the disk (and optionally the partition) */
2194 *pDiskEntry = DiskEntry;
2195 if (pPartEntry) *pPartEntry = PartEntry;
2196 return TRUE;
2197}
PPARTENTRY GetPartition(IN PDISKENTRY DiskEntry, IN ULONG PartitionNumber)
Definition: partlist.c:2116
PDISKENTRY GetDiskByNumber(IN PPARTLIST List, IN ULONG DiskNumber)
Definition: partlist.c:2034
#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 2227 of file partlist.c.

2230{
2231 PLIST_ENTRY DiskListEntry;
2232 PLIST_ENTRY PartListEntry;
2234
2235 /* Fail if no disks are available */
2236 if (IsListEmpty(&List->DiskListHead))
2237 return NULL;
2238
2239 /* Check for the next usable entry on the current partition's disk */
2240 if (CurrentPart != NULL)
2241 {
2242 CurrentDisk = CurrentPart->DiskEntry;
2243
2244 if (CurrentPart->LogicalPartition)
2245 {
2246 /* Logical partition */
2247
2248 PartListEntry = CurrentPart->ListEntry.Flink;
2249 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2250 {
2251 /* Next logical partition */
2252 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2253 return CurrentPart;
2254 }
2255 else
2256 {
2257 PartListEntry = CurrentDisk->ExtendedPartition->ListEntry.Flink;
2258 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2259 {
2260 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2261 return CurrentPart;
2262 }
2263 }
2264 }
2265 else
2266 {
2267 /* Primary or extended partition */
2268
2269 if (CurrentPart->IsPartitioned &&
2270 IsContainerPartition(CurrentPart->PartitionType))
2271 {
2272 /* First logical partition */
2273 PartListEntry = CurrentDisk->LogicalPartListHead.Flink;
2274 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2275 {
2276 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2277 return CurrentPart;
2278 }
2279 }
2280 else
2281 {
2282 /* Next primary partition */
2283 PartListEntry = CurrentPart->ListEntry.Flink;
2284 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2285 {
2286 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2287 return CurrentPart;
2288 }
2289 }
2290 }
2291 }
2292
2293 /* Search for the first partition entry on the next disk */
2294 for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Flink
2295 : List->DiskListHead.Flink);
2296 DiskListEntry != &List->DiskListHead;
2297 DiskListEntry = DiskListEntry->Flink)
2298 {
2299 CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2300
2302 {
2303 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2304 continue;
2305 }
2306
2307 PartListEntry = CurrentDisk->PrimaryPartListHead.Flink;
2308 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2309 {
2310 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2311 return CurrentPart;
2312 }
2313 }
2314
2315 return NULL;
2316}
PDISKENTRY CurrentDisk
Definition: partlist.c:74
LIST_ENTRY ListEntry
Definition: partlist.h:80

Referenced by ScrollDownPartitionList().

◆ GetNextUncheckedPartition()

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

Definition at line 4057 of file partlist.c.

4061{
4062 PLIST_ENTRY Entry1, Entry2;
4063 PDISKENTRY DiskEntry;
4064 PPARTENTRY PartEntry;
4065
4066 for (Entry1 = List->DiskListHead.Flink;
4067 Entry1 != &List->DiskListHead;
4068 Entry1 = Entry1->Flink)
4069 {
4070 DiskEntry = CONTAINING_RECORD(Entry1,
4071 DISKENTRY,
4072 ListEntry);
4073
4074 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
4075 {
4076 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
4077 continue;
4078 }
4079
4080 for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
4081 Entry2 != &DiskEntry->PrimaryPartListHead;
4082 Entry2 = Entry2->Flink)
4083 {
4084 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4085 if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
4086 {
4087 ASSERT(DiskEntry == PartEntry->DiskEntry);
4088 if (pDiskEntry) *pDiskEntry = DiskEntry;
4089 *pPartEntry = PartEntry;
4090 return TRUE;
4091 }
4092 }
4093
4094 for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
4095 Entry2 != &DiskEntry->LogicalPartListHead;
4096 Entry2 = Entry2->Flink)
4097 {
4098 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4099 if (PartEntry->IsPartitioned && PartEntry->NeedsCheck)
4100 {
4101 ASSERT(DiskEntry == PartEntry->DiskEntry);
4102 if (pDiskEntry) *pDiskEntry = DiskEntry;
4103 *pPartEntry = PartEntry;
4104 return TRUE;
4105 }
4106 }
4107 }
4108
4109 if (pDiskEntry) *pDiskEntry = NULL;
4110 *pPartEntry = NULL;
4111
4112 return FALSE;
4113}
BOOLEAN NeedsCheck
Definition: partlist.h:74

Referenced by CheckFileSystemPage().

◆ GetNextUnformattedPartition()

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

Definition at line 3998 of file partlist.c.

4002{
4003 PLIST_ENTRY Entry1, Entry2;
4004 PDISKENTRY DiskEntry;
4005 PPARTENTRY PartEntry;
4006
4007 for (Entry1 = List->DiskListHead.Flink;
4008 Entry1 != &List->DiskListHead;
4009 Entry1 = Entry1->Flink)
4010 {
4011 DiskEntry = CONTAINING_RECORD(Entry1,
4012 DISKENTRY,
4013 ListEntry);
4014
4015 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
4016 {
4017 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
4018 continue;
4019 }
4020
4021 for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
4022 Entry2 != &DiskEntry->PrimaryPartListHead;
4023 Entry2 = Entry2->Flink)
4024 {
4025 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4026 if (PartEntry->IsPartitioned && PartEntry->New)
4027 {
4028 ASSERT(DiskEntry == PartEntry->DiskEntry);
4029 if (pDiskEntry) *pDiskEntry = DiskEntry;
4030 *pPartEntry = PartEntry;
4031 return TRUE;
4032 }
4033 }
4034
4035 for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
4036 Entry2 != &DiskEntry->LogicalPartListHead;
4037 Entry2 = Entry2->Flink)
4038 {
4039 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
4040 if (PartEntry->IsPartitioned && PartEntry->New)
4041 {
4042 ASSERT(DiskEntry == PartEntry->DiskEntry);
4043 if (pDiskEntry) *pDiskEntry = DiskEntry;
4044 *pPartEntry = PartEntry;
4045 return TRUE;
4046 }
4047 }
4048 }
4049
4050 if (pDiskEntry) *pDiskEntry = NULL;
4051 *pPartEntry = NULL;
4052
4053 return FALSE;
4054}
BOOLEAN New
Definition: partlist.h:71

Referenced by SelectFileSystemPage().

◆ GetPartition()

PPARTENTRY GetPartition ( IN PDISKENTRY  DiskEntry,
IN ULONG  PartitionNumber 
)

Definition at line 2116 of file partlist.c.

2120{
2121 PPARTENTRY PartEntry;
2123
2124 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2125 {
2126 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2127 return NULL;
2128 }
2129
2130 /* Disk found, loop over the primary partitions first... */
2131 for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2132 Entry != &DiskEntry->PrimaryPartListHead;
2133 Entry = Entry->Flink)
2134 {
2135 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2136
2137 if (PartEntry->PartitionNumber == PartitionNumber)
2138 {
2139 /* Partition found */
2140 return PartEntry;
2141 }
2142 }
2143
2144 /* ... then over the logical partitions if needed */
2145 for (Entry = DiskEntry->LogicalPartListHead.Flink;
2146 Entry != &DiskEntry->LogicalPartListHead;
2147 Entry = Entry->Flink)
2148 {
2149 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2150
2151 if (PartEntry->PartitionNumber == PartitionNumber)
2152 {
2153 /* Partition found */
2154 return PartEntry;
2155 }
2156 }
2157
2158 /* The partition was not found on the disk, stop there */
2159 return NULL;
2160}

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

◆ GetPrevPartition()

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

Definition at line 2319 of file partlist.c.

2322{
2323 PLIST_ENTRY DiskListEntry;
2324 PLIST_ENTRY PartListEntry;
2326
2327 /* Fail if no disks are available */
2328 if (IsListEmpty(&List->DiskListHead))
2329 return NULL;
2330
2331 /* Check for the previous usable entry on the current partition's disk */
2332 if (CurrentPart != NULL)
2333 {
2334 CurrentDisk = CurrentPart->DiskEntry;
2335
2336 if (CurrentPart->LogicalPartition)
2337 {
2338 /* Logical partition */
2339
2340 PartListEntry = CurrentPart->ListEntry.Blink;
2341 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2342 {
2343 /* Previous logical partition */
2344 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2345 }
2346 else
2347 {
2348 /* Extended partition */
2349 CurrentPart = CurrentDisk->ExtendedPartition;
2350 }
2351 return CurrentPart;
2352 }
2353 else
2354 {
2355 /* Primary or extended partition */
2356
2357 PartListEntry = CurrentPart->ListEntry.Blink;
2358 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2359 {
2360 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2361
2362 if (CurrentPart->IsPartitioned &&
2363 IsContainerPartition(CurrentPart->PartitionType))
2364 {
2365 PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2366 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2367 }
2368
2369 return CurrentPart;
2370 }
2371 }
2372 }
2373
2374 /* Search for the last partition entry on the previous disk */
2375 for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink
2376 : List->DiskListHead.Blink);
2377 DiskListEntry != &List->DiskListHead;
2378 DiskListEntry = DiskListEntry->Blink)
2379 {
2380 CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2381
2383 {
2384 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2385 continue;
2386 }
2387
2388 PartListEntry = CurrentDisk->PrimaryPartListHead.Blink;
2389 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2390 {
2391 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2392
2393 if (CurrentPart->IsPartitioned &&
2394 IsContainerPartition(CurrentPart->PartitionType))
2395 {
2396 PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2397 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2398 {
2399 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2400 return CurrentPart;
2401 }
2402 }
2403 else
2404 {
2405 return CurrentPart;
2406 }
2407 }
2408 }
2409
2410 return NULL;
2411}
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122

Referenced by ScrollUpPartitionList().

◆ IsPartitionActive()

BOOLEAN IsPartitionActive ( IN PPARTENTRY  PartEntry)

Definition at line 1788 of file partlist.c.

1790{
1791 // TODO: Support for GPT disks!
1792
1793 if (IsContainerPartition(PartEntry->PartitionType))
1794 return FALSE;
1795
1796 /* Check if the partition is partitioned, used and active */
1797 if (PartEntry->IsPartitioned &&
1798 // !IsContainerPartition(PartEntry->PartitionType) &&
1799 PartEntry->BootIndicator)
1800 {
1801 /* Yes it is */
1802 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
1803 return TRUE;
1804 }
1805
1806 return FALSE;
1807}

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 = GetDiskSizeInBytes(DiskEntry);
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
#define GetDiskSizeInBytes(DiskEntry)
Definition: partlist.h:233
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105

Referenced by AddDiskToList(), BootLoaderHardDiskPage(), ExtendedPartitionCreationChecks(), PartitionCreationChecks(), and xHalIoWritePartitionTable().

◆ PartitionCreationChecks()

ERROR_NUMBER PartitionCreationChecks ( _In_ PPARTENTRY  PartEntry)

Definition at line 2793 of file partlist.c.

2795{
2796 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2797
2798 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2799 {
2800 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2801 return ERROR_WARN_PARTITION;
2802 }
2803
2804 /* Fail if the partition is already in use */
2805 if (PartEntry->IsPartitioned)
2806 return ERROR_NEW_PARTITION;
2807
2808 /*
2809 * For primary partitions
2810 */
2811 if (!PartEntry->LogicalPartition)
2812 {
2813 /* Only one primary partition is allowed on super-floppy */
2814 if (IsSuperFloppy(DiskEntry))
2816
2817 /* Fail if there are already 4 primary partitions in the list */
2818 if (GetPrimaryPartitionCount(DiskEntry) >= 4)
2820 }
2821 /*
2822 * For logical partitions
2823 */
2824 else
2825 {
2826 // TODO: Check that we are inside an extended partition!!
2827 // Then the following check will be useless.
2828
2829 /* Only one (primary) partition is allowed on super-floppy */
2830 if (IsSuperFloppy(DiskEntry))
2832 }
2833
2834 return ERROR_SUCCESS;
2835}

Referenced by CreatePartition(), 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 CreatePartitionPage(), IsPartitionLargeEnough(), ListPartition(), PrettifySize1(), PrettifySize2(), PrintDisk(), PrintDiskData(), PrintPartitionData(), and PrintVolume().

◆ SelectPartition()

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

Definition at line 2203 of file partlist.c.

2207{
2208 PDISKENTRY DiskEntry;
2209 PPARTENTRY PartEntry;
2210
2211 DiskEntry = GetDiskByNumber(List, DiskNumber);
2212 if (!DiskEntry)
2213 return NULL;
2214
2215 PartEntry = GetPartition(/*List,*/ DiskEntry, PartitionNumber);
2216 if (!PartEntry)
2217 return NULL;
2218
2219 ASSERT(PartEntry->DiskEntry == DiskEntry);
2220 ASSERT(DiskEntry->DiskNumber == DiskNumber);
2221 ASSERT(PartEntry->PartitionNumber == PartitionNumber);
2222
2223 return PartEntry;
2224}

Referenced by SelectPartitionPage().

◆ SetActivePartition()

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

Definition at line 3599 of file partlist.c.

3603{
3604 /* Check for empty disk list */
3605 if (IsListEmpty(&List->DiskListHead))
3606 return FALSE;
3607
3608 /* Validate the partition entry */
3609 if (!PartEntry)
3610 return FALSE;
3611
3612 /*
3613 * If the partition entry is already the system partition, or if it is
3614 * the same as the old active partition hint the user provided (and if
3615 * it is already active), just return success.
3616 */
3617 if ((PartEntry == List->SystemPartition) ||
3618 ((PartEntry == OldActivePart) && IsPartitionActive(OldActivePart)))
3619 {
3620 return TRUE;
3621 }
3622
3623 ASSERT(PartEntry->DiskEntry);
3624
3625 /* Ensure that the partition's disk is in the list */
3626 ASSERT(PartEntry->DiskEntry->PartList == List);
3627
3628 /*
3629 * If the user provided an old active partition hint, verify that it is
3630 * indeeed active and belongs to the same disk where the new partition
3631 * belongs. Otherwise determine the current active partition on the disk
3632 * where the new partition belongs.
3633 */
3634 if (!(OldActivePart && IsPartitionActive(OldActivePart) && (OldActivePart->DiskEntry == PartEntry->DiskEntry)))
3635 {
3636 /* It's not, determine the current active partition for the disk */
3637 OldActivePart = GetActiveDiskPartition(PartEntry->DiskEntry);
3638 }
3639
3640 /* Unset the old active partition if it exists */
3641 if (OldActivePart)
3642 {
3643 OldActivePart->BootIndicator = FALSE;
3644 OldActivePart->DiskEntry->LayoutBuffer->PartitionEntry[OldActivePart->PartitionIndex].BootIndicator = FALSE;
3645 OldActivePart->DiskEntry->LayoutBuffer->PartitionEntry[OldActivePart->PartitionIndex].RewritePartition = TRUE;
3646 OldActivePart->DiskEntry->Dirty = TRUE;
3647 }
3648
3649 /* Modify the system partition if the new partition is on the system disk */
3650 if (PartEntry->DiskEntry == GetSystemDisk(List))
3651 List->SystemPartition = PartEntry;
3652
3653 /* Set the new active partition */
3654 PartEntry->BootIndicator = TRUE;
3655 PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].BootIndicator = TRUE;
3656 PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
3657 PartEntry->DiskEntry->Dirty = TRUE;
3658
3659 return TRUE;
3660}
BOOLEAN IsPartitionActive(IN PPARTENTRY PartEntry)
Definition: partlist.c:1788

Referenced by SelectFileSystemPage().

◆ SetMBRPartitionType()

VOID SetMBRPartitionType ( IN PPARTENTRY  PartEntry,
IN UCHAR  PartitionType 
)

Definition at line 3981 of file partlist.c.

3984{
3985 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
3986
3987 ASSERT(DiskEntry->DiskStyle == PARTITION_STYLE_MBR);
3988
3989 PartEntry->PartitionType = PartitionType;
3990
3991 DiskEntry->Dirty = TRUE;
3992 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartitionType;
3993 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RecognizedPartition = IsRecognizedPartition(PartitionType);
3994 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
3995}
@ PARTITION_STYLE_MBR
Definition: imports.h:201
BOOLEAN Dirty
Definition: partlist.h:115
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 3844 of file partlist.c.

3848{
3851 UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"SYSTEM\\MountedDevices");
3853 WCHAR ValueNameBuffer[16];
3855 REG_DISK_MOUNT_INFO MountInfo;
3856
3857 RtlStringCchPrintfW(ValueNameBuffer, ARRAYSIZE(ValueNameBuffer),
3858 L"\\DosDevices\\%c:", Letter);
3859 RtlInitUnicodeString(&ValueName, ValueNameBuffer);
3860
3862 &KeyName,
3865 NULL);
3866
3870 if (!NT_SUCCESS(Status))
3871 {
3875 0,
3876 NULL,
3878 NULL);
3879 }
3880 if (!NT_SUCCESS(Status))
3881 {
3882 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
3883 return FALSE;
3884 }
3885
3886 MountInfo.Signature = Signature;
3887 MountInfo.StartingOffset = StartingOffset;
3889 &ValueName,
3890 0,
3891 REG_BINARY,
3892 (PVOID)&MountInfo,
3893 sizeof(MountInfo));
3895 if (!NT_SUCCESS(Status))
3896 {
3897 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
3898 return FALSE;
3899 }
3900
3901 return TRUE;
3902}
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 3905 of file partlist.c.

3907{
3908 PLIST_ENTRY Entry1, Entry2;
3909 PDISKENTRY DiskEntry;
3910 PPARTENTRY PartEntry;
3912
3913 if (List == NULL)
3914 return FALSE;
3915
3916 for (Entry1 = List->DiskListHead.Flink;
3917 Entry1 != &List->DiskListHead;
3918 Entry1 = Entry1->Flink)
3919 {
3920 DiskEntry = CONTAINING_RECORD(Entry1,
3921 DISKENTRY,
3922 ListEntry);
3923
3924 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3925 {
3926 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3927 continue;
3928 }
3929
3930 for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
3931 Entry2 != &DiskEntry->PrimaryPartListHead;
3932 Entry2 = Entry2->Flink)
3933 {
3934 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
3935 if (PartEntry->IsPartitioned) // && !IsContainerPartition(PartEntry->PartitionType)
3936 {
3938
3939 /* Assign a "\DosDevices\#:" mount point to this partition */
3940 if (PartEntry->DriveLetter)
3941 {
3942 StartingOffset.QuadPart = GetPartEntryOffsetInBytes(PartEntry);
3943 if (!SetMountedDeviceValue(PartEntry->DriveLetter,
3944 DiskEntry->LayoutBuffer->Signature,
3946 {
3947 return FALSE;
3948 }
3949 }
3950 }
3951 }
3952
3953 for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
3954 Entry2 != &DiskEntry->LogicalPartListHead;
3955 Entry2 = Entry2->Flink)
3956 {
3957 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
3958 if (PartEntry->IsPartitioned) // && !IsContainerPartition(PartEntry->PartitionType)
3959 {
3961
3962 /* Assign a "\DosDevices\#:" mount point to this partition */
3963 if (PartEntry->DriveLetter)
3964 {
3965 StartingOffset.QuadPart = GetPartEntryOffsetInBytes(PartEntry);
3966 if (!SetMountedDeviceValue(PartEntry->DriveLetter,
3967 DiskEntry->LayoutBuffer->Signature,
3969 {
3970 return FALSE;
3971 }
3972 }
3973 }
3974 }
3975 }
3976
3977 return TRUE;
3978}
#define GetPartEntryOffsetInBytes(PartEntry)
Definition: partlist.h:227
BOOLEAN SetMountedDeviceValue(IN WCHAR Letter, IN ULONG Signature, IN LARGE_INTEGER StartingOffset)
Definition: partlist.c:3844

Referenced by UpdateRegistry().

◆ WritePartitions()

NTSTATUS WritePartitions ( IN PDISKENTRY  DiskEntry)

Definition at line 3663 of file partlist.c.

3665{
3673 ULONG PartitionCount;
3674 PLIST_ENTRY ListEntry;
3675 PPARTENTRY PartEntry;
3677
3678 DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
3679
3680 /* If the disk is not dirty, there is nothing to do */
3681 if (!DiskEntry->Dirty)
3682 return STATUS_SUCCESS;
3683
3685 L"\\Device\\Harddisk%lu\\Partition0",
3686 DiskEntry->DiskNumber);
3688
3690 &Name,
3692 NULL,
3693 NULL);
3694
3698 &Iosb,
3699 0,
3701 if (!NT_SUCCESS(Status))
3702 {
3703 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
3704 return Status;
3705 }
3706
3707#ifdef DUMP_PARTITION_TABLE
3708 DumpPartitionTable(DiskEntry);
3709#endif
3710
3711 //
3712 // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
3713 // the disk in MBR or GPT format in case the disk was not initialized!!
3714 // For this we must ask the user which format to use.
3715 //
3716
3717 /* Save the original partition count to be restored later (see comment below) */
3718 PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
3719
3720 /* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
3722 ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
3724 NULL,
3725 NULL,
3726 NULL,
3727 &Iosb,
3729 DiskEntry->LayoutBuffer,
3730 BufferSize,
3731 DiskEntry->LayoutBuffer,
3732 BufferSize);
3734
3735 /*
3736 * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
3737 * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
3738 * where such a table is expected to enumerate up to 4 partitions:
3739 * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
3740 * Due to this we need to restore the original PartitionCount number.
3741 */
3742 DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
3743
3744 /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
3745 if (!NT_SUCCESS(Status))
3746 {
3747 DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
3748 return Status;
3749 }
3750
3751#ifdef DUMP_PARTITION_TABLE
3752 DumpPartitionTable(DiskEntry);
3753#endif
3754
3755 /* Update the partition numbers */
3756
3757 /* Update the primary partition table */
3758 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3759 ListEntry != &DiskEntry->PrimaryPartListHead;
3760 ListEntry = ListEntry->Flink)
3761 {
3762 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3763
3764 if (PartEntry->IsPartitioned)
3765 {
3767 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
3768 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
3769 }
3770 }
3771
3772 /* Update the logical partition table */
3773 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
3774 ListEntry != &DiskEntry->LogicalPartListHead;
3775 ListEntry = ListEntry->Flink)
3776 {
3777 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3778
3779 if (PartEntry->IsPartitioned)
3780 {
3782 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
3783 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
3784 }
3785 }
3786
3787 //
3788 // NOTE: Originally (see r40437), we used to install here also a new MBR
3789 // for this disk (by calling InstallMbrBootCodeToDisk), only if:
3790 // DiskEntry->NewDisk == TRUE and DiskEntry->HwDiskNumber == 0.
3791 // Then after that, both DiskEntry->NewDisk and DiskEntry->NoMbr were set
3792 // to FALSE. In the other place (in usetup.c) where InstallMbrBootCodeToDisk
3793 // was called too, the installation test was modified by checking whether
3794 // DiskEntry->NoMbr was TRUE (instead of NewDisk).
3795 //
3796
3797 // HACK: Parts of FIXMEs described above: (Re)set the PartitionStyle to MBR.
3798 DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
3799
3800 /* The layout has been successfully updated, the disk is not dirty anymore */
3801 DiskEntry->Dirty = FALSE;
3802
3803 return Status;
3804}
#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 3807 of file partlist.c.

3809{
3812 PDISKENTRY DiskEntry;
3813
3814 if (List == NULL)
3815 return TRUE;
3816
3817 for (Entry = List->DiskListHead.Flink;
3818 Entry != &List->DiskListHead;
3819 Entry = Entry->Flink)
3820 {
3821 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
3822
3823 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3824 {
3825 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3826 continue;
3827 }
3828
3829 if (DiskEntry->Dirty != FALSE)
3830 {
3831 Status = WritePartitions(DiskEntry);
3832 if (!NT_SUCCESS(Status))
3833 {
3834 DPRINT1("WritePartitionsToDisk() failed to update disk %lu, Status 0x%08lx\n",
3835 DiskEntry->DiskNumber, Status);
3836 }
3837 }
3838 }
3839
3840 return TRUE;
3841}
NTSTATUS WritePartitions(IN PDISKENTRY DiskEntry)
Definition: partlist.c:3663

Referenced by SelectFileSystemPage().