从 SetClipboardData 挂钩获取文件名
Obtain file name from SetClipboardData hook
我用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);
}
相关文章:
- 从 Makefile 中的 $@ 获取文件名
- 有没有一种简单的方法可以从 c++ 中的路径获取文件名?
- 从 SetClipboardData 挂钩获取文件名
- 是否有一种便携式/标准的方法可以在堆栈跟踪中获取文件名和亚麻布
- 如何从文件夹中获取文件名,并将它们添加到QT中的孩子中
- 从 Windows 上的 tmpfile() 获取文件名
- 是否可以从FSEvent id获取文件名
- 如何在单击mfc代码中的关系文件时获取文件名
- 如何在Qt中获取文件名
- 是否有一个WinAPI可以从带有可选空格和其他参数的命令行获取文件名
- 从控制台应用中的命令行参数获取文件名C++
- 从流中获取文件名(或路径)
- 如何在下载文件之前获取文件名
- 在调用函数的任何位置获取文件名和函数名
- 在c++ boost库中使用directory_iterator列出和获取文件名的问题
- 从路径中获取文件名
- gtkmm 和 FileChooserButton 无法获取文件名
- 如何从http请求体字符串获取文件名
- 如何在GNU Makefile中只获取文件名而不扩展名
- 如何从argv中获取文件名并将其与ifstream一起使用/将其更改为ofstream的txt