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 gfLogonProcess
= NtUserxRegisterLogonProcess(dwProcessId
, bRegister
);
50 USER_API_MESSAGE ApiMessage
;
52 ApiMessage
.Data
.RegisterLogonProcessRequest
.ProcessId
= dwProcessId
;
53 ApiMessage
.Data
.RegisterLogonProcessRequest
.Register
= bRegister
;
55 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
57 CSR_CREATE_API_NUMBER(USERSRV_SERVERDLL_INDEX
, UserpRegisterLogonProcess
),
58 sizeof(USER_REGISTER_LOGON_PROCESS
));
59 if (!NT_SUCCESS(Status
))
61 ERR("Failed to register logon process with CSRSS\n");
62 SetLastError(RtlNtStatusToDosError(Status
));
67 return gfLogonProcess
;
75 SetLogonNotifyWindow(HWND Wnd
, HWINSTA WinSta
)
77 return NtUserSetLogonNotifyWindow(Wnd
);
84 UpdatePerUserSystemParameters(
88 return NtUserUpdatePerUserSystemParameters(dwReserved
, bEnable
);
92 GetW32ThreadInfo(VOID
)
96 ti
= (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
99 /* create the THREADINFO structure */
100 NtUserGetThreadState(THREADSTATE_GETTHREADINFO
);
101 ti
= (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
109 * GetUserObjectSecurity
111 * Retrieves security information for user object specified
112 * with handle 'hObject'. Descriptor returned in self-relative
116 * 1) hObject - handle to an object to retrieve information for
117 * 2) pSecurityInfo - type of information to retrieve
118 * 3) pSecurityDescriptor - buffer which receives descriptor
119 * 4) dwLength - size, in bytes, of buffer 'pSecurityDescriptor'
120 * 5) pdwLengthNeeded - reseives actual size of descriptor
124 * FALSE on failure, call GetLastError() for more information
131 GetUserObjectSecurity(
133 IN PSECURITY_INFORMATION pSecurityInfo
,
134 OUT PSECURITY_DESCRIPTOR pSecurityDescriptor
,
136 OUT PDWORD pdwLengthNeeded
143 Status
= NtQuerySecurityObject(
144 hObject
, // Object Handle
145 *pSecurityInfo
, // Security Information
146 pSecurityDescriptor
,// Security Descriptor
147 dwLength
, // Buffer Length
148 pdwLengthNeeded
// Actual Length
151 if ( ! NT_SUCCESS( Status
) ) {
152 dwWin32Error
= RtlNtStatusToDosError( Status
);
153 NtCurrentTeb()->LastErrorValue
= dwWin32Error
;
162 * SetUserObjectSecurity
164 * Sets new security descriptor to user object specified by
165 * handle 'hObject'. Descriptor must be in self-relative format.
168 * 1) hObject - handle to an object to set information for
169 * 2) pSecurityInfo - type of information to apply
170 * 3) pSecurityDescriptor - buffer which descriptor to set
174 * FALSE on failure, call GetLastError() for more information
181 SetUserObjectSecurity(
183 IN PSECURITY_INFORMATION pSecurityInfo
,
184 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
191 Status
= NtSetSecurityObject(
192 hObject
, // Object Handle
193 *pSecurityInfo
, // Security Information
194 pSecurityDescriptor
// Security Descriptor
197 if ( ! NT_SUCCESS( Status
) ) {
198 dwWin32Error
= RtlNtStatusToDosError( Status
);
199 NtCurrentTeb()->LastErrorValue
= dwWin32Error
;
216 SendMessageW(hWnd
, WM_CLOSE
, 0, 0);
221 return DestroyWindow(hWnd
);
237 PTHREADINFO ti
= (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
242 NtUserGetThreadState(THREADSTATE_GETTHREADINFO
);
243 if ((PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
) return TRUE
;
245 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
255 TestWindowProcess(PWND Wnd
)
257 if (Wnd
->head
.pti
== (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
)
260 return (NtUserQueryWindow(Wnd
->head
.h
, QUERY_WINDOW_UNIQUE_PROCESS_ID
) ==
261 (DWORD_PTR
)NtCurrentTeb()->ClientId
.UniqueProcess
);
266 TestState(PWND pWnd
, UINT Flag
)
269 bit
= 1 << LOWORD(Flag
);
273 return (pWnd
->state
& bit
);
275 return (pWnd
->state2
& bit
);
277 return (pWnd
->ExStyle2
& bit
);
284 GetUser32Handle(HANDLE handle
)
289 if (!handle
) return NULL
;
291 Index
= (((UINT_PTR
)handle
& 0xffff) - FIRST_USER_HANDLE
) >> 1;
293 if (Index
< 0 || Index
>= gHandleTable
->nb_handles
)
296 if (!gHandleEntries
[Index
].type
|| !gHandleEntries
[Index
].ptr
)
299 generation
= (UINT_PTR
)handle
>> 16;
301 if (generation
== gHandleEntries
[Index
].generation
|| !generation
|| generation
== 0xffff)
302 return &gHandleEntries
[Index
];
308 * Decide whether an object is located on the desktop or shared heap
310 static const BOOL g_ObjectHeapTypeShared
[TYPE_CTYPES
] =
312 FALSE
, /* TYPE_FREE (not used) */
313 FALSE
, /* TYPE_WINDOW */
314 FALSE
, /* TYPE_MENU */
315 TRUE
, /* TYPE_CURSOR */
316 TRUE
, /* TYPE_SETWINDOWPOS */
317 FALSE
, /* TYPE_HOOK */
318 TRUE
, /* TYPE_CLIPDATA */
319 FALSE
, /* TYPE_CALLPROC */
320 TRUE
, /* TYPE_ACCELTABLE */
321 FALSE
, /* TYPE_DDEACCESS */
322 FALSE
, /* TYPE_DDECONV */
323 FALSE
, /* TYPE_DDEXACT */
324 TRUE
, /* TYPE_MONITOR */
325 TRUE
, /* TYPE_KBDLAYOUT */
326 TRUE
, /* TYPE_KBDFILE */
327 TRUE
, /* TYPE_WINEVENTHOOK */
328 TRUE
, /* TYPE_TIMER */
329 FALSE
, /* TYPE_INPUTCONTEXT */
330 FALSE
, /* TYPE_HIDDATA */
331 FALSE
, /* TYPE_DEVICEINFO */
332 FALSE
, /* TYPE_TOUCHINPUTINFO */
333 FALSE
, /* TYPE_GESTUREINFOOBJ */
337 // Validate Handle and return the pointer to the object.
341 ValidateHandle(HANDLE handle
, UINT uType
)
344 PUSER_HANDLE_ENTRY pEntry
;
346 ASSERT(uType
< TYPE_CTYPES
);
348 pEntry
= GetUser32Handle(handle
);
350 if (pEntry
&& uType
== 0)
351 uType
= pEntry
->type
;
353 // Must have an entry and must be the same type!
355 (pEntry
->type
!= uType
) ||
357 (pEntry
->flags
& HANDLEENTRY_INDESTROY
) )
360 { // Test (with wine too) confirms these results!
362 SetLastError(ERROR_INVALID_WINDOW_HANDLE
);
365 SetLastError(ERROR_INVALID_MENU_HANDLE
);
368 SetLastError(ERROR_INVALID_CURSOR_HANDLE
);
370 case TYPE_SETWINDOWPOS
:
371 SetLastError(ERROR_INVALID_DWP_HANDLE
);
374 SetLastError(ERROR_INVALID_HOOK_HANDLE
);
376 case TYPE_ACCELTABLE
:
377 SetLastError(ERROR_INVALID_ACCEL_HANDLE
);
380 SetLastError(ERROR_INVALID_HANDLE
);
386 if (g_ObjectHeapTypeShared
[uType
])
387 ret
= SharedPtrToUser(pEntry
->ptr
);
389 ret
= DesktopPtrToUser(pEntry
->ptr
);
395 // Validate Handle and return the pointer to the object.
399 ValidateHandleNoErr(HANDLE handle
, UINT uType
)
402 PUSER_HANDLE_ENTRY pEntry
;
404 ASSERT(uType
< TYPE_CTYPES
);
406 pEntry
= GetUser32Handle(handle
);
408 if (pEntry
&& uType
== 0)
409 uType
= pEntry
->type
;
411 // Must have an entry and must be the same type!
412 if ( (!pEntry
) || (pEntry
->type
!= uType
) || !pEntry
->ptr
)
415 if (g_ObjectHeapTypeShared
[uType
])
416 ret
= SharedPtrToUser(pEntry
->ptr
);
418 ret
= DesktopPtrToUser(pEntry
->ptr
);
424 // Validate a callproc handle and return the pointer to the object.
428 ValidateCallProc(HANDLE hCallProc
)
430 PUSER_HANDLE_ENTRY pEntry
;
432 PCALLPROCDATA CallProc
= ValidateHandle(hCallProc
, TYPE_CALLPROC
);
434 pEntry
= GetUser32Handle(hCallProc
);
436 if (CallProc
!= NULL
&& pEntry
->ppi
== g_ppi
)
444 // Validate a window handle and return the pointer to the object.
448 ValidateHwnd(HWND hwnd
)
450 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
451 ASSERT(ClientInfo
!= NULL
);
453 /* See if the window is cached */
454 if (hwnd
&& hwnd
== ClientInfo
->CallbackWnd
.hWnd
)
455 return ClientInfo
->CallbackWnd
.pWnd
;
457 return ValidateHandle((HANDLE
)hwnd
, TYPE_WINDOW
);
461 // Validate a window handle and return the pointer to the object.
465 ValidateHwndNoErr(HWND hwnd
)
468 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
469 ASSERT(ClientInfo
!= NULL
);
471 /* See if the window is cached */
472 if (hwnd
== ClientInfo
->CallbackWnd
.hWnd
)
473 return ClientInfo
->CallbackWnd
.pWnd
;
475 Wnd
= ValidateHandleNoErr((HANDLE
)hwnd
, TYPE_WINDOW
);
486 GetThreadDesktopWnd(VOID
)
488 PWND Wnd
= GetThreadDesktopInfo()->spwnd
;
490 Wnd
= DesktopPtrToUser(Wnd
);
495 // Validate a window handle and return the pointer to the object.
499 ValidateHwndOrDesk(HWND hwnd
)
501 if (hwnd
== HWND_DESKTOP
)
502 return GetThreadDesktopWnd();
504 return ValidateHwnd(hwnd
);
510 DWORD WINAPI
WCSToMBEx(WORD CodePage
,LPWSTR UnicodeString
,LONG UnicodeSize
,LPSTR
*MBString
,LONG MBSize
,BOOL Allocate
)
513 if (UnicodeSize
== -1)
515 UnicodeSize
= wcslen(UnicodeString
)+1;
523 MBSize
= UnicodeSize
* 2;
527 LPSTR SafeString
= RtlAllocateHeap(GetProcessHeap(), 0, MBSize
);
528 if (SafeString
== NULL
)
530 *MBString
= SafeString
;
534 RtlUnicodeToMultiByteN(*MBString
,MBSize
,&Size
,UnicodeString
,UnicodeSize
);
538 WideCharToMultiByte(CodePage
,0,UnicodeString
,UnicodeSize
,*MBString
,MBSize
,0,0);
546 DWORD WINAPI
MBToWCSEx(WORD CodePage
,LPSTR MBString
,LONG MBSize
,LPWSTR
*UnicodeString
,LONG UnicodeSize
,BOOL Allocate
)
551 MBSize
= strlen(MBString
)+1;
553 if (UnicodeSize
== -1)
559 UnicodeSize
= MBSize
;
563 LPWSTR SafeString
= RtlAllocateHeap(GetProcessHeap(), 0, UnicodeSize
);
564 if (SafeString
== NULL
)
566 *UnicodeString
= SafeString
;
568 UnicodeSize
*= sizeof(WCHAR
);
571 RtlMultiByteToUnicodeN(*UnicodeString
,UnicodeSize
,&Size
,MBString
,MBSize
);
575 Size
= MultiByteToWideChar(CodePage
,0,MBString
,MBSize
,*UnicodeString
,UnicodeSize
);