ReactOS 0.4.16-dev-1946-g52006dd
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 196 of file partlist.h.

◆ GetDiskSizeInBytes

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

Definition at line 257 of file partlist.h.

◆ GetPartEntryOffsetInBytes

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

Definition at line 251 of file partlist.h.

◆ GetPartEntrySizeInBytes

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

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

◆ PARTITION_TBL_SIZE

#define PARTITION_TBL_SIZE   4

Definition at line 191 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 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().

◆ CreatePartition()

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

Definition at line 2910 of file partlist.c.

2915{
2918 PDISKENTRY DiskEntry;
2919 PCSTR mainType = "Primary";
2920
2921 if (isContainer)
2922 mainType = "Extended";
2923 else if (PartEntry && PartEntry->LogicalPartition)
2924 mainType = "Logical";
2925
2926 DPRINT1("CreatePartition(%s, %I64u bytes)\n", mainType, SizeBytes);
2927
2928 if (!List || !PartEntry ||
2929 !PartEntry->DiskEntry || PartEntry->IsPartitioned)
2930 {
2931 return FALSE;
2932 }
2933
2934 Error = PartitionCreateChecks(PartEntry, SizeBytes, PartitionInfo);
2935 if (Error != NOT_AN_ERROR)
2936 {
2937 DPRINT1("PartitionCreateChecks(%s) failed with error %lu\n", mainType, Error);
2938 return FALSE;
2939 }
2940
2941 /* Initialize the partition entry, inserting a new blank region if needed */
2942 if (!InitializePartitionEntry(PartEntry, SizeBytes, PartitionInfo))
2943 return FALSE;
2944
2945 DiskEntry = PartEntry->DiskEntry;
2946 UpdateDiskLayout(DiskEntry);
2947
2948 ASSERT(!PartEntry->Volume);
2949 if (!isContainer)
2950 {
2951 /* We create a primary/logical partition: initialize a new basic
2952 * volume entry. When the partition will actually be written onto
2953 * the disk, the PARTMGR will notify the MOUNTMGR that a volume
2954 * associated with this partition has to be created. */
2955 PartEntry->Volume = InitVolume(DiskEntry->PartList, PartEntry);
2956 ASSERT(PartEntry->Volume);
2957 }
2958
2960
2961 return TRUE;
2962}
unsigned char BOOLEAN
#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:2881
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2589
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:138
static PVOLENTRY InitVolume(_In_ PPARTLIST List, _In_opt_ PPARTENTRY PartEntry)
Definition: partlist.c:946
static BOOLEAN InitializePartitionEntry(_Inout_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes, _In_opt_ ULONG_PTR PartitionInfo)
Definition: partlist.c:770
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 1988 of file partlist.c.

