Нарушение доступа при вызове LockFileEx()

#c #windows #winapi #file-locking

#c #Windows #winapi #блокировка файла

Вопрос:

У меня есть класс сопоставления файлов, который позволяет мне также блокировать файл для исключительного использования моим процессом с помощью функции Win32 API LockFileEx() .

 bool FileMapping::lockFile(bool wait) {
    if (isFileLocked())
        return true;

    // We want an exclusive lock.
    DWORD flags = LOCKFILE_EXCLUSIVE_LOCK;

    // If we don't want the thread to block, we have to set the appropriate flag.
    if (!wait)
        flags |= LOCKFILE_FAIL_IMMEDIATELY;

    m_isFileLocked = LockFileEx(m_fileDesc, flags, 0, (DWORD) m_mappingLength, (DWORD) (((uint64_t) m_mappingLength) >> 32), NULL);
    return m_isFileLocked;
}
  

Всякий раз, когда я добираюсь до LockFileEx() вызова, я получаю нарушение доступа:

Необработанное исключение в 0x7466c2ec в tftpServer.exe : 0xC0000005:
местоположение чтения 0x00000008 с нарушением доступа.

Дескриптор файла m_fileDesc определенно является допустимым дескриптором (отображение файла в память с помощью этого дескриптора работает) и m_mappingLength представляет собой просто a size_t , содержащий длину отображаемой части файла в байтах.

У кого-нибудь есть идеи, как это исправить?

Комментарии:

1. Указатель this равен нулю. Вы вызываете этот метод для нулевого объекта сопоставления файлов.

Ответ №1:

Ваш последний аргумент NULL , в то время как он должен быть указателем на OVERLAPPED структуру. Ошибка о местоположении чтения 0x00000008, вероятно, соответствует документированному требованию о том, что:

Вы должны инициализировать элемент hEvent допустимым дескриптором или нулем.

Учитывая hEvent , что элемент появляется после двух указателей, при 32-разрядной компиляции он будет составлять 8 байт от начала структуры. So LockFileEx , вероятно, пытается прочитать участника hEvent и выходит из строя.

Комментарии:

1. Упс, я, должно быть, упустил это из виду. Теперь я создал ПЕРЕКРЫВАЮЩУЮСЯ структуру и передаю ее адрес в LockFileEx(), и это работает. Спасибо вам за вашу помощь.

2. Я только что был укушен той же оплошностью. В документах MSDN это должно быть выделено жирным шрифтом! 🙂

Ответ №2:

Цитирование документов, на которые вы ссылаетесь:

lpOverlapped [вход, выход]

Указатель на ПЕРЕКРЫВАЮЩУЮСЯ структуру, которую функция использует с запросом блокировки. Эта структура, которая требуется, содержит смещение файла в начале диапазона блокировки. Вы должны инициализировать элемент hEvent допустимым дескриптором или нулем.

Итак, ваш последний аргумент неверен.

Комментарии:

1. Упс, я, должно быть, упустил это из виду. Теперь я создал ПЕРЕКРЫВАЮЩУЮСЯ структуру и передаю ее адрес в LockFileEx(), и это работает. Спасибо за вашу помощь. Я знаю о проблеме с 5-м аргументом, если size_t он равен 32 битам. Вот почему я сначала привел его к uint64_t , поэтому у меня есть 64-битное значение для выполнения сдвига. Я знаю, что на 32-разрядной платформе этот параметр всегда должен быть равен нулю, но я хотел, чтобы он работал как на 32-разрядных, так и на 64-разрядных платформах, поэтому я выбрал приведение и сдвиг.