ReactOS 0.4.15-dev-8390-g075894b
partlist.h File Reference
#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  _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 _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 , Preformatted ,
  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 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)
 
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)
 
NTSTATUS DismountVolume (IN PPARTENTRY PartEntry)
 
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 SetMountedDeviceValue (IN WCHAR Letter, IN ULONG Signature, IN LARGE_INTEGER StartingOffset)
 
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 172 of file partlist.h.

◆ GetDiskSizeInBytes

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

Definition at line 233 of file partlist.h.

◆ GetPartEntryOffsetInBytes

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

Definition at line 227 of file partlist.h.

◆ GetPartEntrySizeInBytes

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

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

◆ PARTITION_TBL_SIZE

#define PARTITION_TBL_SIZE   4

Definition at line 167 of file partlist.h.

Typedef Documentation

◆ BIOSDISKENTRY

◆ DISKENTRY

◆ FORMATSTATE

◆ PARTENTRY

◆ PARTITION

◆ PARTITION_SECTOR

◆ PARTLIST

◆ PBIOS_DISK

◆ PBIOSDISKENTRY

◆ PDISKENTRY

◆ PFORMATSTATE

◆ PPARTENTRY

◆ PPARTITION

◆ PPARTITION_SECTOR

◆ PPARTLIST

Enumeration Type Documentation

◆ _FORMATSTATE

Enumerator
Unformatted 
UnformattedOrDamaged 
UnknownFormat 
Preformatted 
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
@ Preformatted
Definition: partlist.h:37
@ Formatted
Definition: partlist.h:38
@ 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 2844 of file partlist.c.

2849{
2852 PCSTR mainType = "Primary";
2853
2854 if (isContainer)
2855 mainType = "Extended";
2856 else if (PartEntry && PartEntry->LogicalPartition)
2857 mainType = "Logical";
2858
2859 DPRINT1("CreatePartition(%s, %I64u bytes)\n", mainType, SizeBytes);
2860
2861 if (!List || !PartEntry ||
2862 !PartEntry->DiskEntry || PartEntry->IsPartitioned)
2863 {
2864 return FALSE;
2865 }
2866
2867 if (isContainer)
2869 else
2870 Error = PartitionCreationChecks(PartEntry);
2871 if (Error != NOT_AN_ERROR)
2872 {
2873 DPRINT1("PartitionCreationChecks(%s) failed with error %lu\n", mainType, Error);
2874 return FALSE;
2875 }
2876
2877 /* Initialize the partition entry, inserting a new blank region if needed */
2878 if (!InitializePartitionEntry(PartEntry, SizeBytes, PartitionInfo))
2879 return FALSE;
2880
2881 if (isContainer)
2882 {
2883 // FIXME? Possibly to make GetNextUnformattedPartition work (i.e. skip the extended partition container)
2884 PartEntry->New = FALSE;
2885 PartEntry->FormatState = Formatted;
2886 }
2887
2888 UpdateDiskLayout(PartEntry->DiskEntry);
2890
2891 return TRUE;
2892}
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 IsContainerPartition(PartitionType)
Definition: ntdddisk.h:321
ERROR_NUMBER ExtendedPartitionCreationChecks(_In_ PPARTENTRY PartEntry)
Definition: partlist.c:2806
ERROR_NUMBER PartitionCreationChecks(_In_ PPARTENTRY PartEntry)
Definition: partlist.c:2761
static VOID UpdateDiskLayout(IN PDISKENTRY DiskEntry)
Definition: partlist.c:2523
static VOID AssignDriveLetters(IN PPARTLIST List)
Definition: partlist.c:138
static BOOLEAN InitializePartitionEntry(_Inout_ PPARTENTRY PartEntry, _In_opt_ ULONGLONG SizeBytes, _In_opt_ ULONG_PTR PartitionInfo)
Definition: partlist.c:708
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(), InitSystemPartition(), and SelectPartitionPage().

◆ CreatePartitionList()

PPARTLIST CreatePartitionList ( VOID  )

Definition at line 1923 of file partlist.c.

