3e0e1c510bd7b1bb755b4bcfcc093291e1deeb79
[reactos.git] / reactos / subsys / win32k / ntuser / misc.c
1 /* $Id$
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
12 #include <w32k.h>
13
14 #define NDEBUG
15 #include <debug.h>
16
17 /* registered Logon process */
18 PW32PROCESS LogonProcess = NULL;
19
20 VOID W32kRegisterPrimitiveMessageQueue(VOID)
21 {
22 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
23 if( !pmPrimitiveMessageQueue )
24 {
25 PW32THREAD pThread;
26 pThread = PsGetWin32Thread();
27 if( pThread && pThread->MessageQueue )
28 {
29 pmPrimitiveMessageQueue = pThread->MessageQueue;
30 IntReferenceMessageQueue(pmPrimitiveMessageQueue);
31 DPRINT( "Installed primitive input queue.\n" );
32 }
33 }
34 else
35 {
36 DPRINT1( "Alert! Someone is trying to steal the primitive queue.\n" );
37 }
38 }
39
40 VOID W32kUnregisterPrimitiveMessageQueue(VOID)
41 {
42 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
43 IntDereferenceMessageQueue(pmPrimitiveMessageQueue);
44 pmPrimitiveMessageQueue = NULL;
45 }
46
47 PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue()
48 {
49 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
50 return pmPrimitiveMessageQueue;
51 }
52
53 BOOL FASTCALL
54 co_IntRegisterLogonProcess(HANDLE ProcessId, BOOL Register)
55 {
56 PEPROCESS Process;
57 NTSTATUS Status;
58 CSR_API_MESSAGE Request;
59
60 Status = PsLookupProcessByProcessId(ProcessId,
61 &Process);
62 if (!NT_SUCCESS(Status))
63 {
64 SetLastWin32Error(RtlNtStatusToDosError(Status));
65 return FALSE;
66 }
67
68 if (Register)
69 {
70 /* Register the logon process */
71 if (LogonProcess != NULL)
72 {
73 ObDereferenceObject(Process);
74 return FALSE;
75 }
76
77 LogonProcess = (PW32PROCESS)Process->Win32Process;
78 }
79 else
80 {
81 /* Deregister the logon process */
82 if (LogonProcess != (PW32PROCESS)Process->Win32Process)
83 {
84 ObDereferenceObject(Process);
85 return FALSE;
86 }
87
88 LogonProcess = NULL;
89 }
90
91 ObDereferenceObject(Process);
92
93 Request.Type = MAKE_CSR_API(REGISTER_LOGON_PROCESS, CSR_GUI);
94 Request.Data.RegisterLogonProcessRequest.ProcessId = ProcessId;
95 Request.Data.RegisterLogonProcessRequest.Register = Register;
96
97 Status = co_CsrNotify(&Request);
98 if (! NT_SUCCESS(Status))
99 {
100 DPRINT1("Failed to register logon process with CSRSS\n");
101 return FALSE;
102 }
103
104 return TRUE;
105 }
106
107 /*
108 * @unimplemented
109 */
110 DWORD
111 STDCALL
112 NtUserCallNoParam(DWORD Routine)
113 {
114 DWORD Result = 0;
115 DECLARE_RETURN(DWORD);
116
117 DPRINT("Enter NtUserCallNoParam\n");
118 UserEnterExclusive();
119
120 switch(Routine)
121 {
122 case NOPARAM_ROUTINE_REGISTER_PRIMITIVE:
123 W32kRegisterPrimitiveMessageQueue();
124 Result = (DWORD)TRUE;
125 break;
126
127 case NOPARAM_ROUTINE_DESTROY_CARET:
128 Result = (DWORD)co_IntDestroyCaret(PsGetCurrentThread()->Tcb.Win32Thread);
129 break;
130
131 case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP:
132 Result = (DWORD)IntInitMessagePumpHook();
133 break;
134
135 case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP:
136 Result = (DWORD)IntUninitMessagePumpHook();
137 break;
138
139 case NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO:
140 Result = (DWORD)MsqGetMessageExtraInfo();
141 break;
142
143 case NOPARAM_ROUTINE_ANYPOPUP:
144 Result = (DWORD)IntAnyPopup();
145 break;
146
147 case NOPARAM_ROUTINE_CSRSS_INITIALIZED:
148 Result = (DWORD)CsrInit();
149 break;
150
151 case NOPARAM_ROUTINE_MSQCLEARWAKEMASK:
152 RETURN( (DWORD)IntMsqClearWakeMask());
153
154 default:
155 DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine);
156 SetLastWin32Error(ERROR_INVALID_PARAMETER);
157 break;
158 }
159 RETURN(Result);
160
161 CLEANUP:
162 DPRINT("Leave NtUserCallNoParam, ret=%i\n",_ret_);
163 UserLeave();
164 END_CLEANUP;
165 }
166
167 /*
168 * @implemented
169 */
170 DWORD
171 STDCALL
172 NtUserCallOneParam(
173 DWORD Param,
174 DWORD Routine)
175 {
176 DECLARE_RETURN(DWORD);
177
178 DPRINT("Enter NtUserCallOneParam\n");
179 UserEnterExclusive();
180
181 switch(Routine)
182 {
183 case ONEPARAM_ROUTINE_GETMENU:
184 {
185 PWINDOW_OBJECT Window;
186 DWORD Result;
187
188 if(!(Window = UserGetWindowObject((HWND)Param)))
189 {
190 RETURN( FALSE);
191 }
192
193 Result = (DWORD)Window->IDMenu;
194
195 RETURN( Result);
196 }
197
198 case ONEPARAM_ROUTINE_ISWINDOWUNICODE:
199 {
200 PWINDOW_OBJECT Window;
201 DWORD Result;
202
203 Window = UserGetWindowObject((HWND)Param);
204 if(!Window)
205 {
206 RETURN( FALSE);
207 }
208 Result = Window->Unicode;
209 RETURN( Result);
210 }
211
212 case ONEPARAM_ROUTINE_WINDOWFROMDC:
213 RETURN( (DWORD)IntWindowFromDC((HDC)Param));
214
215 case ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID:
216 {
217 PWINDOW_OBJECT Window;
218 DWORD Result;
219
220 Window = UserGetWindowObject((HWND)Param);
221 if(!Window)
222 {
223 RETURN( FALSE);
224 }
225
226 Result = Window->ContextHelpId;
227
228 RETURN( Result);
229 }
230
231 case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON:
232 {
233 PWINSTATION_OBJECT WinSta;
234 NTSTATUS Status;
235 DWORD Result;
236
237 Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
238 KernelMode,
239 0,
240 &WinSta);
241 if (!NT_SUCCESS(Status))
242 RETURN( (DWORD)FALSE);
243
244 /* FIXME
245 Result = (DWORD)IntSwapMouseButton(WinStaObject, (BOOL)Param); */
246 Result = 0;
247
248 ObDereferenceObject(WinSta);
249 RETURN( Result);
250 }
251
252 case ONEPARAM_ROUTINE_SWITCHCARETSHOWING:
253 RETURN( (DWORD)IntSwitchCaretShowing((PVOID)Param));
254
255 case ONEPARAM_ROUTINE_SETCARETBLINKTIME:
256 RETURN( (DWORD)IntSetCaretBlinkTime((UINT)Param));
257
258 case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS:
259 RETURN( (DWORD)IntEnumClipboardFormats((UINT)Param));
260
261 case ONEPARAM_ROUTINE_GETWINDOWINSTANCE:
262 {
263 PWINDOW_OBJECT Window;
264 DWORD Result;
265
266 if(!(Window = UserGetWindowObject((HWND)Param)))
267 {
268 RETURN( FALSE);
269 }
270
271 Result = (DWORD)Window->Instance;
272 RETURN( Result);
273 }
274
275 case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO:
276 RETURN( (DWORD)MsqSetMessageExtraInfo((LPARAM)Param));
277
278 case ONEPARAM_ROUTINE_GETCURSORPOSITION:
279 {
280 PWINSTATION_OBJECT WinSta;
281 NTSTATUS Status;
282 POINT Pos;
283
284 if(!Param)
285 RETURN( (DWORD)FALSE);
286 Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
287 KernelMode,
288 0,
289 &WinSta);
290 if (!NT_SUCCESS(Status))
291 RETURN( (DWORD)FALSE);
292
293 /* FIXME - check if process has WINSTA_READATTRIBUTES */
294 IntGetCursorLocation(WinSta, &Pos);
295
296 Status = MmCopyToCaller((PPOINT)Param, &Pos, sizeof(POINT));
297 if(!NT_SUCCESS(Status))
298 {
299 ObDereferenceObject(WinSta);
300 SetLastNtError(Status);
301 RETURN( FALSE);
302 }
303
304 ObDereferenceObject(WinSta);
305
306 RETURN( (DWORD)TRUE);
307 }
308
309 case ONEPARAM_ROUTINE_ISWINDOWINDESTROY:
310 {
311 PWINDOW_OBJECT Window;
312 DWORD Result;
313
314 if(!(Window = UserGetWindowObject((HWND)Param)))
315 {
316 RETURN( FALSE);
317 }
318
319 Result = (DWORD)IntIsWindowInDestroy(Window);
320
321 RETURN( Result);
322 }
323
324 case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING:
325 {
326 BOOL Enable;
327 PW32PROCESS Process = PsGetWin32Process();
328
329 if(Process != NULL)
330 {
331 Enable = (BOOL)(Param != 0);
332
333 if(Enable)
334 {
335 Process->Flags &= ~W32PF_NOWINDOWGHOSTING;
336 }
337 else
338 {
339 Process->Flags |= W32PF_NOWINDOWGHOSTING;
340 }
341
342 RETURN( TRUE);
343 }
344
345 RETURN( FALSE);
346 }
347
348 case ONEPARAM_ROUTINE_MSQSETWAKEMASK:
349 RETURN( (DWORD)IntMsqSetWakeMask(Param));
350
351 case ONEPARAM_ROUTINE_GETKEYBOARDTYPE:
352 RETURN( UserGetKeyboardType(Param));
353
354 case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT:
355 RETURN( (DWORD)UserGetKeyboardLayout(Param));
356 }
357 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
358 Routine, Param);
359 SetLastWin32Error(ERROR_INVALID_PARAMETER);
360 RETURN( 0);
361
362 CLEANUP:
363 DPRINT("Leave NtUserCallOneParam, ret=%i\n",_ret_);
364 UserLeave();
365 END_CLEANUP;
366 }
367
368
369 /*
370 * @implemented
371 */
372 DWORD
373 STDCALL
374 NtUserCallTwoParam(
375 DWORD Param1,
376 DWORD Param2,
377 DWORD Routine)
378 {
379 NTSTATUS Status;
380 PWINDOW_OBJECT Window;
381 DECLARE_RETURN(DWORD);
382
383 DPRINT("Enter NtUserCallTwoParam\n");
384 UserEnterExclusive();
385
386 switch(Routine)
387 {
388 case TWOPARAM_ROUTINE_SETDCPENCOLOR:
389 {
390 RETURN( (DWORD)IntSetDCColor((HDC)Param1, OBJ_PEN, (COLORREF)Param2));
391 }
392 case TWOPARAM_ROUTINE_SETDCBRUSHCOLOR:
393 {
394 RETURN( (DWORD)IntSetDCColor((HDC)Param1, OBJ_BRUSH, (COLORREF)Param2));
395 }
396 case TWOPARAM_ROUTINE_GETDCCOLOR:
397 {
398 RETURN( (DWORD)IntGetDCColor((HDC)Param1, (ULONG)Param2));
399 }
400 case TWOPARAM_ROUTINE_GETWINDOWRGNBOX:
401 {
402 DWORD Ret;
403 RECT rcRect;
404 PWINDOW_OBJECT Window = UserGetWindowObject((HWND)Param1);
405 if (!Window) RETURN(ERROR);
406
407 Ret = (DWORD)IntGetWindowRgnBox(Window, &rcRect);
408 Status = MmCopyToCaller((PVOID)Param2, &rcRect, sizeof(RECT));
409 if(!NT_SUCCESS(Status))
410 {
411 SetLastNtError(Status);
412 RETURN( ERROR);
413 }
414 RETURN( Ret);
415 }
416 case TWOPARAM_ROUTINE_GETWINDOWRGN:
417 {
418 PWINDOW_OBJECT Window = UserGetWindowObject((HWND)Param1);
419 if (!Window) RETURN(ERROR);
420
421 RETURN( (DWORD)IntGetWindowRgn(Window, (HRGN)Param2));
422 }
423 case TWOPARAM_ROUTINE_SETMENUBARHEIGHT:
424 {
425 DWORD Ret;
426 PMENU_OBJECT MenuObject = IntGetMenuObject((HMENU)Param1);
427 if(!MenuObject)
428 RETURN( 0);
429
430 if(Param2 > 0)
431 {
432 Ret = (MenuObject->MenuInfo.Height == (int)Param2);
433 MenuObject->MenuInfo.Height = (int)Param2;
434 }
435 else
436 Ret = (DWORD)MenuObject->MenuInfo.Height;
437 IntReleaseMenuObject(MenuObject);
438 RETURN( Ret);
439 }
440 case TWOPARAM_ROUTINE_SETMENUITEMRECT:
441 {
442 BOOL Ret;
443 SETMENUITEMRECT smir;
444 PMENU_OBJECT MenuObject = IntGetMenuObject((HMENU)Param1);
445 if(!MenuObject)
446 RETURN( 0);
447
448 if(!NT_SUCCESS(MmCopyFromCaller(&smir, (PVOID)Param2, sizeof(SETMENUITEMRECT))))
449 {
450 IntReleaseMenuObject(MenuObject);
451 RETURN( 0);
452 }
453
454 Ret = IntSetMenuItemRect(MenuObject, smir.uItem, smir.fByPosition, &smir.rcRect);
455
456 IntReleaseMenuObject(MenuObject);
457 RETURN( (DWORD)Ret);
458 }
459
460 case TWOPARAM_ROUTINE_SETGUITHRDHANDLE:
461 {
462 PUSER_MESSAGE_QUEUE MsgQueue = PsGetCurrentThread()->Tcb.Win32Thread->MessageQueue;
463
464 ASSERT(MsgQueue);
465 RETURN( (DWORD)MsqSetStateWindow(MsgQueue, (ULONG)Param1, (HWND)Param2));
466 }
467
468 case TWOPARAM_ROUTINE_ENABLEWINDOW:
469 UNIMPLEMENTED
470 RETURN( 0);
471
472 case TWOPARAM_ROUTINE_UNKNOWN:
473 UNIMPLEMENTED
474 RETURN( 0);
475
476 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS:
477 {
478 PWINDOW_OBJECT Window = UserGetWindowObject((HWND)Param1);
479 if (!Window) RETURN(0);
480
481 RETURN( (DWORD)IntShowOwnedPopups(Window, (BOOL) Param2));
482 }
483
484 case TWOPARAM_ROUTINE_ROS_SHOWWINDOW:
485 {
486 #define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040)
487 PWINDOW_OBJECT Window;
488 DPRINT1("ROS_SHOWWINDOW\n");
489
490 if (!(Window = UserGetWindowObject((HWND)Param1)))
491 {
492 RETURN( FALSE);
493 }
494
495 if (Param2)
496 {
497 if (!(Window->Flags & WIN_NEEDS_SHOW_OWNEDPOPUP))
498 {
499 RETURN( TRUE);
500 }
501 Window->Flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP;
502 }
503 else
504 Window->Flags |= WIN_NEEDS_SHOW_OWNEDPOPUP;
505
506 DPRINT1("ROS_SHOWWINDOW ---> 0x%x\n",Window->Flags);
507 RETURN( TRUE);
508 }
509 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW:
510 UNIMPLEMENTED
511 RETURN( 0);
512
513 case TWOPARAM_ROUTINE_VALIDATERGN:
514 {
515 PWINDOW_OBJECT Window = UserGetWindowObject((HWND) Param1);
516 BOOL ret;
517
518 if (!Window)
519 RETURN(FALSE);
520
521 UserRefObjectCo(Window);
522 ret = co_UserValidateRgn(Window, (HRGN) Param2);
523 UserDerefObjectCo(Window);
524
525 RETURN((DWORD) ret);
526 }
527
528 case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID:
529
530 if(!(Window = UserGetWindowObject((HWND)Param1)))
531 {
532 RETURN( (DWORD)FALSE);
533 }
534
535 Window->ContextHelpId = Param2;
536
537 RETURN( (DWORD)TRUE);
538
539 case TWOPARAM_ROUTINE_SETCARETPOS:
540 RETURN( (DWORD)co_IntSetCaretPos((int)Param1, (int)Param2));
541
542 case TWOPARAM_ROUTINE_GETWINDOWINFO:
543 {
544 WINDOWINFO wi;
545 DWORD Ret;
546
547 if(!(Window = UserGetWindowObject((HWND)Param1)))
548 {
549 RETURN( FALSE);
550 }
551
552 #if 0
553 /*
554 * According to WINE, Windows' doesn't check the cbSize field
555 */
556
557 Status = MmCopyFromCaller(&wi.cbSize, (PVOID)Param2, sizeof(wi.cbSize));
558 if(!NT_SUCCESS(Status))
559 {
560 SetLastNtError(Status);
561 RETURN( FALSE);
562 }
563
564 if(wi.cbSize != sizeof(WINDOWINFO))
565 {
566 SetLastWin32Error(ERROR_INVALID_PARAMETER);
567 RETURN( FALSE);
568 }
569 #endif
570
571 if((Ret = (DWORD)IntGetWindowInfo(Window, &wi)))
572 {
573 Status = MmCopyToCaller((PVOID)Param2, &wi, sizeof(WINDOWINFO));
574 if(!NT_SUCCESS(Status))
575 {
576 SetLastNtError(Status);
577 RETURN( FALSE);
578 }
579 }
580
581 RETURN( Ret);
582 }
583
584 case TWOPARAM_ROUTINE_REGISTERLOGONPROC:
585 RETURN( (DWORD)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2));
586
587 case TWOPARAM_ROUTINE_SETSYSCOLORS:
588 {
589 DWORD Ret = 0;
590 PVOID Buffer;
591 struct
592 {
593 INT *Elements;
594 COLORREF *Colors;
595 }
596 ChangeSysColors;
597
598 /* FIXME - we should make use of SEH here... */
599
600 Status = MmCopyFromCaller(&ChangeSysColors, (PVOID)Param1, sizeof(ChangeSysColors));
601 if(!NT_SUCCESS(Status))
602 {
603 SetLastNtError(Status);
604 RETURN( 0);
605 }
606
607 Buffer = ExAllocatePool(PagedPool, (Param2 * sizeof(INT)) + (Param2 * sizeof(COLORREF)));
608 if(Buffer != NULL)
609 {
610 INT *Elements = (INT*)Buffer;
611 COLORREF *Colors = (COLORREF*)Buffer + Param2;
612
613 Status = MmCopyFromCaller(Elements, ChangeSysColors.Elements, Param2 * sizeof(INT));
614 if(NT_SUCCESS(Status))
615 {
616 Status = MmCopyFromCaller(Colors, ChangeSysColors.Colors, Param2 * sizeof(COLORREF));
617 if(NT_SUCCESS(Status))
618 {
619 Ret = (DWORD)IntSetSysColors((UINT)Param2, Elements, Colors);
620 }
621 else
622 SetLastNtError(Status);
623 }
624 else
625 SetLastNtError(Status);
626
627 ExFreePool(Buffer);
628 }
629
630
631 RETURN( Ret);
632 }
633
634 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES:
635 case TWOPARAM_ROUTINE_GETSYSCOLORPENS:
636 case TWOPARAM_ROUTINE_GETSYSCOLORS:
637 {
638 DWORD Ret = 0;
639 union
640 {
641 PVOID Pointer;
642 HBRUSH *Brushes;
643 HPEN *Pens;
644 COLORREF *Colors;
645 } Buffer;
646
647 /* FIXME - we should make use of SEH here... */
648
649 Buffer.Pointer = ExAllocatePool(PagedPool, Param2 * sizeof(HANDLE));
650 if(Buffer.Pointer != NULL)
651 {
652 switch(Routine)
653 {
654 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES:
655 Ret = (DWORD)IntGetSysColorBrushes(Buffer.Brushes, (UINT)Param2);
656 break;
657 case TWOPARAM_ROUTINE_GETSYSCOLORPENS:
658 Ret = (DWORD)IntGetSysColorPens(Buffer.Pens, (UINT)Param2);
659 break;
660 case TWOPARAM_ROUTINE_GETSYSCOLORS:
661 Ret = (DWORD)IntGetSysColors(Buffer.Colors, (UINT)Param2);
662 break;
663 default:
664 Ret = 0;
665 break;
666 }
667
668 if(Ret > 0)
669 {
670 Status = MmCopyToCaller((PVOID)Param1, Buffer.Pointer, Param2 * sizeof(HANDLE));
671 if(!NT_SUCCESS(Status))
672 {
673 SetLastNtError(Status);
674 Ret = 0;
675 }
676 }
677
678 ExFreePool(Buffer.Pointer);
679 }
680 RETURN( Ret);
681 }
682
683 }
684 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
685 Routine, Param1, Param2);
686 SetLastWin32Error(ERROR_INVALID_PARAMETER);
687 RETURN( 0);
688
689 CLEANUP:
690 DPRINT("Leave NtUserCallTwoParam, ret=%i\n",_ret_);
691 UserLeave();
692 END_CLEANUP;
693 }
694
695
696 /*
697 * @unimplemented
698 */
699 BOOL
700 STDCALL
701 NtUserCallHwndLock(
702 HWND hWnd,
703 DWORD Routine)
704 {
705 BOOL Ret = 0;
706 PWINDOW_OBJECT Window;
707 DECLARE_RETURN(BOOLEAN);
708
709 DPRINT("Enter NtUserCallHwndLock\n");
710 UserEnterExclusive();
711
712 if (!(Window = UserGetWindowObject(hWnd)))
713 {
714 RETURN( FALSE);
715 }
716 UserRefObjectCo(Window);
717
718 /* FIXME: Routine can be 0x53 - 0x5E */
719 switch (Routine)
720 {
721 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS:
722 co_WinPosArrangeIconicWindows(Window);
723 break;
724
725 case HWNDLOCK_ROUTINE_DRAWMENUBAR:
726 {
727 PMENU_OBJECT Menu;
728 DPRINT("HWNDLOCK_ROUTINE_DRAWMENUBAR\n");
729 Ret = FALSE;
730 if (!((Window->Style & (WS_CHILD | WS_POPUP)) != WS_CHILD))
731 break;
732
733 if(!(Menu = UserGetMenuObject((HMENU) Window->IDMenu)))
734 break;
735
736 Menu->MenuInfo.WndOwner = hWnd;
737 Menu->MenuInfo.Height = 0;
738
739 co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
740 SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
741
742 Ret = TRUE;
743 break;
744 }
745
746 case HWNDLOCK_ROUTINE_REDRAWFRAME:
747 /* FIXME */
748 break;
749
750 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW:
751 Ret = co_IntSetForegroundWindow(Window);
752 break;
753
754 case HWNDLOCK_ROUTINE_UPDATEWINDOW:
755 /* FIXME */
756 break;
757 }
758
759 UserDerefObjectCo(Window);
760
761 RETURN( Ret);
762
763 CLEANUP:
764 DPRINT("Leave NtUserCallHwndLock, ret=%i\n",_ret_);
765 UserLeave();
766 END_CLEANUP;
767 }
768
769 /*
770 * @unimplemented
771 */
772 HWND
773 STDCALL
774 NtUserCallHwndOpt(
775 HWND Param,
776 DWORD Routine)
777 {
778 switch (Routine)
779 {
780 case HWNDOPT_ROUTINE_SETPROGMANWINDOW:
781 /*
782 * FIXME
783 * Nothing too hard...validate the hWnd and save it in the Desktop Info
784 */
785 DPRINT1("HWNDOPT_ROUTINE_SETPROGMANWINDOW UNIMPLEMENTED\n");
786 break;
787
788 case HWNDOPT_ROUTINE_SETTASKMANWINDOW:
789 /*
790 * FIXME
791 * Nothing too hard...validate the hWnd and save it in the Desktop Info
792 */
793 DPRINT1("HWNDOPT_ROUTINE_SETTASKMANWINDOW UNIMPLEMENTED\n");
794 break;
795 }
796
797 return Param;
798 }
799
800 /*
801 * @unimplemented
802 */
803 DWORD STDCALL
804 NtUserGetThreadState(
805 DWORD Routine)
806 {
807 DECLARE_RETURN(DWORD);
808
809 DPRINT("Enter NtUserGetThreadState\n");
810 UserEnterShared();
811
812 switch (Routine)
813 {
814 case 0:
815 RETURN( (DWORD)IntGetThreadFocusWindow());
816 }
817 RETURN( 0);
818
819 CLEANUP:
820 DPRINT("Leave NtUserGetThreadState, ret=%i\n",_ret_);
821 UserLeave();
822 END_CLEANUP;
823 }
824
825 VOID FASTCALL
826 IntGetFontMetricSetting(LPWSTR lpValueName, PLOGFONTW font)
827 {
828 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
829 NTSTATUS Status;
830 static LOGFONTW DefaultFont = {
831 11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
832 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
833 L"Bitstream Vera Sans"
834 };
835
836 RtlZeroMemory(&QueryTable, sizeof(QueryTable));
837
838 QueryTable[0].Name = lpValueName;
839 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
840 QueryTable[0].EntryContext = font;
841
842 Status = RtlQueryRegistryValues(
843 RTL_REGISTRY_USER,
844 L"Control Panel\\Desktop\\WindowMetrics",
845 QueryTable,
846 NULL,
847 NULL);
848
849 if (!NT_SUCCESS(Status))
850 {
851 RtlCopyMemory(font, &DefaultFont, sizeof(LOGFONTW));
852 }
853 }
854
855 ULONG FASTCALL
856 IntSystemParametersInfo(
857 UINT uiAction,
858 UINT uiParam,
859 PVOID pvParam,
860 UINT fWinIni)
861 {
862 PWINSTATION_OBJECT WinStaObject;
863 NTSTATUS Status;
864
865 static BOOL bInitialized = FALSE;
866 static LOGFONTW IconFont;
867 static NONCLIENTMETRICSW pMetrics;
868 static BOOL GradientCaptions = TRUE;
869 static UINT FocusBorderHeight = 1;
870 static UINT FocusBorderWidth = 1;
871
872 if (!bInitialized)
873 {
874 RtlZeroMemory(&IconFont, sizeof(LOGFONTW));
875 RtlZeroMemory(&pMetrics, sizeof(NONCLIENTMETRICSW));
876
877 IntGetFontMetricSetting(L"CaptionFont", &pMetrics.lfCaptionFont);
878 IntGetFontMetricSetting(L"SmCaptionFont", &pMetrics.lfSmCaptionFont);
879 IntGetFontMetricSetting(L"MenuFont", &pMetrics.lfMenuFont);
880 IntGetFontMetricSetting(L"StatusFont", &pMetrics.lfStatusFont);
881 IntGetFontMetricSetting(L"MessageFont", &pMetrics.lfMessageFont);
882 IntGetFontMetricSetting(L"IconFont", &IconFont);
883
884 pMetrics.iBorderWidth = 1;
885 pMetrics.iScrollWidth = UserGetSystemMetrics(SM_CXVSCROLL);
886 pMetrics.iScrollHeight = UserGetSystemMetrics(SM_CYHSCROLL);
887 pMetrics.iCaptionWidth = UserGetSystemMetrics(SM_CXSIZE);
888 pMetrics.iCaptionHeight = UserGetSystemMetrics(SM_CYSIZE);
889 pMetrics.iSmCaptionWidth = UserGetSystemMetrics(SM_CXSMSIZE);
890 pMetrics.iSmCaptionHeight = UserGetSystemMetrics(SM_CYSMSIZE);
891 pMetrics.iMenuWidth = UserGetSystemMetrics(SM_CXMENUSIZE);
892 pMetrics.iMenuHeight = UserGetSystemMetrics(SM_CYMENUSIZE);
893 pMetrics.cbSize = sizeof(NONCLIENTMETRICSW);
894
895 bInitialized = TRUE;
896 }
897
898 switch(uiAction)
899 {
900 case SPI_SETDOUBLECLKWIDTH:
901 case SPI_SETDOUBLECLKHEIGHT:
902 case SPI_SETDOUBLECLICKTIME:
903 case SPI_SETDESKWALLPAPER:
904 case SPI_GETDESKWALLPAPER:
905 {
906 PSYSTEM_CURSORINFO CurInfo;
907
908 Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
909 KernelMode,
910 0,
911 &WinStaObject);
912 if(!NT_SUCCESS(Status))
913 {
914 SetLastNtError(Status);
915 return (DWORD)FALSE;
916 }
917
918 switch(uiAction)
919 {
920 case SPI_SETDOUBLECLKWIDTH:
921 CurInfo = IntGetSysCursorInfo(WinStaObject);
922 /* FIXME limit the maximum value? */
923 CurInfo->DblClickWidth = uiParam;
924 break;
925 case SPI_SETDOUBLECLKHEIGHT:
926 CurInfo = IntGetSysCursorInfo(WinStaObject);
927 /* FIXME limit the maximum value? */
928 CurInfo->DblClickHeight = uiParam;
929 break;
930 case SPI_SETDOUBLECLICKTIME:
931 CurInfo = IntGetSysCursorInfo(WinStaObject);
932 /* FIXME limit the maximum time to 1000 ms? */
933 CurInfo->DblClickSpeed = uiParam;
934 break;
935 case SPI_SETDESKWALLPAPER:
936 {
937 /* This function expects different parameters than the user mode version!
938
939 We let the user mode code load the bitmap, it passed the handle to
940 the bitmap. We'll change it's ownership to system and replace it with
941 the current wallpaper bitmap */
942 HBITMAP hOldBitmap, hNewBitmap;
943 ASSERT(pvParam);
944
945 hNewBitmap = *(HBITMAP*)pvParam;
946 if(hNewBitmap != NULL)
947 {
948 BITMAPOBJ *bmp;
949 /* try to get the size of the wallpaper */
950 if(!(bmp = BITMAPOBJ_LockBitmap(hNewBitmap)))
951 {
952 ObDereferenceObject(WinStaObject);
953 return FALSE;
954 }
955 WinStaObject->cxWallpaper = bmp->SurfObj.sizlBitmap.cx;
956 WinStaObject->cyWallpaper = bmp->SurfObj.sizlBitmap.cy;
957
958 BITMAPOBJ_UnlockBitmap(bmp);
959
960 /* change the bitmap's ownership */
961 GDIOBJ_SetOwnership(hNewBitmap, NULL);
962 }
963 hOldBitmap = (HBITMAP)InterlockedExchange((LONG*)&WinStaObject->hbmWallpaper, (LONG)hNewBitmap);
964 if(hOldBitmap != NULL)
965 {
966 /* delete the old wallpaper */
967 NtGdiDeleteObject(hOldBitmap);
968 }
969 break;
970 }
971 case SPI_GETDESKWALLPAPER:
972 /* This function expects different parameters than the user mode version!
973
974 We basically return the current wallpaper handle - if any. The user
975 mode version should load the string from the registry and return it
976 without calling this function */
977 ASSERT(pvParam);
978 *(HBITMAP*)pvParam = (HBITMAP)WinStaObject->hbmWallpaper;
979 break;
980 }
981
982 /* FIXME save the value to the registry */
983
984 ObDereferenceObject(WinStaObject);
985 return TRUE;
986 }
987 case SPI_SETWORKAREA:
988 {
989 RECT *rc;
990 PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
991
992 if(!Desktop)
993 {
994 /* FIXME - Set last error */
995 return FALSE;
996 }
997
998 ASSERT(pvParam);
999 rc = (RECT*)pvParam;
1000 Desktop->WorkArea = *rc;
1001
1002 return TRUE;
1003 }
1004 case SPI_GETWORKAREA:
1005 {
1006 PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
1007
1008 if(!Desktop)
1009 {
1010 /* FIXME - Set last error */
1011 return FALSE;
1012 }
1013
1014 ASSERT(pvParam);
1015 IntGetDesktopWorkArea(Desktop, (PRECT)pvParam);
1016
1017 return TRUE;
1018 }
1019 case SPI_SETGRADIENTCAPTIONS:
1020 {
1021 GradientCaptions = (pvParam != NULL);
1022 /* FIXME - should be checked if the color depth is higher than 8bpp? */
1023 return TRUE;
1024 }
1025 case SPI_GETGRADIENTCAPTIONS:
1026 {
1027 HDC hDC;
1028 BOOL Ret = GradientCaptions;
1029
1030 hDC = IntGetScreenDC();
1031 if(hDC)
1032 {
1033 Ret = (NtGdiGetDeviceCaps(hDC, BITSPIXEL) > 8) && Ret;
1034
1035 ASSERT(pvParam);
1036 *((PBOOL)pvParam) = Ret;
1037 return TRUE;
1038 }
1039 return FALSE;
1040 }
1041 case SPI_SETFONTSMOOTHING:
1042 {
1043 IntEnableFontRendering(uiParam != 0);
1044 return TRUE;
1045 }
1046 case SPI_GETFONTSMOOTHING:
1047 {
1048 ASSERT(pvParam);
1049 *((BOOL*)pvParam) = IntIsFontRenderingEnabled();
1050 return TRUE;
1051 }
1052 case SPI_GETICONTITLELOGFONT:
1053 {
1054 ASSERT(pvParam);
1055 *((LOGFONTW*)pvParam) = IconFont;
1056 return TRUE;
1057 }
1058 case SPI_GETNONCLIENTMETRICS:
1059 {
1060 ASSERT(pvParam);
1061 *((NONCLIENTMETRICSW*)pvParam) = pMetrics;
1062 return TRUE;
1063 }
1064 case SPI_GETFOCUSBORDERHEIGHT:
1065 {
1066 ASSERT(pvParam);
1067 *((UINT*)pvParam) = FocusBorderHeight;
1068 return TRUE;
1069 }
1070 case SPI_GETFOCUSBORDERWIDTH:
1071 {
1072 ASSERT(pvParam);
1073 *((UINT*)pvParam) = FocusBorderWidth;
1074 return TRUE;
1075 }
1076 case SPI_SETFOCUSBORDERHEIGHT:
1077 {
1078 FocusBorderHeight = (UINT)pvParam;
1079 return TRUE;
1080 }
1081 case SPI_SETFOCUSBORDERWIDTH:
1082 {
1083 FocusBorderWidth = (UINT)pvParam;
1084 return TRUE;
1085 }
1086
1087 default:
1088 {
1089 DPRINT1("SystemParametersInfo: Unsupported Action 0x%x (uiParam: 0x%x, pvParam: 0x%x, fWinIni: 0x%x)\n",
1090 uiAction, uiParam, pvParam, fWinIni);
1091 return FALSE;
1092 }
1093 }
1094 return FALSE;
1095 }
1096
1097 /*
1098 * @implemented
1099 */
1100 BOOL FASTCALL
1101 UserSystemParametersInfo(
1102 UINT uiAction,
1103 UINT uiParam,
1104 PVOID pvParam,
1105 UINT fWinIni)
1106 {
1107 NTSTATUS Status;
1108
1109 switch(uiAction)
1110 {
1111 case SPI_SETDOUBLECLKWIDTH:
1112 case SPI_SETDOUBLECLKHEIGHT:
1113 case SPI_SETDOUBLECLICKTIME:
1114 case SPI_SETGRADIENTCAPTIONS:
1115 case SPI_SETFONTSMOOTHING:
1116 case SPI_SETFOCUSBORDERHEIGHT:
1117 case SPI_SETFOCUSBORDERWIDTH:
1118 {
1119 return (DWORD)IntSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni);
1120 }
1121 case SPI_SETWORKAREA:
1122 {
1123 RECT rc;
1124 Status = MmCopyFromCaller(&rc, (PRECT)pvParam, sizeof(RECT));
1125 if(!NT_SUCCESS(Status))
1126 {
1127 SetLastNtError(Status);
1128 return( FALSE);
1129 }
1130 return( (DWORD)IntSystemParametersInfo(uiAction, uiParam, &rc, fWinIni));
1131 }
1132 case SPI_GETWORKAREA:
1133 {
1134 RECT rc;
1135
1136 if(!IntSystemParametersInfo(uiAction, uiParam, &rc, fWinIni))
1137 {
1138 return( FALSE);
1139 }
1140
1141 Status = MmCopyToCaller((PRECT)pvParam, &rc, sizeof(RECT));
1142 if(!NT_SUCCESS(Status))
1143 {
1144 SetLastNtError(Status);
1145 return( FALSE);
1146 }
1147 return( TRUE);
1148 }
1149 case SPI_GETFONTSMOOTHING:
1150 case SPI_GETGRADIENTCAPTIONS:
1151 case SPI_GETFOCUSBORDERHEIGHT:
1152 case SPI_GETFOCUSBORDERWIDTH:
1153 {
1154 BOOL Ret;
1155
1156 if(!IntSystemParametersInfo(uiAction, uiParam, &Ret, fWinIni))
1157 {
1158 return( FALSE);
1159 }
1160
1161 Status = MmCopyToCaller(pvParam, &Ret, sizeof(BOOL));
1162 if(!NT_SUCCESS(Status))
1163 {
1164 SetLastNtError(Status);
1165 return( FALSE);
1166 }
1167 return( TRUE);
1168 }
1169 case SPI_SETDESKWALLPAPER:
1170 {
1171 /* !!! As opposed to the user mode version this version accepts a handle
1172 to the bitmap! */
1173 HBITMAP hbmWallpaper;
1174
1175 Status = MmCopyFromCaller(&hbmWallpaper, pvParam, sizeof(HBITMAP));
1176 if(!NT_SUCCESS(Status))
1177 {
1178 SetLastNtError(Status);
1179 return( FALSE);
1180 }
1181 return( IntSystemParametersInfo(SPI_SETDESKWALLPAPER, 0, &hbmWallpaper, fWinIni));
1182 }
1183 case SPI_GETDESKWALLPAPER:
1184 {
1185 /* !!! As opposed to the user mode version this version returns a handle
1186 to the bitmap! */
1187 HBITMAP hbmWallpaper;
1188 BOOL Ret;
1189
1190 Ret = IntSystemParametersInfo(SPI_GETDESKWALLPAPER, 0, &hbmWallpaper, fWinIni);
1191
1192 Status = MmCopyToCaller(pvParam, &hbmWallpaper, sizeof(HBITMAP));
1193 if(!NT_SUCCESS(Status))
1194 {
1195 SetLastNtError(Status);
1196 return( FALSE);
1197 }
1198 return( Ret);
1199 }
1200 case SPI_GETICONTITLELOGFONT:
1201 {
1202 LOGFONTW IconFont;
1203
1204 if(!IntSystemParametersInfo(uiAction, uiParam, &IconFont, fWinIni))
1205 {
1206 return( FALSE);
1207 }
1208
1209 Status = MmCopyToCaller(pvParam, &IconFont, sizeof(LOGFONTW));
1210 if(!NT_SUCCESS(Status))
1211 {
1212 SetLastNtError(Status);
1213 return( FALSE);
1214 }
1215 return( TRUE);
1216 }
1217 case SPI_GETNONCLIENTMETRICS:
1218 {
1219 NONCLIENTMETRICSW metrics;
1220
1221 Status = MmCopyFromCaller(&metrics.cbSize, pvParam, sizeof(UINT));
1222 if(!NT_SUCCESS(Status))
1223 {
1224 SetLastNtError(Status);
1225 return( FALSE);
1226 }
1227 if(metrics.cbSize != sizeof(NONCLIENTMETRICSW))
1228 {
1229 SetLastWin32Error(ERROR_INVALID_PARAMETER);
1230 return( FALSE);
1231 }
1232
1233 if(!IntSystemParametersInfo(uiAction, uiParam, &metrics, fWinIni))
1234 {
1235 return( FALSE);
1236 }
1237
1238 Status = MmCopyToCaller(pvParam, &metrics.cbSize, sizeof(NONCLIENTMETRICSW));
1239 if(!NT_SUCCESS(Status))
1240 {
1241 SetLastNtError(Status);
1242 return( FALSE);
1243 }
1244 return( TRUE);
1245 }
1246 }
1247 return( FALSE);
1248 }
1249
1250
1251
1252
1253 /*
1254 * @implemented
1255 */
1256 BOOL
1257 STDCALL
1258 NtUserSystemParametersInfo(
1259 UINT uiAction,
1260 UINT uiParam,
1261 PVOID pvParam,
1262 UINT fWinIni)
1263 {
1264 DECLARE_RETURN(BOOLEAN);
1265
1266 DPRINT("Enter NtUserSystemParametersInfo\n");
1267 UserEnterExclusive();
1268
1269 RETURN( UserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni));
1270
1271 CLEANUP:
1272 DPRINT("Leave NtUserSystemParametersInfo, ret=%i\n",_ret_);
1273 UserLeave();
1274 END_CLEANUP;
1275 }
1276
1277
1278
1279 UINT
1280 STDCALL
1281 NtUserGetDoubleClickTime(VOID)
1282 {
1283 UINT Result;
1284 NTSTATUS Status;
1285 PWINSTATION_OBJECT WinStaObject;
1286 PSYSTEM_CURSORINFO CurInfo;
1287 DECLARE_RETURN(UINT);
1288
1289 DPRINT("Enter NtUserGetDoubleClickTime\n");
1290 UserEnterShared();
1291
1292 Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
1293 KernelMode,
1294 0,
1295 &WinStaObject);
1296 if (!NT_SUCCESS(Status))
1297 RETURN( (DWORD)FALSE);
1298
1299 CurInfo = IntGetSysCursorInfo(WinStaObject);
1300 Result = CurInfo->DblClickSpeed;
1301
1302 ObDereferenceObject(WinStaObject);
1303 RETURN( Result);
1304
1305 CLEANUP:
1306 DPRINT("Leave NtUserGetDoubleClickTime, ret=%i\n",_ret_);
1307 UserLeave();
1308 END_CLEANUP;
1309 }
1310
1311 BOOL
1312 STDCALL
1313 NtUserGetGUIThreadInfo(
1314 DWORD idThread, /* if NULL use foreground thread */
1315 LPGUITHREADINFO lpgui)
1316 {
1317 NTSTATUS Status;
1318 PTHRDCARETINFO CaretInfo;
1319 GUITHREADINFO SafeGui;
1320 PDESKTOP_OBJECT Desktop;
1321 PUSER_MESSAGE_QUEUE MsgQueue;
1322 PETHREAD Thread = NULL;
1323 DECLARE_RETURN(BOOLEAN);
1324
1325 DPRINT("Enter NtUserGetGUIThreadInfo\n");
1326 UserEnterShared();
1327
1328 Status = MmCopyFromCaller(&SafeGui, lpgui, sizeof(DWORD));
1329 if(!NT_SUCCESS(Status))
1330 {
1331 SetLastNtError(Status);
1332 RETURN( FALSE);
1333 }
1334
1335 if(SafeGui.cbSize != sizeof(GUITHREADINFO))
1336 {
1337 SetLastWin32Error(ERROR_INVALID_PARAMETER);
1338 RETURN( FALSE);
1339 }
1340
1341 if(idThread)
1342 {
1343 Status = PsLookupThreadByThreadId((HANDLE)idThread, &Thread);
1344 if(!NT_SUCCESS(Status))
1345 {
1346 SetLastWin32Error(ERROR_ACCESS_DENIED);
1347 RETURN( FALSE);
1348 }
1349 Desktop = Thread->Tcb.Win32Thread->Desktop;
1350 }
1351 else
1352 {
1353 /* get the foreground thread */
1354 PW32THREAD W32Thread = PsGetCurrentThread()->Tcb.Win32Thread;
1355 Desktop = W32Thread->Desktop;
1356 if(Desktop)
1357 {
1358 MsgQueue = Desktop->ActiveMessageQueue;
1359 if(MsgQueue)
1360 {
1361 Thread = MsgQueue->Thread;
1362 }
1363 }
1364 }
1365
1366 if(!Thread || !Desktop)
1367 {
1368 if(idThread && Thread)
1369 ObDereferenceObject(Thread);
1370 SetLastWin32Error(ERROR_ACCESS_DENIED);
1371 RETURN( FALSE);
1372 }
1373
1374 MsgQueue = (PUSER_MESSAGE_QUEUE)Desktop->ActiveMessageQueue;
1375 CaretInfo = MsgQueue->CaretInfo;
1376
1377 SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0);
1378 if(MsgQueue->MenuOwner)
1379 SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState;
1380 if(MsgQueue->MoveSize)
1381 SafeGui.flags |= GUI_INMOVESIZE;
1382
1383 /* FIXME add flag GUI_16BITTASK */
1384
1385 SafeGui.hwndActive = MsgQueue->ActiveWindow;
1386 SafeGui.hwndFocus = MsgQueue->FocusWindow;
1387 SafeGui.hwndCapture = MsgQueue->CaptureWindow;
1388 SafeGui.hwndMenuOwner = MsgQueue->MenuOwner;
1389 SafeGui.hwndMoveSize = MsgQueue->MoveSize;
1390 SafeGui.hwndCaret = CaretInfo->hWnd;
1391
1392 SafeGui.rcCaret.left = CaretInfo->Pos.x;
1393 SafeGui.rcCaret.top = CaretInfo->Pos.y;
1394 SafeGui.rcCaret.right = SafeGui.rcCaret.left + CaretInfo->Size.cx;
1395 SafeGui.rcCaret.bottom = SafeGui.rcCaret.top + CaretInfo->Size.cy;
1396
1397 if(idThread)
1398 ObDereferenceObject(Thread);
1399
1400 Status = MmCopyToCaller(lpgui, &SafeGui, sizeof(GUITHREADINFO));
1401 if(!NT_SUCCESS(Status))
1402 {
1403 SetLastNtError(Status);
1404 RETURN( FALSE);
1405 }
1406
1407 RETURN( TRUE);
1408
1409 CLEANUP:
1410 DPRINT("Leave NtUserGetGUIThreadInfo, ret=%i\n",_ret_);
1411 UserLeave();
1412 END_CLEANUP;
1413 }
1414
1415
1416 DWORD
1417 STDCALL
1418 NtUserGetGuiResources(
1419 HANDLE hProcess,
1420 DWORD uiFlags)
1421 {
1422 PEPROCESS Process;
1423 PW32PROCESS W32Process;
1424 NTSTATUS Status;
1425 DWORD Ret = 0;
1426 DECLARE_RETURN(DWORD);
1427
1428 DPRINT("Enter NtUserGetGuiResources\n");
1429 UserEnterShared();
1430
1431 Status = ObReferenceObjectByHandle(hProcess,
1432 PROCESS_QUERY_INFORMATION,
1433 PsProcessType,
1434 ExGetPreviousMode(),
1435 (PVOID*)&Process,
1436 NULL);
1437
1438 if(!NT_SUCCESS(Status))
1439 {
1440 SetLastNtError(Status);
1441 RETURN( 0);
1442 }
1443
1444 W32Process = (PW32PROCESS)Process->Win32Process;
1445 if(!W32Process)
1446 {
1447 ObDereferenceObject(Process);
1448 SetLastWin32Error(ERROR_INVALID_PARAMETER);
1449 RETURN( 0);
1450 }
1451
1452 switch(uiFlags)
1453 {
1454 case GR_GDIOBJECTS:
1455 {
1456 Ret = (DWORD)W32Process->GDIObjects;
1457 break;
1458 }
1459 case GR_USEROBJECTS:
1460 {
1461 Ret = (DWORD)W32Process->UserObjects;
1462 break;
1463 }
1464 default:
1465 {
1466 SetLastWin32Error(ERROR_INVALID_PARAMETER);
1467 break;
1468 }
1469 }
1470
1471 ObDereferenceObject(Process);
1472
1473 RETURN( Ret);
1474
1475 CLEANUP:
1476 DPRINT("Leave NtUserGetGuiResources, ret=%i\n",_ret_);
1477 UserLeave();
1478 END_CLEANUP;
1479 }
1480
1481 NTSTATUS FASTCALL
1482 IntSafeCopyUnicodeString(PUNICODE_STRING Dest,
1483 PUNICODE_STRING Source)
1484 {
1485 NTSTATUS Status;
1486 PWSTR Src;
1487
1488 Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING));
1489 if(!NT_SUCCESS(Status))
1490 {
1491 return Status;
1492 }
1493
1494 if(Dest->Length > 0x4000)
1495 {
1496 return STATUS_UNSUCCESSFUL;
1497 }
1498
1499 Src = Dest->Buffer;
1500 Dest->Buffer = NULL;
1501
1502 if(Dest->Length > 0 && Src)
1503 {
1504 Dest->MaximumLength = Dest->Length;
1505 Dest->Buffer = ExAllocatePoolWithTag(PagedPool, Dest->MaximumLength, TAG_STRING);
1506 if(!Dest->Buffer)
1507 {
1508 return STATUS_NO_MEMORY;
1509 }
1510
1511 Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->Length);
1512 if(!NT_SUCCESS(Status))
1513 {
1514 ExFreePool(Dest->Buffer);
1515 Dest->Buffer = NULL;
1516 return Status;
1517 }
1518
1519
1520 return STATUS_SUCCESS;
1521 }
1522
1523 /* string is empty */
1524 return STATUS_SUCCESS;
1525 }
1526
1527 NTSTATUS FASTCALL
1528 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest,
1529 PUNICODE_STRING Source)
1530 {
1531 NTSTATUS Status;
1532 PWSTR Src;
1533
1534 Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING));
1535 if(!NT_SUCCESS(Status))
1536 {
1537 return Status;
1538 }
1539
1540 if(Dest->Length > 0x4000)
1541 {
1542 return STATUS_UNSUCCESSFUL;
1543 }
1544
1545 Src = Dest->Buffer;
1546 Dest->Buffer = NULL;
1547
1548 if(Dest->Length > 0 && Src)
1549 {
1550 Dest->MaximumLength = Dest->Length + sizeof(WCHAR);
1551 Dest->Buffer = ExAllocatePoolWithTag(PagedPool, Dest->MaximumLength, TAG_STRING);
1552 if(!Dest->Buffer)
1553 {
1554 return STATUS_NO_MEMORY;
1555 }
1556
1557 Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->Length);
1558 if(!NT_SUCCESS(Status))
1559 {
1560 ExFreePool(Dest->Buffer);
1561 Dest->Buffer = NULL;
1562 return Status;
1563 }
1564
1565 /* make sure the string is null-terminated */
1566 Src = (PWSTR)((PBYTE)Dest->Buffer + Dest->Length);
1567 *Src = L'\0';
1568
1569 return STATUS_SUCCESS;
1570 }
1571
1572 /* string is empty */
1573 return STATUS_SUCCESS;
1574 }
1575
1576 NTSTATUS FASTCALL
1577 IntUnicodeStringToNULLTerminated(PWSTR *Dest, PUNICODE_STRING Src)
1578 {
1579 if (Src->Length + sizeof(WCHAR) <= Src->MaximumLength
1580 && L'\0' == Src->Buffer[Src->Length / sizeof(WCHAR)])
1581 {
1582 /* The unicode_string is already nul terminated. Just reuse it. */
1583 *Dest = Src->Buffer;
1584 return STATUS_SUCCESS;
1585 }
1586
1587 *Dest = ExAllocatePoolWithTag(PagedPool, Src->Length + sizeof(WCHAR), TAG_STRING);
1588 if (NULL == *Dest)
1589 {
1590 return STATUS_NO_MEMORY;
1591 }
1592 RtlCopyMemory(*Dest, Src->Buffer, Src->Length);
1593 (*Dest)[Src->Length / 2] = L'\0';
1594
1595 return STATUS_SUCCESS;
1596 }
1597
1598 void FASTCALL
1599 IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated, PUNICODE_STRING UnicodeString)
1600 {
1601 if (NullTerminated != UnicodeString->Buffer)
1602 {
1603 ExFreePool(NullTerminated);
1604 }
1605 }
1606
1607 BOOL STDCALL
1608 NtUserUpdatePerUserSystemParameters(
1609 DWORD dwReserved,
1610 BOOL bEnable)
1611 {
1612 BOOL Result = TRUE;
1613 DECLARE_RETURN(BOOLEAN);
1614
1615 DPRINT("Enter NtUserUpdatePerUserSystemParameters\n");
1616 UserEnterExclusive();
1617
1618 Result &= IntDesktopUpdatePerUserSettings(bEnable);
1619 RETURN( Result);
1620
1621 CLEANUP:
1622 DPRINT("Leave NtUserUpdatePerUserSystemParameters, ret=%i\n",_ret_);
1623 UserLeave();
1624 END_CLEANUP;
1625 }
1626
1627 /* EOF */