ReactOS 0.4.16-dev-983-g23ad936
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
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
#define L(x)
Definition: ntvdm.h:50
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:87
#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->Info.DriveLetter ? L'-' : CandidatePartition->Volume->Info.DriveLetter);
3442
3443 /* Return the candidate system partition */
3444 return CandidatePartition;
3445 }
3446
3447 // FIXME: What to do??
3448 DPRINT1("NewDisk TRUE but first partition is used?\n");
3449 }
3450
3451 /*
3452 * The disk is not new, check if any partition is initialized;
3453 * if not, the first one becomes the system partition.
3454 */
3455 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3456 ListEntry != &DiskEntry->PrimaryPartListHead;
3457 ListEntry = ListEntry->Flink)
3458 {
3459 /* Retrieve the partition */
3460 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3461
3462 /* Check if the partition is partitioned and is used */
3463 // !IsContainerPartition(PartEntry->PartitionType);
3464 if (/* PartEntry->IsPartitioned && */
3465 PartEntry->PartitionType != PARTITION_ENTRY_UNUSED || PartEntry->BootIndicator)
3466 {
3467 break;
3468 }
3469 }
3470 if (ListEntry == &DiskEntry->PrimaryPartListHead)
3471 {
3472 /*
3473 * OK we haven't encountered any used and active partition,
3474 * so use the first one as the system partition.
3475 */
3476 ASSERT(DiskEntry == CandidatePartition->DiskEntry);
3477
3478 DPRINT1("Use first active system partition %lu in disk %lu, drive letter %C\n",
3479 CandidatePartition->PartitionNumber,
3480 CandidatePartition->DiskEntry->DiskNumber,
3481 !CandidatePartition->Volume->Info.DriveLetter ? L'-' : CandidatePartition->Volume->Info.DriveLetter);
3482
3483 /* Return the candidate system partition */
3484 return CandidatePartition;
3485 }
3486
3487 /*
3488 * The disk is not new, we did not find any actual active partition,
3489 * or the one we found was not supported, or any possible other candidate
3490 * is not supported. We then use the alternative partition if specified.
3491 */
3492 if (AlternativePart)
3493 {
3494 DPRINT1("No valid or supported system partition has been found, use the alternative partition!\n");
3495 CandidatePartition = AlternativePart;
3496 goto UseAlternativePartition;
3497 }
3498 else
3499 {
3500NoSystemPartition:
3501 DPRINT1("No valid or supported system partition has been found on this system!\n");
3502 return NULL;
3503 }
3504
3505UseAlternativePartition:
3506 /*
3507 * We are here because we did not find any (active) candidate system
3508 * partition that we know how to support. What we are going to do is
3509 * to change the existing system partition and use the alternative partition
3510 * (e.g. on which we install ReactOS) as the new system partition.
3511 * Then we will need to add in FreeLdr's boot menu an entry for booting
3512 * from the original system partition.
3513 */
3514 ASSERT(CandidatePartition);
3515
3516 DPRINT1("Use alternative active system partition %lu in disk %lu, drive letter %C\n",
3517 CandidatePartition->PartitionNumber,
3518 CandidatePartition->DiskEntry->DiskNumber,
3519 !CandidatePartition->Volume->Info.DriveLetter ? L'-' : CandidatePartition->Volume->Info.DriveLetter);
3520
3521 /* Return the candidate system partition */
3522 return CandidatePartition;
3523}
@ 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:680
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:91

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

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

Referenced by InitSystemPartition().

◆ SetMBRPartitionType()

VOID SetMBRPartitionType ( IN PPARTENTRY  PartEntry,
IN UCHAR  PartitionType 
)

Definition at line 3899 of file partlist.c.

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

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

Referenced by UpdateRegistry().

◆ WritePartitions()

NTSTATUS WritePartitions ( IN PDISKENTRY  DiskEntry)

Definition at line 3590 of file partlist.c.

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

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

Referenced by FsVolCommitOpsQueue().