ReactOS 0.4.16-dev-1983-g1a17364
partlist.c File Reference
#include "diskpart.h"
#include <ntddscsi.h>
#include <debug.h>
#include <pshpack1.h>
#include <poppack.h>
Include dependency graph for partlist.c:

Go to the source code of this file.

Classes

struct  _PARTITION
 
struct  _PARTITION_SECTOR
 

Macros

#define NDEBUG
 
#define InsertAscendingList(ListHead, NewEntry, Type, ListEntryField, SortField)
 
#define PARTITION_LINUX   0x83
 
#define PARTITION_TBL_SIZE   4
 
#define MBR_MAGIC   0xAA55
 
#define ROOT_NAME   L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
 

Typedefs

typedef struct _PARTITION PARTITION
 
typedef struct _PARTITIONPPARTITION
 
typedef struct _PARTITION_SECTOR PARTITION_SECTOR
 
typedef struct _PARTITION_SECTORPPARTITION_SECTOR
 

Functions

ULONGLONG AlignDown (_In_ ULONGLONG Value, _In_ ULONG Alignment)
 
static VOID GetDriverName (PDISKENTRY DiskEntry)
 
static NTSTATUS NTAPI DiskIdentifierQueryRoutine (PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
 
static NTSTATUS NTAPI DiskConfigurationDataQueryRoutine (PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
 
static NTSTATUS NTAPI SystemConfigurationDataQueryRoutine (PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
 
static VOID EnumerateBiosDiskEntries (VOID)
 
static VOID AddPartitionToDisk (ULONG DiskNumber, PDISKENTRY DiskEntry, ULONG PartitionIndex, BOOLEAN LogicalPartition)
 
static VOID ScanForUnpartitionedDiskSpace (PDISKENTRY DiskEntry)
 
VOID ReadLayoutBuffer (_In_ HANDLE FileHandle, _In_ PDISKENTRY DiskEntry)
 
static VOID AddDiskToList (HANDLE FileHandle, ULONG DiskNumber)
 
NTSTATUS CreatePartitionList (VOID)
 
VOID DestroyPartitionList (VOID)
 
static VOID GetVolumeExtents (_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
 
static VOID GetVolumeType (_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
 
static VOID AddVolumeToList (ULONG ulVolumeNumber, PWSTR pszVolumeName)
 
NTSTATUS CreateVolumeList (VOID)
 
VOID DestroyVolumeList (VOID)
 
NTSTATUS WritePartitions (_In_ PDISKENTRY DiskEntry)
 
static BOOLEAN IsEmptyLayoutEntry (IN PPARTITION_INFORMATION_EX PartitionInfo)
 
static BOOLEAN IsSamePrimaryLayoutEntry (IN PPARTITION_INFORMATION_EX PartitionInfo, IN PDISKENTRY DiskEntry, IN PPARTENTRY PartEntry)
 
ULONG GetPrimaryPartitionCount (_In_ PDISKENTRY DiskEntry)
 
static ULONG GetLogicalPartitionCount (_In_ PDISKENTRY DiskEntry)
 
static BOOLEAN ReAllocateLayoutBuffer (_In_ PDISKENTRY DiskEntry)
 
VOID UpdateDiskLayout (_In_ PDISKENTRY DiskEntry)
 
PPARTENTRY GetPrevUnpartitionedEntry (_In_ PPARTENTRY PartEntry)
 
PPARTENTRY GetNextUnpartitionedEntry (_In_ PPARTENTRY PartEntry)
 
NTSTATUS DismountVolume (_In_ PPARTENTRY PartEntry)
 
PVOLENTRY GetVolumeFromPartition (_In_ PPARTENTRY PartEntry)
 
VOID RemoveVolume (_In_ PVOLENTRY VolumeEntry)
 

Variables

LIST_ENTRY DiskListHead
 
LIST_ENTRY BiosDiskListHead
 
LIST_ENTRY VolumeListHead
 
PDISKENTRY CurrentDisk = NULL
 
PPARTENTRY CurrentPartition = NULL
 
PVOLENTRY CurrentVolume = NULL
 

Macro Definition Documentation

◆ InsertAscendingList

#define InsertAscendingList (   ListHead,
  NewEntry,
  Type,
  ListEntryField,
  SortField 
)
Value:
{\
\
current = (ListHead)->Flink;\
while (current != (ListHead))\
{\
if (CONTAINING_RECORD(current, Type, ListEntryField)->SortField >=\
(NewEntry)->SortField)\
{\
break;\
}\
current = current->Flink;\
}\
\
InsertTailList(current, &((NewEntry)->ListEntryField));\
}
Type
Definition: Type.h:7
struct task_struct * current
Definition: linux.c:32
Definition: typedefs.h:120
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Definition at line 17 of file partlist.c.

◆ MBR_MAGIC

#define MBR_MAGIC   0xAA55

Definition at line 40 of file partlist.c.

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file partlist.c.

◆ PARTITION_LINUX

#define PARTITION_LINUX   0x83

Definition at line 36 of file partlist.c.

◆ PARTITION_TBL_SIZE

#define PARTITION_TBL_SIZE   4

Definition at line 38 of file partlist.c.

◆ ROOT_NAME

#define ROOT_NAME   L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"

Definition at line 303 of file partlist.c.

Typedef Documentation

◆ PARTITION

◆ PARTITION_SECTOR

◆ PPARTITION

◆ PPARTITION_SECTOR

Function Documentation

◆ AddDiskToList()

static VOID AddDiskToList ( HANDLE  FileHandle,
ULONG  DiskNumber 
)
static

Definition at line 877 of file partlist.c.

880{
881 DISK_GEOMETRY DiskGeometry;
882 SCSI_ADDRESS ScsiAddress;
883 PDISKENTRY DiskEntry;
889 WCHAR Identifier[20];
890 ULONG Checksum;
892 ULONG i;
893 PLIST_ENTRY ListEntry;
894 PBIOSDISKENTRY BiosDiskEntry;
895
897 NULL,
898 NULL,
899 NULL,
900 &Iosb,
902 NULL,
903 0,
904 &DiskGeometry,
905 sizeof(DISK_GEOMETRY));
906 if (!NT_SUCCESS(Status))
907 {
908 return;
909 }
910
911 if (DiskGeometry.MediaType != FixedMedia &&
912 DiskGeometry.MediaType != RemovableMedia)
913 {
914 return;
915 }
916
918 NULL,
919 NULL,
920 NULL,
921 &Iosb,
923 NULL,
924 0,
925 &ScsiAddress,
926 sizeof(SCSI_ADDRESS));
927 if (!NT_SUCCESS(Status))
928 {
929 return;
930 }
931
932 Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(RtlGetProcessHeap(),
933 0,
934 DiskGeometry.BytesPerSector);
935 if (Mbr == NULL)
936 {
937 return;
938 }
939
940 FileOffset.QuadPart = 0;
942 NULL,
943 NULL,
944 NULL,
945 &Iosb,
946 (PVOID)Mbr,
947 DiskGeometry.BytesPerSector,
948 &FileOffset,
949 NULL);
950 if (!NT_SUCCESS(Status))
951 {
952 RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
953 DPRINT1("NtReadFile failed, status=%x\n", Status);
954 return;
955 }
956 Signature = Mbr->Signature;
957
958 /* Calculate the MBR checksum */
959 Checksum = 0;
960 Buffer = (PULONG)Mbr;
961 for (i = 0; i < 128; i++)
962 {
963 Checksum += Buffer[i];
964 }
965 Checksum = ~Checksum + 1;
966
968 L"%08x-%08x-A", Checksum, Signature);
969 DPRINT("Identifier: %S\n", Identifier);
970
971 DiskEntry = RtlAllocateHeap(RtlGetProcessHeap(),
973 sizeof(DISKENTRY));
974 if (DiskEntry == NULL)
975 {
976 return;
977 }
978
979// DiskEntry->Checksum = Checksum;
980// DiskEntry->Signature = Signature;
981 DiskEntry->BiosFound = FALSE;
982
983 /* Check the disk partition style */
984 if (Mbr->Magic != MBR_MAGIC)
985 {
986 DPRINT("Partition style: RAW\n");
987 DiskEntry->PartitionStyle = PARTITION_STYLE_RAW;
988 }
989 else
990 {
992 {
993 DPRINT("Partition style: GPT\n");
995 }
996 else
997 {
998 DPRINT("Partition style: MBR\n");
1000 }
1001 }
1002
1003 /* Free Mbr sector buffer */
1004 RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
1005
1006 ListEntry = BiosDiskListHead.Flink;
1007 while (ListEntry != &BiosDiskListHead)
1008 {
1009 BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
1010 /* FIXME:
1011 * Compare the size from bios and the reported size from driver.
1012 * If we have more than one disk with a zero or with the same signatur
1013 * we must create new signatures and reboot. After the reboot,
1014 * it is possible to identify the disks.
1015 */
1016 if (BiosDiskEntry->Signature == Signature &&
1017 BiosDiskEntry->Checksum == Checksum &&
1018 !BiosDiskEntry->Recognized)
1019 {
1020 if (!DiskEntry->BiosFound)
1021 {
1022 DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
1023 DiskEntry->BiosFound = TRUE;
1024 BiosDiskEntry->Recognized = TRUE;
1025 }
1026 else
1027 {
1028 }
1029 }
1030 ListEntry = ListEntry->Flink;
1031 }
1032
1033 if (!DiskEntry->BiosFound)
1034 {
1035#if 0
1036 RtlFreeHeap(ProcessHeap, 0, DiskEntry);
1037 return;
1038#else
1039 DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber);
1040#endif
1041 }
1042
1045
1046 DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
1047 DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
1048 DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
1049 DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
1050
1051 DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
1052 DPRINT("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder);
1053 DPRINT("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack);
1054 DPRINT("BytesPerSector %I64u\n", DiskEntry->BytesPerSector);
1055
1056 DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
1057 (ULONGLONG)DiskGeometry.TracksPerCylinder *
1058 (ULONGLONG)DiskGeometry.SectorsPerTrack;
1059
1060// DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
1061// DiskEntry->CylinderAlignment = DiskGeometry.SectorsPerTrack * DiskGeometry.TracksPerCylinder;
1062 DiskEntry->SectorAlignment = (1024 * 1024) / DiskGeometry.BytesPerSector;
1063 DiskEntry->CylinderAlignment = (1024 * 1024) / DiskGeometry.BytesPerSector;
1064
1065 DPRINT1("SectorCount: %I64u\n", DiskEntry->SectorCount);
1066 DPRINT1("SectorAlignment: %lu\n", DiskEntry->SectorAlignment);
1067 DPRINT1("CylinderAlignment: %lu\n", DiskEntry->CylinderAlignment);
1068
1069 DiskEntry->DiskNumber = DiskNumber;
1070 DiskEntry->Port = ScsiAddress.PortNumber;
1071 DiskEntry->PathId = ScsiAddress.PathId;
1072 DiskEntry->TargetId = ScsiAddress.TargetId;
1073 DiskEntry->Lun = ScsiAddress.Lun;
1074
1075 GetDriverName(DiskEntry);
1076
1077 InsertAscendingList(&DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
1078
1079 ReadLayoutBuffer(FileHandle, DiskEntry);
1080
1081 DPRINT1("PartitionCount: %lu\n", DiskEntry->LayoutBuffer->PartitionCount);
1082
1083#ifdef DUMP_PARTITION_TABLE
1084 DumpPartitionTable(DiskEntry);
1085#endif
1086
1087 if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0 &&
1089 DiskEntry->LayoutBuffer->PartitionEntry[0].Mbr.PartitionType != 0)
1090 {
1091 if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
1092 {
1093 DPRINT("Use %lu Sector alignment!\n", DiskEntry->SectorsPerTrack);
1094 }
1095 else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart % (1024 * 1024) == 0)
1096 {
1097 DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1098 }
1099 else
1100 {
1101 DPRINT1("No matching alignment found! Partition 1 starts at %I64u\n", DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
1102 }
1103 }
1104 else
1105 {
1106 DPRINT1("No valid partition table found! Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
1107 }
1108
1109
1110 if (DiskEntry->LayoutBuffer->PartitionCount == 0)
1111 {
1112 DiskEntry->NewDisk = TRUE;
1113 DiskEntry->LayoutBuffer->PartitionCount = 4;
1114
1115 for (i = 0; i < 4; i++)
1117 }
1118 else
1119 {
1120 for (i = 0; i < 4; i++)
1121 {
1122 AddPartitionToDisk(DiskNumber, DiskEntry, i, FALSE);
1123 }
1124
1125 for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
1126 {
1127 AddPartitionToDisk(DiskNumber, DiskEntry, i, TRUE);
1128 }
1129 }
1130
1132}
@ Identifier
Definition: asmpp.cpp:95
LONG NTSTATUS
Definition: precomp.h:26
HANDLE ProcessHeap
Definition: servman.c:15
#define DPRINT1
Definition: precomp.h:8
#define PARTITION_GPT
Definition: disk.h:90
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const WCHAR Signature[]
Definition: parser.c:141
#define L(x)
Definition: resources.c:13
return Iosb
Definition: create.c:4403
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
@ PARTITION_STYLE_GPT
Definition: imports.h:202
@ PARTITION_STYLE_MBR
Definition: imports.h:201
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)
@ RemovableMedia
Definition: ntdddisk.h:382
@ FixedMedia
Definition: ntdddisk.h:383
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
static VOID AddPartitionToDisk(IN ULONG DiskNumber, IN PDISKENTRY DiskEntry, IN ULONG PartitionIndex, IN BOOLEAN LogicalPartition)
Definition: partlist.c:985
static VOID GetDriverName(IN PDISKENTRY DiskEntry)
Definition: partlist.c:105
static VOID ScanForUnpartitionedDiskSpace(IN PDISKENTRY DiskEntry)
Definition: partlist.c:1095
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
#define DPRINT
Definition: sndvol32.h:73
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
BOOLEAN Recognized
Definition: diskpart.h:145
ULONG DiskNumber
Definition: partlist.h:162
ULONG Checksum
Definition: partlist.h:164
ULONG Signature
Definition: partlist.h:163
ULONG SectorAlignment
Definition: partlist.h:116
ULONG BiosDiskNumber
Definition: diskpart.h:165
ULARGE_INTEGER SectorCount
Definition: partlist.h:115
ULONG SectorsPerTrack
Definition: partlist.h:112
USHORT TargetId
Definition: diskpart.h:172
LIST_ENTRY LogicalPartListHead
Definition: partlist.h:150
BOOLEAN NewDisk
Definition: partlist.h:138
ULONG DiskNumber
Definition: partlist.h:129
ULONG BytesPerSector
Definition: partlist.h:113
USHORT PathId
Definition: diskpart.h:171
BOOLEAN BiosFound
Definition: partlist.h:120
ULONGLONG Cylinders
Definition: partlist.h:110
USHORT Lun
Definition: diskpart.h:173
USHORT Port
Definition: partlist.h:131
DWORD PartitionStyle
Definition: diskpart.h:179
ULONG TracksPerCylinder
Definition: partlist.h:111
LIST_ENTRY PrimaryPartListHead
Definition: partlist.h:149
ULONG CylinderAlignment
Definition: partlist.h:117
PDRIVE_LAYOUT_INFORMATION LayoutBuffer
Definition: partlist.h:143
MEDIA_TYPE MediaType
Definition: ntdddisk.h:401
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:400
ULONG TracksPerCylinder
Definition: ntdddisk.h:402
ULONG SectorsPerTrack
Definition: ntdddisk.h:403
ULONG BytesPerSector
Definition: ntdddisk.h:404
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:421
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:408
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:409
BOOLEAN RewritePartition
Definition: ntdddisk.h:415
PARTITION Partition[PARTITION_TBL_SIZE]
Definition: partlist.h:219
unsigned char PartitionType
Definition: partlist.h:206
UCHAR PathId
Definition: scsi_port.h:149
UCHAR TargetId
Definition: scsi_port.h:150
UCHAR PortNumber
Definition: scsi_port.h:148
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
LIST_ENTRY BiosDiskListHead
Definition: partlist.c:73
VOID ReadLayoutBuffer(_In_ HANDLE FileHandle, _In_ PDISKENTRY DiskEntry)
Definition: partlist.c:816
LIST_ENTRY DiskListHead
Definition: partlist.c:72
#define MBR_MAGIC
Definition: partlist.c:40
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
LONGLONG QuadPart
Definition: typedefs.h:114
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ AddPartitionToDisk()

static VOID AddPartitionToDisk ( ULONG  DiskNumber,
PDISKENTRY  DiskEntry,
ULONG  PartitionIndex,
BOOLEAN  LogicalPartition 
)
static

Definition at line 452 of file partlist.c.

457{
459 PPARTENTRY PartEntry;
460
461 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
462 if (PartitionInfo->Mbr.PartitionType == 0 ||
463 (LogicalPartition == TRUE && IsContainerPartition(PartitionInfo->Mbr.PartitionType)))
464 return;
465
466 PartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
468 sizeof(PARTENTRY));
469 if (PartEntry == NULL)
470 {
471 return;
472 }
473
474 PartEntry->DiskEntry = DiskEntry;
475
476 PartEntry->StartSector.QuadPart = (ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
477 PartEntry->SectorCount.QuadPart = (ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
478
479 PartEntry->BootIndicator = PartitionInfo->Mbr.BootIndicator;
480 PartEntry->PartitionType = PartitionInfo->Mbr.PartitionType;
481
483 PartEntry->IsPartitioned = TRUE;
484 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
485 PartEntry->PartitionIndex = PartitionIndex;
486
487 if (IsContainerPartition(PartEntry->PartitionType))
488 {
489 PartEntry->FormatState = Unformatted;
490
491 if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition == NULL)
492 DiskEntry->ExtendedPartition = PartEntry;
493 }
494 else if ((PartEntry->PartitionType == PARTITION_FAT_12) ||
495 (PartEntry->PartitionType == PARTITION_FAT_16) ||
496 (PartEntry->PartitionType == PARTITION_HUGE) ||
497 (PartEntry->PartitionType == PARTITION_XINT13) ||
498 (PartEntry->PartitionType == PARTITION_FAT32) ||
500 {
501#if 0
502 if (CheckFatFormat())
503 {
504 PartEntry->FormatState = Preformatted;
505 }
506 else
507 {
508 PartEntry->FormatState = Unformatted;
509 }
510#endif
511 PartEntry->FormatState = Preformatted;
512 }
513 else if (PartEntry->PartitionType == PARTITION_LINUX)
514 {
515#if 0
516 if (CheckExt2Format())
517 {
518 PartEntry->FormatState = Preformatted;
519 }
520 else
521 {
522 PartEntry->FormatState = Unformatted;
523 }
524#endif
525 PartEntry->FormatState = Preformatted;
526 }
527 else if (PartEntry->PartitionType == PARTITION_IFS)
528 {
529#if 0
530 if (CheckNtfsFormat())
531 {
532 PartEntry->FormatState = Preformatted;
533 }
534 else if (CheckHpfsFormat())
535 {
536 PartEntry->FormatState = Preformatted;
537 }
538 else
539 {
540 PartEntry->FormatState = Unformatted;
541 }
542#endif
543 PartEntry->FormatState = Preformatted;
544 }
545 else
546 {
547 PartEntry->FormatState = UnknownFormat;
548 }
549
552 &PartEntry->ListEntry);
553 else
555 &PartEntry->ListEntry);
556}
#define PARTITION_IFS
Definition: disk.h:78
#define PARTITION_XINT13
Definition: disk.h:82
#define PARTITION_FAT32
Definition: disk.h:80
#define PARTITION_FAT_12
Definition: disk.h:72
#define PARTITION_HUGE
Definition: disk.h:77
#define PARTITION_FAT_16
Definition: disk.h:75
#define PARTITION_FAT32_XINT13
Definition: disk.h:81
@ Preformatted
Definition: diskpart.h:89
@ LogicalPartition
Definition: disksup.c:48
#define InsertTailList(ListHead, Entry)
@ UnknownFormat
Definition: partlist.h:36
@ Unformatted
Definition: partlist.h:34
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:321
PPARTENTRY ExtendedPartition
Definition: partlist.h:153
BOOLEAN IsPartitioned
Definition: partlist.h:82
UCHAR PartitionType
Definition: partlist.h:73
ULARGE_INTEGER SectorCount
Definition: partlist.h:70
BOOLEAN BootIndicator
Definition: partlist.h:72
struct _DISKENTRY * DiskEntry
Definition: partlist.h:66
BOOLEAN LogicalPartition
Definition: partlist.h:79
FORMATSTATE FormatState
Definition: diskpart.h:119
LIST_ENTRY ListEntry
Definition: partlist.h:63
ULONG PartitionNumber
Definition: partlist.h:75
ULARGE_INTEGER StartSector
Definition: partlist.h:69
ULONG PartitionIndex
Definition: partlist.h:76
#define PARTITION_LINUX
Definition: partlist.c:36
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105

