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