Windows CancelSynchronousIo与WNetAddConnection2一起工作吗?

Windows CancelSynchronousIo与WNetAddConnection2一起工作吗?,windows,winapi,networking,Windows,Winapi,Networking,我正在尝试取消与的通话,但失败 调用CancelSynchronousIo成功,但实际上没有取消任何操作 我使用的是在Windows7x64上运行的32位控制台应用程序 有人成功地做到了吗?我在做傻事吗?下面是一个示例控制台应用程序(需要与mpr.lib链接): Larry Osterman说(我希望他不介意我引用他的话):“问题在评论中得到了回答:wnetaddconnection2不是一个简单的IOCTL调用。”因此答案(不幸)是否定的。首先,wnetaddconnection2是系统范围的

我正在尝试取消与的通话,但失败

调用CancelSynchronousIo成功,但实际上没有取消任何操作

我使用的是在Windows7x64上运行的32位控制台应用程序

有人成功地做到了吗?我在做傻事吗?下面是一个示例控制台应用程序(需要与mpr.lib链接):


Larry Osterman说(我希望他不介意我引用他的话):“问题在评论中得到了回答:wnetaddconnection2不是一个简单的IOCTL调用。”因此答案(不幸)是否定的。

首先,
wnetaddconnection2
是系统范围的,而不是每个进程。这一点很重要,因为多次调用WNetAddConnection2会破坏系统的稳定性,尤其是在使用explorer时

我使用
WNetGetResourceInformation
首先检查连接是否已经存在,甚至在考虑调用它之前-我的进程可能已经运行过,然后关闭。连接可能仍然存在。当我的Windows服务需要添加这样的连接时,我使用了一个讨厌的小技巧,以防止这些完全不可中止的API阻止我自己的服务关闭

诀窍是在一个单独的进程中运行这些调用:毕竟它们是系统范围的。您通常可以像自己调用函数一样等待进程完成,但如果需要中止以关闭,则可以终止进程并放弃等待


然而,令人遗憾的是,某些Windows资源,例如命名管道句柄和远程计算机上打开的文件句柄,在远程计算机出现故障或关闭后可能需要16秒才能关闭
CancelSynchronousIo
似乎对这些都没有帮助,但可能会增加额外的长延迟。

它会取消I/O操作、驱动程序IRP。WNetAddConnection2是一种完全不同的动物。如果我在远程服务器上创建一个FindFirstFile,那么它所做的第一件事就是阻止尝试启动连接,可能使用与WNetAddConnection2完全相同的内部代码和IRP。似乎没有任何根本的区别,但前者是可以取消的,后者显然不是。我遗漏了什么吗?(你忘了说@Hans。)我会冒险猜测,在FindFirstFile到UNC路径的情况下,只有FindFirstFile操作本身被取消,网络连接尝试本身可能会完成(或超时),然后被丢弃。@arx:只是猜测,但可能存在与支持第三方网络提供商相关的设计问题。WNetAddConnection函数由网络提供程序DLL(NPAddConnection)中的用户模式代码实现,因此任何IRP都可能是从MPR中的系统线程发出的,而不是从您的线程发出的。毫无疑问,这样或那样做是有可能的,但我猜MS从未想过。请参阅实用建议:由于网络连接是每个会话的,如果有帮助的话,您可以从子进程发出对WNetAddConnection2的调用。干杯,尽管我很好奇。拉里是你的朋友吗?
DWORD WINAPI ConnectThread(LPVOID param)
{
    NETRESOURCE nr;
    memset(&nr, 0, sizeof(nr));
    nr.dwType = RESOURCETYPE_ANY;
    nr.lpRemoteName = L"\\\\8.8.8.8\\bog";

    // result is ERROR_BAD_NETPATH (i.e. the call isn't cancelled)
    DWORD result = WNetAddConnection2(&nr, L"pass", L"user", CONNECT_TEMPORARY);

    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    // Create a new thread to run WNetAddConnection2
    HANDLE hThread = CreateThread(0, 0, ConnectThread, 0, 0, 0);
    if (!hThread)
        return 1;

    // Retry the cancel until it fails; keep track of how often
    int count = 0;
    BOOL ok;
    do
    {
        // Sleep to give the thread a chance to start
        Sleep(1000);
        ok = CancelSynchronousIo(hThread);
        ++count;
    }
    while (ok);

    // count will equal two here (i.e. one successful cancellation and
    // one failed cancellation)

    // err is ERROR_NOT_FOUND (i.e. nothing to cancel) which makes
    // sense for the second call
    DWORD err = GetLastError();

    // Wait for the thread to finish; this takes ages (i.e. the
    // WNetAddConnection2 call is not cancelled)
    WaitForSingleObject(hThread, INFINITE);

    return 0;
}