◆ AddVolumeToList()

static VOID AddVolumeToList ( ULONG  ulVolumeNumber,
PWSTR  pszVolumeName 
)
static

Definition at line 1375 of file partlist.c.

1378{
1379 PVOLENTRY VolumeEntry;
1381
1382 DWORD dwError, dwLength;
1383 WCHAR szPathNames[MAX_PATH + 1];
1384 WCHAR szVolumeName[MAX_PATH + 1];
1385 WCHAR szFilesystem[MAX_PATH + 1];
1386
1387 DWORD CharCount = 0;
1388 size_t Index = 0;
1389
1394
1395 DPRINT("AddVolumeToList(%S)\n", pszVolumeName);
1396
1397 VolumeEntry = RtlAllocateHeap(RtlGetProcessHeap(),
1399 sizeof(VOLENTRY));
1400 if (VolumeEntry == NULL)
1401 return;
1402
1403 VolumeEntry->VolumeNumber = ulVolumeNumber;
1404 wcscpy(VolumeEntry->VolumeName, pszVolumeName);
1405
1406 Index = wcslen(pszVolumeName) - 1;
1407
1408 pszVolumeName[Index] = L'\0';
1409
1410 CharCount = QueryDosDeviceW(&pszVolumeName[4], VolumeEntry->DeviceName, ARRAYSIZE(VolumeEntry->DeviceName));
1411
1412 pszVolumeName[Index] = L'\\';
1413
1414 if (CharCount == 0)
1415 {
1416 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
1417 return;
1418 }
1419
1420 DPRINT("DeviceName: %S\n", VolumeEntry->DeviceName);
1421
1422 RtlInitUnicodeString(&Name, VolumeEntry->DeviceName);
1423
1425 &Name,
1426 0,
1427 NULL,
1428 NULL);
1429
1433 &Iosb,
1434 0,
1436 if (NT_SUCCESS(Status))
1437 {
1438 GetVolumeType(VolumeHandle, VolumeEntry);
1439 GetVolumeExtents(VolumeHandle, VolumeEntry);
1441 }
1442
1443 if (GetVolumeInformationW(pszVolumeName,
1444 szVolumeName,
1445 MAX_PATH + 1,
1446 NULL, // [out, optional] LPDWORD lpVolumeSerialNumber,
1447 NULL, // [out, optional] LPDWORD lpMaximumComponentLength,
1448 NULL, // [out, optional] LPDWORD lpFileSystemFlags,
1449 szFilesystem,
1450 MAX_PATH + 1))
1451 {
1452 VolumeEntry->pszLabel = RtlAllocateHeap(RtlGetProcessHeap(),
1453 0,
1454 (wcslen(szVolumeName) + 1) * sizeof(WCHAR));
1455 if (VolumeEntry->pszLabel)
1456 wcscpy(VolumeEntry->pszLabel, szVolumeName);
1457
1458 VolumeEntry->pszFilesystem = RtlAllocateHeap(RtlGetProcessHeap(),
1459 0,
1460 (wcslen(szFilesystem) + 1) * sizeof(WCHAR));
1461 if (VolumeEntry->pszFilesystem)
1462 wcscpy(VolumeEntry->pszFilesystem, szFilesystem);
1463 }
1464 else
1465 {
1466 dwError = GetLastError();
1467 if (dwError == ERROR_UNRECOGNIZED_VOLUME)
1468 {
1469 VolumeEntry->pszFilesystem = RtlAllocateHeap(RtlGetProcessHeap(),
1470 0,
1471 (3 + 1) * sizeof(WCHAR));
1472 if (VolumeEntry->pszFilesystem)
1473 wcscpy(VolumeEntry->pszFilesystem, L"RAW");
1474 }
1475 }
1476
1477 if (GetVolumePathNamesForVolumeNameW(pszVolumeName,
1478 szPathNames,
1479 ARRAYSIZE(szPathNames),
1480 &dwLength))
1481 {
1482 VolumeEntry->DriveLetter = szPathNames[0];
1483 }
1484
1486 &VolumeEntry->ListEntry);
1487}
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
wcscpy
LPWSTR Name
Definition: desk.c:124
#define MAX_PATH
Definition: compat.h:34
static DWORD DWORD * dwLength
Definition: fusion.c:86
DWORD WINAPI QueryDosDeviceW(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax)
Definition: dosdev.c:542
BOOL WINAPI GetVolumeInformationW(IN LPCWSTR lpRootPathName, IN LPWSTR lpVolumeNameBuffer, IN DWORD nVolumeNameSize, OUT LPDWORD lpVolumeSerialNumber OPTIONAL, OUT LPDWORD lpMaximumComponentLength OPTIONAL, OUT LPDWORD lpFileSystemFlags OPTIONAL, OUT LPWSTR lpFileSystemNameBuffer OPTIONAL, IN DWORD nFileSystemNameSize)
Definition: volume.c:226
BOOL WINAPI GetVolumePathNamesForVolumeNameW(IN LPCWSTR lpszVolumeName, IN LPWSTR lpszVolumePathNames, IN DWORD cchBufferLength, OUT PDWORD lpcchReturnLength)
Definition: volume.c:1227
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _Out_ PHANDLE VolumeHandle
Definition: fltkernel.h:2283
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3953
#define SYNCHRONIZE
Definition: nt_native.h:61
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
ULONG VolumeNumber
Definition: diskpart.h:196
PWSTR pszFilesystem
Definition: diskpart.h:203
WCHAR VolumeName[MAX_PATH]
Definition: diskpart.h:197
LIST_ENTRY ListEntry
Entry in VolumesList.
Definition: partlist.h:45
PWSTR pszLabel
Definition: diskpart.h:202
WCHAR DeviceName[MAX_PATH]
Definition: diskpart.h:198
WCHAR DriveLetter
Definition: diskpart.h:200
LIST_ENTRY VolumeListHead
Definition: partlist.c:74
static VOID GetVolumeType(_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
Definition: partlist.c:1335
static VOID GetVolumeExtents(_In_ HANDLE VolumeHandle, _In_ PVOLENTRY VolumeEntry)
Definition: partlist.c:1269
_In_ WDFCOLLECTION _In_ ULONG Index
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_UNRECOGNIZED_VOLUME
Definition: winerror.h:908

Referenced by CreateVolumeList().

◆ AlignDown()

ULONGLONG AlignDown ( _In_ ULONGLONG  Value,
_In_ ULONG  Alignment 
)

Definition at line 135 of file partlist.c.

138{
139 ULONGLONG Temp;
140
141 Temp = Value / Alignment;
142
143 return Temp * Alignment;
144}
union Alignment_ Alignment
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

◆ CreatePartitionList()

NTSTATUS CreatePartitionList ( VOID  )

Definition at line 1136 of file partlist.c.

1137{
1141 ULONG ReturnSize;
1143 ULONG DiskNumber;
1147
1148 CurrentDisk = NULL;
1150
1151// BootDisk = NULL;
1152// BootPartition = NULL;
1153
1154// TempDisk = NULL;
1155// TempPartition = NULL;
1156// FormatState = Start;
1157
1160
1162
1164 &Sdi,
1166 &ReturnSize);
1167 if (!NT_SUCCESS(Status))
1168 {
1169 return Status;
1170 }
1171
1172 for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
1173 {
1175 L"\\Device\\Harddisk%d\\Partition0",
1176 DiskNumber);
1177
1179 Buffer);
1180
1182 &Name,
1183 0,
1184 NULL,
1185 NULL);
1186
1190 &Iosb,
1193 if (NT_SUCCESS(Status))
1194 {
1195 AddDiskToList(FileHandle, DiskNumber);
1196
1198 }
1199 }
1200
1201// UpdateDiskSignatures(List);
1202
1203// AssignDriveLetters(List);
1204
1205 return STATUS_SUCCESS;
1206}
PDISKENTRY CurrentDisk
Definition: partlist.c:76
#define FILE_SHARE_READ
Definition: compat.h:136
@ SystemDeviceInformation
Definition: ntddk_ex.h:18
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
static VOID AddDiskToList(IN HANDLE FileHandle, IN ULONG DiskNumber, IN PPARTLIST List)
Definition: partlist.c:1445
static VOID EnumerateBiosDiskEntries(IN PPARTLIST PartList)
Definition: partlist.c:327
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
PPARTENTRY CurrentPartition
Definition: partlist.c:77

