ReactOS 0.4.15-dev-7131-ge4d03f4
partmgr.c File Reference
#include "partmgr.h"
Include dependency graph for partmgr.c:

Go to the source code of this file.

Functions

static PDRIVE_LAYOUT_INFORMATION PartMgrConvertExtendedToLayout (_In_ CONST PDRIVE_LAYOUT_INFORMATION_EX LayoutEx)
 
static PDRIVE_LAYOUT_INFORMATION_EX PartMgrConvertLayoutToExtended (_In_ CONST PDRIVE_LAYOUT_INFORMATION Layout)
 
static VOID PartMgrUpdatePartitionDevices (_In_ PFDO_EXTENSION FdoExtension, _Inout_ PDRIVE_LAYOUT_INFORMATION_EX NewLayout)
 
static NTSTATUS PartMgrGetDriveLayout (_In_ PFDO_EXTENSION FdoExtension, _Out_ PDRIVE_LAYOUT_INFORMATION_EX *DriveLayout)
 
static NTSTATUS FdoIoctlDiskGetDriveGeometryEx (_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
 
static NTSTATUS FdoIoctlDiskGetPartitionInfo (_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
 
static NTSTATUS FdoIoctlDiskGetPartitionInfoEx (_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
 
static NTSTATUS FdoIoctlDiskGetDriveLayout (_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
 
static NTSTATUS FdoIoctlDiskGetDriveLayoutEx (_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
 
static NTSTATUS FdoIoctlDiskSetDriveLayout (_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
 
static NTSTATUS FdoIoctlDiskSetDriveLayoutEx (_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
 
static NTSTATUS FdoIoctlDiskUpdateProperties (_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
 
static NTSTATUS FdoIoctlDiskCreateDisk (_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
 
static NTSTATUS FdoIoctlDiskDeleteDriveLayout (_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
 
static NTSTATUS FdoHandleStartDevice (_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
 
static NTSTATUS PartMgrRefreshDiskData (_In_ PFDO_EXTENSION FdoExtension)
 
static NTSTATUS FdoHandleDeviceRelations (_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
 
static NTSTATUS FdoHandleRemoveDevice (_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
 
static NTSTATUS FdoHandleSurpriseRemoval (_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
 
static NTSTATUS NTAPI PartMgrAddDevice (_In_ PDRIVER_OBJECT DriverObject, _In_ PDEVICE_OBJECT PhysicalDeviceObject)
 
static NTSTATUS NTAPI PartMgrDeviceControl (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
static NTSTATUS NTAPI PartMgrPnp (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
static NTSTATUS NTAPI PartMgrReadWrite (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
NTSTATUS NTAPI PartMgrPower (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
NTSTATUS NTAPI PartMgrShutdownFlush (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
VOID NTAPI PartMgrUnload (_In_ PDRIVER_OBJECT DriverObject)
 
NTSTATUS NTAPI DriverEntry (_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
 

Variables

DRIVER_DISPATCH PartMgrPower
 
DRIVER_DISPATCH PartMgrShutdownFlush
 

Function Documentation

◆ DriverEntry()

NTSTATUS NTAPI DriverEntry ( _In_ PDRIVER_OBJECT  DriverObject,
_In_ PUNICODE_STRING  RegistryPath 
)

Definition at line 1382 of file partmgr.c.

1385{
1386 DriverObject->DriverUnload = PartMgrUnload;
1387 DriverObject->DriverExtension->AddDevice = PartMgrAddDevice;
1390 DriverObject->MajorFunction[IRP_MJ_READ] = PartMgrReadWrite;
1391 DriverObject->MajorFunction[IRP_MJ_WRITE] = PartMgrReadWrite;
1393 DriverObject->MajorFunction[IRP_MJ_PNP] = PartMgrPnp;
1396 DriverObject->MajorFunction[IRP_MJ_POWER] = PartMgrPower;
1397
1398 return STATUS_SUCCESS;
1399}
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
static NTSTATUS NTAPI PartMgrAddDevice(_In_ PDRIVER_OBJECT DriverObject, _In_ PDEVICE_OBJECT PhysicalDeviceObject)
Definition: partmgr.c:1076
VOID NTAPI PartMgrUnload(_In_ PDRIVER_OBJECT DriverObject)
Definition: partmgr.c:1373
static NTSTATUS NTAPI PartMgrReadWrite(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1270
static NTSTATUS NTAPI PartMgrPnp(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1199
DRIVER_DISPATCH PartMgrPower
Definition: partmgr.c:1295
DRIVER_DISPATCH PartMgrShutdownFlush
Definition: partmgr.c:1336
static NTSTATUS NTAPI PartMgrDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partmgr.c:1125
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define IRP_MJ_FLUSH_BUFFERS
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_POWER

◆ FdoHandleDeviceRelations()

static NTSTATUS FdoHandleDeviceRelations ( _In_ PFDO_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)
static

Definition at line 935 of file partmgr.c.

938{
940 DEVICE_RELATION_TYPE type = ioStack->Parameters.QueryDeviceRelations.Type;
941
942 PAGED_CODE();
943
944 if (type == BusRelations)
945 {
947
949 if (!NT_SUCCESS(status))
950 {
952 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
953 Irp->IoStatus.Information = 0;
955 return Irp->IoStatus.Status;
956 }
957
958 INFO("Partition style %u\n", FdoExtension->DiskData.PartitionStyle);
959
960 // PartMgrAcquireLayoutLock calls PartMgrGetDriveLayout inside
961 // so we're sure here that it returns only cached layout
962 PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
964
966
967 // now fill the DeviceRelations structure
968 TRACE("Reporting %u partitions\n", FdoExtension->EnumeratedPartitionsTotal);
969
970 PDEVICE_RELATIONS deviceRelations =
972 sizeof(DEVICE_RELATIONS)
973 + sizeof(PDEVICE_OBJECT)
974 * (FdoExtension->EnumeratedPartitionsTotal - 1),
976
977 if (!deviceRelations)
978 {
980 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
981 Irp->IoStatus.Information = 0;
983 return Irp->IoStatus.Status;
984 }
985
986 deviceRelations->Count = 0;
987
988 PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
989 while (curEntry != NULL)
990 {
991 PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
993 ListEntry);
994
995 // mark the PDO to know that we don't need to manually delete it
996 partExt->IsEnumerated = TRUE;
997 deviceRelations->Objects[deviceRelations->Count++] = partExt->DeviceObject;
999
1000 curEntry = partExt->ListEntry.Next;
1001 }
1002
1003 ASSERT(deviceRelations->Count == FdoExtension->EnumeratedPartitionsTotal);
1004
1006
1007 Irp->IoStatus.Information = (ULONG_PTR)deviceRelations;
1008 Irp->IoStatus.Status = STATUS_SUCCESS;
1009 }
1010
1012 return IoCallDriver(FdoExtension->LowerDevice, Irp);
1013}
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define INFO
Definition: debug.h:89
#define ULONG_PTR
Definition: config.h:101
@ FdoExtension
Definition: precomp.h:48
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define ASSERT(a)
Definition: mode.c:44
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
#define IoCompleteRequest
Definition: irp.c:1240
#define IoCallDriver
Definition: irp.c:1225
static NTSTATUS PartMgrGetDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _Out_ PDRIVE_LAYOUT_INFORMATION_EX *DriveLayout)
Definition: partmgr.c:322
static VOID PartMgrUpdatePartitionDevices(_In_ PFDO_EXTENSION FdoExtension, _Inout_ PDRIVE_LAYOUT_INFORMATION_EX NewLayout)
Definition: partmgr.c:120
static NTSTATUS PartMgrRefreshDiskData(_In_ PFDO_EXTENSION FdoExtension)
Definition: partmgr.c:886
#define TAG_PARTMGR
Definition: partmgr.h:23
FORCEINLINE VOID PartMgrReleaseLayoutLock(_In_ PFDO_EXTENSION FDOExtension)
Definition: partmgr.h:187
FORCEINLINE VOID PartMgrAcquireLayoutLock(_In_ PFDO_EXTENSION FDOExtension)
Definition: partmgr.h:177
#define TRACE(s)
Definition: solgame.cpp:4
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
SINGLE_LIST_ENTRY ListEntry
Definition: partmgr.h:74
BOOLEAN IsEnumerated
Definition: partmgr.h:78
PDEVICE_OBJECT DeviceObject
Definition: partmgr.h:68
Definition: ntbasedef.h:628
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:629
Definition: ps.c:97
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
@ BusRelations
Definition: iotypes.h:2152
#define IO_NO_INCREMENT
Definition: iotypes.h:598
enum _DEVICE_RELATION_TYPE DEVICE_RELATION_TYPE
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by PartMgrPnp().

◆ FdoHandleRemoveDevice()

static NTSTATUS FdoHandleRemoveDevice ( _In_ PFDO_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)
static

Definition at line 1018 of file partmgr.c.

1021{
1022 PAGED_CODE();
1023
1024 if (FdoExtension->DiskInterfaceName.Buffer)
1025 {
1026 IoSetDeviceInterfaceState(&FdoExtension->DiskInterfaceName, FALSE);
1027 RtlFreeUnicodeString(&FdoExtension->DiskInterfaceName);
1028 RtlInitUnicodeString(&FdoExtension->DiskInterfaceName, NULL);
1029 }
1030
1031 // Send the IRP down the stack
1033 Irp->IoStatus.Status = STATUS_SUCCESS;
1034 NTSTATUS status = IoCallDriver(FdoExtension->LowerDevice, Irp);
1035
1036 IoDetachDevice(FdoExtension->LowerDevice);
1037 IoDeleteDevice(FdoExtension->DeviceObject);
1038 return status;
1039}
#define FALSE
Definition: types.h:117
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1296
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311

Referenced by PartMgrPnp().

◆ FdoHandleStartDevice()

static NTSTATUS FdoHandleStartDevice ( _In_ PFDO_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)
static

Definition at line 833 of file partmgr.c.

836{
837 // obtain the disk device number
838 // this is not expected to change thus not in PartMgrRefreshDiskData
839 STORAGE_DEVICE_NUMBER deviceNumber;
841 FdoExtension->LowerDevice,
842 NULL,
843 0,
844 &deviceNumber,
845 sizeof(deviceNumber),
846 FALSE);
847 if (!NT_SUCCESS(status))
848 {
849 return status;
850 }
851
852 FdoExtension->DiskData.DeviceNumber = deviceNumber.DeviceNumber;
853
854 // register the disk interface
855 // partmgr.sys from Windows 8.1 also registers a mysterious GUID_DEVINTERFACE_HIDDEN_DISK here
856 UNICODE_STRING interfaceName;
858 &GUID_DEVINTERFACE_DISK,
859 NULL,
860 &interfaceName);
861
862 if(!NT_SUCCESS(status))
863 {
864 ERR("Failed to register GUID_DEVINTERFACE_DISK, status %x\n", status);
865 return status;
866 }
867
868 FdoExtension->DiskInterfaceName = interfaceName;
869 status = IoSetDeviceInterfaceState(&interfaceName, TRUE);
870
871 INFO("Disk interface %wZ\n", &interfaceName);
872
873 if (!NT_SUCCESS(status))
874 {
875 RtlFreeUnicodeString(&interfaceName);
876 RtlInitUnicodeString(&FdoExtension->DiskInterfaceName, NULL);
877 }
878
879 return status;
880}
#define ERR(fmt,...)
Definition: debug.h:110
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
NTSTATUS IssueSyncIoControlRequest(_In_ UINT32 IoControlCode, _In_ PDEVICE_OBJECT DeviceObject, _In_ PVOID InputBuffer, _In_ ULONG InputBufferLength, _In_ PVOID OutputBuffer, _In_ ULONG OutputBufferLength, _In_ BOOLEAN InternalDeviceIoControl)
Definition: utils.c:19

Referenced by PartMgrPnp().

◆ FdoHandleSurpriseRemoval()

static NTSTATUS FdoHandleSurpriseRemoval ( _In_ PFDO_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)
static

Definition at line 1044 of file partmgr.c.

1047{
1048 PAGED_CODE();
1049
1050 // all enumerated child devices should receive IRP_MN_REMOVE_DEVICE
1051 // removing only non-enumerated ones here
1052 for (PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
1053 curEntry != NULL;
1054 curEntry = curEntry->Next)
1055 {
1056 PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
1058 ListEntry);
1059
1060 if (partExt->IsEnumerated)
1061 {
1062 PartitionHandleRemove(partExt, TRUE);
1063 }
1064 }
1065
1066 // Send the IRP down the stack
1068 Irp->IoStatus.Status = STATUS_SUCCESS;
1069 return IoCallDriver(FdoExtension->LowerDevice, Irp);
1070}
NTSTATUS PartitionHandleRemove(_In_ PPARTITION_EXTENSION PartExt, _In_ BOOLEAN FinalRemove)
Definition: partition.c:175

Referenced by PartMgrPnp().

◆ FdoIoctlDiskCreateDisk()

static NTSTATUS FdoIoctlDiskCreateDisk ( _In_ PFDO_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)
static

Definition at line 785 of file partmgr.c.

788{
789 PAGED_CODE();
790
791 PCREATE_DISK createDisk = Irp->AssociatedIrp.SystemBuffer;
792 if (!VerifyIrpInBufferSize(Irp, sizeof(*createDisk)))
793 {
795 }
796
798
799 NTSTATUS status = IoCreateDisk(FdoExtension->LowerDevice, createDisk);
800
801 FdoExtension->LayoutValid = FALSE;
803
805 return status;
806}
NTSTATUS NTAPI IoCreateDisk(IN PDEVICE_OBJECT DeviceObject, IN PCREATE_DISK Disk)
Definition: fstubex.c:1801
FORCEINLINE BOOLEAN VerifyIrpInBufferSize(_In_ PIRP Irp, _In_ SIZE_T Size)
Definition: partmgr.h:162
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:1772
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133

Referenced by PartMgrDeviceControl().

◆ FdoIoctlDiskDeleteDriveLayout()

static NTSTATUS FdoIoctlDiskDeleteDriveLayout ( _In_ PFDO_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)
static

Definition at line 811 of file partmgr.c.

814{
815 CREATE_DISK createDisk = { .PartitionStyle = PARTITION_STYLE_RAW };
816
817 PAGED_CODE();
818
820
821 NTSTATUS status = IoCreateDisk(FdoExtension->LowerDevice, &createDisk);
822
823 FdoExtension->LayoutValid = FALSE;
825
827 return status;
828}

Referenced by PartMgrDeviceControl().

◆ FdoIoctlDiskGetDriveGeometryEx()

static NTSTATUS FdoIoctlDiskGetDriveGeometryEx ( _In_ PFDO_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)
static

Definition at line 358 of file partmgr.c.

361{
363
364 PAGED_CODE();
365
366 // We're patching the DISK_PARTITION_INFO part of the returned structure
367 // as disk.sys doesn't really know about the partition table on a disk
368
369 PDISK_GEOMETRY_EX_INTERNAL geometryEx = Irp->AssociatedIrp.SystemBuffer;
370 size_t outBufferLength = ioStack->Parameters.DeviceIoControl.OutputBufferLength;
372
374 FdoExtension->LowerDevice,
375 NULL,
376 0,
377 geometryEx,
378 outBufferLength,
379 FALSE);
380
381 if (!NT_SUCCESS(status))
382 {
383 return status;
384 }
385
386 // if DISK_PARTITION_INFO fits the output size
387 if (outBufferLength >= FIELD_OFFSET(DISK_GEOMETRY_EX_INTERNAL, Detection))
388 {
390
391 geometryEx->Partition.SizeOfPartitionInfo = sizeof(geometryEx->Partition);
392 geometryEx->Partition.PartitionStyle = FdoExtension->DiskData.PartitionStyle;
393
394 switch (geometryEx->Partition.PartitionStyle)
395 {
397 geometryEx->Partition.Mbr.Signature = FdoExtension->DiskData.Mbr.Signature;
398 // checksum?
399 break;
400
402 geometryEx->Partition.Gpt.DiskId = FdoExtension->DiskData.Gpt.DiskId;
403 break;
404
405 default:
406 RtlZeroMemory(&geometryEx->Partition, sizeof(geometryEx->Partition));
407 }
408
410 }
411
412 // the logic is copied from disk.sys
413 Irp->IoStatus.Information = min(outBufferLength, sizeof(DISK_GEOMETRY_EX_INTERNAL));
414
415 return status;
416}
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
@ PARTITION_STYLE_GPT
Definition: imports.h:202
@ PARTITION_STYLE_MBR
Definition: imports.h:201
#define min(a, b)
Definition: monoChain.cc:55
DISK_PARTITION_INFO Partition
Definition: disk.c:3667
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by PartMgrDeviceControl().

◆ FdoIoctlDiskGetDriveLayout()

static NTSTATUS FdoIoctlDiskGetDriveLayout ( _In_ PFDO_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)
static

Definition at line 486 of file partmgr.c.

489{
490 PAGED_CODE();
491
493
494 PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
496
497 if (!NT_SUCCESS(status))
498 {
500 return status;
501 }
502
503 // checking this value from layoutEx in case it has been changed
504 if (layoutEx->PartitionStyle != PARTITION_STYLE_MBR)
505 {
508 }
509
510 size_t size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]);
511 size += layoutEx->PartitionCount * sizeof(PARTITION_INFORMATION);
512
514 {
517 }
518
520
522
523 if (partitionList == NULL)
524 {
525 Irp->IoStatus.Information = 0;
527 }
528
529 RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, partitionList, size);
530 ExFreePoolWithTag(partitionList, TAG_PARTMGR);
531
532 Irp->IoStatus.Information = size;
533 return STATUS_SUCCESS;
534}
GLsizeiptr size
Definition: glext.h:5919
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
struct _PARTITION_INFORMATION PARTITION_INFORMATION
static PDRIVE_LAYOUT_INFORMATION PartMgrConvertExtendedToLayout(_In_ CONST PDRIVE_LAYOUT_INFORMATION_EX LayoutEx)
Definition: partmgr.c:20
FORCEINLINE BOOLEAN VerifyIrpOutBufferSize(_In_ PIRP Irp, _In_ SIZE_T Size)
Definition: partmgr.h:147
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138

Referenced by PartMgrDeviceControl().

◆ FdoIoctlDiskGetDriveLayoutEx()

static NTSTATUS FdoIoctlDiskGetDriveLayoutEx ( _In_ PFDO_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)
static

Definition at line 539 of file partmgr.c.

542{
543 PAGED_CODE();
544
546
547 PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
549 if (!NT_SUCCESS(status))
550 {
552 return status;
553 }
554
555 size_t size = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]);
556 size += layoutEx->PartitionCount * sizeof(PARTITION_INFORMATION_EX);
557
559 {
562 }
563
564 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, layoutEx, size);
565
567
568 Irp->IoStatus.Information = size;
569 return STATUS_SUCCESS;
570}
struct _PARTITION_INFORMATION_EX PARTITION_INFORMATION_EX
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by PartMgrDeviceControl().

◆ FdoIoctlDiskGetPartitionInfo()

static NTSTATUS FdoIoctlDiskGetPartitionInfo ( _In_ PFDO_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)
static

Definition at line 421 of file partmgr.c.

424{
425 PPARTITION_INFORMATION partInfo = Irp->AssociatedIrp.SystemBuffer;
426
427 PAGED_CODE();
428
429 if (!VerifyIrpOutBufferSize(Irp, sizeof(*partInfo)))
430 {
432 }
433
435
436 *partInfo = (PARTITION_INFORMATION){
438 .StartingOffset.QuadPart = 0,
439 .PartitionLength.QuadPart = FdoExtension->DiskData.DiskSize,
440 .HiddenSectors = 0,
441 .PartitionNumber = 0,
442 .BootIndicator = FALSE,
443 .RewritePartition = FALSE,
444 .RecognizedPartition = FALSE,
445 };
446
448
449 Irp->IoStatus.Information = sizeof(*partInfo);
450 return STATUS_SUCCESS;
451}
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86

Referenced by PartMgrDeviceControl().

◆ FdoIoctlDiskGetPartitionInfoEx()

static NTSTATUS FdoIoctlDiskGetPartitionInfoEx ( _In_ PFDO_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)
static

Definition at line 456 of file partmgr.c.

459{
460 PPARTITION_INFORMATION_EX partInfoEx = Irp->AssociatedIrp.SystemBuffer;
461
462 PAGED_CODE();
463
464 if (!VerifyIrpOutBufferSize(Irp, sizeof(*partInfoEx)))
465 {
467 }
468
470
471 // most of the fields a zeroed for Partition0
472 *partInfoEx = (PARTITION_INFORMATION_EX){
473 .PartitionLength.QuadPart = FdoExtension->DiskData.DiskSize,
474 .PartitionStyle = FdoExtension->DiskData.PartitionStyle,
475 };
476
478
479 Irp->IoStatus.Information = sizeof(*partInfoEx);
480 return STATUS_SUCCESS;
481}
LARGE_INTEGER PartitionLength
Definition: imports.h:222
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by PartMgrDeviceControl().

◆ FdoIoctlDiskSetDriveLayout()

static NTSTATUS FdoIoctlDiskSetDriveLayout ( _In_ PFDO_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)
static

Definition at line 575 of file partmgr.c.

578{
579 PDRIVE_LAYOUT_INFORMATION layoutInfo = Irp->AssociatedIrp.SystemBuffer;
580
581 PAGED_CODE();
582
583 if (!VerifyIrpInBufferSize(Irp, sizeof(*layoutInfo)))
584 {
586 }
587
588 size_t layoutSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]);
589 layoutSize += layoutInfo->PartitionCount * sizeof(PARTITION_INFORMATION);
590
591 if (!VerifyIrpInBufferSize(Irp, layoutSize))
592 {
594 }
595
596 PDRIVE_LAYOUT_INFORMATION_EX layoutEx = PartMgrConvertLayoutToExtended(layoutInfo);
597
598 if (layoutEx == NULL)
599 {
600 Irp->IoStatus.Information = 0;
602 }
603
605
606 // this in fact updates the bus relations
608
609 // write the partition table to the disk
610 NTSTATUS status = IoWritePartitionTableEx(FdoExtension->LowerDevice, layoutEx);
611 if (NT_SUCCESS(status))
612 {
613 // save the layout cache
614 if (FdoExtension->LayoutCache)
615 {
616 ExFreePool(FdoExtension->LayoutCache);
617 }
618 FdoExtension->LayoutCache = layoutEx;
619 FdoExtension->LayoutValid = TRUE;
620
621 // set updated partition numbers
622 for (UINT32 i = 0; i < layoutInfo->PartitionCount; i++)
623 {
624 PPARTITION_INFORMATION part = &layoutInfo->PartitionEntry[i];
625
626 part->PartitionNumber = layoutEx->PartitionEntry[i].PartitionNumber;
627 }
628 }
629 else
630 {
631 FdoExtension->LayoutValid = FALSE;
632 }
633
635
637
638 // notify everyone that the disk layout has changed
640
641 notification.Event = GUID_IO_DISK_LAYOUT_CHANGE;
642 notification.Version = 1;
644 notification.FileObject = NULL;
645 notification.NameBufferOffset = -1;
646
649 NULL,
650 NULL);
651
652 Irp->IoStatus.Information = layoutSize;
653 return STATUS_SUCCESS;
654}
unsigned int UINT32
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS NTAPI IoWritePartitionTableEx(IN PDEVICE_OBJECT DeviceObject, IN PDRIVE_LAYOUT_INFORMATION_EX DriveLayout)
Definition: fstubex.c:2460
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
static PDRIVE_LAYOUT_INFORMATION_EX PartMgrConvertLayoutToExtended(_In_ CONST PDRIVE_LAYOUT_INFORMATION Layout)
Definition: partmgr.c:72
NTSTATUS NTAPI IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, IN PVOID Context OPTIONAL)
Definition: pnpreport.c:498
PARTITION_INFORMATION PartitionEntry[1]
Definition: ntdddisk.h:426

Referenced by PartMgrDeviceControl().

◆ FdoIoctlDiskSetDriveLayoutEx()

static NTSTATUS FdoIoctlDiskSetDriveLayoutEx ( _In_ PFDO_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)
static

Definition at line 659 of file partmgr.c.

662{
663 PDRIVE_LAYOUT_INFORMATION_EX layoutEx, layoutUser = Irp->AssociatedIrp.SystemBuffer;
665
666 PAGED_CODE();
667
668 if (!VerifyIrpInBufferSize(Irp, sizeof(*layoutUser)))
669 {
671 }
672
673 size_t layoutSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]);
674 layoutSize += layoutUser->PartitionCount * sizeof(PARTITION_INFORMATION_EX);
675
676 if (!VerifyIrpInBufferSize(Irp, layoutSize))
677 {
679 }
680
681 // we need to copy the structure from the IRP input buffer
682 layoutEx = ExAllocatePoolWithTag(PagedPool, layoutSize, TAG_PARTMGR);
683 if (!layoutEx)
684 {
685 Irp->IoStatus.Information = 0;
687 }
688
689 RtlCopyMemory(layoutEx, layoutUser, layoutSize);
690
692
693 // if partition count is 0, it's the same as IOCTL_DISK_CREATE_DISK
694 if (layoutEx->PartitionCount == 0)
695 {
696 CREATE_DISK createDisk = {0};
697 createDisk.PartitionStyle = layoutEx->PartitionStyle;
698 if (createDisk.PartitionStyle == PARTITION_STYLE_MBR)
699 {
700 createDisk.Mbr.Signature = layoutEx->Mbr.Signature;
701 }
702 else if (createDisk.PartitionStyle == PARTITION_STYLE_GPT)
703 {
704 createDisk.Gpt.DiskId = layoutEx->Gpt.DiskId;
705 }
706
707 status = IoCreateDisk(FdoExtension->LowerDevice, &createDisk);
708 }
709 else
710 {
711 // this in fact updates the bus relations
713
714 // write the partition table to the disk
715 status = IoWritePartitionTableEx(FdoExtension->LowerDevice, layoutEx);
716 if (NT_SUCCESS(status))
717 {
718 // set updated partition numbers
719 for (UINT32 i = 0; i < layoutEx->PartitionCount; i++)
720 {
721 PPARTITION_INFORMATION_EX part = &layoutEx->PartitionEntry[i];
722
723 part->PartitionNumber = layoutEx->PartitionEntry[i].PartitionNumber;
724 }
725 }
726 }
727
728 // update the layout cache
729 if (NT_SUCCESS(status))
730 {
731 if (FdoExtension->LayoutCache)
732 {
733 ExFreePool(FdoExtension->LayoutCache);
734 }
735 FdoExtension->LayoutCache = layoutEx;
736 FdoExtension->LayoutValid = TRUE;
737 }
738 else
739 {
740 FdoExtension->LayoutValid = FALSE;
741 }
742
744
746
747 // notify everyone that the disk layout has changed
749
750 notification.Event = GUID_IO_DISK_LAYOUT_CHANGE;
751 notification.Version = 1;
753 notification.FileObject = NULL;
754 notification.NameBufferOffset = -1;
755
758 NULL,
759 NULL);
760
761 Irp->IoStatus.Information = layoutSize;
762 return STATUS_SUCCESS;
763}

Referenced by PartMgrDeviceControl().

◆ FdoIoctlDiskUpdateProperties()

static NTSTATUS FdoIoctlDiskUpdateProperties ( _In_ PFDO_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)
static

Definition at line 768 of file partmgr.c.

Referenced by PartMgrDeviceControl().

◆ PartMgrAddDevice()

static NTSTATUS NTAPI PartMgrAddDevice ( _In_ PDRIVER_OBJECT  DriverObject,
_In_ PDEVICE_OBJECT  PhysicalDeviceObject 
)
static

Definition at line 1076 of file partmgr.c.

1079{
1081
1082 PAGED_CODE();
1083
1085 sizeof(FDO_EXTENSION),
1086 0,
1089 FALSE,
1090 &deviceObject);
1091
1092 if (!NT_SUCCESS(status))
1093 {
1094 ERR("Failed to create FDO 0x%x\n", status);
1095 return status;
1096 }
1097
1098 PFDO_EXTENSION deviceExtension = deviceObject->DeviceExtension;
1099 RtlZeroMemory(deviceExtension, sizeof(*deviceExtension));
1100
1101 deviceExtension->IsFDO = TRUE;
1102 deviceExtension->DeviceObject = deviceObject;
1104 deviceExtension->PhysicalDiskDO = PhysicalDeviceObject;
1106
1107 // the the attaching failed
1108 if (!deviceExtension->LowerDevice)
1109 {
1111
1112 return STATUS_DEVICE_REMOVED;
1113 }
1115
1116 // device is initialized
1117 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1118
1119 return STATUS_SUCCESS;
1120}
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
MxDeviceObject deviceObject
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
@ SynchronizationEvent
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
#define STATUS_DEVICE_REMOVED
Definition: ntstatus.h:809
#define FILE_DEVICE_BUS_EXTENDER
Definition: winioctl.h:148
KEVENT SyncEvent
Definition: partmgr.h:40
PDEVICE_OBJECT PhysicalDiskDO
Definition: partmgr.h:39
PDEVICE_OBJECT DeviceObject
Definition: partmgr.h:37
PDEVICE_OBJECT LowerDevice
Definition: partmgr.h:38
BOOLEAN IsFDO
Definition: partmgr.h:36
#define DO_POWER_PAGABLE

Referenced by DriverEntry().

◆ PartMgrConvertExtendedToLayout()

static PDRIVE_LAYOUT_INFORMATION PartMgrConvertExtendedToLayout ( _In_ CONST PDRIVE_LAYOUT_INFORMATION_EX  LayoutEx)
static

Definition at line 20 of file partmgr.c.

22{
24 PPARTITION_INFORMATION Partition;
25 PPARTITION_INFORMATION_EX PartitionEx;
26
27 PAGED_CODE();
28
29 ASSERT(LayoutEx);
30
31 if (LayoutEx->PartitionStyle != PARTITION_STYLE_MBR)
32 {
34 return NULL;
35 }
36
37 size_t layoutSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION, PartitionEntry[0]) +
38 LayoutEx->PartitionCount * sizeof (PARTITION_INFORMATION);
39
40 Layout = ExAllocatePoolWithTag(PagedPool, layoutSize, TAG_PARTMGR);
41
42 if (Layout == NULL)
43 {
44 return NULL;
45 }
46
47 Layout->Signature = LayoutEx->Mbr.Signature;
48 Layout->PartitionCount = LayoutEx->PartitionCount;
49
50 for (UINT32 i = 0; i < LayoutEx->PartitionCount; i++)
51 {
52 Partition = &Layout->PartitionEntry[i];
53 PartitionEx = &LayoutEx->PartitionEntry[i];
54
55 Partition->StartingOffset = PartitionEx->StartingOffset;
56 Partition->PartitionLength = PartitionEx->PartitionLength;
57 Partition->RewritePartition = PartitionEx->RewritePartition;
58 Partition->PartitionNumber = PartitionEx->PartitionNumber;
59
60 Partition->PartitionType = PartitionEx->Mbr.PartitionType;
61 Partition->BootIndicator = PartitionEx->Mbr.BootIndicator;
62 Partition->RecognizedPartition = PartitionEx->Mbr.RecognizedPartition;
63 Partition->HiddenSectors = PartitionEx->Mbr.HiddenSectors;
64 }
65
66 return Layout;
67}
LARGE_INTEGER StartingOffset
Definition: imports.h:221
PARTITION_INFORMATION_MBR Mbr
Definition: imports.h:226
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:413
LARGE_INTEGER PartitionLength
Definition: ntdddisk.h:414
BOOLEAN RecognizedPartition
Definition: ntdddisk.h:419
BOOLEAN RewritePartition
Definition: ntdddisk.h:420

Referenced by FdoIoctlDiskGetDriveLayout().

◆ PartMgrConvertLayoutToExtended()

static PDRIVE_LAYOUT_INFORMATION_EX PartMgrConvertLayoutToExtended ( _In_ CONST PDRIVE_LAYOUT_INFORMATION  Layout)
static

Definition at line 72 of file partmgr.c.

74{
75 PDRIVE_LAYOUT_INFORMATION_EX layoutEx;
76
77 PAGED_CODE();
78
79 ASSERT(Layout != NULL);
80
81 size_t layoutSize = FIELD_OFFSET(DRIVE_LAYOUT_INFORMATION_EX, PartitionEntry[0]) +
82 Layout->PartitionCount * sizeof (PARTITION_INFORMATION_EX);
83
84 layoutEx = ExAllocatePoolUninitialized(PagedPool, layoutSize, TAG_PARTMGR);
85
86 if (layoutEx == NULL)
87 {
88 return NULL;
89 }
90
91 layoutEx->PartitionStyle = PARTITION_STYLE_MBR;
92 layoutEx->PartitionCount = Layout->PartitionCount;
93 layoutEx->Mbr.Signature = Layout->Signature;
94
95 for (UINT32 i = 0; i < Layout->PartitionCount; i++)
96 {
97 PPARTITION_INFORMATION part = &Layout->PartitionEntry[i];
98
99 layoutEx->PartitionEntry[i] = (PARTITION_INFORMATION_EX) {
100 .PartitionStyle = PARTITION_STYLE_MBR,
101 .StartingOffset = part->StartingOffset,
102 .PartitionLength = part->PartitionLength,
103 .RewritePartition = part->RewritePartition,
104 .PartitionNumber = part->PartitionNumber,
105 .Mbr = {
106 .PartitionType = part->PartitionType,
107 .BootIndicator = part->BootIndicator,
108 .RecognizedPartition = part->RecognizedPartition,
109 .HiddenSectors = part->HiddenSectors,
110 }
111 };
112 }
113
114 return layoutEx;
115}

Referenced by FdoIoctlDiskSetDriveLayout().

◆ PartMgrDeviceControl()

static NTSTATUS NTAPI PartMgrDeviceControl ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)
static

Definition at line 1125 of file partmgr.c.

1128{
1130 PFDO_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
1132
1133 // Note: IRP_MJ_DEVICE_CONTROL handler in the storage stack must be able to pass IOCTLs
1134 // at an IRQL higher than PASSIVE_LEVEL
1135
1136 INFO("IRP_MJ_DEVICE_CONTROL %p Irp %p IOCTL %x isFdo: %u\n",
1137 DeviceObject, Irp, ioStack->Parameters.DeviceIoControl.IoControlCode, fdoExtension->IsFDO);
1138
1139 if (!fdoExtension->IsFDO)
1140 {
1142 }
1143
1144 switch (ioStack->Parameters.DeviceIoControl.IoControlCode)
1145 {
1147 status = FdoIoctlDiskGetDriveGeometryEx(fdoExtension, Irp);
1148 break;
1149
1151 status = FdoIoctlDiskGetPartitionInfo(fdoExtension, Irp);
1152 break;
1153
1155 status = FdoIoctlDiskGetPartitionInfoEx(fdoExtension, Irp);
1156 break;
1157
1159 status = FdoIoctlDiskGetDriveLayout(fdoExtension, Irp);
1160 break;
1161
1163 status = FdoIoctlDiskGetDriveLayoutEx(fdoExtension, Irp);
1164 break;
1165
1167 status = FdoIoctlDiskSetDriveLayout(fdoExtension, Irp);
1168 break;
1169
1171 status = FdoIoctlDiskSetDriveLayoutEx(fdoExtension, Irp);
1172 break;
1173
1175 status = FdoIoctlDiskUpdateProperties(fdoExtension, Irp);
1176 break;
1177
1179 status = FdoIoctlDiskCreateDisk(fdoExtension, Irp);
1180 break;
1181
1183 status = FdoIoctlDiskDeleteDriveLayout(fdoExtension, Irp);
1184 break;
1185 // case IOCTL_DISK_GROW_PARTITION: // todo
1186 default:
1188 }
1189
1190 Irp->IoStatus.Status = status;
1192 return status;
1193}
NTSTATUS PartitionHandleDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partition.c:449
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Definition: ntddk_ex.h:207
#define IOCTL_DISK_SET_DRIVE_LAYOUT
Definition: ntdddisk.h:205
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:91
#define IOCTL_DISK_CREATE_DISK
Definition: ntdddisk.h:55
#define IOCTL_DISK_SET_DRIVE_LAYOUT_EX
Definition: ntdddisk.h:208
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:106
#define IOCTL_DISK_DELETE_DRIVE_LAYOUT
Definition: ntdddisk.h:58
#define IOCTL_DISK_UPDATE_PROPERTIES
Definition: ntdddisk.h:242
static NTSTATUS FdoIoctlDiskCreateDisk(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:785
static NTSTATUS FdoIoctlDiskSetDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:575
static NTSTATUS FdoIoctlDiskDeleteDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:811
static NTSTATUS FdoIoctlDiskGetPartitionInfoEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:456
static NTSTATUS FdoIoctlDiskUpdateProperties(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:768
static NTSTATUS FdoIoctlDiskGetPartitionInfo(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:421
static NTSTATUS FdoIoctlDiskGetDriveLayoutEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:539
static NTSTATUS FdoIoctlDiskGetDriveGeometryEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:358
static NTSTATUS FdoIoctlDiskSetDriveLayoutEx(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:659
static NTSTATUS FdoIoctlDiskGetDriveLayout(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:486
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055

Referenced by DriverEntry().

◆ PartMgrGetDriveLayout()

static NTSTATUS PartMgrGetDriveLayout ( _In_ PFDO_EXTENSION  FdoExtension,
_Out_ PDRIVE_LAYOUT_INFORMATION_EX *  DriveLayout 
)
static

Definition at line 322 of file partmgr.c.

325{
326 PAGED_CODE();
327
328 if (FdoExtension->LayoutValid)
329 {
330 *DriveLayout = FdoExtension->LayoutCache;
331 return STATUS_SUCCESS;
332 }
333
334 PDRIVE_LAYOUT_INFORMATION_EX layoutEx = NULL;
335 NTSTATUS status = IoReadPartitionTableEx(FdoExtension->LowerDevice, &layoutEx);
336
337 if (!NT_SUCCESS(status))
338 {
339 return status;
340 }
341
342 if (FdoExtension->LayoutCache)
343 {
344 ExFreePool(FdoExtension->LayoutCache);
345 }
346
347 FdoExtension->LayoutCache = layoutEx;
348 FdoExtension->LayoutValid = TRUE;
349
350 *DriveLayout = layoutEx;
351
352 return status;
353}
NTSTATUS NTAPI IoReadPartitionTableEx(IN PDEVICE_OBJECT DeviceObject, IN PDRIVE_LAYOUT_INFORMATION_EX *DriveLayout)
Definition: fstubex.c:2273

Referenced by FdoHandleDeviceRelations(), FdoIoctlDiskGetDriveLayout(), FdoIoctlDiskGetDriveLayoutEx(), and PartMgrRefreshDiskData().

◆ PartMgrPnp()

static NTSTATUS NTAPI PartMgrPnp ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)
static

Definition at line 1199 of file partmgr.c.

1202{
1203 PAGED_CODE();
1204
1205 PFDO_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
1207
1208 INFO("IRP_MJ_PNP %p Irp %p %s isFDO: %u\n",
1209 DeviceObject, Irp, GetIRPMinorFunctionString(ioStack->MinorFunction), fdoExtension->IsFDO);
1210
1211 if (!fdoExtension->IsFDO)
1212 {
1214 }
1215
1216 switch (ioStack->MinorFunction) {
1217
1219 {
1221
1222 // if this is sent to the FDO so we should forward it down the
1223 // attachment chain before we can start the FDO
1224
1225 if (!IoForwardIrpSynchronously(fdoExtension->LowerDevice, Irp))
1226 {
1228 }
1229 else
1230 {
1231 status = FdoHandleStartDevice(fdoExtension, Irp);
1232 }
1233
1234 Irp->IoStatus.Status = status;
1236 return status;
1237 }
1239 {
1240 return FdoHandleDeviceRelations(fdoExtension, Irp);
1241 }
1243 {
1244 return FdoHandleSurpriseRemoval(fdoExtension, Irp);
1245 }
1247 {
1248 return FdoHandleRemoveDevice(fdoExtension, Irp);
1249 }
1254 case IRP_MN_STOP_DEVICE:
1255 {
1256 Irp->IoStatus.Status = STATUS_SUCCESS;
1257 // fallthrough
1258 }
1259 default:
1260 {
1262 return IoCallDriver(fdoExtension->LowerDevice, Irp);
1263 }
1264 }
1265}
FORCEINLINE PCHAR GetIRPMinorFunctionString(UCHAR MinorFunction)
Definition: driverdbg.h:13
NTSTATUS PartitionHandlePnp(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: partition.c:385
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
static NTSTATUS FdoHandleRemoveDevice(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:1018
static NTSTATUS FdoHandleDeviceRelations(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:935
static NTSTATUS FdoHandleSurpriseRemoval(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:1044
static NTSTATUS FdoHandleStartDevice(_In_ PFDO_EXTENSION FdoExtension, _In_ PIRP Irp)
Definition: partmgr.c:833
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define IRP_MN_CANCEL_STOP_DEVICE
#define IRP_MN_START_DEVICE
#define IRP_MN_REMOVE_DEVICE
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_STOP_DEVICE
#define IRP_MN_QUERY_REMOVE_DEVICE

Referenced by DriverEntry().

◆ PartMgrPower()

NTSTATUS NTAPI PartMgrPower ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)

Definition at line 1298 of file partmgr.c.

1301{
1302 PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1304
1306
1307 if (!partExt->IsFDO)
1308 {
1310
1311 if (!partExt->IsEnumerated)
1312 {
1314 }
1315 else if (ioStack->MinorFunction == IRP_MN_SET_POWER ||
1317 {
1319 }
1320 else
1321 {
1322 status = Irp->IoStatus.Status;
1323 }
1324
1325 Irp->IoStatus.Status = status;
1327 return status;
1328 }
1329 else
1330 {
1332 return PoCallDriver(partExt->LowerDevice, Irp);
1333 }
1334}
VOID NTAPI PoStartNextPowerIrp(IN PIRP Irp)
Definition: power.c:746
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
PDEVICE_OBJECT LowerDevice
Definition: partmgr.h:69
#define IRP_MN_SET_POWER
#define IRP_MN_QUERY_POWER

◆ PartMgrReadWrite()

static NTSTATUS NTAPI PartMgrReadWrite ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)
static

Definition at line 1270 of file partmgr.c.

1273{
1274 PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1276
1277 if (!partExt->IsFDO)
1278 {
1279 if (!partExt->IsEnumerated)
1280 {
1281 Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
1284 }
1285 else
1286 {
1287 ioStack->Parameters.Read.ByteOffset.QuadPart += partExt->StartingOffset;
1288 }
1289 }
1290
1292 return IoCallDriver(partExt->LowerDevice, Irp);
1293}
UINT64 StartingOffset
Definition: partmgr.h:72

Referenced by DriverEntry().

◆ PartMgrRefreshDiskData()

static NTSTATUS PartMgrRefreshDiskData ( _In_ PFDO_EXTENSION  FdoExtension)
static

Definition at line 886 of file partmgr.c.

888{
890
891 PAGED_CODE();
892
893 // get the DiskSize and BytesPerSector
894 DISK_GEOMETRY_EX geometryEx;
896 FdoExtension->LowerDevice,
897 NULL,
898 0,
899 &geometryEx,
900 sizeof(geometryEx),
901 FALSE);
902 if (!NT_SUCCESS(status))
903 {
904 return status;
905 }
906
907 FdoExtension->DiskData.DiskSize = geometryEx.DiskSize.QuadPart;
908 FdoExtension->DiskData.BytesPerSector = geometryEx.Geometry.BytesPerSector;
909
910 // get the partition style-related info
911 PDRIVE_LAYOUT_INFORMATION_EX layoutEx = NULL;
913 if (!NT_SUCCESS(status))
914 {
915 return status;
916 }
917
918 FdoExtension->DiskData.PartitionStyle = layoutEx->PartitionStyle;
919 if (FdoExtension->DiskData.PartitionStyle == PARTITION_STYLE_MBR)
920 {
921 FdoExtension->DiskData.Mbr.Signature = layoutEx->Mbr.Signature;
922 // FdoExtension->DiskData.Mbr.Checksum = geometryEx.Partition.Mbr.CheckSum;
923 }
924 else
925 {
926 FdoExtension->DiskData.Gpt.DiskId = layoutEx->Gpt.DiskId;
927 }
928
929 return STATUS_SUCCESS;
930}
DISK_GEOMETRY Geometry
Definition: winioctl.h:330
LARGE_INTEGER DiskSize
Definition: winioctl.h:331
ULONG BytesPerSector
Definition: ntdddisk.h:409

Referenced by FdoHandleDeviceRelations().

◆ PartMgrShutdownFlush()

NTSTATUS NTAPI PartMgrShutdownFlush ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)

Definition at line 1339 of file partmgr.c.

1342{
1343 PPARTITION_EXTENSION partExt = DeviceObject->DeviceExtension;
1344 PDEVICE_OBJECT lowerDevice;
1345
1346 // forward to the partition0 device in both cases
1347 if (!partExt->IsFDO)
1348 {
1349 if (!partExt->IsEnumerated)
1350 {
1351 Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
1354 }
1355 else
1356 {
1357 PFDO_EXTENSION fdoExtension = partExt->LowerDevice->DeviceExtension;
1358 lowerDevice = fdoExtension->LowerDevice;
1359 }
1360 }
1361 else
1362 {
1363 lowerDevice = partExt->LowerDevice;
1364 }
1365
1367 return IoCallDriver(lowerDevice, Irp);
1368}
PVOID DeviceExtension
Definition: env_spec_w32.h:418

◆ PartMgrUnload()

VOID NTAPI PartMgrUnload ( _In_ PDRIVER_OBJECT  DriverObject)

Definition at line 1373 of file partmgr.c.

1375{
1376
1377}

Referenced by DriverEntry().

◆ PartMgrUpdatePartitionDevices()

static VOID PartMgrUpdatePartitionDevices ( _In_ PFDO_EXTENSION  FdoExtension,
_Inout_ PDRIVE_LAYOUT_INFORMATION_EX  NewLayout 
)
static

Definition at line 120 of file partmgr.c.

123{
125 PSINGLE_LIST_ENTRY curEntry, prevEntry;
126 UINT32 totalPartitions = 0;
127
128 // Clear the partition numbers from the list entries
129 for (UINT32 i = 0; i < NewLayout->PartitionCount; i++)
130 {
131 NewLayout->PartitionEntry[i].PartitionNumber = 0;
132 }
133
134 // iterate over old partition list
135 prevEntry = &FdoExtension->PartitionList;
136 curEntry = FdoExtension->PartitionList.Next;
137 while (curEntry != NULL)
138 {
139 PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry, PARTITION_EXTENSION, ListEntry);
140 UINT32 partNumber = 0; // count detected partitions for device symlinks
141 BOOLEAN found = FALSE;
143
144 // trying to find this partition in returned layout
145 for (UINT32 i = 0; i < NewLayout->PartitionCount; i++)
146 {
147 partEntry = &NewLayout->PartitionEntry[i];
148
149 // skip unused and container partitions
150 if (NewLayout->PartitionStyle == PARTITION_STYLE_MBR &&
153 {
154 continue;
155 }
156
157 partNumber++;
158
159 // skip already found partitions
160 if (partEntry->PartitionNumber)
161 {
162 continue;
163 }
164
165 // skip if partitions are not equal
166 if (partEntry->StartingOffset.QuadPart != partExt->StartingOffset ||
167 partEntry->PartitionLength.QuadPart != partExt->PartitionLength)
168 {
169 continue;
170 }
171
172 // found matching partition - processing it
173 found = TRUE;
174 break;
175 }
176
177 if (found)
178 {
179 // update (possibly changed) partition metadata
180 if (NewLayout->PartitionStyle == PARTITION_STYLE_MBR)
181 {
182 partExt->Mbr.PartitionType = partEntry->Mbr.PartitionType;
183 partExt->Mbr.BootIndicator = partEntry->Mbr.BootIndicator;
184 }
185 else
186 {
187 partExt->Gpt.PartitionType = partEntry->Gpt.PartitionType;
188 partExt->Gpt.PartitionId = partEntry->Gpt.PartitionId;
189 partExt->Gpt.Attributes = partEntry->Gpt.Attributes;
190
191 RtlCopyMemory(partExt->Gpt.Name, partEntry->Gpt.Name, sizeof(partExt->Gpt.Name));
192 }
193
194 partExt->OnDiskNumber = partNumber;
195 partEntry->PartitionNumber = partNumber; // mark it as a found one
196 totalPartitions++;
197 }
198 else
199 {
200 // detach the device from the list
201 prevEntry->Next = curEntry->Next;
202 curEntry = prevEntry;
203 partExt->Attached = FALSE;
204
205 // enumerated PDOs will receive IRP_MN_REMOVE_DEVICE
206 if (!partExt->IsEnumerated)
207 {
208 PartitionHandleRemove(partExt, TRUE);
209 }
210 }
211
212 prevEntry = curEntry;
213 curEntry = curEntry->Next;
214 }
215
216 UINT32 partNumber = 0;
217 UINT32 pdoNumber = 1;
218
219 // now looking through remaining "new" partitions
220 for (UINT32 i = 0; i < NewLayout->PartitionCount; i++)
221 {
222 PPARTITION_INFORMATION_EX partEntry = &NewLayout->PartitionEntry[i];
223
224 // again, skip unused and container partitions
225 if (NewLayout->PartitionStyle == PARTITION_STYLE_MBR &&
228 {
229 continue;
230 }
231
232 partNumber++;
233
234 // and skip processed partitions
235 if (partEntry->PartitionNumber != 0)
236 {
237 continue;
238 }
239
240 // find the first free PDO index
241 for (PSINGLE_LIST_ENTRY curEntry = FdoExtension->PartitionList.Next;
242 curEntry != NULL;
243 curEntry = curEntry->Next)
244 {
245 PPARTITION_EXTENSION partExt = CONTAINING_RECORD(curEntry,
247 ListEntry);
248
249 if (partExt->DetectedNumber == pdoNumber)
250 {
251 // found a matching pdo number - restart the search
252 curEntry = FdoExtension->PartitionList.Next;
253 pdoNumber++;
254 }
255 }
256
257 partEntry->PartitionNumber = partNumber;
258
259 PDEVICE_OBJECT partitionDevice;
261 partEntry,
262 pdoNumber,
263 NewLayout->PartitionStyle,
264 &partitionDevice);
265
266 if (!NT_SUCCESS(status))
267 {
268 partEntry->PartitionNumber = 0;
269 continue;
270 }
271
272 // mark partition as removable if parent device is removable
273 if (FdoExtension->LowerDevice->Characteristics & FILE_REMOVABLE_MEDIA)
274 partitionDevice->Characteristics |= FILE_REMOVABLE_MEDIA;
275
276 totalPartitions++;
277
278 // insert the structure to the partition list
279 curEntry = FdoExtension->PartitionList.Next;
280 prevEntry = NULL;
281 while (curEntry != NULL)
282 {
283 PPARTITION_EXTENSION curPart = CONTAINING_RECORD(curEntry,
285 ListEntry);
286 if (curPart->OnDiskNumber < partNumber)
287 {
288 prevEntry = curEntry;
289 curEntry = curPart->ListEntry.Next;
290 }
291 else
292 { // we found where to put the partition
293 break;
294 }
295 }
296
297 PPARTITION_EXTENSION partExt = partitionDevice->DeviceExtension;
298
299 if (prevEntry)
300 {
301 // insert after prevEntry
302 partExt->ListEntry.Next = prevEntry->Next;
303 prevEntry->Next = &partExt->ListEntry;
304 }
305 else
306 {
307 // insert in the beginning
308 partExt->ListEntry.Next = FdoExtension->PartitionList.Next;
309 FdoExtension->PartitionList.Next = &partExt->ListEntry;
310 }
311
312 partExt->Attached = TRUE;
313 }
314
315 FdoExtension->EnumeratedPartitionsTotal = totalPartitions;
316}
unsigned char BOOLEAN
NTSTATUS PartitionCreateDevice(_In_ PDEVICE_OBJECT FDObject, _In_ PPARTITION_INFORMATION_EX PartitionEntry, _In_ UINT32 PdoNumber, _In_ PARTITION_STYLE PartitionStyle, _Out_ PDEVICE_OBJECT *PDO)
Definition: partition.c:15
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define IsContainerPartition(PartitionType)
Definition: ntdddisk.h:316
struct _PARTITION_EXTENSION::@1310::@1312 Gpt
UINT32 DetectedNumber
Definition: partmgr.h:76
BOOLEAN Attached
Definition: partmgr.h:80
UINT64 PartitionLength
Definition: partmgr.h:73
UINT32 OnDiskNumber
Definition: partmgr.h:77
struct _PARTITION_EXTENSION::@1310::@1313 Mbr
PARTITION_INFORMATION_GPT Gpt
Definition: imports.h:227

Referenced by FdoHandleDeviceRelations(), FdoIoctlDiskSetDriveLayout(), and FdoIoctlDiskSetDriveLayoutEx().

Variable Documentation

◆ PartMgrPower

DRIVER_DISPATCH PartMgrPower

Definition at line 1295 of file partmgr.c.

Referenced by DriverEntry().

◆ PartMgrShutdownFlush

DRIVER_DISPATCH PartMgrShutdownFlush

Definition at line 1336 of file partmgr.c.

Referenced by DriverEntry().