ReactOS 0.4.16-dev-2498-g8632030
partlist.h File Reference
#include "volutil.h"
#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  _VOLENTRY
 
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 _VOLENTRY VOLENTRY
 
typedef struct _VOLENTRYPVOLENTRY
 
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 , 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 IsDiskSuperFloppy2 (_In_ const DISK_PARTITION_INFO *DiskInfo, _In_opt_ const ULONGLONG *DiskSize, _In_ const PARTITION_INFORMATION *PartitionInfo)
 
BOOLEAN IsDiskSuperFloppy (_In_ const DRIVE_LAYOUT_INFORMATION *Layout, _In_opt_ const ULONGLONG *DiskSize)
 
BOOLEAN IsDiskSuperFloppyEx (_In_ const DRIVE_LAYOUT_INFORMATION_EX *LayoutEx, _In_opt_ const ULONGLONG *DiskSize)
 
BOOLEAN IsSuperFloppy (_In_ PDISKENTRY DiskEntry)
 
BOOLEAN IsPartitionActive (IN PPARTENTRY PartEntry)
 
PPARTLIST NTAPI CreatePartitionList (VOID)
 
VOID NTAPI 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)
 
PPARTENTRY SelectPartition (_In_ PPARTLIST List, _In_ ULONG DiskNumber, _In_ ULONG PartitionNumber)
 
PPARTENTRY NTAPI GetNextPartition (IN PPARTLIST List, IN PPARTENTRY CurrentPart OPTIONAL)
 
PPARTENTRY NTAPI GetPrevPartition (IN PPARTLIST List, IN PPARTENTRY CurrentPart OPTIONAL)
 
PPARTENTRY NTAPI GetAdjUnpartitionedEntry (_In_ PPARTENTRY PartEntry, _In_ BOOLEAN Direction)
 Retrieves, if any, the unpartitioned disk region that is adjacent (next or previous) to the specified partition.
 
ERROR_NUMBER NTAPI PartitionCreateChecks (_In_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes, _In_opt_ ULONG_PTR PartitionInfo)
 
BOOLEAN NTAPI CreatePartition (_In_ PPARTLIST List, _Inout_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes, _In_opt_ ULONG_PTR PartitionInfo)
 
BOOLEAN NTAPI DeletePartition (_In_ PPARTLIST List, _In_ PPARTENTRY PartEntry, _Out_opt_ PPARTENTRY *FreeRegion)
 
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 SetMountedDeviceValues (_In_ PPARTLIST List)
 
VOID SetMBRPartitionType (IN PPARTENTRY PartEntry, IN UCHAR PartitionType)
 

Macro Definition Documentation

◆ EFI_PMBR_OSTYPE_EFI

#define EFI_PMBR_OSTYPE_EFI   0xEE

Definition at line 197 of file partlist.h.

◆ GetDiskSizeInBytes

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

Definition at line 258 of file partlist.h.

◆ GetPartEntryOffsetInBytes

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

Definition at line 252 of file partlist.h.

◆ GetPartEntrySizeInBytes

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

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

◆ PARTITION_TBL_SIZE

#define PARTITION_TBL_SIZE   4

Definition at line 192 of file partlist.h.

Typedef Documentation

◆ BIOSDISKENTRY

◆ DISKENTRY

◆ FORMATSTATE

◆ PARTENTRY

Definition at line 42 of file partlist.h.

◆ PARTITION

◆ PARTITION_SECTOR

◆ PARTLIST

◆ PBIOS_DISK

◆ PBIOSDISKENTRY

◆ PDISKENTRY

◆ PFORMATSTATE

◆ PPARTENTRY

Definition at line 42 of file partlist.h.

◆ PPARTITION

◆ PPARTITION_SECTOR

◆ PPARTLIST

◆ PVOLENTRY

◆ VOLENTRY

Enumeration Type Documentation

◆ _FORMATSTATE

Enumerator
Unformatted 
UnformattedOrDamaged 
UnknownFormat 
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
@ Formatted
Definition: partlist.h:37
@ Unformatted
Definition: partlist.h:34
@ UnformattedOrDamaged
Definition: partlist.h:35

Function Documentation

◆ AlignDown()

ULONGLONG AlignDown ( IN ULONGLONG  Value,
IN ULONG  Alignment 
)

Definition at line 69 of file partlist.c.

72{
73 ULONGLONG Temp;
74
75 Temp = Value / Alignment;
76
77 return Temp * Alignment;
78}
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 AddDiskToList(), ConvertGPT(), InitializePartitionEntry(), ScanForUnpartitionedDiskSpace(), ScanForUnpartitionedGptDiskSpace(), and ScanForUnpartitionedMbrDiskSpace().

◆ AlignUp()

ULONGLONG AlignUp ( IN ULONGLONG  Value,
IN ULONG  Alignment 
)

Definition at line 81 of file partlist.c.

84{
85 ULONGLONG Temp, Result;
86
87 Temp = Value / Alignment;
88
89 Result = Temp * Alignment;
90 if (Value % Alignment)
92
93 return Result;
94}
_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().

◆ CreatePartition()

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

Definition at line 2975 of file partlist.c.

