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 *****************************************************************/
43 RegisterLogonProcess(DWORD dwProcessId
, BOOL bRegister
)
45 return NtUserxRegisterLogonProcess(dwProcessId
,bRegister
);
53 SetLogonNotifyWindow (HWND Wnd
, HWINSTA WinSta
)
55 /* Maybe we should call NtUserSetLogonNotifyWindow and let that one inform CSRSS??? */
56 CSR_API_MESSAGE Request
;
60 CsrRequest
= MAKE_CSR_API(SET_LOGON_NOTIFY_WINDOW
, CSR_GUI
);
61 Request
.Data
.SetLogonNotifyWindowRequest
.LogonNotifyWindow
= Wnd
;
63 Status
= CsrClientCallServer(&Request
,
66 sizeof(CSR_API_MESSAGE
));
67 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= Request
.Status
))
69 SetLastError(RtlNtStatusToDosError(Status
));
73 return NtUserSetLogonNotifyWindow(Wnd
);
80 UpdatePerUserSystemParameters(
84 return NtUserUpdatePerUserSystemParameters(dwReserved
, bEnable
);
88 GetW32ThreadInfo(VOID
)
92 ti
= (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
95 /* create the THREADINFO structure */
96 NtUserGetThreadState(THREADSTATE_GETTHREADINFO
);
97 ti
= (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
105 * GetUserObjectSecurity
107 * Retrieves security information for user object specified
108 * with handle 'hObject'. Descriptor returned in self-relative
112 * 1) hObject - handle to an object to retrieve information for
113 * 2) pSecurityInfo - type of information to retrieve
114 * 3) pSecurityDescriptor - buffer which receives descriptor
115 * 4) dwLength - size, in bytes, of buffer 'pSecurityDescriptor'
116 * 5) pdwLengthNeeded - reseives actual size of descriptor
120 * FALSE on failure, call GetLastError() for more information
127 GetUserObjectSecurity(
129 IN PSECURITY_INFORMATION pSecurityInfo
,
130 OUT PSECURITY_DESCRIPTOR pSecurityDescriptor
,
132 OUT PDWORD pdwLengthNeeded
139 Status
= NtQuerySecurityObject(
140 hObject
, // Object Handle
141 *pSecurityInfo
, // Security Information
142 pSecurityDescriptor
,// Security Descriptor
143 dwLength
, // Buffer Length
144 pdwLengthNeeded
// Actual Length
147 if ( ! NT_SUCCESS( Status
) ) {
148 dwWin32Error
= RtlNtStatusToDosError( Status
);
149 NtCurrentTeb()->LastErrorValue
= dwWin32Error
;
158 * SetUserObjectSecurity
160 * Sets new security descriptor to user object specified by
161 * handle 'hObject'. Descriptor must be in self-relative format.
164 * 1) hObject - handle to an object to set information for
165 * 2) pSecurityInfo - type of information to apply
166 * 3) pSecurityDescriptor - buffer which descriptor to set
170 * FALSE on failure, call GetLastError() for more information
177 SetUserObjectSecurity(
179 IN PSECURITY_INFORMATION pSecurityInfo
,
180 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
187 Status
= NtSetSecurityObject(
188 hObject
, // Object Handle
189 *pSecurityInfo
, // Security Information
190 pSecurityDescriptor
// Security Descriptor
193 if ( ! NT_SUCCESS( Status
) ) {
194 dwWin32Error
= RtlNtStatusToDosError( Status
);
195 NtCurrentTeb()->LastErrorValue
= dwWin32Error
;
212 SendMessageW(hWnd
, WM_CLOSE
, 0, 0);
217 return DestroyWindow(hWnd
);
233 PTHREADINFO ti
= (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
238 NtUserGetThreadState(THREADSTATE_GETTHREADINFO
);
239 if ((PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
) return TRUE
;
241 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
251 TestWindowProcess(PWND Wnd
)
253 if (Wnd
->head
.pti
== (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
)
256 return (NtUserQueryWindow(Wnd
->head
.h
, QUERY_WINDOW_UNIQUE_PROCESS_ID
) ==
257 (DWORD_PTR
)NtCurrentTeb()->ClientId
.UniqueProcess
);
262 GetUser32Handle(HANDLE handle
)
267 Index
= (((UINT_PTR
)handle
& 0xffff) - FIRST_USER_HANDLE
) >> 1;
269 if (Index
< 0 || Index
>= gHandleTable
->nb_handles
)
272 if (!gHandleEntries
[Index
].type
|| !gHandleEntries
[Index
].ptr
)
275 generation
= (UINT_PTR
)handle
>> 16;
277 if (generation
== gHandleEntries
[Index
].generation
|| !generation
|| generation
== 0xffff)
278 return &gHandleEntries
[Index
];
284 * Decide whether an object is located on the desktop or shared heap
286 static const BOOL g_ObjectHeapTypeShared
[otEvent
+ 1] =
288 FALSE
, /* otFree (not used) */
289 FALSE
, /* otWindow */
290 TRUE
, /* otMenu FALSE */
291 TRUE
, /* otCursorIcon */
294 FALSE
, /* (not used) */
295 FALSE
, /* otCallProc */
297 FALSE
, /* (not used) */
298 FALSE
, /* (not used) */
299 FALSE
, /* (not used) */
300 TRUE
, /* otMonitor */
301 FALSE
, /* (not used) */
302 FALSE
, /* (not used) */
307 // Validate Handle and return the pointer to the object.
311 ValidateHandle(HANDLE handle
, UINT uType
)
314 PUSER_HANDLE_ENTRY pEntry
;
316 ASSERT(uType
<= otEvent
);
318 pEntry
= GetUser32Handle(handle
);
320 if (pEntry
&& uType
== 0)
321 uType
= pEntry
->type
;
323 // Must have an entry and must be the same type!
325 (pEntry
->type
!= uType
) ||
327 (pEntry
->flags
& HANDLEENTRY_INDESTROY
) )
330 { // Test (with wine too) confirms these results!
332 SetLastError(ERROR_INVALID_WINDOW_HANDLE
);
335 SetLastError(ERROR_INVALID_MENU_HANDLE
);
338 SetLastError(ERROR_INVALID_CURSOR_HANDLE
);
341 SetLastError(ERROR_INVALID_DWP_HANDLE
);
344 SetLastError(ERROR_INVALID_HOOK_HANDLE
);
347 SetLastError(ERROR_INVALID_ACCEL_HANDLE
);
350 SetLastError(ERROR_INVALID_HANDLE
);
356 if (g_ObjectHeapTypeShared
[uType
])
357 ret
= SharedPtrToUser(pEntry
->ptr
);
359 ret
= DesktopPtrToUser(pEntry
->ptr
);
365 // Validate Handle and return the pointer to the object.
369 ValidateHandleNoErr(HANDLE handle
, UINT uType
)
372 PUSER_HANDLE_ENTRY pEntry
;
374 ASSERT(uType
<= otEvent
);
376 pEntry
= GetUser32Handle(handle
);
378 if (pEntry
&& uType
== 0)
379 uType
= pEntry
->type
;
381 // Must have an entry and must be the same type!
382 if ( (!pEntry
) || (pEntry
->type
!= uType
) || !pEntry
->ptr
)
385 if (g_ObjectHeapTypeShared
[uType
])
386 ret
= SharedPtrToUser(pEntry
->ptr
);
388 ret
= DesktopPtrToUser(pEntry
->ptr
);
394 // Validate a callproc handle and return the pointer to the object.
398 ValidateCallProc(HANDLE hCallProc
)
400 PUSER_HANDLE_ENTRY pEntry
;
402 PCALLPROCDATA CallProc
= ValidateHandle(hCallProc
, otCallProc
);
404 pEntry
= GetUser32Handle(hCallProc
);
406 if (CallProc
!= NULL
&& pEntry
->ppi
== g_ppi
)
414 // Validate a window handle and return the pointer to the object.
418 ValidateHwnd(HWND hwnd
)
421 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
422 ASSERT(ClientInfo
!= NULL
);
424 /* See if the window is cached */
425 if (hwnd
== ClientInfo
->CallbackWnd
.hWnd
)
426 return ClientInfo
->CallbackWnd
.pWnd
;
428 Wnd
= ValidateHandle((HANDLE
)hwnd
, otWindow
);
438 // Validate a window handle and return the pointer to the object.
442 ValidateHwndNoErr(HWND hwnd
)
445 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
446 ASSERT(ClientInfo
!= NULL
);
448 /* See if the window is cached */
449 if (hwnd
== ClientInfo
->CallbackWnd
.hWnd
)
450 return ClientInfo
->CallbackWnd
.pWnd
;
452 Wnd
= ValidateHandleNoErr((HANDLE
)hwnd
, otWindow
);
463 GetThreadDesktopWnd(VOID
)
465 PWND Wnd
= GetThreadDesktopInfo()->spwnd
;
467 Wnd
= DesktopPtrToUser(Wnd
);
472 // Validate a window handle and return the pointer to the object.
476 ValidateHwndOrDesk(HWND hwnd
)
478 if (hwnd
== HWND_DESKTOP
)
479 return GetThreadDesktopWnd();
481 return ValidateHwnd(hwnd
);
495 if (!hwndParent
) hwndParent
= hwnd
;
497 pwnd
= ValidateHwnd(hwndParent
);
498 if (pwnd
&& !TestWindowProcess(pwnd
))
500 return (HBRUSH
)DefWindowProcW( hwndParent
, CtlMsg
, (WPARAM
)hdc
, (LPARAM
)hwnd
);
503 hBrush
= (HBRUSH
)SendMessageW( hwndParent
, CtlMsg
, (WPARAM
)hdc
, (LPARAM
)hwnd
);
505 if (!hBrush
|| !GdiValidateHandle(hBrush
))
507 hBrush
= (HBRUSH
)DefWindowProcW( hwndParent
, CtlMsg
, (WPARAM
)hdc
, (LPARAM
)hwnd
);
519 HWND hwndParent
= GetParent(hwnd
);
520 return GetControlColor( hwndParent
, hwnd
, hdc
, ctlType
);
526 DWORD WINAPI
WCSToMBEx(WORD CodePage
,LPWSTR UnicodeString
,LONG UnicodeSize
,LPSTR
*MBString
,LONG MBSize
,BOOL Allocate
)
529 if (UnicodeSize
== -1)
531 UnicodeSize
= wcslen(UnicodeString
)+1;
539 MBSize
= UnicodeSize
* 2;
543 LPSTR SafeString
= RtlAllocateHeap(GetProcessHeap(), 0, MBSize
);
544 if (SafeString
== NULL
)
546 *MBString
= SafeString
;
550 RtlUnicodeToMultiByteN(*MBString
,MBSize
,&Size
,UnicodeString
,UnicodeSize
);
554 WideCharToMultiByte(CodePage
,0,UnicodeString
,UnicodeSize
,*MBString
,MBSize
,0,0);
562 DWORD WINAPI
MBToWCSEx(WORD CodePage
,LPSTR MBString
,LONG MBSize
,LPWSTR
*UnicodeString
,LONG UnicodeSize
,BOOL Allocate
)
567 MBSize
= strlen(MBString
)+1;
569 if (UnicodeSize
== -1)
575 UnicodeSize
= MBSize
;
579 LPWSTR SafeString
= RtlAllocateHeap(GetProcessHeap(), 0, UnicodeSize
);
580 if (SafeString
== NULL
)
582 *UnicodeString
= SafeString
;
584 UnicodeSize
*= sizeof(WCHAR
);
587 RtlMultiByteToUnicodeN(*UnicodeString
,UnicodeSize
,&Size
,MBString
,MBSize
);
591 Size
= MultiByteToWideChar(CodePage
,0,MBString
,MBSize
,*UnicodeString
,UnicodeSize
);