VOID FASTCALL co_IntDrawCaret(PWND pWnd, PTHRDCARETINFO CaretInfo) { HDC hdc, hdcMem; HBITMAP hbmOld; BOOL bDone = FALSE; hdc = UserGetDCEx(pWnd, 0, DCX_USESTYLE | DCX_WINDOW); if (!hdc) { ERR("GetDC failed\n"); return; } if (pWnd->hrgnUpdate) { NtGdiSaveDC(hdc); } if(CaretInfo->Bitmap && NtGdiGetBitmapDimension(CaretInfo->Bitmap, &CaretInfo->Size)) { hdcMem = NtGdiCreateCompatibleDC(hdc); if (hdcMem) { hbmOld = NtGdiSelectBitmap(hdcMem, CaretInfo->Bitmap); bDone = NtGdiBitBlt(hdc, CaretInfo->Pos.x, CaretInfo->Pos.y, CaretInfo->Size.cx, CaretInfo->Size.cy, hdcMem, 0, 0, SRCINVERT, 0, 0); NtGdiSelectBitmap(hdcMem, hbmOld); GreDeleteObject(hdcMem); } } if (!bDone) { NtGdiPatBlt(hdc, CaretInfo->Pos.x, CaretInfo->Pos.y, CaretInfo->Size.cx, CaretInfo->Size.cy, DSTINVERT); } if (pWnd->hrgnUpdate) { NtGdiRestoreDC(hdc, -1); } UserReleaseDC(pWnd, hdc, FALSE); }
HANDLE FASTCALL renderBITMAPfromDIB(LPBYTE pDIB) { HDC hdc; HBITMAP hbitmap; PBITMAPINFO pBmi, pConvertedBmi = NULL; NTSTATUS Status ; UINT offset = 0; /* Stupid compiler */ pBmi = (BITMAPINFO*)pDIB; //hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE); hdc = UserGetDCEx(ClipboardWindow, NULL, DCX_USESTYLE); /* Probe it */ _SEH2_TRY { ProbeForRead(&pBmi->bmiHeader.biSize, sizeof(DWORD), 1); ProbeForRead(pBmi, pBmi->bmiHeader.biSize, 1); ProbeForRead(pBmi, DIB_BitmapInfoSize(pBmi, DIB_RGB_COLORS), 1); pConvertedBmi = DIB_ConvertBitmapInfo(pBmi, DIB_RGB_COLORS); if(!pConvertedBmi) { Status = STATUS_INVALID_PARAMETER; } else { offset = DIB_BitmapInfoSize((BITMAPINFO*)pBmi, DIB_RGB_COLORS); ProbeForRead(pDIB + offset, pConvertedBmi->bmiHeader.biSizeImage, 1); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END if(!NT_SUCCESS(Status)) { UserReleaseDC(ClipboardWindow, hdc, FALSE); return NULL; } hbitmap = GreCreateDIBitmapInternal(hdc, pConvertedBmi->bmiHeader.biWidth, pConvertedBmi->bmiHeader.biHeight, CBM_INIT, pDIB+offset, pConvertedBmi, DIB_RGB_COLORS, 0, 0); //UserReleaseDC(NULL, hdc, FALSE); UserReleaseDC(ClipboardWindow, hdc, FALSE); DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi); return hbitmap; }
static VOID WINAPI IntSynthesizeBitmap(PWINSTATION_OBJECT pWinStaObj, PCLIP pBmEl) { HDC hdc = NULL; PBITMAPINFO pBmi, pConvertedBmi = NULL; HBITMAP hBm = NULL; PCLIPBOARDDATA pMemObj; PCLIP pDibEl; ULONG Offset; TRACE("IntSynthesizeBitmap(%p, %p)\n", pWinStaObj, pBmEl); pDibEl = IntIsFormatAvailable(pWinStaObj, CF_DIB); ASSERT(pDibEl && !IS_DATA_SYNTHESIZED(pDibEl)); if(!pDibEl->fGlobalHandle) return; pMemObj = (PCLIPBOARDDATA)UserGetObject(gHandleTable, pDibEl->hData, TYPE_CLIPDATA); if (!pMemObj) return; pBmi = (BITMAPINFO*)pMemObj->Data; if (pMemObj->cbData < sizeof(DWORD) && pMemObj->cbData < pBmi->bmiHeader.biSize) goto cleanup; pConvertedBmi = DIB_ConvertBitmapInfo(pBmi, DIB_RGB_COLORS); if (!pConvertedBmi) goto cleanup; Offset = DIB_BitmapInfoSize(pBmi, DIB_RGB_COLORS); hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE); if (!hdc) goto cleanup; hBm = GreCreateDIBitmapInternal(hdc, pConvertedBmi->bmiHeader.biWidth, pConvertedBmi->bmiHeader.biHeight, CBM_INIT, pMemObj->Data + Offset, pConvertedBmi, DIB_RGB_COLORS, 0, pMemObj->cbData - Offset, 0); if (hBm) { GreSetObjectOwner(hBm, GDI_OBJ_HMGR_PUBLIC); pBmEl->hData = hBm; } cleanup: if (hdc) UserReleaseDC(NULL, hdc, FALSE); if (pConvertedBmi) DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi, -1); }
UINT APIENTRY IntAnimatePalette(HPALETTE hPal, UINT StartIndex, UINT NumEntries, CONST PPALETTEENTRY PaletteColors) { UINT ret = 0; if( hPal != NtGdiGetStockObject(DEFAULT_PALETTE) ) { PPALETTE palPtr; UINT pal_entries; HDC hDC; PDC dc; PWND Wnd; const PALETTEENTRY *pptr = PaletteColors; palPtr = PALETTE_ShareLockPalette(hPal); if (!palPtr) return FALSE; pal_entries = palPtr->NumColors; if (StartIndex >= pal_entries) { PALETTE_ShareUnlockPalette(palPtr); return FALSE; } if (StartIndex+NumEntries > pal_entries) NumEntries = pal_entries - StartIndex; for (NumEntries += StartIndex; StartIndex < NumEntries; StartIndex++, pptr++) { /* According to MSDN, only animate PC_RESERVED colours */ if (palPtr->IndexedColors[StartIndex].peFlags & PC_RESERVED) { memcpy( &palPtr->IndexedColors[StartIndex], pptr, sizeof(PALETTEENTRY) ); ret++; PALETTE_ValidateFlags(&palPtr->IndexedColors[StartIndex], 1); } } PALETTE_ShareUnlockPalette(palPtr); /* Immediately apply the new palette if current window uses it */ Wnd = UserGetDesktopWindow(); hDC = UserGetWindowDC(Wnd); dc = DC_LockDc(hDC); if (NULL != dc) { if (dc->dclevel.hpal == hPal) { DC_UnlockDc(dc); IntGdiRealizePalette(hDC); } else DC_UnlockDc(dc); } UserReleaseDC(Wnd,hDC, FALSE); } return ret; }
/* * @implemented */ DWORD_PTR APIENTRY NtUserCallOneParam( DWORD_PTR Param, DWORD Routine) { DECLARE_RETURN(DWORD_PTR); TRACE("Enter NtUserCallOneParam\n"); UserEnterExclusive(); switch(Routine) { case ONEPARAM_ROUTINE_POSTQUITMESSAGE: { PTHREADINFO pti; pti = PsGetCurrentThreadWin32Thread(); MsqPostQuitMessage(pti->MessageQueue, Param); RETURN(TRUE); } case ONEPARAM_ROUTINE_BEGINDEFERWNDPOS: { PSMWP psmwp; HDWP hDwp = NULL; INT count = (INT)Param; if (count < 0) { EngSetLastError(ERROR_INVALID_PARAMETER); RETURN(0); } /* Windows allows zero count, in which case it allocates context for 8 moves */ if (count == 0) count = 8; psmwp = (PSMWP) UserCreateObject( gHandleTable, NULL, (PHANDLE)&hDwp, otSMWP, sizeof(SMWP)); if (!psmwp) RETURN(0); psmwp->acvr = ExAllocatePoolWithTag(PagedPool, count * sizeof(CVR), USERTAG_SWP); if (!psmwp->acvr) { UserDeleteObject(hDwp, otSMWP); RETURN(0); } RtlZeroMemory(psmwp->acvr, count * sizeof(CVR)); psmwp->bHandle = TRUE; psmwp->ccvr = 0; // actualCount psmwp->ccvrAlloc = count; // suggestedCount RETURN((DWORD_PTR)hDwp); } case ONEPARAM_ROUTINE_SHOWCURSOR: RETURN( (DWORD_PTR)UserShowCursor((BOOL)Param) ); case ONEPARAM_ROUTINE_GETDESKTOPMAPPING: { PTHREADINFO ti; ti = GetW32ThreadInfo(); if (ti != NULL) { /* Try convert the pointer to a user mode pointer if the desktop is mapped into the process */ RETURN((DWORD_PTR)DesktopHeapAddressToUser((PVOID)Param)); } else { RETURN(0); } } case ONEPARAM_ROUTINE_WINDOWFROMDC: RETURN( (DWORD_PTR)IntWindowFromDC((HDC)Param)); case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON: { DWORD_PTR Result; Result = gspv.bMouseBtnSwap; gspv.bMouseBtnSwap = Param ? TRUE : FALSE; gpsi->aiSysMet[SM_SWAPBUTTON] = gspv.bMouseBtnSwap; RETURN(Result); } case ONEPARAM_ROUTINE_SWITCHCARETSHOWING: RETURN( (DWORD_PTR)IntSwitchCaretShowing((PVOID)Param)); case ONEPARAM_ROUTINE_SETCARETBLINKTIME: RETURN( (DWORD_PTR)IntSetCaretBlinkTime((UINT)Param)); case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO: RETURN( (DWORD_PTR)MsqSetMessageExtraInfo((LPARAM)Param)); case ONEPARAM_ROUTINE_CREATEEMPTYCUROBJECT: { PCURICON_OBJECT CurIcon; DWORD_PTR Result ; if (!(CurIcon = IntCreateCurIconHandle())) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); RETURN(0); } Result = (DWORD_PTR)CurIcon->Self; UserDereferenceObject(CurIcon); RETURN(Result); } case ONEPARAM_ROUTINE_GETCURSORPOSITION: { BOOL ret = TRUE; _SEH2_TRY { ProbeForWrite((POINT*)Param,sizeof(POINT),1); RtlCopyMemory((POINT*)Param,&gpsi->ptCursor,sizeof(POINT)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { SetLastNtError(_SEH2_GetExceptionCode()); ret = FALSE; } _SEH2_END; RETURN (ret); } case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING: { BOOL Enable; PPROCESSINFO Process = PsGetCurrentProcessWin32Process(); if(Process != NULL) { Enable = (BOOL)(Param != 0); if(Enable) { Process->W32PF_flags &= ~W32PF_NOWINDOWGHOSTING; } else { Process->W32PF_flags |= W32PF_NOWINDOWGHOSTING; } RETURN( TRUE); } RETURN( FALSE); } case ONEPARAM_ROUTINE_GETINPUTEVENT: RETURN( (DWORD_PTR)IntMsqSetWakeMask(Param)); case ONEPARAM_ROUTINE_GETKEYBOARDTYPE: RETURN( UserGetKeyboardType(Param)); case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT: RETURN( (DWORD_PTR)UserGetKeyboardLayout(Param)); case ONEPARAM_ROUTINE_RELEASEDC: RETURN (UserReleaseDC(NULL, (HDC) Param, FALSE)); case ONEPARAM_ROUTINE_REALIZEPALETTE: RETURN (UserRealizePalette((HDC) Param)); case ONEPARAM_ROUTINE_GETQUEUESTATUS: { RETURN (IntGetQueueStatus((DWORD)Param)); } case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS: /* FIXME: Should use UserEnterShared */ RETURN(IntEnumClipboardFormats(Param)); case ONEPARAM_ROUTINE_CSRSS_GUICHECK: IntUserManualGuiCheck(Param); RETURN(TRUE); case ONEPARAM_ROUTINE_GETCURSORPOS: { BOOL Ret = TRUE; PPOINTL pptl; PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); if (pti->hdesk != InputDesktopHandle) RETURN(FALSE); _SEH2_TRY { pptl = (PPOINTL)Param; *pptl = gpsi->ptCursor; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Ret = FALSE; } _SEH2_END; RETURN(Ret); } case ONEPARAM_ROUTINE_SETPROCDEFLAYOUT: { PPROCESSINFO ppi; if (Param & LAYOUT_ORIENTATIONMASK) { ppi = PsGetCurrentProcessWin32Process(); ppi->dwLayout = Param; RETURN(TRUE); } EngSetLastError(ERROR_INVALID_PARAMETER); RETURN(FALSE); } case ONEPARAM_ROUTINE_GETPROCDEFLAYOUT: { BOOL Ret = TRUE; PPROCESSINFO ppi; PDWORD pdwLayout; if ( PsGetCurrentProcess() == CsrProcess) { EngSetLastError(ERROR_INVALID_ACCESS); RETURN(FALSE); } ppi = PsGetCurrentProcessWin32Process(); _SEH2_TRY { pdwLayout = (PDWORD)Param; *pdwLayout = ppi->dwLayout; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { SetLastNtError(_SEH2_GetExceptionCode()); Ret = FALSE; } _SEH2_END; RETURN(Ret); } case ONEPARAM_ROUTINE_REPLYMESSAGE: RETURN (co_MsqReplyMessage((LRESULT) Param)); case ONEPARAM_ROUTINE_MESSAGEBEEP: RETURN ( UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, Param) ); /* TODO: Implement sound sentry */ } ERR("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n", Routine, Param); EngSetLastError(ERROR_INVALID_PARAMETER); RETURN( 0); CLEANUP: TRACE("Leave NtUserCallOneParam, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; }
static VOID NTAPI IntSynthesizeDib( PWINSTATION_OBJECT pWinStaObj, HBITMAP hbm) { HDC hdc; ULONG cjInfoSize, cjDataSize; PCLIPBOARDDATA pClipboardData; HANDLE hMem; INT iResult; struct { BITMAPINFOHEADER bmih; RGBQUAD rgbColors[256]; } bmiBuffer; PBITMAPINFO pbmi = (PBITMAPINFO)&bmiBuffer; /* Get the display DC */ hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE); if (!hdc) { return; } /* Get information about the bitmap format */ iResult = GreGetDIBitsInternal(hdc, hbm, 0, 0, NULL, pbmi, DIB_RGB_COLORS, 0, sizeof(bmiBuffer)); if (iResult == 0) { goto cleanup; } /* Get the size for a full BITMAPINFO */ cjInfoSize = DIB_BitmapInfoSize(pbmi, DIB_RGB_COLORS); /* Calculate the size of the clipboard data, which is a packed DIB */ cjDataSize = cjInfoSize + pbmi->bmiHeader.biSizeImage; /* Create the clipboard data */ pClipboardData = (PCLIPBOARDDATA)UserCreateObject(gHandleTable, NULL, NULL, &hMem, TYPE_CLIPDATA, cjDataSize); if (!pClipboardData) { goto cleanup; } /* Set the data size */ pClipboardData->cbData = cjDataSize; /* Copy the BITMAPINFOHEADER */ memcpy(pClipboardData->Data, pbmi, sizeof(BITMAPINFOHEADER)); /* Get the bitmap bits and the color table */ iResult = GreGetDIBitsInternal(hdc, hbm, 0, abs(pbmi->bmiHeader.biHeight), (LPBYTE)pClipboardData->Data + cjInfoSize, (LPBITMAPINFO)pClipboardData->Data, DIB_RGB_COLORS, pbmi->bmiHeader.biSizeImage, cjInfoSize); /* Add the clipboard data */ IntAddFormatedData(pWinStaObj, CF_DIB, hMem, TRUE, TRUE); /* Release the extra reference (UserCreateObject added 2 references) */ UserDereferenceObject(pClipboardData); cleanup: UserReleaseDC(NULL, hdc, FALSE); }