2980{
2983 PDISKENTRY DiskEntry;
2984 PCSTR mainType = "Primary";
2985
2986 if (isContainer)
2987 mainType = "Extended";
2988 else if (PartEntry && PartEntry->LogicalPartition)
2989 mainType = "Logical";
2990
2991 DPRINT1("CreatePartition(%s, %I64u bytes)\n", mainType, SizeBytes);
2992
2993 if (!List || !PartEntry ||
2994 !PartEntry->DiskEntry || PartEntry->IsPartitioned)
2995 {
2996 return FALSE;
2997 }
2998
2999 Error = PartitionCreateChecks(PartEntry, SizeBytes, PartitionInfo);
3000 if (Error != NOT_AN_ERROR)
3001 {
3002 DPRINT1("PartitionCreateChecks(%s) failed with error %lu\n", mainType, Error);
3003 return FALSE;
3004 }
3005
3006 /* Initialize the partition entry, inserting a new blank region if needed */
3007 if (!InitializePartitionEntry(PartEntry, SizeBytes, PartitionInfo))
3008 return FALSE;
3009
3010 DiskEntry = PartEntry->DiskEntry;
3011 UpdateDiskLayout(DiskEntry);
3012
3013 ASSERT(!PartEntry->Volume);
3014 if (!isContainer)
3015 {
3016 /* We create a primary/logical partition: initialize a new basic
3017 * volume entry. When the partition will actually be written onto
3018 * the disk, the PARTMGR will notify the MOUNTMGR that a volume
3019 * associated with this partition has to be created. */
3020 PartEntry->Volume = InitVolume(DiskEntry->PartList, PartEntry);
3021 ASSERT(PartEntry->Volume);
3022 }
3023
3025
3026 return TRUE;
3027}
unsigned char BOOLEAN
Definition: actypes.h:127
#define DPRINT1
Definition: precomp.h:8
BOOL Error
Definition: chkdsk.c:66
#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
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:321
ERROR_NUMBER NTAPI PartitionCreateChecks(_In_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes, _In_opt_ ULONG_PTR PartitionInfo)
Definition: partlist.c:2946
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2654
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:140
static PVOLENTRY InitVolume(_In_ PPARTLIST List, _In_opt_ PPARTENTRY PartEntry)
Definition: partlist.c:1001
static BOOLEAN InitializePartitionEntry(_Inout_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes, _In_opt_ ULONG_PTR PartitionInfo)
Definition: partlist.c:772
struct _PARTLIST * PartList
Definition: partlist.h:104
const char * PCSTR
Definition: typedefs.h:52
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by CreatePartitionPage(), DoCreatePartition(), InitSystemPartition(), and SelectPartitionPage().

◆ CreatePartitionList()

PPARTLIST NTAPI CreatePartitionList ( VOID  )

Definition at line 2043 of file partlist.c.

