Prevent from crashing/hanging in Windows 95 OSR2.
[wine] / windows / user.c
1 /*
2  * Misc. USER functions
3  *
4  * Copyright 1993 Robert J. Amstadt
5  *           1996 Alex Korobka
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include "wine/winbase16.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "wine/winuser16.h"
31 #include "winreg.h"
32 #include "winternl.h"
33 #include "user.h"
34 #include "win.h"
35 #include "controls.h"
36 #include "cursoricon.h"
37 #include "message.h"
38 #include "local.h"
39 #include "wine/debug.h"
40
41 WINE_DEFAULT_DEBUG_CHANNEL(user);
42
43 static SYSLEVEL USER_SysLevel;
44 static CRITICAL_SECTION_DEBUG critsect_debug =
45 {
46     0, 0, &USER_SysLevel.crst,
47     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
48       0, 0, { 0, (DWORD)(__FILE__ ": USER_SysLevel") }
49 };
50 static SYSLEVEL USER_SysLevel = { { &critsect_debug, -1, 0, 0, 0, 0 }, 2 };
51
52 /* USER signal proc flags and codes */
53 /* See UserSignalProc for comments */
54 #define USIG_FLAGS_WIN32          0x0001
55 #define USIG_FLAGS_GUI            0x0002
56 #define USIG_FLAGS_FEEDBACK       0x0004
57 #define USIG_FLAGS_FAULT          0x0008
58
59 #define USIG_DLL_UNLOAD_WIN16     0x0001
60 #define USIG_DLL_UNLOAD_WIN32     0x0002
61 #define USIG_FAULT_DIALOG_PUSH    0x0003
62 #define USIG_FAULT_DIALOG_POP     0x0004
63 #define USIG_DLL_UNLOAD_ORPHANS   0x0005
64 #define USIG_THREAD_INIT          0x0010
65 #define USIG_THREAD_EXIT          0x0020
66 #define USIG_PROCESS_CREATE       0x0100
67 #define USIG_PROCESS_INIT         0x0200
68 #define USIG_PROCESS_EXIT         0x0300
69 #define USIG_PROCESS_DESTROY      0x0400
70 #define USIG_PROCESS_RUNNING      0x0500
71 #define USIG_PROCESS_LOADED       0x0600
72
73
74 /***********************************************************************
75  *              GetFreeSystemResources (USER.284)
76  */
77 WORD WINAPI GetFreeSystemResources16( WORD resType )
78 {
79     HINSTANCE16 gdi_inst;
80     WORD gdi_heap;
81     int userPercent, gdiPercent;
82
83     if ((gdi_inst = LoadLibrary16( "GDI" )) < 32) return 0;
84     gdi_heap = gdi_inst | 7;
85
86     switch(resType)
87     {
88     case GFSR_USERRESOURCES:
89         userPercent = (int)LOCAL_CountFree( USER_HeapSel ) * 100 /
90                                LOCAL_HeapSize( USER_HeapSel );
91         gdiPercent  = 100;
92         break;
93
94     case GFSR_GDIRESOURCES:
95         gdiPercent  = (int)LOCAL_CountFree( gdi_inst ) * 100 /
96                                LOCAL_HeapSize( gdi_inst );
97         userPercent = 100;
98         break;
99
100     case GFSR_SYSTEMRESOURCES:
101         userPercent = (int)LOCAL_CountFree( USER_HeapSel ) * 100 /
102                                LOCAL_HeapSize( USER_HeapSel );
103         gdiPercent  = (int)LOCAL_CountFree( gdi_inst ) * 100 /
104                                LOCAL_HeapSize( gdi_inst );
105         break;
106
107     default:
108         userPercent = gdiPercent = 0;
109         break;
110     }
111     FreeLibrary16( gdi_inst );
112     TRACE("<- userPercent %d, gdiPercent %d\n", userPercent, gdiPercent);
113     return (WORD)min( userPercent, gdiPercent );
114 }
115
116
117 /**********************************************************************
118  *              InitApp (USER.5)
119  */
120 INT16 WINAPI InitApp16( HINSTANCE16 hInstance )
121 {
122     /* Create task message queue */
123     if ( !InitThreadInput16( 0, 0 ) ) return 0;
124
125     return 1;
126 }
127
128
129 /***********************************************************************
130  *           USER_Lock
131  */
132 void USER_Lock(void)
133 {
134     _EnterSysLevel( &USER_SysLevel );
135 }
136
137
138 /***********************************************************************
139  *           USER_Unlock
140  */
141 void USER_Unlock(void)
142 {
143     _LeaveSysLevel( &USER_SysLevel );
144 }
145
146
147 /***********************************************************************
148  *           USER_CheckNotLock
149  *
150  * Make sure that we don't hold the user lock.
151  */
152 void USER_CheckNotLock(void)
153 {
154     _CheckNotSysLevel( &USER_SysLevel );
155 }
156
157
158 /***********************************************************************
159  *           WIN_SuspendWndsLock
160  *
161  * Suspend the lock on WND structures.
162  * Returns the number of locks suspended
163  * FIXME: should be removed
164  */
165 int WIN_SuspendWndsLock( void )
166 {
167     int isuspendedLocks = _ConfirmSysLevel( &USER_SysLevel );
168     int count = isuspendedLocks;
169
170     while ( count-- > 0 )
171         _LeaveSysLevel( &USER_SysLevel );
172
173     return isuspendedLocks;
174 }
175
176 /***********************************************************************
177  *           WIN_RestoreWndsLock
178  *
179  * Restore the suspended locks on WND structures
180  * FIXME: should be removed
181  */
182 void WIN_RestoreWndsLock( int ipreviousLocks )
183 {
184     while ( ipreviousLocks-- > 0 )
185         _EnterSysLevel( &USER_SysLevel );
186 }
187
188 /***********************************************************************
189  *              FinalUserInit (USER.400)
190  */
191 void WINAPI FinalUserInit16( void )
192 {
193     /* FIXME: Should chain to FinalGdiInit now. */
194 }
195
196 /***********************************************************************
197  *              SignalProc32 (USER.391)
198  *              UserSignalProc (USER32.@)
199  *
200  * The exact meaning of the USER signals is undocumented, but this
201  * should cover the basic idea:
202  *
203  * USIG_DLL_UNLOAD_WIN16
204  *     This is sent when a 16-bit module is unloaded.
205  *
206  * USIG_DLL_UNLOAD_WIN32
207  *     This is sent when a 32-bit module is unloaded.
208  *
209  * USIG_DLL_UNLOAD_ORPHANS
210  *     This is sent after the last Win3.1 module is unloaded,
211  *     to allow removal of orphaned menus.
212  *
213  * USIG_FAULT_DIALOG_PUSH
214  * USIG_FAULT_DIALOG_POP
215  *     These are called to allow USER to prepare for displaying a
216  *     fault dialog, even though the fault might have happened while
217  *     inside a USER critical section.
218  *
219  * USIG_THREAD_INIT
220  *     This is called from the context of a new thread, as soon as it
221  *     has started to run.
222  *
223  * USIG_THREAD_EXIT
224  *     This is called, still in its context, just before a thread is
225  *     about to terminate.
226  *
227  * USIG_PROCESS_CREATE
228  *     This is called, in the parent process context, after a new process
229  *     has been created.
230  *
231  * USIG_PROCESS_INIT
232  *     This is called in the new process context, just after the main thread
233  *     has started execution (after the main thread's USIG_THREAD_INIT has
234  *     been sent).
235  *
236  * USIG_PROCESS_LOADED
237  *     This is called after the executable file has been loaded into the
238  *     new process context.
239  *
240  * USIG_PROCESS_RUNNING
241  *     This is called immediately before the main entry point is called.
242  *
243  * USIG_PROCESS_EXIT
244  *     This is called in the context of a process that is about to
245  *     terminate (but before the last thread's USIG_THREAD_EXIT has
246  *     been sent).
247  *
248  * USIG_PROCESS_DESTROY
249  *     This is called after a process has terminated.
250  *
251  *
252  * The meaning of the dwFlags bits is as follows:
253  *
254  * USIG_FLAGS_WIN32
255  *     Current process is 32-bit.
256  *
257  * USIG_FLAGS_GUI
258  *     Current process is a (Win32) GUI process.
259  *
260  * USIG_FLAGS_FEEDBACK
261  *     Current process needs 'feedback' (determined from the STARTUPINFO
262  *     flags STARTF_FORCEONFEEDBACK / STARTF_FORCEOFFFEEDBACK).
263  *
264  * USIG_FLAGS_FAULT
265  *     The signal is being sent due to a fault.
266  */
267 WORD WINAPI UserSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
268                             DWORD dwFlags, HMODULE16 hModule )
269 {
270     FIXME("(%04x, %08lx, %04lx, %04x)\n",
271           uCode, dwThreadOrProcessID, dwFlags, hModule );
272     /* FIXME: Should chain to GdiSignalProc now. */
273     return 0;
274 }
275
276 /***********************************************************************
277  *              ExitWindows (USER.7)
278  */
279 BOOL16 WINAPI ExitWindows16( DWORD dwReturnCode, UINT16 wReserved )
280 {
281     return ExitWindowsEx( EWX_LOGOFF, 0xffffffff );
282 }
283
284
285 /***********************************************************************
286  *              ExitWindowsExec (USER.246)
287  */
288 BOOL16 WINAPI ExitWindowsExec16( LPCSTR lpszExe, LPCSTR lpszParams )
289 {
290     TRACE("Should run the following in DOS-mode: \"%s %s\"\n",
291           lpszExe, lpszParams);
292     return ExitWindowsEx( EWX_LOGOFF, 0xffffffff );
293 }
294
295
296 /***********************************************************************
297  *              ExitWindowsEx (USER32.@)
298  */
299 BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reserved )
300 {
301     int i;
302     BOOL result;
303     HWND *list, *phwnd;
304
305     /* We have to build a list of all windows first, as in EnumWindows */
306
307     if (!(list = WIN_ListChildren( GetDesktopWindow() ))) return FALSE;
308
309     /* Send a WM_QUERYENDSESSION message to every window */
310
311     for (i = 0; list[i]; i++)
312     {
313         /* Make sure that the window still exists */
314         if (!IsWindow( list[i] )) continue;
315         if (!SendMessageW( list[i], WM_QUERYENDSESSION, 0, 0 )) break;
316     }
317     result = !list[i];
318
319     /* Now notify all windows that got a WM_QUERYENDSESSION of the result */
320
321     for (phwnd = list; i > 0; i--, phwnd++)
322     {
323         if (!IsWindow( *phwnd )) continue;
324         SendMessageW( *phwnd, WM_ENDSESSION, result, 0 );
325     }
326     HeapFree( GetProcessHeap(), 0, list );
327
328     if (result) ExitKernel16();
329     return TRUE;
330 }
331
332 /***********************************************************************
333  *              ChangeDisplaySettingsA (USER32.@)
334  */
335 LONG WINAPI ChangeDisplaySettingsA( LPDEVMODEA devmode, DWORD flags )
336 {
337   return ChangeDisplaySettingsExA(NULL,devmode,NULL,flags,NULL);
338 }
339
340 /***********************************************************************
341  *              ChangeDisplaySettingsW (USER32.@)
342  */
343 LONG WINAPI ChangeDisplaySettingsW( LPDEVMODEW devmode, DWORD flags )
344 {
345   return ChangeDisplaySettingsExW(NULL,devmode,NULL,flags,NULL);
346 }
347
348 /***********************************************************************
349  *              ChangeDisplaySettings (USER.620)
350  */
351 LONG WINAPI ChangeDisplaySettings16( LPDEVMODEA devmode, DWORD flags )
352 {
353         return ChangeDisplaySettingsA(devmode, flags);
354 }
355
356 /***********************************************************************
357  *              ChangeDisplaySettingsExA (USER32.@)
358  */
359 LONG WINAPI ChangeDisplaySettingsExA(
360         LPCSTR devname, LPDEVMODEA devmode, HWND hwnd, DWORD flags,
361         LPVOID lparam
362 ) {
363     DEVMODEW devmodeW;
364     LONG ret;
365     UNICODE_STRING nameW;
366
367     if (devname) RtlCreateUnicodeStringFromAsciiz(&nameW, devname);
368     else nameW.Buffer = NULL;
369
370     if (devmode)
371     {
372         devmodeW.dmBitsPerPel       = devmode->dmBitsPerPel;
373         devmodeW.dmPelsHeight       = devmode->dmPelsHeight;
374         devmodeW.dmPelsWidth        = devmode->dmPelsWidth;
375         devmodeW.dmDisplayFlags     = devmode->dmDisplayFlags;
376         devmodeW.dmDisplayFrequency = devmode->dmDisplayFrequency;
377         devmodeW.dmFields           = devmode->dmFields;
378         ret = ChangeDisplaySettingsExW(nameW.Buffer, &devmodeW, hwnd, flags, lparam);
379     }
380     else
381     {
382         ret = ChangeDisplaySettingsExW(nameW.Buffer, NULL, hwnd, flags, lparam);
383     }
384
385     if (devname) RtlFreeUnicodeString(&nameW);
386     return ret;
387 }
388
389 /***********************************************************************
390  *              ChangeDisplaySettingsExW (USER32.@)
391  */
392 LONG WINAPI ChangeDisplaySettingsExW( LPCWSTR devname, LPDEVMODEW devmode, HWND hwnd,
393                                       DWORD flags, LPVOID lparam )
394 {
395     /* Pass the request on to the driver */
396     if (!USER_Driver.pChangeDisplaySettingsExW) return DISP_CHANGE_FAILED;
397     return USER_Driver.pChangeDisplaySettingsExW( devname, devmode, hwnd, flags, lparam );
398 }
399
400 /***********************************************************************
401  *              EnumDisplaySettingsW (USER32.@)
402  *
403  * RETURNS
404  *      TRUE if nth setting exists found (described in the LPDEVMODEW struct)
405  *      FALSE if we do not have the nth setting
406  */
407 BOOL WINAPI EnumDisplaySettingsW(
408         LPCWSTR name,           /* [in] huh? */
409         DWORD n,                /* [in] nth entry in display settings list*/
410         LPDEVMODEW devmode      /* [out] devmode for that setting */
411 ) {
412     return EnumDisplaySettingsExW(name, n, devmode, 0);
413 }
414
415 /***********************************************************************
416  *              EnumDisplaySettingsA (USER32.@)
417  */
418 BOOL WINAPI EnumDisplaySettingsA(LPCSTR name,DWORD n,LPDEVMODEA devmode)
419 {
420     return EnumDisplaySettingsExA(name, n, devmode, 0);
421 }
422
423 /***********************************************************************
424  *              EnumDisplaySettings (USER.621)
425  */
426 BOOL16 WINAPI EnumDisplaySettings16(
427         LPCSTR name,            /* [in] huh? */
428         DWORD n,                /* [in] nth entry in display settings list*/
429         LPDEVMODEA devmode      /* [out] devmode for that setting */
430 ) {
431         return (BOOL16)EnumDisplaySettingsA(name, n, devmode);
432 }
433
434 /***********************************************************************
435  *              EnumDisplaySettingsExA (USER32.@)
436  */
437 BOOL WINAPI EnumDisplaySettingsExA(LPCSTR lpszDeviceName, DWORD iModeNum,
438                                    LPDEVMODEA lpDevMode, DWORD dwFlags)
439 {
440     DEVMODEW devmodeW;
441     BOOL ret;
442     UNICODE_STRING nameW;
443
444     if (lpszDeviceName) RtlCreateUnicodeStringFromAsciiz(&nameW, lpszDeviceName);
445     else nameW.Buffer = NULL;
446
447     ret = EnumDisplaySettingsExW(nameW.Buffer,iModeNum,&devmodeW,dwFlags);
448     if (ret)
449     {
450         lpDevMode->dmBitsPerPel       = devmodeW.dmBitsPerPel;
451         lpDevMode->dmPelsHeight       = devmodeW.dmPelsHeight;
452         lpDevMode->dmPelsWidth        = devmodeW.dmPelsWidth;
453         lpDevMode->dmDisplayFlags     = devmodeW.dmDisplayFlags;
454         lpDevMode->dmDisplayFrequency = devmodeW.dmDisplayFrequency;
455         lpDevMode->dmFields           = devmodeW.dmFields;
456     }
457     if (lpszDeviceName) RtlFreeUnicodeString(&nameW);
458     return ret;
459 }
460
461 /***********************************************************************
462  *              EnumDisplaySettingsExW (USER32.@)
463  */
464 BOOL WINAPI EnumDisplaySettingsExW(LPCWSTR lpszDeviceName, DWORD iModeNum,
465                                    LPDEVMODEW lpDevMode, DWORD dwFlags)
466 {
467     /* Pass the request on to the driver */
468     if (!USER_Driver.pEnumDisplaySettingsExW) return FALSE;
469     return USER_Driver.pEnumDisplaySettingsExW(lpszDeviceName, iModeNum, lpDevMode, dwFlags);
470 }
471
472 /***********************************************************************
473  *              EnumDisplayDevicesA (USER32.@)
474  */
475 BOOL WINAPI EnumDisplayDevicesA(
476         LPVOID unused,DWORD i,LPDISPLAY_DEVICEA lpDisplayDevice,DWORD dwFlags
477 ) {
478         if (i)
479                 return FALSE;
480         FIXME("(%p,%ld,%p,0x%08lx), stub!\n",unused,i,lpDisplayDevice,dwFlags);
481         strcpy(lpDisplayDevice->DeviceName,"X11");
482         strcpy(lpDisplayDevice->DeviceString,"X 11 Windowing System");
483         lpDisplayDevice->StateFlags =
484                         DISPLAY_DEVICE_ATTACHED_TO_DESKTOP      |
485                         DISPLAY_DEVICE_PRIMARY_DEVICE           |
486                         DISPLAY_DEVICE_VGA_COMPATIBLE;
487         return TRUE;
488 }
489
490 /***********************************************************************
491  *              EnumDisplayDevicesW (USER32.@)
492  */
493 BOOL WINAPI EnumDisplayDevicesW(
494         LPVOID unused,DWORD i,LPDISPLAY_DEVICEW lpDisplayDevice,DWORD dwFlags
495 ) {
496         if (i)
497                 return FALSE;
498         FIXME("(%p,%ld,%p,0x%08lx), stub!\n",unused,i,lpDisplayDevice,dwFlags);
499         MultiByteToWideChar( CP_ACP, 0, "X11", -1, lpDisplayDevice->DeviceName,
500                              sizeof(lpDisplayDevice->DeviceName)/sizeof(WCHAR) );
501         MultiByteToWideChar( CP_ACP, 0, "X11 Windowing System", -1, lpDisplayDevice->DeviceString,
502                              sizeof(lpDisplayDevice->DeviceString)/sizeof(WCHAR) );
503         lpDisplayDevice->StateFlags =
504                         DISPLAY_DEVICE_ATTACHED_TO_DESKTOP      |
505                         DISPLAY_DEVICE_PRIMARY_DEVICE           |
506                         DISPLAY_DEVICE_VGA_COMPATIBLE;
507         return TRUE;
508 }
509
510 /***********************************************************************
511  *              SetEventHook (USER.321)
512  *
513  *      Used by Turbo Debugger for Windows
514  */
515 FARPROC16 WINAPI SetEventHook16(FARPROC16 lpfnEventHook)
516 {
517         FIXME("(lpfnEventHook=%08x): stub\n", (UINT)lpfnEventHook);
518         return NULL;
519 }
520
521 /***********************************************************************
522  *              UserSeeUserDo (USER.216)
523  */
524 DWORD WINAPI UserSeeUserDo16(WORD wReqType, WORD wParam1, WORD wParam2, WORD wParam3)
525 {
526     switch (wReqType)
527     {
528     case USUD_LOCALALLOC:
529         return LOCAL_Alloc(USER_HeapSel, wParam1, wParam3);
530     case USUD_LOCALFREE:
531         return LOCAL_Free(USER_HeapSel, wParam1);
532     case USUD_LOCALCOMPACT:
533         return LOCAL_Compact(USER_HeapSel, wParam3, 0);
534     case USUD_LOCALHEAP:
535         return USER_HeapSel;
536     case USUD_FIRSTCLASS:
537         FIXME("return a pointer to the first window class.\n");
538         return (DWORD)-1;
539     default:
540         WARN("wReqType %04x (unknown)\n", wReqType);
541         return (DWORD)-1;
542     }
543 }
544
545 /***********************************************************************
546  *              GetSystemDebugState (USER.231)
547  */
548 WORD WINAPI GetSystemDebugState16(void)
549 {
550     return 0;  /* FIXME */
551 }
552
553 /***********************************************************************
554  *              RegisterLogonProcess (USER32.@)
555  */
556 DWORD WINAPI RegisterLogonProcess(HANDLE hprocess,BOOL x) {
557         FIXME("(%p,%d),stub!\n",hprocess,x);
558         return 1;
559 }
560
561 /***********************************************************************
562  *              CreateWindowStationW (USER32.@)
563  */
564 HWINSTA WINAPI CreateWindowStationW(
565         LPWSTR winstation,DWORD res1,DWORD desiredaccess,
566         LPSECURITY_ATTRIBUTES lpsa
567 ) {
568         FIXME("(%s,0x%08lx,0x%08lx,%p),stub!\n",debugstr_w(winstation),
569                 res1,desiredaccess,lpsa
570         );
571         return (HWINSTA)0xdeadcafe;
572 }
573
574 /***********************************************************************
575  *              SetProcessWindowStation (USER32.@)
576  */
577 BOOL WINAPI SetProcessWindowStation(HWINSTA hWinSta) {
578         FIXME("(%p),stub!\n",hWinSta);
579         return TRUE;
580 }
581
582 /***********************************************************************
583  *              SetUserObjectSecurity (USER32.@)
584  */
585 BOOL WINAPI SetUserObjectSecurity(
586         HANDLE hObj,
587         PSECURITY_INFORMATION pSIRequested,
588         PSECURITY_DESCRIPTOR pSID
589 ) {
590         FIXME("(%p,%p,%p),stub!\n",hObj,pSIRequested,pSID);
591         return TRUE;
592 }
593
594 /***********************************************************************
595  *              CreateDesktopA (USER32.@)
596  */
597 HDESK WINAPI CreateDesktopA(
598         LPSTR lpszDesktop,LPSTR lpszDevice,LPDEVMODEA pDevmode,
599         DWORD dwFlags,DWORD dwDesiredAccess,LPSECURITY_ATTRIBUTES lpsa
600 ) {
601         FIXME("(%s,%s,%p,0x%08lx,0x%08lx,%p),stub!\n",
602                 lpszDesktop,lpszDevice,pDevmode,
603                 dwFlags,dwDesiredAccess,lpsa
604         );
605         return (HDESK)0xcafedead;
606 }
607
608 /***********************************************************************
609  *              CreateDesktopW (USER32.@)
610  */
611 HDESK WINAPI CreateDesktopW(
612         LPWSTR lpszDesktop,LPWSTR lpszDevice,LPDEVMODEW pDevmode,
613         DWORD dwFlags,DWORD dwDesiredAccess,LPSECURITY_ATTRIBUTES lpsa
614 ) {
615         FIXME("(%s,%s,%p,0x%08lx,0x%08lx,%p),stub!\n",
616                 debugstr_w(lpszDesktop),debugstr_w(lpszDevice),pDevmode,
617                 dwFlags,dwDesiredAccess,lpsa
618         );
619         return (HDESK)0xcafedead;
620 }
621
622 /***********************************************************************
623  *              EnumDesktopWindows (USER32.@)
624  */
625 BOOL WINAPI EnumDesktopWindows( HDESK hDesktop, WNDENUMPROC lpfn, LPARAM lParam ) {
626   FIXME("(%p, %p, 0x%08lx), stub!\n", hDesktop, lpfn, lParam );
627   return TRUE;
628 }
629
630
631 /***********************************************************************
632  *              CloseWindowStation (USER32.@)
633  */
634 BOOL WINAPI CloseWindowStation(HWINSTA hWinSta)
635 {
636     FIXME("(%p)\n", hWinSta);
637     return TRUE;
638 }
639
640 /***********************************************************************
641  *              CloseDesktop (USER32.@)
642  */
643 BOOL WINAPI CloseDesktop(HDESK hDesk)
644 {
645     FIXME("(%p)\n", hDesk);
646     return TRUE;
647 }
648
649 /***********************************************************************
650  *              SetWindowStationUser (USER32.@)
651  */
652 DWORD WINAPI SetWindowStationUser(DWORD x1,DWORD x2) {
653         FIXME("(0x%08lx,0x%08lx),stub!\n",x1,x2);
654         return 1;
655 }
656
657 /***********************************************************************
658  *              SetLogonNotifyWindow (USER32.@)
659  */
660 DWORD WINAPI SetLogonNotifyWindow(HWINSTA hwinsta,HWND hwnd) {
661         FIXME("(%p,%p),stub!\n",hwinsta,hwnd);
662         return 1;
663 }
664
665 /***********************************************************************
666  *              LoadLocalFonts (USER32.@)
667  */
668 VOID WINAPI LoadLocalFonts(VOID) {
669         /* are loaded. */
670         return;
671 }
672 /***********************************************************************
673  *              GetUserObjectInformationA (USER32.@)
674  */
675 BOOL WINAPI GetUserObjectInformationA( HANDLE hObj, INT nIndex, LPVOID pvInfo, DWORD nLength, LPDWORD lpnLen )
676 {       FIXME("(%p %i %p %ld %p),stub!\n", hObj, nIndex, pvInfo, nLength, lpnLen );
677         return TRUE;
678 }
679 /***********************************************************************
680  *              GetUserObjectInformationW (USER32.@)
681  */
682 BOOL WINAPI GetUserObjectInformationW( HANDLE hObj, INT nIndex, LPVOID pvInfo, DWORD nLength, LPDWORD lpnLen )
683 {       FIXME("(%p %i %p %ld %p),stub!\n", hObj, nIndex, pvInfo, nLength, lpnLen );
684         return TRUE;
685 }
686 /***********************************************************************
687  *              GetUserObjectSecurity (USER32.@)
688  */
689 BOOL WINAPI GetUserObjectSecurity(HANDLE hObj, PSECURITY_INFORMATION pSIRequested,
690         PSECURITY_DESCRIPTOR pSID, DWORD nLength, LPDWORD lpnLengthNeeded)
691 {       FIXME("(%p %p %p len=%ld %p),stub!\n",  hObj, pSIRequested, pSID, nLength, lpnLengthNeeded);
692         return TRUE;
693 }
694
695 /***********************************************************************
696  *              SetSystemCursor (USER32.@)
697  */
698 BOOL WINAPI SetSystemCursor(HCURSOR hcur, DWORD id)
699 {       FIXME("(%p,%08lx),stub!\n",  hcur, id);
700         return TRUE;
701 }
702
703 /***********************************************************************
704  *              RegisterSystemThread (USER32.@)
705  */
706 void WINAPI RegisterSystemThread(DWORD flags, DWORD reserved)
707 {
708         FIXME("(%08lx, %08lx)\n", flags, reserved);
709 }
710
711 /***********************************************************************
712  *              RegisterDeviceNotificationA (USER32.@)
713  *
714  * See RegisterDeviceNotificationW.
715  */
716 HDEVNOTIFY WINAPI RegisterDeviceNotificationA(HANDLE hnd, LPVOID notifyfilter, DWORD flags)
717 {
718     FIXME("(hwnd=%p, filter=%p,flags=0x%08lx), STUB!\n", hnd,notifyfilter,flags );
719     return 0;
720 }
721
722 /***********************************************************************
723  *              RegisterDeviceNotificationW (USER32.@)
724  *
725  * Registers a window with the system so that it will receive
726  * notifications about a device.
727  *
728  * PARAMS
729  *     hRecepient           [I] Window or service status handle that
730  *                              will receive notifications.
731  *     pNotificationFilter  [I] DEV_BROADCAST_HDR followed by some
732  *                              type-specific data.
733  *     dwFlags              [I] See notes
734  *
735  * RETURNS
736  *
737  * A handle to the device notification.
738  *
739  * NOTES
740  *
741  * The dwFlags parameter can be one of two values:
742  *| DEVICE_NOTIFY_WINDOW_HANDLE  - hRecepient is a window handle
743  *| DEVICE_NOTIFY_SERVICE_HANDLE - hRecepient is a service status handle
744  */
745 HDEVNOTIFY WINAPI RegisterDeviceNotificationW(HANDLE hRecepient, LPVOID pNotificationFilter, DWORD dwFlags)
746 {
747     FIXME("(hwnd=%p, filter=%p,flags=0x%08lx), STUB!\n", hRecepient,pNotificationFilter,dwFlags );
748     return 0;
749 }