2012-12-13 42 views
2

我想挂钩IDropTarget ::拖放COM方法,但我不是,在此之前,我挂钩的IFileOperation :: RenameItems方法它工作正常,并为我连接的RenameItems使用下面的代码。 。IDropTarget ::删除方法挂接

#include "stdafx.h" 
#include <windows.h> 
#include "MinHook.h" 
#include <Winternl.h> 
#include <stdio.h> 
#include <shlwapi.h> 
#include <tchar.h> 
#include <string.h> 
#include <psapi.h> 
#include <strsafe.h> 
#include <Shobjidl.h> 
#include <Shellapi.h> 
#include <Shlguid.h> 

#if defined _M_X64 
#pragma comment(lib, "libMinHook.x64.lib") 
bool __is32bitMachine = false ; 
#elif defined _M_IX86 
#pragma comment(lib, "libMinHook.x86.lib") 
bool __is32bitMachine = true; 
#endif 

PVOID GetInterfaceMethod(PVOID intf, DWORD methodIndex) 
{ 
if (__is32bitMachine) 
    return *(PVOID*)(*(DWORD_PTR*)intf + methodIndex * 4); 
else 
    return *(PVOID*)(*(DWORD_PTR*)intf + methodIndex * 8); 
} 

typedef HRESULT (STDMETHODCALLTYPE *RenameItemsNext)(IFileOperation *pThis, IUnknown *pUnkItems, LPCWSTR pszNewName); 
RenameItemsNext Real_RenameItems = NULL; 
RenameItemsNext Actual_RenameItems ; 

HRESULT STDMETHODCALLTYPE RenameItemsCallback(IFileOperation *pThis, IUnknown *pUnkItems, LPCWSTR pszNewName) 
{ 
IID IID_ShellItemArray; 
IID IID_DataObject; 
CLSIDFromString(L"{b63ea76d-1f85-456f-a19c-48159efa858b}", &IID_ShellItemArray); 
CLSIDFromString(L"{0000010E-0000-0000-C000-000000000046}", &IID_DataObject); 

void *shellItemArray; 
void *dataObject; 
LPWSTR dstFN; 

if (pUnkItems->QueryInterface(IID_ShellItemArray, &shellItemArray) == S_OK) 
{ 
    DWORD numItems = 0; 
    IShellItem *shell; 
    IShellItemArray *pItems = (IShellItemArray *) pUnkItems; 
    pItems->GetCount(&numItems); 
    for (int i = 0; i < numItems; i++) 
    { 
     pItems->GetItemAt(i, &shell); 
     shell->GetDisplayName(SIGDN_FILESYSPATH, &dstFN); 
     MessageBoxW(NULL, dstFN, L"Renamed From", MB_OK); 
    } 
    MessageBoxW(NULL, pszNewName, L"Renamed To", MB_OK); 
} 

if (pUnkItems->QueryInterface(IID_DataObject, &dataObject) == S_OK) 
{ 
    Real_SHCreateShell = (SHCreateShellNext)GetProcAddress(LoadLibraryA("shell32.dll"), "SHCreateShellItemArrayFromDataObject"); 
    if (Real_SHCreateShell != NULL) 
    { 
     if (Real_SHCreateShell((IDataObject*)dataObject, IID_ShellItemArray, &shellItemArray) == S_OK) 
     { 
      DWORD numItems = 0; 
      IShellItem *shell; 
      IShellItemArray *pItems = (IShellItemArray *)shellItemArray; 
      pItems->GetCount(&numItems); 
      if (pItems->GetCount(&numItems) == S_OK) 
      { 
       for (int i = 0; i < numItems; i++) 
       { 
        if (pItems->GetItemAt(i, &shell) == S_OK) 
        { 
         shell->GetDisplayName(SIGDN_FILESYSPATH, &dstFN); 
         MessageBoxW(NULL, dstFN, L"Renamed From", MB_OK); 
        } 
       } 
      } 
     } 
    } 
    MessageBoxW(NULL, dstFN, L"Renamed To", MB_OK); 
} 
return Real_RenameItems(pThis, pUnkItems, pszNewName); 
} 

