문제

Trying to read the sizes of disks that were created in multiple sessions using GetDiskFreeSpaceEx() gives the size of the last session only. How do I read correctly the number and sizes of all sessions in C/C++?

Thanks.

도움이 되었습니까?

해결책

You might want to look at the DeviceIoControl API function. See here for control codes. Here is a code example that retrieves the size of a CD disk. Substitute

CreateFile(TEXT("\\\\.\\PhysicalDrive0")

for e.g.

CreateFile(TEXT("\\\\.\\F:") /* Drive is F: */

if you wish.

Note: The page says that DeviceIoControl can be used to "retrieve information about a floppy disk drive, hard disk drive, tape drive, or CD-ROM drive", but I have also tested it on a DVD, and it seemed to work perfectly. I did not have access to any multisession DVDs to test, so you'll have to test if that works yourself. If it doesn't work, I'd try some of the other control codes, at least IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, IOCTL_DISK_GET_LENGTH_INFO and IOCTL_DISK_GET_PARTITION_INFO_EX.


If all fails with DeviceIoControl, you could possibly make use of the Windows Image Mastering API (IMAPI). You'll need v2 of the API (included with Vista & later, can be added to XP & 2003 too, see here: What's new in IMAPIv2) for DVD support. This API is primarily for CD burning, but does perhaps contain some functionality for retrieving disk size, I'd find it weird if it didn't. Particularly, this example seems to be interesting. I do not know if this one works for multisession disks either, but since it can create them, I guess it's likely.

Here are some resources for IMAPI:
MSDN - IMAPI
MSDN - IMAPI interfaces
MSDN - Creating multisession disks with IMAPI (note: example with VB, not C or C++)

다른 팁

Hey I got at least 2 solutions for you:

1) Download dvd+rw-mediainfo.exe from http://fy.chalmers.se/~appro/linux/DVD+RW/tools/win32/, it's a tool that reads info about your disc. Then just make a system call from your app and parse the results. Here's example output:

D:\Downloads>"dvd+rw-mediainfo.exe" f:
INQUIRY:                [HL-DT-ST][DVDRAM GT30N    ][1.01]
GET [CURRENT] CONFIGURATION:
 Mounted Media:         10h, DVD-ROM
 Current Write Speed:   1.0x1385=1385KB/s
 Write Speed #0:        8.0x1385=11080KB/s
 Write Speed #1:        4.0x1385=5540KB/s
 Write Speed #2:        2.0x1385=2770KB/s
 Write Speed #3:        1.0x1385=1385KB/s
 Speed Descriptor#0:    00/2292991 R@8.0x1385=11080KB/s W@8.0x1385=11080KB/s
READ DVD STRUCTURE[#0h]:
 Media Book Type:       01h, DVD-ROM book [revision 1]
 Legacy lead-out at:    2292992*2KB=4696047616
READ DISC INFORMATION:
 Disc status:           complete
 Number of Sessions:    1
 State of Last Session: complete
 Number of Tracks:      1
READ TRACK INFORMATION[#1]:
 Track State:           complete
 Track Start Address:   0*2KB
 Free Blocks:           0*2KB
 Track Size:            2292992*2KB
 Last Recorded Address: 2292991*2KB
FABRICATED TOC:
 Track#1  :             17@0
 Track#AA :             17@2292992
 Multi-session Info:    #1@0
READ CAPACITY:          2292992*2048=4696047616

2) Investigate mciSendString from [DllImport("winmm.dll", EntryPoint = "mciSendStringA", CharSet = CharSet.Ansi)], I suspect you can send some command and get the desired results.

PS: of course you may download dvd+rw-mediainfo.exe sources from here and investigate further, I am just giving you ideas to think of.

UPDATE

Link to source code updated, thanks @oystein

There are many way to do this since the DVD drives have several interfaces for this due to legacy and backward-compatibility issues.

You could send an IOCTL_SCSI_PASSTHROUGH_DIRECT command to the DVD-drive ( the physicaldevice handle for it). With it you issue a SCSI commands that will be answered by the drive. You can read session information, disk information disk capcity and more. I believe that dvd+rw-mediainfo.exe issues these.

Unfortunatly, the interface is a bit tricky and obscure, since it is a command within a command. Th passthrough has a byte buffer you will have to fill in yourself with the command structure.

Or you can call IOCTL_CDROM_READ_TOC_EX: http://www.osronline.com/ddkx/storage/k306_2cs2.htm

I also believe that the exact set of the IOCTL / commands that will work depends on on the drive and its firmaware.

Older drives will not support the newr interfaces and some of the newer drives will not support legacy interfaces.

Thus, some of the libraries & tools might use one or more of these interfaces.

Accseeing the older sessons is all quite messy, really, since most OS will not care about them, only the most recent ones.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top