~stomato463/+junk/nvdajp

« back to all changes in this revision

Viewing changes to nvdaHelper/remote/apiHook.cpp

  • Committer: Masataka Shinke
  • Date: 2011-10-25 12:35:26 UTC
  • mfrom: (4185 jpmain)
  • mto: This revision was merged to the branch mainline in revision 4211.
  • Revision ID: mshinke@users.sourceforge.jp-20111025123526-ze527a2rl3z0g2ky
lp:~nishimotz/nvdajp/main : 4185 をマージ

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
This file is a part of the NVDA project.
 
3
URL: http://www.nvda-project.org/
 
4
Copyright 2006-2010 NVDA contributers.
 
5
    This program is free software: you can redistribute it and/or modify
 
6
    it under the terms of the GNU General Public License version 2.0, as published by
 
7
    the Free Software Foundation.
 
8
    This program is distributed in the hope that it will be useful,
 
9
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
11
This license can be found at:
 
12
http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 
13
*/
 
14
 
 
15
#include <iostream>
 
16
#include <set>
 
17
#define WIN32_LEAN_AND_MEAN 
 
18
#include <windows.h>
 
19
#include <minHook/newMinHook.h>
 
20
#include "nvdaControllerInternal.h"
 
21
#include "log.h"
 
22
#include "apiHook.h"
 
23
 
 
24
using namespace std;
 
25
 
 
26
typedef multiset<HMODULE> moduleSet_t;
 
27
typedef set<void*> functionSet_t;
 
28
 
 
29
moduleSet_t g_hookedModules;
 
30
functionSet_t g_hookedFunctions;
 
31
 
 
32
bool apiHook_initialize() {
 
33
        LOG_DEBUG("calling MH_Initialize");
 
34
        int res;
 
35
        if ((res=MH_Initialize())!=MH_OK) {
 
36
                LOG_ERROR("MH_CreateHook failed with " << res);
 
37
                return false;
 
38
        } 
 
39
        else return true;
 
40
}
 
41
 
 
42
void* apiHook_hookFunction(const char* moduleName, const char* functionName, void* newHookProc) {
 
43
        HMODULE moduleHandle=LoadLibraryA(moduleName);
 
44
        if(!moduleHandle) {
 
45
                LOG_ERROR("module " << moduleName << " not loaded");
 
46
                return NULL;
 
47
        }
 
48
        void* realFunc=GetProcAddress(moduleHandle,functionName);
 
49
        if(!realFunc) {
 
50
                LOG_ERROR("function " << functionName << " does not exist in module " << moduleName);
 
51
                FreeLibrary(moduleHandle);
 
52
                return NULL;
 
53
        }
 
54
        LOG_DEBUG("requesting to hook function " << functionName << " at address 0X" << std::hex << realFunc << " in module " << moduleName << " at address 0X" << moduleHandle << " with  new function at address 0X" << newHookProc);
 
55
        void* origFunc;
 
56
        int res;
 
57
        if((res=MH_CreateHook(realFunc,newHookProc,&origFunc))!=MH_OK) {
 
58
                LOG_ERROR("MH_CreateHook failed with " << res);
 
59
                FreeLibrary(moduleHandle);
 
60
                return NULL;
 
61
        }
 
62
        g_hookedModules.insert(moduleHandle);
 
63
        g_hookedFunctions.insert(realFunc);
 
64
        LOG_DEBUG("successfully hooked function " << functionName << " in module " << moduleName << " with hook procedure at address 0X" << std::hex << newHookProc << ", returning true");
 
65
        return origFunc;
 
66
}
 
67
 
 
68
bool apiHook_enableHooks() {
 
69
        int res;
 
70
        res=MH_EnableAllHooks();
 
71
        nhAssert(res==MH_OK);
 
72
        return TRUE;
 
73
}
 
74
 
 
75
bool apiHook_terminate() {
 
76
        int res;
 
77
        res=MH_DisableAllHooks();
 
78
        nhAssert(res==MH_OK);
 
79
        g_hookedFunctions.clear();
 
80
        //Give enough time for all hook functions to complete.
 
81
        Sleep(250);
 
82
        res=MH_Uninitialize();
 
83
        nhAssert(res==MH_OK);
 
84
        for(moduleSet_t::iterator i=g_hookedModules.begin();i!=g_hookedModules.end();++i) {
 
85
                FreeLibrary(*i);
 
86
        }
 
87
        g_hookedModules.clear();
 
88
        return TRUE;
 
89
}