diff --git a/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp b/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp index 4c3a1ce..356f718 100644 --- a/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp +++ b/VKernel/Kernel/drivers/fs/fat32/fat32_types.vp @@ -1329,11 +1329,31 @@ class volinfo: if path[pi] == '/' or path[pi] == '\\': pi += 1 while path[pi] == '/' or path[pi] == '\\': pi += 1 is_root: int = 1 if path[pi] == 0 else 0 + # 路径末尾是 "." / ".." 时,follow_path 已经把 dp 打开成目标目录本身。 + # 不能再按"父目录中的最后一项"去回读目录项:那会把目标目录的第一个子项 + # 当成最终项打开(例如根目录 cd .. 会误入第一个子目录 APP)。 + last: int = 0 + lp: int = 0 + while path[lp] != 0: + if path[lp] != '/' and path[lp] != '\\': + last = lp + lp += 1 + ends_special: int = 0 + if path[last] == '.': + if last == 0: + ends_special = 1 + elif path[last - 1] == '/' or path[last - 1] == '\\': + ends_special = 1 + elif path[last - 1] == '.': + if last == 1: + ends_special = 1 + elif path[last - 2] == '/' or path[last - 2] == '\\': + ends_special = 1 lfn_buf: [256]uint16 string.memset(&lfn_buf, 0, 256 * 2) res: FRESULT = self.follow_path(&dp, path, uint16*(&lfn_buf[0])) if res != FRESULT.FR_OK: return res - if is_root: return FRESULT.FR_OK + if is_root or ends_special: return FRESULT.FR_OK entry_sector: uint64 = dp.sector + (dp.offset / (512 / ENTRY_SIZE)) entry_offset_in_sector: uint32 = (dp.offset % (512 / ENTRY_SIZE)) * ENTRY_SIZE res_wr: FRESULT = self.win_read(entry_sector)