python / python/cpython

Windows device read failure through Python file interface with read buffering enabled

未关闭
#128,111 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

OS-windows type-bug
主要语言
Python
星标
77.2k
派生
35.9k
PR 合并指标
PR 指标待抓取

描述

Bug report

Bug description:

Attempting to read the last 16 sectors from a Windows device through the Python file interface fails unexpectedly when buffering is enabled. Those same sectors seem to be accessible without issue through the WIN32 file API itself.

I've included minimal reproduction code. To demonstrate this, configure DEVICE_SECTOR_CNT and DEVICE_PATH to match a drive attached to your system:

import win32file

DEVICE_PATH = "\\\\.\\PhysicalDrive3"
DEVICE_SECTOR_CNT = 62333952
DEVICE_SECTOR_SIZ = 512

for DEVICE_SECTOR_CHK in [DEVICE_SECTOR_CNT - 16, DEVICE_SECTOR_CNT - 15]:

	print("Read sector " + str(DEVICE_SECTOR_CHK) + " through win32file:")
	try:
		handle = win32file.CreateFile(
			DEVICE_PATH,
			win32file.GENERIC_READ | win32file.GENERIC_WRITE,
			win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE,
			None,
			win32file.OPEN_EXISTING,
			0,
			None
		)
		win32file.SetFilePointer(handle, DEVICE_SECTOR_CHK * DEVICE_SECTOR_SIZ, win32file.FILE_BEGIN)
		(_, result) = win32file.ReadFile(handle, DEVICE_SECTOR_SIZ)
		print(" ".join(["{:02X}".format(x) for x in result]))
	finally:
		win32file.CloseHandle(handle)

	print("Read sector " + str(DEVICE_SECTOR_CHK) + " through open:")
	with open(DEVICE_PATH, "rb") as device:
		device.seek(DEVICE_SECTOR_CHK * DEVICE_SECTOR_SIZ)
		result = device.read(DEVICE_SECTOR_SIZ)
		print(" ".join(["{:02X}".format(x) for x in result]))

Testing this with any drive attached to my system, I see a result like:

