Chuyu-Team / YY-Thunks

Fix DecodePointer, EncodePointer,RegDeleteKeyEx etc. APIs not found in Windows XP RTM.
MIT License
496 stars 102 forks source link

为tokio rust库提供Windows Vista RTM兼容 #70

Closed zhuxiujia closed 2 months ago

zhuxiujia commented 4 months ago

yy-thunks version: v1.0.9 beta3

原因

Vista系统 SetFileCompletionNotificationModes尝试设置AFD句柄时发生了拒绝访问。

修复方案

特意针对SetFileCompletionNotificationModes平台,将拒绝访问任然返回成功。 因为SetFileCompletionNotificationModes起到一个性能优化作用,其失败不影响主体功能。

复现代码(#60)

use tokio::net::TcpListener;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let listener = TcpListener::bind("127.0.0.1:8080").await?;// 这里报错PermissionDined
    loop {
        let (mut socket, _) = listener.accept().await?;
        tokio::spawn(async move {
            let mut buf = [0; 1024];
            loop {
                let n = match socket.read(&mut buf).await {
                    // socket closed
                    Ok(n) if n == 0 => return,
                    Ok(n) => n,
                    Err(e) => {
                        eprintln!("failed to read from socket; err = {:?}", e);
                        return;
                    }
                };
                if let Err(e) = socket.write_all(&buf[0..n]).await {
                    eprintln!("failed to write to socket; err = {:?}", e);
                    return;
                }
            }
        });
    }
}

46af50a01c2de890cfeac0a0045cf24

han1548772930 commented 3 months ago

我也有同样的问题, 希望作者大佬能支持一下

mingkuang-Chuyu commented 3 months ago

@zhuxiujia 可以分析一下那里出错了吗?

zhuxiujia commented 3 months ago

@zhuxiujia 可以分析一下那里出错了吗?

如果使用rust nightly编译,会提示没有找到 bcryptprimitives.dll。 如果使用stable 编译,tokio的TcpListener::bind("0.0.0.0:9000").await? 绑定端口操作会失败。 我在每个代码加了打印错误后,分析了下,是SetFileCompletionNotificationModes这个函数在绑定端口的最后提示 拒绝访问。

以下是我提供的测试代码(代码包含了tokio和mio的源码方便修改和测试) w.zip

MouriNaruto commented 3 months ago

@zhuxiujia 按理来说 Vista 开始提供了这个 API 的原生支持(按照 YY-Thunks 的这个 API 的 fallback 实现是无脑返回 TRUE),于是你看到了拒绝访问,于是其实可能需要用 Process Explorer 看一下一些句柄的类型啥的

毛利

zhuxiujia commented 3 months ago

@zhuxiujia 按理来说 Vista 开始提供了这个 API 的原生支持(按照 YY-Thunks 的这个 API 的 fallback 实现是无脑返回 TRUE),于是你看到了拒绝访问,于是其实可能需要用 Process Explorer 看一下一些句柄的类型啥的

毛利

我看 YY-Thunks 的这个 API 代码是 先尝试try_get_SetFileCompletionNotificationModes 这个,我看不到这个函数的实现。 只有低于vista,2008的系统才会无脑返回 TRUE

mingkuang-Chuyu commented 3 months ago

没错。Vista中这个函数调用的是系统的。

如果你提供的信息没有错,那么是系统API本身返回了拒绝访问。

获取Outlook for Androidhttps://aka.ms/AAb9ysg