1924{
1926 PDISKENTRY SystemDisk;
1930 ULONG ReturnSize;
1932 ULONG DiskNumber;
1936
1938 0,
1939 sizeof(PARTLIST));
1940 if (List == NULL)
1941 return NULL;
1942
1943 List->SystemPartition = NULL;
1944
1945 InitializeListHead(&List->DiskListHead);
1946 InitializeListHead(&List->BiosDiskListHead);
1947
1948 /*
1949 * Enumerate the disks seen by the BIOS; this will be used later
1950 * to map drives seen by NTOS with their corresponding BIOS names.
1951 */
1953
1954 /* Enumerate disks seen by NTOS */
1956 &Sdi,
1957 sizeof(Sdi),
1958 &ReturnSize);
1959 if (!NT_SUCCESS(Status))
1960 {
1961 DPRINT1("NtQuerySystemInformation() failed, Status 0x%08lx\n", Status);
1963 return NULL;
1964 }
1965
1966 for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
1967 {
1969 L"\\Device\\Harddisk%lu\\Partition0",
1970 DiskNumber);
1972
1974 &Name,
1976 NULL,
1977 NULL);
1978
1982 &Iosb,
1985 if (NT_SUCCESS(Status))
1986 {
1987 AddDiskToList(FileHandle, DiskNumber, List);
1989 }
1990 }
1991
1995
1996 /*
1997 * Retrieve the system partition: the active partition on the system
1998 * disk (the one that will be booted by default by the hardware).
1999 */
2000 SystemDisk = GetSystemDisk(List);
2001 List->SystemPartition = (SystemDisk ? GetActiveDiskPartition(SystemDisk) : NULL);
2002
2003 return List;
2004}
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:1794
static VOID AddDiskToList(IN HANDLE FileHandle, IN ULONG DiskNumber, IN PPARTLIST List)
Definition: partlist.c:1382
static VOID UpdateDiskSignatures(IN PPARTLIST List)
Definition: partlist.c:1291
static VOID EnumerateBiosDiskEntries(IN PPARTLIST PartList)
Definition: partlist.c:337
static PPARTENTRY GetActiveDiskPartition(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1867
static VOID UpdateHwDiskNumbers(IN PPARTLIST List)
Definition: partlist.c:1321
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 3002 of file partlist.c.

3006{
3007 PDISKENTRY DiskEntry;
3008 PPARTENTRY PrevPartEntry;
3009 PPARTENTRY NextPartEntry;
3010 PPARTENTRY LogicalPartEntry;
3012
3013 if (!List || !PartEntry ||
3014 !PartEntry->DiskEntry || !PartEntry->IsPartitioned)
3015 {
3016 return FALSE;
3017 }
3018
3019 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
3020
3021 /* Clear the system partition if it is being deleted */
3022 if (List->SystemPartition == PartEntry)
3023 {
3024 ASSERT(List->SystemPartition);
3025 List->SystemPartition = NULL;
3026 }
3027
3028 DiskEntry = PartEntry->DiskEntry;
3029
3030 /* Check which type of partition (primary/logical or extended) is being deleted */
3031 if (DiskEntry->ExtendedPartition == PartEntry)
3032 {
3033 /* An extended partition is being deleted: delete all logical partition entries */
3034 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
3035 {
3037 LogicalPartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
3038
3039 /* Dismount the logical partition */
3040 DismountVolume(LogicalPartEntry);
3041
3042 /* Delete it */
3043 RtlFreeHeap(ProcessHeap, 0, LogicalPartEntry);
3044 }
3045
3046 DiskEntry->ExtendedPartition = NULL;
3047 }
3048 else
3049 {
3050 /* A primary partition is being deleted: dismount it */
3051 DismountVolume(PartEntry);
3052 }
3053
3054 /* Adjust the unpartitioned disk space entries */
3055
3056 /* Get pointer to previous and next unpartitioned entries */
3057 PrevPartEntry = GetAdjUnpartitionedEntry(PartEntry, FALSE);
3058 NextPartEntry = GetAdjUnpartitionedEntry(PartEntry, TRUE);
3059
3060 if (PrevPartEntry != NULL && NextPartEntry != NULL)
3061 {
3062 /* Merge the previous, current and next unpartitioned entries */
3063
3064 /* Adjust the previous entry length */
3065 PrevPartEntry->SectorCount.QuadPart += (PartEntry->SectorCount.QuadPart + NextPartEntry->SectorCount.QuadPart);
3066
3067 /* Remove the current and next entries */
3068 RemoveEntryList(&PartEntry->ListEntry);
3069 RtlFreeHeap(ProcessHeap, 0, PartEntry);
3070 RemoveEntryList(&NextPartEntry->ListEntry);
3071 RtlFreeHeap(ProcessHeap, 0, NextPartEntry);
3072
3073 /* Optionally return the freed region */
3074 if (FreeRegion)
3075 *FreeRegion = PrevPartEntry;
3076 }
3077 else if (PrevPartEntry != NULL && NextPartEntry == NULL)
3078 {
3079 /* Merge the current and the previous unpartitioned entries */
3080
3081 /* Adjust the previous entry length */
3082 PrevPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3083
3084 /* Remove the current entry */
3085 RemoveEntryList(&PartEntry->ListEntry);
3086 RtlFreeHeap(ProcessHeap, 0, PartEntry);
3087
3088 /* Optionally return the freed region */
3089 if (FreeRegion)
3090 *FreeRegion = PrevPartEntry;
3091 }
3092 else if (PrevPartEntry == NULL && NextPartEntry != NULL)
3093 {
3094 /* Merge the current and the next unpartitioned entries */
3095
3096 /* Adjust the next entry offset and length */
3097 NextPartEntry->StartSector.QuadPart = PartEntry->StartSector.QuadPart;
3098 NextPartEntry->SectorCount.QuadPart += PartEntry->SectorCount.QuadPart;
3099
3100 /* Remove the current entry */
3101 RemoveEntryList(&PartEntry->ListEntry);
3102 RtlFreeHeap(ProcessHeap, 0, PartEntry);
3103
3104 /* Optionally return the freed region */
3105 if (FreeRegion)
3106 *FreeRegion = NextPartEntry;
3107 }
3108 else
3109 {
3110 /* Nothing to merge but change the current entry */
3111 PartEntry->IsPartitioned = FALSE;
3112 PartEntry->OnDiskPartitionNumber = 0;
3113 PartEntry->PartitionNumber = 0;
3114 // PartEntry->PartitionIndex = 0;
3115 PartEntry->BootIndicator = FALSE;
3116 PartEntry->PartitionType = PARTITION_ENTRY_UNUSED;
3117 PartEntry->FormatState = Unformatted;
3118 PartEntry->FileSystem[0] = L'\0';
3119 PartEntry->DriveLetter = 0;
3120 RtlZeroMemory(PartEntry->VolumeLabel, sizeof(PartEntry->VolumeLabel));
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:86
#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 ASSERT(a)
Definition: mode.c:44
static 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:2725
NTSTATUS DismountVolume(IN PPARTENTRY PartEntry)
Definition: partlist.c:2895
base of all file and directory entries
Definition: entries.h:83
PPARTENTRY ExtendedPartition
Definition: partlist.h:132
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:129
Definition: typedefs.h:120
BOOLEAN IsPartitioned
Definition: partlist.h:66
ULARGE_INTEGER SectorCount
Definition: partlist.h:50
LIST_ENTRY ListEntry
Definition: partlist.h:43
ULARGE_INTEGER StartSector
Definition: partlist.h:49
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by DeletePartitionPage().

◆ DestroyPartitionList()

VOID DestroyPartitionList ( IN PPARTLIST  List)

Definition at line 2007 of file partlist.c.

2009{
2010 PDISKENTRY DiskEntry;
2011 PBIOSDISKENTRY BiosDiskEntry;
2012 PPARTENTRY PartEntry;
2014
2015 /* Release disk and partition info */
2016 while (!IsListEmpty(&List->DiskListHead))
2017 {
2018 Entry = RemoveHeadList(&List->DiskListHead);
2019 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2020
2021 /* Release driver name */
2022 RtlFreeUnicodeString(&DiskEntry->DriverName);
2023
2024 /* Release primary partition list */
2025 while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
2026 {
2028 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2029
2030 RtlFreeHeap(ProcessHeap, 0, PartEntry);
2031 }
2032
2033 /* Release logical partition list */
2034 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
2035 {
2037 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2038
2039 RtlFreeHeap(ProcessHeap, 0, PartEntry);
2040 }
2041
2042 /* Release layout buffer */
2043 if (DiskEntry->LayoutBuffer != NULL)
2044 RtlFreeHeap(ProcessHeap, 0, DiskEntry->LayoutBuffer);
2045
2046 /* Release disk entry */
2047 RtlFreeHeap(ProcessHeap, 0, DiskEntry);
2048 }
2049
2050 /* Release the bios disk info */
2051 while (!IsListEmpty(&List->BiosDiskListHead))
2052 {
2053 Entry = RemoveHeadList(&List->BiosDiskListHead);
2054 BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
2055
2056 RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry);
2057 }
2058
2059 /* Release list head */
2061}
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
UNICODE_STRING DriverName
Definition: partlist.h:120
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:128
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:122

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

◆ DismountVolume()

NTSTATUS DismountVolume ( IN PPARTENTRY  PartEntry)

Definition at line 2895 of file partlist.c.

2897{
2899 NTSTATUS LockStatus;
2903 HANDLE PartitionHandle;
2905
2906 /* Check whether the partition is valid and was mounted by the system */
2907 if (!PartEntry->IsPartitioned ||
2908 IsContainerPartition(PartEntry->PartitionType) ||
2909 !IsRecognizedPartition(PartEntry->PartitionType) ||
2910 PartEntry->FormatState == UnknownFormat ||
2911 // NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
2912 // it has been usually mounted with RawFS and thus needs to be dismounted.
2913 !*PartEntry->FileSystem ||
2914 PartEntry->PartitionNumber == 0)
2915 {
2916 /* The partition is not mounted, so just return success */
2917 return STATUS_SUCCESS;
2918 }
2919
2920 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
2921
2922 /* Open the volume */
2924 L"\\Device\\Harddisk%lu\\Partition%lu",
2925 PartEntry->DiskEntry->DiskNumber,
2926 PartEntry->PartitionNumber);
2928
2930 &Name,
2932 NULL,
2933 NULL);
2934
2935 Status = NtOpenFile(&PartitionHandle,
2941 if (!NT_SUCCESS(Status))
2942 {
2943 DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
2944 return Status;
2945 }
2946
2947 /* Lock the volume */
2948 LockStatus = NtFsControlFile(PartitionHandle,
2949 NULL,
2950 NULL,
2951 NULL,
2954 NULL,
2955 0,
2956 NULL,
2957 0);
2958 if (!NT_SUCCESS(LockStatus))
2959 {
2960 DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
2961 }
2962
2963 /* Dismount the volume */
2964 Status = NtFsControlFile(PartitionHandle,
2965 NULL,
2966 NULL,
2967 NULL,
2970 NULL,
2971 0,
2972 NULL,
2973 0);
2974 if (!NT_SUCCESS(Status))
2975 {
2976 DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
2977 }
2978
2979 /* Unlock the volume */
2980 LockStatus = NtFsControlFile(PartitionHandle,
2981 NULL,
2982 NULL,
2983 NULL,
2986 NULL,
2987 0,
2988 NULL,
2989 0);
2990 if (!NT_SUCCESS(LockStatus))
2991 {
2992 DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
2993 }
2994
2995 /* Close the volume */
2996 NtClose(PartitionHandle);
2997
2998 return Status;
2999}
#define GENERIC_READ
Definition: compat.h:135
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
#define GENERIC_WRITE
Definition: nt_native.h:90
NTSYSAPI NTSTATUS NTAPI NtFsControlFile(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 IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by AddPartitionToDisk(), clean_main(), and DeletePartition().

◆ ExtendedPartitionCreationChecks()

ERROR_NUMBER ExtendedPartitionCreationChecks ( _In_ PPARTENTRY  PartEntry)

Definition at line 2806 of file partlist.c.

2808{
2809 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2810
2811 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2812 {
2813 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2814 return ERROR_WARN_PARTITION;
2815 }
2816
2817 /* Fail if the partition is already in use */
2818 if (PartEntry->IsPartitioned)
2819 return ERROR_NEW_PARTITION;
2820
2821 /* Cannot create an extended partition within logical partition space */
2822 if (PartEntry->LogicalPartition)
2824
2825 /* Only one primary partition is allowed on super-floppy */
2826 if (IsSuperFloppy(DiskEntry))
2828
2829 /* Fail if there are already 4 primary partitions in the list */
2830 if (GetPrimaryPartitionCount(DiskEntry) >= 4)
2832
2833 /* Fail if there is another extended partition in the list */
2834 if (DiskEntry->ExtendedPartition)
2836
2837 return ERROR_SUCCESS;
2838}
#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:501
#define GetPrimaryPartitionCount(DiskEntry)
Definition: partlist.c:2461
PARTITION_STYLE DiskStyle
Definition: partlist.h:118

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

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

Referenced by InitSystemPartition().

◆ GetDiskByBiosNumber()

PDISKENTRY GetDiskByBiosNumber ( _In_ PPARTLIST  List,
_In_ ULONG  HwDiskNumber 
)

Definition at line 2064 of file partlist.c.

2067{
2068 PDISKENTRY DiskEntry;
2070
2071 /* Loop over the disks and find the correct one */
2072 for (Entry = List->DiskListHead.Flink;
2073 Entry != &List->DiskListHead;
2074 Entry = Entry->Flink)
2075 {
2076 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2077
2078 if (DiskEntry->HwDiskNumber == HwDiskNumber)
2079 return DiskEntry; /* Disk found, return it */
2080 }
2081
2082 /* Disk not found, stop there */
2083 return NULL;
2084}
ULONG HwDiskNumber
Definition: partlist.h:102

◆ GetDiskByNumber()

PDISKENTRY GetDiskByNumber ( _In_ PPARTLIST  List,
_In_ ULONG  DiskNumber 
)

Definition at line 2087 of file partlist.c.

2090{
2091 PDISKENTRY DiskEntry;
2093
2094 /* Loop over the disks and find the correct one */
2095 for (Entry = List->DiskListHead.Flink;
2096 Entry != &List->DiskListHead;
2097 Entry = Entry->Flink)
2098 {
2099 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2100
2101 if (DiskEntry->DiskNumber == DiskNumber)
2102 return DiskEntry; /* Disk found, return it */
2103 }
2104
2105 /* Disk not found, stop there */
2106 return NULL;
2107}
ULONG DiskNumber
Definition: partlist.h:108

Referenced by SelectPartition().

◆ GetDiskBySCSI()

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

Definition at line 2110 of file partlist.c.

2115{
2116 PDISKENTRY DiskEntry;
2118
2119 /* Loop over the disks and find the correct one */
2120 for (Entry = List->DiskListHead.Flink;
2121 Entry != &List->DiskListHead;
2122 Entry = Entry->Flink)
2123 {
2124 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2125
2126 if (DiskEntry->Port == Port &&
2127 DiskEntry->Bus == Bus &&
2128 DiskEntry->Id == Id)
2129 {
2130 /* Disk found, return it */
2131 return DiskEntry;
2132 }
2133 }
2134
2135 /* Disk not found, stop there */
2136 return NULL;
2137}
DWORD Id
CPPORT Port[4]
Definition: headless.c:35
USHORT Bus
Definition: partlist.h:111
USHORT Id
Definition: partlist.h:112
USHORT Port
Definition: partlist.h:110

Referenced by ResolveArcNameManually().

◆ GetDiskBySignature()

PDISKENTRY GetDiskBySignature ( _In_ PPARTLIST  List,
_In_ ULONG  Signature 
)

Definition at line 2140 of file partlist.c.

2143{
2144 PDISKENTRY DiskEntry;
2146
2147 /* Loop over the disks and find the correct one */
2148 for (Entry = List->DiskListHead.Flink;
2149 Entry != &List->DiskListHead;
2150 Entry = Entry->Flink)
2151 {
2152 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
2153
2154 if (DiskEntry->LayoutBuffer->Signature == Signature)
2155 return DiskEntry; /* Disk found, return it */
2156 }
2157
2158 /* Disk not found, stop there */
2159 return NULL;
2160}
static const WCHAR Signature[]
Definition: parser.c:141

Referenced by ResolveArcNameManually().

◆ GetNextPartition()

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

Definition at line 2229 of file partlist.c.

2232{
2233 PLIST_ENTRY DiskListEntry;
2234 PLIST_ENTRY PartListEntry;
2236
2237 /* Fail if no disks are available */
2238 if (IsListEmpty(&List->DiskListHead))
2239 return NULL;
2240
2241 /* Check for the next usable entry on the current partition's disk */
2242 if (CurrentPart != NULL)
2243 {
2244 CurrentDisk = CurrentPart->DiskEntry;
2245
2246 if (CurrentPart->LogicalPartition)
2247 {
2248 /* Logical partition */
2249
2250 PartListEntry = CurrentPart->ListEntry.Flink;
2251 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2252 {
2253 /* Next logical partition */
2254 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2255 return CurrentPart;
2256 }
2257 else
2258 {
2259 PartListEntry = CurrentDisk->ExtendedPartition->ListEntry.Flink;
2260 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2261 {
2262 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2263 return CurrentPart;
2264 }
2265 }
2266 }
2267 else
2268 {
2269 /* Primary or extended partition */
2270
2271 if (CurrentPart->IsPartitioned &&
2272 IsContainerPartition(CurrentPart->PartitionType))
2273 {
2274 /* First logical partition */
2275 PartListEntry = CurrentDisk->LogicalPartListHead.Flink;
2276 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2277 {
2278 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2279 return CurrentPart;
2280 }
2281 }
2282 else
2283 {
2284 /* Next primary partition */
2285 PartListEntry = CurrentPart->ListEntry.Flink;
2286 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2287 {
2288 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2289 return CurrentPart;
2290 }
2291 }
2292 }
2293 }
2294
2295 /* Search for the first partition entry on the next disk */
2296 for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Flink
2297 : List->DiskListHead.Flink);
2298 DiskListEntry != &List->DiskListHead;
2299 DiskListEntry = DiskListEntry->Flink)
2300 {
2301 CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2302
2304 {
2305 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2306 continue;
2307 }
2308
2309 PartListEntry = CurrentDisk->PrimaryPartListHead.Flink;
2310 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2311 {
2312 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2313 return CurrentPart;
2314 }
2315 }
2316
2317 return NULL;
2318}
PDISKENTRY CurrentDisk
Definition: partlist.c:74
#define DPRINT
Definition: sndvol32.h:73
LIST_ENTRY ListEntry
Definition: partlist.h:80

