【问题标题】:How to read a multi-session DVD disk size in Windows?如何在 Windows 中读取多会话 DVD 磁盘大小?
【发布时间】:2010-10-24 08:58:12
【问题描述】:

尝试使用 GetDiskFreeSpaceEx() 读取在多个会话中创建的磁盘大小只会给出最后一个会话的大小。如何正确读取 C/C++ 中所有会话的数量和大小?

谢谢。

【问题讨论】:

  • 您想知道每个单独会话的大小,还是只知道整个磁盘的大小?

标签: c++ winapi diskspace cddvd


【解决方案1】:

您可能想查看DeviceIoControl API 函数。有关控制代码,请参阅hereHere 是一个检索 CD 磁盘大小的代码示例。替换

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

例如

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

如果你愿意。

注意:该页面上说DeviceIoControl 可用于“检索有关软盘驱动器、硬盘驱动器、磁带驱动器或 CD-ROM 驱动器的信息”,但我也有在 DVD 上对其进行了测试,它似乎工作得很好。我无法访问任何要测试的多区段 DVD,因此您必须自己测试它是否有效。如果它不起作用,我会尝试其他一些控制代码,至少IOCTL_DISK_GET_DRIVE_GEOMETRY_EXIOCTL_DISK_GET_DRIVE_LAYOUT_EXIOCTL_DISK_GET_LENGTH_INFOIOCTL_DISK_GET_PARTITION_INFO_EX


如果 DeviceIoControl 都失败了,您可以使用 Windows Image Mastering API (IMAPI)。您需要 API 的 v2(包括在 Vista 和更高版本中,也可以添加到 XP 和 2003,参见此处:What's new in IMAPIv2)以获得 DVD 支持。此 API 主要用于 CD 刻录,但可能包含一些用于检索磁盘大小的功能,如果没有,我会觉得很奇怪。特别是,this 的例子似乎很有趣。我不知道这是否也适用于多会话磁盘,但由于它可以创建它们,我想它很可能。

以下是 IMAPI 的一些资源:
MSDN - IMAPI
MSDN - IMAPI interfaces
MSDN - Creating multisession disks with IMAPI(注意:示例使用 VB,而不是 C 或 C++)

【讨论】:

  • 我认为你的答案应该得到赏金。
【解决方案2】:

嘿,我为您找到了至少 2 个解决方案:

1) 从http://fy.chalmers.se/~appro/linux/DVD+RW/tools/win32/ 下载dvd+rw-mediainfo.exe,这是一个读取光盘信息的工具。然后只需从您的应用程序进行系统调用并解析结果。这是示例输出:

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)从[DllImport("winmm.dll", EntryPoint = "mciSendStringA", CharSet = CharSet.Ansi)]调查mciSendString,我怀疑你可以发送一些命令并得到想要的结果。

PS:当然你可以从here下载dvd+rw-mediainfo.exe的源代码并进一步研究,我只是给你一些想法。

更新

源代码链接已更新,感谢@oystein

【讨论】:

  • OP 显然是从 C++ 和 WinAPI 发布的,不需要提供 P/Invoke。
  • 如果您再次阅读我的评论,您会注意到我的 PS 是在查看源代码。我不读cpp,只是想帮忙。像你这样的混蛋只是拖钓任何善意
  • 那是 mkisofs 的来源,而不是您发布的程序。可以下载源代码here - 你可能想编辑你的帖子
【解决方案3】:

有很多方法可以做到这一点,因为由于遗留问题和向后兼容性问题,DVD 驱动器有多个接口。

您可以将 IOCTL_SCSI_PASSTHROUGH_DIRECT 命令发送到 DVD 驱动器(它的物理设备句柄)。使用它您可以发出一个 SCSI 命令,该命令将由驱动器响应。您可以读取会话信息、磁盘信息磁盘容量等。 我相信 dvd+rw-mediainfo.exe 会发出这些。

不幸的是,界面有点棘手和晦涩,因为它是命令中的命令。直通有一个字节缓冲区,您必须自己填写命令结构。

或者您可以调用 IOCTL_CDROM_READ_TOC_EX: http://www.osronline.com/ddkx/storage/k306_2cs2.htm

我也相信 IOCTL / 命令的确切集合取决于驱动器及其固件。

较旧的驱动器将不支持较新的接口,并且一些较新的驱动器将不支持旧接口。

因此,一些库和工具可能会使用这些接口中的一个或多个。

访问旧的 sesson 真的很麻烦,因为大多数操作系统不会关心它们,只关心最新的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-06
    • 1970-01-01
    • 2018-09-17
    • 2018-12-04
    • 1970-01-01
    • 1970-01-01
    • 2012-09-13
    • 2013-06-26
    相关资源
    最近更新 更多