CancelIoEx: указатель на функцию typedef

Следующий код скопирован из 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;
}

2

Решение

Предполагая, что это весь код, в нем есть серьезная ошибка. Это:

CANCELIOEXPROC pfnCancelIoEx = NULL;

определяет pfnCancelIoEx как указатель на функцию, чья подпись совпадает с сигнатурой CancelIoEx, Указатель инициализируется нулевым значением, и очевидным намерением является указать его на CancelIoEx потом.

Эта функция определена в Kernel32.dllтак что загрузка это логичный следующий шаг. Если это удастся, код следует продолжить делая это:

pfnCancelIoEx = GetProcAddress(hKernel32, "CancelIoEx");

И тогда он должен проверить результат. Тем не мение, это не делает ни того, ни другого.

Далее по этой строке:

bResult = (pfnCancelIoEx)(m_hFile, NULL);

он пытается вызвать функцию, указанную pfnCancelIoEx, Однако этот указатель никогда не изменяется от своего начального нулевого значения, поэтому он будет пытаться разыменовать нулевой указатель, что приведет к неопределенному поведению и вероятности сбоя.

1

Другие решения

Других решений пока нет …