From d1d0ff51ca959a1e0f60c34382260d8d353b5f6a Mon Sep 17 00:00:00 2001 From: David Hall Date: Tue, 29 Nov 2022 08:02:07 -0600 Subject: [PATCH] Added Missing Disk Management Control Codes #345 --- PInvoke/Kernel32/WinIOCtl.Enums.cs | 18 ++++ PInvoke/Kernel32/WinIOCtl.Structs.cs | 45 ++++++++ PInvoke/Kernel32/WinIOCtl.cs | 192 +++++++++++++++++++++++++++++------ 3 files changed, 226 insertions(+), 29 deletions(-) diff --git a/PInvoke/Kernel32/WinIOCtl.Enums.cs b/PInvoke/Kernel32/WinIOCtl.Enums.cs index 935c7552..0fd6f086 100644 --- a/PInvoke/Kernel32/WinIOCtl.Enums.cs +++ b/PInvoke/Kernel32/WinIOCtl.Enums.cs @@ -826,6 +826,24 @@ namespace Vanara.PInvoke KeepReadData } + /// A combination of flags related to disks and clusters. + [PInvokeData("Ntdddisk.h")] + [Flags] + public enum DISK_CLUSTER_FLAG : ulong + { + /// The disk is used as part of the cluster service. + DISK_CLUSTER_FLAG_ENABLED = 1, + + /// Volumes on the disk are exposed by CSVFS on all nodes of the cluster. + DISK_CLUSTER_FLAG_CSV = 2, + + /// The cluster resource associated with this disk is in maintenance mode. + DISK_CLUSTER_FLAG_IN_MAINTENANCE = 4, + + /// The cluster disk driver for kernel mode (clusdisk) has received PnP notification of the arrival of the disk. + DISK_CLUSTER_FLAG_PNP_ARRIVAL_COMPLETE = 8, + } + /// An exception code that indicates that the element is in an abnormal state. [PInvokeData("winioctl.h", MSDNShortId = "NS:winioctl._CHANGER_ELEMENT_STATUS")] [Flags] diff --git a/PInvoke/Kernel32/WinIOCtl.Structs.cs b/PInvoke/Kernel32/WinIOCtl.Structs.cs index 63c8e69c..3104f2f1 100644 --- a/PInvoke/Kernel32/WinIOCtl.Structs.cs +++ b/PInvoke/Kernel32/WinIOCtl.Structs.cs @@ -362,6 +362,51 @@ namespace Vanara.PInvoke public ushort MaximumBlocks; } + /// Represents information maintained on the partition manager about a disk that is part of a cluster. + // https://learn.microsoft.com/en-us/windows/win32/fileio/disk-cluster-info typedef struct _DISK_CLUSTER_INFO { ULONG Version; + // ULONGLONG Flags; ULONGLONG FlagsMask; BOOLEAN Notify; } DISK_CLUSTER_INFO, *PDISK_CLUSTER_INFO; + [PInvokeData("Ntdddisk.h")] + [StructLayout(LayoutKind.Sequential)] + public struct DISK_CLUSTER_INFO + { + /// The version number. This value must be set to the size of this structure. + public uint Version; + + /// + /// A combination of flags related to disks and clusters. + /// + /// + /// Value + /// Meaning + /// + /// + /// DISK_CLUSTER_FLAG_ENABLED 1 + /// The disk is used as part of the cluster service. + /// + /// + /// DISK_CLUSTER_FLAG_CSV 2 + /// Volumes on the disk are exposed by CSVFS on all nodes of the cluster. + /// + /// + /// DISK_CLUSTER_FLAG_IN_MAINTENANCE 4 + /// The cluster resource associated with this disk is in maintenance mode. + /// + /// + /// DISK_CLUSTER_FLAG_PNP_ARRIVAL_COMPLETE 8 + /// The cluster disk driver for kernel mode (clusdisk) has received PnP notification of the arrival of the disk. + /// + /// + /// + public DISK_CLUSTER_FLAG Flags; + + /// The flags that are being modified in the Flags member. + public DISK_CLUSTER_FLAG FlagsMask; + + /// TRUE to send a layout change notification; otherwise, FALSE. + [MarshalAs(UnmanagedType.U1)] + public bool Notify; + } + /// Contains detected drive parameters. // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-disk_detection_info typedef struct _DISK_DETECTION_INFO { // DWORD SizeOfDetectInfo; DETECTION_TYPE DetectionType; union { struct { DISK_INT13_INFO Int13; DISK_EX_INT13_INFO ExInt13; } diff --git a/PInvoke/Kernel32/WinIOCtl.cs b/PInvoke/Kernel32/WinIOCtl.cs index c5e9e755..c486ded9 100644 --- a/PInvoke/Kernel32/WinIOCtl.cs +++ b/PInvoke/Kernel32/WinIOCtl.cs @@ -1460,7 +1460,52 @@ namespace Vanara.PInvoke /// public static uint IOCTL_CHANGER_SET_POSITION => CTL_CODE(DEVICE_TYPE.IOCTL_CHANGER_BASE, 0x0007, IOMethod.METHOD_BUFFERED, IOAccess.FILE_READ_ACCESS); - + + /// + /// Waits for all volumes on the specified disk to be ready for use. + /// To perform this operation, call the DeviceIoControl function with the following parameters. + /// Parameters + /// hDevice + /// A handle to the disk. + /// To retrieve a device handle, call the CreateFile function. + /// dwIoControlCode + /// The control code for the operation. + /// Use IOCTL_DISK_ARE_VOLUMES_READY for this operation. + /// lpInBuffer + /// Not used with this operation. Set to NULL. + /// nInBufferSize + /// The size of the input buffer, in bytes. Set to 0 (zero). + /// lpOutBuffer + /// Not used with this operation. Set to NULL. + /// nOutBufferSize + /// Not used with this operation. Set to 0 (zero). + /// lpBytesReturned + /// Not used with this operation. Set to NULL. + /// lpOverlapped + /// A pointer to an OVERLAPPED structure. + /// If hDevice was opened without specifying FILE_FLAG_OVERLAPPED, lpOverlapped is ignored. + /// + /// If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, the operation is performed as an overlapped (asynchronous) + /// operation. In this case, lpOverlapped must point to a valid OVERLAPPED structure that contains a handle to an event object. + /// Otherwise, the function fails in unpredictable ways. + /// + /// + /// For overlapped operations, DeviceIoControl returns immediately, and the event object is signaled when the operation has been + /// completed. Otherwise, the function does not return until the operation has been completed or an error occurs. + /// + /// Return value + /// + /// If the operation completes successfully, indicating that all volumes on the disk are ready for use, DeviceIoControl + /// returns a nonzero value. + /// + /// + /// If the operation fails or is pending, DeviceIoControl returns zero. To get extended error information, call GetLastError. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/fileio/ioctl-disk-are-volumes-ready + [PInvokeData("Ntdddisk.h")] + public static uint IOCTL_DISK_ARE_VOLUMES_READY => CTL_CODE(DEVICE_TYPE.FILE_DEVICE_DISK, 0x0087, IOMethod.METHOD_BUFFERED, IOAccess.FILE_READ_ACCESS | IOAccess.FILE_WRITE_ACCESS); + /// public static uint IOCTL_DISK_CHECK_VERIFY => CTL_CODE(DEVICE_TYPE.FILE_DEVICE_DISK, 0x0200, IOMethod.METHOD_BUFFERED, IOAccess.FILE_READ_ACCESS); @@ -1534,7 +1579,50 @@ namespace Vanara.PInvoke [CorrespondingType(typeof(DISK_CACHE_INFORMATION), CorrespondingAction.Get)] public static uint IOCTL_DISK_GET_CACHE_INFORMATION => CTL_CODE(DEVICE_TYPE.FILE_DEVICE_DISK, 0x0035, IOMethod.METHOD_BUFFERED, IOAccess.FILE_READ_ACCESS); - + /// + /// Retrieves the attributes of the specified disk device. + /// To perform this operation, call the DeviceIoControl function with the following parameters. + /// hDevice + /// A handle to the disk. + /// To retrieve a device handle, call the CreateFile function. + /// dwIoControlCode + /// The control code for the operation. + /// Use IOCTL_DISK_GET_CLUSTER_INFO for this operation. + /// lpInBuffer + /// Not used with this operation. Set to NULL. + /// nInBufferSize + /// The size of the input buffer, in bytes. Set to 0 (zero). + /// lpOutBuffer + /// A pointer to a buffer that receives a DISK_CLUSTER_INFO data structure. + /// nOutBufferSize + /// The size of the output buffer, in bytes. + /// lpBytesReturned + /// Not used with this operation. Set to NULL. + /// lpOverlapped + /// A pointer to an OVERLAPPED structure. + /// If hDevice was opened without specifying FILE_FLAG_OVERLAPPED, lpOverlapped is ignored. + /// + /// If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, the operation is performed as an overlapped (asynchronous) + /// operation. In this case, lpOverlapped must point to a valid OVERLAPPED structure that contains a handle to an event + /// object. Otherwise, the function fails in unpredictable ways. + /// + /// + /// For overlapped operations, DeviceIoControl returns immediately, and the event object is signaled when the operation + /// has been completed. Otherwise, the function does not return until the operation has been completed or an error occurs. + /// + /// + /// If the operation completes successfully, indicating that all volumes on the disk are ready for use, DeviceIoControl + /// returns a nonzero value. + /// + /// + /// If the operation fails or is pending, DeviceIoControl returns zero. To get extended error information, call GetLastError. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/fileio/ioctl-disk-get-cluster-info + [PInvokeData("Ntdddisk.h")] + [CorrespondingType(typeof(DISK_CLUSTER_INFO), CorrespondingAction.Get)] + public static uint IOCTL_DISK_GET_CLUSTER_INFO => CTL_CODE(DEVICE_TYPE.FILE_DEVICE_DISK, 0x0085, IOMethod.METHOD_BUFFERED, IOAccess.FILE_ANY_ACCESS); + /// public static uint IOCTL_DISK_GET_DISK_ATTRIBUTES => CTL_CODE(DEVICE_TYPE.FILE_DEVICE_DISK, 0x003c, IOMethod.METHOD_BUFFERED, IOAccess.FILE_ANY_ACCESS); @@ -1595,32 +1683,32 @@ namespace Vanara.PInvoke public static uint IOCTL_DISK_GET_DRIVE_GEOMETRY_EX => CTL_CODE(DEVICE_TYPE.FILE_DEVICE_DISK, 0x0028, IOMethod.METHOD_BUFFERED, IOAccess.FILE_ANY_ACCESS); /// - /// Retrieves information for each entry in the partition tables for a disk. - /// - /// NoteIOCTL_DISK_GET_DRIVE_LAYOUT has been superseded by IOCTL_DISK_GET_DRIVE_LAYOUT_EX, which retrieves layout - /// information for AT and EFI (Extensible Firmware Interface) partitions. - /// - /// - /// To perform this operation, call the DeviceIoControl function with the following parameters. You must have read access to the - /// drive in order to use this control code. - /// - /// Major Code - /// IRP_MJ_DEVICE_CONTROL - /// Input Buffer - /// Input Buffer Length - /// Output Buffer - /// Output Buffer Length - /// Input / Output Buffer - /// Input / Output Buffer Length - /// Status Block - /// Irp->IoStatus.Status is set to STATUS_SUCCESS if the request is successful. - /// Otherwise, Status to the appropriate error condition as a NTSTATUS code. - /// For more information, see NTSTATUS Values. - /// - /// - /// This operation retrieves information for each primary partition as well as each logical drive. To determine whether the entry - /// is an extended or unused partition, check the disk partition type. - /// + /// Retrieves information for each entry in the partition tables for a disk. + /// + /// NoteIOCTL_DISK_GET_DRIVE_LAYOUT has been superseded by IOCTL_DISK_GET_DRIVE_LAYOUT_EX, which retrieves layout + /// information for AT and EFI (Extensible Firmware Interface) partitions. + /// + /// + /// To perform this operation, call the DeviceIoControl function with the following parameters. You must have read access to the + /// drive in order to use this control code. + /// + /// Major Code + /// IRP_MJ_DEVICE_CONTROL + /// Input Buffer + /// Input Buffer Length + /// Output Buffer + /// Output Buffer Length + /// Input / Output Buffer + /// Input / Output Buffer Length + /// Status Block + /// Irp->IoStatus.Status is set to STATUS_SUCCESS if the request is successful. + /// Otherwise, Status to the appropriate error condition as a NTSTATUS code. + /// For more information, see NTSTATUS Values. + /// + /// + /// This operation retrieves information for each primary partition as well as each logical drive. To determine whether the entry + /// is an extended or unused partition, check the disk partition type. + /// // https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ni-winioctl-ioctl_disk_get_drive_layout [PInvokeData("winioctl.h", MSDNShortId = "6c1bc445-3cd1-4f86-a36b-f74ad8f4d2e5")] [CorrespondingType(typeof(DRIVE_LAYOUT_INFORMATION), CorrespondingAction.Get)] @@ -1905,7 +1993,53 @@ namespace Vanara.PInvoke /// public static uint IOCTL_DISK_SET_CACHE_INFORMATION => CTL_CODE(DEVICE_TYPE.FILE_DEVICE_DISK, 0x0036, IOMethod.METHOD_BUFFERED, IOAccess.FILE_READ_ACCESS | IOAccess.FILE_WRITE_ACCESS); - + + /// + /// Sets the cluster information on a disk. + /// To perform this operation, call the DeviceIoControl function with the following parameters. + /// Parameters + /// hDevice + /// A handle to the disk. + /// To retrieve a device handle, call the CreateFile function. + /// dwIoControlCode + /// The control code for the operation. + /// Use IOCTL_DISK_SET_CLUSTER_INFO for this operation. + /// lpInBuffer + /// A pointer to a DISK_CLUSTER_INFO data structure that contains cluster information for the disk. + /// nInBufferSize + /// The size of the input buffer, in bytes. + /// lpOutBuffer + /// Not used with this operation. Set to NULL. + /// nOutBufferSize + /// The size of the output buffer, in bytes. Set to 0 (zero). + /// lpBytesReturned + /// Not used with this operation. Set to NULL. + /// lpOverlapped + /// A pointer to an OVERLAPPED structure. + /// If hDevice was opened without specifying FILE_FLAG_OVERLAPPED, lpOverlapped is ignored. + /// + /// If hDevice was opened with the FILE_FLAG_OVERLAPPED flag, the operation is performed as an overlapped (asynchronous) + /// operation. In this case, lpOverlapped must point to a valid OVERLAPPED structure that contains a handle to an event object. + /// Otherwise, the function fails in unpredictable ways. + /// + /// + /// For overlapped operations, DeviceIoControl returns immediately, and the event object is signaled when the operation has been + /// completed. Otherwise, the function does not return until the operation has been completed or an error occurs. + /// + /// Return value + /// + /// If the operation completes successfully, indicating that all volumes on the disk are ready for use, DeviceIoControl + /// returns a nonzero value. + /// + /// + /// If the operation fails or is pending, DeviceIoControl returns zero. To get extended error information, call GetLastError. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/fileio/ioctl-disk-set-cluster-info + [PInvokeData("Ntdddisk.h")] + [CorrespondingType(typeof(DISK_CLUSTER_INFO), CorrespondingAction.Set)] + public static uint IOCTL_DISK_SET_CLUSTER_INFO => CTL_CODE(DEVICE_TYPE.FILE_DEVICE_DISK, 0x0086, IOMethod.METHOD_BUFFERED, IOAccess.FILE_ANY_ACCESS); + /// public static uint IOCTL_DISK_SET_DISK_ATTRIBUTES => CTL_CODE(DEVICE_TYPE.FILE_DEVICE_DISK, 0x003d, IOMethod.METHOD_BUFFERED, IOAccess.FILE_READ_ACCESS | IOAccess.FILE_WRITE_ACCESS);