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