1989{
1991 PDISKENTRY SystemDisk;
1995 ULONG ReturnSize;
1997 ULONG DiskNumber;
2001
2003 0,
2004 sizeof(PARTLIST));
2005 if (!List)
2006 return NULL;
2007
2008 List->SystemPartition = NULL;
2009
2010 InitializeListHead(&List->DiskListHead);
2011 InitializeListHead(&List->BiosDiskListHead);
2012 InitializeListHead(&List->VolumesList);
2013
2014 /*
2015 * Enumerate the disks seen by the BIOS; this will be used later
2016 * to map drives seen by NTOS with their corresponding BIOS names.
2017 */
2019
2020 /* Enumerate disks seen by NTOS */
2022 &Sdi,
2023 sizeof(Sdi),
2024 &ReturnSize);
2025 if (!NT_SUCCESS(Status))
2026 {
2027 DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx\n", Status);
2029 return NULL;
2030 }
2031
2032 for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
2033 {
2035 L"\\Device\\Harddisk%lu\\Partition0",
2036 DiskNumber);
2038
2040 &Name,
2042 NULL,
2043 NULL);
2044
2048 &Iosb,
2051 if (NT_SUCCESS(Status))
2052 {
2053 AddDiskToList(FileHandle, DiskNumber, List);
2055 }
2056 }
2057
2061
2062 /*
2063 * Retrieve the system partition: the active partition on the system
2064 * disk (the one that will be booted by default by the hardware).
2065 */
2066 SystemDisk = GetSystemDisk(List);
2067 List->SystemPartition = (SystemDisk ? GetActiveDiskPartition(SystemDisk) : NULL);
2068
2069 return List;
2070}
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
#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: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
static PDISKENTRY GetSystemDisk(IN PPARTLIST List)
Definition: partlist.c:1857
static VOID AddDiskToList(IN HANDLE FileHandle, IN ULONG DiskNumber, IN PPARTLIST List)
Definition: partlist.c:1445
static VOID UpdateDiskSignatures(IN PPARTLIST List)
Definition: partlist.c:1354
static VOID EnumerateBiosDiskEntries(IN PPARTLIST PartList)
Definition: partlist.c:327
static PPARTENTRY GetActiveDiskPartition(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1930
static VOID UpdateHwDiskNumbers(IN PPARTLIST List)
Definition: partlist.c:1384
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 3001 of file partlist.c.

3005{
3006 PDISKENTRY DiskEntry;
3007 PPARTENTRY PrevPartEntry;
3008 PPARTENTRY NextPartEntry;
3009 PPARTENTRY LogicalPartEntry;
3011
3012 if (!List || !PartEntry ||
3013 !PartEntry->DiskEntry || !PartEntry->IsPartitioned)
3014 {
3015 return FALSE;
3016 }
3017
3018 ASSERT(PartEntry->DiskEntry->PartList == List);
3019 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
3020
3021 /* Clear the system partition if it is being deleted */
3022 if (List->SystemPartition == PartEntry)
3023 {
3024 ASSERT(List->SystemPartition);
3025 List->SystemPartition = NULL;
3026 }
3027
3028 DiskEntry = PartEntry->DiskEntry;
3029
3030 /* Check which type of partition (primary/logical or extended) is being deleted */
3031 if (DiskEntry->ExtendedPartition == PartEntry)
3032 {
3033 /* An extended partition is being deleted: delete all logical partition entries */
3034 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
3035 {
3037 LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
3038
3039 /* Dismount the logical partition and delete it */
3040 DismountPartition(List, LogicalPartEntry);
3041 DestroyRegion(LogicalPartEntry);
3042 }
3043
3044 DiskEntry->ExtendedPartition = NULL;
3045 }
3046 else
3047 {
3048 /* A primary/logical partition is being deleted: dismount it */
3049 DismountPartition(List, PartEntry);
3050 }
3051
3052 /* Adjust the unpartitioned disk space entries */
3053
3054 /* Get pointer to previous and next unpartitioned entries */
3055 PrevPartEntry = GetAdjUnpartitionedEntry(PartEntry, FALSE);
3056 NextPartEntry = GetAdjUnpartitionedEntry(PartEntry, TRUE);
3057
3058 if (PrevPartEntry != NULL && NextPartEntry != NULL)
3059 {
3060 /* Merge the previous, current and next unpartitioned entries */
3061
3062 /* Adjust the previous entry length */
3063 PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
3064
3065 /* Remove the current and next entries */
3066 RemoveEntryList(&PartEntry->ListEntry);
3067 DestroyRegion(PartEntry);
3068 RemoveEntryList(&NextPartEntry->ListEntry);
3069 DestroyRegion(NextPartEntry);
3070
3071 /* Optionally return the freed region */
3072 if (FreeRegion)
3073 *FreeRegion = PrevPartEntry;
3074 }
3075 else if (PrevPartEntry != NULL && NextPartEntry == NULL)
3076 {
3077 /* Merge the current and the previous unpartitioned entries */
3078
3079 /* Adjust the previous entry length */
3080 PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3081
3082 /* Remove the current entry */
3083 RemoveEntryList(&PartEntry->ListEntry);
3084 DestroyRegion(PartEntry);
3085
3086 /* Optionally return the freed region */
3087 if (FreeRegion)
3088 *FreeRegion = PrevPartEntry;
3089 }
3090 else if (PrevPartEntry == NULL && NextPartEntry != NULL)
3091 {
3092 /* Merge the current and the next unpartitioned entries */
3093
3094 /* Adjust the next entry offset and length */
3095 NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
3096 NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3097
3098 /* Remove the current entry */
3099 RemoveEntryList(&PartEntry->ListEntry);
3100 DestroyRegion(PartEntry);
3101
3102 /* Optionally return the freed region */
3103 if (FreeRegion)
3104 *FreeRegion = NextPartEntry;
3105 }
3106 else
3107 {
3108 /* Nothing to merge but change the current entry */
3109 PartEntry->New = FALSE;
3110 PartEntry->IsPartitioned = FALSE;
3111 PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
3112 PartEntry->OnDiskPartitionNumber = 0;
3113 PartEntry->PartitionNumber = 0;
3114 // PartEntry->PartitionIndex = 0;
3115 PartEntry->BootIndicator = FALSE;
3116 PartEntry->DeviceName[0] = UNICODE_NULL;
3117
3118 if (PartEntry->Volume)
3119 {
3120 RemoveEntryList(&PartEntry->Volume->ListEntry);
3121 RtlFreeHeap(ProcessHeap, 0, PartEntry->Volume);
3122 }
3123 PartEntry->Volume = NULL;
3124
3125 /* Optionally return the freed region */
3126 if (FreeRegion)
3127 *FreeRegion = PartEntry;
3128 }
3129
3130 UpdateDiskLayout(DiskEntry);
3132
3133 return TRUE;
3134}
#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:729
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:2791
static NTSTATUS DismountPartition(_In_ PPARTLIST List, _In_ PPARTENTRY PartEntry)
Definition: partlist.c:2965
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 2074 of file partlist.c.

2076{
2077 PDISKENTRY DiskEntry;
2078 PBIOSDISKENTRY BiosDiskEntry;
2079 PPARTENTRY PartEntry;
2081
2082 /* Release disk and partition info */
2083 while (!IsListEmpty(&List->DiskListHead))
2084 {
2085 Entry = RemoveHeadList(&List->DiskListHead);
2086 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2087
2088 /* Release driver name */
2089 RtlFreeUnicodeString(&DiskEntry->DriverName);
2090
2091 /* Release primary partition list */
2092 while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
2093 {
2095 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2096 DestroyRegion(PartEntry);
2097 }
2098
2099 /* Release logical partition list */
2100 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
2101 {
2103 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2104 DestroyRegion(PartEntry);
2105 }
2106
2107 /* Release layout buffer */
2108 if (DiskEntry->LayoutBuffer != NULL)
2109 RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
2110
2111 /* Release disk entry */
2112 RtlFreeHeap(ProcessHeap, 0, DiskEntry);
2113 }
2114
2115 /* Release the BIOS disk info */
2116 while (!IsListEmpty(&List->BiosDiskListHead))
2117 {
2118 Entry = RemoveHeadList(&List->BiosDiskListHead);
2119 BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
2120 RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
2121 }
2122
2123 /* Release list head */
2125}
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 3226 of file partlist.c.

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

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

2794{
2795 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2796 PLIST_ENTRY ListHead, AdjEntry;
2797
2798 /* In case of MBR disks only, check the logical partitions if necessary */
2799 if ((DiskEntry->DiskStyle == PARTITION_STYLE_MBR) &&
2800 PartEntry->LogicalPartition)
2801 {
2802 ListHead = &DiskEntry->LogicalPartListHead;
2803 }
2804 else
2805 {
2806 ListHead = &DiskEntry->PrimaryPartListHead;
2807 }
2808
2809 if (Direction)
2810 AdjEntry = PartEntry->ListEntry.Flink; // Next region.
2811 else
2812 AdjEntry = PartEntry->ListEntry.Blink; // Previous region.
2813
2814 if (AdjEntry != ListHead)
2815 {
2816 PartEntry = CONTAINING_RECORD(AdjEntry, PARTENTRY, ListEntry);
2817 if (!PartEntry->IsPartitioned)
2818 {
2819 ASSERT(PartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2820 return PartEntry;
2821 }
2822 }
2823 return NULL;
2824}
@ 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 2128 of file partlist.c.

2131{
2132 PDISKENTRY DiskEntry;
2134
2135 /* Loop over the disks and find the correct one */
2136 for (Entry = List->DiskListHead.Flink;
2137 Entry != &List->DiskListHead;
2138 Entry = Entry->Flink)
2139 {
2140 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2141
2142 if (DiskEntry->HwDiskNumber == HwDiskNumber)
2143 return DiskEntry; /* Disk found, return it */
2144 }
2145
2146 /* Disk not found, stop there */
2147 return NULL;
2148}
ULONG HwDiskNumber
Definition: partlist.h:123

◆ GetDiskByNumber()

PDISKENTRY GetDiskByNumber ( _In_ PPARTLIST  List,
_In_ ULONG  DiskNumber 
)

Definition at line 2151 of file partlist.c.

2154{
2155 PDISKENTRY DiskEntry;
2157
2158 /* Loop over the disks and find the correct one */
2159 for (Entry = List->DiskListHead.Flink;
2160 Entry != &List->DiskListHead;
2161 Entry = Entry->Flink)
2162 {
2163 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2164
2165 if (DiskEntry->DiskNumber == DiskNumber)
2166 return DiskEntry; /* Disk found, return it */
2167 }
2168
2169 /* Disk not found, stop there */
2170 return NULL;
2171}
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 2174 of file partlist.c.

2179{
2180 PDISKENTRY DiskEntry;
2182
2183 /* Loop over the disks and find the correct one */
2184 for (Entry = List->DiskListHead.Flink;
2185 Entry != &List->DiskListHead;
2186 Entry = Entry->Flink)
2187 {
2188 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2189
2190 if (DiskEntry->Port == Port &&
2191 DiskEntry->Bus == Bus &&
2192 DiskEntry->Id == Id)
2193 {
2194 /* Disk found, return it */
2195 return DiskEntry;
2196 }
2197 }
2198
2199 /* Disk not found, stop there */
2200 return NULL;
2201}
DWORD Id
CPPORT Port[4]
Definition: headless.c:35
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 2204 of file partlist.c.

2207{
2208 PDISKENTRY DiskEntry;
2210
2211 /* Loop over the disks and find the correct one */
2212 for (Entry = List->DiskListHead.Flink;
2213 Entry != &List->DiskListHead;
2214 Entry = Entry->Flink)
2215 {
2216 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2217
2218 if (DiskEntry->LayoutBuffer->Signature == Signature)
2219 return DiskEntry; /* Disk found, return it */
2220 }
2221
2222 /* Disk not found, stop there */
2223 return NULL;
2224}
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 2294 of file partlist.c.

2297{
2298 PLIST_ENTRY DiskListEntry;
2299 PLIST_ENTRY PartListEntry;
2301
2302 /* Fail if no disks are available */
2303 if (IsListEmpty(&List->DiskListHead))
2304 return NULL;
2305
2306 /* Check for the next usable entry on the current partition's disk */
2307 if (CurrentPart != NULL)
2308 {
2309 CurrentDisk = CurrentPart->DiskEntry;
2310
2311 if (CurrentPart->LogicalPartition)
2312 {
2313 /* Logical partition */
2314
2315 PartListEntry = CurrentPart->ListEntry.Flink;
2316 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2317 {
2318 /* Next logical partition */
2319 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2320 return CurrentPart;
2321 }
2322 else
2323 {
2324 PartListEntry = CurrentDisk->ExtendedPartition->ListEntry.Flink;
2325 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2326 {
2327 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2328 return CurrentPart;
2329 }
2330 }
2331 }
2332 else
2333 {
2334 /* Primary or extended partition */
2335
2336 if (CurrentPart->IsPartitioned &&
2337 IsContainerPartition(CurrentPart->PartitionType))
2338 {
2339 /* First logical partition */
2340 PartListEntry = CurrentDisk->LogicalPartListHead.Flink;
2341 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2342 {
2343 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2344 return CurrentPart;
2345 }
2346 }
2347 else
2348 {
2349 /* Next primary partition */
2350 PartListEntry = CurrentPart->ListEntry.Flink;
2351 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2352 {
2353 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2354 return CurrentPart;
2355 }
2356 }
2357 }
2358 }
2359
2360 /* Search for the first partition entry on the next disk */
2361 for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Flink
2362 : List->DiskListHead.Flink);
2363 DiskListEntry != &List->DiskListHead;
2364 DiskListEntry = DiskListEntry->Flink)
2365 {
2366 CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2367
2369 {
2370 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2371 continue;
2372 }
2373
2374 PartListEntry = CurrentDisk->PrimaryPartListHead.Flink;
2375 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2376 {
2377 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2378 return CurrentPart;
2379 }
2380 }
2381
2382 return NULL;
2383}
PDISKENTRY CurrentDisk
Definition: partlist.c:76
#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 2227 of file partlist.c.

