Obtain file name from SetClipboardData hook

笑着哭i 提交于 2019-12-25 17:43:09

问题


I used EasyHook to hook into the SetClipboardData() function.

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

I can either pass the data to the original function or return NULL.

The goal is to prevent the user from copying specific files.

This DLL will be injected into Explorer.exe and will be called whenever a user tries to copy a file.

How to obtain the filename being copied?

Is there any other way to achieve this?


回答1:


Files can be copied/pasted using a number of different clipboard formats, and multiple formats can reside on the clipboard at the same time.

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

Refer to Shell Clipboard Formats for specific details about each format. In particular, see Formats for Transferring File System Objects.

So, you would need something like this:

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


来源:https://stackoverflow.com/questions/57790792/obtain-file-name-from-setclipboarddata-hook

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!