From: zxj @.> Sent: Friday, April 5, 2024 12:05:17 AM To: Chuyu-Team/YY-Thunks @.> Cc: mingkuang @.>; Comment @.> Subject: Re: [Chuyu-Team/YY-Thunks] windows vista/server 2008运行tokio绑定端口失败,已经是用管理员权限运行。 (Issue #70)

@zhuxiujiahttps://github.com/zhuxiujia 按理来说 Vista 开始提供了这个 API 的原生支持(按照 YY-Thunks 的这个 API 的 fallback 实现是无脑返回 TRUE),于是你看到了拒绝访问,于是其实可能需要用 Process Explorer 看一下一些句柄的类型啥的

毛利

我看 YY-Thunks 的这个 API 代码是 先尝试try_get_SetFileCompletionNotificationModes 这个,我看不到这个函数的实现。 只有低于vista,2008的系统才会无脑返回 TRUE

― Reply to this email directly, view it on GitHubhttps://github.com/Chuyu-Team/YY-Thunks/issues/70#issuecomment-2037617883, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEX7GZP2OX2J77YEULI6WTDY3V233AVCNFSM6AAAAABDSSU636VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMZXGYYTOOBYGM. You are receiving this because you commented.Message ID: @.***>

mingkuang-Chuyu commented 3 months ago

至于try_get_SetFileCompletionNotificationModes不用太关注,这个就是取SetFileCompletionNotificationModes函数的到处地址,代码是宏自动产生的,

调试时自动能跳转到源代码吧?

获取Outlook for Androidhttps://aka.ms/AAb9ysg


From: 徐 鹏捷 @.> Sent: Friday, April 5, 2024 12:34:18 AM To: Chuyu-Team/YY-Thunks @.>; Chuyu-Team/YY-Thunks @.> Cc: Comment @.> Subject: Re: [Chuyu-Team/YY-Thunks] windows vista/server 2008运行tokio绑定端口失败,已经是用管理员权限运行。 (Issue #70)

没错。Vista中这个函数调用的是系统的。

如果你提供的信息没有错,那么是系统API本身返回了拒绝访问。

获取Outlook for Androidhttps://aka.ms/AAb9ysg


From: zxj @.> Sent: Friday, April 5, 2024 12:05:17 AM To: Chuyu-Team/YY-Thunks @.> Cc: mingkuang @.>; Comment @.> Subject: Re: [Chuyu-Team/YY-Thunks] windows vista/server 2008运行tokio绑定端口失败,已经是用管理员权限运行。 (Issue #70)

@zhuxiujiahttps://github.com/zhuxiujia 按理来说 Vista 开始提供了这个 API 的原生支持(按照 YY-Thunks 的这个 API 的 fallback 实现是无脑返回 TRUE),于是你看到了拒绝访问,于是其实可能需要用 Process Explorer 看一下一些句柄的类型啥的

毛利

我看 YY-Thunks 的这个 API 代码是 先尝试try_get_SetFileCompletionNotificationModes 这个,我看不到这个函数的实现。 只有低于vista,2008的系统才会无脑返回 TRUE

― Reply to this email directly, view it on GitHubhttps://github.com/Chuyu-Team/YY-Thunks/issues/70#issuecomment-2037617883, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEX7GZP2OX2J77YEULI6WTDY3V233AVCNFSM6AAAAABDSSU636VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMZXGYYTOOBYGM. You are receiving this because you commented.Message ID: @.***>

zhuxiujia commented 3 months ago

额,我暂时无法定位具体问题出在哪里了,目测tokio在win7以上版本正常,感觉问题还是在替换的某个api的环节上(std::net::TcpListener::bind也是正常,只有tokio绑定端口是失败)。 这个问题也反馈给了 https://github.com/tokio-rs/tokio/issues/6461

mingkuang-Chuyu commented 3 months ago

你不是有环境吗?可以调试。

目前根据你的信息,八成你那边的Vista系统API本身出了问题。大概就是给套接字设置FILE_SKIP_COMPLETION_PORT_ON_SUCCESS时失败了。

建议本地先把函数 SetFileCompletionNotificationModes 改成直接返回TRUE试试。

获取Outlook for Androidhttps://aka.ms/AAb9ysg


From: zxj @.> Sent: Friday, April 5, 2024 1:15:35 AM To: Chuyu-Team/YY-Thunks @.> Cc: mingkuang @.>; Comment @.> Subject: Re: [Chuyu-Team/YY-Thunks] windows vista/server 2008运行tokio绑定端口失败,已经是用管理员权限运行。 (Issue #70)

额,我暂时无法定位具体问题出在哪里了,目测tokio在win7以上版本正常,感觉问题还是在替换的某个api的环节上。

― Reply to this email directly, view it on GitHubhttps://github.com/Chuyu-Team/YY-Thunks/issues/70#issuecomment-2037761580, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEX7GZJ4DBK2KCCBTRRBFPTY3WDDPAVCNFSM6AAAAABDSSU636VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMZXG43DCNJYGA. You are receiving this because you commented.Message ID: @.***>

zhuxiujia commented 3 months ago

SetFileCompletionNotificationModes

强制改成返回TRUE 似乎不影响Tokio的运行(能跑起来),我看了tokio的源码并不是 设置参数FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 而是设置FILE_SKIP_SET_EVENT_ON_HANDLE (这一步) 源码位置可以看 https://github.com/tokio-rs/mio/blob/master/src/sys/windows/afd.rs 的213行

zhuxiujia commented 3 months ago

你不是有环境吗?可以调试。 目前根据你的信息,八成你那边的Vista系统API本身出了问题。大概就是给套接字设置FILE_SKIP_COMPLETION_PORT_ON_SUCCESS时失败了。 建议本地先把函数 SetFileCompletionNotificationModes 改成直接返回TRUE试试。 获取Outlook for Androidhttps://aka.ms/AAb9ysg ____ From: zxj @.> Sent: Friday, April 5, 2024 1:15:35 AM To: Chuyu-Team/YY-Thunks @.> Cc: mingkuang @.>; Comment @.> Subject: Re: [Chuyu-Team/YY-Thunks] windows vista/server 2008运行tokio绑定端口失败,已经是用管理员权限运行。 (Issue #70) 额,我暂时无法定位具体问题出在哪里了,目测tokio在win7以上版本正常,感觉问题还是在替换的某个api的环节上。 ― Reply to this email directly, view it on GitHub<#70 (comment)>, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEX7GZJ4DBK2KCCBTRRBFPTY3WDDPAVCNFSM6AAAAABDSSU636VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMZXG43DCNJYGA. You are receiving this because you commented.Message ID: @.***>

如果SetFileCompletionNotificationModes调用失败,mio仍然能够接收到I/O完成的通知,因为mio使用了Windows的重叠I/O机制(异步 I/O 也称为重叠 I/O)。在这种机制下,即使SetFileCompletionNotificationModes没有成功设置FILE_SKIP_SET_EVENT_ON_HANDLE,Windows也会在I/O操作完成时通过其他方式通知mio。具体来说,mio会使用GetQueuedCompletionStatus或GetQueuedCompletionStatusEx函数来轮询I/O完成端口,以获取已完成I/O操作的通知。 但是这样的代价可能是tokio/mio性能会下降很多

但是我看 https://learn.microsoft.com/zh-cn/windows/win32/api/winbase/nf-winbase-setfilecompletionnotificationmodes 文档中描述的是支持在vista使用FILE_SKIP_SET_EVENT_ON_HANDLE这个参数,具体就不清楚了。。。。。

zhuxiujia commented 3 months ago

没错。Vista中这个函数调用的是系统的。 如果你提供的信息没有错,那么是系统API本身返回了拒绝访问。 获取Outlook for Androidhttps://aka.ms/AAb9ysg ____ From: zxj @.> Sent: Friday, April 5, 2024 12:05:17 AM To: Chuyu-Team/YY-Thunks @.> Cc: mingkuang @.>; Comment @.> Subject: Re: [Chuyu-Team/YY-Thunks] windows vista/server 2008运行tokio绑定端口失败,已经是用管理员权限运行。 (Issue #70) @zhuxiujiahttps://github.com/zhuxiujia 按理来说 Vista 开始提供了这个 API 的原生支持(按照 YY-Thunks 的这个 API 的 fallback 实现是无脑返回 TRUE),于是你看到了拒绝访问,于是其实可能需要用 Process Explorer 看一下一些句柄的类型啥的 毛利 我看 YY-Thunks 的这个 API 代码是 先尝试try_get_SetFileCompletionNotificationModes 这个,我看不到这个函数的实现。 只有低于vista,2008的系统才会无脑返回 TRUE ― Reply to this email directly, view it on GitHub<#70 (comment)>, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEX7GZP2OX2J77YEULI6WTDY3V233AVCNFSM6AAAAABDSSU636VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMZXGYYTOOBYGM. You are receiving this because you commented.Message ID: @.***>

还请大佬看看 如何支持 bcryptprimitives.dll 找不到的这个问题哈。

mingkuang-Chuyu commented 3 months ago

我觉得你说的某些地方存在一些问题,FILE_SKIP_SET_EVENT_ON_HANDLE是用提升性能的,避免给文件句柄设置信号状态,这一定程度避免了句柄竞争,可以提升效率。

但是完成端口是必须的,即使FILE_SKIP_SET_EVENT_ON_HANDLE成功,最终数据也由完成端口处理。

那个FILE_SKIP_COMPLETION_PORT_ON_SUCCESS才是特定场景不走完成端口。

现在疑惑的是为什么VISTA系统FILE_SKIP_SET_EVENT_ON_HANDLE会失败……

获取Outlook for Androidhttps://aka.ms/AAb9ysg


发件人: zxj @.> 发送时间: 星期五, 四月 5, 2024 1:44:50 上午 收件人: Chuyu-Team/YY-Thunks @.> 抄送: mingkuang @.>; Comment @.> 主题: Re: [Chuyu-Team/YY-Thunks] windows vista/server 2008运行tokio绑定端口失败,已经是用管理员权限运行。 (Issue #70)

你不是有环境吗?可以调试。 目前根据你的信息,八成你那边的Vista系统API本身出了问题。大概就是给套接字设置FILE_SKIP_COMPLETION_PORT_ON_SUCCESS时失败了。 建议本地先把函数 SetFileCompletionNotificationModes 改成直接返回TRUE试试。 获取Outlook for Androidhttps://aka.ms/AAb9ysg … ____ From: zxj @.> Sent: Friday, April 5, 2024 1:15:35 AM To: Chuyu-Team/YY-Thunks @.> Cc: mingkuang @.>; Comment @.> Subject: Re: [Chuyu-Team/YY-Thunks] windows vista/server 2008运行tokio绑定端口失败,已经是用管理员权限运行。 (Issue #70https://github.com/Chuyu-Team/YY-Thunks/issues/70) 额,我暂时无法定位具体问题出在哪里了,目测tokio在win7以上版本正常,感觉问题还是在替换的某个api的环节上。 D Reply to this email directly, view it on GitHub<#70 (comment)https://github.com/Chuyu-Team/YY-Thunks/issues/70#issuecomment-2037761580>, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEX7GZJ4DBK2KCCBTRRBFPTY3WDDPAVCNFSM6AAAAABDSSU636VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMZXG43DCNJYGA. You are receiving this because you commented.Message ID: @.***>

如果SetFileCompletionNotificationModes调用失败,mio仍然能够接收到I/O完成的通知,因为mio使用了Windows的重叠I/O机制。在这种机制下,即使SetFileCompletionNotificationModes没有成功设置FILE_SKIP_SET_EVENT_ON_HANDLE,Windows也会在I/O操作完成时通过其他方式通知mio。具体来说,mio会使用GetQueuedCompletionStatus或GetQueuedCompletionStatusEx函数来轮询I/O完成端口,以获取已完成I/O操作的通知。 但是这样的代价可能是tokio/mio性能会下降很多

― Reply to this email directly, view it on GitHubhttps://github.com/Chuyu-Team/YY-Thunks/issues/70#issuecomment-2037818286, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEX7GZODSUEMHD6UTOXSPHTY3WGQZAVCNFSM6AAAAABDSSU636VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMZXHAYTQMRYGY. You are receiving this because you commented.Message ID: @.***>

MouriNaruto commented 3 months ago

没错。Vista中这个函数调用的是系统的。 如果你提供的信息没有错,那么是系统API本身返回了拒绝访问。 获取Outlook for Androidhttps://aka.ms/AAb9ysg ____ From: zxj @.**> Sent: Friday, April 5, 2024 12:05:17 AM To: Chuyu-Team/YY-Thunks @.**> Cc: mingkuang @.**>; Comment @.**> Subject: Re: [Chuyu-Team/YY-Thunks] windows vista/server 2008运行tokio绑定端口失败,已经是用管理员权限运行。 (Issue #70) @zhuxiujiahttps://github.com/zhuxiujia 按理来说 Vista 开始提供了这个 API 的原生支持(按照 YY-Thunks 的这个 API 的 fallback 实现是无脑返回 TRUE),于是你看到了拒绝访问,于是其实可能需要用 Process Explorer 看一下一些句柄的类型啥的 毛利 我看 YY-Thunks 的这个 API 代码是 先尝试try_getSetFileCompletionNotificationModes 这个,我看不到这个函数的实现。 只有低于vista,2008的系统才会无脑返回 TRUE ― Reply to this email directly, view it on GitHub<#70 (comment)>, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AEX7GZP2OX2J77YEULI6WTDY3V233AVCNFSM6AAAAABDSSU636VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMZXGYYTOOBYGM. You are receiving this because you commented.Message ID: @_.***>

还请大佬看看 如何支持 bcryptprimitives.dll 找不到的这个问题哈。

image bcryptprimitives.dll 反而是实现一些 API fallback 的事情

毛利

mingkuang-Chuyu commented 3 months ago

@zhuxiujia 可以分析一下那里出错了吗?

如果使用rust nightly编译,会提示没有找到 bcryptprimitives.dll。 如果使用stable 编译,tokio的TcpListener::bind("0.0.0.0:9000").await? 绑定端口操作会失败。 我在每个代码加了打印错误后,分析了下,是SetFileCompletionNotificationModes这个函数在绑定端口的最后提示 拒绝访问。

以下是我提供的测试代码(代码包含了tokio和mio的源码方便修改和测试) w.zip

bcryptprimitives.dll的问题建议单独开Bug,另外是否可以提供详细的bcryptprimitives.dll中依赖的函数列表?

对于这个问题,我计划为Vista系统增加特殊行为,SetFileCompletionNotificationModes这个函数拒绝访问时 忽略这个错误。

zhuxiujia commented 3 months ago

bcryptprimitives.dll

那太棒了,bcryptprimitives.dll中依赖的函数列表,这个需要研究研究看看(目前是rust nightly 工具链会提示缺少这个)。

mingkuang-Chuyu commented 2 months ago

CI中已经有临时规避的版本,可以下载尝试使用。

https://github.com/Chuyu-Team/YY-Thunks/actions/runs/8908062548

mingkuang-Chuyu commented 2 months ago

新版本已经发布 https://github.com/Chuyu-Team/YY-Thunks/releases/tag/v1.0.10-Beta2