<directory name="bzip2">
<xi:include href="lib/3rdparty/bzip2/bzip2.rbuild" />
</directory>
++ <directory name="cardlib">
++ <xi:include href="lib/3rdparty/cardlib/cardlib.rbuild" />
++ </directory>
<directory name="expat">
<xi:include href="lib/3rdparty/expat/expat.rbuild" />
</directory>
; 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\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\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\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\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\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\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\network\ftp\ftp.exe 1
++;base\applications\network\ipconfig\ipconfig.exe 1
++;base\applications\network\netstat\netstat.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\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\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
+;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\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\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\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\powercfg\powercfg.cpl 1
+;dll\cpl\sysdm\sysdm.cpl 1
;dll\cpl\telephon\telephon.cpl 1
-dll\cpl\timedate\timedate.cpl 1
+;dll\cpl\timedate\timedate.cpl 1
;dll\cpl\usrmgr\usrmgr.cpl 1
-dll\directx\amstream\amstream.dll 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\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\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\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\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
+;dll\directx\amstream\amstream.dll 1
+;dll\directx\dinput\dinput.dll 1
+;dll\directx\dinput8\dinput8.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\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\nt;dll\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\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\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\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
+;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\bus\isapnp\isapnp.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\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
+;drivers\base\bootvid\bootvid.dll 1
+;drivers\base\beep\beep.sys 2
+;drivers\base\null\null.sys 2
+
+;drivers\bus\isapnp\isapnp.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\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\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\services 5
-media\inf\audio.inf 6
-media\inf\acpi.inf 6
-media\inf\cdrom.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\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\tahoma.ttf 3
+;media\fonts\tahomabd.ttf 3
+
+;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\services 5
+;media\inf\audio.inf 6
+;media\inf\acpi.inf 6
+;media\inf\cdrom.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
CLIENT_ID ClientId;
/* If we don't have a PID, look it up */
- if (dwProcessId == -1U) dwProcessId = (DWORD_PTR)CsrGetProcessId();
- if (dwProcessId == MAXDWORD) dwProcessId = (DWORD)CsrGetProcessId();
++ if (dwProcessId == MAXDWORD) dwProcessId = (DWORD_PTR)CsrGetProcessId();
/* Open a handle to the process */
ClientId.UniqueThread = NULL;
((PCHAR)LinkAddress)[5] & 0xff));
}
- NdisQueryPacketLength(NdisPacket, &PacketLength);
-
- if (Adapter->MTU < PacketLength) {
+ if (Adapter->MTU < Size) {
/* This is NOT a pointer. MSDN explicitly says so. */
NDIS_PER_PACKET_INFO_FROM_PACKET(NdisPacket,
- TcpLargeSendPacketInfo) = (PVOID)((ULONG)Adapter->MTU);
+ TcpLargeSendPacketInfo) = (PVOID)((ULONG_PTR)Adapter->MTU);
}
TcpipAcquireSpinLock( &Adapter->Lock, &OldIrql );
- <?xml version="1.0"?>\r
- <!DOCTYPE group SYSTEM "../../../tools/rbuild/project.dtd">\r
- <group xmlns:xi="http://www.w3.org/2001/XInclude">\r
- <directory name="atapi">\r
- <xi:include href="atapi/atapi.rbuild" />\r
- </directory>\r
- <directory name="pciide">\r
- <xi:include href="pciide/pciide.rbuild" />\r
- </directory>\r
- <directory name="pciidex">\r
- <xi:include href="pciidex/pciidex.rbuild" />\r
- </directory>\r
- <!-- directory name="uniata">\r
- <xi:include href="uniata/uniata.rbuild" />\r
- </directory -->\r
- </group>\r
+ <?xml version="1.0"?>
+ <!DOCTYPE group SYSTEM "../../../tools/rbuild/project.dtd">
+ <group xmlns:xi="http://www.w3.org/2001/XInclude">
+ <directory name="atapi">
+ <xi:include href="atapi/atapi.rbuild" />
+ </directory>
+ <directory name="pciide">
+ <xi:include href="pciide/pciide.rbuild" />
+ </directory>
+ <directory name="pciidex">
+ <xi:include href="pciidex/pciidex.rbuild" />
+ </directory>
- <directory name="uniata">
++ <!-- directory name="uniata">
+ <xi:include href="uniata/uniata.rbuild" />
- </directory>
++ </directory -->
+ </group>
typedef struct
{
+ KSSTREAM_HEADER Header;
SOUND_DEVICE_TYPE DeviceType;
- ULONG DeviceIndex;
+ ULONG_PTR DeviceIndex;
HANDLE hDevice;
ULONG DeviceCount;
Access.SegmentType = I386_INTERRUPT_GATE;
idt = (KIDTENTRY*)((ULONG)KeGetPcr()->IDT + index * sizeof(KIDTENTRY));
- idt->Offset = address & 0xffff;
+ idt->Offset = (USHORT)(address & 0xffff);
idt->Selector = KGDT_R0_CODE;
idt->Access = Access.Value;
- idt->ExtendedOffset = address >> 16;
+ idt->ExtendedOffset = (USHORT)(address >> 16);
+ #endif
+#endif
}
VOID HaliInitBSP(VOID)
- #ifndef _WDMDDK_\r
- #define _WDMDDK_\r
- \r
- //\r
- // Dependencies\r
- //\r
- #define NT_INCLUDED\r
- #include <excpt.h>\r
- #include <ntdef.h>\r
- #include <ntstatus.h>\r
- \r
- #ifndef GUID_DEFINED\r
- #include <guiddef.h>\r
- #endif /* GUID_DEFINED */\r
- \r
- #include "intrin.h"\r
- \r
- #ifdef __cplusplus\r
- extern "C" {\r
- #endif\r
- \r
- #define NTKERNELAPI DECLSPEC_IMPORT\r
- \r
- #ifdef _WIN64\r
- #define PORT_MAXIMUM_MESSAGE_LENGTH 512\r
- #else\r
- #define PORT_MAXIMUM_MESSAGE_LENGTH 256\r
- #endif\r
- \r
- \r
- #if defined(_MSC_VER)\r
- \r
- //\r
- // Indicate if #pragma alloc_text() is supported\r
- //\r
- #if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64)\r
- #define ALLOC_PRAGMA 1\r
- #endif\r
- \r
- //\r
- // Indicate if #pragma data_seg() is supported\r
- //\r
- #if defined(_M_IX86) || defined(_M_AMD64)\r
- #define ALLOC_DATA_PRAGMA 1\r
- #endif\r
- \r
- #endif\r
- \r
- \r
- /* Simple types */\r
- typedef UCHAR KPROCESSOR_MODE;\r
- typedef LONG KPRIORITY;\r
- typedef PVOID PSECURITY_DESCRIPTOR;\r
- typedef ULONG SECURITY_INFORMATION, *PSECURITY_INFORMATION;\r
- \r
- /* Structures not exposed to drivers */\r
- typedef struct _OBJECT_TYPE *POBJECT_TYPE;\r
- typedef struct _HAL_DISPATCH_TABLE *PHAL_DISPATCH_TABLE;\r
- typedef struct _HAL_PRIVATE_DISPATCH_TABLE *PHAL_PRIVATE_DISPATCH_TABLE;\r
- typedef struct _DEVICE_HANDLER_OBJECT *PDEVICE_HANDLER_OBJECT;\r
- typedef struct _BUS_HANDLER *PBUS_HANDLER;\r
- \r
- typedef struct _ADAPTER_OBJECT *PADAPTER_OBJECT; \r
- typedef struct _CALLBACK_OBJECT *PCALLBACK_OBJECT;\r
- typedef struct _ETHREAD *PETHREAD;\r
- typedef struct _EPROCESS *PEPROCESS;\r
- typedef struct _IO_TIMER *PIO_TIMER;\r
- typedef struct _KINTERRUPT *PKINTERRUPT;\r
- typedef struct _KPROCESS *PKPROCESS;\r
- typedef struct _KTHREAD *PKTHREAD, *PRKTHREAD;\r
- \r
- \r
- typedef struct _CONTEXT *PCONTEXT;\r
- \r
- //\r
- // Resource list definitions\r
- //\r
- typedef int CM_RESOURCE_TYPE;\r
- \r
- #define CmResourceTypeNull 0\r
- #define CmResourceTypePort 1\r
- #define CmResourceTypeInterrupt 2\r
- #define CmResourceTypeMemory 3\r
- #define CmResourceTypeDma 4\r
- #define CmResourceTypeDeviceSpecific 5\r
- #define CmResourceTypeBusNumber 6\r
- #define CmResourceTypeNonArbitrated 128\r
- #define CmResourceTypeConfigData 128\r
- #define CmResourceTypeDevicePrivate 129\r
- #define CmResourceTypePcCardConfig 130\r
- #define CmResourceTypeMfCardConfig 131\r
- \r
- typedef enum _INTERFACE_TYPE {\r
- InterfaceTypeUndefined = -1,\r
- Internal,\r
- Isa,\r
- Eisa,\r
- MicroChannel,\r
- TurboChannel,\r
- PCIBus,\r
- VMEBus,\r
- NuBus,\r
- PCMCIABus,\r
- CBus,\r
- MPIBus,\r
- MPSABus,\r
- ProcessorInternal,\r
- InternalPowerBus,\r
- PNPISABus,\r
- PNPBus,\r
- MaximumInterfaceType\r
- } INTERFACE_TYPE, *PINTERFACE_TYPE;\r
- \r
- /* IO_RESOURCE_DESCRIPTOR.Option */\r
- \r
- #define IO_RESOURCE_PREFERRED 0x01\r
- #define IO_RESOURCE_DEFAULT 0x02\r
- #define IO_RESOURCE_ALTERNATIVE 0x08\r
- \r
- typedef struct _IO_RESOURCE_DESCRIPTOR {\r
- UCHAR Option;\r
- UCHAR Type;\r
- UCHAR ShareDisposition;\r
- UCHAR Spare1;\r
- USHORT Flags;\r
- USHORT Spare2;\r
- union {\r
- struct {\r
- ULONG Length;\r
- ULONG Alignment;\r
- PHYSICAL_ADDRESS MinimumAddress;\r
- PHYSICAL_ADDRESS MaximumAddress;\r
- } Port;\r
- struct {\r
- ULONG Length;\r
- ULONG Alignment;\r
- PHYSICAL_ADDRESS MinimumAddress;\r
- PHYSICAL_ADDRESS MaximumAddress;\r
- } Memory;\r
- struct {\r
- ULONG MinimumVector;\r
- ULONG MaximumVector;\r
- } Interrupt;\r
- struct {\r
- ULONG MinimumChannel;\r
- ULONG MaximumChannel;\r
- } Dma;\r
- struct {\r
- ULONG Length;\r
- ULONG Alignment;\r
- PHYSICAL_ADDRESS MinimumAddress;\r
- PHYSICAL_ADDRESS MaximumAddress;\r
- } Generic;\r
- struct {\r
- ULONG Data[3];\r
- } DevicePrivate;\r
- struct {\r
- ULONG Length;\r
- ULONG MinBusNumber;\r
- ULONG MaxBusNumber;\r
- ULONG Reserved;\r
- } BusNumber;\r
- struct {\r
- ULONG Priority;\r
- ULONG Reserved1;\r
- ULONG Reserved2;\r
- } ConfigData;\r
- } u;\r
- } IO_RESOURCE_DESCRIPTOR, *PIO_RESOURCE_DESCRIPTOR;\r
- \r
- typedef struct _IO_RESOURCE_LIST {\r
- USHORT Version;\r
- USHORT Revision;\r
- ULONG Count;\r
- IO_RESOURCE_DESCRIPTOR Descriptors[1];\r
- } IO_RESOURCE_LIST, *PIO_RESOURCE_LIST;\r
- \r
- typedef struct _IO_RESOURCE_REQUIREMENTS_LIST {\r
- ULONG ListSize;\r
- INTERFACE_TYPE InterfaceType;\r
- ULONG BusNumber;\r
- ULONG SlotNumber;\r
- ULONG Reserved[3];\r
- ULONG AlternativeLists;\r
- IO_RESOURCE_LIST List[1];\r
- } IO_RESOURCE_REQUIREMENTS_LIST, *PIO_RESOURCE_REQUIREMENTS_LIST;\r
- \r
- //\r
- // Global debug flag\r
- //\r
- extern ULONG NtGlobalFlag;\r
- \r
- \r
- #include <pshpack4.h>\r
- typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR {\r
- UCHAR Type;\r
- UCHAR ShareDisposition;\r
- USHORT Flags;\r
- union {\r
- struct {\r
- PHYSICAL_ADDRESS Start;\r
- ULONG Length;\r
- } Generic;\r
- struct {\r
- PHYSICAL_ADDRESS Start;\r
- ULONG Length;\r
- } Port;\r
- struct {\r
- ULONG Level;\r
- ULONG Vector;\r
- KAFFINITY Affinity;\r
- } Interrupt;\r
- #if (NTDDI_VERSION >= NTDDI_LONGHORN)\r
- struct {\r
- union {\r
- struct {\r
- USHORT Reserved;\r
- USHORT MessageCount;\r
- ULONG Vector;\r
- KAFFINITY Affinity;\r
- } Raw;\r
- struct {\r
- ULONG Level;\r
- ULONG Vector;\r
- KAFFINITY Affinity;\r
- } Translated;\r
- };\r
- } MessageInterrupt;\r
- #endif\r
- struct {\r
- PHYSICAL_ADDRESS Start;\r
- ULONG Length;\r
- } Memory;\r
- struct {\r
- ULONG Channel;\r
- ULONG Port;\r
- ULONG Reserved1;\r
- } Dma;\r
- struct {\r
- ULONG Data[3];\r
- } DevicePrivate;\r
- struct {\r
- ULONG Start;\r
- ULONG Length;\r
- ULONG Reserved;\r
- } BusNumber;\r
- struct {\r
- ULONG DataSize;\r
- ULONG Reserved1;\r
- ULONG Reserved2;\r
- } DeviceSpecificData;\r
- #if (NTDDI_VERSION >= NTDDI_LONGHORN)\r
- struct {\r
- PHYSICAL_ADDRESS Start;\r
- ULONG Length40;\r
- } Memory40;\r
- struct {\r
- PHYSICAL_ADDRESS Start;\r
- ULONG Length48;\r
- } Memory48;\r
- struct {\r
- PHYSICAL_ADDRESS Start;\r
- ULONG Length64;\r
- } Memory64;\r
- #endif\r
- } u;\r
- } CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;\r
- #include <poppack.h>\r
- \r
- //\r
- // Section map options\r
- //\r
- typedef enum _SECTION_INHERIT {\r
- ViewShare = 1,\r
- ViewUnmap = 2\r
- } SECTION_INHERIT;\r
- \r
- //\r
- // Section access rights\r
- //\r
- #define SECTION_QUERY 0x0001\r
- #define SECTION_MAP_WRITE 0x0002\r
- #define SECTION_MAP_READ 0x0004\r
- #define SECTION_MAP_EXECUTE 0x0008\r
- #define SECTION_EXTEND_SIZE 0x0010\r
- #define SECTION_MAP_EXECUTE_EXPLICIT 0x0020\r
- \r
- #define SECTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SECTION_QUERY|\\r
- SECTION_MAP_WRITE | \\r
- SECTION_MAP_READ | \\r
- SECTION_MAP_EXECUTE | \\r
- SECTION_EXTEND_SIZE)\r
- \r
- #define SESSION_QUERY_ACCESS 0x0001\r
- #define SESSION_MODIFY_ACCESS 0x0002\r
- \r
- #define SESSION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \\r
- SESSION_QUERY_ACCESS | \\r
- SESSION_MODIFY_ACCESS)\r
- \r
- \r
- \r
- #define SEGMENT_ALL_ACCESS SECTION_ALL_ACCESS\r
- \r
- #define PAGE_NOACCESS 0x01\r
- #define PAGE_READONLY 0x02\r
- #define PAGE_READWRITE 0x04\r
- #define PAGE_WRITECOPY 0x08\r
- #define PAGE_EXECUTE 0x10\r
- #define PAGE_EXECUTE_READ 0x20\r
- #define PAGE_EXECUTE_READWRITE 0x40\r
- #define PAGE_EXECUTE_WRITECOPY 0x80\r
- #define PAGE_GUARD 0x100\r
- #define PAGE_NOCACHE 0x200\r
- #define PAGE_WRITECOMBINE 0x400\r
- \r
- #define MEM_COMMIT 0x1000\r
- #define MEM_RESERVE 0x2000\r
- #define MEM_DECOMMIT 0x4000\r
- #define MEM_RELEASE 0x8000\r
- #define MEM_FREE 0x10000\r
- #define MEM_PRIVATE 0x20000\r
- #define MEM_MAPPED 0x40000\r
- #define MEM_RESET 0x80000\r
- #define MEM_TOP_DOWN 0x100000\r
- #define MEM_LARGE_PAGES 0x20000000\r
- #define MEM_4MB_PAGES 0x80000000\r
- \r
- #define SEC_RESERVE 0x4000000 \r
- #define SEC_LARGE_PAGES 0x80000000\r
- \r
- #define PROCESS_DUP_HANDLE (0x0040)\r
- \r
- #if (NTDDI_VERSION >= NTDDI_VISTA)\r
- #define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \\r
- 0xFFFF)\r
- #else\r
- #define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \\r
- 0xFFF)\r
- #endif\r
- \r
- \r
- \r
- //\r
- // Processor features\r
- //\r
- #define PF_FLOATING_POINT_PRECISION_ERRATA 0 \r
- #define PF_FLOATING_POINT_EMULATED 1 \r
- #define PF_COMPARE_EXCHANGE_DOUBLE 2 \r
- #define PF_MMX_INSTRUCTIONS_AVAILABLE 3 \r
- #define PF_PPC_MOVEMEM_64BIT_OK 4 \r
- #define PF_ALPHA_BYTE_INSTRUCTIONS 5 \r
- #define PF_XMMI_INSTRUCTIONS_AVAILABLE 6 \r
- #define PF_3DNOW_INSTRUCTIONS_AVAILABLE 7 \r
- #define PF_RDTSC_INSTRUCTION_AVAILABLE 8 \r
- #define PF_PAE_ENABLED 9 \r
- #define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10 \r
- #define PF_SSE_DAZ_MODE_AVAILABLE 11 \r
- #define PF_NX_ENABLED 12 \r
- #define PF_SSE3_INSTRUCTIONS_AVAILABLE 13 \r
- #define PF_COMPARE_EXCHANGE128 14 \r
- #define PF_COMPARE64_EXCHANGE128 15 \r
- #define PF_CHANNELS_ENABLED 16 \r
- \r
- \r
- \r
- //\r
- // Intrinsics (note: taken from our winnt.h)\r
- // FIXME: 64-bit\r
- //\r
- #if defined(__GNUC__)\r
- \r
- static __inline__ BOOLEAN\r
- InterlockedBitTestAndSet(IN LONG volatile *Base,\r
- IN LONG Bit)\r
- {\r
- #if defined(_M_IX86)\r
- LONG OldBit;\r
- __asm__ __volatile__("lock "\r
- "btsl %2,%1\n\t"\r
- "sbbl %0,%0\n\t"\r
- :"=r" (OldBit),"+m" (*Base)\r
- :"Ir" (Bit)\r
- : "memory");\r
- return OldBit;\r
- #else\r
- return (_InterlockedOr(Base, 1 << Bit) >> Bit) & 1;\r
- #endif\r
- }\r
- \r
- static __inline__ BOOLEAN\r
- InterlockedBitTestAndReset(IN LONG volatile *Base,\r
- IN LONG Bit)\r
- {\r
- #if defined(_M_IX86)\r
- LONG OldBit;\r
- __asm__ __volatile__("lock "\r
- "btrl %2,%1\n\t"\r
- "sbbl %0,%0\n\t"\r
- :"=r" (OldBit),"+m" (*Base)\r
- :"Ir" (Bit)\r
- : "memory");\r
- return OldBit;\r
- #else\r
- return (_InterlockedAnd(Base, ~(1 << Bit)) >> Bit) & 1;\r
- #endif\r
- }\r
- \r
- #endif\r
- \r
- #define BitScanForward _BitScanForward\r
- #define BitScanReverse _BitScanReverse\r
- \r
- #define BitTest _bittest\r
- #define BitTestAndComplement _bittestandcomplement\r
- #define BitTestAndSet _bittestandset\r
- #define BitTestAndReset _bittestandreset\r
- #define InterlockedBitTestAndSet _interlockedbittestandset\r
- #define InterlockedBitTestAndReset _interlockedbittestandreset\r
- \r
- \r
- /** INTERLOCKED FUNCTIONS *****************************************************/\r
- \r
- #if !defined(__INTERLOCKED_DECLARED)\r
- #define __INTERLOCKED_DECLARED\r
- \r
- #if defined (_X86_)\r
- #if defined(NO_INTERLOCKED_INTRINSICS)\r
- NTKERNELAPI\r
- LONG\r
- FASTCALL\r
- InterlockedIncrement(\r
- IN OUT LONG volatile *Addend);\r
- \r
- NTKERNELAPI\r
- LONG\r
- FASTCALL\r
- InterlockedDecrement(\r
- IN OUT LONG volatile *Addend);\r
- \r
- NTKERNELAPI\r
- LONG\r
- FASTCALL\r
- InterlockedCompareExchange(\r
- IN OUT LONG volatile *Destination,\r
- IN LONG Exchange,\r
- IN LONG Comparand);\r
- \r
- NTKERNELAPI\r
- LONG\r
- FASTCALL\r
- InterlockedExchange(\r
- IN OUT LONG volatile *Destination,\r
- IN LONG Value);\r
- \r
- NTKERNELAPI\r
- LONG\r
- FASTCALL\r
- InterlockedExchangeAdd(\r
- IN OUT LONG volatile *Addend,\r
- IN LONG Value);\r
- \r
- #else // !defined(NO_INTERLOCKED_INTRINSICS)\r
- \r
- #define InterlockedExchange _InterlockedExchange\r
- #define InterlockedIncrement _InterlockedIncrement\r
- #define InterlockedDecrement _InterlockedDecrement\r
- #define InterlockedExchangeAdd _InterlockedExchangeAdd\r
- #define InterlockedCompareExchange _InterlockedCompareExchange\r
- #define InterlockedOr _InterlockedOr\r
- #define InterlockedAnd _InterlockedAnd\r
- #define InterlockedXor _InterlockedXor\r
- \r
- #endif // !defined(NO_INTERLOCKED_INTRINSICS)\r
- \r
- #endif // defined (_X86_)\r
- \r
- #if !defined (_WIN64)\r
- /*\r
- * PVOID\r
- * InterlockedExchangePointer(\r
- * IN OUT PVOID volatile *Target,\r
- * IN PVOID Value)\r
- */\r
- #define InterlockedExchangePointer(Target, Value) \\r
- ((PVOID) InterlockedExchange((PLONG) Target, (LONG) Value))\r
- \r
- /*\r
- * PVOID\r
- * InterlockedCompareExchangePointer(\r
- * IN OUT PVOID *Destination,\r
- * IN PVOID Exchange,\r
- * IN PVOID Comparand)\r
- */\r
- #define InterlockedCompareExchangePointer(Destination, Exchange, Comparand) \\r
- ((PVOID) InterlockedCompareExchange((PLONG) Destination, (LONG) Exchange, (LONG) Comparand))\r
- \r
- #define InterlockedExchangeAddSizeT(a, b) InterlockedExchangeAdd((LONG *)a, b)\r
- #define InterlockedIncrementSizeT(a) InterlockedIncrement((LONG *)a)\r
- #define InterlockedDecrementSizeT(a) InterlockedDecrement((LONG *)a)\r
- \r
- #endif // !defined (_WIN64)\r
- \r
- #if defined (_M_AMD64)\r
- \r
- #define InterlockedExchangeAddSizeT(a, b) InterlockedExchangeAdd64((LONGLONG *)a, (LONGLONG)b)\r
- #define InterlockedIncrementSizeT(a) InterlockedIncrement64((LONGLONG *)a)\r
- #define InterlockedDecrementSizeT(a) InterlockedDecrement64((LONGLONG *)a)\r
- #define InterlockedAnd _InterlockedAnd\r
- #define InterlockedOr _InterlockedOr\r
- #define InterlockedXor _InterlockedXor\r
- #define InterlockedIncrement _InterlockedIncrement\r
- #define InterlockedDecrement _InterlockedDecrement\r
- #define InterlockedAdd _InterlockedAdd\r
- #define InterlockedExchange _InterlockedExchange\r
- #define InterlockedExchangeAdd _InterlockedExchangeAdd\r
- #define InterlockedCompareExchange _InterlockedCompareExchange\r
- #define InterlockedAnd64 _InterlockedAnd64\r
- #define InterlockedOr64 _InterlockedOr64\r
- #define InterlockedXor64 _InterlockedXor64\r
- #define InterlockedIncrement64 _InterlockedIncrement64\r
- #define InterlockedDecrement64 _InterlockedDecrement64\r
- #define InterlockedAdd64 _InterlockedAdd64\r
- #define InterlockedExchange64 _InterlockedExchange64\r
- #define InterlockedExchangeAdd64 _InterlockedExchangeAdd64\r
- #define InterlockedCompareExchange64 _InterlockedCompareExchange64\r
- #define InterlockedCompareExchangePointer _InterlockedCompareExchangePointer\r
- #define InterlockedExchangePointer _InterlockedExchangePointer\r
- #define InterlockedBitTestAndSet64 _interlockedbittestandset64\r
- #define InterlockedBitTestAndReset64 _interlockedbittestandreset64\r
- \r
- #endif // _M_AMD64\r
- \r
- #if defined(_M_AMD64) && !defined(RC_INVOKED) && !defined(MIDL_PASS)\r
- //#if !defined(_X86AMD64_) // FIXME: what's _X86AMD64_ used for?\r
- FORCEINLINE\r
- LONG64\r
- InterlockedAdd64(\r
- IN OUT LONG64 volatile *Addend,\r
- IN LONG64 Value)\r
- {\r
- return InterlockedExchangeAdd64(Addend, Value) + Value;\r
- }\r
- //#endif\r
- #define BitScanForward _BitScanForward\r
- #define BitScanReverse _BitScanReverse\r
- #endif\r
- \r
- #ifdef _M_AMD64\r
- #define InterlockedBitTestAndSet64 _interlockedbittestandset64\r
- #define InterlockedBitTestAndReset64 _interlockedbittestandreset64\r
- #endif\r
- \r
- #endif /* !__INTERLOCKED_DECLARED */\r
- \r
- #if defined(_M_IX86)\r
- #define YieldProcessor _mm_pause\r
- #elif defined (_M_AMD64)\r
- #define YieldProcessor _mm_pause\r
- #elif defined(_M_PPC)\r
- #define YieldProcessor() __asm__ __volatile__("nop");\r
- #elif defined(_M_MIPS)\r
- #define YieldProcessor() __asm__ __volatile__("nop");\r
- #elif defined(_M_ARM)\r
- #define YieldProcessor()\r
- #else\r
- #error Unknown architecture\r
- #endif\r
- \r
- \r
- \r
- //\r
- // Slist Header\r
- //\r
- #ifndef _SLIST_HEADER_\r
- #define _SLIST_HEADER_\r
- \r
- #define SLIST_ENTRY SINGLE_LIST_ENTRY\r
- #define _SLIST_ENTRY _SINGLE_LIST_ENTRY\r
- #define PSLIST_ENTRY PSINGLE_LIST_ENTRY\r
- \r
- #if defined(_WIN64)\r
- typedef union DECLSPEC_ALIGN(16) _SLIST_HEADER {\r
- struct {\r
- ULONGLONG Alignment;\r
- ULONGLONG Region;\r
- } DUMMYSTRUCTNAME;\r
- struct {\r
- ULONGLONG Depth:16;\r
- ULONGLONG Sequence:9;\r
- ULONGLONG NextEntry:39;\r
- ULONGLONG HeaderType:1;\r
- ULONGLONG Init:1;\r
- ULONGLONG Reserved:59;\r
- ULONGLONG Region:3;\r
- } Header8;\r
- struct {\r
- ULONGLONG Depth:16;\r
- ULONGLONG Sequence:48;\r
- ULONGLONG HeaderType:1;\r
- ULONGLONG Init:1;\r
- ULONGLONG Reserved:2;\r
- ULONGLONG NextEntry:60;\r
- } Header16;\r
- } SLIST_HEADER, *PSLIST_HEADER;\r
- #else\r
- typedef union _SLIST_HEADER {\r
- ULONGLONG Alignment;\r
- struct {\r
- SLIST_ENTRY Next;\r
- USHORT Depth;\r
- USHORT Sequence;\r
- } DUMMYSTRUCTNAME;\r
- } SLIST_HEADER, *PSLIST_HEADER;\r
- #endif\r
- \r
- #endif /* _SLIST_HEADER_ */\r
- \r
- \r
- \r
- //\r
- // Power States/Levels\r
- //\r
- typedef enum _SYSTEM_POWER_STATE {\r
- PowerSystemUnspecified,\r
- PowerSystemWorking,\r
- PowerSystemSleeping1,\r
- PowerSystemSleeping2,\r
- PowerSystemSleeping3,\r
- PowerSystemHibernate,\r
- PowerSystemShutdown,\r
- PowerSystemMaximum\r
- } SYSTEM_POWER_STATE, *PSYSTEM_POWER_STATE;\r
- \r
- #define POWER_SYSTEM_MAXIMUM PowerSystemMaximum\r
- \r
- typedef enum _POWER_INFORMATION_LEVEL {\r
- SystemPowerPolicyAc,\r
- SystemPowerPolicyDc,\r
- VerifySystemPolicyAc,\r
- VerifySystemPolicyDc,\r
- SystemPowerCapabilities,\r
- SystemBatteryState,\r
- SystemPowerStateHandler,\r
- ProcessorStateHandler,\r
- SystemPowerPolicyCurrent,\r
- AdministratorPowerPolicy,\r
- SystemReserveHiberFile,\r
- ProcessorInformation,\r
- SystemPowerInformation,\r
- ProcessorStateHandler2,\r
- LastWakeTime,\r
- LastSleepTime,\r
- SystemExecutionState,\r
- SystemPowerStateNotifyHandler,\r
- ProcessorPowerPolicyAc,\r
- ProcessorPowerPolicyDc,\r
- VerifyProcessorPowerPolicyAc,\r
- VerifyProcessorPowerPolicyDc,\r
- ProcessorPowerPolicyCurrent\r
- } POWER_INFORMATION_LEVEL;\r
- \r
- typedef enum {\r
- PowerActionNone,\r
- PowerActionReserved,\r
- PowerActionSleep,\r
- PowerActionHibernate,\r
- PowerActionShutdown,\r
- PowerActionShutdownReset,\r
- PowerActionShutdownOff,\r
- PowerActionWarmEject\r
- } POWER_ACTION, *PPOWER_ACTION;\r
- \r
- typedef enum _DEVICE_POWER_STATE {\r
- PowerDeviceUnspecified,\r
- PowerDeviceD0,\r
- PowerDeviceD1,\r
- PowerDeviceD2,\r
- PowerDeviceD3,\r
- PowerDeviceMaximum\r
- } DEVICE_POWER_STATE, *PDEVICE_POWER_STATE;\r
- \r
- #define ES_SYSTEM_REQUIRED 0x00000001\r
- #define ES_DISPLAY_REQUIRED 0x00000002\r
- #define ES_USER_PRESENT 0x00000004\r
- #define ES_CONTINUOUS 0x80000000\r
- \r
- typedef ULONG EXECUTION_STATE;\r
- \r
- typedef enum {\r
- LT_DONT_CARE,\r
- LT_LOWEST_LATENCY\r
- } LATENCY_TIME;\r
- \r
- \r
- \r
- //\r
- // Access/Security Stuff\r
- //\r
- typedef ULONG ACCESS_MASK, *PACCESS_MASK;\r
- typedef PVOID PACCESS_TOKEN;\r
- \r
- #define DELETE 0x00010000L\r
- #define READ_CONTROL 0x00020000L\r
- #define WRITE_DAC 0x00040000L\r
- #define WRITE_OWNER 0x00080000L\r
- #define SYNCHRONIZE 0x00100000L\r
- #define STANDARD_RIGHTS_REQUIRED 0x000F0000L\r
- #define STANDARD_RIGHTS_READ READ_CONTROL\r
- #define STANDARD_RIGHTS_WRITE READ_CONTROL\r
- #define STANDARD_RIGHTS_EXECUTE READ_CONTROL\r
- #define STANDARD_RIGHTS_ALL 0x001F0000L\r
- #define SPECIFIC_RIGHTS_ALL 0x0000FFFFL\r
- #define ACCESS_SYSTEM_SECURITY 0x01000000L\r
- #define MAXIMUM_ALLOWED 0x02000000L\r
- #define GENERIC_READ 0x80000000L\r
- #define GENERIC_WRITE 0x40000000L\r
- #define GENERIC_EXECUTE 0x20000000L\r
- #define GENERIC_ALL 0x10000000L\r
- \r
- typedef struct _GENERIC_MAPPING {\r
- ACCESS_MASK GenericRead;\r
- ACCESS_MASK GenericWrite;\r
- ACCESS_MASK GenericExecute;\r
- ACCESS_MASK GenericAll;\r
- } GENERIC_MAPPING, *PGENERIC_MAPPING;\r
- \r
- #define ACL_REVISION 2\r
- #define ACL_REVISION_DS 4\r
- \r
- #define ACL_REVISION1 1\r
- #define ACL_REVISION2 2\r
- #define ACL_REVISION3 3\r
- #define ACL_REVISION4 4\r
- #define MIN_ACL_REVISION ACL_REVISION2\r
- #define MAX_ACL_REVISION ACL_REVISION4\r
- \r
- typedef struct _ACL {\r
- UCHAR AclRevision;\r
- UCHAR Sbz1;\r
- USHORT AclSize;\r
- USHORT AceCount;\r
- USHORT Sbz2;\r
- } ACL, *PACL;\r
- \r
- \r
- \r
- //\r
- // Current security descriptor revision value\r
- //\r
- #define SECURITY_DESCRIPTOR_REVISION (1)\r
- #define SECURITY_DESCRIPTOR_REVISION1 (1)\r
- \r
- //\r
- // Privilege attributes\r
- //\r
- #define SE_PRIVILEGE_ENABLED_BY_DEFAULT (0x00000001L)\r
- #define SE_PRIVILEGE_ENABLED (0x00000002L)\r
- #define SE_PRIVILEGE_REMOVED (0X00000004L)\r
- #define SE_PRIVILEGE_USED_FOR_ACCESS (0x80000000L)\r
- \r
- #define SE_PRIVILEGE_VALID_ATTRIBUTES (SE_PRIVILEGE_ENABLED_BY_DEFAULT | \\r
- SE_PRIVILEGE_ENABLED | \\r
- SE_PRIVILEGE_REMOVED | \\r
- SE_PRIVILEGE_USED_FOR_ACCESS)\r
- \r
- #include <pshpack4.h>\r
- typedef struct _LUID_AND_ATTRIBUTES {\r
- LUID Luid;\r
- ULONG Attributes;\r
- } LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;\r
- #include <poppack.h>\r
- typedef LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY];\r
- typedef LUID_AND_ATTRIBUTES_ARRAY *PLUID_AND_ATTRIBUTES_ARRAY;\r
- \r
- \r
- \r
- //\r
- // Privilege sets\r
- //\r
- #define PRIVILEGE_SET_ALL_NECESSARY (1)\r
- \r
- typedef struct _PRIVILEGE_SET {\r
- ULONG PrivilegeCount;\r
- ULONG Control;\r
- LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];\r
- } PRIVILEGE_SET,*PPRIVILEGE_SET;\r
- \r
- typedef enum _SECURITY_IMPERSONATION_LEVEL {\r
- SecurityAnonymous,\r
- SecurityIdentification,\r
- SecurityImpersonation,\r
- SecurityDelegation\r
- } SECURITY_IMPERSONATION_LEVEL, * PSECURITY_IMPERSONATION_LEVEL;\r
- \r
- #define SECURITY_MAX_IMPERSONATION_LEVEL SecurityDelegation\r
- #define SECURITY_MIN_IMPERSONATION_LEVEL SecurityAnonymous\r
- #define DEFAULT_IMPERSONATION_LEVEL SecurityImpersonation\r
- #define VALID_IMPERSONATION_LEVEL(Level) (((Level) >= SECURITY_MIN_IMPERSONATION_LEVEL) && ((Level) <= SECURITY_MAX_IMPERSONATION_LEVEL))\r
- \r
- #define SECURITY_DYNAMIC_TRACKING (TRUE)\r
- #define SECURITY_STATIC_TRACKING (FALSE)\r
- \r
- typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, *PSECURITY_CONTEXT_TRACKING_MODE;\r
- \r
- typedef struct _SECURITY_QUALITY_OF_SERVICE {\r
- ULONG Length;\r
- SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;\r
- SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;\r
- BOOLEAN EffectiveOnly;\r
- } SECURITY_QUALITY_OF_SERVICE, *PSECURITY_QUALITY_OF_SERVICE;\r
- \r
- typedef struct _SE_IMPERSONATION_STATE {\r
- PACCESS_TOKEN Token;\r
- BOOLEAN CopyOnOpen;\r
- BOOLEAN EffectiveOnly;\r
- SECURITY_IMPERSONATION_LEVEL Level;\r
- } SE_IMPERSONATION_STATE, *PSE_IMPERSONATION_STATE;\r
- \r
- #define OWNER_SECURITY_INFORMATION (0x00000001L)\r
- #define GROUP_SECURITY_INFORMATION (0x00000002L)\r
- #define DACL_SECURITY_INFORMATION (0x00000004L)\r
- #define SACL_SECURITY_INFORMATION (0x00000008L)\r
- #define LABEL_SECURITY_INFORMATION (0x00000010L)\r
- \r
- #define PROTECTED_DACL_SECURITY_INFORMATION (0x80000000L)\r
- #define PROTECTED_SACL_SECURITY_INFORMATION (0x40000000L)\r
- #define UNPROTECTED_DACL_SECURITY_INFORMATION (0x20000000L)\r
- #define UNPROTECTED_SACL_SECURITY_INFORMATION (0x10000000L)\r
- \r
- \r
- \r
- //\r
- // Registry Access Rights\r
- //\r
- #define KEY_QUERY_VALUE (0x0001)\r
- #define KEY_SET_VALUE (0x0002)\r
- #define KEY_CREATE_SUB_KEY (0x0004)\r
- #define KEY_ENUMERATE_SUB_KEYS (0x0008)\r
- #define KEY_NOTIFY (0x0010)\r
- #define KEY_CREATE_LINK (0x0020)\r
- #define KEY_WOW64_32KEY (0x0200)\r
- #define KEY_WOW64_64KEY (0x0100)\r
- #define KEY_WOW64_RES (0x0300)\r
- \r
- #define KEY_READ ((STANDARD_RIGHTS_READ |\\r
- KEY_QUERY_VALUE |\\r
- KEY_ENUMERATE_SUB_KEYS |\\r
- KEY_NOTIFY) \\r
- & \\r
- (~SYNCHRONIZE))\r
- \r
- #define KEY_WRITE ((STANDARD_RIGHTS_WRITE |\\r
- KEY_SET_VALUE |\\r
- KEY_CREATE_SUB_KEY) \\r
- & \\r
- (~SYNCHRONIZE))\r
- \r
- #define KEY_EXECUTE ((KEY_READ) \\r
- & \\r
- (~SYNCHRONIZE))\r
- \r
- #define KEY_ALL_ACCESS ((STANDARD_RIGHTS_ALL |\\r
- KEY_QUERY_VALUE |\\r
- KEY_SET_VALUE |\\r
- KEY_CREATE_SUB_KEY |\\r
- KEY_ENUMERATE_SUB_KEYS |\\r
- KEY_NOTIFY |\\r
- KEY_CREATE_LINK) \\r
- & \\r
- (~SYNCHRONIZE))\r
- \r
- //\r
- // Registry Open/Create Options\r
- //\r
- #define REG_OPTION_RESERVED (0x00000000L)\r
- #define REG_OPTION_NON_VOLATILE (0x00000000L)\r
- #define REG_OPTION_VOLATILE (0x00000001L)\r
- #define REG_OPTION_CREATE_LINK (0x00000002L)\r
- #define REG_OPTION_BACKUP_RESTORE (0x00000004L)\r
- #define REG_OPTION_OPEN_LINK (0x00000008L)\r
- \r
- #define REG_LEGAL_OPTION \\r
- (REG_OPTION_RESERVED |\\r
- REG_OPTION_NON_VOLATILE |\\r
- REG_OPTION_VOLATILE |\\r
- REG_OPTION_CREATE_LINK |\\r
- REG_OPTION_BACKUP_RESTORE |\\r
- REG_OPTION_OPEN_LINK)\r
- \r
- //\r
- // Key creation/open disposition\r
- //\r
- #define REG_CREATED_NEW_KEY (0x00000001L)\r
- #define REG_OPENED_EXISTING_KEY (0x00000002L)\r
- \r
- //\r
- // Key restore & hive load flags\r
- //\r
- #define REG_WHOLE_HIVE_VOLATILE (0x00000001L)\r
- #define REG_REFRESH_HIVE (0x00000002L)\r
- #define REG_NO_LAZY_FLUSH (0x00000004L)\r
- #define REG_FORCE_RESTORE (0x00000008L)\r
- #define REG_APP_HIVE (0x00000010L)\r
- #define REG_PROCESS_PRIVATE (0x00000020L)\r
- #define REG_START_JOURNAL (0x00000040L)\r
- #define REG_HIVE_EXACT_FILE_GROWTH (0x00000080L)\r
- #define REG_HIVE_NO_RM (0x00000100L)\r
- #define REG_HIVE_SINGLE_LOG (0x00000200L)\r
- \r
- //\r
- // Unload Flags\r
- //\r
- #define REG_FORCE_UNLOAD 1\r
- \r
- //\r
- // Notify Filter Values\r
- //\r
- #define REG_NOTIFY_CHANGE_NAME (0x00000001L)\r
- #define REG_NOTIFY_CHANGE_ATTRIBUTES (0x00000002L)\r
- #define REG_NOTIFY_CHANGE_LAST_SET (0x00000004L)\r
- #define REG_NOTIFY_CHANGE_SECURITY (0x00000008L)\r
- \r
- #define REG_LEGAL_CHANGE_FILTER \\r
- (REG_NOTIFY_CHANGE_NAME |\\r
- REG_NOTIFY_CHANGE_ATTRIBUTES |\\r
- REG_NOTIFY_CHANGE_LAST_SET |\\r
- REG_NOTIFY_CHANGE_SECURITY)\r
- \r
- \r
- \r
- //\r
- // Thread Access Rights\r
- //\r
- #define THREAD_TERMINATE (0x0001) \r
- #define THREAD_SUSPEND_RESUME (0x0002) \r
- #define THREAD_ALERT (0x0004)\r
- #define THREAD_GET_CONTEXT (0x0008) \r
- #define THREAD_SET_CONTEXT (0x0010) \r
- #define THREAD_SET_INFORMATION (0x0020) \r
- #define THREAD_SET_LIMITED_INFORMATION (0x0400) \r
- #define THREAD_QUERY_LIMITED_INFORMATION (0x0800) \r
- #if (NTDDI_VERSION >= NTDDI_VISTA)\r
- #define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \\r
- 0xFFFF)\r
- #else\r
- #define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \\r
- 0x3FF)\r
- #endif\r
- \r
- //\r
- // Service Start Types\r
- //\r
- #define SERVICE_BOOT_START 0x00000000\r
- #define SERVICE_SYSTEM_START 0x00000001\r
- #define SERVICE_AUTO_START 0x00000002\r
- #define SERVICE_DEMAND_START 0x00000003\r
- #define SERVICE_DISABLED 0x00000004\r
- \r
- //\r
- // Exception Records\r
- //\r
- #define EXCEPTION_NONCONTINUABLE 1\r
- #define EXCEPTION_MAXIMUM_PARAMETERS 15\r
- \r
- typedef struct _EXCEPTION_RECORD {\r
- NTSTATUS ExceptionCode;\r
- ULONG ExceptionFlags;\r
- struct _EXCEPTION_RECORD *ExceptionRecord;\r
- PVOID ExceptionAddress;\r
- ULONG NumberParameters;\r
- ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];\r
- } EXCEPTION_RECORD, *PEXCEPTION_RECORD;\r
- \r
- typedef struct _EXCEPTION_RECORD32 {\r
- NTSTATUS ExceptionCode;\r
- ULONG ExceptionFlags;\r
- ULONG ExceptionRecord;\r
- ULONG ExceptionAddress;\r
- ULONG NumberParameters;\r
- ULONG ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];\r
- } EXCEPTION_RECORD32, *PEXCEPTION_RECORD32;\r
- \r
- typedef struct _EXCEPTION_RECORD64 {\r
- NTSTATUS ExceptionCode;\r
- ULONG ExceptionFlags;\r
- ULONG64 ExceptionRecord;\r
- ULONG64 ExceptionAddress;\r
- ULONG NumberParameters;\r
- ULONG __unusedAlignment;\r
- ULONG64 ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];\r
- } EXCEPTION_RECORD64, *PEXCEPTION_RECORD64;\r
- \r
- typedef struct _EXCEPTION_POINTERS {\r
- PEXCEPTION_RECORD ExceptionRecord;\r
- PCONTEXT ContextRecord;\r
- } EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;\r
- \r
- \r
- \r
- //\r
- // Process Qoutas\r
- //\r
- typedef struct _QUOTA_LIMITS {\r
- SIZE_T PagedPoolLimit;\r
- SIZE_T NonPagedPoolLimit;\r
- SIZE_T MinimumWorkingSetSize;\r
- SIZE_T MaximumWorkingSetSize;\r
- SIZE_T PagefileLimit;\r
- LARGE_INTEGER TimeLimit;\r
- } QUOTA_LIMITS, *PQUOTA_LIMITS;\r
- \r
- #define QUOTA_LIMITS_HARDWS_MIN_ENABLE 0x00000001\r
- #define QUOTA_LIMITS_HARDWS_MIN_DISABLE 0x00000002\r
- #define QUOTA_LIMITS_HARDWS_MAX_ENABLE 0x00000004\r
- #define QUOTA_LIMITS_HARDWS_MAX_DISABLE 0x00000008\r
- #define QUOTA_LIMITS_USE_DEFAULT_LIMITS 0x00000010\r
- \r
- \r
- /******************************************************************************\r
- * WINBASE Functions *\r
- ******************************************************************************/\r
- #if !defined(_WINBASE_)\r
- \r
- #if defined(_WIN64)\r
- \r
- #define InterlockedPopEntrySList(Head) \\r
- ExpInterlockedPopEntrySList(Head)\r
- \r
- #define InterlockedPushEntrySList(Head, Entry) \\r
- ExpInterlockedPushEntrySList(Head, Entry)\r
- \r
- #define InterlockedFlushSList(Head) \\r
- ExpInterlockedFlushSList(Head)\r
- \r
- #define QueryDepthSList(Head) \\r
- ExQueryDepthSList(Head)\r
- \r
- #else // !defined(_WIN64)\r
- \r
- NTKERNELAPI\r
- PSLIST_ENTRY\r
- FASTCALL\r
- InterlockedPopEntrySList(\r
- IN PSLIST_HEADER ListHead);\r
- \r
- NTKERNELAPI\r
- PSLIST_ENTRY\r
- FASTCALL\r
- InterlockedPushEntrySList(\r
- IN PSLIST_HEADER ListHead,\r
- IN PSLIST_ENTRY ListEntry);\r
- \r
- #define InterlockedFlushSList(ListHead) \\r
- ExInterlockedFlushSList(ListHead)\r
- \r
- #define QueryDepthSList(Head) \\r
- ExQueryDepthSList(Head)\r
- \r
- #endif // !defined(_WIN64)\r
- \r
- #endif // !defined(_WINBASE_)\r
- \r
- \r
- /******************************************************************************\r
- * Kernel Types *\r
- ******************************************************************************/\r
- \r
- typedef struct _DISPATCHER_HEADER\r
- {\r
- union\r
- {\r
- struct\r
- {\r
- UCHAR Type;\r
- union\r
- {\r
- UCHAR Absolute;\r
- UCHAR NpxIrql;\r
- };\r
- union\r
- {\r
- UCHAR Size;\r
- UCHAR Hand;\r
- };\r
- union\r
- {\r
- UCHAR Inserted;\r
- BOOLEAN DebugActive;\r
- };\r
- };\r
- volatile LONG Lock;\r
- };\r
- LONG SignalState;\r
- LIST_ENTRY WaitListHead;\r
- } DISPATCHER_HEADER, *PDISPATCHER_HEADER;\r
- \r
- typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK;\r
- \r
- typedef struct _KEVENT {\r
- DISPATCHER_HEADER Header;\r
- } KEVENT, *PKEVENT, *RESTRICTED_POINTER PRKEVENT;\r
- \r
- typedef struct _KSEMAPHORE {\r
- DISPATCHER_HEADER Header;\r
- LONG Limit;\r
- } KSEMAPHORE, *PKSEMAPHORE, *RESTRICTED_POINTER PRKSEMAPHORE;\r
- \r
- /******************************************************************************\r
- * RTL Types *\r
- ******************************************************************************/\r
- \r
- #define RTL_REGISTRY_ABSOLUTE 0\r
- #define RTL_REGISTRY_SERVICES 1\r
- #define RTL_REGISTRY_CONTROL 2\r
- #define RTL_REGISTRY_WINDOWS_NT 3\r
- #define RTL_REGISTRY_DEVICEMAP 4\r
- #define RTL_REGISTRY_USER 5\r
- #define RTL_REGISTRY_MAXIMUM 6\r
- #define RTL_REGISTRY_HANDLE 0x40000000\r
- #define RTL_REGISTRY_OPTIONAL 0x80000000\r
- \r
- /* RTL_QUERY_REGISTRY_TABLE.Flags */\r
- #define RTL_QUERY_REGISTRY_SUBKEY 0x00000001\r
- #define RTL_QUERY_REGISTRY_TOPKEY 0x00000002\r
- #define RTL_QUERY_REGISTRY_REQUIRED 0x00000004\r
- #define RTL_QUERY_REGISTRY_NOVALUE 0x00000008\r
- #define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010\r
- #define RTL_QUERY_REGISTRY_DIRECT 0x00000020\r
- #define RTL_QUERY_REGISTRY_DELETE 0x00000040\r
- \r
- typedef struct _RTL_BITMAP {\r
- ULONG SizeOfBitMap;\r
- PULONG Buffer;\r
- } RTL_BITMAP, *PRTL_BITMAP;\r
- \r
- typedef struct _RTL_BITMAP_RUN {\r
- ULONG StartingIndex;\r
- ULONG NumberOfBits;\r
- } RTL_BITMAP_RUN, *PRTL_BITMAP_RUN;\r
- \r
- typedef NTSTATUS\r
- (DDKAPI *PRTL_QUERY_REGISTRY_ROUTINE)(\r
- IN PWSTR ValueName,\r
- IN ULONG ValueType,\r
- IN PVOID ValueData,\r
- IN ULONG ValueLength,\r
- IN PVOID Context,\r
- IN PVOID EntryContext);\r
- \r
- typedef struct _RTL_QUERY_REGISTRY_TABLE {\r
- PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;\r
- ULONG Flags;\r
- PCWSTR Name;\r
- PVOID EntryContext;\r
- ULONG DefaultType;\r
- PVOID DefaultData;\r
- ULONG DefaultLength;\r
- } RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;\r
- \r
- typedef struct _TIME_FIELDS {\r
- CSHORT Year;\r
- CSHORT Month;\r
- CSHORT Day;\r
- CSHORT Hour;\r
- CSHORT Minute;\r
- CSHORT Second;\r
- CSHORT Milliseconds;\r
- CSHORT Weekday;\r
- } TIME_FIELDS, *PTIME_FIELDS;\r
- \r
- \r
- /******************************************************************************\r
- * RTL Functions *\r
- ******************************************************************************/\r
- \r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlAssert(\r
- IN PVOID FailedAssertion,\r
- IN PVOID FileName,\r
- IN ULONG LineNumber,\r
- IN PCHAR Message);\r
- \r
- /* VOID\r
- * RtlCopyMemory(\r
- * IN VOID UNALIGNED *Destination,\r
- * IN CONST VOID UNALIGNED *Source,\r
- * IN SIZE_T Length)\r
- */\r
- #define RtlCopyMemory(Destination, Source, Length) \\r
- memcpy(Destination, Source, Length)\r
- \r
- #define RtlCopyBytes RtlCopyMemory\r
- \r
- #if defined(_M_AMD64)\r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlCopyMemoryNonTemporal(\r
- VOID UNALIGNED *Destination,\r
- CONST VOID UNALIGNED *Source,\r
- SIZE_T Length);\r
- #else\r
- #define RtlCopyMemoryNonTemporal RtlCopyMemory\r
- #endif\r
- \r
- /* BOOLEAN\r
- * RtlEqualLuid(\r
- * IN PLUID Luid1,\r
- * IN PLUID Luid2)\r
- */\r
- #define RtlEqualLuid(Luid1, Luid2) \\r
- (((Luid1)->LowPart == (Luid2)->LowPart) && ((Luid1)->HighPart == (Luid2)->HighPart))\r
- \r
- /* ULONG\r
- * RtlEqualMemory(\r
- * IN VOID UNALIGNED *Destination,\r
- * IN CONST VOID UNALIGNED *Source,\r
- * IN SIZE_T Length)\r
- */\r
- #define RtlEqualMemory(Destination, Source, Length) \\r
- (!memcmp(Destination, Source, Length))\r
- \r
- /* VOID\r
- * RtlFillMemory(\r
- * IN VOID UNALIGNED *Destination,\r
- * IN SIZE_T Length,\r
- * IN UCHAR Fill)\r
- */\r
- #define RtlFillMemory(Destination, Length, Fill) \\r
- memset(Destination, Fill, Length)\r
- \r
- #define RtlFillBytes RtlFillMemory\r
- \r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlFreeUnicodeString(\r
- IN PUNICODE_STRING UnicodeString);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlGUIDFromString(\r
- IN PUNICODE_STRING GuidString,\r
- OUT GUID *Guid);\r
- \r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlInitUnicodeString(\r
- IN OUT PUNICODE_STRING DestinationString,\r
- IN PCWSTR SourceString);\r
- \r
- /* VOID\r
- * RtlMoveMemory(\r
- * IN VOID UNALIGNED *Destination,\r
- * IN CONST VOID UNALIGNED *Source,\r
- * IN SIZE_T Length)\r
- */\r
- #define RtlMoveMemory(Destination, Source, Length) \\r
- memmove(Destination, Source, Length)\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlStringFromGUID(\r
- IN REFGUID Guid,\r
- OUT PUNICODE_STRING GuidString);\r
- \r
- /* VOID\r
- * RtlZeroMemory(\r
- * IN VOID UNALIGNED *Destination,\r
- * IN SIZE_T Length)\r
- */\r
- #define RtlZeroMemory(Destination, Length) \\r
- memset(Destination, 0, Length)\r
- \r
- #define RtlZeroBytes RtlZeroMemory\r
- \r
- \r
- #if (NTDDI_VERSION >= NTDDI_WIN2K)\r
- NTSYSAPI\r
- BOOLEAN\r
- NTAPI\r
- RtlAreBitsClear(\r
- IN PRTL_BITMAP BitMapHeader,\r
- IN ULONG StartingIndex,\r
- IN ULONG Length);\r
- \r
- NTSYSAPI\r
- BOOLEAN\r
- NTAPI\r
- RtlAreBitsSet(\r
- IN PRTL_BITMAP BitMapHeader,\r
- IN ULONG StartingIndex,\r
- IN ULONG Length);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlAnsiStringToUnicodeString(\r
- IN OUT PUNICODE_STRING DestinationString,\r
- IN PANSI_STRING SourceString,\r
- IN BOOLEAN AllocateDestinationString);\r
- \r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlxAnsiStringToUnicodeSize(\r
- IN PCANSI_STRING AnsiString);\r
- \r
- #define RtlAnsiStringToUnicodeSize(String) ( \\r
- NLS_MB_CODE_PAGE_TAG ? \\r
- RtlxAnsiStringToUnicodeSize(String) : \\r
- ((String)->Length + sizeof(ANSI_NULL)) * sizeof(WCHAR) \\r
- )\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlAppendUnicodeStringToString(\r
- IN OUT PUNICODE_STRING Destination,\r
- IN PCUNICODE_STRING Source);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlAppendUnicodeToString(\r
- IN OUT PUNICODE_STRING Destination,\r
- IN PCWSTR Source);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlCheckRegistryKey(\r
- IN ULONG RelativeTo,\r
- IN PWSTR Path);\r
- \r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlClearAllBits(\r
- IN PRTL_BITMAP BitMapHeader);\r
- \r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlClearBits(\r
- IN PRTL_BITMAP BitMapHeader,\r
- IN ULONG StartingIndex,\r
- IN ULONG NumberToClear);\r
- \r
- NTSYSAPI\r
- SIZE_T\r
- NTAPI\r
- RtlCompareMemory(\r
- IN CONST VOID *Source1,\r
- IN CONST VOID *Source2,\r
- IN SIZE_T Length);\r
- \r
- NTSYSAPI\r
- LONG\r
- NTAPI\r
- RtlCompareUnicodeString(\r
- IN PCUNICODE_STRING String1,\r
- IN PCUNICODE_STRING String2,\r
- IN BOOLEAN CaseInSensitive);\r
- \r
- NTSYSAPI\r
- LONG\r
- NTAPI\r
- RtlCompareUnicodeStrings(\r
- IN PCWCH String1,\r
- IN SIZE_T String1Length,\r
- IN PCWCH String2,\r
- IN SIZE_T String2Length,\r
- IN BOOLEAN CaseInSensitive);\r
- \r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlCopyUnicodeString(\r
- IN OUT PUNICODE_STRING DestinationString,\r
- IN PCUNICODE_STRING SourceString);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlCreateRegistryKey(\r
- IN ULONG RelativeTo,\r
- IN PWSTR Path);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlCreateSecurityDescriptor(\r
- IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,\r
- IN ULONG Revision);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlDeleteRegistryValue(\r
- IN ULONG RelativeTo,\r
- IN PCWSTR Path,\r
- IN PCWSTR ValueName);\r
- \r
- NTSYSAPI\r
- BOOLEAN\r
- NTAPI\r
- RtlEqualUnicodeString(\r
- IN CONST UNICODE_STRING *String1,\r
- IN CONST UNICODE_STRING *String2,\r
- IN BOOLEAN CaseInSensitive);\r
- \r
- #if !defined(_AMD64_) && !defined(_IA64_)\r
- NTSYSAPI\r
- LARGE_INTEGER\r
- NTAPI\r
- RtlExtendedIntegerMultiply(\r
- IN LARGE_INTEGER Multiplicand,\r
- IN LONG Multiplier);\r
- \r
- NTSYSAPI\r
- LARGE_INTEGER\r
- NTAPI\r
- RtlExtendedLargeIntegerDivide(\r
- IN LARGE_INTEGER Dividend,\r
- IN ULONG Divisor,\r
- IN OUT PULONG Remainder);\r
- #endif\r
- \r
- #if defined(_X86_) || defined(_IA64_)\r
- NTSYSAPI\r
- LARGE_INTEGER\r
- NTAPI\r
- RtlExtendedMagicDivide(\r
- IN LARGE_INTEGER Dividend,\r
- IN LARGE_INTEGER MagicDivisor,\r
- IN CCHAR ShiftCount);\r
- #endif\r
- \r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlFreeAnsiString(\r
- IN PANSI_STRING AnsiString);\r
- \r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlFindClearBits(\r
- IN PRTL_BITMAP BitMapHeader,\r
- IN ULONG NumberToFind,\r
- IN ULONG HintIndex);\r
- \r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlFindClearBitsAndSet(\r
- IN PRTL_BITMAP BitMapHeader,\r
- IN ULONG NumberToFind,\r
- IN ULONG HintIndex);\r
- \r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlFindFirstRunClear(\r
- IN PRTL_BITMAP BitMapHeader,\r
- OUT PULONG StartingIndex);\r
- \r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlFindClearRuns(\r
- IN PRTL_BITMAP BitMapHeader,\r
- OUT PRTL_BITMAP_RUN RunArray,\r
- IN ULONG SizeOfRunArray,\r
- IN BOOLEAN LocateLongestRuns);\r
- \r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlFindLastBackwardRunClear(\r
- IN PRTL_BITMAP BitMapHeader,\r
- IN ULONG FromIndex,\r
- OUT PULONG StartingRunIndex);\r
- \r
- NTSYSAPI\r
- CCHAR\r
- NTAPI\r
- RtlFindLeastSignificantBit(\r
- IN ULONGLONG Set);\r
- \r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlFindLongestRunClear(\r
- IN PRTL_BITMAP BitMapHeader,\r
- OUT PULONG StartingIndex);\r
- \r
- NTSYSAPI\r
- CCHAR\r
- NTAPI\r
- RtlFindMostSignificantBit(\r
- IN ULONGLONG Set);\r
- \r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlFindNextForwardRunClear(\r
- IN PRTL_BITMAP BitMapHeader,\r
- IN ULONG FromIndex,\r
- OUT PULONG StartingRunIndex);\r
- \r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlFindSetBits(\r
- IN PRTL_BITMAP BitMapHeader,\r
- IN ULONG NumberToFind,\r
- IN ULONG HintIndex);\r
- \r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlFindSetBitsAndClear(\r
- IN PRTL_BITMAP BitMapHeader,\r
- IN ULONG NumberToFind,\r
- IN ULONG HintIndex);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlHashUnicodeString(\r
- IN CONST UNICODE_STRING *String,\r
- IN BOOLEAN CaseInSensitive,\r
- IN ULONG HashAlgorithm,\r
- OUT PULONG HashValue);\r
- \r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlInitAnsiString(\r
- IN OUT PANSI_STRING DestinationString,\r
- IN PCSZ SourceString);\r
- \r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlInitializeBitMap(\r
- IN PRTL_BITMAP BitMapHeader,\r
- IN PULONG BitMapBuffer,\r
- IN ULONG SizeOfBitMap);\r
- \r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlInitString(\r
- IN OUT PSTRING DestinationString,\r
- IN PCSZ SourceString);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlIntegerToUnicodeString(\r
- IN ULONG Value,\r
- IN ULONG Base OPTIONAL,\r
- IN OUT PUNICODE_STRING String);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlInt64ToUnicodeString(\r
- IN ULONGLONG Value,\r
- IN ULONG Base OPTIONAL,\r
- IN OUT PUNICODE_STRING String);\r
- \r
- #ifdef _WIN64\r
- #define RtlIntPtrToUnicodeString(Value, Base, String) \\r
- RtlInt64ToUnicodeString(Value, Base, String)\r
- #else\r
- #define RtlIntPtrToUnicodeString(Value, Base, String) \\r
- RtlIntegerToUnicodeString(Value, Base, String)\r
- #endif\r
- \r
- /* BOOLEAN\r
- * RtlIsZeroLuid(\r
- * IN PLUID L1);\r
- */\r
- #define RtlIsZeroLuid(_L1) \\r
- ((BOOLEAN) ((!(_L1)->LowPart) && (!(_L1)->HighPart)))\r
- \r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlLengthSecurityDescriptor(\r
- IN PSECURITY_DESCRIPTOR SecurityDescriptor);\r
- \r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlNumberOfClearBits(\r
- IN PRTL_BITMAP BitMapHeader);\r
- \r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlNumberOfSetBits(\r
- IN PRTL_BITMAP BitMapHeader);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlQueryRegistryValues(\r
- IN ULONG RelativeTo,\r
- IN PCWSTR Path,\r
- IN PRTL_QUERY_REGISTRY_TABLE QueryTable,\r
- IN PVOID Context,\r
- IN PVOID Environment OPTIONAL);\r
- \r
- #define LONG_SIZE (sizeof(LONG))\r
- #define LONG_MASK (LONG_SIZE - 1)\r
- \r
- /* VOID\r
- * RtlRetrieveUlong(\r
- * PULONG DestinationAddress,\r
- * PULONG SourceAddress);\r
- */\r
- #if defined(_AMD64_)\r
- #define RtlRetrieveUlong(DestAddress,SrcAddress) \\r
- *(ULONG UNALIGNED *)(DestAddress) = *(PULONG)(SrcAddress)\r
- #else\r
- #define RtlRetrieveUlong(DestAddress,SrcAddress) \\r
- if ((ULONG_PTR)(SrcAddress) & LONG_MASK) \\r
- { \\r
- ((PUCHAR)(DestAddress))[0]=((PUCHAR)(SrcAddress))[0]; \\r
- ((PUCHAR)(DestAddress))[1]=((PUCHAR)(SrcAddress))[1]; \\r
- ((PUCHAR)(DestAddress))[2]=((PUCHAR)(SrcAddress))[2]; \\r
- ((PUCHAR)(DestAddress))[3]=((PUCHAR)(SrcAddress))[3]; \\r
- } \\r
- else \\r
- { \\r
- *((PULONG)(DestAddress))=*((PULONG)(SrcAddress)); \\r
- }\r
- #endif\r
- \r
- /* VOID\r
- * RtlRetrieveUshort(\r
- * PUSHORT DestinationAddress,\r
- * PUSHORT SourceAddress);\r
- */\r
- #if defined(_AMD64_)\r
- #define RtlRetrieveUshort(DestAddress,SrcAddress) \\r
- *(USHORT UNALIGNED *)(DestAddress) = *(USHORT)(SrcAddress)\r
- #else\r
- #define RtlRetrieveUshort(DestAddress,SrcAddress) \\r
- if ((ULONG_PTR)(SrcAddress) & LONG_MASK) \\r
- { \\r
- ((PUCHAR)(DestAddress))[0]=((PUCHAR)(SrcAddress))[0]; \\r
- ((PUCHAR)(DestAddress))[1]=((PUCHAR)(SrcAddress))[1]; \\r
- } \\r
- else \\r
- { \\r
- *((PUSHORT)(DestAddress))=*((PUSHORT)(SrcAddress)); \\r
- }\r
- #endif\r
- \r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlSetAllBits(\r
- IN PRTL_BITMAP BitMapHeader);\r
- \r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlSetBits(\r
- IN PRTL_BITMAP BitMapHeader,\r
- IN ULONG StartingIndex,\r
- IN ULONG NumberToSet);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlSetDaclSecurityDescriptor(\r
- IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,\r
- IN BOOLEAN DaclPresent,\r
- IN PACL Dacl OPTIONAL,\r
- IN BOOLEAN DaclDefaulted OPTIONAL);\r
- \r
- /* VOID\r
- * RtlStoreUlong(\r
- * IN PULONG Address,\r
- * IN ULONG Value);\r
- */\r
- #if defined(_AMD64_)\r
- #define RtlStoreUlong(Address,Value) \\r
- *(ULONG UNALIGNED *)(Address) = (Value)\r
- #else\r
- #define RtlStoreUlong(Address,Value) \\r
- if ((ULONG_PTR)(Address) & LONG_MASK) { \\r
- ((PUCHAR) (Address))[LONG_LEAST_SIGNIFICANT_BIT] = (UCHAR)(FIRSTBYTE(Value)); \\r
- ((PUCHAR) (Address))[LONG_3RD_MOST_SIGNIFICANT_BIT] = (UCHAR)(SECONDBYTE(Value)); \\r
- ((PUCHAR) (Address))[LONG_2ND_MOST_SIGNIFICANT_BIT] = (UCHAR)(THIRDBYTE(Value)); \\r
- ((PUCHAR) (Address))[LONG_MOST_SIGNIFICANT_BIT] = (UCHAR)(FOURTHBYTE(Value)); \\r
- } \\r
- else { \\r
- *((PULONG)(Address)) = (ULONG) (Value); \\r
- }\r
- #endif\r
- \r
- /* VOID\r
- * RtlStoreUlonglong(\r
- * IN OUT PULONGLONG Address,\r
- * ULONGLONG Value);\r
- */\r
- #if defined(_AMD64_)\r
- #define RtlStoreUlonglong(Address,Value) \\r
- *(ULONGLONG UNALIGNED *)(Address) = (Value)\r
- #else\r
- #define RtlStoreUlonglong(Address,Value) \\r
- if ((ULONG_PTR)(Address) & LONGLONG_MASK) { \\r
- RtlStoreUlong((ULONG_PTR)(Address), \\r
- (ULONGLONG)(Value) & 0xFFFFFFFF); \\r
- RtlStoreUlong((ULONG_PTR)(Address)+sizeof(ULONG), \\r
- (ULONGLONG)(Value) >> 32); \\r
- } else { \\r
- *((PULONGLONG)(Address)) = (ULONGLONG)(Value); \\r
- }\r
- #endif\r
- \r
- /* VOID\r
- * RtlStoreUlongPtr(\r
- * IN OUT PULONG_PTR Address,\r
- * IN ULONG_PTR Value);\r
- */\r
- #ifdef _WIN64\r
- #define RtlStoreUlongPtr(Address,Value) \\r
- RtlStoreUlonglong(Address,Value)\r
- #else\r
- #define RtlStoreUlongPtr(Address,Value) \\r
- RtlStoreUlong(Address,Value)\r
- #endif\r
- \r
- /* VOID\r
- * RtlStoreUshort(\r
- * IN PUSHORT Address,\r
- * IN USHORT Value);\r
- */\r
- #if defined(_AMD64_)\r
- #define RtlStoreUshort(Address,Value) \\r
- *(USHORT UNALIGNED *)(Address) = (Value)\r
- #else\r
- #define RtlStoreUshort(Address,Value) \\r
- if ((ULONG_PTR)(Address) & SHORT_MASK) { \\r
- ((PUCHAR) (Address))[SHORT_LEAST_SIGNIFICANT_BIT] = (UCHAR)(FIRSTBYTE(Value)); \\r
- ((PUCHAR) (Address))[SHORT_MOST_SIGNIFICANT_BIT ] = (UCHAR)(SECONDBYTE(Value)); \\r
- } \\r
- else { \\r
- *((PUSHORT) (Address)) = (USHORT)Value; \\r
- }\r
- #endif\r
- \r
- NTSYSAPI\r
- BOOLEAN\r
- NTAPI\r
- RtlTimeFieldsToTime(\r
- IN PTIME_FIELDS TimeFields,\r
- IN PLARGE_INTEGER Time);\r
- \r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlTimeToTimeFields(\r
- IN PLARGE_INTEGER Time,\r
- IN PTIME_FIELDS TimeFields);\r
- \r
- NTSYSAPI\r
- ULONG\r
- FASTCALL\r
- RtlUlongByteSwap(\r
- IN ULONG Source);\r
- \r
- NTSYSAPI\r
- ULONGLONG\r
- FASTCALL\r
- RtlUlonglongByteSwap(\r
- IN ULONGLONG Source);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlUnicodeStringToAnsiString(\r
- IN OUT PANSI_STRING DestinationString,\r
- IN PCUNICODE_STRING SourceString,\r
- IN BOOLEAN AllocateDestinationString);\r
- \r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlxUnicodeStringToAnsiSize(\r
- IN PCUNICODE_STRING UnicodeString);\r
- \r
- #define RtlUnicodeStringToAnsiSize(String) ( \\r
- NLS_MB_CODE_PAGE_TAG ? \\r
- RtlxUnicodeStringToAnsiSize(String) : \\r
- ((String)->Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR) \\r
- )\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlUnicodeStringToInteger(\r
- IN PCUNICODE_STRING String,\r
- IN ULONG Base OPTIONAL,\r
- OUT PULONG Value);\r
- \r
- NTSYSAPI\r
- WCHAR\r
- NTAPI\r
- RtlUpcaseUnicodeChar(\r
- IN WCHAR SourceCharacter);\r
- \r
- NTSYSAPI\r
- USHORT\r
- FASTCALL\r
- RtlUshortByteSwap(\r
- IN USHORT Source);\r
- \r
- NTSYSAPI\r
- BOOLEAN\r
- NTAPI\r
- RtlValidRelativeSecurityDescriptor(\r
- IN PSECURITY_DESCRIPTOR SecurityDescriptorInput,\r
- IN ULONG SecurityDescriptorLength,\r
- IN SECURITY_INFORMATION RequiredInformation);\r
- \r
- NTSYSAPI\r
- BOOLEAN\r
- NTAPI\r
- RtlValidSecurityDescriptor(\r
- IN PSECURITY_DESCRIPTOR SecurityDescriptor);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlWriteRegistryValue(\r
- IN ULONG RelativeTo,\r
- IN PCWSTR Path,\r
- IN PCWSTR ValueName,\r
- IN ULONG ValueType,\r
- IN PVOID ValueData,\r
- IN ULONG ValueLength);\r
- \r
- #endif // (NTDDI_VERSION >= NTDDI_WIN2K)\r
- \r
- #if (NTDDI_VERSION >= NTDDI_WIN2KSP3)\r
- NTSYSAPI\r
- VOID\r
- FASTCALL\r
- RtlPrefetchMemoryNonTemporal(\r
- IN PVOID Source,\r
- IN SIZE_T Length);\r
- #endif\r
- \r
- #if (NTDDI_VERSION >= NTDDI_WINXP)\r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlClearBit(\r
- PRTL_BITMAP BitMapHeader,\r
- ULONG BitNumber);\r
- \r
- NTSYSAPI\r
- WCHAR\r
- NTAPI\r
- RtlDowncaseUnicodeChar(\r
- IN WCHAR SourceCharacter);\r
- \r
- NTSYSAPI\r
- VOID\r
- NTAPI\r
- RtlSetBit(\r
- PRTL_BITMAP BitMapHeader,\r
- ULONG BitNumber);\r
- \r
- NTSYSAPI\r
- BOOLEAN\r
- NTAPI\r
- RtlTestBit(\r
- IN PRTL_BITMAP BitMapHeader,\r
- IN ULONG BitNumber);\r
- \r
- #endif // (NTDDI_VERSION >= NTDDI_WINXP)\r
- \r
- #if (NTDDI_VERSION >= NTDDI_VISTA)\r
- NTSYSAPI\r
- ULONG\r
- NTAPI\r
- RtlNumberOfSetBitsUlongPtr(\r
- IN ULONG_PTR Target);\r
- \r
- NTSYSAPI\r
- ULONGLONG\r
- NTAPI\r
- RtlIoDecodeMemIoResource (\r
- IN PIO_RESOURCE_DESCRIPTOR Descriptor,\r
- OUT PULONGLONG Alignment OPTIONAL,\r
- OUT PULONGLONG MinimumAddress OPTIONAL,\r
- OUT PULONGLONG MaximumAddress OPTIONAL);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlIoEncodeMemIoResource(\r
- IN PIO_RESOURCE_DESCRIPTOR Descriptor,\r
- IN UCHAR Type,\r
- IN ULONGLONG Length,\r
- IN ULONGLONG Alignment,\r
- IN ULONGLONG MinimumAddress,\r
- IN ULONGLONG MaximumAddress);\r
- \r
- NTSYSAPI\r
- ULONGLONG\r
- NTAPI\r
- RtlCmDecodeMemIoResource(\r
- IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,\r
- OUT PULONGLONG Start OPTIONAL);\r
- \r
- NTSYSAPI\r
- NTSTATUS\r
- NTAPI\r
- RtlFindClosestEncodableLength(\r
- IN ULONGLONG SourceLength,\r
- OUT PULONGLONG TargetLength);\r
- \r
- #endif\r
- \r
- #if !defined(MIDL_PASS)\r
- /* inline funftions */\r
- //DECLSPEC_DEPRECATED_DDK_WINXP\r
- static __inline\r
- LARGE_INTEGER\r
- NTAPI_INLINE\r
- RtlConvertLongToLargeInteger(LONG SignedInteger)\r
- {\r
- LARGE_INTEGER ret;\r
- ret.QuadPart = SignedInteger;\r
- return ret;\r
- }\r
- \r
- //DECLSPEC_DEPRECATED_DDK_WINXP\r
- static __inline\r
- LARGE_INTEGER\r
- NTAPI_INLINE\r
- RtlConvertUlongToLargeInteger(\r
- ULONG UnsignedInteger)\r
- {\r
- LARGE_INTEGER ret;\r
- ret.QuadPart = UnsignedInteger;\r
- return ret;\r
- }\r
- \r
- //DECLSPEC_DEPRECATED_DDK\r
- static __inline\r
- ULONG\r
- NTAPI_INLINE\r
- RtlEnlargedUnsignedDivide(\r
- IN ULARGE_INTEGER Dividend,\r
- IN ULONG Divisor,\r
- IN OUT PULONG Remainder)\r
- {\r
- if (Remainder)\r
- *Remainder = (ULONG)(Dividend.QuadPart % Divisor);\r
- return (ULONG)(Dividend.QuadPart / Divisor);\r
- }\r
- \r
- //DECLSPEC_DEPRECATED_DDK\r
- static __inline\r
- LARGE_INTEGER\r
- NTAPI_INLINE\r
- RtlEnlargedUnsignedMultiply(\r
- IN ULONG Multiplicand,\r
- IN ULONG Multiplier)\r
- {\r
- LARGE_INTEGER ret;\r
- ret.QuadPart = (ULONGLONG)Multiplicand * (ULONGLONG)Multiplier;\r
- return ret;\r
- }\r
- \r
- //DECLSPEC_DEPRECATED_DDK\r
- static __inline\r
- LARGE_INTEGER\r
- NTAPI_INLINE\r
- RtlEnlargedIntegerMultiply(\r
- IN LONG Multiplicand,\r
- IN LONG Multiplier)\r
- {\r
- LARGE_INTEGER ret;\r
- ret.QuadPart = (LONGLONG)Multiplicand * (ULONGLONG)Multiplier;\r
- return ret;\r
- }\r
- \r
- FORCEINLINE\r
- VOID\r
- RtlInitEmptyAnsiString(OUT PANSI_STRING AnsiString,\r
- IN PCHAR Buffer,\r
- IN USHORT BufferSize)\r
- {\r
- AnsiString->Length = 0;\r
- AnsiString->MaximumLength = BufferSize;\r
- AnsiString->Buffer = Buffer;\r
- }\r
- \r
- FORCEINLINE\r
- VOID\r
- RtlInitEmptyUnicodeString(\r
- OUT PUNICODE_STRING UnicodeString,\r
- IN PWSTR Buffer,\r
- IN USHORT BufferSize)\r
- {\r
- UnicodeString->Length = 0;\r
- UnicodeString->MaximumLength = BufferSize;\r
- UnicodeString->Buffer = Buffer;\r
- }\r
- \r
- #if defined(_AMD64_) || defined(_IA64_)\r
- static __inline\r
- LARGE_INTEGER\r
- NTAPI_INLINE\r
- RtlExtendedIntegerMultiply(\r
- LARGE_INTEGER Multiplicand,\r
- LONG Multiplier)\r
- {\r
- LARGE_INTEGER ret;\r
- ret.QuadPart = Multiplicand.QuadPart * Multiplier;\r
- return ret;\r
- }\r
- \r
- static __inline\r
- LARGE_INTEGER\r
- NTAPI_INLINE\r
- RtlExtendedLargeIntegerDivide(\r
- LARGE_INTEGER Dividend,\r
- ULONG Divisor,\r
- PULONG Remainder)\r
- {\r
- LARGE_INTEGER ret;\r
- ret.QuadPart = (ULONG64)Dividend.QuadPart / Divisor;\r
- if (Remainder)\r
- *Remainder = (ULONG)(Dividend.QuadPart % Divisor);\r
- return ret;\r
- }\r
- #endif\r
- \r
- #if defined(_AMD64_)\r
- \r
- #define MultiplyHigh __mulh\r
- #define UnsignedMultiplyHigh __umulh\r
- \r
- //DECLSPEC_DEPRECATED_DDK\r
- static __inline\r
- LARGE_INTEGER\r
- NTAPI_INLINE\r
- RtlExtendedMagicDivide(\r
- IN LARGE_INTEGER Dividend,\r
- IN LARGE_INTEGER MagicDivisor,\r
- IN CCHAR ShiftCount)\r
- {\r
- LARGE_INTEGER ret;\r
- ULONG64 ret64;\r
- BOOLEAN Pos;\r
- Pos = (Dividend.QuadPart >= 0);\r
- ret64 = UnsignedMultiplyHigh(Pos ? Dividend.QuadPart : -Dividend.QuadPart,\r
- MagicDivisor.QuadPart);\r
- ret64 >>= ShiftCount;\r
- ret.QuadPart = Pos ? ret64 : -ret64;\r
- return ret;\r
- }\r
- #endif\r
- \r
- //DECLSPEC_DEPRECATED_DDK\r
- static __inline\r
- LARGE_INTEGER\r
- NTAPI_INLINE\r
- RtlLargeIntegerAdd(\r
- IN LARGE_INTEGER Addend1,\r
- IN LARGE_INTEGER Addend2)\r
- {\r
- LARGE_INTEGER ret;\r
- ret.QuadPart = Addend1.QuadPart + Addend2.QuadPart;\r
- return ret;\r
- }\r
- \r
- /* VOID\r
- * RtlLargeIntegerAnd(\r
- * IN OUT LARGE_INTEGER Result,\r
- * IN LARGE_INTEGER Source,\r
- * IN LARGE_INTEGER Mask);\r
- */\r
- #define RtlLargeIntegerAnd(Result, Source, Mask) \\r
- Result.QuadPart = Source.QuadPart & Mask.QuadPart\r
- \r
- //DECLSPEC_DEPRECATED_DDK\r
- static __inline\r
- LARGE_INTEGER\r
- NTAPI_INLINE\r
- RtlLargeIntegerArithmeticShift(\r
- IN LARGE_INTEGER LargeInteger,\r
- IN CCHAR ShiftCount)\r
- {\r
- LARGE_INTEGER ret;\r
- ret.QuadPart = LargeInteger.QuadPart >> ShiftCount;\r
- return ret;\r
- }\r
- \r
- /* BOOLEAN\r
- * RtlLargeIntegerEqualTo(\r
- * IN LARGE_INTEGER Operand1,\r
- * IN LARGE_INTEGER Operand2);\r
- */\r
- #define RtlLargeIntegerEqualTo(X,Y) \\r
- (!(((X).LowPart ^ (Y).LowPart) | ((X).HighPart ^ (Y).HighPart)))\r
- \r
- FORCEINLINE\r
- PVOID\r
- RtlSecureZeroMemory(\r
- OUT PVOID Pointer,\r
- IN SIZE_T Size)\r
- {\r
- volatile char* vptr = (volatile char*)Pointer;\r
- #if defined(_M_AMD64)\r
- __stosb((PUCHAR)vptr, 0, Size);\r
- #else\r
- char * endptr = (char *)vptr + Size;\r
- while (vptr < endptr)\r
- {\r
- *vptr = 0; vptr++;\r
- }\r
- #endif\r
- return Pointer;\r
- }\r
- \r
- #if defined(_M_AMD64)\r
- FORCEINLINE\r
- ULONG\r
- RtlCheckBit(\r
- IN PRTL_BITMAP BitMapHeader,\r
- IN ULONG BitPosition)\r
- {\r
- return BitTest((LONG CONST*)BitMapHeader->Buffer, BitPosition);\r
- }\r
- #else\r
- #define RtlCheckBit(BMH,BP) (((((PLONG)(BMH)->Buffer)[(BP)/32]) >> ((BP)%32)) & 0x1)\r
- #endif // defined(_M_AMD64)\r
- \r
- #endif // !defined(MIDL_PASS)\r
- \r
- //\r
- // Byte Swap Functions\r
- //\r
- #if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037 || defined(__GNUC__))) || \\r
- ((defined(_M_AMD64) || defined(_M_IA64)) \\r
- && (_MSC_FULL_VER > 13009175 || defined(__GNUC__)))\r
- \r
- #define RtlUshortByteSwap(_x) _byteswap_ushort((USHORT)(_x))\r
- #define RtlUlongByteSwap(_x) _byteswap_ulong((_x))\r
- #define RtlUlonglongByteSwap(_x) _byteswap_uint64((_x))\r
- \r
- #endif\r
- \r
- /******************************************************************************\r
- * Memory manager Types *\r
- ******************************************************************************/\r
- \r
- typedef struct _MDL {\r
- struct _MDL *Next;\r
- CSHORT Size;\r
- CSHORT MdlFlags;\r
- struct _EPROCESS *Process;\r
- PVOID MappedSystemVa;\r
- PVOID StartVa;\r
- ULONG ByteCount;\r
- ULONG ByteOffset;\r
- } MDL, *PMDL;\r
- \r
- \r
- /******************************************************************************\r
- * Memory manager Functions *\r
- ******************************************************************************/\r
- \r
- /* PVOID MmGetSystemAddressForMdl(\r
- * IN PMDL Mdl);\r
- */\r
- #define MmGetSystemAddressForMdl(Mdl) \\r
- (((Mdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | \\r
- MDL_SOURCE_IS_NONPAGED_POOL)) ? \\r
- ((Mdl)->MappedSystemVa) : \\r
- (MmMapLockedPages((Mdl), KernelMode)))\r
- \r
- /* PVOID\r
- * MmGetSystemAddressForMdlSafe(\r
- * IN PMDL Mdl,\r
- * IN MM_PAGE_PRIORITY Priority)\r
- */\r
- #define MmGetSystemAddressForMdlSafe(_Mdl, _Priority) \\r
- (((_Mdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA \\r
- | MDL_SOURCE_IS_NONPAGED_POOL)) ? \\r
- (_Mdl)->MappedSystemVa : \\r
- (PVOID) MmMapLockedPagesSpecifyCache((_Mdl), \\r
- KernelMode, MmCached, NULL, FALSE, (_Priority)))\r
- \r
- #if (NTDDI_VERSION >= NTDDI_WIN2K)\r
- NTKERNELAPI\r
- PMDL\r
- NTAPI\r
- MmCreateMdl(\r
- IN PMDL MemoryDescriptorList OPTIONAL,\r
- IN PVOID Base,\r
- IN SIZE_T Length);\r
- \r
- #endif\r
- \r
- \r
- /******************************************************************************\r
- * I/O Manager Functions *\r
- ******************************************************************************/\r
- \r
- #if defined(USE_DMA_MACROS) && !defined(_NTHAL_) && \\r
- (defined(_NTDDK_) || defined(_NTDRIVER_)) || defined(_WDM_INCLUDED_)\r
- \r
- #define DMA_MACROS_DEFINED\r
- \r
- FORCEINLINE\r
- NTSTATUS\r
- IoAllocateAdapterChannel(\r
- IN PADAPTER_OBJECT AdapterObject,\r
- IN PDEVICE_OBJECT DeviceObject,\r
- IN ULONG NumberOfMapRegisters,\r
- IN PDRIVER_CONTROL ExecutionRoutine,\r
- IN PVOID Context)\r
- {\r
- PALLOCATE_ADAPTER_CHANNEL AllocateAdapterChannel;\r
- AllocateAdapterChannel =\r
- *(DmaAdapter)->DmaOperations->AllocateAdapterChannel;\r
- ASSERT(AllocateAdapterChannel);\r
- return AllocateAdapterChannel(DmaAdapter,\r
- DeviceObject,\r
- NumberOfMapRegisters,\r
- ExecutionRoutine,\r
- Context );\r
- }\r
- \r
- FORCEINLINE\r
- BOOLEAN\r
- IoFlushAdapterBuffers(\r
- IN PADAPTER_OBJECT AdapterObject,\r
- IN PMDL Mdl,\r
- IN PVOID MapRegisterBase,\r
- IN PVOID CurrentVa,\r
- IN ULONG Length,\r
- IN BOOLEAN WriteToDevice)\r
- {\r
- PFLUSH_ADAPTER_BUFFERS FlushAdapterBuffers;\r
- FlushAdapterBuffers = *(DmaAdapter)->DmaOperations->FlushAdapterBuffers;\r
- ASSERT(FlushAdapterBuffers);\r
- return FlushAdapterBuffers(DmaAdapter,\r
- Mdl,\r
- MapRegisterBase,\r
- CurrentVa,\r
- Length,\r
- WriteToDevice );\r
- }\r
- \r
- FORCEINLINE\r
- VOID\r
- IoFreeAdapterChannel(\r
- IN PADAPTER_OBJECT AdapterObject)\r
- {\r
- PFREE_ADAPTER_CHANNEL FreeAdapterChannel;\r
- FreeAdapterChannel = *(DmaAdapter)->DmaOperations->FreeAdapterChannel;\r
- ASSERT(FreeAdapterChannel);\r
- FreeAdapterChannel(DmaAdapter);\r
- }\r
- \r
- FORCEINLINE\r
- VOID\r
- IoFreeMapRegisters(\r
- IN PADAPTER_OBJECT AdapterObject,\r
- IN PVOID MapRegisterBase,\r
- IN ULONG NumberOfMapRegisters)\r
- {\r
- PFREE_MAP_REGISTERS FreeMapRegisters;\r
- FreeMapRegisters = *(DmaAdapter)->DmaOperations->FreeMapRegisters;\r
- ASSERT(FreeMapRegisters);\r
- FreeMapRegisters(DmaAdapter, MapRegisterBase, NumberOfMapRegisters);\r
- }\r
- \r
- FORCEINLINE\r
- PHYSICAL_ADDRESS\r
- IoMapTransfer(\r
- IN PDMA_ADAPTER DmaAdapter,\r
- IN PMDL Mdl,\r
- IN PVOID MapRegisterBase,\r
- IN PVOID CurrentVa,\r
- IN OUT PULONG Length,\r
- IN BOOLEAN WriteToDevice)\r
- {\r
- PMAP_TRANSFER MapTransfer;\r
- \r
- MapTransfer = *(DmaAdapter)->DmaOperations->MapTransfer;\r
- ASSERT(MapTransfer);\r
- return MapTransfer(DmaAdapter,\r
- Mdl,\r
- MapRegisterBase,\r
- CurrentVa,\r
- Length,\r
- WriteToDevice);\r
- }\r
- #endif\r
- \r
- \r
- /******************************************************************************\r
- * Executive Types *\r
- ******************************************************************************/\r
- \r
- typedef enum _POOL_TYPE {\r
- NonPagedPool,\r
- PagedPool,\r
- NonPagedPoolMustSucceed,\r
- DontUseThisType,\r
- NonPagedPoolCacheAligned,\r
- PagedPoolCacheAligned,\r
- NonPagedPoolCacheAlignedMustS,\r
- MaxPoolType,\r
- NonPagedPoolSession = 32,\r
- PagedPoolSession,\r
- NonPagedPoolMustSucceedSession,\r
- DontUseThisTypeSession,\r
- NonPagedPoolCacheAlignedSession,\r
- PagedPoolCacheAlignedSession,\r
- NonPagedPoolCacheAlignedMustSSession\r
- } POOL_TYPE;\r
- \r
- typedef enum _SUITE_TYPE {\r
- SmallBusiness,\r
- Enterprise,\r
- BackOffice,\r
- CommunicationServer,\r
- TerminalServer,\r
- SmallBusinessRestricted,\r
- EmbeddedNT,\r
- DataCenter,\r
- SingleUserTS,\r
- Personal,\r
- Blade,\r
- MaxSuiteType\r
- } SUITE_TYPE;\r
- \r
- typedef enum _EX_POOL_PRIORITY {\r
- LowPoolPriority,\r
- LowPoolPrioritySpecialPoolOverrun = 8,\r
- LowPoolPrioritySpecialPoolUnderrun = 9,\r
- NormalPoolPriority = 16,\r
- NormalPoolPrioritySpecialPoolOverrun = 24,\r
- NormalPoolPrioritySpecialPoolUnderrun = 25,\r
- HighPoolPriority = 32,\r
- HighPoolPrioritySpecialPoolOverrun = 40,\r
- HighPoolPrioritySpecialPoolUnderrun = 41\r
- } EX_POOL_PRIORITY;\r
- \r
- typedef struct _FAST_MUTEX\r
- {\r
- LONG Count;\r
- PKTHREAD Owner;\r
- ULONG Contention;\r
- KEVENT Gate;\r
- ULONG OldIrql;\r
- } FAST_MUTEX, *PFAST_MUTEX;\r
- \r
- typedef ULONG_PTR ERESOURCE_THREAD, *PERESOURCE_THREAD;\r
- \r
- typedef struct _OWNER_ENTRY {\r
- ERESOURCE_THREAD OwnerThread;\r
- _ANONYMOUS_UNION union {\r
- LONG OwnerCount;\r
- ULONG TableSize;\r
- } DUMMYUNIONNAME;\r
- } OWNER_ENTRY, *POWNER_ENTRY;\r
- \r
- typedef struct _ERESOURCE\r
- {\r
- LIST_ENTRY SystemResourcesList;\r
- POWNER_ENTRY OwnerTable;\r
- SHORT ActiveCount;\r
- USHORT Flag;\r
- volatile PKSEMAPHORE SharedWaiters;\r
- volatile PKEVENT ExclusiveWaiters;\r
- OWNER_ENTRY OwnerEntry;\r
- ULONG ActiveEntries;\r
- ULONG ContentionCount;\r
- ULONG NumberOfSharedWaiters;\r
- ULONG NumberOfExclusiveWaiters;\r
- union\r
- {\r
- PVOID Address;\r
- ULONG_PTR CreatorBackTraceIndex;\r
- };\r
- KSPIN_LOCK SpinLock;\r
- } ERESOURCE, *PERESOURCE;\r
- \r
- #if !defined(_WIN64) && (defined(_NTDDK_) || defined(_NTIFS_) || defined(_NDIS_))\r
- #define LOOKASIDE_ALIGN\r
- #else\r
- #define LOOKASIDE_ALIGN /* FIXME: DECLSPEC_CACHEALIGN */\r
- #endif\r
- \r
- typedef struct _LOOKASIDE_LIST_EX *PLOOKASIDE_LIST_EX;\r
- \r
- typedef PVOID\r
- (DDKAPI *PALLOCATE_FUNCTION)(\r
- IN POOL_TYPE PoolType,\r
- IN SIZE_T NumberOfBytes,\r
- IN ULONG Tag);\r
- \r
- typedef PVOID\r
- (DDKAPI *PALLOCATE_FUNCTION_EX)(\r
- IN POOL_TYPE PoolType,\r
- IN SIZE_T NumberOfBytes,\r
- IN ULONG Tag,\r
- IN OUT PLOOKASIDE_LIST_EX Lookaside);\r
- \r
- typedef VOID\r
- (DDKAPI *PFREE_FUNCTION)(\r
- IN PVOID Buffer);\r
- \r
- typedef VOID\r
- (DDKAPI *PFREE_FUNCTION_EX)(\r
- IN PVOID Buffer,\r
- IN OUT PLOOKASIDE_LIST_EX Lookaside);\r
- \r
- typedef VOID\r
- (DDKAPI *PCALLBACK_FUNCTION)(\r
- IN PVOID CallbackContext,\r
- IN PVOID Argument1,\r
- IN PVOID Argument2);\r
- \r
- typedef struct LOOKASIDE_ALIGN _GENERAL_LOOKASIDE {\r
- union {\r
- SLIST_HEADER ListHead;\r
- SINGLE_LIST_ENTRY SingleListHead;\r
- } DUMMYUNIONNAME;\r
- USHORT Depth;\r
- USHORT MaximumDepth;\r
- ULONG TotalAllocates;\r
- union {\r
- ULONG AllocateMisses;\r
- ULONG AllocateHits;\r
- } DUMMYUNIONNAME2;\r
- ULONG TotalFrees;\r
- union {\r
- ULONG FreeMisses;\r
- ULONG FreeHits;\r
- } DUMMYUNIONNAME3;\r
- POOL_TYPE Type;\r
- ULONG Tag;\r
- ULONG Size;\r
- union {\r
- PALLOCATE_FUNCTION_EX AllocateEx; \r
- PALLOCATE_FUNCTION Allocate;\r
- } DUMMYUNIONNAME4;\r
- union {\r
- PFREE_FUNCTION_EX FreeEx;\r
- PFREE_FUNCTION Free;\r
- } DUMMYUNIONNAME5;\r
- LIST_ENTRY ListEntry;\r
- ULONG LastTotalAllocates;\r
- union {\r
- ULONG LastAllocateMisses;\r
- ULONG LastAllocateHits;\r
- } DUMMYUNIONNAME6;\r
- ULONG Future[2];\r
- } GENERAL_LOOKASIDE, *PGENERAL_LOOKASIDE;\r
- \r
- typedef struct _PAGED_LOOKASIDE_LIST {\r
- GENERAL_LOOKASIDE L;\r
- #if !defined(_AMD64_) && !defined(_IA64_)\r
- FAST_MUTEX Lock__ObsoleteButDoNotDelete;\r
- #endif\r
- } PAGED_LOOKASIDE_LIST, *PPAGED_LOOKASIDE_LIST;\r
- \r
- typedef struct LOOKASIDE_ALIGN _NPAGED_LOOKASIDE_LIST {\r
- GENERAL_LOOKASIDE L;\r
- #if !defined(_AMD64_) && !defined(_IA64_)\r
- KSPIN_LOCK Lock__ObsoleteButDoNotDelete;\r
- #endif\r
- } NPAGED_LOOKASIDE_LIST, *PNPAGED_LOOKASIDE_LIST;\r
- \r
- //typedef struct _LOOKASIDE_LIST_EX {\r
- // GENERAL_LOOKASIDE_POOL L;\r
- //} LOOKASIDE_LIST_EX, *PLOOKASIDE_LIST_EX;\r
- \r
- typedef struct _EX_RUNDOWN_REF {\r
- union {\r
- volatile ULONG_PTR Count;\r
- volatile PVOID Ptr;\r
- };\r
- } EX_RUNDOWN_REF, *PEX_RUNDOWN_REF;\r
- \r
- typedef struct _EX_RUNDOWN_REF_CACHE_AWARE *PEX_RUNDOWN_REF_CACHE_AWARE;\r
- \r
- typedef enum _WORK_QUEUE_TYPE {\r
- CriticalWorkQueue,\r
- DelayedWorkQueue,\r
- HyperCriticalWorkQueue,\r
- MaximumWorkQueue\r
- } WORK_QUEUE_TYPE;\r
- \r
- typedef VOID\r
- (DDKAPI *PWORKER_THREAD_ROUTINE)(\r
- IN PVOID Parameter);\r
- \r
- typedef struct _WORK_QUEUE_ITEM {\r
- LIST_ENTRY List;\r
- PWORKER_THREAD_ROUTINE WorkerRoutine;\r
- volatile PVOID Parameter;\r
- } WORK_QUEUE_ITEM, *PWORK_QUEUE_ITEM;\r
- \r
- \r
- /******************************************************************************\r
- * Executive Functions *\r
- ******************************************************************************/\r
- \r
- #if defined(_X86_)\r
- #if defined(_NTHAL_)\r
- #define ExAcquireFastMutex ExiAcquireFastMutex\r
- #define ExReleaseFastMutex ExiReleaseFastMutex\r
- #define ExTryToAcquireFastMutex ExiTryToAcquireFastMutex\r
- #endif\r
- #define ExInterlockedAddUlong ExfInterlockedAddUlong\r
- #define ExInterlockedInsertHeadList ExfInterlockedInsertHeadList\r
- #define ExInterlockedInsertTailList ExfInterlockedInsertTailList\r
- #define ExInterlockedRemoveHeadList ExfInterlockedRemoveHeadList\r
- #define ExInterlockedPopEntryList ExfInterlockedPopEntryList\r
- #define ExInterlockedPushEntryList ExfInterlockedPushEntryList\r
- #endif\r
- \r
- #if defined(_WIN64)\r
- \r
- #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || \\r
- defined(_NTHAL_) || defined(_NTOSP_)\r
- NTKERNELAPI\r
- USHORT\r
- ExQueryDepthSList(IN PSLIST_HEADER ListHead);\r
- #else\r
- FORCEINLINE\r
- USHORT\r
- ExQueryDepthSList(IN PSLIST_HEADER ListHead)\r
- {\r
- return (USHORT)(ListHead->Alignment & 0xffff);\r
- }\r
- #endif\r
- \r
- NTKERNELAPI\r
- PSLIST_ENTRY\r
- ExpInterlockedFlushSList(\r
- PSLIST_HEADER ListHead);\r
- \r
- NTKERNELAPI\r
- PSLIST_ENTRY\r
- ExpInterlockedPopEntrySList(\r
- PSLIST_HEADER ListHead);\r
- \r
- NTKERNELAPI\r
- PSLIST_ENTRY\r
- ExpInterlockedPushEntrySList(\r
- PSLIST_HEADER ListHead,\r
- PSLIST_ENTRY ListEntry);\r
- \r
- #define ExInterlockedFlushSList(Head) \\r
- ExpInterlockedFlushSList(Head)\r
- #define ExInterlockedPopEntrySList(Head, Lock) \\r
- ExpInterlockedPopEntrySList(Head)\r
- #define ExInterlockedPushEntrySList(Head, Entry, Lock) \\r
- ExpInterlockedPushEntrySList(Head, Entry)\r
- \r
- #else // !defined(_WIN64)\r
- \r
- #define ExQueryDepthSList(listhead) (listhead)->Depth\r
- \r
- NTKERNELAPI\r
- PSINGLE_LIST_ENTRY\r
- FASTCALL\r
- ExInterlockedFlushSList(\r
- IN PSLIST_HEADER ListHead);\r
- \r
- #if defined(_WIN2K_COMPAT_SLIST_USAGE) && defined(_X86_)\r
- NTKERNELAPI\r
- PSINGLE_LIST_ENTRY \r
- FASTCALL\r
- ExInterlockedPopEntrySList(\r
- IN PSLIST_HEADER ListHead,\r
- IN PKSPIN_LOCK Lock);\r
- \r
- NTKERNELAPI\r
- PSINGLE_LIST_ENTRY \r
- FASTCALL\r
- ExInterlockedPushEntrySList(\r
- IN PSLIST_HEADER ListHead,\r
- IN PSINGLE_LIST_ENTRY ListEntry,\r
- IN PKSPIN_LOCK Lock);\r
- #else\r
- #define ExInterlockedPopEntrySList(_ListHead, _Lock) \\r
- InterlockedPopEntrySList(_ListHead)\r
- #define ExInterlockedPushEntrySList(_ListHead, _ListEntry, _Lock) \\r
- InterlockedPushEntrySList(_ListHead, _ListEntry)\r
- #endif // _WIN2K_COMPAT_SLIST_USAGE\r
- \r
- #endif // !defined(_WIN64)\r
- \r
- /* ERESOURCE_THREAD\r
- * ExGetCurrentResourceThread(\r
- * VOID);\r
- */\r
- #define ExGetCurrentResourceThread() ((ERESOURCE_THREAD)PsGetCurrentThread())\r
- \r
- #define ExReleaseResource(R) (ExReleaseResourceLite(R))\r
- \r
- /* VOID\r
- * ExInitializeWorkItem(\r
- * IN PWORK_QUEUE_ITEM Item,\r
- * IN PWORKER_THREAD_ROUTINE Routine,\r
- * IN PVOID Context)\r
- */\r
- #define ExInitializeWorkItem(Item, Routine, Context) \\r
- { \\r
- (Item)->WorkerRoutine = Routine; \\r
- (Item)->Parameter = Context; \\r
- (Item)->List.Flink = NULL; \\r
- }\r
- \r
- #if (NTDDI_VERSION >= NTDDI_WIN2K)\r
- \r
- NTKERNELAPI\r
- VOID\r
- FASTCALL\r
- ExAcquireFastMutex(\r
- IN OUT PFAST_MUTEX FastMutex);\r
- \r
- NTKERNELAPI\r
- VOID\r
- FASTCALL\r
- ExReleaseFastMutex(\r
- IN OUT PFAST_MUTEX FastMutex);\r
- \r
- NTKERNELAPI\r
- BOOLEAN\r
- FASTCALL\r
- ExTryToAcquireFastMutex(\r
- IN OUT PFAST_MUTEX FastMutex);\r
- \r
- NTKERNELAPI\r
- VOID\r
- FASTCALL\r
- ExAcquireFastMutexUnsafe(\r
- IN OUT PFAST_MUTEX FastMutex);\r
- \r
- NTKERNELAPI\r
- VOID\r
- FASTCALL\r
- ExReleaseFastMutexUnsafe(\r
- IN OUT PFAST_MUTEX FastMutex);\r
- \r
- NTKERNELAPI\r
- BOOLEAN\r
- NTAPI\r
- ExAcquireResourceExclusiveLite(\r
- IN PERESOURCE Resource,\r
- IN BOOLEAN Wait);\r
- \r
- NTKERNELAPI\r
- BOOLEAN\r
- NTAPI\r
- ExAcquireResourceSharedLite(\r
- IN PERESOURCE Resource,\r
- IN BOOLEAN Wait);\r
- \r
- NTKERNELAPI\r
- BOOLEAN\r
- NTAPI\r
- ExAcquireSharedStarveExclusive(\r
- IN PERESOURCE Resource,\r
- IN BOOLEAN Wait);\r
- \r
- NTKERNELAPI\r
- BOOLEAN\r
- NTAPI\r
- ExAcquireSharedWaitForExclusive(\r
- IN PERESOURCE Resource,\r
- IN BOOLEAN Wait);\r
- \r
- NTKERNELAPI\r
- PVOID\r
- NTAPI\r
- ExAllocatePool(\r
- IN POOL_TYPE PoolType,\r
- IN SIZE_T NumberOfBytes);\r
- \r
- #ifdef POOL_TAGGING\r
- #define ExAllocatePool(p,n) ExAllocatePoolWithTag(p,n,' kdD')\r
- #endif /* POOL_TAGGING */\r
- \r
- NTKERNELAPI\r
- PVOID\r
- NTAPI\r
- ExAllocatePoolWithQuota(\r
- IN POOL_TYPE PoolType,\r
- IN SIZE_T NumberOfBytes);\r
- \r
- #ifdef POOL_TAGGING\r
- #define ExAllocatePoolWithQuota(p,n) ExAllocatePoolWithQuotaTag(p,n,' kdD')\r
- #endif /* POOL_TAGGING */\r
- \r
- NTKERNELAPI\r
- PVOID\r
- NTAPI\r
- ExAllocatePoolWithQuotaTag(\r
- IN POOL_TYPE PoolType,\r
- IN SIZE_T NumberOfBytes,\r
- IN ULONG Tag);\r
- \r
- #ifndef POOL_TAGGING\r
- #define ExAllocatePoolWithQuotaTag(a,b,c) ExAllocatePoolWithQuota(a,b)\r
- #endif /* POOL_TAGGING */\r
- \r
- NTKERNELAPI\r
- PVOID\r
- NTAPI\r
- ExAllocatePoolWithTag(\r
- IN POOL_TYPE PoolType,\r
- IN SIZE_T NumberOfBytes,\r
- IN ULONG Tag);\r
- \r
- NTKERNELAPI\r
- PVOID\r
- NTAPI\r
- ExAllocatePoolWithTagPriority(\r
- IN POOL_TYPE PoolType,\r
- IN SIZE_T NumberOfBytes,\r
- IN ULONG Tag,\r
- IN EX_POOL_PRIORITY Priority);\r
- \r
- NTKERNELAPI\r
- VOID\r
- NTAPI\r
- ExConvertExclusiveToSharedLite(\r
- IN PERESOURCE Resource);\r
- \r
- NTKERNELAPI\r
- NTSTATUS\r
- NTAPI\r
- ExCreateCallback(\r
- OUT PCALLBACK_OBJECT *CallbackObject,\r
- IN POBJECT_ATTRIBUTES ObjectAttributes,\r
- IN BOOLEAN Create,\r
- IN BOOLEAN AllowMultipleCallbacks);\r
- \r
- NTKERNELAPI\r
- VOID\r
- NTAPI\r
- ExDeleteNPagedLookasideList(\r
- IN PNPAGED_LOOKASIDE_LIST Lookaside);\r
- \r
- NTKERNELAPI\r
- VOID\r
- NTAPI\r
- ExDeletePagedLookasideList(\r
- IN PPAGED_LOOKASIDE_LIST Lookaside);\r
- \r
- NTKERNELAPI\r
- NTSTATUS\r
- NTAPI\r
- ExDeleteResourceLite(\r
- IN PERESOURCE Resource);\r
- \r
- NTKERNELAPI\r
- VOID\r
- NTAPI\r
- ExFreePool(\r
- IN PVOID P);\r
- \r
- #ifdef POOL_TAGGING\r
- #define ExFreePool(P) ExFreePoolWithTag(P, 0)\r
- #endif\r
- \r
- NTKERNELAPI\r
- VOID\r
- NTAPI\r
- ExFreePoolWithTag(\r
- IN PVOID P,\r
- IN ULONG Tag);\r
- \r
- NTKERNELAPI\r
- ULONG\r
- NTAPI\r
- ExGetExclusiveWaiterCount(\r
- IN PERESOURCE Resource);\r
- \r
- NTKERNELAPI\r
- KPROCESSOR_MODE\r
- NTAPI\r
- ExGetPreviousMode(\r
- VOID);\r
- \r
- NTKERNELAPI\r
- ULONG\r
- NTAPI\r
- ExGetSharedWaiterCount(\r
- IN PERESOURCE Resource);\r
- \r
- NTKERNELAPI\r
- VOID\r
- NTAPI\r
- ExInitializeNPagedLookasideList(\r
- IN PNPAGED_LOOKASIDE_LIST Lookaside,\r
- IN PALLOCATE_FUNCTION Allocate OPTIONAL,\r
- IN PFREE_FUNCTION Free OPTIONAL,\r
- IN ULONG Flags,\r
- IN SIZE_T Size,\r
- IN ULONG Tag,\r
- IN USHORT Depth);\r
- \r
- NTKERNELAPI\r
- VOID\r
- NTAPI\r
- ExInitializePagedLookasideList(\r
- IN PPAGED_LOOKASIDE_LIST Lookaside,\r
- IN PALLOCATE_FUNCTION Allocate OPTIONAL,\r
- IN PFREE_FUNCTION Free OPTIONAL,\r
- IN ULONG Flags,\r
- IN SIZE_T Size,\r
- IN ULONG Tag,\r
- IN USHORT Depth);\r
- \r
- NTKERNELAPI\r
- NTSTATUS\r
- NTAPI\r
- ExInitializeResourceLite(\r
- IN PERESOURCE Resource);\r
- \r
- NTKERNELAPI\r
- LARGE_INTEGER\r
- NTAPI\r
- ExInterlockedAddLargeInteger(\r
- IN PLARGE_INTEGER Addend,\r
- IN LARGE_INTEGER Increment,\r
- IN PKSPIN_LOCK Lock);\r
- \r
- #if defined(_WIN64)\r
- #define ExInterlockedAddLargeStatistic(Addend, Increment) \\r
- (VOID)InterlockedAdd64(&(Addend)->QuadPart, Increment)\r
- #else\r
- #define ExInterlockedAddLargeStatistic(Addend, Increment) \\r
- _InterlockedAddLargeStatistic((PLONGLONG)&(Addend)->QuadPart, Increment)\r
- #endif\r
- \r
- NTKERNELAPI\r
- ULONG\r
- FASTCALL\r
- ExInterlockedAddUlong(\r
- IN PULONG Addend,\r
- IN ULONG Increment,\r
- PKSPIN_LOCK Lock);\r
- \r
- #if defined(_AMD64_) || defined(_IA64_)\r
- #define ExInterlockedCompareExchange64(Destination, Exchange, Comperand, Lock) \\r
- InterlockedCompareExchange64(Destination, *(Exchange), *(Comperand))\r
- #elif defined(_X86_)\r
- NTKERNELAPI\r
- LONGLONG\r
- FASTCALL\r
- ExfInterlockedCompareExchange64(\r
- IN OUT LONGLONG volatile *Destination,\r
- IN PLONGLONG Exchange,\r
- IN PLONGLONG Comperand);\r
- #define ExInterlockedCompareExchange64(Destination, Exchange, Comperand, Lock) \\r
- ExfInterlockedCompareExchange64(Destination, Exchange, Comperand)\r
- #else\r
- NTKERNELAPI\r
- LONGLONG\r
- FASTCALL\r
- ExInterlockedCompareExchange64(\r
- IN OUT LONGLONG volatile *Destination,\r
- IN PLONGLONG Exchange,\r
- IN PLONGLONG Comparand,\r
- IN PKSPIN_LOCK Lock);\r
- #endif\r
- \r
- NTKERNELAPI\r
- PLIST_ENTRY\r
- FASTCALL\r
- ExInterlockedInsertHeadList(\r
- IN PLIST_ENTRY ListHead,\r
- IN PLIST_ENTRY ListEntry,\r
- IN PKSPIN_LOCK Lock);\r
- \r
- NTKERNELAPI\r
- PLIST_ENTRY\r
- FASTCALL\r
- ExInterlockedInsertTailList(\r
- IN PLIST_ENTRY ListHead,\r
- IN PLIST_ENTRY ListEntry,\r
- IN PKSPIN_LOCK Lock);\r
- \r
- NTKERNELAPI\r
- PSINGLE_LIST_ENTRY\r
- FASTCALL\r
- ExInterlockedPopEntryList(\r
- IN PSINGLE_LIST_ENTRY ListHead,\r
- IN PKSPIN_LOCK Lock);\r
- \r
- NTKERNELAPI\r
- PSINGLE_LIST_ENTRY\r
- FASTCALL\r
- ExInterlockedPushEntryList(\r
- IN PSINGLE_LIST_ENTRY ListHead,\r
- IN PSINGLE_LIST_ENTRY ListEntry,\r
- IN PKSPIN_LOCK Lock);\r
- \r
- NTKERNELAPI\r
- PLIST_ENTRY\r
- FASTCALL\r
- ExInterlockedRemoveHeadList(\r
- IN PLIST_ENTRY ListHead,\r
- IN PKSPIN_LOCK Lock);\r
- \r
- NTKERNELAPI\r
- BOOLEAN\r
- NTAPI\r
- ExIsProcessorFeaturePresent(\r
- IN ULONG ProcessorFeature);\r
- \r
- NTKERNELAPI\r
- BOOLEAN\r
- NTAPI\r
- ExIsResourceAcquiredExclusiveLite(\r
- IN PERESOURCE Resource);\r
- \r
- NTKERNELAPI\r
- ULONG\r
- NTAPI\r
- ExIsResourceAcquiredSharedLite(\r
- IN PERESOURCE Resource);\r
- \r
- #define ExIsResourceAcquiredLite ExIsResourceAcquiredSharedLite\r
- \r
- NTKERNELAPI\r
- VOID\r
- NTAPI\r
- ExLocalTimeToSystemTime(\r
- IN PLARGE_INTEGER LocalTime,\r
- OUT PLARGE_INTEGER SystemTime);\r
- \r
- NTKERNELAPI\r
- VOID\r
- NTAPI\r
- ExNotifyCallback(\r
- IN PCALLBACK_OBJECT CallbackObject,\r
- IN PVOID Argument1,\r
- IN PVOID Argument2);\r
- \r
- NTKERNELAPI\r
- VOID\r
- NTAPI\r
- ExQueueWorkItem(\r
- IN PWORK_QUEUE_ITEM WorkItem,\r
- IN WORK_QUEUE_TYPE QueueType);\r
- \r
- NTKERNELAPI\r
- DECLSPEC_NORETURN\r
- VOID\r
- NTAPI\r
- ExRaiseStatus(\r
- IN NTSTATUS Status);\r
- \r
- NTKERNELAPI\r
- PVOID\r
- NTAPI\r
- ExRegisterCallback(\r
- IN PCALLBACK_OBJECT CallbackObject,\r
- IN PCALLBACK_FUNCTION CallbackFunction,\r
- IN PVOID CallbackContext);\r
- \r
- NTKERNELAPI\r
- NTSTATUS\r
- NTAPI\r
- ExReinitializeResourceLite(\r
- IN PERESOURCE Resource);\r
- \r
- NTKERNELAPI\r
- VOID\r
- NTAPI\r
- ExReleaseResourceForThreadLite(\r
- IN PERESOURCE Resource,\r
- IN ERESOURCE_THREAD ResourceThreadId);\r
- \r
- NTKERNELAPI\r
- VOID\r
- FASTCALL\r
- ExReleaseResourceLite(\r
- IN PERESOURCE Resource);\r
- \r
- NTKERNELAPI\r
- VOID\r
- NTAPI\r
- ExSetResourceOwnerPointer(\r
- IN PERESOURCE Resource,\r
- IN PVOID OwnerPointer);\r
- \r
- NTKERNELAPI\r
- ULONG\r
- NTAPI\r
- ExSetTimerResolution(\r
- IN ULONG DesiredTime,\r
- IN BOOLEAN SetResolution);\r
- \r
- NTKERNELAPI\r
- VOID\r
- NTAPI\r
- ExSystemTimeToLocalTime(\r
- IN PLARGE_INTEGER SystemTime,\r
- OUT PLARGE_INTEGER LocalTime);\r
- \r
- NTKERNELAPI\r
- VOID\r
- NTAPI\r
- ExUnregisterCallback(\r
- IN PVOID CbRegistration);\r
- \r
- \r
- #endif // (NTDDI_VERSION >= NTDDI_WIN2K)\r
- \r
- #if (NTDDI_VERSION >= NTDDI_WINXP)\r
- NTKERNELAPI\r
- BOOLEAN\r
- FASTCALL\r
- ExAcquireRundownProtection(\r
- IN OUT PEX_RUNDOWN_REF RunRef);\r
- \r
- NTKERNELAPI\r
- VOID\r
- FASTCALL\r
- ExInitializeRundownProtection(\r
- OUT PEX_RUNDOWN_REF RunRef);\r
- \r
- NTKERNELAPI\r
- VOID\r
- FASTCALL\r
- ExReInitializeRundownProtection(\r
- OUT PEX_RUNDOWN_REF RunRef);\r
- \r
- NTKERNELAPI\r
- VOID\r
- FASTCALL\r
- ExReleaseRundownProtection(\r
- IN OUT PEX_RUNDOWN_REF RunRef);\r
- \r
- NTKERNELAPI\r
- VOID\r
- FASTCALL\r
- ExRundownCompleted(\r
- OUT PEX_RUNDOWN_REF RunRef);\r
- \r
- NTKERNELAPI\r
- BOOLEAN\r
- NTAPI\r
- ExVerifySuite(\r
- IN SUITE_TYPE SuiteType);\r
- \r
- NTKERNELAPI\r
- VOID\r
- FASTCALL\r
- ExWaitForRundownProtectionRelease(\r
- IN OUT PEX_RUNDOWN_REF RunRef);\r
- \r
- #endif // (NTDDI_VERSION >= NTDDI_WINXP)\r
- \r
- #if (NTDDI_VERSION >= NTDDI_WINXPSP2)\r
- NTKERNELAPI\r
- BOOLEAN\r
- FASTCALL\r
- ExAcquireRundownProtectionEx(\r
- IN OUT PEX_RUNDOWN_REF RunRef,\r
- IN ULONG Count);\r
- \r
- NTKERNELAPI\r
- VOID\r
- FASTCALL\r
- ExReleaseRundownProtectionEx(\r
- IN OUT PEX_RUNDOWN_REF RunRef,\r
- IN ULONG Count);\r
- #endif // (NTDDI_VERSION >= NTDDI_WINXPSP2)\r
- \r
- #if (NTDDI_VERSION >= NTDDI_WS03)\r
- \r
- #endif // (NTDDI_VERSION >= NTDDI_WS03)\r
- \r
- #if (NTDDI_VERSION >= NTDDI_WS03SP1)\r
- NTKERNELAPI\r
- PEX_RUNDOWN_REF_CACHE_AWARE\r
- ExAllocateCacheAwareRundownProtection(\r
- IN POOL_TYPE PoolType,\r
- IN ULONG PoolTag);\r
- \r
- NTKERNELAPI\r
- SIZE_T\r
- ExSizeOfRundownProtectionCacheAware(VOID);\r
- \r
- #endif // (NTDDI_VERSION >= NTDDI_WS03SP1)\r
- \r
- #if (NTDDI_VERSION >= NTDDI_VISTA)\r
- NTKERNELAPI\r
- NTSTATUS\r
- ExInitializeLookasideListEx(\r
- OUT PLOOKASIDE_LIST_EX Lookaside,\r
- IN PALLOCATE_FUNCTION_EX Allocate OPTIONAL,\r
- IN PFREE_FUNCTION_EX Free OPTIONAL,\r
- IN POOL_TYPE PoolType,\r
- IN ULONG Flags,\r
- IN SIZE_T Size,\r
- IN ULONG Tag,\r
- IN USHORT Depth);\r
- #endif\r
- \r
- \r
- #if !defined(MIDL_PASS)\r
- \r
- static __inline PVOID\r
- ExAllocateFromNPagedLookasideList(\r
- IN PNPAGED_LOOKASIDE_LIST Lookaside)\r
- {\r
- PVOID Entry;\r
- \r
- Lookaside->L.TotalAllocates++;\r
- Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead);\r
- if (Entry == NULL) {\r
- Lookaside->L.AllocateMisses++;\r
- Entry = (Lookaside->L.Allocate)(Lookaside->L.Type,\r
- Lookaside->L.Size,\r
- Lookaside->L.Tag);\r
- }\r
- return Entry;\r
- }\r
- \r
- static __inline PVOID\r
- ExAllocateFromPagedLookasideList(\r
- IN PPAGED_LOOKASIDE_LIST Lookaside)\r
- {\r
- PVOID Entry;\r
- \r
- Lookaside->L.TotalAllocates++;\r
- Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead);\r
- if (Entry == NULL) {\r
- Lookaside->L.AllocateMisses++;\r
- Entry = (Lookaside->L.Allocate)(Lookaside->L.Type,\r
- Lookaside->L.Size,\r
- Lookaside->L.Tag);\r
- }\r
- return Entry;\r
- }\r
- \r
- static __inline VOID\r
- ExFreeToNPagedLookasideList(\r
- IN PNPAGED_LOOKASIDE_LIST Lookaside,\r
- IN PVOID Entry)\r
- {\r
- Lookaside->L.TotalFrees++;\r
- if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) {\r
- Lookaside->L.FreeMisses++;\r
- (Lookaside->L.Free)(Entry);\r
- } else {\r
- InterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry);\r
- }\r
- }\r
- \r
- static __inline VOID\r
- ExFreeToPagedLookasideList(\r
- IN PPAGED_LOOKASIDE_LIST Lookaside,\r
- IN PVOID Entry)\r
- {\r
- Lookaside->L.TotalFrees++;\r
- if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) {\r
- Lookaside->L.FreeMisses++;\r
- (Lookaside->L.Free)(Entry);\r
- } else {\r
- InterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry);\r
- }\r
- }\r
- \r
- \r
- #endif // !defined(MIDL_PASS)\r
- \r
- \r
- #ifdef __cplusplus\r
- }\r
- #endif\r
- \r
- #endif // _WDMDDK_\r
+ #ifndef _WDMDDK_
+ #define _WDMDDK_
+
+ //
+ // Dependencies
+ //
+ #define NT_INCLUDED
+ #include <excpt.h>
+ #include <ntdef.h>
+ #include <ntstatus.h>
+
+ #ifndef GUID_DEFINED
+ #include <guiddef.h>
+ #endif /* GUID_DEFINED */
+
+ #include "intrin.h"
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ #define NTKERNELAPI DECLSPEC_IMPORT
+
+ #ifdef _WIN64
+ #define PORT_MAXIMUM_MESSAGE_LENGTH 512
+ #else
+ #define PORT_MAXIMUM_MESSAGE_LENGTH 256
+ #endif
+
+
+ #if defined(_MSC_VER)
+
+ //
+ // Indicate if #pragma alloc_text() is supported
+ //
+ #if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64)
+ #define ALLOC_PRAGMA 1
+ #endif
+
+ //
+ // Indicate if #pragma data_seg() is supported
+ //
+ #if defined(_M_IX86) || defined(_M_AMD64)
+ #define ALLOC_DATA_PRAGMA 1
+ #endif
+
+ #endif
+
+
+ /* Simple types */
+ typedef UCHAR KPROCESSOR_MODE;
+ typedef LONG KPRIORITY;
+ typedef PVOID PSECURITY_DESCRIPTOR;
+ typedef ULONG SECURITY_INFORMATION, *PSECURITY_INFORMATION;
+
+ /* Structures not exposed to drivers */
+ typedef struct _OBJECT_TYPE *POBJECT_TYPE;
+ typedef struct _HAL_DISPATCH_TABLE *PHAL_DISPATCH_TABLE;
+ typedef struct _HAL_PRIVATE_DISPATCH_TABLE *PHAL_PRIVATE_DISPATCH_TABLE;
+ typedef struct _DEVICE_HANDLER_OBJECT *PDEVICE_HANDLER_OBJECT;
+ typedef struct _BUS_HANDLER *PBUS_HANDLER;
+
+ typedef struct _ADAPTER_OBJECT *PADAPTER_OBJECT;
+ typedef struct _CALLBACK_OBJECT *PCALLBACK_OBJECT;
+ typedef struct _ETHREAD *PETHREAD;
+ typedef struct _EPROCESS *PEPROCESS;
+ typedef struct _IO_TIMER *PIO_TIMER;
+ typedef struct _KINTERRUPT *PKINTERRUPT;
+ typedef struct _KPROCESS *PKPROCESS;
+ typedef struct _KTHREAD *PKTHREAD, *PRKTHREAD;
+
+
+ typedef struct _CONTEXT *PCONTEXT;
+
+ //
+ // Resource list definitions
+ //
+ typedef int CM_RESOURCE_TYPE;
+
+ #define CmResourceTypeNull 0
+ #define CmResourceTypePort 1
+ #define CmResourceTypeInterrupt 2
+ #define CmResourceTypeMemory 3
+ #define CmResourceTypeDma 4
+ #define CmResourceTypeDeviceSpecific 5
+ #define CmResourceTypeBusNumber 6
+ #define CmResourceTypeNonArbitrated 128
+ #define CmResourceTypeConfigData 128
+ #define CmResourceTypeDevicePrivate 129
+ #define CmResourceTypePcCardConfig 130
+ #define CmResourceTypeMfCardConfig 131
+
+ typedef enum _INTERFACE_TYPE {
+ InterfaceTypeUndefined = -1,
+ Internal,
+ Isa,
+ Eisa,
+ MicroChannel,
+ TurboChannel,
+ PCIBus,
+ VMEBus,
+ NuBus,
+ PCMCIABus,
+ CBus,
+ MPIBus,
+ MPSABus,
+ ProcessorInternal,
+ InternalPowerBus,
+ PNPISABus,
+ PNPBus,
+ MaximumInterfaceType
+ } INTERFACE_TYPE, *PINTERFACE_TYPE;
+
+ /* IO_RESOURCE_DESCRIPTOR.Option */
+
+ #define IO_RESOURCE_PREFERRED 0x01
+ #define IO_RESOURCE_DEFAULT 0x02
+ #define IO_RESOURCE_ALTERNATIVE 0x08
+
+ typedef struct _IO_RESOURCE_DESCRIPTOR {
+ UCHAR Option;
+ UCHAR Type;
+ UCHAR ShareDisposition;
+ UCHAR Spare1;
+ USHORT Flags;
+ USHORT Spare2;
+ union {
+ struct {
+ ULONG Length;
+ ULONG Alignment;
+ PHYSICAL_ADDRESS MinimumAddress;
+ PHYSICAL_ADDRESS MaximumAddress;
+ } Port;
+ struct {
+ ULONG Length;
+ ULONG Alignment;
+ PHYSICAL_ADDRESS MinimumAddress;
+ PHYSICAL_ADDRESS MaximumAddress;
+ } Memory;
+ struct {
+ ULONG MinimumVector;
+ ULONG MaximumVector;
+ } Interrupt;
+ struct {
+ ULONG MinimumChannel;
+ ULONG MaximumChannel;
+ } Dma;
+ struct {
+ ULONG Length;
+ ULONG Alignment;
+ PHYSICAL_ADDRESS MinimumAddress;
+ PHYSICAL_ADDRESS MaximumAddress;
+ } Generic;
+ struct {
+ ULONG Data[3];
+ } DevicePrivate;
+ struct {
+ ULONG Length;
+ ULONG MinBusNumber;
+ ULONG MaxBusNumber;
+ ULONG Reserved;
+ } BusNumber;
+ struct {
+ ULONG Priority;
+ ULONG Reserved1;
+ ULONG Reserved2;
+ } ConfigData;
+ } u;
+ } IO_RESOURCE_DESCRIPTOR, *PIO_RESOURCE_DESCRIPTOR;
+
+ typedef struct _IO_RESOURCE_LIST {
+ USHORT Version;
+ USHORT Revision;
+ ULONG Count;
+ IO_RESOURCE_DESCRIPTOR Descriptors[1];
+ } IO_RESOURCE_LIST, *PIO_RESOURCE_LIST;
+
+ typedef struct _IO_RESOURCE_REQUIREMENTS_LIST {
+ ULONG ListSize;
+ INTERFACE_TYPE InterfaceType;
+ ULONG BusNumber;
+ ULONG SlotNumber;
+ ULONG Reserved[3];
+ ULONG AlternativeLists;
+ IO_RESOURCE_LIST List[1];
+ } IO_RESOURCE_REQUIREMENTS_LIST, *PIO_RESOURCE_REQUIREMENTS_LIST;
+
+ //
+ // Global debug flag
+ //
+ extern ULONG NtGlobalFlag;
+
+
+ #include <pshpack4.h>
+ typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR {
+ UCHAR Type;
+ UCHAR ShareDisposition;
+ USHORT Flags;
+ union {
+ struct {
+ PHYSICAL_ADDRESS Start;
+ ULONG Length;
+ } Generic;
+ struct {
+ PHYSICAL_ADDRESS Start;
+ ULONG Length;
+ } Port;
+ struct {
+ ULONG Level;
+ ULONG Vector;
+ KAFFINITY Affinity;
+ } Interrupt;
+ #if (NTDDI_VERSION >= NTDDI_LONGHORN)
+ struct {
+ union {
+ struct {
+ USHORT Reserved;
+ USHORT MessageCount;
+ ULONG Vector;
+ KAFFINITY Affinity;
+ } Raw;
+ struct {
+ ULONG Level;
+ ULONG Vector;
+ KAFFINITY Affinity;
+ } Translated;
+ };
+ } MessageInterrupt;
+ #endif
+ struct {
+ PHYSICAL_ADDRESS Start;
+ ULONG Length;
+ } Memory;
+ struct {
+ ULONG Channel;
+ ULONG Port;
+ ULONG Reserved1;
+ } Dma;
+ struct {
+ ULONG Data[3];
+ } DevicePrivate;
+ struct {
+ ULONG Start;
+ ULONG Length;
+ ULONG Reserved;
+ } BusNumber;
+ struct {
+ ULONG DataSize;
+ ULONG Reserved1;
+ ULONG Reserved2;
+ } DeviceSpecificData;
+ #if (NTDDI_VERSION >= NTDDI_LONGHORN)
+ struct {
+ PHYSICAL_ADDRESS Start;
+ ULONG Length40;
+ } Memory40;
+ struct {
+ PHYSICAL_ADDRESS Start;
+ ULONG Length48;
+ } Memory48;
+ struct {
+ PHYSICAL_ADDRESS Start;
+ ULONG Length64;
+ } Memory64;
+ #endif
+ } u;
+ } CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;
+ #include <poppack.h>
+
+ //
+ // Section map options
+ //
+ typedef enum _SECTION_INHERIT {
+ ViewShare = 1,
+ ViewUnmap = 2
+ } SECTION_INHERIT;
+
+ //
+ // Section access rights
+ //
+ #define SECTION_QUERY 0x0001
+ #define SECTION_MAP_WRITE 0x0002
+ #define SECTION_MAP_READ 0x0004
+ #define SECTION_MAP_EXECUTE 0x0008
+ #define SECTION_EXTEND_SIZE 0x0010
+ #define SECTION_MAP_EXECUTE_EXPLICIT 0x0020
+
+ #define SECTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SECTION_QUERY|\
+ SECTION_MAP_WRITE | \
+ SECTION_MAP_READ | \
+ SECTION_MAP_EXECUTE | \
+ SECTION_EXTEND_SIZE)
+
+ #define SESSION_QUERY_ACCESS 0x0001
+ #define SESSION_MODIFY_ACCESS 0x0002
+
+ #define SESSION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | \
+ SESSION_QUERY_ACCESS | \
+ SESSION_MODIFY_ACCESS)
+
+
+
+ #define SEGMENT_ALL_ACCESS SECTION_ALL_ACCESS
+
+ #define PAGE_NOACCESS 0x01
+ #define PAGE_READONLY 0x02
+ #define PAGE_READWRITE 0x04
+ #define PAGE_WRITECOPY 0x08
+ #define PAGE_EXECUTE 0x10
+ #define PAGE_EXECUTE_READ 0x20
+ #define PAGE_EXECUTE_READWRITE 0x40
+ #define PAGE_EXECUTE_WRITECOPY 0x80
+ #define PAGE_GUARD 0x100
+ #define PAGE_NOCACHE 0x200
+ #define PAGE_WRITECOMBINE 0x400
+
+ #define MEM_COMMIT 0x1000
+ #define MEM_RESERVE 0x2000
+ #define MEM_DECOMMIT 0x4000
+ #define MEM_RELEASE 0x8000
+ #define MEM_FREE 0x10000
+ #define MEM_PRIVATE 0x20000
+ #define MEM_MAPPED 0x40000
+ #define MEM_RESET 0x80000
+ #define MEM_TOP_DOWN 0x100000
+ #define MEM_LARGE_PAGES 0x20000000
+ #define MEM_4MB_PAGES 0x80000000
+
+ #define SEC_RESERVE 0x4000000
+ #define SEC_LARGE_PAGES 0x80000000
+
+ #define PROCESS_DUP_HANDLE (0x0040)
+
+ #if (NTDDI_VERSION >= NTDDI_VISTA)
+ #define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
+ 0xFFFF)
+ #else
+ #define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
+ 0xFFF)
+ #endif
+
+
+
+ //
+ // Processor features
+ //
+ #define PF_FLOATING_POINT_PRECISION_ERRATA 0
+ #define PF_FLOATING_POINT_EMULATED 1
+ #define PF_COMPARE_EXCHANGE_DOUBLE 2
+ #define PF_MMX_INSTRUCTIONS_AVAILABLE 3
+ #define PF_PPC_MOVEMEM_64BIT_OK 4
+ #define PF_ALPHA_BYTE_INSTRUCTIONS 5
+ #define PF_XMMI_INSTRUCTIONS_AVAILABLE 6
+ #define PF_3DNOW_INSTRUCTIONS_AVAILABLE 7
+ #define PF_RDTSC_INSTRUCTION_AVAILABLE 8
+ #define PF_PAE_ENABLED 9
+ #define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10
+ #define PF_SSE_DAZ_MODE_AVAILABLE 11
+ #define PF_NX_ENABLED 12
+ #define PF_SSE3_INSTRUCTIONS_AVAILABLE 13
+ #define PF_COMPARE_EXCHANGE128 14
+ #define PF_COMPARE64_EXCHANGE128 15
+ #define PF_CHANNELS_ENABLED 16
+
+
+
+ //
+ // Intrinsics (note: taken from our winnt.h)
+ // FIXME: 64-bit
+ //
+ #if defined(__GNUC__)
+
+ static __inline__ BOOLEAN
+ InterlockedBitTestAndSet(IN LONG volatile *Base,
+ IN LONG Bit)
+ {
+ #if defined(_M_IX86)
+ LONG OldBit;
+ __asm__ __volatile__("lock "
+ "btsl %2,%1\n\t"
+ "sbbl %0,%0\n\t"
+ :"=r" (OldBit),"+m" (*Base)
+ :"Ir" (Bit)
+ : "memory");
+ return OldBit;
+ #else
+ return (_InterlockedOr(Base, 1 << Bit) >> Bit) & 1;
+ #endif
+ }
+
+ static __inline__ BOOLEAN
+ InterlockedBitTestAndReset(IN LONG volatile *Base,
+ IN LONG Bit)
+ {
+ #if defined(_M_IX86)
+ LONG OldBit;
+ __asm__ __volatile__("lock "
+ "btrl %2,%1\n\t"
+ "sbbl %0,%0\n\t"
+ :"=r" (OldBit),"+m" (*Base)
+ :"Ir" (Bit)
+ : "memory");
+ return OldBit;
+ #else
+ return (_InterlockedAnd(Base, ~(1 << Bit)) >> Bit) & 1;
+ #endif
+ }
+
+ #endif
+
+ #define BitScanForward _BitScanForward
+ #define BitScanReverse _BitScanReverse
+
+ #define BitTest _bittest
+ #define BitTestAndComplement _bittestandcomplement
+ #define BitTestAndSet _bittestandset
+ #define BitTestAndReset _bittestandreset
+ #define InterlockedBitTestAndSet _interlockedbittestandset
+ #define InterlockedBitTestAndReset _interlockedbittestandreset
+
+
+ /** INTERLOCKED FUNCTIONS *****************************************************/
+
+ #if !defined(__INTERLOCKED_DECLARED)
+ #define __INTERLOCKED_DECLARED
+
+ #if defined (_X86_)
+ #if defined(NO_INTERLOCKED_INTRINSICS)
+ NTKERNELAPI
+ LONG
+ FASTCALL
+ InterlockedIncrement(
+ IN OUT LONG volatile *Addend);
+
+ NTKERNELAPI
+ LONG
+ FASTCALL
+ InterlockedDecrement(
+ IN OUT LONG volatile *Addend);
+
+ NTKERNELAPI
+ LONG
+ FASTCALL
+ InterlockedCompareExchange(
+ IN OUT LONG volatile *Destination,
+ IN LONG Exchange,
+ IN LONG Comparand);
+
+ NTKERNELAPI
+ LONG
+ FASTCALL
+ InterlockedExchange(
+ IN OUT LONG volatile *Destination,
+ IN LONG Value);
+
+ NTKERNELAPI
+ LONG
+ FASTCALL
+ InterlockedExchangeAdd(
+ IN OUT LONG volatile *Addend,
+ IN LONG Value);
+
+ #else // !defined(NO_INTERLOCKED_INTRINSICS)
+
+ #define InterlockedExchange _InterlockedExchange
+ #define InterlockedIncrement _InterlockedIncrement
+ #define InterlockedDecrement _InterlockedDecrement
+ #define InterlockedExchangeAdd _InterlockedExchangeAdd
+ #define InterlockedCompareExchange _InterlockedCompareExchange
+ #define InterlockedOr _InterlockedOr
+ #define InterlockedAnd _InterlockedAnd
+ #define InterlockedXor _InterlockedXor
+
+ #endif // !defined(NO_INTERLOCKED_INTRINSICS)
+
+ #endif // defined (_X86_)
+
+ #if !defined (_WIN64)
+ /*
+ * PVOID
+ * InterlockedExchangePointer(
+ * IN OUT PVOID volatile *Target,
+ * IN PVOID Value)
+ */
+ #define InterlockedExchangePointer(Target, Value) \
+ ((PVOID) InterlockedExchange((PLONG) Target, (LONG) Value))
+
+ /*
+ * PVOID
+ * InterlockedCompareExchangePointer(
+ * IN OUT PVOID *Destination,
+ * IN PVOID Exchange,
+ * IN PVOID Comparand)
+ */
+ #define InterlockedCompareExchangePointer(Destination, Exchange, Comparand) \
+ ((PVOID) InterlockedCompareExchange((PLONG) Destination, (LONG) Exchange, (LONG) Comparand))
+
+ #define InterlockedExchangeAddSizeT(a, b) InterlockedExchangeAdd((LONG *)a, b)
+ #define InterlockedIncrementSizeT(a) InterlockedIncrement((LONG *)a)
+ #define InterlockedDecrementSizeT(a) InterlockedDecrement((LONG *)a)
+
+ #endif // !defined (_WIN64)
+
+ #if defined (_M_AMD64)
+
+ #define InterlockedExchangeAddSizeT(a, b) InterlockedExchangeAdd64((LONGLONG *)a, (LONGLONG)b)
+ #define InterlockedIncrementSizeT(a) InterlockedIncrement64((LONGLONG *)a)
+ #define InterlockedDecrementSizeT(a) InterlockedDecrement64((LONGLONG *)a)
+ #define InterlockedAnd _InterlockedAnd
+ #define InterlockedOr _InterlockedOr
+ #define InterlockedXor _InterlockedXor
+ #define InterlockedIncrement _InterlockedIncrement
+ #define InterlockedDecrement _InterlockedDecrement
+ #define InterlockedAdd _InterlockedAdd
+ #define InterlockedExchange _InterlockedExchange
+ #define InterlockedExchangeAdd _InterlockedExchangeAdd
+ #define InterlockedCompareExchange _InterlockedCompareExchange
+ #define InterlockedAnd64 _InterlockedAnd64
+ #define InterlockedOr64 _InterlockedOr64
+ #define InterlockedXor64 _InterlockedXor64
+ #define InterlockedIncrement64 _InterlockedIncrement64
+ #define InterlockedDecrement64 _InterlockedDecrement64
+ #define InterlockedAdd64 _InterlockedAdd64
+ #define InterlockedExchange64 _InterlockedExchange64
+ #define InterlockedExchangeAdd64 _InterlockedExchangeAdd64
+ #define InterlockedCompareExchange64 _InterlockedCompareExchange64
+ #define InterlockedCompareExchangePointer _InterlockedCompareExchangePointer
+ #define InterlockedExchangePointer _InterlockedExchangePointer
+ #define InterlockedBitTestAndSet64 _interlockedbittestandset64
+ #define InterlockedBitTestAndReset64 _interlockedbittestandreset64
+
+ #endif // _M_AMD64
+
+ #if defined(_M_AMD64) && !defined(RC_INVOKED) && !defined(MIDL_PASS)
+ //#if !defined(_X86AMD64_) // FIXME: what's _X86AMD64_ used for?
+ FORCEINLINE
+ LONG64
+ InterlockedAdd64(
+ IN OUT LONG64 volatile *Addend,
+ IN LONG64 Value)
+ {
+ return InterlockedExchangeAdd64(Addend, Value) + Value;
+ }
+ //#endif
++#define BitScanForward _BitScanForward
++#define BitScanReverse _BitScanReverse
++#endif
++
++#ifdef _M_AMD64
++#define InterlockedBitTestAndSet64 _interlockedbittestandset64
++#define InterlockedBitTestAndReset64 _interlockedbittestandreset64
+ #endif
+
+ #endif /* !__INTERLOCKED_DECLARED */
+
+ #if defined(_M_IX86)
+ #define YieldProcessor _mm_pause
+ #elif defined (_M_AMD64)
+ #define YieldProcessor _mm_pause
+ #elif defined(_M_PPC)
+ #define YieldProcessor() __asm__ __volatile__("nop");
+ #elif defined(_M_MIPS)
+ #define YieldProcessor() __asm__ __volatile__("nop");
+ #elif defined(_M_ARM)
+ #define YieldProcessor()
+ #else
+ #error Unknown architecture
+ #endif
+
+
+
+ //
+ // Slist Header
+ //
+ #ifndef _SLIST_HEADER_
+ #define _SLIST_HEADER_
+
+ #define SLIST_ENTRY SINGLE_LIST_ENTRY
+ #define _SLIST_ENTRY _SINGLE_LIST_ENTRY
+ #define PSLIST_ENTRY PSINGLE_LIST_ENTRY
+
+ #if defined(_WIN64)
-typedef union _SLIST_HEADER {
++typedef union DECLSPEC_ALIGN(16) _SLIST_HEADER {
+ struct {
+ ULONGLONG Alignment;
+ ULONGLONG Region;
+ } DUMMYSTRUCTNAME;
+ struct {
+ ULONGLONG Depth:16;
+ ULONGLONG Sequence:9;
+ ULONGLONG NextEntry:39;
+ ULONGLONG HeaderType:1;
+ ULONGLONG Init:1;
+ ULONGLONG Reserved:59;
+ ULONGLONG Region:3;
+ } Header8;
+ struct {
+ ULONGLONG Depth:16;
+ ULONGLONG Sequence:48;
+ ULONGLONG HeaderType:1;
+ ULONGLONG Init:1;
+ ULONGLONG Reserved:2;
+ ULONGLONG NextEntry:60;
+ } Header16;
+ } SLIST_HEADER, *PSLIST_HEADER;
+ #else
+ typedef union _SLIST_HEADER {
+ ULONGLONG Alignment;
+ struct {
+ SLIST_ENTRY Next;
+ USHORT Depth;
+ USHORT Sequence;
+ } DUMMYSTRUCTNAME;
+ } SLIST_HEADER, *PSLIST_HEADER;
+ #endif
+
+ #endif /* _SLIST_HEADER_ */
+
+
+
+ //
+ // Power States/Levels
+ //
+ typedef enum _SYSTEM_POWER_STATE {
+ PowerSystemUnspecified,
+ PowerSystemWorking,
+ PowerSystemSleeping1,
+ PowerSystemSleeping2,
+ PowerSystemSleeping3,
+ PowerSystemHibernate,
+ PowerSystemShutdown,
+ PowerSystemMaximum
+ } SYSTEM_POWER_STATE, *PSYSTEM_POWER_STATE;
+
+ #define POWER_SYSTEM_MAXIMUM PowerSystemMaximum
+
+ typedef enum _POWER_INFORMATION_LEVEL {
+ SystemPowerPolicyAc,
+ SystemPowerPolicyDc,
+ VerifySystemPolicyAc,
+ VerifySystemPolicyDc,
+ SystemPowerCapabilities,
+ SystemBatteryState,
+ SystemPowerStateHandler,
+ ProcessorStateHandler,
+ SystemPowerPolicyCurrent,
+ AdministratorPowerPolicy,
+ SystemReserveHiberFile,
+ ProcessorInformation,
+ SystemPowerInformation,
+ ProcessorStateHandler2,
+ LastWakeTime,
+ LastSleepTime,
+ SystemExecutionState,
+ SystemPowerStateNotifyHandler,
+ ProcessorPowerPolicyAc,
+ ProcessorPowerPolicyDc,
+ VerifyProcessorPowerPolicyAc,
+ VerifyProcessorPowerPolicyDc,
+ ProcessorPowerPolicyCurrent
+ } POWER_INFORMATION_LEVEL;
+
+ typedef enum {
+ PowerActionNone,
+ PowerActionReserved,
+ PowerActionSleep,
+ PowerActionHibernate,
+ PowerActionShutdown,
+ PowerActionShutdownReset,
+ PowerActionShutdownOff,
+ PowerActionWarmEject
+ } POWER_ACTION, *PPOWER_ACTION;
+
+ typedef enum _DEVICE_POWER_STATE {
+ PowerDeviceUnspecified,
+ PowerDeviceD0,
+ PowerDeviceD1,
+ PowerDeviceD2,
+ PowerDeviceD3,
+ PowerDeviceMaximum
+ } DEVICE_POWER_STATE, *PDEVICE_POWER_STATE;
+
+ #define ES_SYSTEM_REQUIRED 0x00000001
+ #define ES_DISPLAY_REQUIRED 0x00000002
+ #define ES_USER_PRESENT 0x00000004
+ #define ES_CONTINUOUS 0x80000000
+
+ typedef ULONG EXECUTION_STATE;
+
+ typedef enum {
+ LT_DONT_CARE,
+ LT_LOWEST_LATENCY
+ } LATENCY_TIME;
+
+
+
+ //
+ // Access/Security Stuff
+ //
+ typedef ULONG ACCESS_MASK, *PACCESS_MASK;
+ typedef PVOID PACCESS_TOKEN;
+
+ #define DELETE 0x00010000L
+ #define READ_CONTROL 0x00020000L
+ #define WRITE_DAC 0x00040000L
+ #define WRITE_OWNER 0x00080000L
+ #define SYNCHRONIZE 0x00100000L
+ #define STANDARD_RIGHTS_REQUIRED 0x000F0000L
+ #define STANDARD_RIGHTS_READ READ_CONTROL
+ #define STANDARD_RIGHTS_WRITE READ_CONTROL
+ #define STANDARD_RIGHTS_EXECUTE READ_CONTROL
+ #define STANDARD_RIGHTS_ALL 0x001F0000L
+ #define SPECIFIC_RIGHTS_ALL 0x0000FFFFL
+ #define ACCESS_SYSTEM_SECURITY 0x01000000L
+ #define MAXIMUM_ALLOWED 0x02000000L
+ #define GENERIC_READ 0x80000000L
+ #define GENERIC_WRITE 0x40000000L
+ #define GENERIC_EXECUTE 0x20000000L
+ #define GENERIC_ALL 0x10000000L
+
+ typedef struct _GENERIC_MAPPING {
+ ACCESS_MASK GenericRead;
+ ACCESS_MASK GenericWrite;
+ ACCESS_MASK GenericExecute;
+ ACCESS_MASK GenericAll;
+ } GENERIC_MAPPING, *PGENERIC_MAPPING;
+
+ #define ACL_REVISION 2
+ #define ACL_REVISION_DS 4
+
+ #define ACL_REVISION1 1
+ #define ACL_REVISION2 2
+ #define ACL_REVISION3 3
+ #define ACL_REVISION4 4
+ #define MIN_ACL_REVISION ACL_REVISION2
+ #define MAX_ACL_REVISION ACL_REVISION4
+
+ typedef struct _ACL {
+ UCHAR AclRevision;
+ UCHAR Sbz1;
+ USHORT AclSize;
+ USHORT AceCount;
+ USHORT Sbz2;
+ } ACL, *PACL;
+
+
+
+ //
+ // Current security descriptor revision value
+ //
+ #define SECURITY_DESCRIPTOR_REVISION (1)
+ #define SECURITY_DESCRIPTOR_REVISION1 (1)
+
+ //
+ // Privilege attributes
+ //
+ #define SE_PRIVILEGE_ENABLED_BY_DEFAULT (0x00000001L)
+ #define SE_PRIVILEGE_ENABLED (0x00000002L)
+ #define SE_PRIVILEGE_REMOVED (0X00000004L)
+ #define SE_PRIVILEGE_USED_FOR_ACCESS (0x80000000L)
+
+ #define SE_PRIVILEGE_VALID_ATTRIBUTES (SE_PRIVILEGE_ENABLED_BY_DEFAULT | \
+ SE_PRIVILEGE_ENABLED | \
+ SE_PRIVILEGE_REMOVED | \
+ SE_PRIVILEGE_USED_FOR_ACCESS)
+
+ #include <pshpack4.h>
+ typedef struct _LUID_AND_ATTRIBUTES {
+ LUID Luid;
+ ULONG Attributes;
+ } LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
+ #include <poppack.h>
+ typedef LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY];
+ typedef LUID_AND_ATTRIBUTES_ARRAY *PLUID_AND_ATTRIBUTES_ARRAY;
+
+
+
+ //
+ // Privilege sets
+ //
+ #define PRIVILEGE_SET_ALL_NECESSARY (1)
+
+ typedef struct _PRIVILEGE_SET {
+ ULONG PrivilegeCount;
+ ULONG Control;
+ LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];
+ } PRIVILEGE_SET,*PPRIVILEGE_SET;
+
+ typedef enum _SECURITY_IMPERSONATION_LEVEL {
+ SecurityAnonymous,
+ SecurityIdentification,
+ SecurityImpersonation,
+ SecurityDelegation
+ } SECURITY_IMPERSONATION_LEVEL, * PSECURITY_IMPERSONATION_LEVEL;
+
+ #define SECURITY_MAX_IMPERSONATION_LEVEL SecurityDelegation
+ #define SECURITY_MIN_IMPERSONATION_LEVEL SecurityAnonymous
+ #define DEFAULT_IMPERSONATION_LEVEL SecurityImpersonation
+ #define VALID_IMPERSONATION_LEVEL(Level) (((Level) >= SECURITY_MIN_IMPERSONATION_LEVEL) && ((Level) <= SECURITY_MAX_IMPERSONATION_LEVEL))
+
+ #define SECURITY_DYNAMIC_TRACKING (TRUE)
+ #define SECURITY_STATIC_TRACKING (FALSE)
+
+ typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, *PSECURITY_CONTEXT_TRACKING_MODE;
+
+ typedef struct _SECURITY_QUALITY_OF_SERVICE {
+ ULONG Length;
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
+ SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;
+ BOOLEAN EffectiveOnly;
+ } SECURITY_QUALITY_OF_SERVICE, *PSECURITY_QUALITY_OF_SERVICE;
+
+ typedef struct _SE_IMPERSONATION_STATE {
+ PACCESS_TOKEN Token;
+ BOOLEAN CopyOnOpen;
+ BOOLEAN EffectiveOnly;
+ SECURITY_IMPERSONATION_LEVEL Level;
+ } SE_IMPERSONATION_STATE, *PSE_IMPERSONATION_STATE;
+
+ #define OWNER_SECURITY_INFORMATION (0x00000001L)
+ #define GROUP_SECURITY_INFORMATION (0x00000002L)
+ #define DACL_SECURITY_INFORMATION (0x00000004L)
+ #define SACL_SECURITY_INFORMATION (0x00000008L)
+ #define LABEL_SECURITY_INFORMATION (0x00000010L)
+
+ #define PROTECTED_DACL_SECURITY_INFORMATION (0x80000000L)
+ #define PROTECTED_SACL_SECURITY_INFORMATION (0x40000000L)
+ #define UNPROTECTED_DACL_SECURITY_INFORMATION (0x20000000L)
+ #define UNPROTECTED_SACL_SECURITY_INFORMATION (0x10000000L)
+
+
+
+ //
+ // Registry Access Rights
+ //
+ #define KEY_QUERY_VALUE (0x0001)
+ #define KEY_SET_VALUE (0x0002)
+ #define KEY_CREATE_SUB_KEY (0x0004)
+ #define KEY_ENUMERATE_SUB_KEYS (0x0008)
+ #define KEY_NOTIFY (0x0010)
+ #define KEY_CREATE_LINK (0x0020)
+ #define KEY_WOW64_32KEY (0x0200)
+ #define KEY_WOW64_64KEY (0x0100)
+ #define KEY_WOW64_RES (0x0300)
+
+ #define KEY_READ ((STANDARD_RIGHTS_READ |\
+ KEY_QUERY_VALUE |\
+ KEY_ENUMERATE_SUB_KEYS |\
+ KEY_NOTIFY) \
+ & \
+ (~SYNCHRONIZE))
+
+ #define KEY_WRITE ((STANDARD_RIGHTS_WRITE |\
+ KEY_SET_VALUE |\
+ KEY_CREATE_SUB_KEY) \
+ & \
+ (~SYNCHRONIZE))
+
+ #define KEY_EXECUTE ((KEY_READ) \
+ & \
+ (~SYNCHRONIZE))
+
+ #define KEY_ALL_ACCESS ((STANDARD_RIGHTS_ALL |\
+ KEY_QUERY_VALUE |\
+ KEY_SET_VALUE |\
+ KEY_CREATE_SUB_KEY |\
+ KEY_ENUMERATE_SUB_KEYS |\
+ KEY_NOTIFY |\
+ KEY_CREATE_LINK) \
+ & \
+ (~SYNCHRONIZE))
+
+ //
+ // Registry Open/Create Options
+ //
+ #define REG_OPTION_RESERVED (0x00000000L)
+ #define REG_OPTION_NON_VOLATILE (0x00000000L)
+ #define REG_OPTION_VOLATILE (0x00000001L)
+ #define REG_OPTION_CREATE_LINK (0x00000002L)
+ #define REG_OPTION_BACKUP_RESTORE (0x00000004L)
+ #define REG_OPTION_OPEN_LINK (0x00000008L)
+
+ #define REG_LEGAL_OPTION \
+ (REG_OPTION_RESERVED |\
+ REG_OPTION_NON_VOLATILE |\
+ REG_OPTION_VOLATILE |\
+ REG_OPTION_CREATE_LINK |\
+ REG_OPTION_BACKUP_RESTORE |\
+ REG_OPTION_OPEN_LINK)
+
+ //
+ // Key creation/open disposition
+ //
+ #define REG_CREATED_NEW_KEY (0x00000001L)
+ #define REG_OPENED_EXISTING_KEY (0x00000002L)
+
+ //
+ // Key restore & hive load flags
+ //
+ #define REG_WHOLE_HIVE_VOLATILE (0x00000001L)
+ #define REG_REFRESH_HIVE (0x00000002L)
+ #define REG_NO_LAZY_FLUSH (0x00000004L)
+ #define REG_FORCE_RESTORE (0x00000008L)
+ #define REG_APP_HIVE (0x00000010L)
+ #define REG_PROCESS_PRIVATE (0x00000020L)
+ #define REG_START_JOURNAL (0x00000040L)
+ #define REG_HIVE_EXACT_FILE_GROWTH (0x00000080L)
+ #define REG_HIVE_NO_RM (0x00000100L)
+ #define REG_HIVE_SINGLE_LOG (0x00000200L)
+
+ //
+ // Unload Flags
+ //
+ #define REG_FORCE_UNLOAD 1
+
+ //
+ // Notify Filter Values
+ //
+ #define REG_NOTIFY_CHANGE_NAME (0x00000001L)
+ #define REG_NOTIFY_CHANGE_ATTRIBUTES (0x00000002L)
+ #define REG_NOTIFY_CHANGE_LAST_SET (0x00000004L)
+ #define REG_NOTIFY_CHANGE_SECURITY (0x00000008L)
+
+ #define REG_LEGAL_CHANGE_FILTER \
+ (REG_NOTIFY_CHANGE_NAME |\
+ REG_NOTIFY_CHANGE_ATTRIBUTES |\
+ REG_NOTIFY_CHANGE_LAST_SET |\
+ REG_NOTIFY_CHANGE_SECURITY)
+
+
+
+ //
+ // Thread Access Rights
+ //
+ #define THREAD_TERMINATE (0x0001)
+ #define THREAD_SUSPEND_RESUME (0x0002)
+ #define THREAD_ALERT (0x0004)
+ #define THREAD_GET_CONTEXT (0x0008)
+ #define THREAD_SET_CONTEXT (0x0010)
+ #define THREAD_SET_INFORMATION (0x0020)
+ #define THREAD_SET_LIMITED_INFORMATION (0x0400)
+ #define THREAD_QUERY_LIMITED_INFORMATION (0x0800)
+ #if (NTDDI_VERSION >= NTDDI_VISTA)
+ #define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
+ 0xFFFF)
+ #else
+ #define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
+ 0x3FF)
+ #endif
+
+ //
+ // Service Start Types
+ //
+ #define SERVICE_BOOT_START 0x00000000
+ #define SERVICE_SYSTEM_START 0x00000001
+ #define SERVICE_AUTO_START 0x00000002
+ #define SERVICE_DEMAND_START 0x00000003
+ #define SERVICE_DISABLED 0x00000004
+
+ //
+ // Exception Records
+ //
+ #define EXCEPTION_NONCONTINUABLE 1
+ #define EXCEPTION_MAXIMUM_PARAMETERS 15
+
+ typedef struct _EXCEPTION_RECORD {
+ NTSTATUS ExceptionCode;
+ ULONG ExceptionFlags;
+ struct _EXCEPTION_RECORD *ExceptionRecord;
+ PVOID ExceptionAddress;
+ ULONG NumberParameters;
+ ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
+ } EXCEPTION_RECORD, *PEXCEPTION_RECORD;
+
+ typedef struct _EXCEPTION_RECORD32 {
+ NTSTATUS ExceptionCode;
+ ULONG ExceptionFlags;
+ ULONG ExceptionRecord;
+ ULONG ExceptionAddress;
+ ULONG NumberParameters;
+ ULONG ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
+ } EXCEPTION_RECORD32, *PEXCEPTION_RECORD32;
+
+ typedef struct _EXCEPTION_RECORD64 {
+ NTSTATUS ExceptionCode;
+ ULONG ExceptionFlags;
+ ULONG64 ExceptionRecord;
+ ULONG64 ExceptionAddress;
+ ULONG NumberParameters;
+ ULONG __unusedAlignment;
+ ULONG64 ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
+ } EXCEPTION_RECORD64, *PEXCEPTION_RECORD64;
+
+ typedef struct _EXCEPTION_POINTERS {
+ PEXCEPTION_RECORD ExceptionRecord;
+ PCONTEXT ContextRecord;
+ } EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
+
+
+
+ //
+ // Process Qoutas
+ //
+ typedef struct _QUOTA_LIMITS {
+ SIZE_T PagedPoolLimit;
+ SIZE_T NonPagedPoolLimit;
+ SIZE_T MinimumWorkingSetSize;
+ SIZE_T MaximumWorkingSetSize;
+ SIZE_T PagefileLimit;
+ LARGE_INTEGER TimeLimit;
+ } QUOTA_LIMITS, *PQUOTA_LIMITS;
+
+ #define QUOTA_LIMITS_HARDWS_MIN_ENABLE 0x00000001
+ #define QUOTA_LIMITS_HARDWS_MIN_DISABLE 0x00000002
+ #define QUOTA_LIMITS_HARDWS_MAX_ENABLE 0x00000004
+ #define QUOTA_LIMITS_HARDWS_MAX_DISABLE 0x00000008
+ #define QUOTA_LIMITS_USE_DEFAULT_LIMITS 0x00000010
+
+
+ /******************************************************************************
+ * WINBASE Functions *
+ ******************************************************************************/
+ #if !defined(_WINBASE_)
+
+ #if defined(_WIN64)
+
+ #define InterlockedPopEntrySList(Head) \
+ ExpInterlockedPopEntrySList(Head)
+
+ #define InterlockedPushEntrySList(Head, Entry) \
+ ExpInterlockedPushEntrySList(Head, Entry)
+
+ #define InterlockedFlushSList(Head) \
+ ExpInterlockedFlushSList(Head)
+
+ #define QueryDepthSList(Head) \
+ ExQueryDepthSList(Head)
+
+ #else // !defined(_WIN64)
+
+ NTKERNELAPI
+ PSLIST_ENTRY
+ FASTCALL
+ InterlockedPopEntrySList(
+ IN PSLIST_HEADER ListHead);
+
+ NTKERNELAPI
+ PSLIST_ENTRY
+ FASTCALL
+ InterlockedPushEntrySList(
+ IN PSLIST_HEADER ListHead,
+ IN PSLIST_ENTRY ListEntry);
+
+ #define InterlockedFlushSList(ListHead) \
+ ExInterlockedFlushSList(ListHead)
+
+ #define QueryDepthSList(Head) \
+ ExQueryDepthSList(Head)
+
+ #endif // !defined(_WIN64)
+
+ #endif // !defined(_WINBASE_)
+
+
+ /******************************************************************************
+ * Kernel Types *
+ ******************************************************************************/
+
+ typedef struct _DISPATCHER_HEADER
+ {
+ union
+ {
+ struct
+ {
+ UCHAR Type;
+ union
+ {
+ UCHAR Absolute;
+ UCHAR NpxIrql;
+ };
+ union
+ {
+ UCHAR Size;
+ UCHAR Hand;
+ };
+ union
+ {
+ UCHAR Inserted;
+ BOOLEAN DebugActive;
+ };
+ };
+ volatile LONG Lock;
+ };
+ LONG SignalState;
+ LIST_ENTRY WaitListHead;
+ } DISPATCHER_HEADER, *PDISPATCHER_HEADER;
+
+ typedef ULONG_PTR KSPIN_LOCK, *PKSPIN_LOCK;
+
+ typedef struct _KEVENT {
+ DISPATCHER_HEADER Header;
+ } KEVENT, *PKEVENT, *RESTRICTED_POINTER PRKEVENT;
+
+ typedef struct _KSEMAPHORE {
+ DISPATCHER_HEADER Header;
+ LONG Limit;
+ } KSEMAPHORE, *PKSEMAPHORE, *RESTRICTED_POINTER PRKSEMAPHORE;
+
+ /******************************************************************************
+ * RTL Types *
+ ******************************************************************************/
+
+ #define RTL_REGISTRY_ABSOLUTE 0
+ #define RTL_REGISTRY_SERVICES 1
+ #define RTL_REGISTRY_CONTROL 2
+ #define RTL_REGISTRY_WINDOWS_NT 3
+ #define RTL_REGISTRY_DEVICEMAP 4
+ #define RTL_REGISTRY_USER 5
+ #define RTL_REGISTRY_MAXIMUM 6
+ #define RTL_REGISTRY_HANDLE 0x40000000
+ #define RTL_REGISTRY_OPTIONAL 0x80000000
+
+ /* RTL_QUERY_REGISTRY_TABLE.Flags */
+ #define RTL_QUERY_REGISTRY_SUBKEY 0x00000001
+ #define RTL_QUERY_REGISTRY_TOPKEY 0x00000002
+ #define RTL_QUERY_REGISTRY_REQUIRED 0x00000004
+ #define RTL_QUERY_REGISTRY_NOVALUE 0x00000008
+ #define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010
+ #define RTL_QUERY_REGISTRY_DIRECT 0x00000020
+ #define RTL_QUERY_REGISTRY_DELETE 0x00000040
+
+ typedef struct _RTL_BITMAP {
+ ULONG SizeOfBitMap;
+ PULONG Buffer;
+ } RTL_BITMAP, *PRTL_BITMAP;
+
+ typedef struct _RTL_BITMAP_RUN {
+ ULONG StartingIndex;
+ ULONG NumberOfBits;
+ } RTL_BITMAP_RUN, *PRTL_BITMAP_RUN;
+
+ typedef NTSTATUS
+ (DDKAPI *PRTL_QUERY_REGISTRY_ROUTINE)(
+ IN PWSTR ValueName,
+ IN ULONG ValueType,
+ IN PVOID ValueData,
+ IN ULONG ValueLength,
+ IN PVOID Context,
+ IN PVOID EntryContext);
+
+ typedef struct _RTL_QUERY_REGISTRY_TABLE {
+ PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
+ ULONG Flags;
+ PCWSTR Name;
+ PVOID EntryContext;
+ ULONG DefaultType;
+ PVOID DefaultData;
+ ULONG DefaultLength;
+ } RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;
+
+ typedef struct _TIME_FIELDS {
+ CSHORT Year;
+ CSHORT Month;
+ CSHORT Day;
+ CSHORT Hour;
+ CSHORT Minute;
+ CSHORT Second;
+ CSHORT Milliseconds;
+ CSHORT Weekday;
+ } TIME_FIELDS, *PTIME_FIELDS;
+
+
+ /******************************************************************************
+ * RTL Functions *
+ ******************************************************************************/
+
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlAssert(
+ IN PVOID FailedAssertion,
+ IN PVOID FileName,
+ IN ULONG LineNumber,
+ IN PCHAR Message);
+
+ /* VOID
+ * RtlCopyMemory(
+ * IN VOID UNALIGNED *Destination,
+ * IN CONST VOID UNALIGNED *Source,
+ * IN SIZE_T Length)
+ */
+ #define RtlCopyMemory(Destination, Source, Length) \
+ memcpy(Destination, Source, Length)
+
+ #define RtlCopyBytes RtlCopyMemory
+
+ #if defined(_M_AMD64)
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlCopyMemoryNonTemporal(
+ VOID UNALIGNED *Destination,
+ CONST VOID UNALIGNED *Source,
+ SIZE_T Length);
+ #else
+ #define RtlCopyMemoryNonTemporal RtlCopyMemory
+ #endif
+
+ /* BOOLEAN
+ * RtlEqualLuid(
+ * IN PLUID Luid1,
+ * IN PLUID Luid2)
+ */
+ #define RtlEqualLuid(Luid1, Luid2) \
+ (((Luid1)->LowPart == (Luid2)->LowPart) && ((Luid1)->HighPart == (Luid2)->HighPart))
+
+ /* ULONG
+ * RtlEqualMemory(
+ * IN VOID UNALIGNED *Destination,
+ * IN CONST VOID UNALIGNED *Source,
+ * IN SIZE_T Length)
+ */
+ #define RtlEqualMemory(Destination, Source, Length) \
+ (!memcmp(Destination, Source, Length))
+
+ /* VOID
+ * RtlFillMemory(
+ * IN VOID UNALIGNED *Destination,
+ * IN SIZE_T Length,
+ * IN UCHAR Fill)
+ */
+ #define RtlFillMemory(Destination, Length, Fill) \
+ memset(Destination, Fill, Length)
+
+ #define RtlFillBytes RtlFillMemory
+
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlFreeUnicodeString(
+ IN PUNICODE_STRING UnicodeString);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlGUIDFromString(
+ IN PUNICODE_STRING GuidString,
+ OUT GUID *Guid);
+
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlInitUnicodeString(
+ IN OUT PUNICODE_STRING DestinationString,
+ IN PCWSTR SourceString);
+
+ /* VOID
+ * RtlMoveMemory(
+ * IN VOID UNALIGNED *Destination,
+ * IN CONST VOID UNALIGNED *Source,
+ * IN SIZE_T Length)
+ */
+ #define RtlMoveMemory(Destination, Source, Length) \
+ memmove(Destination, Source, Length)
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlStringFromGUID(
+ IN REFGUID Guid,
+ OUT PUNICODE_STRING GuidString);
+
+ /* VOID
+ * RtlZeroMemory(
+ * IN VOID UNALIGNED *Destination,
+ * IN SIZE_T Length)
+ */
+ #define RtlZeroMemory(Destination, Length) \
+ memset(Destination, 0, Length)
+
+ #define RtlZeroBytes RtlZeroMemory
+
+
+ #if (NTDDI_VERSION >= NTDDI_WIN2K)
+ NTSYSAPI
+ BOOLEAN
+ NTAPI
+ RtlAreBitsClear(
+ IN PRTL_BITMAP BitMapHeader,
+ IN ULONG StartingIndex,
+ IN ULONG Length);
+
+ NTSYSAPI
+ BOOLEAN
+ NTAPI
+ RtlAreBitsSet(
+ IN PRTL_BITMAP BitMapHeader,
+ IN ULONG StartingIndex,
+ IN ULONG Length);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlAnsiStringToUnicodeString(
+ IN OUT PUNICODE_STRING DestinationString,
+ IN PANSI_STRING SourceString,
+ IN BOOLEAN AllocateDestinationString);
+
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlxAnsiStringToUnicodeSize(
+ IN PCANSI_STRING AnsiString);
+
+ #define RtlAnsiStringToUnicodeSize(String) ( \
+ NLS_MB_CODE_PAGE_TAG ? \
+ RtlxAnsiStringToUnicodeSize(String) : \
+ ((String)->Length + sizeof(ANSI_NULL)) * sizeof(WCHAR) \
+ )
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlAppendUnicodeStringToString(
+ IN OUT PUNICODE_STRING Destination,
+ IN PCUNICODE_STRING Source);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlAppendUnicodeToString(
+ IN OUT PUNICODE_STRING Destination,
+ IN PCWSTR Source);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlCheckRegistryKey(
+ IN ULONG RelativeTo,
+ IN PWSTR Path);
+
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlClearAllBits(
+ IN PRTL_BITMAP BitMapHeader);
+
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlClearBits(
+ IN PRTL_BITMAP BitMapHeader,
+ IN ULONG StartingIndex,
+ IN ULONG NumberToClear);
+
+ NTSYSAPI
+ SIZE_T
+ NTAPI
+ RtlCompareMemory(
+ IN CONST VOID *Source1,
+ IN CONST VOID *Source2,
+ IN SIZE_T Length);
+
+ NTSYSAPI
+ LONG
+ NTAPI
+ RtlCompareUnicodeString(
+ IN PCUNICODE_STRING String1,
+ IN PCUNICODE_STRING String2,
+ IN BOOLEAN CaseInSensitive);
+
+ NTSYSAPI
+ LONG
+ NTAPI
+ RtlCompareUnicodeStrings(
+ IN PCWCH String1,
+ IN SIZE_T String1Length,
+ IN PCWCH String2,
+ IN SIZE_T String2Length,
+ IN BOOLEAN CaseInSensitive);
+
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlCopyUnicodeString(
+ IN OUT PUNICODE_STRING DestinationString,
+ IN PCUNICODE_STRING SourceString);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlCreateRegistryKey(
+ IN ULONG RelativeTo,
+ IN PWSTR Path);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlCreateSecurityDescriptor(
+ IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
+ IN ULONG Revision);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlDeleteRegistryValue(
+ IN ULONG RelativeTo,
+ IN PCWSTR Path,
+ IN PCWSTR ValueName);
+
+ NTSYSAPI
+ BOOLEAN
+ NTAPI
+ RtlEqualUnicodeString(
+ IN CONST UNICODE_STRING *String1,
+ IN CONST UNICODE_STRING *String2,
+ IN BOOLEAN CaseInSensitive);
+
+ #if !defined(_AMD64_) && !defined(_IA64_)
+ NTSYSAPI
+ LARGE_INTEGER
+ NTAPI
+ RtlExtendedIntegerMultiply(
+ IN LARGE_INTEGER Multiplicand,
+ IN LONG Multiplier);
+
+ NTSYSAPI
+ LARGE_INTEGER
+ NTAPI
+ RtlExtendedLargeIntegerDivide(
+ IN LARGE_INTEGER Dividend,
+ IN ULONG Divisor,
+ IN OUT PULONG Remainder);
+ #endif
+
+ #if defined(_X86_) || defined(_IA64_)
+ NTSYSAPI
+ LARGE_INTEGER
+ NTAPI
+ RtlExtendedMagicDivide(
+ IN LARGE_INTEGER Dividend,
+ IN LARGE_INTEGER MagicDivisor,
+ IN CCHAR ShiftCount);
+ #endif
+
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlFreeAnsiString(
+ IN PANSI_STRING AnsiString);
+
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlFindClearBits(
+ IN PRTL_BITMAP BitMapHeader,
+ IN ULONG NumberToFind,
+ IN ULONG HintIndex);
+
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlFindClearBitsAndSet(
+ IN PRTL_BITMAP BitMapHeader,
+ IN ULONG NumberToFind,
+ IN ULONG HintIndex);
+
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlFindFirstRunClear(
+ IN PRTL_BITMAP BitMapHeader,
+ OUT PULONG StartingIndex);
+
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlFindClearRuns(
+ IN PRTL_BITMAP BitMapHeader,
+ OUT PRTL_BITMAP_RUN RunArray,
+ IN ULONG SizeOfRunArray,
+ IN BOOLEAN LocateLongestRuns);
+
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlFindLastBackwardRunClear(
+ IN PRTL_BITMAP BitMapHeader,
+ IN ULONG FromIndex,
+ OUT PULONG StartingRunIndex);
+
+ NTSYSAPI
+ CCHAR
+ NTAPI
+ RtlFindLeastSignificantBit(
+ IN ULONGLONG Set);
+
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlFindLongestRunClear(
+ IN PRTL_BITMAP BitMapHeader,
+ OUT PULONG StartingIndex);
+
+ NTSYSAPI
+ CCHAR
+ NTAPI
+ RtlFindMostSignificantBit(
+ IN ULONGLONG Set);
+
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlFindNextForwardRunClear(
+ IN PRTL_BITMAP BitMapHeader,
+ IN ULONG FromIndex,
+ OUT PULONG StartingRunIndex);
+
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlFindSetBits(
+ IN PRTL_BITMAP BitMapHeader,
+ IN ULONG NumberToFind,
+ IN ULONG HintIndex);
+
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlFindSetBitsAndClear(
+ IN PRTL_BITMAP BitMapHeader,
+ IN ULONG NumberToFind,
+ IN ULONG HintIndex);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlHashUnicodeString(
+ IN CONST UNICODE_STRING *String,
+ IN BOOLEAN CaseInSensitive,
+ IN ULONG HashAlgorithm,
+ OUT PULONG HashValue);
+
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlInitAnsiString(
+ IN OUT PANSI_STRING DestinationString,
+ IN PCSZ SourceString);
+
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlInitializeBitMap(
+ IN PRTL_BITMAP BitMapHeader,
+ IN PULONG BitMapBuffer,
+ IN ULONG SizeOfBitMap);
+
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlInitString(
+ IN OUT PSTRING DestinationString,
+ IN PCSZ SourceString);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlIntegerToUnicodeString(
+ IN ULONG Value,
+ IN ULONG Base OPTIONAL,
+ IN OUT PUNICODE_STRING String);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlInt64ToUnicodeString(
+ IN ULONGLONG Value,
+ IN ULONG Base OPTIONAL,
+ IN OUT PUNICODE_STRING String);
+
+ #ifdef _WIN64
+ #define RtlIntPtrToUnicodeString(Value, Base, String) \
+ RtlInt64ToUnicodeString(Value, Base, String)
+ #else
+ #define RtlIntPtrToUnicodeString(Value, Base, String) \
+ RtlIntegerToUnicodeString(Value, Base, String)
+ #endif
+
+ /* BOOLEAN
+ * RtlIsZeroLuid(
+ * IN PLUID L1);
+ */
+ #define RtlIsZeroLuid(_L1) \
+ ((BOOLEAN) ((!(_L1)->LowPart) && (!(_L1)->HighPart)))
+
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlLengthSecurityDescriptor(
+ IN PSECURITY_DESCRIPTOR SecurityDescriptor);
+
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlNumberOfClearBits(
+ IN PRTL_BITMAP BitMapHeader);
+
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlNumberOfSetBits(
+ IN PRTL_BITMAP BitMapHeader);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlQueryRegistryValues(
+ IN ULONG RelativeTo,
+ IN PCWSTR Path,
+ IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
+ IN PVOID Context,
+ IN PVOID Environment OPTIONAL);
+
+ #define LONG_SIZE (sizeof(LONG))
+ #define LONG_MASK (LONG_SIZE - 1)
+
+ /* VOID
+ * RtlRetrieveUlong(
+ * PULONG DestinationAddress,
+ * PULONG SourceAddress);
+ */
+ #if defined(_AMD64_)
+ #define RtlRetrieveUlong(DestAddress,SrcAddress) \
+ *(ULONG UNALIGNED *)(DestAddress) = *(PULONG)(SrcAddress)
+ #else
+ #define RtlRetrieveUlong(DestAddress,SrcAddress) \
+ if ((ULONG_PTR)(SrcAddress) & LONG_MASK) \
+ { \
+ ((PUCHAR)(DestAddress))[0]=((PUCHAR)(SrcAddress))[0]; \
+ ((PUCHAR)(DestAddress))[1]=((PUCHAR)(SrcAddress))[1]; \
+ ((PUCHAR)(DestAddress))[2]=((PUCHAR)(SrcAddress))[2]; \
+ ((PUCHAR)(DestAddress))[3]=((PUCHAR)(SrcAddress))[3]; \
+ } \
+ else \
+ { \
+ *((PULONG)(DestAddress))=*((PULONG)(SrcAddress)); \
+ }
+ #endif
+
+ /* VOID
+ * RtlRetrieveUshort(
+ * PUSHORT DestinationAddress,
+ * PUSHORT SourceAddress);
+ */
+ #if defined(_AMD64_)
+ #define RtlRetrieveUshort(DestAddress,SrcAddress) \
+ *(USHORT UNALIGNED *)(DestAddress) = *(USHORT)(SrcAddress)
+ #else
+ #define RtlRetrieveUshort(DestAddress,SrcAddress) \
+ if ((ULONG_PTR)(SrcAddress) & LONG_MASK) \
+ { \
+ ((PUCHAR)(DestAddress))[0]=((PUCHAR)(SrcAddress))[0]; \
+ ((PUCHAR)(DestAddress))[1]=((PUCHAR)(SrcAddress))[1]; \
+ } \
+ else \
+ { \
+ *((PUSHORT)(DestAddress))=*((PUSHORT)(SrcAddress)); \
+ }
+ #endif
+
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlSetAllBits(
+ IN PRTL_BITMAP BitMapHeader);
+
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlSetBits(
+ IN PRTL_BITMAP BitMapHeader,
+ IN ULONG StartingIndex,
+ IN ULONG NumberToSet);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlSetDaclSecurityDescriptor(
+ IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
+ IN BOOLEAN DaclPresent,
+ IN PACL Dacl OPTIONAL,
+ IN BOOLEAN DaclDefaulted OPTIONAL);
+
+ /* VOID
+ * RtlStoreUlong(
+ * IN PULONG Address,
+ * IN ULONG Value);
+ */
+ #if defined(_AMD64_)
+ #define RtlStoreUlong(Address,Value) \
+ *(ULONG UNALIGNED *)(Address) = (Value)
+ #else
+ #define RtlStoreUlong(Address,Value) \
+ if ((ULONG_PTR)(Address) & LONG_MASK) { \
+ ((PUCHAR) (Address))[LONG_LEAST_SIGNIFICANT_BIT] = (UCHAR)(FIRSTBYTE(Value)); \
+ ((PUCHAR) (Address))[LONG_3RD_MOST_SIGNIFICANT_BIT] = (UCHAR)(SECONDBYTE(Value)); \
+ ((PUCHAR) (Address))[LONG_2ND_MOST_SIGNIFICANT_BIT] = (UCHAR)(THIRDBYTE(Value)); \
+ ((PUCHAR) (Address))[LONG_MOST_SIGNIFICANT_BIT] = (UCHAR)(FOURTHBYTE(Value)); \
+ } \
+ else { \
+ *((PULONG)(Address)) = (ULONG) (Value); \
+ }
+ #endif
+
+ /* VOID
+ * RtlStoreUlonglong(
+ * IN OUT PULONGLONG Address,
+ * ULONGLONG Value);
+ */
+ #if defined(_AMD64_)
+ #define RtlStoreUlonglong(Address,Value) \
+ *(ULONGLONG UNALIGNED *)(Address) = (Value)
+ #else
+ #define RtlStoreUlonglong(Address,Value) \
+ if ((ULONG_PTR)(Address) & LONGLONG_MASK) { \
+ RtlStoreUlong((ULONG_PTR)(Address), \
+ (ULONGLONG)(Value) & 0xFFFFFFFF); \
+ RtlStoreUlong((ULONG_PTR)(Address)+sizeof(ULONG), \
+ (ULONGLONG)(Value) >> 32); \
+ } else { \
+ *((PULONGLONG)(Address)) = (ULONGLONG)(Value); \
+ }
+ #endif
+
+ /* VOID
+ * RtlStoreUlongPtr(
+ * IN OUT PULONG_PTR Address,
+ * IN ULONG_PTR Value);
+ */
+ #ifdef _WIN64
+ #define RtlStoreUlongPtr(Address,Value) \
+ RtlStoreUlonglong(Address,Value)
+ #else
+ #define RtlStoreUlongPtr(Address,Value) \
+ RtlStoreUlong(Address,Value)
+ #endif
+
+ /* VOID
+ * RtlStoreUshort(
+ * IN PUSHORT Address,
+ * IN USHORT Value);
+ */
+ #if defined(_AMD64_)
+ #define RtlStoreUshort(Address,Value) \
+ *(USHORT UNALIGNED *)(Address) = (Value)
+ #else
+ #define RtlStoreUshort(Address,Value) \
+ if ((ULONG_PTR)(Address) & SHORT_MASK) { \
+ ((PUCHAR) (Address))[SHORT_LEAST_SIGNIFICANT_BIT] = (UCHAR)(FIRSTBYTE(Value)); \
+ ((PUCHAR) (Address))[SHORT_MOST_SIGNIFICANT_BIT ] = (UCHAR)(SECONDBYTE(Value)); \
+ } \
+ else { \
+ *((PUSHORT) (Address)) = (USHORT)Value; \
+ }
+ #endif
+
+ NTSYSAPI
+ BOOLEAN
+ NTAPI
+ RtlTimeFieldsToTime(
+ IN PTIME_FIELDS TimeFields,
+ IN PLARGE_INTEGER Time);
+
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlTimeToTimeFields(
+ IN PLARGE_INTEGER Time,
+ IN PTIME_FIELDS TimeFields);
+
+ NTSYSAPI
+ ULONG
+ FASTCALL
+ RtlUlongByteSwap(
+ IN ULONG Source);
+
+ NTSYSAPI
+ ULONGLONG
+ FASTCALL
+ RtlUlonglongByteSwap(
+ IN ULONGLONG Source);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlUnicodeStringToAnsiString(
+ IN OUT PANSI_STRING DestinationString,
+ IN PCUNICODE_STRING SourceString,
+ IN BOOLEAN AllocateDestinationString);
+
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlxUnicodeStringToAnsiSize(
+ IN PCUNICODE_STRING UnicodeString);
+
+ #define RtlUnicodeStringToAnsiSize(String) ( \
+ NLS_MB_CODE_PAGE_TAG ? \
+ RtlxUnicodeStringToAnsiSize(String) : \
+ ((String)->Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR) \
+ )
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlUnicodeStringToInteger(
+ IN PCUNICODE_STRING String,
+ IN ULONG Base OPTIONAL,
+ OUT PULONG Value);
+
+ NTSYSAPI
+ WCHAR
+ NTAPI
+ RtlUpcaseUnicodeChar(
+ IN WCHAR SourceCharacter);
+
+ NTSYSAPI
+ USHORT
+ FASTCALL
+ RtlUshortByteSwap(
+ IN USHORT Source);
+
+ NTSYSAPI
+ BOOLEAN
+ NTAPI
+ RtlValidRelativeSecurityDescriptor(
+ IN PSECURITY_DESCRIPTOR SecurityDescriptorInput,
+ IN ULONG SecurityDescriptorLength,
+ IN SECURITY_INFORMATION RequiredInformation);
+
+ NTSYSAPI
+ BOOLEAN
+ NTAPI
+ RtlValidSecurityDescriptor(
+ IN PSECURITY_DESCRIPTOR SecurityDescriptor);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlWriteRegistryValue(
+ IN ULONG RelativeTo,
+ IN PCWSTR Path,
+ IN PCWSTR ValueName,
+ IN ULONG ValueType,
+ IN PVOID ValueData,
+ IN ULONG ValueLength);
+
+ #endif // (NTDDI_VERSION >= NTDDI_WIN2K)
+
+ #if (NTDDI_VERSION >= NTDDI_WIN2KSP3)
+ NTSYSAPI
+ VOID
+ FASTCALL
+ RtlPrefetchMemoryNonTemporal(
+ IN PVOID Source,
+ IN SIZE_T Length);
+ #endif
+
+ #if (NTDDI_VERSION >= NTDDI_WINXP)
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlClearBit(
+ PRTL_BITMAP BitMapHeader,
+ ULONG BitNumber);
+
+ NTSYSAPI
+ WCHAR
+ NTAPI
+ RtlDowncaseUnicodeChar(
+ IN WCHAR SourceCharacter);
+
+ NTSYSAPI
+ VOID
+ NTAPI
+ RtlSetBit(
+ PRTL_BITMAP BitMapHeader,
+ ULONG BitNumber);
+
+ NTSYSAPI
+ BOOLEAN
+ NTAPI
+ RtlTestBit(
+ IN PRTL_BITMAP BitMapHeader,
+ IN ULONG BitNumber);
+
+ #endif // (NTDDI_VERSION >= NTDDI_WINXP)
+
+ #if (NTDDI_VERSION >= NTDDI_VISTA)
+ NTSYSAPI
+ ULONG
+ NTAPI
+ RtlNumberOfSetBitsUlongPtr(
+ IN ULONG_PTR Target);
+
+ NTSYSAPI
+ ULONGLONG
+ NTAPI
+ RtlIoDecodeMemIoResource (
+ IN PIO_RESOURCE_DESCRIPTOR Descriptor,
+ OUT PULONGLONG Alignment OPTIONAL,
+ OUT PULONGLONG MinimumAddress OPTIONAL,
+ OUT PULONGLONG MaximumAddress OPTIONAL);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlIoEncodeMemIoResource(
+ IN PIO_RESOURCE_DESCRIPTOR Descriptor,
+ IN UCHAR Type,
+ IN ULONGLONG Length,
+ IN ULONGLONG Alignment,
+ IN ULONGLONG MinimumAddress,
+ IN ULONGLONG MaximumAddress);
+
+ NTSYSAPI
+ ULONGLONG
+ NTAPI
+ RtlCmDecodeMemIoResource(
+ IN PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
+ OUT PULONGLONG Start OPTIONAL);
+
+ NTSYSAPI
+ NTSTATUS
+ NTAPI
+ RtlFindClosestEncodableLength(
+ IN ULONGLONG SourceLength,
+ OUT PULONGLONG TargetLength);
+
+ #endif
+
+ #if !defined(MIDL_PASS)
+ /* inline funftions */
+ //DECLSPEC_DEPRECATED_DDK_WINXP
+ static __inline
+ LARGE_INTEGER
+ NTAPI_INLINE
+ RtlConvertLongToLargeInteger(LONG SignedInteger)
+ {
+ LARGE_INTEGER ret;
+ ret.QuadPart = SignedInteger;
+ return ret;
+ }
+
+ //DECLSPEC_DEPRECATED_DDK_WINXP
+ static __inline
+ LARGE_INTEGER
+ NTAPI_INLINE
+ RtlConvertUlongToLargeInteger(
+ ULONG UnsignedInteger)
+ {
+ LARGE_INTEGER ret;
+ ret.QuadPart = UnsignedInteger;
+ return ret;
+ }
+
+ //DECLSPEC_DEPRECATED_DDK
+ static __inline
+ ULONG
+ NTAPI_INLINE
+ RtlEnlargedUnsignedDivide(
+ IN ULARGE_INTEGER Dividend,
+ IN ULONG Divisor,
+ IN OUT PULONG Remainder)
+ {
+ if (Remainder)
+ *Remainder = (ULONG)(Dividend.QuadPart % Divisor);
+ return (ULONG)(Dividend.QuadPart / Divisor);
+ }
+
+ //DECLSPEC_DEPRECATED_DDK
+ static __inline
+ LARGE_INTEGER
+ NTAPI_INLINE
+ RtlEnlargedUnsignedMultiply(
+ IN ULONG Multiplicand,
+ IN ULONG Multiplier)
+ {
+ LARGE_INTEGER ret;
+ ret.QuadPart = (ULONGLONG)Multiplicand * (ULONGLONG)Multiplier;
+ return ret;
+ }
+
+ //DECLSPEC_DEPRECATED_DDK
+ static __inline
+ LARGE_INTEGER
+ NTAPI_INLINE
+ RtlEnlargedIntegerMultiply(
+ IN LONG Multiplicand,
+ IN LONG Multiplier)
+ {
+ LARGE_INTEGER ret;
+ ret.QuadPart = (LONGLONG)Multiplicand * (ULONGLONG)Multiplier;
+ return ret;
+ }
+
+ FORCEINLINE
+ VOID
+ RtlInitEmptyAnsiString(OUT PANSI_STRING AnsiString,
+ IN PCHAR Buffer,
+ IN USHORT BufferSize)
+ {
+ AnsiString->Length = 0;
+ AnsiString->MaximumLength = BufferSize;
+ AnsiString->Buffer = Buffer;
+ }
+
+ FORCEINLINE
+ VOID
+ RtlInitEmptyUnicodeString(
+ OUT PUNICODE_STRING UnicodeString,
+ IN PWSTR Buffer,
+ IN USHORT BufferSize)
+ {
+ UnicodeString->Length = 0;
+ UnicodeString->MaximumLength = BufferSize;
+ UnicodeString->Buffer = Buffer;
+ }
+
+ #if defined(_AMD64_) || defined(_IA64_)
+ static __inline
+ LARGE_INTEGER
+ NTAPI_INLINE
+ RtlExtendedIntegerMultiply(
+ LARGE_INTEGER Multiplicand,
+ LONG Multiplier)
+ {
+ LARGE_INTEGER ret;
+ ret.QuadPart = Multiplicand.QuadPart * Multiplier;
+ return ret;
+ }
+
+ static __inline
+ LARGE_INTEGER
+ NTAPI_INLINE
+ RtlExtendedLargeIntegerDivide(
+ LARGE_INTEGER Dividend,
+ ULONG Divisor,
+ PULONG Remainder)
+ {
+ LARGE_INTEGER ret;
+ ret.QuadPart = (ULONG64)Dividend.QuadPart / Divisor;
+ if (Remainder)
+ *Remainder = (ULONG)(Dividend.QuadPart % Divisor);
+ return ret;
+ }
+ #endif
+
+ #if defined(_AMD64_)
+
+ #define MultiplyHigh __mulh
+ #define UnsignedMultiplyHigh __umulh
+
+ //DECLSPEC_DEPRECATED_DDK
+ static __inline
+ LARGE_INTEGER
+ NTAPI_INLINE
+ RtlExtendedMagicDivide(
+ IN LARGE_INTEGER Dividend,
+ IN LARGE_INTEGER MagicDivisor,
+ IN CCHAR ShiftCount)
+ {
+ LARGE_INTEGER ret;
+ ULONG64 ret64;
+ BOOLEAN Pos;
+ Pos = (Dividend.QuadPart >= 0);
+ ret64 = UnsignedMultiplyHigh(Pos ? Dividend.QuadPart : -Dividend.QuadPart,
+ MagicDivisor.QuadPart);
+ ret64 >>= ShiftCount;
+ ret.QuadPart = Pos ? ret64 : -ret64;
+ return ret;
+ }
+ #endif
+
+ //DECLSPEC_DEPRECATED_DDK
+ static __inline
+ LARGE_INTEGER
+ NTAPI_INLINE
+ RtlLargeIntegerAdd(
+ IN LARGE_INTEGER Addend1,
+ IN LARGE_INTEGER Addend2)
+ {
+ LARGE_INTEGER ret;
+ ret.QuadPart = Addend1.QuadPart + Addend2.QuadPart;
+ return ret;
+ }
+
+ /* VOID
+ * RtlLargeIntegerAnd(
+ * IN OUT LARGE_INTEGER Result,
+ * IN LARGE_INTEGER Source,
+ * IN LARGE_INTEGER Mask);
+ */
+ #define RtlLargeIntegerAnd(Result, Source, Mask) \
+ Result.QuadPart = Source.QuadPart & Mask.QuadPart
+
+ //DECLSPEC_DEPRECATED_DDK
+ static __inline
+ LARGE_INTEGER
+ NTAPI_INLINE
+ RtlLargeIntegerArithmeticShift(
+ IN LARGE_INTEGER LargeInteger,
+ IN CCHAR ShiftCount)
+ {
+ LARGE_INTEGER ret;
+ ret.QuadPart = LargeInteger.QuadPart >> ShiftCount;
+ return ret;
+ }
+
+ /* BOOLEAN
+ * RtlLargeIntegerEqualTo(
+ * IN LARGE_INTEGER Operand1,
+ * IN LARGE_INTEGER Operand2);
+ */
+ #define RtlLargeIntegerEqualTo(X,Y) \
+ (!(((X).LowPart ^ (Y).LowPart) | ((X).HighPart ^ (Y).HighPart)))
+
+ FORCEINLINE
+ PVOID
+ RtlSecureZeroMemory(
+ OUT PVOID Pointer,
+ IN SIZE_T Size)
+ {
+ volatile char* vptr = (volatile char*)Pointer;
+ #if defined(_M_AMD64)
+ __stosb((PUCHAR)vptr, 0, Size);
+ #else
+ char * endptr = (char *)vptr + Size;
+ while (vptr < endptr)
+ {
+ *vptr = 0; vptr++;
+ }
+ #endif
+ return Pointer;
+ }
+
+ #if defined(_M_AMD64)
+ FORCEINLINE
+ ULONG
+ RtlCheckBit(
+ IN PRTL_BITMAP BitMapHeader,
+ IN ULONG BitPosition)
+ {
+ return BitTest((LONG CONST*)BitMapHeader->Buffer, BitPosition);
+ }
+ #else
+ #define RtlCheckBit(BMH,BP) (((((PLONG)(BMH)->Buffer)[(BP)/32]) >> ((BP)%32)) & 0x1)
+ #endif // defined(_M_AMD64)
+
+ #endif // !defined(MIDL_PASS)
+
+ //
+ // Byte Swap Functions
+ //
+ #if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037 || defined(__GNUC__))) || \
+ ((defined(_M_AMD64) || defined(_M_IA64)) \
+ && (_MSC_FULL_VER > 13009175 || defined(__GNUC__)))
+
+ #define RtlUshortByteSwap(_x) _byteswap_ushort((USHORT)(_x))
+ #define RtlUlongByteSwap(_x) _byteswap_ulong((_x))
+ #define RtlUlonglongByteSwap(_x) _byteswap_uint64((_x))
+
+ #endif
+
+ /******************************************************************************
+ * Memory manager Types *
+ ******************************************************************************/
+
+ typedef struct _MDL {
+ struct _MDL *Next;
+ CSHORT Size;
+ CSHORT MdlFlags;
+ struct _EPROCESS *Process;
+ PVOID MappedSystemVa;
+ PVOID StartVa;
+ ULONG ByteCount;
+ ULONG ByteOffset;
+ } MDL, *PMDL;
+
+
+ /******************************************************************************
+ * Memory manager Functions *
+ ******************************************************************************/
+
+ /* PVOID MmGetSystemAddressForMdl(
+ * IN PMDL Mdl);
+ */
+ #define MmGetSystemAddressForMdl(Mdl) \
+ (((Mdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | \
+ MDL_SOURCE_IS_NONPAGED_POOL)) ? \
+ ((Mdl)->MappedSystemVa) : \
+ (MmMapLockedPages((Mdl), KernelMode)))
+
+ /* PVOID
+ * MmGetSystemAddressForMdlSafe(
+ * IN PMDL Mdl,
+ * IN MM_PAGE_PRIORITY Priority)
+ */
+ #define MmGetSystemAddressForMdlSafe(_Mdl, _Priority) \
+ (((_Mdl)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA \
+ | MDL_SOURCE_IS_NONPAGED_POOL)) ? \
+ (_Mdl)->MappedSystemVa : \
+ (PVOID) MmMapLockedPagesSpecifyCache((_Mdl), \
+ KernelMode, MmCached, NULL, FALSE, (_Priority)))
+
+ #if (NTDDI_VERSION >= NTDDI_WIN2K)
+ NTKERNELAPI
+ PMDL
+ NTAPI
+ MmCreateMdl(
+ IN PMDL MemoryDescriptorList OPTIONAL,
+ IN PVOID Base,
+ IN SIZE_T Length);
+
+ #endif
+
+
+ /******************************************************************************
+ * I/O Manager Functions *
+ ******************************************************************************/
+
+ #if defined(USE_DMA_MACROS) && !defined(_NTHAL_) && \
+ (defined(_NTDDK_) || defined(_NTDRIVER_)) || defined(_WDM_INCLUDED_)
+
+ #define DMA_MACROS_DEFINED
+
+ FORCEINLINE
+ NTSTATUS
+ IoAllocateAdapterChannel(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG NumberOfMapRegisters,
+ IN PDRIVER_CONTROL ExecutionRoutine,
+ IN PVOID Context)
+ {
+ PALLOCATE_ADAPTER_CHANNEL AllocateAdapterChannel;
+ AllocateAdapterChannel =
+ *(DmaAdapter)->DmaOperations->AllocateAdapterChannel;
+ ASSERT(AllocateAdapterChannel);
+ return AllocateAdapterChannel(DmaAdapter,
+ DeviceObject,
+ NumberOfMapRegisters,
+ ExecutionRoutine,
+ Context );
+ }
+
+ FORCEINLINE
+ BOOLEAN
+ IoFlushAdapterBuffers(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN PMDL Mdl,
+ IN PVOID MapRegisterBase,
+ IN PVOID CurrentVa,
+ IN ULONG Length,
+ IN BOOLEAN WriteToDevice)
+ {
+ PFLUSH_ADAPTER_BUFFERS FlushAdapterBuffers;
+ FlushAdapterBuffers = *(DmaAdapter)->DmaOperations->FlushAdapterBuffers;
+ ASSERT(FlushAdapterBuffers);
+ return FlushAdapterBuffers(DmaAdapter,
+ Mdl,
+ MapRegisterBase,
+ CurrentVa,
+ Length,
+ WriteToDevice );
+ }
+
+ FORCEINLINE
+ VOID
+ IoFreeAdapterChannel(
+ IN PADAPTER_OBJECT AdapterObject)
+ {
+ PFREE_ADAPTER_CHANNEL FreeAdapterChannel;
+ FreeAdapterChannel = *(DmaAdapter)->DmaOperations->FreeAdapterChannel;
+ ASSERT(FreeAdapterChannel);
+ FreeAdapterChannel(DmaAdapter);
+ }
+
+ FORCEINLINE
+ VOID
+ IoFreeMapRegisters(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN PVOID MapRegisterBase,
+ IN ULONG NumberOfMapRegisters)
+ {
+ PFREE_MAP_REGISTERS FreeMapRegisters;
+ FreeMapRegisters = *(DmaAdapter)->DmaOperations->FreeMapRegisters;
+ ASSERT(FreeMapRegisters);
+ FreeMapRegisters(DmaAdapter, MapRegisterBase, NumberOfMapRegisters);
+ }
+
+ FORCEINLINE
+ PHYSICAL_ADDRESS
+ IoMapTransfer(
+ IN PDMA_ADAPTER DmaAdapter,
+ IN PMDL Mdl,
+ IN PVOID MapRegisterBase,
+ IN PVOID CurrentVa,
+ IN OUT PULONG Length,
+ IN BOOLEAN WriteToDevice)
+ {
+ PMAP_TRANSFER MapTransfer;
+
+ MapTransfer = *(DmaAdapter)->DmaOperations->MapTransfer;
+ ASSERT(MapTransfer);
+ return MapTransfer(DmaAdapter,
+ Mdl,
+ MapRegisterBase,
+ CurrentVa,
+ Length,
+ WriteToDevice);
+ }
+ #endif
+
+
+ /******************************************************************************
+ * Executive Types *
+ ******************************************************************************/
+
+ typedef enum _POOL_TYPE {
+ NonPagedPool,
+ PagedPool,
+ NonPagedPoolMustSucceed,
+ DontUseThisType,
+ NonPagedPoolCacheAligned,
+ PagedPoolCacheAligned,
+ NonPagedPoolCacheAlignedMustS,
+ MaxPoolType,
+ NonPagedPoolSession = 32,
+ PagedPoolSession,
+ NonPagedPoolMustSucceedSession,
+ DontUseThisTypeSession,
+ NonPagedPoolCacheAlignedSession,
+ PagedPoolCacheAlignedSession,
+ NonPagedPoolCacheAlignedMustSSession
+ } POOL_TYPE;
+
+ typedef enum _SUITE_TYPE {
+ SmallBusiness,
+ Enterprise,
+ BackOffice,
+ CommunicationServer,
+ TerminalServer,
+ SmallBusinessRestricted,
+ EmbeddedNT,
+ DataCenter,
+ SingleUserTS,
+ Personal,
+ Blade,
+ MaxSuiteType
+ } SUITE_TYPE;
+
+ typedef enum _EX_POOL_PRIORITY {
+ LowPoolPriority,
+ LowPoolPrioritySpecialPoolOverrun = 8,
+ LowPoolPrioritySpecialPoolUnderrun = 9,
+ NormalPoolPriority = 16,
+ NormalPoolPrioritySpecialPoolOverrun = 24,
+ NormalPoolPrioritySpecialPoolUnderrun = 25,
+ HighPoolPriority = 32,
+ HighPoolPrioritySpecialPoolOverrun = 40,
+ HighPoolPrioritySpecialPoolUnderrun = 41
+ } EX_POOL_PRIORITY;
+
+ typedef struct _FAST_MUTEX
+ {
+ LONG Count;
+ PKTHREAD Owner;
+ ULONG Contention;
+ KEVENT Gate;
+ ULONG OldIrql;
+ } FAST_MUTEX, *PFAST_MUTEX;
+
+ typedef ULONG_PTR ERESOURCE_THREAD, *PERESOURCE_THREAD;
+
+ typedef struct _OWNER_ENTRY {
+ ERESOURCE_THREAD OwnerThread;
+ _ANONYMOUS_UNION union {
+ LONG OwnerCount;
+ ULONG TableSize;
+ } DUMMYUNIONNAME;
+ } OWNER_ENTRY, *POWNER_ENTRY;
+
+ typedef struct _ERESOURCE
+ {
+ LIST_ENTRY SystemResourcesList;
+ POWNER_ENTRY OwnerTable;
+ SHORT ActiveCount;
+ USHORT Flag;
+ volatile PKSEMAPHORE SharedWaiters;
+ volatile PKEVENT ExclusiveWaiters;
+ OWNER_ENTRY OwnerEntry;
+ ULONG ActiveEntries;
+ ULONG ContentionCount;
+ ULONG NumberOfSharedWaiters;
+ ULONG NumberOfExclusiveWaiters;
+ union
+ {
+ PVOID Address;
+ ULONG_PTR CreatorBackTraceIndex;
+ };
+ KSPIN_LOCK SpinLock;
+ } ERESOURCE, *PERESOURCE;
+
+ #if !defined(_WIN64) && (defined(_NTDDK_) || defined(_NTIFS_) || defined(_NDIS_))
+ #define LOOKASIDE_ALIGN
+ #else
+ #define LOOKASIDE_ALIGN /* FIXME: DECLSPEC_CACHEALIGN */
+ #endif
+
+ typedef struct _LOOKASIDE_LIST_EX *PLOOKASIDE_LIST_EX;
+
+ typedef PVOID
+ (DDKAPI *PALLOCATE_FUNCTION)(
+ IN POOL_TYPE PoolType,
+ IN SIZE_T NumberOfBytes,
+ IN ULONG Tag);
+
+ typedef PVOID
+ (DDKAPI *PALLOCATE_FUNCTION_EX)(
+ IN POOL_TYPE PoolType,
+ IN SIZE_T NumberOfBytes,
+ IN ULONG Tag,
+ IN OUT PLOOKASIDE_LIST_EX Lookaside);
+
+ typedef VOID
+ (DDKAPI *PFREE_FUNCTION)(
+ IN PVOID Buffer);
+
+ typedef VOID
+ (DDKAPI *PFREE_FUNCTION_EX)(
+ IN PVOID Buffer,
+ IN OUT PLOOKASIDE_LIST_EX Lookaside);
+
+ typedef VOID
+ (DDKAPI *PCALLBACK_FUNCTION)(
+ IN PVOID CallbackContext,
+ IN PVOID Argument1,
+ IN PVOID Argument2);
+
+ typedef struct LOOKASIDE_ALIGN _GENERAL_LOOKASIDE {
+ union {
+ SLIST_HEADER ListHead;
+ SINGLE_LIST_ENTRY SingleListHead;
+ } DUMMYUNIONNAME;
+ USHORT Depth;
+ USHORT MaximumDepth;
+ ULONG TotalAllocates;
+ union {
+ ULONG AllocateMisses;
+ ULONG AllocateHits;
+ } DUMMYUNIONNAME2;
+ ULONG TotalFrees;
+ union {
+ ULONG FreeMisses;
+ ULONG FreeHits;
+ } DUMMYUNIONNAME3;
+ POOL_TYPE Type;
+ ULONG Tag;
+ ULONG Size;
+ union {
+ PALLOCATE_FUNCTION_EX AllocateEx;
+ PALLOCATE_FUNCTION Allocate;
+ } DUMMYUNIONNAME4;
+ union {
+ PFREE_FUNCTION_EX FreeEx;
+ PFREE_FUNCTION Free;
+ } DUMMYUNIONNAME5;
+ LIST_ENTRY ListEntry;
+ ULONG LastTotalAllocates;
+ union {
+ ULONG LastAllocateMisses;
+ ULONG LastAllocateHits;
+ } DUMMYUNIONNAME6;
+ ULONG Future[2];
+ } GENERAL_LOOKASIDE, *PGENERAL_LOOKASIDE;
+
+ typedef struct _PAGED_LOOKASIDE_LIST {
+ GENERAL_LOOKASIDE L;
+ #if !defined(_AMD64_) && !defined(_IA64_)
+ FAST_MUTEX Lock__ObsoleteButDoNotDelete;
+ #endif
+ } PAGED_LOOKASIDE_LIST, *PPAGED_LOOKASIDE_LIST;
+
+ typedef struct LOOKASIDE_ALIGN _NPAGED_LOOKASIDE_LIST {
+ GENERAL_LOOKASIDE L;
+ #if !defined(_AMD64_) && !defined(_IA64_)
+ KSPIN_LOCK Lock__ObsoleteButDoNotDelete;
+ #endif
+ } NPAGED_LOOKASIDE_LIST, *PNPAGED_LOOKASIDE_LIST;
+
+ //typedef struct _LOOKASIDE_LIST_EX {
+ // GENERAL_LOOKASIDE_POOL L;
+ //} LOOKASIDE_LIST_EX, *PLOOKASIDE_LIST_EX;
+
+ typedef struct _EX_RUNDOWN_REF {
+ union {
+ volatile ULONG_PTR Count;
+ volatile PVOID Ptr;
+ };
+ } EX_RUNDOWN_REF, *PEX_RUNDOWN_REF;
+
+ typedef struct _EX_RUNDOWN_REF_CACHE_AWARE *PEX_RUNDOWN_REF_CACHE_AWARE;
+
+ typedef enum _WORK_QUEUE_TYPE {
+ CriticalWorkQueue,
+ DelayedWorkQueue,
+ HyperCriticalWorkQueue,
+ MaximumWorkQueue
+ } WORK_QUEUE_TYPE;
+
+ typedef VOID
+ (DDKAPI *PWORKER_THREAD_ROUTINE)(
+ IN PVOID Parameter);
+
+ typedef struct _WORK_QUEUE_ITEM {
+ LIST_ENTRY List;
+ PWORKER_THREAD_ROUTINE WorkerRoutine;
+ volatile PVOID Parameter;
+ } WORK_QUEUE_ITEM, *PWORK_QUEUE_ITEM;
+
+
+ /******************************************************************************
+ * Executive Functions *
+ ******************************************************************************/
+
+ #if defined(_X86_)
+ #if defined(_NTHAL_)
+ #define ExAcquireFastMutex ExiAcquireFastMutex
+ #define ExReleaseFastMutex ExiReleaseFastMutex
+ #define ExTryToAcquireFastMutex ExiTryToAcquireFastMutex
+ #endif
+ #define ExInterlockedAddUlong ExfInterlockedAddUlong
+ #define ExInterlockedInsertHeadList ExfInterlockedInsertHeadList
+ #define ExInterlockedInsertTailList ExfInterlockedInsertTailList
+ #define ExInterlockedRemoveHeadList ExfInterlockedRemoveHeadList
+ #define ExInterlockedPopEntryList ExfInterlockedPopEntryList
+ #define ExInterlockedPushEntryList ExfInterlockedPushEntryList
+ #endif
+
+ #if defined(_WIN64)
+
+ #if defined(_NTDRIVER_) || defined(_NTDDK_) || defined(_NTIFS_) || \
+ defined(_NTHAL_) || defined(_NTOSP_)
+ NTKERNELAPI
+ USHORT
+ ExQueryDepthSList(IN PSLIST_HEADER ListHead);
+ #else
+ FORCEINLINE
+ USHORT
+ ExQueryDepthSList(IN PSLIST_HEADER ListHead)
+ {
+ return (USHORT)(ListHead->Alignment & 0xffff);
+ }
+ #endif
+
+ NTKERNELAPI
+ PSLIST_ENTRY
+ ExpInterlockedFlushSList(
+ PSLIST_HEADER ListHead);
+
+ NTKERNELAPI
+ PSLIST_ENTRY
+ ExpInterlockedPopEntrySList(
+ PSLIST_HEADER ListHead);
+
+ NTKERNELAPI
+ PSLIST_ENTRY
+ ExpInterlockedPushEntrySList(
+ PSLIST_HEADER ListHead,
+ PSLIST_ENTRY ListEntry);
+
+ #define ExInterlockedFlushSList(Head) \
+ ExpInterlockedFlushSList(Head)
+ #define ExInterlockedPopEntrySList(Head, Lock) \
+ ExpInterlockedPopEntrySList(Head)
+ #define ExInterlockedPushEntrySList(Head, Entry, Lock) \
+ ExpInterlockedPushEntrySList(Head, Entry)
+
+ #else // !defined(_WIN64)
+
+ #define ExQueryDepthSList(listhead) (listhead)->Depth
+
+ NTKERNELAPI
+ PSINGLE_LIST_ENTRY
+ FASTCALL
+ ExInterlockedFlushSList(
+ IN PSLIST_HEADER ListHead);
+
+ #if defined(_WIN2K_COMPAT_SLIST_USAGE) && defined(_X86_)
+ NTKERNELAPI
+ PSINGLE_LIST_ENTRY
+ FASTCALL
+ ExInterlockedPopEntrySList(
+ IN PSLIST_HEADER ListHead,
+ IN PKSPIN_LOCK Lock);
+
+ NTKERNELAPI
+ PSINGLE_LIST_ENTRY
+ FASTCALL
+ ExInterlockedPushEntrySList(
+ IN PSLIST_HEADER ListHead,
+ IN PSINGLE_LIST_ENTRY ListEntry,
+ IN PKSPIN_LOCK Lock);
+ #else
+ #define ExInterlockedPopEntrySList(_ListHead, _Lock) \
+ InterlockedPopEntrySList(_ListHead)
+ #define ExInterlockedPushEntrySList(_ListHead, _ListEntry, _Lock) \
+ InterlockedPushEntrySList(_ListHead, _ListEntry)
+ #endif // _WIN2K_COMPAT_SLIST_USAGE
+
+ #endif // !defined(_WIN64)
+
+ /* ERESOURCE_THREAD
+ * ExGetCurrentResourceThread(
+ * VOID);
+ */
+ #define ExGetCurrentResourceThread() ((ERESOURCE_THREAD)PsGetCurrentThread())
+
+ #define ExReleaseResource(R) (ExReleaseResourceLite(R))
+
+ /* VOID
+ * ExInitializeWorkItem(
+ * IN PWORK_QUEUE_ITEM Item,
+ * IN PWORKER_THREAD_ROUTINE Routine,
+ * IN PVOID Context)
+ */
+ #define ExInitializeWorkItem(Item, Routine, Context) \
+ { \
+ (Item)->WorkerRoutine = Routine; \
+ (Item)->Parameter = Context; \
+ (Item)->List.Flink = NULL; \
+ }
+
+ #if (NTDDI_VERSION >= NTDDI_WIN2K)
+
+ NTKERNELAPI
+ VOID
+ FASTCALL
+ ExAcquireFastMutex(
+ IN OUT PFAST_MUTEX FastMutex);
+
+ NTKERNELAPI
+ VOID
+ FASTCALL
+ ExReleaseFastMutex(
+ IN OUT PFAST_MUTEX FastMutex);
+
+ NTKERNELAPI
+ BOOLEAN
+ FASTCALL
+ ExTryToAcquireFastMutex(
+ IN OUT PFAST_MUTEX FastMutex);
+
+ NTKERNELAPI
+ VOID
+ FASTCALL
+ ExAcquireFastMutexUnsafe(
+ IN OUT PFAST_MUTEX FastMutex);
+
+ NTKERNELAPI
+ VOID
+ FASTCALL
+ ExReleaseFastMutexUnsafe(
+ IN OUT PFAST_MUTEX FastMutex);
+
+ NTKERNELAPI
+ BOOLEAN
+ NTAPI
+ ExAcquireResourceExclusiveLite(
+ IN PERESOURCE Resource,
+ IN BOOLEAN Wait);
+
+ NTKERNELAPI
+ BOOLEAN
+ NTAPI
+ ExAcquireResourceSharedLite(
+ IN PERESOURCE Resource,
+ IN BOOLEAN Wait);
+
+ NTKERNELAPI
+ BOOLEAN
+ NTAPI
+ ExAcquireSharedStarveExclusive(
+ IN PERESOURCE Resource,
+ IN BOOLEAN Wait);
+
+ NTKERNELAPI
+ BOOLEAN
+ NTAPI
+ ExAcquireSharedWaitForExclusive(
+ IN PERESOURCE Resource,
+ IN BOOLEAN Wait);
+
+ NTKERNELAPI
+ PVOID
+ NTAPI
+ ExAllocatePool(
+ IN POOL_TYPE PoolType,
+ IN SIZE_T NumberOfBytes);
+
+ #ifdef POOL_TAGGING
+ #define ExAllocatePool(p,n) ExAllocatePoolWithTag(p,n,' kdD')
+ #endif /* POOL_TAGGING */
+
+ NTKERNELAPI
+ PVOID
+ NTAPI
+ ExAllocatePoolWithQuota(
+ IN POOL_TYPE PoolType,
+ IN SIZE_T NumberOfBytes);
+
+ #ifdef POOL_TAGGING
+ #define ExAllocatePoolWithQuota(p,n) ExAllocatePoolWithQuotaTag(p,n,' kdD')
+ #endif /* POOL_TAGGING */
+
+ NTKERNELAPI
+ PVOID
+ NTAPI
+ ExAllocatePoolWithQuotaTag(
+ IN POOL_TYPE PoolType,
+ IN SIZE_T NumberOfBytes,
+ IN ULONG Tag);
+
+ #ifndef POOL_TAGGING
+ #define ExAllocatePoolWithQuotaTag(a,b,c) ExAllocatePoolWithQuota(a,b)
+ #endif /* POOL_TAGGING */
+
+ NTKERNELAPI
+ PVOID
+ NTAPI
+ ExAllocatePoolWithTag(
+ IN POOL_TYPE PoolType,
+ IN SIZE_T NumberOfBytes,
+ IN ULONG Tag);
+
+ NTKERNELAPI
+ PVOID
+ NTAPI
+ ExAllocatePoolWithTagPriority(
+ IN POOL_TYPE PoolType,
+ IN SIZE_T NumberOfBytes,
+ IN ULONG Tag,
+ IN EX_POOL_PRIORITY Priority);
+
+ NTKERNELAPI
+ VOID
+ NTAPI
+ ExConvertExclusiveToSharedLite(
+ IN PERESOURCE Resource);
+
+ NTKERNELAPI
+ NTSTATUS
+ NTAPI
+ ExCreateCallback(
+ OUT PCALLBACK_OBJECT *CallbackObject,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN BOOLEAN Create,
+ IN BOOLEAN AllowMultipleCallbacks);
+
+ NTKERNELAPI
+ VOID
+ NTAPI
+ ExDeleteNPagedLookasideList(
+ IN PNPAGED_LOOKASIDE_LIST Lookaside);
+
+ NTKERNELAPI
+ VOID
+ NTAPI
+ ExDeletePagedLookasideList(
+ IN PPAGED_LOOKASIDE_LIST Lookaside);
+
+ NTKERNELAPI
+ NTSTATUS
+ NTAPI
+ ExDeleteResourceLite(
+ IN PERESOURCE Resource);
+
+ NTKERNELAPI
+ VOID
+ NTAPI
+ ExFreePool(
+ IN PVOID P);
+
+ #ifdef POOL_TAGGING
+ #define ExFreePool(P) ExFreePoolWithTag(P, 0)
+ #endif
+
+ NTKERNELAPI
+ VOID
+ NTAPI
+ ExFreePoolWithTag(
+ IN PVOID P,
+ IN ULONG Tag);
+
+ NTKERNELAPI
+ ULONG
+ NTAPI
+ ExGetExclusiveWaiterCount(
+ IN PERESOURCE Resource);
+
+ NTKERNELAPI
+ KPROCESSOR_MODE
+ NTAPI
+ ExGetPreviousMode(
+ VOID);
+
+ NTKERNELAPI
+ ULONG
+ NTAPI
+ ExGetSharedWaiterCount(
+ IN PERESOURCE Resource);
+
+ NTKERNELAPI
+ VOID
+ NTAPI
+ ExInitializeNPagedLookasideList(
+ IN PNPAGED_LOOKASIDE_LIST Lookaside,
+ IN PALLOCATE_FUNCTION Allocate OPTIONAL,
+ IN PFREE_FUNCTION Free OPTIONAL,
+ IN ULONG Flags,
+ IN SIZE_T Size,
+ IN ULONG Tag,
+ IN USHORT Depth);
+
+ NTKERNELAPI
+ VOID
+ NTAPI
+ ExInitializePagedLookasideList(
+ IN PPAGED_LOOKASIDE_LIST Lookaside,
+ IN PALLOCATE_FUNCTION Allocate OPTIONAL,
+ IN PFREE_FUNCTION Free OPTIONAL,
+ IN ULONG Flags,
+ IN SIZE_T Size,
+ IN ULONG Tag,
+ IN USHORT Depth);
+
+ NTKERNELAPI
+ NTSTATUS
+ NTAPI
+ ExInitializeResourceLite(
+ IN PERESOURCE Resource);
+
+ NTKERNELAPI
+ LARGE_INTEGER
+ NTAPI
+ ExInterlockedAddLargeInteger(
+ IN PLARGE_INTEGER Addend,
+ IN LARGE_INTEGER Increment,
+ IN PKSPIN_LOCK Lock);
+
+ #if defined(_WIN64)
+ #define ExInterlockedAddLargeStatistic(Addend, Increment) \
+ (VOID)InterlockedAdd64(&(Addend)->QuadPart, Increment)
+ #else
+ #define ExInterlockedAddLargeStatistic(Addend, Increment) \
+ _InterlockedAddLargeStatistic((PLONGLONG)&(Addend)->QuadPart, Increment)
+ #endif
+
+ NTKERNELAPI
+ ULONG
+ FASTCALL
+ ExInterlockedAddUlong(
+ IN PULONG Addend,
+ IN ULONG Increment,
+ PKSPIN_LOCK Lock);
+
+ #if defined(_AMD64_) || defined(_IA64_)
+ #define ExInterlockedCompareExchange64(Destination, Exchange, Comperand, Lock) \
+ InterlockedCompareExchange64(Destination, *(Exchange), *(Comperand))
+ #elif defined(_X86_)
+ NTKERNELAPI
+ LONGLONG
+ FASTCALL
+ ExfInterlockedCompareExchange64(
+ IN OUT LONGLONG volatile *Destination,
+ IN PLONGLONG Exchange,
+ IN PLONGLONG Comperand);
+ #define ExInterlockedCompareExchange64(Destination, Exchange, Comperand, Lock) \
+ ExfInterlockedCompareExchange64(Destination, Exchange, Comperand)
+ #else
+ NTKERNELAPI
+ LONGLONG
+ FASTCALL
+ ExInterlockedCompareExchange64(
+ IN OUT LONGLONG volatile *Destination,
+ IN PLONGLONG Exchange,
+ IN PLONGLONG Comparand,
+ IN PKSPIN_LOCK Lock);
+ #endif
+
+ NTKERNELAPI
+ PLIST_ENTRY
+ FASTCALL
+ ExInterlockedInsertHeadList(
+ IN PLIST_ENTRY ListHead,
+ IN PLIST_ENTRY ListEntry,
+ IN PKSPIN_LOCK Lock);
+
+ NTKERNELAPI
+ PLIST_ENTRY
+ FASTCALL
+ ExInterlockedInsertTailList(
+ IN PLIST_ENTRY ListHead,
+ IN PLIST_ENTRY ListEntry,
+ IN PKSPIN_LOCK Lock);
+
+ NTKERNELAPI
+ PSINGLE_LIST_ENTRY
+ FASTCALL
+ ExInterlockedPopEntryList(
+ IN PSINGLE_LIST_ENTRY ListHead,
+ IN PKSPIN_LOCK Lock);
+
+ NTKERNELAPI
+ PSINGLE_LIST_ENTRY
+ FASTCALL
+ ExInterlockedPushEntryList(
+ IN PSINGLE_LIST_ENTRY ListHead,
+ IN PSINGLE_LIST_ENTRY ListEntry,
+ IN PKSPIN_LOCK Lock);
+
+ NTKERNELAPI
+ PLIST_ENTRY
+ FASTCALL
+ ExInterlockedRemoveHeadList(
+ IN PLIST_ENTRY ListHead,
+ IN PKSPIN_LOCK Lock);
+
+ NTKERNELAPI
+ BOOLEAN
+ NTAPI
+ ExIsProcessorFeaturePresent(
+ IN ULONG ProcessorFeature);
+
+ NTKERNELAPI
+ BOOLEAN
+ NTAPI
+ ExIsResourceAcquiredExclusiveLite(
+ IN PERESOURCE Resource);
+
+ NTKERNELAPI
+ ULONG
+ NTAPI
+ ExIsResourceAcquiredSharedLite(
+ IN PERESOURCE Resource);
+
+ #define ExIsResourceAcquiredLite ExIsResourceAcquiredSharedLite
+
+ NTKERNELAPI
+ VOID
+ NTAPI
+ ExLocalTimeToSystemTime(
+ IN PLARGE_INTEGER LocalTime,
+ OUT PLARGE_INTEGER SystemTime);
+
+ NTKERNELAPI
+ VOID
+ NTAPI
+ ExNotifyCallback(
+ IN PCALLBACK_OBJECT CallbackObject,
+ IN PVOID Argument1,
+ IN PVOID Argument2);
+
+ NTKERNELAPI
+ VOID
+ NTAPI
+ ExQueueWorkItem(
+ IN PWORK_QUEUE_ITEM WorkItem,
+ IN WORK_QUEUE_TYPE QueueType);
+
+ NTKERNELAPI
+ DECLSPEC_NORETURN
+ VOID
+ NTAPI
+ ExRaiseStatus(
+ IN NTSTATUS Status);
+
+ NTKERNELAPI
+ PVOID
+ NTAPI
+ ExRegisterCallback(
+ IN PCALLBACK_OBJECT CallbackObject,
+ IN PCALLBACK_FUNCTION CallbackFunction,
+ IN PVOID CallbackContext);
+
+ NTKERNELAPI
+ NTSTATUS
+ NTAPI
+ ExReinitializeResourceLite(
+ IN PERESOURCE Resource);
+
+ NTKERNELAPI
+ VOID
+ NTAPI
+ ExReleaseResourceForThreadLite(
+ IN PERESOURCE Resource,
+ IN ERESOURCE_THREAD ResourceThreadId);
+
+ NTKERNELAPI
+ VOID
+ FASTCALL
+ ExReleaseResourceLite(
+ IN PERESOURCE Resource);
+
+ NTKERNELAPI
+ VOID
+ NTAPI
+ ExSetResourceOwnerPointer(
+ IN PERESOURCE Resource,
+ IN PVOID OwnerPointer);
+
+ NTKERNELAPI
+ ULONG
+ NTAPI
+ ExSetTimerResolution(
+ IN ULONG DesiredTime,
+ IN BOOLEAN SetResolution);
+
+ NTKERNELAPI
+ VOID
+ NTAPI
+ ExSystemTimeToLocalTime(
+ IN PLARGE_INTEGER SystemTime,
+ OUT PLARGE_INTEGER LocalTime);
+
+ NTKERNELAPI
+ VOID
+ NTAPI
+ ExUnregisterCallback(
+ IN PVOID CbRegistration);
+
+
+ #endif // (NTDDI_VERSION >= NTDDI_WIN2K)
+
+ #if (NTDDI_VERSION >= NTDDI_WINXP)
+ NTKERNELAPI
+ BOOLEAN
+ FASTCALL
+ ExAcquireRundownProtection(
+ IN OUT PEX_RUNDOWN_REF RunRef);
+
+ NTKERNELAPI
+ VOID
+ FASTCALL
+ ExInitializeRundownProtection(
+ OUT PEX_RUNDOWN_REF RunRef);
+
+ NTKERNELAPI
+ VOID
+ FASTCALL
+ ExReInitializeRundownProtection(
+ OUT PEX_RUNDOWN_REF RunRef);
+
+ NTKERNELAPI
+ VOID
+ FASTCALL
+ ExReleaseRundownProtection(
+ IN OUT PEX_RUNDOWN_REF RunRef);
+
+ NTKERNELAPI
+ VOID
+ FASTCALL
+ ExRundownCompleted(
+ OUT PEX_RUNDOWN_REF RunRef);
+
+ NTKERNELAPI
+ BOOLEAN
+ NTAPI
+ ExVerifySuite(
+ IN SUITE_TYPE SuiteType);
+
+ NTKERNELAPI
+ VOID
+ FASTCALL
+ ExWaitForRundownProtectionRelease(
+ IN OUT PEX_RUNDOWN_REF RunRef);
+
+ #endif // (NTDDI_VERSION >= NTDDI_WINXP)
+
+ #if (NTDDI_VERSION >= NTDDI_WINXPSP2)
+ NTKERNELAPI
+ BOOLEAN
+ FASTCALL
+ ExAcquireRundownProtectionEx(
+ IN OUT PEX_RUNDOWN_REF RunRef,
+ IN ULONG Count);
+
+ NTKERNELAPI
+ VOID
+ FASTCALL
+ ExReleaseRundownProtectionEx(
+ IN OUT PEX_RUNDOWN_REF RunRef,
+ IN ULONG Count);
+ #endif // (NTDDI_VERSION >= NTDDI_WINXPSP2)
+
+ #if (NTDDI_VERSION >= NTDDI_WS03)
+
+ #endif // (NTDDI_VERSION >= NTDDI_WS03)
+
+ #if (NTDDI_VERSION >= NTDDI_WS03SP1)
+ NTKERNELAPI
+ PEX_RUNDOWN_REF_CACHE_AWARE
+ ExAllocateCacheAwareRundownProtection(
+ IN POOL_TYPE PoolType,
+ IN ULONG PoolTag);
+
+ NTKERNELAPI
+ SIZE_T
+ ExSizeOfRundownProtectionCacheAware(VOID);
+
+ #endif // (NTDDI_VERSION >= NTDDI_WS03SP1)
+
+ #if (NTDDI_VERSION >= NTDDI_VISTA)
+ NTKERNELAPI
+ NTSTATUS
+ ExInitializeLookasideListEx(
+ OUT PLOOKASIDE_LIST_EX Lookaside,
+ IN PALLOCATE_FUNCTION_EX Allocate OPTIONAL,
+ IN PFREE_FUNCTION_EX Free OPTIONAL,
+ IN POOL_TYPE PoolType,
+ IN ULONG Flags,
+ IN SIZE_T Size,
+ IN ULONG Tag,
+ IN USHORT Depth);
+ #endif
+
+
+ #if !defined(MIDL_PASS)
+
+ static __inline PVOID
+ ExAllocateFromNPagedLookasideList(
+ IN PNPAGED_LOOKASIDE_LIST Lookaside)
+ {
+ PVOID Entry;
+
+ Lookaside->L.TotalAllocates++;
+ Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead);
+ if (Entry == NULL) {
+ Lookaside->L.AllocateMisses++;
+ Entry = (Lookaside->L.Allocate)(Lookaside->L.Type,
+ Lookaside->L.Size,
+ Lookaside->L.Tag);
+ }
+ return Entry;
+ }
+
+ static __inline PVOID
+ ExAllocateFromPagedLookasideList(
+ IN PPAGED_LOOKASIDE_LIST Lookaside)
+ {
+ PVOID Entry;
+
+ Lookaside->L.TotalAllocates++;
+ Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead);
+ if (Entry == NULL) {
+ Lookaside->L.AllocateMisses++;
+ Entry = (Lookaside->L.Allocate)(Lookaside->L.Type,
+ Lookaside->L.Size,
+ Lookaside->L.Tag);
+ }
+ return Entry;
+ }
+
+ static __inline VOID
+ ExFreeToNPagedLookasideList(
+ IN PNPAGED_LOOKASIDE_LIST Lookaside,
+ IN PVOID Entry)
+ {
+ Lookaside->L.TotalFrees++;
+ if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) {
+ Lookaside->L.FreeMisses++;
+ (Lookaside->L.Free)(Entry);
+ } else {
+ InterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry);
+ }
+ }
+
+ static __inline VOID
+ ExFreeToPagedLookasideList(
+ IN PPAGED_LOOKASIDE_LIST Lookaside,
+ IN PVOID Entry)
+ {
+ Lookaside->L.TotalFrees++;
+ if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) {
+ Lookaside->L.FreeMisses++;
+ (Lookaside->L.Free)(Entry);
+ } else {
+ InterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry);
+ }
+ }
+
+
+ #endif // !defined(MIDL_PASS)
+
+
+ #ifdef __cplusplus
+ }
+ #endif
+
+ #endif // _WDMDDK_
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
-<module name="oskittcp" type="staticlibrary">
+<module name="oskittcp" type="staticlibrary" allowwarnings="true">
<define name="__NTDRIVER__"/>
<define name="KERNEL"/>
- <define name="__NO_CTYPE_INLINES" />
<include base="oskittcp">include/freebsd</include>
<include base="oskittcp">include/freebsd/sys/include</include>
<include base="oskittcp">include/freebsd/src/sys</include>
case WIDM_GETDEVCAPS :
{
+
Result = MmeGetSoundDeviceCapabilities(WAVE_IN_DEVICE_TYPE,
DeviceId,
- (PVOID) Parameter1,
+ Parameter1,
Parameter2);
break;
}
/* Max size of the blocks on the free lists */
static const DWORD HEAP_freeListSizes[HEAP_NB_FREE_LISTS] =
{
- 0x10, 0x20, 0x80, 0x200, ~0UL
+ 0x10, 0x20, 0x80, 0x200, MAXULONG
};
-typedef struct
+typedef union
{
ARENA_FREE arena;
void *aligment[4];
- <?xml version="1.0"?>\r
- <!DOCTYPE group SYSTEM "../../tools/rbuild/project.dtd">\r
- <group xmlns:xi="http://www.w3.org/2001/XInclude">\r
- <directory name="crt">\r
- <xi:include href="crt/crt.rbuild" />\r
- <xi:include href="crt/libcntpr.rbuild" />\r
- </directory>\r
- <directory name="delayimp">\r
- <xi:include href="delayimp/delayimp.rbuild" />\r
- </directory>\r
- <directory name="dxguid">\r
- <xi:include href="dxguid/dxguid.rbuild" />\r
- </directory>\r
- <directory name="nt">\r
- <xi:include href="nt/nt.rbuild" />\r
- </directory>\r
- <directory name="strmiids">\r
- <xi:include href="strmiids/strmiids.rbuild" />\r
- </directory>\r
- <directory name="strsafe">\r
- <xi:include href="strsafe/strsafe.rbuild" />\r
- </directory>\r
- <directory name="uuid">\r
- <xi:include href="uuid/uuid.rbuild" />\r
- </directory>\r
- <directory name="wdmguid">\r
- <xi:include href="wdmguid/wdmguid.rbuild" />\r
- </directory>\r
- <directory name="scrnsave">\r
- <xi:include href="scrnsave/scrnsave.rbuild" />\r
- </directory>\r
- </group>\r
+ <?xml version="1.0"?>
+ <!DOCTYPE group SYSTEM "../../tools/rbuild/project.dtd">
+ <group xmlns:xi="http://www.w3.org/2001/XInclude">
+ <directory name="crt">
+ <xi:include href="crt/crt.rbuild" />
+ <xi:include href="crt/libcntpr.rbuild" />
+ </directory>
+ <directory name="delayimp">
+ <xi:include href="delayimp/delayimp.rbuild" />
+ </directory>
+ <directory name="dxguid">
+ <xi:include href="dxguid/dxguid.rbuild" />
+ </directory>
+ <directory name="nt">
+ <xi:include href="nt/nt.rbuild" />
+ </directory>
+ <directory name="strmiids">
+ <xi:include href="strmiids/strmiids.rbuild" />
+ </directory>
++ <directory name="strsafe">
++ <xi:include href="strsafe/strsafe.rbuild" />
++ </directory>
+ <directory name="uuid">
+ <xi:include href="uuid/uuid.rbuild" />
+ </directory>
+ <directory name="wdmguid">
+ <xi:include href="wdmguid/wdmguid.rbuild" />
+ </directory>
+ <directory name="scrnsave">
+ <xi:include href="scrnsave/scrnsave.rbuild" />
+ </directory>
+ </group>
--- /dev/null
- #if __GNUC__ >=3
- #pragma GCC system_header
- #endif
-
+#ifndef __NTOSKRNL_INCLUDE_INTERNAL_AMD64_KE_H
+#define __NTOSKRNL_INCLUDE_INTERNAL_AMD64_KE_H
+
- typedef
- VOID
- (NTAPI*PKSYSTEM_ROUTINE)(PKSTART_ROUTINE StartRoutine,
- PVOID StartContext);
-
+#define X86_EFLAGS_TF 0x00000100 /* Trap flag */
+#define X86_EFLAGS_IF 0x00000200 /* Interrupt Enable flag */
+#define X86_EFLAGS_IOPL 0x00003000 /* I/O Privilege Level bits */
+#define X86_EFLAGS_NT 0x00004000 /* Nested Task flag */
+#define X86_EFLAGS_RF 0x00010000 /* Resume flag */
+#define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */
+#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
+
+#define X86_CR0_PE 0x00000001 /* enable Protected Mode */
+#define X86_CR0_NE 0x00000020 /* enable native FPU error reporting */
+#define X86_CR0_TS 0x00000008 /* enable exception on FPU instruction for task switch */
+#define X86_CR0_EM 0x00000004 /* enable FPU emulation (disable FPU) */
+#define X86_CR0_MP 0x00000002 /* enable FPU monitoring */
+#define X86_CR0_WP 0x00010000 /* enable Write Protect (copy on write) */
+#define X86_CR0_PG 0x80000000 /* enable Paging */
+
+#define X86_CR4_PAE 0x00000020 /* enable physical address extensions */
+#define X86_CR4_PGE 0x00000080 /* enable global pages */
+#define X86_CR4_OSFXSR 0x00000200 /* enable FXSAVE/FXRSTOR instructions */
+#define X86_CR4_OSXMMEXCPT 0x00000400 /* enable #XF exception */
+
+#define X86_FEATURE_VME 0x00000002 /* Virtual 8086 Extensions are present */
+#define X86_FEATURE_TSC 0x00000010 /* time stamp counters are present */
+#define X86_FEATURE_PAE 0x00000040 /* physical address extension is present */
+#define X86_FEATURE_CX8 0x00000100 /* CMPXCHG8B instruction present */
+#define X86_FEATURE_SYSCALL 0x00000800 /* SYSCALL/SYSRET support present */
+#define X86_FEATURE_PGE 0x00002000 /* Page Global Enable */
+#define X86_FEATURE_MMX 0x00800000 /* MMX extension present */
+#define X86_FEATURE_FXSR 0x01000000 /* FXSAVE/FXRSTOR instructions present */
+#define X86_FEATURE_SSE 0x02000000 /* SSE extension present */
+#define X86_FEATURE_SSE2 0x04000000 /* SSE2 extension present */
+#define X86_FEATURE_HT 0x10000000 /* Hyper-Threading present */
+
+#define X86_EXT_FEATURE_SSE3 0x00000001 /* SSE3 extension present */
+#define X86_EXT_FEATURE_3DNOW 0x40000000 /* 3DNOW! extension present */
+
+#define FRAME_EDITED 0xFFF8
+
+#define X86_MSR_GSBASE 0xC0000101
+#define X86_MSR_KERNEL_GSBASE 0xC0000102
+#define X86_MSR_STAR 0xC0000081
+#define X86_MSR_LSTAR 0xC0000082
+#define X86_MSR_CSTAR 0xC0000083
+#define X86_MSR_SFMASK 0xC0000084
+
+#ifndef __ASM__
+
+#include "intrin_i.h"
+
+typedef struct _KIDT_INIT
+{
+ UCHAR InterruptId;
+ UCHAR Dpl;
+ UCHAR IstIndex;
+ PVOID ServiceRoutine;
+} KIDT_INIT, *PKIDT_INIT;
+
+//#define KeArchFnInit() Ke386FnInit()
+#define KeArchFnInit() DbgPrint("KeArchFnInit is unimplemented!\n");
+#define KeArchHaltProcessor() Ke386HaltProcessor()
+#define KfLowerIrql KeLowerIrql
+#define KfAcquireSpinLock KeAcquireSpinLock
+#define KfReleaseSpinLock KeReleaseSpinLock
+
+extern ULONG Ke386CacheAlignment;
+
++#define IMAGE_FILE_MACHINE_ARCHITECTURE IMAGE_FILE_MACHINE_I386
++
++//
++// INT3 is 1 byte long
++//
++#define KD_BREAKPOINT_TYPE UCHAR
++#define KD_BREAKPOINT_SIZE sizeof(UCHAR)
++#define KD_BREAKPOINT_VALUE 0xCC
++
++
+struct _KPCR;
+VOID
+KiInitializeGdt(struct _KPCR* Pcr);
+VOID
+Ki386ApplicationProcessorInitializeTSS(VOID);
+
+VOID
+FASTCALL
+Ki386InitializeTss(
+ IN PKTSS Tss,
+ IN PKIDTENTRY Idt,
+ IN PKGDTENTRY Gdt,
+ IN UINT64 Stack
+);
+
+VOID KiDivideErrorFault();
+VOID KiDebugTrapOrFault();
+VOID KiNmiInterrupt();
+VOID KiBreakpointTrap();
+VOID KiOverflowTrap();
+VOID KiBoundFault();
+VOID KiInvalidOpcodeFault();
+VOID KiNpxNotAvailableFault();
+VOID KiDoubleFaultAbort();
+VOID KiNpxSegmentOverrunAbort();
+VOID KiInvalidTssFault();
+VOID KiSegmentNotPresentFault();
+VOID KiStackFault();
+VOID KiGeneralProtectionFault();
+VOID KiPageFault();
+VOID KiFloatingErrorFault();
+VOID KiAlignmentFault();
+VOID KiMcheckAbort();
+VOID KiXmmException();
+VOID KiApcInterrupt();
+VOID KiRaiseAssertion();
+VOID KiDebugServiceTrap();
+VOID KiDpcInterrupt();
+VOID KiIpiInterrupt();
+
+VOID
+KiGdtPrepareForApplicationProcessorInit(ULONG Id);
+VOID
+Ki386InitializeLdt(VOID);
+VOID
+Ki386SetProcessorFeatures(VOID);
+
+VOID
+NTAPI
+KiGetCacheInformation(VOID);
+
+BOOLEAN
+NTAPI
+KiIsNpxPresent(
+ VOID
+);
+
+BOOLEAN
+NTAPI
+KiIsNpxErrataPresent(
+ VOID
+);
+
+VOID
+NTAPI
+KiSetProcessorType(VOID);
+
+ULONG
+NTAPI
+KiGetFeatureBits(VOID);
+
+VOID
+NTAPI
+KiInitializeCpuFeatures();
+
+ULONG KeAllocateGdtSelector(ULONG Desc[2]);
+VOID KeFreeGdtSelector(ULONG Entry);
+VOID
+NtEarlyInitVdm(VOID);
+VOID
+KeApplicationProcessorInitDispatcher(VOID);
+VOID
+KeCreateApplicationProcessorIdleThread(ULONG Id);
+
+VOID
+NTAPI
+Ke386InitThreadWithContext(PKTHREAD Thread,
+ PKSYSTEM_ROUTINE SystemRoutine,
+ PKSTART_ROUTINE StartRoutine,
+ PVOID StartContext,
+ PCONTEXT Context);
+#define KeArchInitThreadWithContext(Thread,SystemRoutine,StartRoutine,StartContext,Context) \
+ Ke386InitThreadWithContext(Thread,SystemRoutine,StartRoutine,StartContext,Context)
+
+#ifdef _NTOSKRNL_ /* FIXME: Move flags above to NDK instead of here */
+VOID
+NTAPI
+KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
+ PKSTART_ROUTINE StartRoutine,
+ PVOID StartContext,
+ BOOLEAN UserThread,
+ KTRAP_FRAME TrapFrame);
+#endif
+
+#endif
+#endif /* __NTOSKRNL_INCLUDE_INTERNAL_AMD64_KE_H */
+
+/* EOF */
- /*\r
- * ReactOS kernel\r
- * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
- */\r
- #ifndef __NTOSKRNL_INCLUDE_INTERNAL_ARCH_INTRIN_I_H\r
- #define __NTOSKRNL_INCLUDE_INTERNAL_ARCH_INTRIN_I_H\r
- \r
- #ifdef _M_IX86\r
- #include "../i386/intrin_i.h"\r
- #elif defined(_M_PPC)\r
- #include "../powerpc/intrin_i.h"\r
- #elif defined(_M_MIPS)\r
- #include "../mips/intrin_i.h"\r
- #elif defined(_M_ARM)\r
- #include "../arm/intrin_i.h"\r
- #elif defined(_M_AMD64)\r
- #include "../amd64/intrin_i.h"\r
- #else\r
- #error "Unknown processor"\r
- #endif\r
- \r
- #endif /* __NTOSKRNL_INCLUDE_INTERNAL_ARCH_INTRIN_I_H */\r
- \r
- /* EOF */\r
+ /*
+ * ReactOS kernel
+ * Copyright (C) 1998, 1999, 2000, 2001 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+ #ifndef __NTOSKRNL_INCLUDE_INTERNAL_ARCH_INTRIN_I_H
+ #define __NTOSKRNL_INCLUDE_INTERNAL_ARCH_INTRIN_I_H
+
+ #ifdef _M_IX86
+ #include "../i386/intrin_i.h"
+ #elif defined(_M_PPC)
+ #include "../powerpc/intrin_i.h"
+ #elif defined(_M_MIPS)
+ #include "../mips/intrin_i.h"
+ #elif defined(_M_ARM)
+ #include "../arm/intrin_i.h"
++#elif defined(_M_AMD64)
++#include "../amd64/intrin_i.h"
+ #else
+ #error "Unknown processor"
+ #endif
+
+ #endif /* __NTOSKRNL_INCLUDE_INTERNAL_ARCH_INTRIN_I_H */
+
+ /* EOF */
#endif
}
+ #else
+ //
+ // HACK: Hacked to work like normal spinlocks
+ //
+
+ VOID
+ FASTCALL
+ KeAcquireQueuedSpinLockAtDpcLevel(IN PKSPIN_LOCK_QUEUE LockHandle)
+ {
+ #ifdef CONFIG_SMP
+ /* Make sure we are at DPC or above! */
+ if (KeGetCurrentIrql() < DISPATCH_LEVEL)
+ {
+ /* We aren't -- bugcheck */
+ KeBugCheckEx(IRQL_NOT_GREATER_OR_EQUAL,
+ (ULONG_PTR)LockHandle->Lock,
+ KeGetCurrentIrql(),
+ 0,
+ 0);
+ }
+
+ /* Do the inlined function */
+ KxAcquireSpinLock(LockHandle->Lock);
+ #endif
+ }
+
+ VOID
+ FASTCALL
+ KeReleaseQueuedSpinLockFromDpcLevel(IN PKSPIN_LOCK_QUEUE LockHandle)
+ {
+ #ifdef CONFIG_SMP
+ /* Make sure we are at DPC or above! */
+ if (KeGetCurrentIrql() < DISPATCH_LEVEL)
+ {
+ /* We aren't -- bugcheck */
+ KeBugCheckEx(IRQL_NOT_GREATER_OR_EQUAL,
+ (ULONG_PTR)LockHandle->Lock,
+ KeGetCurrentIrql(),
+ 0,
+ 0);
+ }
+
+ /* Do the inlined function */
+ KxReleaseSpinLock(LockHandle->Lock);
+ #endif
+ }
+
+ #endif
+
/* PUBLIC FUNCTIONS **********************************************************/
+#ifdef _X86_
/*
* @implemented
*/
- /*\r
- * PROJECT: ReactOS Kernel\r
- * LICENSE: GPL - See COPYING in the top level directory\r
- * FILE: ntoskrnl/mm/sysldr.c\r
- * PURPOSE: Contains the Kernel Loader (SYSLDR) for loading PE files.\r
- * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)\r
- */\r
- \r
- /* INCLUDES ******************************************************************/\r
- \r
- #include <ntoskrnl.h>\r
- #define NDEBUG\r
- #include <debug.h>\r
- \r
- /* GCC's incompetence strikes again */\r
- __inline\r
- VOID\r
- sprintf_nt(IN PCHAR Buffer,\r
- IN PCHAR Format,\r
- IN ...)\r
- {\r
- va_list ap;\r
- va_start(ap, Format);\r
- vsprintf(Buffer, Format, ap);\r
- va_end(ap);\r
- }\r
- \r
- /* GLOBALS *******************************************************************/\r
- \r
- LIST_ENTRY PsLoadedModuleList;\r
- KSPIN_LOCK PsLoadedModuleSpinLock;\r
- ULONG_PTR PsNtosImageBase;\r
- KMUTANT MmSystemLoadLock;\r
- extern ULONG NtGlobalFlag;\r
- \r
- /* FUNCTIONS *****************************************************************/\r
- \r
- PVOID\r
- NTAPI\r
- MiCacheImageSymbols(IN PVOID BaseAddress)\r
- {\r
- ULONG DebugSize;\r
- PVOID DebugDirectory = NULL;\r
- PAGED_CODE();\r
- \r
- /* Make sure it's safe to access the image */\r
- _SEH2_TRY\r
- {\r
- /* Get the debug directory */\r
- DebugDirectory = RtlImageDirectoryEntryToData(BaseAddress,\r
- TRUE,\r
- IMAGE_DIRECTORY_ENTRY_DEBUG,\r
- &DebugSize);\r
- }\r
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)\r
- {\r
- /* Nothing */\r
- }\r
- _SEH2_END;\r
- \r
- /* Return the directory */\r
- return DebugDirectory;\r
- }\r
- \r
- VOID\r
- NTAPI\r
- MiFreeBootDriverMemory(PVOID BaseAddress,\r
- ULONG Length)\r
- {\r
- ULONG i;\r
- \r
- /* Loop each page */\r
- for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++)\r
- {\r
- /* Free the page */\r
- MmDeleteVirtualMapping(NULL,\r
- (PVOID)((ULONG_PTR)BaseAddress + i * PAGE_SIZE),\r
- TRUE,\r
- NULL,\r
- NULL);\r
- }\r
- }\r
- \r
- NTSTATUS\r
- NTAPI\r
- MiLoadImageSection(IN OUT PVOID *SectionPtr,\r
- OUT PVOID *ImageBase,\r
- IN PUNICODE_STRING FileName,\r
- IN BOOLEAN SessionLoad,\r
- IN PLDR_DATA_TABLE_ENTRY LdrEntry)\r
- {\r
- PROS_SECTION_OBJECT Section = *SectionPtr;\r
- NTSTATUS Status;\r
- PEPROCESS Process;\r
- PVOID Base = NULL;\r
- SIZE_T ViewSize = 0;\r
- KAPC_STATE ApcState;\r
- LARGE_INTEGER SectionOffset = {{0, 0}};\r
- BOOLEAN LoadSymbols = FALSE;\r
- ULONG DriverSize;\r
- PVOID DriverBase;\r
- PAGED_CODE();\r
- \r
- /* Detect session load */\r
- if (SessionLoad)\r
- {\r
- /* Fail */\r
- DPRINT1("Session loading not yet supported!\n");\r
- while (TRUE);\r
- }\r
- \r
- /* Not session load, shouldn't have an entry */\r
- ASSERT(LdrEntry == NULL);\r
- \r
- /* Attach to the system process */\r
- KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState);\r
- \r
- /* Check if we need to load symbols */\r
- if (NtGlobalFlag & FLG_ENABLE_KDEBUG_SYMBOL_LOAD)\r
- {\r
- /* Yes we do */\r
- LoadSymbols = TRUE;\r
- NtGlobalFlag &= ~FLG_ENABLE_KDEBUG_SYMBOL_LOAD;\r
- }\r
- \r
- /* Map the driver */\r
- Process = PsGetCurrentProcess();\r
- Status = MmMapViewOfSection(Section,\r
- Process,\r
- &Base,\r
- 0,\r
- 0,\r
- &SectionOffset,\r
- &ViewSize,\r
- ViewUnmap,\r
- 0,\r
- PAGE_EXECUTE);\r
- \r
- /* Re-enable the flag */\r
- if (LoadSymbols) NtGlobalFlag |= FLG_ENABLE_KDEBUG_SYMBOL_LOAD;\r
- \r
- /* Check if we failed with distinguished status code */\r
- if (Status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH)\r
- {\r
- /* Change it to something more generic */\r
- Status = STATUS_INVALID_IMAGE_FORMAT;\r
- }\r
- \r
- /* Now check if we failed */\r
- if (!NT_SUCCESS(Status))\r
- {\r
- /* Detach and return */\r
- KeUnstackDetachProcess(&ApcState);\r
- return Status;\r
- }\r
- \r
- /* Get the driver size */\r
- DriverSize = Section->ImageSection->ImageSize;\r
- \r
- /* Allocate a virtual section for the module */\r
- DriverBase = MmAllocateSection(DriverSize, NULL);\r
- *ImageBase = DriverBase;\r
- \r
- /* Copy the image */\r
- RtlCopyMemory(DriverBase, Base, DriverSize);\r
- \r
- /* Now unmap the view */\r
- Status = MmUnmapViewOfSection(Process, Base);\r
- ASSERT(NT_SUCCESS(Status));\r
- \r
- /* Detach and return status */\r
- KeUnstackDetachProcess(&ApcState);\r
- return Status;\r
- }\r
- \r
- NTSTATUS\r
- NTAPI\r
- MiDereferenceImports(IN PLOAD_IMPORTS ImportList)\r
- {\r
- SIZE_T i;\r
- \r
- /* Check if there's no imports or if we're a boot driver */\r
- if ((ImportList == (PVOID)-1) ||\r
- (ImportList == (PVOID)-2) ||\r
- (ImportList->Count == 0))\r
- {\r
- /* Then there's nothing to do */\r
- return STATUS_SUCCESS;\r
- }\r
- \r
- /* Otherwise, FIXME */\r
- DPRINT1("%u imports not dereferenced!\n", ImportList->Count);\r
- for (i = 0; i < ImportList->Count; i++)\r
- {\r
- DPRINT1("%wZ <%wZ>\n", &ImportList->Entry[i]->FullDllName, &ImportList->Entry[i]->BaseDllName);\r
- }\r
- return STATUS_UNSUCCESSFUL;\r
- }\r
- \r
- VOID\r
- NTAPI\r
- MiClearImports(IN PLDR_DATA_TABLE_ENTRY LdrEntry)\r
- {\r
- PAGED_CODE();\r
- \r
- /* Check if there's no imports or we're a boot driver or only one entry */\r
- if ((LdrEntry->LoadedImports == (PVOID)-1) ||\r
- (LdrEntry->LoadedImports == (PVOID)-2) ||\r
- ((ULONG_PTR)LdrEntry->LoadedImports & 1))\r
- {\r
- /* Nothing to do */\r
- return;\r
- }\r
- \r
- /* Otherwise, free the import list */\r
- ExFreePool(LdrEntry->LoadedImports);\r
- }\r
- \r
- PVOID\r
- NTAPI\r
- MiFindExportedRoutineByName(IN PVOID DllBase,\r
- IN PANSI_STRING ExportName)\r
- {\r
- PULONG NameTable;\r
- PUSHORT OrdinalTable;\r
- PIMAGE_EXPORT_DIRECTORY ExportDirectory;\r
- LONG Low = 0, Mid = 0, High, Ret;\r
- USHORT Ordinal;\r
- PVOID Function;\r
- ULONG ExportSize;\r
- PULONG ExportTable;\r
- PAGED_CODE();\r
- \r
- /* Get the export directory */\r
- ExportDirectory = RtlImageDirectoryEntryToData(DllBase,\r
- TRUE,\r
- IMAGE_DIRECTORY_ENTRY_EXPORT,\r
- &ExportSize);\r
- if (!ExportDirectory) return NULL;\r
- \r
- /* Setup name tables */\r
- NameTable = (PULONG)((ULONG_PTR)DllBase +\r
- ExportDirectory->AddressOfNames);\r
- OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +\r
- ExportDirectory->AddressOfNameOrdinals);\r
- \r
- /* Do a binary search */\r
- High = ExportDirectory->NumberOfNames - 1;\r
- while (High >= Low)\r
- {\r
- /* Get new middle value */\r
- Mid = (Low + High) >> 1;\r
- \r
- /* Compare name */\r
- Ret = strcmp(ExportName->Buffer, (PCHAR)DllBase + NameTable[Mid]);\r
- if (Ret < 0)\r
- {\r
- /* Update high */\r
- High = Mid - 1;\r
- }\r
- else if (Ret > 0)\r
- {\r
- /* Update low */\r
- Low = Mid + 1;\r
- }\r
- else\r
- {\r
- /* We got it */\r
- break;\r
- }\r
- }\r
- \r
- /* Check if we couldn't find it */\r
- if (High < Low) return NULL;\r
- \r
- /* Otherwise, this is the ordinal */\r
- Ordinal = OrdinalTable[Mid];\r
- \r
- /* Resolve the address and write it */\r
- ExportTable = (PULONG)((ULONG_PTR)DllBase +\r
- ExportDirectory->AddressOfFunctions);\r
- Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);\r
- \r
- /* We found it! */\r
- ASSERT(!(Function > (PVOID)ExportDirectory) &&\r
- (Function < (PVOID)((ULONG_PTR)ExportDirectory + ExportSize)));\r
- return Function;\r
- }\r
- \r
- PVOID\r
- NTAPI\r
- MiLocateExportName(IN PVOID DllBase,\r
- IN PCHAR ExportName)\r
- {\r
- PULONG NameTable;\r
- PUSHORT OrdinalTable;\r
- PIMAGE_EXPORT_DIRECTORY ExportDirectory;\r
- LONG Low = 0, Mid = 0, High, Ret;\r
- USHORT Ordinal;\r
- PVOID Function;\r
- ULONG ExportSize;\r
- PULONG ExportTable;\r
- PAGED_CODE();\r
- \r
- /* Get the export directory */\r
- ExportDirectory = RtlImageDirectoryEntryToData(DllBase,\r
- TRUE,\r
- IMAGE_DIRECTORY_ENTRY_EXPORT,\r
- &ExportSize);\r
- if (!ExportDirectory) return NULL;\r
- \r
- /* Setup name tables */\r
- NameTable = (PULONG)((ULONG_PTR)DllBase +\r
- ExportDirectory->AddressOfNames);\r
- OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +\r
- ExportDirectory->AddressOfNameOrdinals);\r
- \r
- /* Do a binary search */\r
- High = ExportDirectory->NumberOfNames - 1;\r
- while (High >= Low)\r
- {\r
- /* Get new middle value */\r
- Mid = (Low + High) >> 1;\r
- \r
- /* Compare name */\r
- Ret = strcmp(ExportName, (PCHAR)DllBase + NameTable[Mid]);\r
- if (Ret < 0)\r
- {\r
- /* Update high */\r
- High = Mid - 1;\r
- }\r
- else if (Ret > 0)\r
- {\r
- /* Update low */\r
- Low = Mid + 1;\r
- }\r
- else\r
- {\r
- /* We got it */\r
- break;\r
- }\r
- }\r
- \r
- /* Check if we couldn't find it */\r
- if (High < Low) return NULL;\r
- \r
- /* Otherwise, this is the ordinal */\r
- Ordinal = OrdinalTable[Mid];\r
- \r
- /* Resolve the address and write it */\r
- ExportTable = (PULONG)((ULONG_PTR)DllBase +\r
- ExportDirectory->AddressOfFunctions);\r
- Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);\r
- \r
- /* Check if the function is actually a forwarder */\r
- if (((ULONG_PTR)Function > (ULONG_PTR)ExportDirectory) &&\r
- ((ULONG_PTR)Function < ((ULONG_PTR)ExportDirectory + ExportSize)))\r
- {\r
- /* It is, fail */\r
- return NULL;\r
- }\r
- \r
- /* We found it */\r
- return Function;\r
- }\r
- \r
- NTSTATUS\r
- NTAPI\r
- MmCallDllInitialize(IN PLDR_DATA_TABLE_ENTRY LdrEntry,\r
- IN PLIST_ENTRY ListHead)\r
- {\r
- UNICODE_STRING ServicesKeyName = RTL_CONSTANT_STRING(\r
- L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");\r
- PMM_DLL_INITIALIZE DllInit;\r
- UNICODE_STRING RegPath, ImportName;\r
- NTSTATUS Status;\r
- \r
- /* Try to see if the image exports a DllInitialize routine */\r
- DllInit = (PMM_DLL_INITIALIZE)MiLocateExportName(LdrEntry->DllBase,\r
- "DllInitialize");\r
- if (!DllInit) return STATUS_SUCCESS;\r
- \r
- /* Do a temporary copy of BaseDllName called ImportName\r
- * because we'll alter the length of the string\r
- */\r
- ImportName.Length = LdrEntry->BaseDllName.Length;\r
- ImportName.MaximumLength = LdrEntry->BaseDllName.MaximumLength;\r
- ImportName.Buffer = LdrEntry->BaseDllName.Buffer;\r
- \r
- /* Obtain the path to this dll's service in the registry */\r
- RegPath.MaximumLength = ServicesKeyName.Length +\r
- ImportName.Length + sizeof(UNICODE_NULL);\r
- RegPath.Buffer = ExAllocatePoolWithTag(NonPagedPool,\r
- RegPath.MaximumLength,\r
- TAG_LDR_WSTR);\r
- \r
- /* Check if this allocation was unsuccessful */\r
- if (!RegPath.Buffer) return STATUS_INSUFFICIENT_RESOURCES;\r
- \r
- /* Build and append the service name itself */\r
- RegPath.Length = ServicesKeyName.Length;\r
- RtlCopyMemory(RegPath.Buffer,\r
- ServicesKeyName.Buffer,\r
- ServicesKeyName.Length);\r
- \r
- /* Check if there is a dot in the filename */\r
- if (wcschr(ImportName.Buffer, L'.'))\r
- {\r
- /* Remove the extension */\r
- ImportName.Length = (wcschr(ImportName.Buffer, L'.') -\r
- ImportName.Buffer) * sizeof(WCHAR);\r
- }\r
- \r
- /* Append service name (the basename without extension) */\r
- RtlAppendUnicodeStringToString(&RegPath, &ImportName);\r
- \r
- /* Now call the DllInit func */\r
- DPRINT("Calling DllInit(%wZ)\n", &RegPath);\r
- Status = DllInit(&RegPath);\r
- \r
- /* Clean up */\r
- ExFreePool(RegPath.Buffer);\r
- \r
- /* Return status value which DllInitialize returned */\r
- return Status;\r
- }\r
- \r
- VOID\r
- NTAPI\r
- MiProcessLoaderEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry,\r
- IN BOOLEAN Insert)\r
- {\r
- KIRQL OldIrql;\r
- \r
- /* Acquire the lock */\r
- KeAcquireSpinLock(&PsLoadedModuleSpinLock, &OldIrql);\r
- \r
- /* Insert or remove from the list */\r
- Insert ? InsertTailList(&PsLoadedModuleList, &LdrEntry->InLoadOrderLinks) :\r
- RemoveEntryList(&LdrEntry->InLoadOrderLinks);\r
- \r
- /* Release the lock */\r
- KeReleaseSpinLock(&PsLoadedModuleSpinLock, OldIrql);\r
- }\r
- \r
- VOID\r
- NTAPI\r
- MiUpdateThunks(IN PLOADER_PARAMETER_BLOCK LoaderBlock,\r
- IN PVOID OldBase,\r
- IN PVOID NewBase,\r
- IN ULONG Size)\r
- {\r
- ULONG_PTR OldBaseTop, Delta;\r
- PLDR_DATA_TABLE_ENTRY LdrEntry;\r
- PLIST_ENTRY NextEntry;\r
- ULONG ImportSize;\r
- PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;\r
- PULONG ImageThunk;\r
- \r
- /* Calculate the top and delta */\r
- OldBaseTop = (ULONG_PTR)OldBase + Size - 1;\r
- Delta = (ULONG_PTR)NewBase - (ULONG_PTR)OldBase;\r
- \r
- /* Loop the loader block */\r
- for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;\r
- NextEntry != &LoaderBlock->LoadOrderListHead;\r
- NextEntry = NextEntry->Flink)\r
- {\r
- /* Get the loader entry */\r
- LdrEntry = CONTAINING_RECORD(NextEntry,\r
- LDR_DATA_TABLE_ENTRY,\r
- InLoadOrderLinks);\r
- \r
- /* Get the import table */\r
- ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,\r
- TRUE,\r
- IMAGE_DIRECTORY_ENTRY_IMPORT,\r
- &ImportSize);\r
- if (!ImportDescriptor) continue;\r
- \r
- /* Make sure we have an IAT */\r
- DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);\r
- while ((ImportDescriptor->Name) &&\r
- (ImportDescriptor->OriginalFirstThunk))\r
- {\r
- /* Get the image thunk */\r
- ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +\r
- ImportDescriptor->FirstThunk);\r
- while (*ImageThunk)\r
- {\r
- /* Check if it's within this module */\r
- if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))\r
- {\r
- /* Relocate it */\r
- DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",\r
- ImageThunk, *ImageThunk, *ImageThunk + Delta);\r
- *ImageThunk += Delta;\r
- }\r
- \r
- /* Go to the next thunk */\r
- ImageThunk++;\r
- }\r
- \r
- /* Go to the next import */\r
- ImportDescriptor++;\r
- }\r
- }\r
- }\r
- \r
- NTSTATUS\r
- NTAPI\r
- MiSnapThunk(IN PVOID DllBase,\r
- IN PVOID ImageBase,\r
- IN PIMAGE_THUNK_DATA Name,\r
- IN PIMAGE_THUNK_DATA Address,\r
- IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,\r
- IN ULONG ExportSize,\r
- IN BOOLEAN SnapForwarder,\r
- OUT PCHAR *MissingApi)\r
- {\r
- BOOLEAN IsOrdinal;\r
- USHORT Ordinal;\r
- PULONG NameTable;\r
- PUSHORT OrdinalTable;\r
- PIMAGE_IMPORT_BY_NAME NameImport;\r
- USHORT Hint;\r
- ULONG Low = 0, Mid = 0, High;\r
- LONG Ret;\r
- NTSTATUS Status;\r
- PCHAR MissingForwarder;\r
- CHAR NameBuffer[MAXIMUM_FILENAME_LENGTH];\r
- PULONG ExportTable;\r
- ANSI_STRING DllName;\r
- UNICODE_STRING ForwarderName;\r
- PLIST_ENTRY NextEntry;\r
- PLDR_DATA_TABLE_ENTRY LdrEntry;\r
- ULONG ForwardExportSize;\r
- PIMAGE_EXPORT_DIRECTORY ForwardExportDirectory;\r
- PIMAGE_IMPORT_BY_NAME ForwardName;\r
- ULONG ForwardLength;\r
- IMAGE_THUNK_DATA ForwardThunk;\r
- PAGED_CODE();\r
- \r
- /* Check if this is an ordinal */\r
- IsOrdinal = IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal);\r
- if ((IsOrdinal) && !(SnapForwarder))\r
- {\r
- /* Get the ordinal number and set it as missing */\r
- Ordinal = (USHORT)(IMAGE_ORDINAL(Name->u1.Ordinal) -\r
- ExportDirectory->Base);\r
- *MissingApi = (PCHAR)(ULONG_PTR)Ordinal;\r
- }\r
- else\r
- {\r
- /* Get the VA if we don't have to snap */\r
- if (!SnapForwarder) Name->u1.AddressOfData += (ULONG_PTR)ImageBase;\r
- NameImport = (PIMAGE_IMPORT_BY_NAME)Name->u1.AddressOfData;\r
- \r
- /* Copy the procedure name */\r
- strncpy(*MissingApi,\r
- (PCHAR)&NameImport->Name[0],\r
- MAXIMUM_FILENAME_LENGTH - 1);\r
- \r
- /* Setup name tables */\r
- DPRINT("Import name: %s\n", NameImport->Name);\r
- NameTable = (PULONG)((ULONG_PTR)DllBase +\r
- ExportDirectory->AddressOfNames);\r
- OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +\r
- ExportDirectory->AddressOfNameOrdinals);\r
- \r
- /* Get the hint and check if it's valid */\r
- Hint = NameImport->Hint;\r
- if ((Hint < ExportDirectory->NumberOfNames) &&\r
- !(strcmp((PCHAR) NameImport->Name, (PCHAR)DllBase + NameTable[Hint])))\r
- {\r
- /* We have a match, get the ordinal number from here */\r
- Ordinal = OrdinalTable[Hint];\r
- }\r
- else\r
- {\r
- /* Do a binary search */\r
- High = ExportDirectory->NumberOfNames - 1;\r
- while (High >= Low)\r
- {\r
- /* Get new middle value */\r
- Mid = (Low + High) >> 1;\r
- \r
- /* Compare name */\r
- Ret = strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Mid]);\r
- if (Ret < 0)\r
- {\r
- /* Update high */\r
- High = Mid - 1;\r
- }\r
- else if (Ret > 0)\r
- {\r
- /* Update low */\r
- Low = Mid + 1;\r
- }\r
- else\r
- {\r
- /* We got it */\r
- break;\r
- }\r
- }\r
- \r
- /* Check if we couldn't find it */\r
- if (High < Low) return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;\r
- \r
- /* Otherwise, this is the ordinal */\r
- Ordinal = OrdinalTable[Mid];\r
- }\r
- }\r
- \r
- /* Check if the ordinal is invalid */\r
- if (Ordinal >= ExportDirectory->NumberOfFunctions)\r
- {\r
- /* Fail */\r
- Status = STATUS_DRIVER_ORDINAL_NOT_FOUND;\r
- }\r
- else\r
- {\r
- /* In case the forwarder is missing */\r
- MissingForwarder = NameBuffer;\r
- \r
- /* Resolve the address and write it */\r
- ExportTable = (PULONG)((ULONG_PTR)DllBase +\r
- ExportDirectory->AddressOfFunctions);\r
- Address->u1.Function = (ULONG_PTR)DllBase + ExportTable[Ordinal];\r
- \r
- /* Assume success from now on */\r
- Status = STATUS_SUCCESS;\r
- \r
- /* Check if the function is actually a forwarder */\r
- if ((Address->u1.Function > (ULONG_PTR)ExportDirectory) &&\r
- (Address->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)))\r
- {\r
- /* Now assume failure in case the forwarder doesn't exist */\r
- Status = STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;\r
- \r
- /* Build the forwarder name */\r
- DllName.Buffer = (PCHAR)Address->u1.Function;\r
- DllName.Length = strchr(DllName.Buffer, '.') -\r
- DllName.Buffer +\r
- sizeof(ANSI_NULL);\r
- DllName.MaximumLength = DllName.Length;\r
- \r
- /* Convert it */\r
- if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ForwarderName,\r
- &DllName,\r
- TRUE)))\r
- {\r
- /* We failed, just return an error */\r
- return Status;\r
- }\r
- \r
- /* Loop the module list */\r
- NextEntry = PsLoadedModuleList.Flink;\r
- while (NextEntry != &PsLoadedModuleList)\r
- {\r
- /* Get the loader entry */\r
- LdrEntry = CONTAINING_RECORD(NextEntry,\r
- LDR_DATA_TABLE_ENTRY,\r
- InLoadOrderLinks);\r
- \r
- /* Check if it matches */\r
- if (RtlPrefixString((PSTRING)&ForwarderName,\r
- (PSTRING)&LdrEntry->BaseDllName,\r
- TRUE))\r
- {\r
- /* Get the forwarder export directory */\r
- ForwardExportDirectory =\r
- RtlImageDirectoryEntryToData(LdrEntry->DllBase,\r
- TRUE,\r
- IMAGE_DIRECTORY_ENTRY_EXPORT,\r
- &ForwardExportSize);\r
- if (!ForwardExportDirectory) break;\r
- \r
- /* Allocate a name entry */\r
- ForwardLength = strlen(DllName.Buffer + DllName.Length) +\r
- sizeof(ANSI_NULL);\r
- ForwardName = ExAllocatePoolWithTag(PagedPool,\r
- sizeof(*ForwardName) +\r
- ForwardLength,\r
- TAG_LDR_WSTR);\r
- if (!ForwardName) break;\r
- \r
- /* Copy the data */\r
- RtlCopyMemory(&ForwardName->Name[0],\r
- DllName.Buffer + DllName.Length,\r
- ForwardLength);\r
- ForwardName->Hint = 0;\r
- \r
- /* Set the new address */\r
- ForwardThunk.u1.AddressOfData = (ULONG_PTR)ForwardName;\r
- \r
- /* Snap the forwarder */\r
- Status = MiSnapThunk(LdrEntry->DllBase,\r
- ImageBase,\r
- &ForwardThunk,\r
- &ForwardThunk,\r
- ForwardExportDirectory,\r
- ForwardExportSize,\r
- TRUE,\r
- &MissingForwarder);\r
- \r
- /* Free the forwarder name and set the thunk */\r
- ExFreePoolWithTag(ForwardName, TAG_LDR_WSTR);\r
- Address->u1 = ForwardThunk.u1;\r
- break;\r
- }\r
- \r
- /* Go to the next entry */\r
- NextEntry = NextEntry->Flink;\r
- }\r
- \r
- /* Free the name */\r
- RtlFreeUnicodeString(&ForwarderName);\r
- }\r
- }\r
- \r
- /* Return status */\r
- return Status;\r
- }\r
- \r
- NTSTATUS\r
- NTAPI\r
- MmUnloadSystemImage(IN PVOID ImageHandle)\r
- {\r
- PLDR_DATA_TABLE_ENTRY LdrEntry = ImageHandle;\r
- PVOID BaseAddress = LdrEntry->DllBase;\r
- NTSTATUS Status;\r
- ANSI_STRING TempName;\r
- BOOLEAN HadEntry = FALSE;\r
- \r
- /* Acquire the loader lock */\r
- KeEnterCriticalRegion();\r
- KeWaitForSingleObject(&MmSystemLoadLock,\r
- WrVirtualMemory,\r
- KernelMode,\r
- FALSE,\r
- NULL);\r
- \r
- /* Check if this driver was loaded at boot and didn't get imports parsed */\r
- if (LdrEntry->LoadedImports == (PVOID)-1) goto Done;\r
- \r
- /* We should still be alive */\r
- ASSERT(LdrEntry->LoadCount != 0);\r
- LdrEntry->LoadCount--;\r
- \r
- /* Check if we're still loaded */\r
- if (LdrEntry->LoadCount) goto Done;\r
- \r
- /* We should cleanup... are symbols loaded */\r
- if (LdrEntry->Flags & LDRP_DEBUG_SYMBOLS_LOADED)\r
- {\r
- /* Create the ANSI name */\r
- Status = RtlUnicodeStringToAnsiString(&TempName,\r
- &LdrEntry->BaseDllName,\r
- TRUE);\r
- if (NT_SUCCESS(Status))\r
- {\r
- /* Unload the symbols */\r
- DbgUnLoadImageSymbols(&TempName, BaseAddress, -1);\r
- RtlFreeAnsiString(&TempName);\r
- }\r
- }\r
- \r
- /* FIXME: Free the driver */\r
- //MmFreeSection(LdrEntry->DllBase);\r
- \r
- /* Check if we're linked in */\r
- if (LdrEntry->InLoadOrderLinks.Flink)\r
- {\r
- /* Remove us */\r
- MiProcessLoaderEntry(LdrEntry, FALSE);\r
- HadEntry = TRUE;\r
- }\r
- \r
- /* Dereference and clear the imports */\r
- MiDereferenceImports(LdrEntry->LoadedImports);\r
- MiClearImports(LdrEntry);\r
- \r
- /* Check if the entry needs to go away */\r
- if (HadEntry)\r
- {\r
- /* Check if it had a name */\r
- if (LdrEntry->FullDllName.Buffer)\r
- {\r
- /* Free it */\r
- ExFreePool(LdrEntry->FullDllName.Buffer);\r
- }\r
- \r
- /* Check if we had a section */\r
- if (LdrEntry->SectionPointer)\r
- {\r
- /* Dereference it */\r
- ObDereferenceObject(LdrEntry->SectionPointer);\r
- }\r
- \r
- /* Free the entry */\r
- ExFreePool(LdrEntry);\r
- }\r
- \r
- /* Release the system lock and return */\r
- Done:\r
- KeReleaseMutant(&MmSystemLoadLock, 1, FALSE, FALSE);\r
- KeLeaveCriticalRegion();\r
- return STATUS_SUCCESS;\r
- }\r
- \r
- NTSTATUS\r
- NTAPI\r
- MiResolveImageReferences(IN PVOID ImageBase,\r
- IN PUNICODE_STRING ImageFileDirectory,\r
- IN PUNICODE_STRING NamePrefix OPTIONAL,\r
- OUT PCHAR *MissingApi,\r
- OUT PWCHAR *MissingDriver,\r
- OUT PLOAD_IMPORTS *LoadImports)\r
- {\r
- PCHAR MissingApiBuffer = *MissingApi, ImportName;\r
- PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport;\r
- ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize;\r
- PLOAD_IMPORTS LoadedImports, NewImports;\r
- ULONG GdiLink, NormalLink, i;\r
- BOOLEAN ReferenceNeeded, Loaded;\r
- ANSI_STRING TempString;\r
- UNICODE_STRING NameString, DllName;\r
- PLDR_DATA_TABLE_ENTRY LdrEntry = NULL, DllEntry, ImportEntry = NULL;\r
- PVOID ImportBase, DllBase;\r
- PLIST_ENTRY NextEntry;\r
- PIMAGE_EXPORT_DIRECTORY ExportDirectory;\r
- NTSTATUS Status;\r
- PIMAGE_THUNK_DATA OrigThunk, FirstThunk;\r
- PAGED_CODE();\r
- DPRINT("%s - ImageBase: %p. ImageFileDirectory: %wZ\n",\r
- __FUNCTION__, ImageBase, ImageFileDirectory);\r
- \r
- /* Assume no imports */\r
- *LoadImports = (PVOID)-2;\r
- \r
- /* Get the import descriptor */\r
- ImportDescriptor = RtlImageDirectoryEntryToData(ImageBase,\r
- TRUE,\r
- IMAGE_DIRECTORY_ENTRY_IMPORT,\r
- &ImportSize);\r
- if (!ImportDescriptor) return STATUS_SUCCESS;\r
- \r
- /* Loop all imports to count them */\r
- for (CurrentImport = ImportDescriptor;\r
- (CurrentImport->Name) && (CurrentImport->OriginalFirstThunk);\r
- CurrentImport++)\r
- {\r
- /* One more */\r
- ImportCount++;\r
- }\r
- \r
- /* Make sure we have non-zero imports */\r
- if (ImportCount)\r
- {\r
- /* Calculate and allocate the list we'll need */\r
- LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);\r
- LoadedImports = ExAllocatePoolWithTag(PagedPool,\r
- LoadedImportsSize,\r
- TAG_LDR_WSTR);\r
- if (LoadedImports)\r
- {\r
- /* Zero it */\r
- RtlZeroMemory(LoadedImports, LoadedImportsSize);\r
- }\r
- }\r
- else\r
- {\r
- /* No table */\r
- LoadedImports = NULL;\r
- }\r
- \r
- /* Reset the import count and loop descriptors again */\r
- ImportCount = GdiLink = NormalLink = 0;\r
- while ((ImportDescriptor->Name) && (ImportDescriptor->OriginalFirstThunk))\r
- {\r
- /* Get the name */\r
- ImportName = (PCHAR)((ULONG_PTR)ImageBase + ImportDescriptor->Name);\r
- \r
- /* Check if this is a GDI driver */\r
- GdiLink = GdiLink |\r
- !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1));\r
- \r
- /* We can also allow dxapi */\r
- NormalLink = NormalLink |\r
- ((_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) &&\r
- (_strnicmp(ImportName, "dxapi", sizeof("dxapi") - 1)));\r
- \r
- /* Check if this is a valid GDI driver */\r
- if ((GdiLink) && (NormalLink))\r
- {\r
- /* It's not, it's importing stuff it shouldn't be! */\r
- MiDereferenceImports(LoadedImports);\r
- if (LoadedImports) ExFreePool(LoadedImports);\r
- return STATUS_PROCEDURE_NOT_FOUND;\r
- }\r
- \r
- /* Check if this is a "core" import, which doesn't get referenced */\r
- if (!(_strnicmp(ImportName, "ntoskrnl", sizeof("ntoskrnl") - 1)) ||\r
- !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) ||\r
- !(_strnicmp(ImportName, "hal", sizeof("hal") - 1)))\r
- {\r
- /* Don't reference this */\r
- ReferenceNeeded = FALSE;\r
- }\r
- else\r
- {\r
- /* Reference these modules */\r
- ReferenceNeeded = TRUE;\r
- }\r
- \r
- /* Now setup a unicode string for the import */\r
- RtlInitAnsiString(&TempString, ImportName);\r
- Status = RtlAnsiStringToUnicodeString(&NameString, &TempString, TRUE);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- /* Failed */\r
- MiDereferenceImports(LoadedImports);\r
- if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);\r
- return Status;\r
- }\r
- \r
- /* We don't support name prefixes yet */\r
- if (NamePrefix) DPRINT1("Name Prefix not yet supported!\n");\r
- \r
- /* Remember that we haven't loaded the import at this point */\r
- CheckDllState:\r
- Loaded = FALSE;\r
- ImportBase = NULL;\r
- \r
- /* Loop the driver list */\r
- NextEntry = PsLoadedModuleList.Flink;\r
- while (NextEntry != &PsLoadedModuleList)\r
- {\r
- /* Get the loader entry and compare the name */\r
- LdrEntry = CONTAINING_RECORD(NextEntry,\r
- LDR_DATA_TABLE_ENTRY,\r
- InLoadOrderLinks);\r
- if (RtlEqualUnicodeString(&NameString,\r
- &LdrEntry->BaseDllName,\r
- TRUE))\r
- {\r
- /* Get the base address */\r
- ImportBase = LdrEntry->DllBase;\r
- \r
- /* Check if we haven't loaded yet, and we need references */\r
- if (!(Loaded) && (ReferenceNeeded))\r
- {\r
- /* Make sure we're not already loading */\r
- if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))\r
- {\r
- /* Increase the load count */\r
- LdrEntry->LoadCount++;\r
- }\r
- }\r
- \r
- /* Done, break out */\r
- break;\r
- }\r
- \r
- /* Go to the next entry */\r
- NextEntry = NextEntry->Flink;\r
- }\r
- \r
- /* Check if we haven't loaded the import yet */\r
- if (!ImportBase)\r
- {\r
- /* Setup the import DLL name */\r
- DllName.MaximumLength = NameString.Length +\r
- ImageFileDirectory->Length +\r
- sizeof(UNICODE_NULL);\r
- DllName.Buffer = ExAllocatePoolWithTag(NonPagedPool,\r
- DllName.MaximumLength,\r
- TAG_LDR_WSTR);\r
- if (DllName.Buffer)\r
- {\r
- /* Setup the base length and copy it */\r
- DllName.Length = ImageFileDirectory->Length;\r
- RtlCopyMemory(DllName.Buffer,\r
- ImageFileDirectory->Buffer,\r
- ImageFileDirectory->Length);\r
- \r
- /* Now add the import name and null-terminate it */\r
- RtlAppendStringToString((PSTRING)&DllName,\r
- (PSTRING)&NameString);\r
- DllName.Buffer[(DllName.MaximumLength - 1) / 2] = UNICODE_NULL;\r
- \r
- /* Load the image */\r
- Status = MmLoadSystemImage(&DllName,\r
- NamePrefix,\r
- NULL,\r
- 0,\r
- (PVOID)&DllEntry,\r
- &DllBase);\r
- if (NT_SUCCESS(Status))\r
- {\r
- /* We can free the DLL Name */\r
- ExFreePool(DllName.Buffer);\r
- }\r
- else\r
- {\r
- /* Fill out the information for the error */\r
- *MissingDriver = DllName.Buffer;\r
- *(PULONG)MissingDriver |= 1;\r
- *MissingApi = NULL;\r
- }\r
- }\r
- else\r
- {\r
- /* We're out of resources */\r
- Status = STATUS_INSUFFICIENT_RESOURCES;\r
- }\r
- \r
- /* Check if we're OK until now */\r
- if (NT_SUCCESS(Status))\r
- {\r
- /* We're now loaded */\r
- Loaded = TRUE;\r
- \r
- /* Sanity check */\r
- ASSERT(DllBase = DllEntry->DllBase);\r
- \r
- /* Call the initialization routines */\r
- Status = MmCallDllInitialize(DllEntry, &PsLoadedModuleList);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- /* We failed, unload the image */\r
- MmUnloadSystemImage(DllEntry);\r
- while (TRUE);\r
- Loaded = FALSE;\r
- }\r
- }\r
- \r
- /* Check if we failed by here */\r
- if (!NT_SUCCESS(Status))\r
- {\r
- /* Cleanup and return */\r
- RtlFreeUnicodeString(&NameString);\r
- MiDereferenceImports(LoadedImports);\r
- if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);\r
- return Status;\r
- }\r
- \r
- /* Loop again to make sure that everything is OK */\r
- goto CheckDllState;\r
- }\r
- \r
- /* Check if we're support to reference this import */\r
- if ((ReferenceNeeded) && (LoadedImports))\r
- {\r
- /* Make sure we're not already loading */\r
- if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))\r
- {\r
- /* Add the entry */\r
- LoadedImports->Entry[LoadedImports->Count] = LdrEntry;\r
- LoadedImports->Count++;\r
- }\r
- }\r
- \r
- /* Free the import name */\r
- RtlFreeUnicodeString(&NameString);\r
- \r
- /* Set the missing driver name and get the export directory */\r
- *MissingDriver = LdrEntry->BaseDllName.Buffer;\r
- ExportDirectory = RtlImageDirectoryEntryToData(ImportBase,\r
- TRUE,\r
- IMAGE_DIRECTORY_ENTRY_EXPORT,\r
- &ExportSize);\r
- if (!ExportDirectory)\r
- {\r
- /* Cleanup and return */\r
- MiDereferenceImports(LoadedImports);\r
- if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);\r
- return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;\r
- }\r
- \r
- /* Make sure we have an IAT */\r
- if (ImportDescriptor->OriginalFirstThunk)\r
- {\r
- /* Get the first thunks */\r
- OrigThunk = (PVOID)((ULONG_PTR)ImageBase +\r
- ImportDescriptor->OriginalFirstThunk);\r
- FirstThunk = (PVOID)((ULONG_PTR)ImageBase +\r
- ImportDescriptor->FirstThunk);\r
- \r
- /* Loop the IAT */\r
- while (OrigThunk->u1.AddressOfData)\r
- {\r
- /* Snap thunk */\r
- Status = MiSnapThunk(ImportBase,\r
- ImageBase,\r
- OrigThunk++,\r
- FirstThunk++,\r
- ExportDirectory,\r
- ExportSize,\r
- FALSE,\r
- MissingApi);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- /* Cleanup and return */\r
- MiDereferenceImports(LoadedImports);\r
- if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);\r
- return Status;\r
- }\r
- \r
- /* Reset the buffer */\r
- *MissingApi = MissingApiBuffer;\r
- }\r
- }\r
- \r
- /* Go to the next import */\r
- ImportDescriptor++;\r
- }\r
- \r
- /* Check if we have an import list */\r
- if (LoadedImports)\r
- {\r
- /* Reset the count again, and loop entries*/\r
- ImportCount = 0;\r
- for (i = 0; i < LoadedImports->Count; i++)\r
- {\r
- if (LoadedImports->Entry[i])\r
- {\r
- /* Got an entry, OR it with 1 in case it's the single entry */\r
- ImportEntry = (PVOID)((ULONG_PTR)LoadedImports->Entry[i] | 1);\r
- ImportCount++;\r
- }\r
- }\r
- \r
- /* Check if we had no imports */\r
- if (!ImportCount)\r
- {\r
- /* Free the list and set it to no imports */\r
- ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);\r
- LoadedImports = (PVOID)-2;\r
- }\r
- else if (ImportCount == 1)\r
- {\r
- /* Just one entry, we can free the table and only use our entry */\r
- ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);\r
- LoadedImports = (PLOAD_IMPORTS)ImportEntry;\r
- }\r
- else if (ImportCount != LoadedImports->Count)\r
- {\r
- /* Allocate a new list */\r
- LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);\r
- NewImports = ExAllocatePoolWithTag(PagedPool,\r
- LoadedImportsSize,\r
- TAG_LDR_WSTR);\r
- if (NewImports)\r
- {\r
- /* Set count */\r
- NewImports->Count = 0;\r
- \r
- /* Loop all the imports */\r
- for (i = 0; i < LoadedImports->Count; i++)\r
- {\r
- /* Make sure it's valid */\r
- if (LoadedImports->Entry[i])\r
- {\r
- /* Copy it */\r
- NewImports->Entry[NewImports->Count] = LoadedImports->Entry[i];\r
- NewImports->Count++;\r
- }\r
- }\r
- \r
- /* Free the old copy */\r
- ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);\r
- LoadedImports = NewImports;\r
- }\r
- }\r
- \r
- /* Return the list */\r
- *LoadImports = LoadedImports;\r
- }\r
- \r
- /* Return success */\r
- return STATUS_SUCCESS;\r
- }\r
- \r
- VOID\r
- NTAPI\r
- MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock)\r
- {\r
- PLIST_ENTRY NextEntry;\r
- ULONG i = 0;\r
- PIMAGE_NT_HEADERS NtHeader;\r
- PLDR_DATA_TABLE_ENTRY LdrEntry;\r
- PIMAGE_FILE_HEADER FileHeader;\r
- BOOLEAN ValidRelocs;\r
- PIMAGE_DATA_DIRECTORY DataDirectory;\r
- PVOID DllBase, NewImageAddress;\r
- NTSTATUS Status;\r
- \r
- /* Loop driver list */\r
- for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;\r
- NextEntry != &LoaderBlock->LoadOrderListHead;\r
- NextEntry = NextEntry->Flink)\r
- {\r
- /* Get the loader entry and NT header */\r
- LdrEntry = CONTAINING_RECORD(NextEntry,\r
- LDR_DATA_TABLE_ENTRY,\r
- InLoadOrderLinks);\r
- NtHeader = RtlImageNtHeader(LdrEntry->DllBase);\r
- \r
- /* Debug info */\r
- DPRINT("[Mm0]: Driver at: %p ending at: %p for module: %wZ\n",\r
- LdrEntry->DllBase,\r
- (ULONG_PTR)LdrEntry->DllBase+ LdrEntry->SizeOfImage,\r
- &LdrEntry->FullDllName);\r
- \r
- /* Skip kernel and HAL */\r
- /* ROS HACK: Skip BOOTVID/KDCOM too */\r
- i++;\r
- if (i <= 4) continue;\r
- \r
- /* Skip non-drivers */\r
- if (!NtHeader) continue;\r
- \r
- /* Get the file header and make sure we can relocate */\r
- FileHeader = &NtHeader->FileHeader;\r
- if (FileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) continue;\r
- if (NtHeader->OptionalHeader.NumberOfRvaAndSizes <\r
- IMAGE_DIRECTORY_ENTRY_BASERELOC) continue;\r
- \r
- /* Everything made sense until now, check the relocation section too */\r
- DataDirectory = &NtHeader->OptionalHeader.\r
- DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
- if (!DataDirectory->VirtualAddress)\r
- {\r
- /* We don't really have relocations */\r
- ValidRelocs = FALSE;\r
- }\r
- else\r
- {\r
- /* Make sure the size is valid */\r
- if ((DataDirectory->VirtualAddress + DataDirectory->Size) >\r
- LdrEntry->SizeOfImage)\r
- {\r
- /* They're not, skip */\r
- continue;\r
- }\r
- \r
- /* We have relocations */\r
- ValidRelocs = TRUE;\r
- }\r
- \r
- /* Remember the original address */\r
- DllBase = LdrEntry->DllBase;\r
- \r
- /* Allocate a virtual section for the module */\r
- NewImageAddress = MmAllocateSection(LdrEntry->SizeOfImage, NULL);\r
- if (!NewImageAddress)\r
- {\r
- /* Shouldn't happen */\r
- DPRINT1("[Mm0]: Couldn't allocate driver section!\n");\r
- while (TRUE);\r
- }\r
- \r
- /* Sanity check */\r
- DPRINT("[Mm0]: Copying from: %p to: %p\n", DllBase, NewImageAddress);\r
- ASSERT(ExpInitializationPhase == 0);\r
- \r
- /* Now copy the entire driver over */\r
- RtlCopyMemory(NewImageAddress, DllBase, LdrEntry->SizeOfImage);\r
- \r
- /* Sanity check */\r
- ASSERT(*(PULONG)NewImageAddress == *(PULONG)DllBase);\r
- \r
- /* Set the image base to the address where the loader put it */\r
- NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;\r
- NtHeader = RtlImageNtHeader(NewImageAddress);\r
- NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;\r
- \r
- /* Check if we had relocations */\r
- if (ValidRelocs)\r
- {\r
- /* Relocate the image */\r
- Status = LdrRelocateImageWithBias(NewImageAddress,\r
- 0,\r
- "SYSLDR",\r
- STATUS_SUCCESS,\r
- STATUS_CONFLICTING_ADDRESSES,\r
- STATUS_INVALID_IMAGE_FORMAT);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- /* This shouldn't happen */\r
- DPRINT1("Relocations failed!\n");\r
- while (TRUE);\r
- }\r
- }\r
- \r
- /* Update the loader entry */\r
- LdrEntry->DllBase = NewImageAddress;\r
- \r
- /* Update the thunks */\r
- DPRINT("[Mm0]: Updating thunks to: %wZ\n", &LdrEntry->BaseDllName);\r
- MiUpdateThunks(LoaderBlock,\r
- DllBase,\r
- NewImageAddress,\r
- LdrEntry->SizeOfImage);\r
- \r
- /* Update the loader entry */\r
- LdrEntry->Flags |= 0x01000000;\r
- LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress +\r
- NtHeader->OptionalHeader.AddressOfEntryPoint);\r
- LdrEntry->SizeOfImage = LdrEntry->SizeOfImage;\r
- \r
- /* Free the old copy */\r
- MiFreeBootDriverMemory(DllBase, LdrEntry->SizeOfImage);\r
- }\r
- }\r
- \r
- BOOLEAN\r
- NTAPI\r
- MiInitializeLoadedModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock)\r
- {\r
- PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;\r
- PLIST_ENTRY ListHead, NextEntry;\r
- ULONG EntrySize;\r
- \r
- /* Setup the loaded module list and lock */\r
- KeInitializeSpinLock(&PsLoadedModuleSpinLock);\r
- InitializeListHead(&PsLoadedModuleList);\r
- \r
- /* Get loop variables and the kernel entry */\r
- ListHead = &LoaderBlock->LoadOrderListHead;\r
- NextEntry = ListHead->Flink;\r
- LdrEntry = CONTAINING_RECORD(NextEntry,\r
- LDR_DATA_TABLE_ENTRY,\r
- InLoadOrderLinks);\r
- PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;\r
- \r
- /* Loop the loader block */\r
- while (NextEntry != ListHead)\r
- {\r
- /* Get the loader entry */\r
- LdrEntry = CONTAINING_RECORD(NextEntry,\r
- LDR_DATA_TABLE_ENTRY,\r
- InLoadOrderLinks);\r
- \r
- /* FIXME: ROS HACK. Make sure this is a driver */\r
- if (!RtlImageNtHeader(LdrEntry->DllBase))\r
- {\r
- /* Skip this entry */\r
- NextEntry= NextEntry->Flink;\r
- continue;\r
- }\r
- \r
- /* Calculate the size we'll need and allocate a copy */\r
- EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +\r
- LdrEntry->BaseDllName.MaximumLength +\r
- sizeof(UNICODE_NULL);\r
- NewEntry = ExAllocatePoolWithTag(NonPagedPool, EntrySize, TAG_LDR_WSTR);\r
- if (!NewEntry) return FALSE;\r
- \r
- /* Copy the entry over */\r
- *NewEntry = *LdrEntry;\r
- \r
- /* Allocate the name */\r
- NewEntry->FullDllName.Buffer =\r
- ExAllocatePoolWithTag(PagedPool,\r
- LdrEntry->FullDllName.MaximumLength +\r
- sizeof(UNICODE_NULL),\r
- TAG_LDR_WSTR);\r
- if (!NewEntry->FullDllName.Buffer) return FALSE;\r
- \r
- /* Set the base name */\r
- NewEntry->BaseDllName.Buffer = (PVOID)(NewEntry + 1);\r
- \r
- /* Copy the full and base name */\r
- RtlCopyMemory(NewEntry->FullDllName.Buffer,\r
- LdrEntry->FullDllName.Buffer,\r
- LdrEntry->FullDllName.MaximumLength);\r
- RtlCopyMemory(NewEntry->BaseDllName.Buffer,\r
- LdrEntry->BaseDllName.Buffer,\r
- LdrEntry->BaseDllName.MaximumLength);\r
- \r
- /* Null-terminate the base name */\r
- NewEntry->BaseDllName.Buffer[NewEntry->BaseDllName.Length /\r
- sizeof(WCHAR)] = UNICODE_NULL;\r
- \r
- /* Insert the entry into the list */\r
- InsertTailList(&PsLoadedModuleList, &NewEntry->InLoadOrderLinks);\r
- NextEntry = NextEntry->Flink;\r
- }\r
- \r
- /* Build the import lists for the boot drivers */\r
- //MiBuildImportsForBootDrivers();\r
- \r
- /* We're done */\r
- return TRUE;\r
- }\r
- \r
- BOOLEAN\r
- NTAPI\r
- MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress)\r
- {\r
- PIMAGE_NT_HEADERS NtHeader;\r
- PAGED_CODE();\r
- \r
- /* Get NT Headers */\r
- NtHeader = RtlImageNtHeader(BaseAddress);\r
- if (NtHeader)\r
- {\r
- /* Check if this image is only safe for UP while we have 2+ CPUs */\r
- if ((KeNumberProcessors > 1) &&\r
- (NtHeader->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY))\r
- {\r
- /* Fail */\r
- return FALSE;\r
- }\r
- }\r
- \r
- /* Otherwise, it's safe */\r
- return TRUE;\r
- }\r
- \r
- NTSTATUS\r
- NTAPI\r
- MmCheckSystemImage(IN HANDLE ImageHandle,\r
- IN BOOLEAN PurgeSection)\r
- {\r
- NTSTATUS Status;\r
- HANDLE SectionHandle;\r
- PVOID ViewBase = NULL;\r
- SIZE_T ViewSize = 0;\r
- IO_STATUS_BLOCK IoStatusBlock;\r
- FILE_STANDARD_INFORMATION FileStandardInfo;\r
- KAPC_STATE ApcState;\r
- PAGED_CODE();\r
- \r
- /* Create a section for the DLL */\r
- Status = ZwCreateSection(&SectionHandle,\r
- SECTION_MAP_EXECUTE,\r
- NULL,\r
- NULL,\r
- PAGE_EXECUTE,\r
- SEC_COMMIT,\r
- ImageHandle);\r
- if (!NT_SUCCESS(Status)) return Status;\r
- \r
- /* Make sure we're in the system process */\r
- KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState);\r
- \r
- /* Map it */\r
- Status = ZwMapViewOfSection(SectionHandle,\r
- NtCurrentProcess(),\r
- &ViewBase,\r
- 0,\r
- 0,\r
- NULL,\r
- &ViewSize,\r
- ViewShare,\r
- 0,\r
- PAGE_EXECUTE);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- /* We failed, close the handle and return */\r
- KeUnstackDetachProcess(&ApcState);\r
- ZwClose(SectionHandle);\r
- return Status;\r
- }\r
- \r
- /* Now query image information */\r
- Status = ZwQueryInformationFile(ImageHandle,\r
- &IoStatusBlock,\r
- &FileStandardInfo,\r
- sizeof(FileStandardInfo),\r
- FileStandardInformation);\r
- if ( NT_SUCCESS(Status) )\r
- {\r
- /* First, verify the checksum */\r
- if (!LdrVerifyMappedImageMatchesChecksum(ViewBase,\r
- FileStandardInfo.\r
- EndOfFile.LowPart,\r
- FileStandardInfo.\r
- EndOfFile.LowPart))\r
- {\r
- /* Set checksum failure */\r
- Status = STATUS_IMAGE_CHECKSUM_MISMATCH;\r
- }\r
- \r
- /* Check that it's a valid SMP image if we have more then one CPU */\r
- if (!MmVerifyImageIsOkForMpUse(ViewBase))\r
- {\r
- /* Otherwise it's not the right image */\r
- Status = STATUS_IMAGE_MP_UP_MISMATCH;\r
- }\r
- }\r
- \r
- /* Unmap the section, close the handle, and return status */\r
- ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);\r
- KeUnstackDetachProcess(&ApcState);\r
- ZwClose(SectionHandle);\r
- return Status;\r
- }\r
- \r
- NTSTATUS\r
- NTAPI\r
- MmLoadSystemImage(IN PUNICODE_STRING FileName,\r
- IN PUNICODE_STRING NamePrefix OPTIONAL,\r
- IN PUNICODE_STRING LoadedName OPTIONAL,\r
- IN ULONG Flags,\r
- OUT PVOID *ModuleObject,\r
- OUT PVOID *ImageBaseAddress)\r
- {\r
- PVOID ModuleLoadBase = NULL;\r
- NTSTATUS Status;\r
- HANDLE FileHandle = NULL;\r
- OBJECT_ATTRIBUTES ObjectAttributes;\r
- IO_STATUS_BLOCK IoStatusBlock;\r
- PIMAGE_NT_HEADERS NtHeader;\r
- UNICODE_STRING BaseName, BaseDirectory, PrefixName, UnicodeTemp;\r
- PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;\r
- ULONG EntrySize, DriverSize;\r
- PLOAD_IMPORTS LoadedImports = (PVOID)-2;\r
- PCHAR MissingApiName, Buffer;\r
- PWCHAR MissingDriverName;\r
- HANDLE SectionHandle;\r
- ACCESS_MASK DesiredAccess;\r
- PVOID Section = NULL;\r
- BOOLEAN LockOwned = FALSE;\r
- PLIST_ENTRY NextEntry;\r
- IMAGE_INFO ImageInfo;\r
- ANSI_STRING AnsiTemp;\r
- PAGED_CODE();\r
- \r
- /* Detect session-load */\r
- if (Flags)\r
- {\r
- /* Sanity checks */\r
- ASSERT(NamePrefix == NULL);\r
- ASSERT(LoadedName == NULL);\r
- \r
- /* Make sure the process is in session too */\r
- if (!PsGetCurrentProcess()->ProcessInSession) return STATUS_NO_MEMORY;\r
- }\r
- \r
- if (ModuleObject) *ModuleObject = NULL;\r
- if (ImageBaseAddress) *ImageBaseAddress = NULL;\r
- \r
- /* Allocate a buffer we'll use for names */\r
- Buffer = ExAllocatePoolWithTag(NonPagedPool, MAX_PATH, TAG_LDR_WSTR);\r
- if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES;\r
- \r
- /* Check for a separator */\r
- if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)\r
- {\r
- PWCHAR p;\r
- ULONG BaseLength;\r
- \r
- /* Loop the path until we get to the base name */\r
- p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];\r
- while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;\r
- \r
- /* Get the length */\r
- BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);\r
- BaseLength *= sizeof(WCHAR);\r
- \r
- /* Setup the string */\r
- BaseName.Length = (USHORT)BaseLength;\r
- BaseName.Buffer = p;\r
- }\r
- else\r
- {\r
- /* Otherwise, we already have a base name */\r
- BaseName.Length = FileName->Length;\r
- BaseName.Buffer = FileName->Buffer;\r
- }\r
- \r
- /* Setup the maximum length */\r
- BaseName.MaximumLength = BaseName.Length;\r
- \r
- /* Now compute the base directory */\r
- BaseDirectory = *FileName;\r
- BaseDirectory.Length -= BaseName.Length;\r
- BaseDirectory.MaximumLength = BaseDirectory.Length;\r
- \r
- /* And the prefix, which for now is just the name itself */\r
- PrefixName = *FileName;\r
- \r
- /* Check if we have a prefix */\r
- if (NamePrefix) DPRINT1("Prefixed images are not yet supported!\n");\r
- \r
- /* Check if we already have a name, use it instead */\r
- if (LoadedName) BaseName = *LoadedName;\r
- \r
- /* Acquire the load lock */\r
- LoaderScan:\r
- ASSERT(LockOwned == FALSE);\r
- LockOwned = TRUE;\r
- KeEnterCriticalRegion();\r
- KeWaitForSingleObject(&MmSystemLoadLock,\r
- WrVirtualMemory,\r
- KernelMode,\r
- FALSE,\r
- NULL);\r
- \r
- /* Scan the module list */\r
- NextEntry = PsLoadedModuleList.Flink;\r
- while (NextEntry != &PsLoadedModuleList)\r
- {\r
- /* Get the entry and compare the names */\r
- LdrEntry = CONTAINING_RECORD(NextEntry,\r
- LDR_DATA_TABLE_ENTRY,\r
- InLoadOrderLinks);\r
- if (RtlEqualUnicodeString(&PrefixName, &LdrEntry->FullDllName, TRUE))\r
- {\r
- /* Found it, break out */\r
- break;\r
- }\r
- \r
- /* Keep scanning */\r
- NextEntry = NextEntry->Flink;\r
- }\r
- \r
- /* Check if we found the image */\r
- if (NextEntry != &PsLoadedModuleList)\r
- {\r
- /* Check if we had already mapped a section */\r
- if (Section)\r
- {\r
- /* Dereference and clear */\r
- ObDereferenceObject(Section);\r
- Section = NULL;\r
- }\r
- \r
- /* Check if this was supposed to be a session load */\r
- if (!Flags)\r
- {\r
- /* It wasn't, so just return the data */\r
- if (ModuleObject) *ModuleObject = LdrEntry;\r
- if (ImageBaseAddress) *ImageBaseAddress = LdrEntry->DllBase;\r
- Status = STATUS_IMAGE_ALREADY_LOADED;\r
- }\r
- else\r
- {\r
- /* We don't support session loading yet */\r
- DPRINT1("Unsupported Session-Load!\n");\r
- while (TRUE);\r
- }\r
- \r
- /* Do cleanup */\r
- goto Quickie;\r
- }\r
- else if (!Section)\r
- {\r
- /* It wasn't loaded, and we didn't have a previous attempt */\r
- KeReleaseMutant(&MmSystemLoadLock, 1, FALSE, FALSE);\r
- KeLeaveCriticalRegion();\r
- LockOwned = FALSE;\r
- \r
- /* Check if KD is enabled */\r
- if ((KdDebuggerEnabled) && !(KdDebuggerNotPresent))\r
- {\r
- /* FIXME: Attempt to get image from KD */\r
- }\r
- \r
- /* We don't have a valid entry */\r
- LdrEntry = NULL;\r
- \r
- /* Setup image attributes */\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- FileName,\r
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,\r
- NULL,\r
- NULL);\r
- \r
- /* Open the image */\r
- Status = ZwOpenFile(&FileHandle,\r
- FILE_EXECUTE,\r
- &ObjectAttributes,\r
- &IoStatusBlock,\r
- FILE_SHARE_READ | FILE_SHARE_DELETE,\r
- 0);\r
- if (!NT_SUCCESS(Status)) goto Quickie;\r
- \r
- /* Validate it */\r
- Status = MmCheckSystemImage(FileHandle, FALSE);\r
- if ((Status == STATUS_IMAGE_CHECKSUM_MISMATCH) ||\r
- (Status == STATUS_IMAGE_MP_UP_MISMATCH) ||\r
- (Status == STATUS_INVALID_IMAGE_FORMAT))\r
- {\r
- /* Fail loading */\r
- goto Quickie;\r
- }\r
- \r
- /* Check if this is a session-load */\r
- if (Flags)\r
- {\r
- /* Then we only need read and execute */\r
- DesiredAccess = SECTION_MAP_READ | SECTION_MAP_EXECUTE;\r
- }\r
- else\r
- {\r
- /* Otherwise, we can allow write access */\r
- DesiredAccess = SECTION_ALL_ACCESS;\r
- }\r
- \r
- /* Initialize the attributes for the section */\r
- InitializeObjectAttributes(&ObjectAttributes,\r
- NULL,\r
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,\r
- NULL,\r
- NULL);\r
- \r
- /* Create the section */\r
- Status = ZwCreateSection(&SectionHandle,\r
- DesiredAccess,\r
- &ObjectAttributes,\r
- NULL,\r
- PAGE_EXECUTE,\r
- SEC_IMAGE,\r
- FileHandle);\r
- if (!NT_SUCCESS(Status)) goto Quickie;\r
- \r
- /* Now get the section pointer */\r
- Status = ObReferenceObjectByHandle(SectionHandle,\r
- SECTION_MAP_EXECUTE,\r
- MmSectionObjectType,\r
- KernelMode,\r
- &Section,\r
- NULL);\r
- ZwClose(SectionHandle);\r
- if (!NT_SUCCESS(Status)) goto Quickie;\r
- \r
- /* Check if this was supposed to be a session-load */\r
- if (Flags)\r
- {\r
- /* We don't support session loading yet */\r
- DPRINT1("Unsupported Session-Load!\n");\r
- while (TRUE);\r
- }\r
- \r
- /* Check the loader list again, we should end up in the path below */\r
- goto LoaderScan;\r
- }\r
- else\r
- {\r
- /* We don't have a valid entry */\r
- LdrEntry = NULL;\r
- }\r
- \r
- /* Load the image */\r
- Status = MiLoadImageSection(&Section,\r
- &ModuleLoadBase,\r
- FileName,\r
- FALSE,\r
- NULL);\r
- ASSERT(Status != STATUS_ALREADY_COMMITTED);\r
- \r
- /* Get the size of the driver */\r
- DriverSize = ((PROS_SECTION_OBJECT)Section)->ImageSection->ImageSize;\r
- \r
- /* Make sure we're not being loaded into session space */\r
- if (!Flags)\r
- {\r
- /* Check for success */\r
- if (NT_SUCCESS(Status))\r
- {\r
- /* FIXME: Support large pages for drivers */\r
- }\r
- \r
- /* Dereference the section */\r
- ObDereferenceObject(Section);\r
- Section = NULL;\r
- }\r
- \r
- /* Get the NT Header */\r
- NtHeader = RtlImageNtHeader(ModuleLoadBase);\r
- \r
- /* Relocate the driver */\r
- Status = LdrRelocateImageWithBias(ModuleLoadBase,\r
- 0,\r
- "SYSLDR",\r
- STATUS_SUCCESS,\r
- STATUS_CONFLICTING_ADDRESSES,\r
- STATUS_INVALID_IMAGE_FORMAT);\r
- if (!NT_SUCCESS(Status)) goto Quickie;\r
- \r
- /* Calculate the size we'll need for the entry and allocate it */\r
- EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +\r
- BaseName.Length +\r
- sizeof(UNICODE_NULL);\r
- \r
- /* Allocate the entry */\r
- LdrEntry = ExAllocatePoolWithTag(NonPagedPool, EntrySize, TAG_MODULE_OBJECT);\r
- if (!LdrEntry)\r
- {\r
- /* Fail */\r
- Status = STATUS_INSUFFICIENT_RESOURCES;\r
- goto Quickie;\r
- }\r
- \r
- /* Setup the entry */\r
- LdrEntry->Flags = LDRP_LOAD_IN_PROGRESS;\r
- LdrEntry->LoadCount = 1;\r
- LdrEntry->LoadedImports = LoadedImports;\r
- LdrEntry->PatchInformation = NULL;\r
- \r
- /* Check the version */\r
- if ((NtHeader->OptionalHeader.MajorOperatingSystemVersion >= 5) &&\r
- (NtHeader->OptionalHeader.MajorImageVersion >= 5))\r
- {\r
- /* Mark this image as a native image */\r
- LdrEntry->Flags |= 0x80000000;\r
- }\r
- \r
- /* Setup the rest of the entry */\r
- LdrEntry->DllBase = ModuleLoadBase;\r
- LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase +\r
- NtHeader->OptionalHeader.AddressOfEntryPoint);\r
- LdrEntry->SizeOfImage = DriverSize;\r
- LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum;\r
- LdrEntry->SectionPointer = Section;\r
- \r
- /* Now write the DLL name */\r
- LdrEntry->BaseDllName.Buffer = (PVOID)(LdrEntry + 1);\r
- LdrEntry->BaseDllName.Length = BaseName.Length;\r
- LdrEntry->BaseDllName.MaximumLength = BaseName.Length;\r
- \r
- /* Copy and null-terminate it */\r
- RtlCopyMemory(LdrEntry->BaseDllName.Buffer,\r
- BaseName.Buffer,\r
- BaseName.Length);\r
- LdrEntry->BaseDllName.Buffer[BaseName.Length / 2] = UNICODE_NULL;\r
- \r
- /* Now allocate the full name */\r
- LdrEntry->FullDllName.Buffer = ExAllocatePoolWithTag(PagedPool,\r
- PrefixName.Length +\r
- sizeof(UNICODE_NULL),\r
- TAG_LDR_WSTR);\r
- if (!LdrEntry->FullDllName.Buffer)\r
- {\r
- /* Don't fail, just set it to zero */\r
- LdrEntry->FullDllName.Length = 0;\r
- LdrEntry->FullDllName.MaximumLength = 0;\r
- }\r
- else\r
- {\r
- /* Set it up */\r
- LdrEntry->FullDllName.Length = PrefixName.Length;\r
- LdrEntry->FullDllName.MaximumLength = PrefixName.Length;\r
- \r
- /* Copy and null-terminate */\r
- RtlCopyMemory(LdrEntry->FullDllName.Buffer,\r
- PrefixName.Buffer,\r
- PrefixName.Length);\r
- LdrEntry->FullDllName.Buffer[PrefixName.Length / 2] = UNICODE_NULL;\r
- }\r
- \r
- /* Add the entry */\r
- MiProcessLoaderEntry(LdrEntry, TRUE);\r
- \r
- /* Resolve imports */\r
- MissingApiName = Buffer;\r
- Status = MiResolveImageReferences(ModuleLoadBase,\r
- &BaseDirectory,\r
- NULL,\r
- &MissingApiName,\r
- &MissingDriverName,\r
- &LoadedImports);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- /* Fail */\r
- MiProcessLoaderEntry(LdrEntry, FALSE);\r
- \r
- /* Check if we need to free the name */\r
- if (LdrEntry->FullDllName.Buffer)\r
- {\r
- /* Free it */\r
- ExFreePool(LdrEntry->FullDllName.Buffer);\r
- }\r
- \r
- /* Free the entry itself */\r
- ExFreePoolWithTag(LdrEntry, TAG_MODULE_OBJECT);\r
- LdrEntry = NULL;\r
- goto Quickie;\r
- }\r
- \r
- /* Update the loader entry */\r
- LdrEntry->Flags |= (LDRP_SYSTEM_MAPPED |\r
- LDRP_ENTRY_PROCESSED |\r
- LDRP_MM_LOADED);\r
- LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;\r
- LdrEntry->LoadedImports = LoadedImports;\r
- \r
- /* FIXME: Apply driver verifier */\r
- \r
- /* FIXME: Write-protect the system image */\r
- \r
- /* Check if notifications are enabled */\r
- if (PsImageNotifyEnabled)\r
- {\r
- /* Fill out the notification data */\r
- ImageInfo.Properties = 0;\r
- ImageInfo.ImageAddressingMode = IMAGE_ADDRESSING_MODE_32BIT;\r
- ImageInfo.SystemModeImage = TRUE;\r
- ImageInfo.ImageSize = LdrEntry->SizeOfImage;\r
- ImageInfo.ImageBase = LdrEntry->DllBase;\r
- ImageInfo.ImageSectionNumber = ImageInfo.ImageSelector = 0;\r
- \r
- /* Send the notification */\r
- PspRunLoadImageNotifyRoutines(FileName, NULL, &ImageInfo);\r
- }\r
- \r
- /* Check if there's symbols */\r
- #ifdef KDBG\r
- /* If KDBG is defined, then we always have symbols */\r
- if (TRUE)\r
- #else\r
- if (MiCacheImageSymbols(LdrEntry->DllBase))\r
- #endif\r
- {\r
- /* Check if the system root is present */\r
- if ((PrefixName.Length > (11 * sizeof(WCHAR))) &&\r
- !(_wcsnicmp(PrefixName.Buffer, L"\\SystemRoot", 11)))\r
- {\r
- /* Add the system root */\r
- UnicodeTemp = PrefixName;\r
- UnicodeTemp.Buffer += 11;\r
- UnicodeTemp.Length -= (11 * sizeof(WCHAR));\r
- sprintf_nt(Buffer,\r
- "%ws%wZ",\r
- &SharedUserData->NtSystemRoot[2],\r
- &UnicodeTemp);\r
- }\r
- else\r
- {\r
- /* Build the name */\r
- sprintf_nt(Buffer, "%wZ", &BaseName);\r
- }\r
- \r
- /* Setup the ansi string */\r
- RtlInitString(&AnsiTemp, Buffer);\r
- \r
- /* Notify the debugger */\r
- DbgLoadImageSymbols(&AnsiTemp, LdrEntry->DllBase, -1);\r
- LdrEntry->Flags |= LDRP_DEBUG_SYMBOLS_LOADED;\r
- }\r
- \r
- /* FIXME: Page the driver */\r
- ASSERT(Section == NULL);\r
- \r
- /* Return pointers */\r
- if (ModuleObject) *ModuleObject = LdrEntry;\r
- if (ImageBaseAddress) *ImageBaseAddress = LdrEntry->DllBase;\r
- \r
- Quickie:\r
- /* If we have a file handle, close it */\r
- if (FileHandle) ZwClose(FileHandle);\r
- \r
- /* Check if we have the lock acquired */\r
- if (LockOwned)\r
- {\r
- /* Release the lock */\r
- KeReleaseMutant(&MmSystemLoadLock, 1, FALSE, FALSE);\r
- KeLeaveCriticalRegion();\r
- LockOwned = FALSE;\r
- }\r
- \r
- /* Check if we had a prefix */\r
- if (NamePrefix) ExFreePool(PrefixName.Buffer);\r
- \r
- /* Free the name buffer and return status */\r
- ExFreePoolWithTag(Buffer, TAG_LDR_WSTR);\r
- return Status;\r
- }\r
- \r
- /*\r
- * @implemented\r
- */\r
- PVOID\r
- NTAPI\r
- MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName)\r
- {\r
- PVOID ProcAddress = NULL;\r
- ANSI_STRING AnsiRoutineName;\r
- NTSTATUS Status;\r
- PLIST_ENTRY NextEntry;\r
- extern LIST_ENTRY PsLoadedModuleList;\r
- PLDR_DATA_TABLE_ENTRY LdrEntry;\r
- BOOLEAN Found = FALSE;\r
- UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");\r
- UNICODE_STRING HalName = RTL_CONSTANT_STRING(L"hal.dll");\r
- ULONG Modules = 0;\r
- \r
- /* Convert routine to ansi name */\r
- Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName,\r
- SystemRoutineName,\r
- TRUE);\r
- if (!NT_SUCCESS(Status)) return NULL;\r
- \r
- /* Lock the list */\r
- KeEnterCriticalRegion();\r
- \r
- /* Loop the loaded module list */\r
- NextEntry = PsLoadedModuleList.Flink;\r
- while (NextEntry != &PsLoadedModuleList)\r
- {\r
- /* Get the entry */\r
- LdrEntry = CONTAINING_RECORD(NextEntry,\r
- LDR_DATA_TABLE_ENTRY,\r
- InLoadOrderLinks);\r
- \r
- /* Check if it's the kernel or HAL */\r
- if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))\r
- {\r
- /* Found it */\r
- Found = TRUE;\r
- Modules++;\r
- }\r
- else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))\r
- {\r
- /* Found it */\r
- Found = TRUE;\r
- Modules++;\r
- }\r
- \r
- /* Check if we found a valid binary */\r
- if (Found)\r
- {\r
- /* Find the procedure name */\r
- ProcAddress = MiFindExportedRoutineByName(LdrEntry->DllBase,\r
- &AnsiRoutineName);\r
- \r
- /* Break out if we found it or if we already tried both modules */\r
- if (ProcAddress) break;\r
- if (Modules == 2) break;\r
- }\r
- \r
- /* Keep looping */\r
- NextEntry = NextEntry->Flink;\r
- }\r
- \r
- /* Release the lock */\r
- KeLeaveCriticalRegion();\r
- \r
- /* Free the string and return */\r
- RtlFreeAnsiString(&AnsiRoutineName);\r
- return ProcAddress;\r
- }\r
- \r
+ /*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/mm/sysldr.c
+ * PURPOSE: Contains the Kernel Loader (SYSLDR) for loading PE files.
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+ /* INCLUDES ******************************************************************/
+
+ #include <ntoskrnl.h>
+ #define NDEBUG
+ #include <debug.h>
+
+ /* GCC's incompetence strikes again */
+ __inline
+ VOID
+ sprintf_nt(IN PCHAR Buffer,
+ IN PCHAR Format,
+ IN ...)
+ {
+ va_list ap;
+ va_start(ap, Format);
+ vsprintf(Buffer, Format, ap);
+ va_end(ap);
+ }
+
+ /* GLOBALS *******************************************************************/
+
+ LIST_ENTRY PsLoadedModuleList;
+ KSPIN_LOCK PsLoadedModuleSpinLock;
+ ULONG_PTR PsNtosImageBase;
+ KMUTANT MmSystemLoadLock;
+ extern ULONG NtGlobalFlag;
+
+ /* FUNCTIONS *****************************************************************/
+
+ PVOID
+ NTAPI
+ MiCacheImageSymbols(IN PVOID BaseAddress)
+ {
+ ULONG DebugSize;
+ PVOID DebugDirectory = NULL;
+ PAGED_CODE();
+
+ /* Make sure it's safe to access the image */
+ _SEH2_TRY
+ {
+ /* Get the debug directory */
+ DebugDirectory = RtlImageDirectoryEntryToData(BaseAddress,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_DEBUG,
+ &DebugSize);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Nothing */
+ }
+ _SEH2_END;
+
+ /* Return the directory */
+ return DebugDirectory;
+ }
+
+ VOID
+ NTAPI
+ MiFreeBootDriverMemory(PVOID BaseAddress,
+ ULONG Length)
+ {
+ ULONG i;
+
+ /* Loop each page */
+ for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++)
+ {
+ /* Free the page */
+ MmDeleteVirtualMapping(NULL,
+ (PVOID)((ULONG_PTR)BaseAddress + i * PAGE_SIZE),
+ TRUE,
+ NULL,
+ NULL);
+ }
+ }
+
+ NTSTATUS
+ NTAPI
+ MiLoadImageSection(IN OUT PVOID *SectionPtr,
+ OUT PVOID *ImageBase,
+ IN PUNICODE_STRING FileName,
+ IN BOOLEAN SessionLoad,
+ IN PLDR_DATA_TABLE_ENTRY LdrEntry)
+ {
+ PROS_SECTION_OBJECT Section = *SectionPtr;
+ NTSTATUS Status;
+ PEPROCESS Process;
+ PVOID Base = NULL;
+ SIZE_T ViewSize = 0;
+ KAPC_STATE ApcState;
+ LARGE_INTEGER SectionOffset = {{0, 0}};
+ BOOLEAN LoadSymbols = FALSE;
+ ULONG DriverSize;
+ PVOID DriverBase;
+ PAGED_CODE();
+
+ /* Detect session load */
+ if (SessionLoad)
+ {
+ /* Fail */
+ DPRINT1("Session loading not yet supported!\n");
+ while (TRUE);
+ }
+
+ /* Not session load, shouldn't have an entry */
+ ASSERT(LdrEntry == NULL);
+
+ /* Attach to the system process */
+ KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState);
+
+ /* Check if we need to load symbols */
+ if (NtGlobalFlag & FLG_ENABLE_KDEBUG_SYMBOL_LOAD)
+ {
+ /* Yes we do */
+ LoadSymbols = TRUE;
+ NtGlobalFlag &= ~FLG_ENABLE_KDEBUG_SYMBOL_LOAD;
+ }
+
+ /* Map the driver */
+ Process = PsGetCurrentProcess();
+ Status = MmMapViewOfSection(Section,
+ Process,
+ &Base,
+ 0,
+ 0,
+ &SectionOffset,
+ &ViewSize,
+ ViewUnmap,
+ 0,
+ PAGE_EXECUTE);
+
+ /* Re-enable the flag */
+ if (LoadSymbols) NtGlobalFlag |= FLG_ENABLE_KDEBUG_SYMBOL_LOAD;
+
+ /* Check if we failed with distinguished status code */
+ if (Status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH)
+ {
+ /* Change it to something more generic */
+ Status = STATUS_INVALID_IMAGE_FORMAT;
+ }
+
+ /* Now check if we failed */
+ if (!NT_SUCCESS(Status))
+ {
+ /* Detach and return */
+ KeUnstackDetachProcess(&ApcState);
+ return Status;
+ }
+
+ /* Get the driver size */
+ DriverSize = Section->ImageSection->ImageSize;
+
+ /* Allocate a virtual section for the module */
+ DriverBase = MmAllocateSection(DriverSize, NULL);
+ *ImageBase = DriverBase;
+
+ /* Copy the image */
+ RtlCopyMemory(DriverBase, Base, DriverSize);
+
+ /* Now unmap the view */
+ Status = MmUnmapViewOfSection(Process, Base);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Detach and return status */
+ KeUnstackDetachProcess(&ApcState);
+ return Status;
+ }
+
+ NTSTATUS
+ NTAPI
+ MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
+ {
+ SIZE_T i;
+
+ /* Check if there's no imports or if we're a boot driver */
+ if ((ImportList == (PVOID)-1) ||
+ (ImportList == (PVOID)-2) ||
+ (ImportList->Count == 0))
+ {
+ /* Then there's nothing to do */
+ return STATUS_SUCCESS;
+ }
+
+ /* Otherwise, FIXME */
+ DPRINT1("%u imports not dereferenced!\n", ImportList->Count);
+ for (i = 0; i < ImportList->Count; i++)
+ {
+ DPRINT1("%wZ <%wZ>\n", &ImportList->Entry[i]->FullDllName, &ImportList->Entry[i]->BaseDllName);
+ }
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ VOID
+ NTAPI
+ MiClearImports(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
+ {
+ PAGED_CODE();
+
+ /* Check if there's no imports or we're a boot driver or only one entry */
+ if ((LdrEntry->LoadedImports == (PVOID)-1) ||
+ (LdrEntry->LoadedImports == (PVOID)-2) ||
+ ((ULONG_PTR)LdrEntry->LoadedImports & 1))
+ {
+ /* Nothing to do */
+ return;
+ }
+
+ /* Otherwise, free the import list */
+ ExFreePool(LdrEntry->LoadedImports);
+ }
+
+ PVOID
+ NTAPI
+ MiFindExportedRoutineByName(IN PVOID DllBase,
+ IN PANSI_STRING ExportName)
+ {
+ PULONG NameTable;
+ PUSHORT OrdinalTable;
+ PIMAGE_EXPORT_DIRECTORY ExportDirectory;
+ LONG Low = 0, Mid = 0, High, Ret;
+ USHORT Ordinal;
+ PVOID Function;
+ ULONG ExportSize;
+ PULONG ExportTable;
+ PAGED_CODE();
+
+ /* Get the export directory */
+ ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &ExportSize);
+ if (!ExportDirectory) return NULL;
+
+ /* Setup name tables */
+ NameTable = (PULONG)((ULONG_PTR)DllBase +
+ ExportDirectory->AddressOfNames);
+ OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
+ ExportDirectory->AddressOfNameOrdinals);
+
+ /* Do a binary search */
+ High = ExportDirectory->NumberOfNames - 1;
+ while (High >= Low)
+ {
+ /* Get new middle value */
+ Mid = (Low + High) >> 1;
+
+ /* Compare name */
+ Ret = strcmp(ExportName->Buffer, (PCHAR)DllBase + NameTable[Mid]);
+ if (Ret < 0)
+ {
+ /* Update high */
+ High = Mid - 1;
+ }
+ else if (Ret > 0)
+ {
+ /* Update low */
+ Low = Mid + 1;
+ }
+ else
+ {
+ /* We got it */
+ break;
+ }
+ }
+
+ /* Check if we couldn't find it */
+ if (High < Low) return NULL;
+
+ /* Otherwise, this is the ordinal */
+ Ordinal = OrdinalTable[Mid];
+
+ /* Resolve the address and write it */
+ ExportTable = (PULONG)((ULONG_PTR)DllBase +
+ ExportDirectory->AddressOfFunctions);
+ Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
+
+ /* We found it! */
+ ASSERT(!(Function > (PVOID)ExportDirectory) &&
+ (Function < (PVOID)((ULONG_PTR)ExportDirectory + ExportSize)));
+ return Function;
+ }
+
+ PVOID
+ NTAPI
+ MiLocateExportName(IN PVOID DllBase,
+ IN PCHAR ExportName)
+ {
+ PULONG NameTable;
+ PUSHORT OrdinalTable;
+ PIMAGE_EXPORT_DIRECTORY ExportDirectory;
+ LONG Low = 0, Mid = 0, High, Ret;
+ USHORT Ordinal;
+ PVOID Function;
+ ULONG ExportSize;
+ PULONG ExportTable;
+ PAGED_CODE();
+
+ /* Get the export directory */
+ ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &ExportSize);
+ if (!ExportDirectory) return NULL;
+
+ /* Setup name tables */
+ NameTable = (PULONG)((ULONG_PTR)DllBase +
+ ExportDirectory->AddressOfNames);
+ OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
+ ExportDirectory->AddressOfNameOrdinals);
+
+ /* Do a binary search */
+ High = ExportDirectory->NumberOfNames - 1;
+ while (High >= Low)
+ {
+ /* Get new middle value */
+ Mid = (Low + High) >> 1;
+
+ /* Compare name */
+ Ret = strcmp(ExportName, (PCHAR)DllBase + NameTable[Mid]);
+ if (Ret < 0)
+ {
+ /* Update high */
+ High = Mid - 1;
+ }
+ else if (Ret > 0)
+ {
+ /* Update low */
+ Low = Mid + 1;
+ }
+ else
+ {
+ /* We got it */
+ break;
+ }
+ }
+
+ /* Check if we couldn't find it */
+ if (High < Low) return NULL;
+
+ /* Otherwise, this is the ordinal */
+ Ordinal = OrdinalTable[Mid];
+
+ /* Resolve the address and write it */
+ ExportTable = (PULONG)((ULONG_PTR)DllBase +
+ ExportDirectory->AddressOfFunctions);
+ Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
+
+ /* Check if the function is actually a forwarder */
+ if (((ULONG_PTR)Function > (ULONG_PTR)ExportDirectory) &&
+ ((ULONG_PTR)Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
+ {
+ /* It is, fail */
+ return NULL;
+ }
+
+ /* We found it */
+ return Function;
+ }
+
+ NTSTATUS
+ NTAPI
+ MmCallDllInitialize(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
+ IN PLIST_ENTRY ListHead)
+ {
+ UNICODE_STRING ServicesKeyName = RTL_CONSTANT_STRING(
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
+ PMM_DLL_INITIALIZE DllInit;
+ UNICODE_STRING RegPath, ImportName;
+ NTSTATUS Status;
+
+ /* Try to see if the image exports a DllInitialize routine */
+ DllInit = (PMM_DLL_INITIALIZE)MiLocateExportName(LdrEntry->DllBase,
+ "DllInitialize");
+ if (!DllInit) return STATUS_SUCCESS;
+
+ /* Do a temporary copy of BaseDllName called ImportName
+ * because we'll alter the length of the string
+ */
+ ImportName.Length = LdrEntry->BaseDllName.Length;
+ ImportName.MaximumLength = LdrEntry->BaseDllName.MaximumLength;
+ ImportName.Buffer = LdrEntry->BaseDllName.Buffer;
+
+ /* Obtain the path to this dll's service in the registry */
+ RegPath.MaximumLength = ServicesKeyName.Length +
+ ImportName.Length + sizeof(UNICODE_NULL);
+ RegPath.Buffer = ExAllocatePoolWithTag(NonPagedPool,
+ RegPath.MaximumLength,
+ TAG_LDR_WSTR);
+
+ /* Check if this allocation was unsuccessful */
+ if (!RegPath.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Build and append the service name itself */
+ RegPath.Length = ServicesKeyName.Length;
+ RtlCopyMemory(RegPath.Buffer,
+ ServicesKeyName.Buffer,
+ ServicesKeyName.Length);
+
+ /* Check if there is a dot in the filename */
+ if (wcschr(ImportName.Buffer, L'.'))
+ {
+ /* Remove the extension */
+ ImportName.Length = (wcschr(ImportName.Buffer, L'.') -
+ ImportName.Buffer) * sizeof(WCHAR);
+ }
+
+ /* Append service name (the basename without extension) */
+ RtlAppendUnicodeStringToString(&RegPath, &ImportName);
+
+ /* Now call the DllInit func */
+ DPRINT("Calling DllInit(%wZ)\n", &RegPath);
+ Status = DllInit(&RegPath);
+
+ /* Clean up */
+ ExFreePool(RegPath.Buffer);
+
+ /* Return status value which DllInitialize returned */
+ return Status;
+ }
+
+ VOID
+ NTAPI
+ MiProcessLoaderEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry,
+ IN BOOLEAN Insert)
+ {
+ KIRQL OldIrql;
+
+ /* Acquire the lock */
+ KeAcquireSpinLock(&PsLoadedModuleSpinLock, &OldIrql);
+
+ /* Insert or remove from the list */
+ Insert ? InsertTailList(&PsLoadedModuleList, &LdrEntry->InLoadOrderLinks) :
+ RemoveEntryList(&LdrEntry->InLoadOrderLinks);
+
+ /* Release the lock */
+ KeReleaseSpinLock(&PsLoadedModuleSpinLock, OldIrql);
+ }
+
+ VOID
+ NTAPI
+ MiUpdateThunks(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN PVOID OldBase,
+ IN PVOID NewBase,
+ IN ULONG Size)
+ {
+ ULONG_PTR OldBaseTop, Delta;
+ PLDR_DATA_TABLE_ENTRY LdrEntry;
+ PLIST_ENTRY NextEntry;
+ ULONG ImportSize;
+ PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
+ PULONG ImageThunk;
+
+ /* Calculate the top and delta */
+ OldBaseTop = (ULONG_PTR)OldBase + Size - 1;
+ Delta = (ULONG_PTR)NewBase - (ULONG_PTR)OldBase;
+
+ /* Loop the loader block */
+ for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
+ NextEntry != &LoaderBlock->LoadOrderListHead;
+ NextEntry = NextEntry->Flink)
+ {
+ /* Get the loader entry */
+ LdrEntry = CONTAINING_RECORD(NextEntry,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
+
+ /* Get the import table */
+ ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_IMPORT,
+ &ImportSize);
+ if (!ImportDescriptor) continue;
+
+ /* Make sure we have an IAT */
+ DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
+ while ((ImportDescriptor->Name) &&
+ (ImportDescriptor->OriginalFirstThunk))
+ {
+ /* Get the image thunk */
+ ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +
+ ImportDescriptor->FirstThunk);
+ while (*ImageThunk)
+ {
+ /* Check if it's within this module */
+ if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
+ {
+ /* Relocate it */
+ DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
+ ImageThunk, *ImageThunk, *ImageThunk + Delta);
+ *ImageThunk += Delta;
+ }
+
+ /* Go to the next thunk */
+ ImageThunk++;
+ }
+
+ /* Go to the next import */
+ ImportDescriptor++;
+ }
+ }
+ }
+
+ NTSTATUS
+ NTAPI
+ MiSnapThunk(IN PVOID DllBase,
+ IN PVOID ImageBase,
+ IN PIMAGE_THUNK_DATA Name,
+ IN PIMAGE_THUNK_DATA Address,
+ IN PIMAGE_EXPORT_DIRECTORY ExportDirectory,
+ IN ULONG ExportSize,
+ IN BOOLEAN SnapForwarder,
+ OUT PCHAR *MissingApi)
+ {
+ BOOLEAN IsOrdinal;
+ USHORT Ordinal;
+ PULONG NameTable;
+ PUSHORT OrdinalTable;
+ PIMAGE_IMPORT_BY_NAME NameImport;
+ USHORT Hint;
+ ULONG Low = 0, Mid = 0, High;
+ LONG Ret;
+ NTSTATUS Status;
+ PCHAR MissingForwarder;
+ CHAR NameBuffer[MAXIMUM_FILENAME_LENGTH];
+ PULONG ExportTable;
+ ANSI_STRING DllName;
+ UNICODE_STRING ForwarderName;
+ PLIST_ENTRY NextEntry;
+ PLDR_DATA_TABLE_ENTRY LdrEntry;
+ ULONG ForwardExportSize;
+ PIMAGE_EXPORT_DIRECTORY ForwardExportDirectory;
+ PIMAGE_IMPORT_BY_NAME ForwardName;
+ ULONG ForwardLength;
+ IMAGE_THUNK_DATA ForwardThunk;
+ PAGED_CODE();
+
+ /* Check if this is an ordinal */
+ IsOrdinal = IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal);
+ if ((IsOrdinal) && !(SnapForwarder))
+ {
+ /* Get the ordinal number and set it as missing */
+ Ordinal = (USHORT)(IMAGE_ORDINAL(Name->u1.Ordinal) -
+ ExportDirectory->Base);
+ *MissingApi = (PCHAR)(ULONG_PTR)Ordinal;
+ }
+ else
+ {
+ /* Get the VA if we don't have to snap */
+ if (!SnapForwarder) Name->u1.AddressOfData += (ULONG_PTR)ImageBase;
+ NameImport = (PIMAGE_IMPORT_BY_NAME)Name->u1.AddressOfData;
+
+ /* Copy the procedure name */
+ strncpy(*MissingApi,
+ (PCHAR)&NameImport->Name[0],
+ MAXIMUM_FILENAME_LENGTH - 1);
+
+ /* Setup name tables */
+ DPRINT("Import name: %s\n", NameImport->Name);
+ NameTable = (PULONG)((ULONG_PTR)DllBase +
+ ExportDirectory->AddressOfNames);
+ OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
+ ExportDirectory->AddressOfNameOrdinals);
+
+ /* Get the hint and check if it's valid */
+ Hint = NameImport->Hint;
+ if ((Hint < ExportDirectory->NumberOfNames) &&
+ !(strcmp((PCHAR) NameImport->Name, (PCHAR)DllBase + NameTable[Hint])))
+ {
+ /* We have a match, get the ordinal number from here */
+ Ordinal = OrdinalTable[Hint];
+ }
+ else
+ {
+ /* Do a binary search */
+ High = ExportDirectory->NumberOfNames - 1;
+ while (High >= Low)
+ {
+ /* Get new middle value */
+ Mid = (Low + High) >> 1;
+
+ /* Compare name */
+ Ret = strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Mid]);
+ if (Ret < 0)
+ {
+ /* Update high */
+ High = Mid - 1;
+ }
+ else if (Ret > 0)
+ {
+ /* Update low */
+ Low = Mid + 1;
+ }
+ else
+ {
+ /* We got it */
+ break;
+ }
+ }
+
+ /* Check if we couldn't find it */
+ if (High < Low) return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
+
+ /* Otherwise, this is the ordinal */
+ Ordinal = OrdinalTable[Mid];
+ }
+ }
+
+ /* Check if the ordinal is invalid */
+ if (Ordinal >= ExportDirectory->NumberOfFunctions)
+ {
+ /* Fail */
+ Status = STATUS_DRIVER_ORDINAL_NOT_FOUND;
+ }
+ else
+ {
+ /* In case the forwarder is missing */
+ MissingForwarder = NameBuffer;
+
+ /* Resolve the address and write it */
+ ExportTable = (PULONG)((ULONG_PTR)DllBase +
+ ExportDirectory->AddressOfFunctions);
+ Address->u1.Function = (ULONG_PTR)DllBase + ExportTable[Ordinal];
+
+ /* Assume success from now on */
+ Status = STATUS_SUCCESS;
+
+ /* Check if the function is actually a forwarder */
+ if ((Address->u1.Function > (ULONG_PTR)ExportDirectory) &&
+ (Address->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
+ {
+ /* Now assume failure in case the forwarder doesn't exist */
+ Status = STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
+
+ /* Build the forwarder name */
+ DllName.Buffer = (PCHAR)Address->u1.Function;
+ DllName.Length = strchr(DllName.Buffer, '.') -
+ DllName.Buffer +
+ sizeof(ANSI_NULL);
+ DllName.MaximumLength = DllName.Length;
+
+ /* Convert it */
+ if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ForwarderName,
+ &DllName,
+ TRUE)))
+ {
+ /* We failed, just return an error */
+ return Status;
+ }
+
+ /* Loop the module list */
+ NextEntry = PsLoadedModuleList.Flink;
+ while (NextEntry != &PsLoadedModuleList)
+ {
+ /* Get the loader entry */
+ LdrEntry = CONTAINING_RECORD(NextEntry,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
+
+ /* Check if it matches */
+ if (RtlPrefixString((PSTRING)&ForwarderName,
+ (PSTRING)&LdrEntry->BaseDllName,
+ TRUE))
+ {
+ /* Get the forwarder export directory */
+ ForwardExportDirectory =
+ RtlImageDirectoryEntryToData(LdrEntry->DllBase,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &ForwardExportSize);
+ if (!ForwardExportDirectory) break;
+
+ /* Allocate a name entry */
+ ForwardLength = strlen(DllName.Buffer + DllName.Length) +
+ sizeof(ANSI_NULL);
+ ForwardName = ExAllocatePoolWithTag(PagedPool,
+ sizeof(*ForwardName) +
+ ForwardLength,
+ TAG_LDR_WSTR);
+ if (!ForwardName) break;
+
+ /* Copy the data */
+ RtlCopyMemory(&ForwardName->Name[0],
+ DllName.Buffer + DllName.Length,
+ ForwardLength);
+ ForwardName->Hint = 0;
+
+ /* Set the new address */
- *(PULONG)&ForwardThunk.u1.AddressOfData = (ULONG)ForwardName;
++ ForwardThunk.u1.AddressOfData = (ULONG_PTR)ForwardName;
+
+ /* Snap the forwarder */
+ Status = MiSnapThunk(LdrEntry->DllBase,
+ ImageBase,
+ &ForwardThunk,
+ &ForwardThunk,
+ ForwardExportDirectory,
+ ForwardExportSize,
+ TRUE,
+ &MissingForwarder);
+
+ /* Free the forwarder name and set the thunk */
+ ExFreePoolWithTag(ForwardName, TAG_LDR_WSTR);
+ Address->u1 = ForwardThunk.u1;
+ break;
+ }
+
+ /* Go to the next entry */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Free the name */
+ RtlFreeUnicodeString(&ForwarderName);
+ }
+ }
+
+ /* Return status */
+ return Status;
+ }
+
+ NTSTATUS
+ NTAPI
+ MmUnloadSystemImage(IN PVOID ImageHandle)
+ {
+ PLDR_DATA_TABLE_ENTRY LdrEntry = ImageHandle;
+ PVOID BaseAddress = LdrEntry->DllBase;
+ NTSTATUS Status;
+ ANSI_STRING TempName;
+ BOOLEAN HadEntry = FALSE;
+
+ /* Acquire the loader lock */
+ KeEnterCriticalRegion();
+ KeWaitForSingleObject(&MmSystemLoadLock,
+ WrVirtualMemory,
+ KernelMode,
+ FALSE,
+ NULL);
+
+ /* Check if this driver was loaded at boot and didn't get imports parsed */
+ if (LdrEntry->LoadedImports == (PVOID)-1) goto Done;
+
+ /* We should still be alive */
+ ASSERT(LdrEntry->LoadCount != 0);
+ LdrEntry->LoadCount--;
+
+ /* Check if we're still loaded */
+ if (LdrEntry->LoadCount) goto Done;
+
+ /* We should cleanup... are symbols loaded */
+ if (LdrEntry->Flags & LDRP_DEBUG_SYMBOLS_LOADED)
+ {
+ /* Create the ANSI name */
+ Status = RtlUnicodeStringToAnsiString(&TempName,
+ &LdrEntry->BaseDllName,
+ TRUE);
+ if (NT_SUCCESS(Status))
+ {
+ /* Unload the symbols */
+ DbgUnLoadImageSymbols(&TempName, BaseAddress, -1);
+ RtlFreeAnsiString(&TempName);
+ }
+ }
+
+ /* FIXME: Free the driver */
+ //MmFreeSection(LdrEntry->DllBase);
+
+ /* Check if we're linked in */
+ if (LdrEntry->InLoadOrderLinks.Flink)
+ {
+ /* Remove us */
+ MiProcessLoaderEntry(LdrEntry, FALSE);
+ HadEntry = TRUE;
+ }
+
+ /* Dereference and clear the imports */
+ MiDereferenceImports(LdrEntry->LoadedImports);
+ MiClearImports(LdrEntry);
+
+ /* Check if the entry needs to go away */
+ if (HadEntry)
+ {
+ /* Check if it had a name */
+ if (LdrEntry->FullDllName.Buffer)
+ {
+ /* Free it */
+ ExFreePool(LdrEntry->FullDllName.Buffer);
+ }
+
+ /* Check if we had a section */
+ if (LdrEntry->SectionPointer)
+ {
+ /* Dereference it */
+ ObDereferenceObject(LdrEntry->SectionPointer);
+ }
+
+ /* Free the entry */
+ ExFreePool(LdrEntry);
+ }
+
+ /* Release the system lock and return */
+ Done:
+ KeReleaseMutant(&MmSystemLoadLock, 1, FALSE, FALSE);
+ KeLeaveCriticalRegion();
+ return STATUS_SUCCESS;
+ }
+
+ NTSTATUS
+ NTAPI
+ MiResolveImageReferences(IN PVOID ImageBase,
+ IN PUNICODE_STRING ImageFileDirectory,
+ IN PUNICODE_STRING NamePrefix OPTIONAL,
+ OUT PCHAR *MissingApi,
+ OUT PWCHAR *MissingDriver,
+ OUT PLOAD_IMPORTS *LoadImports)
+ {
+ PCHAR MissingApiBuffer = *MissingApi, ImportName;
+ PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport;
+ ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize;
+ PLOAD_IMPORTS LoadedImports, NewImports;
+ ULONG GdiLink, NormalLink, i;
+ BOOLEAN ReferenceNeeded, Loaded;
+ ANSI_STRING TempString;
+ UNICODE_STRING NameString, DllName;
+ PLDR_DATA_TABLE_ENTRY LdrEntry = NULL, DllEntry, ImportEntry = NULL;
+ PVOID ImportBase, DllBase;
+ PLIST_ENTRY NextEntry;
+ PIMAGE_EXPORT_DIRECTORY ExportDirectory;
+ NTSTATUS Status;
+ PIMAGE_THUNK_DATA OrigThunk, FirstThunk;
+ PAGED_CODE();
+ DPRINT("%s - ImageBase: %p. ImageFileDirectory: %wZ\n",
+ __FUNCTION__, ImageBase, ImageFileDirectory);
+
+ /* Assume no imports */
+ *LoadImports = (PVOID)-2;
+
+ /* Get the import descriptor */
+ ImportDescriptor = RtlImageDirectoryEntryToData(ImageBase,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_IMPORT,
+ &ImportSize);
+ if (!ImportDescriptor) return STATUS_SUCCESS;
+
+ /* Loop all imports to count them */
+ for (CurrentImport = ImportDescriptor;
+ (CurrentImport->Name) && (CurrentImport->OriginalFirstThunk);
+ CurrentImport++)
+ {
+ /* One more */
+ ImportCount++;
+ }
+
+ /* Make sure we have non-zero imports */
+ if (ImportCount)
+ {
+ /* Calculate and allocate the list we'll need */
+ LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
+ LoadedImports = ExAllocatePoolWithTag(PagedPool,
+ LoadedImportsSize,
+ TAG_LDR_WSTR);
+ if (LoadedImports)
+ {
+ /* Zero it */
+ RtlZeroMemory(LoadedImports, LoadedImportsSize);
+ }
+ }
+ else
+ {
+ /* No table */
+ LoadedImports = NULL;
+ }
+
+ /* Reset the import count and loop descriptors again */
+ ImportCount = GdiLink = NormalLink = 0;
+ while ((ImportDescriptor->Name) && (ImportDescriptor->OriginalFirstThunk))
+ {
+ /* Get the name */
+ ImportName = (PCHAR)((ULONG_PTR)ImageBase + ImportDescriptor->Name);
+
+ /* Check if this is a GDI driver */
+ GdiLink = GdiLink |
+ !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1));
+
+ /* We can also allow dxapi */
+ NormalLink = NormalLink |
+ ((_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) &&
+ (_strnicmp(ImportName, "dxapi", sizeof("dxapi") - 1)));
+
+ /* Check if this is a valid GDI driver */
+ if ((GdiLink) && (NormalLink))
+ {
+ /* It's not, it's importing stuff it shouldn't be! */
+ MiDereferenceImports(LoadedImports);
+ if (LoadedImports) ExFreePool(LoadedImports);
+ return STATUS_PROCEDURE_NOT_FOUND;
+ }
+
+ /* Check if this is a "core" import, which doesn't get referenced */
+ if (!(_strnicmp(ImportName, "ntoskrnl", sizeof("ntoskrnl") - 1)) ||
+ !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) ||
+ !(_strnicmp(ImportName, "hal", sizeof("hal") - 1)))
+ {
+ /* Don't reference this */
+ ReferenceNeeded = FALSE;
+ }
+ else
+ {
+ /* Reference these modules */
+ ReferenceNeeded = TRUE;
+ }
+
+ /* Now setup a unicode string for the import */
+ RtlInitAnsiString(&TempString, ImportName);
+ Status = RtlAnsiStringToUnicodeString(&NameString, &TempString, TRUE);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Failed */
+ MiDereferenceImports(LoadedImports);
+ if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);
+ return Status;
+ }
+
+ /* We don't support name prefixes yet */
+ if (NamePrefix) DPRINT1("Name Prefix not yet supported!\n");
+
+ /* Remember that we haven't loaded the import at this point */
+ CheckDllState:
+ Loaded = FALSE;
+ ImportBase = NULL;
+
+ /* Loop the driver list */
+ NextEntry = PsLoadedModuleList.Flink;
+ while (NextEntry != &PsLoadedModuleList)
+ {
+ /* Get the loader entry and compare the name */
+ LdrEntry = CONTAINING_RECORD(NextEntry,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
+ if (RtlEqualUnicodeString(&NameString,
+ &LdrEntry->BaseDllName,
+ TRUE))
+ {
+ /* Get the base address */
+ ImportBase = LdrEntry->DllBase;
+
+ /* Check if we haven't loaded yet, and we need references */
+ if (!(Loaded) && (ReferenceNeeded))
+ {
+ /* Make sure we're not already loading */
+ if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
+ {
+ /* Increase the load count */
+ LdrEntry->LoadCount++;
+ }
+ }
+
+ /* Done, break out */
+ break;
+ }
+
+ /* Go to the next entry */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Check if we haven't loaded the import yet */
+ if (!ImportBase)
+ {
+ /* Setup the import DLL name */
+ DllName.MaximumLength = NameString.Length +
+ ImageFileDirectory->Length +
+ sizeof(UNICODE_NULL);
+ DllName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
+ DllName.MaximumLength,
+ TAG_LDR_WSTR);
+ if (DllName.Buffer)
+ {
+ /* Setup the base length and copy it */
+ DllName.Length = ImageFileDirectory->Length;
+ RtlCopyMemory(DllName.Buffer,
+ ImageFileDirectory->Buffer,
+ ImageFileDirectory->Length);
+
+ /* Now add the import name and null-terminate it */
+ RtlAppendStringToString((PSTRING)&DllName,
+ (PSTRING)&NameString);
+ DllName.Buffer[(DllName.MaximumLength - 1) / 2] = UNICODE_NULL;
+
+ /* Load the image */
+ Status = MmLoadSystemImage(&DllName,
+ NamePrefix,
+ NULL,
+ 0,
+ (PVOID)&DllEntry,
+ &DllBase);
+ if (NT_SUCCESS(Status))
+ {
+ /* We can free the DLL Name */
+ ExFreePool(DllName.Buffer);
+ }
+ else
+ {
+ /* Fill out the information for the error */
+ *MissingDriver = DllName.Buffer;
+ *(PULONG)MissingDriver |= 1;
+ *MissingApi = NULL;
+ }
+ }
+ else
+ {
+ /* We're out of resources */
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Check if we're OK until now */
+ if (NT_SUCCESS(Status))
+ {
+ /* We're now loaded */
+ Loaded = TRUE;
+
+ /* Sanity check */
+ ASSERT(DllBase = DllEntry->DllBase);
+
+ /* Call the initialization routines */
+ Status = MmCallDllInitialize(DllEntry, &PsLoadedModuleList);
+ if (!NT_SUCCESS(Status))
+ {
+ /* We failed, unload the image */
+ MmUnloadSystemImage(DllEntry);
+ while (TRUE);
+ Loaded = FALSE;
+ }
+ }
+
+ /* Check if we failed by here */
+ if (!NT_SUCCESS(Status))
+ {
+ /* Cleanup and return */
+ RtlFreeUnicodeString(&NameString);
+ MiDereferenceImports(LoadedImports);
+ if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);
+ return Status;
+ }
+
+ /* Loop again to make sure that everything is OK */
+ goto CheckDllState;
+ }
+
+ /* Check if we're support to reference this import */
+ if ((ReferenceNeeded) && (LoadedImports))
+ {
+ /* Make sure we're not already loading */
+ if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
+ {
+ /* Add the entry */
+ LoadedImports->Entry[LoadedImports->Count] = LdrEntry;
+ LoadedImports->Count++;
+ }
+ }
+
+ /* Free the import name */
+ RtlFreeUnicodeString(&NameString);
+
+ /* Set the missing driver name and get the export directory */
+ *MissingDriver = LdrEntry->BaseDllName.Buffer;
+ ExportDirectory = RtlImageDirectoryEntryToData(ImportBase,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_EXPORT,
+ &ExportSize);
+ if (!ExportDirectory)
+ {
+ /* Cleanup and return */
+ MiDereferenceImports(LoadedImports);
+ if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);
+ return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
+ }
+
+ /* Make sure we have an IAT */
+ if (ImportDescriptor->OriginalFirstThunk)
+ {
+ /* Get the first thunks */
+ OrigThunk = (PVOID)((ULONG_PTR)ImageBase +
+ ImportDescriptor->OriginalFirstThunk);
+ FirstThunk = (PVOID)((ULONG_PTR)ImageBase +
+ ImportDescriptor->FirstThunk);
+
+ /* Loop the IAT */
+ while (OrigThunk->u1.AddressOfData)
+ {
+ /* Snap thunk */
+ Status = MiSnapThunk(ImportBase,
+ ImageBase,
+ OrigThunk++,
+ FirstThunk++,
+ ExportDirectory,
+ ExportSize,
+ FALSE,
+ MissingApi);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Cleanup and return */
+ MiDereferenceImports(LoadedImports);
+ if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);
+ return Status;
+ }
+
+ /* Reset the buffer */
+ *MissingApi = MissingApiBuffer;
+ }
+ }
+
+ /* Go to the next import */
+ ImportDescriptor++;
+ }
+
+ /* Check if we have an import list */
+ if (LoadedImports)
+ {
+ /* Reset the count again, and loop entries*/
+ ImportCount = 0;
+ for (i = 0; i < LoadedImports->Count; i++)
+ {
+ if (LoadedImports->Entry[i])
+ {
+ /* Got an entry, OR it with 1 in case it's the single entry */
+ ImportEntry = (PVOID)((ULONG_PTR)LoadedImports->Entry[i] | 1);
+ ImportCount++;
+ }
+ }
+
+ /* Check if we had no imports */
+ if (!ImportCount)
+ {
+ /* Free the list and set it to no imports */
+ ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);
+ LoadedImports = (PVOID)-2;
+ }
+ else if (ImportCount == 1)
+ {
+ /* Just one entry, we can free the table and only use our entry */
+ ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);
+ LoadedImports = (PLOAD_IMPORTS)ImportEntry;
+ }
+ else if (ImportCount != LoadedImports->Count)
+ {
+ /* Allocate a new list */
+ LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
+ NewImports = ExAllocatePoolWithTag(PagedPool,
+ LoadedImportsSize,
+ TAG_LDR_WSTR);
+ if (NewImports)
+ {
+ /* Set count */
+ NewImports->Count = 0;
+
+ /* Loop all the imports */
+ for (i = 0; i < LoadedImports->Count; i++)
+ {
+ /* Make sure it's valid */
+ if (LoadedImports->Entry[i])
+ {
+ /* Copy it */
+ NewImports->Entry[NewImports->Count] = LoadedImports->Entry[i];
+ NewImports->Count++;
+ }
+ }
+
+ /* Free the old copy */
+ ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);
+ LoadedImports = NewImports;
+ }
+ }
+
+ /* Return the list */
+ *LoadImports = LoadedImports;
+ }
+
+ /* Return success */
+ return STATUS_SUCCESS;
+ }
+
+ VOID
+ NTAPI
+ MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+ {
+ PLIST_ENTRY NextEntry;
+ ULONG i = 0;
+ PIMAGE_NT_HEADERS NtHeader;
+ PLDR_DATA_TABLE_ENTRY LdrEntry;
+ PIMAGE_FILE_HEADER FileHeader;
+ BOOLEAN ValidRelocs;
+ PIMAGE_DATA_DIRECTORY DataDirectory;
+ PVOID DllBase, NewImageAddress;
+ NTSTATUS Status;
+
+ /* Loop driver list */
+ for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
+ NextEntry != &LoaderBlock->LoadOrderListHead;
+ NextEntry = NextEntry->Flink)
+ {
+ /* Get the loader entry and NT header */
+ LdrEntry = CONTAINING_RECORD(NextEntry,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
+ NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
+
+ /* Debug info */
+ DPRINT("[Mm0]: Driver at: %p ending at: %p for module: %wZ\n",
+ LdrEntry->DllBase,
+ (ULONG_PTR)LdrEntry->DllBase+ LdrEntry->SizeOfImage,
+ &LdrEntry->FullDllName);
+
+ /* Skip kernel and HAL */
+ /* ROS HACK: Skip BOOTVID/KDCOM too */
+ i++;
+ if (i <= 4) continue;
+
+ /* Skip non-drivers */
+ if (!NtHeader) continue;
+
+ /* Get the file header and make sure we can relocate */
+ FileHeader = &NtHeader->FileHeader;
+ if (FileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) continue;
+ if (NtHeader->OptionalHeader.NumberOfRvaAndSizes <
+ IMAGE_DIRECTORY_ENTRY_BASERELOC) continue;
+
+ /* Everything made sense until now, check the relocation section too */
+ DataDirectory = &NtHeader->OptionalHeader.
+ DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
+ if (!DataDirectory->VirtualAddress)
+ {
+ /* We don't really have relocations */
+ ValidRelocs = FALSE;
+ }
+ else
+ {
+ /* Make sure the size is valid */
+ if ((DataDirectory->VirtualAddress + DataDirectory->Size) >
+ LdrEntry->SizeOfImage)
+ {
+ /* They're not, skip */
+ continue;
+ }
+
+ /* We have relocations */
+ ValidRelocs = TRUE;
+ }
+
+ /* Remember the original address */
+ DllBase = LdrEntry->DllBase;
+
+ /* Allocate a virtual section for the module */
+ NewImageAddress = MmAllocateSection(LdrEntry->SizeOfImage, NULL);
+ if (!NewImageAddress)
+ {
+ /* Shouldn't happen */
+ DPRINT1("[Mm0]: Couldn't allocate driver section!\n");
+ while (TRUE);
+ }
+
+ /* Sanity check */
+ DPRINT("[Mm0]: Copying from: %p to: %p\n", DllBase, NewImageAddress);
+ ASSERT(ExpInitializationPhase == 0);
+
+ /* Now copy the entire driver over */
+ RtlCopyMemory(NewImageAddress, DllBase, LdrEntry->SizeOfImage);
+
+ /* Sanity check */
+ ASSERT(*(PULONG)NewImageAddress == *(PULONG)DllBase);
+
+ /* Set the image base to the address where the loader put it */
+ NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;
+ NtHeader = RtlImageNtHeader(NewImageAddress);
+ NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;
+
+ /* Check if we had relocations */
+ if (ValidRelocs)
+ {
+ /* Relocate the image */
+ Status = LdrRelocateImageWithBias(NewImageAddress,
+ 0,
+ "SYSLDR",
+ STATUS_SUCCESS,
+ STATUS_CONFLICTING_ADDRESSES,
+ STATUS_INVALID_IMAGE_FORMAT);
+ if (!NT_SUCCESS(Status))
+ {
+ /* This shouldn't happen */
+ DPRINT1("Relocations failed!\n");
+ while (TRUE);
+ }
+ }
+
+ /* Update the loader entry */
+ LdrEntry->DllBase = NewImageAddress;
+
+ /* Update the thunks */
+ DPRINT("[Mm0]: Updating thunks to: %wZ\n", &LdrEntry->BaseDllName);
+ MiUpdateThunks(LoaderBlock,
+ DllBase,
+ NewImageAddress,
+ LdrEntry->SizeOfImage);
+
+ /* Update the loader entry */
+ LdrEntry->Flags |= 0x01000000;
+ LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress +
+ NtHeader->OptionalHeader.AddressOfEntryPoint);
+ LdrEntry->SizeOfImage = LdrEntry->SizeOfImage;
+
+ /* Free the old copy */
+ MiFreeBootDriverMemory(DllBase, LdrEntry->SizeOfImage);
+ }
+ }
+
+ BOOLEAN
+ NTAPI
+ MiInitializeLoadedModuleList(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+ {
+ PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;
+ PLIST_ENTRY ListHead, NextEntry;
+ ULONG EntrySize;
+
+ /* Setup the loaded module list and lock */
+ KeInitializeSpinLock(&PsLoadedModuleSpinLock);
+ InitializeListHead(&PsLoadedModuleList);
+
+ /* Get loop variables and the kernel entry */
+ ListHead = &LoaderBlock->LoadOrderListHead;
+ NextEntry = ListHead->Flink;
+ LdrEntry = CONTAINING_RECORD(NextEntry,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
+ PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
+
+ /* Loop the loader block */
+ while (NextEntry != ListHead)
+ {
+ /* Get the loader entry */
+ LdrEntry = CONTAINING_RECORD(NextEntry,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
+
+ /* FIXME: ROS HACK. Make sure this is a driver */
+ if (!RtlImageNtHeader(LdrEntry->DllBase))
+ {
+ /* Skip this entry */
+ NextEntry= NextEntry->Flink;
+ continue;
+ }
+
+ /* Calculate the size we'll need and allocate a copy */
+ EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
+ LdrEntry->BaseDllName.MaximumLength +
+ sizeof(UNICODE_NULL);
+ NewEntry = ExAllocatePoolWithTag(NonPagedPool, EntrySize, TAG_LDR_WSTR);
+ if (!NewEntry) return FALSE;
+
+ /* Copy the entry over */
+ *NewEntry = *LdrEntry;
+
+ /* Allocate the name */
+ NewEntry->FullDllName.Buffer =
+ ExAllocatePoolWithTag(PagedPool,
+ LdrEntry->FullDllName.MaximumLength +
+ sizeof(UNICODE_NULL),
+ TAG_LDR_WSTR);
+ if (!NewEntry->FullDllName.Buffer) return FALSE;
+
+ /* Set the base name */
+ NewEntry->BaseDllName.Buffer = (PVOID)(NewEntry + 1);
+
+ /* Copy the full and base name */
+ RtlCopyMemory(NewEntry->FullDllName.Buffer,
+ LdrEntry->FullDllName.Buffer,
+ LdrEntry->FullDllName.MaximumLength);
+ RtlCopyMemory(NewEntry->BaseDllName.Buffer,
+ LdrEntry->BaseDllName.Buffer,
+ LdrEntry->BaseDllName.MaximumLength);
+
+ /* Null-terminate the base name */
+ NewEntry->BaseDllName.Buffer[NewEntry->BaseDllName.Length /
+ sizeof(WCHAR)] = UNICODE_NULL;
+
+ /* Insert the entry into the list */
+ InsertTailList(&PsLoadedModuleList, &NewEntry->InLoadOrderLinks);
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Build the import lists for the boot drivers */
+ //MiBuildImportsForBootDrivers();
+
+ /* We're done */
+ return TRUE;
+ }
+
+ BOOLEAN
+ NTAPI
+ MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress)
+ {
+ PIMAGE_NT_HEADERS NtHeader;
+ PAGED_CODE();
+
+ /* Get NT Headers */
+ NtHeader = RtlImageNtHeader(BaseAddress);
+ if (NtHeader)
+ {
+ /* Check if this image is only safe for UP while we have 2+ CPUs */
+ if ((KeNumberProcessors > 1) &&
+ (NtHeader->FileHeader.Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY))
+ {
+ /* Fail */
+ return FALSE;
+ }
+ }
+
+ /* Otherwise, it's safe */
+ return TRUE;
+ }
+
+ NTSTATUS
+ NTAPI
+ MmCheckSystemImage(IN HANDLE ImageHandle,
+ IN BOOLEAN PurgeSection)
+ {
+ NTSTATUS Status;
+ HANDLE SectionHandle;
+ PVOID ViewBase = NULL;
+ SIZE_T ViewSize = 0;
+ IO_STATUS_BLOCK IoStatusBlock;
+ FILE_STANDARD_INFORMATION FileStandardInfo;
+ KAPC_STATE ApcState;
+ PAGED_CODE();
+
+ /* Create a section for the DLL */
+ Status = ZwCreateSection(&SectionHandle,
+ SECTION_MAP_EXECUTE,
+ NULL,
+ NULL,
+ PAGE_EXECUTE,
+ SEC_COMMIT,
+ ImageHandle);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Make sure we're in the system process */
+ KeStackAttachProcess(&PsInitialSystemProcess->Pcb, &ApcState);
+
+ /* Map it */
+ Status = ZwMapViewOfSection(SectionHandle,
+ NtCurrentProcess(),
+ &ViewBase,
+ 0,
+ 0,
+ NULL,
+ &ViewSize,
+ ViewShare,
+ 0,
+ PAGE_EXECUTE);
+ if (!NT_SUCCESS(Status))
+ {
+ /* We failed, close the handle and return */
+ KeUnstackDetachProcess(&ApcState);
+ ZwClose(SectionHandle);
+ return Status;
+ }
+
+ /* Now query image information */
+ Status = ZwQueryInformationFile(ImageHandle,
+ &IoStatusBlock,
+ &FileStandardInfo,
+ sizeof(FileStandardInfo),
+ FileStandardInformation);
+ if ( NT_SUCCESS(Status) )
+ {
+ /* First, verify the checksum */
+ if (!LdrVerifyMappedImageMatchesChecksum(ViewBase,
+ FileStandardInfo.
+ EndOfFile.LowPart,
+ FileStandardInfo.
+ EndOfFile.LowPart))
+ {
+ /* Set checksum failure */
+ Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
+ }
+
+ /* Check that it's a valid SMP image if we have more then one CPU */
+ if (!MmVerifyImageIsOkForMpUse(ViewBase))
+ {
+ /* Otherwise it's not the right image */
+ Status = STATUS_IMAGE_MP_UP_MISMATCH;
+ }
+ }
+
+ /* Unmap the section, close the handle, and return status */
+ ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
+ KeUnstackDetachProcess(&ApcState);
+ ZwClose(SectionHandle);
+ return Status;
+ }
+
+ NTSTATUS
+ NTAPI
+ MmLoadSystemImage(IN PUNICODE_STRING FileName,
+ IN PUNICODE_STRING NamePrefix OPTIONAL,
+ IN PUNICODE_STRING LoadedName OPTIONAL,
+ IN ULONG Flags,
+ OUT PVOID *ModuleObject,
+ OUT PVOID *ImageBaseAddress)
+ {
+ PVOID ModuleLoadBase = NULL;
+ NTSTATUS Status;
+ HANDLE FileHandle = NULL;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ PIMAGE_NT_HEADERS NtHeader;
+ UNICODE_STRING BaseName, BaseDirectory, PrefixName, UnicodeTemp;
+ PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
+ ULONG EntrySize, DriverSize;
+ PLOAD_IMPORTS LoadedImports = (PVOID)-2;
+ PCHAR MissingApiName, Buffer;
+ PWCHAR MissingDriverName;
+ HANDLE SectionHandle;
+ ACCESS_MASK DesiredAccess;
+ PVOID Section = NULL;
+ BOOLEAN LockOwned = FALSE;
+ PLIST_ENTRY NextEntry;
+ IMAGE_INFO ImageInfo;
+ ANSI_STRING AnsiTemp;
+ PAGED_CODE();
+
+ /* Detect session-load */
+ if (Flags)
+ {
+ /* Sanity checks */
+ ASSERT(NamePrefix == NULL);
+ ASSERT(LoadedName == NULL);
+
+ /* Make sure the process is in session too */
+ if (!PsGetCurrentProcess()->ProcessInSession) return STATUS_NO_MEMORY;
+ }
+
+ if (ModuleObject) *ModuleObject = NULL;
+ if (ImageBaseAddress) *ImageBaseAddress = NULL;
+
+ /* Allocate a buffer we'll use for names */
+ Buffer = ExAllocatePoolWithTag(NonPagedPool, MAX_PATH, TAG_LDR_WSTR);
+ if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Check for a separator */
+ if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
+ {
+ PWCHAR p;
+ ULONG BaseLength;
+
+ /* Loop the path until we get to the base name */
+ p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
+ while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
+
+ /* Get the length */
+ BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
+ BaseLength *= sizeof(WCHAR);
+
+ /* Setup the string */
+ BaseName.Length = (USHORT)BaseLength;
+ BaseName.Buffer = p;
+ }
+ else
+ {
+ /* Otherwise, we already have a base name */
+ BaseName.Length = FileName->Length;
+ BaseName.Buffer = FileName->Buffer;
+ }
+
+ /* Setup the maximum length */
+ BaseName.MaximumLength = BaseName.Length;
+
+ /* Now compute the base directory */
+ BaseDirectory = *FileName;
+ BaseDirectory.Length -= BaseName.Length;
+ BaseDirectory.MaximumLength = BaseDirectory.Length;
+
+ /* And the prefix, which for now is just the name itself */
+ PrefixName = *FileName;
+
+ /* Check if we have a prefix */
+ if (NamePrefix) DPRINT1("Prefixed images are not yet supported!\n");
+
+ /* Check if we already have a name, use it instead */
+ if (LoadedName) BaseName = *LoadedName;
+
+ /* Acquire the load lock */
+ LoaderScan:
+ ASSERT(LockOwned == FALSE);
+ LockOwned = TRUE;
+ KeEnterCriticalRegion();
+ KeWaitForSingleObject(&MmSystemLoadLock,
+ WrVirtualMemory,
+ KernelMode,
+ FALSE,
+ NULL);
+
+ /* Scan the module list */
+ NextEntry = PsLoadedModuleList.Flink;
+ while (NextEntry != &PsLoadedModuleList)
+ {
+ /* Get the entry and compare the names */
+ LdrEntry = CONTAINING_RECORD(NextEntry,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
+ if (RtlEqualUnicodeString(&PrefixName, &LdrEntry->FullDllName, TRUE))
+ {
+ /* Found it, break out */
+ break;
+ }
+
+ /* Keep scanning */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Check if we found the image */
+ if (NextEntry != &PsLoadedModuleList)
+ {
+ /* Check if we had already mapped a section */
+ if (Section)
+ {
+ /* Dereference and clear */
+ ObDereferenceObject(Section);
+ Section = NULL;
+ }
+
+ /* Check if this was supposed to be a session load */
+ if (!Flags)
+ {
+ /* It wasn't, so just return the data */
+ if (ModuleObject) *ModuleObject = LdrEntry;
+ if (ImageBaseAddress) *ImageBaseAddress = LdrEntry->DllBase;
+ Status = STATUS_IMAGE_ALREADY_LOADED;
+ }
+ else
+ {
+ /* We don't support session loading yet */
+ DPRINT1("Unsupported Session-Load!\n");
+ while (TRUE);
+ }
+
+ /* Do cleanup */
+ goto Quickie;
+ }
+ else if (!Section)
+ {
+ /* It wasn't loaded, and we didn't have a previous attempt */
+ KeReleaseMutant(&MmSystemLoadLock, 1, FALSE, FALSE);
+ KeLeaveCriticalRegion();
+ LockOwned = FALSE;
+
+ /* Check if KD is enabled */
+ if ((KdDebuggerEnabled) && !(KdDebuggerNotPresent))
+ {
+ /* FIXME: Attempt to get image from KD */
+ }
+
+ /* We don't have a valid entry */
+ LdrEntry = NULL;
+
+ /* Setup image attributes */
+ InitializeObjectAttributes(&ObjectAttributes,
+ FileName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+
+ /* Open the image */
+ Status = ZwOpenFile(&FileHandle,
+ FILE_EXECUTE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_DELETE,
+ 0);
+ if (!NT_SUCCESS(Status)) goto Quickie;
+
+ /* Validate it */
+ Status = MmCheckSystemImage(FileHandle, FALSE);
+ if ((Status == STATUS_IMAGE_CHECKSUM_MISMATCH) ||
+ (Status == STATUS_IMAGE_MP_UP_MISMATCH) ||
+ (Status == STATUS_INVALID_IMAGE_FORMAT))
+ {
+ /* Fail loading */
+ goto Quickie;
+ }
+
+ /* Check if this is a session-load */
+ if (Flags)
+ {
+ /* Then we only need read and execute */
+ DesiredAccess = SECTION_MAP_READ | SECTION_MAP_EXECUTE;
+ }
+ else
+ {
+ /* Otherwise, we can allow write access */
+ DesiredAccess = SECTION_ALL_ACCESS;
+ }
+
+ /* Initialize the attributes for the section */
+ InitializeObjectAttributes(&ObjectAttributes,
+ NULL,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+
+ /* Create the section */
+ Status = ZwCreateSection(&SectionHandle,
+ DesiredAccess,
+ &ObjectAttributes,
+ NULL,
+ PAGE_EXECUTE,
+ SEC_IMAGE,
+ FileHandle);
+ if (!NT_SUCCESS(Status)) goto Quickie;
+
+ /* Now get the section pointer */
+ Status = ObReferenceObjectByHandle(SectionHandle,
+ SECTION_MAP_EXECUTE,
+ MmSectionObjectType,
+ KernelMode,
+ &Section,
+ NULL);
+ ZwClose(SectionHandle);
+ if (!NT_SUCCESS(Status)) goto Quickie;
+
+ /* Check if this was supposed to be a session-load */
+ if (Flags)
+ {
+ /* We don't support session loading yet */
+ DPRINT1("Unsupported Session-Load!\n");
+ while (TRUE);
+ }
+
+ /* Check the loader list again, we should end up in the path below */
+ goto LoaderScan;
+ }
+ else
+ {
+ /* We don't have a valid entry */
+ LdrEntry = NULL;
+ }
+
+ /* Load the image */
+ Status = MiLoadImageSection(&Section,
+ &ModuleLoadBase,
+ FileName,
+ FALSE,
+ NULL);
+ ASSERT(Status != STATUS_ALREADY_COMMITTED);
+
+ /* Get the size of the driver */
+ DriverSize = ((PROS_SECTION_OBJECT)Section)->ImageSection->ImageSize;
+
+ /* Make sure we're not being loaded into session space */
+ if (!Flags)
+ {
+ /* Check for success */
+ if (NT_SUCCESS(Status))
+ {
+ /* FIXME: Support large pages for drivers */
+ }
+
+ /* Dereference the section */
+ ObDereferenceObject(Section);
+ Section = NULL;
+ }
+
+ /* Get the NT Header */
+ NtHeader = RtlImageNtHeader(ModuleLoadBase);
+
+ /* Relocate the driver */
+ Status = LdrRelocateImageWithBias(ModuleLoadBase,
+ 0,
+ "SYSLDR",
+ STATUS_SUCCESS,
+ STATUS_CONFLICTING_ADDRESSES,
+ STATUS_INVALID_IMAGE_FORMAT);
+ if (!NT_SUCCESS(Status)) goto Quickie;
+
+ /* Calculate the size we'll need for the entry and allocate it */
+ EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
+ BaseName.Length +
+ sizeof(UNICODE_NULL);
+
+ /* Allocate the entry */
+ LdrEntry = ExAllocatePoolWithTag(NonPagedPool, EntrySize, TAG_MODULE_OBJECT);
+ if (!LdrEntry)
+ {
+ /* Fail */
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Quickie;
+ }
+
+ /* Setup the entry */
+ LdrEntry->Flags = LDRP_LOAD_IN_PROGRESS;
+ LdrEntry->LoadCount = 1;
+ LdrEntry->LoadedImports = LoadedImports;
+ LdrEntry->PatchInformation = NULL;
+
+ /* Check the version */
+ if ((NtHeader->OptionalHeader.MajorOperatingSystemVersion >= 5) &&
+ (NtHeader->OptionalHeader.MajorImageVersion >= 5))
+ {
+ /* Mark this image as a native image */
+ LdrEntry->Flags |= 0x80000000;
+ }
+
+ /* Setup the rest of the entry */
+ LdrEntry->DllBase = ModuleLoadBase;
+ LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase +
+ NtHeader->OptionalHeader.AddressOfEntryPoint);
+ LdrEntry->SizeOfImage = DriverSize;
+ LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum;
+ LdrEntry->SectionPointer = Section;
+
+ /* Now write the DLL name */
+ LdrEntry->BaseDllName.Buffer = (PVOID)(LdrEntry + 1);
+ LdrEntry->BaseDllName.Length = BaseName.Length;
+ LdrEntry->BaseDllName.MaximumLength = BaseName.Length;
+
+ /* Copy and null-terminate it */
+ RtlCopyMemory(LdrEntry->BaseDllName.Buffer,
+ BaseName.Buffer,
+ BaseName.Length);
+ LdrEntry->BaseDllName.Buffer[BaseName.Length / 2] = UNICODE_NULL;
+
+ /* Now allocate the full name */
+ LdrEntry->FullDllName.Buffer = ExAllocatePoolWithTag(PagedPool,
+ PrefixName.Length +
+ sizeof(UNICODE_NULL),
+ TAG_LDR_WSTR);
+ if (!LdrEntry->FullDllName.Buffer)
+ {
+ /* Don't fail, just set it to zero */
+ LdrEntry->FullDllName.Length = 0;
+ LdrEntry->FullDllName.MaximumLength = 0;
+ }
+ else
+ {
+ /* Set it up */
+ LdrEntry->FullDllName.Length = PrefixName.Length;
+ LdrEntry->FullDllName.MaximumLength = PrefixName.Length;
+
+ /* Copy and null-terminate */
+ RtlCopyMemory(LdrEntry->FullDllName.Buffer,
+ PrefixName.Buffer,
+ PrefixName.Length);
+ LdrEntry->FullDllName.Buffer[PrefixName.Length / 2] = UNICODE_NULL;
+ }
+
+ /* Add the entry */
+ MiProcessLoaderEntry(LdrEntry, TRUE);
+
+ /* Resolve imports */
+ MissingApiName = Buffer;
+ Status = MiResolveImageReferences(ModuleLoadBase,
+ &BaseDirectory,
+ NULL,
+ &MissingApiName,
+ &MissingDriverName,
+ &LoadedImports);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ MiProcessLoaderEntry(LdrEntry, FALSE);
+
+ /* Check if we need to free the name */
+ if (LdrEntry->FullDllName.Buffer)
+ {
+ /* Free it */
+ ExFreePool(LdrEntry->FullDllName.Buffer);
+ }
+
+ /* Free the entry itself */
+ ExFreePoolWithTag(LdrEntry, TAG_MODULE_OBJECT);
+ LdrEntry = NULL;
+ goto Quickie;
+ }
+
+ /* Update the loader entry */
+ LdrEntry->Flags |= (LDRP_SYSTEM_MAPPED |
+ LDRP_ENTRY_PROCESSED |
+ LDRP_MM_LOADED);
+ LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
+ LdrEntry->LoadedImports = LoadedImports;
+
+ /* FIXME: Apply driver verifier */
+
+ /* FIXME: Write-protect the system image */
+
+ /* Check if notifications are enabled */
+ if (PsImageNotifyEnabled)
+ {
+ /* Fill out the notification data */
+ ImageInfo.Properties = 0;
+ ImageInfo.ImageAddressingMode = IMAGE_ADDRESSING_MODE_32BIT;
+ ImageInfo.SystemModeImage = TRUE;
+ ImageInfo.ImageSize = LdrEntry->SizeOfImage;
+ ImageInfo.ImageBase = LdrEntry->DllBase;
+ ImageInfo.ImageSectionNumber = ImageInfo.ImageSelector = 0;
+
+ /* Send the notification */
+ PspRunLoadImageNotifyRoutines(FileName, NULL, &ImageInfo);
+ }
+
+ /* Check if there's symbols */
+ #ifdef KDBG
+ /* If KDBG is defined, then we always have symbols */
+ if (TRUE)
+ #else
+ if (MiCacheImageSymbols(LdrEntry->DllBase))
+ #endif
+ {
+ /* Check if the system root is present */
+ if ((PrefixName.Length > (11 * sizeof(WCHAR))) &&
+ !(_wcsnicmp(PrefixName.Buffer, L"\\SystemRoot", 11)))
+ {
+ /* Add the system root */
+ UnicodeTemp = PrefixName;
+ UnicodeTemp.Buffer += 11;
+ UnicodeTemp.Length -= (11 * sizeof(WCHAR));
+ sprintf_nt(Buffer,
+ "%ws%wZ",
+ &SharedUserData->NtSystemRoot[2],
+ &UnicodeTemp);
+ }
+ else
+ {
+ /* Build the name */
+ sprintf_nt(Buffer, "%wZ", &BaseName);
+ }
+
+ /* Setup the ansi string */
+ RtlInitString(&AnsiTemp, Buffer);
+
+ /* Notify the debugger */
+ DbgLoadImageSymbols(&AnsiTemp, LdrEntry->DllBase, -1);
+ LdrEntry->Flags |= LDRP_DEBUG_SYMBOLS_LOADED;
+ }
+
+ /* FIXME: Page the driver */
+ ASSERT(Section == NULL);
+
+ /* Return pointers */
+ if (ModuleObject) *ModuleObject = LdrEntry;
+ if (ImageBaseAddress) *ImageBaseAddress = LdrEntry->DllBase;
+
+ Quickie:
+ /* If we have a file handle, close it */
+ if (FileHandle) ZwClose(FileHandle);
+
+ /* Check if we have the lock acquired */
+ if (LockOwned)
+ {
+ /* Release the lock */
+ KeReleaseMutant(&MmSystemLoadLock, 1, FALSE, FALSE);
+ KeLeaveCriticalRegion();
+ LockOwned = FALSE;
+ }
+
+ /* Check if we had a prefix */
+ if (NamePrefix) ExFreePool(PrefixName.Buffer);
+
+ /* Free the name buffer and return status */
+ ExFreePoolWithTag(Buffer, TAG_LDR_WSTR);
+ return Status;
+ }
+
+ /*
+ * @implemented
+ */
+ PVOID
+ NTAPI
+ MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName)
+ {
+ PVOID ProcAddress = NULL;
+ ANSI_STRING AnsiRoutineName;
+ NTSTATUS Status;
+ PLIST_ENTRY NextEntry;
+ extern LIST_ENTRY PsLoadedModuleList;
+ PLDR_DATA_TABLE_ENTRY LdrEntry;
+ BOOLEAN Found = FALSE;
+ UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
+ UNICODE_STRING HalName = RTL_CONSTANT_STRING(L"hal.dll");
+ ULONG Modules = 0;
+
+ /* Convert routine to ansi name */
+ Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName,
+ SystemRoutineName,
+ TRUE);
+ if (!NT_SUCCESS(Status)) return NULL;
+
+ /* Lock the list */
+ KeEnterCriticalRegion();
+
+ /* Loop the loaded module list */
+ NextEntry = PsLoadedModuleList.Flink;
+ while (NextEntry != &PsLoadedModuleList)
+ {
+ /* Get the entry */
+ LdrEntry = CONTAINING_RECORD(NextEntry,
+ LDR_DATA_TABLE_ENTRY,
+ InLoadOrderLinks);
+
+ /* Check if it's the kernel or HAL */
+ if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
+ {
+ /* Found it */
+ Found = TRUE;
+ Modules++;
+ }
+ else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
+ {
+ /* Found it */
+ Found = TRUE;
+ Modules++;
+ }
+
+ /* Check if we found a valid binary */
+ if (Found)
+ {
+ /* Find the procedure name */
+ ProcAddress = MiFindExportedRoutineByName(LdrEntry->DllBase,
+ &AnsiRoutineName);
+
+ /* Break out if we found it or if we already tried both modules */
+ if (ProcAddress) break;
+ if (Modules == 2) break;
+ }
+
+ /* Keep looping */
+ NextEntry = NextEntry->Flink;
+ }
+
+ /* Release the lock */
+ KeLeaveCriticalRegion();
+
+ /* Free the string and return */
+ RtlFreeAnsiString(&AnsiRoutineName);
+ return ProcAddress;
+ }
+
@ extern KiBugCheckData
@ stdcall KiCheckForKernelApcDelivery()
;KiCheckForSListAddress
-#ifdef _M_IX86
-@ stdcall KiCoprocessorError()
-#endif
+@ stdcall -arch=i386 KiCoprocessorError()
@ stdcall KiDeliverApc(long ptr ptr)
-#ifdef _M_IX86
-@ stdcall KiDispatchInterrupt()
-#endif
+@ stdcall -arch=i386 KiDispatchInterrupt()
@ extern KiEnableTimerWatchdog
@ stdcall KiIpiServiceRoutine(ptr ptr)
-@ fastcall KiReleaseSpinLock(ptr)
+@ FASTCALL KiReleaseSpinLock(ptr)
@ cdecl KiUnexpectedInterrupt()
- ;-arch=i386 Kii386SpinOnSpinLock
+ #ifdef _M_IX86
+ @ stdcall Kii386SpinOnSpinLock(ptr long)
+ #endif
@ stdcall LdrAccessResource(ptr ptr ptr ptr)
@ stdcall LdrEnumResources(ptr ptr long ptr ptr)
@ stdcall LdrFindResourceDirectory_U(ptr ptr long ptr)
// Must be inside the event window.
if ( (pEH->eventMin <= Event) && (pEH->eventMax >= Event))
{
- if ((pEH->Thread != PsGetCurrentThread()) && (pEH->Thread != NULL))
+ if (pEH->head.pti->pEThread != PsGetCurrentThread())
{ // if all process || all thread || other thread same process
if (!(pEH->idProcess) || !(pEH->idThread) ||
- (NtCurrentTeb()->ClientId.UniqueProcess == (PVOID)pEH->idProcess))
+ (NtCurrentTeb()->ClientId.UniqueProcess == (PVOID)(DWORD_PTR)pEH->idProcess))
{
Result = IntCallLowLevelEvent( pEH,
Event,
- \r
- /*\r
- * PROJECT: ReactOS Kernel\r
- * LICENSE: GPL - See COPYING in the top level directory\r
- * FILE: subsystems/win32/win32k/ntuser/kbdlayout.c\r
- * PURPOSE: Keyboard layout management\r
- * COPYRIGHT: Copyright 2007 Saveliy Tretiakov\r
- * Copyright 2008 Colin Finck\r
- *\r
- */\r
- \r
- \r
- /* INCLUDES ******************************************************************/\r
- \r
- #include <w32k.h>\r
- \r
- #define NDEBUG\r
- #include <debug.h>\r
- \r
- PKBL KBLList = NULL; // Keyboard layout list.\r
- \r
- typedef PVOID (*KbdLayerDescriptor)(VOID);\r
- NTSTATUS APIENTRY LdrGetProcedureAddress(PVOID module,\r
- PANSI_STRING import_name,\r
- DWORD flags,\r
- PVOID *func_addr);\r
- \r
- \r
- \r
- /* PRIVATE FUNCTIONS ******************************************************/\r
- \r
- \r
- /*\r
- * Utility function to read a value from the registry more easily.\r
- *\r
- * IN PUNICODE_STRING KeyName -> Name of key to open\r
- * IN PUNICODE_STRING ValueName -> Name of value to open\r
- * OUT PUNICODE_STRING ReturnedValue -> String contained in registry\r
- *\r
- * Returns NTSTATUS\r
- */\r
- \r
- static NTSTATUS APIENTRY ReadRegistryValue( PUNICODE_STRING KeyName,\r
- PUNICODE_STRING ValueName,\r
- PUNICODE_STRING ReturnedValue )\r
- {\r
- NTSTATUS Status;\r
- HANDLE KeyHandle;\r
- OBJECT_ATTRIBUTES KeyAttributes;\r
- PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;\r
- ULONG Length = 0;\r
- ULONG ResLength = 0;\r
- PWCHAR ReturnBuffer;\r
- \r
- InitializeObjectAttributes(&KeyAttributes, KeyName, OBJ_CASE_INSENSITIVE,\r
- NULL, NULL);\r
- Status = ZwOpenKey(&KeyHandle, KEY_READ, &KeyAttributes);\r
- if( !NT_SUCCESS(Status) )\r
- {\r
- return Status;\r
- }\r
- \r
- Status = ZwQueryValueKey(KeyHandle, ValueName, KeyValuePartialInformation,\r
- 0,\r
- 0,\r
- &ResLength);\r
- \r
- if( Status != STATUS_BUFFER_TOO_SMALL )\r
- {\r
- NtClose(KeyHandle);\r
- return Status;\r
- }\r
- \r
- ResLength += sizeof( *KeyValuePartialInfo );\r
- KeyValuePartialInfo =\r
- ExAllocatePoolWithTag(PagedPool, ResLength, TAG_STRING);\r
- Length = ResLength;\r
- \r
- if( !KeyValuePartialInfo )\r
- {\r
- NtClose(KeyHandle);\r
- return STATUS_NO_MEMORY;\r
- }\r
- \r
- Status = ZwQueryValueKey(KeyHandle,\r
- ValueName,\r
- KeyValuePartialInformation,\r
- (PVOID)KeyValuePartialInfo,\r
- Length,\r
- &ResLength);\r
- \r
- if( !NT_SUCCESS(Status) )\r
- {\r
- NtClose(KeyHandle);\r
- ExFreePoolWithTag(KeyValuePartialInfo, TAG_STRING);\r
- return Status;\r
- }\r
- \r
- /* At this point, KeyValuePartialInfo->Data contains the key data */\r
- ReturnBuffer = ExAllocatePoolWithTag(PagedPool,\r
- KeyValuePartialInfo->DataLength,\r
- TAG_STRING);\r
- \r
- if(!ReturnBuffer)\r
- {\r
- NtClose(KeyHandle);\r
- ExFreePoolWithTag(KeyValuePartialInfo, TAG_STRING);\r
- return STATUS_NO_MEMORY;\r
- }\r
- \r
- RtlCopyMemory(ReturnBuffer,\r
- KeyValuePartialInfo->Data,\r
- KeyValuePartialInfo->DataLength);\r
- RtlInitUnicodeString(ReturnedValue, ReturnBuffer);\r
- \r
- ExFreePoolWithTag(KeyValuePartialInfo, TAG_STRING);\r
- NtClose(KeyHandle);\r
- \r
- return Status;\r
- }\r
- \r
- static BOOL UserLoadKbdDll(WCHAR *wsKLID,\r
- HANDLE *phModule,\r
- PKBDTABLES *pKbdTables)\r
- {\r
- NTSTATUS Status;\r
- KbdLayerDescriptor layerDescGetFn;\r
- ANSI_STRING kbdProcedureName;\r
- UNICODE_STRING LayoutKeyName;\r
- UNICODE_STRING LayoutValueName;\r
- UNICODE_STRING LayoutFile;\r
- UNICODE_STRING FullLayoutPath;\r
- UNICODE_STRING klid;\r
- WCHAR LayoutPathBuffer[MAX_PATH] = L"\\SystemRoot\\System32\\";\r
- WCHAR KeyNameBuffer[MAX_PATH] = L"\\REGISTRY\\Machine\\SYSTEM\\"\r
- L"CurrentControlSet\\Control\\Keyboard Layouts\\";\r
- \r
- RtlInitUnicodeString(&klid, wsKLID);\r
- RtlInitUnicodeString(&LayoutValueName,L"Layout File");\r
- RtlInitUnicodeString(&LayoutKeyName, KeyNameBuffer);\r
- LayoutKeyName.MaximumLength = sizeof(KeyNameBuffer);\r
- \r
- RtlAppendUnicodeStringToString(&LayoutKeyName, &klid);\r
- Status = ReadRegistryValue(&LayoutKeyName, &LayoutValueName, &LayoutFile);\r
- \r
- if(!NT_SUCCESS(Status))\r
- {\r
- DPRINT("Can't get layout filename for %wZ. (%08lx)\n", klid, Status);\r
- return FALSE;\r
- }\r
- \r
- DPRINT("Read registry and got %wZ\n", &LayoutFile);\r
- RtlInitUnicodeString(&FullLayoutPath, LayoutPathBuffer);\r
- FullLayoutPath.MaximumLength = sizeof(LayoutPathBuffer);\r
- RtlAppendUnicodeStringToString(&FullLayoutPath, &LayoutFile);\r
- DPRINT("Loading Keyboard DLL %wZ\n", &FullLayoutPath);\r
- ExFreePoolWithTag(LayoutFile.Buffer, TAG_STRING);\r
- \r
- *phModule = EngLoadImage(FullLayoutPath.Buffer);\r
- \r
- if(*phModule)\r
- {\r
- DPRINT("Loaded %wZ\n", &FullLayoutPath);\r
- \r
- RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" );\r
- LdrGetProcedureAddress((PVOID)*phModule,\r
- &kbdProcedureName,\r
- 0,\r
- (PVOID*)&layerDescGetFn);\r
- \r
- if(layerDescGetFn)\r
- {\r
- *pKbdTables = layerDescGetFn();\r
- }\r
- else\r
- {\r
- DPRINT1("Error: %wZ has no KbdLayerDescriptor()\n", &FullLayoutPath);\r
- }\r
- \r
- if(!layerDescGetFn || !*pKbdTables)\r
- {\r
- DPRINT1("Failed to load the keyboard layout.\n");\r
- EngUnloadImage(*phModule);\r
- return FALSE;\r
- }\r
- }\r
- else\r
- {\r
- DPRINT1("Failed to load dll %wZ\n", &FullLayoutPath);\r
- return FALSE;\r
- }\r
- \r
- return TRUE;\r
- }\r
- \r
- static PKBL UserLoadDllAndCreateKbl(DWORD LocaleId)\r
- {\r
- PKBL NewKbl;\r
- ULONG hKl;\r
- LANGID langid;\r
- \r
- NewKbl = ExAllocatePool(PagedPool, sizeof(KBL));\r
- \r
- if(!NewKbl)\r
- {\r
- DPRINT1("%s: Can't allocate memory!\n", __FUNCTION__);\r
- return NULL;\r
- }\r
- \r
- swprintf(NewKbl->Name, L"%08lx", LocaleId);\r
- \r
- if(!UserLoadKbdDll(NewKbl->Name, &NewKbl->hModule, &NewKbl->KBTables))\r
- {\r
- DPRINT("%s: failed to load %x dll!\n", __FUNCTION__, LocaleId);\r
- ExFreePool(NewKbl);\r
- return NULL;\r
- }\r
- \r
- /* Microsoft Office expects this value to be something specific\r
- * for Japanese and Korean Windows with an IME the value is 0xe001\r
- * We should probably check to see if an IME exists and if so then\r
- * set this word properly.\r
- */\r
- langid = PRIMARYLANGID(LANGIDFROMLCID(LocaleId));\r
- hKl = LocaleId;\r
- \r
- if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN)\r
- hKl |= 0xe001 << 16; /* FIXME */\r
- else hKl |= hKl << 16;\r
- \r
- NewKbl->hkl = (HKL)(ULONG_PTR) hKl;\r
- NewKbl->klid = LocaleId;\r
- NewKbl->Flags = 0;\r
- NewKbl->RefCount = 0;\r
- \r
- return NewKbl;\r
- }\r
- \r
- BOOL UserInitDefaultKeyboardLayout()\r
- {\r
- LCID LocaleId;\r
- NTSTATUS Status;\r
- \r
- Status = ZwQueryDefaultLocale(FALSE, &LocaleId);\r
- if (!NT_SUCCESS(Status))\r
- {\r
- DPRINT1("Could not get default locale (%08lx).\n", Status);\r
- }\r
- else\r
- {\r
- DPRINT("DefaultLocale = %08lx\n", LocaleId);\r
- }\r
- \r
- if(!NT_SUCCESS(Status) || !(KBLList = UserLoadDllAndCreateKbl(LocaleId)))\r
- {\r
- DPRINT1("Trying to load US Keyboard Layout.\n");\r
- LocaleId = 0x409;\r
- \r
- if(!(KBLList = UserLoadDllAndCreateKbl(LocaleId)))\r
- {\r
- DPRINT1("Failed to load any Keyboard Layout\n");\r
- return FALSE;\r
- }\r
- }\r
- \r
- KBLList->Flags |= KBL_PRELOAD;\r
- \r
- InitializeListHead(&KBLList->List);\r
- return TRUE;\r
- }\r
- \r
- PKBL W32kGetDefaultKeyLayout(VOID)\r
- {\r
- const WCHAR szKeyboardLayoutPath[] = L"\\Keyboard Layout\\Preload";\r
- const WCHAR szDefaultUserPath[] = L"\\REGISTRY\\USER\\.DEFAULT";\r
- \r
- HANDLE KeyHandle;\r
- LCID LayoutLocaleId = 0;\r
- NTSTATUS Status;\r
- OBJECT_ATTRIBUTES KeyAttributes;\r
- PKBL pKbl;\r
- UNICODE_STRING CurrentUserPath;\r
- UNICODE_STRING FullKeyboardLayoutPath;\r
- UNICODE_STRING LayoutValueName;\r
- UNICODE_STRING LayoutLocaleIdString;\r
- WCHAR wszBuffer[MAX_PATH];\r
- \r
- // Get the path to HKEY_CURRENT_USER\r
- Status = RtlFormatCurrentUserKeyPath(&CurrentUserPath);\r
- \r
- if( NT_SUCCESS(Status) )\r
- {\r
- // FIXME: Is this 100% correct?\r
- // We're called very early, so HKEY_CURRENT_USER might not be available yet. Check this first.\r
- InitializeObjectAttributes(&KeyAttributes, &CurrentUserPath, OBJ_CASE_INSENSITIVE, NULL, NULL);\r
- Status = ZwOpenKey(&KeyHandle, KEY_READ, &KeyAttributes);\r
- \r
- if(Status == STATUS_OBJECT_NAME_NOT_FOUND)\r
- {\r
- // It is not available, so read it from HKEY_USERS\.DEFAULT\r
- RtlCopyMemory(wszBuffer, szDefaultUserPath, sizeof(szDefaultUserPath));\r
- }\r
- else\r
- {\r
- // The path is available\r
- ZwClose(KeyHandle);\r
- RtlCopyMemory(wszBuffer, CurrentUserPath.Buffer, CurrentUserPath.MaximumLength);\r
- }\r
- \r
- // Build the full path\r
- RtlInitUnicodeString(&FullKeyboardLayoutPath, wszBuffer);\r
- FullKeyboardLayoutPath.MaximumLength = MAX_PATH;\r
- \r
- Status = RtlAppendUnicodeToString(&FullKeyboardLayoutPath, szKeyboardLayoutPath);\r
- \r
- if( NT_SUCCESS(Status) )\r
- {\r
- // Return the first keyboard layout listed there\r
- RtlInitUnicodeString(&LayoutValueName, L"1");\r
- \r
- Status = ReadRegistryValue(&FullKeyboardLayoutPath, &LayoutValueName, &LayoutLocaleIdString);\r
- \r
- if( NT_SUCCESS(Status) )\r
- {\r
- RtlUnicodeStringToInteger(&LayoutLocaleIdString, 16, &LayoutLocaleId);\r
- ExFreePoolWithTag(LayoutLocaleIdString.Buffer, TAG_STRING);\r
- }\r
- else\r
- DPRINT1("ReadRegistryValue failed! (%08lx).\n", Status);\r
- }\r
- else\r
- DPRINT1("RtlAppendUnicodeToString failed! (%08lx)\n", Status);\r
- \r
- RtlFreeUnicodeString(&CurrentUserPath);\r
- }\r
- else\r
- DPRINT1("RtlFormatCurrentUserKeyPath failed! (%08lx)\n", Status);\r
- \r
- if(!LayoutLocaleId)\r
- {\r
- // This block is only reached in case of a failure, so use DPRINT1 here\r
- DPRINT1("Assuming default locale for the keyboard layout (0x409 - US)\n");\r
- LayoutLocaleId = 0x409;\r
- }\r
- \r
- pKbl = KBLList;\r
- do\r
- {\r
- if(pKbl->klid == LayoutLocaleId)\r
- {\r
- return pKbl;\r
- }\r
- \r
- pKbl = (PKBL) pKbl->List.Flink;\r
- } while(pKbl != KBLList);\r
- \r
- DPRINT("Loading new default keyboard layout.\n");\r
- pKbl = UserLoadDllAndCreateKbl(LayoutLocaleId);\r
- \r
- if(!pKbl)\r
- {\r
- DPRINT("Failed to load %x!!! Returning any availableKL.\n", LayoutLocaleId);\r
- return KBLList;\r
- }\r
- \r
- InsertTailList(&KBLList->List, &pKbl->List);\r
- return pKbl;\r
- }\r
- \r
- PKBL UserHklToKbl(HKL hKl)\r
- {\r
- PKBL pKbl = KBLList;\r
- do\r
- {\r
- if(pKbl->hkl == hKl) return pKbl;\r
- pKbl = (PKBL) pKbl->List.Flink;\r
- } while(pKbl != KBLList);\r
- \r
- return NULL;\r
- }\r
- \r
- BOOL UserUnloadKbl(PKBL pKbl)\r
- {\r
- /* According to msdn, UnloadKeyboardLayout can fail\r
- if the keyboard layout identifier was preloaded. */\r
- \r
- if(pKbl->Flags & KBL_PRELOAD)\r
- {\r
- DPRINT1("Attempted to unload preloaded keyboard layout.\n");\r
- return FALSE;\r
- }\r
- \r
- if(pKbl->RefCount > 0)\r
- {\r
- /* Layout is used by other threads.\r
- Mark it as unloaded and don't do anything else. */\r
- pKbl->Flags |= KBL_UNLOAD;\r
- }\r
- else\r
- {\r
- //Unload the layout\r
- EngUnloadImage(pKbl->hModule);\r
- RemoveEntryList(&pKbl->List);\r
- ExFreePool(pKbl);\r
- }\r
- \r
- return TRUE;\r
- }\r
- \r
- static PKBL co_UserActivateKbl(PTHREADINFO w32Thread, PKBL pKbl, UINT Flags)\r
- {\r
- PKBL Prev;\r
- \r
- Prev = w32Thread->KeyboardLayout;\r
- Prev->RefCount--;\r
- w32Thread->KeyboardLayout = pKbl;\r
- pKbl->RefCount++;\r
- \r
- if(Flags & KLF_SETFORPROCESS)\r
- {\r
- //FIXME\r
- \r
- }\r
- \r
- if(Prev->Flags & KBL_UNLOAD && Prev->RefCount == 0)\r
- {\r
- UserUnloadKbl(Prev);\r
- }\r
- \r
- // Send WM_INPUTLANGCHANGE to thread's focus window\r
- co_IntSendMessage(w32Thread->MessageQueue->FocusWindow,\r
- WM_INPUTLANGCHANGE,\r
- 0, // FIXME: put charset here (what is this?)\r
- (LPARAM)pKbl->hkl); //klid\r
- \r
- return Prev;\r
- }\r
- \r
- /* EXPORTS *******************************************************************/\r
- \r
- HKL FASTCALL\r
- UserGetKeyboardLayout(\r
- DWORD dwThreadId)\r
- {\r
- NTSTATUS Status;\r
- PETHREAD Thread;\r
- PTHREADINFO W32Thread;\r
- HKL Ret;\r
- \r
- if(!dwThreadId)\r
- {\r
- W32Thread = PsGetCurrentThreadWin32Thread();\r
- return W32Thread->KeyboardLayout->hkl;\r
- }\r
- \r
- Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)dwThreadId, &Thread);\r
- if(!NT_SUCCESS(Status))\r
- {\r
- SetLastWin32Error(ERROR_INVALID_PARAMETER);\r
- return NULL;\r
- }\r
- \r
- W32Thread = PsGetThreadWin32Thread(Thread);\r
- Ret = W32Thread->KeyboardLayout->hkl;\r
- ObDereferenceObject(Thread);\r
- return Ret;\r
- }\r
- \r
- UINT\r
- APIENTRY\r
- NtUserGetKeyboardLayoutList(\r
- INT nItems,\r
- HKL* pHklBuff)\r
- {\r
- UINT Ret = 0;\r
- PKBL pKbl;\r
- \r
- UserEnterShared();\r
- pKbl = KBLList;\r
- \r
- if(nItems == 0)\r
- {\r
- do\r
- {\r
- Ret++;\r
- pKbl = (PKBL) pKbl->List.Flink;\r
- } while(pKbl != KBLList);\r
- }\r
- else\r
- {\r
- _SEH2_TRY\r
- {\r
- ProbeForWrite(pHklBuff, nItems*sizeof(HKL), 4);\r
- \r
- while(Ret < nItems)\r
- {\r
- if(!(pKbl->Flags & KBL_UNLOAD))\r
- {\r
- pHklBuff[Ret] = pKbl->hkl;\r
- Ret++;\r
- pKbl = (PKBL) pKbl->List.Flink;\r
- if(pKbl == KBLList) break;\r
- }\r
- }\r
- \r
- }\r
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)\r
- {\r
- SetLastNtError(_SEH2_GetExceptionCode());\r
- Ret = 0;\r
- }\r
- _SEH2_END;\r
- }\r
- \r
- UserLeave();\r
- return Ret;\r
- }\r
- \r
- BOOL\r
- APIENTRY\r
- NtUserGetKeyboardLayoutName(\r
- LPWSTR lpszName)\r
- {\r
- BOOL ret = FALSE;\r
- PKBL pKbl;\r
- PTHREADINFO pti;\r
- \r
- UserEnterShared();\r
- \r
- _SEH2_TRY\r
- {\r
- ProbeForWrite(lpszName, KL_NAMELENGTH*sizeof(WCHAR), 1);\r
- pti = PsGetCurrentThreadWin32Thread();\r
- pKbl = pti->KeyboardLayout;\r
- RtlCopyMemory(lpszName, pKbl->Name, KL_NAMELENGTH*sizeof(WCHAR));\r
- ret = TRUE;\r
- }\r
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)\r
- {\r
- SetLastNtError(_SEH2_GetExceptionCode());\r
- ret = FALSE;\r
- }\r
- _SEH2_END;\r
- \r
- UserLeave();\r
- return ret;\r
- }\r
- \r
- \r
- HKL\r
- APIENTRY\r
- NtUserLoadKeyboardLayoutEx(\r
- IN HANDLE Handle,\r
- IN DWORD offTable,\r
- IN PUNICODE_STRING puszKeyboardName,\r
- IN HKL hKL,\r
- IN PUNICODE_STRING puszKLID,\r
- IN DWORD dwKLID,\r
- IN UINT Flags)\r
- {\r
- HKL Ret = NULL;\r
- PKBL pKbl = NULL, Cur;\r
- \r
- UserEnterExclusive();\r
- \r
- //Let's see if layout was already loaded.\r
- Cur = KBLList;\r
- do\r
- {\r
- if(Cur->klid == dwKLID)\r
- {\r
- pKbl = Cur;\r
- pKbl->Flags &= ~KBL_UNLOAD;\r
- break;\r
- }\r
- \r
- Cur = (PKBL) Cur->List.Flink;\r
- } while(Cur != KBLList);\r
- \r
- //It wasn't, so load it.\r
- if(!pKbl)\r
- {\r
- pKbl = UserLoadDllAndCreateKbl(dwKLID);\r
- \r
- if(!pKbl)\r
- {\r
- goto the_end;\r
- }\r
- \r
- InsertTailList(&KBLList->List, &pKbl->List);\r
- }\r
- \r
- if(Flags & KLF_REORDER) KBLList = pKbl;\r
- \r
- if(Flags & KLF_ACTIVATE)\r
- {\r
- co_UserActivateKbl(PsGetCurrentThreadWin32Thread(), pKbl, Flags);\r
- }\r
- \r
- Ret = pKbl->hkl;\r
- \r
- //FIXME: KLF_NOTELLSHELL\r
- // KLF_REPLACELANG\r
- // KLF_SUBSTITUTE_OK\r
- \r
- the_end:\r
- UserLeave();\r
- return Ret;\r
- }\r
- \r
- HKL\r
- APIENTRY\r
- NtUserActivateKeyboardLayout(\r
- HKL hKl,\r
- ULONG Flags)\r
- {\r
- PKBL pKbl;\r
- HKL Ret = NULL;\r
- PTHREADINFO pWThread;\r
- \r
- UserEnterExclusive();\r
- \r
- pWThread = PsGetCurrentThreadWin32Thread();\r
- \r
- if(pWThread->KeyboardLayout->hkl == hKl)\r
- {\r
- Ret = hKl;\r
- goto the_end;\r
- }\r
- \r
- if(hKl == (HKL)HKL_NEXT)\r
- {\r
- pKbl = (PKBL)pWThread->KeyboardLayout->List.Flink;\r
- }\r
- else if(hKl == (HKL)HKL_PREV)\r
- {\r
- pKbl = (PKBL)pWThread->KeyboardLayout->List.Blink;\r
- }\r
- else pKbl = UserHklToKbl(hKl);\r
- \r
- //FIXME: KLF_RESET, KLF_SHIFTLOCK\r
- \r
- if(pKbl)\r
- {\r
- if(Flags & KLF_REORDER)\r
- KBLList = pKbl;\r
- \r
- if(pKbl == pWThread->KeyboardLayout)\r
- {\r
- Ret = pKbl->hkl;\r
- }\r
- else\r
- {\r
- pKbl = co_UserActivateKbl(pWThread, pKbl, Flags);\r
- Ret = pKbl->hkl;\r
- }\r
- }\r
- else\r
- {\r
- DPRINT1("%s: Invalid HKL %x!\n", __FUNCTION__, hKl);\r
- }\r
- \r
- the_end:\r
- UserLeave();\r
- return Ret;\r
- }\r
- \r
- BOOL\r
- APIENTRY\r
- NtUserUnloadKeyboardLayout(\r
- HKL hKl)\r
- {\r
- PKBL pKbl;\r
- BOOL Ret = FALSE;\r
- \r
- UserEnterExclusive();\r
- \r
- if((pKbl = UserHklToKbl(hKl)))\r
- {\r
- Ret = UserUnloadKbl(pKbl);\r
- }\r
- else\r
- {\r
- DPRINT1("%s: Invalid HKL %x!\n", __FUNCTION__, hKl);\r
- }\r
- \r
- UserLeave();\r
- return Ret;\r
- }\r
- \r
- /* EOF */\r
+
+ /*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: subsystems/win32/win32k/ntuser/kbdlayout.c
+ * PURPOSE: Keyboard layout management
+ * COPYRIGHT: Copyright 2007 Saveliy Tretiakov
+ * Copyright 2008 Colin Finck
+ *
+ */
+
+
+ /* INCLUDES ******************************************************************/
+
+ #include <w32k.h>
+
+ #define NDEBUG
+ #include <debug.h>
+
+ PKBL KBLList = NULL; // Keyboard layout list.
+
+ typedef PVOID (*KbdLayerDescriptor)(VOID);
+ NTSTATUS APIENTRY LdrGetProcedureAddress(PVOID module,
+ PANSI_STRING import_name,
+ DWORD flags,
+ PVOID *func_addr);
+
+
+
+ /* PRIVATE FUNCTIONS ******************************************************/
+
+
+ /*
+ * Utility function to read a value from the registry more easily.
+ *
+ * IN PUNICODE_STRING KeyName -> Name of key to open
+ * IN PUNICODE_STRING ValueName -> Name of value to open
+ * OUT PUNICODE_STRING ReturnedValue -> String contained in registry
+ *
+ * Returns NTSTATUS
+ */
+
+ static NTSTATUS APIENTRY ReadRegistryValue( PUNICODE_STRING KeyName,
+ PUNICODE_STRING ValueName,
+ PUNICODE_STRING ReturnedValue )
+ {
+ NTSTATUS Status;
+ HANDLE KeyHandle;
+ OBJECT_ATTRIBUTES KeyAttributes;
+ PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
+ ULONG Length = 0;
+ ULONG ResLength = 0;
+ PWCHAR ReturnBuffer;
+
+ InitializeObjectAttributes(&KeyAttributes, KeyName, OBJ_CASE_INSENSITIVE,
+ NULL, NULL);
+ Status = ZwOpenKey(&KeyHandle, KEY_READ, &KeyAttributes);
+ if( !NT_SUCCESS(Status) )
+ {
+ return Status;
+ }
+
+ Status = ZwQueryValueKey(KeyHandle, ValueName, KeyValuePartialInformation,
+ 0,
+ 0,
+ &ResLength);
+
+ if( Status != STATUS_BUFFER_TOO_SMALL )
+ {
+ NtClose(KeyHandle);
+ return Status;
+ }
+
+ ResLength += sizeof( *KeyValuePartialInfo );
+ KeyValuePartialInfo =
+ ExAllocatePoolWithTag(PagedPool, ResLength, TAG_STRING);
+ Length = ResLength;
+
+ if( !KeyValuePartialInfo )
+ {
+ NtClose(KeyHandle);
+ return STATUS_NO_MEMORY;
+ }
+
+ Status = ZwQueryValueKey(KeyHandle,
+ ValueName,
+ KeyValuePartialInformation,
+ (PVOID)KeyValuePartialInfo,
+ Length,
+ &ResLength);
+
+ if( !NT_SUCCESS(Status) )
+ {
+ NtClose(KeyHandle);
+ ExFreePoolWithTag(KeyValuePartialInfo, TAG_STRING);
+ return Status;
+ }
+
+ /* At this point, KeyValuePartialInfo->Data contains the key data */
+ ReturnBuffer = ExAllocatePoolWithTag(PagedPool,
+ KeyValuePartialInfo->DataLength,
+ TAG_STRING);
+
+ if(!ReturnBuffer)
+ {
+ NtClose(KeyHandle);
+ ExFreePoolWithTag(KeyValuePartialInfo, TAG_STRING);
+ return STATUS_NO_MEMORY;
+ }
+
+ RtlCopyMemory(ReturnBuffer,
+ KeyValuePartialInfo->Data,
+ KeyValuePartialInfo->DataLength);
+ RtlInitUnicodeString(ReturnedValue, ReturnBuffer);
+
+ ExFreePoolWithTag(KeyValuePartialInfo, TAG_STRING);
+ NtClose(KeyHandle);
+
+ return Status;
+ }
+
+ static BOOL UserLoadKbdDll(WCHAR *wsKLID,
+ HANDLE *phModule,
+ PKBDTABLES *pKbdTables)
+ {
+ NTSTATUS Status;
+ KbdLayerDescriptor layerDescGetFn;
+ ANSI_STRING kbdProcedureName;
+ UNICODE_STRING LayoutKeyName;
+ UNICODE_STRING LayoutValueName;
+ UNICODE_STRING LayoutFile;
+ UNICODE_STRING FullLayoutPath;
+ UNICODE_STRING klid;
+ WCHAR LayoutPathBuffer[MAX_PATH] = L"\\SystemRoot\\System32\\";
+ WCHAR KeyNameBuffer[MAX_PATH] = L"\\REGISTRY\\Machine\\SYSTEM\\"
+ L"CurrentControlSet\\Control\\Keyboard Layouts\\";
+
+ RtlInitUnicodeString(&klid, wsKLID);
+ RtlInitUnicodeString(&LayoutValueName,L"Layout File");
+ RtlInitUnicodeString(&LayoutKeyName, KeyNameBuffer);
+ LayoutKeyName.MaximumLength = sizeof(KeyNameBuffer);
+
+ RtlAppendUnicodeStringToString(&LayoutKeyName, &klid);
+ Status = ReadRegistryValue(&LayoutKeyName, &LayoutValueName, &LayoutFile);
+
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT("Can't get layout filename for %wZ. (%08lx)\n", klid, Status);
+ return FALSE;
+ }
+
+ DPRINT("Read registry and got %wZ\n", &LayoutFile);
+ RtlInitUnicodeString(&FullLayoutPath, LayoutPathBuffer);
+ FullLayoutPath.MaximumLength = sizeof(LayoutPathBuffer);
+ RtlAppendUnicodeStringToString(&FullLayoutPath, &LayoutFile);
+ DPRINT("Loading Keyboard DLL %wZ\n", &FullLayoutPath);
+ ExFreePoolWithTag(LayoutFile.Buffer, TAG_STRING);
+
+ *phModule = EngLoadImage(FullLayoutPath.Buffer);
+
+ if(*phModule)
+ {
+ DPRINT("Loaded %wZ\n", &FullLayoutPath);
+
+ RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" );
+ LdrGetProcedureAddress((PVOID)*phModule,
+ &kbdProcedureName,
+ 0,
+ (PVOID*)&layerDescGetFn);
+
+ if(layerDescGetFn)
+ {
+ *pKbdTables = layerDescGetFn();
+ }
+ else
+ {
+ DPRINT1("Error: %wZ has no KbdLayerDescriptor()\n", &FullLayoutPath);
+ }
+
+ if(!layerDescGetFn || !*pKbdTables)
+ {
+ DPRINT1("Failed to load the keyboard layout.\n");
+ EngUnloadImage(*phModule);
+ return FALSE;
+ }
+ }
+ else
+ {
+ DPRINT1("Failed to load dll %wZ\n", &FullLayoutPath);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ static PKBL UserLoadDllAndCreateKbl(DWORD LocaleId)
+ {
+ PKBL NewKbl;
+ ULONG hKl;
+ LANGID langid;
+
+ NewKbl = ExAllocatePool(PagedPool, sizeof(KBL));
+
+ if(!NewKbl)
+ {
+ DPRINT1("%s: Can't allocate memory!\n", __FUNCTION__);
+ return NULL;
+ }
+
+ swprintf(NewKbl->Name, L"%08lx", LocaleId);
+
+ if(!UserLoadKbdDll(NewKbl->Name, &NewKbl->hModule, &NewKbl->KBTables))
+ {
+ DPRINT("%s: failed to load %x dll!\n", __FUNCTION__, LocaleId);
+ ExFreePool(NewKbl);
+ return NULL;
+ }
+
+ /* Microsoft Office expects this value to be something specific
+ * for Japanese and Korean Windows with an IME the value is 0xe001
+ * We should probably check to see if an IME exists and if so then
+ * set this word properly.
+ */
+ langid = PRIMARYLANGID(LANGIDFROMLCID(LocaleId));
+ hKl = LocaleId;
+
+ if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN)
+ hKl |= 0xe001 << 16; /* FIXME */
+ else hKl |= hKl << 16;
+
- NewKbl->hkl = (HKL) hKl;
++ NewKbl->hkl = (HKL)(ULONG_PTR) hKl;
+ NewKbl->klid = LocaleId;
+ NewKbl->Flags = 0;
+ NewKbl->RefCount = 0;
+
+ return NewKbl;
+ }
+
+ BOOL UserInitDefaultKeyboardLayout()
+ {
+ LCID LocaleId;
+ NTSTATUS Status;
+
+ Status = ZwQueryDefaultLocale(FALSE, &LocaleId);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not get default locale (%08lx).\n", Status);
+ }
+ else
+ {
+ DPRINT("DefaultLocale = %08lx\n", LocaleId);
+ }
+
+ if(!NT_SUCCESS(Status) || !(KBLList = UserLoadDllAndCreateKbl(LocaleId)))
+ {
+ DPRINT1("Trying to load US Keyboard Layout.\n");
+ LocaleId = 0x409;
+
+ if(!(KBLList = UserLoadDllAndCreateKbl(LocaleId)))
+ {
+ DPRINT1("Failed to load any Keyboard Layout\n");
+ return FALSE;
+ }
+ }
+
+ KBLList->Flags |= KBL_PRELOAD;
+
+ InitializeListHead(&KBLList->List);
+ return TRUE;
+ }
+
+ PKBL W32kGetDefaultKeyLayout(VOID)
+ {
+ const WCHAR szKeyboardLayoutPath[] = L"\\Keyboard Layout\\Preload";
+ const WCHAR szDefaultUserPath[] = L"\\REGISTRY\\USER\\.DEFAULT";
+
+ HANDLE KeyHandle;
+ LCID LayoutLocaleId = 0;
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES KeyAttributes;
+ PKBL pKbl;
+ UNICODE_STRING CurrentUserPath;
+ UNICODE_STRING FullKeyboardLayoutPath;
+ UNICODE_STRING LayoutValueName;
+ UNICODE_STRING LayoutLocaleIdString;
+ WCHAR wszBuffer[MAX_PATH];
+
+ // Get the path to HKEY_CURRENT_USER
+ Status = RtlFormatCurrentUserKeyPath(&CurrentUserPath);
+
+ if( NT_SUCCESS(Status) )
+ {
+ // FIXME: Is this 100% correct?
+ // We're called very early, so HKEY_CURRENT_USER might not be available yet. Check this first.
+ InitializeObjectAttributes(&KeyAttributes, &CurrentUserPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
+ Status = ZwOpenKey(&KeyHandle, KEY_READ, &KeyAttributes);
+
+ if(Status == STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ // It is not available, so read it from HKEY_USERS\.DEFAULT
+ RtlCopyMemory(wszBuffer, szDefaultUserPath, sizeof(szDefaultUserPath));
+ }
+ else
+ {
+ // The path is available
+ ZwClose(KeyHandle);
+ RtlCopyMemory(wszBuffer, CurrentUserPath.Buffer, CurrentUserPath.MaximumLength);
+ }
+
+ // Build the full path
+ RtlInitUnicodeString(&FullKeyboardLayoutPath, wszBuffer);
+ FullKeyboardLayoutPath.MaximumLength = MAX_PATH;
+
+ Status = RtlAppendUnicodeToString(&FullKeyboardLayoutPath, szKeyboardLayoutPath);
+
+ if( NT_SUCCESS(Status) )
+ {
+ // Return the first keyboard layout listed there
+ RtlInitUnicodeString(&LayoutValueName, L"1");
+
+ Status = ReadRegistryValue(&FullKeyboardLayoutPath, &LayoutValueName, &LayoutLocaleIdString);
+
+ if( NT_SUCCESS(Status) )
+ {
+ RtlUnicodeStringToInteger(&LayoutLocaleIdString, 16, &LayoutLocaleId);
+ ExFreePoolWithTag(LayoutLocaleIdString.Buffer, TAG_STRING);
+ }
+ else
+ DPRINT1("ReadRegistryValue failed! (%08lx).\n", Status);
+ }
+ else
+ DPRINT1("RtlAppendUnicodeToString failed! (%08lx)\n", Status);
+
+ RtlFreeUnicodeString(&CurrentUserPath);
+ }
+ else
+ DPRINT1("RtlFormatCurrentUserKeyPath failed! (%08lx)\n", Status);
+
+ if(!LayoutLocaleId)
+ {
+ // This block is only reached in case of a failure, so use DPRINT1 here
+ DPRINT1("Assuming default locale for the keyboard layout (0x409 - US)\n");
+ LayoutLocaleId = 0x409;
+ }
+
+ pKbl = KBLList;
+ do
+ {
+ if(pKbl->klid == LayoutLocaleId)
+ {
+ return pKbl;
+ }
+
+ pKbl = (PKBL) pKbl->List.Flink;
+ } while(pKbl != KBLList);
+
+ DPRINT("Loading new default keyboard layout.\n");
+ pKbl = UserLoadDllAndCreateKbl(LayoutLocaleId);
+
+ if(!pKbl)
+ {
+ DPRINT("Failed to load %x!!! Returning any availableKL.\n", LayoutLocaleId);
+ return KBLList;
+ }
+
+ InsertTailList(&KBLList->List, &pKbl->List);
+ return pKbl;
+ }
+
+ PKBL UserHklToKbl(HKL hKl)
+ {
+ PKBL pKbl = KBLList;
+ do
+ {
+ if(pKbl->hkl == hKl) return pKbl;
+ pKbl = (PKBL) pKbl->List.Flink;
+ } while(pKbl != KBLList);
+
+ return NULL;
+ }
+
+ BOOL UserUnloadKbl(PKBL pKbl)
+ {
+ /* According to msdn, UnloadKeyboardLayout can fail
+ if the keyboard layout identifier was preloaded. */
+
+ if(pKbl->Flags & KBL_PRELOAD)
+ {
+ DPRINT1("Attempted to unload preloaded keyboard layout.\n");
+ return FALSE;
+ }
+
+ if(pKbl->RefCount > 0)
+ {
+ /* Layout is used by other threads.
+ Mark it as unloaded and don't do anything else. */
+ pKbl->Flags |= KBL_UNLOAD;
+ }
+ else
+ {
+ //Unload the layout
+ EngUnloadImage(pKbl->hModule);
+ RemoveEntryList(&pKbl->List);
+ ExFreePool(pKbl);
+ }
+
+ return TRUE;
+ }
+
+ static PKBL co_UserActivateKbl(PTHREADINFO w32Thread, PKBL pKbl, UINT Flags)
+ {
+ PKBL Prev;
+
+ Prev = w32Thread->KeyboardLayout;
+ Prev->RefCount--;
+ w32Thread->KeyboardLayout = pKbl;
+ pKbl->RefCount++;
+
+ if(Flags & KLF_SETFORPROCESS)
+ {
+ //FIXME
+
+ }
+
+ if(Prev->Flags & KBL_UNLOAD && Prev->RefCount == 0)
+ {
+ UserUnloadKbl(Prev);
+ }
+
+ // Send WM_INPUTLANGCHANGE to thread's focus window
+ co_IntSendMessage(w32Thread->MessageQueue->FocusWindow,
+ WM_INPUTLANGCHANGE,
+ 0, // FIXME: put charset here (what is this?)
+ (LPARAM)pKbl->hkl); //klid
+
+ return Prev;
+ }
+
+ /* EXPORTS *******************************************************************/
+
+ HKL FASTCALL
+ UserGetKeyboardLayout(
+ DWORD dwThreadId)
+ {
+ NTSTATUS Status;
+ PETHREAD Thread;
+ PTHREADINFO W32Thread;
+ HKL Ret;
+
+ if(!dwThreadId)
+ {
+ W32Thread = PsGetCurrentThreadWin32Thread();
+ return W32Thread->KeyboardLayout->hkl;
+ }
+
- Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);
++ Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)dwThreadId, &Thread);
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ W32Thread = PsGetThreadWin32Thread(Thread);
+ Ret = W32Thread->KeyboardLayout->hkl;
+ ObDereferenceObject(Thread);
+ return Ret;
+ }
+
+ UINT
+ APIENTRY
+ NtUserGetKeyboardLayoutList(
+ INT nItems,
+ HKL* pHklBuff)
+ {
+ UINT Ret = 0;
+ PKBL pKbl;
+
+ UserEnterShared();
+ pKbl = KBLList;
+
+ if(nItems == 0)
+ {
+ do
+ {
+ Ret++;
+ pKbl = (PKBL) pKbl->List.Flink;
+ } while(pKbl != KBLList);
+ }
+ else
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(pHklBuff, nItems*sizeof(HKL), 4);
+
+ while(Ret < nItems)
+ {
+ if(!(pKbl->Flags & KBL_UNLOAD))
+ {
+ pHklBuff[Ret] = pKbl->hkl;
+ Ret++;
+ pKbl = (PKBL) pKbl->List.Flink;
+ if(pKbl == KBLList) break;
+ }
+ }
+
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Ret = 0;
+ }
+ _SEH2_END;
+ }
+
+ UserLeave();
+ return Ret;
+ }
+
+ BOOL
+ APIENTRY
+ NtUserGetKeyboardLayoutName(
+ LPWSTR lpszName)
+ {
+ BOOL ret = FALSE;
+ PKBL pKbl;
+ PTHREADINFO pti;
+
+ UserEnterShared();
+
+ _SEH2_TRY
+ {
+ ProbeForWrite(lpszName, KL_NAMELENGTH*sizeof(WCHAR), 1);
+ pti = PsGetCurrentThreadWin32Thread();
+ pKbl = pti->KeyboardLayout;
+ RtlCopyMemory(lpszName, pKbl->Name, KL_NAMELENGTH*sizeof(WCHAR));
+ ret = TRUE;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ ret = FALSE;
+ }
+ _SEH2_END;
+
+ UserLeave();
+ return ret;
+ }
+
+
+ HKL
+ APIENTRY
+ NtUserLoadKeyboardLayoutEx(
+ IN HANDLE Handle,
+ IN DWORD offTable,
+ IN PUNICODE_STRING puszKeyboardName,
+ IN HKL hKL,
+ IN PUNICODE_STRING puszKLID,
+ IN DWORD dwKLID,
+ IN UINT Flags)
+ {
+ HKL Ret = NULL;
+ PKBL pKbl = NULL, Cur;
+
+ UserEnterExclusive();
+
+ //Let's see if layout was already loaded.
+ Cur = KBLList;
+ do
+ {
+ if(Cur->klid == dwKLID)
+ {
+ pKbl = Cur;
+ pKbl->Flags &= ~KBL_UNLOAD;
+ break;
+ }
+
+ Cur = (PKBL) Cur->List.Flink;
+ } while(Cur != KBLList);
+
+ //It wasn't, so load it.
+ if(!pKbl)
+ {
+ pKbl = UserLoadDllAndCreateKbl(dwKLID);
+
+ if(!pKbl)
+ {
+ goto the_end;
+ }
+
+ InsertTailList(&KBLList->List, &pKbl->List);
+ }
+
+ if(Flags & KLF_REORDER) KBLList = pKbl;
+
+ if(Flags & KLF_ACTIVATE)
+ {
+ co_UserActivateKbl(PsGetCurrentThreadWin32Thread(), pKbl, Flags);
+ }
+
+ Ret = pKbl->hkl;
+
+ //FIXME: KLF_NOTELLSHELL
+ // KLF_REPLACELANG
+ // KLF_SUBSTITUTE_OK
+
+ the_end:
+ UserLeave();
+ return Ret;
+ }
+
+ HKL
+ APIENTRY
+ NtUserActivateKeyboardLayout(
+ HKL hKl,
+ ULONG Flags)
+ {
+ PKBL pKbl;
+ HKL Ret = NULL;
+ PTHREADINFO pWThread;
+
+ UserEnterExclusive();
+
+ pWThread = PsGetCurrentThreadWin32Thread();
+
+ if(pWThread->KeyboardLayout->hkl == hKl)
+ {
+ Ret = hKl;
+ goto the_end;
+ }
+
+ if(hKl == (HKL)HKL_NEXT)
+ {
+ pKbl = (PKBL)pWThread->KeyboardLayout->List.Flink;
+ }
+ else if(hKl == (HKL)HKL_PREV)
+ {
+ pKbl = (PKBL)pWThread->KeyboardLayout->List.Blink;
+ }
+ else pKbl = UserHklToKbl(hKl);
+
+ //FIXME: KLF_RESET, KLF_SHIFTLOCK
+
+ if(pKbl)
+ {
+ if(Flags & KLF_REORDER)
+ KBLList = pKbl;
+
+ if(pKbl == pWThread->KeyboardLayout)
+ {
+ Ret = pKbl->hkl;
+ }
+ else
+ {
+ pKbl = co_UserActivateKbl(pWThread, pKbl, Flags);
+ Ret = pKbl->hkl;
+ }
+ }
+ else
+ {
+ DPRINT1("%s: Invalid HKL %x!\n", __FUNCTION__, hKl);
+ }
+
+ the_end:
+ UserLeave();
+ return Ret;
+ }
+
+ BOOL
+ APIENTRY
+ NtUserUnloadKeyboardLayout(
+ HKL hKl)
+ {
+ PKBL pKbl;
+ BOOL Ret = FALSE;
+
+ UserEnterExclusive();
+
+ if((pKbl = UserHklToKbl(hKl)))
+ {
+ Ret = UserUnloadKbl(pKbl);
+ }
+ else
+ {
+ DPRINT1("%s: Invalid HKL %x!\n", __FUNCTION__, hKl);
+ }
+
+ UserLeave();
+ return Ret;
+ }
+
+ /* EOF */