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)
19 IntGdiGetLanguageID(VOID
)
22 ULONG Size
= sizeof(WCHAR
) * (MAX_PATH
+ 12);
23 OBJECT_ATTRIBUTES ObAttr
;
24 // http://support.microsoft.com/kb/324097
25 ULONG Ret
= 0x409; // English
27 UNICODE_STRING Language
;
29 RtlInitUnicodeString( &Language
,
30 L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language");
32 InitializeObjectAttributes( &ObAttr
,
38 if ( NT_SUCCESS(ZwOpenKey(&KeyHandle
, KEY_READ
, &ObAttr
)))
40 KeyInfo
= ExAllocatePoolWithTag(PagedPool
, Size
, TAG_STRING
);
43 RtlInitUnicodeString(&Language
, L
"Default");
45 if ( NT_SUCCESS(ZwQueryValueKey( KeyHandle
,
47 KeyValuePartialInformation
,
52 RtlInitUnicodeString(&Language
, (PVOID
)((char *)KeyInfo
+ 12));
53 RtlUnicodeStringToInteger(&Language
, 16, &Ret
);
55 ExFreePoolWithTag(KeyInfo
, TAG_STRING
);
59 DPRINT("Language ID = %x\n",Ret
);
72 DPRINT("Enter NtUserGetThreadState\n");
73 if (Routine
!= THREADSTATE_GETTHREADINFO
)
84 case THREADSTATE_GETTHREADINFO
:
87 case THREADSTATE_FOCUSWINDOW
:
88 ret
= (DWORD_PTR
)IntGetThreadFocusWindow();
90 case THREADSTATE_CAPTUREWINDOW
:
91 /* FIXME should use UserEnterShared */
92 ret
= (DWORD_PTR
)IntGetCapture();
94 case THREADSTATE_PROGMANWINDOW
:
95 ret
= (DWORD_PTR
)GetW32ThreadInfo()->pDeskInfo
->hProgmanWindow
;
97 case THREADSTATE_TASKMANWINDOW
:
98 ret
= (DWORD_PTR
)GetW32ThreadInfo()->pDeskInfo
->hTaskManWindow
;
100 case THREADSTATE_ACTIVEWINDOW
:
101 ret
= (DWORD_PTR
)UserGetActiveWindow();
103 case THREADSTATE_INSENDMESSAGE
:
105 PUSER_SENT_MESSAGE Message
=
106 ((PTHREADINFO
)PsGetCurrentThreadWin32Thread())->pusmCurrent
;
107 DPRINT1("THREADSTATE_INSENDMESSAGE\n");
112 if (Message
->SenderQueue
)
116 if (Message
->CompletionCallback
)
117 ret
= ISMEX_CALLBACK
;
121 /* if ReplyMessage */
122 if (Message
->QS_Flags
& QS_SMRESULT
) ret
|= ISMEX_REPLIED
;
127 case THREADSTATE_GETMESSAGETIME
:
128 ret
= ((PTHREADINFO
)PsGetCurrentThreadWin32Thread())->timeLast
;
131 case THREADSTATE_UPTIMELASTREAD
:
134 LARGE_INTEGER LargeTickCount
;
135 pti
= PsGetCurrentThreadWin32Thread();
136 KeQueryTickCount(&LargeTickCount
);
137 pti
->MessageQueue
->LastMsgRead
= LargeTickCount
.u
.LowPart
;
138 pti
->pcti
->tickLastMsgChecked
= LargeTickCount
.u
.LowPart
;
142 case THREADSTATE_GETINPUTSTATE
:
143 ret
= LOWORD(IntGetQueueStatus(QS_POSTMESSAGE
|QS_TIMER
|QS_PAINT
|QS_SENDMESSAGE
|QS_INPUT
)) & (QS_KEY
| QS_MOUSEBUTTON
);
147 DPRINT("Leave NtUserGetThreadState, ret=%i\n", ret
);
156 NtUserGetDoubleClickTime(VOID
)
160 DPRINT("Enter NtUserGetDoubleClickTime\n");
163 // FIXME: Check if this works on non-interactive winsta
164 Result
= gspv
.iDblClickTime
;
166 DPRINT("Leave NtUserGetDoubleClickTime, ret=%i\n", Result
);
173 NtUserGetGUIThreadInfo(
174 DWORD idThread
, /* if NULL use foreground thread */
175 LPGUITHREADINFO lpgui
)
178 PTHRDCARETINFO CaretInfo
;
179 GUITHREADINFO SafeGui
;
181 PUSER_MESSAGE_QUEUE MsgQueue
;
182 PETHREAD Thread
= NULL
;
183 DECLARE_RETURN(BOOLEAN
);
185 DPRINT("Enter NtUserGetGUIThreadInfo\n");
188 Status
= MmCopyFromCaller(&SafeGui
, lpgui
, sizeof(DWORD
));
189 if(!NT_SUCCESS(Status
))
191 SetLastNtError(Status
);
195 if(SafeGui
.cbSize
!= sizeof(GUITHREADINFO
))
197 EngSetLastError(ERROR_INVALID_PARAMETER
);
203 Status
= PsLookupThreadByThreadId((HANDLE
)(DWORD_PTR
)idThread
, &Thread
);
204 if(!NT_SUCCESS(Status
))
206 EngSetLastError(ERROR_ACCESS_DENIED
);
209 Desktop
= ((PTHREADINFO
)Thread
->Tcb
.Win32Thread
)->rpdesk
;
213 /* get the foreground thread */
214 PTHREADINFO W32Thread
= (PTHREADINFO
)PsGetCurrentThread()->Tcb
.Win32Thread
;
215 Desktop
= W32Thread
->rpdesk
;
218 MsgQueue
= Desktop
->ActiveMessageQueue
;
221 Thread
= MsgQueue
->Thread
;
226 if(!Thread
|| !Desktop
)
228 if(idThread
&& Thread
)
229 ObDereferenceObject(Thread
);
230 EngSetLastError(ERROR_ACCESS_DENIED
);
234 MsgQueue
= (PUSER_MESSAGE_QUEUE
)Desktop
->ActiveMessageQueue
;
235 CaretInfo
= MsgQueue
->CaretInfo
;
237 SafeGui
.flags
= (CaretInfo
->Visible
? GUI_CARETBLINKING
: 0);
238 if(MsgQueue
->MenuOwner
)
239 SafeGui
.flags
|= GUI_INMENUMODE
| MsgQueue
->MenuState
;
240 if(MsgQueue
->MoveSize
)
241 SafeGui
.flags
|= GUI_INMOVESIZE
;
243 /* FIXME add flag GUI_16BITTASK */
245 SafeGui
.hwndActive
= MsgQueue
->ActiveWindow
;
246 SafeGui
.hwndFocus
= MsgQueue
->FocusWindow
;
247 SafeGui
.hwndCapture
= MsgQueue
->CaptureWindow
;
248 SafeGui
.hwndMenuOwner
= MsgQueue
->MenuOwner
;
249 SafeGui
.hwndMoveSize
= MsgQueue
->MoveSize
;
250 SafeGui
.hwndCaret
= CaretInfo
->hWnd
;
252 SafeGui
.rcCaret
.left
= CaretInfo
->Pos
.x
;
253 SafeGui
.rcCaret
.top
= CaretInfo
->Pos
.y
;
254 SafeGui
.rcCaret
.right
= SafeGui
.rcCaret
.left
+ CaretInfo
->Size
.cx
;
255 SafeGui
.rcCaret
.bottom
= SafeGui
.rcCaret
.top
+ CaretInfo
->Size
.cy
;
258 ObDereferenceObject(Thread
);
260 Status
= MmCopyToCaller(lpgui
, &SafeGui
, sizeof(GUITHREADINFO
));
261 if(!NT_SUCCESS(Status
))
263 SetLastNtError(Status
);
270 DPRINT("Leave NtUserGetGUIThreadInfo, ret=%i\n",_ret_
);
278 NtUserGetGuiResources(
283 PPROCESSINFO W32Process
;
286 DECLARE_RETURN(DWORD
);
288 DPRINT("Enter NtUserGetGuiResources\n");
291 Status
= ObReferenceObjectByHandle(hProcess
,
292 PROCESS_QUERY_INFORMATION
,
298 if(!NT_SUCCESS(Status
))
300 SetLastNtError(Status
);
304 W32Process
= (PPROCESSINFO
)Process
->Win32Process
;
307 ObDereferenceObject(Process
);
308 EngSetLastError(ERROR_INVALID_PARAMETER
);
316 Ret
= (DWORD
)W32Process
->GDIHandleCount
;
321 Ret
= (DWORD
)W32Process
->UserHandleCount
;
326 EngSetLastError(ERROR_INVALID_PARAMETER
);
331 ObDereferenceObject(Process
);
336 DPRINT("Leave NtUserGetGuiResources, ret=%i\n",_ret_
);
342 IntSafeCopyUnicodeString(PUNICODE_STRING Dest
,
343 PUNICODE_STRING Source
)
348 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
349 if(!NT_SUCCESS(Status
))
354 if(Dest
->Length
> 0x4000)
356 return STATUS_UNSUCCESSFUL
;
361 Dest
->MaximumLength
= Dest
->Length
;
363 if(Dest
->Length
> 0 && Src
)
365 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
368 return STATUS_NO_MEMORY
;
371 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
372 if(!NT_SUCCESS(Status
))
374 ExFreePoolWithTag(Dest
->Buffer
, TAG_STRING
);
380 return STATUS_SUCCESS
;
383 /* string is empty */
384 return STATUS_SUCCESS
;
388 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest
,
389 PUNICODE_STRING Source
)
394 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
395 if(!NT_SUCCESS(Status
))
400 if(Dest
->Length
> 0x4000)
402 return STATUS_UNSUCCESSFUL
;
407 Dest
->MaximumLength
= 0;
409 if(Dest
->Length
> 0 && Src
)
411 Dest
->MaximumLength
= Dest
->Length
+ sizeof(WCHAR
);
412 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
415 return STATUS_NO_MEMORY
;
418 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
419 if(!NT_SUCCESS(Status
))
421 ExFreePoolWithTag(Dest
->Buffer
, TAG_STRING
);
426 /* make sure the string is null-terminated */
427 Src
= (PWSTR
)((PBYTE
)Dest
->Buffer
+ Dest
->Length
);
430 return STATUS_SUCCESS
;
433 /* string is empty */
434 return STATUS_SUCCESS
;
438 IntUnicodeStringToNULLTerminated(PWSTR
*Dest
, PUNICODE_STRING Src
)
440 if (Src
->Length
+ sizeof(WCHAR
) <= Src
->MaximumLength
441 && L
'\0' == Src
->Buffer
[Src
->Length
/ sizeof(WCHAR
)])
443 /* The unicode_string is already nul terminated. Just reuse it. */
445 return STATUS_SUCCESS
;
448 *Dest
= ExAllocatePoolWithTag(PagedPool
, Src
->Length
+ sizeof(WCHAR
), TAG_STRING
);
451 return STATUS_NO_MEMORY
;
453 RtlCopyMemory(*Dest
, Src
->Buffer
, Src
->Length
);
454 (*Dest
)[Src
->Length
/ 2] = L
'\0';
456 return STATUS_SUCCESS
;
460 IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated
, PUNICODE_STRING UnicodeString
)
462 if (NullTerminated
!= UnicodeString
->Buffer
)
464 ExFreePool(NullTerminated
);
469 GetW32ProcessInfo(VOID
)
471 return (PPROCESSINFO
)PsGetCurrentProcessWin32Process();
475 GetW32ThreadInfo(VOID
)
480 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
484 /* FIXME - temporary hack for system threads... */
488 pti
->ppi
= ppi
= GetW32ProcessInfo();
490 if (pti
->rpdesk
!= NULL
)
492 pti
->pDeskInfo
= pti
->rpdesk
->pDeskInfo
;
496 pti
->pDeskInfo
= NULL
;
499 Teb
= NtCurrentTeb();
500 pci
= GetWin32ClientInfo();
501 pti
->pClientInfo
= pci
;
508 Teb
->Win32ThreadInfo
= (PW32THREAD
) pti
;
511 pci
->fsHooks
= pti
->fsHooks
;
512 if (pti
->KeyboardLayout
) pci
->hKL
= pti
->KeyboardLayout
->hkl
;
513 pci
->dwTIFlags
= pti
->TIF_flags
;
514 /* CI may not have been initialized. */
515 if (!pci
->pDeskInfo
&& pti
->pDeskInfo
)
517 if (!pci
->ulClientDelta
) pci
->ulClientDelta
= DesktopHeapGetUserDelta();
519 pci
->pDeskInfo
= (PVOID
)((ULONG_PTR
)pti
->pDeskInfo
- pci
->ulClientDelta
);
521 if (pti
->pcti
&& pci
->pDeskInfo
)
522 pci
->pClientThreadInfo
= (PVOID
)((ULONG_PTR
)pti
->pcti
- pci
->ulClientDelta
);
524 pci
->pClientThreadInfo
= NULL
;
527 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
529 SetLastNtError(_SEH2_GetExceptionCode());