chore(debug): fat32 dir_find/win_read 加取证探针 - 请求8.3短名 vs 磁盘目录项、读盘失败扇区、win_dirty 写盘痕迹

This commit is contained in:
TermiNexus committed 2026-10-15 17:08:58 +08:00
1 parent 152c4c5683
commit 2eea065a67
1 file changed
+55 -3
+55 -3
View File
@@ -12,6 +12,16 @@ def _read32(buf: uint8*, off: uint32) -> uint32:
def _read16(buf: uint8*, off: uint32) -> uint16:
return uint16(buf[off]) | (uint16(buf[off + 1]) << 8)
# [临时探针] FAT32 目录枚举/读盘取证:请求短名 vs 磁盘目录项、win_read 失败扇区、是否发生过写盘
# (定位 spawn 失败用,定位后连同调用点一起删除)
_f32_dbg: int = 0
def _f32_dbg_on() -> int:
global _f32_dbg
if _f32_dbg >= 200: return 0
_f32_dbg = _f32_dbg + 1
return 1
def _write32(buf: uint8*, off: uint32, val: uint32):
buf[off + 0] = uint8(val & 0xFF)
buf[off + 1] = uint8((val >> 8) & 0xFF)
@@ -347,6 +357,9 @@ class volinfo:
last_error: uint32 = 0
def win_read(self, sector: uint64) -> FRESULT:
# [临时探针] win_dirty 非 0 = 此前发生过写盘(镜像被改动的直接证据)
if self.win_dirty != 0 and _f32_dbg_on():
serial.puts("[f32] win_read: win_dirty=1 -> 之前有未落盘的写\n")
if self.winsect == sector: return FRESULT.FR_OK
if self.win_dirty:
res: FRESULT = self.win_flush()
@@ -356,7 +369,14 @@ class volinfo:
win_addr: rawptr = &self.win[0]
res2: DRESULT = diskio.read(self.pdrv, win_addr, uint32(abs_sector), 1)
self.lock.unlock()
if res2 != DRESULT.RES_OK: return FRESULT.FR_DISK_ERR
if res2 != DRESULT.RES_OK:
# [临时探针] 读盘失败的绝对扇区:判断是否越界/镜像异常
if _f32_dbg_on():
_fb: [160]char
viperlib.snprintf(&_fb, 160, "[f32] winread FAIL sec=%lu abs=%lu hid=%lu pdrv=%lu res=%d\n",
sector, abs_sector, uint64(self.hidden_sectors), uint64(self.pdrv), int(res2))
serial.puts(&_fb)
return FRESULT.FR_DISK_ERR
self.winsect = sector
return FRESULT.FR_OK
@@ -709,14 +729,41 @@ class volinfo:
def dir_find(self, dp: dirobj*, name: const str, lfn_buf: uint16*) -> FRESULT:
sfn: [12]char
sfn_from_lfn(name, &sfn[0])
# [临时探针] 请求名 与 生成的 8.3 短名
if _f32_dbg_on():
_rn: [16]char
sfn_to_str(&sfn[0], &_rn[0])
_rb: [96]char
viperlib.snprintf(&_rb, 96, "[f32] find req='%s' sfn='%s'\n", name, &_rn[0])
serial.puts(&_rb)
while True:
res: FRESULT = self.dir_read_entry(dp, lfn_buf)
if res != FRESULT.FR_OK:
# [临时探针] 枚举结束时游标位置(扫到哪、返回什么)
if _f32_dbg_on():
_eb: [128]char
viperlib.snprintf(&_eb, 128, "[f32] find end res=%d sec=%lu off=%lu\n",
int(res), dp.sector, uint64(dp.offset))
serial.puts(&_eb)
return res
entry_sector: uint64 = dp.sector + (dp.offset / (512 / ENTRY_SIZE))
entry_offset_in_sector: uint32 = (dp.offset % (512 / ENTRY_SIZE)) * ENTRY_SIZE
res2: FRESULT = self.win_read(entry_sector)
if res2 != FRESULT.FR_OK: return FRESULT.FR_DISK_ERR
if res2 != FRESULT.FR_OK:
if _f32_dbg_on():
_wb: [128]char
viperlib.snprintf(&_wb, 128, "[f32] find winread fail ent_sec=%lu off=%lu\n",
entry_sector, uint64(dp.offset))
serial.puts(&_wb)
return FRESULT.FR_DISK_ERR
# [临时探针] 磁盘上逐项的 8.3 短名 + 属性(用来和请求 sfn 对照)
if _f32_dbg_on():
_en: [16]char
sfn_to_str(str(&self.win[0] + entry_offset_in_sector), &_en[0])
_nb: [144]char
viperlib.snprintf(&_nb, 144, "[f32] ent sec=%lu off=%lu name='%s' attr=%02x\n",
entry_sector, uint64(dp.offset), &_en[0], uint32(self.win[entry_offset_in_sector + 11]))
serial.puts(&_nb)
match_found: int = 1
i: int
for i in range(11):
@@ -727,7 +774,10 @@ class volinfo:
if a != b:
match_found = 0
break
if match_found: return FRESULT.FR_OK
if match_found:
if _f32_dbg_on():
serial.puts("[f32] find HIT (sfn)\n")
return FRESULT.FR_OK
if lfn_buf and dp.lfn_ofs != 0xFFFFFFFF and dp.lfn_ofs < dp.offset:
lfn_matched: int = 1
li: int = 0
@@ -744,6 +794,8 @@ class volinfo:
if lfn_matched:
lfn_end: uint16 = *(uint16*(uint64(lfn_buf) + li * 2))
if lfn_end == 0 or lfn_end == 0xFFFF:
if _f32_dbg_on():
serial.puts("[f32] find HIT (lfn)\n")
return FRESULT.FR_OK
dp.offset += 1