/* * NtUserGetKeyboardLayoutName * * Returns KLID of current thread keyboard layout */ BOOL APIENTRY NtUserGetKeyboardLayoutName( LPWSTR pwszName) { BOOL bRet = FALSE; PKL pKl; PTHREADINFO pti; UserEnterShared(); pti = PsGetCurrentThreadWin32Thread(); pKl = pti->KeyboardLayout; if (!pKl) goto cleanup; _SEH2_TRY { ProbeForWrite(pwszName, KL_NAMELENGTH*sizeof(WCHAR), 1); wcscpy(pwszName, pKl->spkf->awchKF); bRet = TRUE; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { SetLastNtError(_SEH2_GetExceptionCode()); } _SEH2_END; cleanup: UserLeave(); return bRet; }
/* NtUserMonitorFromPoint * * Returns a handle to the monitor containing the given point. * * Arguments * * pt * Point for which to find monitor * * dwFlags * Specifies the behaviour if the point isn't on any of the monitors. * * Return value * If the point is found a handle to the monitor is returned; if not the * return value depends on dwFlags */ HMONITOR APIENTRY NtUserMonitorFromPoint( IN POINT pt, IN DWORD dwFlags) { RECTL rc; HMONITOR hMonitor = NULL; /* Check if flags are valid */ if (dwFlags != MONITOR_DEFAULTTONULL && dwFlags != MONITOR_DEFAULTTOPRIMARY && dwFlags != MONITOR_DEFAULTTONEAREST) { EngSetLastError(ERROR_INVALID_FLAGS); return NULL; } /* Fill rect (bottom-right exclusive) */ rc.left = pt.x; rc.right = pt.x + 1; rc.top = pt.y; rc.bottom = pt.y + 1; UserEnterShared(); /* Find intersecting monitor */ IntGetMonitorsFromRect(&rc, &hMonitor, NULL, 1, dwFlags); UserLeave(); return hMonitor; }
BOOL APIENTRY NtUserGetCaretPos( LPPOINT lpPoint) { PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; NTSTATUS Status; DECLARE_RETURN(BOOL); TRACE("Enter NtUserGetCaretPos\n"); UserEnterShared(); pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; Status = MmCopyToCaller(lpPoint, &(ThreadQueue->CaretInfo->Pos), sizeof(POINT)); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); RETURN(FALSE); } RETURN(TRUE); CLEANUP: TRACE("Leave NtUserGetCaretPos, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; }
ULONG APIENTRY NtUserCopyAcceleratorTable( HACCEL hAccel, LPACCEL Entries, ULONG EntriesCount) { PACCELERATOR_TABLE Accel; ULONG Ret; DECLARE_RETURN(int); TRACE("Enter NtUserCopyAcceleratorTable\n"); UserEnterShared(); Accel = UserGetAccelObject(hAccel); if (!Accel) { RETURN(0); } /* If Entries is NULL return table size */ if (!Entries) { RETURN(Accel->Count); } /* Don't overrun */ if (Accel->Count < EntriesCount) EntriesCount = Accel->Count; Ret = 0; _SEH2_TRY { ProbeForWrite(Entries, EntriesCount*sizeof(Entries[0]), 4); for (Ret = 0; Ret < EntriesCount; Ret++) { Entries[Ret].fVirt = Accel->Table[Ret].fVirt; Entries[Ret].key = Accel->Table[Ret].key; Entries[Ret].cmd = Accel->Table[Ret].cmd; } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { SetLastNtError(_SEH2_GetExceptionCode()); Ret = 0; } _SEH2_END; RETURN(Ret); CLEANUP: TRACE("Leave NtUserCopyAcceleratorTable, ret=%i\n", _ret_); UserLeave(); END_CLEANUP; }
/* * NtUserGetKeyboardLayoutList * * Returns list of loaded keyboard layouts in system */ UINT APIENTRY NtUserGetKeyboardLayoutList( ULONG nBuff, HKL *pHklBuff) { UINT uRet = 0; PKL pKl; if (!pHklBuff) nBuff = 0; UserEnterShared(); if (!gspklBaseLayout) { UserLeave(); return 0; } pKl = gspklBaseLayout; if (nBuff == 0) { do { uRet++; pKl = pKl->pklNext; } while (pKl != gspklBaseLayout); } else { _SEH2_TRY { ProbeForWrite(pHklBuff, nBuff*sizeof(HKL), 4); while (uRet < nBuff) { pHklBuff[uRet] = pKl->hkl; uRet++; pKl = pKl->pklNext; if (pKl == gspklBaseLayout) break; } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { SetLastNtError(_SEH2_GetExceptionCode()); uRet = 0; } _SEH2_END; } UserLeave(); return uRet; }
DWORD APIENTRY NtUserCallHwnd( HWND hWnd, DWORD Routine) { switch (Routine) { case HWND_ROUTINE_GETWNDCONTEXTHLPID: { PWND Window; DWORD HelpId; UserEnterShared(); if (!(Window = UserGetWindowObject(hWnd))) { UserLeave(); return 0; } HelpId = (DWORD)(DWORD_PTR)UserGetProp(Window, gpsi->atomContextHelpIdProp, TRUE); UserLeave(); return HelpId; } case HWND_ROUTINE_REGISTERSHELLHOOKWINDOW: if (IntIsWindow(hWnd)) return IntRegisterShellHookWindow(hWnd); return FALSE; break; case HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW: if (IntIsWindow(hWnd)) return IntDeRegisterShellHookWindow(hWnd); return FALSE; case HWND_ROUTINE_SETMSGBOX: { PWND Window; UserEnterExclusive(); if ((Window = UserGetWindowObject(hWnd))) { Window->state |= WNDS_MSGBOX; } UserLeave(); return FALSE; } } STUB; return 0; }
UINT APIENTRY NtUserGetCaretBlinkTime(VOID) { UINT ret; UserEnterShared(); ret = gpsi->dtCaretBlink; UserLeave(); return ret; }
INT APIENTRY NtUserGetPriorityClipboardFormat(UINT *paFormatPriorityList, INT cFormats) { INT i, iRet = 0; PWINSTATION_OBJECT pWinStaObj; UserEnterShared(); pWinStaObj = IntGetWinStaForCbAccess(); if (!pWinStaObj) goto cleanup; if (pWinStaObj->pClipBase == NULL) { iRet = 0; } else { _SEH2_TRY { ProbeForRead(paFormatPriorityList, cFormats * sizeof(UINT), sizeof(UINT)); iRet = -1; for (i = 0; i < cFormats; ++i) { if (IntIsFormatAvailable(pWinStaObj, paFormatPriorityList[i])) { iRet = paFormatPriorityList[i]; break; } } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { SetLastNtError(_SEH2_GetExceptionCode()); } _SEH2_END; } ObDereferenceObject(pWinStaObj); cleanup: UserLeave(); return iRet; }
BOOL APIENTRY NtUserValidateTimerCallback( HWND hWnd, WPARAM wParam, LPARAM lParam) { BOOL Ret = FALSE; UserEnterShared(); Ret = ValidateTimerCallback(PsGetCurrentThreadWin32Thread(), lParam); UserLeave(); return Ret; }
UINT APIENTRY NtUserGetCaretBlinkTime(VOID) { DECLARE_RETURN(UINT); TRACE("Enter NtUserGetCaretBlinkTime\n"); UserEnterShared(); RETURN(IntGetCaretBlinkTime()); CLEANUP: TRACE("Leave NtUserGetCaretBlinkTime, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; }
HWND APIENTRY NtUserGetOpenClipboardWindow(VOID) { HWND ret = NULL; UserEnterShared(); if (ClipboardWindow) { ret = ClipboardWindow->head.h; } UserLeave(); return ret; }
/* * CreateSystemThreads * * Called form dedicated thread in CSRSS. RIT is started in context of this * thread because it needs valid Win32 process with TEB initialized. */ DWORD NTAPI CreateSystemThreads(UINT Type) { UserLeave(); switch (Type) { case 0: RawInputThreadMain(); break; case 1: DesktopThreadMain(); break; default: ERR("Wrong type: %x\n", Type); } UserEnterShared(); return 0; }
UINT APIENTRY NtUserGetDoubleClickTime(VOID) { UINT Result; TRACE("Enter NtUserGetDoubleClickTime\n"); UserEnterShared(); // FIXME: Check if this works on non-interactive winsta Result = gspv.iDblClickTime; TRACE("Leave NtUserGetDoubleClickTime, ret=%u\n", Result); UserLeave(); return Result; }
NTSTATUS APIENTRY NtUserCreateLocalMemHandle( HANDLE hMem, PVOID pData, DWORD cbData, DWORD *pcbData) { PCLIPBOARDDATA pMemObj; NTSTATUS Status = STATUS_SUCCESS; UserEnterShared(); /* Get Clipboard data object */ pMemObj = (PCLIPBOARDDATA)UserGetObject(gHandleTable, hMem, TYPE_CLIPDATA); if (!pMemObj) { Status = STATUS_INVALID_HANDLE; goto cleanup; } /* Don't overrun */ if (cbData > pMemObj->cbData) cbData = pMemObj->cbData; /* Copy data to usermode */ _SEH2_TRY { if (pcbData) { ProbeForWrite(pcbData, sizeof(*pcbData), 1); *pcbData = pMemObj->cbData; } ProbeForWrite(pData, cbData, 1); memcpy(pData, pMemObj->Data, cbData); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END; cleanup: UserLeave(); return Status; }
HMONITOR APIENTRY NtUserMonitorFromWindow( IN HWND hWnd, IN DWORD dwFlags) { PWND pWnd; HMONITOR hMonitor = NULL; RECTL Rect = {0, 0, 0, 0}; TRACE("Enter NtUserMonitorFromWindow\n"); /* Check if flags are valid */ if (dwFlags != MONITOR_DEFAULTTONULL && dwFlags != MONITOR_DEFAULTTOPRIMARY && dwFlags != MONITOR_DEFAULTTONEAREST) { EngSetLastError(ERROR_INVALID_FLAGS); return NULL; } UserEnterShared(); /* If window is given, use it first */ if (hWnd) { /* Get window object */ pWnd = UserGetWindowObject(hWnd); if (!pWnd) goto cleanup; /* Find only monitors which have intersection with given window */ Rect.left = Rect.right = pWnd->rcWindow.left; Rect.top = Rect.bottom = pWnd->rcWindow.bottom; } /* Find monitors now */ IntGetMonitorsFromRect(&Rect, &hMonitor, NULL, 1, dwFlags); cleanup: TRACE("Leave NtUserMonitorFromWindow, ret=%p\n", hMonitor); UserLeave(); return hMonitor; }
DWORD APIENTRY NtUserCountClipboardFormats(VOID) { DWORD cFormats = 0; PWINSTATION_OBJECT pWinStaObj = NULL; UserEnterShared(); pWinStaObj = IntGetWinStaForCbAccess(); if (!pWinStaObj) goto cleanup; cFormats = pWinStaObj->cNumClipFormats; ObDereferenceObject(pWinStaObj); cleanup: UserLeave(); return cFormats; }
INT APIENTRY NtUserGetClipboardFormatName(UINT fmt, LPWSTR lpszFormatName, INT cchMaxCount) { INT iRet = 0; UserEnterShared(); /* If the format is built-in we fail */ if (fmt < 0xc000) { /* Registetrated formats are >= 0xc000 */ goto cleanup; } if (cchMaxCount < 1 || !lpszFormatName) { EngSetLastError(ERROR_INVALID_PARAMETER); goto cleanup; } _SEH2_TRY { ProbeForWrite(lpszFormatName, cchMaxCount * sizeof(WCHAR), 1); iRet = IntGetAtomName((RTL_ATOM)fmt, lpszFormatName, cchMaxCount * sizeof(WCHAR)); iRet /= sizeof(WCHAR); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { SetLastNtError(_SEH2_GetExceptionCode()); } _SEH2_END; cleanup: UserLeave(); return iRet; }
HWND APIENTRY NtUserGetClipboardViewer(VOID) { HWND hWnd = NULL; PWINSTATION_OBJECT pWinStaObj; UserEnterShared(); pWinStaObj = IntGetWinStaForCbAccess(); if(!pWinStaObj) goto cleanup; if (pWinStaObj->spwndClipViewer) hWnd = pWinStaObj->spwndClipViewer->head.h; ObDereferenceObject(pWinStaObj); cleanup: UserLeave(); return hWnd; }
DWORD APIENTRY NtUserGetClipboardSequenceNumber(VOID) { DWORD dwRet = 0; PWINSTATION_OBJECT pWinStaObj; UserEnterShared(); pWinStaObj = IntGetWinStaForCbAccess(); if (!pWinStaObj) goto cleanup; /* Get windowstation sequence number */ dwRet = (DWORD)pWinStaObj->iClipSequenceNumber; ObDereferenceObject(pWinStaObj); cleanup: UserLeave(); return dwRet; }
HMONITOR APIENTRY NtUserMonitorFromWindow( IN HWND hWnd, IN DWORD dwFlags) { PWND Window; HMONITOR hMonitor = NULL; RECTL Rect; DECLARE_RETURN(HMONITOR); TRACE("Enter NtUserMonitorFromWindow\n"); UserEnterShared(); if (!(Window = UserGetWindowObject(hWnd))) { if (dwFlags == MONITOR_DEFAULTTONULL) { RETURN(hMonitor); } IntGetMonitorsFromRect(NULL, &hMonitor, NULL, 1, dwFlags); RETURN(hMonitor); } Rect.left = Rect.right = Window->rcWindow.left; Rect.top = Rect.bottom = Window->rcWindow.bottom; IntGetMonitorsFromRect(&Rect, &hMonitor, NULL, 1, dwFlags); RETURN(hMonitor); CLEANUP: TRACE("Leave NtUserMonitorFromWindow, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; }
BOOL APIENTRY NtUserIsClipboardFormatAvailable(UINT fmt) { BOOL bRet = FALSE; PWINSTATION_OBJECT pWinStaObj; TRACE("NtUserIsClipboardFormatAvailable(%x)\n", fmt); UserEnterShared(); pWinStaObj = IntGetWinStaForCbAccess(); if (!pWinStaObj) goto cleanup; if (IntIsFormatAvailable(pWinStaObj, fmt)) bRet = TRUE; ObDereferenceObject(pWinStaObj); cleanup: UserLeave(); return bRet; }
BOOL APIENTRY NtUserGetGUIThreadInfo( DWORD idThread, /* If NULL use foreground thread */ LPGUITHREADINFO lpgui) { NTSTATUS Status; PTHRDCARETINFO CaretInfo; GUITHREADINFO SafeGui; PDESKTOP Desktop; PUSER_MESSAGE_QUEUE MsgQueue; PTHREADINFO W32Thread; PETHREAD Thread = NULL; DECLARE_RETURN(BOOLEAN); TRACE("Enter NtUserGetGUIThreadInfo\n"); UserEnterShared(); Status = MmCopyFromCaller(&SafeGui, lpgui, sizeof(DWORD)); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); RETURN( FALSE); } if(SafeGui.cbSize != sizeof(GUITHREADINFO)) { EngSetLastError(ERROR_INVALID_PARAMETER); RETURN( FALSE); } if (idThread) { Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)idThread, &Thread); if(!NT_SUCCESS(Status)) { EngSetLastError(ERROR_ACCESS_DENIED); RETURN( FALSE); } W32Thread = (PTHREADINFO)Thread->Tcb.Win32Thread; Desktop = W32Thread->rpdesk; if (!Thread || !Desktop ) { if(Thread) ObDereferenceObject(Thread); EngSetLastError(ERROR_ACCESS_DENIED); RETURN( FALSE); } if ( W32Thread->MessageQueue ) MsgQueue = W32Thread->MessageQueue; else { if ( Desktop ) MsgQueue = Desktop->ActiveMessageQueue; } } else { /* Get the foreground thread */ /* FIXME: Handle NULL queue properly? */ MsgQueue = IntGetFocusMessageQueue(); if(!MsgQueue) { EngSetLastError(ERROR_ACCESS_DENIED); RETURN( FALSE); } } CaretInfo = &MsgQueue->CaretInfo; SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0); /* if (W32Thread->pMenuState->pGlobalPopupMenu) { SafeGui.flags |= GUI_INMENUMODE; if (W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify) SafeGui.hwndMenuOwner = UserHMGetHandle(W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify); if (W32Thread->pMenuState->pGlobalPopupMenu->fHasMenuBar) { if (W32Thread->pMenuState->pGlobalPopupMenu->fIsSysMenu) { SafeGui.flags |= GUI_SYSTEMMENUMODE; } } else { SafeGui.flags |= GUI_POPUPMENUMODE; } } */ SafeGui.hwndMenuOwner = MsgQueue->MenuOwner; if (MsgQueue->MenuOwner) SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState; if (MsgQueue->MoveSize) SafeGui.flags |= GUI_INMOVESIZE; /* FIXME: Add flag GUI_16BITTASK */ SafeGui.hwndActive = MsgQueue->spwndActive ? UserHMGetHandle(MsgQueue->spwndActive) : 0; SafeGui.hwndFocus = MsgQueue->spwndFocus ? UserHMGetHandle(MsgQueue->spwndFocus) : 0; SafeGui.hwndCapture = MsgQueue->spwndCapture ? UserHMGetHandle(MsgQueue->spwndCapture) : 0; SafeGui.hwndMoveSize = MsgQueue->MoveSize; SafeGui.hwndCaret = CaretInfo->hWnd; SafeGui.rcCaret.left = CaretInfo->Pos.x; SafeGui.rcCaret.top = CaretInfo->Pos.y; SafeGui.rcCaret.right = SafeGui.rcCaret.left + CaretInfo->Size.cx; SafeGui.rcCaret.bottom = SafeGui.rcCaret.top + CaretInfo->Size.cy; if (idThread) ObDereferenceObject(Thread); Status = MmCopyToCaller(lpgui, &SafeGui, sizeof(GUITHREADINFO)); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); RETURN( FALSE); } RETURN( TRUE); CLEANUP: TRACE("Leave NtUserGetGUIThreadInfo, ret=%u\n",_ret_); UserLeave(); END_CLEANUP; }
DWORD APIENTRY NtUserGetGuiResources( HANDLE hProcess, DWORD uiFlags) { PEPROCESS Process; PPROCESSINFO W32Process; NTSTATUS Status; DWORD Ret = 0; DECLARE_RETURN(DWORD); TRACE("Enter NtUserGetGuiResources\n"); UserEnterShared(); Status = ObReferenceObjectByHandle(hProcess, PROCESS_QUERY_INFORMATION, *PsProcessType, ExGetPreviousMode(), (PVOID*)&Process, NULL); if(!NT_SUCCESS(Status)) { SetLastNtError(Status); RETURN( 0); } W32Process = (PPROCESSINFO)Process->Win32Process; if(!W32Process) { ObDereferenceObject(Process); EngSetLastError(ERROR_INVALID_PARAMETER); RETURN( 0); } switch(uiFlags) { case GR_GDIOBJECTS: { Ret = (DWORD)W32Process->GDIHandleCount; break; } case GR_USEROBJECTS: { Ret = (DWORD)W32Process->UserHandleCount; break; } default: { EngSetLastError(ERROR_INVALID_PARAMETER); break; } } ObDereferenceObject(Process); RETURN( Ret); CLEANUP: TRACE("Leave NtUserGetGuiResources, ret=%lu\n",_ret_); UserLeave(); END_CLEANUP; }
/* * @unimplemented */ DWORD_PTR APIENTRY NtUserGetThreadState( DWORD Routine) { DWORD_PTR ret = 0; TRACE("Enter NtUserGetThreadState\n"); if (Routine != THREADSTATE_GETTHREADINFO) { UserEnterShared(); } else { UserEnterExclusive(); } switch (Routine) { case THREADSTATE_GETTHREADINFO: GetW32ThreadInfo(); break; case THREADSTATE_FOCUSWINDOW: ret = (DWORD_PTR)IntGetThreadFocusWindow(); break; case THREADSTATE_CAPTUREWINDOW: /* FIXME: Should use UserEnterShared */ ret = (DWORD_PTR)IntGetCapture(); break; case THREADSTATE_PROGMANWINDOW: ret = (DWORD_PTR)GetW32ThreadInfo()->pDeskInfo->hProgmanWindow; break; case THREADSTATE_TASKMANWINDOW: ret = (DWORD_PTR)GetW32ThreadInfo()->pDeskInfo->hTaskManWindow; break; case THREADSTATE_ACTIVEWINDOW: ret = (DWORD_PTR)UserGetActiveWindow(); break; case THREADSTATE_INSENDMESSAGE: { PUSER_SENT_MESSAGE Message = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->pusmCurrent; TRACE("THREADSTATE_INSENDMESSAGE\n"); ret = ISMEX_NOSEND; if (Message) { if (Message->ptiSender) ret = ISMEX_SEND; else { if (Message->CompletionCallback) ret = ISMEX_CALLBACK; else ret = ISMEX_NOTIFY; } /* If ReplyMessage */ if (Message->QS_Flags & QS_SMRESULT) ret |= ISMEX_REPLIED; } break; } case THREADSTATE_GETMESSAGETIME: ret = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->timeLast; break; case THREADSTATE_UPTIMELASTREAD: { PTHREADINFO pti; pti = PsGetCurrentThreadWin32Thread(); pti->timeLast = EngGetTickCount32(); pti->pcti->tickLastMsgChecked = pti->timeLast; } break; case THREADSTATE_GETINPUTSTATE: ret = LOWORD(IntGetQueueStatus(QS_POSTMESSAGE|QS_TIMER|QS_PAINT|QS_SENDMESSAGE|QS_INPUT)) & (QS_KEY | QS_MOUSEBUTTON); break; case THREADSTATE_FOREGROUNDTHREAD: ret = (gpqForeground == GetW32ThreadInfo()->MessageQueue); break; case THREADSTATE_GETCURSOR: ret = (DWORD_PTR) (GetW32ThreadInfo()->MessageQueue->CursorObject ? UserHMGetHandle(GetW32ThreadInfo()->MessageQueue->CursorObject) : 0); break; case THREADSTATE_GETMESSAGEEXTRAINFO: ret = (DWORD_PTR)MsqGetMessageExtraInfo(); break; } TRACE("Leave NtUserGetThreadState, ret=%lu\n", ret); UserLeave(); return ret; }
HANDLE APIENTRY NtUserGetClipboardData(UINT fmt, PGETCLIPBDATA pgcd) { HANDLE hRet = NULL; PCLIP pElement; PWINSTATION_OBJECT pWinStaObj = NULL; TRACE("NtUserGetClipboardData(%x, %p)\n", fmt, pgcd); UserEnterShared(); pWinStaObj = IntGetWinStaForCbAccess(); if (!pWinStaObj) goto cleanup; if (!IntIsClipboardOpenByMe(pWinStaObj)) { EngSetLastError(ERROR_CLIPBOARD_NOT_OPEN); goto cleanup; } pElement = IntIsFormatAvailable(pWinStaObj, fmt); if (pElement && IS_DATA_DELAYED(pElement) && pWinStaObj->spwndClipOwner) { /* Send WM_RENDERFORMAT message */ pWinStaObj->fInDelayedRendering = TRUE; co_IntSendMessage(pWinStaObj->spwndClipOwner->head.h, WM_RENDERFORMAT, (WPARAM)fmt, 0); pWinStaObj->fInDelayedRendering = FALSE; /* Data should be in clipboard now */ pElement = IntIsFormatAvailable(pWinStaObj, fmt); } if (!pElement || IS_DATA_DELAYED(pElement)) goto cleanup; if (IS_DATA_SYNTHESIZED(pElement)) { /* Note: Data is synthesized in usermode */ /* TODO: Add more formats */ switch (fmt) { case CF_UNICODETEXT: case CF_TEXT: case CF_OEMTEXT: pElement = IntIsFormatAvailable(pWinStaObj, CF_UNICODETEXT); if (IS_DATA_SYNTHESIZED(pElement)) pElement = IntIsFormatAvailable(pWinStaObj, CF_TEXT); if (IS_DATA_SYNTHESIZED(pElement)) pElement = IntIsFormatAvailable(pWinStaObj, CF_OEMTEXT); break; case CF_BITMAP: IntSynthesizeBitmap(pWinStaObj, pElement); break; default: ASSERT(FALSE); } } _SEH2_TRY { ProbeForWrite(pgcd, sizeof(*pgcd), 1); pgcd->uFmtRet = pElement->fmt; pgcd->fGlobalHandle = pElement->fGlobalHandle; /* Text and bitmap needs more data */ if (fmt == CF_TEXT) { PCLIP pLocaleEl; pLocaleEl = IntIsFormatAvailable(pWinStaObj, CF_LOCALE); if (pLocaleEl && !IS_DATA_DELAYED(pLocaleEl)) pgcd->hLocale = pLocaleEl->hData; } else if (fmt == CF_BITMAP) { PCLIP pPaletteEl; pPaletteEl = IntIsFormatAvailable(pWinStaObj, CF_PALETTE); if (pPaletteEl && !IS_DATA_DELAYED(pPaletteEl)) pgcd->hPalette = pPaletteEl->hData; } hRet = pElement->hData; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { SetLastNtError(_SEH2_GetExceptionCode()); } _SEH2_END; cleanup: if(pWinStaObj) ObDereferenceObject(pWinStaObj); UserLeave(); TRACE("NtUserGetClipboardData returns %p\n", hRet); return hRet; }
NTSTATUS APIENTRY NtUserBuildPropList(HWND hWnd, LPVOID Buffer, DWORD BufferSize, DWORD *Count) { PWND Window; PPROPERTY Property; PLIST_ENTRY ListEntry; PROPLISTITEM listitem, *li; NTSTATUS Status; DWORD Cnt = 0; DECLARE_RETURN(NTSTATUS); TRACE("Enter NtUserBuildPropList\n"); UserEnterShared(); if (!(Window = UserGetWindowObject(hWnd))) { RETURN( STATUS_INVALID_HANDLE); } if(Buffer) { if(!BufferSize || (BufferSize % sizeof(PROPLISTITEM) != 0)) { RETURN( STATUS_INVALID_PARAMETER); } /* copy list */ li = (PROPLISTITEM *)Buffer; ListEntry = Window->PropListHead.Flink; while((BufferSize >= sizeof(PROPLISTITEM)) && (ListEntry != &Window->PropListHead)) { Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry); listitem.Atom = Property->Atom; listitem.Data = Property->Data; Status = MmCopyToCaller(li, &listitem, sizeof(PROPLISTITEM)); if(!NT_SUCCESS(Status)) { RETURN( Status); } BufferSize -= sizeof(PROPLISTITEM); Cnt++; li++; ListEntry = ListEntry->Flink; } } else { Cnt = Window->PropListItems * sizeof(PROPLISTITEM); } if(Count) { Status = MmCopyToCaller(Count, &Cnt, sizeof(DWORD)); if(!NT_SUCCESS(Status)) { RETURN( Status); } } RETURN( STATUS_SUCCESS); CLEANUP: TRACE("Leave NtUserBuildPropList, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; }
int APIENTRY NtUserTranslateAccelerator( HWND hWnd, HACCEL hAccel, LPMSG pUnsafeMessage) { PWND Window = NULL; PACCELERATOR_TABLE Accel = NULL; ULONG i; MSG Message; USER_REFERENCE_ENTRY AccelRef, WindowRef; DECLARE_RETURN(int); TRACE("NtUserTranslateAccelerator(hWnd %p, hAccel %p, Message %p)\n", hWnd, hAccel, pUnsafeMessage); UserEnterShared(); if (hWnd == NULL) { RETURN( 0); } _SEH2_TRY { ProbeForRead(pUnsafeMessage, sizeof(MSG), 4); RtlCopyMemory(&Message, pUnsafeMessage, sizeof(MSG)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { SetLastNtError(_SEH2_GetExceptionCode()); _SEH2_YIELD(RETURN( 0)); } _SEH2_END; if ((Message.message != WM_KEYDOWN) && (Message.message != WM_SYSKEYDOWN) && (Message.message != WM_SYSCHAR) && (Message.message != WM_CHAR)) { RETURN( 0); } Accel = UserGetAccelObject(hAccel); if (!Accel) { RETURN( 0); } UserRefObjectCo(Accel, &AccelRef); Window = UserGetWindowObject(hWnd); if (!Window) { RETURN( 0); } UserRefObjectCo(Window, &WindowRef); /* FIXME: Associate AcceleratorTable with the current thread */ for (i = 0; i < Accel->Count; i++) { if (co_IntTranslateAccelerator(Window, &Message, &Accel->Table[i])) { RETURN( 1); } /* Undocumented feature... */ if (Accel->Table[i].fVirt & FVIRT_TBL_END) break; } RETURN( 0); CLEANUP: if (Window) UserDerefObjectCo(Window); if (Accel) UserDerefObjectCo(Accel); TRACE("NtUserTranslateAccelerator returns %d\n", _ret_); UserLeave(); END_CLEANUP; }
HANDLE APIENTRY NtUserGetClipboardData(UINT uFormat, PVOID pBuffer) { HANDLE ret = NULL; UserEnterShared(); if (intIsClipboardOpenByMe()) { /* when Unknown1 is zero, we returns to user32 the data size */ if (!pBuffer) { PCLIPBOARDELEMENT data = intIsFormatAvailable(uFormat); if (data) { /* format exists in clipboard */ if (data->size == DATA_DELAYED_RENDER) { /* tell owner what data needs to be rendered */ if (ClipboardOwnerWindow) { ASSERT(ClipboardOwnerWindow->head.h); co_IntSendMessage(ClipboardOwnerWindow->head.h, WM_RENDERFORMAT, (WPARAM)uFormat, 0); data = intIsFormatAvailable(uFormat); ASSERT(data->size); ret = (HANDLE)(ULONG_PTR)data->size; } } else { if (data->size == DATA_SYNTHESIZED_RENDER) { data->size = synthesizeData(uFormat); } } ret = (HANDLE)(ULONG_PTR)data->size; } else { /* there is no data in this format */ //ret = (HANDLE)FALSE; } } else { PCLIPBOARDELEMENT data = intIsFormatAvailable(uFormat); if (data) { if (data->size == DATA_DELAYED_RENDER) { // we rendered it in 1st call of getclipboard data } else { if (data->size == DATA_SYNTHESIZED_RENDER) { if (uFormat == CF_BITMAP) { /* BITMAP & METAFILEs returns a GDI handle */ PCLIPBOARDELEMENT data = intIsFormatAvailable(CF_DIB); if (data) { ret = renderBITMAPfromDIB(data->hData); } } else { ret = (HANDLE)pBuffer; _SEH2_TRY { ProbeForWrite(pBuffer, synthesizedDataSize, 1); memcpy(pBuffer, (PCHAR)synthesizedData, synthesizedDataSize); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ret = NULL; } _SEH2_END freeSynthesizedData(); } } else { ret = (HANDLE)pBuffer; _SEH2_TRY { ProbeForWrite(pBuffer, data->size, 1); memcpy(pBuffer, (PCHAR)data->hData, data->size); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ret = NULL; } _SEH2_END } } } } }
//NTSTATUS BOOL NTAPI NtUserEnumDisplayDevices( PUNICODE_STRING pustrDevice, DWORD iDevNum, PDISPLAY_DEVICEW pDisplayDevice, DWORD dwFlags) { UNICODE_STRING ustrDevice; WCHAR awcDevice[CCHDEVICENAME]; DISPLAY_DEVICEW dispdev; NTSTATUS Status; TRACE("Enter NtUserEnumDisplayDevices(%wZ, %ld)\n", pustrDevice, iDevNum); dispdev.cb = sizeof(dispdev); if (pustrDevice) { /* Initialize destination string */ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice)); _SEH2_TRY { /* Probe the UNICODE_STRING and the buffer */ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1); ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1); /* Copy the string */ RtlCopyUnicodeString(&ustrDevice, pustrDevice); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { // _SEH2_YIELD(return _SEH2_GetExceptionCode()); _SEH2_YIELD(return NT_SUCCESS(_SEH2_GetExceptionCode())); } _SEH2_END if (ustrDevice.Length > 0) pustrDevice = &ustrDevice; else pustrDevice = NULL; } /* If name is given only iDevNum==0 gives results */ if (pustrDevice && iDevNum != 0) return FALSE; /* Acquire global USER lock */ UserEnterShared(); /* Call the internal function */ Status = UserEnumDisplayDevices(pustrDevice, iDevNum, &dispdev, dwFlags); /* Release lock */ UserLeave(); /* On success copy data to caller */ if (NT_SUCCESS(Status)) { /* Enter SEH */ _SEH2_TRY { /* First probe the cb field */ ProbeForWrite(&pDisplayDevice->cb, sizeof(DWORD), 1); /* Check the buffer size */ if (pDisplayDevice->cb) { /* Probe the output buffer */ pDisplayDevice->cb = min(pDisplayDevice->cb, sizeof(dispdev)); ProbeForWrite(pDisplayDevice, pDisplayDevice->cb, 1); /* Copy as much as the given buffer allows */ RtlCopyMemory(pDisplayDevice, &dispdev, pDisplayDevice->cb); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END } TRACE("Leave NtUserEnumDisplayDevices, Status = 0x%lx\n", Status); /* Return the result */ // return Status; return NT_SUCCESS(Status); // FIXME }
NTSTATUS APIENTRY NtUserEnumDisplaySettings( IN PUNICODE_STRING pustrDevice, IN DWORD iModeNum, OUT LPDEVMODEW lpDevMode, IN DWORD dwFlags) { UNICODE_STRING ustrDevice; WCHAR awcDevice[CCHDEVICENAME]; NTSTATUS Status; ULONG cbSize, cbExtra; DEVMODEW dmReg, *pdm; TRACE("Enter NtUserEnumDisplaySettings(%wZ, %ld, %p, 0x%lx)\n", pustrDevice, iModeNum, lpDevMode, dwFlags); if (pustrDevice) { /* Initialize destination string */ RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice)); _SEH2_TRY { /* Probe the UNICODE_STRING and the buffer */ ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1); ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1); /* Copy the string */ RtlCopyUnicodeString(&ustrDevice, pustrDevice); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END pustrDevice = &ustrDevice; } /* Acquire global USER lock */ UserEnterShared(); if (iModeNum == ENUM_REGISTRY_SETTINGS) { /* Get the registry settings */ Status = UserEnumRegistryDisplaySettings(pustrDevice, &dmReg); pdm = &dmReg; } else if (iModeNum == ENUM_CURRENT_SETTINGS) { /* Get the current settings */ Status = UserEnumCurrentDisplaySettings(pustrDevice, &pdm); } else { /* Get specified settings */ Status = UserEnumDisplaySettings(pustrDevice, iModeNum, &pdm, dwFlags); } /* Release lock */ UserLeave(); /* Did we succeed? */ if (NT_SUCCESS(Status)) { /* Copy some information back */ _SEH2_TRY { ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1); cbSize = lpDevMode->dmSize; cbExtra = lpDevMode->dmDriverExtra; ProbeForWrite(lpDevMode, cbSize + cbExtra, 1); /* Output what we got */ RtlCopyMemory(lpDevMode, pdm, min(cbSize, pdm->dmSize)); /* Output private/extra driver data */ if (cbExtra > 0 && pdm->dmDriverExtra > 0) { RtlCopyMemory((PCHAR)lpDevMode + cbSize, (PCHAR)pdm + pdm->dmSize, min(cbExtra, pdm->dmDriverExtra)); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END; } return Status; }