从 SetClipboardData 挂钩获取文件名

Obtain file name from SetClipboardData hook

本文关键字:获取 文件名 SetClipboardData      更新时间:2023-10-16

我用EasyHook挂接到SetClipboardData()函数。

HANDLE mySetClipBoardData (UINT uFormat, HANDLE hMem){
return SetClipboardData(uFormat, hMem);
//return NULL;
}

我可以将数据传递给原始函数或返回 NULL。

目标是防止用户复制特定文件。

此 DLL 将注入到Explorer.exe中,并在用户尝试复制文件时调用。

如何获取正在复制的文件名?

还有其他方法可以实现这一点吗?

可以使用多种不同的剪贴板格式复制/粘贴文件,并且可以同时将多种格式驻留在剪贴板上。

  • CF_HDROP
  • CFSTR_FILECONTENTS
  • CFSTR_FILEDESCRIPTOR
  • CFSTR_FILENAME
  • CFSTR_FILENAMEMAP
  • CFSTR_MOUNTEDVOLUME
  • CFSTR_SHELLIDLIST
  • CFSTR_SHELLIDLISTOFFSET

有关每种格式的特定详细信息,请参阅 Shell 剪贴板格式。 具体而言,请参阅传输文件系统对象的格式。

所以,你需要这样的东西:

const UINT ui_CFSTR_SHELLIDLIST = RegisterClipboardFormat(CFSTR_SHELLIDLIST);
const UINT ui_CFSTR_FILENAMEA = RegisterClipboardFormat(CFSTR_FILENAMEA);
const UINT ui_CFSTR_FILENAMEW = RegisterClipboardFormat(CFSTR_FILENAMEW);
...
HANDLE WINAPI mySetClipBoardData (UINT uFormat, HANDLE hMem)
{
if (!hMem) // DELAYED RENDERING! The real data will come later...
return SetClipboardData(uFormat, hMem);
if (uFormat == CF_HDROP)
{
LPDROPFILES pDF = (LPDROPFILES) GlobalLock(hMem);
if (pDF->fWide)
{
LPWSTR pFiles = (LPWSTR) (((LPBYTE)pDF) + pDF->pFiles);
while (*pFiles)
{
LPWSTR pFile = pFiles;
if (pFile refers to the desired file)
{
GlobalUnlock(hMem);
SetLastError(...);
return NULL;
// alternatively, build up a new string to place on the clipboard that omits this file...
}
pFiles += (lstrlenW(pFile) + 1);
}
}
else
{
LPSTR pFiles = (LPSTR) (((LPBYTE)pDF) + pDF->pFiles);
while (*pFiles)
{
LPSTR pFile = pFiles;
if (pFile refers to the desired file)
{
GlobalUnlock(hMem);
SetLastError(...);
return NULL;
// alternatively, build up a new string to place on the clipboard that omits this file...
}
pFiles += (lstrlenA(pFile) + 1);
}
}
GlobalUnlock(hMem);
/* alternatively:
TCHAR szFile[MAX_PATH];
UINT count = DragQueryFile((HDROP)hMem, (UINT)-1, NULL, 0);
for (UINT i = 0; i < count; ++i)
{
DragQueryFile((HDROP)hMem, i, szFile, MAX_PATH);
if (szFile refers to the desired file)
{
SetLastError(...);
return NULL;
// alternatively, build up a new string to place on the clipboard that omits this file...
}
}
*/
}
else if (uFormat == ui_CFSTR_SHELLIDLIST)
{
#define HIDA_GetPIDLFolder(pida) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[0])
#define HIDA_GetPIDLItem(pida, i) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[i+1])
LPIDA pIDA = (LPIDA) GlobalLock(hMem);
LPCITEMIDLIST pidlParent = HIDA_GetPIDLFolder(pIDA);
for (UINT i = 0; i < pIDA->cidl; ++i)
{
LPCITEMIDLIST pidlFile = HIDA_GetPIDLItem(pIDA, i);
if (pidlParent+pidlFile refers to the desired file)
{
GlobalUnlock(hMem);
SetLastError(...);
return NULL;
// alternatively, build up a new array to place on the clipboard that omits this file...
}
}
GlobalUnlock(hMem);
}
else if (uFormat == ui_CFSTR_FILENAMEA)
{
LPSTR pFile = (LPSTR) GlobalLock(hMem);
if (pFile refers to the desired file)
{
GlobalUnlock(hMem);
SetLastError(...);
return NULL;
}
GlobalUnlock(hMem);
}
else if (uFormat == ui_CFSTR_FILENAMEW)
{
LPWSTR pFile = (LPWSTR) GlobalLock(hMem);
if (pFile refers to the desired file)
{
GlobalUnlock(hMem);
SetLastError(...);
return NULL;
}
GlobalUnlock(hMem);
}
else
{
// handle other shell formats as needed...
}
return SetClipboardData(uFormat, hMem);
}