• Windows VHD Create, Attach, 获得Disk序号


    // create_vhd.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <Windows.h>
    #include <Shlwapi.h>
    #include <initguid.h>
    #include <virtdisk.h>
    #include <sddl.h>
    
    DWORD
    SampleCreateVirtualDisk(
        _In_        LPCWSTR                     VirtualDiskPath,
        _In_opt_    LPCWSTR                     ParentPath,
        _In_        CREATE_VIRTUAL_DISK_FLAG    Flags,
        _In_        ULONGLONG                   FileSize,
        _In_        DWORD                       BlockSize,
        _In_        DWORD                       LogicalSectorSize,
        _In_        DWORD                       PhysicalSectorSize)
    {
        VIRTUAL_STORAGE_TYPE storageType;
        CREATE_VIRTUAL_DISK_PARAMETERS parameters;
        HANDLE vhdHandle = INVALID_HANDLE_VALUE;
        DWORD opStatus;
        GUID uniqueId;
    
        if (RPC_S_OK != UuidCreate((UUID*)&uniqueId))
        {
            opStatus = ERROR_NOT_ENOUGH_MEMORY;
            goto Cleanup;
        }
    
        //
        // Specify UNKNOWN for both device and vendor so the system will use the
        // file extension to determine the correct VHD format.
        //
    
        storageType.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN;
        storageType.VendorId = VIRTUAL_STORAGE_TYPE_VENDOR_UNKNOWN;
    
        memset(&parameters, 0, sizeof(parameters));
    
        //
        // CREATE_VIRTUAL_DISK_VERSION_2 allows specifying a richer set a values and returns
        // a V2 handle.
        //
        // VIRTUAL_DISK_ACCESS_NONE is the only acceptable access mask for V2 handle opens.
        //
        // Valid BlockSize values are as follows (use 0 to indicate default value):
        //      Fixed VHD: 0
        //      Dynamic VHD: 512kb, 2mb (default)
        //      Differencing VHD: 512kb, 2mb (if parent is fixed, default is 2mb; if parent is dynamic or differencing, default is parent blocksize)
        //      Fixed VHDX: 0
        //      Dynamic VHDX: 1mb, 2mb, 4mb, 8mb, 16mb, 32mb (default), 64mb, 128mb, 256mb
        //      Differencing VHDX: 1mb, 2mb (default), 4mb, 8mb, 16mb, 32mb, 64mb, 128mb, 256mb
        //
        // Valid LogicalSectorSize values are as follows (use 0 to indicate default value):
        //      VHD: 512 (default)
        //      VHDX: 512 (for fixed or dynamic, default is 512; for differencing, default is parent logicalsectorsize), 4096
        //
        // Valid PhysicalSectorSize values are as follows (use 0 to indicate default value):
        //      VHD: 512 (default)
        //      VHDX: 512, 4096 (for fixed or dynamic, default is 4096; for differencing, default is parent physicalsectorsize)
        //
        parameters.Version = CREATE_VIRTUAL_DISK_VERSION_2;
        parameters.Version2.UniqueId = uniqueId;
        parameters.Version2.MaximumSize = FileSize;
        parameters.Version2.BlockSizeInBytes = BlockSize;
        parameters.Version2.SectorSizeInBytes = LogicalSectorSize;
        parameters.Version2.PhysicalSectorSizeInBytes = PhysicalSectorSize;
        parameters.Version2.ParentPath = ParentPath;
    
        opStatus = CreateVirtualDisk(
            &storageType,
            VirtualDiskPath,
            VIRTUAL_DISK_ACCESS_NONE,
            NULL,
            Flags,
            0,
            &parameters,
            NULL,
            &vhdHandle);
    
        if (opStatus != ERROR_SUCCESS)
        {
            goto Cleanup;
        }
    
    Cleanup:
    
        if (opStatus == ERROR_SUCCESS)
        {
            wprintf(L"Create success
    ");
        }
        else
        {
            wprintf(L"Create error = %u
    ", opStatus);
        }
    
        if (vhdHandle != INVALID_HANDLE_VALUE)
        {
            printf("%s: Handle closed.
    ", __func__);
            CloseHandle(vhdHandle);
        }
    
        return opStatus;
    }
    
    
    int make_vhd()
    {
        GUID myGUID;
        HRESULT h = CoCreateGuid(&myGUID);
        if (h != S_OK)
            printf("Failed to generate GUID.
    ");
    
        OLECHAR* guidString;
        StringFromCLSID(myGUID, &guidString);
        printf("%ls
    ", guidString);
    
        VIRTUAL_STORAGE_TYPE           VirtualStorageType;
        VirtualStorageType.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN;
        VirtualStorageType.VendorId = VIRTUAL_STORAGE_TYPE_VENDOR_UNKNOWN;
    
        PCWSTR                          Path = L"c:\vhd_test.vhd";
    
        VIRTUAL_DISK_ACCESS_MASK        VirtualDiskAccessMask = VIRTUAL_DISK_ACCESS_NONE;
    
        PSECURITY_DESCRIPTOR            SecurityDescriptor = NULL;
    
        CREATE_VIRTUAL_DISK_FLAG        Flags = CREATE_VIRTUAL_DISK_FLAG_FULL_PHYSICAL_ALLOCATION;
        //CREATE_VIRTUAL_DISK_FLAG        Flags = CREATE_VIRTUAL_DISK_FLAG_NONE;
    
        ULONG                           ProviderSpecificFlags = 0;
    
        printf("sizeof(PCREATE_VIRTUAL_DISK_PARAMETERS) %zd
    ", sizeof(_CREATE_VIRTUAL_DISK_PARAMETERS));
        PCREATE_VIRTUAL_DISK_PARAMETERS Parameters = (PCREATE_VIRTUAL_DISK_PARAMETERS)malloc(sizeof(_CREATE_VIRTUAL_DISK_PARAMETERS));
        memset(Parameters, 0, sizeof(_CREATE_VIRTUAL_DISK_PARAMETERS));
    
        Parameters->Version = CREATE_VIRTUAL_DISK_VERSION_2;
    
        Parameters->Version2.UniqueId = myGUID;
        StringFromCLSID(Parameters->Version2.UniqueId, &guidString);
        printf("Parameters->Version2.UniqueId %ls
    ", guidString);
    
        Parameters->Version2.MaximumSize = 0x200000000;
        Parameters->Version2.BlockSizeInBytes = 0;
        Parameters->Version2.SectorSizeInBytes = 0;
        Parameters->Version2.PhysicalSectorSizeInBytes = 0;
        Parameters->Version2.OpenFlags = OPEN_VIRTUAL_DISK_FLAG_NONE;
        Parameters->Version2.ParentPath = NULL;
        Parameters->Version2.SourcePath = NULL;
    
        LPOVERLAPPED                    Overlapped = NULL;
    
        PHANDLE                         Handle = NULL;
    
        DWORD ret = CreateVirtualDisk(
            &VirtualStorageType,
            Path,
            VirtualDiskAccessMask,
            SecurityDescriptor,
            Flags,
            ProviderSpecificFlags,
            Parameters,
            Overlapped,
            Handle
        );
    
        if(ret != ERROR_SUCCESS)
        {
            printf("%s: CreateVirtualDisk failed (%d)
    ", __func__, ret);
        }
    
        return 0;
    }
    
    DWORD
    SampleAttachVirtualDisk(
        _In_    LPCWSTR     VirtualDiskPath,
        _In_    BOOLEAN     ReadOnly)
    {
        OPEN_VIRTUAL_DISK_PARAMETERS openParameters;
        VIRTUAL_DISK_ACCESS_MASK accessMask;
        ATTACH_VIRTUAL_DISK_PARAMETERS attachParameters;
        PSECURITY_DESCRIPTOR sd;
        VIRTUAL_STORAGE_TYPE storageType;
        LPCTSTR extension;
        HANDLE vhdHandle;
        ATTACH_VIRTUAL_DISK_FLAG attachFlags;
        DWORD opStatus;
    
        vhdHandle = INVALID_HANDLE_VALUE;
        sd = NULL;
    
        //
        // Specify UNKNOWN for both device and vendor so the system will use the
        // file extension to determine the correct VHD format.
        //
    
        storageType.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN;
        storageType.VendorId = VIRTUAL_STORAGE_TYPE_VENDOR_UNKNOWN;
    
        memset(&openParameters, 0, sizeof(openParameters));
    
        extension = ::PathFindExtension(VirtualDiskPath);
    
        if (extension != NULL && _wcsicmp(extension, L".iso") == 0)
        {
            //
            // ISO files can only be mounted read-only and using the V1 API.
            //
    
            if (ReadOnly != TRUE)
            {
                opStatus = ERROR_NOT_SUPPORTED;
                goto Cleanup;
            }
    
            openParameters.Version = OPEN_VIRTUAL_DISK_VERSION_1;
            accessMask = VIRTUAL_DISK_ACCESS_READ;
        }
        else
        {
            //
            // VIRTUAL_DISK_ACCESS_NONE is the only acceptable access mask for V2 handle opens.
            //
    
            openParameters.Version = OPEN_VIRTUAL_DISK_VERSION_2;
            openParameters.Version2.GetInfoOnly = FALSE;
            accessMask = VIRTUAL_DISK_ACCESS_NONE;
        }
    
        //
        // Open the VHD or ISO.
        //
        // OPEN_VIRTUAL_DISK_FLAG_NONE bypasses any special handling of the open.
        //
    
        opStatus = OpenVirtualDisk(
            &storageType,
            VirtualDiskPath,
            accessMask,
            OPEN_VIRTUAL_DISK_FLAG_NONE,
            &openParameters,
            &vhdHandle);
    
        if (opStatus != ERROR_SUCCESS)
        {
            goto Cleanup;
        }
    
        //
        // Create the world-RW SD.
        //
    
        if (!::ConvertStringSecurityDescriptorToSecurityDescriptor(
            L"O:BAG:BAD:(A;;GA;;;WD)",
            SDDL_REVISION_1,
            &sd,
            NULL))
        {
            opStatus = ::GetLastError();
            goto Cleanup;
        }
    
        //
        // Attach the VHD/VHDX or ISO.
        //
    
        memset(&attachParameters, 0, sizeof(attachParameters));
        attachParameters.Version = ATTACH_VIRTUAL_DISK_VERSION_1;
    
        //
        // A "Permanent" surface persists even when the handle is closed.
        //
    
        attachFlags = ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME;
    
        if (ReadOnly)
        {
            // ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY specifies a read-only mount.
            attachFlags |= ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY;
        }
    
        opStatus = AttachVirtualDisk(
            vhdHandle,
            sd,
            attachFlags,
            0,
            &attachParameters,
            NULL);
    
        if (opStatus != ERROR_SUCCESS)
        {
            goto Cleanup;
        }
    
    Cleanup:
    
        if (opStatus == ERROR_SUCCESS)
        {
            wprintf(L"Attach success
    ");
        }
        else
        {
            wprintf(L"Attach error = %u
    ", opStatus);
        }
    
        if (sd != NULL)
        {
            LocalFree(sd);
            sd = NULL;
        }
    
        if (vhdHandle != INVALID_HANDLE_VALUE)
        {
            printf("%s: Handle closed.
    ", __func__);
            CloseHandle(vhdHandle);
        }
    
        return opStatus;
    }
    
    HANDLE DoOpenVHD(LPCWSTR VirtualDiskPath, BOOL GetInfoOnly)
    {
        HANDLE vhdHandle;
        OPEN_VIRTUAL_DISK_PARAMETERS openParameters;
        openParameters.Version = OPEN_VIRTUAL_DISK_VERSION_2;
        openParameters.Version2.GetInfoOnly = GetInfoOnly;
    
        VIRTUAL_STORAGE_TYPE storageType;
        storageType.DeviceId = VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN;
        storageType.VendorId = VIRTUAL_STORAGE_TYPE_VENDOR_UNKNOWN;
    
        int ret = OpenVirtualDisk(&storageType, VirtualDiskPath,
            VIRTUAL_DISK_ACCESS_NONE, OPEN_VIRTUAL_DISK_FLAG_NONE,
            &openParameters, &vhdHandle);
        if (ret != ERROR_SUCCESS) {
            // If return value of OpenVirtualDisk isn't ERROR_SUCCESS, there was a problem opening the VHD
            printf("Failed to open VHD %ls. (%d)
    ", VirtualDiskPath, ret);
            return NULL;
        }
        return vhdHandle;
    }
    
    int getPhyDrive(HANDLE vhdHandle)
    {
        wchar_t physicalDrive[MAX_PATH];
        ULONG bufferSize = sizeof(physicalDrive);
        GetVirtualDiskPhysicalPath(vhdHandle, &bufferSize, physicalDrive);
    
        printf("physicalDrive %ls
    ", physicalDrive);
    
        if (vhdHandle != INVALID_HANDLE_VALUE)
        {
            printf("%s: Handle closed.
    ", __func__);
            CloseHandle(vhdHandle);
        }
        
        char name[1024];
        memset(name, 0, 1024);
        snprintf(name, 1024, "%ls", physicalDrive);
        DWORD driveNumber = name[strlen(name) - 1] - '0';
        printf("Drive idx %d
    ", driveNumber);
        return driveNumber;
    }
    
    int __cdecl wmain(_In_ int argc, _In_reads_(argc) WCHAR *argv[])
    {
        int rc = 0;
        LPCWSTR virtualDiskPath = argv[1];
        LPCWSTR parentPath = NULL;
    
        ULONGLONG fileSize = _wtoi64(argv[2]);
        DWORD blockSize = _wtoi(argv[3]);
        DWORD logicalSectorSize = _wtoi(argv[4]);
        DWORD physicalSectorSize = _wtoi(argv[5]);
    
        /*rc = SampleCreateVirtualDisk(
            virtualDiskPath,
            parentPath,
            CREATE_VIRTUAL_DISK_FLAG_FULL_PHYSICAL_ALLOCATION,
            fileSize,
            blockSize,
            logicalSectorSize,
            physicalSectorSize);
    
        printf("SampleCreateVirtualDisk %d
    ", rc);
    
        rc = SampleAttachVirtualDisk(virtualDiskPath, FALSE);
        printf("SampleAttachVirtualDisk %d
    ", rc);*/
    
        //wchar_t physicalDrive[MAX_PATH];
        //ULONG bufferSize = sizeof(physicalDrive);
        HANDLE vhdHandle = DoOpenVHD(virtualDiskPath, TRUE);
        int drive_idx = getPhyDrive(vhdHandle);
        /*char name[1024];
        memset(name, 0, 1024);
        snprintf(name, 1024, "%ls", physicalDrive);
        DWORD driveNumber = name[strlen(name) - 1] - '0';
        printf("Drive idx %d
    ", driveNumber);*/
        //MountVol(drive_idx);
    
        getchar();
        return 0;
    }
  • 相关阅读:
    ASP.NET 无提示关闭窗口
    C# Winform程序获取外网IP地址
    使用System.Drawing.Printing 画报表。
    C# Winform调用IP地址、手机归属和身份证查询接口
    C# 获取文中文字符首字母
    C# WinForm给Button或其它控件添加快捷键响应
    C# 获取农历日期
    TSQL之插入的内容是查询出的值
    C# 获取中文星期的两种方法
    C#批量操作控件
  • 原文地址:https://www.cnblogs.com/liujx2019/p/12750526.html
Copyright © 2020-2023  润新知