sync with trunk r47227
authorJérôme Gardou <jerome.gardou@reactos.org>
Sat, 15 May 2010 22:30:01 +0000 (22:30 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Sat, 15 May 2010 22:30:01 +0000 (22:30 +0000)
svn path=/branches/reactos-yarotows/; revision=47228

120 files changed:
1  2 
Makefile
base/applications/cacls/lang/ja-JP.rc
base/applications/cacls/rsrc.rc
base/applications/rapps/lang/it-IT.rc
base/applications/rapps/rapps/firefox3.txt
base/applications/rapps/rapps/mirandaim.txt
base/applications/rapps/rapps/openttd.txt
base/applications/rapps/rapps/opera.txt
base/applications/rapps/rapps/scummvm.txt
base/applications/rapps/rsrc.rc
base/setup/usetup/lang/it-IT.h
base/system/winlogon/environment.c
base/system/winlogon/sas.c
base/system/winlogon/winlogon.h
boot/bootdata/packages/reactos.dff
boot/freeldr/freeldr/fs/iso.c
boot/freeldr/freeldr/setupldr.rbuild
dll/cpl/appwiz/lang/cs-CZ.rc
dll/cpl/console/colors.c
dll/cpl/console/layout.c
dll/cpl/input/settings.c
dll/cpl/sysdm/lang/cs-CZ.rc
dll/cpl/sysdm/lang/it-IT.rc
dll/cpl/usrmgr/groups.c
dll/cpl/usrmgr/users.c
dll/win32/advapi32/reg/reg.c
dll/win32/gdi32/misc/wingl.c
dll/win32/iphlpapi/iphlpapi_main.c
dll/win32/iphlpapi/iphlpapi_private.h
dll/win32/kernel32/lang/bg-BG.mc
dll/win32/kernel32/lang/de-DE.mc
dll/win32/kernel32/lang/pl-PL.mc
dll/win32/kernel32/lang/ru-RU.mc
dll/win32/kernel32/misc/console.c
dll/win32/msgina/lang/bg-BG.rc
dll/win32/msgina/lang/cs-CZ.rc
dll/win32/msgina/lang/de-DE.rc
dll/win32/msgina/lang/en-US.rc
dll/win32/msgina/lang/es-ES.rc
dll/win32/msgina/lang/fr-FR.rc
dll/win32/msgina/lang/id-ID.rc
dll/win32/msgina/lang/it-IT.rc
dll/win32/msgina/lang/ja-JP.rc
dll/win32/msgina/lang/no-NO.rc
dll/win32/msgina/lang/pl-PL.rc
dll/win32/msgina/lang/ro-RO.rc
dll/win32/msgina/lang/ru-RU.rc
dll/win32/msgina/lang/sk-SK.rc
dll/win32/msgina/lang/uk-UA.rc
dll/win32/msgina/msgina.c
dll/win32/netshell/lang/it-IT.rc
dll/win32/opengl32/opengl32.c
dll/win32/opengl32/opengl32.h
dll/win32/opengl32/wgl.c
dll/win32/shell32/lang/cs-CZ.rc
dll/win32/shell32/lang/it-IT.rc
dll/win32/shell32/shfldr_cpanel.c
dll/win32/shell32/shlview.c
dll/win32/userenv/environment.c
drivers/network/afd/afd/read.c
drivers/usb/nt4compat/usbdriver/devmgr.c
drivers/usb/nt4compat/usbdriver/devmgr.h
drivers/usb/nt4compat/usbdriver/ehci.c
drivers/usb/nt4compat/usbdriver/uhci.c
drivers/usb/nt4compat/usbdriver/usbdriver.rbuild
drivers/wdm/audio/backpln/portcls/pin_dmus.cpp
drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp
drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp
drivers/wdm/audio/backpln/portcls/port_dmus.cpp
drivers/wdm/audio/backpln/portcls/port_topology.cpp
drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp
drivers/wdm/audio/backpln/portcls/port_wavepci.cpp
drivers/wdm/audio/backpln/portcls/port_wavert.cpp
drivers/wdm/audio/backpln/portcls/registry.cpp
drivers/wdm/audio/backpln/portcls/service_group.cpp
drivers/wdm/audio/sysaudio/control.c
drivers/wdm/audio/sysaudio/deviface.c
drivers/wdm/audio/sysaudio/main.c
drivers/wdm/audio/sysaudio/pin.c
drivers/wdm/audio/sysaudio/sysaudio.h
hal/hal.pspec
hal/halx86/generic/bus/pcibus.c
include/reactos/subsys/csrss/csrss.h
lib/newinflib/infhostgen.c
lib/newinflib/infhostrtl.c
media/inf/cpu.inf
media/inf/ports.inf
ntoskrnl/ex/init.c
ntoskrnl/include/internal/i386/mm.h
ntoskrnl/kd/kdinit.c
ntoskrnl/kdbg/kdb.c
ntoskrnl/ke/i386/traphdlr.c
ntoskrnl/mm/ARM3/arm/init.c
ntoskrnl/mm/ARM3/contmem.c
ntoskrnl/mm/ARM3/i386/init.c
ntoskrnl/mm/ARM3/miarm.h
ntoskrnl/mm/ARM3/mminit.c
ntoskrnl/mm/ARM3/pagfault.c
ntoskrnl/mm/ARM3/pfnlist.c
ntoskrnl/mm/ARM3/pool.c
ntoskrnl/mm/ARM3/procsup.c
ntoskrnl/mm/freelist.c
ntoskrnl/mm/mmfault.c
ntoskrnl/mm/mminit.c
subsystems/win32/csrss/include/conio.h
subsystems/win32/csrss/win32csr/conio.c
subsystems/win32/csrss/win32csr/dllmain.c
subsystems/win32/csrss/win32csr/guiconsole.c
subsystems/win32/csrss/win32csr/guiconsole.h
subsystems/win32/csrss/win32csr/harderror.c
subsystems/win32/csrss/win32csr/tuiconsole.c
subsystems/win32/win32k/eng/device.c
subsystems/win32/win32k/include/timer.h
subsystems/win32/win32k/main/dllmain.c
subsystems/win32/win32k/ntuser/caret.c
subsystems/win32/win32k/ntuser/focus.c
subsystems/win32/win32k/ntuser/keyboard.c
subsystems/win32/win32k/ntuser/message.c
subsystems/win32/win32k/ntuser/msgqueue.c
subsystems/win32/win32k/ntuser/timer.c

diff --cc Makefile
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 1dbc24b,0000000..386cc75
mode 100644,000000..100644
--- /dev/null
@@@ -1,819 -1,0 +1,823 @@@
 +; Main ReactOS package
 +
 +.Set DiskLabelTemplate="ReactOS"                ; Label of disk
 +.Set CabinetNameTemplate="reactos.cab"          ; reactos.cab
 +.Set InfFileName="reactos.inf"                  ; reactos.inf
 +
 +
 +;.Set Cabinet=on
 +;.Set Compress=on
 +
 +.InfBegin
 +[Version]
 +Signature = "$ReactOS$"
 +
 +[Directories]
 +1 = system32
 +2 = system32\drivers
 +3 = Fonts
 +4 =
 +5 = system32\drivers\etc
 +6 = inf
 +7 = bin
 +8 = media
 +
 +.InfEnd
 +
 +; Contents of disk
 +.InfBegin
 +[SourceFiles]
 +.InfEnd
 +
 +
 +; Base files
 +base\applications\cacls\cacls.exe                       1
 +base\applications\calc\calc.exe                         1
 +base\applications\charmap\charmap.exe                   1
 +base\applications\cmdutils\dbgprint\dbgprint.exe        1
 +base\applications\cmdutils\doskey\doskey.exe            1
 +base\applications\cmdutils\find\find.exe                1
 +base\applications\cmdutils\hostname\hostname.exe        1
 +base\applications\cmdutils\lodctr\lodctr.exe            1
 +base\applications\cmdutils\more\more.exe                1
 +base\applications\cmdutils\reg\reg.exe                  1
 +base\applications\cmdutils\xcopy\xcopy.exe              1
 +base\applications\control\control.exe                   1
 +base\applications\dxdiag\dxdiag.exe                     1
 +base\applications\fontview\fontview.exe                 1
 +base\applications\mscutils\devmgmt\devmgmt.exe          1
 +base\applications\mscutils\eventvwr\eventvwr.exe        1
 +base\applications\games\solitaire\sol.exe               1
 +base\applications\games\spider\spider.exe               1
 +base\applications\games\winemine\winemine.exe           1
 +base\applications\hh\hh.exe                             4
 +base\applications\kbswitch\kbswitch.exe                 1
 +base\applications\kbswitch\kbsdll\kbsdll.dll            1
 +base\applications\logoff\logoff.exe                     1
 +base\applications\magnify\magnify.exe                   1
 +base\applications\mplay32\mplay32.exe                   1
 +base\applications\msconfig\msconfig.exe                 1
 +base\applications\mstsc\mstsc.exe                       1
 +base\applications\network\arp\arp.exe                   1
 +base\applications\network\dwnl\dwnl.exe                 1
 +base\applications\network\route\route.exe               1
 +base\applications\network\finger\finger.exe             1
 +base\applications\network\ftp\ftp.exe                   1
 +base\applications\network\ipconfig\ipconfig.exe         1
 +base\applications\network\netstat\netstat.exe           1
 +base\applications\network\nslookup\nslookup.exe         1
 +base\applications\network\ping\ping.exe                 1
 +base\applications\network\telnet\telnet.exe             1
 +base\applications\network\tracert\tracert.exe           1
 +base\applications\network\whois\whois.exe               1
 +base\applications\notepad\notepad.exe                   1
 +base\applications\paint\paint.exe                       1
 +base\applications\rapps\rapps.exe                       1
 +base\applications\regedit\regedit.exe                   4
 +base\applications\regedit\clb\clb.dll                   1
 +base\applications\regedt32\regedt32.exe                 1
 +base\applications\sc\sc.exe                             1
 +base\applications\screensavers\3dtext\3dtext.scr        1
 +base\applications\screensavers\logon\logon.scr          1
 +base\applications\mscutils\servman\servman.exe          1
 +base\applications\shutdown\shutdown.exe                 1
 +base\applications\sndrec32\sndrec32.exe                 1
 +base\applications\sndvol32\sndvol32.exe                 1
 +base\applications\taskmgr\taskmgr.exe                   1
 +base\applications\winhlp32\winhlp32.exe                 4
 +base\applications\winver\winver.exe                     1
 +base\applications\wordpad\wordpad.exe                   1
 +base\applications\write\write.exe                       1
 +
 +base\services\audiosrv\audiosrv.exe                 1
 +base\services\dhcp\dhcp.exe                         1
 +base\services\eventlog\eventlog.exe                 1
 +base\services\rpcss\rpcss.exe                       1
 +base\services\spoolsv\spoolsv.exe                   1
 +base\services\tcpsvcs\tcpsvcs.exe                   1
 +base\services\telnetd\telnetd.exe                   1
 +base\services\tcpsvcs\quotes                        5
 +base\services\umpnpmgr\umpnpmgr.exe                 1
 +base\services\wlansvc\wlansvc.exe                   1
 +base\services\svchost\svchost.exe                   1
 +
 +base\setup\setup\setup.exe                          1
 +base\setup\vmwinst\vmwinst.exe                      1
 +
 +base\shell\cmd\cmd.exe                              1
 +base\shell\explorer\explorer.exe                    4
 +base\shell\explorer\explorer-cfg-template.xml       4
 +base\shell\explorer\notifyhook\notifyhook.dll       1
 +base\shell\explorer-new\explorer_new.exe            4   optional
 +
 +base\system\autochk\autochk.exe                     1
 +base\system\bootok\bootok.exe                       1
 +base\system\format\format.exe                       1
 +base\system\lsass\lsass.exe                         1
 +base\system\msiexec\msiexec.exe                     1
 +base\system\regsvr32\regsvr32.exe                   1
 +base\system\rundll32\rundll32.exe                   1
 +base\system\runonce\runonce.exe                     1
 +base\system\services\services.exe                   1
 +base\system\userinit\userinit.exe                   1
 +base\system\winlogon\winlogon.exe                   1
 +base\system\expand\expand.exe                       1
 +base\system\smss\smss.exe                           1
 +
 +
 +; Dynamic Link Libraries
 +dll\3rdparty\mesa32\mesa32.dll                      1
 +dll\3rdparty\libjpeg\libjpeg.dll                    1
 +dll\3rdparty\libxslt\libxslt.dll                    1
 +dll\3rdparty\dxtn\dxtn.dll                          1   optional
 +
 +dll\cpl\access\access.cpl                           1
 +dll\cpl\appwiz\appwiz.cpl                           1
 +dll\cpl\console\console.dll                         1
 +dll\cpl\desk\desk.cpl                               1
 +dll\cpl\hdwwiz\hdwwiz.cpl                           1
 +dll\cpl\input\input.dll                             1
 +dll\cpl\intl\intl.cpl                               1
 +dll\cpl\joy\joy.cpl                                 1
 +;dll\cpl\liccpa\liccpa.cpl                          1
 +dll\cpl\main\main.cpl                               1
 +dll\cpl\mmsys\mmsys.cpl                             1
 +dll\cpl\ncpa\ncpa.cpl                               1
 +;dll\cpl\odbccp32\odbccp32.cpl                      1
 +dll\cpl\powercfg\powercfg.cpl                       1
 +dll\cpl\sysdm\sysdm.cpl                             1
 +;dll\cpl\telephon\telephon.cpl                      1
 +dll\cpl\timedate\timedate.cpl                       1
 +;dll\cpl\usrmgr\usrmgr.cpl                          1
 +
 +dll\directx\amstream\amstream.dll                   1
 +dll\directx\bdaplgin\bdaplgin.ax                    1
 +dll\directx\dinput\dinput.dll                       1
 +dll\directx\dinput8\dinput8.dll                     1
 +dll\directx\dmusic\dmusic.dll                       1
 +dll\directx\dplay\dplay.dll                         1
 +dll\directx\dplayx\dplayx.dll                       1
 +dll\directx\dsound\dsound.dll                       1
 +dll\directx\dxdiagn\dxdiagn.dll                     1
 +dll\directx\wine\ddraw\ddraw.dll                    1
 +dll\directx\d3d8thk\d3d8thk.dll                     1
 +dll\directx\devenum\devenum.dll                     1
 +dll\directx\ksproxy\ksproxy.ax                      1
 +dll\directx\ksuser\ksuser.dll                       1
 +dll\directx\msdmo\msdmo.dll                         1
 +dll\directx\msdvbnp\msdvbnp.ax                      1
 +dll\directx\msvidctl\msvidctl.dll                   1
 +dll\directx\quartz\quartz.dll                       1
 +dll\directx\qedit\qedit.dll                         1
 +dll\directx\wine\d3d8\d3d8.dll                      1
 +dll\directx\wine\wined3d\wined3d.dll                1
 +dll\directx\wine\d3d9\d3d9.dll                      1
 +
 +dll\keyboard\kbda1\kbda1.dll                        1
 +dll\keyboard\kbda2\kbda2.dll                        1
 +dll\keyboard\kbda3\kbda3.dll                        1
 +dll\keyboard\kbdal\kbdal.dll                        1
 +dll\keyboard\kbdarme\kbdarme.dll                    1
 +dll\keyboard\kbdarmw\kbdarmw.dll                    1
 +dll\keyboard\kbdaze\kbdaze.dll                      1
 +dll\keyboard\kbdazel\kbdazel.dll                    1
 +dll\keyboard\kbdbgm\kbdbgm.dll                      1
 +dll\keyboard\kbdbgt\kbdbgt.dll                      1
 +dll\keyboard\kbdblr\kbdblr.dll                      1
 +dll\keyboard\kbdbr\kbdbr.dll                        1
 +dll\keyboard\kbdbga\kbdbga.dll                      1
 +dll\keyboard\kbdbe\kbdbe.dll                        1
 +dll\keyboard\kbdbur\kbdbur.dll                      1
 +dll\keyboard\kbdcan\kbdcan.dll                      1
 +dll\keyboard\kbdcr\kbdcr.dll                        1
 +dll\keyboard\kbdcz\kbdcz.dll                        1
 +dll\keyboard\kbdcz1\kbdcz1.dll                      1
 +dll\keyboard\kbdda\kbdda.dll                        1
 +dll\keyboard\kbddv\kbddv.dll                        1
 +dll\keyboard\kbdes\kbdes.dll                        1
 +dll\keyboard\kbdest\kbdest.dll                      1
 +dll\keyboard\kbdfc\kbdfc.dll                        1
 +dll\keyboard\kbdfi\kbdfi.dll                        1
 +dll\keyboard\kbdfr\kbdfr.dll                        1
 +dll\keyboard\kbdgeo\kbdgeo.dll                      1
 +dll\keyboard\kbdgerg\kbdgerg.dll                    1
 +dll\keyboard\kbdgneo\kbdgneo.dll                    1
 +dll\keyboard\kbdgrist\kbdgrist.dll                  1
 +dll\keyboard\kbdgr\kbdgr.dll                        1
 +dll\keyboard\kbdhe\kbdhe.dll                        1
 +dll\keyboard\kbdheb\kbdheb.dll                      1
 +dll\keyboard\kbdhu\kbdhu.dll                        1
 +dll\keyboard\kbdic\kbdic.dll                        1
 +dll\keyboard\kbdinasa\kbdinasa.dll                  1
 +dll\keyboard\kbdinben\kbdinben.dll                  1
 +dll\keyboard\kbdindev\kbdindev.dll                  1
 +dll\keyboard\kbdinguj\kbdinguj.dll                  1
 +dll\keyboard\kbdinmal\kbdinmal.dll                  1
 +dll\keyboard\kbdir\kbdir.dll                        1
 +dll\keyboard\kbdit\kbdit.dll                        1
 +dll\keyboard\kbdja\kbdja.dll                        1
 +dll\keyboard\kbdkaz\kbdkaz.dll                      1
 +dll\keyboard\kbdla\kbdla.dll                        1
 +dll\keyboard\kbdlt1\kbdlt1.dll                      1
 +dll\keyboard\kbdlv\kbdlv.dll                        1
 +dll\keyboard\kbdmac\kbdmac.dll                      1
 +dll\keyboard\kbdne\kbdne.dll                        1
 +dll\keyboard\kbdno\kbdno.dll                        1
 +dll\keyboard\kbdpl1\kbdpl1.dll                      1
 +dll\keyboard\kbdpo\kbdpo.dll                        1
 +dll\keyboard\kbdro\kbdro.dll                        1
 +dll\keyboard\kbdru\kbdru.dll                        1
 +dll\keyboard\kbdru1\kbdru1.dll                      1
 +dll\keyboard\kbdsg\kbdsg.dll                        1
 +dll\keyboard\kbdsk\kbdsk.dll                        1
 +dll\keyboard\kbdsk1\kbdsk1.dll                      1
 +dll\keyboard\kbdsw\kbdsw.dll                        1
 +dll\keyboard\kbdtat\kbdtat.dll                      1
 +dll\keyboard\kbdth0\kbdth0.dll                      1
 +dll\keyboard\kbdth1\kbdth1.dll                      1
 +dll\keyboard\kbdth2\kbdth2.dll                      1
 +dll\keyboard\kbdth3\kbdth3.dll                      1
 +dll\keyboard\kbdtuf\kbdtuf.dll                      1
 +dll\keyboard\kbdtuq\kbdtuq.dll                      1
 +dll\keyboard\kbduk\kbduk.dll                        1
 +dll\keyboard\kbdur\kbdur.dll                        1
 +dll\keyboard\kbdurs\kbdurs.dll                      1
 +dll\keyboard\kbdus\kbdus.dll                        1
 +dll\keyboard\kbdusa\kbdusa.dll                      1
 +dll\keyboard\kbdusl\kbdusl.dll                      1
 +dll\keyboard\kbdusr\kbdusr.dll                      1
 +dll\keyboard\kbdusx\kbdusx.dll                      1
 +dll\keyboard\kbduzb\kbduzb.dll                      1
 +dll\keyboard\kbdvntc\kbdvntc.dll                    1
 +dll\keyboard\kbdycc\kbdycc.dll                      1
 +dll\keyboard\kbdycl\kbdycl.dll                      1
 +dll\keyboard\kbdko\kbdko.dll                        1
 +
 +dll\ntdll\ntdll.dll                                 1
 +
 +dll\win32\acledit\acledit.dll                       1
 +dll\win32\aclui\aclui.dll                           1
 +dll\win32\activeds\activeds.dll                     1
 +dll\win32\advapi32\advapi32.dll                     1
 +dll\win32\advpack\advpack.dll                       1
 +dll\win32\actxprxy\actxprxy.dll                     1
 +dll\win32\atl\atl.dll                               1
 +dll\win32\authz\authz.dll                           1
 +dll\win32\avicap32\avicap32.dll                     1
 +dll\win32\avifil32\avifil32.dll                     1
 +dll\win32\batt\batt.dll                             1
 +dll\win32\bcrypt\bcrypt.dll                         1
 +dll\win32\beepmidi\beepmidi.dll                     1
 +dll\win32\browseui\browseui.dll                     1
 +dll\win32\cabinet\cabinet.dll                       1
 +dll\win32\cards\cards.dll                           1
 +dll\win32\cfgmgr32\cfgmgr32.dll                     1
 +dll\win32\clusapi\clusapi.dll                       1
 +dll\win32\comcat\comcat.dll                         1
 +dll\win32\comctl32\comctl32.dll                     1
 +dll\win32\comdlg32\comdlg32.dll                     1
 +dll\win32\compstui\compstui.dll                     1
 +dll\win32\credui\credui.dll                         1
 +dll\win32\crtdll\crtdll.dll                         1
 +dll\win32\crypt32\crypt32.dll                       1
 +dll\win32\cryptdlg\cryptdlg.dll                     1
 +dll\win32\cryptdll\cryptdll.dll                     1
 +dll\win32\cryptnet\cryptnet.dll                     1
 +dll\win32\cryptui\cryptui.dll                       1
 +dll\win32\dbghelp\dbghelp.dll                       1
 +dll\win32\dciman32\dciman32.dll                     1
 +dll\win32\dwmapi\dwmapi.dll                         1
 +dll\win32\devmgr\devmgr.dll                         1
 +dll\win32\dhcpcsvc\dhcpcsvc.dll                     1
 +dll\win32\dnsapi\dnsapi.dll                         1
 +dll\win32\faultrep\faultrep.dll                     1
 +dll\win32\fmifs\fmifs.dll                           1
 +dll\win32\fusion\fusion.dll                         1
 +dll\win32\gdi32\gdi32.dll                           1
 +dll\win32\gdiplus\gdiplus.dll                       1
 +dll\win32\getuname\getuname.dll                     1
 +dll\win32\glu32\glu32.dll                           1
 +dll\win32\hhctrl.ocx\hhctrl.ocx                     1
 +dll\win32\hid\hid.dll                               1
 +dll\win32\hlink\hlink.dll                           1
 +dll\win32\hnetcfg\hnetcfg.dll                       1
 +dll\win32\httpapi\httpapi.dll                       1
 +dll\win32\iccvid\iccvid.dll                         1
 +dll\win32\icmp\icmp.dll                             1
 +dll\win32\imaadp32.acm\imaadp32.acm                 1
 +dll\win32\imagehlp\imagehlp.dll                     1
 +dll\win32\imm32\imm32.dll                           1
 +dll\win32\inetcomm\inetcomm.dll                     1
 +dll\win32\inetmib1\inetmib1.dll                     1
 +dll\win32\initpki\initpki.dll                       1
 +dll\win32\inseng\inseng.dll                         1
 +dll\win32\iphlpapi\iphlpapi.dll                     1
 +dll\win32\itircl\itircl.dll                         1
 +dll\win32\itss\itss.dll                             1
 +dll\win32\jscript\jscript.dll                       1
 +dll\win32\kernel32\kernel32.dll                     1
 +dll\win32\loadperf\loadperf.dll                     1
 +dll\win32\localspl\localspl.dll                     1
 +dll\win32\localui\localui.dll                       1
 +dll\win32\lsasrv\lsasrv.dll                         1
 +dll\win32\lz32\lz32.dll                             1
 +dll\win32\mapi32\mapi32.dll                         1
 +dll\win32\mciavi32\mciavi32.dll                     1
 +dll\win32\mcicda\mcicda.dll                         1
 +dll\win32\mciqtz32\mciqtz32.dll                     1
 +dll\win32\mciseq\mciseq.dll                         1
 +dll\win32\mciwave\mciwave.dll                       1
 +dll\win32\mlang\mlang.dll                           1
 +dll\win32\mmdrv\mmdrv.dll                           1
 +dll\win32\modemui\modemui.dll                       1
 +dll\win32\mpr\mpr.dll                               1
 +dll\win32\mprapi\mprapi.dll                         1
 +dll\win32\msacm32\msacm32.dll                       1
 +dll\win32\msacm32\msacm32.drv\msacm32.drv           1
 +dll\win32\msadp32.acm\msadp32.acm                   1
 +dll\win32\msafd\msafd.dll                           1
 +dll\win32\mscat32\mscat32.dll                       1
 +dll\win32\mscms\mscms.dll                           1
 +dll\win32\mscoree\mscoree.dll                       1
 +dll\win32\msctf\msctf.dll                           1
 +dll\win32\msftedit\msftedit.dll                     1
 +dll\win32\msg711.acm\msg711.acm                     1
 +dll\win32\msgina\msgina.dll                         1
 +dll\win32\msgsm32.acm\msgsm32.acm                   1
 +dll\win32\mshtml\mshtml.dll                         1
 +dll\win32\mshtml.tlb\mshtml.tlb                     1
 +dll\win32\msi\msi.dll                               1
 +dll\win32\msimg32\msimg32.dll                       1
 +dll\win32\msimtf\msimtf.dll                         1
 +dll\win32\msisip\msisip.dll                         1
 +dll\win32\msisys.ocx\msisys.ocx                     1
 +dll\win32\msnet32\msnet32.dll                       1
 +dll\win32\msrle32\msrle32.dll                       1
 +dll\win32\mssign32\mssign32.dll                     1
 +dll\win32\mssip32\mssip32.dll                       1
 +dll\win32\mstask\mstask.dll                         1
 +dll\win32\msvcrt\msvcrt.dll                         1
 +dll\win32\msvcrt20\msvcrt20.dll                     1
 +dll\win32\msvcrt40\msvcrt40.dll                     1
 +dll\win32\msvfw32\msvfw32.dll                       1
 +dll\win32\msvidc32\msvidc32.dll                     1
 +dll\win32\mswsock\mswsock.dll                       1
 +dll\win32\msxml3\msxml3.dll                         1
 +dll\win32\nddeapi\nddeapi.dll                       1
 +dll\win32\netapi32\netapi32.dll                     1
 +dll\win32\netcfgx\netcfgx.dll                       1
 +dll\win32\netid\netid.dll                           1
 +dll\win32\netshell\netshell.dll                     1
 +dll\win32\newdev\newdev.dll                         1
 +dll\win32\ntdsapi\ntdsapi.dll                       1
 +dll\win32\ntlanman\ntlanman.dll                     1
 +dll\win32\ntmarta\ntmarta.dll                       1
 +dll\win32\ntprint\ntprint.dll                       1
 +dll\win32\objsel\objsel.dll                         1
 +dll\win32\odbc32\odbc32.dll                         1
 +dll\win32\odbccp32\odbccp32.dll                     1
 +dll\win32\ole32\ole32.dll                           1
 +dll\win32\oleacc\oleacc.dll                         1
 +dll\win32\oleaut32\oleaut32.dll                     1
 +dll\win32\olecli32\olecli32.dll                     1
 +dll\win32\oledlg\oledlg.dll                         1
 +dll\win32\olepro32\olepro32.dll                     1
 +dll\win32\olesvr32\olesvr32.dll                     1
 +dll\win32\olethk32\olethk32.dll                     1
 +dll\win32\opengl32\opengl32.dll                     1
 +dll\win32\pdh\pdh.dll                               1
 +dll\win32\pidgen\pidgen.dll                         1
 +dll\win32\powrprof\powrprof.dll                     1
 +dll\win32\printui\printui.dll                       1
 +dll\win32\psapi\psapi.dll                           1
 +dll\win32\pstorec\pstorec.dll                       1
 +dll\win32\qmgr\qmgr.dll                             1
 +dll\win32\qmgrprxy\qmgrprxy.dll                     1
 +dll\win32\query\query.dll                           1
 +dll\win32\rasadhlp\rasadhlp.dll                     1
 +dll\win32\rasapi32\rasapi32.dll                     1
 +dll\win32\rasdlg\rasdlg.dll                         1
 +dll\win32\resutils\resutils.dll                     1
 +dll\win32\rasman\rasman.dll                         1
 +dll\win32\riched20\riched20.dll                     1
 +dll\win32\riched32\riched32.dll                     1
 +dll\win32\rpcrt4\rpcrt4.dll                         1
 +dll\win32\rsabase\rsabase.dll                       1
 +dll\win32\rsaenh\rsaenh.dll                         1
 +dll\win32\samlib\samlib.dll                         1
 +dll\win32\samsrv\samsrv.dll                         1
 +dll\win32\sccbase\sccbase.dll                       1
 +dll\win32\schannel\schannel.dll                     1
 +dll\win32\secur32\secur32.dll                       1
 +dll\win32\security\security.dll                     1
 +dll\win32\sensapi\sensapi.dll                       1
 +dll\win32\serialui\serialui.dll                     1
 +dll\win32\setupapi\setupapi.dll                     1
 +dll\win32\sfc\sfc.dll                               1
 +dll\win32\sfc_os\sfc_os.dll                         1
 +dll\win32\shdoclc\shdoclc.dll                       1
 +dll\win32\shdocvw\shdocvw.dll                       1
 +dll\win32\shell32\shell32.dll                       1
 +dll\win32\shfolder\shfolder.dll                     1
 +dll\win32\shimgvw\shimgvw.dll                       1
 +dll\win32\shlwapi\shlwapi.dll                       1
 +dll\win32\slbcsp\slbcsp.dll                         1
 +dll\win32\smdll\smdll.dll                           1
 +dll\win32\snmpapi\snmpapi.dll                       1
 +dll\win32\softpub\softpub.dll                       1
 +dll\win32\spoolss\spoolss.dll                       1
 +dll\win32\srclient\srclient.dll                     1
 +dll\win32\stdole2.tlb\stdole2.tlb                   1
 +dll\win32\stdole32.tlb\stdole32.tlb                 1
 +dll\win32\sti\sti.dll                               1
 +dll\win32\sxs\sxs.dll                               1
 +dll\win32\syssetup\syssetup.dll                     1
 +dll\win32\t2embed\t2embed.dll                       1
 +dll\win32\tapi32\tapi32.dll                         1
 +dll\win32\tapiui\tapiui.dll                         1
 +dll\win32\traffic\traffic.dll                       1
 +dll\win32\twain_32\twain_32.dll                     1
 +dll\win32\uext2\uext2.dll                           1
 +dll\win32\ufat\ufat.dll                             1
 +dll\win32\ufatx\ufatx.dll                           1   optional
 +dll\win32\untfs\untfs.dll                           1
 +dll\win32\updspapi\updspapi.dll                     1
 +dll\win32\url\url.dll                               1
 +dll\win32\urlmon\urlmon.dll                         1
 +dll\win32\user32\user32.dll                         1
 +dll\win32\userenv\userenv.dll                       1
 +dll\win32\usp10\usp10.dll                           1
 +dll\win32\uxtheme\uxtheme.dll                       1
 +dll\win32\vdmdbg\vdmdbg.dll                         1
 +dll\win32\version\version.dll                       1
 +dll\win32\windowscodecs\windowscodecs.dll           1
 +dll\win32\winemp3.acm\winemp3.acm                   1
 +dll\win32\winfax\winfax.dll                         1
 +dll\win32\winhttp\winhttp.dll                       1
 +dll\win32\wininet\wininet.dll                       1
 +dll\win32\winmm\winmm.dll                           1
 +dll\win32\winspool\winspool.drv                     1
 +dll\win32\winsta\winsta.dll                         1
 +dll\win32\wlanapi\wlanapi.dll                       1
 +dll\win32\wintrust\wintrust.dll                     1
 +dll\win32\wldap32\wldap32.dll                       1
 +dll\win32\wmi\wmi.dll                               1
 +dll\win32\ws2_32\ws2_32.dll                         1
 +dll\win32\ws2help\ws2help.dll                       1
 +dll\win32\wshirda\wshirda.dll                       1
 +dll\win32\wshtcpip\wshtcpip.dll                     1
 +dll\win32\wsock32\wsock32.dll                       1
 +dll\win32\wtsapi32\wtsapi32.dll                     1
 +dll\win32\wuapi\wuapi.dll                           1
 +dll\win32\xinput1_1\xinput1_1.dll                   1
 +dll\win32\xinput1_2\xinput1_2.dll                   1
 +dll\win32\xinput1_3\xinput1_3.dll                   1
 +dll\win32\xinput9_1_0\xinput9_1_0.dll               1
 +dll\win32\xmllite\xmllite.dll                       1
 +dll\win32\winmm\midimap\midimap.dll                 1
 +dll\win32\wdmaud.drv\wdmaud.drv                     1
 +
 +; Shell Extensions
 +dll\shellext\deskadp\deskadp.dll                    1
 +dll\shellext\deskmon\deskmon.dll                    1
 +
 +; Drivers
 +drivers\base\bootvid\bootvid.dll                    1
 +drivers\base\beep\beep.sys                          2
 +drivers\base\null\null.sys                          2
 +drivers\base\nmidebug\nmidebug.sys                  2
 +
 +drivers\battery\battc\battc.sys                     2
 +
 +drivers\bus\acpi\cmbatt\cmbatt.sys                  2
 +drivers\bus\acpi\compbatt\compbatt.sys              2
 +
 +drivers\directx\dxapi\dxapi.sys                     2
 +drivers\directx\dxg\dxg.sys                         2
 +drivers\directx\dxgthk\dxgthk.sys                   2
 +
 +drivers\filesystems\fs_rec\fs_rec.sys               2
 +drivers\filesystems\msfs\msfs.sys                   2
 +drivers\filesystems\mup\mup.sys                     2
 +drivers\filesystems\npfs\npfs.sys                   2
 +
 +drivers\input\mouclass\mouclass.sys                 2
 +drivers\input\sermouse\sermouse.sys                 2
 +
 +drivers\ksfilter\ks\ks.sys                          2
 +drivers\multimedia\bdasup\bdasup.sys                2
 +
 +drivers\network\afd\afd.sys                         2
 +drivers\network\ndis\ndis.sys                       2
 +drivers\network\tcpip\tcpip.sys                     2
 +drivers\network\tdi\tdi.sys                         2
 +drivers\network\dd\ne2000\ne2000.sys                2
 +drivers\network\dd\pcnet\pcnet.sys                  2
 +
 +drivers\serial\serenum\serenum.sys                  2
 +drivers\serial\serial\serial.sys                    2
 +
 +drivers\storage\ide\pciide\pciide.sys               2
 +drivers\storage\ide\pciidex\pciidex.sys             2
 +
 +;drivers\usb\miniport\usbohci\usbohci.sys           2
 +;drivers\usb\miniport\usbuhci\usbuhci.sys           2
 +;drivers\usb\usbhub\usbhub.sys                      2
 +;drivers\usb\usbport\usbport.sys                    2
 +drivers\usb\nt4compat\usbdriver\usbdriver.sys       2
 +
 +drivers\video\displays\vga\vgaddi.dll               1
 +drivers\video\displays\framebuf\framebuf.dll        1
 +drivers\video\miniport\vga\vgamp.sys                2
 +drivers\video\miniport\vbe\vbemp.sys                2
 +drivers\video\videoprt\videoprt.sys                 2
 +drivers\video\font\ftfd\ftfd.dll                   1
 +
 +drivers\wdm\audio\filters\kmixer\kmixer.sys         2
 +drivers\wdm\audio\sysaudio\sysaudio.sys             2
 +drivers\wdm\audio\legacy\wdmaud\wdmaud.sys          2
 +drivers\wdm\audio\backpln\portcls\portcls.sys       2
 +drivers\wdm\audio\drm\drmk\drmk.sys                 2
 +drivers\wmi\wmilib.sys                              2
 +
 +; Media
 +media\fonts\DejaVuSans.ttf                          3
 +media\fonts\DejaVuSans-Bold.ttf                     3
 +media\fonts\DejaVuSans-BoldOblique.ttf              3
 +media\fonts\DejaVuSansMono.ttf                      3
 +media\fonts\DejaVuSansMono-Bold.ttf                 3
 +media\fonts\DejaVuSansMono-BoldOblique.ttf          3
 +media\fonts\DejaVuSansMono-Oblique.ttf              3
 +media\fonts\DejaVuSans-Oblique.ttf                  3
 +media\fonts\DejaVuSerif.ttf                         3
 +media\fonts\DejaVuSerif-Bold.ttf                    3
 +media\fonts\DejaVuSerif-BoldItalic.ttf              3
 +media\fonts\DejaVuSerif-Italic.ttf                  3
 +
 +media\fonts\FreeMono.ttf                            3
 +media\fonts\FreeMonoBold.ttf                        3
 +media\fonts\FreeMonoBoldOblique.ttf                 3
 +media\fonts\FreeMonoOblique.ttf                     3
 +
 +media\fonts\LiberationMono-Bold.ttf                 3
 +media\fonts\LiberationMono-BoldItalic.ttf           3
 +media\fonts\LiberationMono-Italic.ttf               3
 +media\fonts\LiberationMono-Regular.ttf              3
 +media\fonts\LiberationSans-Bold.ttf                 3
 +media\fonts\LiberationSans-BoldItalic.ttf           3
 +media\fonts\LiberationSans-Italic.ttf               3
 +media\fonts\LiberationSans-Regular.ttf              3
 +media\fonts\LiberationSerif-Bold.ttf                3
 +media\fonts\LiberationSerif-BoldItalic.ttf          3
 +media\fonts\LiberationSerif-Italic.ttf              3
 +media\fonts\LiberationSerif-Regular.ttf             3
 +
 +media\fonts\Marlett.ttf                             3
 +media\fonts\symbol.ttf                              3
 +media\fonts\tahoma.ttf                              3
 +media\fonts\tahomabd.ttf                            3
 +
 +media\vgafonts\vgafonts.cab                         4
 +
 +media\nls\c_037.nls                                 1
 +media\nls\c_424.nls                                 1
 +media\nls\c_500.nls                                 1
 +media\nls\c_737.nls                                 1
 +media\nls\c_775.nls                                 1
 +media\nls\c_850.nls                                 1
 +media\nls\c_852.nls                                 1
 +media\nls\c_855.nls                                 1
 +media\nls\c_856.nls                                 1
 +media\nls\c_857.nls                                 1
 +media\nls\c_860.nls                                 1
 +media\nls\c_861.nls                                 1
 +media\nls\c_862.nls                                 1
 +media\nls\c_863.nls                                 1
 +media\nls\c_864.nls                                 1
 +media\nls\c_865.nls                                 1
 +media\nls\c_866.nls                                 1
 +media\nls\c_869.nls                                 1
 +media\nls\c_874.nls                                 1
 +media\nls\c_875.nls                                 1
 +media\nls\c_878.nls                                 1
 +media\nls\c_932.nls                                 1
 +media\nls\c_936.nls                                 1
 +media\nls\c_949.nls                                 1
 +media\nls\c_950.nls                                 1
 +media\nls\c_1006.nls                                1
 +media\nls\c_1026.nls                                1
 +media\nls\c_1250.nls                                1
 +media\nls\c_1251.nls                                1
 +media\nls\c_1253.nls                                1
 +media\nls\c_1254.nls                                1
 +media\nls\c_1255.nls                                1
 +media\nls\c_1256.nls                                1
 +media\nls\c_1257.nls                                1
 +media\nls\c_1258.nls                                1
 +media\nls\c_10000.nls                               1
 +media\nls\c_10006.nls                               1
 +media\nls\c_10007.nls                               1
 +media\nls\c_10029.nls                               1
 +media\nls\c_10079.nls                               1
 +media\nls\c_10081.nls                               1
 +media\nls\c_20866.nls                               1
 +media\nls\c_21866.nls                               1
 +media\nls\c_28591.nls                               1
 +media\nls\c_28592.nls                               1
 +media\nls\c_28593.nls                               1
 +media\nls\c_28594.nls                               1
 +media\nls\c_28595.nls                               1
 +media\nls\c_28596.nls                               1
 +media\nls\c_28597.nls                               1
 +media\nls\c_28598.nls                               1
 +media\nls\c_28599.nls                               1
 +media\nls\c_28600.nls                               1
 +media\nls\c_28603.nls                               1
 +media\nls\c_28604.nls                               1
 +media\nls\c_28605.nls                               1
 +media\nls\c_28606.nls                               1
 +media\drivers\etc\hosts                             5
 +media\drivers\etc\services                          5
 +media\inf\audio.inf                                 6
 +media\inf\acpi.inf                                  6
 +media\inf\battery.inf                               6
 +media\inf\cdrom.inf                                 6
 +media\inf\cpu.inf                                   6
 +media\inf\display.inf                               6
 +media\inf\font.inf                                  6
 +media\inf\fdc.inf                                   6
 +media\inf\hdc.inf                                   6
 +media\inf\intl.inf                                  6
 +media\inf\layout.inf                                6
 +media\inf\machine.inf                               6
 +media\inf\msmouse.inf                               6
 +media\inf\keyboard.inf                              6
 +media\inf\ks.inf                                    6
 +media\inf\NET_NIC.inf                               6
 +media\inf\netamd.inf                                6
 +media\inf\netisa.inf                                6
 +media\inf\netrtpnt.inf                              6
 +media\inf\nettcpip.inf                              6
 +media\inf\ports.inf                                 6
 +media\inf\scsi.inf                                  6
 +media\inf\syssetup.inf                              6
 +media\inf\usbport.inf                               6
 +media\inf\usb.inf                                   6
 +media\inf\usbstor.inf                               6
 +media\inf\xboxdisp.inf                              6
 +
 +
 +; Media Files
 +media\sounds\ReactOS_LogOn.wav                      8
 +
 +; Ini Files
 +boot\bootdata\system.ini                            4
 +
 +; Regression Testing
 +boot\bootdata\bootcdregtest\regtest.cmd             7   optional
 +
 +; Subsystems
 +subsystems\win32\csrss\csrss.exe                    1
 +subsystems\win32\csrss\win32csr\win32csr.dll        1
 +subsystems\win32\csrss\csrsrv\csrsrv.dll            1
 +subsystems\ntvdm\ntvdm.exe                          1
 +subsystems\win32\win32k\win32k.sys                  1
 +
 +; Optional/proprietary files
 +modules\optional\DroidSansFallback.ttf              3  optional
 +modules\optional\NOTICE_for_Droid_Font.txt          4  optional
 +modules\optional\netkvm2k.inf                       6  optional
 +modules\optional\netkvm2k.cat                       6  optional
 +modules\optional\netkvm.sys                         2  optional
 +modules\optional\alcxwdm.inf                        6  optional
 +modules\optional\alcxwdm.sys                        2  optional
 +modules\optional\mfc42.dll                          1  optional
 +modules\optional\mfc42u.dll                         1  optional
 +modules\optional\mfc71.dll                          1  optional
 +modules\optional\mfc71u.dll                         1  optional
 +modules\optional\msvbvm50.dll                       1  optional
 +modules\optional\msvbvm60.dll                       1  optional
 +modules\optional\msvcirt.dll                        1  optional
 +modules\optional\msvcp71.dll                        1  optional
 +modules\optional\msvcr71.dll                        1  optional
 +modules\optional\vmx_fb.dll                         1  optional
 +modules\optional\vmx_mode.dll                       1  optional
 +modules\optional\vmx_svga.inf                       6  optional
 +modules\optional\vmx_svga.sys                       2  optional
 +modules\optional\wine_gecko-1.0.0-x86.cab           4  optional
 +
 +; Rosapps
 +modules\rosapps\applications\screensavers\cylfrac\cylfrac.scr              1   optional
 +modules\rosapps\applications\screensavers\matrix\matrix.scr                1   optional
 +modules\rosapps\applications\screensavers\blankscr\scrnsave.scr            1   optional
 +modules\rosapps\applications\screensavers\starfield\starfield.scr          1   optional
 +modules\rosapps\applications\screensavers\mazescr\mazescr.scr              1   optional
 +modules\rosapps\applications\screensavers\butterflies\butterflies.scr      1   optional
 +modules\rosapps\applications\cmdutils\comp\comp.exe                                     1   optional
 +modules\rosapps\applications\cmdutils\mode\mode.exe                                     1   optional
 +modules\rosapps\applications\cmdutils\sort\sort.exe                                     1   optional
 +modules\rosapps\applications\cmdutils\tee\tee.exe                                       1   optional
 +modules\rosapps\applications\cmdutils\touch\touch.exe                                   1   optional
 +modules\rosapps\applications\cmdutils\uptime\uptime.exe                                 1   optional
 +modules\rosapps\applications\cmdutils\y\y.exe                                           1   optional
 +modules\rosapps\applications\devutils\gdb2\gdb2.exe                                     1   optional
 +modules\rosapps\applications\devutils\gdihv\gdihv.exe                                   1   optional
 +modules\rosapps\applications\devutils\genguid\genguid.exe                               1   optional
 +modules\rosapps\applications\sysutils\gettype\gettype.exe                               1   optional
 +modules\rosapps\applications\net\ncftp\ncftp.exe                                        1   optional
 +modules\rosapps\applications\net\netreg\netreg.exe                                      1   optional
 +modules\rosapps\applications\net\niclist\niclist.exe                                    1   optional
 +modules\rosapps\applications\net\roshttpd\roshttpd.exe                                  1   optional
 +modules\rosapps\applications\notevil\notevil.exe                                        1   optional
 +modules\rosapps\applications\sysutils\chkdsk\chkdsk.exe                                 1   optional
 +modules\rosapps\applications\sysutils\systeminfo\systeminfo.exe                         1   optional
 +modules\rosapps\applications\sysutils\chklib\chklib.exe                                 1   optional
 +modules\rosapps\applications\sysutils\ctm\ctm.exe                                       1   optional
 +modules\rosapps\applications\sysutils\kill\kill.exe                                     1   optional
 +modules\rosapps\applications\sysutils\lsdd\lsdd.exe                                     1   optional
 +modules\rosapps\applications\sysutils\man\man.exe                                       1   optional
 +modules\rosapps\applications\sysutils\pedump\pedump.exe                                 1   optional
 +modules\rosapps\applications\sysutils\regexpl\regexpl.exe                               1   optional
 +modules\rosapps\applications\sysutils\tcat\tcat.exe                                     1   optional
 +modules\rosapps\applications\sysutils\tlist\tlist.exe                                   1   optional
 +modules\rosapps\applications\sysutils\screenshot\screenshot.exe                         1   optional
 +modules\rosapps\applications\sysutils\utils\binpatch\binpatch.exe                       1   optional
 +modules\rosapps\applications\sysutils\utils\cat\cat.exe                                 1   optional
 +modules\rosapps\applications\sysutils\utils\driver\load\load.exe                        1   optional
 +modules\rosapps\applications\sysutils\utils\driver\unload\unload.exe                    1   optional
 +modules\rosapps\applications\sysutils\utils\infinst\infinst.exe                         1   optional
 +modules\rosapps\applications\sysutils\utils\nts2w32err\nts2w32err.exe                   1   optional
 +modules\rosapps\applications\sysutils\utils\objdir\objdir.exe                           1   optional
 +modules\rosapps\applications\sysutils\utils\partinfo\partinfo.exe                       1   optional
 +modules\rosapps\applications\sysutils\utils\ps\ps.exe                                   1   optional
 +modules\rosapps\applications\sysutils\utils\rosperf\rosperf.exe                         1   optional
 +modules\rosapps\applications\sysutils\utils\stats\stats.exe                             1   optional
 +modules\rosapps\applications\sysutils\utils\tickcount\tickcount.exe                     1   optional
 +modules\rosapps\applications\winfile\winfile.exe                                        1   optional
 +modules\rosapps\demos\maze\maze.exe                                        1   optional
 +modules\rosapps\drivers\green\green.sys                                    2   optional
 +
 +; Rostests
 +modules\rostests\rosautotest\rosautotest.exe                               1   optional
 +modules\rostests\tests\pseh2\pseh2_test.exe                                7   optional
 +modules\rostests\winetests\advapi32\advapi32_winetest.exe                  7   optional
 +modules\rostests\winetests\advpack\advpack_winetest.exe                    7   optional
 +modules\rostests\winetests\browseui\browseui_winetest.exe                  7   optional
 +modules\rostests\winetests\cabinet\cabinet_winetest.exe                    7   optional
 +modules\rostests\winetests\comcat\comcat_winetest.exe                      7   optional
 +modules\rostests\winetests\comctl32\comctl32_winetest.exe                  7   optional
 +modules\rostests\winetests\comdlg32\comdlg32_winetest.exe                  7   optional
 +modules\rostests\winetests\crypt32\crypt32_winetest.exe                    7   optional
 +modules\rostests\winetests\cryptnet\cryptnet_winetest.exe                  7   optional
 +modules\rostests\winetests\dsound\dsound_winetest.exe                      7   optional
 +modules\rostests\winetests\gdi32\gdi32_winetest.exe                        7   optional
 +modules\rostests\winetests\gdiplus\gdiplus_winetest.exe                    7   optional
 +modules\rostests\winetests\hlink\hlink_winetest.exe                        7   optional
 +modules\rostests\winetests\icmp\icmp_winetest.exe                          7   optional
 +modules\rostests\winetests\iphlpapi\iphlpapi_winetest.exe                  7   optional
 +modules\rostests\winetests\jscript\jscript_winetest.exe                    7   optional
 +modules\rostests\winetests\kernel32\kernel32_winetest.exe                  7   optional
 +modules\rostests\winetests\lz32\lz32_winetest.exe                          7   optional
 +modules\rostests\winetests\mapi32\mapi32_winetest.exe                      7   optional
 +modules\rostests\winetests\mlang\mlang_winetest.exe                        7   optional
 +modules\rostests\winetests\mshtml\mshtml_winetest.exe                      7   optional
 +modules\rostests\winetests\msi\msi_winetest.exe                            7   optional
 +modules\rostests\winetests\mstask\mstask_winetest.exe                      7   optional
 +modules\rostests\winetests\msvcrt\msvcrt_winetest.exe                      7   optional
 +modules\rostests\winetests\msxml3\msxml3_winetest.exe                      7   optional
 +modules\rostests\winetests\netapi32\netapi32_winetest.exe                  7   optional
 +modules\rostests\winetests\ntdll\ntdll_winetest.exe                        7   optional
 +modules\rostests\winetests\odbccp32\odbccp32_winetest.exe                  7   optional
 +modules\rostests\winetests\ole32\ole32_winetest.exe                        7   optional
 +modules\rostests\winetests\oleaut32\oleaut32_winetest.exe                  7   optional
 +modules\rostests\winetests\powrprof\powrprof_winetest.exe                  7   optional
 +modules\rostests\winetests\psapi\psapi_winetest.exe                        7   optional
 +modules\rostests\winetests\riched20\riched20_winetest.exe                  7   optional
 +modules\rostests\winetests\rpcrt4\rpcrt4_winetest.exe                      7   optional
 +modules\rostests\winetests\rsabase\rsabase_winetest.exe                    7   optional
 +modules\rostests\winetests\rsaenh\rsaenh_winetest.exe                      7   optional
 +modules\rostests\winetests\schannel\schannel_winetest.exe                  7   optional
 +modules\rostests\winetests\secur32\secur32_winetest.exe                    7   optional
 +modules\rostests\winetests\setupapi\setupapi_winetest.exe                  7   optional
 +modules\rostests\winetests\shdocvw\shdocvw_winetest.exe                    7   optional
 +modules\rostests\winetests\shell32\shell32_winetest.exe                    7   optional
 +modules\rostests\winetests\shlwapi\shlwapi_winetest.exe                    7   optional
 +modules\rostests\winetests\urlmon\urlmon_winetest.exe                      7   optional
 +modules\rostests\winetests\user32\user32_winetest.exe                      7   optional
 +modules\rostests\winetests\usp10\usp10_winetest.exe                        7   optional
 +modules\rostests\winetests\uxtheme\uxtheme_winetest.exe                    7   optional
 +modules\rostests\winetests\version\version_winetest.exe                    7   optional
 +modules\rostests\winetests\winhttp\winhttp_winetest.exe                    7   optional
 +modules\rostests\winetests\wininet\wininet_winetest.exe                    7   optional
 +modules\rostests\winetests\winmm\winmm_winetest.exe                        7   optional
 +modules\rostests\winetests\wintrust\wintrust_winetest.exe                  7   optional
 +modules\rostests\winetests\wlanapi\wlanapi_winetest.exe                    7   optional
 +modules\rostests\winetests\ws2_32\ws2_32_winetest.exe                      7   optional
 +modules\rostests\winetests\xmllite\xmllite_winetest.exe                    7   optional
 +
 +
 +modules\wallpaper\Angelus_02_ROSWP.bmp                                     4   optional
++
++modules\drivers\video\cirrus\cirrus.inf                                       6  optional
++modules\drivers\video\cirrus\cirrus.dll                                       1  optional
++modules\drivers\video\cirrus\cirrus.sys                                       2  optional
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 5373c6f,0000000..b20ac7e
mode 100644,000000..100644
--- /dev/null
@@@ -1,225 -1,0 +1,229 @@@
 +/*
 + *  ReactOS Gdi32
 + *  Copyright (C) 2003 ReactOS Team
 + *
 + * This library is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * This library is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with this library; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 + *
 + *
 + *
 + *
 + */
 +
 +#include "precomp.h"
 +
 +#define NDEBUG
 +#include <debug.h>
 +
 +
 +
 +typedef int  (WINAPI *CHOOSEPIXELFMT) (HDC, CONST PIXELFORMATDESCRIPTOR *);
 +typedef BOOL (WINAPI *SETPIXELFMT) (HDC, int, CONST PIXELFORMATDESCRIPTOR *);
 +typedef BOOL (WINAPI *SWAPBUFFERS) (HDC hdc);
 +typedef int  (WINAPI *DESCRIBEPIXELFMT) (HDC, int, UINT, LPPIXELFORMATDESCRIPTOR);
 +typedef int  (WINAPI *GETPIXELFMT) (HDC);
 +
 +
 +static CHOOSEPIXELFMT    glChoosePixelFormat   = NULL;
 +static SETPIXELFMT       glSetPixelFormat      = NULL;
 +static SWAPBUFFERS       glSwapBuffers         = NULL;
 +static DESCRIBEPIXELFMT  glDescribePixelFormat = NULL;
 +static GETPIXELFMT       glGetPixelFormat      = NULL;
 +
 +/*
 +              OpenGL Handle.
 +*/
 +HINSTANCE                hOpenGL               = NULL;
 +
 +static BOOL OpenGLInitFunction(PCSTR name,
 +                               FARPROC *funcptr)
 +{
 +    PVOID func;
 +
 +    func = (PVOID)GetProcAddress(hOpenGL, name);
 +    if (func != NULL)
 +    {
 +        (void)InterlockedCompareExchangePointer((PVOID*)funcptr,
 +                                                func,
 +                                                NULL);
 +        return TRUE;
 +    }
 +
 +    return FALSE;
 +}
 +
 +static BOOL OpenGLEnable(void)
 +{
 +    HMODULE hModOpengl32;
 +    BOOL Ret = TRUE;
 +
 +    hModOpengl32 = LoadLibraryW(L"OPENGL32.DLL");
 +    if (hModOpengl32 == NULL)
 +        return FALSE;
 +
 +    if (InterlockedCompareExchangePointer((PVOID*)&hOpenGL,
 +                                          (PVOID)hModOpengl32,
 +                                          NULL) != NULL)
 +    {
 +        FreeLibrary(hModOpengl32);
 +
 +        /* NOTE: Even though another thread was faster loading the
 +                 library we can't just bail out here. We really need
 +                 to *try* to locate every function. This is slow but
 +                 thread-safe */
 +    }
 +
 +
 +    if (!OpenGLInitFunction("wglChoosePixelFormat", &glChoosePixelFormat))
 +        Ret = FALSE;
 +
 +    if (!OpenGLInitFunction("wglSetPixelFormat", &glSetPixelFormat))
 +        Ret = FALSE;
 +
 +    if (!OpenGLInitFunction("wglSwapBuffers", &glSwapBuffers))
 +        Ret = FALSE;
 +
 +    if (!OpenGLInitFunction("wglDescribePixelFormat", &glDescribePixelFormat))
 +        Ret = FALSE;
 +
 +    if (!OpenGLInitFunction("wglGetPixelFormat", &glGetPixelFormat))
 +        Ret = FALSE;
 +
 +    return Ret;
 +}
 +
 +
 +
 +/*
 + * @implemented
 + */
 +INT
 +WINAPI
 +ChoosePixelFormat(HDC  hdc,
 +                  CONST PIXELFORMATDESCRIPTOR * ppfd)
 +{
 +  if (glChoosePixelFormat == NULL)
 +    if (OpenGLEnable() == FALSE)
 +      return(0);
 +
 +  return(glChoosePixelFormat(hdc, ppfd));
 +}
 +
 +
 +
 +/*
 + * @implemented
 + */
 +INT
 +WINAPI
 +DescribePixelFormat(HDC  hdc,
 +                    INT  iPixelFormat,
 +                    UINT  nBytes,
 +                    LPPIXELFORMATDESCRIPTOR  ppfd)
 +{
 +  if (glDescribePixelFormat == NULL)
 +    if (OpenGLEnable() == FALSE)
 +      return(0);
 +
 +  return(glDescribePixelFormat(hdc, iPixelFormat, nBytes, ppfd));
 +}
 +
 +
 +
 +/*
 + * @implemented
 + */
 +INT
 +WINAPI
 +GetPixelFormat(HDC  hdc)
 +{
 +  if (glGetPixelFormat == NULL)
 +    if (OpenGLEnable() == FALSE)
 +      return(0);
 +
 +  return(glGetPixelFormat(hdc));
 +}
 +
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +SetPixelFormat(HDC  hdc,
 +               INT  iPixelFormat,
 +               CONST PIXELFORMATDESCRIPTOR * ppfd)
 +{
++  /* Can only be set once */
++  INT current = GetPixelFormat(hdc);
++  if(current) return current == iPixelFormat ;
++  
 +  if (glSetPixelFormat == NULL)
 +    if (OpenGLEnable() == FALSE)
 +      return(0);
 +
 +  return(glSetPixelFormat(hdc, iPixelFormat, ppfd));
 +}
 +
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +SwapBuffers(HDC  hdc)
 +{
 +  if (glSwapBuffers == NULL)
 +    if (OpenGLEnable() == FALSE)
 +      return(0);
 +
 +
 +  return(glSwapBuffers(hdc));
 +}
 +
 +
 +/*
 +      Do this here for now.
 +*/
 +
 +/*
 + * @implemented
 + */
 +UINT
 +WINAPI
 +GetEnhMetaFilePixelFormat(
 +      HENHMETAFILE                    hemf,
 +      UINT                            cbBuffer,
 +      PIXELFORMATDESCRIPTOR   *ppfd
 +      )
 +{
 +      ENHMETAHEADER pemh;
 +
 +      if(GetEnhMetaFileHeader(hemf, sizeof(ENHMETAHEADER), &pemh))
 +      {
 +      if(pemh.bOpenGL)
 +      {
 +              if(pemh.cbPixelFormat)
 +              {
 +              memcpy((void*)ppfd, UlongToPtr(pemh.offPixelFormat), cbBuffer );
 +              return(pemh.cbPixelFormat);
 +              }
 +      }
 +      }
 +      return(0);
 +}
 +
 +/* EOF */
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 2dd3312,0000000..cf46007
mode 100644,000000..100644
--- /dev/null
@@@ -1,656 -1,0 +1,652 @@@
-             icd->refcount++;
 +/*
 + * COPYRIGHT:            See COPYING in the top level directory
 + * PROJECT:              ReactOS kernel
 + * FILE:                 lib/opengl32/opengl32.c
 + * PURPOSE:              OpenGL32 lib
 + * PROGRAMMER:           Anich Gregor (blight), Royce Mitchell III
 + * UPDATE HISTORY:
 + *                       Feb 1, 2004: Created
 + */
 +
 +#include "opengl32.h"
 +
 +/* function prototypes */
 +static void OPENGL32_AppendICD( GLDRIVERDATA *icd );
 +static void OPENGL32_RemoveICD( GLDRIVERDATA *icd );
 +static GLDRIVERDATA *OPENGL32_LoadDriver( LPCWSTR regKey );
 +static DWORD OPENGL32_InitializeDriver( GLDRIVERDATA *icd );
 +static BOOL OPENGL32_UnloadDriver( GLDRIVERDATA *icd );
 +static DWORD OPENGL32_RegGetDriverInfo( LPCWSTR driver, GLDRIVERDATA *icd );
 +
 +
 +/* global vars */
 +/* Do not assume it have the free value MAXDWORD set, any value can be in here */
 +DWORD OPENGL32_tls = MAXDWORD;
 +GLPROCESSDATA OPENGL32_processdata;
 +
 +
 +static BOOL
 +OPENGL32_ThreadAttach( void )
 +{
 +    GLTHREADDATA* lpData = NULL;
 +    PROC *dispatchTable = NULL;
 +    TEB *teb = NULL;
 +
 +    dispatchTable = (PROC*)HeapAlloc( GetProcessHeap(),
 +                                      HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
 +                                      sizeof (((ICDTable *)(0))->dispatch_table) );
 +    if (dispatchTable == NULL)
 +    {
 +        DBGPRINT( "Error: Couldn't allocate GL dispatch table" );
 +        return FALSE;
 +    }
 +
 +    lpData = (GLTHREADDATA*)HeapAlloc( GetProcessHeap(),
 +                                       HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
 +                                       sizeof (GLTHREADDATA) );
 +    if (lpData == NULL)
 +    {
 +        DBGPRINT( "Error: Couldn't allocate GLTHREADDATA" );
 +        HeapFree( GetProcessHeap(), 0, dispatchTable );
 +        return FALSE;
 +    }
 +
 +    teb = NtCurrentTeb();
 +
 +    /* initialize dispatch table with empty functions */
 +    #define X(func, ret, typeargs, args, icdidx, tebidx, stack)            \
 +        dispatchTable[icdidx] = (PROC)glEmptyFunc##stack;                  \
 +        if (tebidx >= 0)                                                   \
 +            teb->glDispatchTable[tebidx] = (PVOID)glEmptyFunc##stack;
 +    GLFUNCS_MACRO
 +    #undef X
 +
 +    teb->glTable = dispatchTable;
 +    TlsSetValue( OPENGL32_tls, lpData );
 +
 +    return TRUE;
 +}
 +
 +
 +static void
 +OPENGL32_ThreadDetach( void )
 +{
 +    GLTHREADDATA* lpData = NULL;
 +    PROC *dispatchTable = NULL;
 +
 +    rosglMakeCurrent( NULL, NULL );
 +
 +    lpData = (GLTHREADDATA*)TlsGetValue( OPENGL32_tls );
 +    if (lpData != NULL)
 +    {
 +        if (!HeapFree( GetProcessHeap(), 0, lpData ))
 +            DBGPRINT( "Warning: HeapFree() on GLTHREADDATA failed (%d)",
 +                      GetLastError() );
 +        lpData = NULL;
 +    }
 +
 +    dispatchTable = NtCurrentTeb()->glTable;
 +    if (dispatchTable != NULL)
 +    {
 +        if (!HeapFree( GetProcessHeap(), 0, dispatchTable ))
 +            DBGPRINT( "Warning: HeapFree() on dispatch table failed (%d)",
 +                      GetLastError() );
 +    }
 +}
 +
 +
 +static BOOL
 +OPENGL32_ProcessAttach( void )
 +{
 +    SECURITY_ATTRIBUTES attrib = { sizeof (SECURITY_ATTRIBUTES), /* nLength */
 +                                   NULL, /* lpSecurityDescriptor */
 +                                   TRUE /* bInheritHandle */ };
 +
 +    OPENGL32_tls = TlsAlloc();
 +    if (OPENGL32_tls == MAXDWORD)
 +        return FALSE;
 +
 +    memset( &OPENGL32_processdata, 0, sizeof (OPENGL32_processdata) );
 +
 +    /* create driver, glrc & dcdata list mutex */
 +    OPENGL32_processdata.driver_mutex = CreateMutex( &attrib, FALSE, NULL );
 +    if (OPENGL32_processdata.driver_mutex == NULL)
 +    {
 +        DBGPRINT( "Error: Couldn't create driver_list mutex (%d)",
 +                  GetLastError() );
 +        return FALSE;
 +    }
 +    OPENGL32_processdata.glrc_mutex = CreateMutex( &attrib, FALSE, NULL );
 +    if (OPENGL32_processdata.glrc_mutex == NULL)
 +    {
 +        DBGPRINT( "Error: Couldn't create glrc_list mutex (%d)",
 +                  GetLastError() );
 +        return FALSE;
 +    }
 +    OPENGL32_processdata.dcdata_mutex = CreateMutex( &attrib, FALSE, NULL );
 +    if (OPENGL32_processdata.dcdata_mutex == NULL)
 +    {
 +        DBGPRINT( "Error: Couldn't create dcdata_list mutex (%d)",
 +                  GetLastError() );
 +        return FALSE;
 +    }
 +
 +    return TRUE;
 +}
 +
 +
 +static void
 +OPENGL32_ProcessDetach( void )
 +{
 +    GLDRIVERDATA *icd, *icd2;
 +    GLDCDATA *dcdata, *dcdata2;
 +    GLRC *glrc, *glrc2;
 +
 +    /* free lists */
 +    for (dcdata = OPENGL32_processdata.dcdata_list; dcdata != NULL;)
 +    {
 +        dcdata2 = dcdata;
 +        dcdata = dcdata->next;
 +        if (!HeapFree( GetProcessHeap(), 0, dcdata2 ))
 +            DBGPRINT( "Warning: HeapFree() on DCDATA 0x%08x failed (%d)",
 +                      dcdata2, GetLastError() );
 +    }
 +
 +    for (glrc = OPENGL32_processdata.glrc_list; glrc != NULL;)
 +    {
 +        glrc2 = glrc;
 +        glrc = glrc->next;
 +        if (!HeapFree( GetProcessHeap(), 0, glrc2 ))
 +            DBGPRINT( "Warning: HeapFree() on GLRC 0x%08x failed (%d)",
 +                      glrc2, GetLastError() );
 +    }
 +
 +    for (icd = OPENGL32_processdata.driver_list; icd != NULL;)
 +    {
 +        icd2 = icd;
 +        icd = icd->next;
 +        if (!HeapFree( GetProcessHeap(), 0, icd2 ))
 +            DBGPRINT( "Warning: HeapFree() on DRIVERDATA 0x%08x failed (%d)",
 +                      icd2, GetLastError() );
 +    }
 +
 +    /* free mutexes */
 +    if (OPENGL32_processdata.driver_mutex != NULL)
 +        CloseHandle( OPENGL32_processdata.driver_mutex );
 +    if (OPENGL32_processdata.glrc_mutex != NULL)
 +        CloseHandle( OPENGL32_processdata.glrc_mutex );
 +    if (OPENGL32_processdata.dcdata_mutex != NULL)
 +        CloseHandle( OPENGL32_processdata.dcdata_mutex );
 +
 +    /* free TLS */
 +    if (OPENGL32_tls != MAXDWORD)
 +        TlsFree(OPENGL32_tls);
 +}
 +
 +
 +BOOL WINAPI
 +DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
 +{
 +    DBGPRINT( "Info: Called!" );
 +    switch ( Reason )
 +    {
 +    /* The DLL is loading due to process
 +     * initialization or a call to LoadLibrary.
 +     */
 +    case DLL_PROCESS_ATTACH:
 +        DBGTRACE( "Process attach" );
 +        if (!OPENGL32_ProcessAttach())
 +            return FALSE;
 +        /* No break: Initialize the index for first thread. */
 +
 +    /* The attached process creates a new thread. */
 +    case DLL_THREAD_ATTACH:
 +        DBGTRACE( "Thread attach" );
 +        if (!OPENGL32_ThreadAttach())
 +            return FALSE;
 +        break;
 +
 +    /* The thread of the attached process terminates. */
 +    case DLL_THREAD_DETACH:
 +        DBGTRACE( "Thread detach" );
 +        /* Release the allocated memory for this thread.*/
 +        OPENGL32_ThreadDetach();
 +        break;
 +
 +    /* DLL unload due to process termination or FreeLibrary. */
 +    case DLL_PROCESS_DETACH:
 +        DBGTRACE( "Process detach" );
 +        OPENGL32_ThreadDetach();
 +        OPENGL32_ProcessDetach();
 +        break;
 +    }
 +
 +    return TRUE;
 +}
 +
 +
 +/*! \brief Append ICD to linked list.
 + *
 + * \param icd  GLDRIVERDATA to append to list
 + *
 + * \note Only call this when you hold the driver_mutex.
 + */
 +static void
 +OPENGL32_AppendICD( GLDRIVERDATA *icd )
 +{
 +    if (OPENGL32_processdata.driver_list == NULL)
 +        OPENGL32_processdata.driver_list = icd;
 +    else
 +    {
 +        GLDRIVERDATA *p = OPENGL32_processdata.driver_list;
 +        while (p->next != NULL)
 +            p = p->next;
 +        p->next = icd;
 +    }
 +}
 +
 +
 +/*! \brief Remove ICD from linked list.
 + *
 + * \param icd  GLDRIVERDATA to remove from list
 + *
 + * \note Only call this when you hold the driver_mutex.
 + */
 +static void
 +OPENGL32_RemoveICD( GLDRIVERDATA *icd )
 +{
 +    if (icd == OPENGL32_processdata.driver_list)
 +        OPENGL32_processdata.driver_list = icd->next;
 +    else
 +    {
 +        GLDRIVERDATA *p = OPENGL32_processdata.driver_list;
 +        while (p != NULL)
 +        {
 +            if (p->next == icd)
 +            {
 +                p->next = icd->next;
 +                return;
 +            }
 +            p = p->next;
 +        }
 +        DBGPRINT( "Error: ICD 0x%08x not found in list!", icd );
 +    }
 +}
 +
 +
 +/*! \brief  Load an ICD.
 + *
 + * \param driver  Name of installable client driver.
 + *
 + * \return Pointer to an allocated GLDRIVERDATA struct.
 + * \retval NULL  Failure.
 + *
 + * \todo Call SetLastError() where appropriate.
 + */
 +static GLDRIVERDATA *
 +OPENGL32_LoadDriver( LPCWSTR driver )
 +{
 +    LONG ret;
 +    GLDRIVERDATA *icd;
 +
 +    DBGPRINT( "Info: Loading driver %ws...", driver );
 +
 +    /* allocate driver data */
 +    icd = (GLDRIVERDATA*)HeapAlloc( GetProcessHeap(),
 +                                    HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
 +                                    sizeof (GLDRIVERDATA) );
 +    if (icd == NULL)
 +    {
 +        DBGPRINT( "Error: Couldn't allocate GLDRIVERDATA! (%d)", GetLastError() );
 +        return NULL;
 +    }
 +
 +    ret = OPENGL32_RegGetDriverInfo( driver, icd );
 +    if (ret != ERROR_SUCCESS)
 +    {
 +        DBGPRINT( "Error: Couldn't query driver information (%d)", ret );
 +        if (!HeapFree( GetProcessHeap(), 0, icd ))
 +            DBGPRINT( "Error: HeapFree() returned false, error code = %d",
 +                      GetLastError() );
 +        return NULL;
 +    }
 +
 +    DBGPRINT( "Info: Dll = %ws", icd->dll );
 +    DBGPRINT( "Info: Version = 0x%08x", icd->version );
 +    DBGPRINT( "Info: DriverVersion = 0x%08x", icd->driver_version );
 +    DBGPRINT( "Info: Flags = 0x%08x", icd->flags );
 +
 +    /* load/initialize ICD */
 +    ret = OPENGL32_InitializeDriver( icd );
 +    if (ret != ERROR_SUCCESS)
 +    {
 +        DBGPRINT( "Error: Couldnt initialize ICD!" );
 +        if (!HeapFree( GetProcessHeap(), 0, icd ))
 +            DBGPRINT( "Error: HeapFree() returned false, error code = %d",
 +                      GetLastError() );
 +        return NULL;
 +    }
 +
 +    /* append ICD to list */
 +    OPENGL32_AppendICD( icd );
 +    DBGPRINT( "Info: ICD loaded." );
 +
 +    return icd;
 +}
 +
 +
 +/*! \brief Initialize a driver (Load DLL and DrvXxx procs)
 + *
 + * \param icd  ICD to initialize with the dll, version, driverVersion
 + *             and flags already filled.
 + * \return Error code.
 + * \retval ERROR_SUCCESS  Success
 + */
 +#define LOAD_DRV_PROC( icd, proc, required ) \
 +    *(char**)&icd->proc = (char*)GetProcAddress( icd->handle, #proc ); \
 +    if (required && icd->proc == NULL) { \
 +        DBGPRINT( "Error: GetProcAddress(\"%s\") failed!", #proc ); \
 +        FreeLibrary( icd->handle ); \
 +        return GetLastError(); \
 +    }
 +
 +static DWORD
 +OPENGL32_InitializeDriver( GLDRIVERDATA *icd )
 +{
 +    /* check version */
 +    if (icd->version > 2)
 +        DBGPRINT( "Warning: ICD version > 2 (%d)", icd->version );
 +
 +    /* load dll */
 +    icd->handle = LoadLibraryW( icd->dll );
 +    if (icd->handle == NULL)
 +    {
 +        DWORD err = GetLastError();
 +        DBGPRINT( "Error: Couldn't load DLL! (%d)", err );
 +        return err;
 +    }
 +
 +    /* validate version */
 +    if (icd->driver_version > 1)
 +    {
 +        LOAD_DRV_PROC(icd, DrvValidateVersion, FALSE);
 +        if (icd->DrvValidateVersion != NULL)
 +        {
 +            if (!icd->DrvValidateVersion( icd->driver_version ))
 +            {
 +                DBGPRINT( "Error: DrvValidateVersion failed!" );
 +                DBGBREAK();
 +                FreeLibrary( icd->handle );
 +                return ERROR_INVALID_FUNCTION; /* FIXME: use better error code */
 +            }
 +        }
 +        else
 +            DBGPRINT( "Info: DrvValidateVersion not exported by ICD" );
 +    }
 +
 +    /* load DrvXXX procs */
 +    LOAD_DRV_PROC(icd, DrvCopyContext, TRUE);
 +    LOAD_DRV_PROC(icd, DrvCreateContext, FALSE);
 +    LOAD_DRV_PROC(icd, DrvCreateLayerContext, FALSE);
 +    LOAD_DRV_PROC(icd, DrvDeleteContext, TRUE);
 +    LOAD_DRV_PROC(icd, DrvDescribeLayerPlane, TRUE);
 +    LOAD_DRV_PROC(icd, DrvDescribePixelFormat, TRUE);
 +    LOAD_DRV_PROC(icd, DrvGetLayerPaletteEntries, TRUE);
 +    LOAD_DRV_PROC(icd, DrvGetProcAddress, TRUE);
 +    LOAD_DRV_PROC(icd, DrvReleaseContext, TRUE);
 +    LOAD_DRV_PROC(icd, DrvRealizeLayerPalette, TRUE);
 +    LOAD_DRV_PROC(icd, DrvSetContext, TRUE);
 +    LOAD_DRV_PROC(icd, DrvSetLayerPaletteEntries, TRUE);
 +    LOAD_DRV_PROC(icd, DrvSetPixelFormat, TRUE);
 +    LOAD_DRV_PROC(icd, DrvShareLists, TRUE);
 +    LOAD_DRV_PROC(icd, DrvSwapBuffers, TRUE);
 +    LOAD_DRV_PROC(icd, DrvSwapLayerBuffers, TRUE);
 +
 +    /* we require at least one of DrvCreateContext and DrvCreateLayerContext */
 +    if (icd->DrvCreateContext == NULL && icd->DrvCreateLayerContext == NULL)
 +    {
 +        DBGPRINT( "Error: One of DrvCreateContext/DrvCreateLayerContext is required!" );
 +        FreeLibrary( icd->handle );
 +        return ERROR_INVALID_FUNCTION; /* FIXME: use better error code... */
 +    }
 +
 +    return ERROR_SUCCESS;
 +}
 +
 +
 +/*! \brief Unload ICD.
 + *
 + * \retval  TRUE  Success.
 + * \retval  FALSE Failure.
 + */
 +static BOOL
 +OPENGL32_UnloadDriver( GLDRIVERDATA *icd )
 +{
 +    BOOL allOk = TRUE;
 +
 +    DBGPRINT( "Info: Unloading driver %ws...", icd->driver_name );
 +    if (icd->refcount != 0)
 +        DBGPRINT( "Warning: ICD refcount = %d (should be 0)", icd->refcount );
 +
 +    /* unload dll */
 +    if (!FreeLibrary( icd->handle ))
 +    {
 +        allOk = FALSE;
 +        DBGPRINT( "Warning: FreeLibrary on ICD %ws failed! (%d)", icd->dll,
 +                  GetLastError() );
 +    }
 +
 +    /* free resources */
 +    OPENGL32_RemoveICD( icd );
 +    if (!HeapFree( GetProcessHeap(), 0, icd ))
 +    {
 +        allOk = FALSE;
 +        DBGPRINT( "Warning: HeapFree() returned FALSE, error code = %d",
 +                  GetLastError() );
 +    }
 +
 +    return allOk;
 +}
 +
 +
 +/*! \brief Load ICD (shared ICD data)
 + *
 + * \return Pointer to an allocated GLDRIVERDATA on success.
 + * \retval NULL  Failure.
 + */
 +GLDRIVERDATA *
 +OPENGL32_LoadICD( LPCWSTR driver )
 +{
 +    GLDRIVERDATA *icd;
 +
 +    /* synchronize */
 +    if (WaitForSingleObject( OPENGL32_processdata.driver_mutex, INFINITE ) ==
 +        WAIT_FAILED)
 +    {
 +        DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
 +        return NULL; /* FIXME: do we have to expect such an error and handle it? */
 +    }
 +
 +    /* look if ICD is already loaded */
 +    for (icd = OPENGL32_processdata.driver_list; icd; icd = icd->next)
 +    {
 +        if (!_wcsicmp( driver, icd->driver_name )) /* found */
 +        {
-     if (icd != NULL)
-         icd->refcount = 1;
 +            /* release mutex */
 +            if (!ReleaseMutex( OPENGL32_processdata.driver_mutex ))
 +                DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
 +
 +            return icd;
 +        }
 +    }
 +
 +    /* not found - try to load */
 +    icd = OPENGL32_LoadDriver( driver );
-     if (--icd->refcount == 0)
 +
 +    /* release mutex */
 +    if (!ReleaseMutex( OPENGL32_processdata.driver_mutex ))
 +        DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
 +
 +    return icd;
 +}
 +
 +
 +/*! \brief Unload ICD (shared ICD data)
 + *
 + * \retval TRUE   Success.
 + * \retval FALSE  Failure.
 + */
 +BOOL
 +OPENGL32_UnloadICD( GLDRIVERDATA *icd )
 +{
 +    BOOL ret = TRUE;
 +
 +    /* synchronize */
 +    if (WaitForSingleObject( OPENGL32_processdata.driver_mutex, INFINITE ) ==
 +        WAIT_FAILED)
 +    {
 +        DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
 +        return FALSE; /* FIXME: do we have to expect such an error and handle it? */
 +    }
 +
++    if (icd->refcount == 0)
 +        ret = OPENGL32_UnloadDriver( icd );
 +
 +    /* release mutex */
 +    if (!ReleaseMutex( OPENGL32_processdata.driver_mutex ))
 +        DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
 +
 +    return ret;
 +}
 +
 +
 +/*! \brief Enumerate OpenGLDrivers (from registry)
 + *
 + * \param idx    Index of the driver to get information about.
 + * \param name   Pointer to an array of WCHARs (can be NULL)
 + * \param cName  Pointer to a DWORD. Input is len of name array.
 + *               Output is length of the drivername.
 + *               Can be NULL if name is NULL.
 + *
 + * \return Error code
 + * \retval ERROR_NO_MORE_ITEMS  End of driver list.
 + * \retval ERROR_SUCCESS        Success.
 + */
 +#if 0 /* unused */
 +DWORD
 +OPENGL32_RegEnumDrivers( DWORD idx, LPWSTR name, LPDWORD cName )
 +{
 +    HKEY hKey;
 +    LPCWSTR subKey = OPENGL_DRIVERS_SUBKEY;
 +    LONG ret;
 +    DWORD size;
 +    WCHAR driver[256];
 +
 +    if (name == NULL)
 +        return ERROR_SUCCESS; /* nothing to do */
 +
 +    if (cName == NULL)
 +        return ERROR_INVALID_FUNCTION; /* we need cName when name is given */
 +
 +    /* open OpenGLDrivers registry key */
 +    ret = RegOpenKeyExW( HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &hKey );
 +    if (ret != ERROR_SUCCESS)
 +    {
 +        DBGPRINT( "Error: Couldn't open registry key '%ws'", subKey );
 +        return ret;
 +    }
 +
 +    /* get subkey name */
 +    size = sizeof (driver) / sizeof (driver[0]);
 +    ret = RegEnumKeyW( hKey, idx, name, *cName );
 +    if (ret != ERROR_SUCCESS)
 +    {
 +        DBGPRINT( "Error: Couldn't get OpenGLDrivers subkey name (%d)", ret );
 +        RegCloseKey( hKey );
 +        return ret;
 +    }
 +    *cName = wcslen( name );
 +
 +    /* close key */
 +    RegCloseKey( hKey );
 +    return ERROR_SUCCESS;
 +}
 +#endif /* 0 -- unused */
 +
 +
 +/*! \brief Get registry values for a driver given a name.
 + *
 + * \param driver  Name of the driver to get information about.
 + * \param icd     Pointer to GLDRIVERDATA.
 + *
 + * \return Error code.
 + * \retval ERROR_SUCCESS  Success.
 + *
 + * \note On success the following fields of \a icd are filled: \a driver_name,
 + *       \a dll, \a version, \a driver_version and \a flags.
 + */
 +static DWORD
 +OPENGL32_RegGetDriverInfo( LPCWSTR driver, GLDRIVERDATA *icd )
 +{
 +    HKEY hKey;
 +    WCHAR subKey[1024] = OPENGL_DRIVERS_SUBKEY2;
 +    LONG ret;
 +    DWORD type, size;
 +
 +    /* drivers registry values */
 +    DWORD version = 1, driverVersion = 0, flags = 0;
 +    WCHAR dll[256];
 +
 +    /* open driver registry key */
 +    wcsncat( subKey, driver, 1024 );
 +    ret = RegOpenKeyExW( HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &hKey );
 +    if (ret != ERROR_SUCCESS)
 +    {
 +        DBGPRINT( "Error: Couldn't open registry key '%ws'", subKey );
 +        return ret;
 +    }
 +
 +    /* query values */
 +    size = sizeof (dll);
 +    ret = RegQueryValueExW( hKey, L"Dll", 0, &type, (LPBYTE)dll, &size );
 +    if (ret != ERROR_SUCCESS || type != REG_SZ)
 +    {
 +        DBGPRINT( "Error: Couldn't query Dll value or not a string" );
 +        RegCloseKey( hKey );
 +        return ret;
 +    }
 +
 +    size = sizeof (DWORD);
 +    ret = RegQueryValueExW( hKey, L"Version", 0, &type, (LPBYTE)&version, &size );
 +    if (ret != ERROR_SUCCESS || type != REG_DWORD)
 +        DBGPRINT( "Warning: Couldn't query Version value or not a DWORD" );
 +
 +    size = sizeof (DWORD);
 +    ret = RegQueryValueExW( hKey, L"DriverVersion", 0, &type,
 +                            (LPBYTE)&driverVersion, &size );
 +    if (ret != ERROR_SUCCESS || type != REG_DWORD)
 +        DBGPRINT( "Warning: Couldn't query DriverVersion value or not a DWORD" );
 +
 +    size = sizeof (DWORD);
 +    ret = RegQueryValueExW( hKey, L"Flags", 0, &type, (LPBYTE)&flags, &size );
 +    if (ret != ERROR_SUCCESS || type != REG_DWORD)
 +        DBGPRINT( "Warning: Couldn't query Flags value or not a DWORD" );
 +
 +    /* close key */
 +    RegCloseKey( hKey );
 +
 +    /* output data */
 +    /* FIXME: NUL-terminate strings? */
 +    wcsncpy( icd->driver_name, driver,
 +             sizeof (icd->driver_name) / sizeof (icd->driver_name[0]) - 1 );
 +    wcsncpy( icd->dll, dll,
 +             sizeof (icd->dll) / sizeof (icd->dll[0]) );
 +    icd->version = version;
 +    icd->driver_version = driverVersion;
 +    icd->flags = flags;
 +
 +    return ERROR_SUCCESS;
 +}
 +
 +/* EOF */
 +
index e22386c,0000000..2cc3a9c
mode 100644,000000..100644
--- /dev/null
@@@ -1,240 -1,0 +1,241 @@@
 +/*
 + * COPYRIGHT:            See COPYING in the top level directory
 + * PROJECT:              ReactOS kernel
 + * FILE:                 lib/opengl32/opengl32.h
 + * PURPOSE:              OpenGL32 lib
 + * PROGRAMMER:           Royce Mitchell III, Anich Gregor (blight)
 + * UPDATE HISTORY:
 + *                       Feb 1, 2004: Created
 + */
 +
 +#ifndef OPENGL32_PRIVATE_H
 +#define OPENGL32_PRIVATE_H
 +
 +#define snwprintf _snwprintf
 +
 +#ifdef __cplusplus
 +extern "C" {
 +#endif /* __cplusplus */
 +
 +#define NDEBUG
 +
 +#ifndef PFD_GENERIC_ACCELERATED
 +# define PFD_GENERIC_ACCELERATED 0x00001000
 +#endif
 +
 +#define OPENGL_DRIVERS_SUBKEY L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers"
 +#define OPENGL_DRIVERS_SUBKEY2 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers\\"
 +
 +#include <stdio.h>
 +#include <stdlib.h>
 +#include <string.h>
 +
 +#define WIN32_LEAN_AND_MEAN
 +#define WIN32_NO_STATUS
 +#include <windows.h>
 +#include <winreg.h>
 +
 +#define NTOS_MODE_USER
 +#include <winddi.h>
 +#include <ndk/ntndk.h>
 +
 +#include <GL/gl.h>
 +#include <GL/glu.h>
 +
 +/* gl function list */
 +#include "glfuncs.h"
 +
 +/* ICD index list/types */
 +#include "icdtable.h"
 +
 +/* debug flags */
 +#if !defined(NDEBUG)
 +# define DEBUG_OPENGL32
 +/* enable breakpoints */
 +/*# define DEBUG_OPENGL32_BRKPTS*/
 +/* dumps the list of (un)supported glXXX functions when an ICD is loaded. */
 +# define DEBUG_OPENGL32_ICD_EXPORTS
 +/* prints much information about whats going on */
 +# define DEBUG_OPENGL32_TRACE
 +#endif /* !NDEBUG */
 +
 +/* debug macros */
 +# ifdef DEBUG_OPENGL32
 +#  include <debug.h>
 +#  define DBGPRINT( fmt, args... ) \
 +          DPRINT( "OpenGL32.DLL: %s: "fmt"\n", __FUNCTION__, ##args )
 +# endif
 +
 +#ifndef DBGPRINT
 +# define DBGPRINT( ... ) do {} while (0)
 +#endif
 +
 +#ifdef DEBUG_OPENGL32_BRKPTS
 +# if defined(__GNUC__)
 +#  define DBGBREAK() __asm__( "int $3" );
 +# elif defined(_MSC_VER)
 +#  define DBGBREAK() __asm { int 3 }
 +# else
 +#  error Unsupported compiler!
 +# endif
 +#else
 +# define DBGBREAK() do {} while (0)
 +#endif
 +
 +#ifdef DEBUG_OPENGL32_TRACE
 +# define DBGTRACE( args... ) DBGPRINT( args )
 +#else
 +# define DBGTRACE( ... ) do {} while (0)
 +#endif
 +
 +/* function/data attributes */
 +#define EXPORT __declspec(dllexport)
 +#ifdef _MSC_VER
 +#  define NAKED __declspec(naked)
 +#  define SHARED
 +#  ifndef WINAPI
 +#    define WINAPI __stdcall
 +#  endif /* WINAPI */
 +#else /* GCC */
 +#  define NAKED __attribute__((naked))
 +#  define SHARED __attribute__((section("shared"), shared))
 +#endif
 +
 +#ifdef APIENTRY
 +#undef APIENTRY
 +#endif /* APIENTRY */
 +#define APIENTRY __stdcall
 +
 +/* Called by the driver to set the dispatch table */
 +typedef DWORD (WINAPI *SetContextCallBack)( const ICDTable * );
 +
 +/* OpenGL ICD data */
 +typedef struct tagGLDRIVERDATA
 +{
 +    HMODULE handle;                 /*!< DLL handle */
 +    UINT    refcount;               /*!< Number of references to this ICD */
 +    WCHAR   driver_name[256];       /*!< Name of ICD driver */
 +
 +    WCHAR   dll[256];               /*!< Dll filename from registry */
 +    DWORD   version;                /*!< Version value from registry */
 +    DWORD   driver_version;         /*!< DriverVersion value from registry */
 +    DWORD   flags;                  /*!< Flags value from registry */
 +
 +    BOOL      (WINAPI *DrvCopyContext)( HGLRC, HGLRC, UINT );
 +    HGLRC     (WINAPI *DrvCreateContext)( HDC );
 +    HGLRC     (WINAPI *DrvCreateLayerContext)( HDC, int );
 +    BOOL      (WINAPI *DrvDeleteContext)( HGLRC );
 +    BOOL      (WINAPI *DrvDescribeLayerPlane)( HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR );
 +    int       (WINAPI *DrvDescribePixelFormat)( IN HDC, IN int, IN UINT, OUT LPPIXELFORMATDESCRIPTOR );
 +    int       (WINAPI *DrvGetLayerPaletteEntries)( HDC, int, int, int, COLORREF * );
 +    PROC      (WINAPI *DrvGetProcAddress)( LPCSTR lpProcName );
 +    void      (WINAPI *DrvReleaseContext)( HGLRC hglrc ); /* maybe returns BOOL? */
 +    BOOL      (WINAPI *DrvRealizeLayerPalette)( HDC, int, BOOL );
 +    PICDTable (WINAPI *DrvSetContext)( HDC hdc, HGLRC hglrc, SetContextCallBack callback );
 +    int       (WINAPI *DrvSetLayerPaletteEntries)( HDC, int, int, int, CONST COLORREF * );
 +    BOOL      (WINAPI *DrvSetPixelFormat)( IN HDC, IN int, const PIXELFORMATDESCRIPTOR * );
 +    BOOL      (WINAPI *DrvShareLists)( HGLRC, HGLRC );
 +    BOOL      (WINAPI *DrvSwapBuffers)( HDC );
 +    BOOL      (WINAPI *DrvSwapLayerBuffers)( HDC, UINT );
 +    BOOL      (WINAPI *DrvValidateVersion)( DWORD );
 +
 +    struct tagGLDRIVERDATA *next;   /* next ICD -- linked list */
 +} GLDRIVERDATA;
 +
 +/* Our private OpenGL context (stored in TLS) */
 +typedef struct tagGLRC
 +{
 +    GLDRIVERDATA *icd;  /*!< driver used for this context */
 +    HDC     hdc;        /*!< DC handle */
 +    BOOL    is_current; /*!< Wether this context is current for some DC */
 +    DWORD   thread_id;  /*!< Thread holding this context */
 +
 +    HGLRC   hglrc;      /*!< GLRC from DrvCreateContext (ICD internal) */
 +
 +    struct tagGLRC *next; /* linked list */
 +} GLRC;
 +
 +/* OpenGL private device context data */
 +typedef struct tagGLDCDATA
 +{
 +    HDC hdc;           /*!< Device context handle for which this data is */
 +    GLDRIVERDATA *icd; /*!< Driver used for this DC */
 +    int pixel_format;  /*!< Selected pixel format */
 +
 +    struct tagGLDCDATA *next; /* linked list */
 +} GLDCDATA;
 +
 +
 +/* Process data */
 +typedef struct tagGLPROCESSDATA
 +{
 +    GLDRIVERDATA *driver_list;  /*!< List of loaded drivers */
 +    HANDLE        driver_mutex; /*!< Mutex to protect driver list */
 +    GLRC         *glrc_list;    /*!< List of GL rendering contexts */
 +    HANDLE        glrc_mutex;   /*!< Mutex to protect glrc list */
 +    GLDCDATA     *dcdata_list;  /*!< List of GL private DC data */
 +    HANDLE        dcdata_mutex; /*!< Mutex to protect glrc list */
 +} GLPROCESSDATA;
 +
 +/* TLS data */
 +typedef struct tagGLTHREADDATA
 +{
 +    GLRC   *glrc;      /*!< current GL rendering context */
 +} GLTHREADDATA;
 +
 +extern DWORD OPENGL32_tls;
 +extern GLPROCESSDATA OPENGL32_processdata;
 +#define OPENGL32_threaddata ((GLTHREADDATA *)TlsGetValue( OPENGL32_tls ))
 +
 +/* function prototypes */
 +GLDRIVERDATA *OPENGL32_LoadICD( LPCWSTR driver );
 +BOOL OPENGL32_UnloadICD( GLDRIVERDATA *icd );
 +BOOL APIENTRY rosglMakeCurrent( HDC hdc, HGLRC hglrc );
++int APIENTRY rosglGetPixelFormat( HDC );
 +BOOL APIENTRY IntUseFontBitmapsA( HDC hDC, DWORD first, DWORD count, DWORD listBase );
 +BOOL APIENTRY IntUseFontBitmapsW( HDC hDC, DWORD first, DWORD count, DWORD listBase );
 +BOOL APIENTRY IntUseFontOutlinesA( HDC hDC, DWORD first, DWORD count, DWORD listBase,
 +                                  FLOAT chordalDeviation, FLOAT extrusion, INT format,
 +                                  GLYPHMETRICSFLOAT *glyphMetricsFloatArray );
 +BOOL APIENTRY IntUseFontOutlinesW( HDC hDC, DWORD first, DWORD count, DWORD listBase,
 +                                  FLOAT chordalDeviation, FLOAT extrusion, INT format,
 +                                  GLYPHMETRICSFLOAT *glyphMetricsFloatArray );
 +
 +/* empty gl functions from gl.c */
 +int WINAPI glEmptyFunc0( void );
 +int WINAPI glEmptyFunc4( long );
 +int WINAPI glEmptyFunc8( long, long );
 +int WINAPI glEmptyFunc12( long, long, long );
 +int WINAPI glEmptyFunc16( long, long, long, long );
 +int WINAPI glEmptyFunc20( long, long, long, long, long );
 +int WINAPI glEmptyFunc24( long, long, long, long, long, long );
 +int WINAPI glEmptyFunc28( long, long, long, long, long, long, long );
 +int WINAPI glEmptyFunc32( long, long, long, long, long, long, long, long );
 +int WINAPI glEmptyFunc36( long, long, long, long, long, long, long, long,
 +                           long );
 +int WINAPI glEmptyFunc40( long, long, long, long, long, long, long, long,
 +                           long, long );
 +int WINAPI glEmptyFunc44( long, long, long, long, long, long, long, long,
 +                           long, long, long );
 +int WINAPI glEmptyFunc48( long, long, long, long, long, long, long, long,
 +                           long, long, long, long );
 +int WINAPI glEmptyFunc52( long, long, long, long, long, long, long, long,
 +                           long, long, long, long, long );
 +int WINAPI glEmptyFunc56( long, long, long, long, long, long, long, long,
 +                           long, long, long, long, long, long );
 +
 +#ifdef OPENGL32_GL_FUNC_PROTOTYPES
 +
 +#define X(func,ret,typeargs,args,icdidx,tebidx,stack) ret WINAPI func typeargs;
 +GLFUNCS_MACRO
 +#undef X
 +
 +#endif /* OPENGL32_GL_FUNC_PROTOTYPES */
 +
 +#ifdef __cplusplus
 +}; /* extern "C" */
 +#endif /* __cplusplus */
 +
 +#endif /* OPENGL32_PRIVATE_H */
 +
 +/* EOF */
index 953305b,0000000..cb10478
mode 100644,000000..100644
--- /dev/null
@@@ -1,1248 -1,0 +1,1267 @@@
-     if (glrc->icd != NULL)
 +/*
 + * COPYRIGHT:            See COPYING in the top level directory
 + * PROJECT:              ReactOS kernel
 + * FILE:                 lib/opengl32/wgl.c
 + * PURPOSE:              OpenGL32 lib, rosglXXX functions
 + * PROGRAMMER:           Anich Gregor (blight)
 + * UPDATE HISTORY:
 + *                       Feb 2, 2004: Created
 + */
 +
 +#define OPENGL32_GL_FUNC_PROTOTYPES
 +#include "opengl32.h"
 +
 +#ifdef __cplusplus
 +extern "C" {
 +#endif /* __cplusplus */
 +
 +#if !defined(UNIMPLEMENTED)
 +# define UNIMPLEMENTED DBGPRINT( "UNIMPLEMENTED" )
 +#endif
 +
 +
 +typedef struct _OPENGL_INFO
 +{
 +    DWORD Version;          /*!< Driver interface version */
 +    DWORD DriverVersion;    /*!< Driver version */
 +    WCHAR DriverName[256];  /*!< Driver name */
 +} OPENGL_INFO, *POPENGL_INFO;
 +
 +
 +/*! \brief Append OpenGL Rendering Context (GLRC) to list
 + *
 + * \param glrc [IN] Pointer to GLRC to append to list
 + */
 +static
 +void
 +ROSGL_AppendContext( GLRC *glrc )
 +{
 +    /* synchronize */
 +    if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) ==
 +        WAIT_FAILED)
 +    {
 +        DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
 +        return; /* FIXME: do we have to expect such an error and handle it? */
 +    }
 +
 +    if (OPENGL32_processdata.glrc_list == NULL)
 +        OPENGL32_processdata.glrc_list = glrc;
 +    else
 +    {
 +        GLRC *p = OPENGL32_processdata.glrc_list;
 +        while (p->next != NULL)
 +            p = p->next;
 +        p->next = glrc;
 +    }
 +
 +    /* release mutex */
 +    if (!ReleaseMutex( OPENGL32_processdata.glrc_mutex ))
 +        DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
 +}
 +
 +
 +/*! \brief Remove OpenGL Rendering Context (GLRC) from list
 + *
 + * \param glrc [IN] Pointer to GLRC to remove from list
 + */
 +static
 +void
 +ROSGL_RemoveContext( GLRC *glrc )
 +{
 +    /* synchronize */
 +    if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) ==
 +        WAIT_FAILED)
 +    {
 +        DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
 +        return; /* FIXME: do we have to expect such an error and handle it? */
 +    }
 +
 +    if (glrc == OPENGL32_processdata.glrc_list)
 +        OPENGL32_processdata.glrc_list = glrc->next;
 +    else
 +    {
 +        GLRC *p = OPENGL32_processdata.glrc_list;
 +        while (p != NULL)
 +        {
 +            if (p->next == glrc)
 +            {
 +                p->next = glrc->next;
 +                break;
 +            }
 +            p = p->next;
 +        }
 +        if (p == NULL)
 +            DBGPRINT( "Error: GLRC 0x%08x not found in list!", glrc );
 +    }
 +
 +    /* release mutex */
 +    if (!ReleaseMutex( OPENGL32_processdata.glrc_mutex ))
 +        DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
 +}
 +
 +
 +/*! \brief Create a new GL Context (GLRC) and append it to the list
 + *
 + * \return Pointer to new GLRC on success
 + * \retval NULL Returned on failure (i.e. Out of memory)
 + */
 +static
 +GLRC *
 +ROSGL_NewContext(void)
 +{
 +    GLRC *glrc;
 +
 +    /* allocate GLRC */
 +    glrc = (GLRC*)HeapAlloc( GetProcessHeap(),
 +                  HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, sizeof (GLRC) );
 +
 +    /* append to list */
 +    ROSGL_AppendContext( glrc );
 +
 +    return glrc;
 +}
 +
 +/*! \brief Delete all GLDCDATA with this IDC
 + *
 + * \param icd [IN] Pointer to a ICD
 + */
 +static
 +VOID
 +ROSGL_DeleteDCDataForICD( GLDRIVERDATA *icd )
 +{
 +    GLDCDATA *p, **pptr;
 +
 +    /* synchronize */
 +    if (WaitForSingleObject( OPENGL32_processdata.dcdata_mutex, INFINITE ) ==
 +        WAIT_FAILED)
 +    {
 +        DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
 +        return;
 +    }
 +
 +    p = OPENGL32_processdata.dcdata_list;
 +    pptr = &OPENGL32_processdata.dcdata_list;
 +    while (p != NULL)
 +    {
 +        if (p->icd == icd)
 +        {
 +            *pptr = p->next;
 +            OPENGL32_UnloadICD( p->icd );
 +
 +            if (!HeapFree( GetProcessHeap(), 0, p ))
 +                DBGPRINT( "Warning: HeapFree() on GLDCDATA failed (%d)",
 +                          GetLastError() );
 +
 +            p = *pptr;
 +        }
 +        else
 +        {
 +            pptr = &p->next;
 +            p = p->next;
 +        }
 +    }
 +
 +    /* release mutex */
 +    if (!ReleaseMutex( OPENGL32_processdata.dcdata_mutex ))
 +        DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
 +}
 +
 +
 +/*! \brief Delete a GL Context (GLRC) and remove it from the list
 + *
 + * \param glrc [IN] Pointer to GLRC to delete
 + *
 + * \retval TRUE  Success
 + * \retval FALSE Failure
 + */
 +static
 +BOOL
 +ROSGL_DeleteContext( GLRC *glrc )
 +{
 +    /* unload icd */
-         if (data->hdc == hdc) /* found */
++    if ((glrc->icd != NULL) && !(InterlockedDecrement((LONG*)&glrc->icd->refcount)))
++    {
++        /* This is the last context, remove the ICD */
 +        ROSGL_DeleteDCDataForICD( glrc->icd );
++    }
 +
 +    /* remove from list */
 +    ROSGL_RemoveContext( glrc );
 +
 +    /* free memory */
 +    HeapFree( GetProcessHeap(), 0, glrc );
 +
 +    return TRUE;
 +}
 +
 +
 +/*! \brief Check wether a GLRC is in the list
 + *
 + * \param glrc [IN] Pointer to GLRC to look for in the list
 + *
 + * \retval TRUE  GLRC was found
 + * \retval FALSE GLRC was not found
 + */
 +static
 +BOOL
 +ROSGL_ContainsContext( GLRC *glrc )
 +{
 +    GLRC *p;
 +    BOOL found = FALSE;
 +
 +    /* synchronize */
 +    if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) ==
 +        WAIT_FAILED)
 +    {
 +        DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
 +        return FALSE; /* FIXME: do we have to expect such an error and handle it? */
 +    }
 +
 +    p = OPENGL32_processdata.glrc_list;
 +    while (p != NULL)
 +    {
 +        if (p == glrc)
 +        {
 +            found = TRUE;
 +            break;
 +        }
 +        p = p->next;
 +    }
 +
 +    /* release mutex */
 +    if (!ReleaseMutex( OPENGL32_processdata.glrc_mutex ))
 +        DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
 +
 +    return found;
 +}
 +
 +
 +/*! \brief Get GL private DC data.
 + *
 + * This function adds an empty GLDCDATA to the list if there is no data for the
 + * given DC yet.
 + *
 + * \param hdc [IN] Handle to a Device Context for which to get the data
 + *
 + * \return Pointer to GLDCDATA on success
 + * \retval NULL on failure
 + */
 +static
 +GLDCDATA *
 +ROSGL_GetPrivateDCData( HDC hdc )
 +{
 +    GLDCDATA *data;
 +
 +    /* check hdc */
 +    if (GetObjectType( hdc ) != OBJ_DC && GetObjectType( hdc ) != OBJ_MEMDC)
 +    {
 +        DBGPRINT( "Error: hdc is not a DC handle!" );
 +        SetLastError( ERROR_INVALID_HANDLE );
 +        return FALSE;
 +    }
 +
 +    /* synchronize */
 +    if (WaitForSingleObject( OPENGL32_processdata.dcdata_mutex, INFINITE ) ==
 +        WAIT_FAILED)
 +    {
 +        DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
 +        return NULL; /* FIXME: do we have to expect such an error and handle it? */
 +    }
 +
 +    /* look for data in list */
 +    data = OPENGL32_processdata.dcdata_list;
 +    while (data != NULL)
 +    {
-                 OPENGL32_UnloadICD(drvdata);
++        if ((data->hdc == hdc) || (WindowFromDC(data->hdc) == WindowFromDC(hdc))) /* found */
 +            break;
 +        data = data->next;
 +    }
 +
 +    /* allocate new data if not found in list */
 +    if (data == NULL)
 +    {
 +        data = HeapAlloc( GetProcessHeap(),
 +                          HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS,
 +                          sizeof (GLDCDATA) );
 +        if (data == NULL)
 +        {
 +            DBGPRINT( "Error: HeapAlloc() failed (%d)", GetLastError() );
 +        }
 +        else
 +        {
 +            data->hdc = hdc;
 +
 +            /* append data to list */
 +            if (OPENGL32_processdata.dcdata_list == NULL)
 +                OPENGL32_processdata.dcdata_list = data;
 +            else
 +            {
 +                GLDCDATA *p = OPENGL32_processdata.dcdata_list;
 +                while (p->next != NULL)
 +                    p = p->next;
 +                p->next = data;
 +            }
 +        }
 +    }
 +
 +    /* release mutex */
 +    if (!ReleaseMutex( OPENGL32_processdata.dcdata_mutex ))
 +        DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
 +
 +    return data;
 +}
 +
 +
 +/*! \brief Get ICD from HDC.
 + *
 + * This function asks the display driver which OpenGL ICD to load for the given
 + * HDC, loads it and returns a pointer to a GLDRIVERDATA struct on success.
 + *
 + * \param hdc [IN] Handle for DC for which to load/get the ICD
 + *
 + * \return Pointer to GLDRIVERDATA
 + * \retval NULL Failure.
 + */
 +static
 +GLDRIVERDATA *
 +ROSGL_ICDForHDC( HDC hdc )
 +{
 +    GLDCDATA *dcdata;
 +    GLDRIVERDATA *drvdata;
 +
 +    dcdata = ROSGL_GetPrivateDCData( hdc );
 +    if (dcdata == NULL)
 +        return NULL;
 +
 +    if (dcdata->icd == NULL)
 +    {
 +        LPCWSTR driverName;
 +        OPENGL_INFO info;
 +
 +        /* NOTE: This might be done by multiple threads simultaneously, but only the fastest
 +                 actually gets to set the ICD! */
 +
 +        driverName = _wgetenv( L"OPENGL32_DRIVER" );
 +        if (driverName == NULL)
 +        {
 +            DWORD dwInput;
 +            LONG ret;
 +
 +            /* get driver name */
 +            dwInput = OPENGL_GETINFO;
 +            ret = ExtEscape( hdc, QUERYESCSUPPORT, sizeof (dwInput), (LPCSTR)&dwInput, 0, NULL );
 +            if (ret > 0)
 +            {
 +                dwInput = 0;
 +                ret = ExtEscape( hdc, OPENGL_GETINFO, sizeof (dwInput),
 +                                 (LPCSTR)&dwInput, sizeof (OPENGL_INFO),
 +                                 (LPSTR)&info );
 +            }
 +            if (ret <= 0)
 +            {
 +                HKEY hKey;
 +                DWORD type, size;
 +
 +                if (ret < 0)
 +                {
 +                    DBGPRINT( "Warning: ExtEscape to get the drivername failed! (%d)", GetLastError() );
 +                    if (MessageBox( WindowFromDC( hdc ), L"Couldn't get installable client driver name!\nUsing default driver.",
 +                                    L"OPENGL32.dll: Warning", MB_OKCANCEL | MB_ICONWARNING ) == IDCANCEL)
 +                    {
 +                        return NULL;
 +                    }
 +                }
 +
 +                /* open registry key */
 +                ret = RegOpenKeyExW( HKEY_LOCAL_MACHINE, OPENGL_DRIVERS_SUBKEY, 0, KEY_QUERY_VALUE, &hKey );
 +                if (ret != ERROR_SUCCESS)
 +                {
 +                    DBGPRINT( "Error: Couldn't open registry key '%ws'", OPENGL_DRIVERS_SUBKEY );
 +                    SetLastError( ret );
 +                    return NULL;
 +                }
 +
 +                /* query value */
 +                size = sizeof (info.DriverName);
 +                ret = RegQueryValueExW( hKey, L"DefaultDriver", 0, &type, (LPBYTE)info.DriverName, &size );
 +                RegCloseKey( hKey );
 +                if (ret != ERROR_SUCCESS || type != REG_SZ)
 +                {
 +                    DBGPRINT( "Error: Couldn't query DefaultDriver value or not a string" );
 +                    SetLastError( ret );
 +                    return NULL;
 +                }
 +            }
 +        }
 +        else
 +        {
 +            wcsncpy( info.DriverName, driverName, sizeof (info.DriverName) / sizeof (info.DriverName[0]) );
 +        }
 +        /* load driver (or get a reference) */
 +        drvdata = OPENGL32_LoadICD( info.DriverName );
 +        if (drvdata == NULL)
 +        {
 +            WCHAR Buffer[256];
 +            snwprintf(Buffer, sizeof(Buffer)/sizeof(WCHAR),
 +                      L"Couldn't load driver \"%s\".", info.DriverName);
 +            MessageBox(WindowFromDC( hdc ), Buffer,
 +                       L"OPENGL32.dll: Warning",
 +                       MB_OK | MB_ICONWARNING);
 +        }
 +        else
 +        {
 +            /* Atomically set the ICD!!! */
 +            if (InterlockedCompareExchangePointer((PVOID*)&dcdata->icd,
 +                                                  (PVOID)drvdata,
 +                                                  NULL) != NULL)
 +            {
 +                /* Too bad, somebody else was faster... */
++                DBGTRACE("Uh, Someone beat you to it!\n");
 +            }
 +        }
 +    }
 +
 +    return dcdata->icd;
 +}
 +
 +
 +/*! \brief SetContextCallBack passed to DrvSetContext.
 + *
 + * This function gets called by the OpenGL driver whenever the current GL
 + * context (dispatch table) is to be changed.
 + *
 + * \param table [IN] Function pointer table (first DWORD is number of functions)
 + *
 + * \return unkown (maybe void? ERROR_SUCCESS at the moment)
 + */
 +DWORD
 +CALLBACK
 +ROSGL_SetContextCallBack( const ICDTable *table )
 +{
 +    TEB *teb;
 +    PROC *tebTable, *tebDispatchTable;
 +    INT size;
 +
 +    teb = NtCurrentTeb();
 +    tebTable = (PROC *)teb->glTable;
 +    tebDispatchTable = (PROC *)teb->glDispatchTable;
 +
 +    DBGTRACE( "Called!" );
 +
 +    if (table != NULL)
 +    {
 +        DBGPRINT( "Function count: %d\n", table->num_funcs );
 +
 +        /* save table */
 +        size = sizeof (PROC) * table->num_funcs;
 +        memcpy( tebTable, table->dispatch_table, size );
 +        memset( tebTable + table->num_funcs, 0,
 +                sizeof (table->dispatch_table) - size );
 +    }
 +    else
 +    {
 +        DBGPRINT( "Unsetting current context" );
 +        memset( tebTable, 0, sizeof (table->dispatch_table) );
 +    }
 +
 +    /* put in empty functions as long as we dont have a fallback */
 +    #define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
 +        if (tebTable[icdidx] == NULL) \
 +        { \
 +            if (table != NULL) \
 +                DBGPRINT( "Warning: GL proc '%s' is NULL", #func ); \
 +            tebTable[icdidx] = (PROC)glEmptyFunc##stack; \
 +        }
 +    GLFUNCS_MACRO
 +#undef X
 +
 +    /* fill teb->glDispatchTable for fast calls */
 +#define X(func, ret, typeargs, args, icdidx, tebidx, stack) \
 +        if (tebidx >= 0) \
 +            tebDispatchTable[tebidx] = tebTable[icdidx];
 +    GLFUNCS_MACRO
 +#undef X
 +
 +    DBGPRINT( "Done." );
 +
 +    return ERROR_SUCCESS;
 +}
 +
 +
 +/*! \brief Attempts to find the best matching pixel format for HDC
 + *
 + * This function is comparing each available format with the preferred one
 + * and returns the one which is closest to it.
 + * If PFD_DOUBLEBUFFER, PFD_STEREO or one of PFD_DRAW_TO_WINDOW,
 + * PFD_DRAW_TO_BITMAP, PFD_SUPPORT_GDI and PDF_SUPPORT_OPENGL is given then
 + * only formats which also support those will be enumerated (unless
 + * PFD_DOUBLEBUFFER_DONTCARE or PFD_STEREO_DONTCARE is also set)
 + *
 + * \param hdc [IN] Handle to DC for which to get a pixel format index
 + * \param pfd [IN] PFD describing what kind of format you want
 + *
 + * \return Pixel format index
 + * \retval 0 Failed to find a suitable format
 + */
 +#define BUFFERDEPTH_SCORE(want, have) \
 +    ((want == 0) ? (0) : ((want < have) ? (1) : ((want > have) ? (3) : (0))))
 +
 +/* Score if we want and not have it */
 +#define FLAG_SCORE(want, have, flag) \
 +    (((want & ~have) & flag) ? (1) : (0))
 +
 +/* Score if what we want is different than what we have, except when
 +   _DONTCARE was set */
 +#define FLAG_SCORE_DONTCARE(want, have, flag) \
 +    ((!(have & flag ## _DONTCARE)) && ((want & flag) != (have & flag)) ? (1) : (0))
 +
 +int
 +APIENTRY
 +rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
 +{
 +    GLDRIVERDATA *icd;
 +    PIXELFORMATDESCRIPTOR icdPfd;
 +    int i;
 +    int best = 0;
 +    int score, bestScore = 0x7fff; /* used to choose a pfd if no exact match */
 +    int icdNumFormats;
 +
 +    DBGTRACE( "Called!" );
 +
 +    /* load ICD */
 +    icd = ROSGL_ICDForHDC( hdc );
 +    if (icd == NULL)
 +        return 0;
 +
 +    /* check input */
 +    if (pfd->nSize != sizeof (PIXELFORMATDESCRIPTOR) || pfd->nVersion != 1)
 +    {
 +        SetLastError( ERROR_INVALID_PARAMETER );
 +        return 0;
 +    }
 +
 +    /* get number of formats */
 +    icdNumFormats = icd->DrvDescribePixelFormat( hdc, 1,
 +                    sizeof (PIXELFORMATDESCRIPTOR), &icdPfd );
 +    if (icdNumFormats == 0)
 +    {
 +        DBGPRINT( "Error: DrvDescribePixelFormat failed (%d)", GetLastError() );
 +        return 0;
 +    }
 +    DBGPRINT( "Info: Enumerating %d pixelformats", icdNumFormats );
 +
 +    /* try to find best format */
 +    for (i = 0; i < icdNumFormats; i++)
 +    {
 +        if (icd->DrvDescribePixelFormat( hdc, i + 1,
 +            sizeof (PIXELFORMATDESCRIPTOR), &icdPfd ) == 0)
 +        {
 +            DBGPRINT( "Warning: DrvDescribePixelFormat failed (%d)",
 +                        GetLastError() );
 +            break;
 +        }
 +
 +        if ((pfd->dwFlags & PFD_GENERIC_ACCELERATED) != 0) /* we do not support such kind of drivers */
 +        {
 +            continue;
 +        }
 +
 +        score = 0; /* higher is worse */
 +
 +        /* compare flags */
 +        score += FLAG_SCORE(pfd->dwFlags, icdPfd.dwFlags, PFD_DRAW_TO_WINDOW);
 +        score += FLAG_SCORE(pfd->dwFlags, icdPfd.dwFlags, PFD_DRAW_TO_BITMAP);
 +        score += FLAG_SCORE(pfd->dwFlags, icdPfd.dwFlags, PFD_SUPPORT_GDI);
 +        score += FLAG_SCORE(pfd->dwFlags, icdPfd.dwFlags, PFD_SUPPORT_OPENGL);
 +        score += FLAG_SCORE_DONTCARE(pfd->dwFlags, icdPfd.dwFlags, PFD_DOUBLEBUFFER);
 +        score += FLAG_SCORE_DONTCARE(pfd->dwFlags, icdPfd.dwFlags, PFD_STEREO);
 +
 +        /* check other attribs */
 +        if (pfd->iPixelType != icdPfd.iPixelType)
 +            score += 5; /* this is really bad i think */
 +        if (pfd->iLayerType != icdPfd.iLayerType)
 +            score += 15; /* this is very very bad ;) */
 +
 +        score += BUFFERDEPTH_SCORE(pfd->cAlphaBits, icdPfd.cAlphaBits);
 +        score += BUFFERDEPTH_SCORE(pfd->cAccumBits, icdPfd.cAccumBits);
 +        score += BUFFERDEPTH_SCORE(pfd->cDepthBits, icdPfd.cDepthBits);
 +        score += BUFFERDEPTH_SCORE(pfd->cStencilBits, icdPfd.cStencilBits);
 +        score += BUFFERDEPTH_SCORE(pfd->cAuxBuffers, icdPfd.cAuxBuffers);
 +
 +        /* check score */
 +        if (score < bestScore)
 +        {
 +            bestScore = score;
 +            best = i + 1;
 +            if (bestScore == 0)
 +                break;
 +        }
 +    }
 +
 +    if (best == 0)
 +        SetLastError( 0 ); /* FIXME: set appropriate error */
 +
 +    DBGPRINT( "Info: Suggesting pixelformat %d", best );
 +    return best;
 +}
 +
 +
 +/*! \brief Copy data specified by mask from one GLRC to another.
 + *
 + * \param src  [IN] Source GLRC
 + * \param src  [OUT] Destination GLRC
 + * \param mask [IN] Bitfield like given to glPushAttrib()
 + *
 + * \retval TRUE  Success
 + * \retval FALSE Failure
 + */
 +BOOL
 +APIENTRY
 +rosglCopyContext( HGLRC hsrc, HGLRC hdst, UINT mask )
 +{
 +    GLRC *src = (GLRC *)hsrc;
 +    GLRC *dst = (GLRC *)hdst;
 +
 +    /* check glrcs */
 +    if (!ROSGL_ContainsContext( src ))
 +    {
 +        DBGPRINT( "Error: src GLRC not found!" );
 +        SetLastError( ERROR_INVALID_HANDLE );
 +        return FALSE;
 +    }
 +    if (!ROSGL_ContainsContext( dst ))
 +    {
 +        DBGPRINT( "Error: dst GLRC not found!" );
 +        SetLastError( ERROR_INVALID_HANDLE );
 +        return FALSE;
 +    }
 +
 +    /* I think this is only possible within one ICD */
 +    if (src->icd != dst->icd)
 +    {
 +        DBGPRINT( "Error: src and dst GLRC use different ICDs!" );
 +        SetLastError( ERROR_INVALID_HANDLE );
 +        return FALSE;
 +    }
 +
 +    /* copy data (call ICD) */
 +    return src->icd->DrvCopyContext( src->hglrc, dst->hglrc, mask );
 +}
 +
 +
 +/*! \brief Create a new GL Rendering Context.
 + *
 + * This function can create over- or underlay surfaces.
 + *
 + * \param hdc [IN] Handle for DC for which to create context
 + * \param layer [IN] Layer number to bind (draw?) to
 + *
 + * \return Handle for the created GLRC
 + * \retval NULL Failure
 + */
 +HGLRC
 +APIENTRY
 +rosglCreateLayerContext( HDC hdc, int layer )
 +{
 +    GLDRIVERDATA *icd = NULL;
 +    GLRC *glrc;
 +    HGLRC drvHglrc = NULL;
 +
 +    DBGTRACE( "Called!" );
 +
 +/*    if (GetObjectType( hdc ) != OBJ_DC)
 +    {
 +        DBGPRINT( "Error: hdc is not a DC handle!" );
 +        return NULL;
 +    }
 +*/
 +    /* create new GLRC */
 +    glrc = ROSGL_NewContext();
 +    if (glrc == NULL)
 +        return NULL;
 +
 +    /* load ICD */
 +    icd = ROSGL_ICDForHDC( hdc );
 +    if (icd == NULL)
 +    {
 +        ROSGL_DeleteContext( glrc );
 +        DBGPRINT( "Couldn't get ICD by HDC :-(" );
 +        /* FIXME: fallback? */
 +        return NULL;
 +    }
++    
++    /* Don't forget to refcount it, icd will be released when last context is deleted */
++    InterlockedIncrement((LONG*)&icd->refcount);
++    
++    if(!rosglGetPixelFormat(hdc))
++    {
++        ROSGL_DeleteContext(glrc);
++      SetLastError(ERROR_INVALID_PIXEL_FORMAT);
++      return NULL;
++    }
 +
 +    /* create context */
 +    if (icd->DrvCreateLayerContext != NULL)
 +        drvHglrc = icd->DrvCreateLayerContext( hdc, layer );
 +    if (drvHglrc == NULL)
 +    {
 +        if (layer == 0 && icd->DrvCreateContext != NULL)
 +            drvHglrc = icd->DrvCreateContext( hdc );
 +        else
 +            DBGPRINT( "Warning: CreateLayerContext not supported by ICD!" );
 +    }
 +
 +    if (drvHglrc == NULL)
 +    {
 +        /* FIXME: fallback to mesa? */
 +        DBGPRINT( "Error: DrvCreate[Layer]Context failed! (%d)", GetLastError() );
 +        ROSGL_DeleteContext( glrc );
 +        return NULL;
 +    }
 +
 +    /* we have our GLRC in glrc and the ICD's GLRC in drvHglrc */
 +    glrc->hglrc = drvHglrc;
 +    glrc->icd = icd;
 +
 +    return (HGLRC)glrc;
 +}
 +
 +
 +/*! \brief Create a new GL Rendering Context.
 + *
 + * \param hdc [IN] Handle for DC for which to create context
 + *
 + * \return Handle for the created GLRC
 + * \retval NULL Failure
 + */
 +HGLRC
 +APIENTRY
 +rosglCreateContext( HDC hdc )
 +{
 +    return rosglCreateLayerContext( hdc, 0 );
 +}
 +
 +
 +/*! \brief Delete an OpenGL context
 + *
 + * \param hglrc [IN] Handle to GLRC to delete; must not be a threads current RC!
 + *
 + * \retval TRUE  Success
 + * \retval FALSE Failure (i.e. GLRC is current for a thread)
 + */
 +BOOL
 +APIENTRY
 +rosglDeleteContext( HGLRC hglrc )
 +{
 +    GLRC *glrc = (GLRC *)hglrc;
 +
 +    /* check if we know about this context */
 +    if (!ROSGL_ContainsContext( glrc ))
 +    {
 +        DBGPRINT( "Error: hglrc not found!" );
 +        SetLastError( ERROR_INVALID_HANDLE );
 +        return FALSE;
 +    }
 +
 +    /* make sure GLRC is not current for some thread */
 +    if (glrc->is_current)
 +    {
 +        DBGPRINT( "Error: GLRC is current for DC 0x%08x", glrc->hdc );
 +        SetLastError( ERROR_INVALID_FUNCTION );
 +        return FALSE;
 +    }
 +
 +    /* release ICD's context */
 +    if (glrc->hglrc != NULL)
 +    {
 +        if (!glrc->icd->DrvDeleteContext( glrc->hglrc ))
 +        {
 +            DBGPRINT( "Warning: DrvDeleteContext() failed (%d)", GetLastError() );
 +            return FALSE;
 +        }
 +    }
 +
 +    /* free resources */
 +    return ROSGL_DeleteContext( glrc );
 +}
 +
 +
 +BOOL
 +APIENTRY
 +rosglDescribeLayerPlane( HDC hdc, int iPixelFormat, int iLayerPlane,
 +                         UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd )
 +{
 +    UNIMPLEMENTED;
 +    SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
 +    return FALSE;
 +}
 +
 +
 +/*! \brief Gets information about a pixelformat.
 + *
 + * \param hdc     [IN]  Handle to DC
 + * \param iFormat [IN]  Pixelformat index
 + * \param nBytes  [IN]  sizeof (pfd) - at most nBytes are copied into pfd
 + * \param pfd     [OUT] Pointer to a PIXELFORMATDESCRIPTOR
 + *
 + * \return Maximum pixelformat index/number of formats
 + * \retval 0 Failure
 + */
 +int
 +APIENTRY
 +rosglDescribePixelFormat( HDC hdc, int iFormat, UINT nBytes,
 +                          LPPIXELFORMATDESCRIPTOR pfd )
 +{
 +    int ret = 0;
 +    GLDRIVERDATA *icd = ROSGL_ICDForHDC( hdc );
 +
 +    if (icd != NULL)
 +    {
 +        ret = icd->DrvDescribePixelFormat( hdc, iFormat, nBytes, pfd );
 +        if (ret == 0)
 +            DBGPRINT( "Error: DrvDescribePixelFormat(format=%d) failed (%d)", iFormat, GetLastError() );
 +    }
 +    else
 +    {
 +        SetLastError( ERROR_INVALID_FUNCTION );
 +    }
 +
 +    return ret;
 +}
 +
 +
 +/*! \brief Return the thread's current GLRC
 + *
 + * \return Handle for thread's current GLRC
 + * \retval NULL No current GLRC set
 + */
 +HGLRC
 +APIENTRY
 +rosglGetCurrentContext()
 +{
 +    return (HGLRC)(OPENGL32_threaddata->glrc);
 +}
 +
 +
 +/*! \brief Return the thread's current DC
 + *
 + * \return Handle for thread's current DC
 + * \retval NULL No current DC/GLRC set
 + */
 +HDC
 +APIENTRY
 +rosglGetCurrentDC()
 +{
 +    /* FIXME: is it correct to return NULL when there is no current GLRC or
 +       is there another way to find out the wanted HDC? */
 +    if (OPENGL32_threaddata->glrc == NULL)
 +        return NULL;
 +    return (HDC)(OPENGL32_threaddata->glrc->hdc);
 +}
 +
 +
 +int
 +APIENTRY
 +rosglGetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
 +                             int cEntries, COLORREF *pcr )
 +{
 +    UNIMPLEMENTED;
 +    SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
 +    return 0;
 +}
 +
 +
 +/*! \brief Returns the current pixelformat.
 + *
 + * \param hdc [IN] Handle to DC to get the pixelformat from
 + *
 + * \return Pixelformat index
 + * \retval 0 Failure
 + */
 +int
 +WINAPI
 +rosglGetPixelFormat( HDC hdc )
 +{
 +    GLDCDATA *dcdata;
 +
 +    DBGTRACE( "Called!" );
 +
 +    dcdata = ROSGL_GetPrivateDCData( hdc );
 +    if (dcdata == NULL)
 +    {
 +        DBGPRINT( "Error: ROSGL_GetPrivateDCData failed!" );
 +        return 0;
 +    }
 +
 +    return dcdata->pixel_format;
 +}
 +
 +
 +/*! \brief Get the address for an OpenGL extension function.
 + *
 + * The addresses this function returns are only valid within the same thread
 + * which it was called from.
 + *
 + * \param proc [IN] Name of the function to look for
 + *
 + * \return The address of the proc
 + * \retval NULL Failure
 + */
 +PROC
 +APIENTRY
 +rosglGetProcAddress( LPCSTR proc )
 +{
 +    PROC func;
 +    GLDRIVERDATA *icd;
 +
 +    /* FIXME we should Flush the gl here */
 +
 +    if (OPENGL32_threaddata->glrc == NULL)
 +    {
 +        DBGPRINT( "Error: No current GLRC!" );
 +        SetLastError( ERROR_INVALID_FUNCTION );
 +        return NULL;
 +    }
 +
 +    icd = OPENGL32_threaddata->glrc->icd;
 +    func = icd->DrvGetProcAddress( proc );
 +    if (func != NULL)
 +    {
 +        DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc );
 +        return func;
 +    }
 +
 +    /* FIXME: Should we return wgl/gl 1.1 functions? */
 +    SetLastError( ERROR_PROC_NOT_FOUND );
 +    return NULL;
 +}
 +
 +PROC
 +APIENTRY
 +rosglGetDefaultProcAddress( LPCSTR proc )
 +{
 +    PROC func;
 +    GLDRIVERDATA *icd;
 +
 +    /*  wglGetDefaultProcAddress does not flush the gl */
 +
 +    if (OPENGL32_threaddata->glrc == NULL)
 +    {
 +        DBGPRINT( "Error: No current GLRC!" );
 +        SetLastError( ERROR_INVALID_FUNCTION );
 +        return NULL;
 +    }
 +
 +    icd = OPENGL32_threaddata->glrc->icd;
 +    func = icd->DrvGetProcAddress( proc );
 +    if (func != NULL)
 +    {
 +        DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc );
 +        return func;
 +    }
 +
 +    /* FIXME: Should we return wgl/gl 1.1 functions? */
 +    SetLastError( ERROR_PROC_NOT_FOUND );
 +    return NULL;
 +}
 +
 +
 +/*! \brief Make the given GLRC the threads current GLRC for hdc
 + *
 + * \param hdc   [IN] Handle for a DC to be drawn on
 + * \param hglrc [IN] Handle for a GLRC to make current
 + *
 + * \retval TRUE  Success
 + * \retval FALSE Failure
 + */
 +BOOL
 +APIENTRY
 +rosglMakeCurrent( HDC hdc, HGLRC hglrc )
 +{
 +    GLRC *glrc = (GLRC *)hglrc;
 +    ICDTable *icdTable = NULL;
 +
 +    DBGTRACE( "Called!" );
 +
 +    if (OPENGL32_threaddata == NULL)
 +        return FALSE;
 +
 +    /* flush current context */
 +    if (OPENGL32_threaddata->glrc != NULL)
 +    {
 +        glFlush();
 +    }
 +
 +    /* check if current context is unset */
 +    if (glrc == NULL)
 +    {
 +        if (OPENGL32_threaddata->glrc != NULL)
 +        {
 +            glrc = OPENGL32_threaddata->glrc;
 +            glrc->icd->DrvReleaseContext( glrc->hglrc );
 +            glrc->is_current = FALSE;
 +            OPENGL32_threaddata->glrc = NULL;
 +        }
++        else if ((GetObjectType(hdc) != OBJ_DC) && (GetObjectType(hdc) != OBJ_MEMDC))
++      {
++          DBGPRINT("Current context is NULL and requested HDC is invalid.\n");
++          SetLastError(ERROR_INVALID_HANDLE);
++          return FALSE;
++      }
 +    }
 +    else
 +    {
 +        /* check hdc */
 +        if (GetObjectType( hdc ) != OBJ_DC && GetObjectType( hdc ) != OBJ_MEMDC)
 +        {
 +            DBGPRINT( "Error: hdc is not a DC handle!" );
 +            SetLastError( ERROR_INVALID_HANDLE );
 +            return FALSE;
 +        }
 +
 +        /* check if we know about this glrc */
 +        if (!ROSGL_ContainsContext( glrc ))
 +        {
 +            DBGPRINT( "Error: hglrc not found!" );
 +            SetLastError( ERROR_INVALID_HANDLE );
 +            return FALSE;
 +        }
 +
 +        /* check if it is available */
 +        if (glrc->is_current && glrc->thread_id != GetCurrentThreadId()) /* used by another thread */
 +        {
 +            DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id );
 +            SetLastError( ERROR_INVALID_HANDLE );
 +            return FALSE;
 +        }
 +
 +        /* call the ICD */
 +        if (glrc->hglrc != NULL)
 +        {
 +            DBGPRINT( "Info: Calling DrvSetContext!" );
 +            SetLastError( ERROR_SUCCESS );
 +            icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc,
 +                                                 (void *)ROSGL_SetContextCallBack );
 +            if (icdTable == NULL)
 +            {
 +                DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
 +                return FALSE;
 +            }
 +            DBGPRINT( "Info: DrvSetContext succeeded!" );
 +        }
 +
 +        /* make it current */
 +        if (OPENGL32_threaddata->glrc != NULL)
 +            OPENGL32_threaddata->glrc->is_current = FALSE;
 +        glrc->is_current = TRUE;
 +        glrc->thread_id = GetCurrentThreadId();
 +        glrc->hdc = hdc;
 +        OPENGL32_threaddata->glrc = glrc;
 +    }
 +
 +    if (ROSGL_SetContextCallBack( icdTable ) != ERROR_SUCCESS && icdTable == NULL)
 +    {
 +        DBGPRINT( "Warning: ROSGL_SetContextCallBack failed!" );
 +    }
 +
 +    return TRUE;
 +}
 +
 +
 +BOOL
 +APIENTRY
 +rosglRealizeLayerPalette( HDC hdc, int iLayerPlane, BOOL bRealize )
 +{
 +    UNIMPLEMENTED;
 +    SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
 +    return FALSE;
 +}
 +
 +
 +int
 +APIENTRY
 +rosglSetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
 +                             int cEntries, CONST COLORREF *pcr )
 +{
 +    UNIMPLEMENTED;
 +    SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
 +    return 0;
 +}
 +
 +
 +/*! \brief Set a DCs pixelformat
 + *
 + * \param hdc     [IN] Handle to DC for which to set the format
 + * \param iFormat [IN] Index of the pixelformat to set
 + * \param pfd     [IN] Not sure what this is for
 + *
 + * \retval TRUE  Success
 + * \retval FALSE Failure
 + */
 +BOOL
 +WINAPI
 +rosglSetPixelFormat( HDC hdc, int iFormat, CONST PIXELFORMATDESCRIPTOR *pfd )
 +{
 +    GLDRIVERDATA *icd;
 +    GLDCDATA *dcdata;
 +
 +    DBGTRACE( "Called!" );
 +
 +    /* load ICD */
 +    icd = ROSGL_ICDForHDC( hdc );
 +    if (icd == NULL)
 +    {
 +        DBGPRINT( "Warning: ICDForHDC() failed" );
 +        return FALSE;
 +    }
 +
 +    /* call ICD */
 +    if (!icd->DrvSetPixelFormat( hdc, iFormat, pfd ))
 +    {
 +        DBGPRINT( "Warning: DrvSetPixelFormat(format=%d) failed (%d)",
 +                  iFormat, GetLastError() );
 +        return FALSE;
 +    }
 +
 +    /* store format in private DC data */
 +    dcdata = ROSGL_GetPrivateDCData( hdc );
 +    if (dcdata == NULL)
 +    {
 +        DBGPRINT( "Error: ROSGL_GetPrivateDCData() failed!" );
 +        return FALSE;
 +    }
 +    dcdata->pixel_format = iFormat;
 +
 +    return TRUE;
 +}
 +
 +
 +/*! \brief Enable display-list sharing between multiple GLRCs
 + *
 + * This will only work if both GLRCs are from the same driver.
 + *
 + * \param hglrc1 [IN] GLRC number 1
 + * \param hglrc2 [IN] GLRC number 2
 + *
 + * \retval TRUE  Success
 + * \retval FALSE Failure
 + */
 +BOOL
 +APIENTRY
 +rosglShareLists( HGLRC hglrc1, HGLRC hglrc2 )
 +{
 +    GLRC *glrc1 = (GLRC *)hglrc1;
 +    GLRC *glrc2 = (GLRC *)hglrc2;
 +
 +    /* check glrcs */
 +    if (!ROSGL_ContainsContext( glrc1 ))
 +    {
 +        DBGPRINT( "Error: hglrc1 not found!" );
 +        SetLastError( ERROR_INVALID_HANDLE );
 +        return FALSE;
 +    }
 +    if (!ROSGL_ContainsContext( glrc2 ))
 +    {
 +        DBGPRINT( "Error: hglrc2 not found!" );
 +        SetLastError( ERROR_INVALID_HANDLE );
 +        return FALSE;
 +    }
 +
 +    /* I think this is only possible within one ICD */
 +    if (glrc1->icd != glrc2->icd)
 +    {
 +        DBGPRINT( "Error: hglrc1 and hglrc2 use different ICDs!" );
 +        SetLastError( ERROR_INVALID_HANDLE );
 +        return FALSE;
 +    }
 +
 +    /* share lists (call ICD) */
 +    return glrc1->icd->DrvShareLists( glrc1->hglrc, glrc2->hglrc );
 +}
 +
 +
 +/*! \brief Flushes GL and swaps front/back buffer if appropriate
 + *
 + * \param hdc [IN] Handle to device context to swap buffers for
 + *
 + * \retval TRUE  Success
 + * \retval FALSE Failure
 + */
 +BOOL
 +APIENTRY
 +rosglSwapBuffers( HDC hdc )
 +{
 +    GLDRIVERDATA *icd = ROSGL_ICDForHDC( hdc );
 +    DBGTRACE( "Called!" );
 +    if (icd != NULL)
 +    {
 +        DBGPRINT( "Swapping buffers!" );
 +        if (!icd->DrvSwapBuffers( hdc ))
 +        {
 +            DBGPRINT( "Error: DrvSwapBuffers failed (%d)", GetLastError() );
 +            return FALSE;
 +        }
 +        return TRUE;
 +    }
 +
 +    /* FIXME: implement own functionality? */
 +    SetLastError( ERROR_INVALID_FUNCTION );
 +    return FALSE;
 +}
 +
 +
 +BOOL
 +APIENTRY
 +rosglSwapLayerBuffers( HDC hdc, UINT fuPlanes )
 +{
 +    BOOL ret = FALSE;
 +
 +    if(fuPlanes & WGL_SWAP_MAIN_PLANE)
 +        ret = rosglSwapBuffers(hdc);
 +
 +    if(fuPlanes &~WGL_SWAP_MAIN_PLANE)
 +        DBGTRACE("wglSwapLayerBuffers is not fully implemented\n");
 +
 +    return ret;
 +}
 +
 +
 +BOOL
 +APIENTRY
 +rosglUseFontBitmapsA( HDC hdc, DWORD first, DWORD count, DWORD listBase )
 +{
 +    return IntUseFontBitmapsA(hdc, first, count, listBase);
 +}
 +
 +
 +BOOL
 +APIENTRY
 +rosglUseFontBitmapsW( HDC hdc, DWORD first, DWORD count, DWORD listBase )
 +{
 +    return IntUseFontBitmapsW(hdc, first, count, listBase);
 +}
 +
 +BOOL
 +APIENTRY
 +rosglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase,
 +                       FLOAT deviation, FLOAT extrusion, int format,
 +                       GLYPHMETRICSFLOAT *pgmf )
 +{
 +    return IntUseFontOutlinesA(hdc, first, count, listBase, deviation, extrusion, format, pgmf);
 +}
 +
 +
 +BOOL
 +APIENTRY
 +rosglUseFontOutlinesW( HDC hdc, DWORD first, DWORD count, DWORD listBase,
 +                       FLOAT deviation, FLOAT extrusion, int format,
 +                       GLYPHMETRICSFLOAT *pgmf )
 +{
 +    return IntUseFontOutlinesW(hdc, first, count, listBase, deviation, extrusion, format, pgmf);
 +}
 +
 +#ifdef __cplusplus
 +}; /* extern "C" */
 +#endif /* __cplusplus */
 +
 +/* EOF */
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc hal/hal.pspec
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 087ab20,90cc393..90cc393
Binary files differ
index 8423d32,198bf98..198bf98
Binary files differ
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index ad8f576,0000000..a823b44
mode 100644,000000..100644
--- /dev/null
@@@ -1,477 -1,0 +1,478 @@@
-     /* Loop through the driver names */
 +/*
 + * COPYRIGHT:         See COPYING in the top level directory
 + * PROJECT:           ReactOS kernel
 + * PURPOSE:           GDI Driver Device Functions
 + * FILE:              subsys/win32k/eng/device.c
 + * PROGRAMER:         Jason Filby
 + *                    Timo Kreuzer
 + */
 +
 +#include <win32k.h>
 +
 +#define NDEBUG
 +#include <debug.h>
 +
 +static PGRAPHICS_DEVICE gpGraphicsDeviceFirst = NULL;
 +static PGRAPHICS_DEVICE gpGraphicsDeviceLast = NULL;
 +static HSEMAPHORE ghsemGraphicsDeviceList;
 +static ULONG giDevNum = 1;
 +
 +BOOL
 +NTAPI
 +InitDeviceImpl()
 +{
 +    ghsemGraphicsDeviceList = EngCreateSemaphore();
 +    if (!ghsemGraphicsDeviceList)
 +        return FALSE;
 +
 +    return TRUE;
 +}
 +
 +
 +PGRAPHICS_DEVICE
 +NTAPI
 +EngpRegisterGraphicsDevice(
 +    PUNICODE_STRING pustrDeviceName,
 +    PUNICODE_STRING pustrDiplayDrivers,
 +    PUNICODE_STRING pustrDescription,
 +    PDEVMODEW pdmDefault)
 +{
 +    PGRAPHICS_DEVICE pGraphicsDevice;
 +    PDEVICE_OBJECT pDeviceObject;
 +    PFILE_OBJECT pFileObject;
 +    NTSTATUS Status;
 +    PWSTR pwsz;
 +    ULONG i, cj, cModes = 0;
 +    BOOL bEnable = TRUE;
 +    PDEVMODEINFO pdminfo;
 +    PDEVMODEW pdm, pdmEnd;
 +    PLDEVOBJ pldev;
 +
 +    DPRINT1("EngpRegisterGraphicsDevice(%S)\n", pustrDeviceName->Buffer);
 +
 +    /* Allocate a GRAPHICS_DEVICE structure */
 +    pGraphicsDevice = ExAllocatePoolWithTag(PagedPool,
 +                                            sizeof(GRAPHICS_DEVICE),
 +                                            GDITAG_GDEVICE);
 +    if (!pGraphicsDevice)
 +    {
 +        DPRINT1("ExAllocatePoolWithTag failed\n");
 +        return NULL;
 +    }
 +
 +    /* Try to open the driver */
 +    Status = IoGetDeviceObjectPointer(pustrDeviceName,
 +                                      FILE_READ_DATA | FILE_WRITE_DATA,
 +                                      &pFileObject,
 +                                      &pDeviceObject);
 +    if (!NT_SUCCESS(Status))
 +    {
 +        DPRINT1("Could not open driver, 0x%lx\n", Status);
 +        ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE);
 +        return NULL;
 +    }
 +
 +    /* Enable the device */
 +    EngFileWrite(pFileObject, &bEnable, sizeof(BOOL), &cj);
 +
 +    /* Copy the device and file object pointers */
 +    pGraphicsDevice->DeviceObject = pDeviceObject;
 +    pGraphicsDevice->FileObject = pFileObject;
 +
 +    /* Copy device name */
 +    wcsncpy(pGraphicsDevice->szNtDeviceName,
 +            pustrDeviceName->Buffer,
 +            sizeof(pGraphicsDevice->szNtDeviceName) / sizeof(WCHAR));
 +
 +    /* Create a win device name (FIXME: virtual devices!) */
 +    swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\VIDEO%d", (CHAR)giDevNum);
 +
 +    /* Allocate a buffer for the strings */
 +    cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR);
 +    pwsz = ExAllocatePoolWithTag(PagedPool, cj, GDITAG_DRVSUP);
 +    if (!pwsz)
 +    {
 +        DPRINT1("Could not allocate string buffer\n");
 +        ASSERT(FALSE); // FIXME
 +    }
 +
 +    /* Copy display driver names */
 +    pGraphicsDevice->pDiplayDrivers = pwsz;
 +    RtlCopyMemory(pGraphicsDevice->pDiplayDrivers,
 +                  pustrDiplayDrivers->Buffer,
 +                  pustrDiplayDrivers->Length);
 +
 +    /* Copy description */
 +    pGraphicsDevice->pwszDescription = pwsz + pustrDiplayDrivers->Length / sizeof(WCHAR);
 +    RtlCopyMemory(pGraphicsDevice->pwszDescription,
 +                  pustrDescription->Buffer,
 +                  pustrDescription->Length + sizeof(WCHAR));
 +
 +    /* Initialize the pdevmodeInfo list and default index  */
 +    pGraphicsDevice->pdevmodeInfo = NULL;
 +    pGraphicsDevice->iDefaultMode = 0;
 +    pGraphicsDevice->iCurrentMode = 0;
 +
 +    // FIXME: initialize state flags
 +    pGraphicsDevice->StateFlags = 0;
 +
