Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

Безопасен ли вызов в DllMain такой функции   Найти похожие ветки 

 
Егорка   (2012-08-24 16:33) [0]

Доброго времени суток. Прочитал много страшного про вызовы из DllMain и так и не понял чего там можно, а чего нет.
Меня интересует только ниже приведенный код. При загрузке DLL нужно извлечь из нее ресурс.
Все вместе это выглядет примерно так так:


library MyLib;

uses
 Windows;

function ExtractResource(const ResName, FileName: string): Boolean;
var
 hNewFile, hResInfo, hResData: THandle;
 dwResSize, dwWritten: Cardinal;
 PRes: Pointer;
begin
 Result := False;
 hResInfo := FindResource(hInstance, CharUpper(PChar(ResName)), RT_RCDATA);
 if hResInfo = 0 then
   Exit;
 dwResSize := SizeOfResource(hInstance, hResInfo);
 hResData := LoadResource(hInstance, hResInfo);
 PRes := LockResource(hResData);
 if Assigned(PRes) then
 begin
   hNewFile := CreateFile(PChar(FileName), GENERIC_WRITE, 0, nil, CREATE_ALWAYS, 0, 0);
   if hNewFile <> INVALID_HANDLE_VALUE then
   begin
     if WriteFile(hNewFile, PRes^, dwResSize, dwWritten, nil) then
Result := dwWritten = dwResSize;
     CloseHandle(hNewFile);
   end;
 end;
end;

function GetLibDir: string;
var
 I: Integer;
 ModuleName: array[0..MAX_PATH] of Char;
begin
 Result := "";
 ZeroMemory(@ModuleName, SizeOf(ModuleName));
 if GetModuleFileName(hInstance, ModuleName, SizeOf(ModuleName)) > 0 then
 begin
   for I := High(ModuleName) downto Low(ModuleName) do
     if ModuleName[I] = "\" then
     begin
       Result := Copy(ModuleName, 0, Succ(I));
       Break;
     end;
 end;
end;

var
 FileName: string;

begin
 FileName := GetLibDir + "myfilename.ext";

 if GetFileAttributes(PChar(FileName)) = DWORD(-1) then
   if not ExtractResource("MyResName", FileName) then
     MessageBox(0, "Не удалось извлечь ресурс", nil, MB_ICONERROR);
end;


 
Егорка   (2012-08-24 16:34) [1]

Вобщем вопрос: можно так делать или нет?


 
Dimka Maslov ©   (2012-08-24 16:46) [2]

Делать можно, но не нужно.


 
bems ©   (2012-08-24 20:49) [3]

MessageBox нельзя, хоть обычно и работает


 
Сергей М. ©   (2012-08-24 22:06) [4]

в DllMain следует остерегаться манипуляций созданием тредов, равно как и иных ОС-объектов (например, образов DLL, впервые динамически загружаемых в АП пространство процесса), создание которых претендует на блокировку таблиц PEB и TEB.


 
Сергей М. ©   (2012-08-24 22:07) [5]


> MessageBox нельзя


Чтой-то вдруг ?


 
sniknik ©   (2012-08-24 22:44) [6]

> Чтой-то вдруг ?
из dll? сообщение с ожиданием нажатия... даже при ошибке, я бы не делал.


 
Rouse_ ©   (2012-08-25 00:31) [7]


> в DllMain следует остерегаться манипуляций созданием тредов,
>  равно как и иных ОС-объектов

Ненаказуемо © :)
А вот воспользоваться DisableThreadLibraryCalls() желательно.
Ну а TEB в динамике залочить - этож я даже не знаю как постараться нужно с учетом библиотеки . Ну точнее знаю, но стандартные компилеры не позволяют прописывать TLS-callback даже с учетом асм-вставок.


 
Rouse_ ©   (2012-08-25 00:36) [8]

Зы, чуть не забыл ответить авторы темы :)
Код нормальный, должен работать, только не привязывай данную бибилотеку статически. На  вызове user32 функций лоадер может терминировать процесс.


 
Егорка   (2012-08-25 00:59) [9]

Вызов MessageBox не критичен, я его привел для наглядности) Спасибо всем ответившим!


 
bems ©   (2012-08-25 13:32) [10]


> Чтой-то вдруг ?

потому что user32.dll еще может быть не инициализирована


> в DllMain следует остерегаться манипуляций созданием тредов

треды создавать можно, но нельзя ожидать любого события в коде выполнения треда (потому что фактическое выполнение начнется после выхода из DllMain)


 
Leonid Troyanovsky ©   (2012-08-25 13:57) [11]


> Егорка   (24.08.12 16:34) [1]

http://msdn.microsoft.com/en-us/windows/hardware/gg487379.aspx

--
Regards, LVT.


 
Сергей М. ©   (2012-08-27 09:33) [12]


> user32.dll еще может быть не инициализирована


Это еще надо умудриться загрузить свою либу раньше user32


 
bems ©   (2012-09-03 02:36) [13]

> Это еще надо умудриться загрузить свою либу раньше user32
в этой ситуации нет ничего невероятного. в msdn обещают только то, что будет доступна kernel32. Это подразумевает доступность ntdll
dllmain остальных модулей может быть еще не вызвана на момент вызова dllmain модуля который их использует


 
Дмитрий С ©   (2012-09-03 18:04) [14]

А разве загрузчик не выстроит порядок загрузки DLL на основе зависимостей?


 
Rouse_ ©   (2012-09-03 20:41) [15]


> Дмитрий С ©   (03.09.12 18:04) [14]
> А разве загрузчик не выстроит порядок загрузки DLL на основе
> зависимостей?

Если проект написан на дельфи, то шансов ошибки практически не существует.
Статические линкуемые библиотеки будут подгружены до передачи управления на OP. Правда я уже не помню по какому принципу идет подгрузка но в принципе, если имеешь желание навредить самому себе, то остаются еще TLS каллбэки, во время исполнения которых некоторые "особо продвинутые пакеры" умудряются искать API из еще не подгруженных модулей, не озабачиваясь о их подгрузке и полагаясь что тот-же shell32.dll или еще что-то из com* уже присутствует.


 
bems ©   (2012-09-03 23:04) [16]

> А разве загрузчик не выстроит порядок загрузки DLL на основе зависимостей?

Обычно выстраивает правильно, но гарантий никто не даёт. К тому же user-функции внутренне любят делать динамическую загрузку, которая всё ломает

длл на дельфи не удавалось использовать для загрузки из KnownDLLs, если дллка спользовала SysUtils. не помню точно, но кажется дело было в каком-то user-вызове в секции инициализации юнита


 
bems ©   (2012-09-04 00:42) [17]


> длл на дельфи не удавалось использовать для загрузки из KnownDLLs

AppInit конечно же



Страницы: 1 вся ветка

Текущий архив: 2013.03.22;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.312 c
15-1339000608
alexdn
2012-06-06 20:36
2013.03.22
Умер Рэй Брэдбери


15-1347955003
Kerk
2012-09-18 11:56
2013.03.22
Книжка "Выучи Delphi за 21 день" явно устарела.


15-1346171752
Baks
2012-08-28 20:35
2013.03.22
Маленький тест Delphi программиста для Yandex


15-1353443403
Юрий
2012-11-21 00:30
2013.03.22
С днем рождения ! 21 ноября 2012 среда


2-1342633944
Nilman
2012-07-18 21:52
2013.03.22
Фон StringGrid вне ячеек