如何在 C# 中使用 DeviceIoControl 和 FSCTL_MAKE_MEDIA_COMPATIBLE 完成 Live File System (LiveUDF) 光盘?

Posted

技术标签:

【中文标题】如何在 C# 中使用 DeviceIoControl 和 FSCTL_MAKE_MEDIA_COMPATIBLE 完成 Live File System (LiveUDF) 光盘?【英文标题】:How to finalize Live File System (LiveUDF) disc with DeviceIoControl and FSCTL_MAKE_MEDIA_COMPATIBLE in C#? 【发布时间】:2012-08-17 07:39:15 【问题描述】:

我正在尝试用 C# 完成 Live File System(或“Live UDF”)光盘。根据我阅读 MSDN 和 TechNet 文章以及各种论坛帖子的了解,Image Mastering API(或 IMAPI)不支持这种类型的文件系统,并且在我的编码工作中,我未能成功使用 IMAPI 完成 LiveUDF 光盘。因此,我使用了使用 FSCTL_MAKE_MEDIA_COMPATIBLE 控制代码的 DeviceIoControl 函数。

首先,我正在同步调用 DeviceIoControl,但该函数将返回 1117,并且磁盘最终会在几分钟后完成。这种结果是不可接受的,因为我需要该过程仅在最终失败或实际成功时返回。

接下来,我继续异步调用 DeviceIoControl,方法是使用带有 FILE_FLAG_OVERLAPPED (0x40000000) dwFlagsAndAttributes 标志的 CreateFile 打开设备句柄,并将 NativeOverlapped 对象传递给 DeviceIoControl 调用。在此之前,很明显,我设置了一个 IOCompletionCallback 来处理任何 Overlapped 事件。

按照描述的异步调用 DeviceIoControl,它仍然几乎立即返回 1117(就像同步调用时一样),永远不会调用 IOCompletionCallback 方法,并且磁盘会在几分钟后完成。

我的问题是:如何在 Windows 7 平台上使用 C# 和 DeviceIoControl(同步或异步,具有“等待" 完成它的过程以捕获最终的成功或失败结果)?

非常感谢。

【问题讨论】:

【参考方案1】:

调用 DeviceIoControl 传递 IOCTL_SCSI_PASS_THROUGH_DIRECT 控制代码和用 Close Track/Session SCSI 定义的 SCSI_PASS_THROUGH_DIRECT 结构MultiMedia Command (MMC) 提供了一种方法来完成 Live UDF 光盘,并在最终成功或失败时返回 DeviceIoControl 函数。

我在阅读INCITS T10 Technical Committee 的 SCSI 多媒体命令提案和http://sourceforge.net/projects/bwgburn/ 的项目时将其拼凑在一起。

基本上,它只是向设备发送 SCSI 命令(在委员会的提案中定义)。

【讨论】:

【参考方案2】:

我最近遇到了同样的问题,发现刻录完成后可以使用 IMAPI2.MsftDiscFormat2Data 的 .ForceMediaToBeClosed 来完成 CD。这是我的代码(在 powershell 中):

$TargetFolder="c:\path\to\files\to\be\burned"
$DiskMaster = New-Object -com IMAPI2.MsftDiscMaster2
$DiscRecorder = New-Object -com IMAPI2.MsftDiscRecorder2
$id = $DiskMaster.Item(0) #specify drive index here
$DiscRecorder.InitializeDiscRecorder($id)               
$FileSystemImage = New-Object -com IMAPI2FS.MsftFileSystemImage
$dir = $FileSystemImage.Root
$DiscFormatData  = New-Object -com IMAPI2.MsftDiscFormat2Data
$DiscFormatData.Recorder = $DiscRecorder
$DiscFormatData.ClientName = 'cd label' #specify cd label here
$DiscFormatData.ForceMediaToBeClosed = $true   #to finalize cd after burn
$FileSystemImage.ChooseImageDefaults($DiscRecorder)                
$dir.AddTree($TargetFolder, $false)
$result = $FileSystemImage.CreateResultImage()
$stream = $result.ImageStream
$DiscFormatData.Write($stream)

【讨论】:

以上是关于如何在 C# 中使用 DeviceIoControl 和 FSCTL_MAKE_MEDIA_COMPATIBLE 完成 Live File System (LiveUDF) 光盘?的主要内容,如果未能解决你的问题,请参考以下文章

如何在网站项目中使用 C# 7? [复制]

如何在 C# 中使用 libcinder?

如何在 C# 中使用 imageMagick

我如何在 webBrowser 中使用 c# 执行点击事件

如何使用 SMO 在存储过程中调用 c# 函数?

如何在打字稿中使用 C# 字典?