ReactOS 0.4.16-dev-178-g8ba6102
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 CreatePartitionList (VOID)
 
VOID DestroyPartitionList (IN PPARTLIST List)
 
PDISKENTRY GetDiskByBiosNumber (_In_ PPARTLIST List, _In_ ULONG HwDiskNumber)
 
PDISKENTRY GetDiskByNumber (_In_ PPARTLIST List, _In_ ULONG DiskNumber)
 
PDISKENTRY GetDiskBySCSI (_In_ PPARTLIST List, _In_ USHORT Port, _In_ USHORT Bus, _In_ USHORT Id)
 
PDISKENTRY GetDiskBySignature (_In_ PPARTLIST List, _In_ ULONG Signature)
 
PPARTENTRY GetPartition (_In_ PDISKENTRY DiskEntry, _In_ ULONG PartitionNumber)
 
PPARTENTRY SelectPartition (_In_ PPARTLIST List, _In_ ULONG DiskNumber, _In_ ULONG PartitionNumber)
 
PPARTENTRY GetNextPartition (IN PPARTLIST List, IN PPARTENTRY CurrentPart OPTIONAL)
 
PPARTENTRY GetPrevPartition (IN PPARTLIST List, IN PPARTENTRY CurrentPart OPTIONAL)
 
PPARTENTRY 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 PartitionCreationChecks (_In_ PPARTENTRY PartEntry)
 
ERROR_NUMBER ExtendedPartitionCreationChecks (_In_ PPARTENTRY PartEntry)
 
BOOLEAN CreatePartition (_In_ PPARTLIST List, _Inout_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes, _In_opt_ ULONG_PTR PartitionInfo)
 
BOOLEAN 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 CreatePartition ( _In_ PPARTLIST  List,
_Inout_ PPARTENTRY  PartEntry,
_In_opt_ ULONGLONG  SizeBytes,
_In_opt_ ULONG_PTR  PartitionInfo 
)

Definition at line 2905 of file partlist.c.

2910{
2913 PDISKENTRY DiskEntry;
2914 PCSTR mainType = "Primary";
2915
2916 if (isContainer)
2917 mainType = "Extended";
2918 else if (PartEntry && PartEntry->LogicalPartition)
2919 mainType = "Logical";
2920
2921 DPRINT1("CreatePartition(%s, %I64u bytes)\n", mainType, SizeBytes);
2922
2923 if (!List || !PartEntry ||
2924 !PartEntry->DiskEntry || PartEntry->IsPartitioned)
2925 {
2926 return FALSE;
2927 }
2928
2929 if (isContainer)
2931 else
2932 Error = PartitionCreationChecks(PartEntry);
2933 if (Error != NOT_AN_ERROR)
2934 {
2935 DPRINT1("PartitionCreationChecks(%s) failed with error %lu\n", mainType, Error);
2936 return FALSE;
2937 }
2938
2939 /* Initialize the partition entry, inserting a new blank region if needed */
2940 if (!InitializePartitionEntry(PartEntry, SizeBytes, PartitionInfo))
2941 return FALSE;
2942
2943 DiskEntry = PartEntry->DiskEntry;
2944 UpdateDiskLayout(DiskEntry);
2945
2946 ASSERT(!PartEntry->Volume);
2947 if (!isContainer)
2948 {
2949 /* We create a primary/logical partition: initialize a new basic
2950 * volume entry. When the partition will actually be written onto
2951 * the disk, the PARTMGR will notify the MOUNTMGR that a volume
2952 * associated with this partition has to be created. */
2953 PartEntry->Volume = InitVolume(DiskEntry->PartList, PartEntry);
2954 ASSERT(PartEntry->Volume);
2955 }
2956
2958
2959 return TRUE;
2960}
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 ExtendedPartitionCreationChecks(_In_ PPARTENTRY PartEntry)
Definition: partlist.c:2867
ERROR_NUMBER PartitionCreationChecks(_In_ PPARTENTRY PartEntry)
Definition: partlist.c:2822
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2585
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 CreatePartitionList ( VOID  )

Definition at line 1987 of file partlist.c.

