MSoft LdrpLoaderLock да только не создается а Enter и не перед созданием а в процессе иницыализацыи, фактически на резьюме и исходники для этого не нужны - PDB достаточно
ну это я и хотел сказать - просто сильно спешил и некогда было объяснять никогда не пользовался, потому и не посоветовал
Ещё один момент. Допустим библиотека создала поток. тот должен умереть только вместе с процессом. тут проблемма - как определить когда пора на покой? Ладно, если прога завершается вызовом ExitProcess - тогда библиотеке приходит сообщение DLL_PROCESS_DETACH. Другое дело, если прога завершается обычным ret. В этом случае управление переходит в kernel32 и вызывается ExitThread; библиотеке приходит сообщение DLL_THREAD_DETACH. Как тут быть? отлавливать сообщения DLL_THREAD_DETACH и каждый раз считать количество потоков?
Quark Если такой поток один - можно вызывая zwquerysysteminformation определить не один ли тред остался в текущем процессе. Если таких вот тредов насколько - то ваще никак. К счастью большинство прог юзает exitprocess
Мдя.. постоянно дёргать ZwQuerySystemInformation... А если прога постоянно создаёт/уничтожает потоки.. А в PEB количество потоков не считается? я смотрел - при создании потока ничего в PEB не меняется, да и дизассемблерный листинг CreateThread смотрел - тоже, вроде как обращений к глобальным переменным нет
Интересно, скокаж эта тема обсуждаться будет ? Перехватываеш KiUserApcDispatcher и никаких проблем с критическими секциями. Чтото последнее время на форуме какуюта х*ню обсождают!?.
KiUserApcDispatcher - обработчик Apc-вызовов. При создании в процессе потока(ZwCreateThread), когда он выйдет из спящего состояния(ZwResumeThread), он начнёт своё исполнение с функции KiUserApcDispatcher. В стеке структура APC_DISPATCHER. Если вызов по причине создания потока, то APC_DISPATCHER.ApcRoutine содержит адрес функции LdrInitializeThunk, которая сообщает загруженным модулям о создании потока(DLL_THREAD_ATTACH), загружает статически подключённые модули и др. Выполнение продолжается посредством ZwContinue(APC_DISPATCHER.Context.regEip=ZwCreateThread.StartAddress). Если поток создан через Kernel32.CreateRemoteThread, то APC_DISPATCHER.Context.regEip обычно указывает на процедуру(их две) в Kernel32.dll (NT:ETHREAD.StartAddress), которая помещает в стек первый SEH-фрейм, устанавливает ThreadQuerySetWin32StartAddress(NT:ETHREAD.Win32StartAddress) для потока, информирует csrss о создании потока CsrNewThread() и передаёт управление на адрес APC_DISPATCHER.Context.regEax=ZwCreateThread(InitialEip). KiUserApcDispatcher: lea edi,dword ptr [esp+10h] pop eax call eax ;ntdll.LdrInitializeThunk push 1 push edi call ZwContinue ;(WinXP, для Vista код немного другой).
Quark Если один поток остался - значит это твой, фсё, больше новых не будет Или ты и про свой поток толком не знаешь че он там создает ?
perdimonokl Хоть убейте, не пойму из-за чего гвалд затеяли? Зачем вообще нужно создавать поток в DllMain? Я в данном вопросе полностью на стороне AsmGuru62. Создай функцию, в которой будет создаваться поток(и). В ней же можешь создать событие (CreateEvent). И функцию, в которой будешь убивать потоки в случае срабатывания события. Если же родительское приложение закроется, то независимо от того, есть у тебя рабочие потоки или их нет, библиотека будет выгружена осью насильно. А функция деинициализации потоков, позволит убивать потоки более корректно и тогда, когда это нужно твоей программе и тебе лично.