Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > не работает хук на части компов


Автор: holmes 14.11.2008, 13:13
на моем компьютере (и еще на многих) с хуком все в порядке
на некоторых компах отказывается работать ...
в чем теоретически может быть проблема?

Автор: dumb 14.11.2008, 13:16
http://forum.vingrad.ru/act-Help/CODE-01/HID-17.html

Автор: Alexeis 14.11.2008, 13:40
Цитата(holmes @  14.11.2008,  12:13 Найти цитируемый пост)
на некоторых компах отказывается работать ...
в чем теоретически может быть проблема? 

  Ну я делах хуков не спец, но слышал что при исполнении под WOW64 т.е. х64 в режиме Win32 хуки не работают.

Автор: CodeMonkey 14.11.2008, 13:52
...Vista, права, кривой код и ещё 1000 и одна причина...

Автор: holmes 14.11.2008, 14:46
сама библа

Код

library hooks;

uses Windows, Messages, ShellAPI, fmapu in 'fmapu.pas';

const
  LIB_VERSION = 3;
  CLASS_TrayProc = 'Shell_TrayWnd';
//------------------------------------------------------------------------------
function SysErrorMessage(ErrorCode: Integer): string;
var
  Buffer: array[0..255] of Char;
  Len: Integer;
begin
  Len:= FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_ARGUMENT_ARRAY,
    nil, ErrorCode, 0, Buffer, SizeOf(Buffer), nil);
  while (Len > 0) and (Buffer[Len - 1] in [#0..#32, '.']) do Dec(Len);
  SetString(Result, Buffer, Len);
end;
//------------------------------------------------------------------------------
function HookProc(code: integer; wParam: WPARAM; lParam: LPARAM): integer; stdcall;
var
  pt: TSmallPoint;
begin
  result:= 0;
  if not assigned(fmap) then exit;

  if code < 0 then
    result:= CallNextHookEx(fmap^.hHook, code, wParam, lParam)
  else begin
    pt.x:= PMouseHookStruct(lParam)^.pt.x;
    pt.y:= PMouseHookStruct(lParam)^.pt.y;
    if assigned(fmap) then SendMessage(fmap^.hWnd, wm_user + wParam{wm_mousemsg}, PMouseHookStruct(lParam)^.hWnd, uint(pt));
    result:= CallNextHookEx(fmap^.hHook, code, wParam, lParam);
  end;
end;
//------------------------------------------------------------------------------
function KbHookProc(code: integer; wParam: WPARAM; lParam: LPARAM): integer; stdcall;
begin
  result:= 0;
  if not assigned(fmap) then exit;

  if code < 0 then
    result:= CallNextHookEx(fmap^.hKbHook, code, wParam, lParam)
  else begin
    SendMessage(fmap^.hWnd, wm_user + wm_keydown, wParam, lParam);
    result:= CallNextHookEx(fmap^.hKbHook, code, wParam, lParam);
  end;
end;
//------------------------------------------------------------------------------
function TrayHookProc(code: integer; wParam: WPARAM; lParam: LPARAM): integer; stdcall;
var
  pInfo: PCWPRETSTRUCT;
  pcds: PCOPYDATASTRUCT;
  nicData: PNOTIFYICONDATA;
  iTrayCmd: integer;
  bFound: boolean;
  i: uint;
begin
  result:= 0;
  if not assigned(fmap) then exit;

  if (code >= 0) and not fmap^.closing then
  begin

    pInfo:= PCWPRETSTRUCT(lParam);

    // Interested in copydata messages
    if pInfo^.message = WM_COPYDATA then
    begin
        // Make sure we have a valid handle on the Tray window
        if not boolean(fmap^.hTrayWin) or not IsWindow(fmap^.hTrayWin) then fmap^.hTrayWin:= FindWindow(CLASS_TrayProc, nil);

        // Make sure this message is from the Tray window
        if IsWindow(fmap^.hTrayWin) and (pInfo^.hwnd = fmap^.hTrayWin) then
        begin
            pcds:= PCOPYDATASTRUCT(pInfo^.lParam);

            if pcds^.dwData = 1 then    // if this data refers to a tray icon //
            begin
                // maintain a copy of the tray icon //
                iTrayCmd:= PInteger(uint(pcds.lpData) + 4)^;
          nicData:= PNotifyIconData(uint(pcds.lpData) + 8);

                if integer(nicData^.uID) = -1 then
          begin
            result:= CallNextHookEx(fmap^.hTrayHook, code, wParam, lParam);
            exit;
          end;

                if (iTrayCmd = NIM_ADD) or (iTrayCmd = NIM_MODIFY) then
                begin

                    bFound:= false;
            i:= 0;
                    while (i < fmap^.iNextFreePos) and (i < MAXSAVEDTRAYDATA) do
                    begin

                        if (fmap^.SavedTrayData[i].NicHolder.IconData.uID = nicData^.uID) and
                            (fmap^.SavedTrayData[i].NicHolder.IconData.Wnd = nicData^.Wnd) then
                        begin
                            CopyMemory(@fmap^.SavedTrayData[i].CopyData, pcds, sizeof(COPYDATASTRUCT));

                            if iTrayCmd = NIM_ADD then
                            begin
                  if IsWindow(nicData^.Wnd) and boolean(nicData^.uCallbackMessage) and boolean(nicData^.hIcon) then
                  begin
                    if integer(nicData^.cbSize) > sizeof(NOTIFYICONDATA) then
                                    CopyMemory(@fmap^.SavedTrayData[i].NicHolder.IconData, nicData, integer(nicData^.cbSize))
                    else CopyMemory(@fmap^.SavedTrayData[i].NicHolder.IconData, nicData, sizeof(NOTIFYICONDATA));
                  end;
                            end else  begin
                                if (boolean(nicData^.uFlags and NIF_ICON) and boolean(nicData^.hIcon)) or
                                    (not boolean(fmap^.SavedTrayData[i].NicHolder.IconData.hIcon) and boolean(nicData^.hIcon)) then
                                    fmap^.SavedTrayData[i].NicHolder.IconData.hIcon:= nicData^.hIcon;

                                if boolean(nicData^.uFlags and NIF_MESSAGE) or
                                    (not boolean(fmap^.SavedTrayData[i].NicHolder.IconData.uCallbackMessage) and boolean(nicData^.uCallbackMessage)) then
                                fmap^.SavedTrayData[i].NicHolder.IconData.uCallbackMessage:= nicData^.uCallbackMessage;

                                if boolean(nicData^.uFlags and NIF_TIP) or
                                    ((fmap^.SavedTrayData[i].NicHolder.IconData.szTip[0] = #0) and (nicData^.szTip[0] <> #0)) then
                                 CopyMemory(@fmap^.SavedTrayData[i].NicHolder.IconData.szTip[0], @nicData^.szTip[0], 64);

                                fmap^.SavedTrayData[i].NicHolder.IconData.uFlags:= nicData^.uFlags;
                            end;

                            bFound:= true;
                            break;
                        end;

              inc(i);
            end;

            // if not found then add icon data //
            if IsWindow(nicData^.Wnd) and boolean(nicData^.uCallbackMessage) and boolean(nicData^.hIcon) then
            begin
              i:= fmap^.iNextFreePos;
                      if not bFound and (i < MAXSAVEDTRAYDATA) then
              begin
                          CopyMemory(@fmap^.SavedTrayData[i].CopyData, pcds, sizeof(COPYDATASTRUCT));
                if integer(nicData^.cbSize) > sizeof(NOTIFYICONDATA) then
                            CopyMemory(@fmap^.SavedTrayData[i].NicHolder.IconData, nicData, integer(nicData^.cbSize))
                else CopyMemory(@fmap^.SavedTrayData[i].NicHolder.IconData, nicData, sizeof(NOTIFYICONDATA));
                          inc(fmap^.iNextFreePos);
                      end;
            end;

                end else if iTrayCmd = NIM_DELETE then
             begin

            i:= 0;
                    while (i < fmap^.iNextFreePos) and (i < MAXSAVEDTRAYDATA) do
                    begin
                        if (fmap^.SavedTrayData[i].NicHolder.IconData.uID = nicData^.uID) and
                            (fmap^.SavedTrayData[i].NicHolder.IconData.Wnd = nicData^.Wnd) then
                        begin
                            MoveMemory(@fmap^.SavedTrayData[i], @fmap^.SavedTrayData[i + 1], sizeof(_TrayItem) * (fmap^.iNextFreePos - i - 1) );
                            dec(fmap^.iNextFreePos);
                            break;
                        end;
              inc(i);
                    end;

                end;

                // Forward the message //
                if IsWindow(fmap^.hWnd) then SendMessage(fmap^.hWnd, WM_COPYDATA, 0, 0);
            end;
        end;

    end;

  end;

  result:= CallNextHookEx(fmap^.hTrayHook, code, wParam, lParam);
end;
//------------------------------------------------------------------------------
function SetHook(activate: bool): bool; stdcall;
begin
  result:= false;
  if not assigned(fmap) then exit;

  if activate then
  begin
    try fmap^.hHook:= SetWindowsHookEx(WH_Mouse, @HookProc, hInstance, 0);
    except messagebox(fmap^.hWnd, pchar(SysErrorMessage(GetLastError)), 'HookMouse', mb_iconerror);
    end;
    result:= fmap^.hHook <> 0;
  end else begin
    if fmap^.hHook <> 0 then
    begin
      try result:= UnhookWindowsHookEx(fmap^.hHook);
      except messagebox(fmap^.hWnd, pchar(SysErrorMessage(GetLastError)), 'UnHookMouse', mb_iconerror);
      end;
      if result then fmap^.hHook:= 0;
    end;
  end;
end;
//------------------------------------------------------------------------------
function SetKbHook(activate: bool): bool; stdcall;
begin
  result:= false;
  if not assigned(fmap) then exit;

  if activate then
  begin
    try fmap^.hKbHook:= SetWindowsHookEx(WH_Keyboard, @KbHookProc, hInstance, 0);
    except messagebox(fmap^.hWnd, pchar(SysErrorMessage(GetLastError)), 'HookKb', mb_iconerror);
    end;
    result:= fmap^.hKbHook <> 0;
  end else begin
    if fmap^.hKbHook <> 0 then
    begin
      try result:= UnhookWindowsHookEx(fmap^.hKbHook);
      except messagebox(fmap^.hWnd, pchar(SysErrorMessage(GetLastError)), 'UnHookKb', mb_iconerror);
      end;
      if result then fmap^.hKbHook:= 0;
    end;
  end;
end;
//------------------------------------------------------------------------------
function SetTrayHook(activate: bool): bool; stdcall;
var
  dwThreadID: dword;
  hwndTray: HWND;
begin
    dwThreadID:= 0;
  result:= false;

  if activate then
  begin
    if fmap^.hTrayHook = 0 then
    begin
      hwndTray:= FindWindow(CLASS_TrayProc, nil);
      if hwndTray > 0 then
      begin
        dwThreadID:= GetWindowThreadProcessId(hwndTray, nil);
        fmap^.hTrayHook:= SetWindowsHookEx(WH_CALLWNDPROCRET, @TrayHookProc, hInstance, dwThreadID);
      end;
      FillMemory(@fmap^.SavedTrayData, MAXSAVEDTRAYDATA * sizeof(COPYDATASTRUCT), 0);
    end;
      result:= fmap^.hTrayHook <> 0;
  end else begin
    if fmap^.hTrayHook <> 0 then
    begin
      try result:= UnhookWindowsHookEx(fmap^.hTrayHook);
      except messagebox(fmap^.hWnd, pchar(SysErrorMessage(GetLastError)), 'UnHookTray', mb_iconerror);
      end;
      if result then fmap^.hTrayHook:= 0;
    end;
  end;
end;
//------------------------------------------------------------------------------
function Version: integer; stdcall;
begin
  result:= LIB_VERSION;
end;
//------------------------------------------------------------------------------
exports SetHook, SetKbHook, SetTrayHook, Version;
//------------------------------------------------------------------------------
begin
end.


второй модуль (с файлмэппингом)

Код

unit fmapu;

interface

uses Windows, ShellAPI;

const
  FMapID = 'TerryFMapID::56D27F6B-DC27-443A-A109-F00AE47DE599';
  MAXSAVEDTRAYDATA = 32;
  PAD_SIZE =    65;

type
  _NicHolder = record
        bPad: array [0..7] of byte;
        IconData: NotifyIconData;
        szPad: array [0..PAD_SIZE - 1] of char;
  end;

  _TrayItem = record
      CopyData: COPYDATASTRUCT;
    NicHolder: _NicHolder;
  end;

  PMapA = ^TMapA;
  TMapA = record
    closing: longbool;
    hWnd: cardinal;
    hHook: cardinal;
    hKbHook: cardinal;

    // tray //
    hTrayHook: cardinal;
    hTrayWin: cardinal;
    iNextFreePos: cardinal;
    SavedTrayData: array [0..MAXSAVEDTRAYDATA - 1] of _TrayItem;
  end;

var
  fmap: PMapA = nil;
  Mapping: uint = 0;

implementation
//------------------------------------------------------------------------------
initialization
  Mapping:= CreateFileMapping($ffffffff, nil, PAGE_READWRITE, 0, SizeOf(fmap), FMapID);
  fmap:= MapViewOfFile(Mapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
finalization
  if Assigned(fmap) then UnmapViewOfFile(fmap);
  if Mapping <> 0 then CloseHandle(Mapping);
end.


в настоящий момент используется из библы только первый хук (тот что на мышку)
тестирую под XP

Код

if hHookLib < 32 then hHookLib:= LoadLibrary(pansichar(ExpandPath('%pp%\hooks.dll')));

    if hHookLib >= 32 then
    begin
      fmap^.hWnd:= self.handle;
      fmap^.closing:= false;
      fmap^.hTrayWin:= 0;
      fmap^.hTrayHook:= 0;
      fmap^.iNextFreePos:= 0;

      @SetHook:= GetProcAddress(hHookLib, 'SetHook');
      SetHook(true);
....

Автор: MetalFan 14.11.2008, 19:47
чтото както странно работа с MMF просходит...
Код

var
  fmap: PMapA = nil;
...
 Mapping:= CreateFileMapping($ffffffff, nil, PAGE_READWRITE, 0, SizeOf(fmap), FMapID);
...

создал маппинг на 4 байта...

Автор: holmes 21.11.2008, 10:32
емае, чето проглядел ... MetalFan спасибо
хотя я хуки уже поправил

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)