2230{
2231 PPARTENTRY PartEntry;
2233
2234 /* Forbid whole-disk or extended container partition access */
2235 if (PartitionNumber == 0)
2236 return NULL;
2237
2238 /* Loop over the primary partitions first... */
2239 for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2240 Entry != &DiskEntry->PrimaryPartListHead;
2241 Entry = Entry->Flink)
2242 {
2243 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2244
2245 if (PartEntry->PartitionNumber == PartitionNumber)
2246 return PartEntry; /* Partition found, return it */
2247 }
2248
2249 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2250 return NULL;
2251
2252 /* ... then over the logical partitions if needed */
2253 for (Entry = DiskEntry->LogicalPartListHead.Flink;
2254 Entry != &DiskEntry->LogicalPartListHead;
2255 Entry = Entry->Flink)
2256 {
2257 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2258
2259 if (PartEntry->PartitionNumber == PartitionNumber)
2260 return PartEntry; /* Partition found, return it */
2261 }
2262
2263 /* The partition was not found on the disk, stop there */
2264 return NULL;
2265}
_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 2387 of file partlist.c.

2390{
2391 PLIST_ENTRY DiskListEntry;
2392 PLIST_ENTRY PartListEntry;
2394
2395 /* Fail if no disks are available */
2396 if (IsListEmpty(&List->DiskListHead))
2397 return NULL;
2398
2399 /* Check for the previous usable entry on the current partition's disk */
2400 if (CurrentPart != NULL)
2401 {
2402 CurrentDisk = CurrentPart->DiskEntry;
2403
2404 if (CurrentPart->LogicalPartition)
2405 {
2406 /* Logical partition */
2407
2408 PartListEntry = CurrentPart->ListEntry.Blink;
2409 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2410 {
2411 /* Previous logical partition */
2412 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2413 }
2414 else
2415 {
2416 /* Extended partition */
2417 CurrentPart = CurrentDisk->ExtendedPartition;
2418 }
2419 return CurrentPart;
2420 }
2421 else
2422 {
2423 /* Primary or extended partition */
2424
2425 PartListEntry = CurrentPart->ListEntry.Blink;
2426 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2427 {
2428 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2429
2430 if (CurrentPart->IsPartitioned &&
2431 IsContainerPartition(CurrentPart->PartitionType))
2432 {
2433 PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2434 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2435 }
2436
2437 return CurrentPart;
2438 }
2439 }
2440 }
2441
2442 /* Search for the last partition entry on the previous disk */
2443 for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink
2444 : List->DiskListHead.Blink);
2445 DiskListEntry != &List->DiskListHead;
2446 DiskListEntry = DiskListEntry->Blink)
2447 {
2448 CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2449
2451 {
2452 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2453 continue;
2454 }
2455
2456 PartListEntry = CurrentDisk->PrimaryPartListHead.Blink;
2457 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2458 {
2459 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2460
2461 if (CurrentPart->IsPartitioned &&
2462 IsContainerPartition(CurrentPart->PartitionType))
2463 {
2464 PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2465 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2466 {
2467 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2468 return CurrentPart;
2469 }
2470 }
2471 else
2472 {
2473 return CurrentPart;
2474 }
2475 }
2476 }
2477
2478 return NULL;
2479}

