Python-Windows原始磁盘无法读取最终扇区

Python-Windows原始磁盘无法读取最终扇区,python,windows,winapi,cd-rom,iso9660,Python,Windows,Winapi,Cd Rom,Iso9660,当通过Pythonopen()访问Windows上的原始磁盘时,无论出于何种原因,它都不允许我读取最后的10240字节(即2048字节/扇区的最后5个扇区) 当通过其他方式转储光盘映像并比较映像时,我可以看到数据也不能假定为空。事实上,缺少的第一个扇区中有一个UDF锚定标记,其中包含相关元数据。以下部分完全是空白 这就是我转储光盘内容的方式: out=open(“test.iso”、“wb”) 以开放式(r“\\.\D:,“rb”)作为f: 尽管如此: 数据=f.read(512) 如果len(

当通过Python
open()
访问Windows上的原始磁盘时,无论出于何种原因,它都不允许我读取最后的10240字节(即2048字节/扇区的最后5个扇区)

当通过其他方式转储光盘映像并比较映像时,我可以看到数据也不能假定为空。事实上,缺少的第一个扇区中有一个UDF锚定标记,其中包含相关元数据。以下部分完全是空白

这就是我转储光盘内容的方式:

out=open(“test.iso”、“wb”)
以开放式(r“\\.\D:,“rb”)作为f:
尽管如此:
数据=f.read(512)
如果len(数据)==0:
打破
out.写入(数据)
如果我取同一个open()对象并告诉它搜索到光盘的最末端,它会这样做。因此,它可以明确地接触到各行业,至少在寻求帮助方面是如此。如果我随后返回10240字节,然后尝试
f.read(…)
,它将返回
b''
(空结果),而不是错误。我让它读多大也没关系。我尝试了各种尺寸,没有参数/默认值,1、12、255、512、2048、999999等等

另一个不同(但相关)问题的StackOverflow也报告了增强型音频光盘的类似发现,但此后似乎没有进行讨论

我已经在不同类型的工作室和创作者的多张DVD光盘上测试了这一点,所有这些都处于良好的状态,它仍然在发生

复制代码示例:

  • 我不知道这是否会发生在你的系统配置/光盘/阅读器上)
  • PyPI依赖项:wmic
  • WMIC也报告了光盘大小为10240,可能是Windows的问题
导入操作系统
从wmi导入wmi
DISC_LETTER=“D:”
c=WMI()
光盘信息=下一个(iter(c.Win32光盘驱动器(驱动器=光盘字母)),无)
如果不是光盘信息:
升起(“未找到光盘%s…”,光盘字母)
光盘大小=整数(光盘信息大小)
disc_size+=10240#WMIC也会报告没有10240的大小,但它是真实的!
f=打开(r“\\.\%s”%DISC\U字母,“rb”)
f、 搜索(磁盘大小)
如果f.tell()==光盘大小:
打印(“查找到光盘末尾…”)
f、 寻道(-10240,操作系统寻道)
如果f.tell()==光盘大小-(2048*5):
打印(“在光盘末尾之前查找5个扇区…”)
数据=f.read(2048*5):
打印(“数据读取(长度:%d):%b”%(长度(数据),数据))

任何关于这可能是什么的想法都会很好,因为我已经尝试了所有我可以尝试的地方。

这似乎发生在
打开(r'\.\N:')
以受限边界打开设备时

我的解决方案是用IOCTL而不是open()打开光盘。特别是,和

handle=win32file.CreateFile(
r“\\.\D:”,
win32con.允许的最大值,
win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE,
没有一个
win32con.OPEN_存在,
win32con.FILE_属性_正常,
没有一个
)
如果handle==win32file.INVALID\u handle\u值:
引发运行时错误(“无法获取设备句柄…”)
win32file.DeviceIoControl(句柄,winioctlcon.FSCTL\u允许\u扩展\u数据\u IO,无,无)
在这里,我可以分别使用和替换read和seek

我甚至开发了一个新类,它可以加载所有内容,并允许您动态读取和查找,而无需担心扇区对齐

类Win32Device:
"""
类来读取和查找Windows原始设备IO对象,而无需麻烦。
它涉及到获得完整的规模,允许所有部门的完全访问,
并与光盘扇区大小对齐。
作者:凤凰
许可证:免费,享受!这应该是open()默认做的事情。
"""
定义初始(自我,目标):
#类型:(str)->None
self.target=目标
self.sector\u size=无
self.disc_size=无
self.position=0
self.handle=self.get\u handle()
self.geometry=self.get_geometry()
定义输入(自我):
回归自我
定义uuu退出uuu(自我、*uu、***uu):
self.dispose()
定义长度(自)->int:
返回自几何体[-2]
def处置(自我):
如果自行处理!=win32file.0无效的\u句柄\u值:
win32file.CloseHandle(self.handle)
def get_目标(自我):
#类型:()->str
“”“获取UNC目标名称。可以是`E:`或`PhysicalDriveN`。”
target=self.target
如果不是target.startswith(“\\\.\\”):
target+=rf“\\.\{target}”
返回目标
def get_句柄(自身):
#类型:()->int
“”“获取原始UNC目标的直接句柄,并解锁其IO功能。”“”
handle=win32file.CreateFile(
# https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
self.get_target(),#target
win32con.MAXIMUM#允许,#所需访问权限
win32con.FILE_SHARE_READ|win32con.FILE_SHARE_WRITE,#共享模式,需要写入
无,#安全属性
win32con.OPEN#已存在,#创建配置
win32con.FILE_ATTRIBUTE_NORMAL,#标志和属性
无#模板文件
)
如果handle==win32file.INVALID\u handle\u值:
引发运行时错误(“无法获取设备句柄…”)
#提升可访问的扇区,否则最后5个扇区(在我的例子中)将无法读取
win32file.DeviceIoControl(句柄,winioctlcon.FSCTL\u允许\u扩展\u数据\u IO,无,无)
返回手柄
def get_几何体(自):
#类型:()->元组[int,…]
"""
检索有关物理磁盘几何体的信息。
https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-disk_geometry_ex
返回以下内容的元组:
气缸Lo
气缸Hi
媒体类型
每个气缸的轨迹
每轨扇区数
每个扇区的字节数
磁盘大小
额外的