[Win32k|User32]
[reactos.git] / reactos / dll / win32 / user32 / misc / misc.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4 *
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.
9 *
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.
14 *
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.
18 */
19 /*
20 * PROJECT: ReactOS user32.dll
21 * FILE: lib/user32/misc/misc.c
22 * PURPOSE: Misc
23 * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
24 * UPDATE HISTORY:
25 * 19-11-2003 Created
26 */
27
28 /* INCLUDES ******************************************************************/
29
30 #include <user32.h>
31
32 #include <wine/debug.h>
33
34 WINE_DEFAULT_DEBUG_CHANNEL(user32);
35
36 /* FUNCTIONS *****************************************************************/
37
38 /*
39 * @implemented
40 */
41 BOOL
42 WINAPI
43 RegisterLogonProcess(DWORD dwProcessId, BOOL bRegister)
44 {
45 return NtUserCallTwoParam(dwProcessId,
46 (DWORD_PTR)bRegister,
47 TWOPARAM_ROUTINE_REGISTERLOGONPROC);
48 }
49
50 /*
51 * @implemented
52 */
53 BOOL
54 WINAPI
55 SetLogonNotifyWindow (HWND Wnd, HWINSTA WinSta)
56 {
57 /* Maybe we should call NtUserSetLogonNotifyWindow and let that one inform CSRSS??? */
58 CSR_API_MESSAGE Request;
59 ULONG CsrRequest;
60 NTSTATUS Status;
61
62 CsrRequest = MAKE_CSR_API(SET_LOGON_NOTIFY_WINDOW, CSR_GUI);
63 Request.Data.SetLogonNotifyWindowRequest.LogonNotifyWindow = Wnd;
64
65 Status = CsrClientCallServer(&Request,
66 NULL,
67 CsrRequest,
68 sizeof(CSR_API_MESSAGE));
69 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
70 {
71 SetLastError(RtlNtStatusToDosError(Status));
72 return(FALSE);
73 }
74
75 return(TRUE);
76 }
77
78 /*
79 * @implemented
80 */
81 BOOL WINAPI
82 UpdatePerUserSystemParameters(
83 DWORD dwReserved,
84 BOOL bEnable)
85 {
86 return NtUserUpdatePerUserSystemParameters(dwReserved, bEnable);
87 }
88
89 PTHREADINFO
90 GetW32ThreadInfo(VOID)
91 {
92 PTHREADINFO ti;
93
94 ti = (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo;
95 if (ti == NULL)
96 {
97 /* create the THREADINFO structure */
98 NtUserGetThreadState(THREADSTATE_GETTHREADINFO);
99 ti = (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo;
100 }
101
102 return ti;
103 }
104
105
106 /*
107 * GetUserObjectSecurity
108 *
109 * Retrieves security information for user object specified
110 * with handle 'hObject'. Descriptor returned in self-relative
111 * format.
112 *
113 * Arguments:
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
119 *
120 * Return Vaules:
121 * TRUE on success
122 * FALSE on failure, call GetLastError() for more information
123 */
124 /*
125 * @implemented
126 */
127 BOOL
128 WINAPI
129 GetUserObjectSecurity(
130 IN HANDLE hObject,
131 IN PSECURITY_INFORMATION pSecurityInfo,
132 OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
133 IN DWORD dwLength,
134 OUT PDWORD pdwLengthNeeded
135 )
136 {
137 DWORD dwWin32Error;
138 NTSTATUS Status;
139
140
141 Status = NtQuerySecurityObject(
142 hObject, // Object Handle
143 *pSecurityInfo, // Security Information
144 pSecurityDescriptor,// Security Descriptor
145 dwLength, // Buffer Length
146 pdwLengthNeeded // Actual Length
147 );
148
149 if ( ! NT_SUCCESS( Status ) ) {
150 dwWin32Error = RtlNtStatusToDosError( Status );
151 NtCurrentTeb()->LastErrorValue = dwWin32Error;
152 return FALSE;
153 }
154
155 return TRUE;
156 }
157
158
159 /*
160 * SetUserObjectSecurity
161 *
162 * Sets new security descriptor to user object specified by
163 * handle 'hObject'. Descriptor must be in self-relative format.
164 *
165 * Arguments:
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
169 *
170 * Return Vaules:
171 * TRUE on success
172 * FALSE on failure, call GetLastError() for more information
173 */
174 /*
175 * @implemented
176 */
177 BOOL
178 WINAPI
179 SetUserObjectSecurity(
180 IN HANDLE hObject,
181 IN PSECURITY_INFORMATION pSecurityInfo,
182 IN PSECURITY_DESCRIPTOR pSecurityDescriptor
183 )
184 {
185 DWORD dwWin32Error;
186 NTSTATUS Status;
187
188
189 Status = NtSetSecurityObject(
190 hObject, // Object Handle
191 *pSecurityInfo, // Security Information
192 pSecurityDescriptor // Security Descriptor
193 );
194
195 if ( ! NT_SUCCESS( Status ) ) {
196 dwWin32Error = RtlNtStatusToDosError( Status );
197 NtCurrentTeb()->LastErrorValue = dwWin32Error;
198 return FALSE;
199 }
200
201 return TRUE;
202 }
203
204 /*
205 * @implemented
206 */
207 BOOL
208 WINAPI
209 EndTask(
210 HWND hWnd,
211 BOOL fShutDown,
212 BOOL fForce)
213 {
214 SendMessageW(hWnd, WM_CLOSE, 0, 0);
215
216 if (IsWindow(hWnd))
217 {
218 if (fForce)
219 return DestroyWindow(hWnd);
220 else
221 return FALSE;
222 }
223
224 return TRUE;
225 }
226
227 /*
228 * @implemented
229 */
230 BOOL
231 WINAPI
232 IsGUIThread(
233 BOOL bConvert)
234 {
235 PTHREADINFO ti = (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo;
236 if (ti == NULL)
237 {
238 if(bConvert)
239 {
240 NtUserGetThreadState(THREADSTATE_GETTHREADINFO);
241 if ((PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo) return TRUE;
242 else
243 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
244 }
245 return FALSE;
246 }
247 else
248 return TRUE;
249 }
250
251 BOOL
252 FASTCALL
253 TestWindowProcess(PWND Wnd)
254 {
255 if (Wnd->head.pti == (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo)
256 return TRUE;
257 else
258 return (NtUserQueryWindow(Wnd->head.h, QUERY_WINDOW_UNIQUE_PROCESS_ID) ==
259 (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess );
260 }
261
262 BOOL
263 FASTCALL
264 IsMetaFile(HDC hDc)
265 {
266 DWORD Type = GetObjectType((HGDIOBJ) hDc);
267 switch(Type)
268 {
269 case OBJ_METADC:
270 case OBJ_METAFILE:
271 case OBJ_ENHMETADC:
272 case OBJ_ENHMETAFILE:
273 return TRUE;
274 }
275 return FALSE;
276 }
277
278 PUSER_HANDLE_ENTRY
279 FASTCALL
280 GetUser32Handle(HANDLE handle)
281 {
282 INT Index;
283 USHORT generation;
284
285 Index = (((UINT_PTR)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
286
287 if (Index < 0 || Index >= gHandleTable->nb_handles)
288 return NULL;
289
290 if (!gHandleEntries[Index].type || !gHandleEntries[Index].ptr)
291 return NULL;
292
293 generation = (UINT_PTR)handle >> 16;
294
295 if (generation == gHandleEntries[Index].generation || !generation || generation == 0xffff)
296 return &gHandleEntries[Index];
297
298 return NULL;
299 }
300
301 /*
302 * Decide whether an object is located on the desktop or shared heap
303 */
304 static const BOOL g_ObjectHeapTypeShared[VALIDATE_TYPE_EVENT + 1] =
305 {
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 */
322 };
323
324 //
325 // Validate Handle and return the pointer to the object.
326 //
327 PVOID
328 FASTCALL
329 ValidateHandle(HANDLE handle, UINT uType)
330 {
331 PVOID ret;
332 PUSER_HANDLE_ENTRY pEntry;
333
334 ASSERT(uType <= VALIDATE_TYPE_EVENT);
335
336 pEntry = GetUser32Handle(handle);
337
338 if (pEntry && uType == 0)
339 uType = pEntry->type;
340
341 // Must have an entry and must be the same type!
342 if ( (!pEntry) ||
343 (pEntry->type != uType) ||
344 !pEntry->ptr ||
345 (pEntry->flags & HANDLEENTRY_INDESTROY) )
346 {
347 switch ( uType )
348 { // Test (with wine too) confirms these results!
349 case VALIDATE_TYPE_WIN:
350 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
351 break;
352 case VALIDATE_TYPE_MENU:
353 SetLastError(ERROR_INVALID_MENU_HANDLE);
354 break;
355 case VALIDATE_TYPE_CURSOR:
356 SetLastError(ERROR_INVALID_CURSOR_HANDLE);
357 break;
358 case VALIDATE_TYPE_MWPOS:
359 SetLastError(ERROR_INVALID_DWP_HANDLE);
360 break;
361 case VALIDATE_TYPE_HOOK:
362 SetLastError(ERROR_INVALID_HOOK_HANDLE);
363 break;
364 case VALIDATE_TYPE_ACCEL:
365 SetLastError(ERROR_INVALID_ACCEL_HANDLE);
366 break;
367 default:
368 SetLastError(ERROR_INVALID_HANDLE);
369 break;
370 }
371 return NULL;
372 }
373
374 if (g_ObjectHeapTypeShared[uType])
375 ret = SharedPtrToUser(pEntry->ptr);
376 else
377 ret = DesktopPtrToUser(pEntry->ptr);
378
379 return ret;
380 }
381
382 //
383 // Validate Handle and return the pointer to the object.
384 //
385 PVOID
386 FASTCALL
387 ValidateHandleNoErr(HANDLE handle, UINT uType)
388 {
389 PVOID ret;
390 PUSER_HANDLE_ENTRY pEntry;
391
392 ASSERT(uType <= VALIDATE_TYPE_EVENT);
393
394 pEntry = GetUser32Handle(handle);
395
396 if (pEntry && uType == 0)
397 uType = pEntry->type;
398
399 // Must have an entry and must be the same type!
400 if ( (!pEntry) || (pEntry->type != uType) || !pEntry->ptr )
401 return NULL;
402
403 if (g_ObjectHeapTypeShared[uType])
404 ret = SharedPtrToUser(pEntry->ptr);
405 else
406 ret = DesktopPtrToUser(pEntry->ptr);
407
408 return ret;
409 }
410
411 //
412 // Validate a callproc handle and return the pointer to the object.
413 //
414 PCALLPROCDATA
415 FASTCALL
416 ValidateCallProc(HANDLE hCallProc)
417 {
418 PUSER_HANDLE_ENTRY pEntry;
419
420 PCALLPROCDATA CallProc = ValidateHandle(hCallProc, VALIDATE_TYPE_CALLPROC);
421
422 pEntry = GetUser32Handle(hCallProc);
423
424 if (CallProc != NULL && pEntry->ppi == g_ppi)
425 return CallProc;
426
427 return NULL;
428 }
429
430
431 //
432 // Validate a window handle and return the pointer to the object.
433 //
434 PWND
435 FASTCALL
436 ValidateHwnd(HWND hwnd)
437 {
438 PWND Wnd;
439 PCLIENTINFO ClientInfo = GetWin32ClientInfo();
440 ASSERT(ClientInfo != NULL);
441
442 /* See if the window is cached */
443 if (hwnd == ClientInfo->CallbackWnd.hWnd)
444 return ClientInfo->CallbackWnd.pWnd;
445
446 Wnd = ValidateHandle((HANDLE)hwnd, VALIDATE_TYPE_WIN);
447 if (Wnd != NULL)
448 {
449 return Wnd;
450 }
451
452 return NULL;
453 }
454
455 //
456 // Validate a window handle and return the pointer to the object.
457 //
458 PWND
459 FASTCALL
460 ValidateHwndNoErr(HWND hwnd)
461 {
462 PWND Wnd;
463 PCLIENTINFO ClientInfo = GetWin32ClientInfo();
464 ASSERT(ClientInfo != NULL);
465
466 /* See if the window is cached */
467 if (hwnd == ClientInfo->CallbackWnd.hWnd)
468 return ClientInfo->CallbackWnd.pWnd;
469
470 Wnd = ValidateHandleNoErr((HANDLE)hwnd, VALIDATE_TYPE_WIN);
471 if (Wnd != NULL)
472 {
473 return Wnd;
474 }
475
476 return NULL;
477 }
478
479 PWND
480 FASTCALL
481 GetThreadDesktopWnd(VOID)
482 {
483 PWND Wnd = GetThreadDesktopInfo()->spwnd;
484 if (Wnd != NULL)
485 Wnd = DesktopPtrToUser(Wnd);
486 return Wnd;
487 }
488
489 //
490 // Validate a window handle and return the pointer to the object.
491 //
492 PWND
493 FASTCALL
494 ValidateHwndOrDesk(HWND hwnd)
495 {
496 if (hwnd == HWND_DESKTOP)
497 return GetThreadDesktopWnd();
498
499 return ValidateHwnd(hwnd);
500 }
501
502 /*
503 * @implemented
504 */
505 DWORD WINAPI WCSToMBEx(WORD CodePage,LPWSTR UnicodeString,LONG UnicodeSize,LPSTR *MBString,LONG MBSize,BOOL Allocate)
506 {
507 DWORD Size;
508 if (UnicodeSize == -1)
509 {
510 UnicodeSize = wcslen(UnicodeString)+1;
511 }
512 if (MBSize == -1)
513 {
514 if (!Allocate)
515 {
516 return 0;
517 }
518 MBSize = UnicodeSize * 2;
519 }
520 if (Allocate)
521 {
522 LPSTR SafeString = RtlAllocateHeap(GetProcessHeap(), 0, MBSize);
523 if (SafeString == NULL)
524 return 0;
525 *MBString = SafeString;
526 }
527 if (CodePage == 0)
528 {
529 RtlUnicodeToMultiByteN(*MBString,MBSize,&Size,UnicodeString,UnicodeSize);
530 }
531 else
532 {
533 WideCharToMultiByte(CodePage,0,UnicodeString,UnicodeSize,*MBString,MBSize,0,0);
534 }
535 return UnicodeSize;
536 }
537
538 /*
539 * @implemented
540 */
541 DWORD WINAPI MBToWCSEx(WORD CodePage,LPSTR MBString,LONG MBSize,LPWSTR *UnicodeString,LONG UnicodeSize,BOOL Allocate)
542 {
543 DWORD Size;
544 if (MBSize == -1)
545 {
546 MBSize = strlen(MBString)+1;
547 }
548 if (UnicodeSize == -1)
549 {
550 if (!Allocate)
551 {
552 return 0;
553 }
554 UnicodeSize = MBSize;
555 }
556 if (Allocate)
557 {
558 LPWSTR SafeString = RtlAllocateHeap(GetProcessHeap(), 0, UnicodeSize);
559 if (SafeString == NULL)
560 return 0;
561 *UnicodeString = SafeString;
562 }
563 UnicodeSize *= sizeof(WCHAR);
564 if (CodePage == 0)
565 {
566 RtlMultiByteToUnicodeN(*UnicodeString,UnicodeSize,&Size,MBString,MBSize);
567 }
568 else
569 {
570 Size = MultiByteToWideChar(CodePage,0,MBString,MBSize,*UnicodeString,UnicodeSize);
571 }
572 return Size;
573 }