1988{
1990 PDISKENTRY SystemDisk;
1994 ULONG ReturnSize;
1996 ULONG DiskNumber;
2000
2002 0,
2003 sizeof(PARTLIST));
2004 if (!List)
2005 return NULL;
2006
2007 List->SystemPartition = NULL;
2008
2009 InitializeListHead(&List->DiskListHead);
2010 InitializeListHead(&List->BiosDiskListHead);
2011 InitializeListHead(&List->VolumesList);
2012
2013 /*
2014 * Enumerate the disks seen by the BIOS; this will be used later
2015 * to map drives seen by NTOS with their corresponding BIOS names.
2016 */
2018
2019 /* Enumerate disks seen by NTOS */
2021 &Sdi,
2022 sizeof(Sdi),
2023 &ReturnSize);
2024 if (!NT_SUCCESS(Status))
2025 {
2026 DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx\n", Status);
2028 return NULL;
2029 }
2030
2031 for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
2032 {
2034 L"\\Device\\Harddisk%lu\\Partition0",
2035 DiskNumber);
2037
2039 &Name,
2041 NULL,
2042 NULL);
2043
2047 &Iosb,
2050 if (NT_SUCCESS(Status))
2051 {
2052 AddDiskToList(FileHandle, DiskNumber, List);
2054 }
2055 }
2056
2060
2061 /*
2062 * Retrieve the system partition: the active partition on the system
2063 * disk (the one that will be booted by default by the hardware).
2064 */
2065 SystemDisk = GetSystemDisk(List);
2066 List->SystemPartition = (SystemDisk ? GetActiveDiskPartition(SystemDisk) : NULL);
2067
2068 return List;
2069}
struct NameRec_ * Name
Definition: cdprocs.h:460
LONG NTSTATUS
Definition: precomp.h:26
HANDLE ProcessHeap
Definition: servman.c:15
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define 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:4402
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ SystemDeviceInformation
Definition: ntddk_ex.h:18
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
Status
Definition: gdiplustypes.h:25
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
struct _PARTLIST * PPARTLIST
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
#define L(x)
Definition: ntvdm.h:50
static PDISKENTRY GetSystemDisk(IN PPARTLIST List)
Definition: partlist.c: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 DeletePartition ( _In_ PPARTLIST  List,
_In_ PPARTENTRY  PartEntry,
_Out_opt_ PPARTENTRY FreeRegion 
)

Definition at line 2998 of file partlist.c.

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

Definition at line 2072 of file partlist.c.

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

◆ ExtendedPartitionCreationChecks()

ERROR_NUMBER ExtendedPartitionCreationChecks ( _In_ PPARTENTRY  PartEntry)

Definition at line 2867 of file partlist.c.

2869{
2870 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2871
2872 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2873 {
2874 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2875 return ERROR_WARN_PARTITION;
2876 }
2877
2878 /* Fail if the partition is already in use */
2879 if (PartEntry->IsPartitioned)
2880 return ERROR_NEW_PARTITION;
2881
2882 /* Cannot create an extended partition within logical partition space */
2883 if (PartEntry->LogicalPartition)
2885
2886 /* Only one primary partition is allowed on super-floppy */
2887 if (IsSuperFloppy(DiskEntry))
2889
2890 /* Fail if there are already 4 primary partitions in the list */
2891 if (GetPrimaryPartitionCount(DiskEntry) >= 4)
2893
2894 /* Fail if there is another extended partition in the list */
2895 if (DiskEntry->ExtendedPartition)
2897
2898 return ERROR_SUCCESS;
2899}
#define ERROR_SUCCESS
Definition: deptool.c:10
@ ERROR_WARN_PARTITION
Definition: errorcode.h:33
@ ERROR_NEW_PARTITION
Definition: errorcode.h:34
@ ERROR_ONLY_ONE_EXTENDED
Definition: errorcode.h:59
@ ERROR_PARTITION_TABLE_FULL
Definition: errorcode.h:58
@ PARTITION_STYLE_GPT
Definition: imports.h:202
BOOLEAN IsSuperFloppy(_In_ PDISKENTRY DiskEntry)
Definition: partlist.c:600
#define GetPrimaryPartitionCount(DiskEntry)
Definition: partlist.c:2523
PARTITION_STYLE DiskStyle
Definition: partlist.h:139

Referenced by CreatePartition(), and SelectPartitionPage().

◆ FindSupportedSystemPartition()

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

Definition at line 3223 of file partlist.c.

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

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

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

◆ GetDiskByNumber()

