[USER32] Remove unused debug channels. Silences some clang-cl warnings.
[reactos.git] / win32ss / user / user32 / misc / misc.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS user32.dll
4 * FILE: win32ss/user/user32/misc/misc.c
5 * PURPOSE: Misc
6 * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
7 */
8
9 #include <user32.h>
10
11 VOID
12 WINAPI
13 UserSetLastError(IN DWORD dwErrCode)
14 {
15 /*
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.
19 */
20 NtCurrentTeb()->LastErrorValue = dwErrCode;
21 }
22
23 VOID
24 WINAPI
25 UserSetLastNTError(IN NTSTATUS Status)
26 {
27 /*
28 * Equivalent of BaseSetLastNTError in kernel32, but using
29 * UserSetLastError: convert from NT to Win32, then set.
30 */
31 UserSetLastError(RtlNtStatusToDosError(Status));
32 }
33
34
35 PTHREADINFO
36 GetW32ThreadInfo(VOID)
37 {
38 PTHREADINFO ti;
39
40 ti = (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo;
41 if (ti == NULL)
42 {
43 /* create the THREADINFO structure */
44 NtUserGetThreadState(THREADSTATE_GETTHREADINFO);
45 ti = (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo;
46 }
47
48 return ti;
49 }
50
51
52 /*
53 * GetUserObjectSecurity
54 *
55 * Retrieves security information for user object specified
56 * with handle 'hObject'. Descriptor returned in self-relative
57 * format.
58 *
59 * Arguments:
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
65 *
66 * Return Vaules:
67 * TRUE on success
68 * FALSE on failure, call GetLastError() for more information
69 */
70 /*
71 * @implemented
72 */
73 BOOL
74 WINAPI
75 GetUserObjectSecurity(
76 IN HANDLE hObject,
77 IN PSECURITY_INFORMATION pSecurityInfo,
78 OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
79 IN DWORD dwLength,
80 OUT PDWORD pdwLengthNeeded
81 )
82 {
83 DWORD dwWin32Error;
84 NTSTATUS Status;
85
86
87 Status = NtQuerySecurityObject(
88 hObject, // Object Handle
89 *pSecurityInfo, // Security Information
90 pSecurityDescriptor,// Security Descriptor
91 dwLength, // Buffer Length
92 pdwLengthNeeded // Actual Length
93 );
94
95 if ( ! NT_SUCCESS( Status ) ) {
96 dwWin32Error = RtlNtStatusToDosError( Status );
97 NtCurrentTeb()->LastErrorValue = dwWin32Error;
98 return FALSE;
99 }
100
101 return TRUE;
102 }
103
104
105 /*
106 * SetUserObjectSecurity
107 *
108 * Sets new security descriptor to user object specified by
109 * handle 'hObject'. Descriptor must be in self-relative format.
110 *
111 * Arguments:
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
115 *
116 * Return Vaules:
117 * TRUE on success
118 * FALSE on failure, call GetLastError() for more information
119 */
120 /*
121 * @implemented
122 */
123 BOOL
124 WINAPI
125 SetUserObjectSecurity(
126 IN HANDLE hObject,
127 IN PSECURITY_INFORMATION pSecurityInfo,
128 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
129 )
130 {
131 DWORD dwWin32Error;
132 NTSTATUS Status;
133
134
135 Status = NtSetSecurityObject(
136 hObject, // Object Handle
137 *pSecurityInfo, // Security Information
138 pSecurityDescriptor // Security Descriptor
139 );
140
141 if ( ! NT_SUCCESS( Status ) ) {
142 dwWin32Error = RtlNtStatusToDosError( Status );
143 NtCurrentTeb()->LastErrorValue = dwWin32Error;
144 return FALSE;
145 }
146
147 return TRUE;
148 }
149
150 /*
151 * @implemented
152 */
153 BOOL
154 WINAPI
155 IsGUIThread(
156 BOOL bConvert)
157 {
158 PTHREADINFO ti = (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo;
159 if (ti == NULL)
160 {
161 if(bConvert)
162 {
163 NtUserGetThreadState(THREADSTATE_GETTHREADINFO);
164 if ((PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo) return TRUE;
165 else
166 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
167 }
168 return FALSE;
169 }
170 else
171 return TRUE;
172 }
173
174 BOOL
175 FASTCALL
176 TestWindowProcess(PWND Wnd)
177 {
178 if (Wnd->head.pti == (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo)
179 return TRUE;
180 else
181 return (NtUserQueryWindow(Wnd->head.h, QUERY_WINDOW_UNIQUE_PROCESS_ID) ==
182 (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess );
183 }
184
185 BOOL
186 FASTCALL
187 TestState(PWND pWnd, UINT Flag)
188 {
189 UINT bit;
190 bit = 1 << LOWORD(Flag);
191 switch(HIWORD(Flag))
192 {
193 case 0:
194 return (pWnd->state & bit);
195 case 1:
196 return (pWnd->state2 & bit);
197 case 2:
198 return (pWnd->ExStyle2 & bit);
199 }
200 return FALSE;
201 }
202
203 PUSER_HANDLE_ENTRY
204 FASTCALL
205 GetUser32Handle(HANDLE handle)
206 {
207 INT Index;
208 USHORT generation;
209
210 if (!handle) return NULL;
211
212 Index = (((UINT_PTR)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
213
214 if (Index < 0 || Index >= gHandleTable->nb_handles)
215 return NULL;
216
217 if (!gHandleEntries[Index].type || !gHandleEntries[Index].ptr)
218 return NULL;
219
220 generation = (UINT_PTR)handle >> 16;
221
222 if (generation == gHandleEntries[Index].generation || !generation || generation == 0xffff)
223 return &gHandleEntries[Index];
224
225 return NULL;
226 }
227
228 /*
229 * Decide whether an object is located on the desktop or shared heap
230 */
231 static const BOOL g_ObjectHeapTypeShared[TYPE_CTYPES] =
232 {
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 */
255 };
256
257 //
258 // Validate Handle and return the pointer to the object.
259 //
260 PVOID
261 FASTCALL
262 ValidateHandle(HANDLE handle, UINT uType)
263 {
264 PVOID ret;
265 PUSER_HANDLE_ENTRY pEntry;
266
267 ASSERT(uType < TYPE_CTYPES);
268
269 pEntry = GetUser32Handle(handle);
270
271 if (pEntry && uType == 0)
272 uType = pEntry->type;
273
274 // Must have an entry and must be the same type!
275 if ( (!pEntry) ||
276 (pEntry->type != uType) ||
277 !pEntry->ptr ||
278 (pEntry->flags & HANDLEENTRY_DESTROY) || (pEntry->flags & HANDLEENTRY_INDESTROY) )
279 {
280 switch ( uType )
281 { // Test (with wine too) confirms these results!
282 case TYPE_WINDOW:
283 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
284 break;
285 case TYPE_MENU:
286 SetLastError(ERROR_INVALID_MENU_HANDLE);
287 break;
288 case TYPE_CURSOR:
289 SetLastError(ERROR_INVALID_CURSOR_HANDLE);
290 break;
291 case TYPE_SETWINDOWPOS:
292 SetLastError(ERROR_INVALID_DWP_HANDLE);
293 break;
294 case TYPE_HOOK:
295 SetLastError(ERROR_INVALID_HOOK_HANDLE);
296 break;
297 case TYPE_ACCELTABLE:
298 SetLastError(ERROR_INVALID_ACCEL_HANDLE);
299 break;
300 default:
301 SetLastError(ERROR_INVALID_HANDLE);
302 break;
303 }
304 return NULL;
305 }
306
307 if (g_ObjectHeapTypeShared[uType])
308 ret = SharedPtrToUser(pEntry->ptr);
309 else
310 ret = DesktopPtrToUser(pEntry->ptr);
311
312 return ret;
313 }
314
315 //
316 // Validate Handle and return the pointer to the object.
317 //
318 PVOID
319 FASTCALL
320 ValidateHandleNoErr(HANDLE handle, UINT uType)
321 {
322 PVOID ret;
323 PUSER_HANDLE_ENTRY pEntry;
324
325 ASSERT(uType < TYPE_CTYPES);
326
327 pEntry = GetUser32Handle(handle);
328
329 if (pEntry && uType == 0)
330 uType = pEntry->type;
331
332 // Must have an entry and must be the same type!
333 if ( (!pEntry) || (pEntry->type != uType) || !pEntry->ptr )
334 return NULL;
335
336 if (g_ObjectHeapTypeShared[uType])
337 ret = SharedPtrToUser(pEntry->ptr);
338 else
339 ret = DesktopPtrToUser(pEntry->ptr);
340
341 return ret;
342 }
343
344 //
345 // Validate a callproc handle and return the pointer to the object.
346 //
347 PCALLPROCDATA
348 FASTCALL
349 ValidateCallProc(HANDLE hCallProc)
350 {
351 PUSER_HANDLE_ENTRY pEntry;
352
353 PCALLPROCDATA CallProc = ValidateHandle(hCallProc, TYPE_CALLPROC);
354
355 pEntry = GetUser32Handle(hCallProc);
356
357 if (CallProc != NULL && pEntry->ppi == g_ppi)
358 return CallProc;
359
360 return NULL;
361 }
362
363
364 //
365 // Validate a window handle and return the pointer to the object.
366 //
367 PWND
368 FASTCALL
369 ValidateHwnd(HWND hwnd)
370 {
371 PCLIENTINFO ClientInfo = GetWin32ClientInfo();
372 ASSERT(ClientInfo != NULL);
373
374 /* See if the window is cached */
375 if (hwnd && hwnd == ClientInfo->CallbackWnd.hWnd)
376 return ClientInfo->CallbackWnd.pWnd;
377
378 return ValidateHandle((HANDLE)hwnd, TYPE_WINDOW);
379 }
380
381 //
382 // Validate a window handle and return the pointer to the object.
383 //
384 PWND
385 FASTCALL
386 ValidateHwndNoErr(HWND hwnd)
387 {
388 PWND Wnd;
389 PCLIENTINFO ClientInfo = GetWin32ClientInfo();
390 ASSERT(ClientInfo != NULL);
391
392 /* See if the window is cached */
393 if (hwnd == ClientInfo->CallbackWnd.hWnd)
394 return ClientInfo->CallbackWnd.pWnd;
395
396 Wnd = ValidateHandleNoErr((HANDLE)hwnd, TYPE_WINDOW);
397 if (Wnd != NULL)
398 {
399 return Wnd;
400 }
401
402 return NULL;
403 }
404
405 PWND
406 FASTCALL
407 GetThreadDesktopWnd(VOID)
408 {
409 PWND Wnd = GetThreadDesktopInfo()->spwnd;
410 if (Wnd != NULL)
411 Wnd = DesktopPtrToUser(Wnd);
412 return Wnd;
413 }
414
415 //
416 // Validate a window handle and return the pointer to the object.
417 //
418 PWND
419 FASTCALL
420 ValidateHwndOrDesk(HWND hwnd)
421 {
422 if (hwnd == HWND_DESKTOP)
423 return GetThreadDesktopWnd();
424
425 return ValidateHwnd(hwnd);
426 }
427
428 /*
429 * @implemented
430 */
431 DWORD WINAPI WCSToMBEx(WORD CodePage,LPWSTR UnicodeString,LONG UnicodeSize,LPSTR *MBString,LONG MBSize,BOOL Allocate)
432 {
433 DWORD Size;
434 if (UnicodeSize == -1)
435 {
436 UnicodeSize = wcslen(UnicodeString)+1;
437 }
438 if (MBSize == -1)
439 {
440 if (!Allocate)
441 {
442 return 0;
443 }
444 MBSize = UnicodeSize * 2;
445 }
446 if (Allocate)
447 {
448 LPSTR SafeString = RtlAllocateHeap(GetProcessHeap(), 0, MBSize);
449 if (SafeString == NULL)
450 return 0;
451 *MBString = SafeString;
452 }
453 if (CodePage == 0)
454 {
455 RtlUnicodeToMultiByteN(*MBString,MBSize,&Size,UnicodeString,UnicodeSize);
456 }
457 else
458 {
459 WideCharToMultiByte(CodePage,0,UnicodeString,UnicodeSize,*MBString,MBSize,0,0);
460 }
461 return UnicodeSize;
462 }
463
464 /*
465 * @implemented
466 */
467 DWORD WINAPI MBToWCSEx(WORD CodePage,LPSTR MBString,LONG MBSize,LPWSTR *UnicodeString,LONG UnicodeSize,BOOL Allocate)
468 {
469 DWORD Size;
470 if (MBSize == -1)
471 {
472 MBSize = strlen(MBString)+1;
473 }
474 if (UnicodeSize == -1)
475 {
476 if (!Allocate)
477 {
478 return 0;
479 }
480 UnicodeSize = MBSize;
481 }
482 if (Allocate)
483 {
484 LPWSTR SafeString = RtlAllocateHeap(GetProcessHeap(), 0, UnicodeSize);
485 if (SafeString == NULL)
486 return 0;
487 *UnicodeString = SafeString;
488 }
489 UnicodeSize *= sizeof(WCHAR);
490 if (CodePage == 0)
491 {
492 RtlMultiByteToUnicodeN(*UnicodeString,UnicodeSize,&Size,MBString,MBSize);
493 }
494 else
495 {
496 Size = MultiByteToWideChar(CodePage,0,MBString,MBSize,*UnicodeString,UnicodeSize);
497 }
498 return Size;
499 }