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