⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clipboard.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
        if (IntCountClipboardFormats() == 0)
        {
            ret = 0;
        }
        else
        {
            ProbeForRead(paFormatPriorityList, cFormats, sizeof(UINT));

            priorityList = paFormatPriorityList;

            ret = -1;

            for (i = 0; i < cFormats; i++)
            {
                if (intIsFormatAvailable(priorityList[i]))
                {
                    ret = priorityList[i];
                    break;
                }
            }

        }
    }
    _SEH_HANDLE
    {
        SetLastNtError(_SEH_GetExceptionCode());
    }
    _SEH_END;

    UserLeave();

    return ret;

}

BOOL STDCALL
NtUserIsClipboardFormatAvailable(UINT format)
{
    BOOL ret = FALSE;

    UserEnterShared();

    ret = (intIsFormatAvailable(format) != NULL);

    UserLeave();

    return ret;
}



HANDLE STDCALL
NtUserSetClipboardData(UINT uFormat, HANDLE hMem, DWORD size)
{
    HANDLE hCBData = NULL;
    UNICODE_STRING unicodeString;
    OEM_STRING oemString;
    ANSI_STRING ansiString;

    UserEnterExclusive();

    /* to place data here the we need to be the owner */
    if (ClipboardOwnerThread == PsGetCurrentThreadWin32Thread())
    {
        PCLIPBOARDELEMENT data = intIsFormatAvailable(uFormat);
        if (data)
        {

            if (data->size == DATA_DELAYED_RENDER)
            {
                intRemoveFormatedData(uFormat);
            }
            else
            {
                // we already have this format on clipboard
                goto exit_setCB;
            }
        }

        if (hMem)
        {
            _SEH_TRY
            {
                ProbeForRead(hMem, size, 1);
            }
            _SEH_HANDLE
            {
                SetLastNtError(_SEH_GetExceptionCode());
                _SEH_YIELD(goto exit_setCB);
            }
            _SEH_END;

            if (intIsClipboardOpenByMe())
            {
                delayedRender = FALSE;
            }

            if (!canSinthesize(uFormat))
            {
                hCBData = ExAllocatePool(PagedPool, size);
                memcpy(hCBData, hMem, size);
                intAddFormatedData(uFormat, hCBData, size);
                DPRINT1("Data stored\n");
            }

            sendDrawClipboardMsg = TRUE;
            recentlySetClipboard = TRUE;
            lastEnumClipboardFormats = uFormat;

            /* conversions */
            switch (uFormat)
            {
                case CF_TEXT:
                    {
                        //TODO : sinthesize CF_UNICODETEXT & CF_OEMTEXT
                        // CF_TEXT -> CF_UNICODETEXT
                        RtlAnsiStringToUnicodeString(&unicodeString, hCBData, TRUE);
                        intAddFormatedData(CF_UNICODETEXT, unicodeString.Buffer, unicodeString.Length * sizeof(WCHAR));
                        // CF_TEXT -> CF_OEMTEXT
                        RtlUnicodeStringToOemString(&oemString, &unicodeString, TRUE);
                        intAddFormatedData(CF_OEMTEXT, oemString.Buffer, oemString.Length);
                        //HKCU\Control Panel\International\Locale
                        //intAddFormatedData(CF_LOCALE, oemString.Buffer, oemString.Length);
                        break;
                    }
                case CF_UNICODETEXT:
                {
                    //TODO : sinthesize CF_TEXT & CF_OEMTEXT
                    //CF_UNICODETEXT -> CF_TEXT
                    unicodeString.Buffer = hCBData;
                    unicodeString.Length = size;
                    RtlUnicodeStringToAnsiString(&ansiString, &unicodeString, TRUE);
                    intAddFormatedData(CF_TEXT, ansiString.Buffer, ansiString.Length);
                    //CF_UNICODETEXT -> CF_OEMTEXT
                    RtlUnicodeStringToOemString(&oemString, &unicodeString, TRUE);
                    intAddFormatedData(CF_OEMTEXT, oemString.Buffer, oemString.Length);
                    break;
                }
                case CF_OEMTEXT:
                {
                    //TODO : sinthesize CF_TEXT & CF_UNICODETEXT
                    //CF_OEMTEXT -> CF_UNICODETEXT
                    oemString.Buffer = hCBData;
                    oemString.Length = size;
                    RtlOemStringToUnicodeString(&unicodeString, &oemString, TRUE);
                    intAddFormatedData(CF_UNICODETEXT, unicodeString.Buffer, unicodeString.Length * sizeof(WCHAR));
                    //CF_OEMTEXT -> CF_TEXT
                    RtlUnicodeStringToAnsiString(&ansiString, &unicodeString, TRUE);
                    intAddFormatedData(CF_TEXT, ansiString.Buffer, ansiString.Length);
                    break;
                }
                case CF_BITMAP:
                {
                    // we need to render the DIB or DIBV5 format as soon as possible
                    // because pallette information may change

                    HDC hdc;
                    INT ret;
                    BITMAP bm;
                    BITMAPINFO bi;
                    BITMAPOBJ *BitmapObj;

                    hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE);

                    
                    BitmapObj = BITMAPOBJ_LockBitmap(hMem);
                    BITMAP_GetObject(BitmapObj, sizeof(BITMAP), (LPSTR)&bm);
                    if(BitmapObj)
                    {
                        BITMAPOBJ_UnlockBitmap(BitmapObj);
                    }

                    bi.bmiHeader.biSize	= sizeof(BITMAPINFOHEADER);
                    bi.bmiHeader.biWidth = bm.bmWidth;
                    bi.bmiHeader.biHeight = bm.bmHeight;
                    bi.bmiHeader.biPlanes = 1;
                    bi.bmiHeader.biBitCount	= bm.bmPlanes * bm.bmBitsPixel;
                    bi.bmiHeader.biCompression = BI_RGB;
                    bi.bmiHeader.biSizeImage = 0;
                    bi.bmiHeader.biXPelsPerMeter = 0;
                    bi.bmiHeader.biYPelsPerMeter = 0;
                    bi.bmiHeader.biClrUsed = 0;

                    ret = NtGdiGetDIBits(hdc, hMem, 0, bm.bmHeight,  NULL, &bi, DIB_RGB_COLORS);

                    size = bi.bmiHeader.biSizeImage + sizeof(BITMAPINFOHEADER);

                    hCBData = ExAllocatePool(PagedPool, size);
                    memcpy(hCBData, &bi, sizeof(BITMAPINFOHEADER));

                    ret = NtGdiGetDIBits(hdc, hMem, 0, bm.bmHeight, (LPBYTE)hCBData + sizeof(BITMAPINFOHEADER), &bi, DIB_RGB_COLORS);

                    UserReleaseDC(NULL, hdc, FALSE);

                    intAddFormatedData(CF_DIB, hCBData, size);
                    intAddFormatedData(CF_BITMAP, 0, DATA_SYNTHESIZED_RENDER);
                    // intAddFormatedData(CF_DIBV5, hCBData, size);

                    break;
                }
                case CF_DIB:
                {
                    intAddFormatedData(CF_BITMAP, 0, DATA_SYNTHESIZED_RENDER);
                    // intAddFormatedData(CF_DIBV5, hCBData, size);
                    /* investigate */
                    // intAddFormatedData(CF_PALETTE, hCBData, size);
                    break;
                }
                case CF_DIBV5:
                    // intAddFormatedData(CF_BITMAP, hCBData, size);
                    // intAddFormatedData(CF_PALETTE, hCBData, size);
                    // intAddFormatedData(CF_DIB, hCBData, size);
                    break;
                case CF_ENHMETAFILE:
                    // intAddFormatedData(CF_METAFILEPICT, hCBData, size);
                    break;
                case CF_METAFILEPICT:
                    // intAddFormatedData(CF_ENHMETAFILE, hCBData, size);
                    break;
            }

        }
        else
        {
            // the window provides data in the specified format
            delayedRender = TRUE;
            sendDrawClipboardMsg = TRUE;
            intAddFormatedData(uFormat, NULL, 0);
            DPRINT1("SetClipboardData delayed format: %d\n", uFormat);
        }


    }

