Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

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


Страницы:   1 2

Vorobyev Sergey ©   (2003-07-02 14:19:00) 

Привет всем!

ВОПРОС: Можно ли как-нибудь определить версию файла (аналогично функции API GetFileVersionInfo) для образа файла, который находится в памяти, НЕ ЗАПИСЫВАЯ ЕГО НА ДИСК (даже во временную папку)..?

ПОЯСНЕНИЕ: Дело в том, что исполнимый файл, версию которого необходимо определить, находится в ресурсах другой программы. Файл извлекается в память, необходимо определить его версию и в зависимости от этого он записывается на диск (или нет) и исполняется..
--
Спасибо


Vorobyev Sergey   (2003-07-03 08:49:00) [21]

> AlexRush
Пытаюсь разобраться.. Честно говоря для меня это немного сложно, но пытаюсь..
Если бегло, то это возможно как раз то, что мне нужно..
Попробовал в Delphi6, вот так с ходу не откомпилилось..
Описания для PIMAGE_DOS_HEADER и т.п. взял из "Delphi\Demos\ResXplor\rxtypes.pas"
Пока такие вопросы:
1. Что за функция mkptr?
2. Какие юниты еще надо подключать?


AlexRush   (2003-07-02 19:37:00) [22]

Тестировал так:
ResourceExtractToFile(MapPEfromResource("#101","DIGITHEX"),
"#101","DIGITHEX",PathName);
Чуть не забыл :)

//function MapPEfromResource(resName,resType:string):DWORD;
// ПОЛУЧАЕТ Имя и Тип ресурса,который содержит PE-файл.
// ( выделяет сама!)

Тестировал так:
ResourceExtractToFile(MapPEfromResource("#101","DIGITHEX"),
"#101","DIGITHEX",PathName);
Чуть не забыл :)

//function MapPEfromResource(resName,resType:string):DWORD;
// ПОЛУЧАЕТ Имя и Тип ресурса,который содержит PE-файл.
// Грузит PE - в память (выделяет сама!) согласно с таблицей секций
// ВОЗВРАЩАЕТ хендл модуля, который можно использовать
// в функциях работы С РЕСУРСАМИ.



AlexRush   (2003-07-02 19:34:00) [23]

Аж самому интересно стало.
Написал процедурку. Работает, проверял.



function MapPEfromResource(resName,resType:string):DWORD;
var hFile,hRes,hResData:DWORD;
ptrResLock :pointer;
ptrMZ :PIMAGE_DOS_HEADER;
ptrPE :PIMAGE_NT_HEADERS;
ptrSH :PIMAGE_SECTION_HEADER;
hMappedPE :PIMAGE_DOS_HEADER;
dw :DWORD;
i :integer;
p:pointer;
begin
result:=0;
// Ищем ресурс, содержащий ПЕ
hRes:=FindResourceA(hInstance,PChar(resName),PChar(resType));
if (hRes=0)
then begin
result:=1;// внутренний код ошибки
exit;
end;
// Загружаем оный
hResData:=LoadResource(hInstance,hRes);
if (hResData=0)
then begin
result:=2;
exit;
end;
// получаем указатель на его данные
ptrResLock:=nil;
ptrResLock:=LockResource(hResData);

// для наглядности ptrMZ - указатель на DOS заголовок
ptrMZ:=ptrResLock;
// ptrPE - указатель на PE заголовок
ptrPE:=mkptr(ptrMZ,ptrMZ^._lfanew);
// проверка сигнатуры ПЕ
if ptrPE^.Signature<>IMAGE_NT_SIGNATURE
then exit;

// ptrSH - указатель на таблицу секций
ptrSH:=mkptr(ptrPE,sizeof(ptrPE^));
// здесь считаем необходимый размер памяти под загрузку ПЕ
dw:=0;
for i:=0 to ptrPE^.FileHeader.NumberOfSections-1
do begin
if (ptrSH^.VirtualAddress+ptrSH^.SizeOfRawData)>dw
then dw:=ptrSH^.VirtualAddress+ptrSH^.SizeOfRawData;
inc(ptrSH);
end;
inc(dw,sizeof(IMAGE_DOS_HEADER)+sizeof(IMAGE_NT_HEADERS)+4096);

