2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Misc User funcs
5 * FILE: subsystems/win32/win32k/ntuser/misc.c
6 * PROGRAMER: Ge van Geldorp (ge@gse.nl)
13 DBG_DEFAULT_CHANNEL(UserMisc
);
17 IntGdiGetLanguageID(VOID
)
20 ULONG Size
= sizeof(WCHAR
) * (MAX_PATH
+ 12);
21 OBJECT_ATTRIBUTES ObAttr
;
22 // http://support.microsoft.com/kb/324097
23 ULONG Ret
= 0x409; // English
25 UNICODE_STRING Language
;
27 RtlInitUnicodeString( &Language
,
28 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language");
30 InitializeObjectAttributes( &ObAttr
,
36 if ( NT_SUCCESS(ZwOpenKey(&KeyHandle
, KEY_READ
, &ObAttr
)))
38 KeyInfo
= ExAllocatePoolWithTag(PagedPool
, Size
, TAG_STRING
);
41 RtlInitUnicodeString(&Language
, L
"Default");
43 if ( NT_SUCCESS(ZwQueryValueKey( KeyHandle
,
45 KeyValuePartialInformation
,
50 RtlInitUnicodeString(&Language
, (PVOID
)((char *)KeyInfo
+ 12));
51 RtlUnicodeStringToInteger(&Language
, 16, &Ret
);
53 ExFreePoolWithTag(KeyInfo
, TAG_STRING
);
57 TRACE("Language ID = %x\n",Ret
);
70 TRACE("Enter NtUserGetThreadState\n");
71 if (Routine
!= THREADSTATE_GETTHREADINFO
)
82 case THREADSTATE_GETTHREADINFO
:
85 case THREADSTATE_FOCUSWINDOW
:
86 ret
= (DWORD_PTR
)IntGetThreadFocusWindow();
88 case THREADSTATE_CAPTUREWINDOW
:
89 /* FIXME should use UserEnterShared */
90 ret
= (DWORD_PTR
)IntGetCapture();
92 case THREADSTATE_PROGMANWINDOW
:
93 ret
= (DWORD_PTR
)GetW32ThreadInfo()->pDeskInfo
->hProgmanWindow
;
95 case THREADSTATE_TASKMANWINDOW
:
96 ret
= (DWORD_PTR
)GetW32ThreadInfo()->pDeskInfo
->hTaskManWindow
;
98 case THREADSTATE_ACTIVEWINDOW
:
99 ret
= (DWORD_PTR
)UserGetActiveWindow();
101 case THREADSTATE_INSENDMESSAGE
:
103 PUSER_SENT_MESSAGE Message
=
104 ((PTHREADINFO
)PsGetCurrentThreadWin32Thread())->pusmCurrent
;
105 ERR("THREADSTATE_INSENDMESSAGE\n");
110 if (Message
->SenderQueue
)
114 if (Message
->CompletionCallback
)
115 ret
= ISMEX_CALLBACK
;
119 /* if ReplyMessage */
120 if (Message
->QS_Flags
& QS_SMRESULT
) ret
|= ISMEX_REPLIED
;
125 case THREADSTATE_GETMESSAGETIME
:
126 ret
= ((PTHREADINFO
)PsGetCurrentThreadWin32Thread())->timeLast
;
129 case THREADSTATE_UPTIMELASTREAD
:
132 LARGE_INTEGER LargeTickCount
;
133 pti
= PsGetCurrentThreadWin32Thread();
134 KeQueryTickCount(&LargeTickCount
);
135 pti
->MessageQueue
->LastMsgRead
= LargeTickCount
.u
.LowPart
;
136 pti
->pcti
->tickLastMsgChecked
= LargeTickCount
.u
.LowPart
;
140 case THREADSTATE_GETINPUTSTATE
:
141 ret
= LOWORD(IntGetQueueStatus(QS_POSTMESSAGE
|QS_TIMER
|QS_PAINT
|QS_SENDMESSAGE
|QS_INPUT
)) & (QS_KEY
| QS_MOUSEBUTTON
);
145 TRACE("Leave NtUserGetThreadState, ret=%i\n", ret
);
153 NtUserSetThreadState(
159 // Test the only flags user can change.
160 if (Set
& ~(QF_FF10STATUS
|QF_DIALOGACTIVE
|QF_TABSWITCHING
|QF_FMENUSTATUS
|QF_FMENUSTATUSBREAK
)) return 0;
161 if (Flags
& ~(QF_FF10STATUS
|QF_DIALOGACTIVE
|QF_TABSWITCHING
|QF_FMENUSTATUS
|QF_FMENUSTATUSBREAK
)) return 0;
162 UserEnterExclusive();
163 pti
= PsGetCurrentThreadWin32Thread();
164 if (pti
->MessageQueue
)
166 Ret
= pti
->MessageQueue
->QF_flags
; // Get the queue flags.
168 pti
->MessageQueue
->QF_flags
|= (Set
&Flags
); // Set the queue flags.
171 if (Flags
) pti
->MessageQueue
->QF_flags
&= ~Flags
; // Clr the queue flags.
180 NtUserGetDoubleClickTime(VOID
)
184 TRACE("Enter NtUserGetDoubleClickTime\n");
187 // FIXME: Check if this works on non-interactive winsta
188 Result
= gspv
.iDblClickTime
;
190 TRACE("Leave NtUserGetDoubleClickTime, ret=%i\n", Result
);
197 NtUserGetGUIThreadInfo(
198 DWORD idThread
, /* if NULL use foreground thread */
199 LPGUITHREADINFO lpgui
)
202 PTHRDCARETINFO CaretInfo
;
203 GUITHREADINFO SafeGui
;
205 PUSER_MESSAGE_QUEUE MsgQueue
;
206 PTHREADINFO W32Thread
;
207 PETHREAD Thread
= NULL
;
209 DECLARE_RETURN(BOOLEAN
);
211 TRACE("Enter NtUserGetGUIThreadInfo\n");
214 Status
= MmCopyFromCaller(&SafeGui
, lpgui
, sizeof(DWORD
));
215 if(!NT_SUCCESS(Status
))
217 SetLastNtError(Status
);
221 if(SafeGui
.cbSize
!= sizeof(GUITHREADINFO
))
223 EngSetLastError(ERROR_INVALID_PARAMETER
);
229 Status
= PsLookupThreadByThreadId((HANDLE
)(DWORD_PTR
)idThread
, &Thread
);
230 if(!NT_SUCCESS(Status
))
232 EngSetLastError(ERROR_ACCESS_DENIED
);
235 W32Thread
= (PTHREADINFO
)Thread
->Tcb
.Win32Thread
;
236 Desktop
= W32Thread
->rpdesk
;
239 { /* get the foreground thread */
240 Thread
= PsGetCurrentThread();
241 W32Thread
= (PTHREADINFO
)Thread
->Tcb
.Win32Thread
;
242 Desktop
= W32Thread
->rpdesk
;
245 if (!Thread
|| !Desktop
)
247 if(idThread
&& Thread
)
248 ObDereferenceObject(Thread
);
249 EngSetLastError(ERROR_ACCESS_DENIED
);
253 if ( W32Thread
->MessageQueue
)
254 MsgQueue
= W32Thread
->MessageQueue
;
257 if ( Desktop
) MsgQueue
= Desktop
->ActiveMessageQueue
;
260 CaretInfo
= MsgQueue
->CaretInfo
;
262 SafeGui
.flags
= (CaretInfo
->Visible
? GUI_CARETBLINKING
: 0);
264 if (MsgQueue
->MenuOwner
)
265 SafeGui
.flags
|= GUI_INMENUMODE
| MsgQueue
->MenuState
;
267 if (MsgQueue
->MoveSize
)
268 SafeGui
.flags
|= GUI_INMOVESIZE
;
270 /* FIXME add flag GUI_16BITTASK */
272 SafeGui
.hwndActive
= MsgQueue
->ActiveWindow
;
273 SafeGui
.hwndFocus
= MsgQueue
->FocusWindow
;
274 SafeGui
.hwndCapture
= MsgQueue
->CaptureWindow
;
275 SafeGui
.hwndMenuOwner
= MsgQueue
->MenuOwner
;
276 SafeGui
.hwndMoveSize
= MsgQueue
->MoveSize
;
277 SafeGui
.hwndCaret
= CaretInfo
->hWnd
;
279 SafeGui
.rcCaret
.left
= CaretInfo
->Pos
.x
;
280 SafeGui
.rcCaret
.top
= CaretInfo
->Pos
.y
;
281 SafeGui
.rcCaret
.right
= SafeGui
.rcCaret
.left
+ CaretInfo
->Size
.cx
;
282 SafeGui
.rcCaret
.bottom
= SafeGui
.rcCaret
.top
+ CaretInfo
->Size
.cy
;
285 ObDereferenceObject(Thread
);
287 Status
= MmCopyToCaller(lpgui
, &SafeGui
, sizeof(GUITHREADINFO
));
288 if(!NT_SUCCESS(Status
))
290 SetLastNtError(Status
);
297 TRACE("Leave NtUserGetGUIThreadInfo, ret=%i\n",_ret_
);
305 NtUserGetGuiResources(
310 PPROCESSINFO W32Process
;
313 DECLARE_RETURN(DWORD
);
315 TRACE("Enter NtUserGetGuiResources\n");
318 Status
= ObReferenceObjectByHandle(hProcess
,
319 PROCESS_QUERY_INFORMATION
,
325 if(!NT_SUCCESS(Status
))
327 SetLastNtError(Status
);
331 W32Process
= (PPROCESSINFO
)Process
->Win32Process
;
334 ObDereferenceObject(Process
);
335 EngSetLastError(ERROR_INVALID_PARAMETER
);
343 Ret
= (DWORD
)W32Process
->GDIHandleCount
;
348 Ret
= (DWORD
)W32Process
->UserHandleCount
;
353 EngSetLastError(ERROR_INVALID_PARAMETER
);
358 ObDereferenceObject(Process
);
363 TRACE("Leave NtUserGetGuiResources, ret=%i\n",_ret_
);
369 IntSafeCopyUnicodeString(PUNICODE_STRING Dest
,
370 PUNICODE_STRING Source
)
375 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
376 if(!NT_SUCCESS(Status
))
381 if(Dest
->Length
> 0x4000)
383 return STATUS_UNSUCCESSFUL
;
388 Dest
->MaximumLength
= Dest
->Length
;
390 if(Dest
->Length
> 0 && Src
)
392 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
395 return STATUS_NO_MEMORY
;
398 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
399 if(!NT_SUCCESS(Status
))
401 ExFreePoolWithTag(Dest
->Buffer
, TAG_STRING
);
407 return STATUS_SUCCESS
;
410 /* string is empty */
411 return STATUS_SUCCESS
;
415 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest
,
416 PUNICODE_STRING Source
)
421 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
422 if(!NT_SUCCESS(Status
))
427 if(Dest
->Length
> 0x4000)
429 return STATUS_UNSUCCESSFUL
;
434 Dest
->MaximumLength
= 0;
436 if(Dest
->Length
> 0 && Src
)
438 Dest
->MaximumLength
= Dest
->Length
+ sizeof(WCHAR
);
439 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
442 return STATUS_NO_MEMORY
;
445 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
446 if(!NT_SUCCESS(Status
))
448 ExFreePoolWithTag(Dest
->Buffer
, TAG_STRING
);
453 /* make sure the string is null-terminated */
454 Src
= (PWSTR
)((PBYTE
)Dest
->Buffer
+ Dest
->Length
);
457 return STATUS_SUCCESS
;
460 /* string is empty */
461 return STATUS_SUCCESS
;
465 GetW32ProcessInfo(VOID
)
467 return (PPROCESSINFO
)PsGetCurrentProcessWin32Process();
471 GetW32ThreadInfo(VOID
)
476 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
480 /* FIXME - temporary hack for system threads... */
484 pti
->ppi
= ppi
= GetW32ProcessInfo();
486 if (pti
->rpdesk
!= NULL
)
488 pti
->pDeskInfo
= pti
->rpdesk
->pDeskInfo
;
492 pti
->pDeskInfo
= NULL
;
495 Teb
= NtCurrentTeb();
496 pci
= GetWin32ClientInfo();
497 pti
->pClientInfo
= pci
;
504 Teb
->Win32ThreadInfo
= (PW32THREAD
) pti
;
507 pci
->fsHooks
= pti
->fsHooks
;
508 if (pti
->KeyboardLayout
) pci
->hKL
= pti
->KeyboardLayout
->hkl
;
509 pci
->dwTIFlags
= pti
->TIF_flags
;
510 /* CI may not have been initialized. */
511 if (!pci
->pDeskInfo
&& pti
->pDeskInfo
)
513 if (!pci
->ulClientDelta
) pci
->ulClientDelta
= DesktopHeapGetUserDelta();
515 pci
->pDeskInfo
= (PVOID
)((ULONG_PTR
)pti
->pDeskInfo
- pci
->ulClientDelta
);
517 if (pti
->pcti
&& pci
->pDeskInfo
)
518 pci
->pClientThreadInfo
= (PVOID
)((ULONG_PTR
)pti
->pcti
- pci
->ulClientDelta
);
520 pci
->pClientThreadInfo
= NULL
;
523 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
525 SetLastNtError(_SEH2_GetExceptionCode());