Такой код раньше у меня работал, Код (Text): nvoke CreateFile, addr szFileName, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL cmp eax, -1 jz _error mov hFile, eax invoke GetFileSize, hFile, NULL mov dwSize, eax invoke GlobalAlloc, GMEM_MOVEABLE or GMEM_ZEROINIT, dwSize mov ebx, eax mov hMemory, eax invoke GlobalLock, hMemory mov pMemory, eax invoke ReadFile, hFile, pMemory, dwSize, NULL, NULL После захода в ReadFile вываливается здесь Код (Text): 7C80188E 8901 mov dword ptr ds:[ecx], eax 7C801890 33C0 xor eax, eax 7C801892 40 inc eax 7C801893 E8 730C0000 call 7C80250B ; kernel32.7C80250B 7C801898 C2 1400 retn 14 eax=000000F2 ds:[00000000]=??? Подскажите в чем проблема?
Параметр ReadFile, определяющий адрес переменной, получающей количество прочитанных байт, опционален только если есть overlapped-параметр. (Параметр: последний-предпоследний). Можно предположить, что такой код мог работать на win95.
Нужно было LPDWORD lpNumberOfBytesRead указать Код (Text): invoke ReadFile, hFile, pMemory, dwSize, addr lpbr ,NULL Всем спасибо!
Еще один вопрос: Парсер ищет конец строки равен он CLRF(0Ah и 0Dh), но как быть с концом текстового файла, у него тоже есть CLRF, но вот после этих байтов идет мусор, посмотрел в отладчике Код (Text): 00142EEB 0D 0A EE ..о 00142EFB FE EE FE EE FE EE FE EE FE EE FE EE FE 00 00 00 юоюоюоюоюоюою... (0D 0A - '..') - это CLRF, затем EEh и другой мусор, конечно можно было бы, для конкретного текстового файла искать EEh и FEh и что там еще, но может они не постоянны и будут другими для другого текстового файла, вот в чем проблема.
JCronos Это мусор не из файла, а из выделенного блока кучи. Причем 0xFEEE это специальная сигнатура, которой заполняются свободные блоки кучи в режиме отладки (хвосты занятых ,блоков заполняются ABAB-ой , т.е. у тебя похоже либо память не выделена, либо при чтении произошло переполнение - вылет за пределы выделенного блока. А по правильному, нужно выделять память на 1 байт больше размера файла - для записи замыкающего нуля, и либо занулять весь блок при выделении, либо после чтения данных в буфер установить замыкающий ноль ручками по адресу (lpMemory+dwSize). PS: В файле замык.ноль не хранится
leo Почему? Сколько выделил, столько и записал из файла. 0D 0E — последние символы файла, а дальше уже кусок невыделенной памяти.
l_inc Как говориться "учите матчасть" Во-первых, в виндовой куче любой блок памяти (и занятый и свободный) имеет свой 8-байтовый заголовок и размер блока также кратен 8 байтам. В первых 4 байтах заголовка хранятся размеры текущего и предыдущего блоков памяти в 8-байтовых единицах, причем макс.размер блока кучи (специально) ограничен значением < 0xFEEE*8 и поэтому первые 4 байта заголовка не могут быть равны 0xFEEEFEEE. Во-вторых, в режиме отладки для контроля целостности кучи под занятый блок выделяется памяти на 8 байт больше и хвостовые байты в блоке заполняются контрольной сигнатурой 0xABAB. Соот-но свободные блоки также имеют 8-байтовый заголовок и заполнены сигнатурой 0xFEEE. В-третьих, менеджер кучи запрашивает память у винды обычным VirtualAlloc-ом и соотв-но текущий размер памяти кучи всегда кратен 4К. Поэтому вслед за выделенным блоком всегда должен идти либо сводный или занятый блок со своим заголовком (не содержащим 0xFEEE), либо невыделенная память, если этот занятый блок "каким-то чудом" точно вписался в конец последней выделенной страницы. Вывод: Если бы памяти было бы выделено ровно столько, сколько в нее записано данных, то вслед за замыкающими байтами 0D 0A должна была идти сигнатура 0xABAB и затем заголовок следующего блока (не содержащий 0xFEEE). Поэтому ситуация, приведенная в #6, возможна только в двух случаях: 1) Под блок было выделено памяти как минимум на 16 байт больше, чем реально в него записано. Поэтому 0xFEEE это мусор, оставшийся от ранее свободного блока, а хвостовая сигнатура 0xABAB и заголовок следующего блока идут где-то дальше 2) При записи данных произошло переполнение и вылет на середину следующего блока