// и выделяем ее
hMappedPE:=HeapAlloc(GetProcessHeap(),0,dw);

// копируем DOS заголовок, Stub и PE заголовок
dw:=sizeof(ptrMZ^)+ptrMZ^._lfanew+sizeof(ptrPE^);
CopyMemory(hMappedPE,
ptrMZ,
dw);
ptrSH:=mkptr(ptrPE,sizeof(ptrPE^));

// копируем таблицк секций
CopyMemory(mkptr(hMappedPE,dw),
ptrSH,
ptrPE^.FileHeader.NumberOfSections*sizeof(ptrSH^));

// копируем секции согласно RVA
for i:=0 to ptrPE^.FileHeader.NumberOfSections-1
do begin
p:=mkptr(hMappedPE,ptrSH^.VirtualAddress);
CopyMemory(p,
mkptr(ptrMZ,ptrSH^.PointerToRawData),
ptrSH^.SizeOfRawData);
inc(ptrSH);
end;
// ВНИМАНИЕ !!!
// НЕ призводится развязка relocations"сов,
// Запускать (передавать управление нельзя !)

// рэзалт - хендл (он же указатель) загруженного модуля
result:=DWORD(hMappedPE);
end;


Ресурс в файл:


function ResourceExtractToFile(hInst:DWORD;resName,resType,FullFileName:string):DWORD;stdcall;
var hFile,dw_writed:DWORD;
hRes,hResData:DWORD;
ptrResLock:pointer;
begin
hRes:=FindResourceA(hInstance,PChar(resName),PChar(resType));
if (hRes=0)
then begin
result:=1;
exit;
end;
hResData:=LoadResource(hInstance,hRes);
if (hResData=0)
then begin
result:=2;
exit;
end;
ptrResLock:=nil;
ptrResLock:=LockResource(hResData);
if not Assigned(ptrResLock)
then begin
result:=3;
exit;
end;

//ptrResLock


