1 /* $Id: misc.c,v 1.43 2004/01/26 08:44:51 weiden Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Misc User funcs
6 * FILE: subsys/win32k/ntuser/misc.c
7 * PROGRAMER: Ge van Geldorp (ge@gse.nl)
11 #include <ddk/ntddk.h>
12 #include <ddk/ntddmou.h>
13 #include <win32k/win32k.h>
14 #include <win32k/dc.h>
15 #include <internal/safe.h>
16 #include <include/error.h>
17 #include <include/window.h>
18 #include <include/painting.h>
19 #include <include/dce.h>
20 #include <include/mouse.h>
21 #include <include/winsta.h>
22 #include <include/caret.h>
23 #include <include/object.h>
24 #include <include/focus.h>
25 #include <include/clipboard.h>
26 #include <include/msgqueue.h>
27 #include <include/desktop.h>
28 #include <include/text.h>
33 void W32kRegisterPrimitiveMessageQueue() {
34 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
35 if( !pmPrimitiveMessageQueue
) {
37 pThread
= PsGetWin32Thread();
38 if( pThread
&& pThread
->MessageQueue
) {
39 pmPrimitiveMessageQueue
= pThread
->MessageQueue
;
40 DPRINT( "Installed primitive input queue.\n" );
43 DPRINT1( "Alert! Someone is trying to steal the primitive queue.\n" );
47 PUSER_MESSAGE_QUEUE
W32kGetPrimitiveMessageQueue() {
48 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
49 return pmPrimitiveMessageQueue
;
57 NtUserCallNoParam(DWORD Routine
)
63 case NOPARAM_ROUTINE_REGISTER_PRIMITIVE
:
64 W32kRegisterPrimitiveMessageQueue();
68 case NOPARAM_ROUTINE_DESTROY_CARET
:
69 Result
= (DWORD
)IntDestroyCaret(PsGetCurrentThread()->Win32Thread
);
72 case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP
:
73 Result
= (DWORD
)IntInitMessagePumpHook();
76 case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP
:
77 Result
= (DWORD
)IntUninitMessagePumpHook();
80 case NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO
:
81 Result
= (DWORD
)MsqGetMessageExtraInfo();
85 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam\n");
86 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
103 PWINSTATION_OBJECT WinStaObject
;
104 PWINDOW_OBJECT WindowObject
;
108 case ONEPARAM_ROUTINE_GETMENU
:
109 WindowObject
= IntGetWindowObject((HWND
)Param
);
112 SetLastWin32Error(ERROR_INVALID_HANDLE
);
116 Result
= (DWORD
)WindowObject
->IDMenu
;
118 IntReleaseWindowObject(WindowObject
);
121 case ONEPARAM_ROUTINE_ISWINDOWUNICODE
:
122 WindowObject
= IntGetWindowObject((HWND
)Param
);
125 SetLastWin32Error(ERROR_INVALID_HANDLE
);
128 Result
= WindowObject
->Unicode
;
129 IntReleaseWindowObject(WindowObject
);
132 case ONEPARAM_ROUTINE_WINDOWFROMDC
:
133 return (DWORD
)IntWindowFromDC((HDC
)Param
);
135 case ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID
:
136 WindowObject
= IntGetWindowObject((HWND
)Param
);
139 SetLastWin32Error(ERROR_INVALID_HANDLE
);
143 Result
= WindowObject
->ContextHelpId
;
145 IntReleaseWindowObject(WindowObject
);
148 case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON
:
149 Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
153 if (!NT_SUCCESS(Status
))
156 Result
= (DWORD
)IntSwapMouseButton(WinStaObject
, (BOOL
)Param
);
158 ObDereferenceObject(WinStaObject
);
161 case ONEPARAM_ROUTINE_SWITCHCARETSHOWING
:
162 return (DWORD
)IntSwitchCaretShowing((PVOID
)Param
);
164 case ONEPARAM_ROUTINE_SETCARETBLINKTIME
:
165 return (DWORD
)IntSetCaretBlinkTime((UINT
)Param
);
167 case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS
:
168 return (DWORD
)IntEnumClipboardFormats((UINT
)Param
);
170 case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO
:
171 return (DWORD
)MsqSetMessageExtraInfo((LPARAM
)Param
);
173 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam()\n Param=0x%x\n",
175 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
191 PWINDOW_OBJECT WindowObject
;
192 PSYSTEM_CURSORINFO CurInfo
;
193 PWINSTATION_OBJECT WinStaObject
;
198 case TWOPARAM_ROUTINE_SETMENUITEMRECT
:
202 case TWOPARAM_ROUTINE_SETGUITHRDHANDLE
:
205 PUSER_MESSAGE_QUEUE MsgQueue
= PsGetCurrentThread()->Win32Thread
->MessageQueue
;
209 case TPR_SGTH_ACTIVE
:
210 hwnd
= &MsgQueue
->ActiveWindow
;
213 hwnd
= &MsgQueue
->FocusWindow
;
215 case TPR_SGTH_CAPTURE
:
216 hwnd
= &MsgQueue
->CaptureWindow
;
218 case TPR_SGTH_MENUOWNER
:
219 hwnd
= &MsgQueue
->MenuOwner
;
221 case TPR_SGTH_MOVESIZE
:
222 hwnd
= &MsgQueue
->MoveSize
;
225 hwnd
= &MsgQueue
->CaretInfo
->hWnd
;
230 return (DWORD
)(*hwnd
= (HWND
)Param2
);
233 case TWOPARAM_ROUTINE_ENABLEWINDOW
:
237 case TWOPARAM_ROUTINE_UNKNOWN
:
241 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS
:
245 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW
:
249 case TWOPARAM_ROUTINE_VALIDATERGN
:
250 return (DWORD
)NtUserValidateRgn((HWND
) Param1
, (HRGN
) Param2
);
252 case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID
:
253 WindowObject
= IntGetWindowObject((HWND
)Param1
);
256 SetLastWin32Error(ERROR_INVALID_HANDLE
);
260 WindowObject
->ContextHelpId
= Param2
;
262 IntReleaseWindowObject(WindowObject
);
265 case TWOPARAM_ROUTINE_CURSORPOSITION
:
268 Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
272 if (!NT_SUCCESS(Status
))
277 /* set cursor position */
279 Status
= MmCopyFromCaller(&Pos
, (PPOINT
)Param1
, sizeof(POINT
));
280 if(!NT_SUCCESS(Status
))
282 ObDereferenceObject(WinStaObject
);
283 SetLastNtError(Status
);
287 CurInfo
= &WinStaObject
->SystemCursor
;
288 /* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
290 //CheckClipCursor(&Pos->x, &Pos->y, CurInfo);
291 if((Pos
.x
!= CurInfo
->x
) || (Pos
.y
!= CurInfo
->y
))
293 MouseMoveCursor(Pos
.x
, Pos
.y
);
299 /* get cursor position */
300 /* FIXME - check if process has WINSTA_READATTRIBUTES */
301 Pos
.x
= WinStaObject
->SystemCursor
.x
;
302 Pos
.y
= WinStaObject
->SystemCursor
.y
;
304 Status
= MmCopyToCaller((PPOINT
)Param1
, &Pos
, sizeof(POINT
));
305 if(!NT_SUCCESS(Status
))
307 ObDereferenceObject(WinStaObject
);
308 SetLastNtError(Status
);
314 ObDereferenceObject(WinStaObject
);
318 case TWOPARAM_ROUTINE_SETCARETPOS
:
319 return (DWORD
)IntSetCaretPos((int)Param1
, (int)Param2
);
321 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam()\n Param1=0x%x Parm2=0x%x\n",
322 Routine
, Param1
, Param2
);
323 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
337 PWINDOW_OBJECT Window
;
339 Window
= IntGetWindowObject(hWnd
);
342 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
346 /* FIXME: Routine can be 0x53 - 0x5E */
349 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS
:
353 case HWNDLOCK_ROUTINE_DRAWMENUBAR
:
357 case HWNDLOCK_ROUTINE_REDRAWFRAME
:
361 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW
:
362 Ret
= IntSetForegroundWindow(Window
);
365 case HWNDLOCK_ROUTINE_UPDATEWINDOW
:
370 IntReleaseWindowObject(Window
);
383 case HWNDOPT_ROUTINE_SETPROGMANWINDOW
:
387 case HWNDOPT_ROUTINE_SETTASKMANWINDOW
:
399 NtUserGetThreadState(
405 return (DWORD
)IntGetThreadFocusWindow();
415 NtUserSystemParametersInfo(
421 static BOOL GradientCaptions
= TRUE
;
422 /* FIXME: This should be obtained from the registry */
423 static LOGFONTW CaptionFont
=
424 { 12, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
425 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, L
"" };
427 PWINSTATION_OBJECT WinStaObject
;
431 case SPI_SETDOUBLECLKWIDTH
:
432 case SPI_SETDOUBLECLKHEIGHT
:
433 case SPI_SETDOUBLECLICKTIME
:
435 Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
439 if (!NT_SUCCESS(Status
))
444 case SPI_SETDOUBLECLKWIDTH
:
445 /* FIXME limit the maximum value? */
446 WinStaObject
->SystemCursor
.DblClickWidth
= uiParam
;
448 case SPI_SETDOUBLECLKHEIGHT
:
449 /* FIXME limit the maximum value? */
450 WinStaObject
->SystemCursor
.DblClickHeight
= uiParam
;
452 case SPI_SETDOUBLECLICKTIME
:
453 /* FIXME limit the maximum time to 1000 ms? */
454 WinStaObject
->SystemCursor
.DblClickSpeed
= uiParam
;
458 /* FIXME save the value to the registry */
460 ObDereferenceObject(WinStaObject
);
463 case SPI_SETWORKAREA
:
465 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
469 /* FIXME - Set last error */
473 Status
= MmCopyFromCaller(Desktop
->WorkArea
, (PRECT
)pvParam
, sizeof(RECT
));
474 if(!NT_SUCCESS(Status
))
476 SetLastNtError(Status
);
482 case SPI_GETWORKAREA
:
485 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
489 /* FIXME - Set last error */
493 Rect
= IntGetDesktopWorkArea(Desktop
);
495 Status
= MmCopyToCaller((PRECT
)pvParam
, Desktop
->WorkArea
, sizeof(RECT
));
496 if(!NT_SUCCESS(Status
))
498 SetLastNtError(Status
);
504 case SPI_GETICONTITLELOGFONT
:
506 Status
= MmCopyToCaller(pvParam
, &CaptionFont
, sizeof(CaptionFont
));
507 if(!NT_SUCCESS(Status
))
509 SetLastNtError(Status
);
514 case SPI_GETNONCLIENTMETRICS
:
516 /* FIXME - use MmCopyToCaller() !!! */
517 LPNONCLIENTMETRICSW pMetrics
= (LPNONCLIENTMETRICSW
)pvParam
;
519 if (pMetrics
->cbSize
!= sizeof(NONCLIENTMETRICSW
) ||
520 uiParam
!= sizeof(NONCLIENTMETRICSW
))
525 memset((char *)pvParam
+ sizeof(pMetrics
->cbSize
), 0,
526 pMetrics
->cbSize
- sizeof(pMetrics
->cbSize
));
528 pMetrics
->iBorderWidth
= 1;
529 pMetrics
->iScrollWidth
= NtUserGetSystemMetrics(SM_CXVSCROLL
);
530 pMetrics
->iScrollHeight
= NtUserGetSystemMetrics(SM_CYHSCROLL
);
531 pMetrics
->iCaptionWidth
= NtUserGetSystemMetrics(SM_CXSIZE
);
532 pMetrics
->iCaptionHeight
= NtUserGetSystemMetrics(SM_CYSIZE
);
533 memcpy((LPVOID
)&(pMetrics
->lfCaptionFont
), &CaptionFont
, sizeof(CaptionFont
));
534 pMetrics
->lfCaptionFont
.lfWeight
= FW_BOLD
;
535 pMetrics
->iSmCaptionWidth
= NtUserGetSystemMetrics(SM_CXSMSIZE
);
536 pMetrics
->iSmCaptionHeight
= NtUserGetSystemMetrics(SM_CYSMSIZE
);
537 memcpy((LPVOID
)&(pMetrics
->lfSmCaptionFont
), &CaptionFont
, sizeof(CaptionFont
));
538 pMetrics
->iMenuWidth
= NtUserGetSystemMetrics(SM_CXMENUSIZE
);
539 pMetrics
->iMenuHeight
= NtUserGetSystemMetrics(SM_CYMENUSIZE
);
540 memcpy((LPVOID
)&(pMetrics
->lfMenuFont
), &CaptionFont
, sizeof(CaptionFont
));
541 memcpy((LPVOID
)&(pMetrics
->lfStatusFont
), &CaptionFont
, sizeof(CaptionFont
));
542 memcpy((LPVOID
)&(pMetrics
->lfMessageFont
), &CaptionFont
, sizeof(CaptionFont
));
545 case SPI_GETGRADIENTCAPTIONS
:
550 BOOL Ret
= GradientCaptions
;
552 hDC
= IntGetScreenDC();
556 SurfObj
= (PSURFOBJ
)AccessUserObject((ULONG
) dc
->Surface
);
558 Ret
= (SurfObj
->iBitmapFormat
> BMF_8BPP
);
562 Status
= MmCopyToCaller(pvParam
, &Ret
, sizeof(BOOL
));
563 if(!NT_SUCCESS(Status
))
565 SetLastNtError(Status
);
570 case SPI_SETGRADIENTCAPTIONS
:
572 Status
= MmCopyFromCaller(&GradientCaptions
, pvParam
, sizeof(BOOL
));
573 if(!NT_SUCCESS(Status
))
575 SetLastNtError(Status
);
580 case SPI_SETFONTSMOOTHING
:
584 Status
= MmCopyFromCaller(&Enable
, pvParam
, sizeof(BOOL
));
585 if(!NT_SUCCESS(Status
))
587 SetLastNtError(Status
);
591 IntEnableFontRendering(Enable
);
595 case SPI_GETFONTSMOOTHING
:
597 BOOL Enabled
= IntIsFontRenderingEnabled();
599 Status
= MmCopyToCaller(pvParam
, &Enabled
, sizeof(BOOL
));
600 if(!NT_SUCCESS(Status
))
602 SetLastNtError(Status
);
613 NtUserGetDoubleClickTime(VOID
)
617 PWINSTATION_OBJECT WinStaObject
;
619 Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
623 if (!NT_SUCCESS(Status
))
626 Result
= WinStaObject
->SystemCursor
.DblClickSpeed
;
628 ObDereferenceObject(WinStaObject
);
634 NtUserGetGUIThreadInfo(
636 LPGUITHREADINFO lpgui
)
639 PTHRDCARETINFO CaretInfo
;
640 GUITHREADINFO SafeGui
;
641 PDESKTOP_OBJECT Desktop
;
642 PUSER_MESSAGE_QUEUE MsgQueue
;
643 PETHREAD Thread
= NULL
;
645 Status
= MmCopyFromCaller(&SafeGui
, lpgui
, sizeof(DWORD
));
646 if(!NT_SUCCESS(Status
))
648 SetLastNtError(Status
);
652 if(SafeGui
.cbSize
!= sizeof(GUITHREADINFO
))
654 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
660 Status
= PsLookupThreadByThreadId((PVOID
)idThread
, &Thread
);
661 if(!NT_SUCCESS(Status
))
663 SetLastWin32Error(ERROR_ACCESS_DENIED
);
666 Desktop
= Thread
->Win32Thread
->Desktop
;
670 /* get the foreground thread */
671 PW32THREAD W32Thread
= PsGetCurrentThread()->Win32Thread
;
672 Desktop
= W32Thread
->Desktop
;
675 MsgQueue
= Desktop
->ActiveMessageQueue
;
678 Thread
= MsgQueue
->Thread
;
683 if(!Thread
|| !Desktop
)
685 if(idThread
&& Thread
)
686 ObDereferenceObject(Thread
);
687 SetLastWin32Error(ERROR_ACCESS_DENIED
);
691 MsgQueue
= (PUSER_MESSAGE_QUEUE
)Desktop
->ActiveMessageQueue
;
692 CaretInfo
= MsgQueue
->CaretInfo
;
694 SafeGui
.flags
= (CaretInfo
->Visible
? GUI_CARETBLINKING
: 0);
695 if(MsgQueue
->MenuOwner
)
696 SafeGui
.flags
|= GUI_INMENUMODE
| MsgQueue
->MenuState
;
697 if(MsgQueue
->MoveSize
)
698 SafeGui
.flags
|= GUI_INMOVESIZE
;
700 /* FIXME add flag GUI_16BITTASK */
702 SafeGui
.hwndActive
= MsgQueue
->ActiveWindow
;
703 SafeGui
.hwndFocus
= MsgQueue
->FocusWindow
;
704 SafeGui
.hwndCapture
= MsgQueue
->CaptureWindow
;
705 SafeGui
.hwndMenuOwner
= MsgQueue
->MenuOwner
;
706 SafeGui
.hwndMoveSize
= MsgQueue
->MoveSize
;
707 SafeGui
.hwndCaret
= CaretInfo
->hWnd
;
709 SafeGui
.rcCaret
.left
= CaretInfo
->Pos
.x
;
710 SafeGui
.rcCaret
.top
= CaretInfo
->Pos
.y
;
711 SafeGui
.rcCaret
.right
= SafeGui
.rcCaret
.left
+ CaretInfo
->Size
.cx
;
712 SafeGui
.rcCaret
.bottom
= SafeGui
.rcCaret
.top
+ CaretInfo
->Size
.cy
;
715 ObDereferenceObject(Thread
);
717 Status
= MmCopyToCaller(lpgui
, &SafeGui
, sizeof(GUITHREADINFO
));
718 if(!NT_SUCCESS(Status
))
720 SetLastNtError(Status
);
730 NtUserGetGuiResources(
735 PW32PROCESS W32Process
;
739 Status
= ObReferenceObjectByHandle(hProcess
,
740 PROCESS_QUERY_INFORMATION
,
746 if(!NT_SUCCESS(Status
))
748 SetLastNtError(Status
);
752 W32Process
= Process
->Win32Process
;
755 ObDereferenceObject(Process
);
756 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
764 Ret
= (DWORD
)W32Process
->GDIObjects
;
769 Ret
= (DWORD
)W32Process
->UserObjects
;
774 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
779 ObDereferenceObject(Process
);
785 IntSafeCopyUnicodeString(PUNICODE_STRING Dest
,
786 PUNICODE_STRING Source
)
791 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
792 if(!NT_SUCCESS(Status
))
797 if(Dest
->MaximumLength
> 0)
801 Dest
->Buffer
= ExAllocatePool(NonPagedPool
, Dest
->MaximumLength
);
804 return STATUS_NO_MEMORY
;
807 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->MaximumLength
);
808 if(!NT_SUCCESS(Status
))
810 ExFreePool(Dest
->Buffer
);
816 return STATUS_SUCCESS
;
818 return STATUS_UNSUCCESSFUL
;