首页 > 解决方案 > How to programmatically differentiate between dvd or mini dvd disk inserted?

问题描述

I need to get a capacity of inserted DVD disk.

DeviceIoControl function call with IOCTL_DISK_GET_DRIVE_GEOMETRY_EX parameter writes 4128768 bytes as a size of DVD what, obviously, is wrong result. Code was taken from https://docs.microsoft.com/en-us/windows/win32/devio/calling-deviceiocontrol.

Another solution was to determine disk read or write speed via ckMMC lib's Device interface and return size depending on it's type. But it isn't reliable solution since speed can vary on different CD/DVD drives.

Maybe, I'm missing something with DeviceIoControl usage and it can return me correct result or there exists better approach to calculate DVD disk's capacity.

标签: c++windowswinapidvd

解决方案


There is a field DiskSize in DVD_LAYER_DESCRIPTOR, which I was looking for.

Firstly, we should open drive with correct permissions.

HANDLE drive = CreateFileW(devicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr);

Be careful with devicePath, it should be in Win32 Device Namespace. After getting drive handle, with the help of DeviceIoControl get DVD_LAYER_DESCRIPTOR structure.

DWORD unused;
std::array<char, 22> buffer;
DVD_READ_STRUCTURE dvdReadStruct;
dvdReadStruct.Format = DvdPhysicalDescriptor;

DeviceIoControl(drive, IOCTL_DVD_READ_STRUCTURE, &dvdReadStruct, sizeof(dvdReadStruct),
                         buffer.data(), buffer.size(), &unused, nullptr))

DVD_LAYER_DESCRIPTOR layerDescription = *reinterpret_cast<DVD_LAYER_DESCRIPTOR *>(
        reinterpret_cast<DVD_DESCRIPTOR_HEADER *>(buffer.data())->Data);
CloseHandle(drive);

dvdReadStruct.Format determines which structure will be written to buffer. For example, if you will set DvdManufacturerDescriptor, function writes DVD_MANUFACTURER_DESCRIPTOR to buffer.


推荐阅读