Referenced by ScrollUpDownPartitionList().

◆ GetPartition()

PPARTENTRY GetPartition ( _In_ PDISKENTRY  DiskEntry,
_In_ ULONG  PartitionNumber 
)

Definition at line 2163 of file partlist.c.

2166{
2167 PPARTENTRY PartEntry;
2169
2170 /* Forbid whole-disk or extended container partition access */
2171 if (PartitionNumber == 0)
2172 return NULL;
2173
2174 /* Loop over the primary partitions first... */
2175 for (Entry = DiskEntry->PrimaryPartListHead.Flink;
2176 Entry != &DiskEntry->PrimaryPartListHead;
2177 Entry = Entry->Flink)
2178 {
2179 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2180
2181 if (PartEntry->PartitionNumber == PartitionNumber)
2182 return PartEntry; /* Partition found, return it */
2183 }
2184
2185 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2186 return NULL;
2187
2188 /* ... then over the logical partitions if needed */
2189 for (Entry = DiskEntry->LogicalPartListHead.Flink;
2190 Entry != &DiskEntry->LogicalPartListHead;
2191 Entry = Entry->Flink)
2192 {
2193 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
2194
2195 if (PartEntry->PartitionNumber == PartitionNumber)
2196 return PartEntry; /* Partition found, return it */
2197 }
2198
2199 /* The partition was not found on the disk, stop there */
2200 return NULL;
2201}
_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 2321 of file partlist.c.