◆ CreateVolumeList()

NTSTATUS CreateVolumeList ( VOID  )

Definition at line 1491 of file partlist.c.

1492{
1493 HANDLE hVolume = INVALID_HANDLE_VALUE;
1494 WCHAR szVolumeName[MAX_PATH];
1495 ULONG ulVolumeNumber = 0;
1496 BOOL Success;
1497
1499
1501
1502 hVolume = FindFirstVolumeW(szVolumeName, ARRAYSIZE(szVolumeName));
1503 if (hVolume == INVALID_HANDLE_VALUE)
1504 {
1505
1506 return STATUS_UNSUCCESSFUL;
1507 }
1508
1509 AddVolumeToList(ulVolumeNumber++, szVolumeName);
1510
1511 for (;;)
1512 {
1513 Success = FindNextVolumeW(hVolume, szVolumeName, ARRAYSIZE(szVolumeName));
1514 if (!Success)
1515 {
1516 break;
1517 }
1518
1519 AddVolumeToList(ulVolumeNumber++, szVolumeName);
1520 }
1521
1522 FindVolumeClose(hVolume);
1523
1524 return STATUS_SUCCESS;
1525}
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
BOOL WINAPI FindNextVolumeW(IN HANDLE handle, IN LPWSTR volume, IN DWORD len)
Definition: volume.c:1082
HANDLE WINAPI FindFirstVolumeW(IN LPWSTR volume, IN DWORD len)
Definition: volume.c:660
BOOL WINAPI FindVolumeClose(IN HANDLE hFindVolume)
Definition: volume.c:741
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
static VOID AddVolumeToList(ULONG ulVolumeNumber, PWSTR pszVolumeName)
Definition: partlist.c:1375
PVOLENTRY CurrentVolume
Definition: partlist.c:78
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by rescan_main(), and wmain().