exit_setCB:

    UserLeave();

    return hMem;
}

HWND STDCALL
NtUserSetClipboardViewer(HWND hWndNewViewer)
{
    HWND ret = NULL;
    PCLIPBOARDCHAINELEMENT newWC = NULL;
    PWINDOW_OBJECT window;

    UserEnterExclusive();

    window = UserGetWindowObject(hWndNewViewer);

    if (window)
    {
        if ((newWC = IntAddWindowToChain(window)))
        {
            if (newWC)
            {
                // newWC->next may be NULL if we are the first window in the chain
                if (newWC->next)
                {
                    // return the next HWND available window in the chain
                    ret = newWC->next->window->hSelf;
                }
            }
        }
    }

    UserLeave();

    return ret;
}

UINT STDCALL
NtUserEnumClipboardFormats(UINT uFormat)
{
    UINT ret = 0;

    UserEnterShared();

    if (intIsClipboardOpenByMe())
    {
            if (uFormat == 0)
            {
                if (recentlySetClipboard)
                {
                    ret = lastEnumClipboardFormats;
                }
                else
                {
                    /* return the first available format */
                    if (ClipboardData)
                    {
                        ret = ClipboardData->format;
                    }
                }
            }
            else
            {
                if (recentlySetClipboard)
                {
                    ret = 0;
                }
                else
                {
                    /* querying nextt available format */
                    PCLIPBOARDELEMENT data = intIsFormatAvailable(uFormat);

                    if (data)
                    {
                        if (data->next)
                        {
                            ret = data->next->format;
                        }
                        else
                        {
                            /* reached the end */
                            ret = 0;
                        }
                    }
                }

            }
    }
    else
    {
        SetLastWin32Error(ERROR_CLIPBOARD_NOT_OPEN);
    }

    UserLeave();

    return ret;
}

// This number is incremented whenever the contents of the clipboard change
// or the clipboard is emptied.
// If clipboard rendering is delayed,
// the sequence number is not incremented until the changes are rendered.
VOID FASTCALL
IntIncrementSequenceNumber(VOID)
{

    USE_WINSTA

    WINSTA_ClipboardSequenceNumber++;

}

DWORD STDCALL
NtUserGetClipboardSequenceNumber(VOID)
{
    //windowstation sequence number
    //if no WINSTA_ACCESSCLIPBOARD access to the window station,
    //the function returns zero.
    DWORD sn;

    HWINSTA WinSta;
    PWINSTATION_OBJECT WinStaObj;
    NTSTATUS Status;

    WinSta = UserGetProcessWindowStation();

    Status = IntValidateWindowStationHandle(WinSta, UserMode, WINSTA_ACCESSCLIPBOARD, &WinStaObj);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("No WINSTA_ACCESSCLIPBOARD access\n");
        SetLastNtError(Status);
        return 0;
    }

    sn = WinStaObj->ClipboardSequenceNumber;

    ObDereferenceObject(WinStaObj);

    //local copy
    //sn = ClipboardSequenceNumber;

    return sn;
}


/**************** VISTA FUNCTIONS******************/

BOOL STDCALL NtUserAddClipboardFormatListener(
    HWND hwnd
)
{
    UNIMPLEMENTED;
    return FALSE;
}

BOOL STDCALL NtUserRemoveClipboardFormatListener(
    HWND hwnd
)
{
    UNIMPLEMENTED;
    return FALSE;
}

BOOL STDCALL NtUserGetUpdatedClipboardFormats(
    PUINT lpuiFormats,
    UINT cFormats,
    PUINT pcFormatsOut
)
{
    UNIMPLEMENTED;
    return FALSE;
}

/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -