2

以下代码是从 MS Async Filter 复制而来的。假设以下代码正在调用 CancelIo 或 CancelIoEx。无论如何,我看不到在哪里调用 CancelIoEx。假设 typedef 代表 CancelIoEx 但从未被调用。这条线到底在bResult = (pfnCancelIoEx)(m_hFile, NULL);做什么?

// Cancel: Cancels pending I/O requests.
HRESULT CFileStream::Cancel()
{
    CAutoLock lock(&m_CritSec);

    // Use CancelIoEx if available, otherwise use CancelIo.

    typedef BOOL (*CANCELIOEXPROC)(HANDLE hFile, LPOVERLAPPED lpOverlapped);

    BOOL bResult = 0;
    CANCELIOEXPROC pfnCancelIoEx = NULL;


    HMODULE hKernel32 = LoadLibrary(L"Kernel32.dll");

    if (hKernel32){

        //propably bad code !!! Take Care.
        bResult = (pfnCancelIoEx)(m_hFile, NULL);

        FreeLibrary(hKernel32);
    }
    else {

        bResult = CancelIo(m_hFile);
    }

    if (!bResult) {

        return HRESULT_FROM_WIN32(GetLastError());
    }
    return S_OK;
}
4

1 回答 1

1

假设这是所有代码,它有一个严重的错误。这个:

CANCELIOEXPROC pfnCancelIoEx = NULL;

定义pfnCancelIoEx为指向其签名匹配的函数的指针CancelIoExCancelIoEx指针被初始化为空值,明显的意图是稍后指向它。

该函数在 中定义Kernel32.dll,因此加载它是合乎逻辑的下一步。如果成功,则代码应继续执行以下操作:

pfnCancelIoEx = GetProcAddress(hKernel32, "CancelIoEx");

然后它应该检查结果。但是,它并没有这样做。

接下来,在这一行:

bResult = (pfnCancelIoEx)(m_hFile, NULL);

它试图调用 指向的函数pfnCancelIoEx。但是,这个指针永远不会改变它的初始空值,所以这将尝试取消引用空指针,导致未定义的行为并可能崩溃。

于 2013-04-19T17:42:56.303 回答