◆ DestroyPartitionList()

VOID DestroyPartitionList ( VOID  )

Definition at line 1210 of file partlist.c.

1211{
1212 PDISKENTRY DiskEntry;
1213 PBIOSDISKENTRY BiosDiskEntry;
1214 PPARTENTRY PartEntry;
1216
1217 CurrentDisk = NULL;
1219
1220 /* Release disk and partition info */
1221 while (!IsListEmpty(&DiskListHead))
1222 {
1224 DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
1225
1226 /* Release driver name */
1227 RtlFreeUnicodeString(&DiskEntry->DriverName);
1228
1229 /* Release primary partition list */
1230 while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
1231 {
1233 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1234
1235 RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
1236 }
1237
1238 /* Release logical partition list */
1239 while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
1240 {
1242 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1243
1244 RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
1245 }
1246
1247 /* Release layout buffer */
1248 if (DiskEntry->LayoutBuffer != NULL)
1249 RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry->LayoutBuffer);
1250
1251
1252 /* Release disk entry */
1253 RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry);
1254 }
1255
1256 /* Release the bios disk info */
1257 while (!IsListEmpty(&BiosDiskListHead))
1258 {
1260 BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
1261
1262 RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
1263 }
1264}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
base of all file and directory entries
Definition: entries.h:83
UNICODE_STRING DriverName
Definition: partlist.h:141

◆ DestroyVolumeList()

VOID DestroyVolumeList ( VOID  )

Definition at line 1529 of file partlist.c.

1530{
1532 PVOLENTRY VolumeEntry;
1533
1535
1536 /* Release disk and partition info */
1537 while (!IsListEmpty(&VolumeListHead))
1538 {
1540 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
1541
1542 if (VolumeEntry->pszLabel)
1543 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszLabel);
1544
1545 if (VolumeEntry->pszFilesystem)
1546 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszFilesystem);
1547
1548 if (VolumeEntry->pExtents)
1549 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pExtents);
1550
1551 /* Release disk entry */
1552 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
1553 }
1554}
PVOLUME_DISK_EXTENTS pExtents
Definition: diskpart.h:207

Referenced by rescan_main(), and wmain().

◆ DiskConfigurationDataQueryRoutine()

static NTSTATUS NTAPI DiskConfigurationDataQueryRoutine ( PWSTR  ValueName,
ULONG  ValueType,
PVOID  ValueData,
ULONG  ValueLength,
PVOID  Context,
PVOID  EntryContext 
)
static

Definition at line 213 of file partlist.c.

220{
221 PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
222 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
224 ULONG i;
225
228 return STATUS_UNSUCCESSFUL;
229
230 FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
231
232 /* Hm. Version and Revision are not set on Microsoft Windows XP... */
233#if 0
234 if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
235 FullResourceDescriptor->PartialResourceList.Revision != 1)
236 return STATUS_UNSUCCESSFUL;
237#endif
238
239 for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
240 {
243 continue;
244
245 DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1];
246 BiosDiskEntry->DiskGeometry = *DiskGeometry;
247
248 return STATUS_SUCCESS;
249 }
250
251 return STATUS_UNSUCCESSFUL;
252}
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
struct _BIOSDISKENTRY * PBIOSDISKENTRY
#define REG_FULL_RESOURCE_DESCRIPTOR
Definition: nt_native.h:1506
struct _CM_FULL_RESOURCE_DESCRIPTOR * PCM_FULL_RESOURCE_DESCRIPTOR
#define CmResourceTypeDeviceSpecific
Definition: restypes.h:108
CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry
Definition: partlist.h:166
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: restypes.h:144
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@430::@439 DeviceSpecificData
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@430 u
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: restypes.h:100
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275
struct _CM_DISK_GEOMETRY_DEVICE_DATA * PCM_DISK_GEOMETRY_DEVICE_DATA

◆ DiskIdentifierQueryRoutine()

static NTSTATUS NTAPI DiskIdentifierQueryRoutine ( PWSTR  ValueName,
ULONG  ValueType,
PVOID  ValueData,
ULONG  ValueLength,
PVOID  Context,
PVOID  EntryContext 
)
static

Definition at line 183 of file partlist.c.

190{
191 PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
192 UNICODE_STRING NameU;
193
194 if (ValueType == REG_SZ &&
195 ValueLength == 20 * sizeof(WCHAR))
196 {
197 NameU.Buffer = (PWCHAR)ValueData;
198 NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
199 RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
200
201 NameU.Buffer = (PWCHAR)ValueData + 9;
202 RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
203
204 return STATUS_SUCCESS;
205 }
206
207 return STATUS_UNSUCCESSFUL;
208}
#define REG_SZ
Definition: layer.c:22
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWCHAR
Definition: typedefs.h:56

◆ DismountVolume()

NTSTATUS DismountVolume ( _In_ PPARTENTRY  PartEntry)

Definition at line 2045 of file partlist.c.

2047{
2049 NTSTATUS LockStatus;
2053 HANDLE PartitionHandle;
2055
2056 /* Check whether the partition is valid and was mounted by the system */
2057 if (!PartEntry->IsPartitioned ||
2058 IsContainerPartition(PartEntry->PartitionType) ||
2059 !IsRecognizedPartition(PartEntry->PartitionType) ||
2060 PartEntry->FormatState == UnknownFormat ||
2061 // NOTE: If FormatState == Unformatted but *FileSystem != 0 this means
2062 // it has been usually mounted with RawFS and thus needs to be dismounted.
2063/* !*PartEntry->FileSystem || */
2064 PartEntry->PartitionNumber == 0)
2065 {
2066 /* The partition is not mounted, so just return success */
2067 return STATUS_SUCCESS;
2068 }
2069
2070 ASSERT(PartEntry->PartitionType != PARTITION_ENTRY_UNUSED);
2071
2072 /* Open the volume */
2074 L"\\Device\\Harddisk%lu\\Partition%lu",
2075 PartEntry->DiskEntry->DiskNumber,
2076 PartEntry->PartitionNumber);
2078
2080 &Name,
2082 NULL,
2083 NULL);
2084
2085 Status = NtOpenFile(&PartitionHandle,
2091 if (!NT_SUCCESS(Status))
2092 {
2093 DPRINT1("ERROR: Cannot open volume %wZ for dismounting! (Status 0x%lx)\n", &Name, Status);
2094 return Status;
2095 }
2096
2097 /* Lock the volume */
2098 LockStatus = NtFsControlFile(PartitionHandle,
2099 NULL,
2100 NULL,
2101 NULL,
2104 NULL,
2105 0,
2106 NULL,
2107 0);
2108 if (!NT_SUCCESS(LockStatus))
2109 {
2110 DPRINT1("WARNING: Failed to lock volume! Operations may fail! (Status 0x%lx)\n", LockStatus);
2111 }
2112
2113 /* Dismount the volume */
2114 Status = NtFsControlFile(PartitionHandle,
2115 NULL,
2116 NULL,
2117 NULL,
2120 NULL,
2121 0,
2122 NULL,
2123 0);
2124 if (!NT_SUCCESS(Status))
2125 {
2126 DPRINT1("Failed to unmount volume (Status 0x%lx)\n", Status);
2127 }
2128
2129 /* Unlock the volume */
2130 LockStatus = NtFsControlFile(PartitionHandle,
2131 NULL,
2132 NULL,
2133 NULL,
2136 NULL,
2137 0,
2138 NULL,
2139 0);
2140 if (!NT_SUCCESS(LockStatus))
2141 {
2142 DPRINT1("Failed to unlock volume (Status 0x%lx)\n", LockStatus);
2143 }
2144
2145 /* Close the volume */
2146 NtClose(PartitionHandle);
2147
2148 return Status;
2149}
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:71
#define GENERIC_READ
Definition: compat.h:135
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define ASSERT(a)
Definition: mode.c:44
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#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
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75

◆ EnumerateBiosDiskEntries()

static VOID EnumerateBiosDiskEntries ( VOID  )
static

Definition at line 307 of file partlist.c.