Read sector 62333936 through win32file:
FD FF F3 FF FB FF F3 FF F9 FF F8 FF FF FF FB FF 01 00 01 00 03 00 02 00 07 00 05 00 09 00 02 00 06 00 03 00 04 00 02 00 08 00 06 00 0C 00 08 00 0D 00 07 00 0B 00 07 00 0B 00 04 00 0E 00 05 00 0D 00 04 00 0C 00 06 00 0B 00 07 00 0C 00 08 00 0D 00 07 00 0D 00 07 00 0D 00 08 00 0B 00 05 00 0B 00 04 00 0F 00 06 00 13 00 0C 00 15 00 10 00 16 00 0F 00 14 00 0E 00 14 00 0F 00 16 00 0E 00 16 00 0F 00 17 00 10 00 15 00 10 00 11 00 0F 00 13 00 0A 00 14 00 06 00 13 00 09 00 12 00 0C 00 15 00 08 00 11 00 06 00 13 00 06 00 14 00 0A 00 12 00 0D 00 14 00 0A 00 0E 00 07 00 0F 00 04 00 11 00 06 00 0F 00 08 00 0D 00 0C 00 0D 00 0A 00 0F 00 03 00 0D 00 FF FF 0B 00 FD FF 09 00 FF FF 08 00 04 00 07 00 01 00 0A 00 00 00 0C 00 FD FF 0B 00 FC FF 06 00 FE FF 02 00 FD FF 01 00 FC FF 06 00 FD FF 09 00 FA FF 06 00 FD FF 04 00 FF FF 01 00 F9 FF FE FF FC FF FF FF F8 FF 02 00 F7 FF 01 00 F7 FF FE FF FA FF FE FF F6 FF FD FF F5 FF FD FF F5 FF FB FF F5 FF FC FF F4 FF FC FF FA FF FC FF FB FF FF FF FD FF FE FF FA FF 03 00 FE FF 04 00 FD FF FD FF FD FF 01 00 FC FF 02 00 FE FF 01 00 FC FF 02 00 F8 FF 00 00 F7 FF FF FF FB FF 00 00 FB FF 01 00 F5 FF FE FF F7 FF FD FF FA FF FE FF F9 FF 00 00 F7 FF FF FF F8 FF FF FF F9 FF 01 00 F3 FF 00 00 F5 FF FE FF F7 FF FF FF F5 FF FF FF F7 FF 01 00 FD FF 00 00 FA FF FC FF F5 FF F9 FF F3 FF FB FF F2 FF FC FF F3 FF FE FF F9 FF 01 00 FD FF FE FF FE FF FF FF F4 FF FF FF F0 FF FC FF F1 FF FF FF F8 FF 03 00 04 00 04 00 03 00 06 00 FD FF 04 00 F6 FF FC FF F5 FF F8 FF F5 FF F9 FF F9 FF FC FF FD FF 02 00 FB FF 05 00 FA FF
Read sector 62333936 through open:
FD FF F3 FF FB FF F3 FF F9 FF F8 FF FF FF FB FF 01 00 01 00 03 00 02 00 07 00 05 00 09 00 02 00 06 00 03 00 04 00 02 00 08 00 06 00 0C 00 08 00 0D 00 07 00 0B 00 07 00 0B 00 04 00 0E 00 05 00 0D 00 04 00 0C 00 06 00 0B 00 07 00 0C 00 08 00 0D 00 07 00 0D 00 07 00 0D 00 08 00 0B 00 05 00 0B 00 04 00 0F 00 06 00 13 00 0C 00 15 00 10 00 16 00 0F 00 14 00 0E 00 14 00 0F 00 16 00 0E 00 16 00 0F 00 17 00 10 00 15 00 10 00 11 00 0F 00 13 00 0A 00 14 00 06 00 13 00 09 00 12 00 0C 00 15 00 08 00 11 00 06 00 13 00 06 00 14 00 0A 00 12 00 0D 00 14 00 0A 00 0E 00 07 00 0F 00 04 00 11 00 06 00 0F 00 08 00 0D 00 0C 00 0D 00 0A 00 0F 00 03 00 0D 00 FF FF 0B 00 FD FF 09 00 FF FF 08 00 04 00 07 00 01 00 0A 00 00 00 0C 00 FD FF 0B 00 FC FF 06 00 FE FF 02 00 FD FF 01 00 FC FF 06 00 FD FF 09 00 FA FF 06 00 FD FF 04 00 FF FF 01 00 F9 FF FE FF FC FF FF FF F8 FF 02 00 F7 FF 01 00 F7 FF FE FF FA FF FE FF F6 FF FD FF F5 FF FD FF F5 FF FB FF F5 FF FC FF F4 FF FC FF FA FF FC FF FB FF FF FF FD FF FE FF FA FF 03 00 FE FF 04 00 FD FF FD FF FD FF 01 00 FC FF 02 00 FE FF 01 00 FC FF 02 00 F8 FF 00 00 F7 FF FF FF FB FF 00 00 FB FF 01 00 F5 FF FE FF F7 FF FD FF FA FF FE FF F9 FF 00 00 F7 FF FF FF F8 FF FF FF F9 FF 01 00 F3 FF 00 00 F5 FF FE FF F7 FF FF FF F5 FF FF FF F7 FF 01 00 FD FF 00 00 FA FF FC FF F5 FF F9 FF F3 FF FB FF F2 FF FC FF F3 FF FE FF F9 FF 01 00 FD FF FE FF FE FF FF FF F4 FF FF FF F0 FF FC FF F1 FF FF FF F8 FF 03 00 04 00 04 00 03 00 06 00 FD FF 04 00 F6 FF FC FF F5 FF F8 FF F5 FF F9 FF F9 FF FC FF FD FF 02 00 FB FF 05 00 FA FF
Read sector 62333937 through win32file:
FF FF FD FF 01 00 FC FF 01 00 FA FF FE FF F6 FF 02 00 F5 FF 06 00 F7 FF 03 00 FD FF 00 00 03 00 00 00 00 00 04 00 FA FF 07 00 F9 FF 05 00 F7 FF 00 00 FB FF FC FF FD FF 00 00 FC FF 04 00 FB FF 04 00 FB FF 02 00 FF FF 01 00 F9 FF FE FF F4 FF BF 75 03 00 EB B2 11 00 C0 31 2D 67 00 06 00 00 FF FF F2 FF 02 00 F2 FF 03 00 F7 FF 01 00 FB FF FB FF F4 FF FA FF F4 FF F8 FF ED FF F7 FF E8 FF F5 FF F0 FF F6 FF F4 FF F7 FF F9 FF F9 FF F6 FF FF FF F6 FF FF FF F7 FF FC FF F5 FF FA FF F5 FF F7 FF F6 FF FC FF F4 FF FF FF FA FF FE FF FC FF FC FF FD FF FC FF F8 FF F8 FF F3 FF F6 FF EE FF F3 FF EE FF F6 FF F4 FF F6 FF F6 FF FB FF F7 FF FF FF F8 FF FF FF F6 FF FC FF F5 FF F9 FF F5 FF F8 FF F3 FF F6 FF F4 FF FA FF F7 FF FC FF F8 FF FA FF FC FF FE FF FB FF FC FF F6 FF FA FF F4 FF FB FF F2 FF FA FF F3 FF FE FF F5 FF F9 FF FC FF F8 FF FB FF FA FF F4 FF FC FF F7 FF FF FF F5 FF FB FF F8 FF F9 FF F6 FF F7 FF F6 FF F9 FF F3 FF F9 FF F1 FF FA FF F4 FF FA FF F8 FF F6 FF FA FF F6 FF F4 FF F5 FF F1 FF F9 FF F3 FF FB FF F6 FF F6 FF F6 FF F5 FF F6 FF FC FF F9 FF 00 00 F4 FF FC FF F4 FF FD FF F7 FF FD FF F9 FF 01 00 FA FF FF FF FE FF 00 00 FE FF 01 00 02 00 03 00 03 00 03 00 FE FF 05 00 FF FF 05 00 04 00 09 00 0A 00 0C 00 0F 00 0B 00 10 00 0F 00 0D 00 12 00 09 00 11 00 0A 00 11 00 0B 00 0D 00 12 00 11 00 16 00 15 00 15 00 18 00 19 00 19 00 18 00 14 00 18 00 11 00 16 00 12 00 14 00 13 00 15 00 17 00 1C 00 17 00 20 00 1A 00 1F 00 1D 00 1C 00 1A 00 16 00 16 00 14 00 11 00 11 00 11 00 15 00 14 00 1F 00 19 00 1E 00 1B 00 1C 00 15 00 17 00 17 00 16 00
Read sector 62333937 through open:
Traceback (most recent call last):
  File "...", line 29, in <module>
    result = device.read(DEVICE_SECTOR_SIZ)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PermissionError: [Errno 13] Permission denied

Note that when I see this, the generated Errno is different for different devices. This could possibly be a bug in some Windows API that Python is relying on, but I'm not the one to determine that. If buffering is disabled in the Python file interface (by adding , 0 to the end of the open(...) call) then this issue does not occur, so my immediate suspicion is that the buffer implementation is reading past the end of the device for some reason.

This has been tested with Python 3.12.3 on Windows 11 10.0.22631

CPython versions tested on:

3.12

Operating systems tested on:

Windows

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 Windows 11 上使用 Python 3.12.3 的最小复现开始,比较带缓冲的 open(...).read()、禁用缓冲的情况以及 win32file 路径。完成的标准是,带缓冲的 Python 文件接口在读取设备的最后几个扇区时不再失败,并且该行为由适当的回归测试覆盖。

由索引模型根据 Issue 内容生成。

评估

技术栈
python
领域
operating-systems
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。