我用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);
}