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
);
70 DECLARE_RETURN(DWORD
);
72 DPRINT("Enter NtUserGetThreadState\n");
73 if (Routine
!= THREADSTATE_GETTHREADINFO
)
84 case THREADSTATE_GETTHREADINFO
:
88 case THREADSTATE_FOCUSWINDOW
:
89 RETURN( (DWORD
)IntGetThreadFocusWindow());
90 case THREADSTATE_CAPTUREWINDOW
:
91 /* FIXME should use UserEnterShared */
92 RETURN( (DWORD
)IntGetCapture());
93 case THREADSTATE_PROGMANWINDOW
:
94 RETURN( (DWORD
)GetW32ThreadInfo()->pDeskInfo
->hProgmanWindow
);
95 case THREADSTATE_TASKMANWINDOW
:
96 RETURN( (DWORD
)GetW32ThreadInfo()->pDeskInfo
->hTaskManWindow
);
97 case THREADSTATE_ACTIVEWINDOW
:
98 RETURN ( (DWORD
)UserGetActiveWindow());
99 case THREADSTATE_INSENDMESSAGE
:
101 DWORD Ret
= ISMEX_NOSEND
;
102 PUSER_MESSAGE_QUEUE MessageQueue
=
103 ((PTHREADINFO
)PsGetCurrentThreadWin32Thread())->MessageQueue
;
104 DPRINT1("THREADSTATE_INSENDMESSAGE\n");
106 if (!IsListEmpty(&MessageQueue
->SentMessagesListHead
))
110 else if (!IsListEmpty(&MessageQueue
->NotifyMessagesListHead
))
112 /* FIXME Need to set message flag when in callback mode with notify */
115 /* FIXME Need to set message flag if replied to or ReplyMessage */
118 case THREADSTATE_GETMESSAGETIME
:
119 /* FIXME Needs more work! */
120 RETURN( ((PTHREADINFO
)PsGetCurrentThreadWin32Thread())->timeLast
);
122 case THREADSTATE_GETINPUTSTATE
:
123 RETURN( HIWORD(IntGetQueueStatus(FALSE
)) & (QS_KEY
| QS_MOUSEBUTTON
));
128 DPRINT("Leave NtUserGetThreadState, ret=%i\n",_ret_
);
136 NtUserGetDoubleClickTime(VOID
)
140 DPRINT("Enter NtUserGetDoubleClickTime\n");
143 // FIXME: Check if this works on non-interactive winsta
144 Result
= gspv
.iDblClickTime
;
146 DPRINT("Leave NtUserGetDoubleClickTime, ret=%i\n", Result
);
153 NtUserGetGUIThreadInfo(
154 DWORD idThread
, /* if NULL use foreground thread */
155 LPGUITHREADINFO lpgui
)
158 PTHRDCARETINFO CaretInfo
;
159 GUITHREADINFO SafeGui
;
161 PUSER_MESSAGE_QUEUE MsgQueue
;
162 PETHREAD Thread
= NULL
;
163 DECLARE_RETURN(BOOLEAN
);
165 DPRINT("Enter NtUserGetGUIThreadInfo\n");
168 Status
= MmCopyFromCaller(&SafeGui
, lpgui
, sizeof(DWORD
));
169 if(!NT_SUCCESS(Status
))
171 SetLastNtError(Status
);
175 if(SafeGui
.cbSize
!= sizeof(GUITHREADINFO
))
177 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
183 Status
= PsLookupThreadByThreadId((HANDLE
)idThread
, &Thread
);
184 if(!NT_SUCCESS(Status
))
186 SetLastWin32Error(ERROR_ACCESS_DENIED
);
189 Desktop
= ((PTHREADINFO
)Thread
->Tcb
.Win32Thread
)->Desktop
;
193 /* get the foreground thread */
194 PTHREADINFO W32Thread
= (PTHREADINFO
)PsGetCurrentThread()->Tcb
.Win32Thread
;
195 Desktop
= W32Thread
->Desktop
;
198 MsgQueue
= Desktop
->ActiveMessageQueue
;
201 Thread
= MsgQueue
->Thread
;
206 if(!Thread
|| !Desktop
)
208 if(idThread
&& Thread
)
209 ObDereferenceObject(Thread
);
210 SetLastWin32Error(ERROR_ACCESS_DENIED
);
214 MsgQueue
= (PUSER_MESSAGE_QUEUE
)Desktop
->ActiveMessageQueue
;
215 CaretInfo
= MsgQueue
->CaretInfo
;
217 SafeGui
.flags
= (CaretInfo
->Visible
? GUI_CARETBLINKING
: 0);
218 if(MsgQueue
->MenuOwner
)
219 SafeGui
.flags
|= GUI_INMENUMODE
| MsgQueue
->MenuState
;
220 if(MsgQueue
->MoveSize
)
221 SafeGui
.flags
|= GUI_INMOVESIZE
;
223 /* FIXME add flag GUI_16BITTASK */
225 SafeGui
.hwndActive
= MsgQueue
->ActiveWindow
;
226 SafeGui
.hwndFocus
= MsgQueue
->FocusWindow
;
227 SafeGui
.hwndCapture
= MsgQueue
->CaptureWindow
;
228 SafeGui
.hwndMenuOwner
= MsgQueue
->MenuOwner
;
229 SafeGui
.hwndMoveSize
= MsgQueue
->MoveSize
;
230 SafeGui
.hwndCaret
= CaretInfo
->hWnd
;
232 SafeGui
.rcCaret
.left
= CaretInfo
->Pos
.x
;
233 SafeGui
.rcCaret
.top
= CaretInfo
->Pos
.y
;
234 SafeGui
.rcCaret
.right
= SafeGui
.rcCaret
.left
+ CaretInfo
->Size
.cx
;
235 SafeGui
.rcCaret
.bottom
= SafeGui
.rcCaret
.top
+ CaretInfo
->Size
.cy
;
238 ObDereferenceObject(Thread
);
240 Status
= MmCopyToCaller(lpgui
, &SafeGui
, sizeof(GUITHREADINFO
));
241 if(!NT_SUCCESS(Status
))
243 SetLastNtError(Status
);
250 DPRINT("Leave NtUserGetGUIThreadInfo, ret=%i\n",_ret_
);
258 NtUserGetGuiResources(
263 PPROCESSINFO W32Process
;
266 DECLARE_RETURN(DWORD
);
268 DPRINT("Enter NtUserGetGuiResources\n");
271 Status
= ObReferenceObjectByHandle(hProcess
,
272 PROCESS_QUERY_INFORMATION
,
278 if(!NT_SUCCESS(Status
))
280 SetLastNtError(Status
);
284 W32Process
= (PPROCESSINFO
)Process
->Win32Process
;
287 ObDereferenceObject(Process
);
288 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
296 Ret
= (DWORD
)W32Process
->GDIHandleCount
;
301 Ret
= (DWORD
)W32Process
->UserHandleCount
;
306 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
311 ObDereferenceObject(Process
);
316 DPRINT("Leave NtUserGetGuiResources, ret=%i\n",_ret_
);
322 IntSafeCopyUnicodeString(PUNICODE_STRING Dest
,
323 PUNICODE_STRING Source
)
328 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
329 if(!NT_SUCCESS(Status
))
334 if(Dest
->Length
> 0x4000)
336 return STATUS_UNSUCCESSFUL
;
341 Dest
->MaximumLength
= Dest
->Length
;
343 if(Dest
->Length
> 0 && Src
)
345 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
348 return STATUS_NO_MEMORY
;
351 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
352 if(!NT_SUCCESS(Status
))
354 ExFreePoolWithTag(Dest
->Buffer
, TAG_STRING
);
360 return STATUS_SUCCESS
;
363 /* string is empty */
364 return STATUS_SUCCESS
;
368 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest
,
369 PUNICODE_STRING Source
)
374 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
375 if(!NT_SUCCESS(Status
))
380 if(Dest
->Length
> 0x4000)
382 return STATUS_UNSUCCESSFUL
;
387 Dest
->MaximumLength
= 0;
389 if(Dest
->Length
> 0 && Src
)
391 Dest
->MaximumLength
= Dest
->Length
+ sizeof(WCHAR
);
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
);
406 /* make sure the string is null-terminated */
407 Src
= (PWSTR
)((PBYTE
)Dest
->Buffer
+ Dest
->Length
);
410 return STATUS_SUCCESS
;
413 /* string is empty */
414 return STATUS_SUCCESS
;
418 IntUnicodeStringToNULLTerminated(PWSTR
*Dest
, PUNICODE_STRING Src
)
420 if (Src
->Length
+ sizeof(WCHAR
) <= Src
->MaximumLength
421 && L
'\0' == Src
->Buffer
[Src
->Length
/ sizeof(WCHAR
)])
423 /* The unicode_string is already nul terminated. Just reuse it. */
425 return STATUS_SUCCESS
;
428 *Dest
= ExAllocatePoolWithTag(PagedPool
, Src
->Length
+ sizeof(WCHAR
), TAG_STRING
);
431 return STATUS_NO_MEMORY
;
433 RtlCopyMemory(*Dest
, Src
->Buffer
, Src
->Length
);
434 (*Dest
)[Src
->Length
/ 2] = L
'\0';
436 return STATUS_SUCCESS
;
440 IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated
, PUNICODE_STRING UnicodeString
)
442 if (NullTerminated
!= UnicodeString
->Buffer
)
444 ExFreePool(NullTerminated
);
449 GetW32ProcessInfo(VOID
)
451 return (PPROCESSINFO
)PsGetCurrentProcessWin32Process();
455 GetW32ThreadInfo(VOID
)
460 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
464 /* FIXME - temporary hack for system threads... */
468 pti
->ppi
= ppi
= GetW32ProcessInfo();
470 pti
->pcti
= &pti
->cti
; // FIXME Need to set it in desktop.c!
472 if (pti
->Desktop
!= NULL
)
474 pti
->pDeskInfo
= pti
->Desktop
->DesktopInfo
;
478 pti
->pDeskInfo
= NULL
;
481 Teb
= NtCurrentTeb();
482 pci
= GetWin32ClientInfo();
483 pti
->pClientInfo
= pci
;
490 Teb
->Win32ThreadInfo
= (PW32THREAD
) pti
;
492 pci
->pClientThreadInfo
= NULL
; // FIXME Need to set it in desktop.c!
494 pci
->fsHooks
= pti
->fsHooks
;
495 /* CI may not have been initialized. */
496 if (!pci
->pDeskInfo
&& pti
->pDeskInfo
)
498 if (!pci
->ulClientDelta
) pci
->ulClientDelta
= DesktopHeapGetUserDelta();
500 pci
->pDeskInfo
= (PVOID
)((ULONG_PTR
)pti
->pDeskInfo
- pci
->ulClientDelta
);
503 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
505 SetLastNtError(_SEH2_GetExceptionCode());