失敗我們有一行代碼與OPEN_ALWAYS的CreateFile Win32 API調用以一種奇怪的方式
if(!CreateFile(m_hFile, szFile, GENERIC_READ|GENERIC_WRITE, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL))
{
DWORD dwErr = GetLastError();
CString czInfo;
czInfo.Format ("CMemoryMapFile::OpenAppend SetFilePointer call failed - GetLastError returned %d", dwErr);
LOG(czInfo);
return false;
}
此代碼工作多年很大。幾個星期前,我們遇到了一個有問題的客戶。原來,問題可以追溯到這行代碼,其中函數將返回一個INVALID_HANDLE_VALUE句柄,而GetLastError()返回ERROR_FILE_NOT_FOUND(2)。
現在,這對我們來說非常混亂。如果文件不存在,OPEN_ALWAYS應該指示文件被創建。那麼,爲什麼我們會收到一個ERROR_FILE_NOT_FOUND?
更多的困惑:對於這個客戶,這隻發生在一個網絡共享點(我們正在使用UNC路徑)。此客戶的其他UNC路徑可以工作。本地路徑工作。我們所有其他客戶(10000+安裝)完全沒有問題。
客戶使用XP作爲客戶端操作系統,服務器運行的似乎是標準的Windows Server 2003(我認爲小型企業服務器版本)。我們無法使用相同的操作系統在我們的測試實驗室中複製它們的錯誤。他們可以用幾個XP客戶端重複這個問題,但問題只出現在一臺服務器上(其他Server 2003服務器沒有出現問題)。
我們通過嵌套兩個CreateFile調用來解決這個問題,第一個調用OPEN_EXISTING,第二個調用CREATE_ALWAYS如果OPEN_EXISTING失敗。所以,我們沒有立即需要修復。
我的問題:有誰知道爲什麼這個API調用會以這種特殊方式失敗嗎?我們感到困惑。
附錄:
在上面的CreateFile函數是在Windows API函數的包裝。代碼如下:
bool CMemoryMapFile::CreateFile(HANDLE & hFile, LPCSTR szFile, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes)
{
hFile = ::CreateFile (szFile, dwDesiredAccess, dwShareMode, NULL,
dwCreationDisposition, dwFlagsAndAttributes, NULL);
return (hFile != INVALID_HANDLE_VALUE)
}
幾位用戶非常有幫助地指出,我們假設CreateFile在失敗時返回NULL句柄。我忘了(mea culpa)提到上面的例子中的CreateFile實際上是一個包裝函數。我將在上面的問題中添加包裝函數。包裝返回一個布爾值。 – 2009-06-05 18:28:06