2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Misc User funcs
5 * FILE: subsystem/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_MESSAGE_QUEUE MessageQueue
=
106 ((PTHREADINFO
)PsGetCurrentThreadWin32Thread())->MessageQueue
;
107 DPRINT1("THREADSTATE_INSENDMESSAGE\n");
110 if (!IsListEmpty(&MessageQueue
->SentMessagesListHead
))
114 else if (!IsListEmpty(&MessageQueue
->NotifyMessagesListHead
))
116 /* FIXME Need to set message flag when in callback mode with notify */
119 /* FIXME Need to set message flag if replied to or ReplyMessage */
122 case THREADSTATE_GETMESSAGETIME
:
123 /* FIXME Needs more work! */
124 ret
= ((PTHREADINFO
)PsGetCurrentThreadWin32Thread())->timeLast
;
127 case THREADSTATE_GETINPUTSTATE
:
128 ret
= HIWORD(IntGetQueueStatus(FALSE
)) & (QS_KEY
| QS_MOUSEBUTTON
);
132 DPRINT("Leave NtUserGetThreadState, ret=%i\n", ret
);
141 NtUserGetDoubleClickTime(VOID
)
145 DPRINT("Enter NtUserGetDoubleClickTime\n");
148 // FIXME: Check if this works on non-interactive winsta
149 Result
= gspv
.iDblClickTime
;
151 DPRINT("Leave NtUserGetDoubleClickTime, ret=%i\n", Result
);
158 NtUserGetGUIThreadInfo(
159 DWORD idThread
, /* if NULL use foreground thread */
160 LPGUITHREADINFO lpgui
)
163 PTHRDCARETINFO CaretInfo
;
164 GUITHREADINFO SafeGui
;
166 PUSER_MESSAGE_QUEUE MsgQueue
;
167 PETHREAD Thread
= NULL
;
168 DECLARE_RETURN(BOOLEAN
);
170 DPRINT("Enter NtUserGetGUIThreadInfo\n");
173 Status
= MmCopyFromCaller(&SafeGui
, lpgui
, sizeof(DWORD
));
174 if(!NT_SUCCESS(Status
))
176 SetLastNtError(Status
);
180 if(SafeGui
.cbSize
!= sizeof(GUITHREADINFO
))
182 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
188 Status
= PsLookupThreadByThreadId((HANDLE
)(DWORD_PTR
)idThread
, &Thread
);
189 if(!NT_SUCCESS(Status
))
191 SetLastWin32Error(ERROR_ACCESS_DENIED
);
194 Desktop
= ((PTHREADINFO
)Thread
->Tcb
.Win32Thread
)->Desktop
;
198 /* get the foreground thread */
199 PTHREADINFO W32Thread
= (PTHREADINFO
)PsGetCurrentThread()->Tcb
.Win32Thread
;
200 Desktop
= W32Thread
->Desktop
;
203 MsgQueue
= Desktop
->ActiveMessageQueue
;
206 Thread
= MsgQueue
->Thread
;
211 if(!Thread
|| !Desktop
)
213 if(idThread
&& Thread
)
214 ObDereferenceObject(Thread
);
215 SetLastWin32Error(ERROR_ACCESS_DENIED
);
219 MsgQueue
= (PUSER_MESSAGE_QUEUE
)Desktop
->ActiveMessageQueue
;
220 CaretInfo
= MsgQueue
->CaretInfo
;
222 SafeGui
.flags
= (CaretInfo
->Visible
? GUI_CARETBLINKING
: 0);
223 if(MsgQueue
->MenuOwner
)
224 SafeGui
.flags
|= GUI_INMENUMODE
| MsgQueue
->MenuState
;
225 if(MsgQueue
->MoveSize
)
226 SafeGui
.flags
|= GUI_INMOVESIZE
;
228 /* FIXME add flag GUI_16BITTASK */
230 SafeGui
.hwndActive
= MsgQueue
->ActiveWindow
;
231 SafeGui
.hwndFocus
= MsgQueue
->FocusWindow
;
232 SafeGui
.hwndCapture
= MsgQueue
->CaptureWindow
;
233 SafeGui
.hwndMenuOwner
= MsgQueue
->MenuOwner
;
234 SafeGui
.hwndMoveSize
= MsgQueue
->MoveSize
;
235 SafeGui
.hwndCaret
= CaretInfo
->hWnd
;
237 SafeGui
.rcCaret
.left
= CaretInfo
->Pos
.x
;
238 SafeGui
.rcCaret
.top
= CaretInfo
->Pos
.y
;
239 SafeGui
.rcCaret
.right
= SafeGui
.rcCaret
.left
+ CaretInfo
->Size
.cx
;
240 SafeGui
.rcCaret
.bottom
= SafeGui
.rcCaret
.top
+ CaretInfo
->Size
.cy
;
243 ObDereferenceObject(Thread
);
245 Status
= MmCopyToCaller(lpgui
, &SafeGui
, sizeof(GUITHREADINFO
));
246 if(!NT_SUCCESS(Status
))
248 SetLastNtError(Status
);
255 DPRINT("Leave NtUserGetGUIThreadInfo, ret=%i\n",_ret_
);
263 NtUserGetGuiResources(
268 PPROCESSINFO W32Process
;
271 DECLARE_RETURN(DWORD
);
273 DPRINT("Enter NtUserGetGuiResources\n");
276 Status
= ObReferenceObjectByHandle(hProcess
,
277 PROCESS_QUERY_INFORMATION
,
283 if(!NT_SUCCESS(Status
))
285 SetLastNtError(Status
);
289 W32Process
= (PPROCESSINFO
)Process
->Win32Process
;
292 ObDereferenceObject(Process
);
293 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
301 Ret
= (DWORD
)W32Process
->GDIHandleCount
;
306 Ret
= (DWORD
)W32Process
->UserHandleCount
;
311 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
316 ObDereferenceObject(Process
);
321 DPRINT("Leave NtUserGetGuiResources, ret=%i\n",_ret_
);
327 IntSafeCopyUnicodeString(PUNICODE_STRING Dest
,
328 PUNICODE_STRING Source
)
333 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
334 if(!NT_SUCCESS(Status
))
339 if(Dest
->Length
> 0x4000)
341 return STATUS_UNSUCCESSFUL
;
346 Dest
->MaximumLength
= Dest
->Length
;
348 if(Dest
->Length
> 0 && Src
)
350 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
353 return STATUS_NO_MEMORY
;
356 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
357 if(!NT_SUCCESS(Status
))
359 ExFreePoolWithTag(Dest
->Buffer
, TAG_STRING
);
365 return STATUS_SUCCESS
;
368 /* string is empty */
369 return STATUS_SUCCESS
;
373 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest
,
374 PUNICODE_STRING Source
)
379 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
380 if(!NT_SUCCESS(Status
))
385 if(Dest
->Length
> 0x4000)
387 return STATUS_UNSUCCESSFUL
;
392 Dest
->MaximumLength
= 0;
394 if(Dest
->Length
> 0 && Src
)
396 Dest
->MaximumLength
= Dest
->Length
+ sizeof(WCHAR
);
397 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
400 return STATUS_NO_MEMORY
;
403 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
404 if(!NT_SUCCESS(Status
))
406 ExFreePoolWithTag(Dest
->Buffer
, TAG_STRING
);
411 /* make sure the string is null-terminated */
412 Src
= (PWSTR
)((PBYTE
)Dest
->Buffer
+ Dest
->Length
);
415 return STATUS_SUCCESS
;
418 /* string is empty */
419 return STATUS_SUCCESS
;
423 IntUnicodeStringToNULLTerminated(PWSTR
*Dest
, PUNICODE_STRING Src
)
425 if (Src
->Length
+ sizeof(WCHAR
) <= Src
->MaximumLength
426 && L
'\0' == Src
->Buffer
[Src
->Length
/ sizeof(WCHAR
)])
428 /* The unicode_string is already nul terminated. Just reuse it. */
430 return STATUS_SUCCESS
;
433 *Dest
= ExAllocatePoolWithTag(PagedPool
, Src
->Length
+ sizeof(WCHAR
), TAG_STRING
);
436 return STATUS_NO_MEMORY
;
438 RtlCopyMemory(*Dest
, Src
->Buffer
, Src
->Length
);
439 (*Dest
)[Src
->Length
/ 2] = L
'\0';
441 return STATUS_SUCCESS
;
445 IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated
, PUNICODE_STRING UnicodeString
)
447 if (NullTerminated
!= UnicodeString
->Buffer
)
449 ExFreePool(NullTerminated
);
454 GetW32ProcessInfo(VOID
)
456 return (PPROCESSINFO
)PsGetCurrentProcessWin32Process();
460 GetW32ThreadInfo(VOID
)
465 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
469 /* FIXME - temporary hack for system threads... */
473 pti
->ppi
= ppi
= GetW32ProcessInfo();
475 pti
->pcti
= &pti
->cti
; // FIXME Need to set it in desktop.c!
477 if (pti
->Desktop
!= NULL
)
479 pti
->pDeskInfo
= pti
->Desktop
->DesktopInfo
;
483 pti
->pDeskInfo
= NULL
;
486 Teb
= NtCurrentTeb();
487 pci
= GetWin32ClientInfo();
488 pti
->pClientInfo
= pci
;
495 Teb
->Win32ThreadInfo
= (PW32THREAD
) pti
;
497 pci
->pClientThreadInfo
= NULL
; // FIXME Need to set it in desktop.c!
499 pci
->fsHooks
= pti
->fsHooks
;
500 if (pti
->KeyboardLayout
) pci
->hKL
= pti
->KeyboardLayout
->hkl
;
501 /* CI may not have been initialized. */
502 if (!pci
->pDeskInfo
&& pti
->pDeskInfo
)
504 if (!pci
->ulClientDelta
) pci
->ulClientDelta
= DesktopHeapGetUserDelta();
506 pci
->pDeskInfo
= (PVOID
)((ULONG_PTR
)pti
->pDeskInfo
- pci
->ulClientDelta
);
509 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
511 SetLastNtError(_SEH2_GetExceptionCode());