-     for (pdminfo = pGraphicsDevice->pdevmodeInfo, i = 0; 
++    /* Loop through the driver names
++     * This is a REG_MULTI_SZ string */
 +    for (; *pwsz; pwsz += wcslen(pwsz) + 1)
 +    {
 +        DPRINT1("trying driver: %ls\n", pwsz);
 +        /* Try to load the display driver */
 +        pldev = EngLoadDriver(pwsz, LDEV_DEVICE_DISPLAY);
 +        if (!pldev)
 +        {
 +            DPRINT1("Could not load driver: '%ls'\n", pwsz);
 +            continue;
 +        }
 +
 +        /* Get the mode list from the driver */
 +        pdminfo = LDEVOBJ_pdmiGetModes(pldev, pDeviceObject);
 +        if (!pdminfo)
 +        {
 +            DPRINT1("Could not get mode list for '%ls'\n", pwsz);
 +            continue;
 +        }
 +
 +        /* Attach the mode info to the device */
 +        pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo;
 +        pGraphicsDevice->pdevmodeInfo = pdminfo;
 +
 +        /* Count DEVMODEs */
 +        pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
 +        for (pdm = pdminfo->adevmode;
 +             pdm + 1 <= pdmEnd;
 +             pdm = (DEVMODEW*)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
 +        {
 +            cModes++;
 +        }
 +
 +        // FIXME: release the driver again until it's used?
 +    }
 +
 +    if (!pGraphicsDevice->pdevmodeInfo || cModes == 0)
 +    {
 +        DPRINT1("No devmodes\n");
 +        ExFreePool(pGraphicsDevice);
 +        return NULL;
 +    }
 +
 +    /* Allocate an index buffer */
 +    pGraphicsDevice->cDevModes = cModes;
 +    pGraphicsDevice->pDevModeList = ExAllocatePoolWithTag(PagedPool,
 +                                                          cModes * sizeof(DEVMODEENTRY),
 +                                                          GDITAG_GDEVICE);
 +    if (!pGraphicsDevice->pDevModeList)
 +    {
 +        DPRINT1("No devmode list\n");
 +        ExFreePool(pGraphicsDevice);
 +        return NULL;
 +    }
 +
 +    /* Loop through all DEVMODEINFOs */
++    for (pdminfo = pGraphicsDevice->pdevmodeInfo, i = 0;
 +         pdminfo;
 +         pdminfo = pdminfo->pdmiNext)
 +    {
 +        /* Calculate End of the DEVMODEs */
 +        pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
 +
 +        /* Loop through the DEVMODEs */
 +        for (pdm = pdminfo->adevmode;
 +             pdm + 1 <= pdmEnd;
 +             pdm = (PDEVMODEW)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
 +        {
 +            /* Compare with the default entry */
 +            if (pdm->dmBitsPerPel == pdmDefault->dmBitsPerPel &&
 +                pdm->dmPelsWidth == pdmDefault->dmPelsWidth &&
 +                pdm->dmPelsHeight == pdmDefault->dmPelsHeight &&
 +                pdm->dmDisplayFrequency == pdmDefault->dmDisplayFrequency)
 +            {
 +                pGraphicsDevice->iDefaultMode = i;
 +                pGraphicsDevice->iCurrentMode = i;
 +                DPRINT1("Found default entry: %ld '%ls'\n", i, pdm->dmDeviceName);
 +            }
 +
 +            /* Initialize the entry */
 +            pGraphicsDevice->pDevModeList[i].dwFlags = 0;
 +            pGraphicsDevice->pDevModeList[i].pdm = pdm;
 +            i++;
 +        }
 +     }
 +
 +    /* Lock loader */
 +    EngAcquireSemaphore(ghsemGraphicsDeviceList);
 +
 +    /* Insert the device into the global list */
 +    pGraphicsDevice->pNextGraphicsDevice = gpGraphicsDeviceLast;
 +    gpGraphicsDeviceLast = pGraphicsDevice;
 +    if (!gpGraphicsDeviceFirst)
 +        gpGraphicsDeviceFirst = pGraphicsDevice;
 +
 +    /* Increment device number */
 +    giDevNum++;
 +
 +    /* Unlock loader */
 +    EngReleaseSemaphore(ghsemGraphicsDeviceList);
 +    DPRINT1("Prepared %ld modes for %ls\n", cModes, pGraphicsDevice->pwszDescription);
 +
 +    return pGraphicsDevice;
 +}
 +
 +
 +PGRAPHICS_DEVICE
 +NTAPI
 +EngpFindGraphicsDevice(
 +    PUNICODE_STRING pustrDevice,
 +    ULONG iDevNum,
 +    DWORD dwFlags)
 +{
 +    UNICODE_STRING ustrCurrent;
 +    PGRAPHICS_DEVICE pGraphicsDevice;
 +    ULONG i;
 +
 +    /* Lock list */
 +    EngAcquireSemaphore(ghsemGraphicsDeviceList);
 +
 +    if (pustrDevice)
 +    {
 +        /* Loop through the list of devices */
 +        for (pGraphicsDevice = gpGraphicsDeviceFirst, i = 0;
 +             pGraphicsDevice;
 +             pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice, i++)
 +        {
 +            /* Compare the device name */
 +            RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName);
 +            if (RtlEqualUnicodeString(&ustrCurrent, pustrDevice, FALSE))
 +            {
 +                break;
 +            }
 +        }
 +    }
 +    else
 +    {
 +        /* Loop through the list of devices */
 +        for (pGraphicsDevice = gpGraphicsDeviceFirst, i = 0;
 +             pGraphicsDevice && i < iDevNum;
 +             pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice, i++);
 +    }
 +
 +    /* Unlock list */
 +    EngReleaseSemaphore(ghsemGraphicsDeviceList);
 +
 +    return pGraphicsDevice;
 +}
 +
 +
 +static
 +NTSTATUS
 +EngpFileIoRequest(
 +    PFILE_OBJECT pFileObject,
 +    ULONG   ulMajorFunction,
 +    LPVOID  lpBuffer,
 +    DWORD   nBufferSize,
 +    ULONGLONG  ullStartOffset,
 +    OUT LPDWORD lpInformation)
 +{
 +    PDEVICE_OBJECT pDeviceObject;
 +    KEVENT Event;
 +    PIRP pIrp;
 +    IO_STATUS_BLOCK Iosb;
 +    NTSTATUS Status;
 +    LARGE_INTEGER liStartOffset;
 +
 +    /* Get corresponding device object */
 +    pDeviceObject = IoGetRelatedDeviceObject(pFileObject);
 +    if (!pDeviceObject)
 +    {
 +        return STATUS_INVALID_PARAMETER;
 +    }
 +
 +    /* Initialize an event */
 +    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
 +
 +    /* Build IRP */
 +    liStartOffset.QuadPart = ullStartOffset;
 +    pIrp = IoBuildSynchronousFsdRequest(ulMajorFunction,
 +                                        pDeviceObject,
 +                                        lpBuffer,
 +                                        nBufferSize,
 +                                        &liStartOffset,
 +                                        &Event,
 +                                        &Iosb);
 +    if (!pIrp)
 +    {
 +        return STATUS_INSUFFICIENT_RESOURCES;
 +    }
 +
 +    /* Call the driver */
 +    Status = IoCallDriver(pDeviceObject, pIrp);
 +
 +    /* Wait if neccessary */
 +    if (STATUS_PENDING == Status)
 +    {
 +        KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
 +        Status = Iosb.Status;
 +    }
 +
 +    /* Return information to the caller about the operation. */
 +    *lpInformation = Iosb.Information;
 +
 +    /* Return NTSTATUS */
 +    return Status;
 +}
 +
 +VOID
 +APIENTRY
 +EngFileWrite(
 +    IN PFILE_OBJECT pFileObject,
 +    IN PVOID lpBuffer,
 +    IN SIZE_T nLength,
 +    IN PSIZE_T lpBytesWritten)
 +{
 +    EngpFileIoRequest(pFileObject,
 +                      IRP_MJ_WRITE,
 +                      lpBuffer,
 +                      nLength,
 +                      0,
 +                      lpBytesWritten);
 +}
 +
 +NTSTATUS
 +APIENTRY
 +EngFileIoControl(
 +    IN PFILE_OBJECT pFileObject,
 +    IN DWORD dwIoControlCode,
 +    IN PVOID lpInBuffer,
 +    IN SIZE_T nInBufferSize,
 +    OUT PVOID lpOutBuffer,
 +    IN SIZE_T nOutBufferSize,
 +    OUT LPDWORD lpInformation)
 +{
 +    PDEVICE_OBJECT pDeviceObject;
 +    KEVENT Event;
 +    PIRP pIrp;
 +    IO_STATUS_BLOCK Iosb;
 +    NTSTATUS Status;
 +
 +    /* Get corresponding device object */
 +    pDeviceObject = IoGetRelatedDeviceObject(pFileObject);
 +    if (!pDeviceObject)
 +    {
 +        return STATUS_INVALID_PARAMETER;
 +    }
 +
 +    /* Initialize an event */
 +    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
 +
 +    /* Build IO control IRP */
 +    pIrp = IoBuildDeviceIoControlRequest(dwIoControlCode,
 +                                         pDeviceObject,
 +                                         lpInBuffer,
 +                                         nInBufferSize,
 +                                         lpOutBuffer,
 +                                         nOutBufferSize,
 +                                         FALSE,
 +                                         &Event,
 +                                         &Iosb);
 +    if (!pIrp)
 +    {
 +        return STATUS_INSUFFICIENT_RESOURCES;
 +    }
 +
 +    /* Call the driver */
 +    Status = IoCallDriver(pDeviceObject, pIrp);
 +
 +    /* Wait if neccessary */
 +    if (Status == STATUS_PENDING)
 +    {
 +        KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
 +        Status = Iosb.Status;
 +    }
 +
 +    /* Return information to the caller about the operation. */
 +    *lpInformation = Iosb.Information;
 +
 +    /* This function returns NTSTATUS */
 +    return Status;
 +}
 +
 +/*
 + * @implemented
 + */
 +DWORD APIENTRY
 +EngDeviceIoControl(
 +    HANDLE  hDevice,
 +    DWORD   dwIoControlCode,
 +    LPVOID  lpInBuffer,
 +    DWORD   nInBufferSize,
 +    LPVOID  lpOutBuffer,
 +    DWORD   nOutBufferSize,
 +    DWORD *lpBytesReturned)
 +{
 +    PIRP Irp;
 +    NTSTATUS Status;
 +    KEVENT Event;
 +    IO_STATUS_BLOCK Iosb;
 +    PDEVICE_OBJECT DeviceObject;
 +
 +    DPRINT("EngDeviceIoControl() called\n");
 +
 +    KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
 +
 +    DeviceObject = (PDEVICE_OBJECT) hDevice;
 +
 +    Irp = IoBuildDeviceIoControlRequest(dwIoControlCode,
 +                                        DeviceObject,
 +                                        lpInBuffer,
 +                                        nInBufferSize,
 +                                        lpOutBuffer,
 +                                        nOutBufferSize, FALSE, &Event, &Iosb);
 +    if (!Irp) return ERROR_NOT_ENOUGH_MEMORY;
 +
 +    Status = IoCallDriver(DeviceObject, Irp);
 +
 +    if (Status == STATUS_PENDING)
 +    {
 +        (VOID)KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0);
 +        Status = Iosb.Status;
 +    }
 +
 +    DPRINT("EngDeviceIoControl(): Returning %X/%X\n", Iosb.Status,
 +           Iosb.Information);
 +
 +    /* Return information to the caller about the operation. */
 +    *lpBytesReturned = Iosb.Information;
 +
 +    /* Convert NT status values to win32 error codes. */
 +    switch (Status)
 +    {
 +        case STATUS_INSUFFICIENT_RESOURCES:
 +            return ERROR_NOT_ENOUGH_MEMORY;
 +
 +        case STATUS_BUFFER_OVERFLOW:
 +            return ERROR_MORE_DATA;
 +
 +        case STATUS_NOT_IMPLEMENTED:
 +            return ERROR_INVALID_FUNCTION;
 +
 +        case STATUS_INVALID_PARAMETER:
 +            return ERROR_INVALID_PARAMETER;
 +
 +        case STATUS_BUFFER_TOO_SMALL:
 +            return ERROR_INSUFFICIENT_BUFFER;
 +
 +        case STATUS_DEVICE_DOES_NOT_EXIST:
 +            return ERROR_DEV_NOT_EXIST;
 +
 +        case STATUS_PENDING:
 +            return ERROR_IO_PENDING;
 +    }
 +
 +    return Status;
 +}
 +
 +/* EOF */