2044{
2046 PDISKENTRY SystemDisk;
2050 ULONG ReturnSize;
2052 ULONG DiskNumber;
2056
2058 0,
2059 sizeof(PARTLIST));
2060 if (!List)
2061 return NULL;
2062
2063 List->SystemPartition = NULL;
2064
2065 InitializeListHead(&List->DiskListHead);
2066 InitializeListHead(&List->BiosDiskListHead);
2067 InitializeListHead(&List->VolumesList);
2068 InitializeListHead(&List->PendingUnmountVolumesList);
2069
2070 /*
2071 * Enumerate the disks seen by the BIOS; this will be used later
2072 * to map drives seen by NTOS with their corresponding BIOS names.
2073 */
2075
2076 /* Enumerate disks seen by NTOS */
2078 &Sdi,
2079 sizeof(Sdi),
2080 &ReturnSize);
2081 if (!NT_SUCCESS(Status))
2082 {
2083 DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx\n", Status);
2085 return NULL;
2086 }
2087
2088 for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
2089 {
2091 L"\\Device\\Harddisk%lu\\Partition0",
2092 DiskNumber);
2094
2096 &Name,
2098 NULL,
2099 NULL);
2100
2104 &Iosb,
2107 if (NT_SUCCESS(Status))
2108 {
2109 AddDiskToList(FileHandle, DiskNumber, List);
2111 }
2112 }
2113
2117
2118 /*
2119 * Retrieve the system partition: the active partition on the system
2120 * disk (the one that will be booted by default by the hardware).
2121 */
2122 SystemDisk = GetSystemDisk(List);
2123 List->SystemPartition = (SystemDisk ? GetActiveDiskPartition(SystemDisk) : NULL);
2124
2125 return List;
2126}
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:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define MAX_PATH
Definition: compat.h:34
#define FILE_SHARE_READ
Definition: compat.h:136
#define L(x)
Definition: resources.c:13
return Iosb
Definition: create.c:4403
#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
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:3953
#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 OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static PDISKENTRY GetSystemDisk(IN PPARTLIST List)
Definition: partlist.c:1912
static VOID AddDiskToList(IN HANDLE FileHandle, IN ULONG DiskNumber, IN PPARTLIST List)
Definition: partlist.c:1500
static VOID UpdateDiskSignatures(IN PPARTLIST List)
Definition: partlist.c:1409
static VOID EnumerateBiosDiskEntries(IN PPARTLIST PartList)
Definition: partlist.c:329
static PPARTENTRY GetActiveDiskPartition(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1985
static VOID UpdateHwDiskNumbers(IN PPARTLIST List)
Definition: partlist.c:1439
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 NTAPI DeletePartition ( _In_ PPARTLIST  List,
_In_ PPARTENTRY  PartEntry,
_Out_opt_ PPARTENTRY FreeRegion 
)

Definition at line 3075 of file partlist.c.

3079{
3080 PDISKENTRY DiskEntry;
3081 PPARTENTRY PrevPartEntry;
3082 PPARTENTRY NextPartEntry;
3083 PPARTENTRY LogicalPartEntry;
3085
3086 if (!List || !PartEntry ||
3087 !PartEntry->DiskEntry || !PartEntry->IsPartitioned)
3088 {
3089 return FALSE;
3090 }
3091
3092 ASSERT(PartEntry->DiskEntry->PartList == List);
3093 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
3094
3095 /* Clear the system partition if it is being deleted */
3096 if (List->SystemPartition == PartEntry)
3097 {
3098 ASSERT(List->SystemPartition);
3099 List->SystemPartition = NULL;
3100 }
3101
3102 DiskEntry = PartEntry->DiskEntry;
3103
3104 /* Check which type of partition (primary/logical or extended) is being deleted */
3105 if (DiskEntry->ExtendedPartition == PartEntry)
3106 {
3107 /* An extended partition is being deleted: delete all logical partition entries */
3108 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
3109 {
3111 LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
3112
3113 /* Dismount the logical partition and delete it */
3114 DismountPartition(List, LogicalPartEntry);
3115 DestroyRegion(LogicalPartEntry);
3116 }
3117
3118 DiskEntry->ExtendedPartition = NULL;
3119 }
3120 else
3121 {
3122 /* A primary/logical partition is being deleted: dismount it */
3123 DismountPartition(List, PartEntry);
3124 }
3125
3126 /* Adjust the unpartitioned disk space entries */
3127
3128 /* Get pointer to previous and next unpartitioned entries */
3129 PrevPartEntry = GetAdjUnpartitionedEntry(PartEntry, FALSE);
3130 NextPartEntry = GetAdjUnpartitionedEntry(PartEntry, TRUE);
3131
3132 if (PrevPartEntry != NULL && NextPartEntry != NULL)
3133 {
3134 /* Merge the previous, current and next unpartitioned entries */
3135
3136 /* Adjust the previous entry length */
3137 PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
3138
3139 /* Remove the current and next entries */
3140 RemoveEntryList(&PartEntry->ListEntry);
3141 DestroyRegion(PartEntry);
3142 RemoveEntryList(&NextPartEntry->ListEntry);
3143 DestroyRegion(NextPartEntry);
3144
3145 /* Optionally return the freed region */
3146 if (FreeRegion)
3147 *FreeRegion = PrevPartEntry;
3148 }
3149 else if (PrevPartEntry != NULL && NextPartEntry == NULL)
3150 {
3151 /* Merge the current and the previous unpartitioned entries */
3152
3153 /* Adjust the previous entry length */
3154 PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3155
3156 /* Remove the current entry */
3157 RemoveEntryList(&PartEntry->ListEntry);
3158 DestroyRegion(PartEntry);
3159
3160 /* Optionally return the freed region */
3161 if (FreeRegion)
3162 *FreeRegion = PrevPartEntry;
3163 }
3164 else if (PrevPartEntry == NULL && NextPartEntry != NULL)
3165 {
3166 /* Merge the current and the next unpartitioned entries */
3167
3168 /* Adjust the next entry offset and length */
3169 NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
3170 NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3171
3172 /* Remove the current entry */
3173 RemoveEntryList(&PartEntry->ListEntry);
3174 DestroyRegion(PartEntry);
3175
3176 /* Optionally return the freed region */
3177 if (FreeRegion)
3178 *FreeRegion = NextPartEntry;
3179 }
3180 else
3181 {
3182 /* Nothing to merge but change the current entry */
3183 PartEntry->New = FALSE;
3184 PartEntry->IsPartitioned = FALSE;
3185 PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
3186 PartEntry->OnDiskPartitionNumber = 0;
3187 PartEntry->PartitionNumber = 0;
3188 // PartEntry->PartitionIndex = 0;
3189 PartEntry->BootIndicator = FALSE;
3190 PartEntry->DeviceName[0] = UNICODE_NULL;
3191
3192 if (PartEntry->Volume)
3193 {
3194 RemoveEntryList(&PartEntry->Volume->ListEntry);
3195 RtlFreeHeap(ProcessHeap, 0, PartEntry->Volume);
3196 }
3197 PartEntry->Volume = NULL;
3198
3199 /* Optionally return the freed region */
3200 if (FreeRegion)
3201 *FreeRegion = PartEntry;
3202 }
3203
3204 UpdateDiskLayout(DiskEntry);
3206
3207 return TRUE;
3208}
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:71
#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
#define UNICODE_NULL
static VOID DestroyRegion(_Inout_ PPARTENTRY PartEntry)
Definition: partlist.c:731
PPARTENTRY NTAPI GetAdjUnpartitionedEntry(_In_ PPARTENTRY PartEntry, _In_ BOOLEAN Direction)
Retrieves, if any, the unpartitioned disk region that is adjacent (next or previous) to the specified...
Definition: partlist.c:2856
static NTSTATUS DismountPartition(_In_ PPARTLIST List, _In_ PPARTENTRY PartEntry)
Definition: partlist.c:3030
base of all file and directory entries
Definition: entries.h:83
PPARTENTRY ExtendedPartition
Definition: partlist.h:153
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:150
Definition: typedefs.h:120
BOOLEAN New
Definition: partlist.h:85
ULARGE_INTEGER SectorCount
Definition: partlist.h:70
LIST_ENTRY ListEntry
Definition: partlist.h:63
ULARGE_INTEGER StartSector
Definition: partlist.h:69
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by DeletePartitionPage(), and DoDeletePartition().

◆ DestroyPartitionList()

VOID NTAPI DestroyPartitionList ( IN PPARTLIST  List)

Definition at line 2130 of file partlist.c.

2132{
2133 PDISKENTRY DiskEntry;
2134 PBIOSDISKENTRY BiosDiskEntry;
2135 PPARTENTRY PartEntry;
2136 PVOLENTRY VolumeEntry;
2138
2139 /* Release disk and partition info */
2140 while (!IsListEmpty(&List->DiskListHead))
2141 {
2142 Entry = RemoveHeadList(&List->DiskListHead);
2143 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2144
2145 /* Release driver name */
2146 RtlFreeUnicodeString(&DiskEntry->DriverName);
2147
2148 /* Release primary partition list */
2149 while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
2150 {
2152 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2153 DestroyRegion(PartEntry);
2154 }
2155
2156 /* Release logical partition list */
2157 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
2158 {
2160 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2161 DestroyRegion(PartEntry);
2162 }
2163
2164 /* Release layout buffer */
2165 if (DiskEntry->LayoutBuffer != NULL)
2166 RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
2167
2168 /* Release disk entry */
2169 RtlFreeHeap(ProcessHeap, 0, DiskEntry);
2170 }
2171
2172 /* Release the BIOS disk info */
2173 while (!IsListEmpty(&List->BiosDiskListHead))
2174 {
2175 Entry = RemoveHeadList(&List->BiosDiskListHead);
2176 BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
2177 RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
2178 }
2179
2180 /* Release the pending volumes info */
2181 while (!IsListEmpty(&List->PendingUnmountVolumesList))
2182 {
2183 Entry = RemoveHeadList(&List->PendingUnmountVolumesList);
2184 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
2185 RtlFreeHeap(ProcessHeap, 0, VolumeEntry);
2186 }
2187
2188 /* Release list head */
2190}
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
UNICODE_STRING DriverName
Definition: partlist.h:141
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:149
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:143

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

◆ FindSupportedSystemPartition()

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

Definition at line 3300 of file partlist.c.

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

Referenced by InitSystemPartition().

◆ GetAdjUnpartitionedEntry()

PPARTENTRY NTAPI GetAdjUnpartitionedEntry ( _In_ PPARTENTRY  PartEntry,
_In_ BOOLEAN  Direction 
)

Retrieves, if any, the unpartitioned disk region that is adjacent (next or previous) to the specified partition.

Parameters
[in]PartEntryPartition from where to find the adjacent unpartitioned region.
[in]DirectionTRUE or FALSE to search the next or previous region, respectively.
Returns
The adjacent unpartitioned region, if it exists, or NULL.

Definition at line 2856 of file partlist.c.

2859{
2860 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2861 PLIST_ENTRY ListHead, AdjEntry;
2862
2863 /* In case of MBR disks only, check the logical partitions if necessary */
2864 if ((DiskEntry->DiskStyle == PARTITION_STYLE_MBR) &&
2865 PartEntry->LogicalPartition)
2866 {
2867 ListHead = &DiskEntry->LogicalPartListHead;
2868 }
2869 else
2870 {
2871 ListHead = &DiskEntry->PrimaryPartListHead;
2872 }
2873
2874 if (Direction)
2875 AdjEntry = PartEntry->ListEntry.Flink; // Next region.
2876 else
2877 AdjEntry = PartEntry->ListEntry.Blink; // Previous region.
2878
2879 if (AdjEntry != ListHead)
2880 {
2881 PartEntry = CONTAINING_RECORD(AdjEntry, PARTENTRY, ListEntry);
2882 if (!PartEntry->IsPartitioned)
2883 {
2884 ASSERT(PartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2885 return PartEntry;
2886 }
2887 }
2888 return NULL;
2889}
@ PARTITION_STYLE_MBR
Definition: imports.h:201
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
WDF_EXTERN_C_START typedef _In_ WDFDEVICE _In_ WDFCONTEXT _In_ WDF_DMA_DIRECTION Direction

Referenced by DeletePartition(), DoCreatePartition(), and DoDeletePartition().

◆ GetDiskByBiosNumber()

PDISKENTRY GetDiskByBiosNumber ( _In_ PPARTLIST  List,
_In_ ULONG  HwDiskNumber 
)

Definition at line 2193 of file partlist.c.

2196{
2197 PDISKENTRY DiskEntry;
2199
2200 /* Loop over the disks and find the correct one */
2201 for (Entry = List->DiskListHead.Flink;
2202 Entry != &List->DiskListHead;
2203 Entry = Entry->Flink)
2204 {
2205 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2206
2207 if (DiskEntry->HwDiskNumber == HwDiskNumber)
2208 return DiskEntry; /* Disk found, return it */
2209 }
2210
2211 /* Disk not found, stop there */
2212 return NULL;
2213}
ULONG HwDiskNumber
Definition: partlist.h:123

◆ GetDiskByNumber()

PDISKENTRY GetDiskByNumber ( _In_ PPARTLIST  List,
_In_ ULONG  DiskNumber 
)

Definition at line 2216 of file partlist.c.

2219{
2220 PDISKENTRY DiskEntry;
2222
2223 /* Loop over the disks and find the correct one */
2224 for (Entry = List->DiskListHead.Flink;
2225 Entry != &List->DiskListHead;
2226 Entry = Entry->Flink)
2227 {
2228 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2229
2230 if (DiskEntry->DiskNumber == DiskNumber)
2231 return DiskEntry; /* Disk found, return it */
2232 }
2233
2234 /* Disk not found, stop there */
2235 return NULL;
2236}
ULONG DiskNumber
Definition: partlist.h:129

Referenced by SelectPartition().

◆ GetDiskBySCSI()

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

Definition at line 2239 of file partlist.c.

2244{
2245 PDISKENTRY DiskEntry;
2247
2248 /* Loop over the disks and find the correct one */
2249 for (Entry = List->DiskListHead.Flink;
2250 Entry != &List->DiskListHead;
2251 Entry = Entry->Flink)
2252 {
2253 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2254
2255 if (DiskEntry->Port == Port &&
2256 DiskEntry->Bus == Bus &&
2257 DiskEntry->Id == Id)
2258 {
2259 /* Disk found, return it */
2260 return DiskEntry;
2261 }
2262 }
2263
2264 /* Disk not found, stop there */
2265 return NULL;
2266}
DWORD Id
CPPORT Port[4]
Definition: headless.c:38
USHORT Bus
Definition: partlist.h:132
USHORT Id
Definition: partlist.h:133
USHORT Port
Definition: partlist.h:131

Referenced by ResolveArcNameManually().

◆ GetDiskBySignature()

PDISKENTRY GetDiskBySignature ( _In_ PPARTLIST  List,
_In_ ULONG  Signature 
)

Definition at line 2269 of file partlist.c.

2272{
2273 PDISKENTRY DiskEntry;
2275
2276 /* Loop over the disks and find the correct one */
2277 for (Entry = List->DiskListHead.Flink;
2278 Entry != &List->DiskListHead;
2279 Entry = Entry->Flink)
2280 {
2281 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2282
2283 if (DiskEntry->LayoutBuffer->Signature == Signature)
2284 return DiskEntry; /* Disk found, return it */
2285 }
2286
2287 /* Disk not found, stop there */
2288 return NULL;
2289}
static const WCHAR Signature[]
Definition: parser.c:141

Referenced by ResolveArcNameManually().

◆ GetNextPartition()

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

Definition at line 2359 of file partlist.c.

2362{
2363 PLIST_ENTRY DiskListEntry;
2364 PLIST_ENTRY PartListEntry;
2366
2367 /* Fail if no disks are available */
2368 if (IsListEmpty(&List->DiskListHead))
2369 return NULL;
2370
2371 /* Check for the next usable entry on the current partition's disk */
2372 if (CurrentPart != NULL)
2373 {
2374 CurrentDisk = CurrentPart->DiskEntry;
2375
2376 if (CurrentPart->LogicalPartition)
2377 {
2378 /* Logical partition */
2379
2380 PartListEntry = CurrentPart->ListEntry.Flink;
2381 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2382 {
2383 /* Next logical partition */
2384 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2385 return CurrentPart;
2386 }
2387 else
2388 {
2389 PartListEntry = CurrentDisk->ExtendedPartition->ListEntry.Flink;
2390 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2391 {
2392 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2393 return CurrentPart;
2394 }
2395 }
2396 }
2397 else
2398 {
2399 /* Primary or extended partition */
2400
2401 if (CurrentPart->IsPartitioned &&
2402 IsContainerPartition(CurrentPart->PartitionType))
2403 {
2404 /* First logical partition */
2405 PartListEntry = CurrentDisk->LogicalPartListHead.Flink;
2406 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2407 {
2408 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2409 return CurrentPart;
2410 }
2411 }
2412 else
2413 {
2414 /* Next primary partition */
2415 PartListEntry = CurrentPart->ListEntry.Flink;
2416 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2417 {
2418 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2419 return CurrentPart;
2420 }
2421 }
2422 }
2423 }
2424
2425 /* Search for the first partition entry on the next disk */
2426 for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Flink
2427 : List->DiskListHead.Flink);
2428 DiskListEntry != &List->DiskListHead;
2429 DiskListEntry = DiskListEntry->Flink)
2430 {
2431 CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2432
2434 {
2435 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2436 continue;
2437 }
2438
2439 PartListEntry = CurrentDisk->PrimaryPartListHead.Flink;
2440 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2441 {
2442 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2443 return CurrentPart;
2444 }
2445 }
2446
2447 return NULL;
2448}
PDISKENTRY CurrentDisk
Definition: partlist.c:75
#define DPRINT
Definition: sndvol32.h:73
LIST_ENTRY ListEntry
Definition: partlist.h:101

