从 SetClipboardData 挂钩获取文件名
Obtain file name from SetClipboardData hook
我使用 EasyHook 挂接到 SetClipboardData()
函数。
HANDLE mySetClipBoardData (UINT uFormat, HANDLE hMem){
return SetClipboardData(uFormat, hMem);
//return NULL;
}
我可以将数据传递给原始函数或 return NULL。
目标是防止用户复制特定文件。
此 DLL 将被注入 Explorer.exe
并在用户尝试复制文件时调用。
如何获取被复制的文件名?
还有其他方法可以实现吗?
文件可以copied/pasted使用多种不同的剪贴板格式,并且多种格式可以同时驻留在剪贴板上。
- CF_HDROP
- CFSTR_FILECONTENTS
- CFSTR_FILEDESCRIPTOR
- CFSTR_FILENAME
- CFSTR_FILENAME地图
- CFSTR_MOUNTEDVOLUME
- CFSTR_SHELLIDLIST
- CFSTR_SHELLIDLIST偏移量
参考Shell Clipboard Formats for specific details about each format. In particular, see Formats for Transferring File System Objects.
所以,你需要这样的东西:
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);
}
我使用 EasyHook 挂接到 SetClipboardData()
函数。
HANDLE mySetClipBoardData (UINT uFormat, HANDLE hMem){
return SetClipboardData(uFormat, hMem);
//return NULL;
}
我可以将数据传递给原始函数或 return NULL。
目标是防止用户复制特定文件。
此 DLL 将被注入 Explorer.exe
并在用户尝试复制文件时调用。
如何获取被复制的文件名?
还有其他方法可以实现吗?
文件可以copied/pasted使用多种不同的剪贴板格式,并且多种格式可以同时驻留在剪贴板上。
- CF_HDROP
- CFSTR_FILECONTENTS
- CFSTR_FILEDESCRIPTOR
- CFSTR_FILENAME
- CFSTR_FILENAME地图
- CFSTR_MOUNTEDVOLUME
- CFSTR_SHELLIDLIST
- CFSTR_SHELLIDLIST偏移量
参考Shell Clipboard Formats for specific details about each format. In particular, see Formats for Transferring File System Objects.
所以,你需要这样的东西:
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);
}