gave NtUserCall*Param decent names
[reactos.git] / reactos / subsys / win32k / ntuser / misc.c
1 /* $Id: misc.c,v 1.43 2004/01/26 08:44:51 weiden Exp $
2 *
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)
8 * REVISION HISTORY:
9 * 2003/05/22 Created
10 */
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>
24 #include <include/focus.h>
25 #include <include/clipboard.h>
26 #include <include/msgqueue.h>
27 #include <include/desktop.h>
28 #include <include/text.h>
29
30 #define NDEBUG
31 #include <debug.h>
32
33 void W32kRegisterPrimitiveMessageQueue() {
34 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
35 if( !pmPrimitiveMessageQueue ) {
36 PW32THREAD pThread;
37 pThread = PsGetWin32Thread();
38 if( pThread && pThread->MessageQueue ) {
39 pmPrimitiveMessageQueue = pThread->MessageQueue;
40 DPRINT( "Installed primitive input queue.\n" );
41 }
42 } else {
43 DPRINT1( "Alert! Someone is trying to steal the primitive queue.\n" );
44 }
45 }
46
47 PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue() {
48 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
49 return pmPrimitiveMessageQueue;
50 }
51
52 /*
53 * @unimplemented
54 */
55 DWORD
56 STDCALL
57 NtUserCallNoParam(DWORD Routine)
58 {
59 DWORD Result = 0;
60
61 switch(Routine)
62 {
63 case NOPARAM_ROUTINE_REGISTER_PRIMITIVE:
64 W32kRegisterPrimitiveMessageQueue();
65 Result = (DWORD)TRUE;
66 break;
67
68 case NOPARAM_ROUTINE_DESTROY_CARET:
69 Result = (DWORD)IntDestroyCaret(PsGetCurrentThread()->Win32Thread);
70 break;
71
72 case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP:
73 Result = (DWORD)IntInitMessagePumpHook();
74 break;
75
76 case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP:
77 Result = (DWORD)IntUninitMessagePumpHook();
78 break;
79
80 case NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO:
81 Result = (DWORD)MsqGetMessageExtraInfo();
82 break;
83
84 default:
85 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam\n");
86 SetLastWin32Error(ERROR_INVALID_PARAMETER);
87 break;
88 }
89 return Result;
90 }
91
92 /*
93 * @implemented
94 */
95 DWORD
96 STDCALL
97 NtUserCallOneParam(
98 DWORD Param,
99 DWORD Routine)
100 {
101 NTSTATUS Status;
102 DWORD Result = 0;
103 PWINSTATION_OBJECT WinStaObject;
104 PWINDOW_OBJECT WindowObject;
105
106 switch(Routine)
107 {
108 case ONEPARAM_ROUTINE_GETMENU:
109 WindowObject = IntGetWindowObject((HWND)Param);
110 if(!WindowObject)
111 {
112 SetLastWin32Error(ERROR_INVALID_HANDLE);
113 return FALSE;
114 }
115
116 Result = (DWORD)WindowObject->IDMenu;
117
118 IntReleaseWindowObject(WindowObject);
119 return Result;
120
121 case ONEPARAM_ROUTINE_ISWINDOWUNICODE:
122 WindowObject = IntGetWindowObject((HWND)Param);
123 if(!WindowObject)
124 {
125 SetLastWin32Error(ERROR_INVALID_HANDLE);
126 return FALSE;
127 }
128 Result = WindowObject->Unicode;
129 IntReleaseWindowObject(WindowObject);
130 return Result;
131
132 case ONEPARAM_ROUTINE_WINDOWFROMDC:
133 return (DWORD)IntWindowFromDC((HDC)Param);
134
135 case ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID:
136 WindowObject = IntGetWindowObject((HWND)Param);
137 if(!WindowObject)
138 {
139 SetLastWin32Error(ERROR_INVALID_HANDLE);
140 return FALSE;
141 }
142
143 Result = WindowObject->ContextHelpId;
144
145 IntReleaseWindowObject(WindowObject);
146 return Result;
147
148 case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON:
149 Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
150 KernelMode,
151 0,
152 &WinStaObject);
153 if (!NT_SUCCESS(Status))
154 return (DWORD)FALSE;
155
156 Result = (DWORD)IntSwapMouseButton(WinStaObject, (BOOL)Param);
157
158 ObDereferenceObject(WinStaObject);
159 return Result;
160
161 case ONEPARAM_ROUTINE_SWITCHCARETSHOWING:
162 return (DWORD)IntSwitchCaretShowing((PVOID)Param);
163
164 case ONEPARAM_ROUTINE_SETCARETBLINKTIME:
165 return (DWORD)IntSetCaretBlinkTime((UINT)Param);
166
167 case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS:
168 return (DWORD)IntEnumClipboardFormats((UINT)Param);
169
170 case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO:
171 return (DWORD)MsqSetMessageExtraInfo((LPARAM)Param);
172 }
173 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam()\n Param=0x%x\n",
174 Routine, Param);
175 SetLastWin32Error(ERROR_INVALID_PARAMETER);
176 return 0;
177 }
178
179
180 /*
181 * @implemented
182 */
183 DWORD
184 STDCALL
185 NtUserCallTwoParam(
186 DWORD Param1,
187 DWORD Param2,
188 DWORD Routine)
189 {
190 NTSTATUS Status;
191 PWINDOW_OBJECT WindowObject;
192 PSYSTEM_CURSORINFO CurInfo;
193 PWINSTATION_OBJECT WinStaObject;
194 POINT Pos;
195
196 switch(Routine)
197 {
198 case TWOPARAM_ROUTINE_SETMENUITEMRECT:
199 UNIMPLEMENTED
200 return 0;
201
202 case TWOPARAM_ROUTINE_SETGUITHRDHANDLE:
203 {
204 HWND *hwnd;
205 PUSER_MESSAGE_QUEUE MsgQueue = PsGetCurrentThread()->Win32Thread->MessageQueue;
206
207 switch(Param1)
208 {
209 case TPR_SGTH_ACTIVE:
210 hwnd = &MsgQueue->ActiveWindow;
211 break;
212 case TPR_SGTH_FOCUS:
213 hwnd = &MsgQueue->FocusWindow;
214 break;
215 case TPR_SGTH_CAPTURE:
216 hwnd = &MsgQueue->CaptureWindow;
217 break;
218 case TPR_SGTH_MENUOWNER:
219 hwnd = &MsgQueue->MenuOwner;
220 break;
221 case TPR_SGTH_MOVESIZE:
222 hwnd = &MsgQueue->MoveSize;
223 break;
224 case TPR_SGTH_CARET:
225 hwnd = &MsgQueue->CaretInfo->hWnd;
226 break;
227 default:
228 return 0;
229 }
230 return (DWORD)(*hwnd = (HWND)Param2);
231 }
232
233 case TWOPARAM_ROUTINE_ENABLEWINDOW:
234 UNIMPLEMENTED
235 return 0;
236
237 case TWOPARAM_ROUTINE_UNKNOWN:
238 UNIMPLEMENTED
239 return 0;
240
241 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS:
242 UNIMPLEMENTED
243 return 0;
244
245 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW:
246 UNIMPLEMENTED
247 return 0;
248
249 case TWOPARAM_ROUTINE_VALIDATERGN:
250 return (DWORD)NtUserValidateRgn((HWND) Param1, (HRGN) Param2);
251
252 case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID:
253 WindowObject = IntGetWindowObject((HWND)Param1);
254 if(!WindowObject)
255 {
256 SetLastWin32Error(ERROR_INVALID_HANDLE);
257 return (DWORD)FALSE;
258 }
259
260 WindowObject->ContextHelpId = Param2;
261
262 IntReleaseWindowObject(WindowObject);
263 return (DWORD)TRUE;
264
265 case TWOPARAM_ROUTINE_CURSORPOSITION:
266 if(!Param1)
267 return (DWORD)FALSE;
268 Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
269 KernelMode,
270 0,
271 &WinStaObject);
272 if (!NT_SUCCESS(Status))
273 return (DWORD)FALSE;
274
275 if(Param2)
276 {
277 /* set cursor position */
278
279 Status = MmCopyFromCaller(&Pos, (PPOINT)Param1, sizeof(POINT));
280 if(!NT_SUCCESS(Status))
281 {
282 ObDereferenceObject(WinStaObject);
283 SetLastNtError(Status);
284 return FALSE;
285 }
286
287 CurInfo = &WinStaObject->SystemCursor;
288 /* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
289
290 //CheckClipCursor(&Pos->x, &Pos->y, CurInfo);
291 if((Pos.x != CurInfo->x) || (Pos.y != CurInfo->y))
292 {
293 MouseMoveCursor(Pos.x, Pos.y);
294 }
295
296 }
297 else
298 {
299 /* get cursor position */
300 /* FIXME - check if process has WINSTA_READATTRIBUTES */
301 Pos.x = WinStaObject->SystemCursor.x;
302 Pos.y = WinStaObject->SystemCursor.y;
303
304 Status = MmCopyToCaller((PPOINT)Param1, &Pos, sizeof(POINT));
305 if(!NT_SUCCESS(Status))
306 {
307 ObDereferenceObject(WinStaObject);
308 SetLastNtError(Status);
309 return FALSE;
310 }
311
312 }
313
314 ObDereferenceObject(WinStaObject);
315
316 return (DWORD)TRUE;
317
318 case TWOPARAM_ROUTINE_SETCARETPOS:
319 return (DWORD)IntSetCaretPos((int)Param1, (int)Param2);
320 }
321 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam()\n Param1=0x%x Parm2=0x%x\n",
322 Routine, Param1, Param2);
323 SetLastWin32Error(ERROR_INVALID_PARAMETER);
324 return 0;
325 }
326
327 /*
328 * @unimplemented
329 */
330 BOOL
331 STDCALL
332 NtUserCallHwndLock(
333 HWND hWnd,
334 DWORD Routine)
335 {
336 BOOL Ret = 0;
337 PWINDOW_OBJECT Window;
338
339 Window = IntGetWindowObject(hWnd);
340 if (Window == 0)
341 {
342 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
343 return FALSE;
344 }
345
346 /* FIXME: Routine can be 0x53 - 0x5E */
347 switch (Routine)
348 {
349 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS:
350 /* FIXME */
351 break;
352
353 case HWNDLOCK_ROUTINE_DRAWMENUBAR:
354 /* FIXME */
355 break;
356
357 case HWNDLOCK_ROUTINE_REDRAWFRAME:
358 /* FIXME */
359 break;
360
361 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW:
362 Ret = IntSetForegroundWindow(Window);
363 break;
364
365 case HWNDLOCK_ROUTINE_UPDATEWINDOW:
366 /* FIXME */
367 break;
368 }
369
370 IntReleaseWindowObject(Window);
371
372 return Ret;
373 }
374
375 HWND
376 STDCALL
377 NtUserCallHwndOpt(
378 HWND Param,
379 DWORD Routine)
380 {
381 switch (Routine)
382 {
383 case HWNDOPT_ROUTINE_SETPROGMANWINDOW:
384 /* FIXME */
385 break;
386
387 case HWNDOPT_ROUTINE_SETTASKMANWINDOW:
388 /* FIXME */
389 break;
390 }
391
392 return 0;
393 }
394
395 /*
396 * @unimplemented
397 */
398 DWORD STDCALL
399 NtUserGetThreadState(
400 DWORD Routine)
401 {
402 switch (Routine)
403 {
404 case 0:
405 return (DWORD)IntGetThreadFocusWindow();
406 }
407 return 0;
408 }
409
410 /*
411 * @implemented
412 */
413 DWORD
414 STDCALL
415 NtUserSystemParametersInfo(
416 UINT uiAction,
417 UINT uiParam,
418 PVOID pvParam,
419 UINT fWinIni)
420 {
421 static BOOL GradientCaptions = TRUE;
422 /* FIXME: This should be obtained from the registry */
423 static LOGFONTW CaptionFont =
424 { 12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
425 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, L"" };
426 NTSTATUS Status;
427 PWINSTATION_OBJECT WinStaObject;
428
429 switch(uiAction)
430 {
431 case SPI_SETDOUBLECLKWIDTH:
432 case SPI_SETDOUBLECLKHEIGHT:
433 case SPI_SETDOUBLECLICKTIME:
434 {
435 Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
436 KernelMode,
437 0,
438 &WinStaObject);
439 if (!NT_SUCCESS(Status))
440 return (DWORD)FALSE;
441
442 switch(uiAction)
443 {
444 case SPI_SETDOUBLECLKWIDTH:
445 /* FIXME limit the maximum value? */
446 WinStaObject->SystemCursor.DblClickWidth = uiParam;
447 break;
448 case SPI_SETDOUBLECLKHEIGHT:
449 /* FIXME limit the maximum value? */
450 WinStaObject->SystemCursor.DblClickHeight = uiParam;
451 break;
452 case SPI_SETDOUBLECLICKTIME:
453 /* FIXME limit the maximum time to 1000 ms? */
454 WinStaObject->SystemCursor.DblClickSpeed = uiParam;
455 break;
456 }
457
458 /* FIXME save the value to the registry */
459
460 ObDereferenceObject(WinStaObject);
461 return TRUE;
462 }
463 case SPI_SETWORKAREA:
464 {
465 PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
466
467 if(!Desktop)
468 {
469 /* FIXME - Set last error */
470 return FALSE;
471 }
472
473 Status = MmCopyFromCaller(Desktop->WorkArea, (PRECT)pvParam, sizeof(RECT));
474 if(!NT_SUCCESS(Status))
475 {
476 SetLastNtError(Status);
477 return FALSE;
478 }
479
480 return TRUE;
481 }
482 case SPI_GETWORKAREA:
483 {
484 PRECT Rect;
485 PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
486
487 if(!Desktop)
488 {
489 /* FIXME - Set last error */
490 return FALSE;
491 }
492
493 Rect = IntGetDesktopWorkArea(Desktop);
494
495 Status = MmCopyToCaller((PRECT)pvParam, Desktop->WorkArea, sizeof(RECT));
496 if(!NT_SUCCESS(Status))
497 {
498 SetLastNtError(Status);
499 return FALSE;
500 }
501
502 return TRUE;
503 }
504 case SPI_GETICONTITLELOGFONT:
505 {
506 Status = MmCopyToCaller(pvParam, &CaptionFont, sizeof(CaptionFont));
507 if(!NT_SUCCESS(Status))
508 {
509 SetLastNtError(Status);
510 return FALSE;
511 }
512 return TRUE;
513 }
514 case SPI_GETNONCLIENTMETRICS:
515 {
516 /* FIXME - use MmCopyToCaller() !!! */
517 LPNONCLIENTMETRICSW pMetrics = (LPNONCLIENTMETRICSW)pvParam;
518
519 if (pMetrics->cbSize != sizeof(NONCLIENTMETRICSW) ||
520 uiParam != sizeof(NONCLIENTMETRICSW))
521 {
522 return FALSE;
523 }
524
525 memset((char *)pvParam + sizeof(pMetrics->cbSize), 0,
526 pMetrics->cbSize - sizeof(pMetrics->cbSize));
527
528 pMetrics->iBorderWidth = 1;
529 pMetrics->iScrollWidth = NtUserGetSystemMetrics(SM_CXVSCROLL);
530 pMetrics->iScrollHeight = NtUserGetSystemMetrics(SM_CYHSCROLL);
531 pMetrics->iCaptionWidth = NtUserGetSystemMetrics(SM_CXSIZE);
532 pMetrics->iCaptionHeight = NtUserGetSystemMetrics(SM_CYSIZE);
533 memcpy((LPVOID)&(pMetrics->lfCaptionFont), &CaptionFont, sizeof(CaptionFont));
534 pMetrics->lfCaptionFont.lfWeight = FW_BOLD;
535 pMetrics->iSmCaptionWidth = NtUserGetSystemMetrics(SM_CXSMSIZE);
536 pMetrics->iSmCaptionHeight = NtUserGetSystemMetrics(SM_CYSMSIZE);
537 memcpy((LPVOID)&(pMetrics->lfSmCaptionFont), &CaptionFont, sizeof(CaptionFont));
538 pMetrics->iMenuWidth = NtUserGetSystemMetrics(SM_CXMENUSIZE);
539 pMetrics->iMenuHeight = NtUserGetSystemMetrics(SM_CYMENUSIZE);
540 memcpy((LPVOID)&(pMetrics->lfMenuFont), &CaptionFont, sizeof(CaptionFont));
541 memcpy((LPVOID)&(pMetrics->lfStatusFont), &CaptionFont, sizeof(CaptionFont));
542 memcpy((LPVOID)&(pMetrics->lfMessageFont), &CaptionFont, sizeof(CaptionFont));
543 return TRUE;
544 }
545 case SPI_GETGRADIENTCAPTIONS:
546 {
547 HDC hDC;
548 PDC dc;
549 PSURFOBJ SurfObj;
550 BOOL Ret = GradientCaptions;
551
552 hDC = IntGetScreenDC();
553 if(hDC)
554 {
555 dc = DC_LockDc(hDC);
556 SurfObj = (PSURFOBJ)AccessUserObject((ULONG) dc->Surface);
557 if(SurfObj)
558 Ret = (SurfObj->iBitmapFormat > BMF_8BPP);
559 DC_UnlockDc(hDC);
560 }
561
562 Status = MmCopyToCaller(pvParam, &Ret, sizeof(BOOL));
563 if(!NT_SUCCESS(Status))
564 {
565 SetLastNtError(Status);
566 return FALSE;
567 }
568 return TRUE;
569 }
570 case SPI_SETGRADIENTCAPTIONS:
571 {
572 Status = MmCopyFromCaller(&GradientCaptions, pvParam, sizeof(BOOL));
573 if(!NT_SUCCESS(Status))
574 {
575 SetLastNtError(Status);
576 return FALSE;
577 }
578 return TRUE;
579 }
580 case SPI_SETFONTSMOOTHING:
581 {
582 BOOL Enable;
583
584 Status = MmCopyFromCaller(&Enable, pvParam, sizeof(BOOL));
585 if(!NT_SUCCESS(Status))
586 {
587 SetLastNtError(Status);
588 return FALSE;
589 }
590
591 IntEnableFontRendering(Enable);
592
593 return TRUE;
594 }
595 case SPI_GETFONTSMOOTHING:
596 {
597 BOOL Enabled = IntIsFontRenderingEnabled();
598
599 Status = MmCopyToCaller(pvParam, &Enabled, sizeof(BOOL));
600 if(!NT_SUCCESS(Status))
601 {
602 SetLastNtError(Status);
603 return FALSE;
604 }
605 return TRUE;
606 }
607 }
608 return FALSE;
609 }
610
611 UINT
612 STDCALL
613 NtUserGetDoubleClickTime(VOID)
614 {
615 UINT Result;
616 NTSTATUS Status;
617 PWINSTATION_OBJECT WinStaObject;
618
619 Status = IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
620 KernelMode,
621 0,
622 &WinStaObject);
623 if (!NT_SUCCESS(Status))
624 return (DWORD)FALSE;
625
626 Result = WinStaObject->SystemCursor.DblClickSpeed;
627
628 ObDereferenceObject(WinStaObject);
629 return Result;
630 }
631
632 BOOL
633 STDCALL
634 NtUserGetGUIThreadInfo(
635 DWORD idThread,
636 LPGUITHREADINFO lpgui)
637 {
638 NTSTATUS Status;
639 PTHRDCARETINFO CaretInfo;
640 GUITHREADINFO SafeGui;
641 PDESKTOP_OBJECT Desktop;
642 PUSER_MESSAGE_QUEUE MsgQueue;
643 PETHREAD Thread = NULL;
644
645 Status = MmCopyFromCaller(&SafeGui, lpgui, sizeof(DWORD));
646 if(!NT_SUCCESS(Status))
647 {
648 SetLastNtError(Status);
649 return FALSE;
650 }
651
652 if(SafeGui.cbSize != sizeof(GUITHREADINFO))
653 {
654 SetLastWin32Error(ERROR_INVALID_PARAMETER);
655 return FALSE;
656 }
657
658 if(idThread)
659 {
660 Status = PsLookupThreadByThreadId((PVOID)idThread, &Thread);
661 if(!NT_SUCCESS(Status))
662 {
663 SetLastWin32Error(ERROR_ACCESS_DENIED);
664 return FALSE;
665 }
666 Desktop = Thread->Win32Thread->Desktop;
667 }
668 else
669 {
670 /* get the foreground thread */
671 PW32THREAD W32Thread = PsGetCurrentThread()->Win32Thread;
672 Desktop = W32Thread->Desktop;
673 if(Desktop)
674 {
675 MsgQueue = Desktop->ActiveMessageQueue;
676 if(MsgQueue)
677 {
678 Thread = MsgQueue->Thread;
679 }
680 }
681 }
682
683 if(!Thread || !Desktop)
684 {
685 if(idThread && Thread)
686 ObDereferenceObject(Thread);
687 SetLastWin32Error(ERROR_ACCESS_DENIED);
688 return FALSE;
689 }
690
691 MsgQueue = (PUSER_MESSAGE_QUEUE)Desktop->ActiveMessageQueue;
692 CaretInfo = MsgQueue->CaretInfo;
693
694 SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0);
695 if(MsgQueue->MenuOwner)
696 SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState;
697 if(MsgQueue->MoveSize)
698 SafeGui.flags |= GUI_INMOVESIZE;
699
700 /* FIXME add flag GUI_16BITTASK */
701
702 SafeGui.hwndActive = MsgQueue->ActiveWindow;
703 SafeGui.hwndFocus = MsgQueue->FocusWindow;
704 SafeGui.hwndCapture = MsgQueue->CaptureWindow;
705 SafeGui.hwndMenuOwner = MsgQueue->MenuOwner;
706 SafeGui.hwndMoveSize = MsgQueue->MoveSize;
707 SafeGui.hwndCaret = CaretInfo->hWnd;
708
709 SafeGui.rcCaret.left = CaretInfo->Pos.x;
710 SafeGui.rcCaret.top = CaretInfo->Pos.y;
711 SafeGui.rcCaret.right = SafeGui.rcCaret.left + CaretInfo->Size.cx;
712 SafeGui.rcCaret.bottom = SafeGui.rcCaret.top + CaretInfo->Size.cy;
713
714 if(idThread)
715 ObDereferenceObject(Thread);
716
717 Status = MmCopyToCaller(lpgui, &SafeGui, sizeof(GUITHREADINFO));
718 if(!NT_SUCCESS(Status))
719 {
720 SetLastNtError(Status);
721 return FALSE;
722 }
723
724 return TRUE;
725 }
726
727
728 DWORD
729 STDCALL
730 NtUserGetGuiResources(
731 HANDLE hProcess,
732 DWORD uiFlags)
733 {
734 PEPROCESS Process;
735 PW32PROCESS W32Process;
736 NTSTATUS Status;
737 DWORD Ret = 0;
738
739 Status = ObReferenceObjectByHandle(hProcess,
740 PROCESS_QUERY_INFORMATION,
741 PsProcessType,
742 ExGetPreviousMode(),
743 (PVOID*)&Process,
744 NULL);
745
746 if(!NT_SUCCESS(Status))
747 {
748 SetLastNtError(Status);
749 return 0;
750 }
751
752 W32Process = Process->Win32Process;
753 if(!W32Process)
754 {
755 ObDereferenceObject(Process);
756 SetLastWin32Error(ERROR_INVALID_PARAMETER);
757 return 0;
758 }
759
760 switch(uiFlags)
761 {
762 case GR_GDIOBJECTS:
763 {
764 Ret = (DWORD)W32Process->GDIObjects;
765 break;
766 }
767 case GR_USEROBJECTS:
768 {
769 Ret = (DWORD)W32Process->UserObjects;
770 break;
771 }
772 default:
773 {
774 SetLastWin32Error(ERROR_INVALID_PARAMETER);
775 break;
776 }
777 }
778
779 ObDereferenceObject(Process);
780
781 return Ret;
782 }
783
784 NTSTATUS FASTCALL
785 IntSafeCopyUnicodeString(PUNICODE_STRING Dest,
786 PUNICODE_STRING Source)
787 {
788 NTSTATUS Status;
789 PWSTR Src;
790
791 Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING));
792 if(!NT_SUCCESS(Status))
793 {
794 return Status;
795 }
796
797 if(Dest->MaximumLength > 0)
798 {
799 Src = Dest->Buffer;
800
801 Dest->Buffer = ExAllocatePool(NonPagedPool, Dest->MaximumLength);
802 if(!Dest->Buffer)
803 {
804 return STATUS_NO_MEMORY;
805 }
806
807 Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->MaximumLength);
808 if(!NT_SUCCESS(Status))
809 {
810 ExFreePool(Dest->Buffer);
811 Dest->Buffer = NULL;
812 return Status;
813 }
814
815
816 return STATUS_SUCCESS;
817 }
818 return STATUS_UNSUCCESSFUL;
819 }
820