Win 32 Writefile: доступ к Viloation и ошибка 1784

Две проблемы с кодом ниже. Для начала я искал на этом и других форумах ответы на мой код ошибки 1784 года, и все, что я пробовал, провалилось. Два потока, которые я проверял на stackoverflow: WriteFile возвращает ошибку 1784 а также Ошибка ввода-вывода BlockWrite 1784. Я проверил некоторые другие на этом форуме, но я не помню точно, что сейчас.

Я пытаюсь сохранить массив структур в пустой двоичный файл. Первая проблема заключается в том, что я получаю нарушение прав доступа, если моя переменная размера (параметр nNumberOfBytesToWrite) меньше 99000 байт. Это число прыгает вокруг. Некоторое время, когда я тестировал, было бы нарушение доступа, если бы оно было 99,999 байт, но не 100 000 байт. Конечно, в конечном итоге я хочу установить размер всего массива. Исходный код для обработки, который теперь закомментирован, так что я могу тестировать с различными размерами.

Второе, что происходит (если я не получаю нарушения прав доступа), это то, что я получаю код ошибки 1784 и каждый раз происходит сбой WriteFile. Как заявили другие потоки в этой теме, это определено в MSDN как ERROR_INVALID_USER_BUFFER, а описание: «Предоставленный пользовательский буфер недопустим для запрошенной операции». Я посмотрел на собственный пример MSDN для открытия файлов, как это (http://msdn.microsoft.com/en-us/library/windows/desktop/bb540534%28v=vs.85%29.aspx) и попробовал некоторые варианты, основанные на их коде, но, похоже, ничего не работает.

Эта проблема, вероятно, в значительной степени нуб, и я уверен, что я пропускаю что-то смехотворно простое, но если у кого-то есть предложения, они будут очень признательны.

case IDM_SAVE1:
{
HANDLE hFile = CreateFile("MineSave.mss", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
int test_buffer[] = {1,2,3,4,5,6,7,8,9,10};

if(hFile != INVALID_HANDLE_VALUE)
{
BOOL bSuccess;
DWORD size = 100000; //DWORD size = (((sizeof(tile)) * tiles_total));
LPDWORD bytes_written = 0;
bSuccess = WriteFile(hFile, test_buffer, size, bytes_written, NULL);
if(bSuccess)
{
MessageBox(hwnd, "File saved successfully.", "Great Job!", MB_OK);
}
else
{
DWORD error = GetLastError();
MessageBox(hwnd, "Could not write to file.", "Error", MB_OK);
}

CloseHandle(hFile);
}
else
{
MessageBox(hwnd, "Could not create file.", "Error", MB_OK);
}
}
break;

2

Решение

Ваш буфер имеет размер 10 дюймов, что составляет 40 байт в Windows. Вы пытаетесь записать 100 000 байтов из этого буфера. Это неопределенное поведение, переполнение буфера. Отсюда и нарушение прав доступа.

Вы не должны передавать значение больше sizeof(test_buffer)т.е. 40к nNumberOfBytesToWrite параметр WriteFile,

Вам нужно будет записать этот файл в цикле, записывая 40 байтов за раз, пока вы не напишите столько, сколько вам нужно. Возможно, что-то вроде этого:

BOOL bSuccess = TRUE;
DWORD bytesRemaining = 100000;
while (bSuccess && bytesRemaining>0)
{
DWORD bytesToWrite = std::min(sizeof(test_buffer), bytesRemaining);
DWORD bytesWritten;
bSuccess = WriteFile(hFile, test_buffer, bytesToWrite, &bytesWritten, NULL);
bytesRemaining -= bytesToWrite;
}
if (!bSuccess)
{
//handle error;
}

Запись 40 байтов за раз довольно медленная. Вы найдете более эффективным написать несколько килобайт при каждом вызове WriteFile,

Обратите внимание, что вы не можете пройти NULL к lpNumberOfBytesWritten параметр, если вы также передаете NULL в lpOverlapped, как вы делаете здесь. От документация:

lpNumberOfBytesWritten [опционально]

……

Этот параметр может быть NULL, только если параметр lpOverlapped не равен NULL.

7

Другие решения

Вы должен предоставить буфер для получения количества записанных байтов, либо lpNumberOfBytesWritten параметр должен быть ненулевым, или lpOverlapped Параметр должен быть ненулевым.

Вы передаете NULL для обоих, что является незаконным и вызывает нарушение прав доступа.

1

По вопросам рекламы [email protected]