index c229e57,0000000..83a3f84
mode 100644,000000..100644
--- /dev/null
@@@ -1,559 -1,0 +1,561 @@@
 +/*
 + *  ReactOS W32 Subsystem
 + *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 ReactOS Team
 + *
 + *  This program is free software; you can redistribute it and/or modify
 + *  it under the terms of the GNU General Public License as published by
 + *  the Free Software Foundation; either version 2 of the License, or
 + *  (at your option) any later version.
 + *
 + *  This program is distributed in the hope that it will be useful,
 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + *  GNU General Public License for more details.
 + *
 + *  You should have received a copy of the GNU General Public License along
 + *  with this program; if not, write to the Free Software Foundation, Inc.,
 + *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 + */
 +/*
 + *  Entry Point for win32k.sys
 + */
 +
 +#include <win32k.h>
 +#include <include/napi.h>
 +
 +#define NDEBUG
 +#include <debug.h>
 +
 +HANDLE hModuleWin;
 +
 +PGDI_HANDLE_TABLE INTERNAL_CALL GDIOBJ_iAllocHandleTable(OUT PSECTION_OBJECT *SectionObject);
 +BOOL INTERNAL_CALL GDI_CleanupForProcess (struct _EPROCESS *Process);
 +/* FIXME */
 +PGDI_HANDLE_TABLE GdiHandleTable = NULL;
 +PSECTION_OBJECT GdiTableSection = NULL;
 +
 +HANDLE GlobalUserHeap = NULL;
 +PSECTION_OBJECT GlobalUserHeapSection = NULL;
 +
 +PSERVERINFO gpsi = NULL; // Global User Server Information.
 +
 +HSEMAPHORE hsemDriverMgmt = NULL;
 +
 +SHORT gusLanguageID;
 +
 +extern ULONG_PTR Win32kSSDT[];
 +extern UCHAR Win32kSSPT[];
 +extern ULONG Win32kNumberOfSysCalls;
 +
 +NTSTATUS
 +APIENTRY
 +Win32kProcessCallback(struct _EPROCESS *Process,
 +                      BOOLEAN Create)
 +{
 +    PPROCESSINFO Win32Process;
 +    DECLARE_RETURN(NTSTATUS);
 +
 +    DPRINT("Enter Win32kProcessCallback\n");
 +    UserEnterExclusive();
 +
 +    /* Get the Win32 Process */
 +    Win32Process = PsGetProcessWin32Process(Process);
 +
 +    /* Allocate one if needed */
 +    if (!Win32Process)
 +    {
 +        /* FIXME - lock the process */
 +        Win32Process = ExAllocatePoolWithTag(NonPagedPool,
 +                                             sizeof(PROCESSINFO),
 +                                             'p23W');
 +
 +        if (Win32Process == NULL) RETURN( STATUS_NO_MEMORY);
 +
 +        RtlZeroMemory(Win32Process, sizeof(PROCESSINFO));
 +
 +        PsSetProcessWin32Process(Process, Win32Process);
 +        /* FIXME - unlock the process */
 +    }
 +
 +  if (Create)
 +    {
 +      SIZE_T ViewSize = 0;
 +      LARGE_INTEGER Offset;
 +      PVOID UserBase = NULL;
 +      NTSTATUS Status;
 +      extern PSECTION_OBJECT GlobalUserHeapSection;
 +      DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
 +
 +      /* map the global heap into the process */
 +      Offset.QuadPart = 0;
 +      Status = MmMapViewOfSection(GlobalUserHeapSection,
 +                                  PsGetCurrentProcess(),
 +                                  &UserBase,
 +                                  0,
 +                                  0,
 +                                  &Offset,
 +                                  &ViewSize,
 +                                  ViewUnmap,
 +                                  SEC_NO_CHANGE,
 +                                  PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but thanks to RTL heaps... */
 +      if (!NT_SUCCESS(Status))
 +      {
 +          DPRINT1("Failed to map the global heap! 0x%x\n", Status);
 +          RETURN(Status);
 +      }
 +      Win32Process->HeapMappings.Next = NULL;
 +      Win32Process->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap;
 +      Win32Process->HeapMappings.UserMapping = UserBase;
 +      Win32Process->HeapMappings.Count = 1;
 +
 +      InitializeListHead(&Win32Process->ClassList);
 +
 +      InitializeListHead(&Win32Process->MenuListHead);
 +
 +      InitializeListHead(&Win32Process->GDIBrushAttrFreeList);
 +      InitializeListHead(&Win32Process->GDIDcAttrFreeList);
 +
 +      InitializeListHead(&Win32Process->PrivateFontListHead);
 +      ExInitializeFastMutex(&Win32Process->PrivateFontListLock);
 +
 +      InitializeListHead(&Win32Process->DriverObjListHead);
 +      ExInitializeFastMutex(&Win32Process->DriverObjListLock);
 +
 +      Win32Process->KeyboardLayout = W32kGetDefaultKeyLayout();
 +
 +      if(Process->Peb != NULL)
 +      {
 +        /* map the gdi handle table to user land */
 +        Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(GdiTableSection, Process);
 +        Process->Peb->GdiDCAttributeList = GDI_BATCH_LIMIT;
 +      }
 +
 +      Win32Process->peProcess = Process;
 +      /* setup process flags */
 +      Win32Process->W32PF_flags = 0;
 +    }
 +  else
 +    {
 +      DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
 +      IntCleanupMenus(Process, Win32Process);
 +      IntCleanupCurIcons(Process, Win32Process);
 +      CleanupMonitorImpl();
 +
 +      /* no process windows should exist at this point, or the function will assert! */
 +      DestroyProcessClasses(Win32Process);
 +
 +      GDI_CleanupForProcess(Process);
 +
 +      co_IntGraphicsCheck(FALSE);
 +
 +      /*
 +       * Deregister logon application automatically
 +       */
 +      if(LogonProcess == Win32Process)
 +      {
 +        LogonProcess = NULL;
 +      }
 +    }
 +
 +  RETURN( STATUS_SUCCESS);
 +
 +CLEANUP:
 +  UserLeave();
 +  DPRINT("Leave Win32kProcessCallback, ret=%i\n",_ret_);
 +  END_CLEANUP;
 +}
 +
 +
 +NTSTATUS
 +APIENTRY
 +Win32kThreadCallback(struct _ETHREAD *Thread,
 +                     PSW32THREADCALLOUTTYPE Type)
 +{
 +    struct _EPROCESS *Process;
 +    PTHREADINFO Win32Thread;
 +    DECLARE_RETURN(NTSTATUS);
 +
 +    DPRINT("Enter Win32kThreadCallback\n");
 +    UserEnterExclusive();
 +
 +    Process = Thread->ThreadsProcess;
 +
 +    /* Get the Win32 Thread */
 +    Win32Thread = PsGetThreadWin32Thread(Thread);
 +
 +    /* Allocate one if needed */
 +    if (!Win32Thread)
 +    {
 +        /* FIXME - lock the process */
 +        Win32Thread = ExAllocatePoolWithTag(NonPagedPool,
 +                                            sizeof(THREADINFO),
 +                                            't23W');
 +
 +        if (Win32Thread == NULL) RETURN( STATUS_NO_MEMORY);
 +
 +        RtlZeroMemory(Win32Thread, sizeof(THREADINFO));
 +
 +        PsSetThreadWin32Thread(Thread, Win32Thread);
 +        /* FIXME - unlock the process */
 +    }
 +  if (Type == PsW32ThreadCalloutInitialize)
 +    {
 +      HWINSTA hWinSta = NULL;
 +      PTEB pTeb;
 +      HDESK hDesk = NULL;
 +      NTSTATUS Status;
 +      PUNICODE_STRING DesktopPath;
 +      PRTL_USER_PROCESS_PARAMETERS ProcessParams = (Process->Peb ? Process->Peb->ProcessParameters : NULL);
 +
 +      DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
 +
 +      InitializeListHead(&Win32Thread->WindowListHead);
 +      InitializeListHead(&Win32Thread->W32CallbackListHead);
 +      InitializeListHead(&Win32Thread->PtiLink);
 +
 +      /*
 +       * inherit the thread desktop and process window station (if not yet inherited) from the process startup
 +       * info structure. See documentation of CreateProcess()
 +       */
 +      DesktopPath = (ProcessParams ? ((ProcessParams->DesktopInfo.Length > 0) ? &ProcessParams->DesktopInfo : NULL) : NULL);
 +      Status = IntParseDesktopPath(Process,
 +                                   DesktopPath,
 +                                   &hWinSta,
 +                                   &hDesk);
 +      if(NT_SUCCESS(Status))
 +      {
 +        if(hWinSta != NULL)
 +        {
 +          if(Process != CsrProcess)
 +          {
 +            HWINSTA hProcessWinSta = (HWINSTA)InterlockedCompareExchangePointer((PVOID)&Process->Win32WindowStation, (PVOID)hWinSta, NULL);
 +            if(hProcessWinSta != NULL)
 +            {
 +              /* our process is already assigned to a different window station, we don't need the handle anymore */
 +              NtClose(hWinSta);
 +            }
 +          }
 +          else
 +          {
 +            NtClose(hWinSta);
 +          }
 +        }
 +
 +        if (hDesk != NULL)
 +        {
 +          PDESKTOP DesktopObject;
 +          Win32Thread->rpdesk = NULL;
 +          Status = ObReferenceObjectByHandle(hDesk,
 +                                             0,
 +                                             ExDesktopObjectType,
 +                                             KernelMode,
 +                                             (PVOID*)&DesktopObject,
 +                                             NULL);
 +          NtClose(hDesk);
 +          if(NT_SUCCESS(Status))
 +          {
 +            if (!IntSetThreadDesktop(DesktopObject,
 +                                     FALSE))
 +            {
 +              DPRINT1("Unable to set thread desktop\n");
 +            }
 +          }
 +          else
 +          {
 +            DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk);
 +          }
 +        }
 +      }
 +      Win32Thread->TIF_flags &= ~TIF_INCLEANUP;
 +      co_IntDestroyCaret(Win32Thread);
 +      Win32Thread->ppi = PsGetCurrentProcessWin32Process();
 +      pTeb = NtCurrentTeb();
 +      if (pTeb)
 +      {
 +          Win32Thread->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;
 +          Win32Thread->pClientInfo->pClientThreadInfo = NULL;
 +      }
 +      Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread);
 +      Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout();
 +      Win32Thread->pEThread = Thread;
 +    }
 +  else
 +    {
 +      PSINGLE_LIST_ENTRY e;
 +
 +      DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
 +
 +      Win32Thread->TIF_flags |= TIF_INCLEANUP;
 +      DceFreeThreadDCE(Win32Thread);
 +      HOOK_DestroyThreadHooks(Thread);
++      /* Cleanup timers */
++      DestroyTimersForThread(Win32Thread);
 +      UnregisterThreadHotKeys(Thread);
 +      /* what if this co_ func crash in umode? what will clean us up then? */
 +      co_DestroyThreadWindows(Thread);
 +      IntBlockInput(Win32Thread, FALSE);
 +      MsqDestroyMessageQueue(Win32Thread->MessageQueue);
 +      IntCleanupThreadCallbacks(Win32Thread);
 +
 +      /* cleanup user object references stack */
 +      e = PopEntryList(&Win32Thread->ReferencesList);
 +      while (e)
 +      {
 +         PUSER_REFERENCE_ENTRY ref = CONTAINING_RECORD(e, USER_REFERENCE_ENTRY, Entry);
 +         DPRINT("thread clean: remove reference obj 0x%x\n",ref->obj);
 +         UserDereferenceObject(ref->obj);
 +
 +         e = PopEntryList(&Win32Thread->ReferencesList);
 +      }
 +
 +      IntSetThreadDesktop(NULL,
 +                          TRUE);
 +
 +      PsSetThreadWin32Thread(Thread, NULL);
 +    }
 +
 +  RETURN( STATUS_SUCCESS);
 +
 +CLEANUP:
 +  UserLeave();
 +  DPRINT("Leave Win32kThreadCallback, ret=%i\n",_ret_);
 +  END_CLEANUP;
 +}
 +
 +/* Only used in ntuser/input.c KeyboardThreadMain(). If it's
 +   not called there anymore, please delete */
 +NTSTATUS
 +Win32kInitWin32Thread(PETHREAD Thread)
 +{
 +  PEPROCESS Process;
 +
 +  Process = Thread->ThreadsProcess;
 +
 +  if (Process->Win32Process == NULL)
 +    {
 +      /* FIXME - lock the process */
 +      Process->Win32Process = ExAllocatePool(NonPagedPool, sizeof(PROCESSINFO));
 +
 +      if (Process->Win32Process == NULL)
 +      return STATUS_NO_MEMORY;
 +
 +      RtlZeroMemory(Process->Win32Process, sizeof(PROCESSINFO));
 +      /* FIXME - unlock the process */
 +
 +      Win32kProcessCallback(Process, TRUE);
 +    }
 +
 +  if (Thread->Tcb.Win32Thread == NULL)
 +    {
 +      Thread->Tcb.Win32Thread = ExAllocatePool (NonPagedPool, sizeof(THREADINFO));
 +      if (Thread->Tcb.Win32Thread == NULL)
 +      return STATUS_NO_MEMORY;
 +
 +      RtlZeroMemory(Thread->Tcb.Win32Thread, sizeof(THREADINFO));
 +
 +      Win32kThreadCallback(Thread, PsW32ThreadCalloutInitialize);
 +    }
 +
 +  return(STATUS_SUCCESS);
 +}
 +
 +C_ASSERT(sizeof(SERVERINFO) <= PAGE_SIZE);
 +
 +/*
 + * This definition doesn't work
 + */
 +NTSTATUS APIENTRY
 +DriverEntry (
 +  IN  PDRIVER_OBJECT  DriverObject,
 +  IN  PUNICODE_STRING RegistryPath)
 +{
 +  NTSTATUS Status;
 +  BOOLEAN Result;
 +  WIN32_CALLOUTS_FPNS CalloutData = {0};
 +  PVOID GlobalUserHeapBase = NULL;
 +
 +  /*
 +   * Register user mode call interface
 +   * (system service table index = 1)
 +   */
 +  Result = KeAddSystemServiceTable (Win32kSSDT,
 +                                  NULL,
 +                                  Win32kNumberOfSysCalls,
 +                                  Win32kSSPT,
 +                                  1);
 +  if (Result == FALSE)
 +    {
 +      DPRINT1("Adding system services failed!\n");
 +      return STATUS_UNSUCCESSFUL;
 +    }
 +
 +  hModuleWin = MmPageEntireDriver(DriverEntry);
 +  DPRINT("Win32k hInstance 0x%x!\n",hModuleWin);
 +    /*
 +     * Register Object Manager Callbacks
 +     */
 +    CalloutData.WindowStationParseProcedure = IntWinStaObjectParse;
 +    CalloutData.WindowStationDeleteProcedure = IntWinStaObjectDelete;
 +    CalloutData.DesktopDeleteProcedure = IntDesktopObjectDelete;
 +    CalloutData.ProcessCallout = Win32kProcessCallback;
 +    CalloutData.ThreadCallout = Win32kThreadCallback;
 +    CalloutData.BatchFlushRoutine = NtGdiFlushUserBatch;
 +
 +    /*
 +     * Register our per-process and per-thread structures.
 +     */
 +    PsEstablishWin32Callouts((PWIN32_CALLOUTS_FPNS)&CalloutData);
 +
 +    GlobalUserHeap = UserCreateHeap(&GlobalUserHeapSection,
 +                                    &GlobalUserHeapBase,
 +                                    1 * 1024 * 1024); /* FIXME - 1 MB for now... */
 +    if (GlobalUserHeap == NULL)
 +    {
 +        DPRINT1("Failed to initialize the global heap!\n");
 +        return STATUS_UNSUCCESSFUL;
 +    }
 +
 +   if (!gpsi)
 +   {
 +      gpsi = UserHeapAlloc(sizeof(SERVERINFO));
 +      if (gpsi)
 +      {
 +         RtlZeroMemory(gpsi, sizeof(SERVERINFO));
 +         DPRINT("Global Server Data -> %x\n", gpsi);
 +      }
 +      else
 +      {
 +          ASSERT(FALSE);
 +      }
 +   }
 +
 +  if(!hsemDriverMgmt) hsemDriverMgmt = EngCreateSemaphore();
 +
 +  GdiHandleTable = GDIOBJ_iAllocHandleTable(&GdiTableSection);
 +  if (GdiHandleTable == NULL)
 +  {
 +      DPRINT1("Failed to initialize the GDI handle table.\n");
 +      return STATUS_UNSUCCESSFUL;
 +  }
 +
 +  /* Create stock objects, ie. precreated objects commonly
 +     used by win32 applications */
 +  CreateStockObjects();
 +  CreateSysColorObjects();
 +
 +  InitXlateImpl();
 +  InitPDEVImpl();
 +  InitLDEVImpl();
 +  InitDeviceImpl();
 +
 +  Status = InitDcImpl();
 +  if (!NT_SUCCESS(Status))
 +  {
 +    DPRINT1("Failed to initialize Device context implementation!\n");
 +    return STATUS_UNSUCCESSFUL;
 +  }
 +
 +  Status = InitUserImpl();
 +  if (!NT_SUCCESS(Status))
 +  {
 +    DPRINT1("Failed to initialize user implementation!\n");
 +    return STATUS_UNSUCCESSFUL;
 +  }
 +
 +  Status = InitHotkeyImpl();
 +  if (!NT_SUCCESS(Status))
 +  {
 +    DPRINT1("Failed to initialize hotkey implementation!\n");
 +    return STATUS_UNSUCCESSFUL;
 +  }
 +
 +  Status = InitWindowStationImpl();
 +  if (!NT_SUCCESS(Status))
 +  {
 +    DPRINT1("Failed to initialize window station implementation!\n");
 +    return STATUS_UNSUCCESSFUL;
 +  }
 +
 +  Status = InitDesktopImpl();
 +  if (!NT_SUCCESS(Status))
 +  {
 +    DPRINT1("Failed to initialize desktop implementation!\n");
 +    return STATUS_UNSUCCESSFUL;
 +  }
 +
 +  Status = InitWindowImpl();
 +  if (!NT_SUCCESS(Status))
 +  {
 +    DPRINT1("Failed to initialize window implementation!\n");
 +    return STATUS_UNSUCCESSFUL;
 +  }
 +
 +  Status = InitMenuImpl();
 +  if (!NT_SUCCESS(Status))
 +  {
 +    DPRINT1("Failed to initialize menu implementation!\n");
 +    return STATUS_UNSUCCESSFUL;
 +  }
 +
 +  Status = InitInputImpl();
 +  if (!NT_SUCCESS(Status))
 +    {
 +      DPRINT1("Failed to initialize input implementation.\n");
 +      return(Status);
 +    }
 +
 +  Status = InitKeyboardImpl();
 +  if (!NT_SUCCESS(Status))
 +    {
 +      DPRINT1("Failed to initialize keyboard implementation.\n");
 +      return(Status);
 +    }
 +
 +  Status = InitMonitorImpl();
 +  if (!NT_SUCCESS(Status))
 +    {
 +      DbgPrint("Failed to initialize monitor implementation!\n");
 +      return STATUS_UNSUCCESSFUL;
 +    }
 +
 +  Status = MsqInitializeImpl();
 +  if (!NT_SUCCESS(Status))
 +    {
 +      DPRINT1("Failed to initialize message queue implementation.\n");
 +      return(Status);
 +    }
 +
 +  Status = InitTimerImpl();
 +  if (!NT_SUCCESS(Status))
 +    {
 +      DPRINT1("Failed to initialize timer implementation.\n");
 +      return(Status);
 +    }
 +
 +  Status = InitAcceleratorImpl();
 +  if (!NT_SUCCESS(Status))
 +    {
 +      DPRINT1("Failed to initialize accelerator implementation.\n");
 +      return(Status);
 +    }
 +
 +  Status = InitGuiCheckImpl();
 +  if (!NT_SUCCESS(Status))
 +    {
 +      DPRINT1("Failed to initialize GUI check implementation.\n");
 +      return(Status);
 +    }
 +
 +  /* Initialize FreeType library */
 +  if (! InitFontSupport())
 +    {
 +      DPRINT1("Unable to initialize font support\n");
 +      return STATUS_UNSUCCESSFUL;
 +    }
 +
 +  gusLanguageID = IntGdiGetLanguageID();
 +
 +  return STATUS_SUCCESS;
 +}
 +
 +/* EOF */