typedef HRESULT (WINAPI *COCREATEINSTANCE)(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID*); 
COCREATEINSTANCE Real_CoCreateInstance = NULL; 

HRESULT WINAPI CoCreateInstanceCallback(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv) 
{ 
const char *IFileOperation_GUID = "{3AD05575-8857-4850-9277-11B85BDB8E09}"; 
char GUIDString[64]; 

HRESULT HR = Real_CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); 

sprintf_s(GUIDString, 64, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\0", 
    rclsid.Data1, rclsid.Data2, rclsid.Data3, 
    rclsid.Data4[0], rclsid.Data4[1], 
    rclsid.Data4[2], rclsid.Data4[3], 
    rclsid.Data4[4], rclsid.Data4[5], 
    rclsid.Data4[6], rclsid.Data4[7]); 

if (strcmp(GUIDString, IFileOperation_GUID) == 0) 
{  
    if(Real_RenameItems == NULL) 
    { 
     Actual_RenameItems = (RenameItemsNext) GetInterfaceMethod(*ppv, 13); 

     if (MH_CreateHook(Actual_RenameItems, &RenameItemsCallback, reinterpret_cast<void**>(&Real_RenameItems)) != MH_OK) 
     { 
      MessageBoxW(NULL, L"Failed CreateHook Real_RenameItems", L"Info!", MB_ICONWARNING|MB_OK); 
     } 
     if (MH_EnableHook(Actual_RenameItems) != MH_OK) 
     { 
      MessageBoxW(NULL, L"Failed EnableHook Real_RenameItems", L"Info!", MB_ICONWARNING|MB_OK); 
     } 
    } 
} 
return HR; 
} 

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 
{ 
switch (ul_reason_for_call) 
{ 
case DLL_PROCESS_ATTACH: 
    if (MH_Initialize() != MH_OK) 
    { 
     MessageBoxW(NULL, L"Failed Initialize", L"Info!", MB_ICONWARNING|MB_OK);  
    } 
    if (MH_CreateHook(&CoCreateInstance, &CoCreateInstanceCallback, reinterpret_cast<void**>(&Real_CoCreateInstance)) != MH_OK) 
    { 
     MessageBoxW(NULL, L"Failed MH_CreateHook CoCreateInstance", L"Info!", MB_ICONWARNING|MB_OK); 
    } 
    if (MH_EnableHook(&CoCreateInstance) != MH_OK) 
    { 
     MessageBoxW(NULL, L"Failed MH_EnableHook CoCreateInstance", L"Info!", MB_ICONWARNING|MB_OK); 
    } 
    break; 

case DLL_PROCESS_DETACH: 
    if (MH_Uninitialize() != MH_OK) 
    {    
    } 
    if (MH_DisableHook(Actual_RenameItems) != MH_OK) 
    { 
    } 
    if (MH_DisableHook(&CoCreateInstance) != MH_OK) 
    { 
    } 
    break; 
} 
return TRUE; 
} 

上面的代码是为IOFileOperation :: RenameItems做工精细,我想实现的::下降目标滴法相同的代码,但所发生的事情是CoCreateInstance函数本身不要求放操作,所以任何可以帮助我如何实现这个IDropTarget ::挂钩.......

+0

并不是每一个COM接口是(),其获取与CoCreateInstance的创建的组件类的一部分。 IDropTarget由一个支持删除内容的窗口实现。它永远不会调用CoCreateInstance(),它已经有一个实例。 –

+0

好的...请问我可以如何实现这个... – nagaradderKantesh

回答

1

通常IDropTarget实施insid e客户端应用程序并通过RegisterDropTarget调用进行注册。 尝试挂钩RegisterDropTarget功能,可能有助于

更新:其实函数名RegisterDragDrop

+0

我没有找到RegisterDropTarget函数,所以你可以告诉我哪个函数正是我应该尝试.... – nagaradderKantesh

+0

对不起,它是命名为RegisterDragDrop [链接](http://msdn.microsoft.com/en-us/library/windows/desktop/ms678405(v = vs.85).aspx) – Serik

+0

它没关系...我试着用RegisterDragDrop函数但它没有帮助,因为它在拖放操作过程中不会调用。所以任何其他方式,请帮助.. – nagaradderKantesh