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 NtUserCallTwoParam(dwProcessId
,
47 TWOPARAM_ROUTINE_REGISTERLOGONPROC
);
55 SetLogonNotifyWindow (HWND Wnd
, HWINSTA WinSta
)
57 /* Maybe we should call NtUserSetLogonNotifyWindow and let that one inform CSRSS??? */
58 CSR_API_MESSAGE Request
;
62 CsrRequest
= MAKE_CSR_API(SET_LOGON_NOTIFY_WINDOW
, CSR_GUI
);
63 Request
.Data
.SetLogonNotifyWindowRequest
.LogonNotifyWindow
= Wnd
;
65 Status
= CsrClientCallServer(&Request
,
68 sizeof(CSR_API_MESSAGE
));
69 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= Request
.Status
))
71 SetLastError(RtlNtStatusToDosError(Status
));
82 UpdatePerUserSystemParameters(
86 return NtUserUpdatePerUserSystemParameters(dwReserved
, bEnable
);
90 GetW32ThreadInfo(VOID
)
94 ti
= (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
97 /* create the THREADINFO structure */
98 NtUserGetThreadState(THREADSTATE_GETTHREADINFO
);
99 ti
= (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
107 * GetUserObjectSecurity
109 * Retrieves security information for user object specified
110 * with handle 'hObject'. Descriptor returned in self-relative
114 * 1) hObject - handle to an object to retrieve information for
115 * 2) pSecurityInfo - type of information to retrieve
116 * 3) pSecurityDescriptor - buffer which receives descriptor
117 * 4) dwLength - size, in bytes, of buffer 'pSecurityDescriptor'
118 * 5) pdwLengthNeeded - reseives actual size of descriptor
122 * FALSE on failure, call GetLastError() for more information
129 GetUserObjectSecurity(
131 IN PSECURITY_INFORMATION pSecurityInfo
,
132 OUT PSECURITY_DESCRIPTOR pSecurityDescriptor
,
134 OUT PDWORD pdwLengthNeeded
141 Status
= NtQuerySecurityObject(
142 hObject
, // Object Handle
143 *pSecurityInfo
, // Security Information
144 pSecurityDescriptor
,// Security Descriptor
145 dwLength
, // Buffer Length
146 pdwLengthNeeded
// Actual Length
149 if ( ! NT_SUCCESS( Status
) ) {
150 dwWin32Error
= RtlNtStatusToDosError( Status
);
151 NtCurrentTeb()->LastErrorValue
= dwWin32Error
;
160 * SetUserObjectSecurity
162 * Sets new security descriptor to user object specified by
163 * handle 'hObject'. Descriptor must be in self-relative format.
166 * 1) hObject - handle to an object to set information for
167 * 2) pSecurityInfo - type of information to apply
168 * 3) pSecurityDescriptor - buffer which descriptor to set
172 * FALSE on failure, call GetLastError() for more information
179 SetUserObjectSecurity(
181 IN PSECURITY_INFORMATION pSecurityInfo
,
182 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
189 Status
= NtSetSecurityObject(
190 hObject
, // Object Handle
191 *pSecurityInfo
, // Security Information
192 pSecurityDescriptor
// Security Descriptor
195 if ( ! NT_SUCCESS( Status
) ) {
196 dwWin32Error
= RtlNtStatusToDosError( Status
);
197 NtCurrentTeb()->LastErrorValue
= dwWin32Error
;
214 SendMessageW(hWnd
, WM_CLOSE
, 0, 0);
219 return DestroyWindow(hWnd
);
235 PTHREADINFO ti
= (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
240 NtUserGetThreadState(THREADSTATE_GETTHREADINFO
);
241 if ((PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
) return TRUE
;
243 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
253 TestWindowProcess(PWND Wnd
)
255 if (Wnd
->head
.pti
== (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
)
258 return (NtUserQueryWindow(Wnd
->head
.h
, QUERY_WINDOW_UNIQUE_PROCESS_ID
) ==
259 (DWORD_PTR
)NtCurrentTeb()->ClientId
.UniqueProcess
);
266 DWORD Type
= GetObjectType((HGDIOBJ
) hDc
);
272 case OBJ_ENHMETAFILE
:
280 GetUser32Handle(HANDLE handle
)
285 Index
= (((UINT_PTR
)handle
& 0xffff) - FIRST_USER_HANDLE
) >> 1;
287 if (Index
< 0 || Index
>= gHandleTable
->nb_handles
)
290 if (!gHandleEntries
[Index
].type
|| !gHandleEntries
[Index
].ptr
)
293 generation
= (UINT_PTR
)handle
>> 16;
295 if (generation
== gHandleEntries
[Index
].generation
|| !generation
|| generation
== 0xffff)
296 return &gHandleEntries
[Index
];
302 * Decide whether an object is located on the desktop or shared heap
304 static const BOOL g_ObjectHeapTypeShared
[VALIDATE_TYPE_EVENT
+ 1] =
306 FALSE
, /* VALIDATE_TYPE_FREE (not used) */
307 FALSE
, /* VALIDATE_TYPE_WIN */
308 TRUE
, /* VALIDATE_TYPE_MENU FALSE */
309 TRUE
, /* VALIDATE_TYPE_CURSOR */
310 TRUE
, /* VALIDATE_TYPE_MWPOS */
311 FALSE
, /* VALIDATE_TYPE_HOOK */
312 FALSE
, /* (not used) */
313 FALSE
, /* VALIDATE_TYPE_CALLPROC */
314 TRUE
, /* VALIDATE_TYPE_ACCEL */
315 FALSE
, /* (not used) */
316 FALSE
, /* (not used) */
317 FALSE
, /* (not used) */
318 TRUE
, /* VALIDATE_TYPE_MONITOR */
319 FALSE
, /* (not used) */
320 FALSE
, /* (not used) */
321 TRUE
/* VALIDATE_TYPE_EVENT */
325 // Validate Handle and return the pointer to the object.
329 ValidateHandle(HANDLE handle
, UINT uType
)
332 PUSER_HANDLE_ENTRY pEntry
;
334 ASSERT(uType
<= VALIDATE_TYPE_EVENT
);
336 pEntry
= GetUser32Handle(handle
);
338 if (pEntry
&& uType
== 0)
339 uType
= pEntry
->type
;
341 // Must have an entry and must be the same type!
343 (pEntry
->type
!= uType
) ||
345 (pEntry
->flags
& HANDLEENTRY_INDESTROY
) )
348 { // Test (with wine too) confirms these results!
349 case VALIDATE_TYPE_WIN
:
350 SetLastError(ERROR_INVALID_WINDOW_HANDLE
);
352 case VALIDATE_TYPE_MENU
:
353 SetLastError(ERROR_INVALID_MENU_HANDLE
);
355 case VALIDATE_TYPE_CURSOR
:
356 SetLastError(ERROR_INVALID_CURSOR_HANDLE
);
358 case VALIDATE_TYPE_MWPOS
:
359 SetLastError(ERROR_INVALID_DWP_HANDLE
);
361 case VALIDATE_TYPE_HOOK
:
362 SetLastError(ERROR_INVALID_HOOK_HANDLE
);
364 case VALIDATE_TYPE_ACCEL
:
365 SetLastError(ERROR_INVALID_ACCEL_HANDLE
);
368 SetLastError(ERROR_INVALID_HANDLE
);
374 if (g_ObjectHeapTypeShared
[uType
])
375 ret
= SharedPtrToUser(pEntry
->ptr
);
377 ret
= DesktopPtrToUser(pEntry
->ptr
);
383 // Validate Handle and return the pointer to the object.
387 ValidateHandleNoErr(HANDLE handle
, UINT uType
)
390 PUSER_HANDLE_ENTRY pEntry
;
392 ASSERT(uType
<= VALIDATE_TYPE_EVENT
);
394 pEntry
= GetUser32Handle(handle
);
396 if (pEntry
&& uType
== 0)
397 uType
= pEntry
->type
;
399 // Must have an entry and must be the same type!
400 if ( (!pEntry
) || (pEntry
->type
!= uType
) || !pEntry
->ptr
)
403 if (g_ObjectHeapTypeShared
[uType
])
404 ret
= SharedPtrToUser(pEntry
->ptr
);
406 ret
= DesktopPtrToUser(pEntry
->ptr
);
412 // Validate a callproc handle and return the pointer to the object.
416 ValidateCallProc(HANDLE hCallProc
)
418 PUSER_HANDLE_ENTRY pEntry
;
420 PCALLPROCDATA CallProc
= ValidateHandle(hCallProc
, VALIDATE_TYPE_CALLPROC
);
422 pEntry
= GetUser32Handle(hCallProc
);
424 if (CallProc
!= NULL
&& pEntry
->ppi
== g_ppi
)
432 // Validate a window handle and return the pointer to the object.
436 ValidateHwnd(HWND hwnd
)
439 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
440 ASSERT(ClientInfo
!= NULL
);
442 /* See if the window is cached */
443 if (hwnd
== ClientInfo
->CallbackWnd
.hWnd
)
444 return ClientInfo
->CallbackWnd
.pWnd
;
446 Wnd
= ValidateHandle((HANDLE
)hwnd
, VALIDATE_TYPE_WIN
);
456 // Validate a window handle and return the pointer to the object.
460 ValidateHwndNoErr(HWND hwnd
)
463 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
464 ASSERT(ClientInfo
!= NULL
);
466 /* See if the window is cached */
467 if (hwnd
== ClientInfo
->CallbackWnd
.hWnd
)
468 return ClientInfo
->CallbackWnd
.pWnd
;
470 Wnd
= ValidateHandleNoErr((HANDLE
)hwnd
, VALIDATE_TYPE_WIN
);
481 GetThreadDesktopWnd(VOID
)
483 PWND Wnd
= GetThreadDesktopInfo()->spwnd
;
485 Wnd
= DesktopPtrToUser(Wnd
);
490 // Validate a window handle and return the pointer to the object.
494 ValidateHwndOrDesk(HWND hwnd
)
496 if (hwnd
== HWND_DESKTOP
)
497 return GetThreadDesktopWnd();
499 return ValidateHwnd(hwnd
);
505 DWORD WINAPI
WCSToMBEx(WORD CodePage
,LPWSTR UnicodeString
,LONG UnicodeSize
,LPSTR
*MBString
,LONG MBSize
,BOOL Allocate
)
508 if (UnicodeSize
== -1)
510 UnicodeSize
= wcslen(UnicodeString
)+1;
518 MBSize
= UnicodeSize
* 2;
522 LPSTR SafeString
= RtlAllocateHeap(GetProcessHeap(), 0, MBSize
);
523 if (SafeString
== NULL
)
525 *MBString
= SafeString
;
529 RtlUnicodeToMultiByteN(*MBString
,MBSize
,&Size
,UnicodeString
,UnicodeSize
);
533 WideCharToMultiByte(CodePage
,0,UnicodeString
,UnicodeSize
,*MBString
,MBSize
,0,0);
541 DWORD WINAPI
MBToWCSEx(WORD CodePage
,LPSTR MBString
,LONG MBSize
,LPWSTR
*UnicodeString
,LONG UnicodeSize
,BOOL Allocate
)
546 MBSize
= strlen(MBString
)+1;
548 if (UnicodeSize
== -1)
554 UnicodeSize
= MBSize
;
558 LPWSTR SafeString
= RtlAllocateHeap(GetProcessHeap(), 0, UnicodeSize
);
559 if (SafeString
== NULL
)
561 *UnicodeString
= SafeString
;
563 UnicodeSize
*= sizeof(WCHAR
);
566 RtlMultiByteToUnicodeN(*UnicodeString
,UnicodeSize
,&Size
,MBString
,MBSize
);
570 Size
= MultiByteToWideChar(CodePage
,0,MBString
,MBSize
,*UnicodeString
,UnicodeSize
);