![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблемы с CreateFileMapping и MapViewOfFile [D7, Win95/98, Win2k, WinXP]
pmm © (2005-01-24 08:34:00)Ставлю хук в длл. Прога на всех платформах выдает ошибку типа "память не может быть рид" и проч. Сначала, правда работает 1-2 минуты. Делал по примеру из инета, пример также глючит. Почему так? А нельзя ли другой способ сделать - обратится к общей ячеи памяти разными экземплярами дллек.
И глучит на 98 на 2000 на ХП.
pmm (2005-01-26 13:31:00) [1]
> тему "calling conventions" в станд.справке изучал ?
почитал, написано мало, и основных принципов при работе с АПИфункцими я там так и не нашел
> ой не верю.
сам возьми, проверь. лист программы приводиться, заодно и stdcall проставь где нужно.
Такое глубокое системное программирование - не мой профиль, и в каком порядке передаются параметры в процедуру, мне честно говоря все равно; поэтому то я сюда и обратился, а нужно то было только отследить бездействие пользователя за компом. а досПриложений у нас на предприятии давно нет
Digitman (2005-01-26 12:33:00) [2]
> забыл немного
"Так не бывает - тут помню, а тут не помню" (с)
это как ? чуть-чуть беременный что ли ?)
> что-то не могу нигде полноценную статью найти
тему "calling conventions" в станд.справке изучал ?
> Гонял и с консолью, все норамльно работает
ой не верю.
а кроме консолей, заметь, есть еще и ntvdm-процессы, эмулирующие ДОС-среду для ДОС-задач.. какие нафих в ДОС GetMessage или PeekMessage ?
ты не в ту степпь подался ... если уж решать задачу с пом.хук-механизма, то ставить нужно хуки WH_LL_KEYBOARD и WH_LL_MOUSE
pmm (2005-01-26 12:24:00) [3]Только не везде нужно было убрать stdcall. Всё же наверное следует разобраться что есть stdcall и вообще соглашения о вызовах.
Да, с stdcall у меня большие пробелы, что-то не могу нигде полноценную статью найти, может подкинет кто ссылку грамотную :-), как бы разобраться. А подключал через LoadLibrary/GetProcAddress так просто, а про Free.. забыл немного. (Совсем Без stdcall 98ой падает напроч.).
> и что будет делать "добрый ppm", если фокусом в течение
> длит.времени обладает некое консольное приложение, не вызывающее
> ни GetMessage ни PeekMessage ?
Гонял и с консолью, все норамльно работает.
Digitman (2005-01-26 08:38:00) [4]
> pmm © (24.01.05 20:42) [17]
> злым (Digitman)
"злой Digitman" иногда справку стандартную почитывает, знаешь ли.
а "добрый ppm" не удосуживается.
а в справке той написано :
The WH_MOUSE hook enables you to monitor mouse messages about to be returned by the GetMessageor PeekMessagefunction
и что будет делать "добрый ppm", если фокусом в течение длит.времени обладает некое консольное приложение, не вызывающее ни GetMessage ни PeekMessage ?
GuAV (2005-01-25 23:44:00) [5]
> Ну вощем я тут переделал, типа думаю, что правильно
> исправил :-/
Да. SysHook должен быть общим для всех экземпляров dll.
Только не везде нужно было убрать stdcall. Всё же наверное следует разобраться что есть stdcall и вообще соглашения о вызовах.
Смысла перехода от импорта к LoadLibrary/GetProcAddress не вижу, однако если уже LoadLibrary неплохо бы и проверить результат. Также следует вызывать FreeLibrary.
pmm (2005-01-25 11:09:00) [6]Соглаасен, что так.
Я большой новичок в этом деле, плохо еще соображаю.
Почему приходится использовать MMF для Znach ?
А как мне сохранять Тик от разных экземляров DLL??? чтоб его потом мой ехе смог взять?
Ну вощем я тут переделал, типа думаю, что правильно исправил :-/
library hookdll;
uses
Windows, Messages, SysUtils, Classes;
{$R *.res}
type
PGlobalDLLData = ^TGlobalDLLData;
TGlobalDLLData = packed record
SysHook : HWND;
Znach : DWord;
end;
const
MMFName: PChar = 'KeyMMFDrozd';
var
GlobalData : PGlobalDLLData;
MMFHandle : THandle;
//-------------------------------------------------------------------------
function hookm(c0de, wParam, lParam : integer): Lresult;
begin
If c0de >= 0 Then
Begin
GlobalData^.Znach := GetTickCount();
End;
result := CallNextHookEx(GlobalData^.SysHook, c0de, wParam, lParam);
end;
//-------------------------------------------------------------------------
function ShowMeTick:DWord; export;
begin
result := GlobalData^.Znach;
end;
//-------------------------------------------------------------------------
procedure SetHook; export;
begin
GlobalData^.SysHook := SetWindowsHookEx(WH_MOUSE, @hookm, hInstance, 0);
if GlobalData^.SysHook = 0 then
messagebox(0,'Error SetWindowsHookEx WH_MOUSE','ERROR',mb_iconhand);
end;
//-------------------------------------------------------------------------
procedure RemoveHook; export;
begin
UnhookWindowsHookEx(GlobalData^.SysHook);
end;
//--------------------------------------------------------------------------
procedure OpenGlobalData();
begin
MMFHandle:= CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, SizeOf(PGlobalDLLData), MMFName);
if MMFHandle = 0 then
begin
MessageBox(0, 'Can''t create FileMapping', 'from dll', 0);
Exit;
end;
GlobalData:= MapViewOfFile(MMFHandle, FILE_MAP_WRITE, 0, 0, SizeOf(PGlobalDLLData));
if GlobalData = nil then
begin
CloseHandle(MMFHandle);
MessageBox(0, 'Can''t make MapViewOfFile', 'from dll', 0);
Exit;
end;
end;
//-----------------------------------------------------------------------------
procedure CloseGlobalData();
begin
UnmapViewOfFile(GlobalData);
CloseHandle(MMFHandle);
end;
//-----------------------------------------------------------------------------
procedure DLLEntryPoint(dwReason: DWord);
begin
case dwReason of
DLL_PROCESS_ATTACH: OpenGlobalData;
DLL_PROCESS_DETACH: CloseGlobalData;
end;
end;
//*************************************
exports
SetHook name 'myhookset',
RemoveHook name 'myhookrem',
ShowMeTick name 'showmetick';
//*************************************
begin
DLLProc:= @DLLEntryPoint;
DLLEntryPoint(DLL_PROCESS_ATTACH);
GlobalData^.Znach := 0;
end.
EXE
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, DateUtils, ComCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
SetHook:procedure;
UnSetHook:procedure;
ShowMeTick:function:DWord;
fhand:Thandle;
implementation
{$R *.dfm}
//---------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
begin
@SetHook := nil;
@UnSetHook := nil;
@ShowMeTick := nil;
fhand := LoadLibrary('hookdll.dll');
@SetHook := GetProcAddress(fhand,'myhookset');
@UnSetHook := GetProcAddress(fhand,'myhookrem');
@ShowMeTick := GetProcAddress(fhand,'showmetick');
SetHook;
Timer1.Interval := 1000;
end;
//---------------------------------------------------
procedure TForm1.Button2Click(Sender: TObject);
begin
UnSetHook;
end;
//---------------------------------------------------
procedure TForm1.Timer1Timer(Sender: TObject);
var
Period: DWord;
begin
Period := (GetTickCount() - ShowMeTick);
Edit1.Text := IntToStr(Period);
end;
//---------------------------------------------------
end.
GuAV (2005-01-25 08:25:00) [7]pmm © (25.01.05 7:35) [19]
Это ещё не значит что ошибок нет.
хинт:
Почему приходится использовать MMF для Znach ?
Чему равен Hm для разных экземпляров библиотеки, если он не в GlobalData ?
В 9х надо передавать в CallNextHookEx именно Hm. Иначе могут быть проблемы, причём не с твоим хуком, а с другими.
И вот не-согласование:
в dll
> procedure sethook;export; stdcall;
в ехе
> procedure SetHook; External 'hookdll.dll' name
> 'myhookset';
работает только потому что параметров нет вообще.
pmm (2005-01-25 07:35:00) [8]Полдня гоняю уже, все путем работает, на всех платформах. :-)
GuAV (2005-01-24 21:51:00) [9]Надеюсь это тоже учтено
> Плюс есть ещё проблемы, с stdcall которые пока не
> сказываются на работу, но тем не менее следует
>разобраться и испавить.
>
> И ещё, в 9х могут быть проблемы с CallNextHookEx, т.к.
> там перый параметр CallNextHookEx не игнорируется.
pmm (2005-01-24 20:42:00) [10]Все теперь работает [16].
Спасибо люди добрые, и злым (Digitman) тоже спасибо.
GuAV (2005-01-24 17:23:00) [11]
>pmm ©
>я сомневаюсь что дело в нем.
> Я тоже ;-))
А я таки вижу проблему
> procedure DLLEntryPoint(dwReason: DWord); stdcall;
См справку по DLLProc. где там stdcall ?
Плюс есть ещё проблемы, с stdcall которые пока не сказываются на работу, но тем не менее следует разобраться и испавить.
И ещё, в 9х могут быть проблемы с CallNextHookEx, т.к. там перый параметр CallNextHookEx не игнорируется.
Eraser (2005-01-24 16:59:00) [12]pmm ©
я сомневаюсь что дело в нем.
Я тоже ;-))
pmm (2005-01-24 16:54:00) [13]Так, понятно, что ничего не понятно.
Мне то что делать? Я никогда не интересовался, что такое stdcall, но что то я сомневаюсь что дело в нем.
Eraser (2005-01-24 16:53:00) [14]BiN ©
Да.
BiN (2005-01-24 16:22:00) [15]Я имею ввиду, что функция обратного вызова обязана вызываться с соглашением о вызовах stdcall
Вероятно, имеется ввиду все-таки функция обратного вызова функции SetWindowsHookEx?
Eraser (2005-01-24 16:09:00) [16]BiN ©
Я имею ввиду, что функция обратного вызова обязана вызываться с соглашением о вызовах stdcall, а экспортируемые функции не обязаны, правда если их объявлять без stdcall их будет проблемотично использовать например из MSVC++.
BiN (2005-01-24 15:41:00) [17]Вообще stdcall должен быть только около функции обратного вызова, но по идеи что плохого, если и не только возле неё.
Ты хоть сам понял, что сказал?
Eraser (2005-01-24 15:02:00) [18]Вообще stdcall должен быть только около функции обратного вызова, но по идеи что плохого, если и не только возле неё.
Я одно время ко всем экспортируемым функциям приписывал stdcall (тоже содрал где-то ;-))- работало. Правда не знаю как насчёт hookdll...
Digitman (2005-01-24 14:25:00) [19]
> pmm © (24.01.05 13:44) [7]
по-моему рановато тебе хуками заниматься.
ты даже о соблюдении соглашений о вызовах, видимо, понятия не имеешь ... содрал где-то stdcall, влупил его в свой код где надо и где не надо, и сидишь-ждешь, что все само-собой заработает ...
pmm (2005-01-24 13:44:00) [20]2Eraser
Такой же абсолютно пример я и взял из инета, только он был с сообщениями и я его "упростил под себя". Так вот он ту же ошибку выдает, хотя примерчик этот опубликован на многих сайтах и примерно один и тот же, и автор утверждает что все работает круто. Я на всех платформах проверял и на нескольких компьютерах -- выдает ошибку.
А бездействие в ХР или 2к очень просто отследить, там функция АПИшная есть, а вот в 98 нет такой функции - нужно ловушкой.