2324{
2325 PLIST_ENTRY DiskListEntry;
2326 PLIST_ENTRY PartListEntry;
2328
2329 /* Fail if no disks are available */
2330 if (IsListEmpty(&List->DiskListHead))
2331 return NULL;
2332
2333 /* Check for the previous usable entry on the current partition's disk */
2334 if (CurrentPart != NULL)
2335 {
2336 CurrentDisk = CurrentPart->DiskEntry;
2337
2338 if (CurrentPart->LogicalPartition)
2339 {
2340 /* Logical partition */
2341
2342 PartListEntry = CurrentPart->ListEntry.Blink;
2343 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2344 {
2345 /* Previous logical partition */
2346 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2347 }
2348 else
2349 {
2350 /* Extended partition */
2351 CurrentPart = CurrentDisk->ExtendedPartition;
2352 }
2353 return CurrentPart;
2354 }
2355 else
2356 {
2357 /* Primary or extended partition */
2358
2359 PartListEntry = CurrentPart->ListEntry.Blink;
2360 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2361 {
2362 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2363
2364 if (CurrentPart->IsPartitioned &&
2365 IsContainerPartition(CurrentPart->PartitionType))
2366 {
2367 PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2368 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2369 }
2370
2371 return CurrentPart;
2372 }
2373 }
2374 }
2375
2376 /* Search for the last partition entry on the previous disk */
2377 for (DiskListEntry = (CurrentPart ? CurrentDisk->ListEntry.Blink
2378 : List->DiskListHead.Blink);
2379 DiskListEntry != &List->DiskListHead;
2380 DiskListEntry = DiskListEntry->Blink)
2381 {
2382 CurrentDisk = CONTAINING_RECORD(DiskListEntry, DISKENTRY, ListEntry);
2383
2385 {
2386 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2387 continue;
2388 }
2389
2390 PartListEntry = CurrentDisk->PrimaryPartListHead.Blink;
2391 if (PartListEntry != &CurrentDisk->PrimaryPartListHead)
2392 {
2393 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2394
2395 if (CurrentPart->IsPartitioned &&
2396 IsContainerPartition(CurrentPart->PartitionType))
2397 {
2398 PartListEntry = CurrentDisk->LogicalPartListHead.Blink;
2399 if (PartListEntry != &CurrentDisk->LogicalPartListHead)
2400 {
2401 CurrentPart = CONTAINING_RECORD(PartListEntry, PARTENTRY, ListEntry);
2402 return CurrentPart;
2403 }
2404 }
2405 else
2406 {
2407 return CurrentPart;
2408 }
2409 }
2410 }
2411
2412 return NULL;
2413}
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122

Referenced by ScrollUpDownPartitionList().

◆ IsPartitionActive()

BOOLEAN IsPartitionActive ( IN PPARTENTRY  PartEntry)

Definition at line 1844 of file partlist.c.

1846{
1847 // TODO: Support for GPT disks!
1848
1849 if (IsContainerPartition(PartEntry->PartitionType))
1850 return FALSE;
1851
1852 /* Check if the partition is partitioned, used and active */
1853 if (PartEntry->IsPartitioned &&
1854 // !IsContainerPartition(PartEntry->PartitionType) &&
1855 PartEntry->BootIndicator)
1856 {
1857 /* Yes it is */
1858 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
1859 return TRUE;
1860 }
1861
1862 return FALSE;
1863}

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

◆ IsSuperFloppy()

BOOLEAN IsSuperFloppy ( IN PDISKENTRY  DiskEntry)

Definition at line 501 of file partlist.c.

503{
505 ULONGLONG PartitionLengthEstimate;
506
507 /* No layout buffer: we cannot say anything yet */
508 if (DiskEntry->LayoutBuffer == NULL)
509 return FALSE;
510
511 /* We must have only one partition */
512 if (DiskEntry->LayoutBuffer->PartitionCount != 1)
513 return FALSE;
514
515 /* Get the single partition entry */
516 PartitionInfo = DiskEntry->LayoutBuffer->PartitionEntry;
517
518 /* The single partition must start at the beginning of the disk */
519 if (!(PartitionInfo->StartingOffset.QuadPart == 0 &&
520 PartitionInfo->HiddenSectors == 0))
521 {
522 return FALSE;
523 }
524
525 /* The disk signature is usually set to one; warn in case it's not */
526 if (DiskEntry->LayoutBuffer->Signature != 1)
527 {
528 DPRINT1("Super-Floppy disk %lu signature %08x != 1!\n",
529 DiskEntry->DiskNumber, DiskEntry->LayoutBuffer->Signature);
530 }
531
532 /*
533 * The partition number must be zero or one, be recognized,
534 * have FAT16 type and report as non-bootable.
535 */
536 if ((PartitionInfo->PartitionNumber != 0 &&
537 PartitionInfo->PartitionNumber != 1) ||
538 PartitionInfo->RecognizedPartition != TRUE ||
539 PartitionInfo->PartitionType != PARTITION_FAT_16 ||
540 PartitionInfo->BootIndicator != FALSE)
541 {
542 DPRINT1("Super-Floppy disk %lu does not return default settings!\n"
543 " PartitionNumber = %lu, expected 0\n"
544 " RecognizedPartition = %s, expected TRUE\n"
545 " PartitionType = 0x%02x, expected 0x04 (PARTITION_FAT_16)\n"
546 " BootIndicator = %s, expected FALSE\n",
547 DiskEntry->DiskNumber,
548 PartitionInfo->PartitionNumber,
549 PartitionInfo->RecognizedPartition ? "TRUE" : "FALSE",
550 PartitionInfo->PartitionType,
551 PartitionInfo->BootIndicator ? "TRUE" : "FALSE");
552 }
553
554 /* The partition lengths should agree */
555 PartitionLengthEstimate = GetDiskSizeInBytes(DiskEntry);
556 if (PartitionInfo->PartitionLength.QuadPart != PartitionLengthEstimate)
557 {
558 DPRINT1("PartitionLength = %I64u is different from PartitionLengthEstimate = %I64u\n",
559 PartitionInfo->PartitionLength.QuadPart, PartitionLengthEstimate);
560 }
561
562 return TRUE;
563}
#define PARTITION_FAT_16
Definition: disk.h:90
#define GetDiskSizeInBytes(DiskEntry)
Definition: partlist.h:233

Referenced by AddDiskToList(), BootLoaderHardDiskPage(), ExtendedPartitionCreationChecks(), PartitionCreationChecks(), and xHalIoWritePartitionTable().

◆ PartitionCreationChecks()

ERROR_NUMBER PartitionCreationChecks ( _In_ PPARTENTRY  PartEntry)

Definition at line 2761 of file partlist.c.

2763{
2764 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2765
2766 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
2767 {
2768 DPRINT1("GPT-partitioned disk detected, not currently supported by SETUP!\n");
2769 return ERROR_WARN_PARTITION;
2770 }
2771
2772 /* Fail if the partition is already in use */
2773 if (PartEntry->IsPartitioned)
2774 return ERROR_NEW_PARTITION;
2775
2776 /*
2777 * For primary partitions
2778 */
2779 if (!PartEntry->LogicalPartition)
2780 {
2781 /* Only one primary partition is allowed on super-floppy */
2782 if (IsSuperFloppy(DiskEntry))
2784
2785 /* Fail if there are already 4 primary partitions in the list */
2786 if (GetPrimaryPartitionCount(DiskEntry) >= 4)
2788 }
2789 /*
2790 * For logical partitions
2791 */
2792 else
2793 {
2794 // TODO: Check that we are inside an extended partition!!
2795 // Then the following check will be useless.
2796
2797 /* Only one (primary) partition is allowed on super-floppy */
2798 if (IsSuperFloppy(DiskEntry))
2800 }
2801
2802 return ERROR_SUCCESS;
2803}

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

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

◆ SelectPartition()

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

Definition at line 2204 of file partlist.c.