hFile:= CreateFile("_testFile.exe",
GENERIC_WRITE,
FILE_SHARE_WRITE or FILE_SHARE_READ,
nil,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
if(hFile=INVALID_HANDLE_VALUE)
then begin
result:=4;
exit;
end;
dw_writed:=SizeofResource(hInstance,hRes);
if not LongBool(WriteFile(hFile,ptrResLock,dw_writed,@dw_writed,nil))
then begin
CloseHandle(hFile);
result:=5;
exit;
( hFile)

Аж самому интересно стало.
Написал процедурку. Работает, проверял.



function MapPEfromResource(resName,resType:string):DWORD;
var hFile,hRes,hResData:DWORD;
ptrResLock :pointer;
ptrMZ :PIMAGE_DOS_HEADER;
ptrPE :PIMAGE_NT_HEADERS;
ptrSH :PIMAGE_SECTION_HEADER;
hMappedPE :PIMAGE_DOS_HEADER;
dw :DWORD;
i :integer;
p:pointer;
begin
result:=0;
// Ищем ресурс, содержащий ПЕ
hRes:=FindResourceA(hInstance,PChar(resName),PChar(resType));
if (hRes=0)
then begin
result:=1;// внутренний код ошибки
exit;
end;
// Загружаем оный
hResData:=LoadResource(hInstance,hRes);
if (hResData=0)
then begin
result:=2;
exit;
end;
// получаем указатель на его данные
ptrResLock:=nil;
ptrResLock:=LockResource(hResData);

// для наглядности ptrMZ - указатель на DOS заголовок
ptrMZ:=ptrResLock;
// ptrPE - указатель на PE заголовок
ptrPE:=mkptr(ptrMZ,ptrMZ^._lfanew);
// проверка сигнатуры ПЕ
if ptrPE^.Signature<>IMAGE_NT_SIGNATURE
then exit;

// ptrSH - указатель на таблицу секций
ptrSH:=mkptr(ptrPE,sizeof(ptrPE^));
// здесь считаем необходимый размер памяти под загрузку ПЕ
dw:=0;
for i:=0 to ptrPE^.FileHeader.NumberOfSections-1
do begin
if (ptrSH^.VirtualAddress+ptrSH^.SizeOfRawData)>dw
then dw:=ptrSH^.VirtualAddress+ptrSH^.SizeOfRawData;
inc(ptrSH);
end;
inc(dw,sizeof(IMAGE_DOS_HEADER)+sizeof(IMAGE_NT_HEADERS)+4096);

// и выделяем ее
hMappedPE:=HeapAlloc(GetProcessHeap(),0,dw);

// копируем DOS заголовок, Stub и PE заголовок
dw:=sizeof(ptrMZ^)+ptrMZ^._lfanew+sizeof(ptrPE^);
CopyMemory(hMappedPE,
ptrMZ,
dw);
ptrSH:=mkptr(ptrPE,sizeof(ptrPE^));

// копируем таблицк секций
CopyMemory(mkptr(hMappedPE,dw),
ptrSH,
ptrPE^.FileHeader.NumberOfSections*sizeof(ptrSH^));

// копируем секции согласно RVA
for i:=0 to ptrPE^.FileHeader.NumberOfSections-1
do begin
p:=mkptr(hMappedPE,ptrSH^.VirtualAddress);
CopyMemory(p,
mkptr(ptrMZ,ptrSH^.PointerToRawData),
ptrSH^.SizeOfRawData);
inc(ptrSH);
end;
// ВНИМАНИЕ !!!
// НЕ призводится развязка relocations"сов,
// Запускать (передавать управление нельзя !)

// рэзалт - хендл (он же указатель) загруженного модуля
result:=DWORD(hMappedPE);
end;


Ресурс в файл:


function ResourceExtractToFile(hInst:DWORD;resName,resType,FullFileName:string):DWORD;stdcall;
var hFile,dw_writed:DWORD;
hRes,hResData:DWORD;
ptrResLock:pointer;
begin
hRes:=FindResourceA(hInstance,PChar(resName),PChar(resType));
if (hRes=0)
then begin
result:=1;
exit;
end;
hResData:=LoadResource(hInstance,hRes);
if (hResData=0)
then begin
result:=2;
exit;
end;
ptrResLock:=nil;
ptrResLock:=LockResource(hResData);
if not Assigned(ptrResLock)
then begin
result:=3;
exit;
end;

//ptrResLock


hFile:= CreateFile("_testFile.exe",
GENERIC_WRITE,
FILE_SHARE_WRITE or FILE_SHARE_READ,
nil,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
0);
if(hFile=INVALID_HANDLE_VALUE)
then begin
result:=4;
exit;
end;
dw_writed:=SizeofResource(hInstance,hRes);
if not LongBool(WriteFile(hFile,ptrResLock,dw_writed,@dw_writed,nil))
then begin
CloseHandle(hFile);
result:=5;
exit;
end;
CloseHandle(hFile);
result:=0;
end;


Игорь Шевченко   (2003-07-02 17:26:00) [24]

Можно. Чтением и обработкой ресурса типа RT_VERSION


Soft   (2003-07-02 16:15:00) [25]

The CreateFileMapping function creates a named or unnamed file-mapping object for the specified file.

HANDLE CreateFileMapping(

HANDLE hFile, // handle to file to map
LPSECURITY_ATTRIBUTES lpFileMappingAttributes, // optional security attributes
DWORD flProtect, // protection for mapping object
DWORD dwMaximumSizeHigh, // high-order 32 bits of object size
DWORD dwMaximumSizeLow, // low-order 32 bits of object size
LPCTSTR lpName // name of file-mapping object
);


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо