📄 clipboard.c
字号:
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 + -