2208{
2209 PDISKENTRY DiskEntry;
2210 PPARTENTRY PartEntry;
2211
2212 /* Find the disk */
2213 DiskEntry = GetDiskByNumber(List, DiskNumber);
2214 if (!DiskEntry)
2215 return NULL;
2216 ASSERT(DiskEntry->DiskNumber == DiskNumber);
2217
2218 /* Find the partition */
2219 PartEntry = GetPartition(DiskEntry, PartitionNumber);
2220 if (!PartEntry)
2221 return NULL;
2222 ASSERT(PartEntry->DiskEntry == DiskEntry);
2223 ASSERT(PartEntry->PartitionNumber == PartitionNumber);
2224
2225 return PartEntry;
2226}
PPARTENTRY GetPartition(_In_ PDISKENTRY DiskEntry, _In_ ULONG PartitionNumber)
Definition: partlist.c:2163
PDISKENTRY GetDiskByNumber(_In_ PPARTLIST List, _In_ ULONG DiskNumber)
Definition: partlist.c:2087

Referenced by EnumerateInstallations(), and SelectPartitionPage().

◆ SetActivePartition()

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

Definition at line 3515 of file partlist.c.

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

Referenced by InitSystemPartition().

◆ SetMBRPartitionType()

VOID SetMBRPartitionType ( IN PPARTENTRY  PartEntry,
IN UCHAR  PartitionType 
)

Definition at line 3897 of file partlist.c.

3900{
3901 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
3902
3903 ASSERT(DiskEntry->DiskStyle == PARTITION_STYLE_MBR);
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}
@ PARTITION_STYLE_MBR
Definition: imports.h:201
BOOLEAN Dirty
Definition: partlist.h:115
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:421
BOOLEAN RecognizedPartition
Definition: ntdddisk.h:414
BOOLEAN RewritePartition
Definition: ntdddisk.h:415

Referenced by FormatPartition().

◆ SetMountedDeviceValue()

BOOLEAN SetMountedDeviceValue ( IN WCHAR  Letter,
IN ULONG  Signature,
IN LARGE_INTEGER  StartingOffset 
)

Definition at line 3760 of file partlist.c.

3764{
3767 UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"SYSTEM\\MountedDevices");
3769 WCHAR ValueNameBuffer[16];
3771 REG_DISK_MOUNT_INFO MountInfo;
3772
3773 RtlStringCchPrintfW(ValueNameBuffer, ARRAYSIZE(ValueNameBuffer),
3774 L"\\DosDevices\\%c:", Letter);
3775 RtlInitUnicodeString(&ValueName, ValueNameBuffer);
3776
3778 &KeyName,
3781 NULL);
3782
3786 if (!NT_SUCCESS(Status))
3787 {
3791 0,
3792 NULL,
3794 NULL);
3795 }
3796 if (!NT_SUCCESS(Status))
3797 {
3798 DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
3799 return FALSE;
3800 }
3801
3802 MountInfo.Signature = Signature;
3803 MountInfo.StartingOffset = StartingOffset;
3805 &ValueName,
3806 0,
3807 REG_BINARY,
3808 (PVOID)&MountInfo,
3809 sizeof(MountInfo));
3811 if (!NT_SUCCESS(Status))
3812 {
3813 DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
3814 return FALSE;
3815 }
3816
3817 return TRUE;
3818}
WCHAR Letter
HANDLE GetRootKeyByPredefKey(IN HANDLE KeyHandle, OUT PCWSTR *RootKeyMountPoint OPTIONAL)
Definition: registry.c:90
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:291
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
#define REG_BINARY
Definition: nt_native.h:1496
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
NTSTATUS NTAPI NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: ntapi.c:240
LARGE_INTEGER StartingOffset
Definition: partlist.c:26
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by SetMountedDeviceValues().

◆ SetMountedDeviceValues()

BOOLEAN SetMountedDeviceValues ( IN PPARTLIST  List)

Definition at line 3821 of file partlist.c.

