Include <limits.h> to get a definition of NAME_MAX.
[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 "tlhelp32.h"
34 #include "user_private.h"
35 #include "win.h"
36 #include "controls.h"
37 #include "cursoricon.h"
38 #include "message.h"
39 #include "local.h"
40 #include "wine/debug.h"
41
42 WINE_DEFAULT_DEBUG_CHANNEL(user);
43
44 static SYSLEVEL USER_SysLevel;
45 static CRITICAL_SECTION_DEBUG critsect_debug =
46 {
47     0, 0, &USER_SysLevel.crst,
48     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
49       0, 0, { 0, (DWORD)(__FILE__ ": USER_SysLevel") }
50 };
51 static SYSLEVEL USER_SysLevel = { { &critsect_debug, -1, 0, 0, 0, 0 }, 2 };
52
53 /* USER signal proc flags and codes */
54 /* See UserSignalProc for comments */
55 #define USIG_FLAGS_WIN32          0x0001
56 #define USIG_FLAGS_GUI            0x0002
57 #define USIG_FLAGS_FEEDBACK       0x0004
58 #define USIG_FLAGS_FAULT          0x0008
59
60 #define USIG_DLL_UNLOAD_WIN16     0x0001
61 #define USIG_DLL_UNLOAD_WIN32     0x0002
62 #define USIG_FAULT_DIALOG_PUSH    0x0003
63 #define USIG_FAULT_DIALOG_POP     0x0004
64 #define USIG_DLL_UNLOAD_ORPHANS   0x0005
65 #define USIG_THREAD_INIT          0x0010
66 #define USIG_THREAD_EXIT          0x0020
67 #define USIG_PROCESS_CREATE       0x0100
68 #define USIG_PROCESS_INIT         0x0200
69 #define USIG_PROCESS_EXIT         0x0300
70 #define USIG_PROCESS_DESTROY      0x0400
71 #define USIG_PROCESS_RUNNING      0x0500
72 #define USIG_PROCESS_LOADED       0x0600
73
74 /* UserSeeUserDo parameters */
75 #define USUD_LOCALALLOC        0x0001
76 #define USUD_LOCALFREE         0x0002
77 #define USUD_LOCALCOMPACT      0x0003
78 #define USUD_LOCALHEAP         0x0004
79 #define USUD_FIRSTCLASS        0x0005
80
81 /***********************************************************************
82  *              GetFreeSystemResources (USER.284)
83  */
84 WORD WINAPI GetFreeSystemResources16( WORD resType )
85 {
86     HINSTANCE16 gdi_inst;
87     WORD gdi_heap;
88     int userPercent, gdiPercent;
89
90     if ((gdi_inst = LoadLibrary16( "GDI" )) < 32) return 0;
91     gdi_heap = gdi_inst | 7;
92
93     switch(resType)
94     {
95     case GFSR_USERRESOURCES:
96         userPercent = (int)LOCAL_CountFree( USER_HeapSel ) * 100 /
97                                LOCAL_HeapSize( USER_HeapSel );
98         gdiPercent  = 100;
99         break;
100
101     case GFSR_GDIRESOURCES:
102         gdiPercent  = (int)LOCAL_CountFree( gdi_inst ) * 100 /
103                                LOCAL_HeapSize( gdi_inst );
104         userPercent = 100;
105         break;
106
107     case GFSR_SYSTEMRESOURCES:
108         userPercent = (int)LOCAL_CountFree( USER_HeapSel ) * 100 /
109                                LOCAL_HeapSize( USER_HeapSel );
110         gdiPercent  = (int)LOCAL_CountFree( gdi_inst ) * 100 /
111                                LOCAL_HeapSize( gdi_inst );
112         break;
113
114     default:
115         userPercent = gdiPercent = 0;
116         break;
117     }
118     FreeLibrary16( gdi_inst );
119     TRACE("<- userPercent %d, gdiPercent %d\n", userPercent, gdiPercent);
120     return (WORD)min( userPercent, gdiPercent );
121 }
122
123
124 /***********************************************************************
125  *           USER_Lock
126  */
127 void USER_Lock(void)
128 {
129     _EnterSysLevel( &USER_SysLevel );
130 }
131
132
133 /***********************************************************************
134  *           USER_Unlock
135  */
136 void USER_Unlock(void)
137 {
138     _LeaveSysLevel( &USER_SysLevel );
139 }
140
141
142 /***********************************************************************
143  *           USER_CheckNotLock
144  *
145  * Make sure that we don't hold the user lock.
146  */
147 void USER_CheckNotLock(void)
148 {
149     _CheckNotSysLevel( &USER_SysLevel );
150 }
151
152
153 /***********************************************************************
154  *              SignalProc32 (USER.391)
155  *              UserSignalProc (USER32.@)
156  *
157  * The exact meaning of the USER signals is undocumented, but this
158  * should cover the basic idea:
159  *
160  * USIG_DLL_UNLOAD_WIN16
161  *     This is sent when a 16-bit module is unloaded.
162  *
163  * USIG_DLL_UNLOAD_WIN32
164  *     This is sent when a 32-bit module is unloaded.
165  *
166  * USIG_DLL_UNLOAD_ORPHANS
167  *     This is sent after the last Win3.1 module is unloaded,
168  *     to allow removal of orphaned menus.
169  *
170  * USIG_FAULT_DIALOG_PUSH
171  * USIG_FAULT_DIALOG_POP
172  *     These are called to allow USER to prepare for displaying a
173  *     fault dialog, even though the fault might have happened while
174  *     inside a USER critical section.
175  *
176  * USIG_THREAD_INIT
177  *     This is called from the context of a new thread, as soon as it
178  *     has started to run.
179  *
180  * USIG_THREAD_EXIT
181  *     This is called, still in its context, just before a thread is
182  *     about to terminate.
183  *
184  * USIG_PROCESS_CREATE
185  *     This is called, in the parent process context, after a new process
186  *     has been created.
187  *
188  * USIG_PROCESS_INIT
189  *     This is called in the new process context, just after the main thread
190  *     has started execution (after the main thread's USIG_THREAD_INIT has
191  *     been sent).
192  *
193  * USIG_PROCESS_LOADED
194  *     This is called after the executable file has been loaded into the
195  *     new process context.
196  *
197  * USIG_PROCESS_RUNNING
198  *     This is called immediately before the main entry point is called.
199  *
200  * USIG_PROCESS_EXIT
201  *     This is called in the context of a process that is about to
202  *     terminate (but before the last thread's USIG_THREAD_EXIT has
203  *     been sent).
204  *
205  * USIG_PROCESS_DESTROY
206  *     This is called after a process has terminated.
207  *
208  *
209  * The meaning of the dwFlags bits is as follows:
210  *
211  * USIG_FLAGS_WIN32
212  *     Current process is 32-bit.
213  *
214  * USIG_FLAGS_GUI
215  *     Current process is a (Win32) GUI process.
216  *
217  * USIG_FLAGS_FEEDBACK
218  *     Current process needs 'feedback' (determined from the STARTUPINFO
219  *     flags STARTF_FORCEONFEEDBACK / STARTF_FORCEOFFFEEDBACK).
220  *
221  * USIG_FLAGS_FAULT
222  *     The signal is being sent due to a fault.
223  */
224 WORD WINAPI UserSignalProc( UINT uCode, DWORD dwThreadOrProcessID,
225                             DWORD dwFlags, HMODULE16 hModule )
226 {
227     FIXME("(%04x, %08lx, %04lx, %04x)\n",
228           uCode, dwThreadOrProcessID, dwFlags, hModule );
229     /* FIXME: Should chain to GdiSignalProc now. */
230     return 0;
231 }
232
233 /***********************************************************************
234  *           USER_GetProcessHandleList(Internal)
235  */
236 static HANDLE *USER_GetProcessHandleList(void)
237 {
238     DWORD count, i, n;
239     HANDLE *list;
240     PROCESSENTRY32 pe;
241     HANDLE hSnapshot;
242     BOOL r;
243
244     hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
245     if (!hSnapshot)
246     {
247         ERR("cannot create snapshot\n");
248         return FALSE;
249     }
250
251     /* count the number of processes plus one */
252     for (count=0; ;count++)
253     {
254         pe.dwSize = sizeof pe;
255         if (count)
256             r = Process32Next( hSnapshot, &pe );
257         else
258             r = Process32First( hSnapshot, &pe );
259         if (!r)
260             break;
261     }
262
263     /* allocate memory make a list of the process handles */
264     list = HeapAlloc( GetProcessHeap(), 0, (count+1)*sizeof(HANDLE) );
265     n=0;
266     for (i=0; i<count; i++)
267     {
268         pe.dwSize = sizeof pe;
269         if (i)
270             r = Process32Next( hSnapshot, &pe );
271         else
272             r = Process32First( hSnapshot, &pe );
273         if (!r)
274             break;
275
276         /* don't kill ourselves */
277         if (GetCurrentProcessId() == pe.th32ProcessID )
278             continue;
279
280         /* open the process so we don't can track it */
281         list[n] = OpenProcess( PROCESS_QUERY_INFORMATION|
282                                   PROCESS_TERMINATE,
283                                   FALSE, pe.th32ProcessID );
284
285         /* check it didn't terminate already */
286         if( list[n] )
287             n++;
288     }
289     list[n]=0;
290     CloseHandle( hSnapshot );
291
292     if (!r)
293         ERR("Error enumerating processes\n");
294
295     TRACE("return %lu processes\n", n);
296
297     return list;
298 }
299
300 /***********************************************************************
301  *              USER_KillProcesses (Internal)
302  */
303 static DWORD USER_KillProcesses(void)
304 {
305     DWORD n, r, i;
306     HANDLE *handles;
307     const DWORD dwShutdownTimeout = 10000;
308
309     TRACE("terminating other processes\n");
310
311     /* kill it and add it to our list of object to wait on */
312     handles = USER_GetProcessHandleList();
313     for (n=0; handles && handles[n]; n++)
314         TerminateProcess( handles[n], 0 );
315
316     /* wait for processes to exit */
317     for (i=0; i<n; i+=MAXIMUM_WAIT_OBJECTS)
318     {
319         int n_objs = ((n-i)>MAXIMUM_WAIT_OBJECTS) ? MAXIMUM_WAIT_OBJECTS : (n-i);
320         r = WaitForMultipleObjects( n_objs, &handles[i], TRUE, dwShutdownTimeout );
321         if (r==WAIT_TIMEOUT)
322             ERR("wait failed!\n");
323     }
324     
325     /* close the handles */
326     for (i=0; i<n; i++)
327         CloseHandle( handles[i] );
328
329     HeapFree( GetProcessHeap(), 0, handles );
330
331     return n;
332 }
333  
334 /***********************************************************************
335  *              USER_DoShutdown (Internal)
336  */
337 static void USER_DoShutdown(void)
338 {
339     DWORD i, n;
340     const DWORD nRetries = 10;
341
342     for (i=0; i<nRetries; i++)
343     {
344         n = USER_KillProcesses();
345         TRACE("Killed %ld processes, attempt %ld\n", n, i);
346         if(!n)
347             break;
348     }
349 }
350  
351 /***********************************************************************
352  *              USER_StartRebootProcess (Internal)
353  */
354 static BOOL USER_StartRebootProcess(void)
355 {
356     WCHAR winebootW[] = { 'w','i','n','e','b','o','o','t',0 };
357     PROCESS_INFORMATION pi;
358     STARTUPINFOW si;
359     BOOL r;
360
361     memset( &si, 0, sizeof si );
362     si.cb = sizeof si;
363
364     r = CreateProcessW( NULL, winebootW, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
365     if (r)
366     {
367         CloseHandle( pi.hProcess );
368         CloseHandle( pi.hThread );
369     }
370     else
371         MESSAGE("wine: Failed to start wineboot\n");
372
373     return r;
374 }
375
376 /***********************************************************************
377  *              ExitWindowsEx (USER32.@)
378  */
379 BOOL WINAPI ExitWindowsEx( UINT flags, DWORD reserved )
380 {
381     int i;
382     BOOL result = FALSE;
383     HWND *list, *phwnd;
384
385     /* We have to build a list of all windows first, as in EnumWindows */
386     TRACE("(%x,%lx)\n", flags, reserved);
387
388     list = WIN_ListChildren( GetDesktopWindow() );
389     if (list)
390     {
391         /* Send a WM_QUERYENDSESSION message to every window */
392
393         for (i = 0; list[i]; i++)
394         {
395             /* Make sure that the window still exists */
396             if (!IsWindow( list[i] )) continue;
397             if (!SendMessageW( list[i], WM_QUERYENDSESSION, 0, 0 )) break;
398         }
399         result = !list[i];
400
401         /* Now notify all windows that got a WM_QUERYENDSESSION of the result */
402
403         for (phwnd = list; i > 0; i--, phwnd++)
404         {
405             if (!IsWindow( *phwnd )) continue;
406             SendMessageW( *phwnd, WM_ENDSESSION, result, 0 );
407         }
408         HeapFree( GetProcessHeap(), 0, list );
409
410         if ( !(result || (flags & EWX_FORCE) ))
411             return FALSE;
412     }
413
414     /* USER_DoShutdown will kill all processes except the current process */
415     USER_DoShutdown();
416
417     if (flags & EWX_REBOOT)
418         USER_StartRebootProcess();
419
420     if (result) ExitProcess(0);
421     return TRUE;
422 }
423
424 /***********************************************************************
425  *              ChangeDisplaySettingsA (USER32.@)
426  */
427 LONG WINAPI ChangeDisplaySettingsA( LPDEVMODEA devmode, DWORD flags )
428 {
429   return ChangeDisplaySettingsExA(NULL,devmode,NULL,flags,NULL);
430 }
431
432 /***********************************************************************
433  *              ChangeDisplaySettingsW (USER32.@)
434  */
435 LONG WINAPI ChangeDisplaySettingsW( LPDEVMODEW devmode, DWORD flags )
436 {
437   return ChangeDisplaySettingsExW(NULL,devmode,NULL,flags,NULL);
438 }
439
440 /***********************************************************************
441  *              ChangeDisplaySettingsExA (USER32.@)
442  */
443 LONG WINAPI ChangeDisplaySettingsExA(
444         LPCSTR devname, LPDEVMODEA devmode, HWND hwnd, DWORD flags,
445         LPVOID lparam
446 ) {
447     DEVMODEW devmodeW;
448     LONG ret;
449     UNICODE_STRING nameW;
450
451     if (devname) RtlCreateUnicodeStringFromAsciiz(&nameW, devname);
452     else nameW.Buffer = NULL;
453
454     if (devmode)
455     {
456         devmodeW.dmBitsPerPel       = devmode->dmBitsPerPel;
457         devmodeW.dmPelsHeight       = devmode->dmPelsHeight;
458         devmodeW.dmPelsWidth        = devmode->dmPelsWidth;
459         devmodeW.dmDisplayFlags     = devmode->dmDisplayFlags;
460         devmodeW.dmDisplayFrequency = devmode->dmDisplayFrequency;
461         devmodeW.dmFields           = devmode->dmFields;
462         ret = ChangeDisplaySettingsExW(nameW.Buffer, &devmodeW, hwnd, flags, lparam);
463     }
464     else
465     {
466         ret = ChangeDisplaySettingsExW(nameW.Buffer, NULL, hwnd, flags, lparam);
467     }
468
469     if (devname) RtlFreeUnicodeString(&nameW);
470     return ret;
471 }
472
473 /***********************************************************************
474  *              ChangeDisplaySettingsExW (USER32.@)
475  */
476 LONG WINAPI ChangeDisplaySettingsExW( LPCWSTR devname, LPDEVMODEW devmode, HWND hwnd,
477                                       DWORD flags, LPVOID lparam )
478 {
479     /* Pass the request on to the driver */
480     if (!USER_Driver.pChangeDisplaySettingsExW) return DISP_CHANGE_FAILED;
481     return USER_Driver.pChangeDisplaySettingsExW( devname, devmode, hwnd, flags, lparam );
482 }
483
484 /***********************************************************************
485  *              EnumDisplaySettingsW (USER32.@)
486  *
487  * RETURNS
488  *      TRUE if nth setting exists found (described in the LPDEVMODEW struct)
489  *      FALSE if we do not have the nth setting
490  */
491 BOOL WINAPI EnumDisplaySettingsW(
492         LPCWSTR name,           /* [in] huh? */
493         DWORD n,                /* [in] nth entry in display settings list*/
494         LPDEVMODEW devmode      /* [out] devmode for that setting */
495 ) {
496     return EnumDisplaySettingsExW(name, n, devmode, 0);
497 }
498
499 /***********************************************************************
500  *              EnumDisplaySettingsA (USER32.@)
501  */
502 BOOL WINAPI EnumDisplaySettingsA(LPCSTR name,DWORD n,LPDEVMODEA devmode)
503 {
504     return EnumDisplaySettingsExA(name, n, devmode, 0);
505 }
506
507 /***********************************************************************
508  *              EnumDisplaySettingsExA (USER32.@)
509  */
510 BOOL WINAPI EnumDisplaySettingsExA(LPCSTR lpszDeviceName, DWORD iModeNum,
511                                    LPDEVMODEA lpDevMode, DWORD dwFlags)
512 {
513     DEVMODEW devmodeW;
514     BOOL ret;
515     UNICODE_STRING nameW;
516
517     if (lpszDeviceName) RtlCreateUnicodeStringFromAsciiz(&nameW, lpszDeviceName);
518     else nameW.Buffer = NULL;
519
520     ret = EnumDisplaySettingsExW(nameW.Buffer,iModeNum,&devmodeW,dwFlags);
521     if (ret)
522     {
523         lpDevMode->dmBitsPerPel       = devmodeW.dmBitsPerPel;
524         lpDevMode->dmPelsHeight       = devmodeW.dmPelsHeight;
525         lpDevMode->dmPelsWidth        = devmodeW.dmPelsWidth;
526         lpDevMode->dmDisplayFlags     = devmodeW.dmDisplayFlags;
527         lpDevMode->dmDisplayFrequency = devmodeW.dmDisplayFrequency;
528         lpDevMode->dmFields           = devmodeW.dmFields;
529     }
530     if (lpszDeviceName) RtlFreeUnicodeString(&nameW);
531     return ret;
532 }
533
534 /***********************************************************************
535  *              EnumDisplaySettingsExW (USER32.@)
536  */
537 BOOL WINAPI EnumDisplaySettingsExW(LPCWSTR lpszDeviceName, DWORD iModeNum,
538                                    LPDEVMODEW lpDevMode, DWORD dwFlags)
539 {
540     /* Pass the request on to the driver */
541     if (!USER_Driver.pEnumDisplaySettingsExW) return FALSE;
542     return USER_Driver.pEnumDisplaySettingsExW(lpszDeviceName, iModeNum, lpDevMode, dwFlags);
543 }
544
545 /***********************************************************************
546  *              EnumDisplayDevicesA (USER32.@)
547  */
548 BOOL WINAPI EnumDisplayDevicesA(
549         LPVOID unused,DWORD i,LPDISPLAY_DEVICEA lpDisplayDevice,DWORD dwFlags
550 ) {
551         if (i)
552                 return FALSE;
553         FIXME("(%p,%ld,%p,0x%08lx), stub!\n",unused,i,lpDisplayDevice,dwFlags);
554         strcpy(lpDisplayDevice->DeviceName,"X11");
555         strcpy(lpDisplayDevice->DeviceString,"X 11 Windowing System");
556         lpDisplayDevice->StateFlags =
557                         DISPLAY_DEVICE_ATTACHED_TO_DESKTOP      |
558                         DISPLAY_DEVICE_PRIMARY_DEVICE           |
559                         DISPLAY_DEVICE_VGA_COMPATIBLE;
560         return TRUE;
561 }
562
563 /***********************************************************************
564  *              EnumDisplayDevicesW (USER32.@)
565  */
566 BOOL WINAPI EnumDisplayDevicesW(
567         LPVOID unused,DWORD i,LPDISPLAY_DEVICEW lpDisplayDevice,DWORD dwFlags
568 ) {
569         if (i)
570                 return FALSE;
571         FIXME("(%p,%ld,%p,0x%08lx), stub!\n",unused,i,lpDisplayDevice,dwFlags);
572         MultiByteToWideChar( CP_ACP, 0, "X11", -1, lpDisplayDevice->DeviceName,
573                              sizeof(lpDisplayDevice->DeviceName)/sizeof(WCHAR) );
574         MultiByteToWideChar( CP_ACP, 0, "X11 Windowing System", -1, lpDisplayDevice->DeviceString,
575                              sizeof(lpDisplayDevice->DeviceString)/sizeof(WCHAR) );
576         lpDisplayDevice->StateFlags =
577                         DISPLAY_DEVICE_ATTACHED_TO_DESKTOP      |
578                         DISPLAY_DEVICE_PRIMARY_DEVICE           |
579                         DISPLAY_DEVICE_VGA_COMPATIBLE;
580         return TRUE;
581 }
582
583 /***********************************************************************
584  *              UserSeeUserDo (USER.216)
585  */
586 DWORD WINAPI UserSeeUserDo16(WORD wReqType, WORD wParam1, WORD wParam2, WORD wParam3)
587 {
588     switch (wReqType)
589     {
590     case USUD_LOCALALLOC:
591         return LOCAL_Alloc(USER_HeapSel, wParam1, wParam3);
592     case USUD_LOCALFREE:
593         return LOCAL_Free(USER_HeapSel, wParam1);
594     case USUD_LOCALCOMPACT:
595         return LOCAL_Compact(USER_HeapSel, wParam3, 0);
596     case USUD_LOCALHEAP:
597         return USER_HeapSel;
598     case USUD_FIRSTCLASS:
599         FIXME("return a pointer to the first window class.\n");
600         return (DWORD)-1;
601     default:
602         WARN("wReqType %04x (unknown)\n", wReqType);
603         return (DWORD)-1;
604     }
605 }
606
607 /***********************************************************************
608  *              RegisterLogonProcess (USER32.@)
609  */
610 DWORD WINAPI RegisterLogonProcess(HANDLE hprocess,BOOL x) {
611         FIXME("(%p,%d),stub!\n",hprocess,x);
612         return 1;
613 }
614
615 /***********************************************************************
616  *              CreateWindowStationW (USER32.@)
617  */
618 HWINSTA WINAPI CreateWindowStationW(
619         LPWSTR winstation,DWORD res1,DWORD desiredaccess,
620         LPSECURITY_ATTRIBUTES lpsa
621 ) {
622         FIXME("(%s,0x%08lx,0x%08lx,%p),stub!\n",debugstr_w(winstation),
623                 res1,desiredaccess,lpsa
624         );
625         return (HWINSTA)0xdeadcafe;
626 }
627
628 /***********************************************************************
629  *              SetProcessWindowStation (USER32.@)
630  */
631 BOOL WINAPI SetProcessWindowStation(HWINSTA hWinSta) {
632         FIXME("(%p),stub!\n",hWinSta);
633         return TRUE;
634 }
635
636 /***********************************************************************
637  *              SetUserObjectSecurity (USER32.@)
638  */
639 BOOL WINAPI SetUserObjectSecurity(
640         HANDLE hObj,
641         PSECURITY_INFORMATION pSIRequested,
642         PSECURITY_DESCRIPTOR pSID
643 ) {
644         FIXME("(%p,%p,%p),stub!\n",hObj,pSIRequested,pSID);
645         return TRUE;
646 }
647
648 /***********************************************************************
649  *              CreateDesktopA (USER32.@)
650  */
651 HDESK WINAPI CreateDesktopA(
652         LPSTR lpszDesktop,LPSTR lpszDevice,LPDEVMODEA pDevmode,
653         DWORD dwFlags,DWORD dwDesiredAccess,LPSECURITY_ATTRIBUTES lpsa
654 ) {
655         FIXME("(%s,%s,%p,0x%08lx,0x%08lx,%p),stub!\n",
656                 lpszDesktop,lpszDevice,pDevmode,
657                 dwFlags,dwDesiredAccess,lpsa
658         );
659         return (HDESK)0xcafedead;
660 }
661
662 /***********************************************************************
663  *              CreateDesktopW (USER32.@)
664  */
665 HDESK WINAPI CreateDesktopW(
666         LPWSTR lpszDesktop,LPWSTR lpszDevice,LPDEVMODEW pDevmode,
667         DWORD dwFlags,DWORD dwDesiredAccess,LPSECURITY_ATTRIBUTES lpsa
668 ) {
669         FIXME("(%s,%s,%p,0x%08lx,0x%08lx,%p),stub!\n",
670                 debugstr_w(lpszDesktop),debugstr_w(lpszDevice),pDevmode,
671                 dwFlags,dwDesiredAccess,lpsa
672         );
673         return (HDESK)0xcafedead;
674 }
675
676 /***********************************************************************
677  *              EnumDesktopWindows (USER32.@)
678  */
679 BOOL WINAPI EnumDesktopWindows( HDESK hDesktop, WNDENUMPROC lpfn, LPARAM lParam ) {
680   FIXME("(%p, %p, 0x%08lx), stub!\n", hDesktop, lpfn, lParam );
681   return TRUE;
682 }
683
684
685 /***********************************************************************
686  *              CloseWindowStation (USER32.@)
687  */
688 BOOL WINAPI CloseWindowStation(HWINSTA hWinSta)
689 {
690     FIXME("(%p)\n", hWinSta);
691     return TRUE;
692 }
693
694 /***********************************************************************
695  *              CloseDesktop (USER32.@)
696  */
697 BOOL WINAPI CloseDesktop(HDESK hDesk)
698 {
699     FIXME("(%p)\n", hDesk);
700     return TRUE;
701 }
702
703 /***********************************************************************
704  *              SetWindowStationUser (USER32.@)
705  */
706 DWORD WINAPI SetWindowStationUser(DWORD x1,DWORD x2) {
707         FIXME("(0x%08lx,0x%08lx),stub!\n",x1,x2);
708         return 1;
709 }
710
711 /***********************************************************************
712  *              SetLogonNotifyWindow (USER32.@)
713  */
714 DWORD WINAPI SetLogonNotifyWindow(HWINSTA hwinsta,HWND hwnd) {
715         FIXME("(%p,%p),stub!\n",hwinsta,hwnd);
716         return 1;
717 }
718
719 /***********************************************************************
720  *              LoadLocalFonts (USER32.@)
721  */
722 VOID WINAPI LoadLocalFonts(VOID) {
723         /* are loaded. */
724         return;
725 }
726 /***********************************************************************
727  *              GetUserObjectInformationA (USER32.@)
728  */
729 BOOL WINAPI GetUserObjectInformationA( HANDLE hObj, INT nIndex, LPVOID pvInfo, DWORD nLength, LPDWORD lpnLen )
730 {       FIXME("(%p %i %p %ld %p),stub!\n", hObj, nIndex, pvInfo, nLength, lpnLen );
731         return TRUE;
732 }
733 /***********************************************************************
734  *              GetUserObjectInformationW (USER32.@)
735  */
736 BOOL WINAPI GetUserObjectInformationW( HANDLE hObj, INT nIndex, LPVOID pvInfo, DWORD nLength, LPDWORD lpnLen )
737 {       FIXME("(%p %i %p %ld %p),stub!\n", hObj, nIndex, pvInfo, nLength, lpnLen );
738         return TRUE;
739 }
740 /***********************************************************************
741  *              GetUserObjectSecurity (USER32.@)
742  */
743 BOOL WINAPI GetUserObjectSecurity(HANDLE hObj, PSECURITY_INFORMATION pSIRequested,
744         PSECURITY_DESCRIPTOR pSID, DWORD nLength, LPDWORD lpnLengthNeeded)
745 {       FIXME("(%p %p %p len=%ld %p),stub!\n",  hObj, pSIRequested, pSID, nLength, lpnLengthNeeded);
746         return TRUE;
747 }
748
749 /***********************************************************************
750  *              SetSystemCursor (USER32.@)
751  */
752 BOOL WINAPI SetSystemCursor(HCURSOR hcur, DWORD id)
753 {       FIXME("(%p,%08lx),stub!\n",  hcur, id);
754         return TRUE;
755 }
756
757 /***********************************************************************
758  *              RegisterSystemThread (USER32.@)
759  */
760 void WINAPI RegisterSystemThread(DWORD flags, DWORD reserved)
761 {
762         FIXME("(%08lx, %08lx)\n", flags, reserved);
763 }
764
765 /***********************************************************************
766  *              RegisterDeviceNotificationA (USER32.@)
767  *
768  * See RegisterDeviceNotificationW.
769  */
770 HDEVNOTIFY WINAPI RegisterDeviceNotificationA(HANDLE hnd, LPVOID notifyfilter, DWORD flags)
771 {
772     FIXME("(hwnd=%p, filter=%p,flags=0x%08lx), STUB!\n", hnd,notifyfilter,flags );
773     return 0;
774 }
775
776 /***********************************************************************
777  *              RegisterDeviceNotificationW (USER32.@)
778  *
779  * Registers a window with the system so that it will receive
780  * notifications about a device.
781  *
782  * PARAMS
783  *     hRecepient           [I] Window or service status handle that
784  *                              will receive notifications.
785  *     pNotificationFilter  [I] DEV_BROADCAST_HDR followed by some
786  *                              type-specific data.
787  *     dwFlags              [I] See notes
788  *
789  * RETURNS
790  *
791  * A handle to the device notification.
792  *
793  * NOTES
794  *
795  * The dwFlags parameter can be one of two values:
796  *| DEVICE_NOTIFY_WINDOW_HANDLE  - hRecepient is a window handle
797  *| DEVICE_NOTIFY_SERVICE_HANDLE - hRecepient is a service status handle
798  */
799 HDEVNOTIFY WINAPI RegisterDeviceNotificationW(HANDLE hRecepient, LPVOID pNotificationFilter, DWORD dwFlags)
800 {
801     FIXME("(hwnd=%p, filter=%p,flags=0x%08lx), STUB!\n", hRecepient,pNotificationFilter,dwFlags );
802     return 0;
803 }