Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Функция ReadFile

Ответить
Настройки темы
Функция ReadFile

Аватара для DillerInc

Обратный инженер


Сообщения: 644
Благодарности: 47

Профиль | Отправить PM | Цитировать


Здраствуйте!
Проблема заключается в том,что указанная функция походу возвращает False,и я не могу разобраться,почему так происходит.
Итак имеется следующая ситуация:
Код: Выделить весь код
var
 hExe : HWND = 0; 
{ Дескриптор получен с помощью CreateFileA с установкой флага GENERIC_READ и без каких-либо FILE_FLAG_NO_BUFFERING }
 MemPtr : Pointer = NIL;
{ Указатель получен с помощью VirtualAlloc }
 FileSize : DWORD;
{ Этот параметр получен от GetFileSize(hExe, NIL) }
 BytesRead : DWORD;
begin
 ReadFile(hExe, MemPtr, FileSize, BytesRead, NIL);
...
В итоге,как я уже говорил,функция возвращает False, по указателю MemPtr не наблюдается никаких считанных данных и переменная BytesRead не содержит кол-ва этих считанных байт.
Собственно,господа,какие будут соображения замечания по данному поводу ?

-------
То,что неясно,следует выяснить.То,что трудно творить,следует делать с великой настойчивостью. © Конфуций


Отправлено: 01:01, 17-07-2005

 

Аватара для Savant

Старожил


Сообщения: 300
Благодарности: 6

Профиль | Сайт | Отправить PM | Цитировать


А мона кода побольше? Вот эти самые CreateFile() (без А), VirtualAlloc()... Кстати, что возвращает GetLastError() после ReadFile()? hEXE на всякий сделай типа HANDLE.

Отправлено: 01:09, 17-07-2005 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Аватара для DillerInc

Обратный инженер


Сообщения: 644
Благодарности: 47

Профиль | Отправить PM | Цитировать