308{
310 WCHAR Name[120];
311 ULONG AdapterCount;
312 ULONG DiskCount;
314 PCM_INT13_DRIVE_PARAMETER Int13Drives;
315 PBIOSDISKENTRY BiosDiskEntry;
316
317 memset(QueryTable, 0, sizeof(QueryTable));
318
319 QueryTable[1].Name = L"Configuration Data";
321 Int13Drives = NULL;
323 L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
324 &QueryTable[1],
325 (PVOID)&Int13Drives,
326 NULL);
327 if (!NT_SUCCESS(Status))
328 {
329 DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status);
330 return;
331 }
332
333 AdapterCount = 0;
334 while (1)
335 {
337 L"%s\\%lu", ROOT_NAME, AdapterCount);
339 Name,
340 &QueryTable[2],
341 NULL,
342 NULL);
343 if (!NT_SUCCESS(Status))
344 {
345 break;
346 }
347
349 L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
351 Name,
352 &QueryTable[2],
353 NULL,
354 NULL);
355 if (NT_SUCCESS(Status))
356 {
357 while (1)
358 {
360 L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount);
362 Name,
363 &QueryTable[2],
364 NULL,
365 NULL);
366 if (!NT_SUCCESS(Status))
367 {
368 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
369 return;
370 }
371
373 L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount);
375 Name,
376 &QueryTable[2],
377 NULL,
378 NULL);
379 if (NT_SUCCESS(Status))
380 {
381 QueryTable[0].Name = L"Identifier";
383 QueryTable[1].Name = L"Configuration Data";
385
386 DiskCount = 0;
387 while (1)
388 {
389 BiosDiskEntry = (BIOSDISKENTRY*)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY));
390 if (BiosDiskEntry == NULL)
391 {
392 break;
393 }
394
396 L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount);
398 Name,
400 (PVOID)BiosDiskEntry,
401 NULL);
402 if (!NT_SUCCESS(Status))
403 {
404 RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
405 break;
406 }
407
408 BiosDiskEntry->DiskNumber = DiskCount;
409 BiosDiskEntry->Recognized = FALSE;
410
411 if (DiskCount < Int13Drives[0].NumberDrives)
412 {
413 BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
414 }
415 else
416 {
417 DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount);
418 }
419
420 InsertTailList(&BiosDiskListHead, &BiosDiskEntry->ListEntry);
421
422 DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber);
423 DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature);
424 DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum);
425 DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector);
426 DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders);
427 DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads);
428 DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect);
429 DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders);
430 DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack);
431 DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads);
432 DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives);
433
434 DiskCount++;
435 }
436 }
437
438 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
439 return;
440 }
441 }
442
443 AdapterCount++;
444 }
445
446 RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
447}
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
struct _BIOSDISKENTRY BIOSDISKENTRY
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4211
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define memset(x, y, z)
Definition: compat.h:39
static NTSTATUS NTAPI DiskConfigurationDataQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:237
#define ROOT_NAME
static NTSTATUS NTAPI SystemConfigurationDataQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:280
static NTSTATUS NTAPI DiskIdentifierQueryRoutine(PWSTR ValueName, ULONG ValueType, PVOID ValueData, ULONG ValueLength, PVOID Context, PVOID EntryContext)
Definition: partlist.c:207
LIST_ENTRY ListEntry
Definition: partlist.h:159
CM_INT13_DRIVE_PARAMETER Int13DiskData
Definition: partlist.h:167
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109

◆ GetDriverName()

static VOID GetDriverName ( PDISKENTRY  DiskEntry)
static

Definition at line 148 of file partlist.c.

150{
152 WCHAR KeyName[32];
154
156 NULL);
157
159 L"\\Scsi\\Scsi Port %lu",
160 DiskEntry->Port);
161
163 sizeof(QueryTable));
164
165 QueryTable[0].Name = L"Driver";
167 QueryTable[0].EntryContext = &DiskEntry->DriverName;
168
170 KeyName,
172 NULL,
173 NULL);
174 if (!NT_SUCCESS(Status))
175 {
176 DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
177 }
178}
#define RTL_REGISTRY_DEVICEMAP
Definition: nt_native.h:165
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2705

◆ GetLogicalPartitionCount()

static ULONG GetLogicalPartitionCount ( _In_ PDISKENTRY  DiskEntry)
static

Definition at line 1736 of file partlist.c.

1738{
1739 PLIST_ENTRY ListEntry;
1740 PPARTENTRY PartEntry;
1741 ULONG Count = 0;
1742
1743 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
1744 ListEntry != &DiskEntry->LogicalPartListHead;
1745 ListEntry = ListEntry->Flink)
1746 {
1747 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1748 if (PartEntry->IsPartitioned)
1749 Count++;
1750 }
1751
1752 return Count;
1753}
int Count
Definition: noreturn.cpp:7

◆ GetNextUnpartitionedEntry()

PPARTENTRY GetNextUnpartitionedEntry ( _In_ PPARTENTRY  PartEntry)

Definition at line 2016 of file partlist.c.

2018{
2019 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
2020 PPARTENTRY NextPartEntry;
2021 PLIST_ENTRY ListHead;
2022
2023 if (PartEntry->LogicalPartition)
2024 ListHead = &DiskEntry->LogicalPartListHead;
2025 else
2026 ListHead = &DiskEntry->PrimaryPartListHead;
2027
2028 if (PartEntry->ListEntry.Flink != ListHead)
2029 {
2030 NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink,
2031 PARTENTRY,
2032 ListEntry);
2033 if (!NextPartEntry->IsPartitioned)
2034 {
2035 ASSERT(NextPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2036 return NextPartEntry;
2037 }
2038 }
2039
2040 return NULL;
2041}

Referenced by DeletePartition().

◆ GetPrevUnpartitionedEntry()

PPARTENTRY GetPrevUnpartitionedEntry ( _In_ PPARTENTRY  PartEntry)

Definition at line 1987 of file partlist.c.

1989{
1990 PDISKENTRY DiskEntry = PartEntry->DiskEntry;
1991 PPARTENTRY PrevPartEntry;
1992 PLIST_ENTRY ListHead;
1993
1994 if (PartEntry->LogicalPartition)
1995 ListHead = &DiskEntry->LogicalPartListHead;
1996 else
1997 ListHead = &DiskEntry->PrimaryPartListHead;
1998
1999 if (PartEntry->ListEntry.Blink != ListHead)
2000 {
2001 PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink,
2002 PARTENTRY,
2003 ListEntry);
2004 if (!PrevPartEntry->IsPartitioned)
2005 {
2006 ASSERT(PrevPartEntry->PartitionType == PARTITION_ENTRY_UNUSED);
2007 return PrevPartEntry;
2008 }
2009 }
2010
2011 return NULL;
2012}

Referenced by DeletePartition().

◆ GetPrimaryPartitionCount()

ULONG GetPrimaryPartitionCount ( _In_ PDISKENTRY  DiskEntry)

Definition at line 1714 of file partlist.c.

1716{
1718 PPARTENTRY PartEntry;
1719 ULONG Count = 0;
1720
1721 for (Entry = DiskEntry->PrimaryPartListHead.Flink;
1722 Entry != &DiskEntry->PrimaryPartListHead;
1723 Entry = Entry->Flink)
1724 {
1725 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
1726 if (PartEntry->IsPartitioned)
1727 Count++;
1728 }
1729
1730 return Count;
1731}

◆ GetVolumeExtents()

static VOID GetVolumeExtents ( _In_ HANDLE  VolumeHandle,
_In_ PVOLENTRY  VolumeEntry 
)
static

Definition at line 1269 of file partlist.c.

1272{
1273 DWORD dwBytesReturned = 0, dwLength, i;
1274 PVOLUME_DISK_EXTENTS pExtents;
1275 BOOL bResult;
1276 DWORD dwError;
1277
1278 dwLength = sizeof(VOLUME_DISK_EXTENTS);
1279 pExtents = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
1280 if (pExtents == NULL)
1281 return;
1282
1283 bResult = DeviceIoControl(VolumeHandle,
1285 NULL,
1286 0,
1287 pExtents,
1288 dwLength,
1289 &dwBytesReturned,
1290 NULL);
1291 if (!bResult)
1292 {
1293 dwError = GetLastError();
1294
1295 if (dwError != ERROR_MORE_DATA)
1296 {
1297 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1298 return;
1299 }
1300 else
1301 {
1302 dwLength = sizeof(VOLUME_DISK_EXTENTS) + ((pExtents->NumberOfDiskExtents - 1) * sizeof(DISK_EXTENT));
1303 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1304 pExtents = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, dwLength);
1305 if (pExtents == NULL)
1306 {
1307 return;
1308 }
1309
1310 bResult = DeviceIoControl(VolumeHandle,
1312 NULL,
1313 0,
1314 pExtents,
1315 dwLength,
1316 &dwBytesReturned,
1317 NULL);
1318 if (!bResult)
1319 {
1320 RtlFreeHeap(RtlGetProcessHeap(), 0, pExtents);
1321 return;
1322 }
1323 }
1324 }
1325
1326 for (i = 0; i < pExtents->NumberOfDiskExtents; i++)
1327 VolumeEntry->Size.QuadPart += pExtents->Extents[i].ExtentLength.QuadPart;
1328
1329 VolumeEntry->pExtents = pExtents;
1330}
#define ERROR_MORE_DATA
Definition: dderror.h:13
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
struct _VOLUME_DISK_EXTENTS VOLUME_DISK_EXTENTS
struct _DISK_EXTENT DISK_EXTENT
#define IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
Definition: ntddvol.h:44
LARGE_INTEGER ExtentLength
Definition: ntddvol.h:50
DISK_EXTENT Extents[1]
Definition: ntddvol.h:55
ULONG NumberOfDiskExtents
Definition: ntddvol.h:54

Referenced by AddVolumeToList().

◆ GetVolumeFromPartition()

PVOLENTRY GetVolumeFromPartition ( _In_ PPARTENTRY  PartEntry)

Definition at line 2153 of file partlist.c.