index fdd2740,0000000..94d80e4
mode 100644,000000..100644
--- /dev/null
@@@ -1,2861 -1,0 +1,2846 @@@
-    if (ThreadQueue->WakeMask & QS_TIMER)
-       if (PostTimerMessages(Window)) // If there are timers ready,
-          goto CheckMessages;       // go back and process them.
-    // LOL! Polling Timer Queue? How much time is spent doing this?
-    /* Check for WM_(SYS)TIMER messages */
-    Present = MsqGetTimerMessage( ThreadQueue,
-                                  Window,
-                                  MsgFilterMin,
-                                  MsgFilterMax,
-                                 &Msg->Msg,
-                                  RemoveMessages);
-    if (Present)
-    {
-       Msg->FreeLParam = FALSE;
-       goto MessageFound;
-    }
 +/*
 + * COPYRIGHT:        See COPYING in the top level directory
 + * PROJECT:          ReactOS kernel
 + * PURPOSE:          Messages
 + * FILE:             subsys/win32k/ntuser/message.c
 + * PROGRAMER:        Casper S. Hornstrup (chorns@users.sourceforge.net)
 + * REVISION HISTORY:
 + *       06-06-2001  CSH  Created
 + */
 +
 +/* INCLUDES ******************************************************************/
 +
 +#include <win32k.h>
 +
 +#define NDEBUG
 +#include <debug.h>
 +
 +#define PM_BADMSGFLAGS ~((QS_RAWINPUT << 16)|PM_QS_SENDMESSAGE|PM_QS_PAINT|PM_QS_POSTMESSAGE|PM_QS_INPUT|PM_NOYIELD|PM_REMOVE)
 +
 +typedef struct
 +{
 +   UINT uFlags;
 +   UINT uTimeout;
 +   ULONG_PTR Result;
 +}
 +DOSENDMESSAGE, *PDOSENDMESSAGE;
 +
 +/* FUNCTIONS *****************************************************************/
 +
 +NTSTATUS FASTCALL
 +IntInitMessageImpl(VOID)
 +{
 +   return STATUS_SUCCESS;
 +}
 +
 +NTSTATUS FASTCALL
 +IntCleanupMessageImpl(VOID)
 +{
 +   return STATUS_SUCCESS;
 +}
 +
 +#define MMS_SIZE_WPARAM      -1
 +#define MMS_SIZE_WPARAMWCHAR -2
 +#define MMS_SIZE_LPARAMSZ    -3
 +#define MMS_SIZE_SPECIAL     -4
 +#define MMS_FLAG_READ        0x01
 +#define MMS_FLAG_WRITE       0x02
 +#define MMS_FLAG_READWRITE   (MMS_FLAG_READ | MMS_FLAG_WRITE)
 +typedef struct tagMSGMEMORY
 +{
 +   UINT Message;
 +   UINT Size;
 +   INT Flags;
 +}
 +MSGMEMORY, *PMSGMEMORY;
 +
 +static MSGMEMORY MsgMemory[] =
 +   {
 +      { WM_CREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
 +      { WM_DDE_ACK, sizeof(KMDDELPARAM), MMS_FLAG_READ },
 +      { WM_DDE_EXECUTE, MMS_SIZE_WPARAM, MMS_FLAG_READ },
 +      { WM_GETMINMAXINFO, sizeof(MINMAXINFO), MMS_FLAG_READWRITE },
 +      { WM_GETTEXT, MMS_SIZE_WPARAMWCHAR, MMS_FLAG_WRITE },
 +      { WM_NCCALCSIZE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
 +      { WM_NCCREATE, MMS_SIZE_SPECIAL, MMS_FLAG_READWRITE },
 +      { WM_SETTEXT, MMS_SIZE_LPARAMSZ, MMS_FLAG_READ },
 +      { WM_STYLECHANGED, sizeof(STYLESTRUCT), MMS_FLAG_READ },
 +      { WM_STYLECHANGING, sizeof(STYLESTRUCT), MMS_FLAG_READWRITE },
 +      { WM_COPYDATA, MMS_SIZE_SPECIAL, MMS_FLAG_READ },
 +      { WM_WINDOWPOSCHANGED, sizeof(WINDOWPOS), MMS_FLAG_READ },
 +      { WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
 +   };
 +
 +static PMSGMEMORY FASTCALL
 +FindMsgMemory(UINT Msg)
 +{
 +   PMSGMEMORY MsgMemoryEntry;
 +
 +   /* See if this message type is present in the table */
 +   for (MsgMemoryEntry = MsgMemory;
 +         MsgMemoryEntry < MsgMemory + sizeof(MsgMemory) / sizeof(MSGMEMORY);
 +         MsgMemoryEntry++)
 +   {
 +      if (Msg == MsgMemoryEntry->Message)
 +      {
 +         return MsgMemoryEntry;
 +      }
 +   }
 +
 +   return NULL;
 +}
 +
 +static UINT FASTCALL
 +MsgMemorySize(PMSGMEMORY MsgMemoryEntry, WPARAM wParam, LPARAM lParam)
 +{
 +   CREATESTRUCTW *Cs;
 +   PUNICODE_STRING WindowName;
 +   PUNICODE_STRING ClassName;
 +   UINT Size = 0;
 +
 +   _SEH2_TRY
 +   {
 +      if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size)
 +      {
 +         Size = (UINT)wParam;
 +      }
 +      else if (MMS_SIZE_WPARAMWCHAR == MsgMemoryEntry->Size)
 +      {
 +         Size = (UINT) (wParam * sizeof(WCHAR));
 +      }
 +      else if (MMS_SIZE_LPARAMSZ == MsgMemoryEntry->Size)
 +      {
 +         Size = (UINT) ((wcslen((PWSTR) lParam) + 1) * sizeof(WCHAR));
 +      }
 +      else if (MMS_SIZE_SPECIAL == MsgMemoryEntry->Size)
 +      {
 +         switch(MsgMemoryEntry->Message)
 +         {
 +            case WM_CREATE:
 +            case WM_NCCREATE:
 +               Cs = (CREATESTRUCTW *) lParam;
 +               WindowName = (PUNICODE_STRING) Cs->lpszName;
 +               ClassName = (PUNICODE_STRING) Cs->lpszClass;
 +               Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR);
 +               if (IS_ATOM(ClassName->Buffer))
 +               {
 +                  Size += sizeof(WCHAR) + sizeof(ATOM);
 +               }
 +               else
 +               {
 +                  Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
 +               }
 +               break;
 +
 +            case WM_NCCALCSIZE:
 +               Size = wParam ? sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS) : sizeof(RECT);
 +               break;
 +
 +            case WM_COPYDATA:
 +               Size = sizeof(COPYDATASTRUCT) + ((PCOPYDATASTRUCT)lParam)->cbData;
 +               break;
 +
 +            case WM_COPYGLOBALDATA:
 +               Size = wParam;
 +               break;
 +
 +            default:
 +               assert(FALSE);
 +               Size = 0;
 +               break;
 +         }
 +      }
 +      else
 +      {
 +         Size = MsgMemoryEntry->Size;
 +      }
 +   }
 +   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
 +   {
 +      DPRINT1("Exception caught in MsgMemorySize()! Status: 0x%x\n", _SEH2_GetExceptionCode());
 +      Size = 0;
 +   }
 +   _SEH2_END;
 +   return Size;
 +}
 +
 +static NTSTATUS
 +PackParam(LPARAM *lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL NonPagedPoolNeeded)
 +{
 +   NCCALCSIZE_PARAMS *UnpackedNcCalcsize;
 +   NCCALCSIZE_PARAMS *PackedNcCalcsize;
 +   CREATESTRUCTW *UnpackedCs;
 +   CREATESTRUCTW *PackedCs;
 +   PUNICODE_STRING WindowName;
 +   PUNICODE_STRING ClassName;
 +   POOL_TYPE PoolType;
 +   UINT Size;
 +   PCHAR CsData;
 +
 +   *lParamPacked = lParam;
 +
 +    if (NonPagedPoolNeeded)
 +       PoolType = NonPagedPool;
 +    else
 +       PoolType = PagedPool;
 +
 +   if (WM_NCCALCSIZE == Msg && wParam)
 +   {
 +
 +      UnpackedNcCalcsize = (NCCALCSIZE_PARAMS *) lParam;
 +      PackedNcCalcsize = ExAllocatePoolWithTag(PoolType,
 +                         sizeof(NCCALCSIZE_PARAMS) + sizeof(WINDOWPOS),
 +                         TAG_MSG);
 +
 +      if (NULL == PackedNcCalcsize)
 +      {
 +         DPRINT1("Not enough memory to pack lParam\n");
 +         return STATUS_NO_MEMORY;
 +      }
 +      RtlCopyMemory(PackedNcCalcsize, UnpackedNcCalcsize, sizeof(NCCALCSIZE_PARAMS));
 +      PackedNcCalcsize->lppos = (PWINDOWPOS) (PackedNcCalcsize + 1);
 +      RtlCopyMemory(PackedNcCalcsize->lppos, UnpackedNcCalcsize->lppos, sizeof(WINDOWPOS));
 +      *lParamPacked = (LPARAM) PackedNcCalcsize;
 +   }
 +   else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
 +   {
 +      UnpackedCs = (CREATESTRUCTW *) lParam;
 +      WindowName = (PUNICODE_STRING) UnpackedCs->lpszName;
 +      ClassName = (PUNICODE_STRING) UnpackedCs->lpszClass;
 +      Size = sizeof(CREATESTRUCTW) + WindowName->Length + sizeof(WCHAR);
 +      if (IS_ATOM(ClassName->Buffer))
 +      {
 +         Size += sizeof(WCHAR) + sizeof(ATOM);
 +      }
 +      else
 +      {
 +         Size += sizeof(WCHAR) + ClassName->Length + sizeof(WCHAR);
 +      }
 +      PackedCs = ExAllocatePoolWithTag(PoolType, Size, TAG_MSG);
 +      if (NULL == PackedCs)
 +      {
 +         DPRINT1("Not enough memory to pack lParam\n");
 +         return STATUS_NO_MEMORY;
 +      }
 +      RtlCopyMemory(PackedCs, UnpackedCs, sizeof(CREATESTRUCTW));
 +      CsData = (PCHAR) (PackedCs + 1);
 +      PackedCs->lpszName = (LPCWSTR) (CsData - (PCHAR) PackedCs);
 +      RtlCopyMemory(CsData, WindowName->Buffer, WindowName->Length);
 +      CsData += WindowName->Length;
 +      *((WCHAR *) CsData) = L'\0';
 +      CsData += sizeof(WCHAR);
 +      PackedCs->lpszClass = (LPCWSTR) (CsData - (PCHAR) PackedCs);
 +      if (IS_ATOM(ClassName->Buffer))
 +      {
 +         *((WCHAR *) CsData) = L'A';
 +         CsData += sizeof(WCHAR);
 +         *((ATOM *) CsData) = (ATOM)(DWORD_PTR) ClassName->Buffer;
 +         CsData += sizeof(ATOM);
 +      }
 +      else
 +      {
 +         *((WCHAR *) CsData) = L'S';
 +         CsData += sizeof(WCHAR);
 +         RtlCopyMemory(CsData, ClassName->Buffer, ClassName->Length);
 +         CsData += ClassName->Length;
 +         *((WCHAR *) CsData) = L'\0';
 +         CsData += sizeof(WCHAR);
 +      }
 +      ASSERT(CsData == (PCHAR) PackedCs + Size);
 +      *lParamPacked = (LPARAM) PackedCs;
 +   }
 +
 +   else if (PoolType == NonPagedPool)
 +   {
 +      PMSGMEMORY MsgMemoryEntry;
 +      PVOID PackedData;
 +
 +      MsgMemoryEntry = FindMsgMemory(Msg);
 +
 +      if ((!MsgMemoryEntry) || (MsgMemoryEntry->Size < 0))
 +      {
 +         /* Keep previous behavior */
 +         return STATUS_SUCCESS;
 +      }
 +      PackedData = ExAllocatePoolWithTag(NonPagedPool, MsgMemorySize(MsgMemoryEntry, wParam, lParam), TAG_MSG);
 +      RtlCopyMemory(PackedData, (PVOID)lParam, MsgMemorySize(MsgMemoryEntry, wParam, lParam));
 +      *lParamPacked = (LPARAM)PackedData;
 +   }
 +
 +   return STATUS_SUCCESS;
 +}
 +
 +static NTSTATUS
 +UnpackParam(LPARAM lParamPacked, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL NonPagedPoolUsed)
 +{
 +   NCCALCSIZE_PARAMS *UnpackedParams;
 +   NCCALCSIZE_PARAMS *PackedParams;
 +   PWINDOWPOS UnpackedWindowPos;
 +
 +   if (lParamPacked == lParam)
 +   {
 +      return STATUS_SUCCESS;
 +   }
 +
 +   if (WM_NCCALCSIZE == Msg && wParam)
 +   {
 +      PackedParams = (NCCALCSIZE_PARAMS *) lParamPacked;
 +      UnpackedParams = (NCCALCSIZE_PARAMS *) lParam;
 +      UnpackedWindowPos = UnpackedParams->lppos;
 +      RtlCopyMemory(UnpackedParams, PackedParams, sizeof(NCCALCSIZE_PARAMS));
 +      UnpackedParams->lppos = UnpackedWindowPos;
 +      RtlCopyMemory(UnpackedWindowPos, PackedParams + 1, sizeof(WINDOWPOS));
 +      ExFreePool((PVOID) lParamPacked);
 +
 +      return STATUS_SUCCESS;
 +   }
 +   else if (WM_CREATE == Msg || WM_NCCREATE == Msg)
 +   {
 +      ExFreePool((PVOID) lParamPacked);
 +
 +      return STATUS_SUCCESS;
 +   }
 +   else if (NonPagedPoolUsed)
 +   {
 +      PMSGMEMORY MsgMemoryEntry;
 +      MsgMemoryEntry = FindMsgMemory(Msg);
 +      if (MsgMemoryEntry->Size < 0)
 +      {
 +         /* Keep previous behavior */
 +         return STATUS_INVALID_PARAMETER;
 +      }
 +
 +      if (MsgMemory->Flags == MMS_FLAG_READWRITE)
 +      {
 +         //RtlCopyMemory((PVOID)lParam, (PVOID)lParamPacked, MsgMemory->Size);
 +      }
 +      ExFreePool((PVOID) lParamPacked);
 +      return STATUS_SUCCESS;
 +   }
 +
 +   ASSERT(FALSE);
 +
 +   return STATUS_INVALID_PARAMETER;
 +}
 +
 +static
 +VOID
 +FASTCALL
 +IntCallWndProc
 +( PWINDOW_OBJECT Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
 +{
 +   BOOL SameThread = FALSE;
 +
 +   if (Window->pti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread()))
 +      SameThread = TRUE;
 +
 +   if ((!SameThread && (Window->pti->fsHooks & HOOKID_TO_FLAG(WH_CALLWNDPROC))) ||
 +        (SameThread && ISITHOOKED(WH_CALLWNDPROC)) )
 +   {
 +      CWPSTRUCT CWP;
 +      CWP.hwnd    = hWnd;
 +      CWP.message = Msg;
 +      CWP.wParam  = wParam;
 +      CWP.lParam  = lParam;
 +      co_HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, SameThread, (LPARAM)&CWP );
 +   }
 +}
 +
 +static
 +VOID
 +FASTCALL
 +IntCallWndProcRet
 +( PWINDOW_OBJECT Window, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *uResult)
 +{
 +   BOOL SameThread = FALSE;
 +
 +   if (Window->pti == ((PTHREADINFO)PsGetCurrentThreadWin32Thread()))
 +      SameThread = TRUE;
 +
 +   if ((!SameThread && (Window->pti->fsHooks & HOOKID_TO_FLAG(WH_CALLWNDPROCRET))) ||
 +        (SameThread && ISITHOOKED(WH_CALLWNDPROCRET)) )
 +   {
 +      CWPRETSTRUCT CWPR;
 +      CWPR.hwnd    = hWnd;
 +      CWPR.message = Msg;
 +      CWPR.wParam  = wParam;
 +      CWPR.lParam  = lParam;
 +      CWPR.lResult = *uResult;
 +      co_HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, SameThread, (LPARAM)&CWPR );
 +   }
 +}
 +
 +LRESULT
 +FASTCALL
 +IntDispatchMessage(PMSG pMsg)
 +{
 +  LARGE_INTEGER TickCount;
 +  LONG Time;
 +  LRESULT retval;
 +  PMSGMEMORY MsgMemoryEntry;
 +  INT lParamBufferSize;
 +  LPARAM lParamPacked;
 +  PWINDOW_OBJECT Window = NULL;
 +
 +  if (pMsg->hwnd)
 +  {
 +     Window = UserGetWindowObject(pMsg->hwnd);
 +     if (!Window || !Window->Wnd) return 0;
 +  }
 +
 +  if (((pMsg->message == WM_SYSTIMER) ||
 +       (pMsg->message == WM_TIMER)) &&
 +      (pMsg->lParam) )
 +  {
 +     if (pMsg->message == WM_TIMER)
 +     {
 +        if (ValidateTimerCallback(PsGetCurrentThreadWin32Thread(),Window,pMsg->wParam,pMsg->lParam))
 +        {
 +           KeQueryTickCount(&TickCount);
 +           Time = MsqCalculateMessageTime(&TickCount);
 +           return co_IntCallWindowProc((WNDPROC)pMsg->lParam,
 +                                        TRUE,
 +                                        pMsg->hwnd,
 +                                        WM_TIMER,
 +                                        pMsg->wParam,
 +                                        (LPARAM)Time,
 +                                        sizeof(LPARAM));
 +        }
 +        return 0;
 +     }
 +     else
 +     {
 +        PTIMER pTimer = FindSystemTimer(pMsg);
 +        if (pTimer && pTimer->pfn)
 +        {
 +           KeQueryTickCount(&TickCount);
 +           Time = MsqCalculateMessageTime(&TickCount);
 +           pTimer->pfn(pMsg->hwnd, WM_SYSTIMER, (UINT)pMsg->wParam, Time);
 +        }
 +        return 0;
 +     }
 +  }
 +  // Need a window!
 +  if ( !Window || !Window->Wnd ) return 0;
 +
 +  /* See if this message type is present in the table */
 +  MsgMemoryEntry = FindMsgMemory(pMsg->message);
 +  if ( !MsgMemoryEntry )
 +  {
 +     lParamBufferSize = -1;
 +  }
 +  else
 +  {
 +     lParamBufferSize = MsgMemorySize(MsgMemoryEntry, pMsg->wParam, pMsg->lParam);
 +  }
 +
 +  if (! NT_SUCCESS(PackParam(&lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam, FALSE)))
 +  {
 +     DPRINT1("Failed to pack message parameters\n");
 +     return 0;
 +  }
 +
 +  retval = co_IntCallWindowProc( Window->Wnd->lpfnWndProc,
 +                                !Window->Wnd->Unicode,
 +                                 pMsg->hwnd,
 +                                 pMsg->message,
 +                                 pMsg->wParam,
 +                                 lParamPacked,
 +                                 lParamBufferSize);
 +
 +  if (! NT_SUCCESS(UnpackParam(lParamPacked, pMsg->message, pMsg->wParam, pMsg->lParam, FALSE)))
 +  {
 +     DPRINT1("Failed to unpack message parameters\n");
 +  }
 +
 +  if (pMsg->message == WM_PAINT)
 +  {
 +  /* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
 +     HRGN hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 );
 +     co_UserGetUpdateRgn( Window, hrgn, TRUE );
 +     REGION_FreeRgnByHandle( hrgn );
 +  }
 +  return retval;
 +}
 +
 +VOID FASTCALL
 +co_IntSendHitTestMessages(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg)
 +{
 +   if(!Msg->hwnd || ThreadQueue->CaptureWindow)
 +   {
 +      return;
 +   }
 +
 +   switch(Msg->message)
 +   {
 +      case WM_MOUSEMOVE:
 +         {
 +            co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(HTCLIENT, Msg->message));
 +            break;
 +         }
 +      case WM_NCMOUSEMOVE:
 +         {
 +            co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(Msg->wParam, Msg->message));
 +            break;
 +         }
 +      case WM_LBUTTONDOWN:
 +      case WM_MBUTTONDOWN:
 +      case WM_RBUTTONDOWN:
 +      case WM_XBUTTONDOWN:
 +      case WM_LBUTTONDBLCLK:
 +      case WM_MBUTTONDBLCLK:
 +      case WM_RBUTTONDBLCLK:
 +      case WM_XBUTTONDBLCLK:
 +         {
 +            WPARAM wParam;
 +            PSYSTEM_CURSORINFO CurInfo;
 +                      CurInfo = IntGetSysCursorInfo();
 +
 +            wParam = (WPARAM)(CurInfo->ButtonsDown);
 +
 +            co_IntSendMessage(Msg->hwnd, WM_MOUSEMOVE, wParam, Msg->lParam);
 +            co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(HTCLIENT, Msg->message));
 +            break;
 +         }
 +      case WM_NCLBUTTONDOWN:
 +      case WM_NCMBUTTONDOWN:
 +      case WM_NCRBUTTONDOWN:
 +      case WM_NCXBUTTONDOWN:
 +      case WM_NCLBUTTONDBLCLK:
 +      case WM_NCMBUTTONDBLCLK:
 +      case WM_NCRBUTTONDBLCLK:
 +      case WM_NCXBUTTONDBLCLK:
 +         {
 +            co_IntSendMessage(Msg->hwnd, WM_NCMOUSEMOVE, (WPARAM)Msg->wParam, Msg->lParam);
 +            co_IntSendMessage(Msg->hwnd, WM_SETCURSOR, (WPARAM)Msg->hwnd, MAKELPARAM(Msg->wParam, Msg->message));
 +            break;
 +         }
 +   }
 +}
 +
 +BOOL FASTCALL
 +co_IntActivateWindowMouse(
 +   PUSER_MESSAGE_QUEUE ThreadQueue,
 +   LPMSG Msg,
 +   PWINDOW_OBJECT MsgWindow,
 +   USHORT *HitTest)
 +{
 +   ULONG Result;
 +   PWINDOW_OBJECT Parent;
 +
 +   ASSERT_REFS_CO(MsgWindow);
 +
 +   if(*HitTest == (USHORT)HTTRANSPARENT)
 +   {
 +      /* eat the message, search again! */
 +      return TRUE;
 +   }
 +
 +   Parent = IntGetParent(MsgWindow);//fixme: deref retval?
 +
 +   /* If no parent window, pass MsgWindows HWND as wParam. Fixes bug #3111 */
 +   Result = co_IntSendMessage(MsgWindow->hSelf,
 +                              WM_MOUSEACTIVATE,
 +                              (WPARAM) (Parent ? Parent->hSelf : MsgWindow->hSelf),
 +                              (LPARAM)MAKELONG(*HitTest, Msg->message)
 +                             );
 +
 +   switch (Result)
 +   {
 +      case MA_NOACTIVATEANDEAT:
 +         return TRUE;
 +      case MA_NOACTIVATE:
 +         break;
 +      case MA_ACTIVATEANDEAT:
 +         co_IntMouseActivateWindow(MsgWindow);
 +         return TRUE;
 +      default:
 +         /* MA_ACTIVATE */
 +         co_IntMouseActivateWindow(MsgWindow);
 +         break;
 +   }
 +
 +   return FALSE;
 +}
 +
 +BOOL FASTCALL
 +co_IntTranslateMouseMessage(
 +   PUSER_MESSAGE_QUEUE ThreadQueue,
 +   LPMSG Msg,
 +   USHORT *HitTest,
 +   BOOL Remove)
 +{
 +   PWINDOW_OBJECT Window;
 +   USER_REFERENCE_ENTRY Ref, DesktopRef;
 +
 +   if(!(Window = UserGetWindowObject(Msg->hwnd)))
 +   {
 +      /* let's just eat the message?! */
 +      return TRUE;
 +   }
 +
 +   UserRefObjectCo(Window, &Ref);
 +
 +   if ( ThreadQueue == Window->pti->MessageQueue &&
 +        ThreadQueue->CaptureWindow != Window->hSelf)
 +   {
 +      /* only send WM_NCHITTEST messages if we're not capturing the window! */
 +      *HitTest = co_IntSendMessage(Window->hSelf, WM_NCHITTEST, 0,
 +                                   MAKELONG(Msg->pt.x, Msg->pt.y));
 +
 +      if (*HitTest == (USHORT)HTTRANSPARENT)
 +      {
 +         PWINDOW_OBJECT DesktopWindow;
 +         HWND hDesktop = IntGetDesktopWindow();
 +
 +         if ((DesktopWindow = UserGetWindowObject(hDesktop)))
 +         {
 +            PWINDOW_OBJECT Wnd;
 +
 +            UserRefObjectCo(DesktopWindow, &DesktopRef);
 +
 +            co_WinPosWindowFromPoint(DesktopWindow, Window->pti->MessageQueue, &Msg->pt, &Wnd);
 +            if (Wnd)
 +            {
 +               if (Wnd != Window)
 +               {
 +                  /* post the message to the other window */
 +                  Msg->hwnd = Wnd->hSelf;
 +                  if(!(Wnd->state & WINDOWSTATUS_DESTROYING))
 +                  {
 +                     MsqPostMessage(Wnd->pti->MessageQueue, Msg, FALSE,
 +                                    Msg->message == WM_MOUSEMOVE ? QS_MOUSEMOVE :
 +                                    QS_MOUSEBUTTON);
 +                  }
 +
 +                  /* eat the message */
 +                  UserDereferenceObject(Wnd);
 +                  UserDerefObjectCo(DesktopWindow);
 +                  UserDerefObjectCo(Window);
 +                  return TRUE;
 +               }
 +               UserDereferenceObject(Wnd);
 +            }
 +
 +            UserDerefObjectCo(DesktopWindow);
 +         }
 +      }
 +   }
 +   else
 +   {
 +      *HitTest = HTCLIENT;
 +   }
 +
 +   if ( gspv.bMouseClickLock &&
 +        ( (Msg->message == WM_LBUTTONUP) ||
 +          (Msg->message == WM_LBUTTONDOWN) ) )
 +   {
 +      if (MsqIsClkLck(Msg, Remove))
 +      {
 +        // FIXME: drop the message, hack: use WM_NULL
 +        Msg->message = WM_NULL;
 +      }
 +   }
 +
 +   if (IS_BTN_MESSAGE(Msg->message, DOWN))
 +   {
 +      /* generate double click messages, if necessary */
 +      if ((((*HitTest) != HTCLIENT) ||
 +            (Window->Wnd->pcls->style & CS_DBLCLKS)) &&
 +            MsqIsDblClk(Msg, Remove))
 +      {
 +         Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
 +      }
 +   }
 +
 +   if(Msg->message != WM_MOUSEWHEEL)
 +   {
 +
 +      if ((*HitTest) != HTCLIENT)
 +      {
 +         Msg->message += WM_NCMOUSEMOVE - WM_MOUSEMOVE;
 +         if ( (Msg->message == WM_NCRBUTTONUP) &&
 +              (((*HitTest) == HTCAPTION) || ((*HitTest) == HTSYSMENU)) )
 +         {
 +            Msg->message = WM_CONTEXTMENU;
 +            Msg->wParam = (WPARAM)Window->hSelf;
 +         }
 +         else
 +         {
 +            Msg->wParam = *HitTest;
 +         }
 +         Msg->lParam = MAKELONG(Msg->pt.x, Msg->pt.y);
 +      }
 +      else if ( ThreadQueue->MoveSize == NULL &&
 +                ThreadQueue->MenuOwner == NULL )
 +      {
 +         /* NOTE: Msg->pt should remain in screen coordinates. -- FiN */
 +         Msg->lParam = MAKELONG(
 +                          Msg->pt.x - (WORD)Window->Wnd->rcClient.left,
 +                          Msg->pt.y - (WORD)Window->Wnd->rcClient.top);
 +      }
 +   }
 +
 +   UserDerefObjectCo(Window);
 +   return FALSE;
 +}
 +
 +BOOL ProcessMouseMessage(MSG* Msg, USHORT HitTest, UINT RemoveMsg)
 +{
 +    MOUSEHOOKSTRUCT MHook;
 +    EVENTMSG Event;
 +
 +    Event.message = Msg->message;
 +    Event.time    = Msg->time;
 +    Event.hwnd    = Msg->hwnd;
 +    Event.paramL  = Msg->pt.x;
 +    Event.paramH  = Msg->pt.y;
 +    co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
 +
 +
 +    MHook.pt           = Msg->pt;
 +    MHook.hwnd         = Msg->hwnd;
 +    MHook.wHitTestCode = HitTest;
 +    MHook.dwExtraInfo  = 0;
 +    if (co_HOOK_CallHooks( WH_MOUSE,
 +                           RemoveMsg ? HC_ACTION : HC_NOREMOVE,
 +                           Msg->message,
 +                           (LPARAM)&MHook ))
 +    {
 +        if (ISITHOOKED(WH_CBT))
 +        {
 +            MHook.pt           = Msg->pt;
 +            MHook.hwnd         = Msg->hwnd;
 +            MHook.wHitTestCode = HitTest;
 +            MHook.dwExtraInfo  = 0;
 +            co_HOOK_CallHooks( WH_CBT,
 +                               HCBT_CLICKSKIPPED,
 +                               Msg->message,
 +                               (LPARAM)&MHook);
 +        }
 +        return FALSE;
 +    }
 +
 +      return TRUE;
 +}
 +
 +BOOL ProcessKeyboardMessage(MSG* Msg, UINT RemoveMsg)
 +{
 +   EVENTMSG Event;
 +
 +   Event.message = Msg->message;
 +   Event.hwnd    = Msg->hwnd;
 +   Event.time    = Msg->time;
 +   Event.paramL  = (Msg->wParam & 0xFF) | (HIWORD(Msg->lParam) << 8);
 +   Event.paramH  = Msg->lParam & 0x7FFF;
 +   if (HIWORD(Msg->lParam) & 0x0100) Event.paramH |= 0x8000;
 +   co_HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)&Event);
 +
 +    if (co_HOOK_CallHooks( WH_KEYBOARD,
 +                           RemoveMsg ? HC_ACTION : HC_NOREMOVE,
 +                           LOWORD(Msg->wParam),
 +                           Msg->lParam))
 +    {
 +        if (ISITHOOKED(WH_CBT))
 +        {
 +            /* skip this message */
 +            co_HOOK_CallHooks( WH_CBT,
 +                               HCBT_KEYSKIPPED,
 +                               LOWORD(Msg->wParam),
 +                               Msg->lParam );
 +        }
 +        return FALSE;
 +    }
 +      return TRUE;
 +}
 +/*
 + * Internal version of PeekMessage() doing all the work
 + */
 +BOOL FASTCALL
 +co_IntPeekMessage( PUSER_MESSAGE Msg,
 +                   PWINDOW_OBJECT Window,
 +                   UINT MsgFilterMin,
 +                   UINT MsgFilterMax,
 +                   UINT RemoveMsg )
 +{
 +   PTHREADINFO pti;
 +   LARGE_INTEGER LargeTickCount;
 +   PUSER_MESSAGE_QUEUE ThreadQueue;
 +   PUSER_MESSAGE Message;
 +   BOOL Present, RemoveMessages;
 +   USER_REFERENCE_ENTRY Ref;
 +   USHORT HitTest;
 +
 +   /* The queues and order in which they are checked are documented in the MSDN
 +      article on GetMessage() */
 +
 +   pti = PsGetCurrentThreadWin32Thread();
 +   ThreadQueue = pti->MessageQueue;
 +
 +   /* Inspect RemoveMsg flags */
 +   /* Note:
 +       The only flag we process is PM_REMOVE.
 +       Processing (High word) PM_QS_Xx Is needed. This and MsgFilterXxx can result
 +       with QS_Xx flags to be used to isolate which message check to test for.
 +       ATM, we look at all messages and the filters are sent to co_MsqFindMessage
 +       and there, it is cross checked.
 +       Example: Wine server/queue.c is_keyboard_msg, check_msg_filter and
 +                filter_contains_hw_range.
 +    */
 +   RemoveMessages = RemoveMsg & PM_REMOVE;
 +
 +/*
 +   If no filter is specified, messages are processed in the following order:
 +
 +    * Sent messages
 +    * Posted messages
 +    * Input (hardware) messages and system internal events
 +    * Sent messages (again)
 +    * WM_PAINT messages
 +    * WM_TIMER messages
 + */
 +CheckMessages:
 +
 +   Present = FALSE;
 +
 +   KeQueryTickCount(&LargeTickCount);
 +   ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart;
 +
 +   /* Dispatch sent messages here. */
 +   while (co_MsqDispatchOneSentMessage(ThreadQueue))
 +      ;
 +
 +   /* Now look for a quit message. */
 +
 +   if (ThreadQueue->QuitPosted)
 +   {
 +      /* According to the PSDK, WM_QUIT messages are always returned, regardless
 +         of the filter specified */
 +      Msg->Msg.hwnd = NULL;
 +      Msg->Msg.message = WM_QUIT;
 +      Msg->Msg.wParam = ThreadQueue->QuitExitCode;
 +      Msg->Msg.lParam = 0;
 +      Msg->FreeLParam = FALSE;
 +      if (RemoveMessages)
 +      {
 +         ThreadQueue->QuitPosted = FALSE;
 +      }
 +      goto MsgExit;
 +   }
 +
 +   /* Now check for normal messages. */
 +   Present = co_MsqFindMessage( ThreadQueue,
 +                                FALSE,
 +                                RemoveMessages,
 +                                Window,
 +                                MsgFilterMin,
 +                                MsgFilterMax,
 +                               &Message );
 +   if (Present)
 +   {
 +      RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
 +      if (RemoveMessages)
 +      {
 +         MsqDestroyMessage(Message);
 +      }
 +      goto MessageFound;
 +   }
 +
 +   /* Check for hardware events. */
 +   Present = co_MsqFindMessage( ThreadQueue,
 +                                TRUE,
 +                                RemoveMessages,
 +                                Window,
 +                                MsgFilterMin,
 +                                MsgFilterMax,
 +                               &Message );
 +   if (Present)
 +   {
 +      RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE));
 +      if (RemoveMessages)
 +      {
 +         MsqDestroyMessage(Message);
 +      }
 +      goto MessageFound;
 +   }
 +
 +   /* Check for sent messages again. */
 +   while (co_MsqDispatchOneSentMessage(ThreadQueue))
 +      ;
 +
 +   /* Check for paint messages. */
 +   if ( IntGetPaintMessage( Window,
 +                            MsgFilterMin,
 +                            MsgFilterMax,
 +                            pti,
 +                            &Msg->Msg,
 +                            RemoveMessages))
 +   {
 +      Msg->FreeLParam = FALSE;
 +      goto MsgExit;
 +   }
 +
