即使Win2012R2上的副本成功,CopyFileEx也会返回ERROR_INVALID_PARAMETER

时间:2016-02-24 16:30:00

标签: winapi windows2012

CopyFileEx以及对GetLastError的以下调用返回ERROR_INVALID_PARAMETER,即使该版本在Win2012R2上大约2个月后(可能是2015年12月)成功返回。在Windows XP上直到Windows 7和Win 2k3到Win2k8R2,这不会发生,GetLastError总是返回0(ERROR_SUCCESS)。

这种Win32 API的预期行为是什么? 您是否必须同时添加结果和GetLastError代码以确保结果?

此KB似乎与问题有关,但应用此修补程序不会改变API行为。可能有另一个KB导致问题出现,但我一直无法找到它 https://support.microsoft.com/en-us/kb/2963918

GetLastError的文档:

  

返回值

     

返回值是调用主题的最后错误代码。

     

每个函数的文档的返回值部分   设置最后一个错误代码注意函数的条件   设置最后一个错误代码。大多数设置线程的函数   最后错误代码在失败时设置它。但是,一些功能也   成功时设置最后一个错误代码。 如果功能不是   记录以设置最后一个错误代码,由此返回的值   函数只是已设置的最新错误代码;   某些函数在成功时将最后错误代码设置为0,而其他函数则设置为0   不

1 个答案:

答案 0 :(得分:3)

来自documentation

  

返回值

     

如果函数成功,则返回值为非零值。

     

如果函数失败,则返回值为零。要获得扩展错误   信息调用GetLastError。

换句话说,如果函数成功,则不应该调用GetLastError,并且如果你这样做,则不会对将返回的内容做出承诺。

因此,您将GetLastError返回的值赋予意义,其中没有任何意义归属。

这是Win32中的常见模式。很多功能都很相似。 GetLastError返回的值仅在函数的返回值指示失败时才有意义。这不是一个普遍的规则,所以你需要逐个函数检查文档。

调用此类Win32函数的典型形式如下所示:

if (CopyFileEx(...))
{
    // function call succeeded, continue
}
else
{
    DWORD err = GetLastError();
    // do something with err
}

请注意,仅当函数通过其返回值指示失败时才会调用GetLastError