2155{
2157 PVOLENTRY VolumeEntry;
2158 ULONG i;
2159
2160 if ((PartEntry == NULL) ||
2161 (PartEntry->DiskEntry == NULL))
2162 return NULL;
2163
2165 while (Entry != &VolumeListHead)
2166 {
2167 VolumeEntry = CONTAINING_RECORD(Entry, VOLENTRY, ListEntry);
2168
2169 if (VolumeEntry->pExtents == NULL)
2170 return NULL;
2171
2172 for (i = 0; i < VolumeEntry->pExtents->NumberOfDiskExtents; i++)
2173 {
2174 if (VolumeEntry->pExtents->Extents[i].DiskNumber == PartEntry->DiskEntry->DiskNumber)
2175 {
2176 if ((VolumeEntry->pExtents->Extents[i].StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * PartEntry->DiskEntry->BytesPerSector) &&
2177 (VolumeEntry->pExtents->Extents[i].ExtentLength.QuadPart == PartEntry->SectorCount.QuadPart * PartEntry->DiskEntry->BytesPerSector))
2178 return VolumeEntry;
2179 }
2180 }
2181
2182 Entry = Entry->Flink;
2183 }
2184
2185 return NULL;
2186}
ULONG DiskNumber
Definition: ntddvol.h:48
LARGE_INTEGER StartingOffset
Definition: ntddvol.h:49

Referenced by clean_main().

◆ GetVolumeType()

static VOID GetVolumeType ( _In_ HANDLE  VolumeHandle,
_In_ PVOLENTRY  VolumeEntry 
)
static

Definition at line 1335 of file partlist.c.

1338{
1342
1345 &DeviceInfo,
1348 if (!NT_SUCCESS(Status))
1349 return;
1350
1351 switch (DeviceInfo.DeviceType)
1352 {
1353 case FILE_DEVICE_CD_ROM:
1355 VolumeEntry->VolumeType = VOLUME_TYPE_CDROM;
1356 break;
1357
1358 case FILE_DEVICE_DISK:
1360 if (DeviceInfo.Characteristics & FILE_REMOVABLE_MEDIA)
1361 VolumeEntry->VolumeType = VOLUME_TYPE_REMOVABLE;
1362 else
1363 VolumeEntry->VolumeType = VOLUME_TYPE_PARTITION;
1364 break;
1365
1366 default:
1367 VolumeEntry->VolumeType = VOLUME_TYPE_UNKNOWN;
1368 break;
1369 }
1370}
@ VOLUME_TYPE_UNKNOWN
Definition: diskpart.h:98
@ VOLUME_TYPE_REMOVABLE
Definition: diskpart.h:97
@ VOLUME_TYPE_CDROM
Definition: diskpart.h:95
@ VOLUME_TYPE_PARTITION
Definition: diskpart.h:96
@ FileFsDeviceInformation
Definition: from_kernel.h:222
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:53
#define FILE_DEVICE_CD_ROM
Definition: winioctl.h:47
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:48
#define FILE_DEVICE_DISK
Definition: winioctl.h:52
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)

Referenced by AddVolumeToList().

◆ IsEmptyLayoutEntry()

static BOOLEAN IsEmptyLayoutEntry ( IN PPARTITION_INFORMATION_EX  PartitionInfo)
static

Definition at line 1683 of file partlist.c.

1685{
1686 if (PartitionInfo->StartingOffset.QuadPart == 0 &&
1687 PartitionInfo->PartitionLength.QuadPart == 0)
1688 {
1689 return TRUE;
1690 }
1691
1692 return FALSE;
1693}

◆ IsSamePrimaryLayoutEntry()

static BOOLEAN IsSamePrimaryLayoutEntry ( IN PPARTITION_INFORMATION_EX  PartitionInfo,
IN PDISKENTRY  DiskEntry,
IN PPARTENTRY  PartEntry 
)
static

Definition at line 1698 of file partlist.c.

1702{
1703 if ((PartitionInfo->StartingOffset.QuadPart == PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector) &&
1704 (PartitionInfo->PartitionLength.QuadPart == PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector))
1705 {
1706 return TRUE;
1707 }
1708
1709 return FALSE;
1710}

◆ ReadLayoutBuffer()

VOID ReadLayoutBuffer ( _In_ HANDLE  FileHandle,
_In_ PDISKENTRY  DiskEntry 
)

Definition at line 816 of file partlist.c.

819{
820 ULONG LayoutBufferSize;
821 PDRIVE_LAYOUT_INFORMATION_EX NewLayoutBuffer;
824
825 /* Allocate a layout buffer with 4 partition entries first */
826 LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
827 ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION_EX));
828 DiskEntry->LayoutBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
830 LayoutBufferSize);
831 if (DiskEntry->LayoutBuffer == NULL)
832 {
833 DPRINT1("Failed to allocate the disk layout buffer!\n");
834 return;
835 }
836
837 for (;;)
838 {
839 DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
841 NULL,
842 NULL,
843 NULL,
844 &Iosb,
846 NULL,
847 0,
848 DiskEntry->LayoutBuffer,
849 LayoutBufferSize);
850 if (NT_SUCCESS(Status))
851 break;
852
854 {
855 DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n", Status);
856 return;
857 }
858
859 LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION_EX);
860 NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
862 DiskEntry->LayoutBuffer,
863 LayoutBufferSize);
864 if (NewLayoutBuffer == NULL)
865 {
866 DPRINT1("Failed to reallocate the disk layout buffer!\n");
867 return;
868 }
869
870 DiskEntry->LayoutBuffer = NewLayoutBuffer;
871 }
872}
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Definition: ntddk_ex.h:207
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T) __WINE_ALLOC_SIZE(4) __WINE_DEALLOC(RtlFreeHeap
struct _PARTITION_INFORMATION_EX PARTITION_INFORMATION_EX
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define ANYSIZE_ARRAY
Definition: typedefs.h:46

Referenced by AddDiskToList(), and CreateDisk().

◆ ReAllocateLayoutBuffer()

static BOOLEAN ReAllocateLayoutBuffer ( _In_ PDISKENTRY  DiskEntry)
static

Definition at line 1758 of file partlist.c.

1760{
1761 PDRIVE_LAYOUT_INFORMATION_EX NewLayoutBuffer;
1762 ULONG NewPartitionCount;
1763 ULONG CurrentPartitionCount = 0;
1764 ULONG LayoutBufferSize;
1765 ULONG i;
1766
1767 DPRINT1("ReAllocateLayoutBuffer()\n");
1768
1769 NewPartitionCount = 4 + GetLogicalPartitionCount(DiskEntry) * 4;
1770
1771 if (DiskEntry->LayoutBuffer)
1772 CurrentPartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
1773
1774 DPRINT1("CurrentPartitionCount: %lu ; NewPartitionCount: %lu\n",
1775 CurrentPartitionCount, NewPartitionCount);
1776
1777 if (CurrentPartitionCount == NewPartitionCount)
1778 return TRUE;
1779
1780 LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
1781 ((NewPartitionCount - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION_EX));
1782 NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
1784 DiskEntry->LayoutBuffer,
1785 LayoutBufferSize);
1786 if (NewLayoutBuffer == NULL)
1787 {
1788 DPRINT1("Failed to allocate the new layout buffer (size: %lu)\n", LayoutBufferSize);
1789 return FALSE;
1790 }
1791
1792 NewLayoutBuffer->PartitionCount = NewPartitionCount;
1793
1794 /* If the layout buffer grows, make sure the new (empty) entries are written to the disk */
1795 if (NewPartitionCount > CurrentPartitionCount)
1796 {
1797 for (i = CurrentPartitionCount; i < NewPartitionCount; i++)
1798 {
1799 NewLayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
1800 }
1801 }
1802
1803 DiskEntry->LayoutBuffer = NewLayoutBuffer;
1804
1805 return TRUE;
1806}
#define GetLogicalPartitionCount(DiskEntry)
Definition: partlist.c:2530

◆ RemoveVolume()

VOID RemoveVolume ( _In_ PVOLENTRY  VolumeEntry)

Definition at line 2190 of file partlist.c.

2192{
2193 if (VolumeEntry == NULL)
2194 return;
2195
2196 if (VolumeEntry == CurrentVolume)
2198
2199 RemoveEntryList(&VolumeEntry->ListEntry);
2200
2201 if (VolumeEntry->pszLabel)
2202 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszLabel);
2203
2204 if (VolumeEntry->pszFilesystem)
2205 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pszFilesystem);
2206
2207 if (VolumeEntry->pExtents)
2208 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry->pExtents);
2209
2210 /* Release disk entry */
2211 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeEntry);
2212}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986

Referenced by clean_main().

◆ ScanForUnpartitionedDiskSpace()

static VOID ScanForUnpartitionedDiskSpace ( PDISKENTRY  DiskEntry)
static

Definition at line 561 of file partlist.c.

563{
564 ULONGLONG LastStartSector;
565 ULONGLONG LastSectorCount;
566 ULONGLONG LastUnusedSectorCount;
567 PPARTENTRY PartEntry;
568 PPARTENTRY NewPartEntry;
570
571 DPRINT("ScanForUnpartitionedDiskSpace()\n");
572
573 if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
574 {
575 DPRINT1("No primary partition!\n");
576
577 /* Create a partition table that represents the empty disk */
578 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
580 sizeof(PARTENTRY));
581 if (NewPartEntry == NULL)
582 return;
583
584 NewPartEntry->DiskEntry = DiskEntry;
585
586 NewPartEntry->IsPartitioned = FALSE;
587 NewPartEntry->StartSector.QuadPart = (ULONGLONG)DiskEntry->SectorAlignment;
588 NewPartEntry->SectorCount.QuadPart = AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) -
589 NewPartEntry->StartSector.QuadPart;
590
591 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
592 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
593 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
594
595 NewPartEntry->FormatState = Unformatted;
596
598 &NewPartEntry->ListEntry);
599
600 return;
601 }
602
603 /* Start partition at head 1, cylinder 0 */
604 LastStartSector = DiskEntry->SectorAlignment;
605 LastSectorCount = 0ULL;
606 LastUnusedSectorCount = 0ULL;
607
608 Entry = DiskEntry->PrimaryPartListHead.Flink;
609 while (Entry != &DiskEntry->PrimaryPartListHead)
610 {
611 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
612
613 if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
614 PartEntry->SectorCount.QuadPart != 0ULL)
615 {
616 LastUnusedSectorCount =
617 PartEntry->StartSector.QuadPart - (LastStartSector + LastSectorCount);
618
619 if (PartEntry->StartSector.QuadPart > (LastStartSector + LastSectorCount) &&
620 LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
621 {
622 DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
623
624 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
626 sizeof(PARTENTRY));
627 if (NewPartEntry == NULL)
628 return;
629
630 NewPartEntry->DiskEntry = DiskEntry;
631
632 NewPartEntry->IsPartitioned = FALSE;
633 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
634 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
635 NewPartEntry->StartSector.QuadPart;
636
637 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
638 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
639 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
640
641 NewPartEntry->FormatState = Unformatted;
642
643 /* Insert the table into the list */
644 InsertTailList(&PartEntry->ListEntry,
645 &NewPartEntry->ListEntry);
646 }
647
648 LastStartSector = PartEntry->StartSector.QuadPart;
649 LastSectorCount = PartEntry->SectorCount.QuadPart;
650 }
651
652 Entry = Entry->Flink;
653 }
654
655 /* Check for trailing unpartitioned disk space */
656 if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart)
657 {
658 LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart - (LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
659
660 if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
661 {
662 DPRINT1("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
663
664 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
666 sizeof(PARTENTRY));
667 if (NewPartEntry == NULL)
668 return;
669
670 NewPartEntry->DiskEntry = DiskEntry;
671
672 NewPartEntry->IsPartitioned = FALSE;
673 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
674 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
675 NewPartEntry->StartSector.QuadPart;
676
677 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
678 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
679 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
680
681 NewPartEntry->FormatState = Unformatted;
682
683 /* Append the table to the list */
685 &NewPartEntry->ListEntry);
686 }
687 }
688
689 if (DiskEntry->ExtendedPartition != NULL)
690 {
691 if (IsListEmpty(&DiskEntry->LogicalPartListHead))
692 {
693 DPRINT1("No logical partition!\n");
694
695 /* Create a partition table entry that represents the empty extended partition */
696 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
698 sizeof(PARTENTRY));
699 if (NewPartEntry == NULL)
700 return;
701
702 NewPartEntry->DiskEntry = DiskEntry;
703 NewPartEntry->LogicalPartition = TRUE;
704
705 NewPartEntry->IsPartitioned = FALSE;
706 NewPartEntry->StartSector.QuadPart = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
707 NewPartEntry->SectorCount.QuadPart = DiskEntry->ExtendedPartition->SectorCount.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment;
708
709 DPRINT1("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
710 DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
711 DPRINT1("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
712
713 NewPartEntry->FormatState = Unformatted;
714
716 &NewPartEntry->ListEntry);
717
718 return;
719 }
720
721 /* Start partition at head 1, cylinder 0 */
722 LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart + (ULONGLONG)DiskEntry->SectorAlignment;
723 LastSectorCount = 0ULL;
724 LastUnusedSectorCount = 0ULL;
725
726 Entry = DiskEntry->LogicalPartListHead.Flink;
727 while (Entry != &DiskEntry->LogicalPartListHead)
728 {
729 PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
730
731 if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
732 PartEntry->SectorCount.QuadPart != 0ULL)
733 {
734 LastUnusedSectorCount =
735 PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount);
736
737 if ((PartEntry->StartSector.QuadPart - (ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount) &&
738 LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
739 {
740 DPRINT("Unpartitioned disk space %I64u sectors\n", LastUnusedSectorCount);
741
742 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
744 sizeof(PARTENTRY));
745 if (NewPartEntry == NULL)
746 return;
747
748 NewPartEntry->DiskEntry = DiskEntry;
749 NewPartEntry->LogicalPartition = TRUE;
750
751 NewPartEntry->IsPartitioned = FALSE;
752 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
753 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
754 NewPartEntry->StartSector.QuadPart;
755
756 DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
757 DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
758 DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
759
760 NewPartEntry->FormatState = Unformatted;
761
762 /* Insert the table into the list */
763 InsertTailList(&PartEntry->ListEntry,
764 &NewPartEntry->ListEntry);
765 }
766
767 LastStartSector = PartEntry->StartSector.QuadPart;
768 LastSectorCount = PartEntry->SectorCount.QuadPart;
769 }
770
771 Entry = Entry->Flink;
772 }
773
774 /* Check for trailing unpartitioned disk space */
775 if ((LastStartSector + LastSectorCount) < DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart)
776 {
777 LastUnusedSectorCount = AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart + DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector + LastSectorCount),
778 DiskEntry->SectorAlignment);
779
780 if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
781 {
782 DPRINT("Unpartitioned disk space: %I64u sectors\n", LastUnusedSectorCount);
783
784 NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
786 sizeof(PARTENTRY));
787 if (NewPartEntry == NULL)
788 return;
789
790 NewPartEntry->DiskEntry = DiskEntry;
791 NewPartEntry->LogicalPartition = TRUE;
792
793 NewPartEntry->IsPartitioned = FALSE;
794 NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
795 NewPartEntry->SectorCount.QuadPart = AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount, DiskEntry->SectorAlignment) -
796 NewPartEntry->StartSector.QuadPart;
797
798 DPRINT("First Sector: %I64u\n", NewPartEntry->StartSector.QuadPart);
799 DPRINT("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
800 DPRINT("Total Sectors: %I64u\n", NewPartEntry->SectorCount.QuadPart);
801
802 NewPartEntry->FormatState = Unformatted;
803
804 /* Append the table to the list */
806 &NewPartEntry->ListEntry);
807 }
808 }
809 }
810
811 DPRINT("ScanForUnpartitionedDiskSpace() done\n");
812}
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
#define ULL(a, b)
Definition: format_msg.c:27
ULONGLONG AlignDown(IN ULONGLONG Value, IN ULONG Alignment)
Definition: partlist.c:67

◆ SystemConfigurationDataQueryRoutine()

static NTSTATUS NTAPI SystemConfigurationDataQueryRoutine ( PWSTR  ValueName,
ULONG  ValueType,
PVOID  ValueData,
ULONG  ValueLength,
PVOID  Context,
PVOID  EntryContext 
)
static

Definition at line 257 of file partlist.c.

264{
265 PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
267 ULONG i;
268
271 return STATUS_UNSUCCESSFUL;
272
273 FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
274
275 /* Hm. Version and Revision are not set on Microsoft Windows XP... */
276#if 0
277 if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
278 FullResourceDescriptor->PartialResourceList.Revision != 1)
279 return STATUS_UNSUCCESSFUL;
280#endif
281
282 for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
283 {
285 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0)
286 continue;
287
288 *Int13Drives = (CM_INT13_DRIVE_PARAMETER*)RtlAllocateHeap(RtlGetProcessHeap(), 0,
289 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
290 if (*Int13Drives == NULL)
291 return STATUS_NO_MEMORY;
292
293 memcpy(*Int13Drives,
294 &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1],
295 FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
296 return STATUS_SUCCESS;
297 }
298
299 return STATUS_UNSUCCESSFUL;
300}
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

◆ UpdateDiskLayout()

VOID UpdateDiskLayout ( _In_ PDISKENTRY  DiskEntry)

Definition at line 1810 of file partlist.c.

