diff --git a/App/lib/VCache.vp b/App/lib/VCache.vp index 45c678c..09457a1 100644 --- a/App/lib/VCache.vp +++ b/App/lib/VCache.vp @@ -30,12 +30,12 @@ import w32.win32base as wb # 字段/容量沿用原实现(App/main.vp 拆分前 :140-150、:188-194)。 # ============================================================ -CACHE_CAP: t.CDefine = 256 # 缓存条目上限 -CACHE_FILE_MAX: t.CDefine = 16777216 # 缓存文件读取上限 16 MiB -DISP_CAP: t.CDefine = 160 # "Viper " + 版本串 -CACHE_TEXT_MAX: t.CDefine = 262144 # 解析文本上限 256 KiB(典型缓存约 60 KiB;超出即视为损坏/异常,按空缓存启动) -CACHE_ARENA_PER_BYTE: t.CDefine = 128 # 解析工作池容量 / 输入字节(保守上界,见 ParseCacheText) -CACHE_ARENA_SLACK: t.CDefine = 4096 # 解析工作池固定余量 +define CACHE_CAP = 256 # 缓存条目上限 +define CACHE_FILE_MAX = 16777216 # 缓存文件读取上限 16 MiB +define DISP_CAP = 160 # "Viper " + 版本串 +define CACHE_TEXT_MAX = 262144 # 解析文本上限 256 KiB(典型缓存约 60 KiB;超出即视为损坏/异常,按空缓存启动) +define CACHE_ARENA_PER_BYTE = 128 # 解析工作池容量 / 输入字节(保守上界,见 ParseCacheText) +define CACHE_ARENA_SLACK = 4096 # 解析工作池固定余量 # 由 App/main.vp 注入 _mbuddy: rawptr[memhub.MemBuddy] @@ -53,7 +53,7 @@ Cache_Count: int = 0 # source 字面量:扫盘侧(VScan)/ check 侧(VCheck)各自传入,缓存本身不解释其含义。 # 旧缓存文件(无 source 字段)按 SOURCE_FALLBACK 载入,保持既有输出不变。 -SOURCE_FALLBACK: t.CDefine = "workspace" +define SOURCE_FALLBACK = "workspace" # ---- 表读取接口(供 VJson 构建 JSON,不暴露数组本身) ---- @@ -143,7 +143,7 @@ def ClearCache(): def CacheAdd(ExeAnsi: str, Id: str, Ver: str, Arch: str, Src: str, Disp: str) -> int: global Cache_Count if Cache_Count >= CACHE_CAP: - VLog.LogFmt1(" 警告: 缓存条目已达上限 %d,忽略新条目\n", t.CSizeT(CACHE_CAP)) + VLog.LogFmt1(" 警告: 缓存条目已达上限 %d,忽略新条目\n", sizet(CACHE_CAP)) return 0 E: str = VFs.DupStr(ExeAnsi) if E is None: @@ -207,7 +207,7 @@ def ValidateCache() -> int: # ============================================================ # 把 EmitJson 生成的文本(Buf,共 Len 字节)写入缓存文件(失败只告警,不中断进程) -def WriteCacheFile(Path: str, Buf: bytes, Len: t.CSizeT) -> int: +def WriteCacheFile(Path: str, Buf: bytes, Len: sizet) -> int: if Buf is None: return 0 rc: int = VFs.WriteFileAll(Path, Buf, Len) @@ -270,18 +270,18 @@ def AddParsedEntry(Obj: rawptr[json.JsonValue], ConvBuf: bytes) -> int: def ParseCacheText(Txt: str) -> int: if Txt is None: return 0 - L: t.CSizeT = string.strlen(Txt) + L: sizet = string.strlen(Txt) if L == 0: return 0 - if L > t.CSizeT(CACHE_TEXT_MAX): + if L > sizet(CACHE_TEXT_MAX): VLog.LogFmt2("缓存: 文本 %zu 字节超出解析上限 %zu,按空缓存启动\n", - L, t.CSizeT(CACHE_TEXT_MAX)) + L, sizet(CACHE_TEXT_MAX)) return 0 # 工作池容量:解析树最坏 ≈ 每输入字节 1 个 JsonValue 节点(9 字段 × 8 = 72 字节上界,bump 池 # 再按 8 字节对齐)+ 每字符串一次键名副本与值副本 + 数字/键名临时缓冲(最坏 ≈ 80 字节/输入字节); # 按 CACHE_ARENA_PER_BYTE(128)再放大,覆盖每次分配的 8 字节对齐浪费。 # (MemPool 耗尽会 printf + exit(1),故必须一次给足;这是不选 MemPool 小池的原因。) - Cap: t.CSizeT = L * t.CSizeT(CACHE_ARENA_PER_BYTE) + t.CSizeT(CACHE_ARENA_SLACK) + Cap: sizet = L * sizet(CACHE_ARENA_PER_BYTE) + sizet(CACHE_ARENA_SLACK) Arena: bytes = stdlib.malloc(Cap) if Arena is None: VLog.LogStr("缓存: 解析工作池分配失败,按空缓存启动\n") @@ -296,7 +296,7 @@ def ParseCacheText(Txt: str) -> int: # Need 与 Cap 同源(同一 L、同一每字节放大系数与固定余量),且 L*128 与 4096 都是 # MEMHUB_ALIGN(8) 的倍数 ⇒ 新池 offset=0 时 AllocOk(Need) 恒成立;一旦 Cap 的推导被 # 改小到放不下最坏解析开销,此处即失败并按"空缓存启动"降级,不会再走到 exit(1)。 - Need: t.CSizeT = L * t.CSizeT(CACHE_ARENA_PER_BYTE) + t.CSizeT(CACHE_ARENA_SLACK) + Need: sizet = L * sizet(CACHE_ARENA_PER_BYTE) + sizet(CACHE_ARENA_SLACK) if Pool.AllocOk(Need) == 0: stdlib.free(t.CPtr(Arena)) VLog.LogFmt1("缓存: 解析工作池预检不足(最坏需要 %zu 字节),按空缓存启动\n", @@ -326,7 +326,7 @@ def ParseCacheText(Txt: str) -> int: # 启动时读缓存做种子。文件不存在/读失败/解析失败均为非致命:告警后按空缓存启动。 def LoadCache(Path: str) -> int: - buf: bytes = VFs.ReadWholeFile(Path, t.CSizeT(CACHE_FILE_MAX), + buf: bytes = VFs.ReadWholeFile(Path, sizet(CACHE_FILE_MAX), wf.FILE_SHARE_READ | wf.FILE_SHARE_WRITE) if buf is None: rc_err: int = VFs.LastReadErr @@ -341,7 +341,7 @@ def LoadCache(Path: str) -> int: return 0 n: int = ParseCacheText(str(buf)) stdlib.free(t.CPtr(buf)) - VLog.VerboseFmt1("缓存: 已载入 %u 项种子\n", t.CSizeT(n)) + VLog.VerboseFmt1("缓存: 已载入 %u 项种子\n", sizet(n)) return n diff --git a/App/lib/VCheck.vp b/App/lib/VCheck.vp index cc32632..11076b3 100644 --- a/App/lib/VCheck.vp +++ b/App/lib/VCheck.vp @@ -78,34 +78,34 @@ import lib.VCache as VCache # ============================================================ # 固定失败原因(check_msg 的全部取值;EXE_ERR 是前缀 + 十六进制码,见 FormatExeErr) -CK_NOT_FOUND: t.CDefine = "NOT_FOUND" -CK_NO_PERMISSION: t.CDefine = "NO_PERMISSION" -CK_NOT_EXE: t.CDefine = "NOT_EXE" -CK_NO_PRVERSN: t.CDefine = "NO_PRVERSN" -CK_PRVERSN_ERR: t.CDefine = "PRVERSN_ERR" -CK_PREFIX_ERR: t.CDefine = "PREFIX_ERR" # --version 拉起成功但输出前 5 字符不是 Viper -CK_TIMEOUT: t.CDefine = "TIMEOUT" +define CK_NOT_FOUND = "NOT_FOUND" +define CK_NO_PERMISSION = "NO_PERMISSION" +define CK_NOT_EXE = "NOT_EXE" +define CK_NO_PRVERSN = "NO_PRVERSN" +define CK_PRVERSN_ERR = "PRVERSN_ERR" +define CK_PREFIX_ERR = "PREFIX_ERR" # --version 拉起成功但输出前 5 字符不是 Viper +define CK_TIMEOUT = "TIMEOUT" # 通道自身不可用(CheckInit 失败):降级回执的唯一原因串,见 EmitReplyUnavailable -CK_CHANNEL_UNAVAILABLE: t.CDefine = "CHANNEL_UNAVAILABLE" +define CK_CHANNEL_UNAVAILABLE = "CHANNEL_UNAVAILABLE" # check 命中入库时的 source 值(与扫盘侧 "workspace" 区分) -CK_SOURCE: t.CDefine = "check" +define CK_SOURCE = "check" # EXE_ERR 的原因串缓冲("EXE_ERR,0x" + 最多 8 位十六进制 + NUL) -CK_MSG_CAP: t.CDefine = 32 +define CK_MSG_CAP = 32 # 请求行解析上限(与 VGuard.GUARD_LINE_CAP 对齐:看门狗的行缓冲即本上限, # 超长行在看门狗侧已被截断/丢弃,这里再兜一层,避免对异常长的输入做解析) -CK_LINE_MAX: t.CDefine = 4096 +define CK_LINE_MAX = 4096 # 解析工作池容量 / 输入字节与固定余量:与 VCache.ParseCacheText 同一保守口径 # (最坏 ≈ 每输入字节 1 个 JsonValue 节点 + 键名/值副本 + 数字临时缓冲 ≈ 80 字节/输入字节, # 再按 128 放大覆盖 8 字节对齐浪费)。MemPool 耗尽会 exit(1),故必须先 AllocOk 预检。 -CK_ARENA_PER_BYTE: t.CDefine = 128 -CK_ARENA_SLACK: t.CDefine = 4096 +define CK_ARENA_PER_BYTE = 128 +define CK_ARENA_SLACK = 4096 # 回执工作池:72 KiB。单条回执的全部池分配(Need)见 CK_REPLY_NEED_FIXED 的推导。 -CK_REPLY_POOL_CAP: t.CDefine = 73728 +define CK_REPLY_POOL_CAP = 73728 # 单条回执在回执池上的固定开销上界: # * JsonValue 节点 9 个(回执对象 + check_result + id + viper 子对象 + 6 个字符串值) @@ -116,18 +116,18 @@ CK_REPLY_POOL_CAP: t.CDefine = 73728 # * 整数序列化的临时缓冲 32 字节(write 的 JSON_INT 分支 pool.alloc(32)); # * 余量 512:各值副本的结尾 NUL 与按 MEMHUB_ALIGN(8) 向上取整的浪费。 # 合计 648 + 68 + 4096 + 32 + 512 = 5356 ⇒ 取 5632(512 对齐)。 -CK_REPLY_NEED_FIXED: t.CDefine = 5632 +define CK_REPLY_NEED_FIXED = 5632 # 回执里 executable / displayName 的取值长度上界:二者都经 Check_Conv(VFs.CONV_CAP 字节) # 转出(WideCharToMultiByte 以 Cap 封顶并写结尾 NUL,失败时 CopyRaw 写空串)⇒ ≤ CONV_CAP-1。 # 写 2047 = VFs.CONV_CAP(2048) - 1 的字面量(与本仓"t.CDefine 不引用跨模块常量"的惯例一致)。 -CK_CONV_MAX: t.CDefine = 2047 +define CK_CONV_MAX = 2047 # 降级回执(EmitReplyUnavailable)的临时行缓冲字节数:stdlib.malloc,与 _mbuddy 无关, # 因为该路径的定义就是"mb 上的缓冲拿不到"。长度上界(含换行与结尾 NUL): # `{"check_result":false,"id":` 27 + id 最长 20(i64 十进制含负号) # + `,"check_msg":"` 14 + CHANNEL_UNAVAILABLE 19 + `"}` 2 + '\n' 1 + NUL 1 = 84 ⇒ 取 128。 -CK_FALLBACK_CAP: t.CDefine = 128 +define CK_FALLBACK_CAP = 128 # 由 App/main.vp 注入(与其它模块同一 MemBuddy 实例) _mbuddy: rawptr[memhub.MemBuddy] @@ -233,10 +233,10 @@ def ParseCheckLine(Txt: str) -> int: Req_PathOk = 0 if Txt is None: return 0 - L: t.CSizeT = string.strlen(Txt) - if L == 0 or L > t.CSizeT(CK_LINE_MAX): + L: sizet = string.strlen(Txt) + if L == 0 or L > sizet(CK_LINE_MAX): return 0 - Cap: t.CSizeT = L * t.CSizeT(CK_ARENA_PER_BYTE) + t.CSizeT(CK_ARENA_SLACK) + Cap: sizet = L * sizet(CK_ARENA_PER_BYTE) + sizet(CK_ARENA_SLACK) Arena: bytes = stdlib.malloc(Cap) if Arena is None: return 0 @@ -323,7 +323,7 @@ def MapPeFailure(Rc: int, OpenErr: ULONG) -> str: # (0 只会出现在"未到达任何 Win32 调用"的失败阶段,如参数/路径非法)。 # 返回值指向模块级缓冲:调用方须立即使用(EmitReplyFail 会把它复制进回执池)。 def FormatExeErr(Err: ULONG) -> str: - viperlib.snprintf(Check_Msg, t.CSizeT(CK_MSG_CAP), "EXE_ERR,0x%X", Err) + viperlib.snprintf(Check_Msg, sizet(CK_MSG_CAP), "EXE_ERR,0x%X", Err) return str(Check_Msg) @@ -347,7 +347,7 @@ def CheckExecutable(PathAnsi: str) -> str: return CK_PRVERSN_ERR # 段在但内容为空(第一个字节即 NUL) # ② --version 验证(进程正常结束且前 5 字符为 Viper 才算通过) pc: int = VProc.RunVersionProbe(PathAnsi, Check_Probe, - t.CSizeT(VProc.VERSION_PROBE_DIAG_CAP), 0) + sizet(VProc.VERSION_PROBE_DIAG_CAP), 0) if pc == 2 or VProc.Probe_TimedOut != 0: return CK_TIMEOUT if pc != 0: @@ -356,7 +356,7 @@ def CheckExecutable(PathAnsi: str) -> str: if VProc.OutputHasViperPrefix(str(Check_Probe)) == 0: # 拉起成功但输出前 5 字符不是 Viper ⇒ 独立原因 PREFIX_ERR(与段定位/读取/内容异常区分) return CK_PREFIX_ERR - viperlib.snprintf(Check_Disp, t.CSizeT(VCache.DISP_CAP), "Viper %s", str(Check_Ver)) + viperlib.snprintf(Check_Disp, sizet(VCache.DISP_CAP), "Viper %s", str(Check_Ver)) return None @@ -401,8 +401,8 @@ def TrackChecked(PathAnsi: str) -> int: # 换行与新的 NUL。这样做是为了让"一行回执"始终是**单次写**——与别人(看门狗失败行、 # 下一轮数组)写入不会在同一行中间交错。 def WriteReplyLine(Txt: str) -> int: - n: t.CSizeT = string.strlen(Txt) - if n + 2 <= t.CSizeT(4096): + n: sizet = string.strlen(Txt) + if n + 2 <= sizet(4096): Txt[n] = '\n' Txt[n + 1] = 0 VLog.StdoutWrite(Txt) @@ -437,10 +437,10 @@ def EmitReplyOk(ReqIdVal: LONGLONG, PathAnsi: str): Id = str(Check_Id) TrackChecked(PathAnsi) Check_Pool.reset() - ValNeed: t.CSizeT = t.CSizeT(CK_CONV_MAX) + t.CSizeT(CK_CONV_MAX) + ValNeed: sizet = sizet(CK_CONV_MAX) + sizet(CK_CONV_MAX) ValNeed = ValNeed + string.strlen(Id) + string.strlen(Ver) + string.strlen(Arch) ValNeed = ValNeed + string.strlen(CK_SOURCE) - if Check_Pool.AllocOk(t.CSizeT(CK_REPLY_NEED_FIXED) + ValNeed) == 0: + if Check_Pool.AllocOk(sizet(CK_REPLY_NEED_FIXED) + ValNeed) == 0: VLog.LogStr(" 警告: check 回执工作池不足,未回复(不会写穿缓冲)\n") return Obj: rawptr[json.JsonValue] = json.object(Check_Pool) @@ -448,7 +448,7 @@ def EmitReplyOk(ReqIdVal: LONGLONG, PathAnsi: str): VLog.LogStr(" 警告: check 回执对象分配失败,未回复\n") return json.object_set(Check_Pool, Obj, "check_result", json.bool_val(Check_Pool, True)) - json.object_set(Check_Pool, Obj, "id", json.int_val(Check_Pool, t.CInt64T(ReqIdVal))) + json.object_set(Check_Pool, Obj, "id", json.int_val(Check_Pool, int64(ReqIdVal))) Sub: rawptr[json.JsonValue] = json.object(Check_Pool) if Sub == None: VLog.LogStr(" 警告: check 回执对象分配失败,未回复\n") @@ -475,7 +475,7 @@ def EmitReplyOk(ReqIdVal: LONGLONG, PathAnsi: str): # 失败回执:{"check_result": false, "id": , "check_msg": "<原因>"} def EmitReplyFail(ReqIdVal: LONGLONG, Msg: str): Check_Pool.reset() - Need: t.CSizeT = t.CSizeT(CK_REPLY_NEED_FIXED) + Need: sizet = sizet(CK_REPLY_NEED_FIXED) if Msg != None: Need = Need + string.strlen(Msg) if Check_Pool.AllocOk(Need) == 0: @@ -486,7 +486,7 @@ def EmitReplyFail(ReqIdVal: LONGLONG, Msg: str): VLog.LogStr(" 警告: check 回执对象分配失败,未回复\n") return json.object_set(Check_Pool, Obj, "check_result", json.bool_val(Check_Pool, False)) - json.object_set(Check_Pool, Obj, "id", json.int_val(Check_Pool, t.CInt64T(ReqIdVal))) + json.object_set(Check_Pool, Obj, "id", json.int_val(Check_Pool, int64(ReqIdVal))) json.object_set(Check_Pool, Obj, "check_msg", json.string_val(Check_Pool, Msg)) Txt: str = json.write(Check_Pool, Obj, False) if Txt == None: @@ -506,9 +506,9 @@ def EmitReplyUnavailable(ReqIdVal: LONGLONG) -> int: Fb: bytes = stdlib.malloc(CK_FALLBACK_CAP) if Fb is None: return 0 - viperlib.snprintf(Fb, t.CSizeT(CK_FALLBACK_CAP), + viperlib.snprintf(Fb, sizet(CK_FALLBACK_CAP), "{\"check_result\":false,\"id\":%lld,\"check_msg\":\"%s\"}\n", - t.CInt64T(ReqIdVal), CK_CHANNEL_UNAVAILABLE) + int64(ReqIdVal), CK_CHANNEL_UNAVAILABLE) VLog.StdoutWrite(str(Fb)) stdlib.free(t.CPtr(Fb)) return 1 diff --git a/App/lib/VCli.vp b/App/lib/VCli.vp index 6a8fe4f..a493d6f 100644 --- a/App/lib/VCli.vp +++ b/App/lib/VCli.vp @@ -38,21 +38,21 @@ import lib.VDirs as VDirs # 取参方式依据:sys._init_argv/_argc/_argv(includes/sys.vp:60-67)。 # ============================================================ -VET_VERSION: t.CDefine = "0.2.0" -SECS_MAX: t.CDefine = 86400 # --need-confirm 秒数上界(1 天;超出视为参数错误) -DEFAULT_SLEEP_MS: t.CDefine = 10000 # --sleep 缺省值(沿用原 SCAN_INTERVAL_MS) -SLEEP_MAX_MS: t.CDefine = 86400000 # --sleep 毫秒上界(1 天;超出视为参数错误) -DEFAULT_CONFIRM_TIMEOUT_MS: t.CDefine = 5000 # --need-confirm-timeout 缺省值 -CONFIRM_TIMEOUT_MAX_MS: t.CDefine = 86400000 # --need-confirm-timeout 毫秒上界(1 天) +define VET_VERSION = "0.2.0" +define SECS_MAX = 86400 # --need-confirm 秒数上界(1 天;超出视为参数错误) +define DEFAULT_SLEEP_MS = 10000 # --sleep 缺省值(沿用原 SCAN_INTERVAL_MS) +define SLEEP_MAX_MS = 86400000 # --sleep 毫秒上界(1 天;超出视为参数错误) +define DEFAULT_CONFIRM_TIMEOUT_MS = 5000 # --need-confirm-timeout 缺省值 +define CONFIRM_TIMEOUT_MAX_MS = 86400000 # --need-confirm-timeout 毫秒上界(1 天) # --pace <毫秒>:节流点睡眠时长,取值域 0..60000。0 = 关闭节流(两个节流点都不 Sleep)。 # 上界取 1 分钟:节流只为降低扫盘对机器的持续压力,睡眠远超 1 分钟只会无谓拖慢单轮而无收益, # 与 --sleep(轮间隔,上界 1 天)的用途不同,故不共用其宽松上界。 -DEFAULT_PACE_SLEEP_MS: t.CDefine = 20 # --pace 缺省值(沿用 VScan.PACE_SLEEP_MS,未给出时逐字保持现状) -PACE_SLEEP_MAX_MS: t.CDefine = 60000 # --pace 毫秒上界(1 分钟) +define DEFAULT_PACE_SLEEP_MS = 20 # --pace 缺省值(沿用 VScan.PACE_SLEEP_MS,未给出时逐字保持现状) +define PACE_SLEEP_MAX_MS = 60000 # --pace 毫秒上界(1 分钟) # --pace-units :文件粒度,取值域 1..1000000(每 N 个文件一个节流点;1 = 每个文件都停)。 # 0 无意义("每 0 个文件"),与非法输入一并报错;上界 1000000 已足够稀疏(等同关闭文件侧节流)。 -DEFAULT_PACE_FILE_UNITS: t.CDefine = 64 # --pace-units 缺省值(沿用 VScan.PACE_FILE_UNITS,未给出时逐字保持现状) -PACE_UNITS_MAX: t.CDefine = 1000000 # --pace-units 文件数上界 +define DEFAULT_PACE_FILE_UNITS = 64 # --pace-units 缺省值(沿用 VScan.PACE_FILE_UNITS,未给出时逐字保持现状) +define PACE_UNITS_MAX = 1000000 # --pace-units 文件数上界 # --parent-pid 上界(DWORD 全域 4294967295)。 # 注意:这里不能用 `t.CDefine = 4294967295`。CDefine 的物化规则(TPV # ExprGenCdef._const_int_for_cdefine)把落在 u32 范围内的值一律按 **i32** 常量生成 @@ -348,7 +348,7 @@ def ParseScanArgs() -> int: M: int = ParseUint(sys._argv[i + 1], SLEEP_MAX_MS) if M < 0: VLog.LogFmt1("错误: --sleep 需要一个 0..%u 的整数字面量毫秒数,实际为: ", - t.CSizeT(SLEEP_MAX_MS)) + sizet(SLEEP_MAX_MS)) VLog.LogFmtS1("%s\n", sys._argv[i + 1]) PrintUsage() return 1 @@ -363,7 +363,7 @@ def ParseScanArgs() -> int: P: int = ParseUint(sys._argv[i + 1], PACE_SLEEP_MAX_MS) if P < 0: VLog.LogFmt1("错误: --pace 需要一个 0..%u 的整数字面量毫秒数,实际为: ", - t.CSizeT(PACE_SLEEP_MAX_MS)) + sizet(PACE_SLEEP_MAX_MS)) VLog.LogFmtS1("%s\n", sys._argv[i + 1]) PrintUsage() return 1 @@ -380,7 +380,7 @@ def ParseScanArgs() -> int: # 0 与非法同为错误(ParseUint 非法返回 -1):0 会让"每 0 个文件一个节流点"无意义 if U <= 0: VLog.LogFmt1("错误: --pace-units 需要一个 1..%u 的整数字面量文件数,实际为: ", - t.CSizeT(PACE_UNITS_MAX)) + sizet(PACE_UNITS_MAX)) VLog.LogFmtS1("%s\n", sys._argv[i + 1]) PrintUsage() return 1 @@ -401,7 +401,7 @@ def ParseScanArgs() -> int: if S < 0: # 两个固定元数调用拼一行(LogFmt1 只带整数,LogFmtS1 只带字符串) VLog.LogFmt1("错误: --need-confirm 需要一个 0..%u 的整数字面量秒数,实际为: ", - t.CSizeT(SECS_MAX)) + sizet(SECS_MAX)) VLog.LogFmtS1("%s\n", sys._argv[i + 1]) PrintUsage() return 1 @@ -416,7 +416,7 @@ def ParseScanArgs() -> int: T: int = ParseUint(sys._argv[i + 1], CONFIRM_TIMEOUT_MAX_MS) if T < 0: VLog.LogFmt1("错误: --need-confirm-timeout 需要一个 0..%u 的整数字面量毫秒数,实际为: ", - t.CSizeT(CONFIRM_TIMEOUT_MAX_MS)) + sizet(CONFIRM_TIMEOUT_MAX_MS)) VLog.LogFmtS1("%s\n", sys._argv[i + 1]) PrintUsage() return 1 diff --git a/App/lib/VDirs.vp b/App/lib/VDirs.vp index 7e8395d..54c36c1 100644 --- a/App/lib/VDirs.vp +++ b/App/lib/VDirs.vp @@ -36,7 +36,7 @@ import w32.win32base as wb # ============================================================ # Win32: typedef LONG HRESULT(有符号 32 位,负值才是失败) -HRESULT: t.CTypedef = t.CInt32T +HRESULT: t.CTypedef = int32 # Win32: typedef const KNOWNFOLDERID *REFKNOWNFOLDERID(指向 16 字节 GUID) REFKNOWNFOLDERID: t.CTypedef = t.CPtr @@ -48,22 +48,22 @@ extern def SHGetKnownFolderPath(rfid: REFKNOWNFOLDERID, dwFlags: DWORD, hToken: ppszPath: t.CPtr) -> HRESULT extern def CoTaskMemFree(pv: t.CPtr) -SEM_FAILCRITICALERRORS: t.CDefine = 0x0001 # SetErrorMode 标志(errhandlingapi.h) -KNOWNFOLDERID_SIZE: t.CDefine = 16 # KNOWNFOLDERID / GUID 字节数 +define SEM_FAILCRITICALERRORS = 0x0001 # SetErrorMode 标志(errhandlingapi.h) +define KNOWNFOLDERID_SIZE = 16 # KNOWNFOLDERID / GUID 字节数 # winnt.h: FILE_ATTRIBUTE_REPARSE_POINT 在 VScan 使用 # GetDriveTypeA 返回值(winbase.h) -DRIVE_NO_ROOT_DIR: t.CDefine = 1 # 跳过:无根路径 -DRIVE_REMOVABLE: t.CDefine = 2 # 探测:可移动介质(U 盘/读卡器) -DRIVE_FIXED: t.CDefine = 3 # 探测:定长磁盘 -DRIVE_REMOTE: t.CDefine = 4 # 探测:网络盘 -DRIVE_CDROM: t.CDefine = 5 # 跳过:光驱 +define DRIVE_NO_ROOT_DIR = 1 # 跳过:无根路径 +define DRIVE_REMOVABLE = 2 # 探测:可移动介质(U 盘/读卡器) +define DRIVE_FIXED = 3 # 探测:定长磁盘 +define DRIVE_REMOTE = 4 # 探测:网络盘 +define DRIVE_CDROM = 5 # 跳过:光驱 # 决策:只跳过 NO_ROOT_DIR(1) 与 CDROM(5),其余(含 REMOVABLE)继续探测 Program Files; # 空介质/卡读卡器触发的弹窗与阻塞由 AddFixedDriveProgramFiles 里的 SetErrorMode 抑制。 -COMMON_DIR_CAPACITY: t.CDefine = 128 # 表容量(内联数组元素个数) -DRIVE_ROOT_CAP: t.CDefine = 8 # "X:\" + NUL 缓冲 -DESKTOP_SUFFIX_CAP: t.CDefine = 9 # r"\Desktop"(8) + NUL(1) +define COMMON_DIR_CAPACITY = 128 # 表容量(内联数组元素个数) +define DRIVE_ROOT_CAP = 8 # "X:\" + NUL 缓冲 +define DESKTOP_SUFFIX_CAP = 9 # r"\Desktop"(8) + NUL(1) # 由 App/main.vp 注入 _mbuddy: rawptr[memhub.MemBuddy] @@ -125,7 +125,7 @@ def AddCommonDirForce(Path: str) -> int: return 0 i += 1 if Common_Dir_Count >= COMMON_DIR_CAPACITY: - VLog.LogFmt1(" 警告: 常用目录表已满 (%d),已忽略该条\n", t.CSizeT(COMMON_DIR_CAPACITY)) + VLog.LogFmt1(" 警告: 常用目录表已满 (%d),已忽略该条\n", sizet(COMMON_DIR_CAPACITY)) return 0 Common_Directory[Common_Dir_Count] = Path Common_Dir_Count += 1 @@ -155,10 +155,10 @@ def AddFixedDriveProgramFiles() -> int: Added: int = 0 Letter: int = 0 while Letter < 26: - if (Mask & (t.CUInt32T(1) << t.CUInt32T(Letter))) != 0: + if (Mask & (uint32(1) << uint32(Letter))) != 0: Root: bytes = _mbuddy.alloc(DRIVE_ROOT_CAP) if Root is not None: - Root[0] = t.CChar(65 + Letter) # 'A' + Letter + Root[0] = char(65 + Letter) # 'A' + Letter Root[1] = ':' Root[2] = '\\' Root[3] = 0 @@ -169,12 +169,12 @@ def AddFixedDriveProgramFiles() -> int: Pf: bytes = _mbuddy.alloc(VFs.PATH_BUF_CAP) if Pf is not None: string.strcpy(Pf, r"Q:\Program Files") # 'Q' 占位,下句改写为首字母 - Pf[0] = t.CChar(65 + Letter) + Pf[0] = char(65 + Letter) Added += AddCommonDir(str(Pf)) Pfx: bytes = _mbuddy.alloc(VFs.PATH_BUF_CAP) if Pfx is not None: string.strcpy(Pfx, r"Q:\Program Files (x86)") - Pfx[0] = t.CChar(65 + Letter) + Pfx[0] = char(65 + Letter) Added += AddCommonDir(str(Pfx)) Letter += 1 return Added @@ -185,7 +185,7 @@ def AddFixedDriveProgramFiles() -> int: def AddDesktopFallback(Buf: bytes) -> int: n: DWORD = GetEnvironmentVariableA("USERPROFILE", Buf, VFs.PATH_BUF_CAP) # 还需追加 "\Desktop"(8 字节)+ NUL,n + 9 必须不超过缓冲容量 - if n == 0 or n + t.CUInt32T(DESKTOP_SUFFIX_CAP) > t.CUInt32T(VFs.PATH_BUF_CAP): + if n == 0 or n + uint32(DESKTOP_SUFFIX_CAP) > uint32(VFs.PATH_BUF_CAP): VLog.LogFmt1(" 桌面兜底: 获取 USERPROFILE 失败或过长 (win32 err=%u)\n", wb.GetLastError()) return 0 Buf[n] = 0 @@ -236,13 +236,13 @@ def AddCurrentUserDesktop() -> int: GuidBuf[15] = 0x41 Pwsz: WCHARPTR = None - Hr: HRESULT = SHGetKnownFolderPath(t.CPtr(GuidBuf), 0, None, t.CPtr(c.Addr(Pwsz))) + Hr: HRESULT = SHGetKnownFolderPath(t.CPtr(GuidBuf), 0, None, t.CPtr(&Pwsz)) stdlib.free(t.CPtr(GuidBuf)) if Hr < 0: # 规范上失败时 *ppszPath 会被置 NULL;仍防御性释放非空返回值,杜绝泄漏 if Pwsz is not None: CoTaskMemFree(t.CPtr(Pwsz)) - VLog.LogFmt1(" 桌面: SHGetKnownFolderPath 失败 (hr=0x%X),改用兜底路径\n", t.CSizeT(t.CUInt32T(Hr))) + VLog.LogFmt1(" 桌面: SHGetKnownFolderPath 失败 (hr=0x%X),改用兜底路径\n", sizet(uint32(Hr))) return AddDesktopFallback(Buf) if Pwsz is None: VLog.LogStr(" 桌面: SHGetKnownFolderPath 返回空指针,改用兜底路径\n") @@ -253,7 +253,7 @@ def AddCurrentUserDesktop() -> int: if Needed <= 0 or Needed > VFs.PATH_BUF_CAP: CoTaskMemFree(t.CPtr(Pwsz)) VLog.LogFmt2(" 桌面: 路径为空或过长 (%d 字节, 上限 %d),改用兜底路径\n", - t.CSizeT(t.CUInt32T(Needed)), t.CSizeT(VFs.PATH_BUF_CAP)) + sizet(uint32(Needed)), sizet(VFs.PATH_BUF_CAP)) return AddDesktopFallback(Buf) Got: int = VFs.WideToUtf8(Pwsz, Buf, VFs.PATH_BUF_CAP) CoTaskMemFree(t.CPtr(Pwsz)) # 用后立即释放:成功/失败分支的同一释放点 @@ -274,9 +274,9 @@ def PrintCommonDirs() -> int: return 1 i: int = 0 while i < Common_Dir_Count: - VLog.VerboseFmtIS(" [%d] %s\n", t.CSizeT(i), Common_Directory[i]) + VLog.VerboseFmtIS(" [%d] %s\n", sizet(i), Common_Directory[i]) i += 1 - VLog.VerboseFmt1(" 合计 %d 个常用目录\n", t.CSizeT(Common_Dir_Count)) + VLog.VerboseFmt1(" 合计 %d 个常用目录\n", sizet(Common_Dir_Count)) return 0 @@ -288,7 +288,7 @@ def BuildTable() -> int: AddCommonDirForce(r"D:\Viper") AddFixedDriveProgramFiles() # 各盘 Program Files / Program Files (x86) AddCurrentUserDesktop() # 当前用户桌面 - VLog.VerboseFmt1(" 目录表来源: 自动表 (%u 条)\n", t.CSizeT(Common_Dir_Count)) + VLog.VerboseFmt1(" 目录表来源: 自动表 (%u 条)\n", sizet(Common_Dir_Count)) else: # 强制替换:完全不做自动构建,表 = --path 序列(保序;去重由 AddCommonDirForce) i: int = 0 @@ -298,5 +298,5 @@ def BuildTable() -> int: else: AddCommonDirForce(Override_Dir[i]) i += 1 - VLog.VerboseFmt1(" 目录表来源: 覆盖表 (%u 条)\n", t.CSizeT(Common_Dir_Count)) + VLog.VerboseFmt1(" 目录表来源: 覆盖表 (%u 条)\n", sizet(Common_Dir_Count)) return PrintCommonDirs() diff --git a/App/lib/VFs.vp b/App/lib/VFs.vp index 498c06d..bf4fa5f 100644 --- a/App/lib/VFs.vp +++ b/App/lib/VFs.vp @@ -36,24 +36,24 @@ import w32.win32base as wb # 原型出处:Win32 API 文档 / winnls.h。 # ============================================================ -PATH_BUF_CAP: t.CDefine = 512 # 单条目录/文件路径缓冲 -CONV_CAP: t.CDefine = 2048 # 编码转换临时缓冲 -INVALID_FILE_ATTRIBUTES: t.CDefine = 0xFFFFFFFF # GetFileAttributesA 失败返回值 -CP_UTF8: t.CDefine = 65001 # Win32 代码页 UTF-8 -CP_ACP: t.CDefine = 0 # Win32 代码页 ANSI(A 系列 API 的当前页) +define PATH_BUF_CAP = 512 # 单条目录/文件路径缓冲 +define CONV_CAP = 2048 # 编码转换临时缓冲 +define INVALID_FILE_ATTRIBUTES = 0xFFFFFFFF # GetFileAttributesA 失败返回值 +define CP_UTF8 = 65001 # Win32 代码页 UTF-8 +define CP_ACP = 0 # Win32 代码页 ANSI(A 系列 API 的当前页) extern def WideCharToMultiByte(CodePage: UINT, dwFlags: DWORD, lpWideCharStr: WCHARPTR, cchWideChar: int, lpMultiByteStr: CHARPTR, cbMultiByte: int, - lpDefaultChar: wb.LPCSTR, lpUsedDefaultChar: BOOL | t.CPtr) -> int + lpDefaultChar: wb.LPCSTR, lpUsedDefaultChar: BOOL*) -> int # 由 App/main.vp 注入(与其它模块同一 MemBuddy 实例) _mbuddy: rawptr[memhub.MemBuddy] # ReadWholeFile / WriteFileAll 的结果输出(模块全局) -LastReadSize: t.CSizeT = 0 # 成功时的实际读取字节数 +LastReadSize: sizet = 0 # 成功时的实际读取字节数 LastReadErr: int = 0 # 1=打开失败 2=取大小失败 3=空文件 4=超过上限 5=分配失败 LastReadWinErr: ULONG = 0 # 打开失败时的 GetLastError() -LastWriteDone: t.CSizeT = 0 # WriteFileAll 实际写入字节数 +LastWriteDone: sizet = 0 # WriteFileAll 实际写入字节数 # ============================================================ @@ -69,11 +69,11 @@ def CopyRaw(Dst: bytes, Cap: int, Src: str) -> int: if Src is None: Dst[0] = 0 return 0 - n: t.CSizeT = string.strlen(Src) - if n + 1 > t.CSizeT(Cap): + n: sizet = string.strlen(Src) + if n + 1 > sizet(Cap): Dst[0] = 0 return 0 - i: t.CSizeT = 0 + i: sizet = 0 while i < n: Dst[i] = Src[i] i += 1 @@ -86,11 +86,11 @@ def CopyRaw(Dst: bytes, Cap: int, Src: str) -> int: def DupStr(S: str) -> str: if S is None: return None - n: t.CSizeT = string.strlen(S) + n: sizet = string.strlen(S) b: bytes = _mbuddy.alloc(n + 1) if b is None: return None - i: t.CSizeT = 0 + i: sizet = 0 while i < n: b[i] = S[i] i += 1 @@ -125,24 +125,24 @@ def StrEqNoCase(A: str, B: str) -> int: def JoinPath(Out: bytes, Cap: int, Parent: str, Child: str) -> int: if Out is None or Parent is None or Child is None: return 0 - pl: t.CSizeT = string.strlen(Parent) - cl: t.CSizeT = string.strlen(Child) + pl: sizet = string.strlen(Parent) + cl: sizet = string.strlen(Child) need_sep: int = 0 if pl > 0: - last: int = int(Parent[t.CInt(pl) - 1]) + last: int = int(Parent[int(pl) - 1]) if last != 47 and last != 92: # '/' or '\' need_sep = 1 - total: t.CSizeT = pl + cl + t.CSizeT(need_sep) - if total + 1 > t.CSizeT(Cap): + total: sizet = pl + cl + sizet(need_sep) + if total + 1 > sizet(Cap): return 0 - i: t.CSizeT = 0 + i: sizet = 0 while i < pl: Out[i] = Parent[i] i += 1 if need_sep != 0: Out[i] = '\\' i += 1 - j: t.CSizeT = 0 + j: sizet = 0 while j < cl: Out[i] = Child[j] i += 1 @@ -184,7 +184,7 @@ def Utf8ToAnsi(Src: str, Dst: bytes, Cap: int) -> int: if n <= 0: CopyRaw(Dst, Cap, Src) return 0 - W: WCHARPTR = stdlib.malloc(t.CSizeT(n) * 2) + W: WCHARPTR = stdlib.malloc(sizet(n) * 2) if W is None: CopyRaw(Dst, Cap, Src) return 0 @@ -206,7 +206,7 @@ def AnsiToUtf8(Src: str, Dst: bytes, Cap: int) -> int: if n <= 0: CopyRaw(Dst, Cap, Src) return 0 - W: WCHARPTR = stdlib.malloc(t.CSizeT(n) * 2) + W: WCHARPTR = stdlib.malloc(sizet(n) * 2) if W is None: CopyRaw(Dst, Cap, Src) return 0 @@ -240,25 +240,25 @@ def WideToUtf8(Src: WCHARPTR, Dst: bytes, Cap: int) -> int: # ============================================================ # 从当前文件指针读满 Want 字节(循环),返回实际读取字节数 -def ReadFull(h: wb.HANDLE, Buf: bytes, Want: t.CSizeT) -> t.CSizeT: - total: t.CSizeT = 0 +def ReadFull(h: wb.HANDLE, Buf: bytes, Want: sizet) -> sizet: + total: sizet = 0 while total < Want: - chunk: t.CSizeT = Want - total + chunk: sizet = Want - total if chunk > 0x7FFFFFFF: - chunk = t.CSizeT(0x7FFFFFFF) + chunk = sizet(0x7FFFFFFF) br: ULONG = 0 - if wf.ReadFile(h, Buf + total, ULONG(chunk), t.CPtr(c.Addr(br)), None) == 0: + if wf.ReadFile(h, Buf + total, ULONG(chunk), t.CPtr(&br), None) == 0: break if br == 0: break - total += t.CSizeT(br) + total += sizet(br) return total # 读取整个文件到 stdlib 分配的缓冲(含 NUL 结尾)。成功返回 bytes,调用方用 stdlib.free 释放; # 失败返回 None,原因见 LastReadErr(4 仅在 MaxBytes>0 时产生)。 # Share 由调用方给出(各调用点原有的 dwShareMode 语义保持一致)。 -def ReadWholeFile(Path: str, MaxBytes: t.CSizeT, Share: ULONG) -> bytes: +def ReadWholeFile(Path: str, MaxBytes: sizet, Share: ULONG) -> bytes: global LastReadSize, LastReadErr, LastReadWinErr LastReadSize = 0 LastReadErr = 0 @@ -270,11 +270,11 @@ def ReadWholeFile(Path: str, MaxBytes: t.CSizeT, Share: ULONG) -> bytes: LastReadErr = 1 return None li: wb.LARGE_INTEGER = wb.LARGE_INTEGER() - if wf.GetFileSizeEx(H, t.CPtr(c.Addr(li))) == 0: + if wf.GetFileSizeEx(H, t.CPtr(&li)) == 0: wb.CloseHandle(H) LastReadErr = 2 return None - Sz: t.CSizeT = t.CSizeT(li.QuadPart) + Sz: sizet = sizet(li.QuadPart) if Sz <= 0: wb.CloseHandle(H) LastReadErr = 3 @@ -288,7 +288,7 @@ def ReadWholeFile(Path: str, MaxBytes: t.CSizeT, Share: ULONG) -> bytes: wb.CloseHandle(H) LastReadErr = 5 return None - Got: t.CSizeT = ReadFull(H, Buf, Sz) + Got: sizet = ReadFull(H, Buf, Sz) wb.CloseHandle(H) Buf[Got] = 0 LastReadSize = Got @@ -297,7 +297,7 @@ def ReadWholeFile(Path: str, MaxBytes: t.CSizeT, Share: ULONG) -> bytes: # 把 Buf[0..Len) 全量写入 Path(CREATE_ALWAYS)。 # 返回 1=完整写入,0=打开/写入失败,-1=写入不完整(实际字节见 LastWriteDone) -def WriteFileAll(Path: str, Buf: bytes, Len: t.CSizeT) -> int: +def WriteFileAll(Path: str, Buf: bytes, Len: sizet) -> int: global LastWriteDone LastWriteDone = 0 if Buf is None: @@ -306,17 +306,17 @@ def WriteFileAll(Path: str, Buf: bytes, Len: t.CSizeT) -> int: None, wf.CREATE_ALWAYS, wf.FILE_ATTRIBUTE_NORMAL, None) if H == wb.INVALID_HANDLE_VALUE: return 0 - total: t.CSizeT = 0 + total: sizet = 0 while total < Len: - chunk: t.CSizeT = Len - total + chunk: sizet = Len - total if chunk > 0x7FFFFFFF: - chunk = t.CSizeT(0x7FFFFFFF) + chunk = sizet(0x7FFFFFFF) bw: ULONG = 0 - if wf.WriteFile(H, Buf + total, ULONG(chunk), t.CPtr(c.Addr(bw)), None) == 0: + if wf.WriteFile(H, Buf + total, ULONG(chunk), t.CPtr(&bw), None) == 0: break if bw == 0: break - total += t.CSizeT(bw) + total += sizet(bw) wb.CloseHandle(H) LastWriteDone = total if total < Len: diff --git a/App/lib/VGuard.vp b/App/lib/VGuard.vp index 70f14a6..e7571b0 100644 --- a/App/lib/VGuard.vp +++ b/App/lib/VGuard.vp @@ -216,45 +216,45 @@ import w32.win32console as wc # 见"加固 1"与 GuardResolveReadEx)。 # ============================================================ -SYNCHRONIZE: t.CDefine = 0x00100000 # winnt.h +define SYNCHRONIZE = 0x00100000 # winnt.h # OpenProcess 需要的访问权限:PROCESS_TERMINATE(0x0001) | SYNCHRONIZE(0x00100000) -WATCH_PARENT_ACCESS: t.CDefine = 0x00100001 -CONFIRM_WATCH_CMD: t.CDefine = "confirm-watch" # 内部隐藏子命令名 +define WATCH_PARENT_ACCESS = 0x00100001 +define CONFIRM_WATCH_CMD = "confirm-watch" # 内部隐藏子命令名 # stdin 行缓冲:既要放 {"ok": 1},也要放 check 请求行({"check":"","id":}, # 路径可达 MAX_PATH 量级)⇒ 取 4096(与 VCheck.CK_LINE_MAX 同值)。行超此上限按"一行结束" # 处理(与旧实现"缓冲写满即截断成一行"一致;超长的 check 行会因路径被截断而判 NOT_FOUND)。 -GUARD_LINE_CAP: t.CDefine = 4096 -GUARD_STAMP_CAP: t.CDefine = 64 # 时间戳文本缓冲 -SELF_PATH_CAP: t.CDefine = 1024 # GetModuleFileNameA 输出缓冲 +define GUARD_LINE_CAP = 4096 +define GUARD_STAMP_CAP = 64 # 时间戳文本缓冲 +define SELF_PATH_CAP = 1024 # GetModuleFileNameA 输出缓冲 # 命令行额外量(子命令 + interval/timeout/parent-pid/ipc-write + --verbose + NUL;句柄按 # 最多 20 位十进制字符计。留足余量以免 snprintf 截断出"看似正常实则错参"的命令行) -WATCH_CMD_EXTRA_CAP: t.CDefine = 256 -WATCH_HANDLE_COUNT: t.CDefine = 2 # WaitForMultipleObjects 句柄个数 +define WATCH_CMD_EXTRA_CAP = 256 +define WATCH_HANDLE_COUNT = 2 # WaitForMultipleObjects 句柄个数 # 拉起后"存活校验"的等待窗口(毫秒)。代价:每次 scan 启动多等这么一会儿(README 已注明); # 取 400 是"够看门狗跑完参数解析/OpenProcess/首次等待"与"不显著拖慢启动"之间的折中。 -WATCH_ALIVE_PROBE_MS: t.CDefine = 400 +define WATCH_ALIVE_PROBE_MS = 400 # ---- 非阻塞确认输入(控制台 / 管道 / 重定向)---- # GetFileType 返回值(fileapi.h;本仓 include 未声明这几个常量) -FILE_TYPE_DISK: t.CDefine = 0x0001 # 磁盘文件(含 `< file` 重定向) -FILE_TYPE_CHAR: t.CDefine = 0x0002 # 字符设备(控制台/LPT 等) -FILE_TYPE_PIPE: t.CDefine = 0x0003 # 管道/套接字(含 `|` 重定向) +define FILE_TYPE_DISK = 0x0001 # 磁盘文件(含 `< file` 重定向) +define FILE_TYPE_CHAR = 0x0002 # 字符设备(控制台/LPT 等) +define FILE_TYPE_PIPE = 0x0003 # 管道/套接字(含 `|` 重定向) # 输入形态(GuardInputKind 返回值) -GUARD_IN_CONSOLE: t.CDefine = 1 # 控制台(CHAR + GetConsoleMode 成功) -GUARD_IN_PIPE: t.CDefine = 2 # 管道(可用 PeekNamedPipe 预询可读量) -GUARD_IN_STREAM: t.CDefine = 3 # 其它流(磁盘文件等:只能有界读) +define GUARD_IN_CONSOLE = 1 # 控制台(CHAR + GetConsoleMode 成功) +define GUARD_IN_PIPE = 2 # 管道(可用 PeekNamedPipe 预询可读量) +define GUARD_IN_STREAM = 3 # 其它流(磁盘文件等:只能有界读) # 清位掩码:ENABLE_LINE_INPUT(0x0002)|ENABLE_ECHO_INPUT(0x0004) 的补(wincon.h) -GUARD_RAW_CLEAR_MASK: t.CDefine = 0xFFFFFFF9 +define GUARD_RAW_CLEAR_MASK = 0xFFFFFFF9 # INPUT_RECORD 内 KEY_EVENT_RECORD 字段偏移(x64 布局推导见 VET/README.md「控制台记录的读取口径」) -GUARD_KEY_DOWN_OFF: t.CDefine = 4 # KeyEvent.bKeyDown (BOOL) -GUARD_KEY_CHAR_OFF: t.CDefine = 14 # KeyEvent.uChar (WCHAR/CHAR union 头 2 字节) -GUARD_REC_SIZE: t.CDefine = 20 # sizeof(INPUT_RECORD)=EventType(2)+pad(2)+union(16) -GUARD_REC_MAX: t.CDefine = 16 # 单次 ReadConsoleInputA 最多读的记录数 -GUARD_REC_CAP: t.CDefine = 320 # 记录缓冲字节数(20*16) -GUARD_CHUNK_CAP: t.CDefine = 64 # 管道/文件单次 ReadFile 上限(字节) -GUARD_POLL_MS: t.CDefine = 20 # 无可读数据时的推进节拍(同 VScan.PACE_SLEEP_MS) +define GUARD_KEY_DOWN_OFF = 4 # KeyEvent.bKeyDown (BOOL) +define GUARD_KEY_CHAR_OFF = 14 # KeyEvent.uChar (WCHAR/CHAR union 头 2 字节) +define GUARD_REC_SIZE = 20 # sizeof(INPUT_RECORD)=EventType(2)+pad(2)+union(16) +define GUARD_REC_MAX = 16 # 单次 ReadConsoleInputA 最多读的记录数 +define GUARD_REC_CAP = 320 # 记录缓冲字节数(20*16) +define GUARD_CHUNK_CAP = 64 # 管道/文件单次 ReadFile 上限(字节) +define GUARD_POLL_MS = 20 # 无可读数据时的推进节拍(同 VScan.PACE_SLEEP_MS) # 取数结果码(两路共用;-1 为"读取失败") -GUARD_PUMP_EOF: t.CDefine = -2 # 不可能再出现输入(ReadFile 读到 0 字节) +define GUARD_PUMP_EOF = -2 # 不可能再出现输入(ReadFile 读到 0 字节) # ---- 快修:未消费输入 FIFO(两路取数共用;见模块头「快修:批量输入与可疑行」)---- # 容量的推导(常量实际值取自本文件上方声明): @@ -267,34 +267,34 @@ GUARD_PUMP_EOF: t.CDefine = -2 # 不可能再出现输 # 不变量(改动任一常量时须保持):GUARD_PEND_CAP >= GUARD_CHUNK_CAP,且 >= GUARD_REC_MAX # (否则单批读入量放不进 FIFO;GuardPumpStream/GuardPumpConsole 里的两处夹取是该不变量的 # 显式执行,GuardPendPut 的边界守卫是最后一道防线)。 -GUARD_PEND_CAP: t.CDefine = 128 # 未消费输入 FIFO 容量(字节) +define GUARD_PEND_CAP = 128 # 未消费输入 FIFO 容量(字节) # 可疑行回显的截断长度(stderr 只回显前缀,避免把超长输入整行打出去) -GUARD_SUSPECT_ECHO_MAX: t.CDefine = 120 +define GUARD_SUSPECT_ECHO_MAX = 120 # 行分类结果码(GuardClassifyLine 返回值,见模块头「快修:批量输入与可疑行」) -GUARD_LINE_SUSPECT: t.CDefine = 0 # 形状可疑 ⇒ 忽略该行并继续等(期限不变) -GUARD_LINE_OK: t.CDefine = 1 # 合法 {"ok": 1} ⇒ 本行确认成功 -GUARD_LINE_BADOK: t.CDefine = 2 # 形状合法但值不对 ⇒ 致命失败(口径不放宽) +define GUARD_LINE_SUSPECT = 0 # 形状可疑 ⇒ 忽略该行并继续等(期限不变) +define GUARD_LINE_OK = 1 # 合法 {"ok": 1} ⇒ 本行确认成功 +define GUARD_LINE_BADOK = 2 # 形状合法但值不对 ⇒ 致命失败(口径不放宽) # 形状检查的长度上界:合法 {"ok": 1} 正常不超过 16 字节(去掉空格/制表符后更短), # 取 256 留足余量(可容忍 "{ \"ok\" : 1 }" 之类的空白展开),超过即按"被撕裂的残行/噪声"处理。 -GUARD_OK_LINE_MAX: t.CDefine = 256 +define GUARD_OK_LINE_MAX = 256 # ---- check 请求通道(看门狗 → 父进程的 IPC 管道;依附 --need-confirm)---- # 行缓冲上限与看门狗侧 GUARD_LINE_CAP 同值(请求行由看门狗逐字节转发,长度不会超过它) -IPC_LINE_CAP: t.CDefine = 4096 -IPC_READ_CHUNK: t.CDefine = 1024 # 单次 ReadFile 上限(只读"已确认可用"的部分) -IPC_PIPE_SIZE: t.CDefine = 65536 # CreatePipe 的 nSize 提示(默认过小,给足以免看门狗写阻塞) +define IPC_LINE_CAP = 4096 +define IPC_READ_CHUNK = 1024 # 单次 ReadFile 上限(只读"已确认可用"的部分) +define IPC_PIPE_SIZE = 65536 # CreatePipe 的 nSize 提示(默认过小,给足以免看门狗写阻塞) # ---- 加固 1:ReadConsoleInputExA 动态解析(无导入库,只能 GetProcAddress)---- -CONSOLE_READ_NOWAIT: t.CDefine = 0x0002 # 输入缓冲为空也立即返回(文档 wFlags) +define CONSOLE_READ_NOWAIT = 0x0002 # 输入缓冲为空也立即返回(文档 wFlags) # ReadConsoleInputExA 的解析状态(Guard_ReadExState;0 = 未尝试解析) -GUARD_EX_OK: t.CDefine = 1 # 已解析到函数地址(走主路径) -GUARD_EX_MISSING: t.CDefine = 2 # 该导出不存在(走降级路径,不再重试) +define GUARD_EX_OK = 1 # 已解析到函数地址(走主路径) +define GUARD_EX_MISSING = 2 # 该导出不存在(走降级路径,不再重试) # 降级路径"等可读"的单次上限(毫秒):把这一步的等待收紧,避免一次等待吃掉整个剩余预算; # 取 5 是"够等一次输入到达"与"不显著拖慢判定"之间的折中(其后还有 GUARD_POLL_MS 节拍)。 -GUARD_LEGACY_WAIT_MS: t.CDefine = 5 +define GUARD_LEGACY_WAIT_MS = 5 # SetConsoleCtrlHandler 的 Add 参数(consoleapi.h 的 TRUE/FALSE 同名,此处用字面量以免混淆) -GUARD_CTRL_ADD: t.CDefine = 1 -GUARD_CTRL_REMOVE: t.CDefine = 0 +define GUARD_CTRL_ADD = 1 +define GUARD_CTRL_REMOVE = 0 # Win32 自声明(本仓 includes/w32 无 PeekNamedPipe): # kernel32!PeekNamedPipe: BOOL PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, @@ -303,7 +303,7 @@ GUARD_CTRL_REMOVE: t.CDefine = 0 # 原型出处:namedpipeapi.h / Kernel32.lib / kernel32.dll(project.vpj 已链接 kernel32)。 # 语义:句柄必须是管道读端;不取走数据、立即返回;lpTotalBytesAvail = 当前可读字节数。 extern def PeekNamedPipe(hNamedPipe: wb.HANDLE, lpBuffer: t.CPtr, nBufferSize: ULONG, - lpBytesRead: t.CPtr, lpTotalBytesAvail: ULONG | t.CPtr, + lpBytesRead: t.CPtr, lpTotalBytesAvail: ULONG*, lpBytesLeftThisMessage: t.CPtr) -> BOOL # Win32 自声明(本仓 includes/w32 无 SetConsoleCtrlHandler): @@ -411,15 +411,15 @@ def GuardIpcCreate() -> wb.HANDLE: if Ipc_Line is None or Ipc_Chunk is None: return None Sa: wb.SECURITY_ATTRIBUTES = wb.SECURITY_ATTRIBUTES() - Sa.nLength = t.CUInt32T(wb.SECURITY_ATTRIBUTES.__sizeof__()) + Sa.nLength = uint32(wb.SECURITY_ATTRIBUTES.__sizeof__()) Sa.lpSecurityDescriptor = t.CPtr(0) Sa.bInheritHandle = 1 # 两端先都建为可继承,随后单方面清读端 hRead: wb.HANDLE = None hWrite: wb.HANDLE = None - if wf.CreatePipe(t.CPtr(c.Addr(hRead)), t.CPtr(c.Addr(hWrite)), - t.CPtr(c.Addr(Sa)), ULONG(IPC_PIPE_SIZE)) == 0: + if wf.CreatePipe(t.CPtr(&hRead), t.CPtr(&hWrite), + t.CPtr(&Sa), ULONG(IPC_PIPE_SIZE)) == 0: VLog.LogFmt1("[confirm] 警告: check 通道 CreatePipe 失败 (GetLastError=%u)\n", - t.CSizeT(wb.GetLastError())) + sizet(wb.GetLastError())) return None # 读端只在父进程用:清掉继承位,避免被任何子进程(看门狗、--version 探测)继承 wf.SetHandleInformation(hRead, wf.HANDLE_FLAG_INHERIT, 0) @@ -448,7 +448,7 @@ def PollIpc() -> int: Done: int = 0 while True: Avail: ULONG = 0 - if PeekNamedPipe(Ipc_Read, t.CPtr(0), 0, t.CPtr(0), t.CPtr(c.Addr(Avail)), t.CPtr(0)) == 0: + if PeekNamedPipe(Ipc_Read, t.CPtr(0), 0, t.CPtr(0), t.CPtr(&Avail), t.CPtr(0)) == 0: return Done # 管道异常:本轮不再读(不阻塞、不重试) if Avail == 0: return Done # 无数据 ⇒ 立即返回(轮询点的高频路径) @@ -456,13 +456,13 @@ def PollIpc() -> int: if Avail < N: N = Avail # 只读"确已有数据"的部分 ⇒ ReadFile 不会阻塞 Br: ULONG = 0 - if wf.ReadFile(Ipc_Read, Ipc_Chunk, N, t.CPtr(c.Addr(Br)), None) == 0: + if wf.ReadFile(Ipc_Read, Ipc_Chunk, N, t.CPtr(&Br), None) == 0: return Done if Br == 0: return Done ub: BYTEPTR = BYTEPTR(Ipc_Chunk) i: int = 0 - while i < t.CInt(Br): + while i < int(Br): Ch: int = int(ub[i]) i += 1 if Ch == 10: # '\n':一行结束 @@ -475,7 +475,7 @@ def PollIpc() -> int: if Ipc_Fill >= IPC_LINE_CAP - 1: Ipc_Fill = 0 # 超长行:丢弃该行(不越界、不与下一行粘连) else: - Ipc_Line[Ipc_Fill] = t.CChar(Ch) + Ipc_Line[Ipc_Fill] = char(Ch) Ipc_Fill += 1 @@ -490,9 +490,9 @@ def SelfExePath(Out: bytes, Cap: int) -> int: n: ULONG = wf.GetModuleFileNameA(None, Out, ULONG(Cap)) if n == 0: return 0 - if t.CSizeT(n) >= t.CSizeT(Cap): + if sizet(n) >= sizet(Cap): return 0 # 缓冲不足(路径被截断)⇒ 视为失败 - Out[t.CInt(n)] = 0 + Out[int(n)] = 0 return 1 @@ -552,11 +552,11 @@ def SpawnWatchdog(IntervalSec: int, TimeoutMs: int) -> int: Extra: str = "" if VCli.Verbose() != 0: Extra = " --verbose" - viperlib.snprintf(Cmd, t.CSizeT(SELF_PATH_CAP + WATCH_CMD_EXTRA_CAP), + viperlib.snprintf(Cmd, sizet(SELF_PATH_CAP + WATCH_CMD_EXTRA_CAP), "\"%s\" %s --interval %u --timeout %u --parent-pid %u --ipc-write %llu%s", str(Self), CONFIRM_WATCH_CMD, - t.CSizeT(IntervalSec), t.CSizeT(TimeoutMs), t.CSizeT(Pid), - t.CUInt64T(IpcW), Extra) + sizet(IntervalSec), sizet(TimeoutMs), sizet(Pid), + uint64(IpcW), Extra) # 标准句柄:与父进程同一(继承控制台/重定向);stdin 也一并交给看门狗 hIn: wb.HANDLE = wf.GetStdHandle(wf.STD_INPUT_HANDLE) @@ -577,7 +577,7 @@ def SpawnWatchdog(IntervalSec: int, TimeoutMs: int) -> int: wf.SetHandleInformation(hErr, wf.HANDLE_FLAG_INHERIT, wf.HANDLE_FLAG_INHERIT) Si: wp.STARTUPINFOA = wp.STARTUPINFOA() - Si.cb = t.CUInt32T(wp.STARTUPINFOA.__sizeof__()) + Si.cb = uint32(wp.STARTUPINFOA.__sizeof__()) Si.dwFlags = wp.STARTF_USESTDHANDLES Si.hStdInput = hIn Si.hStdOutput = hOut @@ -585,7 +585,7 @@ def SpawnWatchdog(IntervalSec: int, TimeoutMs: int) -> int: Pi: wp.PROCESS_INFORMATION = wp.PROCESS_INFORMATION() Ok: BOOL = wp.CreateProcessA(t.CPtr(0), Cmd, t.CPtr(0), t.CPtr(0), 1, 0, - t.CPtr(0), t.CPtr(0), t.CPtr(c.Addr(Si)), t.CPtr(c.Addr(Pi))) + t.CPtr(0), t.CPtr(0), t.CPtr(&Si), t.CPtr(&Pi)) CreateErr: ULONG = wb.GetLastError() # 紧跟调用读取(free 会覆盖 GetLastError) _mbuddy.free(t.CPtr(Self)) _mbuddy.free(t.CPtr(Cmd)) @@ -593,7 +593,7 @@ def SpawnWatchdog(IntervalSec: int, TimeoutMs: int) -> int: wb.CloseHandle(IpcW) GuardIpcClose() VLog.LogFmt1("[confirm] 警告: 看门狗 CreateProcessA 失败 (GetLastError=%u),未启动\n", - t.CSizeT(CreateErr)) + sizet(CreateErr)) return 0 # 写端已由看门狗继承 ⇒ 父进程立即关掉自己的副本:这样后续任何 CreateProcessA @@ -607,9 +607,9 @@ def SpawnWatchdog(IntervalSec: int, TimeoutMs: int) -> int: Wp: ULONG = wsync.WaitForSingleObject(Watch_Process, WATCH_ALIVE_PROBE_MS) if Wp == wb.WAIT_OBJECT_0: Ec: ULONG = 0 - wp.GetExitCodeProcess(Watch_Process, t.CPtr(c.Addr(Ec))) + wp.GetExitCodeProcess(Watch_Process, t.CPtr(&Ec)) VLog.LogFmt1("[confirm] 看门狗拉起后立即退出 (exit=%u),心跳确认无法生效\n", - t.CSizeT(Ec)) + sizet(Ec)) # 致命路径与 StopWatchdog 一样各自 CloseHandle 一次,并清空模块级句柄 # (避免随后 StopWatchdog/再次 Spawn 造成双重关闭)。 wb.CloseHandle(Watch_Process) @@ -623,8 +623,8 @@ def SpawnWatchdog(IntervalSec: int, TimeoutMs: int) -> int: VLog.StdoutWrite("{\"exit\":1, \"msg\": \"timeout/ok!=1\"}\n") return 0 VLog.LogFmt2("[confirm] 心跳看门狗已启动 (pid=%u, 每 %u 秒一次", - t.CSizeT(Pi.dwProcessId), t.CSizeT(IntervalSec)) - VLog.LogFmt1(", 确认超时 %u ms)\n", t.CSizeT(TimeoutMs)) + sizet(Pi.dwProcessId), sizet(IntervalSec)) + VLog.LogFmt1(", 确认超时 %u ms)\n", sizet(TimeoutMs)) return 1 @@ -740,10 +740,10 @@ def GuardForwardLine(): bw: ULONG = 0 if Guard_Fill > 0: if wf.WriteFile(Guard_IpcWrite, Guard_Line, ULONG(Guard_Fill), - t.CPtr(c.Addr(bw)), None) == 0: + t.CPtr(&bw), None) == 0: VLog.LogStr("[confirm] 警告: check 请求转发失败(写管道失败),已丢弃该行\n") return - if wf.WriteFile(Guard_IpcWrite, "\n", 1, t.CPtr(c.Addr(bw)), None) == 0: + if wf.WriteFile(Guard_IpcWrite, "\n", 1, t.CPtr(&bw), None) == 0: VLog.LogStr("[confirm] 警告: check 请求转发失败(写行分隔符失败),该行可能不完整\n") @@ -778,7 +778,7 @@ def GuardFeedByte(Ch: int) -> int: if Guard_Fill >= GUARD_LINE_CAP - 1: Guard_Line[Guard_Fill] = 0 return 1 - Guard_Line[Guard_Fill] = t.CChar(Ch) + Guard_Line[Guard_Fill] = char(Ch) Guard_Fill += 1 Guard_Line[Guard_Fill] = 0 return 0 @@ -816,9 +816,9 @@ def GuardPendPut(Ch: int): global Guard_PendLen if Guard_PendLen >= GUARD_PEND_CAP: VLog.LogFmt1("[confirm] 警告: 未消费输入 FIFO 已满(容量 %u),丢弃该批字节\n", - t.CSizeT(GUARD_PEND_CAP)) + sizet(GUARD_PEND_CAP)) return - Guard_Pend[Guard_PendLen] = t.CChar(Ch) + Guard_Pend[Guard_PendLen] = char(Ch) Guard_PendLen += 1 @@ -829,7 +829,7 @@ def GuardInputKind(hIn: wb.HANDLE) -> int: T: ULONG = wf.GetFileType(hIn) if T == ULONG(FILE_TYPE_CHAR): Mode: ULONG = 0 - if wc.GetConsoleMode(hIn, t.CPtr(c.Addr(Mode))) != 0: + if wc.GetConsoleMode(hIn, t.CPtr(&Mode)) != 0: return GUARD_IN_CONSOLE return GUARD_IN_STREAM if T == ULONG(FILE_TYPE_PIPE): @@ -908,7 +908,7 @@ def GuardRemoveCtrlHandler(): def GuardEnterRaw(hIn: wb.HANDLE) -> int: global Guard_SavedMode, Guard_RawActive, Guard_ConHandle, Guard_CtrlHandlerOn Mode: ULONG = 0 - if wc.GetConsoleMode(hIn, t.CPtr(c.Addr(Mode))) == 0: + if wc.GetConsoleMode(hIn, t.CPtr(&Mode)) == 0: return 0 Guard_SavedMode = Mode Guard_RawActive = 0 @@ -970,7 +970,7 @@ def GuardPumpConsole(hIn: wb.HANDLE, Deadline: ULONGLONG) -> int: # Guard_ReadEx 为模块级 t.Callable,其返回类型签名已随模块级 AnnAssign 登记 # (TranslatorGenMixin.handle_module_level_var),故可直接间接调用。 if Guard_ReadEx(hIn, t.CPtr(Guard_Recs), ULONG(GUARD_REC_MAX), - t.CPtr(c.Addr(Read)), USHORT(CONSOLE_READ_NOWAIT)) == 0: + t.CPtr(&Read), USHORT(CONSOLE_READ_NOWAIT)) == 0: return -1 else: Rem: ULONG = GuardRemainMs(Deadline) @@ -981,25 +981,25 @@ def GuardPumpConsole(hIn: wb.HANDLE, Deadline: ULONGLONG) -> int: if wsync.WaitForSingleObject(hIn, Rem) == ULONG(wb.WAIT_FAILED): return -1 Cnt: ULONG = 0 - if wc.GetNumberOfConsoleInputEvents(hIn, t.CPtr(c.Addr(Cnt))) == 0: + if wc.GetNumberOfConsoleInputEvents(hIn, t.CPtr(&Cnt)) == 0: return -1 if Cnt == 0: return 0 N: ULONG = Cnt if N > ULONG(GUARD_REC_MAX): N = ULONG(GUARD_REC_MAX) - if wc.ReadConsoleInputA(hIn, t.CPtr(Guard_Recs), N, t.CPtr(c.Addr(Read))) == 0: + if wc.ReadConsoleInputA(hIn, t.CPtr(Guard_Recs), N, t.CPtr(&Read)) == 0: return -1 ub: BYTEPTR = BYTEPTR(Guard_Recs) i: int = 0 - while i < t.CInt(Read): + while i < int(Read): Base: int = i * GUARD_REC_SIZE i += 1 - if VPe.ReadU16(ub, Base) != t.CUInt32T(wc.KEY_EVENT): + if VPe.ReadU16(ub, Base) != uint32(wc.KEY_EVENT): continue if VPe.ReadU32(ub, Base + GUARD_KEY_DOWN_OFF) == 0: continue - Ch: int = t.CInt(VPe.ReadU16(ub, Base + GUARD_KEY_CHAR_OFF)) + Ch: int = int(VPe.ReadU16(ub, Base + GUARD_KEY_CHAR_OFF)) if Ch == 13: Ch = 10 # Enter → 行结束(与 '\n' 同一口径) elif Ch != 9 and (Ch < 32 or Ch > 126): @@ -1029,7 +1029,7 @@ def GuardPumpStream(hIn: wb.HANDLE, Kind: int) -> int: N: ULONG = ULONG(GUARD_CHUNK_CAP) if Kind == GUARD_IN_PIPE: Avail: ULONG = 0 - if PeekNamedPipe(hIn, t.CPtr(0), 0, t.CPtr(0), t.CPtr(c.Addr(Avail)), t.CPtr(0)) == 0: + if PeekNamedPipe(hIn, t.CPtr(0), 0, t.CPtr(0), t.CPtr(&Avail), t.CPtr(0)) == 0: return -1 if Avail == 0: return 0 @@ -1044,13 +1044,13 @@ def GuardPumpStream(hIn: wb.HANDLE, Kind: int) -> int: if N > ULONG(GUARD_PEND_CAP): N = ULONG(GUARD_PEND_CAP) Br: ULONG = 0 - if wf.ReadFile(hIn, Guard_Chunk, N, t.CPtr(c.Addr(Br)), None) == 0: + if wf.ReadFile(hIn, Guard_Chunk, N, t.CPtr(&Br), None) == 0: return -1 if Br == 0: return GUARD_PUMP_EOF ub: BYTEPTR = BYTEPTR(Guard_Chunk) i: int = 0 - while i < t.CInt(Br): + while i < int(Br): GuardPendPut(int(ub[i])) # ③ 先整批入队(Br <= N <= GUARD_PEND_CAP) i += 1 if GuardFeedPending() != 0: # ③ 再喂 FIFO;剩余字节留给下次调用 @@ -1127,7 +1127,7 @@ def GuardWaitConfirm(hIn: wb.HANDLE, hParent: wb.HANDLE, Kind: int, TimeoutMs: i if GuardEnterRaw(hIn) == 0: GuardWatchFail(hParent, "控制台模式读取/切换失败") return 0 - Deadline: ULONGLONG = wb.GetTickCount64() + ULONGLONG(t.CUInt32T(TimeoutMs)) + Deadline: ULONGLONG = wb.GetTickCount64() + ULONGLONG(uint32(TimeoutMs)) while True: # ② 先取数(GuardPump* 内部先喂 FIFO):FIFO 里已有整行时不会白等一次 20ms R: int = 0 @@ -1183,7 +1183,7 @@ def GuardWaitConfirm(hIn: wb.HANDLE, hParent: wb.HANDLE, Kind: int, TimeoutMs: i Hs.H0 = hIn Hs.H1 = hParent Wm: ULONG = wsync.WaitForMultipleObjects(ULONG(WATCH_HANDLE_COUNT), - t.CPtr(c.Addr(Hs)), 0, Sl) + t.CPtr(&Hs), 0, Sl) if Wm == ULONG(wb.WAIT_OBJECT_0) + ULONG(1): # 父进程句柄(索引 1)置信号 GuardLeaveRaw(hIn) return 0 @@ -1213,14 +1213,14 @@ def RunConfirmWatch() -> int: return 1 VLog.LogFmt3("[confirm] 看门狗启动: 每 %u 秒要求一次 {\"ok\": 1},超时 %u ms,父进程 pid=%u\n", - t.CSizeT(IntervalSec), t.CSizeT(TimeoutMs), t.CSizeT(ParentPid)) + sizet(IntervalSec), sizet(TimeoutMs), sizet(ParentPid)) # 父进程句柄:同时用于"父退出检测(SYNCHRONIZE)"与"失败时终止父进程(PROCESS_TERMINATE)" hParent: wb.HANDLE = wp.OpenProcess(ULONG(WATCH_PARENT_ACCESS), 0, ULONG(ParentPid)) if hParent is None or hParent == wb.INVALID_HANDLE_VALUE: # 拿不到父进程句柄 ⇒ 既无法监控也无法终止,无法履行契约:只记 stderr 并以 1 退出 VLog.LogFmt1("[confirm] 看门狗: OpenProcess 父进程失败 (GetLastError=%u),自身退出\n", - t.CSizeT(wb.GetLastError())) + sizet(wb.GetLastError())) return 1 hIn: wb.HANDLE = wf.GetStdHandle(wf.STD_INPUT_HANDLE) @@ -1237,19 +1237,19 @@ def RunConfirmWatch() -> int: Ch0: int = 0 if Guard_IpcWrite is not None: Ch0 = 1 - VLog.VerboseFmt1("[confirm] 看门狗: check 通道=%u (1=已配置 0=无)\n", t.CSizeT(Ch0)) + VLog.VerboseFmt1("[confirm] 看门狗: check 通道=%u (1=已配置 0=无)\n", sizet(Ch0)) # 输入形态只判一次(句柄在进程生命周期内不变);控制台与管道/重定向的取数路径不同。 Kind: int = GuardInputKind(hIn) VLog.VerboseFmt1("[confirm] 看门狗: stdin 形态=%u (1=控制台 2=管道 3=其它流)\n", - t.CSizeT(Kind)) + sizet(Kind)) # 控制台取数路径(加固 1):主路径=ReadConsoleInputExA+CONSOLE_READ_NOWAIT, # 降级=GetNumberOfConsoleInputEvents+ReadConsoleInputA(该导出不存在的老系统)。 # 这里提前解析一次(后续判定复用缓存的状态),顺带把实际走哪一路写进 --verbose 日志。 if Kind == GUARD_IN_CONSOLE: GuardResolveReadEx() VLog.VerboseFmt1("[confirm] 看门狗: 控制台取数路径=%u (1=ReadConsoleInputExA+NOWAIT 2=降级查询+ReadConsoleInputA)\n", - t.CSizeT(Guard_ReadExState)) + sizet(Guard_ReadExState)) while True: # 阶段 1:等 interval;父进程先退出则立即自退(无需父侧配合,杜绝孤儿) @@ -1259,15 +1259,15 @@ def RunConfirmWatch() -> int: wb.CloseHandle(hParent) return 0 if Ws != wb.WAIT_TIMEOUT: - VLog.LogFmt1("[confirm] 看门狗: 等待父进程失败 (wait=%u)\n", t.CSizeT(Ws)) + VLog.LogFmt1("[confirm] 看门狗: 等待父进程失败 (wait=%u)\n", sizet(Ws)) GuardWatchFail(hParent, "等待父进程失败") return 1 # 阶段 2:stderr 提示(期限自本行起算)+ 在 timeout 内非阻塞等"完整一行且分类通过" VLog.LogFmt2("[confirm] 请在 %u ms 内输入 {\"ok\": 1}(每 %u 秒一次)\n", - t.CSizeT(TimeoutMs), t.CSizeT(IntervalSec)) + sizet(TimeoutMs), sizet(IntervalSec)) VLog.TimeStampNow(Guard_Stamp, GUARD_STAMP_CAP) - VLog.TimeStampAfter(Guard_Dl, GUARD_STAMP_CAP, t.CSizeT(TimeoutMs)) + VLog.TimeStampAfter(Guard_Dl, GUARD_STAMP_CAP, sizet(TimeoutMs)) VLog.LogFmtS2("[confirm] 当前 %s, 本轮期限 %s\n", str(Guard_Stamp), str(Guard_Dl)) # 失败路径(期限到点/形状合法但值不对/读失败/EOF)已在 GuardWaitConfirm 内收尾并退出进程; @@ -1276,4 +1276,4 @@ def RunConfirmWatch() -> int: VLog.LogStr("[confirm] 看门狗: 父进程已退出,自身退出\n") wb.CloseHandle(hParent) return 0 - VLog.LogFmt1("[confirm] 确认成功 (ok=1),下一次约 %u 秒后\n", t.CSizeT(IntervalSec)) + VLog.LogFmt1("[confirm] 确认成功 (ok=1),下一次约 %u 秒后\n", sizet(IntervalSec)) diff --git a/App/lib/VGuid.vp b/App/lib/VGuid.vp index ff3fbde..bff0cf8 100644 --- a/App/lib/VGuid.vp +++ b/App/lib/VGuid.vp @@ -17,10 +17,10 @@ import lib.VPe as VPe # DLL 归属:ole32(project.vpj 已含 -lole32)。 # ============================================================ -GUID_SIZE: t.CDefine = 16 # GUID:Data1(4)+Data2(2)+Data3(2)+Data4(8) -GUID_STR_CAP: t.CDefine = 40 # "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + NUL +define GUID_SIZE = 16 # GUID:Data1(4)+Data2(2)+Data3(2)+Data4(8) +define GUID_STR_CAP = 40 # "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + NUL -HRESULT: t.CTypedef = t.CInt32T # Win32: typedef LONG HRESULT(负值才是失败) +HRESULT: t.CTypedef = int32 # Win32: typedef LONG HRESULT(负值才是失败) extern def CoCreateGuid(pguid: t.CPtr) -> HRESULT @@ -40,15 +40,15 @@ def NewGuidStr(Out: bytes, Cap: int) -> int: _mbuddy.free(t.CPtr(GB)) return 0 ub: BYTEPTR = BYTEPTR(GB) - D1: t.CUInt32T = VPe.ReadU32(ub, 0) - D2: t.CUInt32T = VPe.ReadU16(ub, 4) - D3: t.CUInt32T = VPe.ReadU16(ub, 6) - viperlib.snprintf(Out, t.CSizeT(Cap), + D1: uint32 = VPe.ReadU32(ub, 0) + D2: uint32 = VPe.ReadU16(ub, 4) + D3: uint32 = VPe.ReadU16(ub, 6) + viperlib.snprintf(Out, sizet(Cap), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", D1, D2, D3, - t.CUInt32T(ub[8]), t.CUInt32T(ub[9]), - t.CUInt32T(ub[10]), t.CUInt32T(ub[11]), - t.CUInt32T(ub[12]), t.CUInt32T(ub[13]), - t.CUInt32T(ub[14]), t.CUInt32T(ub[15])) + uint32(ub[8]), uint32(ub[9]), + uint32(ub[10]), uint32(ub[11]), + uint32(ub[12]), uint32(ub[13]), + uint32(ub[14]), uint32(ub[15])) _mbuddy.free(t.CPtr(GB)) return 1 diff --git a/App/lib/VJson.vp b/App/lib/VJson.vp index 83ab59c..c0f5976 100644 --- a/App/lib/VJson.vp +++ b/App/lib/VJson.vp @@ -51,10 +51,10 @@ import lib.VCache as VCache # NewMemPool 注释与 Debugger/memhub-lifetime.md)。 # ============================================================ -JSON_BUF_CAP: t.CDefine = 1048576 # 一轮 JSON 数组缓冲 1 MiB -JSON_POOL_CAP: t.CDefine = 65536 # 逐条序列化工作池 64 KiB(每条目 reset 复用) -JSON_ENTRY_MAX: t.CDefine = 4096 # 单条上限 = json 库 write 的缺省 cap(4096) -JSON_ENTRY_SLACK: t.CDefine = 512 # 单条固定语法开销上界(实测 77:键/值引号 24 + 键名 40 + 冒号 6 + 逗号 5 + 大括号 2) +define JSON_BUF_CAP = 1048576 # 一轮 JSON 数组缓冲 1 MiB +define JSON_POOL_CAP = 65536 # 逐条序列化工作池 64 KiB(每条目 reset 复用) +define JSON_ENTRY_MAX = 4096 # 单条上限 = json 库 write 的缺省 cap(4096) +define JSON_ENTRY_SLACK = 512 # 单条固定语法开销上界(实测 77:键/值引号 24 + 键名 40 + 冒号 6 + 逗号 5 + 大括号 2) # 单条序列化在 Json_Pool 上的固定开销上界(BuildEntry 的 AllocOk 预检的一部分)。 # 组成(一次 BuildEntry 的全部池分配;条目级 reset 之后 offset=0): @@ -67,13 +67,13 @@ JSON_ENTRY_SLACK: t.CDefine = 512 # 单条固定语法开销上界( # * 余量 512 字节:6 个值副本各带一个结尾 NUL,加条内 20 次池分配按 # MEMHUB_ALIGN=8 向上取整的浪费(每次 ≤7,合计 ≤140)。 # 合计 504 + 46 + 4096 + 512 = 5158。 -JSON_ENTRY_POOL_FIXED: t.CDefine = 5158 +define JSON_ENTRY_POOL_FIXED = 5158 # 单条里 executable / displayName 的取值长度上界:二者都由 Conv_Buf(VFs.CONV_CAP 字节) # 拷出(WideCharToMultiByte 以 Cap 封顶并写结尾 NUL,失败时 VFs.CopyRaw 写空串), # 故每个值 ≤ CONV_CAP-1 字符。写 2047 = VFs.CONV_CAP(2048) - 1 的字面量:模块级 # t.CDefine 不引用跨模块常量,VFs.CONV_CAP 只在函数体内参与算术。 -JSON_ENTRY_CONV_MAX: t.CDefine = 2047 +define JSON_ENTRY_CONV_MAX = 2047 # 由 App/main.vp 注入 _mbuddy: rawptr[memhub.MemBuddy] @@ -125,14 +125,14 @@ def JWrite(S: str) -> int: global Json_Len if S is None or Json_Buf is None: return 0 - n: t.CSizeT = string.strlen(S) - if t.CSizeT(Json_Len) + n + 1 > t.CSizeT(JSON_BUF_CAP): + n: sizet = string.strlen(S) + if sizet(Json_Len) + n + 1 > sizet(JSON_BUF_CAP): return 0 - i: t.CSizeT = 0 + i: sizet = 0 while i < n: - Json_Buf[Json_Len + t.CInt(i)] = S[i] + Json_Buf[Json_Len + int(i)] = S[i] i += 1 - Json_Len += t.CInt(n) + Json_Len += int(n) Json_Buf[Json_Len] = 0 return 1 @@ -147,12 +147,12 @@ def BuildEntry(Idx: int) -> str: # 预检在 EmitJson 的条目级 reset 之后执行(池 offset=0),故单次 AllocOk 覆盖整条; # Need 由固定开销 + 全部值的长度上界构成,是条内池占用(含 20 次分配的 8 字节对齐 # 浪费)的上界,推导见 JSON_ENTRY_POOL_FIXED 与 JSON_ENTRY_CONV_MAX 的注释。 - ValNeed: t.CSizeT = t.CSizeT(JSON_ENTRY_CONV_MAX) + t.CSizeT(JSON_ENTRY_CONV_MAX) + ValNeed: sizet = sizet(JSON_ENTRY_CONV_MAX) + sizet(JSON_ENTRY_CONV_MAX) ValNeed = ValNeed + string.strlen(VCache.CacheId(Idx)) ValNeed = ValNeed + string.strlen(VCache.CacheVer(Idx)) ValNeed = ValNeed + string.strlen(VCache.CacheArch(Idx)) ValNeed = ValNeed + string.strlen(VCache.CacheSrc(Idx)) # source("workspace"/"check") - Need: t.CSizeT = t.CSizeT(JSON_ENTRY_POOL_FIXED) + ValNeed + Need: sizet = sizet(JSON_ENTRY_POOL_FIXED) + ValNeed if Json_Pool.AllocOk(Need) == 0: VLog.VerboseFmtIS(" 警告: JSON 工作池不足(本条需 %zu 字节),已跳过: %s\n", Need, VCache.CacheExe(Idx)) @@ -181,7 +181,7 @@ def BuildEntry(Idx: int) -> str: # 顺带累计各值长度,供容量守卫使用。 Ok: int = 1 N: int = 0 - Sum: t.CSizeT = 0 + Sum: sizet = 0 cu: rawptr[json.JsonValue] = Obj.child while cu != None: if cu.key == None or cu.vtype != json.JSON_STRING or cu.str_val == None: @@ -200,9 +200,9 @@ def BuildEntry(Idx: int) -> str: # 实际输出 = 各值转义长度和 + 固定语法 77(键/值引号 24 + 键名 40 + 冒号 6 + 逗号 5 + 大括号 2) # ≤ 2*Sum + 77 ≤ 2*Sum + JSON_ENTRY_SLACK(512) # 故 2*Sum + JSON_ENTRY_SLACK ≤ JSON_ENTRY_MAX ⇒ 实际输出 ≤ 3661 < 4095,含结尾 NUL 也放得下。 - if 2 * Sum + t.CSizeT(JSON_ENTRY_SLACK) > t.CSizeT(JSON_ENTRY_MAX): + if 2 * Sum + sizet(JSON_ENTRY_SLACK) > sizet(JSON_ENTRY_MAX): VLog.VerboseFmtIS(" 警告: JSON 条目过长(超过 %zu 字节),已跳过: %s\n", - t.CSizeT(JSON_ENTRY_MAX), VCache.CacheExe(Idx)) + sizet(JSON_ENTRY_MAX), VCache.CacheExe(Idx)) return None Txt: str = json.write(Json_Pool, Obj, False) @@ -232,11 +232,11 @@ def EmitJson() -> int: if Txt is None: Skipped += 1 else: - n: t.CSizeT = string.strlen(Txt) - Need: t.CSizeT = n + 3 # 自身 + 结尾 ']' + '\n' + NUL + n: sizet = string.strlen(Txt) + Need: sizet = n + 3 # 自身 + 结尾 ']' + '\n' + NUL if Count > 0: Need = Need + 1 # 分隔逗号 - if t.CSizeT(Json_Len) + Need > t.CSizeT(JSON_BUF_CAP): + if sizet(Json_Len) + Need > sizet(JSON_BUF_CAP): # 缓冲不足:跳过该条(不再像旧实现那样写出半条),末尾仍闭合 ']' Truncated = 1 else: @@ -251,8 +251,8 @@ def EmitJson() -> int: Truncated = 1 if Truncated != 0: VLog.LogFmt2(" 警告: JSON 输出缓冲不足,本轮已截断(已写 %zu 条 / 缓存 %zu 条)\n", - t.CSizeT(Count), t.CSizeT(VCache.CacheCount())) + sizet(Count), sizet(VCache.CacheCount())) if Skipped != 0: VLog.LogFmt1(" 警告: 本轮有 %zu 条 JSON 条目因过长/工作池不足被跳过\n", - t.CSizeT(Skipped)) + sizet(Skipped)) return 0 diff --git a/App/lib/VLog.vp b/App/lib/VLog.vp index a545891..28d7d5f 100644 --- a/App/lib/VLog.vp +++ b/App/lib/VLog.vp @@ -31,7 +31,7 @@ import w32.win32base as wb # viperlib.snprintf(includes/viperlib.vp:25)、string.strlen(includes/string.vp:69)。 # ============================================================ -LOG_CAP: t.CDefine = 4096 # 日志格式化缓冲 +define LOG_CAP = 4096 # 日志格式化缓冲 Log_Buffer: bytes = None # 日志格式化缓冲(stdlib.malloc,进程生命周期) @@ -43,11 +43,11 @@ def LogStr(S: str): H: wb.HANDLE = wf.GetStdHandle(wf.STD_ERROR_HANDLE) if H is None or H == wb.INVALID_HANDLE_VALUE: return - n: t.CSizeT = string.strlen(S) + n: sizet = string.strlen(S) if n == 0: return bw: ULONG = 0 - wf.WriteFile(H, S, ULONG(n), t.CPtr(c.Addr(bw)), None) + wf.WriteFile(H, S, ULONG(n), t.CPtr(&bw), None) def LogInit() -> int: @@ -61,35 +61,35 @@ def LogInit() -> int: # 固定元数的格式化转发(非 varargs 函数 ⇒ 不引入自定义可变参数风险): # 内部调用既有的 viperlib.snprintf,把格式化结果写 stderr。 -def LogFmt1(Fmt: str, A: t.CSizeT) -> int: +def LogFmt1(Fmt: str, A: sizet) -> int: if Log_Buffer is None: return 0 - viperlib.snprintf(Log_Buffer, t.CSizeT(LOG_CAP), Fmt, A) + viperlib.snprintf(Log_Buffer, sizet(LOG_CAP), Fmt, A) LogStr(str(Log_Buffer)) return 1 -def LogFmt2(Fmt: str, A: t.CSizeT, B: t.CSizeT) -> int: +def LogFmt2(Fmt: str, A: sizet, B: sizet) -> int: if Log_Buffer is None: return 0 - viperlib.snprintf(Log_Buffer, t.CSizeT(LOG_CAP), Fmt, A, B) + viperlib.snprintf(Log_Buffer, sizet(LOG_CAP), Fmt, A, B) LogStr(str(Log_Buffer)) return 1 -def LogFmt3(Fmt: str, A: t.CSizeT, B: t.CSizeT, C: t.CSizeT) -> int: +def LogFmt3(Fmt: str, A: sizet, B: sizet, C: sizet) -> int: if Log_Buffer is None: return 0 - viperlib.snprintf(Log_Buffer, t.CSizeT(LOG_CAP), Fmt, A, B, C) + viperlib.snprintf(Log_Buffer, sizet(LOG_CAP), Fmt, A, B, C) LogStr(str(Log_Buffer)) return 1 # 需求 3:扫盘进度行需要 4 个整数(r/dir/file/cand) -def LogFmt4(Fmt: str, A: t.CSizeT, B: t.CSizeT, C: t.CSizeT, D: t.CSizeT) -> int: +def LogFmt4(Fmt: str, A: sizet, B: sizet, C: sizet, D: sizet) -> int: if Log_Buffer is None: return 0 - viperlib.snprintf(Log_Buffer, t.CSizeT(LOG_CAP), Fmt, A, B, C, D) + viperlib.snprintf(Log_Buffer, sizet(LOG_CAP), Fmt, A, B, C, D) LogStr(str(Log_Buffer)) return 1 @@ -97,7 +97,7 @@ def LogFmt4(Fmt: str, A: t.CSizeT, B: t.CSizeT, C: t.CSizeT, D: t.CSizeT) -> int def LogFmtS1(Fmt: str, A: str) -> int: if Log_Buffer is None: return 0 - viperlib.snprintf(Log_Buffer, t.CSizeT(LOG_CAP), Fmt, A) + viperlib.snprintf(Log_Buffer, sizet(LOG_CAP), Fmt, A) LogStr(str(Log_Buffer)) return 1 @@ -105,15 +105,15 @@ def LogFmtS1(Fmt: str, A: str) -> int: def LogFmtS2(Fmt: str, A: str, B: str) -> int: if Log_Buffer is None: return 0 - viperlib.snprintf(Log_Buffer, t.CSizeT(LOG_CAP), Fmt, A, B) + viperlib.snprintf(Log_Buffer, sizet(LOG_CAP), Fmt, A, B) LogStr(str(Log_Buffer)) return 1 -def LogFmtIS(Fmt: str, A: t.CSizeT, B: str) -> int: +def LogFmtIS(Fmt: str, A: sizet, B: str) -> int: if Log_Buffer is None: return 0 - viperlib.snprintf(Log_Buffer, t.CSizeT(LOG_CAP), Fmt, A, B) + viperlib.snprintf(Log_Buffer, sizet(LOG_CAP), Fmt, A, B) LogStr(str(Log_Buffer)) return 1 @@ -144,28 +144,28 @@ def VerboseStr(S: str) -> int: return 1 -def VerboseFmt1(Fmt: str, A: t.CSizeT) -> int: +def VerboseFmt1(Fmt: str, A: sizet) -> int: if Verbose_Enabled == 0: return 0 LogFmt1(Fmt, A) return 1 -def VerboseFmt2(Fmt: str, A: t.CSizeT, B: t.CSizeT) -> int: +def VerboseFmt2(Fmt: str, A: sizet, B: sizet) -> int: if Verbose_Enabled == 0: return 0 LogFmt2(Fmt, A, B) return 1 -def VerboseFmt3(Fmt: str, A: t.CSizeT, B: t.CSizeT, C: t.CSizeT) -> int: +def VerboseFmt3(Fmt: str, A: sizet, B: sizet, C: sizet) -> int: if Verbose_Enabled == 0: return 0 LogFmt3(Fmt, A, B, C) return 1 -def VerboseFmt4(Fmt: str, A: t.CSizeT, B: t.CSizeT, C: t.CSizeT, D: t.CSizeT) -> int: +def VerboseFmt4(Fmt: str, A: sizet, B: sizet, C: sizet, D: sizet) -> int: if Verbose_Enabled == 0: return 0 LogFmt4(Fmt, A, B, C, D) @@ -186,7 +186,7 @@ def VerboseFmtS2(Fmt: str, A: str, B: str) -> int: return 1 -def VerboseFmtIS(Fmt: str, A: t.CSizeT, B: str) -> int: +def VerboseFmtIS(Fmt: str, A: sizet, B: str) -> int: if Verbose_Enabled == 0: return 0 LogFmtIS(Fmt, A, B) @@ -200,11 +200,11 @@ def StdoutWrite(S: str): H: wb.HANDLE = wf.GetStdHandle(wf.STD_OUTPUT_HANDLE) if H is None or H == wb.INVALID_HANDLE_VALUE: return - n: t.CSizeT = string.strlen(S) + n: sizet = string.strlen(S) if n == 0: return bw: ULONG = 0 - wf.WriteFile(H, S, ULONG(n), t.CPtr(c.Addr(bw)), None) + wf.WriteFile(H, S, ULONG(n), t.CPtr(&bw), None) # ============================================================ @@ -216,27 +216,27 @@ def StdoutWrite(S: str): def TimeStampNow(Out: bytes, Cap: int) -> int: St: wb.SYSTEMTIME = wb.SYSTEMTIME() - wb.GetLocalTime(t.CPtr(c.Addr(St))) - viperlib.snprintf(Out, t.CSizeT(Cap), "%04u-%02u-%02u %02u:%02u:%02u", - t.CUInt32T(St.wYear), t.CUInt32T(St.wMonth), t.CUInt32T(St.wDay), - t.CUInt32T(St.wHour), t.CUInt32T(St.wMinute), t.CUInt32T(St.wSecond)) + wb.GetLocalTime(t.CPtr(&St)) + viperlib.snprintf(Out, sizet(Cap), "%04u-%02u-%02u %02u:%02u:%02u", + uint32(St.wYear), uint32(St.wMonth), uint32(St.wDay), + uint32(St.wHour), uint32(St.wMinute), uint32(St.wSecond)) return 1 -def TimeStampAfter(Out: bytes, Cap: int, AddMs: t.CSizeT) -> int: +def TimeStampAfter(Out: bytes, Cap: int, AddMs: sizet) -> int: St: wb.SYSTEMTIME = wb.SYSTEMTIME() - wb.GetLocalTime(t.CPtr(c.Addr(St))) + wb.GetLocalTime(t.CPtr(&St)) Ft: wb.FILETIME = wb.FILETIME() - if wb.SystemTimeToFileTime(t.CPtr(c.Addr(St)), t.CPtr(c.Addr(Ft))) == 0: + if wb.SystemTimeToFileTime(t.CPtr(&St), t.CPtr(&Ft)) == 0: return TimeStampNow(Out, Cap) Ticks: ULONGLONG = (ULONGLONG(Ft.dwHighDateTime) << 32) | ULONGLONG(Ft.dwLowDateTime) Ticks = Ticks + (ULONGLONG(AddMs) * ULONGLONG(10000)) Ft.dwLowDateTime = DWORD(Ticks & ULONGLONG(0xFFFFFFFF)) Ft.dwHighDateTime = DWORD(Ticks >> 32) St2: wb.SYSTEMTIME = wb.SYSTEMTIME() - if wb.FileTimeToSystemTime(t.CPtr(c.Addr(Ft)), t.CPtr(c.Addr(St2))) == 0: + if wb.FileTimeToSystemTime(t.CPtr(&Ft), t.CPtr(&St2)) == 0: return TimeStampNow(Out, Cap) - viperlib.snprintf(Out, t.CSizeT(Cap), "%04u-%02u-%02u %02u:%02u:%02u", - t.CUInt32T(St2.wYear), t.CUInt32T(St2.wMonth), t.CUInt32T(St2.wDay), - t.CUInt32T(St2.wHour), t.CUInt32T(St2.wMinute), t.CUInt32T(St2.wSecond)) + viperlib.snprintf(Out, sizet(Cap), "%04u-%02u-%02u %02u:%02u:%02u", + uint32(St2.wYear), uint32(St2.wMonth), uint32(St2.wDay), + uint32(St2.wHour), uint32(St2.wMinute), uint32(St2.wSecond)) return 1 diff --git a/App/lib/VPe.vp b/App/lib/VPe.vp index 75cc896..9a2f053 100644 --- a/App/lib/VPe.vp +++ b/App/lib/VPe.vp @@ -28,40 +28,40 @@ import w32.win32base as wb # ============================================================ # PE/COFF 常量 -DOS_SIGNATURE: t.CDefine = 0x5A4D # "MZ" 小端 -NT_SIGNATURE: t.CDefine = 0x00004550 # "PE\0\0" 小端 -OPT_MAGIC_PE32: t.CDefine = 0x10B -OPT_MAGIC_PE32P: t.CDefine = 0x20B -SEC_ENTRY_SIZE: t.CDefine = 40 +define DOS_SIGNATURE = 0x5A4D # "MZ" 小端 +define NT_SIGNATURE = 0x00004550 # "PE\0\0" 小端 +define OPT_MAGIC_PE32 = 0x10B +define OPT_MAGIC_PE32P = 0x20B +define SEC_ENTRY_SIZE = 40 -E_LFANEW_OFF: t.CDefine = 0x3C # DOS 头 e_lfanew -COFF_MACHINE_OFF: t.CDefine = 4 # PE签名(4)+COFF: Machine @ COFF+0 -COFF_NUMSEC_OFF: t.CDefine = 6 # PE签名(4)+COFF: NumberOfSections @ COFF+2 -COFF_OPTSIZE_OFF: t.CDefine = 20 # PE签名(4)+COFF: SizeOfOptionalHeader @ COFF+16 -OPT_MAGIC_OFF: t.CDefine = 24 # PE签名(4)+COFF(20) 之后为可选头 Magic +define E_LFANEW_OFF = 0x3C # DOS 头 e_lfanew +define COFF_MACHINE_OFF = 4 # PE签名(4)+COFF: Machine @ COFF+0 +define COFF_NUMSEC_OFF = 6 # PE签名(4)+COFF: NumberOfSections @ COFF+2 +define COFF_OPTSIZE_OFF = 20 # PE签名(4)+COFF: SizeOfOptionalHeader @ COFF+16 +define OPT_MAGIC_OFF = 24 # PE签名(4)+COFF(20) 之后为可选头 Magic -SEC_NAME_OFF: t.CDefine = 0 -SEC_RAWSIZE_OFF: t.CDefine = 16 -SEC_RAWPTR_OFF: t.CDefine = 20 +define SEC_NAME_OFF = 0 +define SEC_RAWSIZE_OFF = 16 +define SEC_RAWPTR_OFF = 20 -VERSION_SECTION: t.CDefine = ".PRVERSN" +define VERSION_SECTION = ".PRVERSN" # COFF Machine 值(winnt.h)→ arch 字符串 -MACHINE_X86_64: t.CDefine = 0x8664 -MACHINE_X86: t.CDefine = 0x14C -MACHINE_ARM64: t.CDefine = 0xAA64 -MACHINE_ARM: t.CDefine = 0x1C0 -MACHINE_ARMNT: t.CDefine = 0x1C4 +define MACHINE_X86_64 = 0x8664 +define MACHINE_X86 = 0x14C +define MACHINE_ARM64 = 0xAA64 +define MACHINE_ARM = 0x1C0 +define MACHINE_ARMNT = 0x1C4 # 扫盘用 PE 读取上限 -PE_HEAD_READ: t.CDefine = 8192 # 单次读取的"头部窗口"(DOS+COFF+可选头+节表) +define PE_HEAD_READ = 8192 # 单次读取的"头部窗口"(DOS+COFF+可选头+节表) -VER_CAP: t.CDefine = 128 # .PRVERSN 版本串缓冲 -ARCH_CAP: t.CDefine = 32 # arch 字符串缓冲("unknown(0xFFFF)" 14 字节) +define VER_CAP = 128 # .PRVERSN 版本串缓冲 +define ARCH_CAP = 32 # arch 字符串缓冲("unknown(0xFFFF)" 14 字节) # ParsePeHead 的输出(用模块全局而非数组出参) -Pe_RawPtr: t.CUInt32T = 0 -Pe_RawSize: t.CUInt32T = 0 +Pe_RawPtr: uint32 = 0 +Pe_RawSize: uint32 = 0 # TryReadPeInfo 打开失败(rc=1)时的 GetLastError(check 通道据此区分 NOT_FOUND / NO_PERMISSION)。 # 生命周期:TryReadPeInfo 每次进入复位为 0;仅在 CreateFileA 返回 INVALID_HANDLE_VALUE 时写入, @@ -74,11 +74,11 @@ Pe_OpenErr: ULONG = 0 # Pe_DbgLastRc :最近一次解析失败码(0=成功;scan 路径为 ParsePeHead 的 prc, # ver 路径为 Phase1VersionSection 按同一条件编码的等价码) # 生命周期:TryReadPeInfo 每次进入复位;Phase1VersionSection 每次进入复位。 -Pe_DbgLfanew: t.CUInt32T = 0 -Pe_DbgNsec: t.CUInt32T = 0 -Pe_DbgOptSize: t.CUInt32T = 0 -Pe_DbgSecOff: t.CUInt32T = 0 -Pe_DbgGot: t.CSizeT = 0 +Pe_DbgLfanew: uint32 = 0 +Pe_DbgNsec: uint32 = 0 +Pe_DbgOptSize: uint32 = 0 +Pe_DbgSecOff: uint32 = 0 +Pe_DbgGot: sizet = 0 Pe_DbgLastRc: int = 0 @@ -86,17 +86,17 @@ Pe_DbgLastRc: int = 0 # 小端读取(Buf 为无符号字节基址,Buf[i] 即 u8) # ============================================================ -def ReadU16(Buf: BYTEPTR, Off: int) -> t.CUInt32T: - Val: t.CUInt32T = t.CUInt32T(Buf[Off]) - Val = Val | (t.CUInt32T(Buf[Off + 1]) << 8) +def ReadU16(Buf: BYTEPTR, Off: int) -> uint32: + Val: uint32 = uint32(Buf[Off]) + Val = Val | (uint32(Buf[Off + 1]) << 8) return Val -def ReadU32(Buf: BYTEPTR, Off: int) -> t.CUInt32T: - Val: t.CUInt32T = t.CUInt32T(Buf[Off]) - Val = Val | (t.CUInt32T(Buf[Off + 1]) << 8) - Val = Val | (t.CUInt32T(Buf[Off + 2]) << 16) - Val = Val | (t.CUInt32T(Buf[Off + 3]) << 24) +def ReadU32(Buf: BYTEPTR, Off: int) -> uint32: + Val: uint32 = uint32(Buf[Off]) + Val = Val | (uint32(Buf[Off + 1]) << 8) + Val = Val | (uint32(Buf[Off + 2]) << 16) + Val = Val | (uint32(Buf[Off + 3]) << 24) return Val @@ -126,7 +126,7 @@ def FillArch(OutArch: bytes, Cap: int, Machine: int) -> int: elif Machine == MACHINE_ARM or Machine == MACHINE_ARMNT: VFs.CopyRaw(OutArch, Cap, "arm") else: - viperlib.snprintf(OutArch, t.CSizeT(Cap), "unknown(0x%X)", t.CUInt32T(Machine)) + viperlib.snprintf(OutArch, sizet(Cap), "unknown(0x%X)", uint32(Machine)) return 1 @@ -134,15 +134,15 @@ def FillArch(OutArch: bytes, Cap: int, Machine: int) -> int: # Rc:失败码;Fsz:文件大小(该点尚不可知时传 0);RawPtr/RawSize:.PRVERSN 段位置(尚不可知时传 0)。 # sectab_end = sec_off + nsec * 40,由打印时当场推算(尚未解析出的量保持 0)。 # 属"内部路径细节"(逐次解析中间量),默认安静,仅 --verbose 时输出。 -def PeDbgPrint(Rc: int, Fsz: t.CSizeT, RawPtr: t.CUInt32T, RawSize: t.CUInt32T): +def PeDbgPrint(Rc: int, Fsz: sizet, RawPtr: uint32, RawSize: uint32): global Pe_DbgLastRc Pe_DbgLastRc = Rc - SecTabEnd: t.CSizeT = t.CSizeT(Pe_DbgSecOff) + t.CSizeT(Pe_DbgNsec) * t.CSizeT(SEC_ENTRY_SIZE) + SecTabEnd: sizet = sizet(Pe_DbgSecOff) + sizet(Pe_DbgNsec) * sizet(SEC_ENTRY_SIZE) VLog.VerboseFmt4(" [pe] rc=%u lfanew=%u nsec=%u optsize=%u", - t.CSizeT(Rc), t.CSizeT(Pe_DbgLfanew), t.CSizeT(Pe_DbgNsec), t.CSizeT(Pe_DbgOptSize)) + sizet(Rc), sizet(Pe_DbgLfanew), sizet(Pe_DbgNsec), sizet(Pe_DbgOptSize)) VLog.VerboseFmt4(" sec_off=%u sectab_end=%u got=%u fsz=%u", - t.CSizeT(Pe_DbgSecOff), SecTabEnd, Pe_DbgGot, Fsz) - VLog.VerboseFmt2(" rawptr=%u rawsize=%u\n", t.CSizeT(RawPtr), t.CSizeT(RawSize)) + sizet(Pe_DbgSecOff), SecTabEnd, Pe_DbgGot, Fsz) + VLog.VerboseFmt2(" rawptr=%u rawsize=%u\n", sizet(RawPtr), sizet(RawSize)) # 取"最近一次 TryReadPeInfo 的 CreateFileA 失败错误码"(rc=1 时才有意义;其余情况为 0)。 @@ -159,7 +159,7 @@ def PeOpenErr() -> ULONG: # 7=未找到 .PRVERSN # 每个 return 前把失败码写入 Pe_DbgLastRc,关键中间量写入 Pe_DbgLfanew/Pe_DbgNsec/ # Pe_DbgOptSize/Pe_DbgSecOff/Pe_DbgGot,供调用点在失败时打 [pe] 行。 -def ParsePeHead(Buf: bytes, Got: t.CSizeT, OutArch: bytes, ArchCap: int) -> int: +def ParsePeHead(Buf: bytes, Got: sizet, OutArch: bytes, ArchCap: int) -> int: global Pe_RawPtr, Pe_RawSize global Pe_DbgLfanew, Pe_DbgNsec, Pe_DbgOptSize, Pe_DbgSecOff, Pe_DbgGot, Pe_DbgLastRc Pe_RawPtr = 0 @@ -177,32 +177,32 @@ def ParsePeHead(Buf: bytes, Got: t.CSizeT, OutArch: bytes, ArchCap: int) -> int: if ReadU16(ub, 0) != DOS_SIGNATURE: Pe_DbgLastRc = 2 return 2 - lfanew: t.CUInt32T = ReadU32(ub, E_LFANEW_OFF) + lfanew: uint32 = ReadU32(ub, E_LFANEW_OFF) Pe_DbgLfanew = lfanew - if t.CSizeT(lfanew) + 24 > Got: + if sizet(lfanew) + 24 > Got: Pe_DbgLastRc = 3 return 3 - if ReadU32(ub, t.CInt(lfanew)) != NT_SIGNATURE: + if ReadU32(ub, int(lfanew)) != NT_SIGNATURE: Pe_DbgLastRc = 4 return 4 - nsec: t.CUInt32T = ReadU16(ub, t.CInt(lfanew) + COFF_NUMSEC_OFF) - optsize: t.CUInt32T = ReadU16(ub, t.CInt(lfanew) + COFF_OPTSIZE_OFF) + nsec: uint32 = ReadU16(ub, int(lfanew) + COFF_NUMSEC_OFF) + optsize: uint32 = ReadU16(ub, int(lfanew) + COFF_OPTSIZE_OFF) Pe_DbgNsec = nsec Pe_DbgOptSize = optsize - magic: t.CUInt32T = ReadU16(ub, t.CInt(lfanew) + OPT_MAGIC_OFF) + magic: uint32 = ReadU16(ub, int(lfanew) + OPT_MAGIC_OFF) if magic != OPT_MAGIC_PE32 and magic != OPT_MAGIC_PE32P: Pe_DbgLastRc = 5 return 5 - mach: t.CUInt32T = ReadU16(ub, t.CInt(lfanew) + COFF_MACHINE_OFF) - FillArch(OutArch, ArchCap, t.CInt(mach)) - sec_off: t.CInt = t.CInt(lfanew) + 24 + t.CInt(optsize) - Pe_DbgSecOff = t.CUInt32T(sec_off) - if t.CSizeT(sec_off) + t.CSizeT(nsec) * t.CSizeT(SEC_ENTRY_SIZE) > Got: + mach: uint32 = ReadU16(ub, int(lfanew) + COFF_MACHINE_OFF) + FillArch(OutArch, ArchCap, int(mach)) + sec_off: int = int(lfanew) + 24 + int(optsize) + Pe_DbgSecOff = uint32(sec_off) + if sizet(sec_off) + sizet(nsec) * sizet(SEC_ENTRY_SIZE) > Got: Pe_DbgLastRc = 6 return 6 # 节表超出头部窗口(极端多节 PE,跳过) i: int = 0 - while i < t.CInt(nsec): - entry: t.CInt = sec_off + i * SEC_ENTRY_SIZE + while i < int(nsec): + entry: int = sec_off + i * SEC_ENTRY_SIZE if string.strncmp(str(Buf + entry + SEC_NAME_OFF), VERSION_SECTION, 8) == 0: Pe_RawPtr = ReadU32(ub, entry + SEC_RAWPTR_OFF) Pe_RawSize = ReadU32(ub, entry + SEC_RAWSIZE_OFF) @@ -213,8 +213,8 @@ def ParsePeHead(Buf: bytes, Got: t.CSizeT, OutArch: bytes, ArchCap: int) -> int: # 把 Src[Off .. Off+Len) 中的版本串(到第一个 NUL 或 VerCap-1)拷入 OutVer -def CopyVersion(Src: bytes, Off: t.CInt, Len: t.CInt, OutVer: bytes, VerCap: int) -> int: - n: t.CInt = 0 +def CopyVersion(Src: bytes, Off: int, Len: int, OutVer: bytes, VerCap: int) -> int: + n: int = 0 while n < Len and n < VerCap - 1: if Src[Off + n] == 0: break @@ -251,33 +251,33 @@ def TryReadPeInfo(Target: str, OutVer: bytes, VerCap: int, OutArch: bytes, ArchC None, wf.OPEN_EXISTING, wf.FILE_ATTRIBUTE_NORMAL, None) if h == wb.INVALID_HANDLE_VALUE: Pe_OpenErr = wb.GetLastError() # 紧跟 CreateFileA 读取(PeDbgPrint 的写日志会覆盖) - PeDbgPrint(1, t.CSizeT(0), t.CUInt32T(0), t.CUInt32T(0)) + PeDbgPrint(1, sizet(0), uint32(0), uint32(0)) return 1 li: wb.LARGE_INTEGER = wb.LARGE_INTEGER() - if wf.GetFileSizeEx(h, t.CPtr(c.Addr(li))) == 0: + if wf.GetFileSizeEx(h, t.CPtr(&li)) == 0: wb.CloseHandle(h) - PeDbgPrint(2, t.CSizeT(0), t.CUInt32T(0), t.CUInt32T(0)) + PeDbgPrint(2, sizet(0), uint32(0), uint32(0)) return 2 - fsz: t.CSizeT = t.CSizeT(li.QuadPart) + fsz: sizet = sizet(li.QuadPart) if fsz < 0x40: wb.CloseHandle(h) - PeDbgPrint(3, fsz, t.CUInt32T(0), t.CUInt32T(0)) + PeDbgPrint(3, fsz, uint32(0), uint32(0)) return 3 - head_cap: t.CSizeT = t.CSizeT(PE_HEAD_READ) + head_cap: sizet = sizet(PE_HEAD_READ) if fsz < head_cap: head_cap = fsz head: bytes = stdlib.malloc(head_cap + 1) if head is None: wb.CloseHandle(h) - PeDbgPrint(4, fsz, t.CUInt32T(0), t.CUInt32T(0)) + PeDbgPrint(4, fsz, uint32(0), uint32(0)) return 4 - got: t.CSizeT = VFs.ReadFull(h, head, head_cap) + got: sizet = VFs.ReadFull(h, head, head_cap) head[got] = 0 Pe_DbgGot = got if got < 0x40: stdlib.free(t.CPtr(head)) wb.CloseHandle(h) - PeDbgPrint(5, fsz, t.CUInt32T(0), t.CUInt32T(0)) + PeDbgPrint(5, fsz, uint32(0), uint32(0)) return 5 prc: int = ParsePeHead(head, got, OutArch, ArchCap) @@ -286,17 +286,17 @@ def TryReadPeInfo(Target: str, OutVer: bytes, VerCap: int, OutArch: bytes, ArchC wb.CloseHandle(h) PeDbgPrint(100 + prc, fsz, Pe_RawPtr, Pe_RawSize) return 100 + prc - raw_ptr: t.CUInt32T = Pe_RawPtr - raw_size: t.CUInt32T = Pe_RawSize - if raw_size == 0 or t.CSizeT(raw_ptr) + t.CSizeT(raw_size) > fsz: + raw_ptr: uint32 = Pe_RawPtr + raw_size: uint32 = Pe_RawSize + if raw_size == 0 or sizet(raw_ptr) + sizet(raw_size) > fsz: stdlib.free(t.CPtr(head)) wb.CloseHandle(h) PeDbgPrint(6, fsz, raw_ptr, raw_size) return 6 - if t.CSizeT(raw_ptr) + t.CSizeT(raw_size) <= got: + if sizet(raw_ptr) + sizet(raw_size) <= got: # 段内容已在头部窗口内 - CopyVersion(head, t.CInt(raw_ptr), t.CInt(raw_size), OutVer, VerCap) + CopyVersion(head, int(raw_ptr), int(raw_size), OutVer, VerCap) else: # 段内容不在头部窗口内:改走"整文件读"路径(与 ver [1/3] 同一套 API,已验证可用)。 # 这里不用 wf.SetFilePointerEx 定位:其 liDistanceToMove 在真实 Win32 上按值传 8 字节, @@ -310,7 +310,7 @@ def TryReadPeInfo(Target: str, OutVer: bytes, VerCap: int, OutArch: bytes, ArchC if whole is None: PeDbgPrint(7, fsz, raw_ptr, raw_size) return 7 - CopyVersion(whole, t.CInt(raw_ptr), t.CInt(raw_size), OutVer, VerCap) + CopyVersion(whole, int(raw_ptr), int(raw_size), OutVer, VerCap) stdlib.free(t.CPtr(whole)) return 0 @@ -340,7 +340,7 @@ def Phase1VersionSection(Target: str) -> int: if buf is None: rc_err: int = VFs.LastReadErr if rc_err == 1: - VLog.LogFmt1(" 打开文件失败 (win32 err=%u)\n", t.CSizeT(VFs.LastReadWinErr)) + VLog.LogFmt1(" 打开文件失败 (win32 err=%u)\n", sizet(VFs.LastReadWinErr)) elif rc_err == 2: VLog.LogStr(" 读取文件大小失败\n") elif rc_err == 3: @@ -348,12 +348,12 @@ def Phase1VersionSection(Target: str) -> int: else: VLog.LogStr(" 分配缓冲区失败\n") return 1 - total: t.CSizeT = VFs.LastReadSize + total: sizet = VFs.LastReadSize Pe_DbgGot = total if total < 0x40: VLog.LogStr(" 不是有效的 PE 文件(文件过短)\n") - PeDbgPrint(1, total, t.CUInt32T(0), t.CUInt32T(0)) + PeDbgPrint(1, total, uint32(0), uint32(0)) stdlib.free(t.CPtr(buf)) return 1 @@ -362,50 +362,50 @@ def Phase1VersionSection(Target: str) -> int: # DOS 头 if ReadU16(ub, 0) != DOS_SIGNATURE: VLog.LogStr(" 不是有效的 PE 文件(缺少 MZ 头)\n") - PeDbgPrint(2, total, t.CUInt32T(0), t.CUInt32T(0)) + PeDbgPrint(2, total, uint32(0), uint32(0)) stdlib.free(t.CPtr(buf)) return 1 # NT 头 - lfanew: t.CUInt32T = ReadU32(ub, E_LFANEW_OFF) + lfanew: uint32 = ReadU32(ub, E_LFANEW_OFF) Pe_DbgLfanew = lfanew - if t.CSizeT(lfanew) + 24 > total: + if sizet(lfanew) + 24 > total: VLog.LogStr(" 不是有效的 PE 文件(e_lfanew 越界)\n") - PeDbgPrint(3, total, t.CUInt32T(0), t.CUInt32T(0)) + PeDbgPrint(3, total, uint32(0), uint32(0)) stdlib.free(t.CPtr(buf)) return 1 - if ReadU32(ub, t.CInt(lfanew)) != NT_SIGNATURE: + if ReadU32(ub, int(lfanew)) != NT_SIGNATURE: VLog.LogStr(" 不是有效的 PE 文件(缺少 PE 签名)\n") - PeDbgPrint(4, total, t.CUInt32T(0), t.CUInt32T(0)) + PeDbgPrint(4, total, uint32(0), uint32(0)) stdlib.free(t.CPtr(buf)) return 1 - nsec: t.CUInt32T = ReadU16(ub, t.CInt(lfanew) + COFF_NUMSEC_OFF) - optsize: t.CUInt32T = ReadU16(ub, t.CInt(lfanew) + COFF_OPTSIZE_OFF) + nsec: uint32 = ReadU16(ub, int(lfanew) + COFF_NUMSEC_OFF) + optsize: uint32 = ReadU16(ub, int(lfanew) + COFF_OPTSIZE_OFF) Pe_DbgNsec = nsec Pe_DbgOptSize = optsize - magic: t.CUInt32T = ReadU16(ub, t.CInt(lfanew) + OPT_MAGIC_OFF) + magic: uint32 = ReadU16(ub, int(lfanew) + OPT_MAGIC_OFF) if magic != OPT_MAGIC_PE32 and magic != OPT_MAGIC_PE32P: VLog.LogFmt1(" 可选头 Magic 未知: 0x%X\n", magic) - PeDbgPrint(5, total, t.CUInt32T(0), t.CUInt32T(0)) + PeDbgPrint(5, total, uint32(0), uint32(0)) stdlib.free(t.CPtr(buf)) return 1 - sec_off: t.CInt = t.CInt(lfanew) + 24 + t.CInt(optsize) - Pe_DbgSecOff = t.CUInt32T(sec_off) - if t.CSizeT(sec_off) + t.CSizeT(nsec) * SEC_ENTRY_SIZE > total: + sec_off: int = int(lfanew) + 24 + int(optsize) + Pe_DbgSecOff = uint32(sec_off) + if sizet(sec_off) + sizet(nsec) * SEC_ENTRY_SIZE > total: VLog.LogFmt1(" 节表越界(节数=%u)\n", nsec) - PeDbgPrint(6, total, t.CUInt32T(0), t.CUInt32T(0)) + PeDbgPrint(6, total, uint32(0), uint32(0)) stdlib.free(t.CPtr(buf)) return 1 # 查找 .PRVERSN found: int = 0 - raw_ptr: t.CUInt32T = 0 - raw_size: t.CUInt32T = 0 + raw_ptr: uint32 = 0 + raw_size: uint32 = 0 i: int = 0 - while i < t.CInt(nsec): - entry: t.CInt = sec_off + i * SEC_ENTRY_SIZE + while i < int(nsec): + entry: int = sec_off + i * SEC_ENTRY_SIZE if string.strncmp(str(buf + entry + SEC_NAME_OFF), VERSION_SECTION, 8) == 0: found = 1 raw_size = ReadU32(ub, entry + SEC_RAWSIZE_OFF) @@ -415,12 +415,12 @@ def Phase1VersionSection(Target: str) -> int: if found == 0: VLog.LogFmtS1(" 未找到 %s 节\n", VERSION_SECTION) - PeDbgPrint(7, total, t.CUInt32T(0), t.CUInt32T(0)) + PeDbgPrint(7, total, uint32(0), uint32(0)) VLog.LogStr(" 实际节名:\n") name8: bytes = stdlib.malloc(9) if name8 is not None: j: int = 0 - while j < t.CInt(nsec): + while j < int(nsec): CopySectionName(ub, sec_off + j * SEC_ENTRY_SIZE, name8) VLog.LogFmtS1(" %s\n", str(name8)) j += 1 @@ -429,17 +429,17 @@ def Phase1VersionSection(Target: str) -> int: return 1 # 取到第一个 NUL 为止 - if t.CSizeT(raw_ptr) + t.CSizeT(raw_size) > total: + if sizet(raw_ptr) + sizet(raw_size) > total: VLog.LogFmt2(" 段内容越界 (offset=%u size=%u)\n", raw_ptr, raw_size) PeDbgPrint(6, total, raw_ptr, raw_size) stdlib.free(t.CPtr(buf)) return 1 - vlen: t.CUInt32T = 0 - while vlen < raw_size and ub[t.CInt(raw_ptr) + t.CInt(vlen)] != 0: + vlen: uint32 = 0 + while vlen < raw_size and ub[int(raw_ptr) + int(vlen)] != 0: vlen += 1 VLog.LogFmt1(" 原始长度: %u 字节\n", vlen) - VLog.LogFmtS1(" 版本串: %s\n", str(buf + t.CInt(raw_ptr))) + VLog.LogFmtS1(" 版本串: %s\n", str(buf + int(raw_ptr))) stdlib.free(t.CPtr(buf)) return 0 diff --git a/App/lib/VProc.vp b/App/lib/VProc.vp index e5e18d2..8d5ffbb 100644 --- a/App/lib/VProc.vp +++ b/App/lib/VProc.vp @@ -38,12 +38,12 @@ import lib.VLog as VLog # wb.CloseHandle(:64)、wb.WAIT_OBJECT_0(:15)、wb.WAIT_TIMEOUT(:16)、wb.INFINITE(:13)。 # ============================================================ -VERSION_PROBE_TIMEOUT_MS: t.CDefine = 5000 # --version 探测超时(毫秒) -VERSION_PROBE_DIAG_CAP: t.CDefine = 4096 # ver [2/3] 诊断输出缓冲 -PROBE_CMD_EXTRA_CAP: t.CDefine = 32 # 命令缓冲额外量(引号 + " --version" + NUL) -PROBE_TARGET_MAX: t.CDefine = 4096 # 目标路径上界(超限直接判启动失败,不构造命令) -PROBE_LINE_CAP: t.CDefine = 208 # 探测输出"首行"诊断缓冲(200 字符 + NUL + 对齐) -VERSION_PREFIX: t.CDefine = "Viper" +define VERSION_PROBE_TIMEOUT_MS = 5000 # --version 探测超时(毫秒) +define VERSION_PROBE_DIAG_CAP = 4096 # ver [2/3] 诊断输出缓冲 +define PROBE_CMD_EXTRA_CAP = 32 # 命令缓冲额外量(引号 + " --version" + NUL) +define PROBE_TARGET_MAX = 4096 # 目标路径上界(超限直接判启动失败,不构造命令) +define PROBE_LINE_CAP = 208 # 探测输出"首行"诊断缓冲(200 字符 + NUL + 对齐) +define VERSION_PREFIX = "Viper" # 结果输出(模块全局);RunVersionProbe 每次进入先复位 Probe_ExitCode: ULONG = 0 @@ -111,7 +111,7 @@ def CopyFirstLine(Src: bytes, Out: bytes, Cap: int) -> int: # 失败诊断(含 GetLastError / 等待结果 / 等待时长)始终输出,且不内嵌被探测路径——路径与 # 已捕获内容/首行属逐次探测细节,仅 --verbose 时经 Verbose* 给出(默认不逐路径刷屏)。 # ============================================================ -def RunVersionProbe(Target: str, Out: bytes, OutCap: t.CSizeT, Trace: int) -> int: +def RunVersionProbe(Target: str, Out: bytes, OutCap: sizet, Trace: int) -> int: global Probe_ExitCode, Probe_TimedOut, Probe_LaunchStage, Probe_LaunchErr Probe_ExitCode = 0 Probe_TimedOut = 0 @@ -122,7 +122,7 @@ def RunVersionProbe(Target: str, Out: bytes, OutCap: t.CSizeT, Trace: int) -> in if Trace != 0: VLog.VerboseStr(" [--version] 启动失败 (rc=1): 参数非法\n") return 1 - if string.strlen(Target) > t.CSizeT(PROBE_TARGET_MAX): + if string.strlen(Target) > sizet(PROBE_TARGET_MAX): Probe_LaunchStage = 1 VLog.LogStr(" 警告: --version 目标路径过长 (rc=1),已跳过该候选\n") return 1 @@ -132,7 +132,7 @@ def RunVersionProbe(Target: str, Out: bytes, OutCap: t.CSizeT, Trace: int) -> in VLog.VerboseFmtS1(" [--version] 开始: %s\n", Target) # --- 命令缓冲:"" --version --- - n: t.CSizeT = string.strlen(Target) + t.CSizeT(PROBE_CMD_EXTRA_CAP) + n: sizet = string.strlen(Target) + sizet(PROBE_CMD_EXTRA_CAP) CmdLine: bytes = stdlib.malloc(n) if CmdLine is None: Probe_LaunchStage = 2 @@ -144,15 +144,15 @@ def RunVersionProbe(Target: str, Out: bytes, OutCap: t.CSizeT, Trace: int) -> in # nLength 必须等于 sizeof(SECURITY_ATTRIBUTES)=24,否则 CreatePipe 直接失败 # (ERROR_INVALID_PARAMETER);lpSecurityDescriptor=NULL 表示默认安全描述符。 Sa: wb.SECURITY_ATTRIBUTES = wb.SECURITY_ATTRIBUTES() - Sa.nLength = t.CUInt32T(wb.SECURITY_ATTRIBUTES.__sizeof__()) + Sa.nLength = uint32(wb.SECURITY_ATTRIBUTES.__sizeof__()) Sa.lpSecurityDescriptor = t.CPtr(0) Sa.bInheritHandle = 1 # --- 管道(可继承;父进程随后关写端) --- hRead: wb.HANDLE = None hWrite: wb.HANDLE = None - if wf.CreatePipe(t.CPtr(c.Addr(hRead)), t.CPtr(c.Addr(hWrite)), - t.CPtr(c.Addr(Sa)), 0) == 0: + if wf.CreatePipe(t.CPtr(&hRead), t.CPtr(&hWrite), + t.CPtr(&Sa), 0) == 0: PipeErr: ULONG = wb.GetLastError() # 紧跟 CreatePipe 读取 Probe_LaunchStage = 3 Probe_LaunchErr = PipeErr @@ -164,7 +164,7 @@ def RunVersionProbe(Target: str, Out: bytes, OutCap: t.CSizeT, Trace: int) -> in # --- STARTUPINFOA:cb=sizeof, dwFlags=STARTF_USESTDHANDLES, hStdOutput=hStdError=写端 --- Si: wp.STARTUPINFOA = wp.STARTUPINFOA() - Si.cb = t.CUInt32T(wp.STARTUPINFOA.__sizeof__()) + Si.cb = uint32(wp.STARTUPINFOA.__sizeof__()) Si.dwFlags = wp.STARTF_USESTDHANDLES Si.hStdOutput = hWrite Si.hStdError = hWrite @@ -174,7 +174,7 @@ def RunVersionProbe(Target: str, Out: bytes, OutCap: t.CSizeT, Trace: int) -> in # --- CreateProcessA(bInheritHandles=TRUE;CREATE_NO_WINDOW:输出走管道,不开控制台窗口) --- Ok: BOOL = wp.CreateProcessA(t.CPtr(0), CmdLine, t.CPtr(0), t.CPtr(0), 1, wp.CREATE_NO_WINDOW, t.CPtr(0), t.CPtr(0), - t.CPtr(c.Addr(Si)), t.CPtr(c.Addr(Pi))) + t.CPtr(&Si), t.CPtr(&Pi)) # GetLastError 紧跟调用读取:其后 stdlib.free 等都会覆盖它 CreateErr: ULONG = wb.GetLastError() stdlib.free(t.CPtr(CmdLine)) @@ -184,7 +184,7 @@ def RunVersionProbe(Target: str, Out: bytes, OutCap: t.CSizeT, Trace: int) -> in wb.CloseHandle(hRead) wb.CloseHandle(hWrite) VLog.LogFmt1(" 警告: --version 探测启动失败 (rc=1, CreateProcessA, GetLastError=%u)\n", - t.CSizeT(CreateErr)) + sizet(CreateErr)) return 1 # 父进程关闭写端(子进程已持有其副本);此后管道只由子进程持有写端 @@ -192,29 +192,29 @@ def RunVersionProbe(Target: str, Out: bytes, OutCap: t.CSizeT, Trace: int) -> in # --- 超时等待:先等进程退出,再读干管道 --- TimedOut: int = 0 - KillMs: t.CSizeT = 0 + KillMs: sizet = 0 Wr: ULONG = wsync.WaitForSingleObject(Pi.hProcess, VERSION_PROBE_TIMEOUT_MS) if Wr != wb.WAIT_OBJECT_0: # WAIT_TIMEOUT(或 WAIT_FAILED 等):杀进程并回收,避免悬挂 TimedOut = 1 - KillMs = t.CSizeT(wb.GetTickCount64() - T0) + KillMs = sizet(wb.GetTickCount64() - T0) wp.TerminateProcess(Pi.hProcess, 1) wsync.WaitForSingleObject(Pi.hProcess, wb.INFINITE) # 读干管道:子进程已退出/被杀 ⇒ 写端全关,ReadFile 到 EOF 返回 - total: t.CSizeT = 0 + total: sizet = 0 while total + 1 < OutCap: br: ULONG = 0 room: ULONG = ULONG(OutCap - 1 - total) - if wf.ReadFile(hRead, Out + total, room, t.CPtr(c.Addr(br)), None) == 0: + if wf.ReadFile(hRead, Out + total, room, t.CPtr(&br), None) == 0: break if br == 0: break - total += t.CSizeT(br) + total += sizet(br) Out[total] = 0 ExitCode: ULONG = 0 - wp.GetExitCodeProcess(Pi.hProcess, t.CPtr(c.Addr(ExitCode))) + wp.GetExitCodeProcess(Pi.hProcess, t.CPtr(&ExitCode)) Probe_ExitCode = ExitCode Probe_TimedOut = TimedOut @@ -222,12 +222,12 @@ def RunVersionProbe(Target: str, Out: bytes, OutCap: t.CSizeT, Trace: int) -> in wb.CloseHandle(Pi.hThread) wb.CloseHandle(hRead) - Elapsed: t.CSizeT = t.CSizeT(wb.GetTickCount64() - T0) + Elapsed: sizet = sizet(wb.GetTickCount64() - T0) if TimedOut != 0: # 超时:写明等待结果(WAIT_TIMEOUT=258 / WAIT_FAILED=4294967295 等)与等待时长。 # 该候选路径与"超时前已捕获内容"属逐次探测细节,仅 --verbose 时给出(默认不逐路径刷屏) VLog.LogFmt3(" 警告: --version 探测超时 (rc=2, wait=%u, 上限 %u ms),已等待 %u ms 后终止子进程\n", - t.CSizeT(Wr), t.CSizeT(VERSION_PROBE_TIMEOUT_MS), KillMs) + sizet(Wr), sizet(VERSION_PROBE_TIMEOUT_MS), KillMs) if total == 0: VLog.VerboseStr(" 警告: 超时前已捕获 0 字节(空)\n") else: @@ -236,7 +236,7 @@ def RunVersionProbe(Target: str, Out: bytes, OutCap: t.CSizeT, Trace: int) -> in VLog.VerboseStr("\n") if Trace != 0: VLog.VerboseFmt4(" [--version] 结束: 耗时 %u ms, 退出码 %u, 超时 %u, 输出 %u 字节\n", - Elapsed, t.CSizeT(ExitCode), t.CSizeT(TimedOut), total) + Elapsed, sizet(ExitCode), sizet(TimedOut), total) if TimedOut == 0: # 正常结束(rc=0):捕获字节数与首行属逐次探测细节,仅 --verbose 时输出 # (ver 路径的 [2/3] 结果仍由 RunVersionPrefixCheck 照常给出)。 @@ -261,7 +261,7 @@ def RunVersionProbe(Target: str, Out: bytes, OutCap: t.CSizeT, Trace: int) -> in # 行为增强:改用带超时探测(原实现无超时),其余日志与判定口径不变。 # ============================================================ def RunVersionPrefixCheck(Target: str) -> int: - OutCap: t.CSizeT = t.CSizeT(VERSION_PROBE_DIAG_CAP) + OutCap: sizet = sizet(VERSION_PROBE_DIAG_CAP) Out: bytes = stdlib.malloc(OutCap) if Out is None: VLog.LogStr(" 分配缓冲区失败\n") @@ -276,7 +276,7 @@ def RunVersionPrefixCheck(Target: str) -> int: stdlib.free(t.CPtr(Out)) return 1 - VLog.LogFmt1(" 退出码: %d\n", t.CSizeT(t.CUInt32T(Probe_ExitCode))) + VLog.LogFmt1(" 退出码: %d\n", sizet(uint32(Probe_ExitCode))) out: str = str(Out) if out is None: VLog.LogStr(" 未捕获到 stdout\n") diff --git a/App/lib/VScan.vp b/App/lib/VScan.vp index 813728e..60ccc61 100644 --- a/App/lib/VScan.vp +++ b/App/lib/VScan.vp @@ -57,20 +57,20 @@ import w32.win32base as wb # wf.FindClose(:119)、wf.FILE_ATTRIBUTE_DIRECTORY(:23)、wb.Sleep(:77)、wb.GetTickCount64(:80)。 # ============================================================ -MAX_SCAN_DEPTH: t.CDefine = 6 # 递归深度上限 -PACE_DIR_UNITS: t.CDefine = 16 # 每处理 16 个目录项 -PACE_FILE_UNITS: t.CDefine = 64 # 每处理 64 个文件 -PACE_SLEEP_MS: t.CDefine = 20 # 上述节流点 Sleep(20) -PROG_INTERVAL_MS: t.CDefine = 1000 # 进度行最短间隔(需求 3) -PROG_STAMP_CAP: t.CDefine = 64 # 时间戳文本缓冲 -PROG_ELAPSED_CAP: t.CDefine = 32 # "3.2s" 文本缓冲 -REJECT_LOG_MAX: t.CDefine = 20 # [reject] 逐条打印上限(超出后只在轮末打一次汇总) +define MAX_SCAN_DEPTH = 6 # 递归深度上限 +define PACE_DIR_UNITS = 16 # 每处理 16 个目录项 +define PACE_FILE_UNITS = 64 # 每处理 64 个文件 +define PACE_SLEEP_MS = 20 # 上述节流点 Sleep(20) +define PROG_INTERVAL_MS = 1000 # 进度行最短间隔(需求 3) +define PROG_STAMP_CAP = 64 # 时间戳文本缓冲 +define PROG_ELAPSED_CAP = 32 # "3.2s" 文本缓冲 +define REJECT_LOG_MAX = 20 # [reject] 逐条打印上限(超出后只在轮末打一次汇总) # WIN32_FIND_DATAA:4+8+8+8+4+4+4+4 = 44 之后为 cFileName(见"API 证据表"推导) -FD_ATTRIBUTES_OFF: t.CDefine = 0 -FD_FILENAME_OFF: t.CDefine = 44 -FIND_DATA_SIZE: t.CDefine = 320 # sizeof(WIN32_FIND_DATAA):318 对齐到 4 = 320 +define FD_ATTRIBUTES_OFF = 0 +define FD_FILENAME_OFF = 44 +define FIND_DATA_SIZE = 320 # sizeof(WIN32_FIND_DATAA):318 对齐到 4 = 320 # winnt.h: FILE_ATTRIBUTE_REPARSE_POINT(符号链接/挂载点等重解析点,递归时跳过以防成环) -FILE_ATTRIBUTE_REPARSE_POINT: t.CDefine = 0x400 +define FILE_ATTRIBUTE_REPARSE_POINT = 0x400 # 由 App/main.vp 注入 _mbuddy: rawptr[memhub.MemBuddy] @@ -138,13 +138,13 @@ def IsSkippedDir(Name: str) -> int: # 文件名是否以 .exe 结尾(大小写无关) def HasExeSuffix(Name: str) -> int: - n: t.CSizeT = string.strlen(Name) + n: sizet = string.strlen(Name) if n < 4: return 0 - a: int = int(Name[t.CInt(n) - 4]) - b: int = int(Name[t.CInt(n) - 3]) - d0: int = int(Name[t.CInt(n) - 2]) - e0: int = int(Name[t.CInt(n) - 1]) + a: int = int(Name[int(n) - 4]) + b: int = int(Name[int(n) - 3]) + d0: int = int(Name[int(n) - 2]) + e0: int = int(Name[int(n) - 1]) if a >= 65 and a <= 90: a += 32 if b >= 65 and b <= 90: @@ -168,16 +168,16 @@ def ProgPrint(): global Prog_LastTick Now: ULONGLONG = wb.GetTickCount64() Prog_LastTick = Now - ElapsedMs: t.CSizeT = t.CSizeT(Now - Prog_T0) - Secs: t.CSizeT = ElapsedMs // 1000 - Tenths: t.CSizeT = (ElapsedMs % 1000) // 100 - viperlib.snprintf(Prog_Elapsed, t.CSizeT(PROG_ELAPSED_CAP), "%u.%us", - t.CUInt32T(Secs), t.CUInt32T(Tenths)) + ElapsedMs: sizet = sizet(Now - Prog_T0) + Secs: sizet = ElapsedMs // 1000 + Tenths: sizet = (ElapsedMs % 1000) // 100 + viperlib.snprintf(Prog_Elapsed, sizet(PROG_ELAPSED_CAP), "%u.%us", + uint32(Secs), uint32(Tenths)) Cur: str = Prog_Cur if Cur is None: Cur = "?" VLog.VerboseFmt4("[scan] r=%u dir=%u file=%u cand=%u", - t.CSizeT(Prog_Round), t.CSizeT(Prog_Dirs), t.CSizeT(Prog_Files), t.CSizeT(Prog_Cands)) + sizet(Prog_Round), sizet(Prog_Dirs), sizet(Prog_Files), sizet(Prog_Cands)) VLog.VerboseFmtS2(" cur=%s elapsed=%s\n", Cur, str(Prog_Elapsed)) @@ -201,7 +201,7 @@ def ProgReset(RoundIdx: int, Roots: int): Prog_Cands = 0 Prog_Cur = None VLog.TimeStampNow(Prog_Stamp, PROG_STAMP_CAP) - VLog.VerboseFmt2("==== 扫盘轮次 %u 开始 (roots=%u", t.CSizeT(RoundIdx), t.CSizeT(Roots)) + VLog.VerboseFmt2("==== 扫盘轮次 %u 开始 (roots=%u", sizet(RoundIdx), sizet(Roots)) VLog.VerboseFmtS1(", t=%s) ====\n", str(Prog_Stamp)) @@ -209,7 +209,7 @@ def ProgRootEnter(Dir: str): VLog.VerboseFmtS1(" [root] 进入: %s\n", Dir) -def ProgRootLeave(Dir: str, ElapsedMs: t.CSizeT): +def ProgRootLeave(Dir: str, ElapsedMs: sizet): global Prog_Cur VLog.VerboseFmtIS(" [root] 离开 (耗时 %u ms): %s\n", ElapsedMs, Dir) Prog_Cur = None # 该根结束后其路径缓冲即将释放,避免遗留悬空指针 @@ -277,7 +277,7 @@ def ScanInit() -> int: # ----version 前缀探测(带 5s 超时;超时/启动失败 ⇒ 判不通过,不入缓存) def ProbeVersion(Target: str) -> int: - rc: int = VProc.RunVersionProbe(Target, Probe_Buf, t.CSizeT(VProc.VERSION_PROBE_DIAG_CAP), 1) + rc: int = VProc.RunVersionProbe(Target, Probe_Buf, sizet(VProc.VERSION_PROBE_DIAG_CAP), 1) if rc == 0: if VProc.OutputHasViperPrefix(str(Probe_Buf)) != 0: return 1 @@ -310,7 +310,7 @@ def HandleCandidate(ExeAnsi: str) -> int: Reject_Total += 1 if Reject_Shown < REJECT_LOG_MAX: Reject_Shown += 1 - VLog.VerboseFmtIS(" [reject] rc=%u %s\n", t.CSizeT(rc), ExeAnsi) + VLog.VerboseFmtIS(" [reject] rc=%u %s\n", sizet(rc), ExeAnsi) return 0 Prog_Cands += 1 # 仅对已过 PE + .PRVERSN 过滤的 exe 调用 --version(这类很少)。 @@ -323,7 +323,7 @@ def HandleCandidate(ExeAnsi: str) -> int: if VGuid.NewGuidStr(Scr_Id, VGuid.GUID_STR_CAP) == 0: VLog.LogStr(" 警告: CoCreateGuid 失败,跳过该条目\n") return 0 - viperlib.snprintf(Scr_Disp, t.CSizeT(VCache.DISP_CAP), "Viper %s", Scr_Ver) + viperlib.snprintf(Scr_Disp, sizet(VCache.DISP_CAP), "Viper %s", Scr_Ver) if VCache.CacheAdd(ExeAnsi, str(Scr_Id), str(Scr_Ver), str(Scr_Arch), "workspace", str(Scr_Disp)) == 0: return 0 @@ -366,7 +366,7 @@ def ScanTree(DirAnsi: str, Depth: int) -> int: if hDir != wb.INVALID_HANDLE_VALUE: while True: PaceDir() - Attrs: t.CUInt32T = VPe.ReadU32(BYTEPTR(Fd), FD_ATTRIBUTES_OFF) + Attrs: uint32 = VPe.ReadU32(BYTEPTR(Fd), FD_ATTRIBUTES_OFF) Name: str = str(Fd + FD_FILENAME_OFF) if string.strcmp(Name, ".") != 0 and string.strcmp(Name, "..") != 0: if (Attrs & wf.FILE_ATTRIBUTE_DIRECTORY) != 0: @@ -388,7 +388,7 @@ def ScanTree(DirAnsi: str, Depth: int) -> int: hExe: wb.HANDLE = wf.FindFirstFileA(Pat, t.CPtr(Fd)) if hExe != wb.INVALID_HANDLE_VALUE: while True: - Attrs2: t.CUInt32T = VPe.ReadU32(BYTEPTR(Fd), FD_ATTRIBUTES_OFF) + Attrs2: uint32 = VPe.ReadU32(BYTEPTR(Fd), FD_ATTRIBUTES_OFF) Name2: str = str(Fd + FD_FILENAME_OFF) if (Attrs2 & wf.FILE_ATTRIBUTE_DIRECTORY) == 0: PaceFile() @@ -469,7 +469,7 @@ def RunScanRound(CachePath: str, RoundIdx: int) -> int: R0: ULONGLONG = wb.GetTickCount64() ProgRootEnter(str(AnsiDir)) ScanTree(str(AnsiDir), 1) - ProgRootLeave(str(AnsiDir), t.CSizeT(wb.GetTickCount64() - R0)) + ProgRootLeave(str(AnsiDir), sizet(wb.GetTickCount64() - R0)) else: # 自动表里的静态两条(C:\Viper / D:\Viper)与盘符枚举结果可能本就不存在, # 逐条回显属过程细节,仅在 --verbose 时给出(--path 的显式告警在 VDirs.BuildTable) @@ -481,26 +481,26 @@ def RunScanRound(CachePath: str, RoundIdx: int) -> int: # 这里只补一行汇总(不逐条重打)——逐条与汇总均属过程细节,仅 --verbose 时给出 if Reject_Total > REJECT_LOG_MAX: VLog.VerboseFmt2(" [reject] 其余省略…(本轮累计 %u 条,已逐条打印前 %u 条)\n", - t.CSizeT(Reject_Total), t.CSizeT(REJECT_LOG_MAX)) + sizet(Reject_Total), sizet(REJECT_LOG_MAX)) # 轮结束前的最后一次轮询:此后到写盘之间不再有等待点(check 命中项因此能进入本轮数组) VGuard.PollIpc() removed: int = VCache.ValidateCache() VJson.EmitJson() VLog.StdoutWrite(str(VJson.JsonBuf())) - VCache.WriteCacheFile(CachePath, VJson.JsonBuf(), t.CSizeT(VJson.JsonLen())) + VCache.WriteCacheFile(CachePath, VJson.JsonBuf(), sizet(VJson.JsonLen())) T1: ULONGLONG = wb.GetTickCount64() # 轮末一行(默认保留,不含路径):常驻模式下它是"本轮已跑完"的存活信号(与启动摘要同构), # --once 时即结束行;"下轮开始"时间戳属下轮过程细节,仅 --verbose。 # "移除"含两部分:完整重校剔除(Revalidated)+ 存在性校验移除(removed)。 VLog.LogFmt3("轮次 %u 结束: 扫描目录 %u 个, 已知条目 %u 项", - t.CSizeT(RoundIdx), t.CSizeT(Dirs), t.CSizeT(VCache.CacheCount())) + sizet(RoundIdx), sizet(Dirs), sizet(VCache.CacheCount())) VLog.LogFmt3(", 新增 %u 项, 移除 %u 项, 耗时 %u ms", - t.CSizeT(Round_Added), t.CSizeT(Revalidated + removed), t.CSizeT(T1 - T0)) + sizet(Round_Added), sizet(Revalidated + removed), sizet(T1 - T0)) # "下轮开始"时间戳属过程细节(仅 --verbose) if VLog.VerboseOn() != 0: - VLog.TimeStampAfter(Prog_Stamp, PROG_STAMP_CAP, t.CSizeT(VCli.SleepMs())) + VLog.TimeStampAfter(Prog_Stamp, PROG_STAMP_CAP, sizet(VCli.SleepMs())) VLog.LogFmtS1(", 下轮开始: %s", str(Prog_Stamp)) VLog.LogStr("\n") return 0 @@ -519,8 +519,8 @@ def RunScan() -> int: # 不含缓存路径与其他被处理路径(路径属过程细节,仅 --verbose 时经目录表/进度行给出): # 该行只承担"进程已启动"这一可观测信号,与轮末一行共同构成本模式的存活指示。 VLog.LogFmtS1("VET - Viper Environment Tool %s (scan)", VCli.Version()) - VLog.LogFmt2(" sleep=%u once=%u", t.CSizeT(VCli.SleepMs()), t.CSizeT(Once)) - VLog.LogFmt1(" need-confirm=%u\n", t.CSizeT(VCli.NeedConfirm())) + VLog.LogFmt2(" sleep=%u once=%u", sizet(VCli.SleepMs()), sizet(Once)) + VLog.LogFmt1(" need-confirm=%u\n", sizet(VCli.NeedConfirm())) if VCli.PaceSet() != 0: # 显式给出 --pace 或 --pace-units ⇒ 一律启用节流(--once 下也生效),时长/粒度取命令行值; @@ -531,7 +531,7 @@ def RunScan() -> int: Pace_Sleep_Ms = VCli.PaceSleepMs() Pace_File_Units = VCli.PaceFileUnits() VLog.VerboseFmt2("--pace: 已启用扫描节流 sleep=%u units=%u\n", - t.CSizeT(Pace_Sleep_Ms), t.CSizeT(Pace_File_Units)) + sizet(Pace_Sleep_Ms), sizet(Pace_File_Units)) elif Once != 0: # 未显式给出节流参数时的原有行为:--once 只跑一轮,关闭节流 sleep(PaceDir/PaceFile 均不再 Sleep) Pace_Enabled = 0 @@ -608,11 +608,11 @@ def RunSearchPathsQuery() -> int: if VFs.PathIsDir(str(Ansi)) == 0: Skip = 1 if Skip != 0: - VLog.LogFmtIS(" [search] [%u] %s (不存在或非目录,扫盘时会跳过)\n", t.CSizeT(i), Path) + VLog.LogFmtIS(" [search] [%u] %s (不存在或非目录,扫盘时会跳过)\n", sizet(i), Path) else: - VLog.LogFmtIS(" [search] [%u] %s\n", t.CSizeT(i), Path) + VLog.LogFmtIS(" [search] [%u] %s\n", sizet(i), Path) i += 1 if Ansi is not None: _mbuddy.free(t.CPtr(Ansi)) - VLog.LogFmt1(" [search] 合计 %u 条;未扫盘、未读写缓存,查询到此结束\n", t.CSizeT(N)) + VLog.LogFmt1(" [search] 合计 %u 条;未扫盘、未读写缓存,查询到此结束\n", sizet(N)) return 0 diff --git a/App/lib/__init__.vp b/App/lib/__init__.vp index dc1d52b..22e73e4 100644 --- a/App/lib/__init__.vp +++ b/App/lib/__init__.vp @@ -12,4 +12,4 @@ import sys # 其它模块只经各模块公开函数访问,不交叉读写本文件的全局。 # ============================================================ -LIB_PACKAGE_MARKER: t.CDefine = 1 +define LIB_PACKAGE_MARKER = 1 diff --git a/App/main.vp b/App/main.vp index 634b54f..fbeab8c 100644 --- a/App/main.vp +++ b/App/main.vp @@ -32,8 +32,8 @@ import lib.VCli as VCli # → 初始化 argv → 分派子命令。所有实现见 lib/ 下各模块。 # ============================================================ -CODE_PAGE: t.CDefine = 65001 -POOL_SIZE: t.CDefine = 16777216 # MemBuddy 主内存池 16 MiB +define CODE_PAGE = 65001 +define POOL_SIZE = 16777216 # MemBuddy 主内存池 16 MiB @t.CExport