28ff45fb88023ad3b12d297a7b05199b8308e355
[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 = ((PW32THREAD)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_SETWNDCONTEXTHLPID:
514
515 if(!(Window = UserGetWindowObject((HWND)Param1)))
516 {
517 RETURN( (DWORD)FALSE);
518 }
519
520 Window->ContextHelpId = Param2;
521
522 RETURN( (DWORD)TRUE);
523
524 case TWOPARAM_ROUTINE_SETCARETPOS:
525 RETURN( (DWORD)co_IntSetCaretPos((int)Param1, (int)Param2));
526
527 case TWOPARAM_ROUTINE_GETWINDOWINFO:
528 {
529 WINDOWINFO wi;
530 DWORD Ret;
531
532 if(!(Window = UserGetWindowObject((HWND)Param1)))
533 {
534 RETURN( FALSE);
535 }
536
537 #if 0
538 /*
539 * According to WINE, Windows' doesn't check the cbSize field
540 */
541
542 Status = MmCopyFromCaller(&wi.cbSize, (PVOID)Param2, sizeof(wi.cbSize));
543 if(!NT_SUCCESS(Status))
544 {
545 SetLastNtError(Status);
546 RETURN( FALSE);
547 }
548
549 if(wi.cbSize != sizeof(WINDOWINFO))
550 {
551 SetLastWin32Error(ERROR_INVALID_PARAMETER);
552 RETURN( FALSE);
553 }
554 #endif
555
556 if((Ret = (DWORD)IntGetWindowInfo(Window, &wi)))
557 {
558 Status = MmCopyToCaller((PVOID)Param2, &wi, sizeof(WINDOWINFO));
559 if(!NT_SUCCESS(Status))
560 {
561 SetLastNtError(Status);
562 RETURN( FALSE);
563 }
564 }
565
566 RETURN( Ret);
567 }
568
569 case TWOPARAM_ROUTINE_REGISTERLOGONPROC:
570 RETURN( (DWORD)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2));
571
572 case TWOPARAM_ROUTINE_SETSYSCOLORS:
573 {
574 DWORD Ret = 0;
575 PVOID Buffer;
576 struct
577 {
578 INT *Elements;
579 COLORREF *Colors;
580 }
581 ChangeSysColors;
582
583 /* FIXME - we should make use of SEH here... */
584
585 Status = MmCopyFromCaller(&ChangeSysColors, (PVOID)Param1, sizeof(ChangeSysColors));
586 if(!NT_SUCCESS(Status))
587 {
588 SetLastNtError(Status);
589 RETURN( 0);
590 }
591
592 Buffer = ExAllocatePool(PagedPool, (Param2 * sizeof(INT)) + (Param2 * sizeof(COLORREF)));
593 if(Buffer != NULL)
594 {
595 INT *Elements = (INT*)Buffer;
596 COLORREF *Colors = (COLORREF*)Buffer + Param2;
597
598 Status = MmCopyFromCaller(Elements, ChangeSysColors.Elements, Param2 * sizeof(INT));
599 if(NT_SUCCESS(Status))
600 {
601 Status = MmCopyFromCaller(Colors, ChangeSysColors.Colors, Param2 * sizeof(COLORREF));
602 if(NT_SUCCESS(Status))
603 {
604 Ret = (DWORD)IntSetSysColors((UINT)Param2, Elements, Colors);
605 }
606 else
607 SetLastNtError(Status);
608 }
609 else
610 SetLastNtError(Status);
611
612 ExFreePool(Buffer);
613 }
614
615
616 RETURN( Ret);
617 }
618
619 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES:
620 case TWOPARAM_ROUTINE_GETSYSCOLORPENS:
621 case TWOPARAM_ROUTINE_GETSYSCOLORS:
622 {
623 DWORD Ret = 0;
624 union
625 {
626 PVOID Pointer;
627 HBRUSH *Brushes;
628 HPEN *Pens;
629 COLORREF *Colors;
630 } Buffer;
631
632 /* FIXME - we should make use of SEH here... */
633
634 Buffer.Pointer = ExAllocatePool(PagedPool, Param2 * sizeof(HANDLE));
635 if(Buffer.Pointer != NULL)
636 {
637 switch(Routine)
638 {
639 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES:
640 Ret = (DWORD)IntGetSysColorBrushes(Buffer.Brushes, (UINT)Param2);
641 break;
642 case TWOPARAM_ROUTINE_GETSYSCOLORPENS:
643 Ret = (DWORD)IntGetSysColorPens(Buffer.Pens, (UINT)Param2);
644 break;
645 case TWOPARAM_ROUTINE_GETSYSCOLORS:
646 Ret = (DWORD)IntGetSysColors(Buffer.Colors, (UINT)Param2);
647 break;
648 default:
649 Ret = 0;
650 break;
651 }
652
653 if(Ret > 0)
654 {
655 Status = MmCopyToCaller((PVOID)Param1, Buffer.Pointer, Param2 * sizeof(HANDLE));
656 if(!NT_SUCCESS(Status))
657 {
658 SetLastNtError(Status);
659 Ret = 0;
660 }
661 }
662
663 ExFreePool(Buffer.Pointer);
664 }
665 RETURN( Ret);
666 }
667
668 }
669 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
670 Routine, Param1, Param2);
671 SetLastWin32Error(ERROR_INVALID_PARAMETER);
672 RETURN( 0);
673
674 CLEANUP:
675 DPRINT("Leave NtUserCallTwoParam, ret=%i\n",_ret_);
676 UserLeave();
677 END_CLEANUP;
678 }
679
680
681 /*
682 * @unimplemented
683 */
684 BOOL
685 STDCALL
686 NtUserCallHwndLock(
687 HWND hWnd,
688 DWORD Routine)
689 {
690 BOOL Ret = 0;
691 PWINDOW_OBJECT Window;
692 USER_REFERENCE_ENTRY Ref;
693 DECLARE_RETURN(BOOLEAN);
694
695 DPRINT("Enter NtUserCallHwndLock\n");
696 UserEnterExclusive();
697
698 if (!(Window = UserGetWindowObject(hWnd)))
699 {
700 RETURN( FALSE);
701 }
702 UserRefObjectCo(Window, &Ref);
703
704 /* FIXME: Routine can be 0x53 - 0x5E */
705 switch (Routine)
706 {
707 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS:
708 co_WinPosArrangeIconicWindows(Window);
709 break;
710
711 case HWNDLOCK_ROUTINE_DRAWMENUBAR:
712 {
713 PMENU_OBJECT Menu;
714 DPRINT("HWNDLOCK_ROUTINE_DRAWMENUBAR\n");
715 Ret = FALSE;
716 if (!((Window->Style & (WS_CHILD | WS_POPUP)) != WS_CHILD))
717 break;
718
719 if(!(Menu = UserGetMenuObject((HMENU) Window->IDMenu)))
720 break;
721
722 Menu->MenuInfo.WndOwner = hWnd;
723 Menu->MenuInfo.Height = 0;
724
725 co_WinPosSetWindowPos(Window, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
726 SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
727
728 Ret = TRUE;
729 break;
730 }
731
732 case HWNDLOCK_ROUTINE_REDRAWFRAME:
733 /* FIXME */
734 break;
735
736 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW:
737 Ret = co_IntSetForegroundWindow(Window);
738 break;
739
740 case HWNDLOCK_ROUTINE_UPDATEWINDOW:
741 /* FIXME */
742 break;
743 }
744
745 UserDerefObjectCo(Window);
746
747 RETURN( Ret);
748
749 CLEANUP:
750 DPRINT("Leave NtUserCallHwndLock, ret=%i\n",_ret_);
751 UserLeave();
752 END_CLEANUP;
753 }
754
755 /*
756 * @unimplemented
757 */
758 HWND
759 STDCALL
760 NtUserCallHwndOpt(
761 HWND Param,
762 DWORD Routine)
763 {
764 switch (Routine)
765 {
766 case HWNDOPT_ROUTINE_SETPROGMANWINDOW:
767 /*
768 * FIXME
769 * Nothing too hard...validate the hWnd and save it in the Desktop Info
770 */
771 DPRINT1("HWNDOPT_ROUTINE_SETPROGMANWINDOW UNIMPLEMENTED\n");
772 break;
773
774 case HWNDOPT_ROUTINE_SETTASKMANWINDOW:
775 /*
776 * FIXME
777 * Nothing too hard...validate the hWnd and save it in the Desktop Info
778 */
779 DPRINT1("HWNDOPT_ROUTINE_SETTASKMANWINDOW UNIMPLEMENTED\n");
780 break;
781 }
782
783 return Param;
784 }
785
786 /*
787 * @unimplemented
788 */
789 DWORD STDCALL
790 NtUserGetThreadState(
791 DWORD Routine)
792 {
793 DECLARE_RETURN(DWORD);
794
795 DPRINT("Enter NtUserGetThreadState\n");
796 UserEnterShared();
797
798 switch (Routine)
799 {
800 case 0:
801 RETURN( (DWORD)IntGetThreadFocusWindow());
802 }
803 RETURN( 0);
804
805 CLEANUP:
806 DPRINT("Leave NtUserGetThreadState, ret=%i\n",_ret_);
807 UserLeave();
808 END_CLEANUP;
809 }
810
811 VOID FASTCALL
812 IntGetFontMetricSetting(LPWSTR lpValueName, PLOGFONTW font)
813 {
814 RTL_QUERY_REGISTRY_TABLE QueryTable[2];
815 NTSTATUS Status;
816 /* Firefox 1.0.7 depends on the lfHeight value being negative */
817 static LOGFONTW DefaultFont = {
818 -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
819 0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
820 L"Bitstream Vera Sans"
821 };
822
823 RtlZeroMemory(&QueryTable, sizeof(QueryTable));
824
825 QueryTable[0].Name = lpValueName;
826 QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED;
827 QueryTable[0].EntryContext = font;
828
829 Status = RtlQueryRegistryValues(
830 RTL_REGISTRY_USER,
831 L"Control Panel\\Desktop\\WindowMetrics",
832 QueryTable,
833 NULL,
834 NULL);
835
836 if (!NT_SUCCESS(Status))
837 {
838 RtlCopyMemory(font, &DefaultFont, sizeof(LOGFONTW));
839 }
840 }
841
842 ULONG FASTCALL
843 IntSystemParametersInfo(
844 UINT uiAction,
845 UINT uiParam,
846 PVOID pvParam,
847 UINT fWinIni)
848 {
849 PWINSTATION_OBJECT WinStaObject;
850 NTSTATUS Status;
851
852 static BOOL bInitialized = FALSE;
853 static LOGFONTW IconFont;
854 static NONCLIENTMETRICSW pMetrics;
855 static BOOL GradientCaptions = TRUE;
856 static UINT FocusBorderHeight = 1;
857 static UINT FocusBorderWidth = 1;
858
859 if (!bInitialized)
860 {
861 RtlZeroMemory(&IconFont, sizeof(LOGFONTW));
862 RtlZeroMemory(&pMetrics, sizeof(NONCLIENTMETRICSW));
863
864 IntGetFontMetricSetting(L"CaptionFont", &pMetrics.lfCaptionFont);
865 IntGetFontMetricSetting(L"SmCaptionFont", &pMetrics.lfSmCaptionFont);
866 IntGetFontMetricSetting(L"MenuFont", &pMetrics.lfMenuFont);
867 IntGetFontMetricSetting(L"StatusFont", &pMetrics.lfStatusFont);
868 IntGetFontMetricSetting(L"MessageFont", &pMetrics.lfMessageFont);
869 IntGetFontMetricSetting(L"IconFont", &IconFont);
870
871 pMetrics.iBorderWidth = 1;
872 pMetrics.iScrollWidth = UserGetSystemMetrics(SM_CXVSCROLL);
873 pMetrics.iScrollHeight = UserGetSystemMetrics(SM_CYHSCROLL);
874 pMetrics.iCaptionWidth = UserGetSystemMetrics(SM_CXSIZE);
875 pMetrics.iCaptionHeight = UserGetSystemMetrics(SM_CYSIZE);
876 pMetrics.iSmCaptionWidth = UserGetSystemMetrics(SM_CXSMSIZE);
877 pMetrics.iSmCaptionHeight = UserGetSystemMetrics(SM_CYSMSIZE);
878 pMetrics.iMenuWidth = UserGetSystemMetrics(SM_CXMENUSIZE);
879 pMetrics.iMenuHeight = UserGetSystemMetrics(SM_CYMENUSIZE);
880 pMetrics.cbSize = sizeof(NONCLIENTMETRICSW);
881
882 bInitialized = TRUE;
883 }
884
885 switch(uiAction)
886 {
887 case SPI_SETDOUBLECLKWIDTH:
888 case SPI_SETDOUBLECLKHEIGHT:
889 case SPI_SETDOUBLECLICKTIME:
890 case SPI_SETDESKWALLPAPER:
891 case SPI_GETDESKWALLPAPER:
892 {
893 PSYSTEM_CURSORINFO CurInfo;
894
895 Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
896 KernelMode,
897 0,
898 &WinStaObject);
899 if(!NT_SUCCESS(Status))
900 {
901 SetLastNtError(Status);
902 return (DWORD)FALSE;
903 }
904
905 switch(uiAction)
906 {
907 case SPI_SETDOUBLECLKWIDTH:
908 CurInfo = IntGetSysCursorInfo(WinStaObject);
909 /* FIXME limit the maximum value? */
910 CurInfo->DblClickWidth = uiParam;
911 break;
912 case SPI_SETDOUBLECLKHEIGHT:
913 CurInfo = IntGetSysCursorInfo(WinStaObject);
914 /* FIXME limit the maximum value? */
915 CurInfo->DblClickHeight = uiParam;
916 break;
917 case SPI_SETDOUBLECLICKTIME:
918 CurInfo = IntGetSysCursorInfo(WinStaObject);
919 /* FIXME limit the maximum time to 1000 ms? */
920 CurInfo->DblClickSpeed = uiParam;
921 break;
922 case SPI_SETDESKWALLPAPER:
923 {
924 /* This function expects different parameters than the user mode version!
925
926 We let the user mode code load the bitmap, it passed the handle to
927 the bitmap. We'll change it's ownership to system and replace it with
928 the current wallpaper bitmap */
929 HBITMAP hOldBitmap, hNewBitmap;
930 ASSERT(pvParam);
931
932 hNewBitmap = *(HBITMAP*)pvParam;
933 if(hNewBitmap != NULL)
934 {
935 BITMAPOBJ *bmp;
936 /* try to get the size of the wallpaper */
937 if(!(bmp = BITMAPOBJ_LockBitmap(hNewBitmap)))
938 {
939 ObDereferenceObject(WinStaObject);
940 return FALSE;
941 }
942 WinStaObject->cxWallpaper = bmp->SurfObj.sizlBitmap.cx;
943 WinStaObject->cyWallpaper = bmp->SurfObj.sizlBitmap.cy;
944
945 BITMAPOBJ_UnlockBitmap(bmp);
946
947 /* change the bitmap's ownership */
948 GDIOBJ_SetOwnership(hNewBitmap, NULL);
949 }
950 hOldBitmap = (HBITMAP)InterlockedExchange((LONG*)&WinStaObject->hbmWallpaper, (LONG)hNewBitmap);
951 if(hOldBitmap != NULL)
952 {
953 /* delete the old wallpaper */
954 NtGdiDeleteObject(hOldBitmap);
955 }
956 break;
957 }
958 case SPI_GETDESKWALLPAPER:
959 /* This function expects different parameters than the user mode version!
960
961 We basically return the current wallpaper handle - if any. The user
962 mode version should load the string from the registry and return it
963 without calling this function */
964 ASSERT(pvParam);
965 *(HBITMAP*)pvParam = (HBITMAP)WinStaObject->hbmWallpaper;
966 break;
967 }
968
969 /* FIXME save the value to the registry */
970
971 ObDereferenceObject(WinStaObject);
972 return TRUE;
973 }
974 case SPI_SETWORKAREA:
975 {
976 RECT *rc;
977 PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
978
979 if(!Desktop)
980 {
981 /* FIXME - Set last error */
982 return FALSE;
983 }
984
985 ASSERT(pvParam);
986 rc = (RECT*)pvParam;
987 Desktop->WorkArea = *rc;
988
989 return TRUE;
990 }
991 case SPI_GETWORKAREA:
992 {
993 PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
994
995 if(!Desktop)
996 {
997 /* FIXME - Set last error */
998 return FALSE;
999 }
1000
1001 ASSERT(pvParam);
1002 IntGetDesktopWorkArea(Desktop, (PRECT)pvParam);
1003
1004 return TRUE;
1005 }
1006 case SPI_SETGRADIENTCAPTIONS:
1007 {
1008 GradientCaptions = (pvParam != NULL);
1009 /* FIXME - should be checked if the color depth is higher than 8bpp? */
1010 return TRUE;
1011 }
1012 case SPI_GETGRADIENTCAPTIONS:
1013 {
1014 HDC hDC;
1015 BOOL Ret = GradientCaptions;
1016
1017 hDC = IntGetScreenDC();
1018 if(hDC)
1019 {
1020 Ret = (NtGdiGetDeviceCaps(hDC, BITSPIXEL) > 8) && Ret;
1021
1022 ASSERT(pvParam);
1023 *((PBOOL)pvParam) = Ret;
1024 return TRUE;
1025 }
1026 return FALSE;
1027 }
1028 case SPI_SETFONTSMOOTHING:
1029 {
1030 IntEnableFontRendering(uiParam != 0);
1031 return TRUE;
1032 }
1033 case SPI_GETFONTSMOOTHING:
1034 {
1035 ASSERT(pvParam);
1036 *((BOOL*)pvParam) = IntIsFontRenderingEnabled();
1037 return TRUE;
1038 }
1039 case SPI_GETICONTITLELOGFONT:
1040 {
1041 ASSERT(pvParam);
1042 *((LOGFONTW*)pvParam) = IconFont;
1043 return TRUE;
1044 }
1045 case SPI_GETNONCLIENTMETRICS:
1046 {
1047 ASSERT(pvParam);
1048 *((NONCLIENTMETRICSW*)pvParam) = pMetrics;
1049 return TRUE;
1050 }
1051 case SPI_GETFOCUSBORDERHEIGHT:
1052 {
1053 ASSERT(pvParam);
1054 *((UINT*)pvParam) = FocusBorderHeight;
1055 return TRUE;
1056 }
1057 case SPI_GETFOCUSBORDERWIDTH:
1058 {
1059 ASSERT(pvParam);
1060 *((UINT*)pvParam) = FocusBorderWidth;
1061 return TRUE;
1062 }
1063 case SPI_SETFOCUSBORDERHEIGHT:
1064 {
1065 FocusBorderHeight = (UINT)pvParam;
1066 return TRUE;
1067 }
1068 case SPI_SETFOCUSBORDERWIDTH:
1069 {
1070 FocusBorderWidth = (UINT)pvParam;
1071 return TRUE;
1072 }
1073
1074 default:
1075 {
1076 DPRINT1("SystemParametersInfo: Unsupported Action 0x%x (uiParam: 0x%x, pvParam: 0x%x, fWinIni: 0x%x)\n",
1077 uiAction, uiParam, pvParam, fWinIni);
1078 return FALSE;
1079 }
1080 }
1081 return FALSE;
1082 }
1083
1084 /*
1085 * @implemented
1086 */
1087 BOOL FASTCALL
1088 UserSystemParametersInfo(
1089 UINT uiAction,
1090 UINT uiParam,
1091 PVOID pvParam,
1092 UINT fWinIni)
1093 {
1094 NTSTATUS Status;
1095
1096 switch(uiAction)
1097 {
1098 case SPI_SETDOUBLECLKWIDTH:
1099 case SPI_SETDOUBLECLKHEIGHT:
1100 case SPI_SETDOUBLECLICKTIME:
1101 case SPI_SETGRADIENTCAPTIONS:
1102 case SPI_SETFONTSMOOTHING:
1103 case SPI_SETFOCUSBORDERHEIGHT:
1104 case SPI_SETFOCUSBORDERWIDTH:
1105 {
1106 return (DWORD)IntSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni);
1107 }
1108 case SPI_SETWORKAREA:
1109 {
1110 RECT rc;
1111 Status = MmCopyFromCaller(&rc, (PRECT)pvParam, sizeof(RECT));
1112 if(!NT_SUCCESS(Status))
1113 {
1114 SetLastNtError(Status);
1115 return( FALSE);
1116 }
1117 return( (DWORD)IntSystemParametersInfo(uiAction, uiParam, &rc, fWinIni));
1118 }
1119 case SPI_GETWORKAREA:
1120 {
1121 RECT rc;
1122
1123 if(!IntSystemParametersInfo(uiAction, uiParam, &rc, fWinIni))
1124 {
1125 return( FALSE);
1126 }
1127
1128 Status = MmCopyToCaller((PRECT)pvParam, &rc, sizeof(RECT));
1129 if(!NT_SUCCESS(Status))
1130 {
1131 SetLastNtError(Status);
1132 return( FALSE);
1133 }
1134 return( TRUE);
1135 }
1136 case SPI_GETFONTSMOOTHING:
1137 case SPI_GETGRADIENTCAPTIONS:
1138 case SPI_GETFOCUSBORDERHEIGHT:
1139 case SPI_GETFOCUSBORDERWIDTH:
1140 {
1141 BOOL Ret;
1142
1143 if(!IntSystemParametersInfo(uiAction, uiParam, &Ret, fWinIni))
1144 {
1145 return( FALSE);
1146 }
1147
1148 Status = MmCopyToCaller(pvParam, &Ret, sizeof(BOOL));
1149 if(!NT_SUCCESS(Status))
1150 {
1151 SetLastNtError(Status);
1152 return( FALSE);
1153 }
1154 return( TRUE);
1155 }
1156 case SPI_SETDESKWALLPAPER:
1157 {
1158 /* !!! As opposed to the user mode version this version accepts a handle
1159 to the bitmap! */
1160 HBITMAP hbmWallpaper;
1161
1162 Status = MmCopyFromCaller(&hbmWallpaper, pvParam, sizeof(HBITMAP));
1163 if(!NT_SUCCESS(Status))
1164 {
1165 SetLastNtError(Status);
1166 return( FALSE);
1167 }
1168 return( IntSystemParametersInfo(SPI_SETDESKWALLPAPER, 0, &hbmWallpaper, fWinIni));
1169 }
1170 case SPI_GETDESKWALLPAPER:
1171 {
1172 /* !!! As opposed to the user mode version this version returns a handle
1173 to the bitmap! */
1174 HBITMAP hbmWallpaper;
1175 BOOL Ret;
1176
1177 Ret = IntSystemParametersInfo(SPI_GETDESKWALLPAPER, 0, &hbmWallpaper, fWinIni);
1178
1179 Status = MmCopyToCaller(pvParam, &hbmWallpaper, sizeof(HBITMAP));
1180 if(!NT_SUCCESS(Status))
1181 {
1182 SetLastNtError(Status);
1183 return( FALSE);
1184 }
1185 return( Ret);
1186 }
1187 case SPI_GETICONTITLELOGFONT:
1188 {
1189 LOGFONTW IconFont;
1190
1191 if(!IntSystemParametersInfo(uiAction, uiParam, &IconFont, fWinIni))
1192 {
1193 return( FALSE);
1194 }
1195
1196 Status = MmCopyToCaller(pvParam, &IconFont, sizeof(LOGFONTW));
1197 if(!NT_SUCCESS(Status))
1198 {
1199 SetLastNtError(Status);
1200 return( FALSE);
1201 }
1202 return( TRUE);
1203 }
1204 case SPI_GETNONCLIENTMETRICS:
1205 {
1206 NONCLIENTMETRICSW metrics;
1207
1208 Status = MmCopyFromCaller(&metrics.cbSize, pvParam, sizeof(UINT));
1209 if(!NT_SUCCESS(Status))
1210 {
1211 SetLastNtError(Status);
1212 return( FALSE);
1213 }
1214 if(metrics.cbSize != sizeof(NONCLIENTMETRICSW))
1215 {
1216 SetLastWin32Error(ERROR_INVALID_PARAMETER);
1217 return( FALSE);
1218 }
1219
1220 if(!IntSystemParametersInfo(uiAction, uiParam, &metrics, fWinIni))
1221 {
1222 return( FALSE);
1223 }
1224
1225 Status = MmCopyToCaller(pvParam, &metrics.cbSize, sizeof(NONCLIENTMETRICSW));
1226 if(!NT_SUCCESS(Status))
1227 {
1228 SetLastNtError(Status);
1229 return( FALSE);
1230 }
1231 return( TRUE);
1232 }
1233 }
1234 return( FALSE);
1235 }
1236
1237
1238
1239
1240 /*
1241 * @implemented
1242 */
1243 BOOL
1244 STDCALL
1245 NtUserSystemParametersInfo(
1246 UINT uiAction,
1247 UINT uiParam,
1248 PVOID pvParam,
1249 UINT fWinIni)
1250 {
1251 DECLARE_RETURN(BOOLEAN);
1252
1253 DPRINT("Enter NtUserSystemParametersInfo\n");
1254 UserEnterExclusive();
1255
1256 RETURN( UserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni));
1257
1258 CLEANUP:
1259 DPRINT("Leave NtUserSystemParametersInfo, ret=%i\n",_ret_);
1260 UserLeave();
1261 END_CLEANUP;
1262 }
1263
1264
1265
1266 UINT
1267 STDCALL
1268 NtUserGetDoubleClickTime(VOID)
1269 {
1270 UINT Result;
1271 NTSTATUS Status;
1272 PWINSTATION_OBJECT WinStaObject;
1273 PSYSTEM_CURSORINFO CurInfo;
1274 DECLARE_RETURN(UINT);
1275
1276 DPRINT("Enter NtUserGetDoubleClickTime\n");
1277 UserEnterShared();
1278
1279 Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
1280 KernelMode,
1281 0,
1282 &WinStaObject);
1283 if (!NT_SUCCESS(Status))
1284 RETURN( (DWORD)FALSE);
1285
1286 CurInfo = IntGetSysCursorInfo(WinStaObject);
1287 Result = CurInfo->DblClickSpeed;
1288
1289 ObDereferenceObject(WinStaObject);
1290 RETURN( Result);
1291
1292 CLEANUP:
1293 DPRINT("Leave NtUserGetDoubleClickTime, ret=%i\n",_ret_);
1294 UserLeave();
1295 END_CLEANUP;
1296 }
1297
1298 BOOL
1299 STDCALL
1300 NtUserGetGUIThreadInfo(
1301 DWORD idThread, /* if NULL use foreground thread */
1302 LPGUITHREADINFO lpgui)
1303 {
1304 NTSTATUS Status;
1305 PTHRDCARETINFO CaretInfo;
1306 GUITHREADINFO SafeGui;
1307 PDESKTOP_OBJECT Desktop;
1308 PUSER_MESSAGE_QUEUE MsgQueue;
1309 PETHREAD Thread = NULL;
1310 DECLARE_RETURN(BOOLEAN);
1311
1312 DPRINT("Enter NtUserGetGUIThreadInfo\n");
1313 UserEnterShared();
1314
1315 Status = MmCopyFromCaller(&SafeGui, lpgui, sizeof(DWORD));
1316 if(!NT_SUCCESS(Status))
1317 {
1318 SetLastNtError(Status);
1319 RETURN( FALSE);
1320 }
1321
1322 if(SafeGui.cbSize != sizeof(GUITHREADINFO))
1323 {
1324 SetLastWin32Error(ERROR_INVALID_PARAMETER);
1325 RETURN( FALSE);
1326 }
1327
1328 if(idThread)
1329 {
1330 Status = PsLookupThreadByThreadId((HANDLE)idThread, &Thread);
1331 if(!NT_SUCCESS(Status))
1332 {
1333 SetLastWin32Error(ERROR_ACCESS_DENIED);
1334 RETURN( FALSE);
1335 }
1336 Desktop = ((PW32THREAD)Thread->Tcb.Win32Thread)->Desktop;
1337 }
1338 else
1339 {
1340 /* get the foreground thread */
1341 PW32THREAD W32Thread = (PW32THREAD)PsGetCurrentThread()->Tcb.Win32Thread;
1342 Desktop = W32Thread->Desktop;
1343 if(Desktop)
1344 {
1345 MsgQueue = Desktop->ActiveMessageQueue;
1346 if(MsgQueue)
1347 {
1348 Thread = MsgQueue->Thread;
1349 }
1350 }
1351 }
1352
1353 if(!Thread || !Desktop)
1354 {
1355 if(idThread && Thread)
1356 ObDereferenceObject(Thread);
1357 SetLastWin32Error(ERROR_ACCESS_DENIED);
1358 RETURN( FALSE);
1359 }
1360
1361 MsgQueue = (PUSER_MESSAGE_QUEUE)Desktop->ActiveMessageQueue;
1362 CaretInfo = MsgQueue->CaretInfo;
1363
1364 SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0);
1365 if(MsgQueue->MenuOwner)
1366 SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState;
1367 if(MsgQueue->MoveSize)
1368 SafeGui.flags |= GUI_INMOVESIZE;
1369
1370 /* FIXME add flag GUI_16BITTASK */
1371
1372 SafeGui.hwndActive = MsgQueue->ActiveWindow;
1373 SafeGui.hwndFocus = MsgQueue->FocusWindow;
1374 SafeGui.hwndCapture = MsgQueue->CaptureWindow;
1375 SafeGui.hwndMenuOwner = MsgQueue->MenuOwner;
1376 SafeGui.hwndMoveSize = MsgQueue->MoveSize;
1377 SafeGui.hwndCaret = CaretInfo->hWnd;
1378
1379 SafeGui.rcCaret.left = CaretInfo->Pos.x;
1380 SafeGui.rcCaret.top = CaretInfo->Pos.y;
1381 SafeGui.rcCaret.right = SafeGui.rcCaret.left + CaretInfo->Size.cx;
1382 SafeGui.rcCaret.bottom = SafeGui.rcCaret.top + CaretInfo->Size.cy;
1383
1384 if(idThread)
1385 ObDereferenceObject(Thread);
1386
1387 Status = MmCopyToCaller(lpgui, &SafeGui, sizeof(GUITHREADINFO));
1388 if(!NT_SUCCESS(Status))
1389 {
1390 SetLastNtError(Status);
1391 RETURN( FALSE);
1392 }
1393
1394 RETURN( TRUE);
1395
1396 CLEANUP:
1397 DPRINT("Leave NtUserGetGUIThreadInfo, ret=%i\n",_ret_);
1398 UserLeave();
1399 END_CLEANUP;
1400 }
1401
1402
1403 DWORD
1404 STDCALL
1405 NtUserGetGuiResources(
1406 HANDLE hProcess,
1407 DWORD uiFlags)
1408 {
1409 PEPROCESS Process;
1410 PW32PROCESS W32Process;
1411 NTSTATUS Status;
1412 DWORD Ret = 0;
1413 DECLARE_RETURN(DWORD);
1414
1415 DPRINT("Enter NtUserGetGuiResources\n");
1416 UserEnterShared();
1417
1418 Status = ObReferenceObjectByHandle(hProcess,
1419 PROCESS_QUERY_INFORMATION,
1420 PsProcessType,
1421 ExGetPreviousMode(),
1422 (PVOID*)&Process,
1423 NULL);
1424
1425 if(!NT_SUCCESS(Status))
1426 {
1427 SetLastNtError(Status);
1428 RETURN( 0);
1429 }
1430
1431 W32Process = (PW32PROCESS)Process->Win32Process;
1432 if(!W32Process)
1433 {
1434 ObDereferenceObject(Process);
1435 SetLastWin32Error(ERROR_INVALID_PARAMETER);
1436 RETURN( 0);
1437 }
1438
1439 switch(uiFlags)
1440 {
1441 case GR_GDIOBJECTS:
1442 {
1443 Ret = (DWORD)W32Process->GDIObjects;
1444 break;
1445 }
1446 case GR_USEROBJECTS:
1447 {
1448 Ret = (DWORD)W32Process->UserObjects;
1449 break;
1450 }
1451 default:
1452 {
1453 SetLastWin32Error(ERROR_INVALID_PARAMETER);
1454 break;
1455 }
1456 }
1457
1458 ObDereferenceObject(Process);
1459
1460 RETURN( Ret);
1461
1462 CLEANUP:
1463 DPRINT("Leave NtUserGetGuiResources, ret=%i\n",_ret_);
1464 UserLeave();
1465 END_CLEANUP;
1466 }
1467
1468 NTSTATUS FASTCALL
1469 IntSafeCopyUnicodeString(PUNICODE_STRING Dest,
1470 PUNICODE_STRING Source)
1471 {
1472 NTSTATUS Status;
1473 PWSTR Src;
1474
1475 Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING));
1476 if(!NT_SUCCESS(Status))
1477 {
1478 return Status;
1479 }
1480
1481 if(Dest->Length > 0x4000)
1482 {
1483 return STATUS_UNSUCCESSFUL;
1484 }
1485
1486 Src = Dest->Buffer;
1487 Dest->Buffer = NULL;
1488
1489 if(Dest->Length > 0 && Src)
1490 {
1491 Dest->MaximumLength = Dest->Length;
1492 Dest->Buffer = ExAllocatePoolWithTag(PagedPool, Dest->MaximumLength, TAG_STRING);
1493 if(!Dest->Buffer)
1494 {
1495 return STATUS_NO_MEMORY;
1496 }
1497
1498 Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->Length);
1499 if(!NT_SUCCESS(Status))
1500 {
1501 ExFreePool(Dest->Buffer);
1502 Dest->Buffer = NULL;
1503 return Status;
1504 }
1505
1506
1507 return STATUS_SUCCESS;
1508 }
1509
1510 /* string is empty */
1511 return STATUS_SUCCESS;
1512 }
1513
1514 NTSTATUS FASTCALL
1515 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest,
1516 PUNICODE_STRING Source)
1517 {
1518 NTSTATUS Status;
1519 PWSTR Src;
1520
1521 Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING));
1522 if(!NT_SUCCESS(Status))
1523 {
1524 return Status;
1525 }
1526
1527 if(Dest->Length > 0x4000)
1528 {
1529 return STATUS_UNSUCCESSFUL;
1530 }
1531
1532 Src = Dest->Buffer;
1533 Dest->Buffer = NULL;
1534
1535 if(Dest->Length > 0 && Src)
1536 {
1537 Dest->MaximumLength = Dest->Length + sizeof(WCHAR);
1538 Dest->Buffer = ExAllocatePoolWithTag(PagedPool, Dest->MaximumLength, TAG_STRING);
1539 if(!Dest->Buffer)
1540 {
1541 return STATUS_NO_MEMORY;
1542 }
1543
1544 Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->Length);
1545 if(!NT_SUCCESS(Status))
1546 {
1547 ExFreePool(Dest->Buffer);
1548 Dest->Buffer = NULL;
1549 return Status;
1550 }
1551
1552 /* make sure the string is null-terminated */
1553 Src = (PWSTR)((PBYTE)Dest->Buffer + Dest->Length);
1554 *Src = L'\0';
1555
1556 return STATUS_SUCCESS;
1557 }
1558
1559 /* string is empty */
1560 return STATUS_SUCCESS;
1561 }
1562
1563 NTSTATUS FASTCALL
1564 IntUnicodeStringToNULLTerminated(PWSTR *Dest, PUNICODE_STRING Src)
1565 {
1566 if (Src->Length + sizeof(WCHAR) <= Src->MaximumLength
1567 && L'\0' == Src->Buffer[Src->Length / sizeof(WCHAR)])
1568 {
1569 /* The unicode_string is already nul terminated. Just reuse it. */
1570 *Dest = Src->Buffer;
1571 return STATUS_SUCCESS;
1572 }
1573
1574 *Dest = ExAllocatePoolWithTag(PagedPool, Src->Length + sizeof(WCHAR), TAG_STRING);
1575 if (NULL == *Dest)
1576 {
1577 return STATUS_NO_MEMORY;
1578 }
1579 RtlCopyMemory(*Dest, Src->Buffer, Src->Length);
1580 (*Dest)[Src->Length / 2] = L'\0';
1581
1582 return STATUS_SUCCESS;
1583 }
1584
1585 void FASTCALL
1586 IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated, PUNICODE_STRING UnicodeString)
1587 {
1588 if (NullTerminated != UnicodeString->Buffer)
1589 {
1590 ExFreePool(NullTerminated);
1591 }
1592 }
1593
1594 BOOL STDCALL
1595 NtUserUpdatePerUserSystemParameters(
1596 DWORD dwReserved,
1597 BOOL bEnable)
1598 {
1599 BOOL Result = TRUE;
1600 DECLARE_RETURN(BOOLEAN);
1601
1602 DPRINT("Enter NtUserUpdatePerUserSystemParameters\n");
1603 UserEnterExclusive();
1604
1605 Result &= IntDesktopUpdatePerUserSettings(bEnable);
1606 RETURN( Result);
1607
1608 CLEANUP:
1609 DPRINT("Leave NtUserUpdatePerUserSystemParameters, ret=%i\n",_ret_);
1610 UserLeave();
1611 END_CLEANUP;
1612 }
1613
1614 /* EOF */