Referenced by ScrollUpDownPartitionList().

◆ IsDiskSuperFloppy()

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

Definition at line 542 of file partlist.c.

545{
546 DISK_PARTITION_INFO DiskInfo;
547
548 /* The layout must contain only one partition */
549 if (Layout->PartitionCount != 1)
550 return FALSE;
551
552 /* Build the disk partition info */
553 DiskInfo.SizeOfPartitionInfo = RTL_SIZEOF_THROUGH_FIELD(DISK_PARTITION_INFO, Mbr);
554 DiskInfo.PartitionStyle = PARTITION_STYLE_MBR;
555 DiskInfo.Mbr.Signature = Layout->Signature;
556 DiskInfo.Mbr.CheckSum = 0; // Dummy value
557
558 /* Call the helper on the single partition entry */
559 return IsDiskSuperFloppy2(&DiskInfo, DiskSize, Layout->PartitionEntry);
560}
#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:491

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

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

566{
567 DISK_PARTITION_INFO DiskInfo;
568 const PARTITION_INFORMATION_EX* PartitionInfoEx;
570
571 /* The layout must be MBR and contain only one partition */
572 if (LayoutEx->PartitionStyle != PARTITION_STYLE_MBR)
573 return FALSE;
574 if (LayoutEx->PartitionCount != 1)
575 return FALSE;
576
577 /* Build the disk partition info */
578 DiskInfo.SizeOfPartitionInfo = RTL_SIZEOF_THROUGH_FIELD(DISK_PARTITION_INFO, Mbr);
579 DiskInfo.PartitionStyle = PARTITION_STYLE_MBR; // LayoutEx->PartitionStyle;
580 DiskInfo.Mbr.Signature = LayoutEx->Mbr.Signature;
581 DiskInfo.Mbr.CheckSum = 0; // Dummy value
582
583 /* Convert the single partition entry */
584 PartitionInfoEx = LayoutEx->PartitionEntry;
585
586 PartitionInfo.StartingOffset = PartitionInfoEx->StartingOffset;
587 PartitionInfo.PartitionLength = PartitionInfoEx->PartitionLength;
588 PartitionInfo.HiddenSectors = PartitionInfoEx->Mbr.HiddenSectors;
589 PartitionInfo.PartitionNumber = PartitionInfoEx->PartitionNumber;
590 PartitionInfo.PartitionType = PartitionInfoEx->Mbr.PartitionType;
591 PartitionInfo.BootIndicator = PartitionInfoEx->Mbr.BootIndicator;
592 PartitionInfo.RecognizedPartition = PartitionInfoEx->Mbr.RecognizedPartition;
593 PartitionInfo.RewritePartition = PartitionInfoEx->RewritePartition;
594
595 /* Call the helper on the single partition entry */
596 return IsDiskSuperFloppy2(&DiskInfo, DiskSize, &PartitionInfo);
597}
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 1907 of file partlist.c.