Referenced by ScrollUpDownPartitionList().

◆ GetPartition()

PPARTENTRY GetPartition ( _In_ PDISKENTRY  DiskEntry,
_In_ ULONG  PartitionNumber 
)

Definition at line 2292 of file partlist.c.

2295{
2296 PPARTENTRY PartEntry;
2298
2299 /* Forbid whole-disk or extended container partition access */
2300 if (PartitionNumber == 0)
2301 return NULL;
2302
2303 /* Loop over the primary partitions first... */
2304 for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2305 Entry != &DiskEntry->PrimaryPartListHead;
2306 Entry = Entry->Flink)
2307 {
2308 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2309
2310 if (PartEntry->PartitionNumber == PartitionNumber)
2311 return PartEntry; /* Partition found, return it */
2312 }
2313
2314 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2315 return NULL;
2316
2317 /* ... then over the logical partitions if needed */
2318 for (Entry = DiskEntry->LogicalPartListHead.Flink;
2319 Entry != &DiskEntry->LogicalPartListHead;
2320 Entry = Entry->Flink)
2321 {
2322 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2323
2324 if (PartEntry->PartitionNumber == PartitionNumber)
2325 return PartEntry; /* Partition found, return it */
2326 }
2327
2328 /* The partition was not found on the disk, stop there */
2329 return NULL;
2330}
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2061

Referenced by ResolveArcNameManually(), and SelectPartition().

◆ GetPrevPartition()

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

Definition at line 2452 of file partlist.c.

2455{
2456 PLIST_ENTRY DiskListEntry;
2457 PLIST_ENTRY PartListEntry;
2459
2460 /* Fail if no disks are available */
2461 if (IsListEmpty(&List->DiskListHead))
2462 return NULL;
2463
2464 /* Check for the previous usable entry on the current partition's disk */
2465 if (CurrentPart != NULL)
2466 {
2467 CurrentDisk = CurrentPart->DiskEntry;
2468
2469 if (CurrentPart->LogicalPartition)
2470 {
2471 /* Logical partition */
2472
2473 PartListEntry = CurrentPart->ListEntry.Blink;
2474 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2475 {
2476 /* Previous logical partition */
2477 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2478 }
2479 else
2480 {
2481 /* Extended partition */
2482 CurrentPart = CurrentDisk->ExtendedPartition;
2483 }
2484 return CurrentPart;
2485 }
2486 else
2487 {
2488 /* Primary or extended partition */
2489
2490 PartListEntry = CurrentPart->ListEntry.Blink;
2491 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2492 {
2493 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2494
2495 if (CurrentPart->IsPartitioned &&
2496 IsContainerPartition(CurrentPart->PartitionType))
2497 {
2498 PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2499 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2500 }
2501
2502 return CurrentPart;
2503 }
2504 }
2505 }
2506
2507 /* Search for the last partition entry on the previous disk */
2508 for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink
2509 : List->DiskListHead.Blink);
2510 DiskListEntry != &List->DiskListHead;
2511 DiskListEntry = DiskListEntry->Blink)
2512 {
2513 CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2514
2516 {
2517 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2518 continue;
2519 }
2520
2521 PartListEntry = CurrentDisk->PrimaryPartListHead.Blink;
2522 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2523 {
2524 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2525
2526 if (CurrentPart->IsPartitioned &&
2527 IsContainerPartition(CurrentPart->PartitionType))
2528 {
2529 PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2530 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2531 {
2532 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2533 return CurrentPart;
2534 }
2535 }
2536 else
2537 {
2538 return CurrentPart;
2539 }
2540 }
2541 }
2542
2543 return NULL;
2544}

Referenced by ScrollUpDownPartitionList().

◆ IsDiskSuperFloppy()

BOOLEAN IsDiskSuperFloppy ( _In_ const DRIVE_LAYOUT_INFORMATION Layout,
_In_opt_ const ULONGLONG DiskSize 
)

Definition at line 544 of file partlist.c.

547{
548 DISK_PARTITION_INFO DiskInfo;
549
550 /* The layout must contain only one partition */
551 if (Layout->PartitionCount != 1)
552 return FALSE;
553
554 /* Build the disk partition info */
555 DiskInfo.SizeOfPartitionInfo = RTL_SIZEOF_THROUGH_FIELD(DISK_PARTITION_INFO, Mbr);
556 DiskInfo.PartitionStyle = PARTITION_STYLE_MBR;
557 DiskInfo.Mbr.Signature = Layout->Signature;
558 DiskInfo.Mbr.CheckSum = 0; // Dummy value
559
560 /* Call the helper on the single partition entry */
561 return IsDiskSuperFloppy2(&DiskInfo, DiskSize, Layout->PartitionEntry);
562}
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:684
BOOLEAN IsDiskSuperFloppy2(_In_ const DISK_PARTITION_INFO *DiskInfo, _In_opt_ const ULONGLONG *DiskSize, _In_ const PARTITION_INFORMATION *PartitionInfo)
Definition: partlist.c:493

Referenced by IsSuperFloppy().

◆ IsDiskSuperFloppy2()

BOOLEAN IsDiskSuperFloppy2 ( _In_ const DISK_PARTITION_INFO *  DiskInfo,
_In_opt_ const ULONGLONG DiskSize,
_In_ const PARTITION_INFORMATION PartitionInfo 
)

Definition at line 493 of file partlist.c.

497{
498 /* Structure size must be valid */
499 if (DiskInfo->SizeOfPartitionInfo < RTL_SIZEOF_THROUGH_FIELD(DISK_PARTITION_INFO, Mbr))
500 return FALSE;
501
502 /* The layout must be MBR */
503 if (DiskInfo->PartitionStyle != PARTITION_STYLE_MBR)
504 return FALSE;
505
506 /* The single partition must start at the beginning of the disk */
507 if (!(PartitionInfo->StartingOffset.QuadPart == 0 &&
508 PartitionInfo->HiddenSectors == 0))
509 {
510 return FALSE;
511 }
512
513 /* The disk signature is usually set to 1; warn in case it's not */
514 if (DiskInfo->Mbr.Signature != 1)
515 {
516 DPRINT1("Super-Floppy signature %08x != 1\n", DiskInfo->Mbr.Signature);
517 }
518
519 /* The partition must be recognized and report as FAT16 non-bootable */
520 if ((PartitionInfo->RecognizedPartition != TRUE) ||
521 (PartitionInfo->PartitionType != PARTITION_FAT_16) ||
522 (PartitionInfo->BootIndicator != FALSE))
523 {
524 DPRINT1("Super-Floppy does not return default settings:\n"
525 " RecognizedPartition = %s, expected TRUE\n"
526 " PartitionType = 0x%02x, expected 0x04 (PARTITION_FAT_16)\n"
527 " BootIndicator = %s, expected FALSE\n",
528 PartitionInfo->RecognizedPartition ? "TRUE" : "FALSE",
529 PartitionInfo->PartitionType,
530 PartitionInfo->BootIndicator ? "TRUE" : "FALSE");
531 }
532
533 /* The partition and disk sizes should agree */
534 if (DiskSize && (PartitionInfo->PartitionLength.QuadPart != *DiskSize))
535 {
536 DPRINT1("PartitionLength = %I64u is different from DiskSize = %I64u\n",
537 PartitionInfo->PartitionLength.QuadPart, *DiskSize);
538 }
539
540 return TRUE;
541}
#define PARTITION_FAT_16
Definition: disk.h:75

Referenced by InstallBootManagerAndBootEntries(), IsDiskSuperFloppy(), and IsDiskSuperFloppyEx().

◆ IsDiskSuperFloppyEx()

BOOLEAN IsDiskSuperFloppyEx ( _In_ const DRIVE_LAYOUT_INFORMATION_EX *  LayoutEx,
_In_opt_ const ULONGLONG DiskSize 
)

Definition at line 565 of file partlist.c.

568{
569 DISK_PARTITION_INFO DiskInfo;
570 const PARTITION_INFORMATION_EX* PartitionInfoEx;
572
573 /* The layout must be MBR and contain only one partition */
574 if (LayoutEx->PartitionStyle != PARTITION_STYLE_MBR)
575 return FALSE;
576 if (LayoutEx->PartitionCount != 1)
577 return FALSE;
578
579 /* Build the disk partition info */
580 DiskInfo.SizeOfPartitionInfo = RTL_SIZEOF_THROUGH_FIELD(DISK_PARTITION_INFO, Mbr);
581 DiskInfo.PartitionStyle = PARTITION_STYLE_MBR; // LayoutEx->PartitionStyle;
582 DiskInfo.Mbr.Signature = LayoutEx->Mbr.Signature;
583 DiskInfo.Mbr.CheckSum = 0; // Dummy value
584
585 /* Convert the single partition entry */
586 PartitionInfoEx = LayoutEx->PartitionEntry;
587
588 PartitionInfo.StartingOffset = PartitionInfoEx->StartingOffset;
589 PartitionInfo.PartitionLength = PartitionInfoEx->PartitionLength;
590 PartitionInfo.HiddenSectors = PartitionInfoEx->Mbr.HiddenSectors;
591 PartitionInfo.PartitionNumber = PartitionInfoEx->PartitionNumber;
592 PartitionInfo.PartitionType = PartitionInfoEx->Mbr.PartitionType;
593 PartitionInfo.BootIndicator = PartitionInfoEx->Mbr.BootIndicator;
594 PartitionInfo.RecognizedPartition = PartitionInfoEx->Mbr.RecognizedPartition;
595 PartitionInfo.RewritePartition = PartitionInfoEx->RewritePartition;
596
597 /* Call the helper on the single partition entry */
598 return IsDiskSuperFloppy2(&DiskInfo, DiskSize, &PartitionInfo);
599}
LARGE_INTEGER StartingOffset
Definition: imports.h:221
PARTITION_INFORMATION_MBR Mbr
Definition: imports.h:226
LARGE_INTEGER PartitionLength
Definition: imports.h:222

◆ IsPartitionActive()

BOOLEAN IsPartitionActive ( IN PPARTENTRY  PartEntry)

Definition at line 1962 of file partlist.c.

1964{
1965 // TODO: Support for GPT disks!
1966
1967 if (IsContainerPartition(PartEntry->PartitionType))
1968 return FALSE;
1969
1970 /* Check if the partition is partitioned, used and active */
1971 if (PartEntry->IsPartitioned &&
1972 // !IsContainerPartition(PartEntry->PartitionType) &&
1973 PartEntry->BootIndicator)
1974 {
1975 /* Yes it is */
1976 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
1977 return TRUE;
1978 }
1979
1980 return FALSE;
1981}

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

◆ IsSuperFloppy()

BOOLEAN IsSuperFloppy ( _In_ PDISKENTRY  DiskEntry)

Definition at line 602 of file partlist.c.

604{
605 ULONGLONG DiskSize;
606
607 /* No layout buffer: we cannot say anything yet */
608 if (!DiskEntry->LayoutBuffer)
609 return FALSE;
610
611 /* The disk must be MBR */
612 if (DiskEntry->DiskStyle != PARTITION_STYLE_MBR)
613 return FALSE;
614
615 DiskSize = GetDiskSizeInBytes(DiskEntry);
616 return IsDiskSuperFloppy(DiskEntry->LayoutBuffer, &DiskSize);
617}
#define GetDiskSizeInBytes(DiskEntry)
Definition: partlist.h:258
BOOLEAN IsDiskSuperFloppy(_In_ const DRIVE_LAYOUT_INFORMATION *Layout, _In_opt_ const ULONGLONG *DiskSize)
Definition: partlist.c:544

Referenced by AddDiskToList(), InstallBootManagerAndBootEntries(), InstallBootManagerAndBootEntriesWorker(), MBRPartitionCreateChecks(), and xHalIoWritePartitionTable().

◆ PartitionCreateChecks()

ERROR_NUMBER NTAPI PartitionCreateChecks ( _In_ PPARTENTRY  PartEntry,
_In_opt_ ULONGLONG  SizeBytes,
_In_opt_ ULONG_PTR  PartitionInfo 
)

Definition at line 2946 of file partlist.c.

2950{
2951 // PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2952
2953 /* Fail if the partition is already in use */
2954 if (PartEntry->IsPartitioned)
2955 return ERROR_NEW_PARTITION;
2956
2957 // TODO: Re-enable once we initialize unpartitioned disks before
2958 // using them; because such disks would be mistook as GPT otherwise.
2959 // if (DiskEntry->DiskStyle == PARTITION_STYLE_MBR)
2960 return MBRPartitionCreateChecks(PartEntry, SizeBytes, PartitionInfo);
2961#if 0
2962 else // if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2963 {
2964 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2965 return ERROR_WARN_PARTITION;
2966 }
2967#endif
2968}
@ ERROR_WARN_PARTITION
Definition: errorcode.h:33
@ ERROR_NEW_PARTITION
Definition: errorcode.h:34
static ERROR_NUMBER MBRPartitionCreateChecks(_In_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes, _In_opt_ ULONG_PTR PartitionInfo)
Definition: partlist.c:2892

Referenced by CreatePartition(), DriveDlgProc(), and SelectPartitionPage().

◆ RoundingDivide()

ULONGLONG RoundingDivide ( IN ULONGLONG  Dividend,
IN ULONGLONG  Divisor 
)

Definition at line 97 of file partlist.c.

100{
101 return (Dividend + Divisor / 2) / Divisor;
102}
_In_ LARGE_INTEGER Divisor
Definition: rtlfuncs.h:3061

Referenced by CreatePartitionPage(), DriveDlgProc(), IsMediumLargeEnough(), PrettifySize1(), PrettifySize2(), PrintSize(), and ShowFileSystemInfo().

◆ SelectPartition()

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

Definition at line 2333 of file partlist.c.

2337{
2338 PDISKENTRY DiskEntry;
2339 PPARTENTRY PartEntry;
2340
2341 /* Find the disk */
2342 DiskEntry = GetDiskByNumber(List, DiskNumber);
2343 if (!DiskEntry)
2344 return NULL;
2345 ASSERT(DiskEntry->DiskNumber == DiskNumber);
2346
2347 /* Find the partition */
2348 PartEntry = GetPartition(DiskEntry, PartitionNumber);
2349 if (!PartEntry)
2350 return NULL;
2351 ASSERT(PartEntry->DiskEntry == DiskEntry);
2352 ASSERT(PartEntry->PartitionNumber == PartitionNumber);
2353
2354 return PartEntry;
2355}
PPARTENTRY GetPartition(_In_ PDISKENTRY DiskEntry, _In_ ULONG PartitionNumber)
Definition: partlist.c:2292
PDISKENTRY GetDiskByNumber(_In_ PPARTLIST List, _In_ ULONG DiskNumber)
Definition: partlist.c:2216

Referenced by EnumerateInstallations(), and SelectPartitionPage().

◆ SetActivePartition()

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

Definition at line 3603 of file partlist.c.

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

Referenced by InitSystemPartition().

◆ SetMBRPartitionType()

VOID SetMBRPartitionType ( IN PPARTENTRY  PartEntry,
IN UCHAR  PartitionType 
)

Definition at line 3991 of file partlist.c.

3994{
3995 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
3996
3997 ASSERT(DiskEntry->DiskStyle == PARTITION_STYLE_MBR);
3998
3999 /* Nothing to do if we assign the same type */
4000 if (PartitionType == PartEntry->PartitionType)
4001 return;
4002
4003 // TODO: We might need to remount the associated basic volume...
4004
4005 PartEntry->PartitionType = PartitionType;
4006
4007 DiskEntry->Dirty = TRUE;
4008 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartitionType;
4009 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RecognizedPartition = IsRecognizedPartition(PartitionType);
4010 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
4011}
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
BOOLEAN Dirty
Definition: partlist.h:136
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:421
BOOLEAN RecognizedPartition
Definition: ntdddisk.h:414
BOOLEAN RewritePartition
Definition: ntdddisk.h:415

Referenced by FormatPartition().

◆ SetMountedDeviceValues()

BOOLEAN SetMountedDeviceValues ( _In_ PPARTLIST  List)

Definition at line 3967 of file partlist.c.

3969{
3972
3973 if (!List)
3974 return FALSE;
3975
3976 for (Entry = List->VolumesList.Flink;
3977 Entry != &List->VolumesList;
3978 Entry = Entry->Flink)
3979 {
3980 Volume = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
3981
3982 /* Assign a "\DosDevices\#:" mount point to this volume */
3984 return FALSE;
3985 }
3986
3987 return TRUE;
3988}
UNICODE_STRING Volume
Definition: fltkernel.h:1172
static BOOLEAN SetMountedDeviceValue(_In_ PVOLENTRY Volume)
Assign a "\DosDevices\#:" mount point drive letter to a disk partition or volume, specified by a give...
Definition: partlist.c:3902

Referenced by UpdateRegistry().

◆ WritePartitions()

NTSTATUS WritePartitions ( IN PDISKENTRY  DiskEntry)

Definition at line 3667 of file partlist.c.

