大家都知道,当用户在Windows资源管理器中选择一个文件,复制该文件的时候,系统将其复制到剪切板,Shell创建一个数据对象,然后它调用OleSetClipboard函数放置一个指针到数据对象的剪切板上的IDataObject接口,我们可以调用IDataObject::GetData来获取文件名现在我就是想写一个关于在指定的应用程序上监控OleSetClipboard函数的Hook,其中OleSetClipboard函数属于ole32.dll,部分代码如下:
DWORD dwIdNew = 0;
DWORD dwIdOld = 0;FARPROC pfCreateTextSer=0;
BOOL InitHook() 
{

HMODULE hRiched; 


hRiched = GetModuleHandle(L"ole32.dll");
if(hRiched==NULL) 
return FALSE; 
         pfCreateTextSer = GetProcAddress(hRiched,"OleGetClipboard");
if(pfCreateTextSer==NULL) {
Log("OleGetClipboard函数地址获取失败");
return FALSE; 
}
else
Log("OleGetClipboard函数地址已获取"); _asm 

lea   edi,OldValue 
mov   esi,pfCreateTextSer 
cld 
movsd 
movsb 


NewValue[0]=0xe9;//jmp   MyOleGetClipboard的相对地址的指令  _asm 

lea   eax,MyOleGetClipboard 
mov   ebx,pfCreateTextSer 
sub   eax,ebx 
sub   eax,5 
mov   dword   ptr   [NewValue+1],eax 
} dwIdNew=GetCurrentProcessId();   //得到所属进程的ID 
dwIdOld=dwIdNew; 

return true;
}剩下的关于HRESULT WINAPI MyOleGetClipboard( LPDATAOBJECT *ppDataObj) 该如何实现呢?请高手指教,不胜感激

解决方案 »

  1.   

    首先定义可访问剪切板类容函数OleGetClipboardL(PDATAOBJECT *ppDataObj)的函数指针:
    __declspec(dllexport) HRESULT WINAPI MyOleGetClipboard( LPDATAOBJECT *ppDataObj);FARPROC pfOleGetClip=0;这是我瞎些的,有错误,请大家帮忙改正:
    HRESULT WINAPI MyOleGetClipboard( LPDATAOBJECT *ppDataObj)
    {
    // 找到原始函数的地址 
    ::PFOleGetClipboard _OleGetClipboard =
    (HRESULT (__stdcall *)(LPDATAOBJECT *))pfOleGetClip;

    if(_OleGetClipboard)
    {
    Log("OleGetClipboard指针已获取");
    }
    else
    {
    Log("OleGetClipboard指针获取失败");
    return 0;
    }

    // 执行原始函数 , 以取得当前 IDataObject 的指针 
    HRESULT ret=(_OleGetClipboard)(ppDataObj); 

    if(SUCCEEDED(ret))
    {
    if(ppDataObj)
    {
    Log("IDataObject指针变量的地址以获取");
    FORMATETC fmtetc = { CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
    STGMEDIUM stgmed;
    if(ppDataObj->IDataObject::GetData(&fmtetc,&stgmed)==S_OK)
    {
    //char *data = GlobalLock(stgmed.hGlobal);
    LPVOID p=GlobalLock(stgmed.hGlobal);
    char *data;
    data = (char *)p;
    FILE *f;

    if((f=fopen("c:\\QQFile.txt","a+"))!=NULL)
    {

    fwrite(data,sizeof(char),strlen(data),f);
    }

    }
    ::GlobalUnlock(stgmed.hGlobal);
    ::ReleaseStgMedium(&stgmed); }
    }
    return ret;}编译的时候出错,就是if(ppDataObj->IDataObject::GetData(&fmtetc,&stgmed)==S_OK)这一句:left of '->GetData' must point to class/struct/union/generic type。请大侠指示错在哪里!
    另外我还不知道这种方法用于获取剪切板中的数据类容对不对,我琢磨好像不行,但其他的不会啊,望高手指教