![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Использование хука из сервиса [D6, WinXP]
Неопытный © (2004-01-19 04:46:00)При написаниии сервиса столкнулся с проблемой. Необходимо поставить хук типа WH_SHELL (что впрочем не важно). Функция, которая устанавливает хук возвращает true. Но хук не работает.
В DLL использую PostThreadMessage для отправки сообщений сервису.
У меня складывается впечатление, что процедура обработки хука не доходит до конца, хотя там и стоит только PostThreadMessage. Пытался перед ней ставить запись в файл какой-нибудь информации (например того-же дескриптора процесса). Но файл даже не создается, а если и создается, то пустой и его нельзя удалить, потому что он используется. То есть получается, что процедура обработки прерывается еще до закрытия файла. Это может происходить только при запуске сервиса, когда хук ставится и сразу же ловит запуск сервиса, который его и поставил (не пойму, почему). После этого похоже хук падает вообще.
Возможно в этой теме в конце как раз такой случай
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1069096480&n=5
Могу привести исходные тексты, если нужно.
NiaSoft (2004-01-20 20:49:00) [1]А у меня надо писать :)
Sting (2004-01-20 11:50:00) [2]> NiaSoft
Нет писать никуда ничего не надо.
Доступ на чтение подойдет.
> Digitman
Спасибо. Попробую.
Digitman (2004-01-20 08:24:00) [3]кстати, упомянутый бродкаст следует выполнить и сразу после SetWindowsHookEx(), иначе хук не будет сразу же внедрен в некоторые "висящие в трее" процессы а-ля Винамп... можешь убедиться в этом сам, выводя по таймеру список процессов, в которые был внедрен хук сразу после его установки ... как только мышка "поелозит" в зоне иконок трея (читай - система пошлет при этом Винампу соотв.оконное сообщение), ты сразу увидишь появление в списке процессов со внедренным хук-модулем процесс того же Винампа
Digitman (2004-01-20 08:18:00) [4]
> Sting (19.01.04 19:06) [14]
сразу после выполнения UnhookWindowsHookEx() (т.е. снятия глоб.хука в ходе завершения или остановки сервиса) выполни
SendMessage(HWND_BROADCAST, WM_NULL, 0, 0);
дело в том, что в трее у тебя наверняка висят разного рода Винампы и иже с ними ... вот в их адресном пр-ве уже после снятия хука и продолжают еще "висеть" экз-ры хук-библ-ки, в контексте которых объеуты глоб.доступа/синхронизации, как ты понимаешь, на этот момент еще не закрыты (оттого и <> 0)
выполнив бродкаст любого dummy-сообщения, ты "подстегнешь" эти оставшиеся процессы, и система выгрузит твою хук-библ-ку и из их АП ... разумеется, сервис должен иметь опцию взаимодействия с дисктопом
NiaSoft (2004-01-19 23:10:00) [5]А выше приведенные методы несколько не подойдут, если из из хуков нужно будет писать в расшаренную область памяти, ведь доступ только на чтение.
NiaSoft (2004-01-19 23:06:00) [6]Я тут попробовал следующую штуку, и как ни странно с первого раза заработало (такое случается достаточно редко :) )
SetSecurityInfo(hFileMappingObject, SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
Nil, Nil, Nil, Nil);
данный код вызывыется после создания мап-файла, и дает всем полные права на доступ к объекту.
ЗЫ: Конечно не так хорошо с по отношению к безопастности как хотелось бы, но работает :).
Sting (2004-01-19 19:06:00) [7]Вот я тут попробовал приведенный код. И все же не пойму. В первый раз он у меня сработал. А потом опять первый вызов функции OpenMutex выдвал не ноль. После перезагрузки компьютера опять все заработало. После рестарта службы история повторяется. Ведь даже в хэлпе написано, что после того как последний процесс, используюший мьютекс закрывается, то и мьютекс уничтожается. Почему этого не происходит у меня. Дллка выдь из памяти выгружается. И службы тоже нет.
Sting (2004-01-19 15:50:00) [8]Ладно. Попробую разобраться.
В любом случае спасибо большое.
Если что, уж тогда через реестр сделаю, хотя при этом DLL получается большая. Еще раз спасибо.
Digitman (2004-01-19 15:47:00) [9]ладно, не мучайся
поступи проще - используй мьютекс
function OpenGlobalData: Boolean;
begin
InitializeSecurityDescriptor(@SecAttr, SECURITY_DESCRIPTOR_REVISION);
WM_ETKAHOOK:= RegisterWindowMessage(HookMonMsg);
hMutex := OpenMutex(SYNCHRONIZE, False, MutexName);
if hMutex = 0 then
IsFirstInstance := True;
try
if IsFirstInstance then
begin
hMutex := CreateMutex(@SecAttr, False, MutexName);
Win32Check(hMutex <> 0);
end;
try
if IsFirstInstance then
begin
hMMF:= CreateFileMapping(INVALID_HANDLE_VALUE, @SecAttr, PAGE_READWRITE, 0, SizeOf(GlobalHookData^), MMFName);
Win32Check(hMMF <> 0);
try
GlobalHookData:= MapViewOfFile(hMMF, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(GlobalHookData^));
Win32Check(Assigned(GlobalHookData));
with GlobalHookData^ do
begin
hCallWndProc := 0;
hCallWndProcRet := 0;
hMonitor := 0;
end;
except
CloseHandle(hMMF);
hMMF := 0;
raise;
end;
end
else
begin
WaitForSingleObject(hMutex, INFINITE);
ReleaseMutex(hMutex);
hMMF:= OpenFileMapping(FILE_MAP_READ, False, MMFName);
Win32Check(hMMF <> 0);
try
GlobalHookData:= MapViewOfFile(hMMF, FILE_MAP_READ, 0, 0, SizeOf(GlobalHookData^));
Win32Check(Assigned(GlobalHookData));
except
CloseHandle(hMMF);
hMMF := 0;
raise;
end;
end;
except
CloseHandle(hMutex);
hMutex := 0;
raise;
end;
Result := True;
except
Result := False;
end;
end;
procedure CloseGlobalData;
begin
if Assigned(GlobalHookData) then
UnmapViewOfFile(GlobalHookData);
if hMMF <> 0 then
CloseHandle(hMMF);
if hMutex <> 0 then
CloseHandle(hMutex);
end;
SuperDee (2004-01-19 15:06:00) [10]Ты лол
Sting (2004-01-19 14:51:00) [11]Вот наваял код:
MapHandle1:=OpenFileMapping(FILE_MAP_READ, false, GlobMapID1);
if MapHandle1 = 0 then
begin
MapHandle1:=CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(TShareInf), GlobMapID1);
ShareInfo:=MapViewOfFile(MapHandle1, FILE_MAP_ALL_ACCESS, 0, 0, SizeOf(TShareInf));
end else
ShareInfo:=MapViewOfFile(MapHandle1, FILE_MAP_READ, 0, 0, SizeOf(TShareInf));
После первого вызова OpenFileMapping возвращает не ноль. Почему? Может я что-то с параметрами напутал.
Digitman (2004-01-19 14:01:00) [12]да
и, соответственно, последующий вызов MapViewOfFile() должен быть выполнен с теми же правами, что и предыдущий CreateFileMapping или OpenFileMapping, завершившийся успешно
Sting (2004-01-19 13:58:00) [13]То есть поставить такой код:
if OpenFileMapping(только чтение)=0 then CreateFileMapping(запись и чтение) ?
Digitman (2004-01-19 13:24:00) [14]можно и без выкрутасов с SE обойтись
достаточно просто попытаться сначала выполнить OpenFileMapping(только чтение)
если MMF-объект не существует еще, то это первый экз-р хук-DLL и следует тут же выполнить CreateFileMapping(запись и чтение)
Digitman (2004-01-19 13:00:00) [15]
> Sting
проблема - в SecurityAttributes при открытии MMF .. необходимо настроить SE должным образом
Sting (2004-01-19 12:57:00) [16]А ведь причина действительно кроется в использовании CreateFileMapping. Только что попробовал убрал ее и нужную переменную записал в реестр, все заработало. Конечно хотелось бы обойтись без дополнительных средств, типа реестра, но видимо тут поделать ничего нельзя.
Sting (2004-01-19 12:21:00) [17]Все это установлено. Interactive = true.
BiN (2004-01-19 10:06:00) [18]скорее всего не установлено взаимодейсвтие с рабочим столом, а точнее с пользовательской средой
Sting (2004-01-19 07:41:00) [19]Смотрел. Там есть пример на перехват клавиш. Он у меня прекрасно работает, но не в сервисе. А насчет сервисов я там ничего не видел.
VMcL (2004-01-19 06:53:00) [20]В FAQ смотрел? Там пример есть.