Форум: "WinAPI";
Текущий архив: 2004.04.04;
Скачать: [xml.tar.bz2];
ВнизИспользование хука из сервиса Найти похожие ветки
← →
Неопытный (2004-01-19 04:46) [0]При написаниии сервиса столкнулся с проблемой. Необходимо поставить хук типа WH_SHELL (что впрочем не важно). Функция, которая устанавливает хук возвращает true. Но хук не работает.
В DLL использую PostThreadMessage для отправки сообщений сервису.
У меня складывается впечатление, что процедура обработки хука не доходит до конца, хотя там и стоит только PostThreadMessage. Пытался перед ней ставить запись в файл какой-нибудь информации (например того-же дескриптора процесса). Но файл даже не создается, а если и создается, то пустой и его нельзя удалить, потому что он используется. То есть получается, что процедура обработки прерывается еще до закрытия файла. Это может происходить только при запуске сервиса, когда хук ставится и сразу же ловит запуск сервиса, который его и поставил (не пойму, почему). После этого похоже хук падает вообще.
Возможно в этой теме в конце как раз такой случай
http://delphimaster.net/view/4-1069096480/
Могу привести исходные тексты, если нужно.
← →
VMcL © (2004-01-19 06:53) [1]В FAQ смотрел? Там пример есть.
← →
Sting (2004-01-19 07:41) [2]Смотрел. Там есть пример на перехват клавиш. Он у меня прекрасно работает, но не в сервисе. А насчет сервисов я там ничего не видел.
← →
BiN © (2004-01-19 10:06) [3]скорее всего не установлено взаимодейсвтие с рабочим столом, а точнее с пользовательской средой
← →
Sting (2004-01-19 12:21) [4]Все это установлено. Interactive = true.
← →
Sting (2004-01-19 12:57) [5]А ведь причина действительно кроется в использовании CreateFileMapping. Только что попробовал убрал ее и нужную переменную записал в реестр, все заработало. Конечно хотелось бы обойтись без дополнительных средств, типа реестра, но видимо тут поделать ничего нельзя.
← →
Digitman © (2004-01-19 13:00) [6]
> Sting
проблема - в SecurityAttributes при открытии MMF .. необходимо настроить SE должным образом
← →
Digitman © (2004-01-19 13:24) [7]можно и без выкрутасов с SE обойтись
достаточно просто попытаться сначала выполнить OpenFileMapping(только чтение)
если MMF-объект не существует еще, то это первый экз-р хук-DLL и следует тут же выполнить CreateFileMapping(запись и чтение)
← →
Sting (2004-01-19 13:58) [8]То есть поставить такой код:
if OpenFileMapping(только чтение)=0 then CreateFileMapping(запись и чтение) ?
← →
Digitman © (2004-01-19 14:01) [9]да
и, соответственно, последующий вызов MapViewOfFile() должен быть выполнен с теми же правами, что и предыдущий CreateFileMapping или OpenFileMapping, завершившийся успешно
← →
Sting (2004-01-19 14:51) [10]Вот наваял код:
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 возвращает не ноль. Почему? Может я что-то с параметрами напутал.
← →
SuperDee (2004-01-19 15:06) [11]Ты лол
← →
Digitman © (2004-01-19 15:47) [12]ладно, не мучайся
поступи проще - используй мьютекс
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;
← →
Sting (2004-01-19 15:50) [13]Ладно. Попробую разобраться.
В любом случае спасибо большое.
Если что, уж тогда через реестр сделаю, хотя при этом DLL получается большая. Еще раз спасибо.
← →
Sting (2004-01-19 19:06) [14]Вот я тут попробовал приведенный код. И все же не пойму. В первый раз он у меня сработал. А потом опять первый вызов функции OpenMutex выдвал не ноль. После перезагрузки компьютера опять все заработало. После рестарта службы история повторяется. Ведь даже в хэлпе написано, что после того как последний процесс, используюший мьютекс закрывается, то и мьютекс уничтожается. Почему этого не происходит у меня. Дллка выдь из памяти выгружается. И службы тоже нет.
← →
NiaSoft (2004-01-19 23:06) [15]Я тут попробовал следующую штуку, и как ни странно с первого раза заработало (такое случается достаточно редко :) )
SetSecurityInfo(hFileMappingObject, SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
Nil, Nil, Nil, Nil);
данный код вызывыется после создания мап-файла, и дает всем полные права на доступ к объекту.
ЗЫ: Конечно не так хорошо с по отношению к безопастности как хотелось бы, но работает :).
← →
NiaSoft (2004-01-19 23:10) [16]А выше приведенные методы несколько не подойдут, если из из хуков нужно будет писать в расшаренную область памяти, ведь доступ только на чтение.
← →
Digitman © (2004-01-20 08:18) [17]
> Sting (19.01.04 19:06) [14]
сразу после выполнения UnhookWindowsHookEx() (т.е. снятия глоб.хука в ходе завершения или остановки сервиса) выполни
SendMessage(HWND_BROADCAST, WM_NULL, 0, 0);
дело в том, что в трее у тебя наверняка висят разного рода Винампы и иже с ними ... вот в их адресном пр-ве уже после снятия хука и продолжают еще "висеть" экз-ры хук-библ-ки, в контексте которых объеуты глоб.доступа/синхронизации, как ты понимаешь, на этот момент еще не закрыты (оттого и <> 0)
выполнив бродкаст любого dummy-сообщения, ты "подстегнешь" эти оставшиеся процессы, и система выгрузит твою хук-библ-ку и из их АП ... разумеется, сервис должен иметь опцию взаимодействия с дисктопом
← →
Digitman © (2004-01-20 08:24) [18]кстати, упомянутый бродкаст следует выполнить и сразу после SetWindowsHookEx(), иначе хук не будет сразу же внедрен в некоторые "висящие в трее" процессы а-ля Винамп... можешь убедиться в этом сам, выводя по таймеру список процессов, в которые был внедрен хук сразу после его установки ... как только мышка "поелозит" в зоне иконок трея (читай - система пошлет при этом Винампу соотв.оконное сообщение), ты сразу увидишь появление в списке процессов со внедренным хук-модулем процесс того же Винампа
← →
Sting (2004-01-20 11:50) [19]> NiaSoft
Нет писать никуда ничего не надо.
Доступ на чтение подойдет.
> Digitman
Спасибо. Попробую.
← →
NiaSoft (2004-01-20 20:49) [20]А у меня надо писать :)
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.04.04;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.032 c