CopyFileEx возвращает ERROR_INVALID_PARAMETER, даже если копирование успешно завершено на Win2012R2
CopyFileEx с последующим вызовом GetLastError возвращает ERROR_INVALID_PARAMETER, даже если копирование успешно завершено на Win2012R2 примерно 2 месяца назад (возможно, с декабря 2015 года). В Windows XP до Windows 7 и Win 2k3 до Win2k8R2 этого не происходит, и GetLastError всегда возвращает 0 (ERROR_SUCCESS).
Это ожидаемое поведение такого рода Win32 API? Нужно ли добавлять результат и код GetLastError, чтобы быть уверенным в результате?
Кажется, этот KB связан с проблемой, но применение этого патча не меняет поведение API. Вероятно, был еще один КБ, из-за которого появилась проблема, но я не смог ее найти https://support.microsoft.com/en-us/kb/2963918
Документация для GetLastError:
Возвращаемое значение
Возвращаемое значение - код последней ошибки вызывающего потока.
В разделе "Возвращаемое значение" документации для каждой функции, которая устанавливает код последней ошибки, отмечаются условия, при которых функция устанавливает код последней ошибки. Большинство функций, которые устанавливают код последней ошибки потока, устанавливают его при сбое. Тем не менее, некоторые функции также устанавливают код последней ошибки, когда они завершаются успешно. Если функция не задокументирована для установки кода последней ошибки, значение, возвращаемое этой функцией, является просто самым последним кодом последней ошибки, который был установлен; некоторые функции устанавливают код последней ошибки равным 0 в случае успеха, а другие нет.
1 ответ
Из документации:
Возвращаемое значение
Если функция завершается успешно, возвращаемое значение отлично от нуля.
Если функция не работает, возвращаемое значение равно нулю. Чтобы получить расширенную информацию об ошибке, вызовите GetLastError.
Другими словами, если функция завершается успешно, вы не должны вызывать GetLastError
и не дается никаких обещаний о том, что будет возвращено, если вы это сделаете.
Итак, вы приписываете значение значению, возвращаемому GetLastError
где не должно быть никакого значения.
Это общий шаблон в Win32. Многие функции похожи. Значение, возвращаемое GetLastError
имеет смысл только в том случае, если возвращаемое значение функции указывает на сбой. Это не универсальное правило, поэтому вам нужно проверять документацию по функциям.
Типичная форма вызова такой функции Win32 выглядит следующим образом:
if (CopyFileEx(...))
{
// function call succeeded, continue
}
else
{
DWORD err = GetLastError();
// do something with err
}
Обратите внимание, что GetLastError
вызывается только в том случае, если функция указывает на ошибку через свое возвращаемое значение.