1812{
1815 PLIST_ENTRY ListEntry;
1816 PPARTENTRY PartEntry;
1817 LARGE_INTEGER HiddenSectors64;
1818 ULONG Index;
1820
1821 DPRINT1("UpdateDiskLayout()\n");
1822
1823 /* Resize the layout buffer if necessary */
1824 if (ReAllocateLayoutBuffer(DiskEntry) == FALSE)
1825 {
1826 DPRINT("ReAllocateLayoutBuffer() failed.\n");
1827 return;
1828 }
1829
1830 DiskEntry->LayoutBuffer->PartitionStyle = PARTITION_STYLE_MBR;
1831
1832 /* Update the primary partition table */
1833 Index = 0;
1834 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
1835 ListEntry != &DiskEntry->PrimaryPartListHead;
1836 ListEntry = ListEntry->Flink)
1837 {
1838 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1839
1840 if (PartEntry->IsPartitioned)
1841 {
1843
1844 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
1845 PartEntry->PartitionIndex = Index;
1846
1847 /* Reset the current partition number only for newly-created (unmounted) partitions */
1848 if (PartEntry->New)
1849 PartEntry->PartitionNumber = 0;
1850
1852
1853 if (!IsSamePrimaryLayoutEntry(PartitionInfo, DiskEntry, PartEntry))
1854 {
1855 DPRINT1("Updating primary partition entry %lu\n", Index);
1856
1857 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
1858 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
1859 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
1860 PartitionInfo->Mbr.HiddenSectors = PartEntry->StartSector.LowPart;
1861 PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
1862 PartitionInfo->Mbr.PartitionType = PartEntry->PartitionType;
1863 PartitionInfo->Mbr.BootIndicator = PartEntry->BootIndicator;
1864 PartitionInfo->Mbr.RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
1865 PartitionInfo->RewritePartition = TRUE;
1866 }
1867
1868 if (!IsContainerPartition(PartEntry->PartitionType))
1870
1871 Index++;
1872 }
1873 }
1874
1875 ASSERT(Index <= 4);
1876
1877 /* Update the logical partition table */
1878 Index = 4;
1879 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
1880 ListEntry != &DiskEntry->LogicalPartListHead;
1881 ListEntry = ListEntry->Flink)
1882 {
1883 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1884
1885 if (PartEntry->IsPartitioned)
1886 {
1888
1889 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
1890 PartEntry->PartitionIndex = Index;
1891
1892 /* Reset the current partition number only for newly-created (unmounted) partitions */
1893 if (PartEntry->New)
1894 PartEntry->PartitionNumber = 0;
1895
1897
1898 DPRINT1("Updating logical partition entry %lu\n", Index);
1899
1900 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
1901 PartitionInfo->StartingOffset.QuadPart = PartEntry->StartSector.QuadPart * DiskEntry->BytesPerSector;
1902 PartitionInfo->PartitionLength.QuadPart = PartEntry->SectorCount.QuadPart * DiskEntry->BytesPerSector;
1903 PartitionInfo->Mbr.HiddenSectors = DiskEntry->SectorAlignment;
1904 PartitionInfo->PartitionNumber = PartEntry->PartitionNumber;
1905 PartitionInfo->Mbr.PartitionType = PartEntry->PartitionType;
1906 PartitionInfo->Mbr.BootIndicator = FALSE;
1907 PartitionInfo->Mbr.RecognizedPartition = IsRecognizedPartition(PartEntry->PartitionType);
1908 PartitionInfo->RewritePartition = TRUE;
1909
1910 /* Fill the link entry of the previous partition entry */
1911 if (LinkInfo != NULL)
1912 {
1914 LinkInfo->StartingOffset.QuadPart = (PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
1915 LinkInfo->PartitionLength.QuadPart = (PartEntry->StartSector.QuadPart + DiskEntry->SectorAlignment) * DiskEntry->BytesPerSector;
1916 HiddenSectors64.QuadPart = PartEntry->StartSector.QuadPart - DiskEntry->SectorAlignment - DiskEntry->ExtendedPartition->StartSector.QuadPart;
1917 LinkInfo->Mbr.HiddenSectors = HiddenSectors64.LowPart;
1918 LinkInfo->PartitionNumber = 0;
1920 LinkInfo->Mbr.BootIndicator = FALSE;
1921 LinkInfo->Mbr.RecognizedPartition = FALSE;
1922 LinkInfo->RewritePartition = TRUE;
1923 }
1924
1925 /* Save a pointer to the link entry of the current partition entry */
1926 LinkInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index + 1];
1927
1929 Index += 4;
1930 }
1931 }
1932
1933 /* Wipe unused primary partition entries */
1934 for (Index = GetPrimaryPartitionCount(DiskEntry); Index < 4; Index++)
1935 {
1936 DPRINT1("Primary partition entry %lu\n", Index);
1937
1938 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
1939
1941 {
1942 DPRINT1("Wiping primary partition entry %lu\n", Index);
1943
1944 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
1945 PartitionInfo->StartingOffset.QuadPart = 0;
1946 PartitionInfo->PartitionLength.QuadPart = 0;
1947 PartitionInfo->Mbr.HiddenSectors = 0;
1948 PartitionInfo->PartitionNumber = 0;
1949 PartitionInfo->Mbr.PartitionType = PARTITION_ENTRY_UNUSED;
1950 PartitionInfo->Mbr.BootIndicator = FALSE;
1951 PartitionInfo->Mbr.RecognizedPartition = FALSE;
1952 PartitionInfo->RewritePartition = TRUE;
1953 }
1954 }
1955
1956 /* Wipe unused logical partition entries */
1957 for (Index = 4; Index < DiskEntry->LayoutBuffer->PartitionCount; Index++)
1958 {
1959 if (Index % 4 >= 2)
1960 {
1961 DPRINT1("Logical partition entry %lu\n", Index);
1962
1963 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[Index];
1964
1966 {
1967 DPRINT1("Wiping partition entry %lu\n", Index);
1968
1969 PartitionInfo->PartitionStyle = PARTITION_STYLE_MBR;
1970 PartitionInfo->StartingOffset.QuadPart = 0;
1971 PartitionInfo->PartitionLength.QuadPart = 0;
1972 PartitionInfo->Mbr.HiddenSectors = 0;
1973 PartitionInfo->PartitionNumber = 0;
1974 PartitionInfo->Mbr.PartitionType = PARTITION_ENTRY_UNUSED;
1975 PartitionInfo->Mbr.BootIndicator = FALSE;
1976 PartitionInfo->Mbr.RecognizedPartition = FALSE;
1977 PartitionInfo->RewritePartition = TRUE;
1978 }
1979 }
1980 }
1981
1982 DiskEntry->Dirty = TRUE;
1983}
#define PARTITION_EXTENDED
Definition: disk.h:76
#define GetPrimaryPartitionCount(DiskEntry)
Definition: partlist.c:2527
BOOLEAN New
Definition: partlist.h:85
ULONG OnDiskPartitionNumber
Definition: partlist.h:74
LARGE_INTEGER StartingOffset
Definition: imports.h:221
PARTITION_STYLE PartitionStyle
Definition: imports.h:220
PARTITION_INFORMATION_MBR Mbr
Definition: imports.h:226
LARGE_INTEGER PartitionLength
Definition: imports.h:222
$ULONG LowPart
Definition: ntbasedef.h:581
static BOOLEAN IsSamePrimaryLayoutEntry(IN PPARTITION_INFORMATION_EX PartitionInfo, IN PDISKENTRY DiskEntry, IN PPARTENTRY PartEntry)
Definition: partlist.c:1698
static BOOLEAN IsEmptyLayoutEntry(IN PPARTITION_INFORMATION_EX PartitionInfo)
Definition: partlist.c:1683
static BOOLEAN ReAllocateLayoutBuffer(_In_ PDISKENTRY DiskEntry)
Definition: partlist.c:1758
ULONG LowPart
Definition: typedefs.h:106
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2061

◆ WritePartitions()

NTSTATUS WritePartitions ( _In_ PDISKENTRY  DiskEntry)

Definition at line 1558 of file partlist.c.

1560{
1568 ULONG PartitionCount;
1569 PLIST_ENTRY ListEntry;
1570 PPARTENTRY PartEntry;
1572
1573 DPRINT("WritePartitions() Disk: %lu\n", DiskEntry->DiskNumber);
1574
1575 /* If the disk is not dirty, there is nothing to do */
1576 if (!DiskEntry->Dirty)
1577 return STATUS_SUCCESS;
1578
1580 L"\\Device\\Harddisk%lu\\Partition0",
1581 DiskEntry->DiskNumber);
1583
1585 &Name,
1587 NULL,
1588 NULL);
1589
1593 &Iosb,
1594 0,
1596 if (!NT_SUCCESS(Status))
1597 {
1598 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1599 return Status;
1600 }
1601
1602 //
1603 // FIXME: We first *MUST* use IOCTL_DISK_CREATE_DISK to initialize
1604 // the disk in MBR or GPT format in case the disk was not initialized!!
1605 // For this we must ask the user which format to use.
1606 //
1607
1608 /* Save the original partition count to be restored later (see comment below) */
1609 PartitionCount = DiskEntry->LayoutBuffer->PartitionCount;
1610
1611 /* Set the new disk layout and retrieve its updated version with possibly modified partition numbers */
1612 BufferSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) +
1613 ((PartitionCount - 1) * sizeof(PARTITION_INFORMATION_EX));
1615 NULL,
1616 NULL,
1617 NULL,
1618 &Iosb,
1620 DiskEntry->LayoutBuffer,
1621 BufferSize,
1622 DiskEntry->LayoutBuffer,
1623 BufferSize);
1625
1626 /*
1627 * IOCTL_DISK_SET_DRIVE_LAYOUT calls IoWritePartitionTable(), which converts
1628 * DiskEntry->LayoutBuffer->PartitionCount into a partition *table* count,
1629 * where such a table is expected to enumerate up to 4 partitions:
1630 * partition *table* count == ROUND_UP(PartitionCount, 4) / 4 .
1631 * Due to this we need to restore the original PartitionCount number.
1632 */
1633 DiskEntry->LayoutBuffer->PartitionCount = PartitionCount;
1634
1635 /* Check whether the IOCTL_DISK_SET_DRIVE_LAYOUT call succeeded */
1636 if (!NT_SUCCESS(Status))
1637 {
1638 DPRINT1("IOCTL_DISK_SET_DRIVE_LAYOUT failed (Status 0x%08lx)\n", Status);
1639 return Status;
1640 }
1641
1642 /* Update the partition numbers */
1643
1644 /* Update the primary partition table */
1645 for (ListEntry = DiskEntry->PrimaryPartListHead.Flink;
1646 ListEntry != &DiskEntry->PrimaryPartListHead;
1647 ListEntry = ListEntry->Flink)
1648 {
1649 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1650
1651 if (PartEntry->IsPartitioned)
1652 {
1654 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
1655 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
1656 }
1657 }
1658
1659 /* Update the logical partition table */
1660 for (ListEntry = DiskEntry->LogicalPartListHead.Flink;
1661 ListEntry != &DiskEntry->LogicalPartListHead;
1662 ListEntry = ListEntry->Flink)
1663 {
1664 PartEntry = CONTAINING_RECORD(ListEntry, PARTENTRY, ListEntry);
1665
1666 if (PartEntry->IsPartitioned)
1667 {
1669 PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartEntry->PartitionIndex];
1670 PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
1671 }
1672 }
1673
1674 /* The layout has been successfully updated, the disk is not dirty anymore */
1675 DiskEntry->Dirty = FALSE;
1676
1677 return Status;
1678}
#define BufferSize
Definition: mmc.h:75
#define IOCTL_DISK_SET_DRIVE_LAYOUT_EX
Definition: ntdddisk.h:208
IN HANDLE DstPath
Definition: fsutil.h:81
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

Variable Documentation

◆ BiosDiskListHead

LIST_ENTRY BiosDiskListHead

◆ CurrentDisk

◆ CurrentPartition

PPARTENTRY CurrentPartition = NULL

Definition at line 77 of file partlist.c.

Referenced by CreatePartitionList(), and DestroyPartitionList().

◆ CurrentVolume

◆ DiskListHead

◆ VolumeListHead