3669{
3677 ULONG PartitionCount;
3678 PLIST_ENTRY ListEntry;
3679 PPARTENTRY PartEntry;
3681
3682 DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
3683
3684 /* If the disk is not dirty, there is nothing to do */
3685 if (!DiskEntry->Dirty)
3686 return STATUS_SUCCESS;
3687
3689 L"\\Device\\Harddisk%lu\\Partition0",
3690 DiskEntry->DiskNumber);
3692
3694 &Name,
3696 NULL,
3697 NULL);
3698
3702 &Iosb,
3703 0,
3705 if (!NT_SUCCESS(Status))
3706 {
3707 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
3708 return Status;
3709 }
3710
3711#ifdef DUMP_PARTITION_TABLE
3712 DumpPartitionTable(DiskEntry);
3713#endif
3714
3715 //
3716 // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
3717 // the disk in MBR or GPT format in case the disk was not initialized!!
3718 // For this we must ask the user which format to use.
3719 //
3720
3721 /* Save the original partition count to be restored later (see comment below) */
3722 PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
3723
3724 /* Set the new disk layout and retrieve its updated version with
3725 * new partition numbers for the new partitions. The PARTMGR will
3726 * automatically notify the MOUNTMGR of new or deleted volumes. */
3728 ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
3730 NULL,
3731 NULL,
3732 NULL,
3733 &Iosb,
3735 DiskEntry->LayoutBuffer,
3736 BufferSize,
3737 DiskEntry->LayoutBuffer,
3738 BufferSize);
3740
3741 /*
3742 * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
3743 * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
3744 * where such a table is expected to enumerate up to 4 partitions:
3745 * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
3746 * Due to this we need to restore the original PartitionCount number.
3747 */
3748 DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
3749
3750 /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
3751 if (!NT_SUCCESS(Status))
3752 {
3753 DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
3754 return Status;
3755 }
3756
3757#ifdef DUMP_PARTITION_TABLE
3758 DumpPartitionTable(DiskEntry);
3759#endif
3760
3761 /* Update the partition numbers and device names */
3762
3763 /* Update the primary partition table */
3764 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3765 ListEntry != &DiskEntry->PrimaryPartListHead;
3766 ListEntry = ListEntry->Flink)
3767 {
3768 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3769 if (!PartEntry->IsPartitioned)
3770 continue;
3772
3773 /*
3774 * Initialize the partition's number and its device name only
3775 * if the partition was new. Note that the partition number
3776 * should not change if this partition has not been deleted
3777 * during repartitioning.
3778 */
3779 // FIXME: Our PartMgr currently returns modified numbers
3780 // in the layout, this needs to be investigated and fixed.
3781 if (PartEntry->New)
3782 {
3783 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
3784 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
3785 InitPartitionDeviceName(PartEntry);
3786 }
3787 PartEntry->New = FALSE;
3788 }
3789
3790 /* Update the logical partition table */
3791 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
3792 ListEntry != &DiskEntry->LogicalPartListHead;
3793 ListEntry = ListEntry->Flink)
3794 {
3795 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3796 if (!PartEntry->IsPartitioned)
3797 continue;
3799
3800 /* See comment above */
3801 if (PartEntry->New)
3802 {
3803 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
3804 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
3805 InitPartitionDeviceName(PartEntry);
3806 }
3807 PartEntry->New = FALSE;
3808 }
3809
3810 //
3811 // NOTE: Originally (see r40437), we used to install here also a new MBR
3812 // for this disk (by calling InstallMbrBootCodeToDisk), only if:
3813 // DiskEntry->NewDisk == TRUE and DiskEntry->HwDiskNumber == 0.
3814 // Then after that, both DiskEntry->NewDisk and DiskEntry->NoMbr were set
3815 // to FALSE. In the other place (in usetup.c) where InstallMbrBootCodeToDisk
3816 // was called too, the installation test was modified by checking whether
3817 // DiskEntry->NoMbr was TRUE (instead of NewDisk).
3818 //
3819
3820 // HACK: Parts of FIXMEs described above: (Re)set the PartitionStyle to MBR.
3821 DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
3822
3823 /* The layout has been successfully updated, the disk is not dirty anymore */
3824 DiskEntry->Dirty = FALSE;
3825
3826 return Status;
3827}
#define BufferSize
Definition: mmc.h:75
#define GENERIC_READ
Definition: compat.h:135
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 GENERIC_WRITE
Definition: nt_native.h:90
#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:81
static VOID InitPartitionDeviceName(_Inout_ PPARTENTRY PartEntry)
Definition: partlist.c:902
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG PartitionIndex
Definition: partlist.h:76
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

Referenced by FormatPartition(), and WritePartitionsToDisk().

◆ WritePartitionsToDisk()

BOOLEAN WritePartitionsToDisk ( IN PPARTLIST  List)

Definition at line 3830 of file partlist.c.

3832{
3835 PDISKENTRY DiskEntry;
3837
3838 if (!List)
3839 return TRUE;
3840
3841 /* Unmount all the pending volumes */
3843 while (!IsListEmpty(&List->PendingUnmountVolumesList))
3844 {
3845 NTSTATUS UnmountStatus;
3846 Entry = RemoveHeadList(&List->PendingUnmountVolumesList);
3847 Volume = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
3848 UnmountStatus = DismountVolume(&Volume->Info, TRUE);
3849 if (!NT_SUCCESS(UnmountStatus))
3850 Status = UnmountStatus;
3852 }
3853 if (!NT_SUCCESS(Status))
3854 return FALSE;
3855
3856 /* Write all the partitions to all the disks */
3857 for (Entry = List->DiskListHead.Flink;
3858 Entry != &List->DiskListHead;
3859 Entry = Entry->Flink)
3860 {
3861 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
3862
3863 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3864 {
3865 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3866 continue;
3867 }
3868
3869 if (DiskEntry->Dirty != FALSE)
3870 {
3871 Status = WritePartitions(DiskEntry);
3872 if (!NT_SUCCESS(Status))
3873 {
3874 DPRINT1("WritePartitionsToDisk() failed to update disk %lu, Status 0x%08lx\n",
3875 DiskEntry->DiskNumber, Status);
3876 }
3877 }
3878 }
3879
3880 /* The PARTMGR should have notified the MOUNTMGR that new volumes
3881 * associated with the new partitions had to be created */
3882
3883 /* Assign valid device names to new volumes */
3884 for (Entry = List->VolumesList.Flink;
3885 Entry != &List->VolumesList;
3886 Entry = Entry->Flink)
3887 {
3888 Volume = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
3890 }
3891
3892 return TRUE;
3893}
static NTSTATUS InitVolumeDeviceName(_Inout_ PVOLENTRY Volume, _In_opt_ PCWSTR AltDeviceName)
Definition: partlist.c:923
NTSTATUS WritePartitions(IN PDISKENTRY DiskEntry)
Definition: partlist.c:3667
NTSTATUS DismountVolume(_Inout_ PVOLINFO Volume, _In_ BOOLEAN Force)
Attempts to dismount the designated volume.
Definition: volutil.c:152

Referenced by FsVolCommitOpsQueue().