Fixed some hard code font name
[reactos.git] / reactos / subsystems / win32 / 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 = PsGetCurrentThreadWin32Thread();
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 /*
169 * @implemented
170 */
171 DWORD
172 STDCALL
173 NtUserCallOneParam(
174 DWORD Param,
175 DWORD Routine)
176 {
177 DECLARE_RETURN(DWORD);
178 PDC dc;
179
180 DPRINT("Enter NtUserCallOneParam\n");
181
182
183 if (Routine == ONEPARAM_ROUTINE_SHOWCURSOR)
184 {
185 PWINSTATION_OBJECT WinSta = PsGetCurrentThreadWin32Thread()->Desktop->WindowStation;
186 PSYSTEM_CURSORINFO CurInfo;
187
188 HDC Screen;
189 HBITMAP dcbmp;
190 SURFOBJ *SurfObj;
191 BITMAPOBJ *BitmapObj;
192 GDIDEVICE *ppdev;
193 GDIPOINTER *pgp;
194 int showpointer=0;
195
196 if(!(Screen = IntGetScreenDC()))
197 {
198 return showpointer; /* No mouse */
199 }
200
201 dc = DC_LockDc(Screen);
202
203 if (!dc)
204 {
205 return showpointer; /* No mouse */
206 }
207
208 dcbmp = dc->w.hBitmap;
209 DC_UnlockDc(dc);
210
211 BitmapObj = BITMAPOBJ_LockBitmap(dcbmp);
212 if ( !BitmapObj )
213 {
214 BITMAPOBJ_UnlockBitmap(BitmapObj);
215 return showpointer; /* No Mouse */
216 }
217
218 SurfObj = &BitmapObj->SurfObj;
219 if (SurfObj == NULL)
220 {
221 BITMAPOBJ_UnlockBitmap(BitmapObj);
222 return showpointer; /* No mouse */
223 }
224
225 ppdev = GDIDEV(SurfObj);
226
227 if(ppdev == NULL)
228 {
229 BITMAPOBJ_UnlockBitmap(BitmapObj);
230 return showpointer; /* No mouse */
231 }
232
233 pgp = &ppdev->Pointer;
234
235 CurInfo = IntGetSysCursorInfo(WinSta);
236
237 if (Param == FALSE)
238 {
239 pgp->ShowPointer--;
240 showpointer = pgp->ShowPointer;
241
242 if (showpointer >= 0)
243 {
244 //ppdev->SafetyRemoveCount = 1;
245 //ppdev->SafetyRemoveLevel = 1;
246 EngMovePointer(SurfObj,-1,-1,NULL);
247 CurInfo->ShowingCursor = 0;
248 }
249
250 }
251 else
252 {
253 pgp->ShowPointer++;
254 showpointer = pgp->ShowPointer;
255
256 /* Show Cursor */
257 if (showpointer < 0)
258 {
259 //ppdev->SafetyRemoveCount = 0;
260 //ppdev->SafetyRemoveLevel = 0;
261 EngMovePointer(SurfObj,-1,-1,NULL);
262 CurInfo->ShowingCursor = CURSOR_SHOWING;
263 }
264 }
265
266 BITMAPOBJ_UnlockBitmap(BitmapObj);
267 return showpointer;
268 }
269
270
271 UserEnterExclusive();
272
273 switch(Routine)
274 {
275 case ONEPARAM_ROUTINE_GETMENU:
276 {
277 PWINDOW_OBJECT Window;
278 DWORD Result;
279
280 if(!(Window = UserGetWindowObject((HWND)Param)))
281 {
282 RETURN( FALSE);
283 }
284
285 Result = (DWORD)Window->IDMenu;
286
287 RETURN( Result);
288 }
289
290 case ONEPARAM_ROUTINE_ISWINDOWUNICODE:
291 {
292 PWINDOW_OBJECT Window;
293 DWORD Result;
294
295 Window = UserGetWindowObject((HWND)Param);
296 if(!Window)
297 {
298 RETURN( FALSE);
299 }
300 Result = Window->Unicode;
301 RETURN( Result);
302 }
303
304 case ONEPARAM_ROUTINE_WINDOWFROMDC:
305 RETURN( (DWORD)IntWindowFromDC((HDC)Param));
306
307 case ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID:
308 {
309 PWINDOW_OBJECT Window;
310 DWORD Result;
311
312 Window = UserGetWindowObject((HWND)Param);
313 if(!Window)
314 {
315 RETURN( FALSE);
316 }
317
318 Result = Window->ContextHelpId;
319
320 RETURN( Result);
321 }
322
323 case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON:
324 {
325 PWINSTATION_OBJECT WinSta;
326 NTSTATUS Status;
327 DWORD Result;
328
329 Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
330 KernelMode,
331 0,
332 &WinSta);
333 if (!NT_SUCCESS(Status))
334 RETURN( (DWORD)FALSE);
335
336 /* FIXME
337 Result = (DWORD)IntSwapMouseButton(WinStaObject, (BOOL)Param); */
338 Result = 0;
339
340 ObDereferenceObject(WinSta);
341 RETURN( Result);
342 }
343
344 case ONEPARAM_ROUTINE_SWITCHCARETSHOWING:
345 RETURN( (DWORD)IntSwitchCaretShowing((PVOID)Param));
346
347 case ONEPARAM_ROUTINE_SETCARETBLINKTIME:
348 RETURN( (DWORD)IntSetCaretBlinkTime((UINT)Param));
349
350 case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS:
351 RETURN( (DWORD)IntEnumClipboardFormats((UINT)Param));
352
353 case ONEPARAM_ROUTINE_GETWINDOWINSTANCE:
354 {
355 PWINDOW_OBJECT Window;
356 DWORD Result;
357
358 if(!(Window = UserGetWindowObject((HWND)Param)))
359 {
360 RETURN( FALSE);
361 }
362
363 Result = (DWORD)Window->Instance;
364 RETURN( Result);
365 }
366
367 case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO:
368 RETURN( (DWORD)MsqSetMessageExtraInfo((LPARAM)Param));
369
370 case ONEPARAM_ROUTINE_GETCURSORPOSITION:
371 {
372 PWINSTATION_OBJECT WinSta;
373 NTSTATUS Status;
374 POINT Pos;
375
376 if(!Param)
377 RETURN( (DWORD)FALSE);
378 Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
379 KernelMode,
380 0,
381 &WinSta);
382 if (!NT_SUCCESS(Status))
383 RETURN( (DWORD)FALSE);
384
385 /* FIXME - check if process has WINSTA_READATTRIBUTES */
386 IntGetCursorLocation(WinSta, &Pos);
387
388 Status = MmCopyToCaller((PPOINT)Param, &Pos, sizeof(POINT));
389 if(!NT_SUCCESS(Status))
390 {
391 ObDereferenceObject(WinSta);
392 SetLastNtError(Status);
393 RETURN( FALSE);
394 }
395
396 ObDereferenceObject(WinSta);
397
398 RETURN( (DWORD)TRUE);
399 }
400
401 case ONEPARAM_ROUTINE_ISWINDOWINDESTROY:
402 {
403 PWINDOW_OBJECT Window;
404 DWORD Result;
405
406 if(!(Window = UserGetWindowObject((HWND)Param)))
407 {
408 RETURN( FALSE);
409 }
410
411 Result = (DWORD)IntIsWindowInDestroy(Window);
412
413 RETURN( Result);
414 }
415
416 case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING:
417 {
418 BOOL Enable;
419 PW32PROCESS Process = PsGetCurrentProcessWin32Process();
420
421 if(Process != NULL)
422 {
423 Enable = (BOOL)(Param != 0);
424
425 if(Enable)
426 {
427 Process->Flags &= ~W32PF_NOWINDOWGHOSTING;
428 }
429 else
430 {
431 Process->Flags |= W32PF_NOWINDOWGHOSTING;
432 }
433
434 RETURN( TRUE);
435 }
436
437 RETURN( FALSE);
438 }
439
440 case ONEPARAM_ROUTINE_MSQSETWAKEMASK:
441 RETURN( (DWORD)IntMsqSetWakeMask(Param));
442
443 case ONEPARAM_ROUTINE_GETKEYBOARDTYPE:
444 RETURN( UserGetKeyboardType(Param));
445
446 case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT:
447 RETURN( (DWORD)UserGetKeyboardLayout(Param));
448 }
449 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
450 Routine, Param);
451 SetLastWin32Error(ERROR_INVALID_PARAMETER);
452 RETURN( 0);
453
454 CLEANUP:
455 DPRINT("Leave NtUserCallOneParam, ret=%i\n",_ret_);
456 UserLeave();
457 END_CLEANUP;
458 }
459
460
461 /*
462 * @implemented
463 */
464 DWORD
465 STDCALL
466 NtUserCallTwoParam(
467 DWORD Param1,
468 DWORD Param2,
469 DWORD Routine)
470 {
471 NTSTATUS Status;
472 PWINDOW_OBJECT Window;
473 DECLARE_RETURN(DWORD);
474
475 DPRINT("Enter NtUserCallTwoParam\n");
476 UserEnterExclusive();
477
478 switch(Routine)
479 {
480 case TWOPARAM_ROUTINE_SETDCPENCOLOR:
481 {
482 RETURN( (DWORD)IntSetDCColor((HDC)Param1, OBJ_PEN, (COLORREF)Param2));
483 }
484 case TWOPARAM_ROUTINE_SETDCBRUSHCOLOR:
485 {
486 RETURN( (DWORD)IntSetDCColor((HDC)Param1, OBJ_BRUSH, (COLORREF)Param2));
487 }
488 case TWOPARAM_ROUTINE_GETDCCOLOR:
489 {
490 RETURN( (DWORD)IntGetDCColor((HDC)Param1, (ULONG)Param2));
491 }
492 case TWOPARAM_ROUTINE_GETWINDOWRGNBOX:
493 {
494 DWORD Ret;
495 RECT rcRect;
496 Window = UserGetWindowObject((HWND)Param1);
497 if (!Window) RETURN(ERROR);
498
499 Ret = (DWORD)IntGetWindowRgnBox(Window, &rcRect);
500 Status = MmCopyToCaller((PVOID)Param2, &rcRect, sizeof(RECT));
501 if(!NT_SUCCESS(Status))
502 {
503 SetLastNtError(Status);
504 RETURN( ERROR);
505 }
506 RETURN( Ret);
507 }
508 case TWOPARAM_ROUTINE_GETWINDOWRGN:
509 {
510 Window = UserGetWindowObject((HWND)Param1);
511 if (!Window) RETURN(ERROR);
512
513 RETURN( (DWORD)IntGetWindowRgn(Window, (HRGN)Param2));
514 }
515 case TWOPARAM_ROUTINE_SETMENUBARHEIGHT:
516 {
517 DWORD Ret;
518 PMENU_OBJECT MenuObject = IntGetMenuObject((HMENU)Param1);
519 if(!MenuObject)
520 RETURN( 0);
521
522 if(Param2 > 0)
523 {
524 Ret = (MenuObject->MenuInfo.Height == (int)Param2);
525 MenuObject->MenuInfo.Height = (int)Param2;
526 }
527 else
528 Ret = (DWORD)MenuObject->MenuInfo.Height;
529 IntReleaseMenuObject(MenuObject);
530 RETURN( Ret);
531 }
532 case TWOPARAM_ROUTINE_SETMENUITEMRECT:
533 {
534 BOOL Ret;
535 SETMENUITEMRECT smir;
536 PMENU_OBJECT MenuObject = IntGetMenuObject((HMENU)Param1);
537 if(!MenuObject)
538 RETURN( 0);
539
540 if(!NT_SUCCESS(MmCopyFromCaller(&smir, (PVOID)Param2, sizeof(SETMENUITEMRECT))))
541 {
542 IntReleaseMenuObject(MenuObject);
543 RETURN( 0);
544 }
545
546 Ret = IntSetMenuItemRect(MenuObject, smir.uItem, smir.fByPosition, &smir.rcRect);
547
548 IntReleaseMenuObject(MenuObject);
549 RETURN( (DWORD)Ret);
550 }
551
552 case TWOPARAM_ROUTINE_SETGUITHRDHANDLE:
553 {
554 PUSER_MESSAGE_QUEUE MsgQueue = ((PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread)->MessageQueue;
555
556 ASSERT(MsgQueue);
557 RETURN( (DWORD)MsqSetStateWindow(MsgQueue, (ULONG)Param1, (HWND)Param2));
558 }
559
560 case TWOPARAM_ROUTINE_ENABLEWINDOW:
561 UNIMPLEMENTED
562 RETURN( 0);
563
564 case TWOPARAM_ROUTINE_UNKNOWN:
565 UNIMPLEMENTED
566 RETURN( 0);
567
568 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS:
569 {
570 Window = UserGetWindowObject((HWND)Param1);
571 if (!Window) RETURN(0);
572
573 RETURN( (DWORD)IntShowOwnedPopups(Window, (BOOL) Param2));
574 }
575
576 case TWOPARAM_ROUTINE_ROS_SHOWWINDOW:
577 {
578 #define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040)
579 DPRINT1("ROS_SHOWWINDOW\n");
580
581 if (!(Window = UserGetWindowObject((HWND)Param1)))
582 {
583 RETURN( 1 );
584 }
585
586 if (Param2)
587 {
588 if (!(Window->Flags & WIN_NEEDS_SHOW_OWNEDPOPUP))
589 {
590 RETURN( -1 );
591 }
592 Window->Flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP;
593 }
594 else
595 Window->Flags |= WIN_NEEDS_SHOW_OWNEDPOPUP;
596
597 DPRINT1("ROS_SHOWWINDOW ---> 0x%x\n",Window->Flags);
598 RETURN( 0 );
599 }
600
601 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW:
602 UNIMPLEMENTED
603 RETURN( 0);
604
605 case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID:
606
607 if(!(Window = UserGetWindowObject((HWND)Param1)))
608 {
609 RETURN( (DWORD)FALSE);
610 }
611
612 Window->ContextHelpId = Param2;
613
614 RETURN( (DWORD)TRUE);
615
616 case TWOPARAM_ROUTINE_SETCARETPOS:
617 RETURN( (DWORD)co_IntSetCaretPos((int)Param1, (int)Param2));
618
619 case TWOPARAM_ROUTINE_GETWINDOWINFO:
620 {
621 WINDOWINFO wi;
622 DWORD Ret;
623
624 if(!(Window = UserGetWindowObject((HWND)Param1)))
625 {
626 RETURN( FALSE);
627 }
628
629 #if 0
630 /*
631 * According to WINE, Windows' doesn't check the cbSize field
632 */
633
634 Status = MmCopyFromCaller(&wi.cbSize, (PVOID)Param2, sizeof(wi.cbSize));
635 if(!NT_SUCCESS(Status))
636 {
637 SetLastNtError(Status);
638 RETURN( FALSE);
639 }
640
641 if(wi.cbSize != sizeof(WINDOWINFO))
642 {
643 SetLastWin32Error(ERROR_INVALID_PARAMETER);
644 RETURN( FALSE);
645 }
646 #endif
647
648 if((Ret = (DWORD)IntGetWindowInfo(Window, &wi)))
649 {
650 Status = MmCopyToCaller((PVOID)Param2, &wi, sizeof(WINDOWINFO));
651 if(!NT_SUCCESS(Status))
652 {
653 SetLastNtError(Status);
654 RETURN( FALSE);
655 }
656 }
657
658 RETURN( Ret);
659 }
660
661 case TWOPARAM_ROUTINE_REGISTERLOGONPROC:
662 RETURN( (DWORD)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2));
663
664 case TWOPARAM_ROUTINE_SETSYSCOLORS:
665 {
666 DWORD Ret = 0;
667 PVOID Buffer;
668 struct
669 {
670 INT *Elements;
671 COLORREF *Colors;
672 }
673 ChangeSysColors;
674
675 /* FIXME - we should make use of SEH here... */
676
677 Status = MmCopyFromCaller(&ChangeSysColors, (PVOID)Param1, sizeof(ChangeSysColors));
678 if(!NT_SUCCESS(Status))
679 {
680 SetLastNtError(Status);
681 RETURN( 0);
682 }
683
684 Buffer = ExAllocatePool(PagedPool, (Param2 * sizeof(INT)) + (Param2 * sizeof(COLORREF)));
685 if(Buffer != NULL)
686 {
687 INT *Elements = (INT*)Buffer;
688 COLORREF *Colors = (COLORREF*)Buffer + Param2;
689
690 Status = MmCopyFromCaller(Elements, ChangeSysColors.Elements, Param2 * sizeof(INT));
691 if(NT_SUCCESS(Status))
692 {
693 Status = MmCopyFromCaller(Colors, ChangeSysColors.Colors, Param2 * sizeof(COLORREF));
694 if(NT_SUCCESS(Status))
695 {
696 Ret = (DWORD)IntSetSysColors((UINT)Param2, Elements, Colors);
697 }
698 else
699 SetLastNtError(Status);
700 }
701 else
702 SetLastNtError(Status);
703
704 ExFreePool(Buffer);
705 }
706
707
708 RETURN( Ret);
709 }
710
711 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES:
712 case TWOPARAM_ROUTINE_GETSYSCOLORPENS:
713 case TWOPARAM_ROUTINE_GETSYSCOLORS:
714 {
715 DWORD Ret = 0;
716 union
717 {
718 PVOID Pointer;
719 HBRUSH *Brushes;
720 HPEN *Pens;
721 COLORREF *Colors;
722 } Buffer;
723
724 /* FIXME - we should make use of SEH here... */
725
726 Buffer.Pointer = ExAllocatePool(PagedPool, Param2 * sizeof(HANDLE));
727 if(Buffer.Pointer != NULL)
728 {
729 switch(Routine)
730 {
731 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES:
732 Ret = (DWORD)IntGetSysColorBrushes(Buffer.Brushes, (UINT)Param2);
733 break;
734 case TWOPARAM_ROUTINE_GETSYSCOLORPENS:
735 Ret = (DWORD)IntGetSysColorPens(Buffer.Pens, (UINT)Param2);
736 break;
737 case TWOPARAM_ROUTINE_GETSYSCOLORS:
738 Ret = (DWORD)IntGetSysColors(Buffer.Colors, (UINT)Param2);
739 break;
740 default:
741 Ret = 0;
742 break;
743 }
744
745 if(Ret > 0)
746 {
747 Status = MmCopyToCaller((PVOID)Param1, Buffer.Pointer, Param2 * sizeof(HANDLE));
748 if(!NT_SUCCESS(Status))
749 {
750 SetLastNtError(Status);
751 Ret = 0;
752 }
753 }
754
755 ExFreePool(Buffer.Pointer);
756 }
757 RETURN( Ret);
758 }
759
760 }
761 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
762 Routine, Param1, Param2);
763 SetLastWin32Error(ERROR_INVALID_PARAMETER);
764 RETURN( 0);
765
766 CLEANUP:
767 DPRINT("Leave NtUserCallTwoParam, ret=%i\n",_ret_);
768 UserLeave();
769 END_CLEANUP;
770 }
771
772
773 /*
774 * @unimplemented
775 */
776 BOOL
777 STDCALL
778 NtUserCallHwndLock(
779 HWND hWnd,
780 DWORD Routine)
781 {
782 BOOL Ret = 0;
783 PWINDOW_OBJECT Window;
784 USER_REFERENCE_ENTRY Ref;
785 DECLARE_RETURN(BOOLEAN);
786
787 DPRINT("Enter NtUserCallHwndLock\n");
788 UserEnterExclusive();
789
790 if (!(Window = UserGetWindowObject(hWnd)))
791 {
792 RETURN( FALSE);
793 }
794 UserRefObjectCo(Window, &Ref);
795
796 /* FIXME: Routine can be 0x53 - 0x5E */
797 switch (Routine)
798 {
799 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS:
800 co_WinPosArrangeIconicWindows(Window);
801 break;
802
803 case HWNDLOCK_ROUTINE_DRAWMENUBAR:
804 {
805 PMENU_OBJECT Menu;
806 DPRINT("HWNDLOCK_ROUTINE_DRAWMENUBAR\n");
807 Ret = FALSE;
808 if (!((Window->Style & (WS_CHILD | WS_POPUP)) != WS_CHILD))
809 break;
810
811 if(!(Menu = UserGetMenuObject((HMENU) Window->IDMenu)))
812 break;
813
814 Menu->MenuInfo.WndOwner = hWnd;
815 Menu->MenuInfo.Height = 0;
816
817 co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
818 SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
819
820 Ret = TRUE;
821 break;
822 }
823
824 case HWNDLOCK_ROUTINE_REDRAWFRAME:
825 /* FIXME */
826 break;
827
828 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW:
829 Ret = co_IntSetForegroundWindow(Window);
830 break;
831
832 case HWNDLOCK_ROUTINE_UPDATEWINDOW:
833 /* FIXME */
834 break;
835 }
836
837 UserDerefObjectCo(Window);
838
839 RETURN( Ret);
840
841 CLEANUP:
842 DPRINT("Leave NtUserCallHwndLock, ret=%i\n",_ret_);
843 UserLeave();
844 END_CLEANUP;
845 }
846
847 /*
848 * @unimplemented
849 */
850 HWND
851 STDCALL
852 NtUserCallHwndOpt(
853 HWND Param,
854 DWORD Routine)
855 {
856 switch (Routine)
857 {
858 case HWNDOPT_ROUTINE_SETPROGMANWINDOW:
859 GetW32ThreadInfo()->Desktop->hProgmanWindow = Param;
860 break;
861
862 case HWNDOPT_ROUTINE_SETTASKMANWINDOW:
863 GetW32ThreadInfo()->Desktop->hTaskManWindow = Param;
864 break;
865 }
866
867 return Param;
868 }
869
870 /*
871 * @unimplemented
872 */
873 DWORD STDCALL
874 NtUserGetThreadState(
875 DWORD Routine)
876 {
877 DECLARE_RETURN(DWORD);
878
879 DPRINT("Enter NtUserGetThreadState\n");
880 if (Routine != THREADSTATE_GETTHREADINFO)
881 {
882 UserEnterShared();
883 }
884 else
885 {
886 UserEnterExclusive();
887 }
888
889 switch (Routine)
890 {
891 case THREADSTATE_GETTHREADINFO:
892 GetW32ThreadInfo();
893 RETURN(0);
894
895 case THREADSTATE_FOCUSWINDOW:
896 RETURN( (DWORD)IntGetThreadFocusWindow());
897 case THREADSTATE_PROGMANWINDOW:
898 RETURN( (DWORD)GetW32ThreadInfo()->Desktop->hProgmanWindow);
899 case THREADSTATE_TASKMANWINDOW:
900 RETURN( (DWORD)GetW32ThreadInfo()->Desktop->hTaskManWindow);
901 }
902 RETURN( 0);
903
904 CLEANUP:
905 DPRINT("Leave NtUserGetThreadState, ret=%i\n",_ret_);
906 UserLeave();
907 END_CLEANUP;
908 }
909
910 VOID FASTCALL
911 IntGetFontMetricSetting(LPWSTR lpValueName, PLOGFONTW font)
912 {
913 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
914 NTSTATUS Status;
915 /* Firefox 1.0.7 depends on the lfHeight value being negative */
916 static LOGFONTW DefaultFont = {
917 -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
918 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
919 L"MS Sans Serif"
920 };
921
922 RtlZeroMemory(&QueryTable, sizeof(QueryTable));
923
924 QueryTable[0].Name = lpValueName;
925 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
926 QueryTable[0].EntryContext = font;
927
928 Status = RtlQueryRegistryValues(
929 RTL_REGISTRY_USER,
930 L"Control Panel\\Desktop\\WindowMetrics",
931 QueryTable,
932 NULL,
933 NULL);
934
935 if (!NT_SUCCESS(Status))
936 {
937 RtlCopyMemory(font, &DefaultFont, sizeof(LOGFONTW));
938 }
939 }
940
941 ULONG FASTCALL
942 IntSystemParametersInfo(
943 UINT uiAction,
944 UINT uiParam,
945 PVOID pvParam,
946 UINT fWinIni)
947 {
948 PWINSTATION_OBJECT WinStaObject;
949 NTSTATUS Status;
950
951 static BOOL bInitialized = FALSE;
952 static LOGFONTW IconFont;
953 static NONCLIENTMETRICSW pMetrics;
954 static BOOL GradientCaptions = TRUE;
955 static UINT FocusBorderHeight = 1;
956 static UINT FocusBorderWidth = 1;
957
958 if (!bInitialized)
959 {
960 RtlZeroMemory(&IconFont, sizeof(LOGFONTW));
961 RtlZeroMemory(&pMetrics, sizeof(NONCLIENTMETRICSW));
962
963 IntGetFontMetricSetting(L"CaptionFont", &pMetrics.lfCaptionFont);
964 IntGetFontMetricSetting(L"SmCaptionFont", &pMetrics.lfSmCaptionFont);
965 IntGetFontMetricSetting(L"MenuFont", &pMetrics.lfMenuFont);
966 IntGetFontMetricSetting(L"StatusFont", &pMetrics.lfStatusFont);
967 IntGetFontMetricSetting(L"MessageFont", &pMetrics.lfMessageFont);
968 IntGetFontMetricSetting(L"IconFont", &IconFont);
969
970 pMetrics.iBorderWidth = 1;
971 pMetrics.iScrollWidth = UserGetSystemMetrics(SM_CXVSCROLL);
972 pMetrics.iScrollHeight = UserGetSystemMetrics(SM_CYHSCROLL);
973 pMetrics.iCaptionWidth = UserGetSystemMetrics(SM_CXSIZE);
974 pMetrics.iCaptionHeight = UserGetSystemMetrics(SM_CYSIZE);
975 pMetrics.iSmCaptionWidth = UserGetSystemMetrics(SM_CXSMSIZE);
976 pMetrics.iSmCaptionHeight = UserGetSystemMetrics(SM_CYSMSIZE);
977 pMetrics.iMenuWidth = UserGetSystemMetrics(SM_CXMENUSIZE);
978 pMetrics.iMenuHeight = UserGetSystemMetrics(SM_CYMENUSIZE);
979 pMetrics.cbSize = sizeof(NONCLIENTMETRICSW);
980
981 bInitialized = TRUE;
982 }
983
984 switch(uiAction)
985 {
986 case SPI_SETDOUBLECLKWIDTH:
987 case SPI_SETDOUBLECLKHEIGHT:
988 case SPI_SETDOUBLECLICKTIME:
989 case SPI_SETDESKWALLPAPER:
990 case SPI_GETDESKWALLPAPER:
991 case SPI_GETWHEELSCROLLLINES:
992 case SPI_GETWHEELSCROLLCHARS:
993 case SPI_SETSCREENSAVERRUNNING:
994 case SPI_GETSCREENSAVERRUNNING:
995 case SPI_GETSCREENSAVETIMEOUT:
996 case SPI_SETSCREENSAVETIMEOUT:
997 case SPI_GETFLATMENU:
998 case SPI_SETFLATMENU:
999 {
1000 PSYSTEM_CURSORINFO CurInfo;
1001
1002 Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
1003 KernelMode,
1004 0,
1005 &WinStaObject);
1006 if(!NT_SUCCESS(Status))
1007 {
1008 SetLastNtError(Status);
1009 return (DWORD)FALSE;
1010 }
1011
1012 switch(uiAction)
1013 {
1014 case SPI_GETFLATMENU:
1015 if (pvParam != NULL) *((UINT*)pvParam) = WinStaObject->FlatMenu;
1016 return TRUE;
1017 break;
1018 case SPI_SETFLATMENU:
1019 WinStaObject->FlatMenu = uiParam;
1020 break;
1021 case SPI_GETSCREENSAVETIMEOUT:
1022 if (pvParam != NULL) *((UINT*)pvParam) = WinStaObject->ScreenSaverTimeOut;
1023 return TRUE;
1024 break;
1025 case SPI_SETSCREENSAVETIMEOUT:
1026 WinStaObject->ScreenSaverTimeOut = uiParam;
1027 break;
1028 case SPI_GETSCREENSAVERRUNNING:
1029 if (pvParam != NULL) *((BOOL*)pvParam) = WinStaObject->ScreenSaverRunning;
1030 return TRUE;
1031 break;
1032 case SPI_SETSCREENSAVERRUNNING:
1033 if (pvParam != NULL) *((BOOL*)pvParam) = WinStaObject->ScreenSaverRunning;
1034 WinStaObject->ScreenSaverRunning = uiParam;
1035 break;
1036 case SPI_GETWHEELSCROLLLINES:
1037 CurInfo = IntGetSysCursorInfo(WinStaObject);
1038 if (pvParam != NULL) *((UINT*)pvParam) = CurInfo->WheelScroLines;
1039 /* FIXME add this value to scroll list as scroll value ?? */
1040 return TRUE;
1041 break;
1042 case SPI_GETWHEELSCROLLCHARS:
1043 CurInfo = IntGetSysCursorInfo(WinStaObject);
1044 if (pvParam != NULL) *((UINT*)pvParam) = CurInfo->WheelScroChars;
1045 // FIXME add this value to scroll list as scroll value ??
1046 return TRUE;
1047 break;
1048 case SPI_SETDOUBLECLKWIDTH:
1049 CurInfo = IntGetSysCursorInfo(WinStaObject);
1050 /* FIXME limit the maximum value? */
1051 CurInfo->DblClickWidth = uiParam;
1052 break;
1053 case SPI_SETDOUBLECLKHEIGHT:
1054 CurInfo = IntGetSysCursorInfo(WinStaObject);
1055 /* FIXME limit the maximum value? */
1056 CurInfo->DblClickHeight = uiParam;
1057 break;
1058 case SPI_SETDOUBLECLICKTIME:
1059 CurInfo = IntGetSysCursorInfo(WinStaObject);
1060 /* FIXME limit the maximum time to 1000 ms? */
1061 CurInfo->DblClickSpeed = uiParam;
1062 break;
1063 case SPI_SETDESKWALLPAPER:
1064 {
1065 /* This function expects different parameters than the user mode version!
1066
1067 We let the user mode code load the bitmap, it passed the handle to
1068 the bitmap. We'll change it's ownership to system and replace it with
1069 the current wallpaper bitmap */
1070 HBITMAP hOldBitmap, hNewBitmap;
1071 UNICODE_STRING Key = RTL_CONSTANT_STRING(L"Control Panel\\Desktop");
1072 UNICODE_STRING Tile = RTL_CONSTANT_STRING(L"TileWallpaper");
1073 UNICODE_STRING Style = RTL_CONSTANT_STRING(L"WallpaperStyle");
1074 UNICODE_STRING KeyPath;
1075 OBJECT_ATTRIBUTES KeyAttributes;
1076 OBJECT_ATTRIBUTES ObjectAttributes;
1077 NTSTATUS Status;
1078 HANDLE CurrentUserKey = NULL;
1079 HANDLE KeyHandle = NULL;
1080 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
1081 ULONG Length = 0;
1082 ULONG ResLength = 0;
1083 ULONG TileNum = 0;
1084 ULONG StyleNum = 0;
1085 ASSERT(pvParam);
1086
1087 hNewBitmap = *(HBITMAP*)pvParam;
1088 if(hNewBitmap != NULL)
1089 {
1090 BITMAPOBJ *bmp;
1091 /* try to get the size of the wallpaper */
1092 if(!(bmp = BITMAPOBJ_LockBitmap(hNewBitmap)))
1093 {
1094 ObDereferenceObject(WinStaObject);
1095 return FALSE;
1096 }
1097 WinStaObject->cxWallpaper = bmp->SurfObj.sizlBitmap.cx;
1098 WinStaObject->cyWallpaper = bmp->SurfObj.sizlBitmap.cy;
1099
1100 BITMAPOBJ_UnlockBitmap(bmp);
1101
1102 /* change the bitmap's ownership */
1103 GDIOBJ_SetOwnership(GdiHandleTable, hNewBitmap, NULL);
1104 }
1105 hOldBitmap = (HBITMAP)InterlockedExchange((LONG*)&WinStaObject->hbmWallpaper, (LONG)hNewBitmap);
1106 if(hOldBitmap != NULL)
1107 {
1108 /* delete the old wallpaper */
1109 NtGdiDeleteObject(hOldBitmap);
1110 }
1111
1112 /* Set the style */
1113
1114 /*default value is center */
1115 WinStaObject->WallpaperMode = wmCenter;
1116
1117
1118
1119 /* Get a handle to the current users settings */
1120 RtlFormatCurrentUserKeyPath(&KeyPath);
1121 InitializeObjectAttributes(&ObjectAttributes,&KeyPath,OBJ_CASE_INSENSITIVE,NULL,NULL);
1122 ZwOpenKey(&CurrentUserKey, KEY_READ, &ObjectAttributes);
1123 RtlFreeUnicodeString(&KeyPath);
1124
1125 /* open up the settings to read the values */
1126 InitializeObjectAttributes(&KeyAttributes, &Key, OBJ_CASE_INSENSITIVE,
1127 CurrentUserKey, NULL);
1128 ZwOpenKey(&KeyHandle, KEY_READ, &KeyAttributes);
1129 ZwClose(CurrentUserKey);
1130
1131 /* read the tile value in the registry */
1132 Status = ZwQueryValueKey(KeyHandle, &Tile, KeyValuePartialInformation,
1133 0, 0, &ResLength);
1134
1135 /* fall back to .DEFAULT if we didnt find values */
1136 if(Status == STATUS_INVALID_HANDLE)
1137 {
1138 RtlInitUnicodeString (&KeyPath,L"\\Registry\\User\\.Default\\Control Panel\\Desktop");
1139 InitializeObjectAttributes(&KeyAttributes, &KeyPath, OBJ_CASE_INSENSITIVE,
1140 NULL, NULL);
1141 ZwOpenKey(&KeyHandle, KEY_READ, &KeyAttributes);
1142 ZwQueryValueKey(KeyHandle, &Tile, KeyValuePartialInformation,
1143 0, 0, &ResLength);
1144 }
1145
1146 ResLength += sizeof(KEY_VALUE_PARTIAL_INFORMATION);
1147 KeyValuePartialInfo = ExAllocatePoolWithTag(PagedPool, ResLength, TAG_STRING);
1148 Length = ResLength;
1149
1150 if(!KeyValuePartialInfo)
1151 {
1152 NtClose(KeyHandle);
1153 return 0;
1154 }
1155
1156 Status = ZwQueryValueKey(KeyHandle, &Tile, KeyValuePartialInformation,
1157 (PVOID)KeyValuePartialInfo, Length, &ResLength);
1158 if(!NT_SUCCESS(Status) || (KeyValuePartialInfo->Type != REG_SZ))
1159 {
1160 ZwClose(KeyHandle);
1161 ExFreePool(KeyValuePartialInfo);
1162 return 0;
1163 }
1164
1165 Tile.Length = KeyValuePartialInfo->DataLength;
1166 Tile.MaximumLength = KeyValuePartialInfo->DataLength;
1167 Tile.Buffer = (PWSTR)KeyValuePartialInfo->Data;
1168
1169 Status = RtlUnicodeStringToInteger(&Tile, 0, &TileNum);
1170 if(!NT_SUCCESS(Status))
1171 {
1172 TileNum = 0;
1173 }
1174 ExFreePool(KeyValuePartialInfo);
1175
1176 /* start over again and look for the style*/
1177 ResLength = 0;
1178 Status = ZwQueryValueKey(KeyHandle, &Style, KeyValuePartialInformation,
1179 0, 0, &ResLength);
1180
1181 ResLength += sizeof(KEY_VALUE_PARTIAL_INFORMATION);
1182 KeyValuePartialInfo = ExAllocatePoolWithTag(PagedPool, ResLength, TAG_STRING);
1183 Length = ResLength;
1184
1185 if(!KeyValuePartialInfo)
1186 {
1187 ZwClose(KeyHandle);
1188 return 0;
1189 }
1190
1191 Status = ZwQueryValueKey(KeyHandle, &Style, KeyValuePartialInformation,
1192 (PVOID)KeyValuePartialInfo, Length, &ResLength);
1193 if(!NT_SUCCESS(Status) || (KeyValuePartialInfo->Type != REG_SZ))
1194 {
1195 ZwClose(KeyHandle);
1196 ExFreePool(KeyValuePartialInfo);
1197 return 0;
1198 }
1199
1200 Style.Length = KeyValuePartialInfo->DataLength;
1201 Style.MaximumLength = KeyValuePartialInfo->DataLength;
1202 Style.Buffer = (PWSTR)KeyValuePartialInfo->Data;
1203
1204 Status = RtlUnicodeStringToInteger(&Style, 0, &StyleNum);
1205 if(!NT_SUCCESS(Status))
1206 {
1207 StyleNum = 0;
1208 }
1209 ExFreePool(KeyValuePartialInfo);
1210
1211 /* Check the values we found in the registry */
1212 if(TileNum && !StyleNum)
1213 {
1214 WinStaObject->WallpaperMode = wmTile;
1215 }
1216 else if(!TileNum && StyleNum == 2)
1217 {
1218 WinStaObject->WallpaperMode = wmStretch;
1219 }
1220
1221 ZwClose(KeyHandle);
1222 break;
1223 }
1224 case SPI_GETDESKWALLPAPER:
1225 /* This function expects different parameters than the user mode version!
1226
1227 We basically return the current wallpaper handle - if any. The user
1228 mode version should load the string from the registry and return it
1229 without calling this function */
1230 ASSERT(pvParam);
1231 *(HBITMAP*)pvParam = (HBITMAP)WinStaObject->hbmWallpaper;
1232 break;
1233 }
1234
1235 /* FIXME save the value to the registry */
1236
1237 ObDereferenceObject(WinStaObject);
1238 return TRUE;
1239 }
1240 case SPI_SETWORKAREA:
1241 {
1242 RECT *rc;
1243 PDESKTOP_OBJECT Desktop = PsGetCurrentThreadWin32Thread()->Desktop;
1244
1245 if(!Desktop)
1246 {
1247 /* FIXME - Set last error */
1248 return FALSE;
1249 }
1250
1251 ASSERT(pvParam);
1252 rc = (RECT*)pvParam;
1253 Desktop->WorkArea = *rc;
1254
1255 return TRUE;
1256 }
1257 case SPI_GETWORKAREA:
1258 {
1259 PDESKTOP_OBJECT Desktop = PsGetCurrentThreadWin32Thread()->Desktop;
1260
1261 if(!Desktop)
1262 {
1263 /* FIXME - Set last error */
1264 return FALSE;
1265 }
1266
1267 ASSERT(pvParam);
1268 IntGetDesktopWorkArea(Desktop, (PRECT)pvParam);
1269
1270 return TRUE;
1271 }
1272 case SPI_SETGRADIENTCAPTIONS:
1273 {
1274 GradientCaptions = (pvParam != NULL);
1275 /* FIXME - should be checked if the color depth is higher than 8bpp? */
1276 return TRUE;
1277 }
1278 case SPI_GETGRADIENTCAPTIONS:
1279 {
1280 HDC hDC;
1281 BOOL Ret = GradientCaptions;
1282
1283 hDC = IntGetScreenDC();
1284 if(hDC)
1285 {
1286 Ret = (NtGdiGetDeviceCaps(hDC, BITSPIXEL) > 8) && Ret;
1287
1288 ASSERT(pvParam);
1289 *((PBOOL)pvParam) = Ret;
1290 return TRUE;
1291 }
1292 return FALSE;
1293 }
1294 case SPI_SETFONTSMOOTHING:
1295 {
1296 IntEnableFontRendering(uiParam != 0);
1297 return TRUE;
1298 }
1299 case SPI_GETFONTSMOOTHING:
1300 {
1301 ASSERT(pvParam);
1302 *((BOOL*)pvParam) = IntIsFontRenderingEnabled();
1303 return TRUE;
1304 }
1305 case SPI_GETICONTITLELOGFONT:
1306 {
1307 ASSERT(pvParam);
1308 *((LOGFONTW*)pvParam) = IconFont;
1309 return TRUE;
1310 }
1311 case SPI_GETNONCLIENTMETRICS:
1312 {
1313 ASSERT(pvParam);
1314 *((NONCLIENTMETRICSW*)pvParam) = pMetrics;
1315 return TRUE;
1316 }
1317 case SPI_GETFOCUSBORDERHEIGHT:
1318 {
1319 ASSERT(pvParam);
1320 *((UINT*)pvParam) = FocusBorderHeight;
1321 return TRUE;
1322 }
1323 case SPI_GETFOCUSBORDERWIDTH:
1324 {
1325 ASSERT(pvParam);
1326 *((UINT*)pvParam) = FocusBorderWidth;
1327 return TRUE;
1328 }
1329 case SPI_SETFOCUSBORDERHEIGHT:
1330 {
1331 FocusBorderHeight = (UINT)pvParam;
1332 return TRUE;
1333 }
1334 case SPI_SETFOCUSBORDERWIDTH:
1335 {
1336 FocusBorderWidth = (UINT)pvParam;
1337 return TRUE;
1338 }
1339
1340 default:
1341 {
1342 DPRINT1("SystemParametersInfo: Unsupported Action 0x%x (uiParam: 0x%x, pvParam: 0x%x, fWinIni: 0x%x)\n",
1343 uiAction, uiParam, pvParam, fWinIni);
1344 return FALSE;
1345 }
1346 }
1347 return FALSE;
1348 }
1349
1350 /*
1351 * @implemented
1352 */
1353 BOOL FASTCALL
1354 UserSystemParametersInfo(
1355 UINT uiAction,
1356 UINT uiParam,
1357 PVOID pvParam,
1358 UINT fWinIni)
1359 {
1360 NTSTATUS Status;
1361
1362 switch(uiAction)
1363 {
1364 case SPI_SETDOUBLECLKWIDTH:
1365 case SPI_SETDOUBLECLKHEIGHT:
1366 case SPI_SETDOUBLECLICKTIME:
1367 case SPI_SETGRADIENTCAPTIONS:
1368 case SPI_SETFONTSMOOTHING:
1369 case SPI_SETFOCUSBORDERHEIGHT:
1370 case SPI_SETFOCUSBORDERWIDTH:
1371 {
1372 return (DWORD)IntSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni);
1373 }
1374 case SPI_SETWORKAREA:
1375 {
1376 RECT rc;
1377 Status = MmCopyFromCaller(&rc, (PRECT)pvParam, sizeof(RECT));
1378 if(!NT_SUCCESS(Status))
1379 {
1380 SetLastNtError(Status);
1381 return( FALSE);
1382 }
1383 return( (DWORD)IntSystemParametersInfo(uiAction, uiParam, &rc, fWinIni));
1384 }
1385 case SPI_GETWORKAREA:
1386 {
1387 RECT rc;
1388
1389 if(!IntSystemParametersInfo(uiAction, uiParam, &rc, fWinIni))
1390 {
1391 return( FALSE);
1392 }
1393
1394 Status = MmCopyToCaller((PRECT)pvParam, &rc, sizeof(RECT));
1395 if(!NT_SUCCESS(Status))
1396 {
1397 SetLastNtError(Status);
1398 return( FALSE);
1399 }
1400 return( TRUE);
1401 }
1402 case SPI_GETFONTSMOOTHING:
1403 case SPI_GETGRADIENTCAPTIONS:
1404 case SPI_GETFOCUSBORDERHEIGHT:
1405 case SPI_GETFOCUSBORDERWIDTH:
1406 case SPI_GETWHEELSCROLLLINES:
1407 case SPI_GETWHEELSCROLLCHARS:
1408 case SPI_GETSCREENSAVERRUNNING:
1409 case SPI_SETSCREENSAVERRUNNING:
1410 case SPI_GETSCREENSAVETIMEOUT:
1411 case SPI_SETSCREENSAVETIMEOUT:
1412 case SPI_GETFLATMENU:
1413 case SPI_SETFLATMENU:
1414 {
1415 BOOL Ret;
1416
1417 if(!IntSystemParametersInfo(uiAction, uiParam, &Ret, fWinIni))
1418 {
1419 return( FALSE);
1420 }
1421
1422 Status = MmCopyToCaller(pvParam, &Ret, sizeof(BOOL));
1423 if(!NT_SUCCESS(Status))
1424 {
1425 SetLastNtError(Status);
1426 return( FALSE);
1427 }
1428 return( TRUE);
1429 }
1430 case SPI_SETDESKWALLPAPER:
1431 {
1432 /* !!! As opposed to the user mode version this version accepts a handle
1433 to the bitmap! */
1434 HBITMAP hbmWallpaper;
1435
1436 Status = MmCopyFromCaller(&hbmWallpaper, pvParam, sizeof(HBITMAP));
1437 if(!NT_SUCCESS(Status))
1438 {
1439 SetLastNtError(Status);
1440 return( FALSE);
1441 }
1442 return( IntSystemParametersInfo(SPI_SETDESKWALLPAPER, 0, &hbmWallpaper, fWinIni));
1443 }
1444 case SPI_GETDESKWALLPAPER:
1445 {
1446 /* !!! As opposed to the user mode version this version returns a handle
1447 to the bitmap! */
1448 HBITMAP hbmWallpaper;
1449 BOOL Ret;
1450
1451 Ret = IntSystemParametersInfo(SPI_GETDESKWALLPAPER, 0, &hbmWallpaper, fWinIni);
1452
1453 Status = MmCopyToCaller(pvParam, &hbmWallpaper, sizeof(HBITMAP));
1454 if(!NT_SUCCESS(Status))
1455 {
1456 SetLastNtError(Status);
1457 return( FALSE);
1458 }
1459 return( Ret);
1460 }
1461 case SPI_GETICONTITLELOGFONT:
1462 {
1463 LOGFONTW IconFont;
1464
1465 if(!IntSystemParametersInfo(uiAction, uiParam, &IconFont, fWinIni))
1466 {
1467 return( FALSE);
1468 }
1469
1470 Status = MmCopyToCaller(pvParam, &IconFont, sizeof(LOGFONTW));
1471 if(!NT_SUCCESS(Status))
1472 {
1473 SetLastNtError(Status);
1474 return( FALSE);
1475 }
1476 return( TRUE);
1477 }
1478 case SPI_GETNONCLIENTMETRICS:
1479 {
1480 NONCLIENTMETRICSW metrics;
1481
1482 Status = MmCopyFromCaller(&metrics.cbSize, pvParam, sizeof(UINT));
1483 if(!NT_SUCCESS(Status))
1484 {
1485 SetLastNtError(Status);
1486 return( FALSE);
1487 }
1488 if(metrics.cbSize != sizeof(NONCLIENTMETRICSW))
1489 {
1490 SetLastWin32Error(ERROR_INVALID_PARAMETER);
1491 return( FALSE);
1492 }
1493
1494 if(!IntSystemParametersInfo(uiAction, uiParam, &metrics, fWinIni))
1495 {
1496 return( FALSE);
1497 }
1498
1499 Status = MmCopyToCaller(pvParam, &metrics.cbSize, sizeof(NONCLIENTMETRICSW));
1500 if(!NT_SUCCESS(Status))
1501 {
1502 SetLastNtError(Status);
1503 return( FALSE);
1504 }
1505 return( TRUE);
1506 }
1507 default :
1508 {
1509 DPRINT1("UserSystemParametersInfo : uiAction = %x \n",uiAction );
1510 break;
1511 }
1512 }
1513 return( FALSE);
1514 }
1515
1516
1517
1518
1519 /*
1520 * @implemented
1521 */
1522 BOOL
1523 STDCALL
1524 NtUserSystemParametersInfo(
1525 UINT uiAction,
1526 UINT uiParam,
1527 PVOID pvParam,
1528 UINT fWinIni)
1529 {
1530 DECLARE_RETURN(BOOLEAN);
1531
1532 DPRINT("Enter NtUserSystemParametersInfo\n");
1533 UserEnterExclusive();
1534
1535 RETURN( UserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni));
1536
1537 CLEANUP:
1538 DPRINT("Leave NtUserSystemParametersInfo, ret=%i\n",_ret_);
1539 UserLeave();
1540 END_CLEANUP;
1541 }
1542
1543
1544
1545 UINT
1546 STDCALL
1547 NtUserGetDoubleClickTime(VOID)
1548 {
1549 UINT Result;
1550 NTSTATUS Status;
1551 PWINSTATION_OBJECT WinStaObject;
1552 PSYSTEM_CURSORINFO CurInfo;
1553 DECLARE_RETURN(UINT);
1554
1555 DPRINT("Enter NtUserGetDoubleClickTime\n");
1556 UserEnterShared();
1557
1558 Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
1559 KernelMode,
1560 0,
1561 &WinStaObject);
1562 if (!NT_SUCCESS(Status))
1563 RETURN( (DWORD)FALSE);
1564
1565 CurInfo = IntGetSysCursorInfo(WinStaObject);
1566 Result = CurInfo->DblClickSpeed;
1567
1568 ObDereferenceObject(WinStaObject);
1569 RETURN( Result);
1570
1571 CLEANUP:
1572 DPRINT("Leave NtUserGetDoubleClickTime, ret=%i\n",_ret_);
1573 UserLeave();
1574 END_CLEANUP;
1575 }
1576
1577 BOOL
1578 STDCALL
1579 NtUserGetGUIThreadInfo(
1580 DWORD idThread, /* if NULL use foreground thread */
1581 LPGUITHREADINFO lpgui)
1582 {
1583 NTSTATUS Status;
1584 PTHRDCARETINFO CaretInfo;
1585 GUITHREADINFO SafeGui;
1586 PDESKTOP_OBJECT Desktop;
1587 PUSER_MESSAGE_QUEUE MsgQueue;
1588 PETHREAD Thread = NULL;
1589 DECLARE_RETURN(BOOLEAN);
1590
1591 DPRINT("Enter NtUserGetGUIThreadInfo\n");
1592 UserEnterShared();
1593
1594 Status = MmCopyFromCaller(&SafeGui, lpgui, sizeof(DWORD));
1595 if(!NT_SUCCESS(Status))
1596 {
1597 SetLastNtError(Status);
1598 RETURN( FALSE);
1599 }
1600
1601 if(SafeGui.cbSize != sizeof(GUITHREADINFO))
1602 {
1603 SetLastWin32Error(ERROR_INVALID_PARAMETER);
1604 RETURN( FALSE);
1605 }
1606
1607 if(idThread)
1608 {
1609 Status = PsLookupThreadByThreadId((HANDLE)idThread, &Thread);
1610 if(!NT_SUCCESS(Status))
1611 {
1612 SetLastWin32Error(ERROR_ACCESS_DENIED);
1613 RETURN( FALSE);
1614 }
1615 Desktop = ((PW32THREAD)Thread->Tcb.Win32Thread)->Desktop;
1616 }
1617 else
1618 {
1619 /* get the foreground thread */
1620 PW32THREAD W32Thread = (PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread;
1621 Desktop = W32Thread->Desktop;
1622 if(Desktop)
1623 {
1624 MsgQueue = Desktop->ActiveMessageQueue;
1625 if(MsgQueue)
1626 {
1627 Thread = MsgQueue->Thread;
1628 }
1629 }
1630 }
1631
1632 if(!Thread || !Desktop)
1633 {
1634 if(idThread && Thread)
1635 ObDereferenceObject(Thread);
1636 SetLastWin32Error(ERROR_ACCESS_DENIED);
1637 RETURN( FALSE);
1638 }
1639
1640 MsgQueue = (PUSER_MESSAGE_QUEUE)Desktop->ActiveMessageQueue;
1641 CaretInfo = MsgQueue->CaretInfo;
1642
1643 SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0);
1644 if(MsgQueue->MenuOwner)
1645 SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState;
1646 if(MsgQueue->MoveSize)
1647 SafeGui.flags |= GUI_INMOVESIZE;
1648
1649 /* FIXME add flag GUI_16BITTASK */
1650
1651 SafeGui.hwndActive = MsgQueue->ActiveWindow;
1652 SafeGui.hwndFocus = MsgQueue->FocusWindow;
1653 SafeGui.hwndCapture = MsgQueue->CaptureWindow;
1654 SafeGui.hwndMenuOwner = MsgQueue->MenuOwner;
1655 SafeGui.hwndMoveSize = MsgQueue->MoveSize;
1656 SafeGui.hwndCaret = CaretInfo->hWnd;
1657
1658 SafeGui.rcCaret.left = CaretInfo->Pos.x;
1659 SafeGui.rcCaret.top = CaretInfo->Pos.y;
1660 SafeGui.rcCaret.right = SafeGui.rcCaret.left + CaretInfo->Size.cx;
1661 SafeGui.rcCaret.bottom = SafeGui.rcCaret.top + CaretInfo->Size.cy;
1662
1663 if(idThread)
1664 ObDereferenceObject(Thread);
1665
1666 Status = MmCopyToCaller(lpgui, &SafeGui, sizeof(GUITHREADINFO));
1667 if(!NT_SUCCESS(Status))
1668 {
1669 SetLastNtError(Status);
1670 RETURN( FALSE);
1671 }
1672
1673 RETURN( TRUE);
1674
1675 CLEANUP:
1676 DPRINT("Leave NtUserGetGUIThreadInfo, ret=%i\n",_ret_);
1677 UserLeave();
1678 END_CLEANUP;
1679 }
1680
1681
1682 DWORD
1683 STDCALL
1684 NtUserGetGuiResources(
1685 HANDLE hProcess,
1686 DWORD uiFlags)
1687 {
1688 PEPROCESS Process;
1689 PW32PROCESS W32Process;
1690 NTSTATUS Status;
1691 DWORD Ret = 0;
1692 DECLARE_RETURN(DWORD);
1693
1694 DPRINT("Enter NtUserGetGuiResources\n");
1695 UserEnterShared();
1696
1697 Status = ObReferenceObjectByHandle(hProcess,
1698 PROCESS_QUERY_INFORMATION,
1699 PsProcessType,
1700 ExGetPreviousMode(),
1701 (PVOID*)&Process,
1702 NULL);
1703
1704 if(!NT_SUCCESS(Status))
1705 {
1706 SetLastNtError(Status);
1707 RETURN( 0);
1708 }
1709
1710 W32Process = (PW32PROCESS)Process->Win32Process;
1711 if(!W32Process)
1712 {
1713 ObDereferenceObject(Process);
1714 SetLastWin32Error(ERROR_INVALID_PARAMETER);
1715 RETURN( 0);
1716 }
1717
1718 switch(uiFlags)
1719 {
1720 case GR_GDIOBJECTS:
1721 {
1722 Ret = (DWORD)W32Process->GDIObjects;
1723 break;
1724 }
1725 case GR_USEROBJECTS:
1726 {
1727 Ret = (DWORD)W32Process->UserObjects;
1728 break;
1729 }
1730 default:
1731 {
1732 SetLastWin32Error(ERROR_INVALID_PARAMETER);
1733 break;
1734 }
1735 }
1736
1737 ObDereferenceObject(Process);
1738
1739 RETURN( Ret);
1740
1741 CLEANUP:
1742 DPRINT("Leave NtUserGetGuiResources, ret=%i\n",_ret_);
1743 UserLeave();
1744 END_CLEANUP;
1745 }
1746
1747 NTSTATUS FASTCALL
1748 IntSafeCopyUnicodeString(PUNICODE_STRING Dest,
1749 PUNICODE_STRING Source)
1750 {
1751 NTSTATUS Status;
1752 PWSTR Src;
1753
1754 Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING));
1755 if(!NT_SUCCESS(Status))
1756 {
1757 return Status;
1758 }
1759
1760 if(Dest->Length > 0x4000)
1761 {
1762 return STATUS_UNSUCCESSFUL;
1763 }
1764
1765 Src = Dest->Buffer;
1766 Dest->Buffer = NULL;
1767
1768 if(Dest->Length > 0 && Src)
1769 {
1770 Dest->MaximumLength = Dest->Length;
1771 Dest->Buffer = ExAllocatePoolWithTag(PagedPool, Dest->MaximumLength, TAG_STRING);
1772 if(!Dest->Buffer)
1773 {
1774 return STATUS_NO_MEMORY;
1775 }
1776
1777 Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->Length);
1778 if(!NT_SUCCESS(Status))
1779 {
1780 ExFreePool(Dest->Buffer);
1781 Dest->Buffer = NULL;
1782 return Status;
1783 }
1784
1785
1786 return STATUS_SUCCESS;
1787 }
1788
1789 /* string is empty */
1790 return STATUS_SUCCESS;
1791 }
1792
1793 NTSTATUS FASTCALL
1794 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest,
1795 PUNICODE_STRING Source)
1796 {
1797 NTSTATUS Status;
1798 PWSTR Src;
1799
1800 Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING));
1801 if(!NT_SUCCESS(Status))
1802 {
1803 return Status;
1804 }
1805
1806 if(Dest->Length > 0x4000)
1807 {
1808 return STATUS_UNSUCCESSFUL;
1809 }
1810
1811 Src = Dest->Buffer;
1812 Dest->Buffer = NULL;
1813
1814 if(Dest->Length > 0 && Src)
1815 {
1816 Dest->MaximumLength = Dest->Length + sizeof(WCHAR);
1817 Dest->Buffer = ExAllocatePoolWithTag(PagedPool, Dest->MaximumLength, TAG_STRING);
1818 if(!Dest->Buffer)
1819 {
1820 return STATUS_NO_MEMORY;
1821 }
1822
1823 Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->Length);
1824 if(!NT_SUCCESS(Status))
1825 {
1826 ExFreePool(Dest->Buffer);
1827 Dest->Buffer = NULL;
1828 return Status;
1829 }
1830
1831 /* make sure the string is null-terminated */
1832 Src = (PWSTR)((PBYTE)Dest->Buffer + Dest->Length);
1833 *Src = L'\0';
1834
1835 return STATUS_SUCCESS;
1836 }
1837
1838 /* string is empty */
1839 return STATUS_SUCCESS;
1840 }
1841
1842 NTSTATUS FASTCALL
1843 IntUnicodeStringToNULLTerminated(PWSTR *Dest, PUNICODE_STRING Src)
1844 {
1845 if (Src->Length + sizeof(WCHAR) <= Src->MaximumLength
1846 && L'\0' == Src->Buffer[Src->Length / sizeof(WCHAR)])
1847 {
1848 /* The unicode_string is already nul terminated. Just reuse it. */
1849 *Dest = Src->Buffer;
1850 return STATUS_SUCCESS;
1851 }
1852
1853 *Dest = ExAllocatePoolWithTag(PagedPool, Src->Length + sizeof(WCHAR), TAG_STRING);
1854 if (NULL == *Dest)
1855 {
1856 return STATUS_NO_MEMORY;
1857 }
1858 RtlCopyMemory(*Dest, Src->Buffer, Src->Length);
1859 (*Dest)[Src->Length / 2] = L'\0';
1860
1861 return STATUS_SUCCESS;
1862 }
1863
1864 void FASTCALL
1865 IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated, PUNICODE_STRING UnicodeString)
1866 {
1867 if (NullTerminated != UnicodeString->Buffer)
1868 {
1869 ExFreePool(NullTerminated);
1870 }
1871 }
1872
1873 BOOL STDCALL
1874 NtUserUpdatePerUserSystemParameters(
1875 DWORD dwReserved,
1876 BOOL bEnable)
1877 {
1878 BOOL Result = TRUE;
1879 DECLARE_RETURN(BOOLEAN);
1880
1881 DPRINT("Enter NtUserUpdatePerUserSystemParameters\n");
1882 UserEnterExclusive();
1883
1884 Result &= IntDesktopUpdatePerUserSettings(bEnable);
1885 RETURN( Result);
1886
1887 CLEANUP:
1888 DPRINT("Leave NtUserUpdatePerUserSystemParameters, ret=%i\n",_ret_);
1889 UserLeave();
1890 END_CLEANUP;
1891 }
1892
1893 PW32PROCESSINFO
1894 GetW32ProcessInfo(VOID)
1895 {
1896 PW32PROCESSINFO pi;
1897 PW32PROCESS W32Process = PsGetCurrentProcessWin32Process();
1898
1899 if (W32Process == NULL)
1900 {
1901 /* FIXME - temporary hack for system threads... */
1902 return NULL;
1903 }
1904
1905 if (W32Process->ProcessInfo == NULL)
1906 {
1907 pi = UserHeapAlloc(sizeof(W32PROCESSINFO));
1908 if (pi != NULL)
1909 {
1910 RtlZeroMemory(pi,
1911 sizeof(W32PROCESSINFO));
1912
1913 /* initialize it */
1914 pi->UserHandleTable = gHandleTable;
1915
1916 if (InterlockedCompareExchangePointer(&W32Process->ProcessInfo,
1917 pi,
1918 NULL) != NULL)
1919 {
1920 UserHeapFree(pi);
1921 }
1922 }
1923 else
1924 {
1925 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
1926 }
1927 }
1928
1929 return W32Process->ProcessInfo;
1930 }
1931
1932 PW32THREADINFO
1933 GetW32ThreadInfo(VOID)
1934 {
1935 PTEB Teb;
1936 PW32THREADINFO ti;
1937 PW32THREAD W32Thread = PsGetCurrentThreadWin32Thread();
1938
1939 if (W32Thread == NULL)
1940 {
1941 /* FIXME - temporary hack for system threads... */
1942 return NULL;
1943 }
1944
1945 /* allocate a W32THREAD structure if neccessary */
1946 if (W32Thread->ThreadInfo == NULL)
1947 {
1948 ti = UserHeapAlloc(sizeof(W32THREADINFO));
1949 if (ti != NULL)
1950 {
1951 RtlZeroMemory(ti,
1952 sizeof(W32THREADINFO));
1953
1954 /* initialize it */
1955 ti->kpi = GetW32ProcessInfo();
1956 ti->pi = UserHeapAddressToUser(ti->kpi);
1957 if (W32Thread->Desktop != NULL)
1958 {
1959 ti->Desktop = W32Thread->Desktop->DesktopInfo;
1960 ti->DesktopHeapDelta = DesktopHeapGetUserDelta();
1961 }
1962 else
1963 {
1964 ti->Desktop = NULL;
1965 ti->DesktopHeapDelta = 0;
1966 }
1967
1968 W32Thread->ThreadInfo = ti;
1969 /* update the TEB */
1970 Teb = NtCurrentTeb();
1971 _SEH_TRY
1972 {
1973 ProbeForWrite(Teb,
1974 sizeof(TEB),
1975 sizeof(ULONG));
1976
1977 Teb->Win32ThreadInfo = UserHeapAddressToUser(W32Thread->ThreadInfo);
1978 }
1979 _SEH_HANDLE
1980 {
1981 SetLastNtError(_SEH_GetExceptionCode());
1982 }
1983 _SEH_END;
1984 }
1985 else
1986 {
1987 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
1988 }
1989 }
1990
1991 return W32Thread->ThreadInfo;
1992 }
1993
1994
1995 /* EOF */