ReactOS 0.4.16-dev-297-gc569aee
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 PartitionCreateChecks (_In_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes, _In_opt_ ULONG_PTR PartitionInfo)
 
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 2903 of file partlist.c.

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

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

◆ FindSupportedSystemPartition()

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

Definition at line 3218 of file partlist.c.

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

Definition at line 2875 of file partlist.c.

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

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

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

Referenced by InitSystemPartition().

◆ SetMBRPartitionType()

VOID SetMBRPartitionType ( IN PPARTENTRY  PartEntry,
IN UCHAR  PartitionType 
)

Definition at line 3891 of file partlist.c.

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

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

Referenced by UpdateRegistry().

◆ WritePartitions()

NTSTATUS WritePartitions ( IN PDISKENTRY  DiskEntry)

Definition at line 3582 of file partlist.c.

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

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

Referenced by FsVolCommitOpsQueue().