Savant
Цитата:
А мона кода побольше?
Код: Выделить весь код
CreateFile(OpenDlgBox.lpstrFile, GENERIC_READ, 0, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
...кстати,почему без "А" - меняется ли от этого что-нибудь?
Код: Выделить весь код
VirtualAlloc(NIL, MemSize, MEM_COMMIT, PAGE_READWRITE);
Параметр MemSize типа DWORD получен какими-то непонятными ухищрениями от значания параметра FileSize:
Код: Выделить весь код
asm
 mov eax, [FileSize]     // Этот 
 add eax, 00010000   // код
 and eax, 3FFF0000 //   не я придумал =]
 mov [MemSize], eax
end;
GetLastError в следующей конструкции:
Код: Выделить весь код
if ReadFile(тра-ля-ля) = False then
 GetLastError;
...вроде бы возвращает значение 03Е6h = 998 = ERROR_NOACCESS (смотрел в отладчике), что возможно означает,что проблема в функции VirtualAlloc.
Цитата:
hEXE на всякий сделай типа HANDLE
...дык, Delphi начинает орать,что не знает такого идентификатора...

-------
То,что неясно,следует выяснить.То,что трудно творить,следует делать с великой настойчивостью. © Конфуций


Отправлено: 02:04, 17-07-2005 | #3

lehha


Сообщения: n/a

Профиль | Цитировать


DillerInc
Цитата:
...кстати,почему без "А" - меняется ли от этого что-нибудь?
Все системы семейства вындос начиная с в2к работают только с уникодом, точнее они работают и с анси строками но с начала они их переведут в уникод сделают нужное преоброзование а затем результат вернут в анси, так что А это для работы с анси а W с уникодом -> с юникодом программа будет быстрее работать
Есть 2 функции CreateFile - это CreateFileA и CreateFileW разница между ними что А работает с анси кодировкой а W с уникодом, когда ты просто пишешь CreateFile компилятор сам определит с чем ты работаешь, вот кусок определеня критфайл из winbase.h
Код: Выделить весь код
WINBASEAPI  HANDLE  WINAPI  CreateFileA(IN LPCSTR lpFileName, 
 IN DWORD dwDesiredAccess, 
 IN DWORD dwShareMode,
 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,
 IN DWORD dwCreationDisposition,
 IN DWORD dwFlagsAndAttributes,
 IN HANDLE hTemplateFile      );
 WINBASEAPI  HANDLE  WINAPI  CreateFileW(IN LPCWSTR lpFileName,
 IN DWORD dwDesiredAccess,      
 IN DWORD dwShareMode,     
 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes,     
 IN DWORD dwCreationDisposition,     
 IN DWORD dwFlagsAndAttributes,     
 IN HANDLE hTemplateFile      );
 #ifdef UNICODE
 #define CreateFile  CreateFileW
 #else
 #define CreateFile  CreateFileA
 #endif // !UNICODE
Такая схема у всех функций которые работают с файлами и со строками.


Отправлено: 14:18, 17-07-2005 | #4

lehha


Сообщения: n/a

Профиль | Цитировать


DillerInc
а файл вообще открылся???

Отправлено: 14:19, 17-07-2005 | #5


Аватара для DillerInc

Обратный инженер


Сообщения: 644
Благодарности: 47

Профиль | Отправить PM | Цитировать


lehha
Цитата:
CreateFile - это CreateFileA и CreateFileW
...значит выгоднее работать с функцией CreateFile ?
Цитата:
а файл вообще открылся???
...да,дескриптор файла возвратился нормальный,на его основе также нормально отработала функция GetFileSize,вернув размер открытого файла в байтах.

Мне кажется,что косяк кроется в работе функции VirtualAlloc,которая,если я правильно понял,должна инициализировать резервируемое пространство нулями.В моём случае,значение возвращаемое ею выглядит в отладчике как:
EAX=01490000
...если же посмотреть,что находится по этому смещению,то наблюдаешь одни знаки вопроса вместо нулей...разве так должно быть ?

Сейчас отлаживал в режиме ручной трассировки - наблюдал следующее:
Код: Выделить весь код
;Значит зайдя внутрь функции ReadFile 
;и очутившись в библиотеке Kernel32...
...
; в стек заносятся необходимые параметры и далее...
call [_imp_NtReadFile]
cmp eax, 00000103 ; а в EAX значение C0000005
jnz ...                   ; тут мы естественно прыгаем к чертям
Вот так вот,в EAX находится "любимое" значение C0000005 - STATUS_ACCESS_VIOLATION .
Как же быть тогда с этой VirtualAlloc - ведь получается,из-за неё тогда выходит такой бедлам ?

-------
То,что неясно,следует выяснить.То,что трудно творить,следует делать с великой настойчивостью. © Конфуций


Последний раз редактировалось DillerInc, 17-07-2005 в 17:20. Причина: Добавлено информации


Отправлено: 16:43, 17-07-2005 | #6


Аватара для Savant

Старожил


Сообщения: 300
Благодарности: 6

Профиль | Сайт | Отправить PM | Цитировать


DillerInc
Хех, как все просто...... А сначала вообще в ступор я впал Даже весь код написать пришлось.
Код: Выделить весь код
program rf;

{$APPTYPE CONSOLE}

uses
  Windows;

var
 hExe: Cardinal = 0;
 MemPtr: Pointer = nil;
 FileSize, BytesRead, MemSize: Cardinal;

begin
  hExe := CreateFile('c:\temp\test.txt', GENERIC_READ, 0, NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if hExe = INVALID_HANDLE_VALUE then WriteLn('CreateFile failed with code: ', GetLastError()) else WriteLn('CreateFile succeeded');
  FileSize := GetFileSize(hExe, nil);
  if FileSize = INVALID_FILE_SIZE then WriteLn('GetSize failed with code: ', GetLastError()) else WriteLn('GetSize succeeded, FileSize = ', FileSize);
  asm
    mov eax, [FileSize]  // FileSize -> eax
    add eax, $00010000   // +65536
    and eax, $3FFF0000   // выравнивание + ограничение по размеру
    mov [MemSize], eax   // eax -> MemSize
  end;
  MemPtr := VirtualAlloc(nil, MemSize, MEM_COMMIT, PAGE_READWRITE);
  if MemPtr = nil then WriteLn('VA failed with code: ', GetLastError()) else WriteLn('VA succeeded');
  if not ReadFile(hExe, MemPtr^, FileSize, BytesRead, NIL) then
    WriteLn('RF failed with code: ', GetLastError(), '. FileSize = ', FileSize, ', BytesRead = ', BytesRead, '.')
  else
    WriteLn('RF succeeded. FileSize = ', FileSize, ', BytesRead = ', BytesRead, '.');
  ReadLn;
  VirtualFree(MemPtr, 0, MEM_RELEASE);
  CloseHandle(hExe);
end.
Видно, что изменилось?

Отправлено: 23:16, 17-07-2005 | #7


Аватара для DillerInc

Обратный инженер


Сообщения: 644
Благодарности: 47

Профиль | Отправить PM | Цитировать


Savant
Цитата:
Видно, что изменилось?
...кто бы мог подумать,что одна перевёрнутая галка,разыменовывающая указатель,может спасти "гиганта мысли"...
Ну,это называется - что я буду без тебя делать в своих инфотехнологических поползновениях .

Кстати,вот всё-таки хотелось бы подробнее узнать,чего мы добиваемся с помощью описанной ассемблерной вставки,в чём её суть ?

-------
То,что неясно,следует выяснить.То,что трудно творить,следует делать с великой настойчивостью. © Конфуций


Последний раз редактировалось DillerInc, 18-07-2005 в 01:28. Причина: Чуть подрихтовал ответ =]


Отправлено: 23:57, 17-07-2005 | #8


Аватара для Savant

Старожил


Сообщения: 300
Благодарности: 6

Профиль | Сайт | Отправить PM | Цитировать


DillerInc
>>Кстати,вот всё-таки хотелось бы подробнее узнать,чего мы добиваемся с помощью описанной ассемблерной вставки,в чём её суть ?
Ну если я правильно понимаю, то:
Код: Выделить весь код
  asm
// кладем значение FileSize в регистр eax процессора
    mov eax, [FileSize]  
// добавляем к значению FileSize (которое в регистре) число 10000h (65536)
    add eax, $00010000   
// выравниваем это значение на границу 10000h (т.е. делаем число кратным 10000h)
// и ограничиваем размерчик загребаемой памяти числом 3FFF0000h (1073676288 байт ~ 1 Гб)
    and eax, $3FFF0000
// кладем полученное значение в MemSize   
    mov [MemSize], eax   
  end;

Отправлено: 07:45, 18-07-2005 | #9



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » Функция ReadFile

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Функция - SLI !!! Ironhammer Видеокарты 2 22-09-2008 05:32
Функция ClearType destrier Microsoft Windows 2000/XP 2 18-11-2006 21:11
функция в Visual C++ Listo Программирование и базы данных 2 04-05-2006 20:50
Массив и функция Scorpion666 Вебмастеру 4 02-03-2006 12:44
Функция Re-Author XPurple Видео и аудио: обработка и кодирование 1 27-04-2005 12:35




 
Переход