2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS user32.dll
4 * FILE: win32ss/user/user32/misc/misc.c
6 * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
13 UserSetLastError(IN DWORD dwErrCode
)
16 * Equivalent of SetLastError in kernel32, but without breaking
17 * into the debugger nor checking whether the last old error is
18 * the same as the one we are going to set.
20 NtCurrentTeb()->LastErrorValue
= dwErrCode
;
25 UserSetLastNTError(IN NTSTATUS Status
)
28 * Equivalent of BaseSetLastNTError in kernel32, but using
29 * UserSetLastError: convert from NT to Win32, then set.
31 UserSetLastError(RtlNtStatusToDosError(Status
));
36 GetW32ThreadInfo(VOID
)
40 ti
= (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
43 /* create the THREADINFO structure */
44 NtUserGetThreadState(THREADSTATE_GETTHREADINFO
);
45 ti
= (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
53 * GetUserObjectSecurity
55 * Retrieves security information for user object specified
56 * with handle 'hObject'. Descriptor returned in self-relative
60 * 1) hObject - handle to an object to retrieve information for
61 * 2) pSecurityInfo - type of information to retrieve
62 * 3) pSecurityDescriptor - buffer which receives descriptor
63 * 4) dwLength - size, in bytes, of buffer 'pSecurityDescriptor'
64 * 5) pdwLengthNeeded - reseives actual size of descriptor
68 * FALSE on failure, call GetLastError() for more information
75 GetUserObjectSecurity(
77 IN PSECURITY_INFORMATION pSecurityInfo
,
78 OUT PSECURITY_DESCRIPTOR pSecurityDescriptor
,
80 OUT PDWORD pdwLengthNeeded
87 Status
= NtQuerySecurityObject(
88 hObject
, // Object Handle
89 *pSecurityInfo
, // Security Information
90 pSecurityDescriptor
,// Security Descriptor
91 dwLength
, // Buffer Length
92 pdwLengthNeeded
// Actual Length
95 if ( ! NT_SUCCESS( Status
) ) {
96 dwWin32Error
= RtlNtStatusToDosError( Status
);
97 NtCurrentTeb()->LastErrorValue
= dwWin32Error
;
106 * SetUserObjectSecurity
108 * Sets new security descriptor to user object specified by
109 * handle 'hObject'. Descriptor must be in self-relative format.
112 * 1) hObject - handle to an object to set information for
113 * 2) pSecurityInfo - type of information to apply
114 * 3) pSecurityDescriptor - buffer which descriptor to set
118 * FALSE on failure, call GetLastError() for more information
125 SetUserObjectSecurity(
127 IN PSECURITY_INFORMATION pSecurityInfo
,
128 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
135 Status
= NtSetSecurityObject(
136 hObject
, // Object Handle
137 *pSecurityInfo
, // Security Information
138 pSecurityDescriptor
// Security Descriptor
141 if ( ! NT_SUCCESS( Status
) ) {
142 dwWin32Error
= RtlNtStatusToDosError( Status
);
143 NtCurrentTeb()->LastErrorValue
= dwWin32Error
;
158 PTHREADINFO ti
= (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
;
163 NtUserGetThreadState(THREADSTATE_GETTHREADINFO
);
164 if ((PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
) return TRUE
;
166 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
176 TestWindowProcess(PWND Wnd
)
178 if (Wnd
->head
.pti
== (PTHREADINFO
)NtCurrentTeb()->Win32ThreadInfo
)
181 return (NtUserQueryWindow(Wnd
->head
.h
, QUERY_WINDOW_UNIQUE_PROCESS_ID
) ==
182 (DWORD_PTR
)NtCurrentTeb()->ClientId
.UniqueProcess
);
187 TestState(PWND pWnd
, UINT Flag
)
190 bit
= 1 << LOWORD(Flag
);
194 return (pWnd
->state
& bit
);
196 return (pWnd
->state2
& bit
);
198 return (pWnd
->ExStyle2
& bit
);
205 GetUser32Handle(HANDLE handle
)
210 if (!handle
) return NULL
;
212 Index
= (((UINT_PTR
)handle
& 0xffff) - FIRST_USER_HANDLE
) >> 1;
214 if (Index
< 0 || Index
>= gHandleTable
->nb_handles
)
217 if (!gHandleEntries
[Index
].type
|| !gHandleEntries
[Index
].ptr
)
220 generation
= (UINT_PTR
)handle
>> 16;
222 if (generation
== gHandleEntries
[Index
].generation
|| !generation
|| generation
== 0xffff)
223 return &gHandleEntries
[Index
];
229 * Decide whether an object is located on the desktop or shared heap
231 static const BOOL g_ObjectHeapTypeShared
[TYPE_CTYPES
] =
233 FALSE
, /* TYPE_FREE (not used) */
234 FALSE
, /* TYPE_WINDOW */
235 FALSE
, /* TYPE_MENU */
236 TRUE
, /* TYPE_CURSOR */
237 TRUE
, /* TYPE_SETWINDOWPOS */
238 FALSE
, /* TYPE_HOOK */
239 TRUE
, /* TYPE_CLIPDATA */
240 FALSE
, /* TYPE_CALLPROC */
241 TRUE
, /* TYPE_ACCELTABLE */
242 FALSE
, /* TYPE_DDEACCESS */
243 FALSE
, /* TYPE_DDECONV */
244 FALSE
, /* TYPE_DDEXACT */
245 TRUE
, /* TYPE_MONITOR */
246 TRUE
, /* TYPE_KBDLAYOUT */
247 TRUE
, /* TYPE_KBDFILE */
248 TRUE
, /* TYPE_WINEVENTHOOK */
249 TRUE
, /* TYPE_TIMER */
250 FALSE
, /* TYPE_INPUTCONTEXT */
251 FALSE
, /* TYPE_HIDDATA */
252 FALSE
, /* TYPE_DEVICEINFO */
253 FALSE
, /* TYPE_TOUCHINPUTINFO */
254 FALSE
, /* TYPE_GESTUREINFOOBJ */
258 // Validate Handle and return the pointer to the object.
262 ValidateHandle(HANDLE handle
, UINT uType
)
265 PUSER_HANDLE_ENTRY pEntry
;
267 ASSERT(uType
< TYPE_CTYPES
);
269 pEntry
= GetUser32Handle(handle
);
271 if (pEntry
&& uType
== 0)
272 uType
= pEntry
->type
;
274 // Must have an entry and must be the same type!
276 (pEntry
->type
!= uType
) ||
278 (pEntry
->flags
& HANDLEENTRY_DESTROY
) || (pEntry
->flags
& HANDLEENTRY_INDESTROY
) )
281 { // Test (with wine too) confirms these results!
283 SetLastError(ERROR_INVALID_WINDOW_HANDLE
);
286 SetLastError(ERROR_INVALID_MENU_HANDLE
);
289 SetLastError(ERROR_INVALID_CURSOR_HANDLE
);
291 case TYPE_SETWINDOWPOS
:
292 SetLastError(ERROR_INVALID_DWP_HANDLE
);
295 SetLastError(ERROR_INVALID_HOOK_HANDLE
);
297 case TYPE_ACCELTABLE
:
298 SetLastError(ERROR_INVALID_ACCEL_HANDLE
);
301 SetLastError(ERROR_INVALID_HANDLE
);
307 if (g_ObjectHeapTypeShared
[uType
])
308 ret
= SharedPtrToUser(pEntry
->ptr
);
310 ret
= DesktopPtrToUser(pEntry
->ptr
);
316 // Validate Handle and return the pointer to the object.
320 ValidateHandleNoErr(HANDLE handle
, UINT uType
)
323 PUSER_HANDLE_ENTRY pEntry
;
325 ASSERT(uType
< TYPE_CTYPES
);
327 pEntry
= GetUser32Handle(handle
);
329 if (pEntry
&& uType
== 0)
330 uType
= pEntry
->type
;
332 // Must have an entry and must be the same type!
333 if ( (!pEntry
) || (pEntry
->type
!= uType
) || !pEntry
->ptr
)
336 if (g_ObjectHeapTypeShared
[uType
])
337 ret
= SharedPtrToUser(pEntry
->ptr
);
339 ret
= DesktopPtrToUser(pEntry
->ptr
);
345 // Validate a callproc handle and return the pointer to the object.
349 ValidateCallProc(HANDLE hCallProc
)
351 PUSER_HANDLE_ENTRY pEntry
;
353 PCALLPROCDATA CallProc
= ValidateHandle(hCallProc
, TYPE_CALLPROC
);
355 pEntry
= GetUser32Handle(hCallProc
);
357 if (CallProc
!= NULL
&& pEntry
->ppi
== g_ppi
)
365 // Validate a window handle and return the pointer to the object.
369 ValidateHwnd(HWND hwnd
)
371 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
372 ASSERT(ClientInfo
!= NULL
);
374 /* See if the window is cached */
375 if (hwnd
&& hwnd
== ClientInfo
->CallbackWnd
.hWnd
)
376 return ClientInfo
->CallbackWnd
.pWnd
;
378 return ValidateHandle((HANDLE
)hwnd
, TYPE_WINDOW
);
382 // Validate a window handle and return the pointer to the object.
386 ValidateHwndNoErr(HWND hwnd
)
389 PCLIENTINFO ClientInfo
= GetWin32ClientInfo();
390 ASSERT(ClientInfo
!= NULL
);
392 /* See if the window is cached */
393 if (hwnd
== ClientInfo
->CallbackWnd
.hWnd
)
394 return ClientInfo
->CallbackWnd
.pWnd
;
396 Wnd
= ValidateHandleNoErr((HANDLE
)hwnd
, TYPE_WINDOW
);
407 GetThreadDesktopWnd(VOID
)
409 PWND Wnd
= GetThreadDesktopInfo()->spwnd
;
411 Wnd
= DesktopPtrToUser(Wnd
);
416 // Validate a window handle and return the pointer to the object.
420 ValidateHwndOrDesk(HWND hwnd
)
422 if (hwnd
== HWND_DESKTOP
)
423 return GetThreadDesktopWnd();
425 return ValidateHwnd(hwnd
);
431 DWORD WINAPI
WCSToMBEx(WORD CodePage
,LPWSTR UnicodeString
,LONG UnicodeSize
,LPSTR
*MBString
,LONG MBSize
,BOOL Allocate
)
434 if (UnicodeSize
== -1)
436 UnicodeSize
= wcslen(UnicodeString
)+1;
444 MBSize
= UnicodeSize
* 2;
448 LPSTR SafeString
= RtlAllocateHeap(GetProcessHeap(), 0, MBSize
);
449 if (SafeString
== NULL
)
451 *MBString
= SafeString
;
455 RtlUnicodeToMultiByteN(*MBString
,MBSize
,&Size
,UnicodeString
,UnicodeSize
);
459 WideCharToMultiByte(CodePage
,0,UnicodeString
,UnicodeSize
,*MBString
,MBSize
,0,0);
467 DWORD WINAPI
MBToWCSEx(WORD CodePage
,LPSTR MBString
,LONG MBSize
,LPWSTR
*UnicodeString
,LONG UnicodeSize
,BOOL Allocate
)
472 MBSize
= strlen(MBString
)+1;
474 if (UnicodeSize
== -1)
480 UnicodeSize
= MBSize
;
484 LPWSTR SafeString
= RtlAllocateHeap(GetProcessHeap(), 0, UnicodeSize
);
485 if (SafeString
== NULL
)
487 *UnicodeString
= SafeString
;
489 UnicodeSize
*= sizeof(WCHAR
);
492 RtlMultiByteToUnicodeN(*UnicodeString
,UnicodeSize
,&Size
,MBString
,MBSize
);
496 Size
= MultiByteToWideChar(CodePage
,0,MBString
,MBSize
,*UnicodeString
,UnicodeSize
);