3823{
3824 PLIST_ENTRY Entry1, Entry2;
3825 PDISKENTRY DiskEntry;
3826 PPARTENTRY PartEntry;
3828
3829 if (List == NULL)
3830 return FALSE;
3831
3832 for (Entry1 = List->DiskListHead.Flink;
3833 Entry1 != &List->DiskListHead;
3834 Entry1 = Entry1->Flink)
3835 {
3836 DiskEntry = CONTAINING_RECORD(Entry1,
3837 DISKENTRY,
3838 ListEntry);
3839
3840 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3841 {
3842 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3843 continue;
3844 }
3845
3846 for (Entry2 = DiskEntry->PrimaryPartListHead.Flink;
3847 Entry2 != &DiskEntry->PrimaryPartListHead;
3848 Entry2 = Entry2->Flink)
3849 {
3850 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
3851 if (PartEntry->IsPartitioned) // && !IsContainerPartition(PartEntry->PartitionType)
3852 {
3854
3855 /* Assign a "\DosDevices\#:" mount point to this partition */
3856 if (PartEntry->DriveLetter)
3857 {
3858 StartingOffset.QuadPart = GetPartEntryOffsetInBytes(PartEntry);
3859 if (!SetMountedDeviceValue(PartEntry->DriveLetter,
3860 DiskEntry->LayoutBuffer->Signature,
3862 {
3863 return FALSE;
3864 }
3865 }
3866 }
3867 }
3868
3869 for (Entry2 = DiskEntry->LogicalPartListHead.Flink;
3870 Entry2 != &DiskEntry->LogicalPartListHead;
3871 Entry2 = Entry2->Flink)
3872 {
3873 PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry);
3874 if (PartEntry->IsPartitioned) // && !IsContainerPartition(PartEntry->PartitionType)
3875 {
3877
3878 /* Assign a "\DosDevices\#:" mount point to this partition */
3879 if (PartEntry->DriveLetter)
3880 {
3881 StartingOffset.QuadPart = GetPartEntryOffsetInBytes(PartEntry);
3882 if (!SetMountedDeviceValue(PartEntry->DriveLetter,
3883 DiskEntry->LayoutBuffer->Signature,
3885 {
3886 return FALSE;
3887 }
3888 }
3889 }
3890 }
3891 }
3892
3893 return TRUE;
3894}
#define GetPartEntryOffsetInBytes(PartEntry)
Definition: partlist.h:227
BOOLEAN SetMountedDeviceValue(IN WCHAR Letter, IN ULONG Signature, IN LARGE_INTEGER StartingOffset)
Definition: partlist.c:3760

Referenced by UpdateRegistry().

◆ WritePartitions()

NTSTATUS WritePartitions ( IN PDISKENTRY  DiskEntry)

Definition at line 3579 of file partlist.c.

3581{
3589 ULONG PartitionCount;
3590 PLIST_ENTRY ListEntry;
3591 PPARTENTRY PartEntry;
3593
3594 DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
3595
3596 /* If the disk is not dirty, there is nothing to do */
3597 if (!DiskEntry->Dirty)
3598 return STATUS_SUCCESS;
3599
3601 L"\\Device\\Harddisk%lu\\Partition0",
3602 DiskEntry->DiskNumber);
3604
3606 &Name,
3608 NULL,
3609 NULL);
3610
3614 &Iosb,
3615 0,
3617 if (!NT_SUCCESS(Status))
3618 {
3619 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
3620 return Status;
3621 }
3622
3623#ifdef DUMP_PARTITION_TABLE
3624 DumpPartitionTable(DiskEntry);
3625#endif
3626
3627 //
3628 // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
3629 // the disk in MBR or GPT format in case the disk was not initialized!!
3630 // For this we must ask the user which format to use.
3631 //
3632
3633 /* Save the original partition count to be restored later (see comment below) */
3634 PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
3635
3636 /* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
3638 ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION));
3640 NULL,
3641 NULL,
3642 NULL,
3643 &Iosb,
3645 DiskEntry->LayoutBuffer,
3646 BufferSize,
3647 DiskEntry->LayoutBuffer,
3648 BufferSize);
3650
3651 /*
3652 * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
3653 * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
3654 * where such a table is expected to enumerate up to 4 partitions:
3655 * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
3656 * Due to this we need to restore the original PartitionCount number.
3657 */
3658 DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
3659
3660 /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
3661 if (!NT_SUCCESS(Status))
3662 {
3663 DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
3664 return Status;
3665 }
3666
3667#ifdef DUMP_PARTITION_TABLE
3668 DumpPartitionTable(DiskEntry);
3669#endif
3670
3671 /* Update the partition numbers */
3672
3673 /* Update the primary partition table */
3674 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
3675 ListEntry != &DiskEntry->PrimaryPartListHead;
3676 ListEntry = ListEntry->Flink)
3677 {
3678 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3679
3680 if (PartEntry->IsPartitioned)
3681 {
3683 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
3684 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
3685 }
3686 }
3687
3688 /* Update the logical partition table */
3689 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
3690 ListEntry != &DiskEntry->LogicalPartListHead;
3691 ListEntry = ListEntry->Flink)
3692 {
3693 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
3694
3695 if (PartEntry->IsPartitioned)
3696 {
3698 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
3699 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
3700 }
3701 }
3702
3703 //
3704 // NOTE: Originally (see r40437), we used to install here also a new MBR
3705 // for this disk (by calling InstallMbrBootCodeToDisk), only if:
3706 // DiskEntry->NewDisk == TRUE and DiskEntry->HwDiskNumber == 0.
3707 // Then after that, both DiskEntry->NewDisk and DiskEntry->NoMbr were set
3708 // to FALSE. In the other place (in usetup.c) where InstallMbrBootCodeToDisk
3709 // was called too, the installation test was modified by checking whether
3710 // DiskEntry->NoMbr was TRUE (instead of NewDisk).
3711 //
3712
3713 // HACK: Parts of FIXMEs described above: (Re)set the PartitionStyle to MBR.
3714 DiskEntry->DiskStyle = PARTITION_STYLE_MBR;
3715
3716 /* The layout has been successfully updated, the disk is not dirty anymore */
3717 DiskEntry->Dirty = FALSE;
3718
3719 return Status;
3720}
#define BufferSize
Definition: mmc.h:75
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 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
ULONG PartitionIndex
Definition: partlist.h:56
_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 3723 of file partlist.c.

3725{
3728 PDISKENTRY DiskEntry;
3729
3730 if (List == NULL)
3731 return TRUE;
3732
3733 for (Entry = List->DiskListHead.Flink;
3734 Entry != &List->DiskListHead;
3735 Entry = Entry->Flink)
3736 {
3737 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
3738
3739 if (DiskEntry->DiskStyle == PARTITION_STYLE_GPT)
3740 {
3741 DPRINT("GPT-partitioned disk detected, not currently supported by SETUP!\n");
3742 continue;
3743 }
3744
3745 if (DiskEntry->Dirty != FALSE)
3746 {
3747 Status = WritePartitions(DiskEntry);
3748 if (!NT_SUCCESS(Status))
3749 {
3750 DPRINT1("WritePartitionsToDisk() failed to update disk %lu, Status 0x%08lx\n",
3751 DiskEntry->DiskNumber, Status);
3752 }
3753 }
3754 }
3755
3756 return TRUE;
3757}
NTSTATUS WritePartitions(IN PDISKENTRY DiskEntry)
Definition: partlist.c:3579

Referenced by FsVolCommitOpsQueue().