1 /* $Id: misc.c,v 1.30 2003/11/23 13:46:33 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>
28 void W32kRegisterPrimitiveMessageQueue() {
29 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
30 if( !pmPrimitiveMessageQueue
) {
32 pThread
= PsGetWin32Thread();
33 if( pThread
&& pThread
->MessageQueue
) {
34 pmPrimitiveMessageQueue
= pThread
->MessageQueue
;
35 DbgPrint( "Installed primitive input queue.\n" );
38 DbgPrint( "Alert! Someone is trying to steal the primitive queue.\n" );
42 PUSER_MESSAGE_QUEUE
W32kGetPrimitiveMessageQueue() {
43 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
44 return pmPrimitiveMessageQueue
;
52 NtUserCallNoParam(DWORD Routine
)
58 case NOPARAM_ROUTINE_REGISTER_PRIMITIVE
:
59 W32kRegisterPrimitiveMessageQueue();
63 case NOPARAM_ROUTINE_DESTROY_CARET
:
64 Result
= (DWORD
)IntDestroyCaret(PsGetCurrentThread()->Win32Thread
);
67 case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP
:
68 Result
= (DWORD
)IntInitMessagePumpHook();
71 case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP
:
72 Result
= (DWORD
)IntUninitMessagePumpHook();
76 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam\n");
77 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
94 PWINSTATION_OBJECT WinStaObject
;
95 PWINDOW_OBJECT WindowObject
;
99 case ONEPARAM_ROUTINE_GETMENU
:
100 WindowObject
= IntGetWindowObject((HWND
)Param
);
103 SetLastWin32Error(ERROR_INVALID_HANDLE
);
107 Result
= (DWORD
)WindowObject
->IDMenu
;
109 IntReleaseWindowObject(WindowObject
);
112 case ONEPARAM_ROUTINE_ISWINDOWUNICODE
:
113 WindowObject
= IntGetWindowObject((HWND
)Param
);
116 SetLastWin32Error(ERROR_INVALID_HANDLE
);
119 Result
= WindowObject
->Unicode
;
120 IntReleaseWindowObject(WindowObject
);
123 case ONEPARAM_ROUTINE_WINDOWFROMDC
:
124 return (DWORD
)IntWindowFromDC((HDC
)Param
);
126 case ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID
:
127 WindowObject
= IntGetWindowObject((HWND
)Param
);
130 SetLastWin32Error(ERROR_INVALID_HANDLE
);
134 Result
= WindowObject
->ContextHelpId
;
136 IntReleaseWindowObject(WindowObject
);
139 case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON
:
140 Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
144 if (!NT_SUCCESS(Status
))
147 Result
= (DWORD
)IntSwapMouseButton(WinStaObject
, (BOOL
)Param
);
149 ObDereferenceObject(WinStaObject
);
152 case ONEPARAM_ROUTINE_SWITCHCARETSHOWING
:
153 return (DWORD
)IntSwitchCaretShowing((PVOID
)Param
);
155 case ONEPARAM_ROUTINE_SETCARETBLINKTIME
:
156 return (DWORD
)IntSetCaretBlinkTime((UINT
)Param
);
159 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam()\n Param=0x%x\n",
161 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
177 PWINDOW_OBJECT WindowObject
;
178 PSYSTEM_CURSORINFO CurInfo
;
179 PWINSTATION_OBJECT WinStaObject
;
184 case TWOPARAM_ROUTINE_ENABLEWINDOW
:
188 case TWOPARAM_ROUTINE_UNKNOWN
:
192 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS
:
196 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW
:
200 case TWOPARAM_ROUTINE_VALIDATERGN
:
201 return (DWORD
)NtUserValidateRgn((HWND
) Param1
, (HRGN
) Param2
);
203 case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID
:
204 WindowObject
= IntGetWindowObject((HWND
)Param1
);
207 SetLastWin32Error(ERROR_INVALID_HANDLE
);
211 WindowObject
->ContextHelpId
= Param2
;
213 IntReleaseWindowObject(WindowObject
);
216 case TWOPARAM_ROUTINE_CURSORPOSITION
:
219 Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
223 if (!NT_SUCCESS(Status
))
228 /* set cursor position */
230 Status
= MmCopyFromCaller(&Pos
, (PPOINT
)Param1
, sizeof(POINT
));
231 if(!NT_SUCCESS(Status
))
233 ObDereferenceObject(WinStaObject
);
234 SetLastNtError(Status
);
238 CurInfo
= &WinStaObject
->SystemCursor
;
239 /* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
241 //CheckClipCursor(&Pos->x, &Pos->y, CurInfo);
242 if((Pos
.x
!= CurInfo
->x
) || (Pos
.y
!= CurInfo
->y
))
244 MouseMoveCursor(Pos
.x
, Pos
.y
);
250 /* get cursor position */
251 /* FIXME - check if process has WINSTA_READATTRIBUTES */
252 Pos
.x
= WinStaObject
->SystemCursor
.x
;
253 Pos
.y
= WinStaObject
->SystemCursor
.y
;
255 Status
= MmCopyToCaller((PPOINT
)Param1
, &Pos
, sizeof(POINT
));
256 if(!NT_SUCCESS(Status
))
258 ObDereferenceObject(WinStaObject
);
259 SetLastNtError(Status
);
265 ObDereferenceObject(WinStaObject
);
269 case TWOPARAM_ROUTINE_SETCARETPOS
:
270 return (DWORD
)IntSetCaretPos((int)Param1
, (int)Param2
);
272 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam()\n Param1=0x%x Parm2=0x%x\n",
273 Routine
, Param1
, Param2
);
274 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
286 case HWNDOPT_ROUTINE_SETPROGMANWINDOW
:
290 case HWNDOPT_ROUTINE_SETTASKMANWINDOW
:
303 NtUserSystemParametersInfo(
309 /* FIXME: This should be obtained from the registry */
310 static LOGFONTW CaptionFont
=
311 { 14, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
312 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
, L
"" };
313 /* { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, OEM_CHARSET,
314 0, 0, DEFAULT_QUALITY, FF_MODERN, L"Bitstream Vera Sans Bold" };*/
316 PWINSTATION_OBJECT WinStaObject
;
320 case SPI_SETDOUBLECLKWIDTH
:
321 case SPI_SETDOUBLECLKHEIGHT
:
322 case SPI_SETDOUBLECLICKTIME
:
324 Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
328 if (!NT_SUCCESS(Status
))
333 case SPI_SETDOUBLECLKWIDTH
:
334 /* FIXME limit the maximum value? */
335 WinStaObject
->SystemCursor
.DblClickWidth
= uiParam
;
337 case SPI_SETDOUBLECLKHEIGHT
:
338 /* FIXME limit the maximum value? */
339 WinStaObject
->SystemCursor
.DblClickHeight
= uiParam
;
341 case SPI_SETDOUBLECLICKTIME
:
342 /* FIXME limit the maximum time to 1000 ms? */
343 WinStaObject
->SystemCursor
.DblClickSpeed
= uiParam
;
347 /* FIXME save the value to the registry */
349 ObDereferenceObject(WinStaObject
);
352 case SPI_SETWORKAREA
:
354 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
358 /* FIXME - Set last error */
362 Status
= MmCopyFromCaller(Desktop
->WorkArea
, (PRECT
)pvParam
, sizeof(RECT
));
363 if(!NT_SUCCESS(Status
))
365 SetLastNtError(Status
);
371 case SPI_GETWORKAREA
:
373 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
377 /* FIXME - Set last error */
381 Status
= MmCopyToCaller((PRECT
)pvParam
, Desktop
->WorkArea
, sizeof(RECT
));
382 if(!NT_SUCCESS(Status
))
384 SetLastNtError(Status
);
390 case SPI_GETICONTITLELOGFONT
:
392 Status
= MmCopyToCaller(pvParam
, &CaptionFont
, sizeof(CaptionFont
));
393 if(!NT_SUCCESS(Status
))
395 SetLastNtError(Status
);
400 case SPI_GETNONCLIENTMETRICS
:
402 /* FIXME - use MmCopyToCaller() !!! */
403 LPNONCLIENTMETRICSW pMetrics
= (LPNONCLIENTMETRICSW
)pvParam
;
405 if (pMetrics
->cbSize
!= sizeof(NONCLIENTMETRICSW
) ||
406 uiParam
!= sizeof(NONCLIENTMETRICSW
))
411 memset((char *)pvParam
+ sizeof(pMetrics
->cbSize
), 0,
412 pMetrics
->cbSize
- sizeof(pMetrics
->cbSize
));
414 pMetrics
->iBorderWidth
= 1;
415 pMetrics
->iScrollWidth
= NtUserGetSystemMetrics(SM_CXVSCROLL
);
416 pMetrics
->iScrollHeight
= NtUserGetSystemMetrics(SM_CYHSCROLL
);
417 pMetrics
->iCaptionWidth
= NtUserGetSystemMetrics(SM_CXSIZE
);
418 pMetrics
->iCaptionHeight
= NtUserGetSystemMetrics(SM_CYSIZE
);
419 memcpy((LPVOID
)&(pMetrics
->lfCaptionFont
), &CaptionFont
, sizeof(CaptionFont
));
420 pMetrics
->lfCaptionFont
.lfWeight
= FW_BOLD
;
421 pMetrics
->iSmCaptionWidth
= NtUserGetSystemMetrics(SM_CXSMSIZE
);
422 pMetrics
->iSmCaptionHeight
= NtUserGetSystemMetrics(SM_CYSMSIZE
);
423 memcpy((LPVOID
)&(pMetrics
->lfSmCaptionFont
), &CaptionFont
, sizeof(CaptionFont
));
424 pMetrics
->iMenuWidth
= NtUserGetSystemMetrics(SM_CXMENUSIZE
);
425 pMetrics
->iMenuHeight
= NtUserGetSystemMetrics(SM_CYMENUSIZE
);
426 memcpy((LPVOID
)&(pMetrics
->lfMenuFont
), &CaptionFont
, sizeof(CaptionFont
));
427 memcpy((LPVOID
)&(pMetrics
->lfStatusFont
), &CaptionFont
, sizeof(CaptionFont
));
428 memcpy((LPVOID
)&(pMetrics
->lfMessageFont
), &CaptionFont
, sizeof(CaptionFont
));
438 NtUserGetDoubleClickTime(VOID
)
442 PWINSTATION_OBJECT WinStaObject
;
444 Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
448 if (!NT_SUCCESS(Status
))
451 Result
= WinStaObject
->SystemCursor
.DblClickSpeed
;
453 ObDereferenceObject(WinStaObject
);
459 NtUserGetGUIThreadInfo(
461 LPGUITHREADINFO lpgui
)
464 PTHRDCARETINFO CaretInfo
;
465 GUITHREADINFO SafeGui
;
466 PDESKTOP_OBJECT Desktop
;
467 PUSER_MESSAGE_QUEUE MsgQueue
;
468 PETHREAD Thread
= NULL
;
470 Status
= MmCopyFromCaller(&SafeGui
, lpgui
, sizeof(DWORD
));
471 if(!NT_SUCCESS(Status
))
473 SetLastNtError(Status
);
477 if(SafeGui
.cbSize
!= sizeof(GUITHREADINFO
))
479 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
485 Status
= PsLookupThreadByThreadId((PVOID
)idThread
, &Thread
);
486 if(!NT_SUCCESS(Status
))
488 SetLastWin32Error(ERROR_ACCESS_DENIED
);
491 Desktop
= Thread
->Win32Thread
->Desktop
;
495 /* get the foreground thread */
496 PW32THREAD W32Thread
= PsGetCurrentThread()->Win32Thread
;
497 Desktop
= W32Thread
->Desktop
;
500 MsgQueue
= Desktop
->ActiveMessageQueue
;
503 Thread
= MsgQueue
->Thread
;
508 if(!Thread
|| !Desktop
)
510 if(idThread
&& Thread
)
511 ObDereferenceObject(Thread
);
512 SetLastWin32Error(ERROR_ACCESS_DENIED
);
516 CaretInfo
= ThrdCaretInfo(Thread
->Win32Thread
);
517 MsgQueue
= (PUSER_MESSAGE_QUEUE
)Desktop
->ActiveMessageQueue
;
519 SafeGui
.flags
= (CaretInfo
->Visible
? GUI_CARETBLINKING
: 0);
520 if(MsgQueue
->MenuOwner
)
521 SafeGui
.flags
|= GUI_INMENUMODE
| MsgQueue
->MenuState
;
522 if(MsgQueue
->MoveSize
)
523 SafeGui
.flags
|= GUI_INMOVESIZE
;
525 /* FIXME add flag GUI_16BITTASK */
527 SafeGui
.hwndActive
= MsgQueue
->ActiveWindow
;
528 SafeGui
.hwndFocus
= MsgQueue
->FocusWindow
;
529 SafeGui
.hwndCapture
= MsgQueue
->CaptureWindow
;
530 SafeGui
.hwndMenuOwner
= MsgQueue
->MenuOwner
;
531 SafeGui
.hwndMoveSize
= MsgQueue
->MoveSize
;
532 SafeGui
.hwndCaret
= CaretInfo
->hWnd
;
534 SafeGui
.rcCaret
.left
= CaretInfo
->Pos
.x
;
535 SafeGui
.rcCaret
.top
= CaretInfo
->Pos
.y
;
536 SafeGui
.rcCaret
.right
= SafeGui
.rcCaret
.left
+ CaretInfo
->Size
.cx
;
537 SafeGui
.rcCaret
.bottom
= SafeGui
.rcCaret
.top
+ CaretInfo
->Size
.cy
;
540 ObDereferenceObject(Thread
);
542 Status
= MmCopyToCaller(lpgui
, &SafeGui
, sizeof(GUITHREADINFO
));
543 if(!NT_SUCCESS(Status
))
545 SetLastNtError(Status
);
555 NtUserGetGuiResources(
560 PW32PROCESS W32Process
;
564 Status
= ObReferenceObjectByHandle(hProcess
,
565 PROCESS_QUERY_INFORMATION
,
571 if(!NT_SUCCESS(Status
))
573 SetLastNtError(Status
);
577 W32Process
= Process
->Win32Process
;
580 ObDereferenceObject(Process
);
581 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
589 Ret
= (DWORD
)W32Process
->GDIObjects
;
594 Ret
= (DWORD
)W32Process
->UserObjects
;
599 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
604 ObDereferenceObject(Process
);