1909{
1910 // TODO: Support for GPT disks!
1911
1912 if (IsContainerPartition(PartEntry->PartitionType))
1913 return FALSE;
1914
1915 /* Check if the partition is partitioned, used and active */
1916 if (PartEntry->IsPartitioned &&
1917 // !IsContainerPartition(PartEntry->PartitionType) &&
1918 PartEntry->BootIndicator)
1919 {
1920 /* Yes it is */
1921 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
1922 return TRUE;
1923 }
1924
1925 return FALSE;
1926}

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

◆ IsSuperFloppy()

BOOLEAN IsSuperFloppy ( _In_ PDISKENTRY  DiskEntry)

Definition at line 600 of file partlist.c.

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

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

2885{
2886 // PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2887
2888 /* Fail if the partition is already in use */
2889 if (PartEntry->IsPartitioned)
2890 return ERROR_NEW_PARTITION;
2891
2892 // TODO: Re-enable once we initialize unpartitioned disks before
2893 // using them; because such disks would be mistook as GPT otherwise.
2894 // if (DiskEntry->DiskStyle == PARTITION_STYLE_MBR)
2895 return MBRPartitionCreateChecks(PartEntry, SizeBytes, PartitionInfo);
2896#if 0
2897 else // if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2898 {
2899 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2900 return ERROR_WARN_PARTITION;
2901 }
2902#endif
2903}
@ 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:2827

Referenced by CreatePartition(), DriveDlgProc(), 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:3061

Referenced by CreatePartitionPage(), DriveDlgProc(), IsMediumLargeEnough(), ListPartition(), PrettifySize1(), PrettifySize2(), PrintDisk(), and PrintVolume().

◆ SelectPartition()

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

Definition at line 2268 of file partlist.c.

2272{
2273 PDISKENTRY DiskEntry;
2274 PPARTENTRY PartEntry;
2275
2276 /* Find the disk */
2277 DiskEntry = GetDiskByNumber(List, DiskNumber);
2278 if (!DiskEntry)
2279 return NULL;
2280 ASSERT(DiskEntry->DiskNumber == DiskNumber);
2281
2282 /* Find the partition */
2283 PartEntry = GetPartition(DiskEntry, PartitionNumber);
2284 if (!PartEntry)
2285 return NULL;
2286 ASSERT(PartEntry->DiskEntry == DiskEntry);
2287 ASSERT(PartEntry->PartitionNumber == PartitionNumber);
2288
2289 return PartEntry;
2290}
PPARTENTRY GetPartition(_In_ PDISKENTRY DiskEntry, _In_ ULONG PartitionNumber)
Definition: partlist.c:2227
PDISKENTRY GetDiskByNumber(_In_ PPARTLIST List, _In_ ULONG DiskNumber)
Definition: partlist.c:2151

Referenced by EnumerateInstallations(), and SelectPartitionPage().

◆ SetActivePartition()

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

Definition at line 3529 of file partlist.c.

3533{
3534 /* Check for empty disk list */
3535 if (IsListEmpty(&List->DiskListHead))
3536 return FALSE;
3537
3538 /* Validate the partition entry */
3539 if (!PartEntry)
3540 return FALSE;
3541
3542 /*
3543 * If the partition entry is already the system partition, or if it is
3544 * the same as the old active partition hint the user provided (and if
3545 * it is already active), just return success.
3546 */
3547 if ((PartEntry == List->SystemPartition) ||
3548 ((PartEntry == OldActivePart) && IsPartitionActive(OldActivePart)))
3549 {
3550 return TRUE;
3551 }
3552
3553 ASSERT(PartEntry->DiskEntry);
3554
3555 /* Ensure that the partition's disk is in the list */
3556 ASSERT(PartEntry->DiskEntry->PartList == List);
3557
3558 /*
3559 * If the user provided an old active partition hint, verify that it is
3560 * indeed active and belongs to the same disk where the new partition
3561 * belongs. Otherwise determine the current active partition on the disk
3562 * where the new partition belongs.
3563 */
3564 if (!(OldActivePart && IsPartitionActive(OldActivePart) && (OldActivePart->DiskEntry == PartEntry->DiskEntry)))
3565 {
3566 /* It's not, determine the current active partition for the disk */
3567 OldActivePart = GetActiveDiskPartition(PartEntry->DiskEntry);
3568 }
3569
3570 /* Unset the old active partition if it exists */
3571 if (OldActivePart)
3572 {
3573 OldActivePart->BootIndicator = FALSE;
3574 OldActivePart->DiskEntry->LayoutBuffer->PartitionEntry[OldActivePart->PartitionIndex].BootIndicator = FALSE;
3575 OldActivePart->DiskEntry->LayoutBuffer->PartitionEntry[OldActivePart->PartitionIndex].RewritePartition = TRUE;
3576 OldActivePart->DiskEntry->Dirty = TRUE;
3577 }
3578
3579 /* Modify the system partition if the new partition is on the system disk */
3580 if (PartEntry->DiskEntry == GetSystemDisk(List))
3581 List->SystemPartition = PartEntry;
3582
3583 /* Set the new active partition */
3584 PartEntry->BootIndicator = TRUE;
3585 PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].BootIndicator = TRUE;
3586 PartEntry->DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
3587 PartEntry->DiskEntry->Dirty = TRUE;
3588
3589 return TRUE;
3590}
BOOLEAN IsPartitionActive(IN PPARTENTRY PartEntry)
Definition: partlist.c:1907

Referenced by InitSystemPartition().

◆ SetMBRPartitionType()

VOID SetMBRPartitionType ( IN PPARTENTRY  PartEntry,
IN UCHAR  PartitionType 
)

Definition at line 3902 of file partlist.c.

3905{
3906 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
3907
3908 ASSERT(DiskEntry->DiskStyle == PARTITION_STYLE_MBR);
3909
3910 /* Nothing to do if we assign the same type */
3911 if (PartitionType == PartEntry->PartitionType)
3912 return;
3913
3914 // TODO: We might need to remount the associated basic volume...
3915
3916 PartEntry->PartitionType = PartitionType;
3917
3918 DiskEntry->Dirty = TRUE;
3919 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].PartitionType = PartitionType;
3920 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RecognizedPartition = IsRecognizedPartition(PartitionType);
3921 DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex].RewritePartition = TRUE;
3922}
#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 3878 of file partlist.c.

3880{
3883
3884 if (!List)
3885 return FALSE;
3886
3887 for (Entry = List->VolumesList.Flink;
3888 Entry != &List->VolumesList;
3889 Entry = Entry->Flink)
3890 {
3891 Volume = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
3892
3893 /* Assign a "\DosDevices\#:" mount point to this volume */
3895 return FALSE;
3896 }
3897
3898 return TRUE;
3899}
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:3813

Referenced by UpdateRegistry().

◆ WritePartitions()

NTSTATUS WritePartitions ( IN PDISKENTRY  DiskEntry)

Definition at line 3593 of file partlist.c.

3595{
3603 ULONG PartitionCount;
3604 PLIST_ENTRY ListEntry;
3605 PPARTENTRY PartEntry;
3607
3608 DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
3609
3610 /* If the disk is not dirty, there is nothing to do */
3611 if (!DiskEntry->Dirty)
3612 return STATUS_SUCCESS;
3613
3615 L"\\Device\\Harddisk%lu\\Partition0",
3616 DiskEntry->DiskNumber);
3618
3620 &Name,
3622 NULL,
3623 NULL);
3624
3628 &Iosb,
3629 0,
3631 if (!NT_SUCCESS(Status))
3632 {
3633 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
3634 return Status;
3635 }
3636
3637#ifdef DUMP_PARTITION_TABLE
3638 DumpPartitionTable(DiskEntry);
3639#endif
3640
3641 //
3642 // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
3643 // the disk in MBR or GPT format in case the disk was not initialized!!
3644 // For this we must ask the user which format to use.
3645 //
3646
3647 /* Save the original partition count to be restored later (see comment below) */
3648 PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
3649
3650 /* Set the new disk layout and retrieve its updated version with
3651 * new partition numbers for the new partitions. The PARTMGR will
3652 * automatically notify the MOUNTMGR of new or deleted volumes. */
3654 ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
3656 NULL,
3657 NULL,
3658 NULL,
3659 &Iosb,
3661 DiskEntry->LayoutBuffer,
3662 BufferSize,
3663 DiskEntry->LayoutBuffer,
3664 BufferSize);
3666
3667 /*
3668 * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
3669 * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
3670 * where such a table is expected to enumerate up to 4 partitions:
3671 * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
3672 * Due to this we need to restore the original PartitionCount number.
3673 */
3674 DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
3675
3676 /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
3677 if (!NT_SUCCESS(Status))
3678 {
3679 DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
3680 return Status;
3681 }
3682
3683#ifdef DUMP_PARTITION_TABLE
3684 DumpPartitionTable(DiskEntry);
3685#endif
3686
3687 /* Update the partition numbers and device names */
3688
3689 /* Update the primary partition table */
3690 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3691 ListEntry != &DiskEntry->PrimaryPartListHead;
3692 ListEntry = ListEntry->Flink)
3693 {
3694 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3695 if (!PartEntry->IsPartitioned)
3696 continue;
3698
3699 /*
3700 * Initialize the partition's number and its device name only
3701 * if the partition was new. Note that the partition number
3702 * should not change if this partition has not been deleted
3703 * during repartitioning.
3704 */
3705 // FIXME: Our PartMgr currently returns modified numbers
3706 // in the layout, this needs to be investigated and fixed.
3707 if (PartEntry->New)
3708 {
3709 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
3710 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
3711 InitPartitionDeviceName(PartEntry);
3712 }
3713 PartEntry->New = FALSE;
3714 }
3715
3716 /* Update the logical partition table */
3717 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
3718 ListEntry != &DiskEntry->LogicalPartListHead;
3719 ListEntry = ListEntry->Flink)
3720 {
3721 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3722 if (!PartEntry->IsPartitioned)
3723 continue;
3725
3726 /* See comment above */
3727 if (PartEntry->New)
3728 {
3729 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
3730 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
3731 InitPartitionDeviceName(PartEntry);
3732 }
3733 PartEntry->New = FALSE;
3734 }
3735
3736 //
3737 // NOTE: Originally (see r40437), we used to install here also a new MBR
3738 // for this disk (by calling InstallMbrBootCodeToDisk), only if:
3739 // DiskEntry->NewDisk == TRUE and DiskEntry->HwDiskNumber == 0.
3740 // Then after that, both DiskEntry->NewDisk and DiskEntry->NoMbr were set
3741 // to FALSE. In the other place (in usetup.c) where InstallMbrBootCodeToDisk
3742 // was called too, the installation test was modified by checking whether
3743 // DiskEntry->NoMbr was TRUE (instead of NewDisk).
3744 //
3745
3746 // HACK: Parts of FIXMEs described above: (Re)set the PartitionStyle to MBR.
3747 DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
3748
3749 /* The layout has been successfully updated, the disk is not dirty anymore */
3750 DiskEntry->Dirty = FALSE;
3751
3752 return Status;
3753}
#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:900
#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 active_main(), CreateExtendedPartition(), CreateLogicalPartition(), CreatePrimaryPartition(), DeletePartition(), FormatPartition(), inactive_main(), setid_main(), UniqueIdDisk(), and WritePartitionsToDisk().

◆ WritePartitionsToDisk()

BOOLEAN WritePartitionsToDisk ( IN PPARTLIST  List)

Definition at line 3756 of file partlist.c.

3758{
3761 PDISKENTRY DiskEntry;
3763
3764 if (!List)
3765 return TRUE;
3766
3767 /* Write all the partitions to all the disks */
3768 for (Entry = List->DiskListHead.Flink;
3769 Entry != &List->DiskListHead;
3770 Entry = Entry->Flink)
3771 {
3772 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
3773
3774 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3775 {
3776 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3777 continue;
3778 }
3779
3780 if (DiskEntry->Dirty != FALSE)
3781 {
3782 Status = WritePartitions(DiskEntry);
3783 if (!NT_SUCCESS(Status))
3784 {
3785 DPRINT1("WritePartitionsToDisk() failed to update disk %lu, Status 0x%08lx\n",
3786 DiskEntry->DiskNumber, Status);
3787 }
3788 }
3789 }
3790
3791 /* The PARTMGR should have notified the MOUNTMGR that new volumes
3792 * associated with the new partitions had to be created */
3793
3794 /* Assign valid device names to new volumes */
3795 for (Entry = List->VolumesList.Flink;
3796 Entry != &List->VolumesList;
3797 Entry = Entry->Flink)
3798 {
3799 Volume = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
3801 }
3802
3803 return TRUE;
3804}
static VOID InitVolumeDeviceName(_Inout_ PVOLENTRY Volume)
Definition: partlist.c:921
NTSTATUS WritePartitions(IN PDISKENTRY DiskEntry)
Definition: partlist.c:3593

Referenced by FsVolCommitOpsQueue().