PDISKENTRY GetDiskByNumber ( _In_ PPARTLIST  List,
_In_ ULONG  DiskNumber 
)

Definition at line 2149 of file partlist.c.

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

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

2205{
2206 PDISKENTRY DiskEntry;
2208
2209 /* Loop over the disks and find the correct one */
2210 for (Entry = List->DiskListHead.Flink;
2211 Entry != &List->DiskListHead;
2212 Entry = Entry->Flink)
2213 {
2214 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2215
2216 if (DiskEntry->LayoutBuffer->Signature == Signature)
2217 return DiskEntry; /* Disk found, return it */
2218 }
2219
2220 /* Disk not found, stop there */
2221 return NULL;
2222}
static const WCHAR Signature[]
Definition: parser.c:141

Referenced by ResolveArcNameManually().

◆ GetNextPartition()

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

Definition at line 2291 of file partlist.c.

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

2228{
2229 PPARTENTRY PartEntry;
2231
2232 /* Forbid whole-disk or extended container partition access */
2233 if (PartitionNumber == 0)
2234 return NULL;
2235
2236 /* Loop over the primary partitions first... */
2237 for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2238 Entry != &DiskEntry->PrimaryPartListHead;
2239 Entry = Entry->Flink)
2240 {
2241 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2242
2243 if (PartEntry->PartitionNumber == PartitionNumber)
2244 return PartEntry; /* Partition found, return it */
2245 }
2246
2247 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2248 return NULL;
2249
2250 /* ... then over the logical partitions if needed */
2251 for (Entry = DiskEntry->LogicalPartListHead.Flink;
2252 Entry != &DiskEntry->LogicalPartListHead;
2253 Entry = Entry->Flink)
2254 {
2255 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2256
2257 if (PartEntry->PartitionNumber == PartitionNumber)
2258 return PartEntry; /* Partition found, return it */
2259 }
2260
2261 /* The partition was not found on the disk, stop there */
2262 return NULL;
2263}
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2061

Referenced by ResolveArcNameManually(), and SelectPartition().

◆ GetPrevPartition()

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

Definition at line 2383 of file partlist.c.

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

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:672
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(), ExtendedPartitionCreationChecks(), InstallBootManagerAndBootEntries(), InstallBootManagerAndBootEntriesWorker(), PartitionCreationChecks(), and xHalIoWritePartitionTable().

◆ PartitionCreationChecks()

ERROR_NUMBER PartitionCreationChecks ( _In_ PPARTENTRY  PartEntry)

Definition at line 2822 of file partlist.c.

2824{
2825 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2826
2827 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2828 {
2829 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2830 return ERROR_WARN_PARTITION;
2831 }
2832
2833 /* Fail if the partition is already in use */
2834 if (PartEntry->IsPartitioned)
2835 return ERROR_NEW_PARTITION;
2836
2837 /*
2838 * For primary partitions
2839 */
2840 if (!PartEntry->LogicalPartition)
2841 {
2842 /* Only one primary partition is allowed on super-floppy */
2843 if (IsSuperFloppy(DiskEntry))
2845
2846 /* Fail if there are already 4 primary partitions in the list */
2847 if (GetPrimaryPartitionCount(DiskEntry) >= 4)
2849 }
2850 /*
2851 * For logical partitions
2852 */
2853 else
2854 {
2855 // TODO: Check that we are inside an extended partition!!
2856 // Then the following check will be useless.
2857
2858 /* Only one (primary) partition is allowed on super-floppy */
2859 if (IsSuperFloppy(DiskEntry))
2861 }
2862
2863 return ERROR_SUCCESS;
2864}

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:3058

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

◆ SelectPartition()

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

Definition at line 2266 of file partlist.c.

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

Referenced by EnumerateInstallations(), and SelectPartitionPage().

◆ SetActivePartition()

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

Definition at line 3523 of file partlist.c.

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

Referenced by InitSystemPartition().

◆ SetMBRPartitionType()

VOID SetMBRPartitionType ( IN PPARTENTRY  PartEntry,
IN UCHAR  PartitionType 
)

Definition at line 3896 of file partlist.c.

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

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

Referenced by UpdateRegistry().

◆ WritePartitions()

NTSTATUS WritePartitions ( IN PDISKENTRY  DiskEntry)

Definition at line 3587 of file partlist.c.

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

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

Referenced by FsVolCommitOpsQueue().