++   if (PostTimerMessages(Window))
++      goto CheckMessages;
 +
 +   if(Present)
 +   {
 +MessageFound:
 +
 +      if(RemoveMessages)
 +      {
 +         PWINDOW_OBJECT MsgWindow = NULL;
 +
 +         /* Mouse message process */
 +
 +         if( Msg->Msg.hwnd &&
 +            ( MsgWindow = UserGetWindowObject(Msg->Msg.hwnd) ) &&
 +             Msg->Msg.message >= WM_MOUSEFIRST &&
 +             Msg->Msg.message <= WM_MOUSELAST )
 +         {
 +            USHORT HitTest;
 +
 +            UserRefObjectCo(MsgWindow, &Ref);
 +
 +            if ( co_IntTranslateMouseMessage( ThreadQueue,
 +                                              &Msg->Msg,
 +                                              &HitTest,
 +                                              TRUE))
 +         /* FIXME - check message filter again, if the message doesn't match anymore,
 +                    search again */
 +            {
 +               UserDerefObjectCo(MsgWindow);
 +               /* eat the message, search again */
 +               goto CheckMessages;
 +            }
 +
 +            if(ThreadQueue->CaptureWindow == NULL)
 +            {
 +               co_IntSendHitTestMessages(ThreadQueue, &Msg->Msg);
 +
 +               if ( ( Msg->Msg.message != WM_MOUSEMOVE &&
 +                      Msg->Msg.message != WM_NCMOUSEMOVE ) &&
 +                     IS_BTN_MESSAGE(Msg->Msg.message, DOWN) &&
 +                     co_IntActivateWindowMouse(ThreadQueue, &Msg->Msg, MsgWindow, &HitTest) )
 +               {
 +                  UserDerefObjectCo(MsgWindow);
 +                  /* eat the message, search again */
 +                  goto CheckMessages;
 +               }
 +            }
 +
 +            UserDerefObjectCo(MsgWindow);
 +         }
 +         else
 +         {
 +            co_IntSendHitTestMessages(ThreadQueue, &Msg->Msg);
 +         }
 +
 +//         if(MsgWindow)
 +//         {
 +//            UserDereferenceObject(MsgWindow);
 +//         }
 +
 +         goto MsgExit;
 +      }
 +
 +      if ( ( Msg->Msg.hwnd &&
 +             Msg->Msg.message >= WM_MOUSEFIRST &&
 +             Msg->Msg.message <= WM_MOUSELAST ) &&
 +           co_IntTranslateMouseMessage( ThreadQueue,
 +                                       &Msg->Msg,
 +                                       &HitTest,
 +                                        FALSE) )
 +    /* FIXME - check message filter again, if the message doesn't match anymore,
 +               search again */
 +      {
 +         /* eat the message, search again */
 +         goto CheckMessages;
 +      }
 +
 +MsgExit:
 +      if ( ISITHOOKED(WH_MOUSE) && IS_MOUSE_MESSAGE(Msg->Msg.message))
 +      {
 +          if(!ProcessMouseMessage(&Msg->Msg, HitTest, RemoveMsg))
 +                {
 +                        return FALSE;
 +                }
 +        }
 +
 +      if ( ISITHOOKED(WH_KEYBOARD) && IS_KBD_MESSAGE(Msg->Msg.message))
 +      {
 +          if(!ProcessKeyboardMessage(&Msg->Msg, RemoveMsg))
 +          {
 +              return FALSE;
 +          }
 +      }
 +      // The WH_GETMESSAGE hook enables an application to monitor messages about to
 +      // be returned by the GetMessage or PeekMessage function.
 +      if (ISITHOOKED(WH_GETMESSAGE))
 +      {
 +         //DPRINT1("Peek WH_GETMESSAGE -> %x\n",&Msg);
 +         co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)&Msg->Msg);
 +      }
 +      return TRUE;
 +   }
 +
 +   return Present;
 +}
 +
 +static NTSTATUS FASTCALL
 +CopyMsgToKernelMem(MSG *KernelModeMsg, MSG *UserModeMsg, PMSGMEMORY MsgMemoryEntry)
 +{
 +   NTSTATUS Status;
 +
 +   PVOID KernelMem;
 +   UINT Size;
 +
 +   *KernelModeMsg = *UserModeMsg;
 +
 +   /* See if this message type is present in the table */
 +   if (NULL == MsgMemoryEntry)
 +   {
 +      /* Not present, no copying needed */
 +      return STATUS_SUCCESS;
 +   }
 +
 +   /* Determine required size */
 +   Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
 +
 +   if (0 != Size)
 +   {
 +      /* Allocate kernel mem */
 +      KernelMem = ExAllocatePoolWithTag(PagedPool, Size, TAG_MSG);
 +      if (NULL == KernelMem)
 +      {
 +         DPRINT1("Not enough memory to copy message to kernel mem\n");
 +         return STATUS_NO_MEMORY;
 +      }
 +      KernelModeMsg->lParam = (LPARAM) KernelMem;
 +
 +      /* Copy data if required */
 +      if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_READ))
 +      {
 +         Status = MmCopyFromCaller(KernelMem, (PVOID) UserModeMsg->lParam, Size);
 +         if (! NT_SUCCESS(Status))
 +         {
 +            DPRINT1("Failed to copy message to kernel: invalid usermode buffer\n");
 +            ExFreePoolWithTag(KernelMem, TAG_MSG);
 +            return Status;
 +         }
 +      }
 +      else
 +      {
 +         /* Make sure we don't pass any secrets to usermode */
 +         RtlZeroMemory(KernelMem, Size);
 +      }
 +   }
 +   else
 +   {
 +      KernelModeMsg->lParam = 0;
 +   }
 +
 +   return STATUS_SUCCESS;
 +}
 +
 +static NTSTATUS FASTCALL
 +CopyMsgToUserMem(MSG *UserModeMsg, MSG *KernelModeMsg)
 +{
 +   NTSTATUS Status;
 +   PMSGMEMORY MsgMemoryEntry;
 +   UINT Size;
 +
 +   /* See if this message type is present in the table */
 +   MsgMemoryEntry = FindMsgMemory(UserModeMsg->message);
 +   if (NULL == MsgMemoryEntry)
 +   {
 +      /* Not present, no copying needed */
 +      return STATUS_SUCCESS;
 +   }
 +
 +   /* Determine required size */
 +   Size = MsgMemorySize(MsgMemoryEntry, UserModeMsg->wParam, UserModeMsg->lParam);
 +
 +   if (0 != Size)
 +   {
 +      /* Copy data if required */
 +      if (0 != (MsgMemoryEntry->Flags & MMS_FLAG_WRITE))
 +      {
 +         Status = MmCopyToCaller((PVOID) UserModeMsg->lParam, (PVOID) KernelModeMsg->lParam, Size);
 +         if (! NT_SUCCESS(Status))
 +         {
 +            DPRINT1("Failed to copy message from kernel: invalid usermode buffer\n");
 +            ExFreePool((PVOID) KernelModeMsg->lParam);
 +            return Status;
 +         }
 +      }
 +
 +      ExFreePool((PVOID) KernelModeMsg->lParam);
 +   }
 +
 +   return STATUS_SUCCESS;
 +}
 +
 +static BOOL FASTCALL
 +co_IntWaitMessage( PWINDOW_OBJECT Window,
 +                   UINT MsgFilterMin,
 +                   UINT MsgFilterMax )
 +{
 +   PTHREADINFO pti;
 +   PUSER_MESSAGE_QUEUE ThreadQueue;
 +   NTSTATUS Status = STATUS_SUCCESS;
 +   USER_MESSAGE Msg;
 +
 +   pti = PsGetCurrentThreadWin32Thread();
 +   ThreadQueue = pti->MessageQueue;
 +
 +   do
 +   {
 +      if ( co_IntPeekMessage( &Msg,
 +                               Window,
 +                               MsgFilterMin,
 +                               MsgFilterMax,
 +                               PM_NOREMOVE))
 +      {
 +         return TRUE;
 +      }
 +      /* Nothing found. Wait for new messages. */
 +      Status = co_MsqWaitForNewMessages( ThreadQueue,
 +                                         Window,
 +                                         MsgFilterMin,
 +                                         MsgFilterMax);
 +   }
 +   while ( (STATUS_WAIT_0 <= Status && Status <= STATUS_WAIT_63) ||
 +           STATUS_TIMEOUT == Status );
 +
 +   if (!NT_SUCCESS(Status))
 +   {
 +      SetLastNtError(Status);
 +      DPRINT1("Exit co_IntWaitMessage on error!\n");
 +   }
 +
 +   return FALSE;
 +}
 +
 +BOOL FASTCALL
 +co_IntGetPeekMessage( PMSG pMsg,
 +                      HWND hWnd,
 +                      UINT MsgFilterMin,
 +                      UINT MsgFilterMax,
 +                      UINT RemoveMsg,
 +                      BOOL bGMSG )
 +{
 +   BOOL Present;
 +   PWINDOW_OBJECT Window;
 +   USER_MESSAGE Msg;
 +
 +   if ( hWnd == HWND_TOPMOST ||
 +        hWnd == HWND_BROADCAST )
 +      hWnd = HWND_BOTTOM;
 +
 +   /* Validate input */
 +   if (hWnd && hWnd != HWND_BOTTOM)
 +   {
 +      if (!(Window = UserGetWindowObject(hWnd)))
 +      {
 +         if (bGMSG)
 +            return -1;
 +         else
 +            return FALSE;
 +      }
 +   }
 +   else
 +   {
 +      Window = (PWINDOW_OBJECT)hWnd;
 +   }
 +
 +   if (MsgFilterMax < MsgFilterMin)
 +   {
 +      MsgFilterMin = 0;
 +      MsgFilterMax = 0;
 +   }
 +
 +   do
 +   {
 +      Present = co_IntPeekMessage( &Msg,
 +                                    Window,
 +                                    MsgFilterMin,
 +                                    MsgFilterMax,
 +                                    RemoveMsg );
 +      if (Present)
 +      {
 +         RtlCopyMemory( pMsg, &Msg.Msg, sizeof(MSG));
 +
 +         if (bGMSG)
 +            return (WM_QUIT != pMsg->message);
 +         else
 +            return TRUE;
 +      }
 +
 +      if ( bGMSG && !co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax) )
 +      {
 +         return -1;
 +      }
 +      else
 +      {
 +         if (!(RemoveMsg & PM_NOYIELD))
 +         {
 +         // Yield this thread!
 +            UserLeave();
 +            ZwYieldExecution();
 +            UserEnterExclusive();
 +         // Fall through to fail.
 +         }
 +      }
 +   }
 +   while( bGMSG && !Present );
 +
 +   return FALSE;
 +}
 +
 +BOOL FASTCALL
 +UserPostThreadMessage( DWORD idThread,
 +                       UINT Msg,
 +                       WPARAM wParam,
 +                       LPARAM lParam )
 +{
 +   MSG Message;
 +   PETHREAD peThread;
 +   PTHREADINFO pThread;
 +   LARGE_INTEGER LargeTickCount;
 +   NTSTATUS Status;
 +
 +   DPRINT1("UserPostThreadMessage wParam 0x%x  lParam 0x%x\n", wParam,lParam);
 +
 +   if (FindMsgMemory(Msg) != 0)
 +   {
 +      SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
 +      return FALSE;
 +   }
 +
 +   Status = PsLookupThreadByThreadId((HANDLE)idThread,&peThread);
 +
 +   if( Status == STATUS_SUCCESS )
 +   {
 +      pThread = (PTHREADINFO)peThread->Tcb.Win32Thread;
 +      if( !pThread ||
 +          !pThread->MessageQueue ||
 +         (pThread->TIF_flags & TIF_INCLEANUP))
 +      {
 +         ObDereferenceObject( peThread );
 +         return FALSE;
 +      }
 +
 +      Message.hwnd = NULL;
 +      Message.message = Msg;
 +      Message.wParam = wParam;
 +      Message.lParam = lParam;
 +      Message.pt = gpsi->ptCursor;
 +
 +      KeQueryTickCount(&LargeTickCount);
 +      pThread->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
 +      MsqPostMessage(pThread->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
 +      ObDereferenceObject( peThread );
 +      return TRUE;
 +   }
 +   else
 +   {
 +      SetLastNtError( Status );
 +   }
 +   return FALSE;
 +}
 +
 +BOOL FASTCALL
 +UserPostMessage( HWND Wnd,
 +                 UINT Msg,
 +                 WPARAM wParam,
 +                 LPARAM lParam )
 +{
 +   PTHREADINFO pti;
 +   MSG Message;
 +   LARGE_INTEGER LargeTickCount;
 +
 +   if (FindMsgMemory(Msg) != 0)
 +   {
 +      SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
 +      return FALSE;
 +   }
 +
 +   if (!Wnd)
 +      return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()),
 +                                    Msg,
 +                                    wParam,
 +                                    lParam);
 +
 +   if (Wnd == HWND_BROADCAST)
 +   {
 +      HWND *List;
 +      PWINDOW_OBJECT DesktopWindow;
 +      ULONG i;
 +
 +      DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
 +      List = IntWinListChildren(DesktopWindow);
 +
 +      if (List != NULL)
 +      {
 +         UserPostMessage(DesktopWindow->hSelf, Msg, wParam, lParam);
 +         for (i = 0; List[i]; i++)
 +            UserPostMessage(List[i], Msg, wParam, lParam);
 +         ExFreePool(List);
 +      }
 +   }
 +   else
 +   {
 +      PWINDOW_OBJECT Window;
 +
 +      Window = UserGetWindowObject(Wnd);
 +      if ( !Window || !Window->Wnd )
 +      {
 +         return FALSE;
 +      }
 +
 +      pti = Window->Wnd->head.pti;
 +      if ( pti->TIF_flags & TIF_INCLEANUP )
 +      {
 +         DPRINT1("Attempted to post message to window 0x%x when the thread is in cleanup!\n", Wnd);
 +         return FALSE;
 +      }
 +
 +      if ( Window->state & WINDOWSTATUS_DESTROYING )
 +      {
 +         DPRINT1("Attempted to post message to window 0x%x that is being destroyed!\n", Wnd);
 +         /* FIXME - last error code? */
 +         return FALSE;
 +      }
 +
 +      if (WM_QUIT == Msg)
 +      {
 +          MsqPostQuitMessage(Window->pti->MessageQueue, wParam);
 +      }
 +      else
 +      {
 +         Message.hwnd = Wnd;
 +         Message.message = Msg;
 +         Message.wParam = wParam;
 +         Message.lParam = lParam;
 +         Message.pt = gpsi->ptCursor;
 +         KeQueryTickCount(&LargeTickCount);
 +         pti->timeLast = Message.time = MsqCalculateMessageTime(&LargeTickCount);
 +         MsqPostMessage(Window->pti->MessageQueue, &Message, FALSE, QS_POSTMESSAGE);
 +      }
 +   }
 +   return TRUE;
 +}
 +
 +
 +LRESULT FASTCALL
 +co_IntSendMessage( HWND hWnd,
 +                   UINT Msg,
 +                   WPARAM wParam,
 +                   LPARAM lParam )
 +{
 +   ULONG_PTR Result = 0;
 +   if(co_IntSendMessageTimeout(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result))
 +   {
 +      return (LRESULT)Result;
 +   }
 +   return 0;
 +}
 +
 +static
 +LRESULT FASTCALL
 +co_IntSendMessageTimeoutSingle( HWND hWnd,
 +                                UINT Msg,
 +                                WPARAM wParam,
 +                                LPARAM lParam,
 +                                UINT uFlags,
 +                                UINT uTimeout,
 +                                ULONG_PTR *uResult )
 +{
 +   ULONG_PTR Result;
 +   NTSTATUS Status;
 +   PWINDOW_OBJECT Window = NULL;
 +   PMSGMEMORY MsgMemoryEntry;
 +   INT lParamBufferSize;
 +   LPARAM lParamPacked;
 +   PTHREADINFO Win32Thread;
 +   DECLARE_RETURN(LRESULT);
 +   USER_REFERENCE_ENTRY Ref;
 +
 +   if (!(Window = UserGetWindowObject(hWnd)))
 +   {
 +       RETURN( FALSE);
 +   }
 +
 +   UserRefObjectCo(Window, &Ref);
 +
 +   Win32Thread = PsGetCurrentThreadWin32Thread();
 +
 +   IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
 +
 +   if ( NULL != Win32Thread &&
 +        Window->pti->MessageQueue == Win32Thread->MessageQueue)
 +   {
 +      if (Win32Thread->TIF_flags & TIF_INCLEANUP)
 +      {
 +         /* Never send messages to exiting threads */
 +          RETURN( FALSE);
 +      }
 +
 +      /* See if this message type is present in the table */
 +      MsgMemoryEntry = FindMsgMemory(Msg);
 +      if (NULL == MsgMemoryEntry)
 +      {
 +         lParamBufferSize = -1;
 +      }
 +      else
 +      {
 +         lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
 +      }
 +
 +      if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, FALSE)))
 +      {
 +          DPRINT1("Failed to pack message parameters\n");
 +          RETURN( FALSE);
 +      }
 +
 +      Result = (ULONG_PTR)co_IntCallWindowProc( Window->Wnd->lpfnWndProc,
 +                                               !Window->Wnd->Unicode,
 +                                                hWnd,
 +                                                Msg,
 +                                                wParam,
 +                                                lParamPacked,
 +                                                lParamBufferSize );
 +      if(uResult)
 +      {
 +         *uResult = Result;
 +      }
 +
 +      IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
 +
 +      if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
 +      {
 +         DPRINT1("Failed to unpack message parameters\n");
 +         RETURN( TRUE);
 +      }
 +
 +      RETURN( TRUE);
 +   }
 +
 +   if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->pti->MessageQueue))
 +   {
 +      /* FIXME - Set a LastError? */
 +      RETURN( FALSE);
 +   }
 +
 +   if (Window->state & WINDOWSTATUS_DESTROYING)
 +   {
 +      /* FIXME - last error? */
 +      DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
 +      RETURN( FALSE);
 +   }
 +
 +   do
 +   {
 +      Status = co_MsqSendMessage( Window->pti->MessageQueue,
 +                                                       hWnd,
 +                                                        Msg,
 +                                                     wParam,
 +                                                     lParam,
 +                                                   uTimeout,
 +                                      (uFlags & SMTO_BLOCK),
 +                                                 MSQ_NORMAL,
 +                                                    uResult );
 +   }
 +   while ((STATUS_TIMEOUT == Status) &&
 +          (uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
 +          !MsqIsHung(Window->pti->MessageQueue));
 +
 +   IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
 +
 +   if (STATUS_TIMEOUT == Status)
 +   {
 +/*
 +   MSDN says:
 +      Microsoft Windows 2000: If GetLastError returns zero, then the function
 +      timed out.
 +      XP+ : If the function fails or times out, the return value is zero.
 +      To get extended error information, call GetLastError. If GetLastError
 +      returns ERROR_TIMEOUT, then the function timed out.
 + */
 +      SetLastWin32Error(ERROR_TIMEOUT);
 +      RETURN( FALSE);
 +   }
 +   else if (! NT_SUCCESS(Status))
 +   {
 +      SetLastNtError(Status);
 +      RETURN( FALSE);
 +   }
 +
 +   RETURN( TRUE);
 +
 +CLEANUP:
 +   if (Window) UserDerefObjectCo(Window);
 +   END_CLEANUP;
 +}
 +
 +LRESULT FASTCALL
 +co_IntSendMessageTimeout( HWND hWnd,
 +                          UINT Msg,
 +                          WPARAM wParam,
 +                          LPARAM lParam,
 +                          UINT uFlags,
 +                          UINT uTimeout,
 +                          ULONG_PTR *uResult )
 +{
 +   PWINDOW_OBJECT DesktopWindow;
 +   HWND *Children;
 +   HWND *Child;
 +
 +   if (HWND_BROADCAST != hWnd)
 +   {
 +      return co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, uFlags, uTimeout, uResult);
 +   }
 +
 +   DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
 +   if (NULL == DesktopWindow)
 +   {
 +      SetLastWin32Error(ERROR_INTERNAL_ERROR);
 +      return 0;
 +   }
 +
 +   /* Send message to the desktop window too! */
 +   co_IntSendMessageTimeoutSingle(DesktopWindow->hSelf, Msg, wParam, lParam, uFlags, uTimeout, uResult);
 +
 +   Children = IntWinListChildren(DesktopWindow);
 +   if (NULL == Children)
 +   {
 +      return 0;
 +   }
 +
 +   for (Child = Children; NULL != *Child; Child++)
 +   {
 +      co_IntSendMessageTimeoutSingle(*Child, Msg, wParam, lParam, uFlags, uTimeout, uResult);
 +   }
 +
 +   ExFreePool(Children);
 +
 +   return (LRESULT) TRUE;
 +}
 +
 +LRESULT FASTCALL co_IntSendMessageNoWait(HWND hWnd,
 +                                         UINT Msg,
 +                                         WPARAM wParam,
 +                                         LPARAM lParam)
 +{
 +   ULONG_PTR Result = 0;
 +   co_IntSendMessageWithCallBack(hWnd,
 +                                 Msg,
 +                                 wParam,
 +                                 lParam,
 +                                 NULL,
 +                                 0,
 +                                 &Result);
 +   return Result;
 +}
 +
 +LRESULT FASTCALL
 +co_IntSendMessageWithCallBack( HWND hWnd,
 +                               UINT Msg,
 +                               WPARAM wParam,
 +                               LPARAM lParam,
 +                               SENDASYNCPROC CompletionCallback,
 +                               ULONG_PTR CompletionCallbackContext,
 +                               ULONG_PTR *uResult)
 +{
 +   ULONG_PTR Result;
 +   PWINDOW_OBJECT Window = NULL;
 +   PMSGMEMORY MsgMemoryEntry;
 +   INT lParamBufferSize;
 +   LPARAM lParamPacked;
 +   PTHREADINFO Win32Thread;
 +   DECLARE_RETURN(LRESULT);
 +   USER_REFERENCE_ENTRY Ref;
 +   PUSER_SENT_MESSAGE Message;
 +
 +   if (!(Window = UserGetWindowObject(hWnd)))
 +   {
 +       RETURN(FALSE);
 +   }
 +
 +   UserRefObjectCo(Window, &Ref);
 +
 +   if (Window->state & WINDOWSTATUS_DESTROYING)
 +   {
 +      /* FIXME - last error? */
 +      DPRINT1("Attempted to send message to window 0x%x that is being destroyed!\n", hWnd);
 +      RETURN(FALSE);
 +   }
 +
 +   Win32Thread = PsGetCurrentThreadWin32Thread();
 +
 +   IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
 +
 +   if (Win32Thread == NULL)
 +   {
 +     ASSERT(FALSE);
 +     RETURN(FALSE);
 +   }
 +
 +   if (Win32Thread->TIF_flags & TIF_INCLEANUP)
 +   {
 +      /* Never send messages to exiting threads */
 +       RETURN(FALSE);
 +   }
 +
 +   /* See if this message type is present in the table */
 +   MsgMemoryEntry = FindMsgMemory(Msg);
 +   if (NULL == MsgMemoryEntry)
 +   {
 +      lParamBufferSize = -1;
 +   }
 +   else
 +   {
 +      lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
 +   }
 +
 +   if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->pti->MessageQueue != Win32Thread->MessageQueue)))
 +   {
 +       DPRINT1("Failed to pack message parameters\n");
 +       RETURN( FALSE);
 +   }
 +
 +   /* If this is not a callback and it can be sent now, then send it. */
 +   if ((Window->pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL))
 +   {
 +
 +      Result = (ULONG_PTR)co_IntCallWindowProc( Window->Wnd->lpfnWndProc,
 +                                               !Window->Wnd->Unicode,
 +                                                hWnd,
 +                                                Msg,
 +                                                wParam,
 +                                                lParamPacked,
 +                                                lParamBufferSize );
 +      if(uResult)
 +      {
 +         *uResult = Result;
 +      }
 +   }
 +
 +   IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
 +
 +   if (Window->pti->MessageQueue == Win32Thread->MessageQueue)
 +   {
 +      if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
 +      {
 +         DPRINT1("Failed to unpack message parameters\n");
 +         RETURN(TRUE);
 +      }
 +      RETURN(TRUE);
 +   }
 +
 +   if(!(Message = ExAllocatePoolWithTag(NonPagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG)))
 +   {
 +      DPRINT1("MsqSendMessage(): Not enough memory to allocate a message");
 +      return STATUS_INSUFFICIENT_RESOURCES;
 +   }
 +
 +   Message->Msg.hwnd = hWnd;
 +   Message->Msg.message = Msg;
 +   Message->Msg.wParam = wParam;
 +   Message->Msg.lParam = lParamPacked;
 +   Message->CompletionEvent = NULL;
 +   Message->Result = 0;
 +   Message->SenderQueue = Win32Thread->MessageQueue;
 +   IntReferenceMessageQueue(Message->SenderQueue);
 +   IntReferenceMessageQueue(Window->pti->MessageQueue);
 +   Message->CompletionCallback = CompletionCallback;
 +   Message->CompletionCallbackContext = CompletionCallbackContext;
 +   Message->HookMessage = MSQ_NORMAL | MSQ_SENTNOWAIT;
 +   Message->HasPackedLParam = (lParamBufferSize > 0);
 +
 +   InsertTailList(&Window->pti->MessageQueue->SentMessagesListHead, &Message->ListEntry);
 +   InsertTailList(&Win32Thread->MessageQueue->DispatchingMessagesHead, &Message->DispatchingListEntry);
 +   IntDereferenceMessageQueue(Window->pti->MessageQueue);
 +   IntDereferenceMessageQueue(Message->SenderQueue);
 +
 +   RETURN(TRUE);
 +
 +CLEANUP:
 +   if (Window) UserDerefObjectCo(Window);
 +   END_CLEANUP;
 +}
 +
 +/* This function posts a message if the destination's message queue belongs to
 +   another thread, otherwise it sends the message. It does not support broadcast
 +   messages! */
 +LRESULT FASTCALL
 +co_IntPostOrSendMessage( HWND hWnd,
 +                         UINT Msg,
 +                         WPARAM wParam,
 +                         LPARAM lParam )
 +{
 +   ULONG_PTR Result;
 +   PTHREADINFO pti;
 +   PWINDOW_OBJECT Window;
 +
 +   if ( hWnd == HWND_BROADCAST )
 +   {
 +      return 0;
 +   }
 +
 +   if(!(Window = UserGetWindowObject(hWnd)))
 +   {
 +      return 0;
 +   }
 +
 +   pti = PsGetCurrentThreadWin32Thread();
 +
 +   if ( Window->pti->MessageQueue != pti->MessageQueue &&
 +        FindMsgMemory(Msg) == 0 )
 +   {
 +      Result = UserPostMessage(hWnd, Msg, wParam, lParam);
 +   }
 +   else
 +   {
 +      if ( !co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, SMTO_NORMAL, 0, &Result) )
 +      {
 +         Result = 0;
 +      }
 +   }
 +
 +   return (LRESULT)Result;
 +}
 +
 +LRESULT FASTCALL
 +co_IntDoSendMessage( HWND hWnd,
 +                     UINT Msg,
 +                     WPARAM wParam,
 +                     LPARAM lParam,
 +                     PDOSENDMESSAGE dsm,
 +                     PNTUSERSENDMESSAGEINFO UnsafeInfo )
 +{
 +   PTHREADINFO pti;
 +   LRESULT Result = TRUE;
 +   NTSTATUS Status;
 +   PWINDOW_OBJECT Window = NULL;
 +   NTUSERSENDMESSAGEINFO Info;
 +   MSG UserModeMsg;
 +   MSG KernelModeMsg;
 +   PMSGMEMORY MsgMemoryEntry;
 +
 +   RtlZeroMemory(&Info, sizeof(NTUSERSENDMESSAGEINFO));
 +
 +   /* FIXME: Call hooks. */
 +   if (HWND_BROADCAST != hWnd)
 +   {
 +      Window = UserGetWindowObject(hWnd);
 +      if ( !Window || !Window->Wnd )
 +      {
 +         /* Tell usermode to not touch this one */
 +         Info.HandledByKernel = TRUE;
 +         MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
 +         return 0;
 +      }
 +   }
 +
 +   /* Check for an exiting window. */
 +   if (Window && Window->state & WINDOWSTATUS_DESTROYING)
 +   {
 +      DPRINT1("co_IntDoSendMessage Window Exiting!\n");
 +   }
 +
 +   /* See if the current thread can handle the message */
 +   pti = PsGetCurrentThreadWin32Thread();
 +
 +   // This is checked in user mode!!!!!!!
 +   if ( HWND_BROADCAST != hWnd &&
 +        NULL != pti &&
 +        Window->pti->MessageQueue == pti->MessageQueue &&
 +       !ISITHOOKED(WH_CALLWNDPROC) &&
 +       !ISITHOOKED(WH_CALLWNDPROCRET) &&
 +        ( Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST ) )
 +   {
 +      /* Gather the information usermode needs to call the window proc directly */
 +      Info.HandledByKernel = FALSE;
 +
 +      Status = MmCopyFromCaller(&(Info.Ansi), &(UnsafeInfo->Ansi),
 +                                sizeof(BOOL));
 +      if (! NT_SUCCESS(Status))
 +      {
 +         Info.Ansi = ! Window->Wnd->Unicode;
 +      }
 +
 +      Info.Ansi = !Window->Wnd->Unicode;
 +      Info.Proc = Window->Wnd->lpfnWndProc;
 +   }
 +   else
 +   {
 +      /* Must be handled by other thread */
 +//      if (HWND_BROADCAST != hWnd)
 +//      {
 +//         UserDereferenceObject(Window);
 +//      }
 +      Info.HandledByKernel = TRUE;
 +      UserModeMsg.hwnd = hWnd;
 +      UserModeMsg.message = Msg;
 +      UserModeMsg.wParam = wParam;
 +      UserModeMsg.lParam = lParam;
 +      MsgMemoryEntry = FindMsgMemory(UserModeMsg.message);
 +
 +      Status = CopyMsgToKernelMem(&KernelModeMsg, &UserModeMsg, MsgMemoryEntry);
 +      if (! NT_SUCCESS(Status))
 +      {
 +         MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
 +         SetLastWin32Error(ERROR_INVALID_PARAMETER);
 +         return (dsm ? 0 : -1);
 +      }
 +
 +      if(!dsm)
 +      {
 +         Result = co_IntSendMessage( KernelModeMsg.hwnd,
 +                                     KernelModeMsg.message,
 +                                     KernelModeMsg.wParam,
 +                                     KernelModeMsg.lParam );
 +      }
 +      else
 +      {
 +         Result = co_IntSendMessageTimeout( KernelModeMsg.hwnd,
 +                                            KernelModeMsg.message,
 +                                            KernelModeMsg.wParam,
 +                                            KernelModeMsg.lParam,
 +                                            dsm->uFlags,
 +                                            dsm->uTimeout,
 +                                           &dsm->Result );
 +      }
 +
 +      Status = CopyMsgToUserMem(&UserModeMsg, &KernelModeMsg);
 +      if (! NT_SUCCESS(Status))
 +      {
 +         MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
 +         SetLastWin32Error(ERROR_INVALID_PARAMETER);
 +         return(dsm ? 0 : -1);
 +      }
 +   }
 +
 +   Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERSENDMESSAGEINFO));
 +   if (! NT_SUCCESS(Status))
 +   {
 +      SetLastWin32Error(ERROR_INVALID_PARAMETER);
 +   }
 +
 +   return (LRESULT)Result;
 +}
 +
 +
 +BOOL FASTCALL
 +UserSendNotifyMessage( HWND hWnd,
 +                       UINT Msg,
 +                       WPARAM wParam,
 +                       LPARAM lParam )
 +{
 +   BOOL Result = TRUE;
 +
 +   if (FindMsgMemory(Msg) != 0)
 +   {
 +      SetLastWin32Error(ERROR_MESSAGE_SYNC_ONLY );
 +      return FALSE;
 +   }
 +
 +   // Basicly the same as IntPostOrSendMessage
 +   if (hWnd == HWND_BROADCAST) //Handle Broadcast
 +   {
 +      HWND *List;
 +      PWINDOW_OBJECT DesktopWindow;
 +      ULONG i;
 +
 +      DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
 +      List = IntWinListChildren(DesktopWindow);
 +
 +      if (List != NULL)
 +      {
 +         UserSendNotifyMessage(DesktopWindow->hSelf, Msg, wParam, lParam);
 +         for (i = 0; List[i]; i++)
 +         {
 +            UserSendNotifyMessage(List[i], Msg, wParam, lParam);
 +         }
 +         ExFreePool(List);
 +      }
 +   }
 +   else
 +   {
 +     ULONG_PTR PResult;
 +     PTHREADINFO pti;
 +     PWINDOW_OBJECT Window;
 +     MSG Message;
 +
 +      if ( !(Window = UserGetWindowObject(hWnd)) ) return FALSE;
 +
 +      pti = PsGetCurrentThreadWin32Thread();
 +
 +      if (Window->pti->MessageQueue != pti->MessageQueue)
 +      { // Send message w/o waiting for it.
 +         Result = UserPostMessage(hWnd, Msg, wParam, lParam);
 +      }
 +      else
 +      { // Handle message and callback.
 +         Message.hwnd = hWnd;
 +         Message.message = Msg;
 +         Message.wParam = wParam;
 +         Message.lParam = lParam;
 +
 +         Result = co_IntSendMessageTimeoutSingle( hWnd,
 +                                                  Msg,
 +                                                  wParam,
 +                                                  lParam,
 +                                                  SMTO_NORMAL,
 +                                                  0,
 +                                                 &PResult );
 +      }
 +   }
 +   return Result;
 +}
 +
 +
 +DWORD APIENTRY
 +IntGetQueueStatus(BOOL ClearChanges)
 +{
 +   PTHREADINFO pti;
 +   PUSER_MESSAGE_QUEUE Queue;
 +   DWORD Result;
 +   DECLARE_RETURN(DWORD);
 +
 +   DPRINT("Enter IntGetQueueStatus\n");
 +
 +   pti = PsGetCurrentThreadWin32Thread();
 +   Queue = pti->MessageQueue;
 +
 +   Result = MAKELONG(Queue->QueueBits, Queue->ChangedBits);
 +   if (ClearChanges)
 +   {
 +      Queue->ChangedBits = 0;
 +   }
 +
 +   RETURN(Result);
 +
 +CLEANUP:
 +   DPRINT("Leave IntGetQueueStatus, ret=%i\n",_ret_);
 +   END_CLEANUP;
 +}
 +
 +BOOL APIENTRY
 +IntInitMessagePumpHook()
 +{
 +   if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti)
 +   {
 +     ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook++;
 +     return TRUE;
 +   }
 +   return FALSE;
 +}
 +
 +BOOL APIENTRY
 +IntUninitMessagePumpHook()
 +{
 +   if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti)
 +   {
 +      if (((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook <= 0)
 +      {
 +         return FALSE;
 +      }
 +      ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->pcti->dwcPumpHook--;
 +      return TRUE;
 +   }
 +   return FALSE;
 +}
 +
 +/** Functions ******************************************************************/
 +
 +BOOL APIENTRY
 +NtUserPostMessage(HWND hWnd,
 +                  UINT Msg,
 +                  WPARAM wParam,
 +                  LPARAM lParam)
 +{
 +   DECLARE_RETURN(BOOL);
 +
 +   DPRINT("Enter NtUserPostMessage\n");
 +   UserEnterExclusive();
 +
 +   RETURN( UserPostMessage(hWnd, Msg, wParam, lParam));
 +
 +CLEANUP:
 +   DPRINT("Leave NtUserPostMessage, ret=%i\n",_ret_);
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +
 +BOOL APIENTRY
 +NtUserPostThreadMessage(DWORD idThread,
 +                        UINT Msg,
 +                        WPARAM wParam,
 +                        LPARAM lParam)
 +{
 +   DECLARE_RETURN(BOOL);
 +
 +   DPRINT("Enter NtUserPostThreadMessage\n");
 +   UserEnterExclusive();
 +
 +   RETURN( UserPostThreadMessage( idThread,
 +                                  Msg,
 +                                  wParam,
 +                                  lParam));
 +
 +CLEANUP:
 +   DPRINT("Leave NtUserPostThreadMessage, ret=%i\n",_ret_);
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +
 +DWORD APIENTRY
 +NtUserQuerySendMessage(DWORD Unknown0)
 +{
 +   UNIMPLEMENTED;
 +
 +   return 0;
 +}
 +
 +
 +////////// API on the way out!
 +LRESULT APIENTRY
 +NtUserSendMessageTimeout( HWND hWnd,
 +                          UINT Msg,
 +                          WPARAM wParam,
 +                          LPARAM lParam,
 +                          UINT uFlags,
 +                          UINT uTimeout,
 +                          ULONG_PTR *uResult,
 +                          PNTUSERSENDMESSAGEINFO UnsafeInfo )
 +{
 +   DOSENDMESSAGE dsm;
 +   LRESULT Result;
 +   DECLARE_RETURN(BOOL);
 +
 +   DPRINT("Enter NtUserSendMessageTimeout\n");
 +   UserEnterExclusive();
 +
 +   dsm.uFlags = uFlags;
 +   dsm.uTimeout = uTimeout;
 +   Result = co_IntDoSendMessage(hWnd, Msg, wParam, lParam, &dsm, UnsafeInfo);
 +   if(uResult != NULL && Result != 0)
 +   {
 +      NTSTATUS Status;
 +
 +      Status = MmCopyToCaller(uResult, &dsm.Result, sizeof(ULONG_PTR));
 +      if(!NT_SUCCESS(Status))
 +      {
 +         SetLastWin32Error(ERROR_INVALID_PARAMETER);
 +         RETURN( FALSE);
 +      }
 +   }
 +   RETURN( Result);
 +
 +CLEANUP:
 +   DPRINT("Leave NtUserSendMessageTimeout, ret=%i\n",_ret_);
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +
 +LRESULT APIENTRY
 +NtUserSendMessage( HWND Wnd,
 +                   UINT Msg,
 +                   WPARAM wParam,
 +                   LPARAM lParam,
 +                   PNTUSERSENDMESSAGEINFO UnsafeInfo )
 +{
 +   DECLARE_RETURN(BOOL);
 +
 +   DPRINT("Enter NtUserSendMessage\n");
 +   UserEnterExclusive();
 +
 +   RETURN(co_IntDoSendMessage(Wnd, Msg, wParam, lParam, NULL, UnsafeInfo));
 +
 +CLEANUP:
 +   DPRINT("Leave NtUserSendMessage, ret=%i\n",_ret_);
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +//////////
 +
 +BOOL APIENTRY
 +NtUserWaitMessage(VOID)
 +{
 +   DECLARE_RETURN(BOOL);
 +
 +   DPRINT("EnterNtUserWaitMessage\n");
 +   UserEnterExclusive();
 +
 +   RETURN(co_IntWaitMessage(NULL, 0, 0));
 +
 +CLEANUP:
 +   DPRINT("Leave NtUserWaitMessage, ret=%i\n",_ret_);
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +
 +
 +BOOL APIENTRY
 +NtUserGetMessage( PNTUSERGETMESSAGEINFO UnsafeInfo,
 +                  HWND hWnd,
 +                  UINT MsgFilterMin,
 +                  UINT MsgFilterMax )
 +/*
 + * FUNCTION: Get a message from the calling thread's message queue.
 + * ARGUMENTS:
 + *      UnsafeMsg - Pointer to the structure which receives the returned message.
 + *      Wnd - Window whose messages are to be retrieved.
 + *      MsgFilterMin - Integer value of the lowest message value to be
 + *                     retrieved.
 + *      MsgFilterMax - Integer value of the highest message value to be
 + *                     retrieved.
 + */
 +{
 +   BOOL GotMessage;
 +   NTUSERGETMESSAGEINFO Info;
 +   NTSTATUS Status;
 +   /* FIXME: if initialization is removed, gcc complains that this may be used before initialization. Please review */
 +   PWINDOW_OBJECT Window = NULL;
 +   PMSGMEMORY MsgMemoryEntry;
 +   PVOID UserMem;
 +   UINT Size;
 +   USER_MESSAGE Msg;
 +   DECLARE_RETURN(BOOL);
 +//   USER_REFERENCE_ENTRY Ref;
 +
 +   DPRINT("Enter NtUserGetMessage\n");
 +   UserEnterExclusive();
 +
 +   /* Validate input */
 +   if (hWnd && !(Window = UserGetWindowObject(hWnd)))
 +   {
 +      RETURN(-1);
 +   }
 +
 +//   if (Window) UserRefObjectCo(Window, &Ref);
 +
 +   if (MsgFilterMax < MsgFilterMin)
 +   {
 +      MsgFilterMin = 0;
 +      MsgFilterMax = 0;
 +   }
 +
 +   do
 +   {
 +      GotMessage = co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, PM_REMOVE);
 +      if (GotMessage)
 +      {
 +         Info.Msg = Msg.Msg;
 +         /* See if this message type is present in the table */
 +         MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
 +         if (NULL == MsgMemoryEntry)
 +         {
 +            /* Not present, no copying needed */
 +            Info.LParamSize = 0;
 +         }
 +         else
 +         {
 +            /* Determine required size */
 +            Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam,
 +                                 Info.Msg.lParam);
 +            /* Allocate required amount of user-mode memory */
 +            Info.LParamSize = Size;
 +            UserMem = NULL;
 +            Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
 +                                             &Info.LParamSize, MEM_COMMIT, PAGE_READWRITE);
 +
 +            if (! NT_SUCCESS(Status))
 +            {
 +               SetLastNtError(Status);
 +               RETURN( (BOOL) -1);
 +            }
 +            /* Transfer lParam data to user-mode mem */
 +            Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Size);
 +            if (! NT_SUCCESS(Status))
 +            {
 +               ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
 +                                   &Info.LParamSize, MEM_DECOMMIT);
 +               SetLastNtError(Status);
 +               RETURN( (BOOL) -1);
 +            }
 +            Info.Msg.lParam = (LPARAM) UserMem;
 +         }
 +         if (Msg.FreeLParam && 0 != Msg.Msg.lParam)
 +         {
 +            ExFreePool((void *) Msg.Msg.lParam);
 +         }
 +         Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
 +         if (! NT_SUCCESS(Status))
 +         {
 +            SetLastNtError(Status);
 +            RETURN( (BOOL) -1);
 +         }
 +      }
 +      else if (! co_IntWaitMessage(Window, MsgFilterMin, MsgFilterMax))
 +      {
 +         RETURN( (BOOL) -1);
 +      }
 +   }
 +   while (! GotMessage);
 +
 +   RETURN( WM_QUIT != Info.Msg.message);
 +
 +CLEANUP:
 +//   if (Window) UserDerefObjectCo(Window);
 +
 +   DPRINT("Leave NtUserGetMessage\n");
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +
 +
 +BOOL
 +APIENTRY
 +NtUserGetMessageX(
 +   PMSG pMsg,
 +   HWND hWnd,
 +   UINT MsgFilterMin,
 +   UINT MsgFilterMax)
 +{
 +   MSG Msg;
 +   BOOL Ret = FALSE;
 +   DECLARE_RETURN(BOOL);
 +
 +   DPRINT("Enter NtUserGetMessage\n");
 +   UserEnterExclusive();
 +
 +   if ( (MsgFilterMin|MsgFilterMax) & ~WM_MAXIMUM )
 +   {
 +      SetLastWin32Error(ERROR_INVALID_PARAMETER);
 +      RETURN( Ret);
 +   }
 +
 +   RtlZeroMemory(&Msg, sizeof(MSG));
 +
 +   Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, PM_REMOVE, TRUE);
 +
 +   if (Ret)
 +   {
 +      _SEH2_TRY
 +      {
 +         ProbeForWrite(pMsg, sizeof(MSG), 1);
 +         RtlCopyMemory(pMsg, &Msg, sizeof(MSG));
 +      }
 +      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
 +      {
 +         SetLastNtError(_SEH2_GetExceptionCode());
 +         Ret = FALSE;
 +      }
 +      _SEH2_END;
 +   }
 +   RETURN( Ret);
 +
 +CLEANUP:
 +   DPRINT("Leave NtUserGetMessage\n");
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +
 +BOOL APIENTRY
 +NtUserPeekMessage(PNTUSERGETMESSAGEINFO UnsafeInfo,
 +                  HWND hWnd,
 +                  UINT MsgFilterMin,
 +                  UINT MsgFilterMax,
 +                  UINT RemoveMsg)
 +{
 +   NTSTATUS Status;
 +   BOOL Present;
 +   NTUSERGETMESSAGEINFO Info;
 +   PWINDOW_OBJECT Window;
 +   PMSGMEMORY MsgMemoryEntry;
 +   PVOID UserMem;
 +   UINT Size;
 +   USER_MESSAGE Msg;
 +   DECLARE_RETURN(BOOL);
 +
 +   DPRINT("Enter NtUserPeekMessage\n");
 +   UserEnterExclusive();
 +
 +   if (hWnd == (HWND)-1 || hWnd == (HWND)0x0000FFFF || hWnd == (HWND)0xFFFFFFFF)
 +      hWnd = (HWND)1;
 +
 +   /* Validate input */
 +   if (hWnd && hWnd != (HWND)1)
 +   {
 +      if (!(Window = UserGetWindowObject(hWnd)))
 +      {
 +         RETURN(-1);
 +      }
 +   }
 +   else
 +   {
 +      Window = (PWINDOW_OBJECT)hWnd;
 +   }
 +
 +   if (MsgFilterMax < MsgFilterMin)
 +   {
 +      MsgFilterMin = 0;
 +      MsgFilterMax = 0;
 +   }
 +
 +   Present = co_IntPeekMessage(&Msg, Window, MsgFilterMin, MsgFilterMax, RemoveMsg);
 +   if (Present)
 +   {
 +
 +      Info.Msg = Msg.Msg;
 +      /* See if this message type is present in the table */
 +      MsgMemoryEntry = FindMsgMemory(Info.Msg.message);
 +      if (NULL == MsgMemoryEntry)
 +      {
 +         /* Not present, no copying needed */
 +         Info.LParamSize = 0;
 +      }
 +      else
 +      {
 +         /* Determine required size */
 +         Size = MsgMemorySize(MsgMemoryEntry, Info.Msg.wParam,
 +                              Info.Msg.lParam);
 +         /* Allocate required amount of user-mode memory */
 +         Info.LParamSize = Size;
 +         UserMem = NULL;
 +         Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &UserMem, 0,
 +                                          &Info.LParamSize, MEM_COMMIT, PAGE_READWRITE);
 +         if (! NT_SUCCESS(Status))
 +         {
 +            SetLastNtError(Status);
 +            RETURN( (BOOL) -1);
 +         }
 +         /* Transfer lParam data to user-mode mem */
 +         Status = MmCopyToCaller(UserMem, (PVOID) Info.Msg.lParam, Size);
 +         if (! NT_SUCCESS(Status))
 +         {
 +            ZwFreeVirtualMemory(NtCurrentProcess(), (PVOID *) &UserMem,
 +                                &Info.LParamSize, MEM_RELEASE);
 +            SetLastNtError(Status);
 +            RETURN( (BOOL) -1);
 +         }
 +         Info.Msg.lParam = (LPARAM) UserMem;
 +      }
 +      if (RemoveMsg && Msg.FreeLParam && 0 != Msg.Msg.lParam)
 +      {
 +         ExFreePool((void *) Msg.Msg.lParam);
 +      }
 +      Status = MmCopyToCaller(UnsafeInfo, &Info, sizeof(NTUSERGETMESSAGEINFO));
 +      if (! NT_SUCCESS(Status))
 +      {
 +         SetLastNtError(Status);
 +         RETURN( (BOOL) -1);
 +      }
 +   }
 +
 +   RETURN( Present);
 +
 +CLEANUP:
 +   DPRINT("Leave NtUserPeekMessage, ret=%i\n",_ret_);
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +
 +BOOL
 +APIENTRY
 +NtUserPeekMessageX(
 +   PMSG pMsg,
 +   HWND hWnd,
 +   UINT MsgFilterMin,
 +   UINT MsgFilterMax,
 +   UINT RemoveMsg)
 +{
 +   MSG Msg;
 +   BOOL Ret = FALSE;
 +   DECLARE_RETURN(BOOL);
 +
 +   DPRINT("Enter NtUserPeekMessage\n");
 +   UserEnterExclusive();
 +
 +   if ( RemoveMsg & PM_BADMSGFLAGS )
 +   {
 +      SetLastWin32Error(ERROR_INVALID_FLAGS);
 +      RETURN( Ret);
 +   }
 +
 +   RtlZeroMemory(&Msg, sizeof(MSG));
 +
 +   Ret = co_IntGetPeekMessage(&Msg, hWnd, MsgFilterMin, MsgFilterMax, RemoveMsg, FALSE);
 +
 +   if (Ret)
 +   {
 +      _SEH2_TRY
 +      {
 +         ProbeForWrite(pMsg, sizeof(MSG), 1);
 +         RtlCopyMemory(pMsg, &Msg, sizeof(MSG));
 +      }
 +      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
 +      {
 +         SetLastNtError(_SEH2_GetExceptionCode());
 +         Ret = FALSE;
 +      }
 +      _SEH2_END;
 +   }
 +   RETURN( Ret);
 +
 +CLEANUP:
 +   DPRINT("Leave NtUserPeekMessage, ret=%i\n",_ret_);
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +
 +BOOL
 +APIENTRY
 +NtUserCallMsgFilter(
 +   LPMSG lpmsg,
 +   INT code)
 +{
 +   BOOL BadChk = FALSE, Ret = FALSE;
 +   MSG Msg;
 +   DECLARE_RETURN(BOOL);
 +
 +   DPRINT("Enter NtUserCallMsgFilter\n");
 +   UserEnterExclusive();
 +   if (lpmsg)
 +   {
 +      _SEH2_TRY
 +      {
 +         ProbeForRead((PVOID)lpmsg,
 +                       sizeof(MSG),
 +                                1);
 +         RtlCopyMemory( &Msg,
 +                (PVOID)lpmsg,
 +                 sizeof(MSG));
 +      }
 +      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
 +      {
 +         BadChk = TRUE;
 +      }
 +      _SEH2_END;
 +   }
 +   else
 +     RETURN( FALSE);
 +
 +   if (BadChk) RETURN( FALSE);
 +
 +   if ( ISITHOOKED(WH_SYSMSGFILTER) &&
 +        co_HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)&Msg))
 +   {
 +      Ret = TRUE;
 +   }
 +   else
 +   {
 +      if ( ISITHOOKED(WH_MSGFILTER) )
 +      {
 +         Ret = co_HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)&Msg);
 +      }
 +   }
 +
 +   _SEH2_TRY
 +   {
 +      ProbeForWrite((PVOID)lpmsg,
 +                     sizeof(MSG),
 +                               1);
 +      RtlCopyMemory((PVOID)lpmsg,
 +                            &Msg,
 +                     sizeof(MSG));
 +   }
 +   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
 +   {
 +      BadChk = TRUE;
 +   }
 +   _SEH2_END;
 +   if (BadChk) RETURN( FALSE);
 +   RETURN( Ret)
 +
 +CLEANUP:
 +   DPRINT("Leave NtUserCallMsgFilter. ret=%i\n", _ret_);
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +
 +LRESULT APIENTRY
 +NtUserDispatchMessage(PMSG UnsafeMsgInfo)
 +{
 +  LRESULT Res = 0;
 +  BOOL Hit = FALSE;
 +  MSG SafeMsg;
 +
 +  UserEnterExclusive();
 +  _SEH2_TRY
 +  {
 +    ProbeForRead(UnsafeMsgInfo, sizeof(MSG), 1);
 +    RtlCopyMemory(&SafeMsg, UnsafeMsgInfo, sizeof(MSG));
 +  }
 +  _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
 +  {
 +    SetLastNtError(_SEH2_GetExceptionCode());
 +    Hit = TRUE;
 +  }
 +  _SEH2_END;
 +
 +  if (!Hit) Res = IntDispatchMessage(&SafeMsg);
 +
 +  UserLeave();
 +  return Res;
 +}
 +
 +
 +BOOL APIENTRY
 +NtUserTranslateMessage(LPMSG lpMsg,
 +                       UINT flags)
 +{
 +   NTSTATUS Status;
 +   MSG SafeMsg;
 +   DECLARE_RETURN(BOOL);
 +
 +   DPRINT("Enter NtUserTranslateMessage\n");
 +   UserEnterExclusive();
 +
 +   Status = MmCopyFromCaller(&SafeMsg, lpMsg, sizeof(MSG));
 +   if(!NT_SUCCESS(Status))
 +   {
 +      SetLastNtError(Status);
 +      RETURN( FALSE);
 +   }
 +
 +   RETURN( IntTranslateKbdMessage(&SafeMsg, flags));
 +
 +CLEANUP:
 +   DPRINT("Leave NtUserTranslateMessage: ret=%i\n",_ret_);
 +   UserLeave();
 +   END_CLEANUP;
 +}
 +
 +BOOL APIENTRY
 +NtUserMessageCall(
 +   HWND hWnd,
 +   UINT Msg,
 +   WPARAM wParam,
 +   LPARAM lParam,
 +   ULONG_PTR ResultInfo,
 +   DWORD dwType, // fnID?
 +   BOOL Ansi)
 +{
 +   LRESULT lResult = 0;
 +   BOOL Ret = FALSE;
 +   BOOL BadChk = FALSE;
 +   PWINDOW_OBJECT Window = NULL;
 +   USER_REFERENCE_ENTRY Ref;
 +
 +   UserEnterExclusive();
 +
 +   /* Validate input */
 +   if (hWnd && (hWnd != INVALID_HANDLE_VALUE) && !(Window = UserGetWindowObject(hWnd)))
 +   {
 +      UserLeave();
 +      return FALSE;
 +   }
 +   switch(dwType)
 +   {
 +      case FNID_DEFWINDOWPROC:
 +         UserRefObjectCo(Window, &Ref);
 +         lResult = IntDefWindowProc(Window, Msg, wParam, lParam, Ansi);
 +         Ret = TRUE;
 +         UserDerefObjectCo(Window);
 +      break;
 +      case FNID_SENDNOTIFYMESSAGE:
 +         Ret = UserSendNotifyMessage(hWnd, Msg, wParam, lParam);
 +      break;
 +      case FNID_BROADCASTSYSTEMMESSAGE:
 +      {
 +         BROADCASTPARM parm;
 +         DWORD_PTR RetVal = 0;
 +
 +         if (ResultInfo)
 +         {
 +            _SEH2_TRY
 +            {
 +               ProbeForWrite((PVOID)ResultInfo,
 +                         sizeof(BROADCASTPARM),
 +                                             1);
 +               RtlCopyMemory(&parm, (PVOID)ResultInfo, sizeof(BROADCASTPARM));
 +            }
 +            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
 +            {
 +               BadChk = TRUE;
 +            }
 +            _SEH2_END;
 +            if (BadChk) break;
 +         }
 +         else
 +           break;
 +
 +         if ( parm.recipients & BSM_ALLDESKTOPS ||
 +              parm.recipients == BSM_ALLCOMPONENTS )
 +         {
 +         }
 +         else if (parm.recipients & BSM_APPLICATIONS)
 +         {
 +            if (parm.flags & BSF_QUERY)
 +            {
 +               if (parm.flags & BSF_FORCEIFHUNG || parm.flags & BSF_NOHANG)
 +               {
 +                  co_IntSendMessageTimeout( HWND_BROADCAST,
 +                                            Msg,
 +                                            wParam,
 +                                            lParam,
 +                                            SMTO_ABORTIFHUNG,
 +                                            2000,
 +                                            &RetVal);
 +               }
 +               else if (parm.flags & BSF_NOTIMEOUTIFNOTHUNG)
 +               {
 +                  co_IntSendMessageTimeout( HWND_BROADCAST,
 +                                            Msg,
 +                                            wParam,
 +                                            lParam,
 +                                            SMTO_NOTIMEOUTIFNOTHUNG,
 +                                            2000,
 +                                            &RetVal);
 +               }
 +               else
 +               {
 +                  co_IntSendMessageTimeout( HWND_BROADCAST,
 +                                            Msg,
 +                                            wParam,
 +                                            lParam,
 +                                            SMTO_NORMAL,
 +                                            2000,
 +                                            &RetVal);
 +               }
 +            }
 +            else if (parm.flags & BSF_POSTMESSAGE)
 +            {
 +               Ret = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam);
 +            }
 +            else if ( parm.flags & BSF_SENDNOTIFYMESSAGE)
 +            {
 +               Ret = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam);
 +            }
 +         }
 +      }
 +      break;
 +      case FNID_SENDMESSAGECALLBACK:
 +      break;
 +      // CallNextHook bypass.
 +      case FNID_CALLWNDPROC:
 +      case FNID_CALLWNDPROCRET:
 +      {
 +         PCLIENTINFO ClientInfo = GetWin32ClientInfo();
 +         PHOOK NextObj, Hook = ClientInfo->phkCurrent;
 +
 +         if (!ClientInfo || !Hook) break;
 +
 +         UserReferenceObject(Hook);
 +
 +         if (Hook->Thread && (Hook->Thread != PsGetCurrentThread()))
 +         {
 +            UserDereferenceObject(Hook);
 +            break;
 +         }
 +
 +         NextObj = IntGetNextHook(Hook);
 +         ClientInfo->phkCurrent = NextObj;
 +
 +         if ( Hook->HookId == WH_CALLWNDPROC)
 +         {
 +            CWPSTRUCT CWP;
 +            CWP.hwnd    = hWnd;
 +            CWP.message = Msg;
 +            CWP.wParam  = wParam;
 +            CWP.lParam  = lParam;
 +            DPRINT("WH_CALLWNDPROC: Hook %x NextHook %x\n", Hook, NextObj );
 +
 +            lResult = co_IntCallHookProc( Hook->HookId,
 +                                          HC_ACTION,
 +                                        ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
 +                                         (LPARAM)&CWP,
 +                                          Hook->Proc,
 +                                          Hook->Ansi,
 +                                          &Hook->ModuleName);
 +         }
 +         else
 +         {
 +            CWPRETSTRUCT CWPR;
 +            CWPR.hwnd    = hWnd;
 +            CWPR.message = Msg;
 +            CWPR.wParam  = wParam;
 +            CWPR.lParam  = lParam;
 +            CWPR.lResult = ClientInfo->dwHookData;
 +
 +            lResult = co_IntCallHookProc( Hook->HookId,
 +                                          HC_ACTION,
 +                                        ((ClientInfo->CI_flags & CI_CURTHPRHOOK) ? 1 : 0),
 +                                         (LPARAM)&CWPR,
 +                                          Hook->Proc,
 +                                          Hook->Ansi,
 +                                          &Hook->ModuleName);
 +         }
 +         UserDereferenceObject(Hook);
 +         lResult = (LRESULT) NextObj;
 +      }
 +      break;
 +   }
 +
 +   switch(dwType)
 +   {
 +      case FNID_DEFWINDOWPROC:
 +      case FNID_CALLWNDPROC:
 +      case FNID_CALLWNDPROCRET:
 +         if (ResultInfo)
 +         {
 +            _SEH2_TRY
 +            {
 +                ProbeForWrite((PVOID)ResultInfo, sizeof(LRESULT), 1);
 +                RtlCopyMemory((PVOID)ResultInfo, &lResult, sizeof(LRESULT));
 +            }
 +            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
 +            {
 +                BadChk = TRUE;
 +            }
 +            _SEH2_END;
 +         }
 +         break;
 +      default:
 +         break;
 +   }
 +
 +   UserLeave();
 +
 +   return BadChk ? FALSE : Ret;
 +}
 +
 +#define INFINITE 0xFFFFFFFF
 +#define WAIT_FAILED ((DWORD)0xFFFFFFFF)
 +
 +DWORD
 +APIENTRY
 +NtUserWaitForInputIdle(
 +   IN HANDLE hProcess,
 +   IN DWORD dwMilliseconds,
 +   IN BOOL Unknown2)
 +{
 +  PEPROCESS Process;
 +  PPROCESSINFO W32Process;
 +  NTSTATUS Status;
 +  HANDLE Handles[2];
 +  LARGE_INTEGER Timeout;
 +  ULONGLONG StartTime, Run, Elapsed = 0;
 +
 +  UserEnterExclusive();
 +
 +  Status = ObReferenceObjectByHandle(hProcess,
 +                                     PROCESS_QUERY_INFORMATION,
 +                                     PsProcessType,
 +                                     UserMode,
 +                                     (PVOID*)&Process,
 +                                     NULL);
 +
 +  if (!NT_SUCCESS(Status))
 +  {
 +     UserLeave();
 +     SetLastNtError(Status);
 +     return WAIT_FAILED;
 +  }
 +
 +  W32Process = (PPROCESSINFO)Process->Win32Process;
 +  if (!W32Process)
 +  {
 +      ObDereferenceObject(Process);
 +      UserLeave();
 +      SetLastWin32Error(ERROR_INVALID_PARAMETER);
 +      return WAIT_FAILED;
 +  }
 +
 +  EngCreateEvent((PEVENT *)&W32Process->InputIdleEvent);
 +
 +  Handles[0] = Process;
 +  Handles[1] = W32Process->InputIdleEvent;
 +
 +  if (!Handles[1])
 +  {
 +      ObDereferenceObject(Process);
 +      UserLeave();
 +      return STATUS_SUCCESS;  /* no event to wait on */
 +  }
 +
 +  StartTime = EngGetTickCount();
 +
 +  Run = dwMilliseconds;
 +
 +  DPRINT("WFII: waiting for %p\n", Handles[1] );
 +  do
 +  {
 +     Timeout.QuadPart = Run - Elapsed;
 +     UserLeave();
 +     Status = KeWaitForMultipleObjects( 2,
 +                                        Handles,
 +                                        WaitAny,
 +                                        UserRequest,
 +                                        UserMode,
 +                                        FALSE,
 +                             dwMilliseconds == INFINITE ? NULL : &Timeout,
 +                                        NULL);
 +     UserEnterExclusive();
 +
 +     if (!NT_SUCCESS(Status))
 +     {
 +        SetLastNtError(Status);
 +        Status = WAIT_FAILED;
 +        goto WaitExit;
 +     }
 +
 +     switch (Status)
 +     {
 +        case STATUS_WAIT_0:
 +           Status = WAIT_FAILED;
 +           goto WaitExit;
 +
 +        case STATUS_WAIT_2:
 +        {
 +           USER_MESSAGE Msg;
 +           co_IntPeekMessage( &Msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE );
 +           break;
 +        }
 +
 +        case STATUS_USER_APC:
 +        case STATUS_ALERTED:
 +        case STATUS_TIMEOUT:
 +           DPRINT1("WFII: timeout\n");
 +           Status = STATUS_TIMEOUT;
 +           goto WaitExit;
 +
 +        default:
 +           DPRINT1("WFII: finished\n");
 +           Status = STATUS_SUCCESS;
 +           goto WaitExit;
 +     }
 +
 +     if (dwMilliseconds != INFINITE)
 +     {
 +        Elapsed = EngGetTickCount() - StartTime;
 +
 +        if (Elapsed > Run)
 +           Status = STATUS_TIMEOUT;
 +           break;
 +     }
 +  }
 +  while (1);
 +
 +WaitExit:
 +  if (W32Process->InputIdleEvent)
 +  {
 +     EngFreeMem((PVOID)W32Process->InputIdleEvent);
 +     W32Process->InputIdleEvent = NULL;
 +  }
 +  ObDereferenceObject(Process);
 +  UserLeave();
 +  return Status;
 +}
 +
 +/* EOF */