3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * PROJECT: ReactOS user32.dll
21 * FILE: lib/user32/misc/misc.c
23 * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
28 /* INCLUDES ******************************************************************/
32 #include <wine/debug.h>
34 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
36 /* FUNCTIONS *****************************************************************/
39 * Private calls for CSRSS
43 PrivateCsrssManualGuiCheck(LONG Check
)
45 NtUserCallOneParam(Check
, ONEPARAM_ROUTINE_CSRSS_GUICHECK
);
50 PrivateCsrssInitialized(VOID
)
52 NtUserCallNoParam(NOPARAM_ROUTINE_CSRSS_INITIALIZED
);
61 RegisterLogonProcess(DWORD dwProcessId
, BOOL bRegister
)
63 return NtUserCallTwoParam(dwProcessId
,
65 TWOPARAM_ROUTINE_REGISTERLOGONPROC
);
73 SetLogonNotifyWindow (HWND Wnd
, HWINSTA WinSta
)
75 /* Maybe we should call NtUserSetLogonNotifyWindow and let that one inform CSRSS??? */
76 CSR_API_MESSAGE Request
;
80 CsrRequest
= MAKE_CSR_API(SET_LOGON_NOTIFY_WINDOW
, CSR_GUI
);
81 Request
.Data
.SetLogonNotifyWindowRequest
.LogonNotifyWindow
= Wnd
;
83 Status
= CsrClientCallServer(&Request
,
86 sizeof(CSR_API_MESSAGE
));
87 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= Request
.Status
))
89 SetLastError(RtlNtStatusToDosError(Status
));
100 UpdatePerUserSystemParameters(
104 return NtUserUpdatePerUserSystemParameters(dwReserved
, bEnable
);
108 GetW32ThreadInfo(VOID
)
112 ti
= (PW32THREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
115 /* create the W32THREADINFO structure */
116 NtUserGetThreadState(THREADSTATE_GETTHREADINFO
);
117 ti
= (PW32THREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
125 * GetUserObjectSecurity
127 * Retrieves security information for user object specified
128 * with handle 'hObject'. Descriptor returned in self-relative
132 * 1) hObject - handle to an object to retrieve information for
133 * 2) pSecurityInfo - type of information to retrieve
134 * 3) pSecurityDescriptor - buffer which receives descriptor
135 * 4) dwLength - size, in bytes, of buffer 'pSecurityDescriptor'
136 * 5) pdwLengthNeeded - reseives actual size of descriptor
140 * FALSE on failure, call GetLastError() for more information
147 GetUserObjectSecurity(
149 IN PSECURITY_INFORMATION pSecurityInfo
,
150 OUT PSECURITY_DESCRIPTOR pSecurityDescriptor
,
152 OUT PDWORD pdwLengthNeeded
159 Status
= NtQuerySecurityObject(
160 hObject
, // Object Handle
161 *pSecurityInfo
, // Security Information
162 pSecurityDescriptor
,// Security Descriptor
163 dwLength
, // Buffer Length
164 pdwLengthNeeded
// Actual Length
167 if ( ! NT_SUCCESS( Status
) ) {
168 dwWin32Error
= RtlNtStatusToDosError( Status
);
169 NtCurrentTeb()->LastErrorValue
= dwWin32Error
;
178 * SetUserObjectSecurity
180 * Sets new security descriptor to user object specified by
181 * handle 'hObject'. Descriptor must be in self-relative format.
184 * 1) hObject - handle to an object to set information for
185 * 2) pSecurityInfo - type of information to apply
186 * 3) pSecurityDescriptor - buffer which descriptor to set
190 * FALSE on failure, call GetLastError() for more information
197 SetUserObjectSecurity(
199 IN PSECURITY_INFORMATION pSecurityInfo
,
200 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
207 Status
= NtSetSecurityObject(
208 hObject
, // Object Handle
209 *pSecurityInfo
, // Security Information
210 pSecurityDescriptor
// Security Descriptor
213 if ( ! NT_SUCCESS( Status
) ) {
214 dwWin32Error
= RtlNtStatusToDosError( Status
);
215 NtCurrentTeb()->LastErrorValue
= dwWin32Error
;
232 SendMessageW(hWnd
, WM_CLOSE
, 0, 0);
237 return DestroyWindow(hWnd
);
253 PW32THREADINFO ti
= (PW32THREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
258 NtUserGetThreadState(THREADSTATE_GETTHREADINFO
);
259 if ((PW32THREADINFO
)NtCurrentTeb()->Win32ThreadInfo
) return TRUE
;
261 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
271 TestWindowProcess(PWND Wnd
)
273 if (Wnd
->head
.pti
== (PW32THREADINFO
)NtCurrentTeb()->Win32ThreadInfo
)
276 return (NtUserQueryWindow(Wnd
->head
.h
, QUERY_WINDOW_UNIQUE_PROCESS_ID
) ==
277 (DWORD
)NtCurrentTeb()->ClientId
.UniqueProcess
);
284 DWORD Type
= GetObjectType((HGDIOBJ
) hDc
);
290 case OBJ_ENHMETAFILE
:
298 GetUser32Handle(HANDLE handle
)
303 Index
= (((UINT
)handle
& 0xffff) - FIRST_USER_HANDLE
) >> 1;
305 if (Index
< 0 || Index
>= gHandleTable
->nb_handles
)
308 if (!gHandleEntries
[Index
].type
|| !gHandleEntries
[Index
].ptr
)
311 generation
= (UINT
)handle
>> 16;
313 if (generation
== gHandleEntries
[Index
].generation
|| !generation
|| generation
== 0xffff)
314 return &gHandleEntries
[Index
];
320 * Decide whether an object is located on the desktop or shared heap
322 static const BOOL g_ObjectHeapTypeShared
[VALIDATE_TYPE_EVENT
+ 1] =
324 FALSE
, /* VALIDATE_TYPE_FREE (not used) */
325 TRUE
, /* VALIDATE_TYPE_WIN */ /* FIXME: FALSE once WINDOW_OBJECT is deleted! */
326 TRUE
, /* VALIDATE_TYPE_MENU */
327 TRUE
, /* VALIDATE_TYPE_CURSOR */
328 TRUE
, /* VALIDATE_TYPE_MWPOS */
329 TRUE
, /* VALIDATE_TYPE_HOOK */
330 FALSE
, /* (not used) */
331 TRUE
, /* VALIDATE_TYPE_CALLPROC */
332 TRUE
, /* VALIDATE_TYPE_ACCEL */
333 FALSE
, /* (not used) */
334 FALSE
, /* (not used) */
335 FALSE
, /* (not used) */
336 TRUE
, /* VALIDATE_TYPE_MONITOR */
337 FALSE
, /* (not used) */
338 FALSE
, /* (not used) */
339 TRUE
/* VALIDATE_TYPE_EVENT */
343 // Validate Handle and return the pointer to the object.
347 ValidateHandle(HANDLE handle
, UINT uType
)
350 PUSER_HANDLE_ENTRY pEntry
;
352 ASSERT(uType
<= VALIDATE_TYPE_EVENT
);
354 pEntry
= GetUser32Handle(handle
);
356 if (pEntry
&& uType
== 0)
357 uType
= pEntry
->type
;
359 // Must have an entry and must be the same type!
360 if ( (!pEntry
) || (pEntry
->type
!= uType
) || !pEntry
->ptr
)
363 { // Test (with wine too) confirms these results!
364 case VALIDATE_TYPE_WIN
:
365 SetLastError(ERROR_INVALID_WINDOW_HANDLE
);
367 case VALIDATE_TYPE_MENU
:
368 SetLastError(ERROR_INVALID_MENU_HANDLE
);
370 case VALIDATE_TYPE_CURSOR
:
371 SetLastError(ERROR_INVALID_CURSOR_HANDLE
);
373 case VALIDATE_TYPE_MWPOS
:
374 SetLastError(ERROR_INVALID_DWP_HANDLE
);
376 case VALIDATE_TYPE_HOOK
:
377 SetLastError(ERROR_INVALID_HOOK_HANDLE
);
379 case VALIDATE_TYPE_ACCEL
:
380 SetLastError(ERROR_INVALID_ACCEL_HANDLE
);
383 SetLastError(ERROR_INVALID_HANDLE
);
389 if (g_ObjectHeapTypeShared
[uType
])
390 ret
= SharedPtrToUser(pEntry
->ptr
);
392 ret
= DesktopPtrToUser(pEntry
->ptr
);
398 // Validate Handle and return the pointer to the object.
402 ValidateHandleNoErr(HANDLE handle
, UINT uType
)
405 PUSER_HANDLE_ENTRY pEntry
;
407 ASSERT(uType
<= VALIDATE_TYPE_EVENT
);
409 pEntry
= GetUser32Handle(handle
);
411 if (pEntry
&& uType
== 0)
412 uType
= pEntry
->type
;
414 // Must have an entry and must be the same type!
415 if ( (!pEntry
) || (pEntry
->type
!= uType
) || !pEntry
->ptr
)
418 if (g_ObjectHeapTypeShared
[uType
])
419 ret
= SharedPtrToUser(pEntry
->ptr
);
421 ret
= DesktopPtrToUser(pEntry
->ptr
);
427 // Validate a callproc handle and return the pointer to the object.
431 ValidateCallProc(HANDLE hCallProc
)
433 PUSER_HANDLE_ENTRY pEntry
;
435 PCALLPROCDATA CallProc
= ValidateHandle(hCallProc
, VALIDATE_TYPE_CALLPROC
);
437 pEntry
= GetUser32Handle(hCallProc
);
439 if (CallProc
!= NULL
&& pEntry
->ppi
== g_ppi
)
446 // Validate a window handle and return the pointer to the object.
450 ValidateHwnd(HWND hwnd
)
453 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
454 ASSERT(ClientInfo
!= NULL
);
456 /* See if the window is cached */
457 if (hwnd
== ClientInfo
->CallbackWnd
.hWnd
)
458 return ClientInfo
->CallbackWnd
.pvWnd
;
460 Wnd
= ValidateHandle((HANDLE
)hwnd
, VALIDATE_TYPE_WIN
);
463 /* FIXME: Check if handle table entry is marked as deleting and
464 return NULL in this case! */
469 /* HACK HACK HACK! This needs to be done until WINDOW_OBJECT is completely
470 superseded by the WINDOW structure. We *ASSUME* a pointer to the WINDOW
471 structure to be at the beginning of the WINDOW_OBJECT structure!!!
473 !!! REMOVE AS SOON AS WINDOW_OBJECT NO LONGER EXISTS !!!
476 if (*((PVOID
*)Wnd
) != NULL
)
477 return DesktopPtrToUser(*((PVOID
*)Wnd
));
485 // Validate a window handle and return the pointer to the object.
489 ValidateHwndNoErr(HWND hwnd
)
492 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
493 ASSERT(ClientInfo
!= NULL
);
495 /* See if the window is cached */
496 if (hwnd
== ClientInfo
->CallbackWnd
.hWnd
)
497 return ClientInfo
->CallbackWnd
.pvWnd
;
499 Wnd
= ValidateHandleNoErr((HANDLE
)hwnd
, VALIDATE_TYPE_WIN
);
502 /* FIXME: Check if handle table entry is marked as deleting and
503 return NULL in this case! */
508 /* HACK HACK HACK! This needs to be done until WINDOW_OBJECT is completely
509 superseded by the WINDOW structure. We *ASSUME* a pointer to the WINDOW
510 structure to be at the beginning of the WINDOW_OBJECT structure!!!
512 !!! REMOVE AS SOON AS WINDOW_OBJECT NO LONGER EXISTS !!!
515 if (*((PVOID
*)Wnd
) != NULL
)
516 return DesktopPtrToUser(*((PVOID
*)Wnd
));
525 GetThreadDesktopWnd(VOID
)
527 PWND Wnd
= GetThreadDesktopInfo()->Wnd
;
529 Wnd
= DesktopPtrToUser(Wnd
);
534 // Validate a window handle and return the pointer to the object.
538 ValidateHwndOrDesk(HWND hwnd
)
540 if (hwnd
== HWND_DESKTOP
)
541 return GetThreadDesktopWnd();
543 return ValidateHwnd(hwnd
);
549 DWORD WINAPI
WCSToMBEx(WORD CodePage
,LPWSTR UnicodeString
,LONG UnicodeSize
,LPSTR
*MBString
,LONG MBSize
,BOOL Allocate
)
552 if (UnicodeSize
== -1)
554 UnicodeSize
= wcslen(UnicodeString
)+1;
562 MBSize
= UnicodeSize
* 2;
566 LPSTR SafeString
= RtlAllocateHeap(GetProcessHeap(), 0, MBSize
);
567 if (SafeString
== NULL
)
569 *MBString
= SafeString
;
573 RtlUnicodeToMultiByteN(*MBString
,MBSize
,&Size
,UnicodeString
,UnicodeSize
);
577 WideCharToMultiByte(CodePage
,0,UnicodeString
,UnicodeSize
,*MBString
,MBSize
,0,0);
585 DWORD WINAPI
MBToWCSEx(WORD CodePage
,LPSTR MBString
,LONG MBSize
,LPWSTR
*UnicodeString
,LONG UnicodeSize
,BOOL Allocate
)
590 MBSize
= strlen(MBString
)+1;
592 if (UnicodeSize
== -1)
598 UnicodeSize
= MBSize
;
602 LPWSTR SafeString
= RtlAllocateHeap(GetProcessHeap(), 0, UnicodeSize
);
603 if (SafeString
== NULL
)
605 *UnicodeString
= SafeString
;
607 UnicodeSize
*= sizeof(WCHAR
);
610 RtlMultiByteToUnicodeN(*UnicodeString
,UnicodeSize
,&Size
,MBString
,MBSize
);
614 Size
= MultiByteToWideChar(CodePage
,0,MBString
,MBSize
,*UnicodeString
,UnicodeSize
);