У нас была строка кода
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)
}